[qfcc] Update generic handling for the new type scheme

And clean up some redundant (premature!) spec processing.
This commit is contained in:
Bill Currie 2025-01-03 21:24:44 +09:00
parent ae4c107384
commit ea3198e8fe
5 changed files with 22 additions and 8 deletions

View file

@ -1158,6 +1158,7 @@ const expr_t *gather_factors (const type_t *type, int op,
const expr_t **factors, int count);
typedef struct rua_ctx_s rua_ctx_t;
void decl_process (const expr_t *expr, rua_ctx_t *ctx);
const expr_t *expr_process (const expr_t *expr, rua_ctx_t *ctx);
specifier_t spec_process (specifier_t spec, rua_ctx_t *ctx);
bool can_inline (const expr_t *expr, symbol_t *fsym);

View file

@ -217,6 +217,7 @@ typedef struct rua_ctx_s {
struct rua_extra_s *extra;
void *scanner;
language_t *language;
bool extdecl;
} rua_ctx_t;
extern language_t lang_ruamoko;

View file

@ -758,7 +758,7 @@ proc_decl (const expr_t *expr, rua_ctx_t *ctx)
}
auto spec = decl_spec;
spec.sym = sym;
if (spec.type_list) {
if (!ctx->extdecl && spec.type_list) {
// to get here, a concrete declaration is being made
spec.is_generic = false;
spec = spec_process (spec, ctx);
@ -911,3 +911,11 @@ expr_process (const expr_t *expr, rua_ctx_t *ctx)
}
return proc;
}
void
decl_process (const expr_t *expr, rua_ctx_t *ctx)
{
ctx->extdecl = true;
expr_process (expr, ctx);
ctx->extdecl = false;
}

View file

@ -290,7 +290,7 @@ parse_generic_function (const char *name, specifier_t spec, rua_ctx_t *ctx)
}
// fake parameter for the return type
param_t ret_param = {
.next = spec.sym->params,
.next = spec.params,
.type = spec.type,
.type_expr = spec.type_expr,
};
@ -352,6 +352,10 @@ parse_generic_function (const char *name, specifier_t spec, rua_ctx_t *ctx)
}
}
auto type = new_type ();
*type = type_func;
spec.sym->type = type;
num_params = 0;
// skip return type so it can be done last to support complex expressions
for (auto p = ret_param.next; p; p = p->next) {

View file

@ -760,9 +760,9 @@ fndef
;
datadef
: defspecs notype_initdecls ';' { expr_process ($2, ctx); }
| declspecs_nots notype_initdecls ';' { expr_process ($2, ctx); }
| declspecs_ts initdecls ';' { expr_process ($2, ctx); }
: defspecs notype_initdecls ';' { decl_process ($2, ctx); }
| declspecs_nots notype_initdecls ';' { decl_process ($2, ctx); }
| declspecs_ts initdecls ';' { decl_process ($2, ctx); }
| declspecs_ts qc_func_params
{
$<spec>$ = qc_function_spec ($1, $2);
@ -1204,7 +1204,7 @@ save_storage
function_body
: method_optional_state_expr[state]
{
specifier_t spec = spec_process ($<spec>0, ctx);
specifier_t spec = $<spec>0;
spec.is_overload |= ctx->language->always_overload;
spec.sym = function_symbol (spec, ctx);
$<spec>$ = spec;
@ -1230,7 +1230,7 @@ function_body
}
| '=' '#' expr ';'
{
specifier_t spec = spec_process ($<spec>0, ctx);
specifier_t spec = $<spec>0;
const expr_t *bi_val = expr_process ($3, ctx);
spec.is_overload |= ctx->language->always_overload;
@ -1239,7 +1239,7 @@ function_body
}
| '=' intrinsic
{
specifier_t spec = spec_process ($<spec>0, ctx);
specifier_t spec = $<spec>0;
build_intrinsic_function (spec, $2, ctx);
}
;