--- /dev/null
+spread_class borked
+
+
+class C {
+ <<<var float f>>>;
+ <<<var int i>>>;
+#!<<< f >>>;
+#!<<< i >>>;
+}
+
+
+new C;
+var C c;
+
+
-Subproject commit 0fc5575bcf9215b59c7b4723c7efd55615217c02
+Subproject commit a9c86cda990ff3e065dedf2b02c2843d42016f65
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:
UnionMember3~u~u
UnionMember4~u~u
DotStatic~p
-DotStatic2~p
+DotStatic2~f
DotStatic3~p~u
DotFunc~u~u
GackType
}
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;
}
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);
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);
// 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;
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);
}
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);
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;
--- /dev/null
+fun void foo:[const float N]() {
+ <<< N >>>;
+}
+foo:[2.6]();
--- /dev/null
+#![contains] 43.2
+class Foo:[const float N] {
+ <<< N >>>;
+}
+new Foo:[43.2];
--- /dev/null
+#![contains] invalid type for const generic argument
+class Foo:[const float N] {
+ <<< N >>>;
+}
+new Foo:[2];
--- /dev/null
+#![contains] 2.6
+fun void foo:[const float N]() {
+ <<< N >>>;
+}
+foo:[2.6]();
+foo:[2.7]();
--- /dev/null
+#![contains] invalid type for const generic argument
+fun void foo:[const float N]() {
+ <<< N >>>;
+}
+foo:[2]();
--- /dev/null
+#! [contains] invalid const expression in variadic template
+class C:[...] {
+ ... T : arg {
+ var T arg;
+ }...
+
+ ... T : arg {
+ <<< "${T} ${arg}" >>>;
+ }...
+}
+
+var C:[float, int, 2] ci;
--- /dev/null
+#![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);
+
class C:[...] {
... T : arg {
- var T arg;
+ zvar T arg;
}...