summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 9bcd389)
raw | patch | inline | side by side (parent: 9bcd389)
author | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Fri, 4 Aug 2017 16:23:43 +0000 (19:23 +0300) | ||
committer | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Fri, 4 Aug 2017 16:23:43 +0000 (19:23 +0300) |
index 29121d6b42614a2ae197d72757feaaf47dfd8d21..705055ee658ce8321a65f8f3b71c7126f4d291b0 100644 (file)
--- a/notes
+++ b/notes
-- Нет оператора IN
- Нет конструкции CASE
- Нет конструкции WITH
index fe8bc003d149bb4640fef9bad7792572aa500c11..03b29f8ae7fed461f5fa3f452b0bdd986b5a5b93 100644 (file)
/* 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)
{
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;
diff --git a/src/oberon-internals.h b/src/oberon-internals.h
index 96fd1662ba6c3e46c429995160342afbca87a2e3..3963146d4ee87f2d1cb65c0ecb807ffbde9f4e8d 100644 (file)
--- a/src/oberon-internals.h
+++ b/src/oberon-internals.h
OP_INTERSECTION,
OP_DIFFERENCE,
OP_SYM_DIFFERENCE,
- OP_COMPLEMENTATION
+ OP_COMPLEMENTATION,
+ OP_IN
};
struct oberon_item_t
diff --git a/src/oberon.c b/src/oberon.c
index 50429645b22a713480253b1fb262128dc1b97af6..38e24a8da8b963669a406220cef798290e3b43ef 100644 (file)
--- a/src/oberon.c
+++ b/src/oberon.c
@@ -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)
diff --git a/src/test.c b/src/test.c
index 9279c33f111597a3291344a5d3817c62fb0b6154..25497b0d22502b0bb7c806ed817a873e36836781 100644 (file)
--- a/src/test.c
+++ b/src/test.c
"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."
;