summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: b8aa586)
raw | patch | inline | side by side (parent: b8aa586)
author | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Sun, 27 Aug 2017 12:04:55 +0000 (15:04 +0300) | ||
committer | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Sun, 27 Aug 2017 12:04:55 +0000 (15:04 +0300) |
Test.obn | patch | blob | history | |
notes | patch | blob | history | |
proguard.conf | patch | blob | history | |
src/backends/jvm/generator-jvm.c | patch | blob | history | |
src/oberon.c | patch | blob | history |
diff --git a/Test.obn b/Test.obn
index 6fae5299c4ceb508ddf3708622d39e419e562a12..0f09bade1d5103f0fca051137c9cc8b9dd5656e5 100644 (file)
--- a/Test.obn
+++ b/Test.obn
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.
index 4c32ef56584b0bfe6c0cf66dab4774b40f14a939..46fe2580f6b3cf7faac2e184637d5e37210fb222 100644 (file)
--- a/notes
+++ b/notes
* Реализовать Mantissa
* Есть нативные рализации Frac и Trunc?
+- Нужно делать проверку границ при касте индекса массива с типом HUGEINT
+
- Нужно передавать информацию о файле и строках в кодогенератор.
- Нет процедур привязанных к типм (10.2)
- Не полная реализация модуля Files
diff --git a/proguard.conf b/proguard.conf
index 3adc0fef4708243054afc1d08219952774f8188a..5f702ac093d1e6bc67e3bec9992b6cbe0441f639 100644 (file)
--- a/proguard.conf
+++ b/proguard.conf
-dontshrink
-dontobfuscate
-dontoptimize
+-microedition
-keep class ** { void BEGIN(); }
index 681b4df71ddf6ea5f4c4c885016b2f1557002fea..4f49cfb86ca94df0b220be27f0d5fad68ac99a3b 100644 (file)
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)
{
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)
{
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:
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 f6bd09e68cc85998290d4ed9fd8c94f3b5c2d6d1..83f39cd2cebea39ac30fd54f1125ba11151bb045 100644 (file)
--- a/src/oberon.c
+++ b/src/oberon.c
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)
{