From: Wolfgang Bumiller Date: Thu, 26 Jul 2012 19:18:39 +0000 (+0200) Subject: ast_return X-Git-Tag: 0.1-rc1~396^2~1 X-Git-Url: https://git.xonotic.org/?a=commitdiff_plain;h=31ba1ec6c1302aa466bd25b9e275b5cc16303808;p=xonotic%2Fgmqcc.git ast_return --- diff --git a/ast.c b/ast.c index 70bc037..56db3f9 100644 --- a/ast.c +++ b/ast.c @@ -200,6 +200,24 @@ void ast_unary_delete(ast_unary *self) mem_d(self); } +ast_return* ast_return_new(lex_ctx ctx, int op, + ast_expression *expr) +{ + ast_instantiate(ast_return, ctx, ast_return_delete); + ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_return_codegen); + + self->operand = expr; + + return self; +} + +void ast_return_delete(ast_return *self) +{ + ast_unref(self->operand); + ast_expression_delete((ast_expression*)self); + mem_d(self); +} + ast_entfield* ast_entfield_new(lex_ctx ctx, ast_expression *entity, ast_expression *field) { const ast_expression *outtype; @@ -785,7 +803,7 @@ bool ast_unary_codegen(ast_unary *self, ast_function *func, bool lvalue, ir_valu if (!(*cgen)((ast_expression*)(self->operand), func, false, &operand)) return false; - *out = ir_block_create_unary(func->curblock, ast_function_label(func, "bin"), + *out = ir_block_create_unary(func->curblock, ast_function_label(func, "unary"), self->op, operand); if (!*out) return false; @@ -793,6 +811,27 @@ bool ast_unary_codegen(ast_unary *self, ast_function *func, bool lvalue, ir_valu return true; } +bool ast_return_codegen(ast_return *self, ast_function *func, bool lvalue, ir_value **out) +{ + ast_expression_codegen *cgen; + ir_value *operand; + + /* In the context of a return operation, we can disregard + * the lvalue flag. + */ + (void)lvalue; + + cgen = self->operand->expression.codegen; + /* lvalue! */ + if (!(*cgen)((ast_expression*)(self->operand), func, false, &operand)) + return false; + + if (!ir_block_create_return(func->curblock, operand)) + return false; + + return true; +} + bool ast_entfield_codegen(ast_entfield *self, ast_function *func, bool lvalue, ir_value **out) { ast_expression_codegen *cgen; diff --git a/ast.h b/ast.h index 663099d..86bb183 100644 --- a/ast.h +++ b/ast.h @@ -168,6 +168,24 @@ void ast_unary_delete(ast_unary*); bool ast_unary_codegen(ast_unary*, ast_function*, bool lvalue, ir_value**); +/* Return + * + * Make sure 'return' only happens at the end of a block, otherwise the IR + * will refuse to create further instructions. + * This should be honored by the parser. + */ +struct ast_return_s +{ + ast_expression_common expression; + ast_expression *operand; +}; +ast_return* ast_return_new(lex_ctx ctx, + int op, + ast_expression *expr); +void ast_return_delete(ast_return*); + +bool ast_return_codegen(ast_return*, ast_function*, bool lvalue, ir_value**); + /* Entity-field * * This must do 2 things: