mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-23 04:42:32 +00:00
Make binary_expr fold constants
This is where constant folding should have happened all along. While unary_expr should fold constants too, it seems to already try to do so and it's a bit much of a mess to clean up right now.
This commit is contained in:
parent
bf0543f7fb
commit
ef4ad52239
4 changed files with 48 additions and 30 deletions
|
@ -1280,7 +1280,7 @@ test_expr (expr_t *e)
|
|||
new = binary_expr (NE, e, new);
|
||||
new->line = e->line;
|
||||
new->file = e->file;
|
||||
return fold_constants (new);
|
||||
return new;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2130,10 +2130,10 @@ array_expr (expr_t *array, expr_t *index)
|
|||
|| ind - array_type->t.array.base >= array_type->t.array.size))
|
||||
return error (index, "array index out of bounds");
|
||||
scale = new_integer_expr (type_size (array_type->t.array.type));
|
||||
index = fold_constants (binary_expr ('*', index, scale));
|
||||
index = binary_expr ('*', index, scale);
|
||||
base = new_integer_expr (array_type->t.array.base);
|
||||
offset = fold_constants (binary_expr ('*', base, scale));
|
||||
index = fold_constants (binary_expr ('-', index, offset));
|
||||
offset = binary_expr ('*', base, scale);
|
||||
index = binary_expr ('-', index, offset);
|
||||
if (is_short_val (index))
|
||||
ind = expr_short (index);
|
||||
if (is_integer_val (index))
|
||||
|
|
|
@ -42,8 +42,11 @@ typedef struct {
|
|||
type_t *type;
|
||||
type_t *a_cast;
|
||||
type_t *b_cast;
|
||||
expr_t *(*process)(int op, expr_t *e1, expr_t *e2);
|
||||
} expr_type_t;
|
||||
|
||||
static expr_t *pointer_arithmetic (int op, expr_t *e1, expr_t *e2);
|
||||
|
||||
static expr_type_t string_string[] = {
|
||||
{'+', &type_string},
|
||||
{EQ, &type_integer},
|
||||
|
@ -157,8 +160,8 @@ static expr_type_t pointer_pointer[] = {
|
|||
};
|
||||
|
||||
static expr_type_t pointer_integer[] = {
|
||||
{'+', &type_pointer},
|
||||
{'-', &type_pointer},
|
||||
{'+', 0, 0, 0, pointer_arithmetic},
|
||||
{'-', 0, 0, 0, pointer_arithmetic},
|
||||
{0, 0}
|
||||
};
|
||||
#define pointer_uinteger pointer_integer
|
||||
|
@ -218,7 +221,7 @@ static expr_type_t integer_vector[] = {
|
|||
};
|
||||
|
||||
static expr_type_t integer_pointer[] = {
|
||||
{'+', &type_pointer},
|
||||
{'+', &type_pointer, 0, &type_integer},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
|
@ -579,6 +582,25 @@ static expr_type_t **binary_expr_types[] = {
|
|||
short_x,
|
||||
};
|
||||
|
||||
static expr_t *
|
||||
pointer_arithmetic (int op, expr_t *e1, expr_t *e2)
|
||||
{
|
||||
expr_t *e;
|
||||
type_t *ptype = get_type (e1);
|
||||
|
||||
if (!is_pointer (ptype)) {
|
||||
ptype = get_type (e2);
|
||||
}
|
||||
if (!is_pointer (ptype)) {
|
||||
internal_error (e1, "pointer arithmetic on non-pointers");
|
||||
}
|
||||
|
||||
e1 = cast_expr (&type_integer, e1);
|
||||
e2 = cast_expr (&type_integer, e2);
|
||||
e = binary_expr (op, e1, e2);
|
||||
return cast_expr (ptype, e);
|
||||
}
|
||||
|
||||
static expr_t *
|
||||
invalid_binary_expr (int op, expr_t *e1, expr_t *e2)
|
||||
{
|
||||
|
@ -780,9 +802,12 @@ binary_expr (int op, expr_t *e1, expr_t *e2)
|
|||
e1 = cast_expr (expr_type->a_cast, e1);
|
||||
if (expr_type->b_cast)
|
||||
e2 = cast_expr (expr_type->b_cast, e2);
|
||||
if (expr_type->process) {
|
||||
return fold_constants (expr_type->process (op, e1, e2));
|
||||
}
|
||||
|
||||
if ((e = reimplement_binary_expr (op, e1, e2)))
|
||||
return e;
|
||||
return fold_constants (e);
|
||||
|
||||
e = new_binary_expr (op, e1, e2);
|
||||
e->e.expr.type = expr_type->type;
|
||||
|
@ -790,5 +815,5 @@ binary_expr (int op, expr_t *e1, expr_t *e2)
|
|||
if (options.code.progsversion == PROG_ID_VERSION)
|
||||
e->e.expr.type = &type_float;
|
||||
}
|
||||
return e;
|
||||
return fold_constants (e);
|
||||
}
|
||||
|
|
|
@ -180,7 +180,7 @@ int yylex (void);
|
|||
%type <symbol> methoddef
|
||||
%type <expr> opt_initializer var_initializer local_def
|
||||
|
||||
%type <expr> opt_init opt_expr cexpr fexpr expr element_list element
|
||||
%type <expr> opt_init opt_expr cexpr expr element_list element
|
||||
%type <expr> optional_state_expr texpr vector_expr
|
||||
%type <expr> statement statements compound_statement
|
||||
%type <expr> else label break_label continue_label
|
||||
|
@ -577,7 +577,7 @@ enumerator_list
|
|||
|
||||
enumerator
|
||||
: identifier { add_enum ($<symbol>0, $1, 0); }
|
||||
| identifier '=' fexpr { add_enum ($<symbol>0, $1, $3); }
|
||||
| identifier '=' expr { add_enum ($<symbol>0, $1, $3); }
|
||||
;
|
||||
|
||||
struct_specifier
|
||||
|
@ -846,9 +846,8 @@ abs_decl
|
|||
;
|
||||
|
||||
array_decl
|
||||
: '[' fexpr ']'
|
||||
: '[' expr ']'
|
||||
{
|
||||
$2 = fold_constants ($2);
|
||||
if (!is_integer_val ($2) || expr_integer ($2) < 1) {
|
||||
error (0, "invalid array size");
|
||||
$$ = 0;
|
||||
|
@ -971,11 +970,11 @@ overloaded_identifier
|
|||
;
|
||||
|
||||
non_code_func
|
||||
: '=' '#' fexpr
|
||||
: '=' '#' expr
|
||||
{
|
||||
build_builtin_function ($<symbol>0, $3, 0);
|
||||
}
|
||||
| '=' fexpr
|
||||
| '=' expr
|
||||
{
|
||||
symbol_t *sym = $<symbol>0;
|
||||
specifier_t spec = $<spec>-1;
|
||||
|
@ -1023,7 +1022,7 @@ opt_initializer
|
|||
;
|
||||
|
||||
var_initializer
|
||||
: '=' fexpr { $$ = $2; }
|
||||
: '=' expr { $$ = $2; }
|
||||
| '=' '{' element_list optional_comma '}' { $$ = $3; }
|
||||
;
|
||||
|
||||
|
@ -1046,7 +1045,7 @@ element_list
|
|||
|
||||
element
|
||||
: '{' element_list optional_comma '}' { $$ = $2; }
|
||||
| fexpr { $$ = $1; }
|
||||
| expr { $$ = $1; }
|
||||
;
|
||||
|
||||
optional_comma
|
||||
|
@ -1128,7 +1127,7 @@ statement
|
|||
else
|
||||
error (0, "continue outside of loop");
|
||||
}
|
||||
| CASE fexpr ':'
|
||||
| CASE expr ':'
|
||||
{
|
||||
$$ = case_label_expr (switch_block, $2);
|
||||
}
|
||||
|
@ -1136,7 +1135,7 @@ statement
|
|||
{
|
||||
$$ = case_label_expr (switch_block, 0);
|
||||
}
|
||||
| SWITCH break_label '(' fexpr switch_block ')' compound_statement
|
||||
| SWITCH break_label '(' expr switch_block ')' compound_statement
|
||||
{
|
||||
$$ = switch_expr (switch_block, break_label, $7);
|
||||
switch_block = $5;
|
||||
|
@ -1295,7 +1294,7 @@ unary_expr
|
|||
;
|
||||
|
||||
vector_expr
|
||||
: '[' fexpr ',' arg_list ']'
|
||||
: '[' expr ',' arg_list ']'
|
||||
{
|
||||
expr_t *t = $4;
|
||||
while (t->next)
|
||||
|
@ -1338,12 +1337,8 @@ expr
|
|||
| expr '%' expr { $$ = binary_expr ('%', $1, $3); }
|
||||
;
|
||||
|
||||
fexpr
|
||||
: expr { $$ = fold_constants ($1); }
|
||||
;
|
||||
|
||||
texpr
|
||||
: fexpr { $$ = convert_bool ($1, 1); }
|
||||
: expr { $$ = convert_bool ($1, 1); }
|
||||
;
|
||||
|
||||
cexpr
|
||||
|
@ -1364,8 +1359,8 @@ opt_arg_list
|
|||
;
|
||||
|
||||
arg_list
|
||||
: fexpr
|
||||
| arg_list ',' fexpr
|
||||
: expr
|
||||
| arg_list ',' expr
|
||||
{
|
||||
$3->next = $1;
|
||||
$$ = $3;
|
||||
|
@ -1874,7 +1869,7 @@ obj_messageexpr
|
|||
;
|
||||
|
||||
receiver
|
||||
: fexpr
|
||||
: expr
|
||||
| CLASS_NAME
|
||||
{
|
||||
$$ = new_symbol_expr ($1);
|
||||
|
|
|
@ -338,8 +338,6 @@ build_switch (expr_t *sw, case_node_t *tree, int op, expr_t *sw_val,
|
|||
int i;
|
||||
expr_t *range = binary_expr ('-', tree->high, tree->low);
|
||||
|
||||
range = fold_constants (range);
|
||||
|
||||
table_init = new_block_expr ();
|
||||
for (i = 0; i <= high - low; i++) {
|
||||
tree->labels[i]->e.label.used++;
|
||||
|
|
Loading…
Reference in a new issue