DEADSOFTWARE

Добавлен оператор IN
authorDeaDDooMER <deaddoomer@deadsoftware.ru>
Fri, 4 Aug 2017 16:23:43 +0000 (19:23 +0300)
committerDeaDDooMER <deaddoomer@deadsoftware.ru>
Fri, 4 Aug 2017 16:23:43 +0000 (19:23 +0300)
notes
src/backends/jvm/generator-jvm.c
src/oberon-internals.h
src/oberon.c
src/test.c

diff --git a/notes b/notes
index 29121d6b42614a2ae197d72757feaaf47dfd8d21..705055ee658ce8321a65f8f3b71c7126f4d291b0 100644 (file)
--- a/notes
+++ b/notes
@@ -1,4 +1,3 @@
-- Нет оператора IN
 - Нет конструкции CASE
 - Нет конструкции WITH
 
index fe8bc003d149bb4640fef9bad7792572aa500c11..03b29f8ae7fed461f5fa3f452b0bdd986b5a5b93 100644 (file)
@@ -1778,6 +1778,34 @@ jvm_generate_range(gen_proc_t * p, oberon_expr_t * a, oberon_expr_t * b)
        /* TODO free registers */
 }
 
+static void
+jvm_generate_in(gen_proc_t * p, oberon_expr_t * a, oberon_expr_t * b)
+{
+       oberon_type_t * t = a -> result;
+       int cell_size = jvm_cell_size_for_type(t);
+       char prefix = jvm_get_prefix(t);
+       int label_else = jvm_new_label_id(p);
+       int label_end = jvm_new_label_id(p);
+
+       jvm_generate_push_int_size(p, 1, t -> size);
+       push_expr(p, a);
+       jvm_generate(p, 2 * cell_size, cell_size, "%cshl", prefix);
+       push_expr(p, b);        
+       jvm_generate(p, 2 * cell_size, cell_size, "%cand", prefix);
+
+       if(cell_size > 1)
+       {
+               jvm_generate(p, cell_size, 0, "lcmp");
+       }
+
+       jvm_generate(p, 1, 0, "ifeq L%i", label_else);
+       jvm_generate(p, 0, 1, "iconst_1");
+       jvm_generate(p, 0, 0, "goto L%i", label_end);
+       jvm_generate_label(p, label_else);
+       jvm_generate(p, 0, 1, "iconst_0");      
+       jvm_generate_label(p, label_end);
+}
+
 static void
 push_operator(gen_proc_t * p, oberon_oper_t * oper)
 {
@@ -1835,6 +1863,9 @@ push_operator(gen_proc_t * p, oberon_oper_t * oper)
                case OP_RANGE:
                        jvm_generate_range(p, oper -> left, oper -> right);
                        break;
+               case OP_IN:
+                       jvm_generate_in(p, oper -> left, oper -> right);
+                       break;
                default:
                        gen_error("push_oper: unk op %i", op);
                        break;
index 96fd1662ba6c3e46c429995160342afbca87a2e3..3963146d4ee87f2d1cb65c0ecb807ffbde9f4e8d 100644 (file)
@@ -211,7 +211,8 @@ enum oberon_operator_kind
        OP_INTERSECTION,
        OP_DIFFERENCE,
        OP_SYM_DIFFERENCE,
-       OP_COMPLEMENTATION
+       OP_COMPLEMENTATION,
+       OP_IN
 };
 
 struct oberon_item_t
index 50429645b22a713480253b1fb262128dc1b97af6..38e24a8da8b963669a406220cef798290e3b43ef 100644 (file)
@@ -1814,7 +1814,22 @@ oberon_make_bin_op(oberon_context_t * ctx, int token, oberon_expr_t * a, oberon_
        oberon_type_t * result;
 
        bool error = false;
-       if(token == IS)
+       if(token == IN)
+       {
+               if(a -> result -> class != OBERON_TYPE_INTEGER)
+               {
+                       oberon_error(ctx, "must be integer");
+               }
+
+               if(b -> result -> class != OBERON_TYPE_SET)
+               {
+                       oberon_error(ctx, "must be set");
+               }
+
+               result = ctx -> bool_type;
+               expr = oberon_new_operator(OP_IN, result, a, b);
+       }
+       else if(token == IS)
        {
                oberon_type_t * v = a -> result;
                if(v -> class == OBERON_TYPE_POINTER)
index 9279c33f111597a3291344a5d3817c62fb0b6154..25497b0d22502b0bb7c806ed817a873e36836781 100644 (file)
@@ -9,11 +9,13 @@ static char source_test[] =
        "MODULE Test;"
        "IMPORT Out;"
        ""
-       "VAR"
-       "  s0 : SET;"
-       ""
        "BEGIN"
-       "  s0 := -{ 1, 3..6 } + { 3, 4, 10 };"
+       "  Out.Open;"
+       "  IF 8 IN { 2, 3, 7..10 } THEN"
+       "    Out.String('Yes'); Out.Ln;"
+       "  ELSE"
+       "    Out.String('No'); Out.Ln;"
+       "  END;"
        "END Test."
 ;