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;
}
MEM_VEC_FUNCTIONS(ast_function, ast_block*, blocks)
+MEM_VEC_FUNCTIONS(ast_function, ast_value*, params)
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);
}
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;
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;
ast_value *vtype;
const char *name;
+ int builtin;
+
ir_function *ir_func;
ir_block *curblock;
ir_block *breakblock;
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 */
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);
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);
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)
{
bool ir_function_finalize(ir_function *self)
{
+ if (self->builtin)
+ return true;
+
if (!ir_function_naive_phi(self))
return false;
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)
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;
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);
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
MEM_VECTOR_MAKE(int, params);
MEM_VECTOR_MAKE(ir_block*, blocks);
+ int builtin;
+
ir_value *value;
/* values generated from operations
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); \
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); \
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);