From 5fe87e6a2077e48e838854789faf5809cc28415f Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Tue, 1 May 2012 16:55:02 +0200 Subject: [PATCH] if-then-else AST node - this one is not for ternary expressions --- ast.c | 31 +++++++++++++++++++++++++++++++ ast.h | 25 +++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/ast.c b/ast.c index 168a80e..3ab7b37 100644 --- a/ast.c +++ b/ast.c @@ -153,6 +153,31 @@ void ast_entfield_delete(ast_entfield *self) mem_d(self); } +ast_ifthen* ast_ifthen_new(lex_ctx ctx, ast_expression *cond, ast_expression *ontrue, ast_expression *onfalse) +{ + ast_instantiate(ast_ifthen, ctx, ast_ifthen_delete); + if (!ontrue && !onfalse) { + /* because it is invalid */ + mem_d(self); + return NULL; + } + ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_ifthen_codegen); + + self->cond = cond; + self->on_true = ontrue; + self->on_false = onfalse; + + return self; +} + +void ast_ifthen_delete(ast_ifthen *self) +{ + ast_unref(self->cond); + ast_unref(self->on_true); + ast_unref(self->on_false); + mem_d(self); +} + ast_store* ast_store_new(lex_ctx ctx, int op, ast_value *dest, ast_expression *source) { @@ -343,3 +368,9 @@ bool ast_entfield_codegen(ast_entfield *self, ast_function *func, bool lvalue, i { return false; } + +bool ast_ifthen_codegen(ast_ifthen *self, ast_function *func, bool lvalue, ir_value **out) +{ + if (out) *out = NULL; + return false; +} diff --git a/ast.h b/ast.h index 1437de8..c9311ee 100644 --- a/ast.h +++ b/ast.h @@ -37,6 +37,7 @@ typedef struct ast_block_s ast_block; typedef struct ast_binary_s ast_binary; typedef struct ast_store_s ast_store; typedef struct ast_entfield_s ast_entfield; +typedef struct ast_ifthen_s ast_ifthen; /* Node interface with common components */ @@ -180,6 +181,30 @@ void ast_store_delete(ast_store*); bool ast_store_codegen(ast_store*, ast_function*, bool lvalue, ir_value**); +/* If + * + * A general 'if then else' statement, either side can be NULL and will + * thus be omitted. It is an error for *both* cases to be NULL at once. + * + * During its 'codegen' it'll be changing the ast_function's block. + * + * An if is also an "expression". Its codegen will put NULL into the + * output field though. For ternary expressions an ast_ternary will be + * added. + */ +struct ast_ifthen_s +{ + ast_expression_common expression; + ast_expression *cond; + /* It's all just 'expressions', since an ast_block is one too. */ + ast_expression *on_true; + ast_expression *on_false; +}; +ast_ifthen* ast_ifthen_new(lex_ctx ctx, ast_expression *cond, ast_expression *ontrue, ast_expression *onfalse); +void ast_ifthen_delete(ast_ifthen*); + +bool ast_ifthen_codegen(ast_ifthen*, ast_function*, bool lvalue, ir_value**); + /* Blocks * */ -- 2.39.2