Use special treatment for .float ()foo; functions.

The parser wants to treat .float () foo; as a function returning a float
field, but qcc treats it as a field holding a function variable.
Fortuantely, field types are always "simple" (ie, at worst, just more
field type wrappers around the non-field type), so all that's needed to
obtain qcc grammar is to reach into the field type layers and do the
function type calculation based on the non-field type found there.
This commit is contained in:
Bill Currie 2011-02-22 08:54:01 +09:00
parent 96c6b31c66
commit 87b240f469
2 changed files with 29 additions and 6 deletions

View file

@ -310,8 +310,14 @@ external_def
| optional_specifiers ';' { } | optional_specifiers ';' { }
| optional_specifiers qc_func_params | optional_specifiers qc_func_params
{ {
type_t **type;
$<spec>$ = $1; // copy spec bits and storage $<spec>$ = $1; // copy spec bits and storage
$<spec>$.type = parse_params ($1.type, $2), st_global, 0; // .float () foo; is a field holding a function variable rather
// than a function that returns a float field.
for (type = &$<spec>$.type; *type && (*type)->type == ev_field;
type = &(*type)->t.fldptr.type)
;
*type = parse_params (*type, $2);
$<spec>$.type = find_type ($<spec>$.type); $<spec>$.type = find_type ($<spec>$.type);
$<spec>$.params = $2; $<spec>$.params = $2;
} }
@ -447,10 +453,13 @@ type_specifier
{ {
$$ = make_spec ($1->type, current_storage, 0, 0); $$ = make_spec ($1->type, current_storage, 0, 0);
} }
// NOTE: fields don't parse the way they should // NOTE: fields don't parse the way they should. This is not a problem
// for basic types, but functions need special treatment
| '.' type_specifier | '.' type_specifier
{ {
$$ = make_spec (field_type ($2.type), current_storage, 0, 0); // avoid find_type()
$$ = make_spec (field_type (0), current_storage, 0, 0);
$$.type = append_type ($$.type, $2.type);
} }
; ;
@ -704,15 +713,20 @@ qc_param_decl
} }
| type qc_func_params NAME | type qc_func_params NAME
{ {
$3->type = parse_params ($1.type, $2); type_t **type;
$3->type = find_type ($3->type); // .float () foo; is a field holding a function variable rather
// than a function that returns a float field.
for (type = &$1.type; *type && (*type)->type == ev_field;
type = &(*type)->t.fldptr.type)
;
*type = parse_params (*type, $2);
$3->type = find_type ($1.type);
$3->params = $2; $3->params = $2;
$$ = new_param (0, $3->type, $3->name); $$ = new_param (0, $3->type, $3->name);
} }
| ELLIPSIS { $$ = new_param (0, 0, 0); } | ELLIPSIS { $$ = new_param (0, 0, 0); }
; ;
//FIXME type construction is inside-out
abs_decl abs_decl
: /* empty */ { $$ = new_symbol (""); } : /* empty */ { $$ = new_symbol (""); }
| '(' abs_decl ')' function_params | '(' abs_decl ')' function_params

View file

@ -0,0 +1,9 @@
.float x;
.vector v;
.void (float y) func;
void (entity ent) foo =
{
ent.x = ent.v * ent.v;
ent.func (ent.v * ent.v);
};