summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 25b7391)
raw | patch | inline | side by side (parent: 25b7391)
author | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Sun, 30 Jul 2017 14:57:00 +0000 (17:57 +0300) | ||
committer | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Sun, 30 Jul 2017 14:57:00 +0000 (17:57 +0300) |
index 79510a02b93db54f93aee3d4508dd2a6391e10d1..7092150dcbbcf53b3179614ba6ea19146adad7ac 100644 (file)
--- a/notes
+++ b/notes
- Нужно изменить передачу информации о вызываемой процедуре в MODE_CALL
На данный момент конкретная процедура передаётся в поле var, вместо parent
Что не позволяет делать процедуры-переменные в полях записей, массивах и т.д.
-- Нужны средства создания биндингов. На данный момент реализуемо как заглушки для модулей.
-- нужен автокаст int -> real для DIV. Да и вообще каст типов.
- нет символов и строк
+- не реализовано расширение типа record
+- нету типа set
- нету операторов if, while и т.д.
-- нету типа set
+- не реализованы все встроенные функции
- не реализована свёртка констант
-- не протестированы типы разнных размеров
-- не реализовано расширение типа record
-- не реализован автокаст
+- нету счёта строк / столбцов
+- любая ошибка фатальна
+
+- Нужны средства создания биндингов. На данный момент реализуемо как заглушки для модулей.
- нет проверок переполнения в компилтайме.
Возможно можно заюзать это:
https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html
-
-- нету счёта строк / столбцов
-- любая ошибка фатальна
index 1225a86a23b4a0f1479b6a8fc0a0265b574a654b..581faf92c302bab84ce601e5087eeb39e480d4ef 100644 (file)
;
char postfix = jvm_get_postfix(item -> result);
int cell_size = jvm_cell_size_for_postfix(postfix);
- push_item(p, item -> parent);
+ assert(item -> parent -> is_item);
+ push_item(p, (oberon_item_t *) 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);
+ assert(item -> parent -> is_item);
+ push_item(p, (oberon_item_t *) item -> parent);
jvm_generate_load(p, item -> result, item -> var -> gen_var);
break;
case MODE_DEREF:
/* Все объекты в jvm представляются как указатели */
- push_item(p, item -> parent);
+ assert(item -> parent -> is_item);
+ push_item(p, (oberon_item_t *) item -> parent);
break;
case MODE_NIL:
jvm_generate(p, 0, 1, "aconst_null");
jvm_generate_push_float(p, item -> real, item -> result -> size);
break;
case MODE_CAST:
- push_item(p, item -> parent);
+ push_expr(p, item -> parent);
jvm_generate_cast_type(p, item -> parent -> result, item -> result);
break;
default:
;
char postfix = jvm_get_postfix(src -> result);
int cell_size = jvm_cell_size_for_postfix(postfix);
- push_item(p, item -> parent);
+ assert(item -> parent -> is_item);
+ push_item(p, (oberon_item_t *) 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);
+ assert(item -> parent -> is_item);
+ push_item(p, (oberon_item_t *) item -> parent);
push_expr(p, src);
jvm_generate_store(p, src -> result, item -> var -> gen_var);
break;
diff --git a/src/oberon-internals.h b/src/oberon-internals.h
index b01a1d71958aa8e43cd9a4b10190291b8357802f..5cfaa1313777e98eb45f8fac7a14406ac67cd6c5 100644 (file)
--- a/src/oberon-internals.h
+++ b/src/oberon-internals.h
int boolean;
oberon_object_t * var;
- oberon_item_t * parent;
+ oberon_expr_t * parent;
int num_args;
oberon_expr_t * args;
diff --git a/src/oberon.c b/src/oberon.c
index 8de42d912fbb0ed03442b54072db6e353316d594..6a74f92c0aad16f6a3b13a6053e3e5b58e145fcc 100644 (file)
--- a/src/oberon.c
+++ b/src/oberon.c
@@ -770,10 +770,9 @@ oberon_expr_list(oberon_context_t * ctx, int * num_expr, oberon_expr_t ** first,
static oberon_expr_t *
oberon_cast_expr(oberon_context_t * ctx, oberon_expr_t * expr, oberon_type_t * pref)
{
- assert(expr -> is_item);
oberon_expr_t * cast;
cast = oberon_new_item(MODE_CAST, pref, expr -> read_only);
- cast -> item.parent = (oberon_item_t *) expr;
+ cast -> item.parent = expr;
cast -> next = expr -> next;
return cast;
}
oberon_expr_t * selector;
selector = oberon_new_item(MODE_DEREF, expr -> result -> base, expr -> read_only);
- selector -> item.parent = (oberon_item_t *) expr;
+ selector -> item.parent = expr;
return selector;
}
@@ -1115,7 +1114,7 @@ oberon_make_array_selector(oberon_context_t * ctx, oberon_expr_t * desig, oberon
oberon_expr_t * selector;
selector = oberon_new_item(MODE_INDEX, base, desig -> read_only);
- selector -> item.parent = (oberon_item_t *) desig;
+ selector -> item.parent = desig;
selector -> item.num_args = 1;
selector -> item.args = index;
@@ -1162,7 +1161,7 @@ oberon_make_record_selector(oberon_context_t * ctx, oberon_expr_t * expr, char *
oberon_expr_t * selector;
selector = oberon_new_item(MODE_FIELD, field -> type, read_only);
selector -> item.var = field;
- selector -> item.parent = (oberon_item_t *) expr;
+ selector -> item.parent = expr;
return selector;
}
#define ITUSEONLYBOOLEAN(x) \
(((x) == OR) || ((x) == AND))
+static void
+oberon_autocast_to_real(oberon_context_t * ctx, oberon_expr_t ** e)
+{
+ oberon_expr_t * expr = *e;
+ if(expr -> result -> class == OBERON_TYPE_INTEGER)
+ {
+ if(expr -> result -> size <= ctx -> real_type -> size)
+ {
+ *e = oberon_cast_expr(ctx, expr, ctx -> real_type);
+ }
+ else
+ {
+ *e = oberon_cast_expr(ctx, expr, ctx -> longreal_type);
+ }
+ }
+ else if(expr -> result -> class != OBERON_TYPE_REAL)
+ {
+ oberon_error(ctx, "required numeric type");
+ }
+}
+
static oberon_expr_t *
oberon_make_bin_op(oberon_context_t * ctx, int token, oberon_expr_t * a, oberon_expr_t * b)
{
@@ -1422,10 +1442,12 @@ oberon_make_bin_op(oberon_context_t * ctx, int token, oberon_expr_t * a, oberon_
{
if(ITUSEONLYINTEGER(token))
{
- if(a -> result -> class != OBERON_TYPE_INTEGER
- || b -> result -> class != OBERON_TYPE_INTEGER)
+ if(a -> result -> class == OBERON_TYPE_INTEGER
+ || b -> result -> class == OBERON_TYPE_INTEGER
+ || a -> result -> class == OBERON_TYPE_REAL
+ || b -> result -> class == OBERON_TYPE_REAL)
{
- oberon_error(ctx, "used only with integer types");
+ oberon_error(ctx, "used only with numeric types");
}
}
else if(ITUSEONLYBOOLEAN(token))
@@ -1437,6 +1459,7 @@ oberon_make_bin_op(oberon_context_t * ctx, int token, oberon_expr_t * a, oberon_
}
}
+ oberon_autocast_binary_op(ctx, &a, &b);
result = ctx -> bool_type;
if(token == EQUAL)
@@ -1478,30 +1501,8 @@ oberon_make_bin_op(oberon_context_t * ctx, int token, oberon_expr_t * a, oberon_
}
else if(token == SLASH)
{
- if(a -> result -> class != OBERON_TYPE_REAL)
- {
- if(a -> result -> class == OBERON_TYPE_INTEGER)
- {
- oberon_error(ctx, "TODO cast int -> real");
- }
- else
- {
- oberon_error(ctx, "operator / requires numeric type");
- }
- }
-
- if(b -> result -> class != OBERON_TYPE_REAL)
- {
- if(b -> result -> class == OBERON_TYPE_INTEGER)
- {
- oberon_error(ctx, "TODO cast int -> real");
- }
- else
- {
- oberon_error(ctx, "operator / requires numeric type");
- }
- }
-
+ oberon_autocast_to_real(ctx, &a);
+ oberon_autocast_to_real(ctx, &b);
oberon_autocast_binary_op(ctx, &a, &b);
expr = oberon_new_operator(OP_DIV, a -> result, a, b);
}
diff --git a/src/test.c b/src/test.c
index 2c5fb0462c6cb482a0d66fbd593af3fa4f85f5d8..9fad93d4461223fcc752d5a79e48261711e9709d 100644 (file)
--- a/src/test.c
+++ b/src/test.c
"BEGIN"
" Out.Open;"
" byte := 127;"
- " int := 666;"
+ " int := 666 DIV 2;"
" long := int;"
- " real := int;"
- " longreal := int;"
+ " real := (4 / 1) - (4 / 3) + (4 / 5) - (4 / 7) + (4 / 9) - (4 / 11) + (4 / 13) - (4 / 15) + (4 / 17);"
+ " longreal := (4 / 1) - (4 / 3) + (4 / 5) - (4 / 7) + (4 / 9) - (4 / 11) + (4 / 13) - (4 / 15) + (4 / 17);"
" Out.Int(666, 0); Out.Ln;"
" Out.Int(byte, 0); Out.Ln;"
- " Out.LongReal(real, 0); Out.Ln;"
+ " Out.Real(real, 0); Out.Ln;"
+ " Out.LongReal(longreal, 0); Out.Ln;"
"END Test."
;