From cbfeec1f4192adbd7adb494ef79447366f051c20 Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Thu, 3 Aug 2017 13:38:25 +0300 Subject: [PATCH] =?utf8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD?= =?utf8?q?=D0=B0=20=D0=BA=D0=BE=D0=BD=D1=81=D1=82=D1=80=D1=83=D0=BA=D1=86?= =?utf8?q?=D0=B8=D1=8F=20WHILE-DO?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- src/oberon.c | 37 ++++++++++++++++++++++++++++++++++++- src/test.c | 13 ++++--------- 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/src/oberon.c b/src/oberon.c index b428ecf..8a84e13 100644 --- a/src/oberon.c +++ b/src/oberon.c @@ -65,7 +65,9 @@ enum { IF, THEN, ELSE, - ELSIF + ELSIF, + WHILE, + DO }; // ======================================================================= @@ -400,6 +402,14 @@ oberon_read_ident(oberon_context_t * ctx) { ctx -> token = ELSIF; } + else if(strcmp(ident, "WHILE") == 0) + { + ctx -> token = WHILE; + } + else if(strcmp(ident, "DO") == 0) + { + ctx -> token = DO; + } } static void @@ -2951,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); diff --git a/src/test.c b/src/test.c index bcc8e86..549e5ea 100644 --- a/src/test.c +++ b/src/test.c @@ -13,16 +13,11 @@ static char source_test[] = " i : INTEGER;" "" "BEGIN" - " i := 4;" + " i := 0;" " Out.Open();" - " IF i = 0 THEN" - " Out.String('Branch 0'); Out.Ln;" - " ELSIF i = 1 THEN" - " Out.String('Branch 1'); Out.Ln;" - " ELSIF i = 2 THEN" - " Out.String('Branch 2'); Out.Ln;" - " ELSE" - " Out.String('Branch else'); Out.Ln;" + " WHILE i < 4 DO" + " Out.String('Count '); Out.Int(i, 0); Out.Ln;" + " i := i + 1;" " END;" " Out.String('end'); Out.Ln;" "END Test." -- 2.29.2