X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Foberon.c;h=8a84e1359dcd48f368f41cd945a76bb92a11b599;hb=cbfeec1f4192adbd7adb494ef79447366f051c20;hp=f2c901433aeb49363ef01007ed8336a1e5db1919;hpb=ffca530414fc4c94c3d95b9bc52f4d0cee3326e9;p=dsw-obn.git diff --git a/src/oberon.c b/src/oberon.c index f2c9014..8a84e13 100644 --- a/src/oberon.c +++ b/src/oberon.c @@ -64,7 +64,10 @@ enum { STRING, IF, THEN, - ELSE + ELSE, + ELSIF, + WHILE, + DO }; // ======================================================================= @@ -395,6 +398,18 @@ oberon_read_ident(oberon_context_t * ctx) { ctx -> token = ELSE; } + else if(strcmp(ident, "ELSIF") == 0) + { + ctx -> token = ELSIF; + } + else if(strcmp(ident, "WHILE") == 0) + { + ctx -> token = WHILE; + } + else if(strcmp(ident, "DO") == 0) + { + ctx -> token = DO; + } } static void @@ -2918,8 +2933,25 @@ oberon_statement(oberon_context_t * ctx) oberon_generate_branch(ctx, cond, false, els); oberon_statement_seq(ctx); oberon_generate_goto(ctx, end); - oberon_generate_label(ctx, els); + + while(ctx -> token == ELSIF) + { + els = oberon_generator_reserve_label(ctx); + + oberon_assert_token(ctx, ELSIF); + cond = oberon_expr(ctx); + if(cond -> result -> class != OBERON_TYPE_BOOLEAN) + { + oberon_error(ctx, "condition must be boolean"); + } + oberon_assert_token(ctx, THEN); + oberon_generate_branch(ctx, cond, false, els); + oberon_statement_seq(ctx); + oberon_generate_goto(ctx, end); + oberon_generate_label(ctx, els); + } + if(ctx -> token == ELSE) { oberon_assert_token(ctx, ELSE); @@ -2929,6 +2961,31 @@ oberon_statement(oberon_context_t * ctx) oberon_generate_label(ctx, end); oberon_assert_token(ctx, END); } + else if(ctx -> token == WHILE) + { + gen_label_t * begin; + gen_label_t * end; + oberon_expr_t * cond; + + begin = oberon_generator_reserve_label(ctx); + end = oberon_generator_reserve_label(ctx); + + oberon_assert_token(ctx, WHILE); + oberon_generate_label(ctx, begin); + cond = oberon_expr(ctx); + if(cond -> result -> class != OBERON_TYPE_BOOLEAN) + { + oberon_error(ctx, "condition must be boolean"); + } + oberon_generate_branch(ctx, cond, false, end); + + oberon_assert_token(ctx, DO); + oberon_statement_seq(ctx); + oberon_generate_goto(ctx, begin); + + oberon_assert_token(ctx, END); + oberon_generate_label(ctx, end); + } else if(ctx -> token == RETURN) { oberon_assert_token(ctx, RETURN);