mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2025-02-17 09:02:25 +00:00
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:
parent
7d9568f806
commit
1ab303c528
3 changed files with 37 additions and 19 deletions
8
ast.c
8
ast.c
|
@ -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
4
ast.h
|
@ -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);
|
||||
|
|
44
parser.c
44
parser.c
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue