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)
{
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);
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;
}
cast -> next = expr -> next;
return cast;
}
oberon_expr_t * selector;
selector = oberon_new_item(MODE_DEREF, expr -> result -> base, expr -> read_only);
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;
}
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);
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;
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;
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;
}
return selector;
}
#define ITUSEONLYBOOLEAN(x) \
(((x) == OR) || ((x) == AND))
#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)
{
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(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))
}
}
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)
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)
{
}
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);
}
oberon_autocast_binary_op(ctx, &a, &b);
expr = oberon_new_operator(OP_DIV, a -> result, a, b);
}