remember if an ast_value is a field-declaration, build fields before globals

This commit is contained in:
Wolfgang (Blub) Bumiller 2012-11-30 21:03:57 +01:00
parent 1a264e5576
commit 316298650e
3 changed files with 18 additions and 12 deletions

1
ast.c
View file

@ -322,6 +322,7 @@ ast_value* ast_value_new(lex_ctx ctx, const char *name, int t)
self->name = name ? util_strdup(name) : NULL; self->name = name ? util_strdup(name) : NULL;
self->expression.vtype = t; self->expression.vtype = t;
self->expression.next = NULL; self->expression.next = NULL;
self->isfield = false;
self->cvq = CV_NONE; self->cvq = CV_NONE;
self->hasvalue = false; self->hasvalue = false;
self->uses = 0; self->uses = 0;

1
ast.h
View file

@ -160,6 +160,7 @@ struct ast_value_s
*/ */
bool cvq; /* const/var qualifier */ bool cvq; /* const/var qualifier */
bool isfield; /* this declares a field */
bool hasvalue; bool hasvalue;
union { union {
double vfloat; double vfloat;

View file

@ -3812,7 +3812,8 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield
if (!localblock) { if (!localblock) {
/* deal with global variables, fields, functions */ /* deal with global variables, fields, functions */
if (!nofields && var->expression.vtype == TYPE_FIELD) { if (!nofields && var->expression.vtype == TYPE_FIELD && parser->tok != '=') {
var->isfield = true;
vec_push(parser->fields, (ast_expression*)var); vec_push(parser->fields, (ast_expression*)var);
util_htset(parser->htfields, var->name, var); util_htset(parser->htfields, var->name, var);
if (isvector) { if (isvector) {
@ -3900,7 +3901,10 @@ skipvar:
if (parser->tok == ',') if (parser->tok == ',')
goto another; goto another;
/*
if (!var || (!localblock && !nofields && basetype->expression.vtype == TYPE_FIELD)) { if (!var || (!localblock && !nofields && basetype->expression.vtype == TYPE_FIELD)) {
*/
if (!var) {
parseerror(parser, "missing comma or semicolon while parsing variables"); parseerror(parser, "missing comma or semicolon while parsing variables");
break; break;
} }
@ -4008,7 +4012,7 @@ skipvar:
if (!localblock) { if (!localblock) {
cval = (ast_value*)cexp; cval = (ast_value*)cexp;
if (!ast_istype(cval, ast_value) || !cval->hasvalue || cval->cvq != CV_CONST) if (!ast_istype(cval, ast_value) || ((!cval->hasvalue || cval->cvq != CV_CONST) && !cval->isfield))
parseerror(parser, "cannot initialize a global constant variable with a non-constant expression"); parseerror(parser, "cannot initialize a global constant variable with a non-constant expression");
else else
{ {
@ -4462,11 +4466,14 @@ bool parser_finish(const char *output)
return false; return false;
} }
} }
for (i = 0; i < vec_size(parser->globals); ++i) { for (i = 0; i < vec_size(parser->fields); ++i) {
ast_value *asvalue; ast_value *asvalue;
if (!ast_istype(parser->globals[i], ast_value)) asvalue = (ast_value*)(parser->fields[i]->expression.next);
if (!ast_istype((ast_expression*)asvalue, ast_value))
continue;
if (asvalue->expression.vtype != TYPE_ARRAY)
continue; continue;
asvalue = (ast_value*)(parser->globals[i]);
if (asvalue->setter) { if (asvalue->setter) {
if (!ast_global_codegen(asvalue->setter, ir, false) || if (!ast_global_codegen(asvalue->setter, ir, false) ||
!ast_function_codegen(asvalue->setter->constval.vfunc, ir) || !ast_function_codegen(asvalue->setter->constval.vfunc, ir) ||
@ -4488,14 +4495,11 @@ bool parser_finish(const char *output)
} }
} }
} }
for (i = 0; i < vec_size(parser->fields); ++i) { for (i = 0; i < vec_size(parser->globals); ++i) {
ast_value *asvalue; ast_value *asvalue;
asvalue = (ast_value*)(parser->fields[i]->expression.next); if (!ast_istype(parser->globals[i], ast_value))
if (!ast_istype((ast_expression*)asvalue, ast_value))
continue;
if (asvalue->expression.vtype != TYPE_ARRAY)
continue; continue;
asvalue = (ast_value*)(parser->globals[i]);
if (asvalue->setter) { if (asvalue->setter) {
if (!ast_global_codegen(asvalue->setter, ir, false) || if (!ast_global_codegen(asvalue->setter, ir, false) ||
!ast_function_codegen(asvalue->setter->constval.vfunc, ir) || !ast_function_codegen(asvalue->setter->constval.vfunc, ir) ||