DEADSOFTWARE

JVM: Добавлены массивы и аллокация фиксированной размерности (без инициализации,...
authorDeaDDooMER <deaddoomer@deadsoftware.ru>
Thu, 27 Jul 2017 21:49:46 +0000 (00:49 +0300)
committerDeaDDooMER <deaddoomer@deadsoftware.ru>
Thu, 27 Jul 2017 21:49:46 +0000 (00:49 +0300)
JTest.java [new file with mode: 0644]
src/backends/jvm/generator-jvm-basic.c
src/backends/jvm/generator-jvm-basic.h
src/backends/jvm/generator-jvm.c
src/test.c

diff --git a/JTest.java b/JTest.java
new file mode 100644 (file)
index 0000000..1ce1766
--- /dev/null
@@ -0,0 +1,9 @@
+class JTest
+{
+       boolean[] z;
+
+       void x(boolean y)
+       {
+               z[666] = y;
+       }
+}
index d419abea2de5e88267b44667ccf95d370d08f698..5fabc3171bf03787173e193640811e552934bd4a 100644 (file)
@@ -138,6 +138,52 @@ jvm_get_prefix(oberon_type_t * type)
        return '!';
 }
 
+char
+jvm_get_postfix(oberon_type_t * type)
+{
+       int size = type -> size;
+       switch(type -> class)
+       {
+               case OBERON_TYPE_BOOLEAN:
+                       return 'b';
+                       break;
+               case OBERON_TYPE_INTEGER:
+                       switch(size)
+                       {
+                               case 1:
+                                       return 'b';
+                                       break;
+                               case 2:
+                                       return 's';
+                                       break;
+                               case 4:
+                                       return 'i';
+                                       break;
+                               case 8:
+                                       return 'l';
+                                       break;
+                               default:
+                                       gen_error("jvm_get_postfix: int wat");
+                                       break;
+                       }
+                       break;
+               case OBERON_TYPE_PROCEDURE:
+               case OBERON_TYPE_ARRAY:
+               case OBERON_TYPE_RECORD:
+               case OBERON_TYPE_POINTER:
+                       return 'a';
+                       break;
+               case OBERON_TYPE_REAL:
+                       return (size <= 4) ? ('f') : ('d');
+                       break;
+               default:
+                       gen_error("jvm_get_postfix: wat");
+                       break;
+       }
+
+       return '!';
+}
+
 char *
 jvm_get_field_full_name(oberon_object_t * x)
 {
@@ -234,22 +280,21 @@ jvm_cell_size_for_type(oberon_type_t * type)
 }
 
 int
-jvm_cell_size_for_prefix(char prefix)
+jvm_cell_size_for_postfix(char postfix)
 {
-       switch(prefix)
+       switch(postfix)
        {
                case 'a':
                case 'b':
                case 's':
                case 'i':
-               case 'z':
                case 'f':
                        return 1;
                case 'l':
                case 'd':
                        return 2;
                default:
-                       gen_error("jvm_cell_size_for_prefix: unk prefix %c", prefix);
+                       gen_error("jvm_cell_size_for_postfix: unk postfix %c", postfix);
        }
 
        return -666;
index 094d88639c47ae46d421e815e9fed70a3c64425b..2d4312f28278c9c20e6386e2114638364ed3e6d2 100644 (file)
@@ -17,6 +17,9 @@ jvm_get_descriptor(oberon_type_t * type);
 char
 jvm_get_prefix(oberon_type_t * type);
 
+char
+jvm_get_postfix(oberon_type_t * type);
+
 char *
 jvm_get_field_full_name(oberon_object_t * x);
 
@@ -32,7 +35,7 @@ int
 jvm_cell_size_for_type(oberon_type_t * type);
 
 int
-jvm_cell_size_for_prefix(char prefix);
+jvm_cell_size_for_postfix(char postix);
 
 bool
 jvm_is_wide_type(oberon_type_t * type);
index 99a4673199d8e432ddb0c98c4e0f397426625cff..84ebe512efcdb595a9c079f1bbc3d02b68cd0f26 100644 (file)
@@ -208,7 +208,9 @@ jvm_generate_label(gen_proc_t * p, int label_id)
 static void
 jvm_generate_new_static(gen_proc_t * p, oberon_type_t * type)
 {
+       int dim;
        char * cname;
+       char * desc;
 
        switch(type -> class)
        {
@@ -217,7 +219,7 @@ jvm_generate_new_static(gen_proc_t * p, oberon_type_t * type)
                case OBERON_TYPE_PROCEDURE:
                case OBERON_TYPE_REAL:
                case OBERON_TYPE_POINTER:
-                       /* ничего не надо делать при статической инициализации */
+                       gen_error("jvm_generate_new_static: static alocation not allowed");
                        break;
                case OBERON_TYPE_RECORD:
                        cname = jvm_get_class_full_name(type);
@@ -226,7 +228,15 @@ jvm_generate_new_static(gen_proc_t * p, oberon_type_t * type)
                        jvm_generate(p, 1, 0, "invokespecial %s/<init>()V", cname);
                        break;
                case OBERON_TYPE_ARRAY:
-                       gen_error("jvm_generate_new_static: TODO array");
+                       dim = 0;
+                       desc = jvm_get_descriptor(type);
+                       while(type -> class == OBERON_TYPE_ARRAY)
+                       {
+                               dim += 1;
+                               jvm_generate_push_int(p, type -> size);
+                               type = type -> base;
+                       }
+                       jvm_generate(p, dim, 1, "multianewarray %s %i", desc, dim);
                        break;
                default:
                        gen_error("jvm_generate_new_static: unk type class %i", type -> class);
@@ -723,7 +733,12 @@ push_item(gen_proc_t * p, oberon_item_t * item)
                        jvm_generate_call_proc(p, (oberon_expr_t *) item);
                        break;
                case MODE_INDEX:
-                       gen_error("push_item: TODO index");
+                       ;
+                       char postfix = jvm_get_postfix(item -> result);
+                       int cell_size = jvm_cell_size_for_postfix(postfix);
+                       push_item(p, item -> parent);
+                       push_expr(p, item -> args);
+                       jvm_generate(p, 1 + 1, cell_size, "%caload", postfix);
                        break;
                case MODE_FIELD:
                        push_item(p, item -> parent);
@@ -770,7 +785,7 @@ static void
 jvm_generate_abs(gen_proc_t * p, char prefix)
 {
        char t = jvm_get_type_of_prefix(prefix);
-       int cell_size = jvm_cell_size_for_prefix(prefix);
+       int cell_size = jvm_cell_size_for_postfix(prefix);
        jvm_generate(p, cell_size, cell_size, "invokestatic java/lang/Math/abs(%c)%c", t, t);
 }
 
@@ -781,7 +796,7 @@ jvm_generate_compare_op(gen_proc_t * p, char prefix, int op)
        int label_done = jvm_new_label_id(p);
        char * label_name_true = jvm_get_label_name(label_true);
        char * label_name_done = jvm_get_label_name(label_done);
-       int cell_size = 2 * jvm_cell_size_for_prefix(prefix);
+       int cell_size = 2 * jvm_cell_size_for_postfix(prefix);
 
        assert(prefix == 'i' || prefix == 'a');
 
@@ -822,7 +837,7 @@ jvm_generate_compare_op(gen_proc_t * p, char prefix, int op)
 static void
 jvm_generate_operator(gen_proc_t * p, char prefix, int op)
 {
-       int cell_size = jvm_cell_size_for_prefix(prefix);
+       int cell_size = jvm_cell_size_for_postfix(prefix);
        switch(op)
        {
                case OP_UNARY_MINUS:
@@ -989,7 +1004,13 @@ store_expr(gen_proc_t * p, oberon_expr_t * dst, oberon_expr_t * src)
                        jvm_generate_store(p, src -> result, item -> var -> gen_var);
                        break;
                case MODE_INDEX:
-                       gen_error("store_expr: TODO index");
+                       ;
+                       char postfix = jvm_get_postfix(src -> result);
+                       int cell_size = jvm_cell_size_for_postfix(postfix);
+                       push_item(p, item -> parent);
+                       push_expr(p, item -> args);
+                       push_expr(p, src);
+                       jvm_generate(p, 1 + 1 + cell_size, 0, "%castore", postfix);
                        break;
                case MODE_FIELD:
                        push_item(p, item -> parent);
@@ -1002,52 +1023,6 @@ store_expr(gen_proc_t * p, oberon_expr_t * dst, oberon_expr_t * src)
        }
 }
 
-/*
-static void
-store_expr(gen_proc_t * p, oberon_expr_t * dst, oberon_expr_t * src)
-{
-       assert(dst -> is_item);
-       oberon_item_t * item = (oberon_item_t *) dst;
-
-       int cell_size = jvm_cell_size_for_type(src -> result);
-
-       char prefix;
-       switch(item -> mode)
-       {
-               case MODE_VAR:
-                       push_expr(p, src);
-                       if(item -> var -> local)
-                       {
-                               int reg = item -> var -> gen_var -> reg;
-                               prefix = jvm_get_prefix(item -> result);
-                               jvm_generate(p, cell_size, 0, "%cstore %i", prefix, reg);
-                       }
-                       else
-                       {
-                               char * fullname = jvm_get_field_full_name(item -> var);
-                               char * desc = jvm_get_descriptor(item -> result);
-                               jvm_generate(p, cell_size, 0, "putstatic %s %s", fullname, desc);
-                       }
-                       break;
-               case MODE_INDEX:
-                       gen_error("store_expr: TODO index");
-                       break;
-               case MODE_FIELD:
-                       {
-                               char * fullname = jvm_get_field_full_name(item -> var);
-                               char * desc = jvm_get_descriptor(item -> result);
-                               push_item(p, item -> parent);
-                               push_expr(p, src);
-                               jvm_generate(p, 1 + cell_size, 0, "putfield %s %s", fullname, desc);
-                       }
-                       break;
-               default:
-                       gen_error("store_expr: unk mode %i", item -> mode);
-                       break;
-       }
-}
-*/
-
 void
 oberon_generate_assign(oberon_context_t * ctx, oberon_expr_t * src, oberon_expr_t * dst)
 {
index 0edbdf483353b545427a87e699d3c071aa3c9644..69cfc99dc7468b5600745cbd73e54dc02cea8b64 100644 (file)
@@ -7,23 +7,11 @@
 static char source_test[] =
        "(* Main module *)"
        "MODULE Test;"
-       "TYPE"
-       "  Rec = POINTER TO RecDesc;"
-       "  RecDesc = RECORD"
-       "    x, y, z : INTEGER;"
-       "    r : RECORD xxx : INTEGER; END;"
-       "  END;"
        "VAR"
-       "  a : INTEGER;"
-       "  r : Rec;"
+       "  l : POINTER TO ARRAY 16 OF BOOLEAN;"
        "BEGIN"
-       "  NEW(r);"
-       "  a := 123;"
-       "  a := -(3 * a + 456);"
-       "  r.x := a;"
-       "  r.y := r.x;"
-       "  r.z := r.y * 3;"
-       "  r.r.xxx := 666;"
+       "  NEW(l);"
+       "  l[0] := l[5];"
        "END Test."
 ;