Store accessors in the ast_value for access from within the ast - generate accessors after generating all the globals to not mess up the order of globals in the output

This commit is contained in:
Wolfgang (Blub) Bumiller 2012-11-11 16:22:09 +01:00
parent 7d9568f806
commit 1ab303c528
3 changed files with 37 additions and 19 deletions

8
ast.c
View file

@ -327,6 +327,9 @@ ast_value* ast_value_new(lex_ctx ctx, const char *name, int t)
self->ir_values = NULL;
self->ir_value_count = 0;
self->setter = NULL;
self->getter = NULL;
return self;
}
@ -918,7 +921,9 @@ bool ast_value_codegen(ast_value *self, ast_function *func, bool lvalue, ir_valu
* on all the globals.
*/
if (!self->ir_v) {
asterror(ast_ctx(self), "ast_value used before generated (%s)", self->name);
char typename[1024];
ast_type_to_string((ast_expression*)self, typename, sizeof(typename));
asterror(ast_ctx(self), "ast_value used before generated %s %s", typename, self->name);
return false;
}
*out = self->ir_v;
@ -928,6 +933,7 @@ bool ast_value_codegen(ast_value *self, ast_function *func, bool lvalue, ir_valu
bool ast_global_codegen(ast_value *self, ir_builder *ir, bool isfield)
{
ir_value *v = NULL;
if (self->isconst && self->expression.vtype == TYPE_FUNCTION)
{
ir_function *func = ir_builder_create_function(ir, self->name, self->expression.next->expression.vtype);

4
ast.h
View file

@ -166,6 +166,10 @@ struct ast_value_s
ir_value *ir_v;
ir_value **ir_values;
size_t ir_value_count;
/* ONLY for arrays in progs version up to 6 */
ast_value *setter;
ast_value *getter;
};
ast_value* ast_value_new(lex_ctx ctx, const char *name, int qctype);

View file

@ -2327,7 +2327,6 @@ static bool parser_create_array_setter(parser_t *parser, ast_value *array, const
ast_value *fval = NULL;
ast_block *body;
ast_value *index, *value;
varentry_t entry;
if (!ast_istype(array->expression.next, ast_value)) {
parseerror(parser, "internal error: array accessor needs to build an ast_value with a copy of the element type");
@ -2389,14 +2388,7 @@ static bool parser_create_array_setter(parser_t *parser, ast_value *array, const
if (!ast_function_blocks_add(func, body))
goto cleanup2;
entry.name = util_strdup(funcname);
entry.var = (ast_expression*)fval;
if (!parser_t_globals_add(parser, entry)) {
mem_d(entry.name);
goto cleanup2;
}
if (!parser_t_functions_add(parser, func))
goto cleanup2;
array->setter = fval;
return true;
cleanup:
@ -2417,7 +2409,6 @@ static bool parser_create_array_getter(parser_t *parser, ast_value *array, const
ast_value *fval = NULL;
ast_block *body;
ast_value *index;
varentry_t entry;
if (!ast_istype(array->expression.next, ast_value)) {
parseerror(parser, "internal error: array accessor needs to build an ast_value with a copy of the element type");
@ -2471,14 +2462,7 @@ static bool parser_create_array_getter(parser_t *parser, ast_value *array, const
if (!ast_function_blocks_add(func, body))
goto cleanup2;
entry.name = util_strdup(funcname);
entry.var = (ast_expression*)fval;
if (!parser_t_globals_add(parser, entry)) {
mem_d(entry.name);
goto cleanup2;
}
if (!parser_t_functions_add(parser, func))
goto cleanup2;
array->getter = fval;
return true;
cleanup:
@ -3545,6 +3529,30 @@ bool parser_finish(const char *output)
return false;
}
}
for (i = 0; i < parser->globals_count; ++i) {
ast_value *asvalue;
if (!ast_istype(parser->globals[i].var, ast_value))
continue;
asvalue = (ast_value*)(parser->globals[i].var);
if (asvalue->setter) {
if (!ast_global_codegen(asvalue->setter, ir, false) ||
!ast_function_codegen(asvalue->setter->constval.vfunc, ir))
{
printf("failed to generate setter for %s\n", parser->globals[i].name);
ir_builder_delete(ir);
return false;
}
}
if (asvalue->getter) {
if (!ast_global_codegen(asvalue->getter, ir, false) ||
!ast_function_codegen(asvalue->getter->constval.vfunc, ir))
{
printf("failed to generate getter for %s\n", parser->globals[i].name);
ir_builder_delete(ir);
return false;
}
}
}
for (i = 0; i < parser->functions_count; ++i) {
if (!ast_function_codegen(parser->functions[i], ir)) {
printf("failed to generate function %s\n", parser->functions[i]->name);