DEADSOFTWARE

Добавлены типы разных размеров
[dsw-obn.git] / src / backends / jvm / generator-jvm.c
index 497b99ed278453c093a55685c29b1ceae6b523e4..1225a86a23b4a0f1479b6a8fc0a0265b574a654b 100644 (file)
@@ -128,6 +128,19 @@ jvm_generate(gen_proc_t * p, unsigned get, unsigned push, char * format, ...)
        va_end(ptr);
 }
 
+static void
+jvm_generate_comment(gen_proc_t * p, char * format, ...)
+{
+       va_list ptr;
+       va_start(ptr, format);
+
+       fprintf(p -> class -> fp, "  ;;;; ");
+       vfprintf(p -> class -> fp, format, ptr);
+       fprintf(p -> class -> fp, "\n");
+
+       va_end(ptr);
+}
+
 static void
 jvm_generate_push_int(gen_proc_t * p, int64_t i)
 {
@@ -157,6 +170,60 @@ jvm_generate_push_int(gen_proc_t * p, int64_t i)
        }
 }
 
+static void
+jvm_generate_push_int_size(gen_proc_t * p, int64_t i, int size)
+{
+       int pushed_cell = 1;
+
+       if(i == -1)
+       {
+               jvm_generate(p, 0, 1, "iconst_m1");
+       }
+       else if(i >= 0 && i <= 5)
+       {
+               jvm_generate(p, 0, 1, "iconst_%li", i);
+       }
+       else if(i >= -128 && i <= 127)
+       {
+               jvm_generate(p, 0, 1, "bipush %li", i);
+       }
+       else if(i >= -32768 && i <= 32767)
+       {
+               jvm_generate(p, 0, 1, "sipush %li", i);
+       }
+       else if(i >= -2147483648 && i <= 2147483647)
+       {
+               jvm_generate(p, 0, 1, "ldc %li", i);
+       }
+       else
+       {
+               pushed_cell = 2;
+               jvm_generate(p, 0, 2, "ldc2 %li", i);
+       }
+
+       assert(size <= 8);
+       if(size > 4 && pushed_cell == 1)
+       {
+               jvm_generate(p, pushed_cell, 2, "i2l");
+       }
+       else if(size <= 4)
+       {
+               if(pushed_cell > 1)
+               {
+                       jvm_generate(p, 2, 1, "l2i");
+               }
+
+               if(size == 2)
+               {
+                       jvm_generate(p, 1, 1, "i2s");
+               }
+               else if(size == 1)
+               {
+                       jvm_generate(p, 1, 1, "i2b");
+               }
+       }
+}
+
 static void
 jvm_generate_push_float(gen_proc_t * p, double f, int size)
 {
@@ -1229,6 +1296,24 @@ jvm_generate_expr_new_pointer(gen_proc_t * p, oberon_type_t * type, int num, obe
        jvm_generate_new(p, type -> base, num);
 }
 
+static void
+jvm_generate_cast_type(gen_proc_t * p, oberon_type_t * from, oberon_type_t * to)
+{
+       char prefix = jvm_get_prefix(from);
+       char postfix = jvm_get_postfix(to);
+       int from_cell_size = jvm_cell_size_for_type(from);
+       int to_cell_size = jvm_cell_size_for_type(to);
+
+       jvm_generate_comment(p, "cast type class from %i(%i) to %i(%i)", from -> class, from -> size, to -> class, to -> size);
+
+       if(prefix == postfix)
+       {
+               return;
+       }
+
+       jvm_generate(p, from_cell_size, to_cell_size, "%c2%c", prefix, postfix);
+}
+
 static void
 push_item(gen_proc_t * p, oberon_item_t * item)
 {
@@ -1245,10 +1330,10 @@ push_item(gen_proc_t * p, oberon_item_t * item)
                        }
                        break;
                case MODE_INTEGER:
-                       jvm_generate_push_int(p, item -> integer);
+                       jvm_generate_push_int_size(p, item -> integer, item -> result -> size);
                        break;
                case MODE_BOOLEAN:
-                       jvm_generate_push_int(p, item -> boolean);
+                       jvm_generate_push_int_size(p, item -> boolean, item -> result -> size);
                        break;
                case MODE_CALL:
                        jvm_generate_call_proc(p, (oberon_expr_t *) item);
@@ -1278,6 +1363,10 @@ push_item(gen_proc_t * p, oberon_item_t * item)
                case MODE_REAL:
                        jvm_generate_push_float(p, item -> real, item -> result -> size);
                        break;
+               case MODE_CAST:
+                       push_item(p, item -> parent);
+                       jvm_generate_cast_type(p, item -> parent -> result, item -> result);
+                       break;
                default:
                        gen_error("push_item: unk mode %i", item -> mode);
                        break;