]> Nishi Git Mirror - gwion.git/commitdiff
:art: Update
authorJérémie Astor <fennecdjay@gmail.com>
Wed, 16 Dec 2020 00:29:40 +0000 (01:29 +0100)
committerJérémie Astor <fennecdjay@gmail.com>
Wed, 16 Dec 2020 00:29:40 +0000 (01:29 +0100)
26 files changed:
ast
include/import/checker.h
src/lib/array.c
src/lib/ptr.c
src/lib/tmpl_info.c
src/lib/union.c
src/parse/check.c
src/parse/operator.c
tests/error/array_cast_err.gw
tests/tree/class_named_union.gw [deleted file]
tests/tree/class_union.gw [deleted file]
tests/tree/cpy_ast.gw
tests/tree/global_named_union.gw [deleted file]
tests/tree/global_unnamed_union.gw [deleted file]
tests/tree/named_union.gw [deleted file]
tests/tree/named_union_private_static.gw [deleted file]
tests/tree/named_union_static.gw [deleted file]
tests/tree/udef.gw [deleted file]
tests/tree/union.gw [deleted file]
tests/tree/union_global.gw [deleted file]
tests/tree/union_tmpl.gw [deleted file]
tests/union/none.gw [new file with mode: 0644]
tests/union/option.gw [new file with mode: 0644]
tests/union/option_check.gw [new file with mode: 0644]
tests/union/option_invalid_runtime.gw [new file with mode: 0644]
tests/union/union.gw [new file with mode: 0644]

diff --git a/ast b/ast
index 607704e19a25cd9985506c75fe600d2a4213aba1..8fdf56e0aabe91bcaded35c38d036e81a3a34432 160000 (submodule)
--- a/ast
+++ b/ast
@@ -1 +1 @@
-Subproject commit 607704e19a25cd9985506c75fe600d2a4213aba1
+Subproject commit 8fdf56e0aabe91bcaded35c38d036e81a3a34432
index f7adeb713ccf8905886c528b2172db5e2557e535..3b81b40cf7f94b5c4082c9e33ec741848575a1d2 100644 (file)
@@ -53,6 +53,12 @@ ANN Var_Decl      str2var(const Gwion, const m_str, const loc_t);
 ANN Var_Decl_List str2varlist(const Gwion, const m_str, const loc_t);
 ANN Type_Decl*    str2td(const Gwion, const m_str, const loc_t);
 ANN Type str2type(const Gwion, const m_str, const loc_t);
+ANN static inline Type_Decl* type2td(const Gwion gwion, const Type t, const loc_t pos) {
+  const m_str str = type2str(gwion->env, t);
+  Type_Decl *td = str2td(gwion, str, pos);
+  free_mstr(gwion->mp, str);
+  return td;
+}
 
 #define gwi_str2sym(gwi, path) str2sym(gwi->gwion, path, gwi->loc)
 #define gwi_str2symlist(gwi, path) str2symlist(gwi->gwion, path, gwi->loc)
index 687e353f4a41d79303d74c026f8abd056b184888..af6d4301987c69329b1a428650a510c00070bedb 100644 (file)
@@ -272,7 +272,7 @@ static OP_CHECK(opck_array_cast) {
     r = r->info->parent;
   if(get_depth(cast->exp->info->type) == get_depth(exp_self(cast)->info->type) && isa(l->info->base_type, r->info->base_type) > 0)
     return l;
-  return env->gwion->type[et_error];
+  return NULL;
 }
 
 static OP_CHECK(opck_array_slice) {
@@ -335,6 +335,14 @@ static OP_CHECK(opck_array) {
   return check_array_access(env, &next);
 }
 
+static OP_CHECK(opck_not_array) {
+  const Array_Sub array = (Array_Sub)data;
+  if(array->depth <= get_depth(array->type))
+    return array->type;
+  ERR_N(array->exp->pos, _("array subscripts (%"UINT_F") exceeds defined dimension (%"UINT_F")"),
+         array->depth, get_depth(array->type))
+}
+
 ANN static void array_loop(const Emitter emit, const m_uint depth) {
   const Instr pre_pop = emit_add_instr(emit, RegPop);
   pre_pop->m_val = depth * SZ_INT;
@@ -432,6 +440,9 @@ GWION_IMPORT(array) {
   GWI_BB(gwi_oper_add(gwi, opck_array_slice))
   GWI_BB(gwi_oper_emi(gwi, opem_array_slice))
   GWI_BB(gwi_oper_end(gwi, "@slice", NULL))
+  GWI_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, (m_str)OP_ANY_TYPE, NULL))
+  GWI_BB(gwi_oper_add(gwi, opck_not_array))
+  GWI_BB(gwi_oper_end(gwi, "@array", NULL))
   GWI_BB(gwi_oper_ini(gwi, "int", "@Array", NULL))
   GWI_BB(gwi_oper_add(gwi, opck_array))
   GWI_BB(gwi_oper_emi(gwi, opem_array_access))
index 35127ad3960c9ec64c1ae0378034de1a087c215b..fabd8c07f3d3e239d619c68557c2377fe489a5da 100644 (file)
@@ -22,6 +22,10 @@ static m_bool ptr_access(const Env env, const Exp e) {
   ERR_B(e->pos, _("operand is %s"), access);
 }
 
+ANN static inline Type ptr_base(const Env env, const Type t) {
+  return known_type(env, t->info->cdef->base.tmpl->call->td);
+}
+
 static OP_CHECK(opck_ptr_assign) {
   const Exp_Binary* bin = (Exp_Binary*)data;
   CHECK_BO(ptr_access(env, bin->lhs))
@@ -32,10 +36,10 @@ static OP_CHECK(opck_ptr_assign) {
   do {
     Type u = bin->rhs->info->type;
     do {
-      const m_str str = get_type_name(env, u, 1);
-      if(str && !strcmp(t->name, str))
-        return bin->lhs->info->type; // use rhs?
-    } while((u = u->info->parent));
+      const Type base = ptr_base(env, u);
+      if(isa(t, base) > 0)
+        return t;
+    } while((u = u->info->parent) && u->info->cdef->base.tmpl->call);
   } while((t = t->info->parent));
   return env->gwion->type[et_error];
 }
@@ -66,8 +70,7 @@ static OP_EMIT(opem_ptr_assign) {
 
 static OP_CHECK(opck_ptr_deref) {
   const Exp_Unary* unary = (Exp_Unary*)data;
-  DECL_ON(const m_str, str, = get_type_name(env, unary->exp->info->type, 1))
-  return exp_self(unary)->info->type = nspc_lookup_type1(env->curr, insert_symbol(str));
+  return ptr_base(env, unary->exp->info->type);
 }
 
 static OP_CHECK(opck_ptr_cast) {
@@ -88,8 +91,8 @@ static OP_CHECK(opck_ptr_cast) {
 static OP_CHECK(opck_ptr_implicit) {
   const struct Implicit* imp = (struct Implicit*)data;
   const Exp e = imp->e;
-  DECL_OO(const m_str, name, = get_type_name(env, imp->t, 1))
-  if(!strcmp(get_type_name(env, imp->t, 1), e->info->type->name)) {
+  const Type base = ptr_base(env, imp->t);
+  if(isa(e->info->type, base) > 0) {
     const m_str access = exp_access(e);
     if(access)
       ERR_N(e->pos, _("can't cast %s value to Ptr"), access);
index f9297e7ee9224872ba60c140b6558a7a68529f95..535d462d6f947e7ea1688a8e6bcb22e2a0541e6e 100644 (file)
@@ -40,8 +40,9 @@ ANN static inline size_t tmpl_set(struct tmpl_info* info, const m_str str) {
 
 ANN static ssize_t template_size(const Env env, struct tmpl_info* info) {
   DECL_OB(const m_str, str, = tl2str(env, info->td->types))
+  const size_t tmpl_sz = tmpl_set(info, str);
   const m_str base = type2str(env, info->base);
-  return tmpl_set(info, str) + tmpl_set(info, base) + 4;
+  return tmpl_sz + tmpl_set(info, base) + 4;
 }
 
 ANEW ANN static Symbol _template_id(const Env env, struct tmpl_info *const info, const size_t sz) {
index f4a689132ea13b7477773705b8eb40bb9cb14802..f5d059d39a91a83f6dbb3cf068386a688dbd6a92 100644 (file)
@@ -16,6 +16,19 @@ static GACK(gack_none) {
   INTERP_PRINTF("None")
 }
 
+static OP_CHECK(opck_none) {
+  Exp_Binary *bin = (Exp_Binary*)data;
+  CHECK_NN(opck_rassign(env, data, mut))
+  exp_setvar(bin->rhs, 1);
+  return bin->rhs->info->type;
+}
+
+static OP_EMIT(opem_none) {
+  const Instr instr = emit_add_instr(emit, RegPop);
+  instr->m_val = SZ_INT;
+  return GW_OK;
+}
+
 static const f_instr dotmember[]  = { DotMember, DotMember2, DotMember3, DotMember4 };
 
 ANN Instr emit_kind(Emitter emit, const m_uint size, const uint addr, const f_instr func[]);
@@ -90,6 +103,11 @@ ANN GWION_IMPORT(union) {
   struct SpecialId_ spid = { .type=gwi->gwion->type[et_none], .exec=NoOp, .is_const=1 };
   gwi_specialid(gwi, "None", &spid);
 
+  GWI_BB(gwi_oper_ini(gwi, "None", "None", "None"))
+  GWI_BB(gwi_oper_add(gwi, opck_none))
+  GWI_BB(gwi_oper_emi(gwi, opem_none))
+  GWI_BB(gwi_oper_end(gwi, "=>", NoOp))
+
   const Type t_union = gwi_class_ini(gwi, "@Union", "Object");
   gwi_class_xtor(gwi, NULL, UnionDtor);
   GWI_BB(gwi_item_ini(gwi, "int", "@index"))
index 08b0c8c3afe5c9906cc32683af6e5b9762ae02c9..e1e5a103b015fab009d38ed799f58fb48498371d 100644 (file)
@@ -393,9 +393,9 @@ ANN static Type check_prim(const Env env, Exp_Primary *prim) {
 }
 
 ANN Type check_array_access(const Env env, const Array_Sub array) {
-  if(!get_depth(array->type))
-    ERR_O(array->exp->pos, _("array subscripts (%"UINT_F") exceeds defined dimension (%"UINT_F")"),
-        array->depth, get_depth(array->type))
+//  if(!get_depth(array->type))
+//    ERR_O(array->exp->pos, _("array subscripts (%"UINT_F") exceeds defined dimension (%"UINT_F")"),
+//        array->depth, get_depth(array->type))
   const Symbol sym = insert_symbol("@array");
   struct Op_Import opi = { .op=sym, .lhs=array->exp->info->type, .rhs=array->type,
     .pos=array->exp->pos, .data=(uintptr_t)array, .op_type=op_array };
index 93faab1980b32b94816401c46a7c84d21f17280d..291010229cb1240359dd905e19251d700fe157a8 100644 (file)
@@ -180,7 +180,7 @@ ANN Type op_check(const Env env, struct Op_Import* opi) {
         const Type ret = op_check_inner(&ock);
         if(ret) {
           if(ret == env->gwion->type[et_error])
-            break;
+            return NULL;
           if(!ock.mut)
             set_nspc(&opi2, nspc);
           return ret;
@@ -188,7 +188,6 @@ ANN Type op_check(const Env env, struct Op_Import* opi) {
       } while(l && (l = l->info->parent));
     }
   } while((nspc = nspc->parent));
-//  if(env->func && env->func->nspc)
   if(opi->op == insert_symbol(env->gwion->st, "$") && opi->rhs == opi->lhs)
     return opi->rhs;
   if(opi->op == insert_symbol(env->gwion->st, "@func_check"))
index a270eb0164a119c99d56efb6fa35637805d14b27..3e18f3a59f70a3fc06b355d68a250454fe515ded 100644 (file)
@@ -1,2 +1,2 @@
-#! [contains] no match found for operator
+#! [contains] can't cast
 <<< [ 1 ] $ int[][] >>>;
diff --git a/tests/tree/class_named_union.gw b/tests/tree/class_named_union.gw
deleted file mode 100644 (file)
index a72232b..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-class C {
-  12 => var int _i;
-  union {
-    int i;
-    float f;
-  } U;
-
-  <<< U >>>;
-  <<< U.i >>>;
-  <<< U.f >>>;
-  12 => U.i;
-  <<< U.i >>>;
-  12.3 => U.f;
-  <<< U.f >>>;
-  <<< U.i >>>;
-}
-
-var C c;
-
-<<< c >>>;
-<<< c.U >>>;
-<<< c.U.i >>>;
-<<< c.U.f >>>;
-123 => c.U.i;
-<<< c.U.i >>>;
-1.23 => c.U.f;
-<<< c.U.f >>>;
-<<< c.U.i >>>;
-<<< c._i >>>;
-
diff --git a/tests/tree/class_union.gw b/tests/tree/class_union.gw
deleted file mode 100644 (file)
index 4a27e0e..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-class C {
-       union
-       {
-         int one;
-         string two;
-       };
-       <<< one, " ", two >>>;
-}
-
index 21ebaae010f2e5975cb7485d5073c3114fb0132e..3ffd53f76d7a95b88945d39e42f109d3eecd33a3 100644 (file)
@@ -8,8 +8,8 @@ class C:[A] {
   i++;
   i ? i : !i;
   ++i;
-  union U { int }
-  union V:[A] { int }
+  union U { int i; }
+  union V:[A] { int i; }
   typeof(i);
   if(i) i; else i;
   for(var int _i; _i < 1; ++_i);
diff --git a/tests/tree/global_named_union.gw b/tests/tree/global_named_union.gw
deleted file mode 100644 (file)
index 5eb4c3a..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-union global {
-  int int_from_global_nanmed_union;
-  float float_from_global_named_union;
-} global_union;
-
-<<< "HERE", global_union >>>;
-<<< 123.456 => global_union.float_from_global_named_union >>>;
-<<< global_union.float_from_global_named_union >>>;
diff --git a/tests/tree/global_unnamed_union.gw b/tests/tree/global_unnamed_union.gw
deleted file mode 100644 (file)
index 9a1a273..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-union global {
-  int int_from_global_union;
-  float float_from_global_union;
-};
-
-<<< float_from_global_union >>>;
diff --git a/tests/tree/named_union.gw b/tests/tree/named_union.gw
deleted file mode 100644 (file)
index 0735743..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-15 => var int i;
-union {
-  int i;
-  float f;
-} U;
-7.3 => var float f;
-<<< U >>>;
-<<< U.i >>>;
-<<< U.f >>>;
-12 => U.i;
-<<< U.i >>>;
-12.3 => U.f;
-<<< U.f >>>;
-<<< U.i >>>;
-<<< i >>>;
-<<< f >>>;
diff --git a/tests/tree/named_union_private_static.gw b/tests/tree/named_union_private_static.gw
deleted file mode 100644 (file)
index 1e59832..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-class C {
-  union private static {
-    int i;
-  } u;
-  <<< this, " ", u, " ", this.u.i >>>;
-}
-
-var C c;
-<<< c >>>;
diff --git a/tests/tree/named_union_static.gw b/tests/tree/named_union_static.gw
deleted file mode 100644 (file)
index 549480c..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-class C {
-  union static {
-    int i;
-  } u;
-  <<< this, " ", u, " ", this.u.i >>>;
-}
-
-var C c;
-<<< c >>>;
-<<< C.u >>>;
-<<< C.u.i >>>;
diff --git a/tests/tree/udef.gw b/tests/tree/udef.gw
deleted file mode 100644 (file)
index 9f08d2d..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-class C {
-  union static { int : float }
-}
diff --git a/tests/tree/union.gw b/tests/tree/union.gw
deleted file mode 100644 (file)
index fb01c1f..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-union U { int : string };
-<<< one, " ", two >>>;
diff --git a/tests/tree/union_global.gw b/tests/tree/union_global.gw
deleted file mode 100644 (file)
index 5c31d32..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-union global GlobalUnion { int : float };
-<<<"test">>>;
diff --git a/tests/tree/union_tmpl.gw b/tests/tree/union_tmpl.gw
deleted file mode 100644 (file)
index f4b22ea..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-union U:[A]{ int : A }
-
-var U:[float] u;
-<<< u.a >>>;
diff --git a/tests/union/none.gw b/tests/union/none.gw
new file mode 100644 (file)
index 0000000..1bb4787
--- /dev/null
@@ -0,0 +1 @@
+None => None;
diff --git a/tests/union/option.gw b/tests/union/option.gw
new file mode 100644 (file)
index 0000000..d5c1c56
--- /dev/null
@@ -0,0 +1,4 @@
+#! [contains] 12
+var int? i;
+<<< 12 => i.val >>>;
+<<< i.val >>>;
diff --git a/tests/union/option_check.gw b/tests/union/option_check.gw
new file mode 100644 (file)
index 0000000..81ed999
--- /dev/null
@@ -0,0 +1,9 @@
+#! [contains] 12
+var int? i;
+
+<<< 12 => i.val >>>;
+if(i.is(val))
+  <<< i.val >>>;
+#!<<< None => i.none >>>;
+#!if(i.is(none))
+#!  <<< "option unset" >>>;
diff --git a/tests/union/option_invalid_runtime.gw b/tests/union/option_invalid_runtime.gw
new file mode 100644 (file)
index 0000000..b83406d
--- /dev/null
@@ -0,0 +1,3 @@
+#! [contains] invalid union acces
+var int? i;
+<<< i.val >>>;
diff --git a/tests/union/union.gw b/tests/union/union.gw
new file mode 100644 (file)
index 0000000..88d47c2
--- /dev/null
@@ -0,0 +1,10 @@
+union U {
+  int i;
+  float f;
+}
+
+var U u;
+<<< u.i >>>;
+
+<<< u.f >>>;
+