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_uexpr, // unary expression
ex_def,
ex_temp, // temporary variable
ex_string,
ex_float,
@ -25,8 +26,16 @@ typedef struct {
typedef struct {
struct expr_s *head;
struct expr_s **tail;
struct expr_s *result;
} block_t;
typedef struct {
struct expr_s *expr;
def_t *def;
type_t *type;
int users;
} temp_t;
typedef struct expr_s {
struct expr_s *next;
expr_type type;
@ -43,6 +52,7 @@ typedef struct expr_s {
struct expr_s *e2;
} expr;
def_t *def;
temp_t temp;
char *string_val;
float float_val;
@ -67,6 +77,7 @@ expr_t *new_label_expr (void);
expr_t *new_block_expr (void);
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_temp_def_expr (type_t *type);
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 *function_expr (expr_t *e1, expr_t *e2);
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);
void emit_expr (expr_t *e);

View file

@ -169,8 +169,14 @@ emit_sub_expr (expr_t *e, def_t *dest)
int priority;
switch (e->type) {
case ex_label:
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");
abort ();
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);
case ex_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_float:
case ex_vector:
@ -383,6 +393,7 @@ emit_expr (expr_t *e)
}
break;
case ex_def:
case ex_temp:
case ex_string:
case ex_float:
case ex_vector:

View file

@ -17,6 +17,7 @@ etype_t qc_types[] = {
ev_void, // ex_expr
ev_void, // ex_uexpr
ev_void, // ex_def
ev_void, // ex_temp
ev_string, // ex_string
ev_float, // ex_float
@ -73,13 +74,18 @@ get_type (expr_t *e)
{
switch (e->type) {
case ex_label:
case ex_block:
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_uexpr:
return e->e.expr.type->type;
case ex_def:
return e->e.def->type->type;
case ex_temp:
return e->e.temp.type->type;
case ex_integer:
if (options.version == PROG_ID_VERSION) {
e->type = ex_float;
@ -250,6 +256,16 @@ new_unary_expr (int op, expr_t *e1)
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 *
append_expr (expr_t *block, expr_t *e)
{
@ -278,6 +294,10 @@ print_expr (expr_t *e)
printf ("%s", e->e.label.name);
break;
case ex_block:
if (e->e.block.result) {
print_expr (e->e.block.result);
printf ("=");
}
printf ("{\n");
for (e = e->e.block.head; e; e = e->next) {
print_expr (e);
@ -309,6 +329,10 @@ print_expr (expr_t *e)
case ex_def:
printf ("%s", e->e.def->name);
break;
case ex_temp:
print_expr (e->e.temp.expr);
printf ("@");
break;
case ex_string:
printf ("\"%s\"", e->e.string_val);
break;
@ -820,14 +844,17 @@ unary_expr (int op, expr_t *e)
case '-':
switch (e->type) {
case ex_label:
case ex_block:
error (e, "internal error");
abort ();
case ex_uexpr:
if (e->e.expr.op == '-')
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_def:
case ex_temp:
{
expr_t *n = new_unary_expr (op, e);
n->e.expr.type = (e->type == ex_def)
@ -863,11 +890,14 @@ unary_expr (int op, expr_t *e)
case '!':
switch (e->type) {
case ex_label:
case ex_block:
abort ();
case ex_block:
if (!e->e.block.result)
return error (e, "invalid type for unary -");
case ex_uexpr:
case ex_expr:
case ex_def:
case ex_temp:
{
expr_t *n = new_unary_expr (op, e);
if (options.version > PROG_ID_VERSION)
@ -911,13 +941,16 @@ unary_expr (int op, expr_t *e)
case '~':
switch (e->type) {
case ex_label:
case ex_block:
abort ();
case ex_uexpr:
if (e->e.expr.op == '~')
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_def:
case ex_temp:
{
expr_t *n = new_unary_expr (op, e);
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);
}
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);
}
[!(){}.*/&|^~+\-=\[\];,#%] return yytext[0];
[!(){}.*/&|^~+\-=\[\];,#%?:] return yytext[0];
"..." return ELIPSIS;

View file

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

View file

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