mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-30 20:50:42 +00:00
temp def expressions and ?:
seems to work :)
This commit is contained in:
parent
3d30361595
commit
c2d3d8f3ab
6 changed files with 128 additions and 44 deletions
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -95,7 +95,7 @@ m ([\-+]?)
|
|||
s_file = ReuseString (pr_immediate_string);
|
||||
}
|
||||
|
||||
[!(){}.*/&|^~+\-=\[\];,#%] return yytext[0];
|
||||
[!(){}.*/&|^~+\-=\[\];,#%?:] return yytext[0];
|
||||
|
||||
"..." return ELIPSIS;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 =
|
||||
|
|
Loading…
Reference in a new issue