2 * Sparse - a semantic source parser.
4 * Copyright (C) 2003 Transmeta Corp.
6 * Licensed under the Open Software License version 1.1
16 #include "expression.h"
18 static struct expression
* dup_expression(struct expression
*expr
)
20 struct expression
*dup
= alloc_expression(expr
->pos
, expr
->type
);
25 static struct statement
* dup_statement(struct statement
*stmt
)
27 struct statement
*dup
= alloc_statement(stmt
->pos
, stmt
->type
);
32 static struct symbol
*copy_symbol(struct position pos
, struct symbol
*sym
)
36 if (sym
->ctype
.modifiers
& (MOD_STATIC
| MOD_EXTERN
| MOD_TOPLEVEL
| MOD_INLINE
))
39 warn(pos
, "unreplaced symbol '%s'", show_ident(sym
->ident
));
45 static struct symbol_list
*copy_symbol_list(struct symbol_list
*src
)
47 struct symbol_list
*dst
= NULL
;
50 FOR_EACH_PTR(src
, sym
) {
51 struct symbol
*newsym
= copy_symbol(sym
->pos
, sym
);
52 add_symbol(&dst
, newsym
);
57 static struct expression
* copy_expression(struct expression
*expr
)
64 * EXPR_SYMBOL is the interesting case, we may need to replace the
65 * symbol to the new copy.
68 struct symbol
*sym
= copy_symbol(expr
->pos
, expr
->symbol
);
69 if (sym
== expr
->symbol
)
71 expr
= dup_expression(expr
);
76 /* Atomics, never change, just return the expression directly */
81 /* Unops: check if the subexpression is unique */
84 struct expression
*unop
= copy_expression(expr
->unop
);
85 if (expr
->unop
== unop
)
87 expr
= dup_expression(expr
);
92 /* Binops: copy left/right expressions */
97 case EXPR_ASSIGNMENT
: {
98 struct expression
*left
= copy_expression(expr
->left
);
99 struct expression
*right
= copy_expression(expr
->right
);
100 if (left
== expr
->left
&& right
== expr
->right
)
102 expr
= dup_expression(expr
);
110 struct expression
*deref
= copy_expression(expr
->deref
);
111 if (deref
== expr
->deref
)
113 expr
= dup_expression(expr
);
121 struct expression
*cast
= copy_expression(expr
->cast_expression
);
122 if (cast
== expr
->cast_expression
)
124 expr
= dup_expression(expr
);
125 expr
->cast_expression
= cast
;
129 /* Conditional expression */
130 case EXPR_CONDITIONAL
: {
131 struct expression
*cond
= copy_expression(expr
->conditional
);
132 struct expression
*true = copy_expression(expr
->cond_true
);
133 struct expression
*false = copy_expression(expr
->cond_false
);
134 if (cond
== expr
->conditional
&& true == expr
->cond_true
&& false == expr
->cond_false
)
136 expr
= dup_expression(expr
);
137 expr
->conditional
= cond
;
138 expr
->cond_true
= true;
139 expr
->cond_false
= false;
143 /* Statement expression */
144 case EXPR_STATEMENT
: {
145 struct statement
*stmt
= alloc_statement(expr
->pos
, STMT_COMPOUND
);
146 copy_statement(expr
->statement
, stmt
);
147 expr
= dup_expression(expr
);
148 expr
->statement
= stmt
;
152 /* Call expression */
154 struct expression
*fn
= copy_expression(expr
->fn
);
155 struct expression_list
*list
= expr
->args
;
156 struct expression
*arg
;
158 expr
= dup_expression(expr
);
161 FOR_EACH_PTR(list
, arg
) {
162 add_expression(&expr
->args
, copy_expression(arg
));
167 /* Initializer list statement */
168 case EXPR_INITIALIZER
: {
169 struct expression_list
*list
= expr
->expr_list
;
170 struct expression
*entry
;
171 expr
= dup_expression(expr
);
172 expr
->expr_list
= NULL
;
173 FOR_EACH_PTR(list
, entry
) {
174 add_expression(&expr
->expr_list
, copy_expression(entry
));
181 warn(expr
->pos
, "trying to copy expression type %d", expr
->type
);
186 void set_replace(struct symbol
*old
, struct symbol
*new)
192 void unset_replace(struct symbol
*sym
)
194 struct symbol
*r
= sym
->replace
;
196 warn(sym
->pos
, "symbol '%s' not replaced?", show_ident(sym
->ident
));
203 static void unset_replace_list(struct symbol_list
*list
)
206 FOR_EACH_PTR(list
, sym
) {
211 static struct statement
*copy_one_statement(struct statement
*stmt
)
218 case STMT_EXPRESSION
: {
219 struct expression
*expr
= copy_expression(stmt
->expression
);
220 if (expr
== stmt
->expression
)
222 stmt
= dup_statement(stmt
);
223 stmt
->expression
= expr
;
226 case STMT_COMPOUND
: {
227 struct statement
*new = alloc_statement(stmt
->pos
, STMT_COMPOUND
);
228 copy_statement(stmt
, new);
233 struct expression
*cond
= stmt
->if_conditional
;
234 struct statement
*true = stmt
->if_true
;
235 struct statement
*false = stmt
->if_false
;
237 cond
= copy_expression(cond
);
238 true = copy_one_statement(true);
239 false = copy_one_statement(false);
240 if (stmt
->if_conditional
== cond
&&
241 stmt
->if_true
== true &&
242 stmt
->if_false
== false)
244 stmt
= dup_statement(stmt
);
245 stmt
->if_conditional
= cond
;
246 stmt
->if_true
= true;
247 stmt
->if_false
= false;
251 struct expression
*retval
= copy_expression(stmt
->ret_value
);
252 struct symbol
*sym
= copy_symbol(stmt
->pos
, stmt
->ret_target
);
254 stmt
= dup_statement(stmt
);
255 stmt
->ret_value
= retval
;
256 stmt
->ret_target
= sym
;
260 stmt
= dup_statement(stmt
);
261 stmt
->case_label
= copy_symbol(stmt
->pos
, stmt
->case_label
);
262 stmt
->case_expression
= copy_expression(stmt
->case_expression
);
263 stmt
->case_to
= copy_expression(stmt
->case_to
);
264 stmt
->case_statement
= copy_one_statement(stmt
->case_statement
);
268 struct symbol
*switch_break
= copy_symbol(stmt
->pos
, stmt
->switch_break
);
269 struct symbol
*switch_case
= copy_symbol(stmt
->pos
, stmt
->switch_case
);
270 struct expression
*expr
= copy_expression(stmt
->switch_expression
);
271 struct statement
*switch_stmt
= copy_one_statement(stmt
->switch_statement
);
272 stmt
= dup_statement(stmt
);
273 stmt
->switch_break
= switch_break
;
274 stmt
->switch_case
= switch_case
;
275 stmt
->switch_expression
= expr
;
276 stmt
->switch_statement
= switch_stmt
;
279 case STMT_ITERATOR
: {
280 stmt
= dup_statement(stmt
);
281 stmt
->iterator_break
= copy_symbol(stmt
->pos
, stmt
->iterator_break
);
282 stmt
->iterator_continue
= copy_symbol(stmt
->pos
, stmt
->iterator_continue
);
283 stmt
->iterator_syms
= copy_symbol_list(stmt
->iterator_syms
);
285 stmt
->iterator_pre_statement
= copy_one_statement(stmt
->iterator_pre_statement
);
286 stmt
->iterator_pre_condition
= copy_expression(stmt
->iterator_pre_condition
);
288 stmt
->iterator_statement
= copy_one_statement(stmt
->iterator_statement
);
290 stmt
->iterator_post_statement
= copy_one_statement(stmt
->iterator_post_statement
);
291 stmt
->iterator_post_condition
= copy_expression(stmt
->iterator_post_condition
);
295 stmt
= dup_statement(stmt
);
296 stmt
->label_identifier
= copy_symbol(stmt
->pos
, stmt
->label_identifier
);
297 stmt
->label_statement
= copy_one_statement(stmt
->label_statement
);
310 warn(stmt
->pos
, "trying to copy statement type %d", stmt
->type
);
317 * Copy a stateemnt tree from 'src' to 'dst', where both
318 * source and destination are of type STMT_COMPOUND.
320 * We do this for the tree-level inliner.
322 * This doesn't do the symbol replacement right: it's not
325 void copy_statement(struct statement
*src
, struct statement
*dst
)
327 struct statement
*stmt
;
330 FOR_EACH_PTR(src
->syms
, sym
) {
331 struct symbol
*newsym
= copy_symbol(src
->pos
, sym
);
332 newsym
->initializer
= copy_expression(sym
->initializer
);
333 add_symbol(&dst
->syms
, newsym
);
336 FOR_EACH_PTR(src
->stmts
, stmt
) {
337 add_statement(&dst
->stmts
, copy_one_statement(stmt
));
340 dst
->ret
= copy_symbol(src
->pos
, src
->ret
);
343 static struct symbol
*create_copy_symbol(struct symbol
*orig
)
345 struct symbol
*sym
= orig
;
347 sym
= alloc_symbol(orig
->pos
, orig
->type
);
348 sym
->ctype
= orig
->ctype
;
349 sym
->initializer
= NULL
;
350 set_replace(orig
, sym
);
355 static struct symbol_list
*create_symbol_list(struct symbol_list
*src
)
357 struct symbol_list
*dst
= NULL
;
360 FOR_EACH_PTR(src
, sym
) {
361 struct symbol
*newsym
= create_copy_symbol(sym
);
362 add_symbol(&dst
, newsym
);
367 int inline_function(struct expression
*expr
, struct symbol
*sym
)
369 struct symbol_list
* fn_symbol_list
;
370 struct symbol
*fn
= sym
->ctype
.base_type
;
371 struct expression_list
*arg_list
= expr
->args
;
372 struct statement
*stmt
= alloc_statement(expr
->pos
, STMT_COMPOUND
);
373 struct symbol_list
*name_list
;
375 struct expression
*arg
;
378 warn(fn
->pos
, "marked inline, but without a definition");
381 name_list
= fn
->arguments
;
383 stmt
= alloc_statement(expr
->pos
, STMT_COMPOUND
);
385 expr
->type
= EXPR_STATEMENT
;
386 expr
->statement
= stmt
;
387 expr
->ctype
= fn
->ctype
.base_type
;
389 fn_symbol_list
= create_symbol_list(sym
->symbol_list
);
391 PREPARE_PTR_LIST(name_list
, name
);
392 FOR_EACH_PTR(arg_list
, arg
) {
393 struct symbol
*a
= alloc_symbol(arg
->pos
, SYM_NODE
);
395 a
->ctype
.base_type
= arg
->ctype
;
397 a
->ident
= name
->ident
;
398 a
->ctype
= name
->ctype
;
399 set_replace(name
, a
);
400 add_symbol(&fn_symbol_list
, a
);
402 a
->initializer
= arg
;
403 add_symbol(&stmt
->syms
, a
);
407 FINISH_PTR_LIST(name
);
409 copy_statement(fn
->stmt
, stmt
);
411 unset_replace_list(fn_symbol_list
);
413 evaluate_statement(stmt
);