}
}
-static void print_compound_statement(const compound_statement_t *block)
+static void print_compound_statement(const statement_t *block)
{
fputs("{\n", out);
indent++;
- statement_t *statement = block->statements;
+ statement_t *statement = block->v.compound_stmt.statements;
while(statement != NULL) {
print_indent();
print_statement(statement);
fputs("}\n", out);
}
-static void print_return_statement(const return_statement_t *statement)
+static void print_return_statement(const statement_t *statement)
{
fprintf(out, "return ");
- if(statement->return_value != NULL)
- print_expression(statement->return_value);
+ if(statement->v.return_value != NULL)
+ print_expression(statement->v.return_value);
fputs(";\n", out);
}
-static void print_expression_statement(const expression_statement_t *statement)
+static void print_expression_statement(const statement_t *statement)
{
- print_expression(statement->expression);
+ print_expression(statement->v.expression);
fputs(";\n", out);
}
-static void print_goto_statement(const goto_statement_t *statement)
+static void print_goto_statement(const statement_t *statement)
{
fprintf(out, "goto ");
- fputs(statement->label->symbol->string, out);
- fprintf(stderr, "(%p)", (void*) statement->label);
+ fputs(statement->v.goto_label->symbol->string, out);
+ fprintf(stderr, "(%p)", (void*) statement->v.goto_label);
fputs(";\n", out);
}
-static void print_label_statement(const label_statement_t *statement)
+static void print_label_statement(const statement_t *statement)
{
- fprintf(stderr, "(%p)", (void*) statement->label);
- fprintf(out, "%s:\n", statement->label->symbol->string);
- if(statement->label_statement != NULL) {
- print_statement(statement->label_statement);
+ fprintf(stderr, "(%p)", (void*) statement->v.label_stmt.label);
+ fprintf(out, "%s:\n", statement->v.label_stmt.label->symbol->string);
+ if(statement->v.label_stmt.label_statement != NULL) {
+ print_statement(statement->v.label_stmt.label_statement);
}
}
-static void print_if_statement(const if_statement_t *statement)
+static void print_if_statement(const statement_t *statement)
{
fputs("if(", out);
- print_expression(statement->condition);
+ print_expression(statement->v.if_stmt.condition);
fputs(") ", out);
- if(statement->true_statement != NULL) {
- print_statement(statement->true_statement);
+ if(statement->v.if_stmt.true_statement != NULL) {
+ print_statement(statement->v.if_stmt.true_statement);
}
- if(statement->false_statement != NULL) {
+ if(statement->v.if_stmt.false_statement != NULL) {
print_indent();
fputs("else ", out);
- print_statement(statement->false_statement);
+ print_statement(statement->v.if_stmt.false_statement);
}
}
-static void print_switch_statement(const switch_statement_t *statement)
+static void print_switch_statement(const statement_t *statement)
{
fputs("switch(", out);
- print_expression(statement->expression);
+ print_expression(statement->v.switch_stmt.expression);
fputs(") ", out);
- print_statement(statement->body);
+ print_statement(statement->v.switch_stmt.body);
}
-static void print_case_label(const case_label_statement_t *statement)
+static void print_case_label(const statement_t *statement)
{
- if(statement->expression == NULL) {
+ if(statement->v.case_label_stmt.expression == NULL) {
fputs("default:\n", out);
} else {
fputs("case ", out);
- print_expression(statement->expression);
+ print_expression(statement->v.case_label_stmt.expression);
fputs(":\n", out);
}
- print_statement(statement->label_statement);
+ print_statement(statement->v.case_label_stmt.label_statement);
}
-static void print_declaration_statement(
- const declaration_statement_t *statement)
+static void print_declaration_statement(const statement_t *statement)
{
int first = 1;
- declaration_t *declaration = statement->declarations_begin;
- for( ; declaration != statement->declarations_end->next;
+ declaration_t *declaration = statement->v.declaration_stmt.begin;
+ for( ; declaration != statement->v.declaration_stmt.end->next;
declaration = declaration->next) {
if(!first) {
print_indent();
}
}
-static void print_while_statement(const while_statement_t *statement)
+static void print_while_statement(const statement_t *statement)
{
fputs("while(", out);
- print_expression(statement->condition);
+ print_expression(statement->v.while_stmt.condition);
fputs(") ", out);
- print_statement(statement->body);
+ print_statement(statement->v.while_stmt.body);
}
-static void print_do_while_statement(const do_while_statement_t *statement)
+static void print_do_while_statement(const statement_t *statement)
{
fputs("do ", out);
- print_statement(statement->body);
+ print_statement(statement->v.while_stmt.body);
print_indent();
fputs("while(", out);
- print_expression(statement->condition);
+ print_expression(statement->v.while_stmt.condition);
fputs(");\n", out);
}
-static void print_for_statement(const for_statement_t *statement)
+static void print_for_statement(const statement_t *statement)
{
fputs("for(", out);
- if(statement->context.declarations != NULL) {
- assert(statement->initialisation == NULL);
- print_declaration(statement->context.declarations);
- if(statement->context.declarations->next != NULL) {
+ if(statement->v.for_stmt.context.declarations != NULL) {
+ assert(statement->v.for_stmt.initialisation == NULL);
+ print_declaration(statement->v.for_stmt.context.declarations);
+ if(statement->v.for_stmt.context.declarations->next != NULL) {
panic("multiple declarations in for statement not supported yet");
}
fputc(' ', out);
} else {
- if(statement->initialisation) {
- print_expression(statement->initialisation);
+ if(statement->v.for_stmt.initialisation) {
+ print_expression(statement->v.for_stmt.initialisation);
}
fputs("; ", out);
}
- if(statement->condition != NULL) {
- print_expression(statement->condition);
+ if(statement->v.for_stmt.condition != NULL) {
+ print_expression(statement->v.for_stmt.condition);
}
fputs("; ", out);
- if(statement->step != NULL) {
- print_expression(statement->step);
+ if(statement->v.for_stmt.step != NULL) {
+ print_expression(statement->v.for_stmt.step);
}
fputs(")", out);
- print_statement(statement->body);
+ print_statement(statement->v.for_stmt.body);
}
void print_statement(const statement_t *statement)
{
switch(statement->type) {
case STATEMENT_COMPOUND:
- print_compound_statement((const compound_statement_t*) statement);
+ print_compound_statement(statement);
break;
case STATEMENT_RETURN:
- print_return_statement((const return_statement_t*) statement);
+ print_return_statement(statement);
break;
case STATEMENT_EXPRESSION:
- print_expression_statement((const expression_statement_t*) statement);
+ print_expression_statement(statement);
break;
case STATEMENT_LABEL:
- print_label_statement((const label_statement_t*) statement);
+ print_label_statement(statement);
break;
case STATEMENT_GOTO:
- print_goto_statement((const goto_statement_t*) statement);
+ print_goto_statement(statement);
break;
case STATEMENT_CONTINUE:
fputs("continue;\n", out);
fputs("break;\n", out);
break;
case STATEMENT_IF:
- print_if_statement((const if_statement_t*) statement);
+ print_if_statement(statement);
break;
case STATEMENT_SWITCH:
- print_switch_statement((const switch_statement_t*) statement);
+ print_switch_statement(statement);
break;
case STATEMENT_CASE_LABEL:
- print_case_label((const case_label_statement_t*) statement);
+ print_case_label(statement);
break;
case STATEMENT_DECLARATION:
- print_declaration_statement((const declaration_statement_t*) statement);
+ print_declaration_statement(statement);
break;
case STATEMENT_WHILE:
- print_while_statement((const while_statement_t*) statement);
+ print_while_statement(statement);
break;
case STATEMENT_DO_WHILE:
- print_do_while_statement((const do_while_statement_t*) statement);
+ print_do_while_statement(statement);
break;
case STATEMENT_FOR:
- print_for_statement((const for_statement_t*) statement);
+ print_for_statement(statement);
break;
case STATEMENT_INVALID:
fprintf(out, "*invalid statement*");
typedef struct declaration_t declaration_t;
typedef struct statement_t statement_t;
-typedef struct compound_statement_t compound_statement_t;
-typedef struct return_statement_t return_statement_t;
-typedef struct if_statement_t if_statement_t;
-typedef struct switch_statement_t switch_statement_t;
-typedef struct declaration_statement_t declaration_statement_t;
-typedef struct expression_statement_t expression_statement_t;
-typedef struct goto_statement_t goto_statement_t;
-typedef struct label_statement_t label_statement_t;
-typedef struct case_label_statement_t case_label_statement_t;
-typedef struct while_statement_t while_statement_t;
-typedef struct do_while_statement_t do_while_statement_t;
-typedef struct for_statement_t for_statement_t;
typedef struct translation_unit_t translation_unit_t;
}
static void statement_to_firm(statement_t *statement);
-static ir_node *compound_statement_to_firm(compound_statement_t *compound);
+static ir_node *compound_statement_to_firm(statement_t *compound);
static ir_node *expression_to_addr(const expression_t *expression);
static void create_condition_evaluation(const expression_t *expression,
statement_t *statement = expr->statement;
assert(statement->type == STATEMENT_COMPOUND);
- return compound_statement_to_firm((compound_statement_t*) statement);
+ return compound_statement_to_firm(statement);
}
static ir_node *dereference_addr(const unary_expression_t *const expression)
}
-static void return_statement_to_firm(return_statement_t *statement)
+static void return_statement_to_firm(statement_t *statement)
{
if(get_cur_block() == NULL)
return;
- dbg_info *dbgi = get_dbg_info(&statement->statement.source_position);
+ dbg_info *dbgi = get_dbg_info(&statement->source_position);
ir_node *ret;
- if(statement->return_value != NULL) {
- ir_node *retval = expression_to_firm(statement->return_value);
+ if(statement->v.return_value != NULL) {
+ ir_node *retval = expression_to_firm(statement->v.return_value);
ir_node *in[1];
in[0] = retval;
set_cur_block(NULL);
}
-static ir_node *expression_statement_to_firm(expression_statement_t *statement)
+static ir_node *expression_statement_to_firm(statement_t *statement)
{
if(get_cur_block() == NULL)
return NULL;
- return expression_to_firm(statement->expression);
+ return expression_to_firm(statement->v.expression);
}
-static ir_node *compound_statement_to_firm(compound_statement_t *compound)
+static ir_node *compound_statement_to_firm(statement_t *compound)
{
ir_node *result = NULL;
- statement_t *statement = compound->statements;
+ statement_t *statement = compound->v.compound_stmt.statements;
for( ; statement != NULL; statement = statement->next) {
//context2firm(&statement->context);
if(statement->next == NULL && statement->type == STATEMENT_EXPRESSION) {
- result = expression_statement_to_firm(
- (expression_statement_t*) statement);
+ result = expression_statement_to_firm(statement);
break;
}
statement_to_firm(statement);
return result;
}
-static void if_statement_to_firm(if_statement_t *statement)
+static void if_statement_to_firm(statement_t *statement)
{
ir_node *cur_block = get_cur_block();
/* the true (blocks) */
ir_node *true_block;
- if (statement->true_statement != NULL) {
+ if (statement->v.if_stmt.true_statement != NULL) {
true_block = new_immBlock();
- statement_to_firm(statement->true_statement);
+ statement_to_firm(statement->v.if_stmt.true_statement);
if(get_cur_block() != NULL) {
ir_node *jmp = new_Jmp();
add_immBlock_pred(fallthrough_block, jmp);
/* the false (blocks) */
ir_node *false_block;
- if(statement->false_statement != NULL) {
+ if(statement->v.if_stmt.false_statement != NULL) {
false_block = new_immBlock();
- statement_to_firm(statement->false_statement);
+ statement_to_firm(statement->v.if_stmt.false_statement);
if(get_cur_block() != NULL) {
ir_node *jmp = new_Jmp();
add_immBlock_pred(fallthrough_block, jmp);
/* create the condition */
if(cur_block != NULL) {
set_cur_block(cur_block);
- create_condition_evaluation(statement->condition, true_block,
+ create_condition_evaluation(statement->v.if_stmt.condition, true_block,
false_block);
}
set_cur_block(fallthrough_block);
}
-static void while_statement_to_firm(while_statement_t *statement)
+static void while_statement_to_firm(statement_t *statement)
{
ir_node *jmp = NULL;
if(get_cur_block() != NULL) {
/* the loop body */
ir_node *body_block;
- if (statement->body != NULL) {
+ if (statement->v.while_stmt.body != NULL) {
ir_node *old_continue_label = continue_label;
ir_node *old_break_label = break_label;
continue_label = header_block;
break_label = false_block;
body_block = new_immBlock();
- statement_to_firm(statement->body);
+ statement_to_firm(statement->v.while_stmt.body);
assert(continue_label == header_block);
assert(break_label == false_block);
/* create the condition */
set_cur_block(header_block);
- create_condition_evaluation(statement->condition, body_block, false_block);
+ create_condition_evaluation(statement->v.while_stmt.condition, body_block, false_block);
mature_immBlock(body_block);
mature_immBlock(false_block);
mature_immBlock(header_block);
set_cur_block(false_block);
}
-static void do_while_statement_to_firm(do_while_statement_t *statement)
+static void do_while_statement_to_firm(statement_t *statement)
{
ir_node *jmp = NULL;
if(get_cur_block() != NULL) {
add_immBlock_pred(body_block, jmp);
}
- if (statement->body != NULL) {
+ if (statement->v.while_stmt.body != NULL) {
ir_node *old_continue_label = continue_label;
ir_node *old_break_label = break_label;
continue_label = header_block;
break_label = false_block;
- statement_to_firm(statement->body);
+ statement_to_firm(statement->v.while_stmt.body);
assert(continue_label == header_block);
assert(break_label == false_block);
/* create the condition */
set_cur_block(header_block);
- create_condition_evaluation(statement->condition, body_block, false_block);
+ create_condition_evaluation(statement->v.while_stmt.condition, body_block, false_block);
mature_immBlock(body_block);
mature_immBlock(false_block);
mature_immBlock(header_block);
set_cur_block(false_block);
}
-static void for_statement_to_firm(for_statement_t *statement)
+static void for_statement_to_firm(statement_t *statement)
{
ir_node *jmp = NULL;
if (get_cur_block() != NULL) {
- if(statement->initialisation != NULL) {
- expression_to_firm(statement->initialisation);
+ if(statement->v.for_stmt.initialisation != NULL) {
+ expression_to_firm(statement->v.for_stmt.initialisation);
}
jmp = new_Jmp();
}
/* create the step block */
ir_node *const step_block = new_immBlock();
- if (statement->step != NULL) {
- expression_to_firm(statement->step);
+ if (statement->v.for_stmt.step != NULL) {
+ expression_to_firm(statement->v.for_stmt.step);
}
ir_node *const step_jmp = new_Jmp();
/* the loop body */
ir_node * body_block;
- if (statement->body != NULL) {
+ if (statement->v.for_stmt.body != NULL) {
ir_node *const old_continue_label = continue_label;
ir_node *const old_break_label = break_label;
continue_label = step_block;
break_label = false_block;
body_block = new_immBlock();
- statement_to_firm(statement->body);
+ statement_to_firm(statement->v.for_stmt.body);
assert(continue_label == step_block);
assert(break_label == false_block);
/* create the condition */
set_cur_block(header_block);
- if (statement->condition != NULL) {
- create_condition_evaluation(statement->condition, body_block,
+ if (statement->v.for_stmt.condition != NULL) {
+ create_condition_evaluation(statement->v.for_stmt.condition, body_block,
false_block);
} else {
keep_alive(header_block);
current_ir_graph = old_current_ir_graph;
}
-static void declaration_statement_to_firm(declaration_statement_t *statement)
+static void declaration_statement_to_firm(statement_t *statement)
{
- declaration_t *declaration = statement->declarations_begin;
- declaration_t *end = statement->declarations_end->next;
+ declaration_t *declaration = statement->v.declaration_stmt.begin;
+ declaration_t *end = statement->v.declaration_stmt.end->next;
for( ; declaration != end; declaration = declaration->next) {
type_t *type = declaration->type;
set_cur_block(NULL);
}
-static void switch_statement_to_firm(const switch_statement_t *statement)
+static void switch_statement_to_firm(const statement_t *statement)
{
- dbg_info *dbgi = get_dbg_info(&statement->statement.source_position);
+ dbg_info *dbgi = get_dbg_info(&statement->source_position);
- ir_node *expression = expression_to_firm(statement->expression);
+ ir_node *expression = expression_to_firm(statement->v.switch_stmt.expression);
ir_node *cond = new_d_Cond(dbgi, expression);
ir_node *break_block = new_immBlock();
current_switch_cond = cond;
break_label = break_block;
- statement_to_firm(statement->body);
+ statement_to_firm(statement->v.switch_stmt.body);
if(get_cur_block() != NULL) {
ir_node *jmp = new_Jmp();
ir_node *cnst = expression_to_firm(expression);
if(!is_Const(cnst)) {
- panic("couldn't fold constantl");
+ panic("couldn't fold constant");
}
tarval *tv = get_Const_tarval(cnst);
if(!tarval_is_long(tv)) {
return res;
}
-static void case_label_to_firm(const case_label_statement_t *statement)
+static void case_label_to_firm(const statement_t *statement)
{
- dbg_info *dbgi = get_dbg_info(&statement->statement.source_position);
+ dbg_info *dbgi = get_dbg_info(&statement->source_position);
ir_node *const fallthrough = (get_cur_block() == NULL ? NULL : new_Jmp());
* node... */
ir_node *proj;
set_cur_block(get_nodes_block(current_switch_cond));
- if(statement->expression) {
- long pn = fold_constant(statement->expression);
+ if(statement->v.case_label_stmt.expression) {
+ long pn = fold_constant(statement->v.case_label_stmt.expression);
if(pn == MAGIC_DEFAULT_PN_NUMBER) {
/* oops someone detected our cheating... */
panic("magic default pn used");
add_immBlock_pred(block, proj);
mature_immBlock(block);
- statement_to_firm(statement->label_statement);
+ statement_to_firm(statement->v.case_label_stmt.label_statement);
}
static ir_node *get_label_block(declaration_t *label)
return block;
}
-static void label_to_firm(const label_statement_t *statement)
+static void label_to_firm(const statement_t *statement)
{
- ir_node *block = get_label_block(statement->label);
+ ir_node *block = get_label_block(statement->v.label_stmt.label);
if(get_cur_block() != NULL) {
ir_node *jmp = new_Jmp();
set_cur_block(block);
keep_alive(block);
- statement_to_firm(statement->label_statement);
+ statement_to_firm(statement->v.label_stmt.label_statement);
}
-static void goto_to_firm(const goto_statement_t *statement)
+static void goto_to_firm(const statement_t *statement)
{
if(get_cur_block() == NULL)
return;
- ir_node *block = get_label_block(statement->label);
+ ir_node *block = get_label_block(statement->v.goto_label);
ir_node *jmp = new_Jmp();
add_immBlock_pred(block, jmp);
{
switch(statement->type) {
case STATEMENT_COMPOUND:
- compound_statement_to_firm((compound_statement_t*) statement);
+ compound_statement_to_firm(statement);
return;
case STATEMENT_RETURN:
- return_statement_to_firm((return_statement_t*) statement);
+ return_statement_to_firm(statement);
return;
case STATEMENT_EXPRESSION:
- expression_statement_to_firm((expression_statement_t*) statement);
+ expression_statement_to_firm(statement);
return;
case STATEMENT_IF:
- if_statement_to_firm((if_statement_t*) statement);
+ if_statement_to_firm(statement);
return;
case STATEMENT_WHILE:
- while_statement_to_firm((while_statement_t*) statement);
+ while_statement_to_firm(statement);
return;
case STATEMENT_DO_WHILE:
- do_while_statement_to_firm((do_while_statement_t*) statement);
+ do_while_statement_to_firm(statement);
return;
case STATEMENT_DECLARATION:
- declaration_statement_to_firm((declaration_statement_t*) statement);
+ declaration_statement_to_firm(statement);
return;
case STATEMENT_BREAK:
create_jump_statement(statement, break_label);
create_jump_statement(statement, continue_label);
return;
case STATEMENT_SWITCH:
- switch_statement_to_firm((switch_statement_t*) statement);
+ switch_statement_to_firm(statement);
return;
case STATEMENT_CASE_LABEL:
- case_label_to_firm((case_label_statement_t*) statement);
+ case_label_to_firm(statement);
return;
case STATEMENT_FOR:
- for_statement_to_firm((for_statement_t*) statement);
+ for_statement_to_firm(statement);
return;
case STATEMENT_LABEL:
- label_to_firm((label_statement_t*) statement);
+ label_to_firm(statement);
return;
case STATEMENT_GOTO:
- goto_to_firm((goto_statement_t*) statement);
+ goto_to_firm(statement);
return;
default:
break;
int count = 0;
for (; stmt != NULL; stmt = stmt->next) {
switch (stmt->type) {
- case STATEMENT_DECLARATION: {
- const declaration_statement_t *const decl_stmt =
- (const declaration_statement_t*)stmt;
- count += count_local_declarations(decl_stmt->declarations_begin,
- decl_stmt->declarations_end->next);
+ case STATEMENT_DECLARATION:
+ count += count_local_declarations(stmt->v.declaration_stmt.begin,
+ stmt->v.declaration_stmt.end->next);
break;
- }
- case STATEMENT_COMPOUND: {
- const compound_statement_t *const comp =
- (const compound_statement_t*)stmt;
- count += count_decls_in_stmts(comp->statements);
+ case STATEMENT_COMPOUND:
+ count += count_decls_in_stmts(stmt->v.compound_stmt.statements);
break;
- }
- case STATEMENT_IF: {
- const if_statement_t *const if_stmt = (const if_statement_t*)stmt;
- count += count_decls_in_stmts(if_stmt->true_statement);
- count += count_decls_in_stmts(if_stmt->false_statement);
+ case STATEMENT_IF:
+ count += count_decls_in_stmts(stmt->v.if_stmt.true_statement);
+ count += count_decls_in_stmts(stmt->v.if_stmt.false_statement);
break;
- }
- case STATEMENT_SWITCH: {
- const switch_statement_t *const switch_stmt =
- (const switch_statement_t*)stmt;
- count += count_decls_in_stmts(switch_stmt->body);
+ case STATEMENT_SWITCH:
+ count += count_decls_in_stmts(stmt->v.switch_stmt.body);
break;
- }
- case STATEMENT_LABEL: {
- const label_statement_t *const label_stmt =
- (const label_statement_t*)stmt;
- count += count_decls_in_stmts(label_stmt->label_statement);
+ case STATEMENT_LABEL:
+ count += count_decls_in_stmts(stmt->v.label_stmt.label_statement);
break;
- }
- case STATEMENT_WHILE: {
- const while_statement_t *const while_stmt =
- (const while_statement_t*)stmt;
- count += count_decls_in_stmts(while_stmt->body);
+ case STATEMENT_WHILE:
+ count += count_decls_in_stmts(stmt->v.while_stmt.body);
break;
- }
- case STATEMENT_DO_WHILE: {
- const do_while_statement_t *const do_while_stmt =
- (const do_while_statement_t*)stmt;
- count += count_decls_in_stmts(do_while_stmt->body);
+ case STATEMENT_DO_WHILE:
+ count += count_decls_in_stmts(stmt->v.while_stmt.body);
break;
- }
case STATEMENT_FOR: {
- const for_statement_t *const for_stmt =
- (const for_statement_t*)stmt;
/* TODO initialisation */
- count += count_decls_in_stmts(for_stmt->body);
+ count += count_decls_in_stmts(stmt->v.for_stmt.body);
break;
}
statement_type_t type;
statement_t *next;
source_position_t source_position;
-};
-
-struct return_statement_t {
- statement_t statement;
- expression_t *return_value;
-};
-
-struct compound_statement_t {
- statement_t statement;
- statement_t *statements;
- context_t context;
-};
-
-struct declaration_statement_t {
- statement_t statement;
- declaration_t *declarations_begin;
- declaration_t *declarations_end;
-};
-
-struct if_statement_t {
- statement_t statement;
- expression_t *condition;
- statement_t *true_statement;
- statement_t *false_statement;
-};
-
-struct switch_statement_t {
- statement_t statement;
- expression_t *expression;
- statement_t *body;
-};
-
-struct goto_statement_t {
- statement_t statement;
- declaration_t *label;
-};
-
-struct case_label_statement_t {
- statement_t statement;
- expression_t *expression;
- statement_t *label_statement;
-};
-
-struct label_statement_t {
- statement_t statement;
- declaration_t *label;
- statement_t *label_statement;
-};
-
-struct expression_statement_t {
- statement_t statement;
- expression_t *expression;
-};
-
-struct while_statement_t {
- statement_t statement;
- expression_t *condition;
- statement_t *body;
-};
-
-struct do_while_statement_t {
- statement_t statement;
- expression_t *condition;
- statement_t *body;
-};
-
-struct for_statement_t {
- statement_t statement;
- expression_t *initialisation;
- expression_t *condition;
- expression_t *step;
- statement_t *body;
- context_t context;
+ union {
+ /* if type == STATEMENT_COMPOUND */
+ struct {
+ statement_t *statements;
+ context_t context;
+ } compound_stmt;
+ /* if type == STATEMENT_RETURN */
+ expression_t *return_value;
+ /* if type == STATEMENT_DECLARATION */
+ struct {
+ declaration_t *begin;
+ declaration_t *end;
+ } declaration_stmt;
+ /* if type == STATEMENT_IF */
+ struct {
+ expression_t *condition;
+ statement_t *true_statement;
+ statement_t *false_statement;
+ } if_stmt;
+ /* if type == STATEMENT_SWITCH */
+ struct {
+ expression_t *expression;
+ statement_t *body;
+ } switch_stmt;
+ /* if type == STATEMENT_EXPRESSION */
+ expression_t *expression;
+ /* if type == STATEMENT_GOTO */
+ declaration_t *goto_label;
+ /* if type == STATEMENT_LABEL */
+ struct {
+ declaration_t *label;
+ statement_t *label_statement;
+ } label_stmt;
+ /* if type == STATEMENT_CASE_LABEL */
+ struct {
+ expression_t *expression;
+ statement_t *label_statement;
+ } case_label_stmt;
+ /* if type == STATEMENT_WHILE or STATEMENT_DO_WHILE */
+ struct {
+ expression_t *condition;
+ statement_t *body;
+ } while_stmt;
+ /* if type == STATEMENT_FOR */
+ struct {
+ expression_t *initialisation;
+ expression_t *condition;
+ expression_t *step;
+ statement_t *body;
+ context_t context;
+ } for_stmt;
+ } v;
};
struct translation_unit_t {
}
assert(statement->type == STATEMENT_COMPOUND);
- compound_statement_t *compound_statement
- = (compound_statement_t*) statement;
/* find last statement and use it's type */
const statement_t *last_statement = NULL;
- const statement_t *iter = compound_statement->statements;
+ const statement_t *iter = statement->v.compound_stmt.statements;
for( ; iter != NULL; iter = iter->next) {
last_statement = iter;
}
if(last_statement->type == STATEMENT_EXPRESSION) {
- const expression_statement_t *expression_statement =
- (const expression_statement_t*) last_statement;
expression->expression.datatype
- = expression_statement->expression->datatype;
+ = last_statement->v.expression->datatype;
} else {
expression->expression.datatype = type_void;
}
static statement_t *parse_case_statement(void)
{
eat(T_case);
- case_label_statement_t *label = allocate_ast_zero(sizeof(label[0]));
- label->statement.type = STATEMENT_CASE_LABEL;
- label->statement.source_position = token.source_position;
+ statement_t *label = allocate_ast_zero(sizeof(label[0]));
+ label->type = STATEMENT_CASE_LABEL;
+ label->source_position = token.source_position;
- label->expression = parse_expression();
+ label->v.case_label_stmt.expression = parse_expression();
expect(':');
- label->label_statement = parse_statement();
+ label->v.case_label_stmt.label_statement = parse_statement();
- return (statement_t*) label;
+ return label;
}
static statement_t *parse_default_statement(void)
{
eat(T_default);
- case_label_statement_t *label = allocate_ast_zero(sizeof(label[0]));
- label->statement.type = STATEMENT_CASE_LABEL;
- label->statement.source_position = token.source_position;
+ statement_t *label = allocate_ast_zero(sizeof(label[0]));
+ label->type = STATEMENT_CASE_LABEL;
+ label->source_position = token.source_position;
expect(':');
- label->label_statement = parse_statement();
+ label->v.case_label_stmt.label_statement = parse_statement();
return (statement_t*) label;
}
label->source_position = token.source_position;
}
- label_statement_t *label_statement = allocate_ast_zero(sizeof(label[0]));
+ statement_t *label_statement = allocate_ast_zero(sizeof(label[0]));
- label_statement->statement.type = STATEMENT_LABEL;
- label_statement->statement.source_position = token.source_position;
- label_statement->label = label;
+ label_statement->type = STATEMENT_LABEL;
+ label_statement->source_position = token.source_position;
+ label_statement->v.label_stmt.label = label;
expect(':');
parse_error("label at end of compound statement");
return (statement_t*) label_statement;
} else {
- label_statement->label_statement = parse_statement();
+ label_statement->v.label_stmt.label_statement = parse_statement();
}
- return (statement_t*) label_statement;
+ return label_statement;
}
static statement_t *parse_if(void)
{
eat(T_if);
- if_statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
- statement->statement.type = STATEMENT_IF;
- statement->statement.source_position = token.source_position;
+ statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
+ statement->type = STATEMENT_IF;
+ statement->source_position = token.source_position;
expect('(');
- statement->condition = parse_expression();
+ statement->v.if_stmt.condition = parse_expression();
expect(')');
- statement->true_statement = parse_statement();
+ statement->v.if_stmt.true_statement = parse_statement();
if(token.type == T_else) {
next_token();
- statement->false_statement = parse_statement();
+ statement->v.if_stmt.false_statement = parse_statement();
}
- return (statement_t*) statement;
+ return statement;
}
static statement_t *parse_switch(void)
{
eat(T_switch);
- switch_statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
- statement->statement.type = STATEMENT_SWITCH;
- statement->statement.source_position = token.source_position;
+ statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
+ statement->type = STATEMENT_SWITCH;
+ statement->source_position = token.source_position;
expect('(');
- statement->expression = parse_expression();
+ statement->v.switch_stmt.expression = parse_expression();
expect(')');
- statement->body = parse_statement();
+ statement->v.switch_stmt.body = parse_statement();
- return (statement_t*) statement;
+ return statement;
}
static statement_t *parse_while(void)
{
eat(T_while);
- while_statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
- statement->statement.type = STATEMENT_WHILE;
- statement->statement.source_position = token.source_position;
+ statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
+ statement->type = STATEMENT_WHILE;
+ statement->source_position = token.source_position;
expect('(');
- statement->condition = parse_expression();
+ statement->v.while_stmt.condition = parse_expression();
expect(')');
- statement->body = parse_statement();
+ statement->v.while_stmt.body = parse_statement();
- return (statement_t*) statement;
+ return statement;
}
static statement_t *parse_do(void)
{
eat(T_do);
- do_while_statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
- statement->statement.type = STATEMENT_DO_WHILE;
- statement->statement.source_position = token.source_position;
+ statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
+ statement->type = STATEMENT_DO_WHILE;
+ statement->source_position = token.source_position;
- statement->body = parse_statement();
+ statement->v.while_stmt.body = parse_statement();
expect(T_while);
expect('(');
- statement->condition = parse_expression();
+ statement->v.while_stmt.condition = parse_expression();
expect(')');
expect(';');
- return (statement_t*) statement;
+ return statement;
}
static statement_t *parse_for(void)
{
eat(T_for);
- for_statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
- statement->statement.type = STATEMENT_FOR;
- statement->statement.source_position = token.source_position;
+ statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
+ statement->type = STATEMENT_FOR;
+ statement->source_position = token.source_position;
expect('(');
int top = environment_top();
context_t *last_context = context;
- set_context(&statement->context);
+ set_context(&statement->v.for_stmt.context);
if(token.type != ';') {
if(is_declaration_specifier(&token, false)) {
parse_declaration();
} else {
- statement->initialisation = parse_expression();
+ statement->v.for_stmt.initialisation = parse_expression();
expect(';');
}
} else {
}
if(token.type != ';') {
- statement->condition = parse_expression();
+ statement->v.for_stmt.condition = parse_expression();
}
expect(';');
if(token.type != ')') {
- statement->step = parse_expression();
+ statement->v.for_stmt.step = parse_expression();
}
expect(')');
- statement->body = parse_statement();
+ statement->v.for_stmt.body = parse_statement();
- assert(context == &statement->context);
+ assert(context == &statement->v.for_stmt.context);
set_context(last_context);
environment_pop_to(top);
- return (statement_t*) statement;
+ return statement;
}
static statement_t *parse_goto(void)
declaration_t *label = get_label(symbol);
- goto_statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
+ statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
- statement->statement.type = STATEMENT_GOTO;
- statement->statement.source_position = token.source_position;
+ statement->type = STATEMENT_GOTO;
+ statement->source_position = token.source_position;
- statement->label = label;
+ statement->v.goto_label = label;
expect(';');
- return (statement_t*) statement;
+ return statement;
}
static statement_t *parse_continue(void)
{
eat(T_return);
- return_statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
+ statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
- statement->statement.type = STATEMENT_RETURN;
- statement->statement.source_position = token.source_position;
+ statement->type = STATEMENT_RETURN;
+ statement->source_position = token.source_position;
assert(current_function->type->type == TYPE_FUNCTION);
function_type_t *function_type = (function_type_t*) current_function->type;
"non-void");
}
}
- statement->return_value = return_value;
+ statement->v.return_value = return_value;
expect(';');
- return (statement_t*) statement;
+ return statement;
}
static statement_t *parse_declaration_statement(void)
{
declaration_t *before = last_declaration;
- declaration_statement_t *statement
+ statement_t *statement
= allocate_ast_zero(sizeof(statement[0]));
- statement->statement.type = STATEMENT_DECLARATION;
- statement->statement.source_position = token.source_position;
+ statement->type = STATEMENT_DECLARATION;
+ statement->source_position = token.source_position;
declaration_specifiers_t specifiers;
memset(&specifiers, 0, sizeof(specifiers));
}
if(before == NULL) {
- statement->declarations_begin = context->declarations;
+ statement->v.declaration_stmt.begin = context->declarations;
} else {
- statement->declarations_begin = before->next;
+ statement->v.declaration_stmt.begin = before->next;
}
- statement->declarations_end = last_declaration;
+ statement->v.declaration_stmt.end = last_declaration;
- return (statement_t*) statement;
+ return statement;
}
static statement_t *parse_expression_statement(void)
{
- expression_statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
- statement->statement.type = STATEMENT_EXPRESSION;
- statement->statement.source_position = token.source_position;
+ statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
+ statement->type = STATEMENT_EXPRESSION;
+ statement->source_position = token.source_position;
- statement->expression = parse_expression();
+ statement->v.expression = parse_expression();
expect(';');
- return (statement_t*) statement;
+ return statement;
}
static statement_t *parse_statement(void)
static statement_t *parse_compound_statement(void)
{
- compound_statement_t *compound_statement
+ statement_t *compound_statement
= allocate_ast_zero(sizeof(compound_statement[0]));
- compound_statement->statement.type = STATEMENT_COMPOUND;
- compound_statement->statement.source_position = token.source_position;
+ compound_statement->type = STATEMENT_COMPOUND;
+ compound_statement->source_position = token.source_position;
eat('{');
int top = environment_top();
context_t *last_context = context;
- set_context(&compound_statement->context);
+ set_context(&compound_statement->v.compound_stmt.context);
statement_t *last_statement = NULL;
if(last_statement != NULL) {
last_statement->next = statement;
} else {
- compound_statement->statements = statement;
+ compound_statement->v.compound_stmt.statements = statement;
}
while(statement->next != NULL)
if(token.type != '}') {
parser_print_error_prefix_pos(
- compound_statement->statement.source_position);
+ compound_statement->source_position);
fprintf(stderr, "end of file while looking for closing '}'\n");
}
next_token();
- assert(context == &compound_statement->context);
+ assert(context == &compound_statement->v.compound_stmt.context);
set_context(last_context);
environment_pop_to(top);
- return (statement_t*) compound_statement;
+ return compound_statement;
}
static translation_unit_t *parse_translation_unit(void)