X-Git-Url: http://deadsoftware.ru/gitweb?p=dsw-obn.git;a=blobdiff_plain;f=src%2Foberon.c;h=5abb2090477536027219f41e2e0b9e78b69d9ab5;hp=437e7694205489c681c5da3757bdc7e58a42ad39;hb=0c29ba1953327a9b476a825d8b9b9d185d544972;hpb=35e75d29be18a7355aaaea9e146f3fda1d91857f diff --git a/src/oberon.c b/src/oberon.c index 437e769..5abb209 100644 --- a/src/oberon.c +++ b/src/oberon.c @@ -1088,6 +1088,12 @@ oberon_cast_expr(oberon_context_t * ctx, oberon_expr_t * expr, oberon_type_t * p cast = oberon_new_item(MODE_CHAR, ctx -> char_type, true); cast -> item.integer = expr -> item.string[0]; } + else if(oberon_is_record_type(pref) || oberon_is_pointer_to_record(pref)) + { + assert(expr -> is_item); + cast = oberon_new_item(MODE_AS, pref, expr -> read_only); + cast -> item.parent = (oberon_item_t *) expr; + } else if(!oberon_is_some_types(expr -> result, pref)) { cast = oberon_new_operator(OP_CAST, pref, expr, NULL); @@ -1995,7 +2001,7 @@ oberon_make_bin_op(oberon_context_t * ctx, int token, oberon_expr_t * a, oberon_ expr = oberon_new_operator(OP_DIV, result, a, b); break; case MOD: - expr = oberon_new_operator(OP_DIV, result, a, b); + expr = oberon_new_operator(OP_MOD, result, a, b); break; default: printf("token %i line %i\n", token, ctx -> loc.line); @@ -2625,9 +2631,8 @@ oberon_field_list(oberon_context_t * ctx, oberon_type_t * rec, oberon_scope_t * static void oberon_type_record_body(oberon_context_t * ctx, oberon_type_t * rec) { - oberon_scope_t * modscope = ctx -> mod -> decl; oberon_scope_t * oldscope = ctx -> decl; - ctx -> decl = modscope; + ctx -> decl = oldscope; if(ctx -> token == LPAREN) { @@ -2668,11 +2673,11 @@ oberon_type_record_body(oberon_context_t * ctx, oberon_type_t * rec) this_scope -> parent = NULL; this_scope -> parent_type = rec; - oberon_field_list(ctx, rec, modscope); + oberon_field_list(ctx, rec, oldscope); while(ctx -> token == SEMICOLON) { oberon_assert_token(ctx, SEMICOLON); - oberon_field_list(ctx, rec, modscope); + oberon_field_list(ctx, rec, oldscope); } rec -> scope = this_scope; @@ -3136,33 +3141,34 @@ oberon_prevent_undeclarated_procedures(oberon_context_t * ctx) static void oberon_decl_seq(oberon_context_t * ctx) { - if(ctx -> token == CONST) + while(ctx -> token >= CONST && ctx -> token <= VAR) { - oberon_assert_token(ctx, CONST); - while(ctx -> token == IDENT) + if(ctx -> token == CONST) { - oberon_const_decl(ctx); - oberon_assert_token(ctx, SEMICOLON); + oberon_assert_token(ctx, CONST); + while(ctx -> token == IDENT) + { + oberon_const_decl(ctx); + oberon_assert_token(ctx, SEMICOLON); + } } - } - - if(ctx -> token == TYPE) - { - oberon_assert_token(ctx, TYPE); - while(ctx -> token == IDENT) + else if(ctx -> token == TYPE) { - oberon_type_decl(ctx); - oberon_assert_token(ctx, SEMICOLON); + oberon_assert_token(ctx, TYPE); + while(ctx -> token == IDENT) + { + oberon_type_decl(ctx); + oberon_assert_token(ctx, SEMICOLON); + } } - } - - if(ctx -> token == VAR) - { - oberon_assert_token(ctx, VAR); - while(ctx -> token == IDENT) + else if(ctx -> token == VAR) { - oberon_var_decl(ctx); - oberon_assert_token(ctx, SEMICOLON); + oberon_assert_token(ctx, VAR); + while(ctx -> token == IDENT) + { + oberon_var_decl(ctx); + oberon_assert_token(ctx, SEMICOLON); + } } } @@ -3316,44 +3322,38 @@ oberon_case_statement(oberon_context_t * ctx) static void oberon_with_guard_do(oberon_context_t * ctx, gen_label_t * end) { - oberon_expr_t * val; - oberon_expr_t * var; - oberon_expr_t * type; + oberon_object_t * var; + oberon_expr_t * var_expr; + oberon_expr_t * type_expr; oberon_expr_t * cond; - oberon_expr_t * cast; + oberon_type_t * type; oberon_type_t * old_type; - gen_var_t * old_var; gen_label_t * this_end; this_end = oberon_generator_reserve_label(ctx); - var = oberon_qualident_expr(ctx); + var_expr = oberon_qualident_expr(ctx); oberon_assert_token(ctx, COLON); - type = oberon_qualident_expr(ctx); - cond = oberon_make_bin_op(ctx, IS, var, type); + type_expr = oberon_qualident_expr(ctx); + cond = oberon_make_bin_op(ctx, IS, var_expr, type_expr); + + var = var_expr -> item.var; + type = type_expr -> result; + old_type = var -> type; oberon_assert_token(ctx, DO); oberon_generate_branch(ctx, cond, false, this_end); - /* Сохраняем ссылку во временной переменной */ - val = oberon_make_temp_var_item(ctx, type -> result); - //cast = oberno_make_record_cast(ctx, var, type -> result); - cast = oberon_cast_expr(ctx, var, type -> result); - oberon_assign(ctx, cast, val); - /* Подменяем тип у оригинальной переменной */ - old_type = var -> item.var -> type; - var -> item.var -> type = type -> result; - /* Подменяем ссылку на переменную */ - old_var = var -> item.var -> gen_var; - var -> item.var -> gen_var = val -> item.var -> gen_var; + var -> type = type; + oberon_set_typecheck(var, true); oberon_statement_seq(ctx); + + var -> type = old_type; + oberon_set_typecheck(var, false); + oberon_generate_goto(ctx, end); oberon_generate_label(ctx, this_end); - - /* Возвращаем исходное состояние */ - var -> item.var -> gen_var = old_var; - var -> item.var -> type = old_type; } static void @@ -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) { @@ -3940,7 +3940,6 @@ oberon_make_inc_call(oberon_context_t * ctx, int num_args, oberon_expr_t * list_ { step = list_args -> next; oberon_check_src(ctx, step); - oberon_check_const(ctx, step); if(!oberon_is_integer_type(step -> result)) { oberon_error(ctx, "expect integer"); @@ -4055,7 +4054,6 @@ oberon_make_dec_call(oberon_context_t * ctx, int num_args, oberon_expr_t * list_ { step = list_args -> next; oberon_check_src(ctx, step); - oberon_check_const(ctx, step); if(!oberon_is_integer_type(step -> result)) { oberon_error(ctx, "expect integer"); @@ -4535,7 +4533,7 @@ oberon_make_ord_call(oberon_context_t * ctx, int num_args, oberon_expr_t * list_ } else { - expr = oberon_cast_expr(ctx, arg, ctx -> int_type); + expr = oberon_cast_expr(ctx, arg, ctx -> shortint_type); } return expr; }