]> de.git.xonotic.org Git - xonotic/gmqcc.git/commitdiff
creating and generating builtin functions, ast-macros for builtins, todo: params
authorWolfgang Bumiller <wolfgang.linux@bumiller.com>
Tue, 3 Jul 2012 21:38:38 +0000 (23:38 +0200)
committerWolfgang Bumiller <wolfgang.linux@bumiller.com>
Tue, 3 Jul 2012 21:38:38 +0000 (23:38 +0200)
ast.c
ast.h
ir.c
ir.h
test/ast-macros.h
test/ast-test.c

diff --git a/ast.c b/ast.c
index 065dfd88dbf2d4fb80dd09c8c70caaa66475cfa7..17c63413cc7de19fa8cc5123150b02a9c9f08afb 100644 (file)
--- 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 f355716f70d04aeb39fa33f656b1d42217d2f3b6..a08c4c0d4072d5df8bd61cacaff8fd971c59b704 100644 (file)
--- 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 ff87a80e59c8cd4fe278b4cd6229cd89033bbf35..eeb55ce5a150c5801c708036ab76bddf4d6a4b0c 100644 (file)
--- 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 171c185f049b34a1c9ccda933624d023fe30b918..7aa889bae7e25ab3ca822c8a562a9d9e90e4447b 100644 (file)
--- 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
index c4cd7eb63640a60d0fe741c0167a6b3255dca1b1..6f52bdfceae491d968ae4ed7ae284de37da6730b 100644 (file)
@@ -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);                                         \
index 022157897f4e1c26703faac36674745bde92fe3a..2217a396e5ccc1373e9800f86e54a512a929601e 100644 (file)
@@ -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);