mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 23:32:09 +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 = binary_expr (NE, e, new);
|
||||||
new->line = e->line;
|
new->line = e->line;
|
||||||
new->file = e->file;
|
new->file = e->file;
|
||||||
return fold_constants (new);
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -2130,10 +2130,10 @@ array_expr (expr_t *array, expr_t *index)
|
||||||
|| ind - array_type->t.array.base >= array_type->t.array.size))
|
|| ind - array_type->t.array.base >= array_type->t.array.size))
|
||||||
return error (index, "array index out of bounds");
|
return error (index, "array index out of bounds");
|
||||||
scale = new_integer_expr (type_size (array_type->t.array.type));
|
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);
|
base = new_integer_expr (array_type->t.array.base);
|
||||||
offset = fold_constants (binary_expr ('*', base, scale));
|
offset = binary_expr ('*', base, scale);
|
||||||
index = fold_constants (binary_expr ('-', index, offset));
|
index = binary_expr ('-', index, offset);
|
||||||
if (is_short_val (index))
|
if (is_short_val (index))
|
||||||
ind = expr_short (index);
|
ind = expr_short (index);
|
||||||
if (is_integer_val (index))
|
if (is_integer_val (index))
|
||||||
|
|
|
@ -42,8 +42,11 @@ typedef struct {
|
||||||
type_t *type;
|
type_t *type;
|
||||||
type_t *a_cast;
|
type_t *a_cast;
|
||||||
type_t *b_cast;
|
type_t *b_cast;
|
||||||
|
expr_t *(*process)(int op, expr_t *e1, expr_t *e2);
|
||||||
} expr_type_t;
|
} expr_type_t;
|
||||||
|
|
||||||
|
static expr_t *pointer_arithmetic (int op, expr_t *e1, expr_t *e2);
|
||||||
|
|
||||||
static expr_type_t string_string[] = {
|
static expr_type_t string_string[] = {
|
||||||
{'+', &type_string},
|
{'+', &type_string},
|
||||||
{EQ, &type_integer},
|
{EQ, &type_integer},
|
||||||
|
@ -157,8 +160,8 @@ static expr_type_t pointer_pointer[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static expr_type_t pointer_integer[] = {
|
static expr_type_t pointer_integer[] = {
|
||||||
{'+', &type_pointer},
|
{'+', 0, 0, 0, pointer_arithmetic},
|
||||||
{'-', &type_pointer},
|
{'-', 0, 0, 0, pointer_arithmetic},
|
||||||
{0, 0}
|
{0, 0}
|
||||||
};
|
};
|
||||||
#define pointer_uinteger pointer_integer
|
#define pointer_uinteger pointer_integer
|
||||||
|
@ -218,7 +221,7 @@ static expr_type_t integer_vector[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static expr_type_t integer_pointer[] = {
|
static expr_type_t integer_pointer[] = {
|
||||||
{'+', &type_pointer},
|
{'+', &type_pointer, 0, &type_integer},
|
||||||
{0, 0}
|
{0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -579,6 +582,25 @@ static expr_type_t **binary_expr_types[] = {
|
||||||
short_x,
|
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 *
|
static expr_t *
|
||||||
invalid_binary_expr (int op, expr_t *e1, expr_t *e2)
|
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);
|
e1 = cast_expr (expr_type->a_cast, e1);
|
||||||
if (expr_type->b_cast)
|
if (expr_type->b_cast)
|
||||||
e2 = cast_expr (expr_type->b_cast, e2);
|
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)))
|
if ((e = reimplement_binary_expr (op, e1, e2)))
|
||||||
return e;
|
return fold_constants (e);
|
||||||
|
|
||||||
e = new_binary_expr (op, e1, e2);
|
e = new_binary_expr (op, e1, e2);
|
||||||
e->e.expr.type = expr_type->type;
|
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)
|
if (options.code.progsversion == PROG_ID_VERSION)
|
||||||
e->e.expr.type = &type_float;
|
e->e.expr.type = &type_float;
|
||||||
}
|
}
|
||||||
return e;
|
return fold_constants (e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -180,7 +180,7 @@ int yylex (void);
|
||||||
%type <symbol> methoddef
|
%type <symbol> methoddef
|
||||||
%type <expr> opt_initializer var_initializer local_def
|
%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> optional_state_expr texpr vector_expr
|
||||||
%type <expr> statement statements compound_statement
|
%type <expr> statement statements compound_statement
|
||||||
%type <expr> else label break_label continue_label
|
%type <expr> else label break_label continue_label
|
||||||
|
@ -577,7 +577,7 @@ enumerator_list
|
||||||
|
|
||||||
enumerator
|
enumerator
|
||||||
: identifier { add_enum ($<symbol>0, $1, 0); }
|
: 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
|
struct_specifier
|
||||||
|
@ -846,9 +846,8 @@ abs_decl
|
||||||
;
|
;
|
||||||
|
|
||||||
array_decl
|
array_decl
|
||||||
: '[' fexpr ']'
|
: '[' expr ']'
|
||||||
{
|
{
|
||||||
$2 = fold_constants ($2);
|
|
||||||
if (!is_integer_val ($2) || expr_integer ($2) < 1) {
|
if (!is_integer_val ($2) || expr_integer ($2) < 1) {
|
||||||
error (0, "invalid array size");
|
error (0, "invalid array size");
|
||||||
$$ = 0;
|
$$ = 0;
|
||||||
|
@ -971,11 +970,11 @@ overloaded_identifier
|
||||||
;
|
;
|
||||||
|
|
||||||
non_code_func
|
non_code_func
|
||||||
: '=' '#' fexpr
|
: '=' '#' expr
|
||||||
{
|
{
|
||||||
build_builtin_function ($<symbol>0, $3, 0);
|
build_builtin_function ($<symbol>0, $3, 0);
|
||||||
}
|
}
|
||||||
| '=' fexpr
|
| '=' expr
|
||||||
{
|
{
|
||||||
symbol_t *sym = $<symbol>0;
|
symbol_t *sym = $<symbol>0;
|
||||||
specifier_t spec = $<spec>-1;
|
specifier_t spec = $<spec>-1;
|
||||||
|
@ -1023,7 +1022,7 @@ opt_initializer
|
||||||
;
|
;
|
||||||
|
|
||||||
var_initializer
|
var_initializer
|
||||||
: '=' fexpr { $$ = $2; }
|
: '=' expr { $$ = $2; }
|
||||||
| '=' '{' element_list optional_comma '}' { $$ = $3; }
|
| '=' '{' element_list optional_comma '}' { $$ = $3; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -1046,7 +1045,7 @@ element_list
|
||||||
|
|
||||||
element
|
element
|
||||||
: '{' element_list optional_comma '}' { $$ = $2; }
|
: '{' element_list optional_comma '}' { $$ = $2; }
|
||||||
| fexpr { $$ = $1; }
|
| expr { $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
optional_comma
|
optional_comma
|
||||||
|
@ -1128,7 +1127,7 @@ statement
|
||||||
else
|
else
|
||||||
error (0, "continue outside of loop");
|
error (0, "continue outside of loop");
|
||||||
}
|
}
|
||||||
| CASE fexpr ':'
|
| CASE expr ':'
|
||||||
{
|
{
|
||||||
$$ = case_label_expr (switch_block, $2);
|
$$ = case_label_expr (switch_block, $2);
|
||||||
}
|
}
|
||||||
|
@ -1136,7 +1135,7 @@ statement
|
||||||
{
|
{
|
||||||
$$ = case_label_expr (switch_block, 0);
|
$$ = 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_expr (switch_block, break_label, $7);
|
||||||
switch_block = $5;
|
switch_block = $5;
|
||||||
|
@ -1295,7 +1294,7 @@ unary_expr
|
||||||
;
|
;
|
||||||
|
|
||||||
vector_expr
|
vector_expr
|
||||||
: '[' fexpr ',' arg_list ']'
|
: '[' expr ',' arg_list ']'
|
||||||
{
|
{
|
||||||
expr_t *t = $4;
|
expr_t *t = $4;
|
||||||
while (t->next)
|
while (t->next)
|
||||||
|
@ -1338,12 +1337,8 @@ expr
|
||||||
| expr '%' expr { $$ = binary_expr ('%', $1, $3); }
|
| expr '%' expr { $$ = binary_expr ('%', $1, $3); }
|
||||||
;
|
;
|
||||||
|
|
||||||
fexpr
|
|
||||||
: expr { $$ = fold_constants ($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
texpr
|
texpr
|
||||||
: fexpr { $$ = convert_bool ($1, 1); }
|
: expr { $$ = convert_bool ($1, 1); }
|
||||||
;
|
;
|
||||||
|
|
||||||
cexpr
|
cexpr
|
||||||
|
@ -1364,8 +1359,8 @@ opt_arg_list
|
||||||
;
|
;
|
||||||
|
|
||||||
arg_list
|
arg_list
|
||||||
: fexpr
|
: expr
|
||||||
| arg_list ',' fexpr
|
| arg_list ',' expr
|
||||||
{
|
{
|
||||||
$3->next = $1;
|
$3->next = $1;
|
||||||
$$ = $3;
|
$$ = $3;
|
||||||
|
@ -1874,7 +1869,7 @@ obj_messageexpr
|
||||||
;
|
;
|
||||||
|
|
||||||
receiver
|
receiver
|
||||||
: fexpr
|
: expr
|
||||||
| CLASS_NAME
|
| CLASS_NAME
|
||||||
{
|
{
|
||||||
$$ = new_symbol_expr ($1);
|
$$ = 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;
|
int i;
|
||||||
expr_t *range = binary_expr ('-', tree->high, tree->low);
|
expr_t *range = binary_expr ('-', tree->high, tree->low);
|
||||||
|
|
||||||
range = fold_constants (range);
|
|
||||||
|
|
||||||
table_init = new_block_expr ();
|
table_init = new_block_expr ();
|
||||||
for (i = 0; i <= high - low; i++) {
|
for (i = 0; i <= high - low; i++) {
|
||||||
tree->labels[i]->e.label.used++;
|
tree->labels[i]->e.label.used++;
|
||||||
|
|
Loading…
Reference in a new issue