summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 99fa357)
raw | patch | inline | side by side (parent: 99fa357)
author | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Thu, 3 Aug 2017 14:11:28 +0000 (17:11 +0300) | ||
committer | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Thu, 3 Aug 2017 14:11:28 +0000 (17:11 +0300) |
notes | patch | blob | history | |
src/oberon-internals.h | patch | blob | history | |
src/oberon.c | patch | blob | history | |
src/test.c | patch | blob | history |
index 693f32a80a90486705b57524ae58393bd068e60d..15aa1da6de3a10d2105fea29184e0af25f7174bf 100644 (file)
--- a/notes
+++ b/notes
- Нет типа SET
- Нет оператора IS
- Нет конструкции CASE
-- Нет конструкции LOOP/EXIT
- Нет конструкции WITH
- Нет модуля SYSTEM
- Нет функций ASH CAP CHR ENTIER LEN LONG MAX MIN ODD ORD SHORT SIZE
diff --git a/src/oberon-internals.h b/src/oberon-internals.h
index f0a6bed23e96fa8ec6b70d9cafc3a133713485ba..7a776d695502bec8b53225c031e31f808d207841 100644 (file)
--- a/src/oberon-internals.h
+++ b/src/oberon-internals.h
int local;
oberon_object_t * parent;
oberon_type_t * parent_type;
+
+ gen_label_t * exit_label;
};
enum oberon_type_kind
diff --git a/src/oberon.c b/src/oberon.c
index f50f4d300246b4beed4fd6e58afaf21cb307cf3a..e95a9bef396271f68b2dff5a6af06147cc530c09 100644 (file)
--- a/src/oberon.c
+++ b/src/oberon.c
REPEAT,
UNTIL,
FOR,
- BY
+ BY,
+ LOOP,
+ EXIT
};
// =======================================================================
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;
{
ctx -> token = BY;
}
+ else if(strcmp(ident, "LOOP") == 0)
+ {
+ ctx -> token = LOOP;
+ }
+ else if(strcmp(ident, "EXIT") == 0)
+ {
+ ctx -> token = EXIT;
+ }
}
static void
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);
diff --git a/src/test.c b/src/test.c
index 42fc4ff3030a00a18b2b673141cc0f7137f2a1fc..ebb807bc518fa1211589cb47f32e2ae7f733bd38 100644 (file)
--- a/src/test.c
+++ b/src/test.c
""
"BEGIN"
" Out.Open();"
- " len := 2 * 8;"
- " FOR i := 0 TO len BY 2 DO"
+ " LOOP"
" Out.String('Count '); Out.Int(i, 0); Out.Ln;"
- " len := len + 2;"
+ " i := i + 1;"
+ " IF i > 4 THEN EXIT END;"
" END;"
" Out.String('end'); Out.Ln;"
"END Test."