|
From: Peep P. <so...@us...> - 2004-06-08 20:43:09
|
Update of /cvsroot/agd/server/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15127 Modified Files: lang.y Log Message: Rearranged stuff; made for, while, do..while work; fixed lvalues Index: lang.y =================================================================== RCS file: /cvsroot/agd/server/src/lang.y,v retrieving revision 1.17 retrieving revision 1.18 diff -u -d -r1.17 -r1.18 --- lang.y 7 Jun 2004 15:54:05 -0000 1.17 +++ lang.y 8 Jun 2004 20:41:49 -0000 1.18 @@ -29,15 +29,15 @@ break_allowed, continue_allowed, is_new_declaration; -typedef struct arr_t arr_t; +/*typedef struct arr_t arr_t;*/ extern int scope_level; extern program_t *this_prog; extern function_t *curr_fun; -void do_assign_expr(expr_t *result, int type1, int type2, int op); +void do_assign_expr(expr_t *result, expr_t *left, int type2, int op); void do_expr(expr_t *result, expr_t *op1, expr_t *op2, int operator); -void do_inc_expr(expr_t *result, int type, int op); +void do_inc_expr(expr_t *result, expr_t *expr, int op); int add_string_to_table(char *s); @@ -53,12 +53,13 @@ char *str; int i; char c; /* used by lex.l */ - struct arr_t { - int length; + struct arr { + int len; int *data; } arr; expr_t expr; def_id_t *id; + void *ptr; /* for() uses this. */ } %token L_IF L_ELSE L_DO L_WHILE L_FOR @@ -102,9 +103,11 @@ %type <str> var_def %type <arr> call_args call_arg_list -%type <expr> expr expr1 expr2 lvalue +%type <expr> expr/* expr1 expr2 lvalue*/ %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 +%type <expr> constant index_expr %type <expr> fun_call call_other %type <i> block_or_semi @@ -168,7 +171,7 @@ '(' arguments ')' { $<id>3->args = $5.data; - $<id>3->numarg = $5.length; + $<id>3->num_arg = $5.len; $<i>$ = yylloc.first_line; } @@ -183,8 +186,8 @@ xfree(buf); } idp->type = ID_FUN; -#if 0 - if($8.data[$8.length-1] != F_RETURN) { + /* 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) { case T_INT: @@ -207,7 +210,7 @@ comp_warning("control reaches end of non-void function"); } } -#endif + add_function(idp, $<i>3/*, &$8*/); curr_fun_type = 0; } else { @@ -227,92 +230,20 @@ ; expr: - expr1 - | expr2; - -expr1: assign_expr | arith_expr | compare_expr | inc_expr - | '-' expr %prec L_NEG - { - $$.side_effect = 0; - $$.direct_type = 0; - $$.type = $2.type; - check_operand(F_NEG, $2.type, 0); - add_token(F_NEG); - } - | '!' expr - { - $$.side_effect = $$.direct_type = 0; - $$.type = T_INT; - check_operand(F_NOT, $2.type, 0); - add_token(F_NOT); - } - | expr L_AND - { - add_two_tokens(F_JUMP_IF_FALSE, 0); - $<i>$ = curr_fun->codelen - 1; /* save length */ - } - expr - { - $$.direct_type = 0; - $$.side_effect = $1.side_effect || $4.side_effect; - $$.type = T_INT; - check_operand(F_AND, $1.type, $4.type); - - curr_fun->code[$<i>3] = $<i>3 + 9; /* Jump past $4. */ - add_two_tokens(F_JUMP_IF_FALSE, 6); - add_two_tokens(F_PUSH_INT, 1); - add_two_tokens(F_JUMP, 3); - add_two_tokens(F_PUSH_INT, 0); - } - | expr L_OR - { - add_two_tokens(F_JUMP_IF_FALSE, 3); - add_two_tokens(F_JUMP, 0); - $<i>$ = curr_fun->codelen - 1; /* Save length. */ - } - expr - { - check_operand(F_OR, $1.type, $4.type); - $$.direct_type = 0; - $$.side_effect = $1.side_effect || $4.side_effect; - $$.type = T_INT; - - curr_fun->code[$<i>3] = $<i>3 + 7; - add_two_tokens(F_JUMP_IF_FALSE, 5); - add_two_tokens(F_PUSH_INT, 1); - add_two_tokens(F_JUMP, 3); - add_two_tokens(F_PUSH_INT, 0); - } - | expr '?' - { - add_two_tokens(F_JUMP_IF_FALSE, 0); - $<i>$ = curr_fun->codelen - 1; -/* ray_push(&$$.arr, (void *) $3.arr.length + 3);*/ - } - expr ':' - { - add_two_tokens(F_JUMP, 0); - $<i>$ = curr_fun->codelen - 1; -/*array_push(&$$.arr, (void *) F_JMP); - array_push(&$$.arr, (void *) $5.arr.length + 1);*/ - } - expr - { - $$.side_effect = $4.side_effect || $7.side_effect; - $$.direct_type = 0; - $$.type = $4.type; - - curr_fun->code[$<i>3] = $<i>6 + 1; - curr_fun->code[$<i>6] = curr_fun->codelen - 1; - - if($4.type != $7.type) { - comp_error("type mismatch"); - } - } + | neg_expr + | not_expr + | and_expr + | or_expr + | trinary_expr + | constant + | '(' expr ')' { $$ = $2; } + | call_other + | fun_call + | index_expr /* | '(' type ')' expr %prec L_TYPECAST { $$.side_effect = $4.side_effect; @@ -334,22 +265,23 @@ init_array(&$$.arr); array_concat(&$$.arr, &$4.arr); }*/ - | L_INTEGER + ; + +constant: + L_INTEGER { $$.side_effect = 0; $$.direct_type = 1; - if($1) - $$.type = T_INT; - else - $$.type = T_ANY; + $$.lval = 0; + +/* $$.type = $1 ? T_INT : T_ANY;*/ + $$.type = T_INT; add_two_tokens(F_PUSH_INT, $1); } - ; - -expr2: - defined_name + | defined_name { $$.side_effect = $$.direct_type = 0; + $$.lval = 1; $$.type = 0; if($1) { @@ -365,15 +297,13 @@ $$.type = $1->lpc_type; } } - | '(' expr ')' { $$ = $2; } - | call_other - | fun_call | string { int index; $$.side_effect = 0; $$.direct_type = 1; + $$.lval = 0; $$.type = T_STRING; index = add_string_to_table($1); @@ -382,21 +312,29 @@ | L_OPEN_ARRAY expr_list L_CLOSE_ARRAY { $$.side_effect = $2.side_effect; + $$.lval = 0; $$.type = $2.type | T_ARRAY; /* $2.arr.length--;*/ add_token(F_PUSH_ARRAY); /* add_two_tokens($2.type, $2.arr.data[$2.arr.length]);*/ } ; - + assign_expr: - lvalue '=' expr { do_assign_expr(&$$, $1.type, $3.type, F_ASSIGN); } - | lvalue L_PLUS_EQ expr { do_assign_expr(&$$, $1.type, $3.type, F_ADD_EQ); } - | lvalue L_MINUS_EQ expr { do_assign_expr(&$$, $1.type, $3.type, F_SUB_EQ); } - | lvalue L_MUL_EQ expr { do_assign_expr(&$$, $1.type, $3.type, F_MUL_EQ); } - | lvalue L_DIV_EQ expr { do_assign_expr(&$$, $1.type, $3.type, F_DIV_EQ); } - | lvalue L_MOD_EQ expr { do_assign_expr(&$$, $1.type, $3.type, F_MOD_EQ); } - | lvalue L_POW_EQ expr { do_assign_expr(&$$, $1.type, $3.type, F_POW_EQ); } + expr '=' { add_token(F_MAKE_LVALUE); } + expr { do_assign_expr(&$$, &$1, $4.type, F_ASSIGN); } + | expr L_PLUS_EQ { add_token(F_MAKE_LVALUE); } + expr { do_assign_expr(&$$, &$1, $4.type, F_ADD_EQ); } + | expr L_MINUS_EQ { add_token(F_MAKE_LVALUE); } + expr { do_assign_expr(&$$, &$1, $4.type, F_SUB_EQ); } + | expr L_MUL_EQ { add_token(F_MAKE_LVALUE); } + expr { do_assign_expr(&$$, &$1, $4.type, F_MUL_EQ); } + | expr L_DIV_EQ { add_token(F_MAKE_LVALUE); } + expr { do_assign_expr(&$$, &$1, $4.type, F_DIV_EQ); } + | expr L_MOD_EQ { add_token(F_MAKE_LVALUE); } + expr { do_assign_expr(&$$, &$1, $4.type, F_MOD_EQ); } + | expr L_POW_EQ { add_token(F_MAKE_LVALUE); } + expr { do_assign_expr(&$$, &$1, $4.type, F_POW_EQ); } ; arith_expr: @@ -406,28 +344,163 @@ if($1.type == T_STRING || $3.type == T_STRING) $$.type = T_STRING; } - | expr '-' expr { do_expr(&$$, &$1, &$3, F_SUB); } - | expr '*' expr { do_expr(&$$, &$1, &$3, F_MUL); } - | expr '/' expr { do_expr(&$$, &$1, &$3, F_DIV); } - | expr '%' expr { do_expr(&$$, &$1, &$3, F_MOD); } - | expr L_POW expr { do_expr(&$$, &$1, &$3, F_POW); } + | expr '-' expr { do_expr(&$$, &$1, &$3, F_SUB); } + | expr '*' expr { do_expr(&$$, &$1, &$3, F_MUL); } + | expr '/' expr { do_expr(&$$, &$1, &$3, F_DIV); } + | expr '%' expr { do_expr(&$$, &$1, &$3, F_MOD); } + | expr L_POW expr { do_expr(&$$, &$1, &$3, F_POW); } compare_expr: - expr '>' expr { do_expr(&$$, &$1, &$3, F_GT); } - | expr L_GE expr { do_expr(&$$, &$1, &$3, F_GE); } - | expr '<' expr { do_expr(&$$, &$1, &$3, F_LT); } - | expr L_LE expr { do_expr(&$$, &$1, &$3, F_LE); } - | expr L_NE expr { do_expr(&$$, &$1, &$3, F_NE); } - | expr L_EQ expr { do_expr(&$$, &$1, &$3, F_EQ); } + expr '>' expr { do_expr(&$$, &$1, &$3, F_GT); } + | expr L_GE expr { do_expr(&$$, &$1, &$3, F_GE); } + | expr '<' expr { do_expr(&$$, &$1, &$3, F_LT); } + | expr L_LE expr { do_expr(&$$, &$1, &$3, F_LE); } + | expr L_NE expr { do_expr(&$$, &$1, &$3, F_NE); } + | expr L_EQ expr { do_expr(&$$, &$1, &$3, F_EQ); } ; inc_expr: - lvalue L_INC { do_inc_expr(&$$, $1.type, F_POSTINC); } - | L_INC lvalue { do_inc_expr(&$$, $2.type, F_PREINC); } - | lvalue L_DEC { do_inc_expr(&$$, $1.type, F_POSTDEC); } - | L_DEC lvalue { do_inc_expr(&$$, $2.type, F_PREDEC); } + expr L_INC + { + add_token(F_MAKE_LVALUE); + do_inc_expr(&$$, &$1, F_POSTINC); + } + | L_INC expr + { + add_token(F_MAKE_LVALUE); + do_inc_expr(&$$, &$2, F_PREINC); + } + | expr L_DEC + { + add_token(F_MAKE_LVALUE); + do_inc_expr(&$$, &$1, F_POSTDEC); + } + | L_DEC expr + { + add_token(F_MAKE_LVALUE); + do_inc_expr(&$$, &$2, F_PREDEC); + } + ; + +neg_expr: + '-' expr %prec L_NEG + { + $$.side_effect = $$.direct_type = 0; + $$.lval = 0; + $$.type = $2.type; + check_operand(F_NEG, $2.type, 0); + add_token(F_NEG); + } + ; + +not_expr: + '!' expr + { + $$.side_effect = $$.direct_type = 0; + $$.lval = 0; + $$.type = T_INT; + check_operand(F_NOT, $2.type, 0); + add_token(F_NOT); + } + ; + +and_expr: + expr L_AND + { + add_two_tokens(F_JUMP_IF_FALSE, 0); + $<i>$ = curr_fun->codelen - 1; /* save length */ + } + expr + { + $$.direct_type = 0; + $$.side_effect = $1.side_effect || $4.side_effect; + $$.lval = 0; + $$.type = T_INT; + check_operand(F_AND, $1.type, $4.type); + + curr_fun->code[$<i>3] = curr_fun->codelen - $<i>3 + 6; /* Jump past $4. */ + add_two_tokens(F_JUMP_IF_FALSE, 5); + add_two_tokens(F_PUSH_INT, 1); + add_two_tokens(F_JUMP, 3); + add_two_tokens(F_PUSH_INT, 0); + } + ; + +or_expr: + expr L_OR + { + add_two_tokens(F_JUMP_IF_FALSE, 3); + add_two_tokens(F_JUMP, 0); + $<i>$ = curr_fun->codelen - 1; /* Save length. */ + } + expr + { + check_operand(F_OR, $1.type, $4.type); + $$.direct_type = 0; + $$.side_effect = $1.side_effect || $4.side_effect; + $$.lval = 0; + $$.type = T_INT; + + curr_fun->code[$<i>3] = curr_fun->codelen - $<i>3 + 2; + add_two_tokens(F_JUMP_IF_FALSE, 5); + add_two_tokens(F_PUSH_INT, 1); + add_two_tokens(F_JUMP, 3); + add_two_tokens(F_PUSH_INT, 0); + } + ; + +trinary_expr: + expr '?' + { + add_two_tokens(F_JUMP_IF_FALSE, 0); + $<i>$ = curr_fun->codelen - 1; + } + expr ':' + { + add_two_tokens(F_JUMP, 0); + $<i>$ = curr_fun->codelen - 1; + } + expr + { + $$.side_effect = $4.side_effect || $7.side_effect; + $$.lval = 0; + $$.direct_type = 0; + $$.type = $4.type; + + curr_fun->code[$<i>3] = curr_fun->codelen - $<i>3 - 2; + curr_fun->code[$<i>6] = curr_fun->codelen - $<i>6; + + if($4.type != $7.type) { + comp_error("type mismatch"); + } + } + ; + +index_expr: /* XXX - first expr must be indexable */ + expr '[' expr ']' + { + $$.side_effect = $1.side_effect || $3.side_effect; + $$.direct_type = 0; + $$.lval = 1; + + if($3.type != T_INT && $3.type != T_ANY) { + comp_error("index must be integer"); + } + $$.type = T_INT; + add_token(F_INDEX); + } + | expr '[' expr L_RANGE expr ']' + { + $$.side_effect = $1.side_effect || $3.side_effect || $5.side_effect; + $$.direct_type = 0; + $$.lval = 1; + $$.type = T_STRING; + + add_token(F_SLICE); + } ; +/* lvalue: expr2 '[' expr ']' { @@ -462,6 +535,7 @@ } | error ';' { comp_error("invalid lvalue"); } ; +*/ expr_list: /* empty */ @@ -511,8 +585,15 @@ ; block: - '{' { scope_level++; /*new_block_level();*/ } statements '}' - { pop_scope(); } + '{' + { + scope_level++; + /*new_block_level();*/ + } + statements '}' + { + pop_scope(); + } ; optional_star: @@ -525,7 +606,12 @@ | type ; -type: L_DATA_TYPE optional_star { $$ = $1|$2; global_type = $$; } ; +type: L_DATA_TYPE optional_star + { + $$ = $1|$2; + global_type = $$; + } + ; defined_name: L_IDENTIFIER @@ -544,15 +630,23 @@ statement: block - | return - | if - | do_while + | stmt_no_semi ';' + | stmt_no_semi_at_all + ; + +stmt_no_semi_at_all: + if | while | for + ; + +stmt_no_semi: + return + | do_while | break | continue | local_var {/* num_locals++;*/ } - | expr ';' + | expr { if($1.side_effect) { add_token(F_POP); @@ -560,19 +654,26 @@ comp_warning("statement with no effect"); } } - | ';' + | /* 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 ; arguments: - /* empty */ { $$.length = 0; } + /* empty */ + { $$.len = 0; } | L_DATA_TYPE { - $$.length = 0; + $$.len = 0; if($1 != T_VOID) { comp_error("syntax error"); } @@ -583,16 +684,16 @@ argument_list: fun_arg { - $$.length = 1; + $$.len = 1; $$.data = malloc(sizeof(int)); $$.data[0] = $1; } | argument_list ',' fun_arg { $$ = $1; - $$.length++; - $$.data = realloc($$.data, $$.length * sizeof(int)); - $$.data[$$.length-1] = $3; + $$.len++; + $$.data = realloc($$.data, $$.len * sizeof(int)); + $$.data[$$.len-1] = $3; } ; @@ -645,7 +746,8 @@ ; lvar_def: - var_def { add_variable($1, global_type, ID_LVAR); } + var_def + { add_variable($1, global_type, ID_LVAR); } | var_def '=' { def_id_t *idp; @@ -667,7 +769,8 @@ ; gvar_def: - var_def { add_variable($1, global_type, ID_GVAR); } + var_def + { add_variable($1, global_type, ID_GVAR); } | var_def '=' { def_id_t *idp; @@ -705,7 +808,7 @@ ; local_var: - type local_vars ';' + type local_vars { global_type = 0; if(!$1) { @@ -717,12 +820,13 @@ ; optional_expr: - /* empty */ { memset(&$$, 0, sizeof($$)); } + /* empty */ + { memset(&$$, 0, sizeof($$)); } | expr ; return: - L_RETURN optional_expr ';' + L_RETURN optional_expr { if(curr_fun_type == T_VOID) { if($2.type) { @@ -744,7 +848,7 @@ add_two_tokens(F_JUMP_IF_FALSE, 0); $<i>$ = curr_fun->codelen - 1; } - statement + stmt_no_semi_or_block { add_two_tokens(F_JUMP, 0); curr_fun->code[$<i>5] = curr_fun->codelen - $<i>5; @@ -761,13 +865,19 @@ else: /* empty */ - | L_ELSE statement + | L_ELSE stmt_no_semi_or_block ; do_while: - L_DO { break_allowed = continue_allowed = 1; } - statement L_WHILE '(' expr ')' + 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 ')' { + add_two_tokens(F_JUMP_IF_FALSE, 3); + add_two_tokens(F_JUMP, $<i>2 - curr_fun->codelen - 1); /* init_array(&$$); array_push(&$$, (void *) F_JMP); array_push(&$$, (void *) ($6.arr.length + 3)); @@ -783,11 +893,21 @@ while: L_WHILE { - break_allowed = continue_allowed = 1; + break_allowed = continue_allowed = /*1*/ 0; /* For now. */ + $<i>$ = curr_fun ? curr_fun->codelen : 0; } - '(' expr ')' statement + '(' expr + { + add_two_tokens(F_JUMP_IF_FALSE, 0); + $<i>$ = curr_fun->codelen - 1; + } + ')' statement { -/* int i; + add_two_tokens(F_JUMP, $<i>2 - curr_fun->codelen - 1); + curr_fun->code[$<i>5] = curr_fun->codelen - $<i>5; + +/* + int i; for(i=0;i<$6.length;i++) { if((int)$6.data[i] == F_BREAK_MAGIC1 && (int)$6.data[i+1] == F_BREAK_MAGIC2) { @@ -801,25 +921,70 @@ $6.data[i] = (void *) -(i + $4.arr.length + 2); } } - - init_array(&$$); +*/ + +/* init_array(&$$); array_concat(&$$, &$4.arr); array_push(&$$, (void *) F_JMPF); array_push(&$$, (void *) ($6.length + 3)); array_concat(&$$, &$6); array_push(&$$, (void *) F_JMP); array_push(&$$, (void *) -($6.length + $4.arr.length + 3)); - break_allowed = continue_allowed = 0;*/ + break_allowed = continue_allowed = 0; +*/ } ; for: - L_FOR '(' expr ';' expr ';' expr ')' - { - break_allowed = continue_allowed = 1; - } + L_FOR '(' expr ';' + { + if($3.side_effect) + add_token(F_POP); + $<i>$ = curr_fun->codelen; + } + expr + { + if($6.side_effect) + add_token(F_POP); + add_two_tokens(F_JUMP_IF_FALSE, 0); + $<i>$ = curr_fun->codelen - 1; + } + ';' + { + $<ptr>$ = curr_fun; + curr_fun = NULL; + } + expr + { + if($10.side_effect) + add_token(F_POP); + + /* Now we have a new curr_fun. */ + $<ptr>$ = (void *) curr_fun; + curr_fun = $<ptr>9; + } + ')' + { break_allowed = continue_allowed = /*1*/ 0; /* For now. */ } statement - { + { + /* Statements are pushed, concatenate the expr3 tokens. */ + int i; + int old_len; + function_t *expr3 = $<ptr>11; + + old_len = curr_fun->codelen; + curr_fun->codelen += expr3->codelen; + curr_fun->code = xrealloc(curr_fun->code, curr_fun->codelen * sizeof(int)); + + for(i=old_len;i<curr_fun->codelen;i++) { + curr_fun->code[i] = expr3->code[i-old_len]; + } + + free_fun(expr3); + + add_two_tokens(F_JUMP, $<i>5 - curr_fun->codelen - 1); + + curr_fun->code[$<i>7] = curr_fun->codelen - $<i>7; /* int i; for(i=0;i<$10.length;i++) { @@ -855,7 +1020,7 @@ ; break: - L_BREAK ';' + L_BREAK { /* $$.length = 2; $$.data = malloc(sizeof(int *) * 2); @@ -869,7 +1034,7 @@ ; continue: - L_CONTINUE ';' + L_CONTINUE { /* $$.length = 2; $$.data = malloc(sizeof(int *) * 2); @@ -887,6 +1052,7 @@ { int i; char *buf; + def_id_t *idp; $$.side_effect = 1; $$.direct_type = 0; @@ -896,18 +1062,18 @@ $$.type = $1->lpc_type; - if($3.length > $1->numarg) { + if($3.len > $1->num_arg) { buf = xmalloc(strlen($1->name) + 23); sprintf(buf, "too many arguments to %s", $1->name); comp_error(buf); xfree(buf); - } else if($3.length < $1->numarg) { + } else if($3.len < $1->num_arg) { buf = xmalloc(strlen($1->name) + 22); sprintf(buf, "too few arguments to %s", $1->name); comp_error(buf); xfree(buf); } else { - for(i=0;i<$1->numarg;i++) { + for(i=0;i<$1->num_arg;i++) { if($1->args[i] != T_ANY && $3.data[i] != T_ANY && $1->args[i] != $3.data[i]) { char *ts1, *ts2; @@ -931,14 +1097,14 @@ add_token(F_CALL_DFUN); } else /* ID_FUN */ add_token(F_CALL_LFUN); - add_two_tokens($1->index, $3.length); + add_two_tokens($1->index, $3.len); } ; call_other: expr L_ARROW L_IDENTIFIER '(' call_args ')' { - int i; + int index; $$.side_effect = 1; $$.direct_type = 0; @@ -949,42 +1115,49 @@ comp_error("not an object to '->'"); } + index = add_string_to_table($3); add_token(F_CALL_OTHER); - add_two_tokens((long int)$3 /*XXX*/, $5.length); + add_two_tokens(index, $5.len); } ; call_args: - /* empty */ { $$.length = 0; } + /* empty */ { $$.len = 0; } | call_arg_list ; call_arg_list: expr { - $$.length = 1; + $$.len = 1; $$.data = malloc(sizeof(int)); $$.data[0] = $1.type; } | call_arg_list ',' expr { $$ = $1; - $$.length++; - $$.data = realloc($$.data, $$.length * sizeof(int)); - $$.data[$$.length-1] = $3.type; + $$.len++; + $$.data = realloc($$.data, $$.len * sizeof(int)); + $$.data[$$.len-1] = $3.type; } ; %% -void do_assign_expr(expr_t *result, int type1, int type2, int op) +void do_assign_expr(expr_t *result, expr_t *left, int type2, int op) { + if(!left->lval) { + comp_error("invalid lvalue"); + } + result->side_effect = 1; - result->type = type1; + result->type = left->type; result->direct_type = 0; - if(type1 && type2 && type1 != type2) { + result->lval = 0; + + if(left->type && type2 && left->type != type2) { comp_error("type mismatch"); } - check_operand(op, type1, type2); + check_operand(op, left->type, type2); add_token(op); } @@ -997,12 +1170,17 @@ add_token(operator); } -void do_inc_expr(expr_t *result, int type, int op) +void do_inc_expr(expr_t *result, expr_t *expr, int op) { + if(!expr->lval) { + comp_error("invalid lvalue"); + } + result->side_effect = 1; result->direct_type = 0; - result->type = type; - check_operand(op, type, 0); + result->lval = 0; + result->type = expr->type; + check_operand(op, expr->type, 0); add_token(op); } |