From ed24ea0cef206020757e9d549929313447988033 Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Tue, 3 Jul 2012 23:38:38 +0200 Subject: [PATCH] creating and generating builtin functions, ast-macros for builtins, todo: params --- ast.c | 20 +++++++++++++++++++- ast.h | 4 ++++ ir.c | 29 +++++++++++++++++++++++------ ir.h | 3 +++ test/ast-macros.h | 27 +++++++++++++++++++++++++++ test/ast-test.c | 7 +++++++ 6 files changed, 83 insertions(+), 7 deletions(-) diff --git a/ast.c b/ast.c index 065dfd8..17c6341 100644 --- a/ast.c +++ b/ast.c @@ -396,8 +396,10 @@ ast_function* ast_function_new(lex_ctx ctx, const char *name, ast_value *vtype) self->vtype = vtype; self->name = name ? util_strdup(name) : NULL; MEM_VECTOR_INIT(self, blocks); + MEM_VECTOR_INIT(self, params); self->labelcount = 0; + self->builtin = 0; self->ir_func = NULL; self->curblock = NULL; @@ -412,6 +414,7 @@ ast_function* ast_function_new(lex_ctx ctx, const char *name, ast_value *vtype) } MEM_VEC_FUNCTIONS(ast_function, ast_block*, blocks) +MEM_VEC_FUNCTIONS(ast_function, ast_value*, params) void ast_function_delete(ast_function *self) { @@ -430,6 +433,9 @@ void ast_function_delete(ast_function *self) for (i = 0; i < self->blocks_count; ++i) ast_delete(self->blocks[i]); MEM_VECTOR_CLEAR(self, blocks); + for (i = 0; i < self->params_count; ++i) + ast_delete(self->params[i]); + MEM_VECTOR_CLEAR(self, params); mem_d(self); } @@ -522,10 +528,11 @@ bool ast_global_codegen(ast_value *self, ir_builder *ir) goto error; break; case TYPE_FUNCTION: + printf("global of type function not properly generated\n"); + goto error; /* Cannot generate an IR value for a function, * need a pointer pointing to a function rather. */ - goto error; default: printf("TODO: global constant type %i\n", self->expression.vtype); break; @@ -601,6 +608,17 @@ bool ast_function_codegen(ast_function *self, ir_builder *ir) return false; } + for (i = 0; i < self->params_count; ++i) + { + if (!ir_function_params_add(irf, self->params[i]->expression.vtype)) + return false; + } + + if (self->builtin) { + irf->builtin = self->builtin; + return true; + } + self->curblock = ir_function_create_block(irf, "entry"); if (!self->curblock) return false; diff --git a/ast.h b/ast.h index f355716..a08c4c0 100644 --- a/ast.h +++ b/ast.h @@ -343,6 +343,8 @@ struct ast_function_s ast_value *vtype; const char *name; + int builtin; + ir_function *ir_func; ir_block *curblock; ir_block *breakblock; @@ -356,6 +358,7 @@ struct ast_function_s char labelbuf[64]; MEM_VECTOR_MAKE(ast_block*, blocks); + MEM_VECTOR_MAKE(ast_value*, params); }; ast_function* ast_function_new(lex_ctx ctx, const char *name, ast_value *vtype); /* This will NOT delete the underlying ast_value */ @@ -366,6 +369,7 @@ void ast_function_delete(ast_function*); const char* ast_function_label(ast_function*, const char *prefix); MEM_VECTOR_PROTO(ast_function, ast_block*, blocks); +MEM_VECTOR_PROTO(ast_function, ast_value*, params); bool ast_function_codegen(ast_function *self, ir_builder *builder); diff --git a/ir.c b/ir.c index ff87a80..eeb55ce 100644 --- a/ir.c +++ b/ir.c @@ -206,6 +206,7 @@ ir_function* ir_function_new(ir_builder* owner, int outtype) self->context.line = 0; self->outtype = outtype; self->value = NULL; + self->builtin = 0; MEM_VECTOR_INIT(self, params); MEM_VECTOR_INIT(self, blocks); MEM_VECTOR_INIT(self, values); @@ -217,6 +218,7 @@ ir_function* ir_function_new(ir_builder* owner, int outtype) MEM_VEC_FUNCTIONS(ir_function, ir_value*, values) MEM_VEC_FUNCTIONS(ir_function, ir_block*, blocks) MEM_VEC_FUNCTIONS(ir_function, ir_value*, locals) +MEM_VEC_FUNCTIONS(ir_function, int, params) bool ir_function_set_name(ir_function *self, const char *name) { @@ -268,6 +270,9 @@ ir_block* ir_function_create_block(ir_function *self, const char *label) bool ir_function_finalize(ir_function *self) { + if (self->builtin) + return true; + if (!ir_function_naive_phi(self)) return false; @@ -529,6 +534,15 @@ bool ir_value_set_float(ir_value *self, float f) return true; } +bool ir_value_set_func(ir_value *self, int f) +{ + if (self->vtype != TYPE_FUNCTION) + return false; + self->constval.vint = f; + self->isconst = true; + return true; +} + bool ir_value_set_vector(ir_value *self, vector v) { if (self->vtype != TYPE_VECTOR) @@ -2321,8 +2335,7 @@ static bool gen_global_function(ir_builder *ir, ir_value *global) size_t i; size_t local_var_end; - if (!global->isconst || - !global->constval.vfunc) + if (!global->isconst || (!global->constval.vfunc)) { printf("Invalid state of function-global: not constant: %s\n", global->name); return false; @@ -2370,10 +2383,14 @@ static bool gen_global_function(ir_builder *ir, ir_value *global) code_globals_add(0); } - fun.entry = code_statements_elements; - if (!gen_function_code(irfun)) { - printf("Failed to generate code for function %s\n", irfun->name); - return false; + if (irfun->builtin) + fun.entry = irfun->builtin; + else { + fun.entry = code_statements_elements; + if (!gen_function_code(irfun)) { + printf("Failed to generate code for function %s\n", irfun->name); + return false; + } } return (code_functions_add(fun) >= 0); diff --git a/ir.h b/ir.h index 171c185..7aa889b 100644 --- a/ir.h +++ b/ir.h @@ -81,6 +81,7 @@ MEM_VECTOR_PROTO_ALL(ir_value, struct ir_instr_s*, reads); MEM_VECTOR_PROTO_ALL(ir_value, struct ir_instr_s*, writes); bool GMQCC_WARN ir_value_set_float(ir_value*, float f); +bool GMQCC_WARN ir_value_set_func(ir_value*, int f); #if 0 bool GMQCC_WARN ir_value_set_int(ir_value*, int i); #endif @@ -228,6 +229,8 @@ typedef struct ir_function_s MEM_VECTOR_MAKE(int, params); MEM_VECTOR_MAKE(ir_block*, blocks); + int builtin; + ir_value *value; /* values generated from operations diff --git a/test/ast-macros.h b/test/ast-macros.h index c4cd7eb..6f52bdf 100644 --- a/test/ast-macros.h +++ b/test/ast-macros.h @@ -56,8 +56,33 @@ do { \ STATE(loop); \ } while(0) +#define BUILTIN(name, outtype, number) \ +do { \ + ast_function *func_##name; \ + ast_function *thisfunc; \ + DEFVAR(return_##name); \ + VARnamed(TYPE_FUNCTION, name, name); \ + VARnamed(outtype, return_##name, "#returntype"); \ + name->expression.next = (ast_expression*)return_##name; \ + MKGLOBAL(name); \ + func_##name = ast_function_new(ctx, #name, name); \ + thisfunc = func_##name; \ + (void)thisfunc; \ + assert(functions_add(func_##name) >= 0); \ + func_##name->builtin = number; + +#define ENDBUILTIN() } while(0) + +#define PARAM(ptype, name) \ +do { \ + DEFVAR(parm); \ + VARnamed(ptype, parm, name); \ + assert(ast_function_params_add(thisfunc, parm)); \ +} while(0) + #define FUNCTION(name, outtype) \ do { \ + ast_function *thisfunc; \ ast_function *func_##name; \ ast_block *my_funcblock; \ DEFVAR(var_##name); \ @@ -67,6 +92,8 @@ do { \ var_##name->expression.next = (ast_expression*)return_##name; \ MKGLOBAL(var_##name); \ func_##name = ast_function_new(ctx, #name, var_##name); \ + thisfunc = func_##name; \ + (void)thisfunc; \ assert(functions_add(func_##name) >= 0); \ my_funcblock = ast_block_new(ctx); \ assert(my_funcblock); \ diff --git a/test/ast-test.c b/test/ast-test.c index 0221578..2217a39 100644 --- a/test/ast-test.c +++ b/test/ast-test.c @@ -27,6 +27,13 @@ int main() DEFVAR(f0); DEFVAR(f1); DEFVAR(f5); + DEFVAR(print); + +#if 0 + BUILTIN(print, TYPE_VOID, -1); + PARAM(TYPE_STRING, text); + ENDBUILTIN(); +#endif TESTINIT(); VAR(TYPE_FLOAT, f0); -- 2.39.2