temp def expressions and ?:

seems to work :)
This commit is contained in:
Bill Currie 2001-08-11 21:15:24 +00:00
parent 3d30361595
commit c2d3d8f3ab
6 changed files with 128 additions and 44 deletions

View file

@ -4,6 +4,7 @@ typedef enum {
ex_expr, // binary expression ex_expr, // binary expression
ex_uexpr, // unary expression ex_uexpr, // unary expression
ex_def, ex_def,
ex_temp, // temporary variable
ex_string, ex_string,
ex_float, ex_float,
@ -25,8 +26,16 @@ typedef struct {
typedef struct { typedef struct {
struct expr_s *head; struct expr_s *head;
struct expr_s **tail; struct expr_s **tail;
struct expr_s *result;
} block_t; } block_t;
typedef struct {
struct expr_s *expr;
def_t *def;
type_t *type;
int users;
} temp_t;
typedef struct expr_s { typedef struct expr_s {
struct expr_s *next; struct expr_s *next;
expr_type type; expr_type type;
@ -43,6 +52,7 @@ typedef struct expr_s {
struct expr_s *e2; struct expr_s *e2;
} expr; } expr;
def_t *def; def_t *def;
temp_t temp;
char *string_val; char *string_val;
float float_val; float float_val;
@ -67,6 +77,7 @@ expr_t *new_label_expr (void);
expr_t *new_block_expr (void); expr_t *new_block_expr (void);
expr_t *new_binary_expr (int op, expr_t *e1, expr_t *e2); expr_t *new_binary_expr (int op, expr_t *e1, expr_t *e2);
expr_t *new_unary_expr (int op, expr_t *e1); expr_t *new_unary_expr (int op, expr_t *e1);
expr_t *new_temp_def_expr (type_t *type);
expr_t *append_expr (expr_t *block, expr_t *e); expr_t *append_expr (expr_t *block, expr_t *e);
@ -80,6 +91,7 @@ expr_t *asx_expr (int op, expr_t *e1, expr_t *e2);
expr_t *unary_expr (int op, expr_t *e); 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);
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

@ -169,8 +169,14 @@ emit_sub_expr (expr_t *e, def_t *dest)
int priority; int priority;
switch (e->type) { switch (e->type) {
case ex_label:
case ex_block: case ex_block:
if (e->e.block.result) {
expr_t *res = e->e.block.result;
for (e = e->e.block.head; e; e = e->next)
emit_expr (e);
return emit_sub_expr (res, 0);
}
case ex_label:
error (e, "internal error"); error (e, "internal error");
abort (); abort ();
case ex_expr: case ex_expr:
@ -293,6 +299,10 @@ emit_sub_expr (expr_t *e, def_t *dest)
return emit_statement (e->line, op, def_a, def_b, dest); return emit_statement (e->line, op, def_a, def_b, dest);
case ex_def: case ex_def:
return e->e.def; return e->e.def;
case ex_temp:
if (!e->e.temp.def)
e->e.temp.def = PR_GetTempDef (e->e.temp.type, pr_scope);
return e->e.temp.def;
case ex_string: case ex_string:
case ex_float: case ex_float:
case ex_vector: case ex_vector:
@ -383,6 +393,7 @@ emit_expr (expr_t *e)
} }
break; break;
case ex_def: case ex_def:
case ex_temp:
case ex_string: case ex_string:
case ex_float: case ex_float:
case ex_vector: case ex_vector:

View file

@ -17,6 +17,7 @@ etype_t qc_types[] = {
ev_void, // ex_expr ev_void, // ex_expr
ev_void, // ex_uexpr ev_void, // ex_uexpr
ev_void, // ex_def ev_void, // ex_def
ev_void, // ex_temp
ev_string, // ex_string ev_string, // ex_string
ev_float, // ex_float ev_float, // ex_float
@ -73,13 +74,18 @@ get_type (expr_t *e)
{ {
switch (e->type) { switch (e->type) {
case ex_label: case ex_label:
case ex_block:
return ev_type_count; // something went very wrong return ev_type_count; // something went very wrong
case ex_block:
if (e->e.block.result)
return get_type (e->e.block.result);
return ev_void;
case ex_expr: case ex_expr:
case ex_uexpr: case ex_uexpr:
return e->e.expr.type->type; return e->e.expr.type->type;
case ex_def: case ex_def:
return e->e.def->type->type; return e->e.def->type->type;
case ex_temp:
return e->e.temp.type->type;
case ex_integer: case ex_integer:
if (options.version == PROG_ID_VERSION) { if (options.version == PROG_ID_VERSION) {
e->type = ex_float; e->type = ex_float;
@ -250,6 +256,16 @@ new_unary_expr (int op, expr_t *e1)
return e; return e;
} }
expr_t *
new_temp_def_expr (type_t *type)
{
expr_t *e = new_expr ();
e->type = ex_temp;
e->e.temp.type = type;
return e;
}
expr_t * expr_t *
append_expr (expr_t *block, expr_t *e) append_expr (expr_t *block, expr_t *e)
{ {
@ -278,6 +294,10 @@ print_expr (expr_t *e)
printf ("%s", e->e.label.name); printf ("%s", e->e.label.name);
break; break;
case ex_block: case ex_block:
if (e->e.block.result) {
print_expr (e->e.block.result);
printf ("=");
}
printf ("{\n"); printf ("{\n");
for (e = e->e.block.head; e; e = e->next) { for (e = e->e.block.head; e; e = e->next) {
print_expr (e); print_expr (e);
@ -309,6 +329,10 @@ print_expr (expr_t *e)
case ex_def: case ex_def:
printf ("%s", e->e.def->name); printf ("%s", e->e.def->name);
break; break;
case ex_temp:
print_expr (e->e.temp.expr);
printf ("@");
break;
case ex_string: case ex_string:
printf ("\"%s\"", e->e.string_val); printf ("\"%s\"", e->e.string_val);
break; break;
@ -820,14 +844,17 @@ unary_expr (int op, expr_t *e)
case '-': case '-':
switch (e->type) { switch (e->type) {
case ex_label: case ex_label:
case ex_block:
error (e, "internal error"); error (e, "internal error");
abort (); abort ();
case ex_uexpr: case ex_uexpr:
if (e->e.expr.op == '-') if (e->e.expr.op == '-')
return e->e.expr.e1; return e->e.expr.e1;
case ex_block:
if (!e->e.block.result)
return error (e, "invalid type for unary -");
case ex_expr: case ex_expr:
case ex_def: case ex_def:
case ex_temp:
{ {
expr_t *n = new_unary_expr (op, e); expr_t *n = new_unary_expr (op, e);
n->e.expr.type = (e->type == ex_def) n->e.expr.type = (e->type == ex_def)
@ -863,11 +890,14 @@ unary_expr (int op, expr_t *e)
case '!': case '!':
switch (e->type) { switch (e->type) {
case ex_label: case ex_label:
case ex_block:
abort (); abort ();
case ex_block:
if (!e->e.block.result)
return error (e, "invalid type for unary -");
case ex_uexpr: case ex_uexpr:
case ex_expr: case ex_expr:
case ex_def: case ex_def:
case ex_temp:
{ {
expr_t *n = new_unary_expr (op, e); expr_t *n = new_unary_expr (op, e);
if (options.version > PROG_ID_VERSION) if (options.version > PROG_ID_VERSION)
@ -911,13 +941,16 @@ unary_expr (int op, expr_t *e)
case '~': case '~':
switch (e->type) { switch (e->type) {
case ex_label: case ex_label:
case ex_block:
abort (); abort ();
case ex_uexpr: case ex_uexpr:
if (e->e.expr.op == '~') if (e->e.expr.op == '~')
return e->e.expr.e1; return e->e.expr.e1;
case ex_block:
if (!e->e.block.result)
return error (e, "invalid type for unary -");
case ex_expr: case ex_expr:
case ex_def: case ex_def:
case ex_temp:
{ {
expr_t *n = new_unary_expr (op, e); expr_t *n = new_unary_expr (op, e);
type_t *t = e->type == ex_expr ? e->e.expr.type type_t *t = e->type == ex_expr ? e->e.expr.type
@ -1058,3 +1091,28 @@ return_expr (function_t *f, expr_t *e)
} }
return new_unary_expr ('r', e); return new_unary_expr ('r', e);
} }
expr_t *
conditional_expr (expr_t *cond, expr_t *e1, expr_t *e2)
{
expr_t *block = new_block_expr ();
type_t *type1 = types[get_type (e1)];
type_t *type2 = types[get_type (e2)];
expr_t *tlabel = new_label_expr ();
expr_t *elabel = new_label_expr ();
block->e.block.result = (type1 == type2) ? new_temp_def_expr (type1) : 0;
append_expr (block, new_binary_expr ('i', test_expr (cond, 1), tlabel));
if (block->e.block.result)
append_expr (block, new_binary_expr ('=', block->e.block.result, e2));
else
append_expr (block, e2);
append_expr (block, new_unary_expr ('g', elabel));
append_expr (block, tlabel);
if (block->e.block.result)
append_expr (block, new_binary_expr ('=', block->e.block.result, e1));
else
append_expr (block, e1);
append_expr (block, elabel);
return block;
}

View file

@ -95,7 +95,7 @@ m ([\-+]?)
s_file = ReuseString (pr_immediate_string); s_file = ReuseString (pr_immediate_string);
} }
[!(){}.*/&|^~+\-=\[\];,#%] return yytext[0]; [!(){}.*/&|^~+\-=\[\];,#%?:] return yytext[0];
"..." return ELIPSIS; "..." return ELIPSIS;

View file

@ -46,6 +46,7 @@ typedef struct {
} }
%right '=' ASADD ASSUB ASMUL ASDIV ASAND ASOR ASXOR ASMOD ASSHL ASSHR %right '=' ASADD ASSUB ASMUL ASDIV ASAND ASOR ASXOR ASMOD ASSHL ASSHR
%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
@ -440,41 +441,42 @@ 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 ASADD expr { $$ = asx_expr (ASADD, $1, $3); }
| expr ASSUB expr { $$ = asx_expr (ASSUB, $1, $3); } | expr ASSUB expr { $$ = asx_expr (ASSUB, $1, $3); }
| expr ASMUL expr { $$ = asx_expr (ASMUL, $1, $3); } | expr ASMUL expr { $$ = asx_expr (ASMUL, $1, $3); }
| expr ASDIV expr { $$ = asx_expr (ASDIV, $1, $3); } | expr ASDIV expr { $$ = asx_expr (ASDIV, $1, $3); }
| expr ASAND expr { $$ = asx_expr (ASAND, $1, $3); } | expr ASAND expr { $$ = asx_expr (ASAND, $1, $3); }
| expr ASOR expr { $$ = asx_expr (ASOR, $1, $3); } | expr ASOR expr { $$ = asx_expr (ASOR, $1, $3); }
| expr ASXOR expr { $$ = asx_expr (ASXOR, $1, $3); } | expr ASXOR expr { $$ = asx_expr (ASXOR, $1, $3); }
| expr ASMOD expr { $$ = asx_expr (ASMOD, $1, $3); } | expr ASMOD expr { $$ = asx_expr (ASMOD, $1, $3); }
| expr ASSHL expr { $$ = asx_expr (ASSHL, $1, $3); } | expr ASSHL expr { $$ = asx_expr (ASSHL, $1, $3); }
| expr ASSHR expr { $$ = asx_expr (ASSHR, $1, $3); } | expr ASSHR expr { $$ = asx_expr (ASSHR, $1, $3); }
| expr AND expr { $$ = binary_expr (AND, $1, $3); } | expr '?' expr ':' expr { $$ = conditional_expr ($1, $3, $5); }
| expr OR expr { $$ = binary_expr (OR, $1, $3); } | expr AND expr { $$ = binary_expr (AND, $1, $3); }
| expr EQ expr { $$ = binary_expr (EQ, $1, $3); } | expr OR expr { $$ = binary_expr (OR, $1, $3); }
| expr NE expr { $$ = binary_expr (NE, $1, $3); } | expr EQ expr { $$ = binary_expr (EQ, $1, $3); }
| expr LE expr { $$ = binary_expr (LE, $1, $3); } | expr NE expr { $$ = binary_expr (NE, $1, $3); }
| expr GE expr { $$ = binary_expr (GE, $1, $3); } | expr LE expr { $$ = binary_expr (LE, $1, $3); }
| expr LT expr { $$ = binary_expr (LT, $1, $3); } | expr GE expr { $$ = binary_expr (GE, $1, $3); }
| expr GT expr { $$ = binary_expr (GT, $1, $3); } | expr LT expr { $$ = binary_expr (LT, $1, $3); }
| expr SHL expr { $$ = binary_expr (SHL, $1, $3); } | expr GT expr { $$ = binary_expr (GT, $1, $3); }
| expr SHR expr { $$ = binary_expr (SHR, $1, $3); } | expr SHL expr { $$ = binary_expr (SHL, $1, $3); }
| expr '+' expr { $$ = binary_expr ('+', $1, $3); } | expr SHR expr { $$ = binary_expr (SHR, $1, $3); }
| expr '-' expr { $$ = binary_expr ('-', $1, $3); } | expr '+' expr { $$ = binary_expr ('+', $1, $3); }
| expr '*' expr { $$ = binary_expr ('*', $1, $3); } | expr '-' expr { $$ = binary_expr ('-', $1, $3); }
| expr '/' expr { $$ = binary_expr ('/', $1, $3); } | expr '*' expr { $$ = binary_expr ('*', $1, $3); }
| expr '&' expr { $$ = binary_expr ('&', $1, $3); } | expr '/' expr { $$ = binary_expr ('/', $1, $3); }
| expr '|' expr { $$ = binary_expr ('|', $1, $3); } | expr '&' expr { $$ = binary_expr ('&', $1, $3); }
| expr '^' expr { $$ = binary_expr ('^', $1, $3); } | expr '|' expr { $$ = binary_expr ('|', $1, $3); }
| expr '%' expr { $$ = binary_expr ('%', $1, $3); } | expr '^' expr { $$ = binary_expr ('^', $1, $3); }
| expr '(' arg_list ')' { $$ = function_expr ($1, $3); } | expr '%' expr { $$ = binary_expr ('%', $1, $3); }
| expr '(' ')' { $$ = function_expr ($1, 0); } | expr '(' arg_list ')' { $$ = function_expr ($1, $3); }
| expr '.' expr { $$ = binary_expr ('.', $1, $3); } | expr '(' ')' { $$ = function_expr ($1, 0); }
| '-' expr %prec '!' { $$ = unary_expr ('-', $2); } | expr '.' expr { $$ = binary_expr ('.', $1, $3); }
| '!' expr { $$ = unary_expr ('!', $2); } | '-' expr %prec '!' { $$ = unary_expr ('-', $2); }
| '~' expr { $$ = unary_expr ('~', $2); } | '!' expr { $$ = unary_expr ('!', $2); }
| '~' expr { $$ = unary_expr ('~', $2); }
| NAME | NAME
{ {
$$ = new_expr (); $$ = new_expr ();
@ -485,8 +487,8 @@ expr
$$->e.def = &def_float; $$->e.def = &def_float;
} }
} }
| const { $$ = $1; } | const { $$ = $1; }
| '(' expr ')' { $$ = $2; $$->paren = 1; } | '(' expr ')' { $$ = $2; $$->paren = 1; }
; ;
arg_list arg_list

View file

@ -53,6 +53,7 @@ float () main =
return foo;*/ return foo;*/
traceon (); traceon ();
boing (boing (1, 2), boing (3, 4)); boing (boing (1, 2), boing (3, 4));
boing (boing (0, 2), boing (3, -3));
return 0; return 0;
}; };
@ -94,7 +95,7 @@ void () blarg =
float (float a, float b) boing = float (float a, float b) boing =
{ {
return a + b; return a ? a + b : b;
}; };
float (float baz) test_int = float (float baz) test_int =