mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-31 05:00:35 +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_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);
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 =
|
||||||
|
|
Loading…
Reference in a new issue