From: fennecdjay Date: Thu, 1 Feb 2024 12:10:37 +0000 (+0100) Subject: :fire: more on const generics and spread X-Git-Tag: nightly~106 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=70de89c30572ef79ebe6065cd5631df9a91fcc29;p=gwion.git :fire: more on const generics and spread --- diff --git a/NOTES b/NOTES new file mode 100644 index 00000000..7df00653 --- /dev/null +++ b/NOTES @@ -0,0 +1,15 @@ +spread_class borked + + +class C { + <<>>; + <<>>; +#!<<< f >>>; +#!<<< i >>>; +} + + +new C; +var C c; + + diff --git a/ast b/ast index 0fc5575b..a9c86cda 160000 --- a/ast +++ b/ast @@ -1 +1 @@ -Subproject commit 0fc5575bcf9215b59c7b4723c7efd55615217c02 +Subproject commit a9c86cda990ff3e065dedf2b02c2843d42016f65 diff --git a/include/opcode.h b/include/opcode.h index 537955ef..9482f57d 100644 --- a/include/opcode.h +++ b/include/opcode.h @@ -1389,7 +1389,7 @@ ANN static inline void dump_opcodes(const VM_Code code) { break; case eDotStatic2: gw_out("{Y}┃{0}{-}% 4lu{0}: DotStatic2 ", j); - gw_out(" {-R}%-14p{0}", instr->m_val); + gw_out(" {-R}%-14f", instr->f); gw_out("\n"); break; case eDotStatic3: diff --git a/opcode.txt b/opcode.txt index ba0271d8..fa379710 100644 --- a/opcode.txt +++ b/opcode.txt @@ -199,7 +199,7 @@ UnionMember2~u~u UnionMember3~u~u UnionMember4~u~u DotStatic~p -DotStatic2~p +DotStatic2~f DotStatic3~p~u DotFunc~u~u GackType diff --git a/src/emit/comptime.c b/src/emit/comptime.c index feb8877c..0206a952 100644 --- a/src/emit/comptime.c +++ b/src/emit/comptime.c @@ -21,13 +21,10 @@ ANN2(1) void comptime_end(const Emitter emit, const size_t size, void *data) { } const VM *vm = emit->gwion->vm; const VM_Code code = finalyze(emit, EOC); // } new code - const VM_Shred shred = vm->cleaner_shred; - shred->code = code; - shred->info->me->ref++; - shredule(vm->shreduler, shred, 0); + const VM_Shred shred = new_vm_shred(emit->gwion->mp, code); + vm_add_shred(vm, shred); const bool loop = vm->shreduler->loop; vm_run(vm); - shred->code = NULL; vm->bbq->is_running = true; vm->shreduler->loop = loop; } diff --git a/src/emit/emit.c b/src/emit/emit.c index 296df6bb..6b99fe65 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -2830,39 +2830,22 @@ ANN static m_bool _emit_func_def(const Emitter emit, const Func_Def f) { const uint global = GET_FLAG(f->base, global); const m_uint scope = !global ? emit->env->scope->depth : env_push_global(emit->env); - if(fdef->base->tmpl) { // check is call? + if(fdef->base->tmpl) { if(tmplarg_ntypes(fdef->base->tmpl->call) != fdef->base->tmpl->call->len) { emit_push_code(emit, "function const generic"); -uint32_t size = 0; -// create new code here + uint32_t size = 0; for(uint32_t i = 0; i < fdef->base->tmpl->call->len; i++) { TmplArg *targ = mp_vector_at(fdef->base->tmpl->call, TmplArg, i); if(targ->type == tmplarg_td)continue; // spec could be null cause of spread ops Specialized *spec = mp_vector_at(fdef->base->tmpl->list, Specialized, i); if(!spec) break; -CHECK_BB(emit_exp(emit, targ->d.exp)); -//oemit_regmove(emit, -targ->d.exp->type->size); -//emit_regmove(emit, -SZ_INT); -//pop_exp(emit, targ->d.exp); -size += targ->d.exp->type->size; + CHECK_BB(emit_exp(emit, targ->d.exp)); + size += targ->d.exp->type->size; } -// set variables values -// and remove code -//emit_regmove(emit, -size); -fdef->base->func->value_ref->type->nspc->class_data_size = size; -fdef->base->func->value_ref->type->nspc->class_data = _mp_malloc(emit->gwion->mp, size); -comptime_end(emit, size, fdef->base->func->value_ref->type->nspc->class_data); -//const Instr instr = emit_add_instr(emit, ConstGenericEOC); -//instr->m_val = size; -//instr->m_val2 = (m_uint)fdef->base->func->value_ref->type->nspc->class_data; -//const VM_Code code = finalyze(emit, EOC); -//const VM_Shred shred = new_vm_shred(emit->gwion->mp, code); -//vm_add_shred(emit->gwion->vm, shred); -//const bool loop = emit->gwion->vm->shreduler->loop; -//vm_run(emit->gwion->vm); -//emit->gwion->vm->bbq->is_running = true; -//emit->gwion->vm->shreduler->loop = loop; + fdef->base->func->value_ref->type->nspc->class_data_size = size; + fdef->base->func->value_ref->type->nspc->class_data = _mp_malloc(emit->gwion->mp, size); + comptime_end(emit, size, fdef->base->func->value_ref->type->nspc->class_data); } } emit_func_def_init(emit, func); diff --git a/src/parse/check.c b/src/parse/check.c index ff04cdf0..3291536f 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -1871,7 +1871,7 @@ ANN static void fdef_const_generic_value(const Env env, const Type owner, const v->from->owner_class = owner; } -ANN static m_bool fdef_const_generic_typecheck(const Env env, const Specialized *spec, const TmplArg *targ) { +ANN m_bool const_generic_typecheck(const Env env, const Specialized *spec, const TmplArg *targ) { CHECK_OB(check_exp(env, targ->d.exp)); // check implicits? const Type target = known_type(env, spec->td); @@ -1899,7 +1899,7 @@ ANN static m_bool check_fdef_const_generic(const Env env, const Func_Def fdef) { // spec could be null cause of spread ops const Specialized *spec = mp_vector_at(fdef->base->tmpl->list, Specialized, i); if(!spec) break; - CHECK_BB(fdef_const_generic_typecheck(env, spec, targ)); + CHECK_BB(const_generic_typecheck(env, spec, targ)); fdef_const_generic_value(env, t, targ->d.exp->type, spec->tag); } return GW_OK; diff --git a/src/parse/func_resolve_tmpl.c b/src/parse/func_resolve_tmpl.c index ea64b455..bf7f3354 100644 --- a/src/parse/func_resolve_tmpl.c +++ b/src/parse/func_resolve_tmpl.c @@ -107,9 +107,17 @@ ANN static Func create_tmpl(const Env env, struct ResolverArgs *ra, if(is_spread_tmpl(value->d.func_ref->def->base->tmpl)) { Arg_List args = fdef->base->args ?: new_mp_vector(env->gwion->mp, Arg, 0); for(uint32_t idx = 0; idx < ra->types->len; idx++) { +// for(uint32_t idx = value->d.func_ref->def->base->tmpl->call->len - 1; idx < ra->types->len; idx++) { char c[256]; sprintf(c, "arg%u", idx); TmplArg targ = *mp_vector_at(ra->types, TmplArg, idx); + if(targ.type != tmplarg_td) { + gwerr_basic("invalid const expression in variadic template", NULL, "can't use expression in spread", env->name, targ.d.exp->loc, 0); + Specialized *spec = mp_vector_at(value->d.func_ref->def->base->tmpl->list, Specialized, value->d.func_ref->def->base->tmpl->list->len - 1); + gwerr_secondary("spread starts here", env->name, spec->tag.loc); + env_set_error(env, true); + return NULL; + } Arg arg = { .var = MK_VAR(cpy_type_decl(env->gwion->mp, targ.d.td), (Var_Decl){ .tag = MK_TAG(insert_symbol(c), fdef->base->tag.loc)})}; mp_vector_add(env->gwion->mp, &args, Arg, arg); } diff --git a/src/parse/spread.c b/src/parse/spread.c index e01f7b14..10ec359b 100644 --- a/src/parse/spread.c +++ b/src/parse/spread.c @@ -18,8 +18,14 @@ ANN m_bool spread_ast(const Env env, const Spread_Def spread, const Tmpl *tmpl) for(uint32_t i = tmpl->list->len - 1; i < tmpl->call->len; i++) { fseek(f, 0, SEEK_SET); const TmplArg targ = *mp_vector_at(tmpl->call, TmplArg, i); - // post spread const expression won't reach here assert(targ.type == tmplarg_td); + if(targ.type != tmplarg_td) { + gwerr_basic("invalid const expression in variadic template", NULL, "can't use expression in spread", env->name, targ.d.exp->loc, 0); + Specialized *spec = mp_vector_at(tmpl->list, Specialized, tmpl->list->len - 1); + gwerr_secondary("spread starts here", env->name, spec->tag.loc); + env_set_error(env, true); + return GW_ERROR; + } DECL_OB(const Type, t, = known_type(env, targ.d.td)); struct AstGetter_ arg = {env->name, f, env->gwion->st, .ppa = env->gwion->ppa}; const m_str type = type2str(env->gwion, t, targ.d.td->tag.loc); diff --git a/src/parse/template.c b/src/parse/template.c index 17f581d3..a3aeb904 100644 --- a/src/parse/template.c +++ b/src/parse/template.c @@ -213,11 +213,7 @@ ANN2(1,2) m_bool check_tmpl(const Env env, const TmplArg_List tl, const Speciali ERR_B(loc, "template const argument mismatch. expected %s", spec->td ? "constant" : "type"); } - DECL_OB(const Type, t, = known_type(env, spec->td)); - CHECK_OB(check_exp(env, arg->d.exp)); - if(isa(arg->d.exp->type, t) < 0) - ERR_B(loc, "invalid type %s for template argument. expected %s", - arg->d.exp->type->name, t->name); + CHECK_BB(const_generic_typecheck(env, spec, targ)); } } return GW_OK; diff --git a/tests/const_generics/const_generics.gw b/tests/const_generics/const_generics.gw new file mode 100644 index 00000000..89ae7156 --- /dev/null +++ b/tests/const_generics/const_generics.gw @@ -0,0 +1,4 @@ +fun void foo:[const float N]() { + <<< N >>>; +} +foo:[2.6](); diff --git a/tests/const_generics/const_generics_class.gw b/tests/const_generics/const_generics_class.gw new file mode 100644 index 00000000..98b71b97 --- /dev/null +++ b/tests/const_generics/const_generics_class.gw @@ -0,0 +1,5 @@ +#![contains] 43.2 +class Foo:[const float N] { + <<< N >>>; +} +new Foo:[43.2]; diff --git a/tests/const_generics/const_generics_class_wrong_type.gw b/tests/const_generics/const_generics_class_wrong_type.gw new file mode 100644 index 00000000..80e137fd --- /dev/null +++ b/tests/const_generics/const_generics_class_wrong_type.gw @@ -0,0 +1,5 @@ +#![contains] invalid type for const generic argument +class Foo:[const float N] { + <<< N >>>; +} +new Foo:[2]; diff --git a/tests/const_generics/const_generics_func.gw b/tests/const_generics/const_generics_func.gw new file mode 100644 index 00000000..ac39a06c --- /dev/null +++ b/tests/const_generics/const_generics_func.gw @@ -0,0 +1,6 @@ +#![contains] 2.6 +fun void foo:[const float N]() { + <<< N >>>; +} +foo:[2.6](); +foo:[2.7](); diff --git a/tests/const_generics/const_generics_func_wrong_type.gw b/tests/const_generics/const_generics_func_wrong_type.gw new file mode 100644 index 00000000..2471a9ef --- /dev/null +++ b/tests/const_generics/const_generics_func_wrong_type.gw @@ -0,0 +1,5 @@ +#![contains] invalid type for const generic argument +fun void foo:[const float N]() { + <<< N >>>; +} +foo:[2](); diff --git a/tests/spread/spread_class_invalid_exp.gw b/tests/spread/spread_class_invalid_exp.gw new file mode 100644 index 00000000..e73729b4 --- /dev/null +++ b/tests/spread/spread_class_invalid_exp.gw @@ -0,0 +1,12 @@ +#! [contains] invalid const expression in variadic template +class C:[...] { + ... T : arg { + var T arg; + }... + + ... T : arg { + <<< "${T} ${arg}" >>>; + }... +} + +var C:[float, int, 2] ci; diff --git a/tests/spread/spread_func_invalid_exp.gw b/tests/spread/spread_func_invalid_exp.gw new file mode 100644 index 00000000..15280174 --- /dev/null +++ b/tests/spread/spread_func_invalid_exp.gw @@ -0,0 +1,11 @@ +#![contains] invalid const expression in variadic template +fun void t:[...](int i) { + ... T : arg { + <<< "${T} ${arg}" >>>; + }... +} +t(1); +t(1, .2); +t:[float, const int, 2](2.2, 1, 3); +t:[int, float](2, 232.4); + diff --git a/tests/spread/spread_error.gw b/tests/spread/spread_syntax_error.gw similarity index 90% rename from tests/spread/spread_error.gw rename to tests/spread/spread_syntax_error.gw index 2bf50fb7..b5903bdf 100644 --- a/tests/spread/spread_error.gw +++ b/tests/spread/spread_syntax_error.gw @@ -3,7 +3,7 @@ class C:[...] { ... T : arg { - var T arg; + zvar T arg; }...