TYPE_FUNCTION values which are not constant are now allowed to be generated, they are function pointers.

This commit is contained in:
Wolfgang (Blub) Bumiller 2012-08-21 16:01:28 +02:00
parent 8f4333df30
commit 19b66800ae
3 changed files with 32 additions and 6 deletions

View file

@ -15,6 +15,14 @@ float(entity targ) visible = {
return targ.vis;
};
void() printworking = {
print("Working\n");
};
void(void() callback) testcallback = {
callback();
};
void() main = {
local entity pawn, pawn2;
@ -26,4 +34,6 @@ void() main = {
if (!visible(pawn.other))
print("Yes\n");
testcallback(printworking);
};

11
ir.c
View file

@ -2718,9 +2718,14 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global)
case TYPE_FUNCTION:
if (code_defs_add(def) < 0)
return false;
ir_value_code_setaddr(global, code_globals_elements);
code_globals_add(code_functions_elements);
return gen_global_function(self, global);
if (!global->isconst) {
ir_value_code_setaddr(global, code_globals_add(0));
return global->code.globaladdr >= 0;
} else {
ir_value_code_setaddr(global, code_globals_elements);
code_globals_add(code_functions_elements);
return gen_global_function(self, global);
}
case TYPE_VARIANT:
/* assume biggest type */
ir_value_code_setaddr(global, code_globals_add(0));

View file

@ -317,7 +317,7 @@ static ast_value *parser_parse_type(parser_t *parser, int basetype, bool *isfunc
ast_value *param;
ast_value *fld;
bool isfield = false;
bool dummy;
bool isfuncparam = false;
if (!parser_next(parser))
goto on_error;
@ -337,8 +337,7 @@ static ast_value *parser_parse_type(parser_t *parser, int basetype, bool *isfunc
if (!parser_next(parser))
goto on_error;
param = parser_parse_type(parser, temptype, &dummy);
(void)dummy;
param = parser_parse_type(parser, temptype, &isfuncparam);
if (!param)
goto on_error;
@ -351,6 +350,18 @@ static ast_value *parser_parse_type(parser_t *parser, int basetype, bool *isfunc
goto on_error;
}
/* This comes before the isfield part! */
if (isfuncparam) {
ast_value *fval = ast_value_new(ast_ctx(param), param->name, TYPE_FUNCTION);
if (!fval) {
ast_delete(param);
goto on_error;
}
fval->expression.next = (ast_expression*)param;
MEM_VECTOR_MOVE(&param->expression, params, &fval->expression, params);
param = fval;
}
if (isfield) {
fld = ast_value_new(ctx, param->name, TYPE_FIELD);
fld->expression.next = (ast_expression*)param;