diff --git a/ruamoko/lib/Entity.r b/ruamoko/lib/Entity.r index 9816d1fb9..1d24aed1a 100644 --- a/ruamoko/lib/Entity.r +++ b/ruamoko/lib/Entity.r @@ -9,7 +9,7 @@ typedef void () void_function; int PR_SetField (entity ent, string field, string value) = #0; -@function PR_FindFunction (string func) = #0; +@function(void) PR_FindFunction (string func) = #0; @static void ParseEntities (string ent_data); @@ -80,7 +80,7 @@ int PR_SetField (entity ent, string field, string value) = #0; local int count; local string field, value; local plitem_t *keys; - local @function func; + local @function(void) func; local Entity *e; classname = PL_String (PL_ObjectForKey (dict, "classname")); diff --git a/tools/qfcc/source/expr_type.c b/tools/qfcc/source/expr_type.c index 4b95a7b7a..98b63147f 100644 --- a/tools/qfcc/source/expr_type.c +++ b/tools/qfcc/source/expr_type.c @@ -171,6 +171,18 @@ evaluate_int_op (int arg_count, const expr_t **args) return evaluate_int (args[0]); } +static const type_t * +resolve_function (int arg_count, const expr_t **args) +{ + return &type_func;//FIXME + auto type = resolve_type (args[0]); + if (type) { + type = field_type (type); + type = find_type (type); + } + return type; +} + static const type_t * resolve_field (int arg_count, const expr_t **args) { @@ -312,6 +324,11 @@ resolve_float (int arg_count, const expr_t **args) } static type_func_t type_funcs[] = { + [QC_AT_FUNCTION - QC_GENERIC] = { + .name = "@function", + .check_params = single_type, + .resolve = resolve_function, + }, [QC_AT_FIELD - QC_GENERIC] = { .name = "@field", .check_params = single_type, @@ -386,7 +403,8 @@ type_function (int op, const expr_t *params) const expr_t *args[arg_count]; list_scatter (¶ms->list, args); unsigned ind = op - QC_GENERIC; - if (ind >= sizeof (type_funcs) / sizeof (type_funcs[0])) { + if (ind >= sizeof (type_funcs) / sizeof (type_funcs[0]) + || !type_funcs[ind].name) { internal_error (params, "invalid type op: %d", op); } const char *msg = type_funcs[ind].check_params (arg_count, args); @@ -428,7 +446,8 @@ resolve_type (const expr_t *te) } int op = te->typ.op; unsigned ind = op - QC_GENERIC; - if (ind >= sizeof (type_funcs) / sizeof (type_funcs[0])) { + if (ind >= sizeof (type_funcs) / sizeof (type_funcs[0]) + || !type_funcs[ind].name) { internal_error (te, "invalid type op: %d", op); } int arg_count = list_count (&te->typ.params->list); @@ -445,7 +464,8 @@ evaluate_type (const expr_t *te) } int op = te->typ.op; unsigned ind = op - QC_GENERIC; - if (ind >= sizeof (type_funcs) / sizeof (type_funcs[0])) { + if (ind >= sizeof (type_funcs) / sizeof (type_funcs[0]) + || !type_funcs[ind].name) { internal_error (te, "invalid type op: %d", op); } int arg_count = list_count (&te->typ.params->list); diff --git a/tools/qfcc/source/qc-parse.y b/tools/qfcc/source/qc-parse.y index a61ab0561..0e9c2ea4d 100644 --- a/tools/qfcc/source/qc-parse.y +++ b/tools/qfcc/source/qc-parse.y @@ -161,7 +161,7 @@ int yylex (YYSTYPE *yylval, YYLTYPE *yylloc); %token PROTECTED PROTOCOL PUBLIC SELECTOR REFERENCE SELF THIS %token GENERIC -%token AT_FIELD AT_POINTER AT_ARRAY +%token AT_FUNCTION AT_FIELD AT_POINTER AT_ARRAY %token AT_BASE AT_WIDTH AT_VECTOR AT_ROWS AT_COLS AT_MATRIX %token AT_INT AT_UINT AT_BOOL AT_FLOAT @@ -1105,6 +1105,7 @@ type_function type_func : AT_FIELD { $$ = QC_AT_FIELD; } + | AT_FUNCTION { $$ = QC_AT_FUNCTION; } | AT_POINTER { $$ = QC_AT_POINTER; } | AT_ARRAY { $$ = QC_AT_ARRAY; } | AT_BASE { $$ = QC_AT_BASE; } @@ -2689,7 +2690,6 @@ static keyword_t qf_keywords[] = { {"long", QC_TYPE_SPEC, .spec = { .is_long = true } }, {"short", QC_TYPE_SPEC, .spec = { .is_short = true } }, - {"@function", QC_TYPE_SPEC, .spec = { .type = &type_func } }, {"@args", QC_ARGS, }, {"@va_list", QC_TYPE_SPEC, .spec = { .type = &type_va_list } }, {"@param", QC_TYPE_SPEC, .spec = { .type = &type_param } }, @@ -2706,6 +2706,7 @@ static keyword_t qf_keywords[] = { {"@undual", QC_UNDUAL, }, {"@generic", QC_GENERIC, }, + {"@function", QC_AT_FUNCTION, }, {"@field", QC_AT_FIELD, }, {"@pointer", QC_AT_POINTER, }, {"@array", QC_AT_ARRAY, },