implement pre and post increment operators (++ and --)

This commit is contained in:
Bill Currie 2001-08-20 06:22:28 +00:00
parent cd59628199
commit cf4ca286f0
5 changed files with 66 additions and 52 deletions

View file

@ -11,9 +11,9 @@ X <op>= operator ( var += expr, etc. )
X allow temp defs at higher levels X allow temp defs at higher levels
X move the chained funcion support out of emit_function_expr into X move the chained funcion support out of emit_function_expr into
funciton_expr funciton_expr
X pre- and post- increment operators (++ and --)
I gut out old parser I gut out old parser
o switch/case, for any type o switch/case, for any type
o break/continue keywords for switch() and for(;;) o break/continue keywords for switch() and for(;;)
o quaternion type. Tricky: requires 4 word args/return o quaternion type. Tricky: requires 4 word args/return
o pre- and post- increment operators (++ and --)
o CSE optimisations o CSE optimisations

View file

@ -92,6 +92,7 @@ expr_t *unary_expr (int op, expr_t *e);
expr_t *function_expr (expr_t *e1, expr_t *e2); expr_t *function_expr (expr_t *e1, expr_t *e2);
expr_t *return_expr (function_t *f, expr_t *e); expr_t *return_expr (function_t *f, expr_t *e);
expr_t *conditional_expr (expr_t *cond, expr_t *e1, expr_t *e2); expr_t *conditional_expr (expr_t *cond, expr_t *e1, expr_t *e2);
expr_t *incop_expr (int op, expr_t *e, int postop);
def_t *emit_statement (int line, opcode_t *op, def_t *var_a, def_t *var_b, def_t *var_c); def_t *emit_statement (int line, opcode_t *op, def_t *var_a, def_t *var_b, def_t *var_c);
void emit_expr (expr_t *e); void emit_expr (expr_t *e);

View file

@ -812,31 +812,7 @@ asx_expr (int op, expr_t *e1, expr_t *e2)
{ {
expr_t *e = new_expr (); expr_t *e = new_expr ();
*e = *e1; *e = *e1;
switch (op) { return binary_expr ('=', e, binary_expr (op, e1, e2));
case ASADD:
return binary_expr ('=', e, binary_expr ('+', e1, e2));
case ASSUB:
return binary_expr ('=', e, binary_expr ('-', e1, e2));
case ASMUL:
return binary_expr ('=', e, binary_expr ('*', e1, e2));
case ASDIV:
return binary_expr ('=', e, binary_expr ('/', e1, e2));
case ASAND:
return binary_expr ('=', e, binary_expr ('&', e1, e2));
case ASOR:
return binary_expr ('=', e, binary_expr ('|', e1, e2));
case ASXOR:
return binary_expr ('=', e, binary_expr ('^', e1, e2));
case ASMOD:
return binary_expr ('=', e, binary_expr ('%', e1, e2));
case ASSHL:
return binary_expr ('=', e, binary_expr (SHL, e1, e2));
case ASSHR:
return binary_expr ('=', e, binary_expr (SHR, e1, e2));
default:
error (e1, "invalid operand for asx");
}
return 0;
} }
expr_t * expr_t *
@ -1138,3 +1114,29 @@ conditional_expr (expr_t *cond, expr_t *e1, expr_t *e2)
append_expr (block, elabel); append_expr (block, elabel);
return block; return block;
} }
expr_t *
incop_expr (int op, expr_t *e, int postop)
{
expr_t *one = new_expr ();
expr_t *incop;
one->type = ex_integer; // integer constants get auto-cast to float
one->e.integer_val = 1;
incop = asx_expr (op, e, one);
if (postop) {
expr_t *temp;
type_t *type;
expr_t *block = new_block_expr ();
type = e->type == ex_def
? e->e.def->type
: e->e.expr.type;
temp = new_temp_def_expr (type);
append_expr (block, binary_expr ('=', temp, e));
append_expr (block, incop);
block->e.block.result = temp;
return block;
}
return incop;
}

View file

@ -95,21 +95,26 @@ m ([\-+]?)
s_file = ReuseString (pr_immediate_string); s_file = ReuseString (pr_immediate_string);
} }
[+\-*/&|^%]= {
yylval.op = yytext[0];
printf ("%s\n", yytext);
return ASX;
}
"<<=" {
yylval.op = SHL;
return ASX;
}
">>=" {
yylval.op = SHR;
return ASX;
}
[!(){}.*/&|^~+\-=\[\];,#%?:] return yytext[0]; [!(){}.*/&|^~+\-=\[\];,#%?:] return yytext[0];
"..." return ELIPSIS; "..." return ELIPSIS;
"+=" return ASADD;
"-=" return ASSUB;
"*=" return ASMUL;
"/=" return ASDIV;
"&=" return ASAND;
"|=" return ASOR;
"^=" return ASXOR;
"%=" return ASMOD;
"<<=" return ASSHL;
">>=" return ASSHR;
"<<" return SHL; "<<" return SHL;
">>" return SHR; ">>" return SHR;
@ -122,6 +127,16 @@ m ([\-+]?)
"<" return LT; "<" return LT;
">" return GT; ">" return GT;
"++" {
yylval.op = '+';
return INCOP;
}
"--" {
yylval.op = '-';
return INCOP;
}
"$"{s}*{ID} { "$"{s}*{ID} {
int ret = do_grab(yytext); int ret = do_grab(yytext);
if (ret > 0) if (ret > 0)

View file

@ -33,6 +33,7 @@ typedef struct {
%} %}
%union { %union {
int op;
scope_t scope; scope_t scope;
def_t *def; def_t *def;
type_t *type; type_t *type;
@ -45,14 +46,15 @@ typedef struct {
function_t *function; function_t *function;
} }
%right '=' ASADD ASSUB ASMUL ASDIV ASAND ASOR ASXOR ASMOD ASSHL ASSHR %right <op> '=' ASX
%right '?' ':' %right '?' ':'
%left OR AND %left OR AND
%left EQ NE LE GE LT GT %left EQ NE LE GE LT GT
%left SHL SHR %left SHL SHR
%left '+' '-' %left '+' '-'
%left '*' '/' '&' '|' '^' '%' %left '*' '/' '&' '|' '^' '%'
%left '!' '~' //%left '!' '~'
%right <op> UNARY INCOP
%right '(' %right '('
%left '.' %left '.'
@ -442,16 +444,7 @@ opt_expr
expr expr
: expr '=' expr { $$ = binary_expr ('=', $1, $3); } : expr '=' expr { $$ = binary_expr ('=', $1, $3); }
| expr ASADD expr { $$ = asx_expr (ASADD, $1, $3); } | expr ASX expr { $$ = asx_expr ($2, $1, $3); }
| expr ASSUB expr { $$ = asx_expr (ASSUB, $1, $3); }
| expr ASMUL expr { $$ = asx_expr (ASMUL, $1, $3); }
| expr ASDIV expr { $$ = asx_expr (ASDIV, $1, $3); }
| expr ASAND expr { $$ = asx_expr (ASAND, $1, $3); }
| expr ASOR expr { $$ = asx_expr (ASOR, $1, $3); }
| expr ASXOR expr { $$ = asx_expr (ASXOR, $1, $3); }
| expr ASMOD expr { $$ = asx_expr (ASMOD, $1, $3); }
| expr ASSHL expr { $$ = asx_expr (ASSHL, $1, $3); }
| expr ASSHR expr { $$ = asx_expr (ASSHR, $1, $3); }
| expr '?' expr ':' expr { $$ = conditional_expr ($1, $3, $5); } | expr '?' expr ':' expr { $$ = conditional_expr ($1, $3, $5); }
| expr AND expr { $$ = binary_expr (AND, $1, $3); } | expr AND expr { $$ = binary_expr (AND, $1, $3); }
| expr OR expr { $$ = binary_expr (OR, $1, $3); } | expr OR expr { $$ = binary_expr (OR, $1, $3); }
@ -474,9 +467,12 @@ expr
| expr '(' arg_list ')' { $$ = function_expr ($1, $3); } | expr '(' arg_list ')' { $$ = function_expr ($1, $3); }
| expr '(' ')' { $$ = function_expr ($1, 0); } | expr '(' ')' { $$ = function_expr ($1, 0); }
| expr '.' expr { $$ = binary_expr ('.', $1, $3); } | expr '.' expr { $$ = binary_expr ('.', $1, $3); }
| '-' expr %prec '!' { $$ = unary_expr ('-', $2); } | '+' expr %prec UNARY { $$ = $2; }
| '!' expr { $$ = unary_expr ('!', $2); } | '-' expr %prec UNARY { $$ = unary_expr ('-', $2); }
| '~' expr { $$ = unary_expr ('~', $2); } | '!' expr %prec UNARY { $$ = unary_expr ('!', $2); }
| '~' expr %prec UNARY { $$ = unary_expr ('~', $2); }
| INCOP expr { $$ = incop_expr ($1, $2, 0); }
| expr INCOP { $$ = incop_expr ($2, $1, 1); }
| NAME | NAME
{ {
$$ = new_expr (); $$ = new_expr ();