]> Nishi Git Mirror - gwion.git/commitdiff
:fire: more on const generics and spread
authorfennecdjay <fennecdjay@gmail.com>
Thu, 1 Feb 2024 12:10:37 +0000 (13:10 +0100)
committerfennecdjay <fennecdjay@gmail.com>
Thu, 1 Feb 2024 12:10:37 +0000 (13:10 +0100)
18 files changed:
NOTES [new file with mode: 0644]
ast
include/opcode.h
opcode.txt
src/emit/comptime.c
src/emit/emit.c
src/parse/check.c
src/parse/func_resolve_tmpl.c
src/parse/spread.c
src/parse/template.c
tests/const_generics/const_generics.gw [new file with mode: 0644]
tests/const_generics/const_generics_class.gw [new file with mode: 0644]
tests/const_generics/const_generics_class_wrong_type.gw [new file with mode: 0644]
tests/const_generics/const_generics_func.gw [new file with mode: 0644]
tests/const_generics/const_generics_func_wrong_type.gw [new file with mode: 0644]
tests/spread/spread_class_invalid_exp.gw [new file with mode: 0644]
tests/spread/spread_func_invalid_exp.gw [new file with mode: 0644]
tests/spread/spread_syntax_error.gw [moved from tests/spread/spread_error.gw with 90% similarity]

diff --git a/NOTES b/NOTES
new file mode 100644 (file)
index 0000000..7df0065
--- /dev/null
+++ b/NOTES
@@ -0,0 +1,15 @@
+spread_class borked
+
+
+class C {
+  <<<var float f>>>;
+  <<<var int i>>>;
+#!<<< f >>>;
+#!<<< i >>>;
+}
+
+
+new C;
+var C c;
+
+
diff --git a/ast b/ast
index 0fc5575bcf9215b59c7b4723c7efd55615217c02..a9c86cda990ff3e065dedf2b02c2843d42016f65 160000 (submodule)
--- a/ast
+++ b/ast
@@ -1 +1 @@
-Subproject commit 0fc5575bcf9215b59c7b4723c7efd55615217c02
+Subproject commit a9c86cda990ff3e065dedf2b02c2843d42016f65
index 537955ef09ae6527d9b9fbba4a9ac3bee1ed39f7..9482f57d6b6998f2e222126a2b77d3b230c9dbab 100644 (file)
@@ -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:
index ba0271d803d84a7c048cc8d240d012d9e6a7b8b7..fa379710289da9be2b88e8b22d5b06d728344111 100644 (file)
@@ -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
index feb8877cdb54de8ef9682577a0952039f620a3fc..0206a9528fdddbde6c577de089f026b8b72d2ed4 100644 (file)
@@ -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;
 }
index 296df6bb1b69f322d3675510389295fda2940f3a..6b99fe65793c168046b99e8d072d7803634cb478 100644 (file)
@@ -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);
index ff04cdf0c10803fc566180a110862455a4ea37e0..3291536fdaf6834d4567abef507a92798b17d49d 100644 (file)
@@ -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;
index ea64b4559856d4edfe899bacbcfbf4426cfdf9fc..bf7f3354888784bcf2c8ba32516de659523d1aea 100644 (file)
@@ -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);
     }
index e01f7b14a7988a3eab4ddd8191788509fbb23878..10ec359b9846023bec3dcf0091524ae8ffd037a8 100644 (file)
@@ -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);
index 17f581d3966cbdd5dd50ea39b8d1b9700abce437..a3aeb904661783bc2ec240fb589941215678b806 100644 (file)
@@ -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 (file)
index 0000000..89ae715
--- /dev/null
@@ -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 (file)
index 0000000..98b71b9
--- /dev/null
@@ -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 (file)
index 0000000..80e137f
--- /dev/null
@@ -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 (file)
index 0000000..ac39a06
--- /dev/null
@@ -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 (file)
index 0000000..2471a9e
--- /dev/null
@@ -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 (file)
index 0000000..e73729b
--- /dev/null
@@ -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 (file)
index 0000000..1528017
--- /dev/null
@@ -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);
+
similarity index 90%
rename from tests/spread/spread_error.gw
rename to tests/spread/spread_syntax_error.gw
index 2bf50fb7e95f194a7a64e3ba744eb2fe7690fb77..b5903bdf1a447943f656026a30cb221a51d9fa2f 100644 (file)
@@ -3,7 +3,7 @@
 class C:[...] {
 
   ... T : arg {
-    var T arg;
+    zvar T arg;
   }...