X-Git-Url: http://deadsoftware.ru/gitweb?p=dsw-obn.git;a=blobdiff_plain;f=src%2Foberon.c;h=6a74f92c0aad16f6a3b13a6053e3e5b58e145fcc;hp=8de42d912fbb0ed03442b54072db6e353316d594;hb=d11b76dfc015306841ed4befae800ba1ed7c765b;hpb=25b73915e7fe0ae7dc51cf6f4a012f021257a35d diff --git a/src/oberon.c b/src/oberon.c index 8de42d9..6a74f92 100644 --- 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; } @@ -1068,7 +1067,7 @@ oberno_make_dereferencing(oberon_context_t * ctx, oberon_expr_t * expr) 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; } @@ -1412,6 +1411,27 @@ oberon_factor(oberon_context_t * ctx) #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); }