From: DeaDDooMER Date: Thu, 3 Aug 2017 10:58:37 +0000 (+0300) Subject: Добавлена конструкция REPEAT-UNTIL X-Git-Url: http://deadsoftware.ru/gitweb?a=commitdiff_plain;h=a4fb30372d14e8415e2f9b8e647c20daeab59d7d;p=dsw-obn.git Добавлена конструкция REPEAT-UNTIL --- diff --git a/notes b/notes index 0675bf3..7279e3f 100644 --- a/notes +++ b/notes @@ -1,16 +1,22 @@ -- нету типа set -- нету операторов if, while и т.д. - - Нужен тип представляющий типы Требуется для оператора IS и некоторых встраиваемых функций + +- Нет типа SET - Нет оператора IS -- не реализованы все встроенные функции -- не реализована свёртка констант +- Нет конструкции CASE +- Нет конструкции FOR +- Нет конструкции LOOP/EXIT +- Нет конструкции WITH +- Нет модуля SYSTEM +- Нет функций ASH CAP CHR ENTIER LEN LONG MAX MIN ODD ORD SHORT SIZE +- Нет процедур ASSERT COPY DEC EXCL HALT INC INCL +- Не реализована свёртка констант +- Не счёта строк / столбцов -- нету счёта строк / столбцов -- любая ошибка фатальна +- Нужно пробежаться по стандарту и всё перепроверить. - Нужны средства создания биндингов. На данный момент реализуемо как заглушки для модулей. -- нет проверок переполнения в компилтайме. +- Любая ошибка фатальна +- Нет проверок переполнения в компилтайме. Возможно можно заюзать это: https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html diff --git a/src/oberon.c b/src/oberon.c index 8a84e13..e8cbf42 100644 --- a/src/oberon.c +++ b/src/oberon.c @@ -67,7 +67,9 @@ enum { ELSE, ELSIF, WHILE, - DO + DO, + REPEAT, + UNTIL }; // ======================================================================= @@ -410,6 +412,14 @@ oberon_read_ident(oberon_context_t * ctx) { ctx -> token = DO; } + else if(strcmp(ident, "REPEAT") == 0) + { + ctx -> token = REPEAT; + } + else if(strcmp(ident, "UNTIL") == 0) + { + ctx -> token = UNTIL; + } } static void @@ -2986,6 +2996,27 @@ oberon_statement(oberon_context_t * ctx) oberon_assert_token(ctx, END); oberon_generate_label(ctx, end); } + else if(ctx -> token == REPEAT) + { + gen_label_t * begin; + oberon_expr_t * cond; + + begin = oberon_generator_reserve_label(ctx); + oberon_generate_label(ctx, begin); + oberon_assert_token(ctx, REPEAT); + + oberon_statement_seq(ctx); + + oberon_assert_token(ctx, UNTIL); + + cond = oberon_expr(ctx); + if(cond -> result -> class != OBERON_TYPE_BOOLEAN) + { + oberon_error(ctx, "condition must be boolean"); + } + + oberon_generate_branch(ctx, cond, true, begin); + } else if(ctx -> token == RETURN) { oberon_assert_token(ctx, RETURN); diff --git a/src/test.c b/src/test.c index 549e5ea..059af71 100644 --- a/src/test.c +++ b/src/test.c @@ -15,10 +15,10 @@ static char source_test[] = "BEGIN" " i := 0;" " Out.Open();" - " WHILE i < 4 DO" + " REPEAT" " Out.String('Count '); Out.Int(i, 0); Out.Ln;" " i := i + 1;" - " END;" + " UNTIL i < 4;" " Out.String('end'); Out.Ln;" "END Test." ;