mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2025-01-18 14:21:36 +00:00
creating and generating builtin functions, ast-macros for builtins, todo: params
This commit is contained in:
parent
e965ffb9df
commit
ed24ea0cef
6 changed files with 83 additions and 7 deletions
20
ast.c
20
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;
|
||||
|
|
4
ast.h
4
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);
|
||||
|
||||
|
|
29
ir.c
29
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);
|
||||
|
|
3
ir.h
3
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
|
||||
|
|
|
@ -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); \
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue