From 0b724e12457f2507d398c51dc35200d833ce9362 Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Sun, 27 Aug 2017 15:04:55 +0300 Subject: [PATCH] =?utf8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5?= =?utf8?q?=D0=BD=20=D1=86=D0=B8=D0=BA=D0=BB=20REPEAT,=20=D0=B8=D1=81=D0=BF?= =?utf8?q?=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=BE=20=D0=B8=D1=81=D0=BF?= =?utf8?q?=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20H?= =?utf8?q?UGEINT=20=D0=BA=D0=B0=D0=BA=20=D0=B8=D0=BD=D0=B4=D0=B5=D0=BA?= =?utf8?q?=D1=81=D0=B0=20=D0=BC=D0=B0=D1=81=D1=81=D0=B8=D0=B2=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- Test.obn | 10 ++ notes | 2 + proguard.conf | 1 + src/backends/jvm/generator-jvm.c | 175 ++++++++++++++++--------------- src/oberon.c | 2 +- 5 files changed, 107 insertions(+), 83 deletions(-) diff --git a/Test.obn b/Test.obn index 6fae529..0f09bad 100644 --- a/Test.obn +++ b/Test.obn @@ -1,3 +1,13 @@ MODULE Test; +IMPORT CPStrings, Out; + +VAR + s : ARRAY 80 OF CHAR; + +BEGIN + CPStrings.IntToString(123456789, s); + Out.String(s); Out.Ln; + CPStrings.RealToString(321.123456, s); + Out.String(s); Out.Ln; END Test. diff --git a/notes b/notes index 4c32ef5..46fe258 100644 --- a/notes +++ b/notes @@ -3,6 +3,8 @@ * Реализовать Mantissa * Есть нативные рализации Frac и Trunc? +- Нужно делать проверку границ при касте индекса массива с типом HUGEINT + - Нужно передавать информацию о файле и строках в кодогенератор. - Нет процедур привязанных к типм (10.2) - Не полная реализация модуля Files diff --git a/proguard.conf b/proguard.conf index 3adc0fe..5f702ac 100644 --- a/proguard.conf +++ b/proguard.conf @@ -1,5 +1,6 @@ -dontshrink -dontobfuscate -dontoptimize +-microedition -keep class ** { void BEGIN(); } diff --git a/src/backends/jvm/generator-jvm.c b/src/backends/jvm/generator-jvm.c index 681b4df..4f49cfb 100644 --- a/src/backends/jvm/generator-jvm.c +++ b/src/backends/jvm/generator-jvm.c @@ -21,6 +21,88 @@ push_item(gen_proc_t * p, oberon_item_t * item); static void jvm_generate_new(gen_proc_t * p, oberon_type_t * type, int num); +static void +jvm_generate_cast_prefix(gen_proc_t * p, char prefix, char postfix) +{ + if((prefix == 'b' || prefix == 's') && (postfix = 'l' || postfix == 'd')) + { + prefix = 'i'; + } + + if(prefix == postfix) + { + return; + } + + if((prefix == 'l' || prefix == 'd') && (postfix == 'b' || postfix == 's')) + { + jvm_generate(p, 2, 1, "%c2i", prefix); + prefix = 'i'; + } + + int from_cell_size = jvm_cell_size_for_postfix(prefix); + int to_cell_size = jvm_cell_size_for_postfix(postfix); + jvm_generate(p, from_cell_size, to_cell_size, "%c2%c", prefix, postfix); +} + +static void +jvm_generate_cast_type(gen_proc_t * p, oberon_type_t * from, oberon_type_t * to) +{ + if(to -> class == OBERON_TYPE_RECORD || to -> class == OBERON_TYPE_POINTER) + { + if(to -> class == OBERON_TYPE_POINTER && to -> base -> class == OBERON_TYPE_RECORD) + { + char * full_name = jvm_get_class_full_name(to); + jvm_generate(p, 1, 1, "checkcast %s", full_name); + } + } + else + { + char prefix = jvm_get_prefix(from); + char postfix = jvm_get_postfix(to); + jvm_generate_cast_prefix(p, prefix, postfix); + } +} + +static void +jvm_generate_hard_cast_type(gen_proc_t * p, oberon_type_t * from, oberon_type_t * to) +{ + if(from -> class == OBERON_TYPE_REAL + && (to -> class == OBERON_TYPE_INTEGER || to -> class == OBERON_TYPE_SYSTEM_BYTE)) + { + char postfix = jvm_get_postfix(to); + if(from -> size <= 4) + { + jvm_generate(p, 1, 1, "invokestatic java/lang/Float/floatToRawIntBits(F)I"); + jvm_generate_cast_prefix(p, 'i', postfix); + } + else + { + jvm_generate(p, 2, 2, "invokestatic java/lang/Double/doubleToRawIntBits(D)J"); + jvm_generate_cast_prefix(p, 'l', postfix); + } + } + else if((from -> class == OBERON_TYPE_INTEGER || from -> class == OBERON_TYPE_SYSTEM_BYTE) + && to -> class == OBERON_TYPE_REAL) + { + char prefix = jvm_get_prefix(from); + if(to -> size <= 4) + { + jvm_generate_cast_prefix(p, prefix, 'i'); + jvm_generate(p, 1, 1, "invokestatic java/lang/Float/intBitsToFloat(I)F"); + } + else + { + jvm_generate_cast_prefix(p, prefix, 'l'); + jvm_generate(p, 2, 2, "invokestatic java/lang/Double/longBitsToDouble(J)D"); + } + } + else + { + jvm_generate_cast_type(p, from, to); + } +} + /* * Генерирует код для инициализации массива со статическим базовым типом * ( aref -- ) @@ -1064,6 +1146,14 @@ oberon_generate_branch(oberon_context_t * ctx, oberon_expr_t * cond, bool gotoif } } +static void +check_index(gen_proc_t * p, oberon_type_t * index_type) +{ + // TODO проверка валидности границ + char prefix = jvm_get_prefix(index_type); + jvm_generate_cast_prefix(p, prefix, 'i'); +} + static void push_varptr(gen_proc_t * p, oberon_expr_t * expr) { @@ -1077,6 +1167,7 @@ push_varptr(gen_proc_t * p, oberon_expr_t * expr) case MODE_INDEX: push_item(p, expr -> item.parent); push_expr(p, expr -> item.args); + check_index(p, expr -> item.args -> result); break; case MODE_FIELD: push_item(p, expr -> item.parent); @@ -1201,88 +1292,6 @@ 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_prefix(gen_proc_t * p, char prefix, char postfix) -{ - if((prefix == 'b' || prefix == 's') && (postfix = 'l' || postfix == 'd')) - { - prefix = 'i'; - } - - if(prefix == postfix) - { - return; - } - - if((prefix == 'l' || prefix == 'd') && (postfix == 'b' || postfix == 's')) - { - jvm_generate(p, 2, 1, "%c2i", prefix); - prefix = 'i'; - } - - int from_cell_size = jvm_cell_size_for_postfix(prefix); - int to_cell_size = jvm_cell_size_for_postfix(postfix); - jvm_generate(p, from_cell_size, to_cell_size, "%c2%c", prefix, postfix); -} - -static void -jvm_generate_cast_type(gen_proc_t * p, oberon_type_t * from, oberon_type_t * to) -{ - if(to -> class == OBERON_TYPE_RECORD || to -> class == OBERON_TYPE_POINTER) - { - if(to -> class == OBERON_TYPE_POINTER && to -> base -> class == OBERON_TYPE_RECORD) - { - char * full_name = jvm_get_class_full_name(to); - jvm_generate(p, 1, 1, "checkcast %s", full_name); - } - } - else - { - char prefix = jvm_get_prefix(from); - char postfix = jvm_get_postfix(to); - jvm_generate_cast_prefix(p, prefix, postfix); - } -} - -static void -jvm_generate_hard_cast_type(gen_proc_t * p, oberon_type_t * from, oberon_type_t * to) -{ - if(from -> class == OBERON_TYPE_REAL - && (to -> class == OBERON_TYPE_INTEGER || to -> class == OBERON_TYPE_SYSTEM_BYTE)) - { - char postfix = jvm_get_postfix(to); - if(from -> size <= 4) - { - jvm_generate(p, 1, 1, "invokestatic java/lang/Float/floatToIntBits(F)I"); - jvm_generate_cast_prefix(p, 'i', postfix); - } - else - { - jvm_generate(p, 2, 2, "invokestatic java/lang/Double/doubleToIntBits(D)J"); - jvm_generate_cast_prefix(p, 'l', postfix); - } - } - else if((from -> class == OBERON_TYPE_INTEGER || from -> class == OBERON_TYPE_SYSTEM_BYTE) - && to -> class == OBERON_TYPE_REAL) - { - char prefix = jvm_get_prefix(from); - if(to -> size <= 4) - { - jvm_generate_cast_prefix(p, prefix, 'i'); - jvm_generate(p, 1, 1, "invokestatic java/lang/Float/intBitsToFloat(I)F"); - } - else - { - jvm_generate_cast_prefix(p, prefix, 'l'); - jvm_generate(p, 2, 2, "invokestatic java/lang/Double/longBitsToDouble(J)D"); - } - } - else - { - jvm_generate_cast_type(p, from, to); - } -} - static void push_item(gen_proc_t * p, oberon_item_t * item) { @@ -1313,6 +1322,7 @@ push_item(gen_proc_t * p, oberon_item_t * item) int cell_size = jvm_cell_size_for_postfix(postfix); push_item(p, item -> parent); push_expr(p, item -> args); + check_index(p, item -> args -> result); jvm_generate(p, 1 + 1, cell_size, "%caload", postfix); break; case MODE_FIELD: @@ -1816,6 +1826,7 @@ store_expr(gen_proc_t * p, oberon_expr_t * dst, oberon_expr_t * src) assert(item -> parent -> is_item); push_item(p, (oberon_item_t *) item -> parent); push_expr(p, item -> args); + check_index(p, item -> args -> result); push_expr(p, src); jvm_generate(p, 1 + 1 + cell_size, 0, "%castore", postfix); break; diff --git a/src/oberon.c b/src/oberon.c index f6bd09e..83f39cd 100644 --- a/src/oberon.c +++ b/src/oberon.c @@ -3495,7 +3495,7 @@ oberon_statement(oberon_context_t * ctx) oberon_error(ctx, "condition must be boolean"); } - oberon_generate_branch(ctx, cond, true, begin); + oberon_generate_branch(ctx, cond, false, begin); } else if(ctx -> token == FOR) { -- 2.29.2