From: Peep P. <so...@us...> - 2004-06-12 20:08:55
|
Update of /cvsroot/agd/server/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27569 Modified Files: lang.y Log Message: Now pops locals after leaving a block. Index: lang.y =================================================================== RCS file: /cvsroot/agd/server/src/lang.y,v retrieving revision 1.19 retrieving revision 1.20 diff -u -d -r1.19 -r1.20 --- lang.y 12 Jun 2004 16:44:22 -0000 1.19 +++ lang.y 12 Jun 2004 20:08:46 -0000 1.20 @@ -1,6 +1,5 @@ %{ -/* TODO: pop locals after returning from block */ #include <stdlib.h> #include "config.h" #include "compile_options.h" @@ -30,6 +29,9 @@ continue_allowed, is_new_declaration; +static int num_locals_pushed, + dont_add_pop; + extern int scope_level; extern program_t *this_prog; extern function_t *curr_fun; @@ -102,7 +104,7 @@ %type <str> var_def %type <arr> call_args call_arg_list -%type <expr> expr/* expr1 expr2 lvalue*/ +%type <expr> expr %type <expr> optional_expr expr_list expr_list2 %type <expr> assign_expr arith_expr compare_expr inc_expr %type <expr> neg_expr not_expr and_expr or_expr trinary_expr @@ -177,7 +179,9 @@ block_or_semi { if($8) { + int dont_warn = 0; def_id_t *idp = $<id>3; + if(idp->lpc_type != $1/* || compare_args(idp->args, &$5) FIXME!*/) { char *buf = xmalloc(strlen($2) + 42 /* ;) */); sprintf(buf, "definition doesn't match declaration for %s", $2); @@ -185,10 +189,9 @@ xfree(buf); } idp->type = ID_FUN; - /* curr_fun can be zero if add_token() wasn't called for this function */ + if(!curr_fun || curr_fun->code[curr_fun->codelen-1] != F_RETURN) { - int warn = 1; - switch($1) { + switch(curr_fun_type) { case T_INT: add_two_tokens(F_PUSH_INT, 0); break; @@ -200,16 +203,19 @@ break; case T_VOID: add_token(F_PUSH_VOID); + dont_warn = 1; + break; default: - warn = 0; + printf("curr_fun_type unknown! (%d)\n", curr_fun_type); break; } + add_token(F_RETURN); - if(warn) { + if(!dont_warn) { comp_warning("control reaches end of non-void function"); } } - + add_function(idp, $<i>3/*, &$8*/); curr_fun_type = 0; } else { @@ -483,43 +489,6 @@ } ; -/* -lvalue: - expr2 '[' expr ']' - { - if($3.type != T_INT && $3.type != T_ANY) { - comp_error("index must be integer"); - } - $$.type = T_INT; - add_token(F_INDEX); - } - | expr2 '[' expr L_RANGE expr ']' - { - $$.type = T_STRING; - add_token(F_SLICE); - } - | defined_name - { - $$.side_effect = $$.direct_type = 0; - $$.type = 0; - - if($1) { - if($1->type == ID_GVAR) - add_token(F_PUSH_GVAR_LVALUE); - else if($1->type == ID_LVAR || $1->type == ID_ARG) - add_token(F_PUSH_LVAR_LVALUE); - else { - comp_error("variable expected"); - } - - add_token($1->index); - $$.type = $1->lpc_type; - } - } - | error ';' { comp_error("invalid lvalue"); } - ; -*/ - expr_list: /* empty */ { @@ -571,10 +540,23 @@ '{' { scope_level++; - /*new_block_level();*/ + $<i>$ = num_locals_pushed; + num_locals_pushed = 0; } statements '}' { + int i; + int num; + /* Don't want F_POP after F_RETURN. */ + if(!dont_add_pop) { + num = $<i>2 + num_locals_pushed; + num_locals_pushed = 0; + for(i=0;i<num;i++) + add_token(F_POP); + } else { + dont_add_pop = 0; + num_locals_pushed = 0; + } pop_scope(); } ; @@ -614,21 +596,17 @@ statement: block | stmt_no_semi ';' - | stmt_no_semi_at_all - ; - -stmt_no_semi_at_all: - if + | if | while | for ; - + stmt_no_semi: return | do_while | break | continue - | local_var {/* num_locals++;*/ } + | local_var | expr { if($1.side_effect) { @@ -640,22 +618,27 @@ | /* empty, for a single ';'-statement to work */ ; -stmt_no_semi_or_block: - stmt_no_semi - | block - | stmt_no_semi_at_all - ; - statements: /* empty */ - | statements statement + {/* $$ = num_locals_pushed = malloc(sizeof(int)); + *num_locals_pushed = 0; + printf("empty statements. num_locals_pushed: %p (value = %d)\n", num_locals_pushed, *num_locals_pushed);*/ + } + | statements { +/* $$ = $1; + printf("statements and another statement reached. num_locals_pushed: %p (value=%d); $$: %p\n", num_locals_pushed, *num_locals_pushed, $$);*/ + } statement ; arguments: /* empty */ - { $$.len = 0; } + { + $$.data = NULL; + $$.len = 0; + } | L_DATA_TYPE { + $$.data = NULL; $$.len = 0; if($1 != T_VOID) { comp_error("syntax error"); @@ -730,12 +713,16 @@ lvar_def: var_def - { add_variable($1, global_type, ID_LVAR); } + { + add_variable($1, global_type, ID_LVAR); + num_locals_pushed++; + } | var_def '=' { def_id_t *idp; idp = add_variable($1, global_type, ID_LVAR); add_two_tokens(F_PUSH_LVAR_LVALUE, idp->index); + num_locals_pushed++; } expr { @@ -822,6 +809,8 @@ if(!$2.type) add_token(F_PUSH_VOID); add_token(F_RETURN); + + dont_add_pop = 1; } ; @@ -831,7 +820,7 @@ add_two_tokens(F_JUMP_IF_FALSE, 0); $<i>$ = curr_fun->codelen - 1; } - stmt_no_semi_or_block + statement { add_two_tokens(F_JUMP, 0); curr_fun->code[$<i>5] = curr_fun->codelen - $<i>5; @@ -848,16 +837,16 @@ else: /* empty */ - | L_ELSE stmt_no_semi_or_block + | L_ELSE statement ; do_while: L_DO - { - break_allowed = continue_allowed = /*1*/ 0; /* For now. */ - $<i>$ = curr_fun ? curr_fun->codelen : 0; - } - stmt_no_semi_or_block L_WHILE '(' expr ')' + { + break_allowed = continue_allowed = /*1*/ 0; /* For now. */ + $<i>$ = curr_fun ? curr_fun->codelen : 0; + } + expr L_WHILE '(' expr ')' { add_two_tokens(F_JUMP_IF_FALSE, 3); add_two_tokens(F_JUMP, $<i>2 - curr_fun->codelen - 1); @@ -919,13 +908,13 @@ ; for: - L_FOR '(' expr ';' + L_FOR '(' optional_expr ';' { if($3.side_effect) add_token(F_POP); $<i>$ = curr_fun->codelen; } - expr + optional_expr { if($6.side_effect) add_token(F_POP); @@ -937,7 +926,7 @@ $<ptr>$ = curr_fun; curr_fun = NULL; } - expr + optional_expr { if($10.side_effect) add_token(F_POP); |