X-Git-Url: http://deadsoftware.ru/gitweb?p=dsw-obn.git;a=blobdiff_plain;f=src%2Foberon.c;h=5816c2b3fb0a96f2076f0e6ff82fbeb2b87058d2;hp=f2310db26de0ab2b1bffb82efee2a4b346bf7052;hb=51a1ab2543ec5c221d4a3a9ab89968ae7dd39981;hpb=86c0ca1aafd465a3e0d4a9d6b1af661eba483ae1 diff --git a/src/oberon.c b/src/oberon.c index f2310db..5816c2b 100644 --- a/src/oberon.c +++ b/src/oberon.c @@ -61,7 +61,10 @@ enum { IMPORT, REAL, CHAR, - STRING + STRING, + IF, + THEN, + ELSE }; // ======================================================================= @@ -380,6 +383,18 @@ oberon_read_ident(oberon_context_t * ctx) { ctx -> token = IS; } + else if(strcmp(ident, "IF") == 0) + { + ctx -> token = IF; + } + else if(strcmp(ident, "THEN") == 0) + { + ctx -> token = THEN; + } + else if(strcmp(ident, "ELSE") == 0) + { + ctx -> token = ELSE; + } } static void @@ -1641,6 +1656,10 @@ oberon_make_bin_op(oberon_context_t * ctx, int token, oberon_expr_t * a, oberon_ || b -> result -> class == OBERON_TYPE_INTEGER || a -> result -> class == OBERON_TYPE_REAL || b -> result -> class == OBERON_TYPE_REAL) + { + // accept + } + else { oberon_error(ctx, "used only with numeric types"); } @@ -2845,6 +2864,9 @@ oberon_decl_seq(oberon_context_t * ctx) oberon_prevent_undeclarated_procedures(ctx); } +static void +oberon_statement_seq(oberon_context_t * ctx); + static void oberon_assign(oberon_context_t * ctx, oberon_expr_t * src, oberon_expr_t * dst) { @@ -2877,6 +2899,36 @@ oberon_statement(oberon_context_t * ctx) oberon_opt_proc_parens(ctx, item1); } } + else if(ctx -> token == IF) + { + gen_label_t * end; + gen_label_t * els; + oberon_expr_t * cond; + + els = oberon_generator_reserve_label(ctx); + end = oberon_generator_reserve_label(ctx); + + oberon_assert_token(ctx, IF); + 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); + + if(ctx -> token == ELSE) + { + oberon_generate_label(ctx, els); + oberon_assert_token(ctx, ELSE); + oberon_statement_seq(ctx); + } + + oberon_generate_label(ctx, end); + oberon_assert_token(ctx, END); + } else if(ctx -> token == RETURN) { oberon_assert_token(ctx, RETURN);