X-Git-Url: http://deadsoftware.ru/gitweb?p=dsw-obn.git;a=blobdiff_plain;f=src%2Foberon.c;h=e95a9bef396271f68b2dff5a6af06147cc530c09;hp=f50f4d300246b4beed4fd6e58afaf21cb307cf3a;hb=5b29102a5440d6511087356b9d9579b7501ca1ec;hpb=99fa357db44a4c30957bd0810e14a20456c58347 diff --git a/src/oberon.c b/src/oberon.c index f50f4d3..e95a9be 100644 --- a/src/oberon.c +++ b/src/oberon.c @@ -71,7 +71,9 @@ enum { REPEAT, UNTIL, FOR, - BY + BY, + LOOP, + EXIT }; // ======================================================================= @@ -165,6 +167,7 @@ oberon_open_scope(oberon_context_t * ctx) scope -> local = scope -> up -> local; scope -> parent = scope -> up -> parent; scope -> parent_type = scope -> up -> parent_type; + scope -> exit_label = scope -> up -> exit_label; } ctx -> decl = scope; @@ -437,6 +440,14 @@ oberon_read_ident(oberon_context_t * ctx) { ctx -> token = BY; } + else if(strcmp(ident, "LOOP") == 0) + { + ctx -> token = LOOP; + } + else if(strcmp(ident, "EXIT") == 0) + { + ctx -> token = EXIT; + } } static void @@ -3160,6 +3171,33 @@ oberon_statement(oberon_context_t * ctx) oberon_generate_label(ctx, end); oberon_assert_token(ctx, END); } + else if(ctx -> token == LOOP) + { + gen_label_t * begin; + gen_label_t * end; + + begin = oberon_generator_reserve_label(ctx); + end = oberon_generator_reserve_label(ctx); + + oberon_open_scope(ctx); + oberon_assert_token(ctx, LOOP); + oberon_generate_label(ctx, begin); + ctx -> decl -> exit_label = end; + oberon_statement_seq(ctx); + oberon_generate_goto(ctx, begin); + oberon_generate_label(ctx, end); + oberon_assert_token(ctx, END); + oberon_close_scope(ctx -> decl); + } + else if(ctx -> token == EXIT) + { + oberon_assert_token(ctx, EXIT); + if(ctx -> decl -> exit_label == NULL) + { + oberon_error(ctx, "not in LOOP-END"); + } + oberon_generate_goto(ctx, ctx -> decl -> exit_label); + } else if(ctx -> token == RETURN) { oberon_assert_token(ctx, RETURN);