]> Nishi Git Mirror - gwion.git/commitdiff
:art: More Tagged unions
authorJérémie Astor <fennecdjay@gmail.com>
Sat, 12 Dec 2020 11:11:37 +0000 (12:11 +0100)
committerJérémie Astor <fennecdjay@gmail.com>
Sat, 12 Dec 2020 11:11:37 +0000 (12:11 +0100)
90 files changed:
ast
examples/member.gw
examples/object.gw [deleted file]
examples/op.gw
examples/static.gw
examples/string.gw
examples/union.gw [deleted file]
examples/vararg.gw
include/emit.h
include/env/env.h
include/env/type.h
include/operator.h
scripts/afl-dict/sum
src/emit/emit.c
src/env/type.c
src/env/type_special.c [deleted file]
src/import/import_checker.c
src/lib/array.c
src/lib/engine.c
src/lib/event.c
src/lib/instr.c
src/lib/lib_func.c
src/lib/lib_func.cnano [deleted file]
src/lib/object.c
src/lib/object_op.c
src/lib/opfunc.c
src/lib/prim.c
src/lib/ptr.c
src/lib/string.c
src/lib/ugen.c
src/lib/vararg.c
src/parse/check.c
src/parse/operator.c
src/parse/scan1.c
src/parse/scanx.c
src/parse/type_decl.c
tests/UsrUgen/null_tick.gw [deleted file]
tests/bug/Tester.gw [deleted file]
tests/error/array_incompatible.gw
tests/error/array_multi_except.gw [deleted file]
tests/error/connect_except.gw [deleted file]
tests/error/empty_member_ptr.gw [deleted file]
tests/error/empty_obj_data.gw [deleted file]
tests/error/ev.gw [deleted file]
tests/error/fail_assign.gw [deleted file]
tests/error/func_non.gw
tests/error/func_ptr_empty.gw [deleted file]
tests/error/if_exp_compat.gw
tests/error/non_public_typedef_global_scope.gw [deleted file]
tests/error/nonnull_class_extend.gw [deleted file]
tests/error/not_nn.gw [deleted file]
tests/error/null_array_access.gw [deleted file]
tests/error/null_array_access_multi.gw [deleted file]
tests/error/null_auto.gw [deleted file]
tests/error/op_match.gw
tests/error/union_unknown.gw
tests/interp/to_string.gw
tests/new/ref.gw
tests/nonnull/cast_non_null.gw [deleted file]
tests/nonnull/cast_non_null2.gw [deleted file]
tests/nonnull/dynamic_implicit_nonnull.gw [deleted file]
tests/nonnull/nonnull2nullable.gw [deleted file]
tests/nonnull/nonnull_assign_nonnull.gw [deleted file]
tests/nonnull/nonnull_at_nonnull.gw [deleted file]
tests/nonnull/nonnull_cast_nonnull.gw [deleted file]
tests/nonnull/nonnull_decl.gw [deleted file]
tests/nonnull/nonnull_decl_ref_assign.gw [deleted file]
tests/nonnull/nonnull_err_cast_dynamic.gw [deleted file]
tests/nonnull/nonnull_err_dynamic.gw [deleted file]
tests/nonnull/nonnull_err_static_cast.gw [deleted file]
tests/nonnull/nonnull_impl_nonnull.gw [deleted file]
tests/nonnull/nonnull_implicit_nonnull.gw [deleted file]
tests/nonnull/normal_at_nonnull.gw [deleted file]
tests/nonnull/normal_cast_nonnull.gw [deleted file]
tests/nonnull/normal_impl_nonnull.gw [deleted file]
tests/nonnull/null_at_nonnull.gw [deleted file]
tests/nonnull/null_cast_nonnull.gw [deleted file]
tests/nonnull/null_impl_nonnull.gw [deleted file]
tests/nonnull/ref.gw [deleted file]
tests/nonnull/ref_at_nonnull.gw [deleted file]
tests/nonnull/ref_cast_nonnull.gw [deleted file]
tests/nonnull/ref_impl_nonnull.gw [deleted file]
tests/nonnull/ref_nonnull.gw [deleted file]
tests/nonnull/static_implicit_nonnull.gw [deleted file]
tests/nonnull/void_nonnull.gw [deleted file]
tests/string/eq.gw
tests/tree/call_nonnull.gw [deleted file]
tests/tree/new.gw
tests/tree/set_obj.gw
tests/tree/variadic_test.gw

diff --git a/ast b/ast
index 3047b71b37f6f2416d9374da8875a7d17da0ad65..2c9e91d5b289259b22c78a2b75b34b3c4111dbc6 160000 (submodule)
--- a/ast
+++ b/ast
@@ -1 +1 @@
-Subproject commit 3047b71b37f6f2416d9374da8875a7d17da0ad65
+Subproject commit 2c9e91d5b289259b22c78a2b75b34b3c4111dbc6
index 1820dead4e3a7639d72b35e604ccbfe175613eec..b06f513debe89e95ebe18541cc636cf7dda70126 100644 (file)
@@ -19,4 +19,3 @@ var C c;
 #! write members
 <<<  12  => c.i  >>>;
 <<<  1.2 => c.f  >>>;
-<<<  null @=> c.o  >>>;
diff --git a/examples/object.gw b/examples/object.gw
deleted file mode 100644 (file)
index b134402..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-fun void test(Object o) { <<< o >>>; }
-<<< new Object  == null , " ", null => test >>>;
index 6a207eeb7a41c0cc9688aa76484250a616107011..f6a264b09281e650f4eaca56fbaa956b022036f8 100644 (file)
@@ -14,7 +14,6 @@ operator void => (Object o, C c) {
   <<< "success" >>>;
 }
 
-#!operator int plusplus(null d, int i){}
 var int i;
 var Object o;
 <<< o, " ", i >>>;
index 1287dbc8b8c6fe7886f87a301b1008154160d297..777b56f781ce0f417775bbb27931cfede7a7fa2d 100644 (file)
@@ -22,4 +22,3 @@ class C
 #! write members
 <<<  12  => C.i  >>>;
 <<<  1.2 => C.f  >>>;
-<<<  null @=> C.o  >>>;
index f6978082f0dd9770d55781ae61682043d665fb24..a0ce84bafd6ed9dd9416678be8fcddbef546639a 100644 (file)
@@ -1,4 +1,3 @@
 var string s;
 "CamelCase" => s;
 <<< "test" => s >>>;
-<<<  null @=> s  >>>; #!test me
diff --git a/examples/union.gw b/examples/union.gw
deleted file mode 100644 (file)
index b20c551..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-union
-{
-       int i;
-       Object o;
-};
-<<< i, " ", o >>>;
index 52c7014638bda2509b0b8dfcb282a8dd5eeb9a1b..6b8603f406a364ecdabb282f07305fcc658b05b2 100644 (file)
@@ -11,4 +11,4 @@ fun void test(...) {
   }
 }
 test(1);
-test(1, 2.3, null);
+test(1, 2.3, new Object);
index 9a8009ab64f927f03613122b7d3e49df3bc381a5..a3204bda5dd8218a1b07ae8169d0c1de9db57a06 100644 (file)
@@ -45,10 +45,6 @@ ANN m_uint emit_code_offset(const Emitter emit);
 ANN m_uint emit_local(const Emitter emit, const Type t);
 ANN Instr emit_exp_spork(const Emitter, const Exp_Unary*);
 ANN m_bool emit_exp(const Emitter, const Exp);
-ANN static inline void emit_except(const Emitter emit, const Type t) {
-  if(!GET_FLAG(t, nonnull))
-    emit_add_instr(emit, GWOP_EXCEPT);
-}
 ANN static inline Instr emit_gc(const Emitter emit, const m_int offset) {
   const Instr gc = emit_add_instr(emit, GcAdd);
   gc->m_val = offset;
index 2e9e5bf58adfc7b4290c0e3a6e3f00be9fb70a3f..41c76f8bd30c4afcdd8a46c765c9f287ae3d3976 100644 (file)
@@ -39,10 +39,6 @@ ANN Value mk_class(const Env env, const Type base);
 ANEW ANN m_str tl2str(const Env, const Type_List); // in type_decl.c
 ANN m_bool compat_func(const __restrict__ Func_Def, const __restrict__ Func_Def);
 ANN Type known_type(const Env env, Type_Decl*);
-__attribute__((returns_nonnull))
-ANN Type special_type(const Env, const Type, const uint);
-#define nonnul_type(a, b) special_type(a, (b), 0);
-#define force_type(a, b) special_type(a, (b), 1);
 ANN Type prim_ref(const Env env, const Type t, const Type_Decl* td);
 ANN m_bool env_access(const Env env, const ae_flag flag, const loc_t pos);
 ANN m_bool env_storage(const Env env, ae_flag flag, const loc_t pos);
index 21811c0b2f5cf9aed88668fb9763df1c7adfef0f..b40df49ecc6f87cdb69d1348e28c20c1a30339b7 100644 (file)
@@ -35,8 +35,6 @@ enum tflag {
   tflag_dtor    = 1 << 15,
   tflag_tmpl    = 1 << 16,
   tflag_typedef = 1 << 17,
-  tflag_nonnull = 1 << 18,
-  tflag_force   = 1 << 19,
 } __attribute__((packed));
 
 struct Type_ {
@@ -81,17 +79,12 @@ ANN static inline Type get_gack(Type t) {
   return t; // unreachable
 }
 
-__attribute__((returns_nonnull))
-ANN Type unflag_type(const Type t);
 __attribute__((returns_nonnull))
 ANN Type get_type(const Type t);
-ANN static inline int is_special(const Type t) {
-  return tflag(t, tflag_nonnull) || tflag(t, tflag_force);
-}
 
 typedef enum {
   et_void, et_int, et_bool, et_char, et_float,
-  et_null, et_compound, et_object, et_shred, et_fork, et_event, et_ugen, et_string, et_ptr, et_array, et_gack,
+  et_error, et_compound, et_object, et_shred, et_fork, et_event, et_ugen, et_string, et_ptr, et_array, et_gack,
   et_function, et_fptr, et_vararg, et_lambda, et_class, et_union, et_undefined, et_auto,
   MAX_TYPE
 } type_enum;
index ff2d3a6a8cfb49ddee71e3c048c79460867d8fbf..f44f404f20f1af10ee66a659681ce05d3bbce603 100644 (file)
@@ -2,15 +2,15 @@
 #define __OPERATOR
 #define OP_ANY_TYPE (Type)1
 
-#define ERR_N(a, b, ...) { env_err(env, (a), (b), ## __VA_ARGS__); return env->gwion->type[et_null]; }
-#define DECL_ON(decl, f, exp) decl f exp; { if(!f)    return env->gwion->type[et_null]; }
-#define DECL_BN(decl, f, exp) decl f exp; { if(f < 0)    return env->gwion->type[et_null]; }
-#define DECL_NN(decl, f, exp) decl f exp; { if(f == env->gwion->type[et_null]) return env->gwion->type[et_null]; }
-#define CHECK_ON(f) { if(!f)    return env->gwion->type[et_null]; }
-#define CHECK_NB(f) { if(f == env->gwion->type[et_null]) return GW_ERROR; }
-#define CHECK_NO(f) { if(f == env->gwion->type[et_null]) return NULL; }
-#define CHECK_BN(f) { if(f < 0) return env->gwion->type[et_null]; }
-#define CHECK_NN(f) { if(f == env->gwion->type[et_null]) return env->gwion->type[et_null]; }
+#define ERR_N(a, b, ...) { env_err(env, (a), (b), ## __VA_ARGS__); return env->gwion->type[et_error]; }
+#define DECL_ON(decl, f, exp) decl f exp; { if(!f)    return env->gwion->type[et_error]; }
+#define DECL_BN(decl, f, exp) decl f exp; { if(f < 0)    return env->gwion->type[et_error]; }
+#define DECL_NN(decl, f, exp) decl f exp; { if(f == env->gwion->type[et_error]) return env->gwion->type[et_error]; }
+#define CHECK_ON(f) { if(!f)    return env->gwion->type[et_error]; }
+#define CHECK_NB(f) { if(f == env->gwion->type[et_error]) return GW_ERROR; }
+#define CHECK_NO(f) { if(f == env->gwion->type[et_error]) return NULL; }
+#define CHECK_BN(f) { if(f < 0) return env->gwion->type[et_error]; }
+#define CHECK_NN(f) { if(f == env->gwion->type[et_error]) return env->gwion->type[et_error]; }
 
 typedef Type (*opck)(const Env, void*, m_bool*);
 typedef struct Instr_* (*opem)(const Emitter, void*);
index 04291c153f0f56a11b8932f3c8dfbdf8dba5c773..1795637c2f91904d7e6a579a2ba42914b80d6da3 100644 (file)
@@ -16,7 +16,6 @@ keyword_protect="protect"
 keyword_private="private"
 keyword_const="const"
 keyword_ref="ref"
-keyword_nonnull="nonnull"
 keyword_if="if"
 keyword_else="else"
 keyword_break="break"
index a7beb5ce180afeb258402509fe48491331d0b2b2..a59c34cadfa28adb456dc87735e74fc8ef0848ec 100644 (file)
@@ -224,7 +224,7 @@ ANN m_uint emit_local(const Emitter emit, const Type t) {
 ANN void emit_ext_ctor(const Emitter emit, const Type t);
 
 ANN static inline void maybe_ctor(const Emitter emit, const Type t) {
-  if(!is_special(t) && tflag(t, tflag_ctor))
+  if(tflag(t, tflag_ctor))
     emit_ext_ctor(emit, t);
 }
 
@@ -594,7 +594,7 @@ ANN static m_bool emit_interp(const Emitter emit, const Exp exp) {
     regseti(emit, (m_uint)e->info->type);
     interp_size(emit, e->info->type);
     const m_bool isobj = isa(e->info->type, emit->gwion->type[et_object]) > 0;
-    if(isobj && !tflag(e->info->type, tflag_force))
+    if(isobj && e->exp_type != ae_exp_cast)
       emit_add_instr(emit, GackType);
     const Instr instr = emit_add_instr(emit, Gack);
     instr->m_val = emit_code_offset(emit);
@@ -777,6 +777,8 @@ ANN static m_bool emit_decl(const Emitter emit, const Exp_Decl* decl) {
       CHECK_BB(emit_exp_decl_non_static(emit, decl, list->self, ref, var))
     else
       CHECK_BB(emit_exp_decl_global(emit, list->self, ref, var))
+    if(!var && !GET_FLAG(decl->td, optionnal) && (GET_FLAG(decl->td, ref) || is_fptr(emit->gwion, list->self->value->type)))
+      ERR_B(list->self->pos, "kljlkj")
   } while((list = list->next));
   return GW_OK;
 }
@@ -1015,7 +1017,6 @@ ANN static void tmpl_prelude(const Emitter emit, const Func f) {
 ANN static Instr get_prelude(const Emitter emit, const Func f) {
   const Type t = actual_type(emit->gwion, f->value_ref->type);
   if(is_fptr(emit->gwion, t)) {
-    emit_except(emit, t);
     if(f->def->base->tmpl)
       tmpl_prelude(emit, f);
   }
@@ -1319,9 +1320,7 @@ ANN static Instr _flow(const Emitter emit, const Exp e, const m_bool b) {
   emit_exp_addref1(emit, e, -exp_size(e));
   struct Op_Import opi = { .op=insert_symbol(b ? "@conditionnal" : "@unconditionnal"),
                            .rhs=e->info->type, .pos=e->pos, .data=(uintptr_t)e, .op_type=op_exp };
-  const Instr instr = op_emit(emit, &opi);
-  assert(instr != (Instr)GW_OK);
-  return instr;
+  return op_emit(emit, &opi);
 }
 #define emit_flow(emit,b) _flow(emit, b, 1)
 
@@ -1444,8 +1443,6 @@ ANN2(1) /*static */m_bool emit_exp(const Emitter emit, /* const */Exp e) {
   Exp exp = e;
   do {
     CHECK_BB(emit_exp_func[exp->exp_type](emit, &exp->d))
-    if(exp_getnonnull(exp))
-      emit_except(emit, exp->info->type);
     if(exp->info->cast_to)
       CHECK_BB(emit_implicit_cast(emit, exp, exp->info->cast_to))
   } while((exp = exp->next));
@@ -1607,7 +1604,6 @@ ANN static m_bool _emit_stmt_each(const Emitter emit, const Stmt_Each stmt, m_ui
   emit_local(emit, emit->gwion->type[et_int]);
   stmt->v->from->offset = offset + SZ_INT;
   const m_uint ini_pc  = emit_code_size(emit);
-  emit_except(emit, stmt->exp->info->type);
   const Instr loop = emit_add_instr(emit, stmt->is_ptr ? AutoLoopPtr : AutoLoop);
   const Instr end = emit_add_instr(emit, BranchEqInt);
   const m_bool ret = scoped_stmt(emit, stmt->body, 1);
index fdf63d042e86c98f7ebb47322a22d12861cb6fb6..4c1bd6217383ef2a69c1ade47dd2a9baa80ee4d7 100644 (file)
@@ -9,7 +9,7 @@
 #include "object.h"
 
 ANN static inline m_bool freeable(const Type a) {
-  return !(tflag(a, tflag_force) || tflag(a, tflag_nonnull)) && (tflag(a, tflag_tmpl) ||GET_FLAG(a, global));
+  return tflag(a, tflag_tmpl) ||GET_FLAG(a, global);
 }
 
 ANN void free_type(const Type a, struct Gwion_ *const gwion) {
diff --git a/src/env/type_special.c b/src/env/type_special.c
deleted file mode 100644 (file)
index 8a7c5cc..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-#include "gwion_util.h"
-#include "gwion_ast.h"
-#include "gwion_env.h"
-#include "vm.h"
-#include "gwion.h"
-
-static m_str const special_name[] = { "^nonnull", "^force" };
-#define SPECIAL_LEN strlen(special_name[0]) + strlen(special_name[1])
-static const enum tflag special_flag[] = { tflag_nonnull, tflag_force };
-
-typedef struct {
-  const Type    type;
-  Symbol  name;
-  enum tflag flag;
-  uint st_type;
-} SpecialType;
-
-
-ANN static Type specialtype_create(const Env env, const SpecialType *s) {
-  const Type t = type_copy(env->gwion->mp, s->type);
-  if(t->nspc)
-    nspc_addref(t->nspc);
-  t->name = s_name(s->name);
-  t->flag = s->type->flag;
-  t->tflag |= s->type->tflag | s->flag;
-  t->info->parent = unflag_type(s->type);
-  nspc_add_type_front(s->type->info->owner, s->name, t);
-  mk_class(env, t);
-  return t;
-}
-
-static inline int get_flag(const Type t, const enum tflag flag) {
-  return (t->tflag & flag) == flag;
-}
-
-
-ANN static void specialtype_flag(SpecialType *s, m_str c, const uint i) {
-  const enum tflag flag = special_flag[i];
-  if(i == s->st_type || get_flag(s->type, flag)) {
-    strcat(c, special_name[i]);
-    s->flag |= flag;
-  }
-}
-
-ANN static void specialtype_init(SymTable *st, SpecialType *s) {
-  const size_t sz = strlen(s->type->name);
-  char c[sz + SPECIAL_LEN + 1];
-  strcpy(c, s->type->name);
-  m_str flagged = strchr(c, '^');
-  if(flagged)
-    *flagged = '\0';
-  specialtype_flag(s, c, 0);
-  specialtype_flag(s, c, 1);
-  s->name = insert_symbol(st, c);
-}
-
-ANN Type special_type(const Env env, const Type t, const uint st_type) {
-  SpecialType s = { .type=t, .st_type=st_type };
-  specialtype_init(env->gwion->st, &s);
-  return nspc_lookup_type1(t->info->owner, s.name) ?:
-    specialtype_create(env, &s);
-}
index 416a22d74a7fb55ab6dca4f03659f7c653a96f7d..214fb755b7f8f89e28ffee102f2fae0f78011948 100644 (file)
@@ -202,16 +202,12 @@ ANN static Type_Decl* _str2decl(const Gwion gwion, struct td_checker *tdc) {
 }
 
 ANN Type_Decl* str2decl(const Gwion gwion, const m_str str, const loc_t pos) {
-  const ae_flag flag = strncmp(str, "nonnull ", 8) ? ae_flag_none : ae_flag_nonnull;
   struct td_checker tdc = { .str=str, .pos=pos };
-  if(flag == ae_flag_nonnull)
-    tdc.str += 8;
   DECL_OO(Type_Decl *, td, = _str2decl(gwion, &tdc))
   if(*tdc.str) {
     free_type_decl(gwion->mp, td);
     GWION_ERR_O(pos, "excedental character '%c'", *tdc.str);
   }
-  td->flag |= flag;
   return td;
 }
 
index 5580439b594c2d4820d8c2953773bfbcbc25c508..775fef1ed61dc59ba1b7b10f718d9102a72efc90 100644 (file)
@@ -48,7 +48,7 @@ void free_m_vector(MemPool p, M_Vector a) {
 }
 
 static DTOR(array_dtor) {
-  const Type t = unflag_type(o->type_ref);
+  const Type t = o->type_ref;
   if(*(void**)(o->data + SZ_INT))
     xfree(*(void**)(o->data + SZ_INT));
   struct M_Vector_* a = ARRAY(o);
@@ -115,7 +115,7 @@ static MFUN(vm_vector_rem) {
   const M_Vector v = ARRAY(o);
   if(index < 0 || (m_uint)index >= ARRAY_LEN(v))
     return;
-  const Type t = unflag_type(o->type_ref);
+  const Type t = o->type_ref;
   if(t->nspc->info->class_data_size)
     (*(f_release**)t->nspc->info->class_data)(shred, array_base(t), ARRAY_PTR(v) + index * ARRAY_SIZE(v));
   m_vector_rem(v, (vtype)index);
@@ -151,9 +151,9 @@ ANN static Type get_array_type(Type t) {
 
 static OP_CHECK(opck_array_at) {
   const Exp_Binary* bin = (Exp_Binary*)data;
-  if(opck_const_rhs(env, data, mut) == env->gwion->type[et_null])
-    return env->gwion->type[et_null];
-  if(bin->lhs->info->type != env->gwion->type[et_null]) {
+  if(opck_const_rhs(env, data, mut) == env->gwion->type[et_error])
+    return env->gwion->type[et_error];
+  if(bin->lhs->info->type != env->gwion->type[et_error]) {
     ARRAY_OPCK(bin->lhs, bin->rhs, exp_self(bin)->pos)
     if(bin->lhs->info->type->array_depth != bin->rhs->info->type->array_depth)
       ERR_N(exp_self(bin)->pos, _("array depths do not match."))
@@ -170,7 +170,7 @@ static OP_CHECK(opck_array_at) {
 
 ANN static Type check_array_shift(const Env env,
     const Exp a, const Exp b, const m_str str, const loc_t pos) {
-  if(a->info->type == env->gwion->type[et_null] &&
+  if(a->info->type == env->gwion->type[et_error] &&
       b->info->type->array_depth > 1)
     return a->info->type;
   ARRAY_OPCK(a, b, pos)
@@ -270,13 +270,12 @@ 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_null];
+  return env->gwion->type[et_error];
 }
 
 static OP_CHECK(opck_array_slice) {
   const Exp e = (Exp)data;
   exp_setmeta(exp_self(e), 1);
-  exp_setnonnull(e->d.exp_slice.base, 1);
   return e->d.exp_slice.base->info->type;
 }
 
@@ -336,7 +335,6 @@ static OP_CHECK(opck_array) {
 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;
-  emit_add_instr(emit, GWOP_EXCEPT);
   for(m_uint i = 0; i < depth - 1; ++i) {
     const Instr access = emit_add_instr(emit, ArrayAccess);
     access->m_val = i * SZ_INT;
@@ -344,7 +342,6 @@ ANN static void array_loop(const Emitter emit, const m_uint depth) {
     const Instr get = emit_add_instr(emit, ArrayGet);
     get->m_val = i * SZ_INT;
     get->m_val2 = -SZ_INT;
-    emit_add_instr(emit, GWOP_EXCEPT);
   }
   const Instr post_pop = emit_add_instr(emit, RegPop);
   post_pop->m_val = SZ_INT;
@@ -391,7 +388,7 @@ static OP_EMIT(opem_array_access) {
   info->array = next;
   return (Instr)(m_uint)(exp ? emit_array_access(emit, info) : GW_ERROR);
 }
-OP_EMIT(opem_at_object);
+
 GWION_IMPORT(array) {
   const Type t_array  = gwi_class_ini(gwi, "@Array", NULL);
   gwi->gwion->type[et_array] = t_array;
@@ -416,23 +413,19 @@ GWION_IMPORT(array) {
   GWI_BB(gwi_class_end(gwi))
   GWI_BB(gwi_oper_ini(gwi, "@Array", "@Array", NULL))
   GWI_BB(gwi_oper_add(gwi, opck_array_at))
-  GWI_BB(gwi_oper_emi(gwi, opem_at_object))
-  GWI_BB(gwi_oper_end(gwi, "@=>", ObjectAssign))
-  GWI_BB(gwi_oper_ini(gwi, "@null", "@Array", NULL))
-  GWI_BB(gwi_oper_add(gwi, opck_array_at))
   GWI_BB(gwi_oper_end(gwi, "@=>", ObjectAssign))
-  GWI_BB(gwi_oper_ini(gwi, "nonnull @Array", (m_str)OP_ANY_TYPE, NULL))
+  GWI_BB(gwi_oper_ini(gwi, "@Array", (m_str)OP_ANY_TYPE, NULL))
   GWI_BB(gwi_oper_add(gwi, opck_array_sl))
   GWI_BB(gwi_oper_emi(gwi, opem_array_sl))
   GWI_BB(gwi_oper_end(gwi, "<<", NULL))
-  GWI_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, "nonnull @Array", NULL))
+  GWI_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, "@Array", NULL))
   GWI_BB(gwi_oper_add(gwi, opck_array_sr))
   GWI_BB(gwi_oper_emi(gwi, opem_array_sr))
   GWI_BB(gwi_oper_end(gwi, ">>", NULL))
   GWI_BB(gwi_oper_ini(gwi, "@Array", "@Array", NULL))
   GWI_BB(gwi_oper_add(gwi, opck_array_cast))
   GWI_BB(gwi_oper_end(gwi, "$", NULL))
-  GWI_BB(gwi_oper_ini(gwi, "int", "nonnull @Array", "int"))
+  GWI_BB(gwi_oper_ini(gwi, "int", "@Array", "int"))
   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))
index b53a4851e5156303f7e026e1a35e3c126ac32d07..6e4f824580e64fca493d9c7444bc488ac6f6eb47 100644 (file)
@@ -99,10 +99,16 @@ static INSTR(UnionGet) {
   POP_REG(shred, SZ_INT - instr->m_val);
   memcpy(REG(-instr->m_val), o->data + SZ_INT, instr->m_val);
 }
-
+MFUN(union_is);
 static OP_EMIT(opem_dot_union) {
   Exp_Dot *dot = (Exp_Dot*)data;
   CHECK_BO(emit_exp(emit, dot->base))
+  if(isa(exp_self(dot)->info->type, emit->gwion->type[et_function]) > 0) {
+    const Func f = (Func)vector_at(&dot->t_base->nspc->info->vtable, 0);
+    const Instr instr = emit_add_instr(emit, RegPushImm);
+    instr->m_val = (m_uint)f->code;
+    return instr;
+  }
   const uint emit_var = exp_getvar(exp_self(dot));
   const Value v = nspc_lookup_value0(dot->t_base->nspc, dot->xid);
   const Instr instr = emit_add_instr(emit, !emit_var ? UnionGet : UnionSet);
index d025f7160b923c4febba3f9c6b261d58efd42856..0d7c09d4dae91f5b5224c40fea5e21eb52c33c7e 100644 (file)
@@ -60,7 +60,7 @@ GWION_IMPORT(event) {
   GWI_BB(gwi_func_ini(gwi, "void", "broadcast"))
   GWI_BB(gwi_func_end(gwi, event_broadcast, ae_flag_none))
   GWI_BB(gwi_class_end(gwi))
-  GWI_BB(gwi_oper_ini(gwi, "nonnull Event", "@now", "int"))
+  GWI_BB(gwi_oper_ini(gwi, "Event", "@now", "int"))
   GWI_BB(gwi_oper_end(gwi, "=>", EventWait))
   return GW_OK;
 }
index ffe2839b815530227f80efd562e33883d078e272..0fe1eb3bad4f7f11de82370775ae4b6025c6851d 100644 (file)
@@ -82,7 +82,7 @@ INSTR(DotTmpl) {
   struct dottmpl_ *dt = (struct dottmpl_*)instr->m_val;
   const m_str name = dt->name;
   const M_Object o = *(M_Object*)REG(-SZ_INT);
-  Type t = !tflag(o->type_ref, tflag_nonnull) ? o->type_ref : o->type_ref->info->parent;
+  Type t = o->type_ref;
   do {
     const Emitter emit = shred->info->vm->gwion->emit;
     emit->env->name = "runtime";
index e73a1de87197bcf6495e1db625ace225eefded56..9fdeaa34a5384b11fcdc7dcbc61148d57db9e144 100644 (file)
@@ -20,7 +20,7 @@ static OP_CHECK(opck_func_call) {
   e->exp_type = ae_exp_call;
   memcpy(&e->d.exp_call, &call, sizeof(Exp_Call));
   ++*mut;
-  return check_exp_call1(env, &e->d.exp_call) ?: env->gwion->type[et_null];
+  return check_exp_call1(env, &e->d.exp_call) ?: env->gwion->type[et_error];
 }
 
 static inline void fptr_instr(const Emitter emit, const Func f, const m_uint i) {
@@ -176,10 +176,8 @@ ANN m_bool check_lambda(const Env env, const Type t, Exp_Lambda *l) {
 
 ANN static m_bool fptr_do(const Env env, struct FptrInfo *info) {
   if(isa(info->exp->info->type, env->gwion->type[et_lambda]) < 0) {
-    m_bool nonnull = tflag(info->exp->info->type, tflag_nonnull);
     CHECK_BB(fptr_check(env, info))
-    DECL_OB(const Type, t, = fptr_type(env, info))
-    info->exp->info->type = !nonnull ? t : nonnul_type(env, t);
+    CHECK_OB((info->exp->info->type = fptr_type(env, info)))
     return GW_OK;
   }
   Exp_Lambda *l = &info->exp->d.exp_lambda;
@@ -190,7 +188,7 @@ static OP_CHECK(opck_auto_fptr) {
   const Exp_Binary* bin = (Exp_Binary*)data;
   // we'll only deal with auto fptr declaration
   if(bin->rhs->exp_type != ae_exp_decl && bin->rhs->d.exp_decl.td->xid != insert_symbol("auto"))
-    return env->gwion->type[et_null];
+    return env->gwion->type[et_error];
   // create a matching signature
   // TODO: we could check first if there a matching existing one
   Func_Base *const fbase = cpy_func_base(env->gwion->mp, bin->lhs->info->type->info->func->def->base);
@@ -205,7 +203,7 @@ static OP_CHECK(opck_auto_fptr) {
   type_remref(t, env->gwion);
   bin->rhs->d.exp_decl.list->self->value->type = bin->rhs->info->type = bin->rhs->d.exp_decl.type = t;
   exp_setvar(bin->rhs, 1);
-  return ret > 0 ? t : env->gwion->type[et_null];
+  return ret > 0 ? t : env->gwion->type[et_error];
 }
 
 static OP_CHECK(opck_fptr_at) {
@@ -225,13 +223,6 @@ static OP_CHECK(opck_fptr_at) {
   return bin->rhs->info->type;
 }
 
-static OP_CHECK(opck_null_fptr_at) {
-  Exp_Binary* bin = (Exp_Binary*)data;
-  CHECK_NN(opck_const_rhs(env, bin, mut))
-  exp_setvar(bin->rhs, 1);
-  return bin->rhs->info->type;
-}
-
 static OP_CHECK(opck_fptr_cast) {
   Exp_Cast* cast = (Exp_Cast*)data;
   const Type t = exp_self(cast)->info->type;
@@ -248,16 +239,15 @@ static void member_fptr(const Emitter emit) {
   dup->m_val = -SZ_INT;
 }
 
-static int is_member(const Type from, const Type to) {
-  return vflag(from->info->func->value_ref, vflag_member) &&
-    !(tflag(from, tflag_nonnull) || tflag(to, tflag_nonnull));
+static inline int is_member(const Type from) {
+  return vflag(from->info->func->value_ref, vflag_member);
 }
 
 static OP_EMIT(opem_fptr_cast) {
   const Exp_Cast* cast = (Exp_Cast*)data;
   if(exp_self(cast)->info->type->info->func->def->base->tmpl)
     fptr_instr(emit, cast->exp->info->type->info->func, 1);
-  if(is_member(cast->exp->info->type, exp_self(cast)->info->type))
+  if(is_member(cast->exp->info->type))
     member_fptr(emit);
   return (Instr)GW_OK;
 }
@@ -272,7 +262,7 @@ static OP_CHECK(opck_fptr_impl) {
 
 static OP_EMIT(opem_fptr_impl) {
   struct Implicit *impl = (struct Implicit*)data;
-  if(is_member(impl->e->info->type, impl->t))
+  if(is_member(impl->e->info->type))
     member_fptr(emit);
   if(impl->t->info->func->def->base->tmpl)
     fptr_instr(emit, ((Exp)impl->e)->info->type->info->func, 1);
@@ -297,7 +287,7 @@ ANN static Type fork_type(const Env env, const Exp_Unary* unary) {
   if(t == env->gwion->type[et_void])
     return env->gwion->type[et_fork];
   char c[21 + strlen(t->name)];
-  sprintf(c, "nonnull TypedFork:[%s]", t->name);
+  sprintf(c, "TypedFork:[%s]", t->name);
   const Type fork = env->gwion->type[et_fork];
   UNSET_FLAG(fork, final);
   const Type typed = str2type(env->gwion, "TypedFork", exp_self(unary)->pos);
@@ -359,16 +349,6 @@ GWION_IMPORT(func) {
   GWI_BB(gwi_oper_add(gwi, opck_fptr_impl))
   GWI_BB(gwi_oper_emi(gwi, opem_fptr_impl))
   GWI_BB(gwi_oper_end(gwi, "@implicit", NULL))
-  GWI_BB(gwi_oper_ini(gwi, "@null", "@func_ptr", NULL))
-  GWI_BB(gwi_oper_add(gwi, opck_null_fptr_at))
-  GWI_BB(gwi_oper_emi(gwi, opem_func_assign))
-  GWI_BB(gwi_oper_end(gwi, "@=>", NULL))
-  GWI_BB(gwi_oper_add(gwi, opck_fptr_cast))
-  GWI_BB(gwi_oper_emi(gwi, opem_fptr_cast))
-  GWI_BB(gwi_oper_end(gwi, "$", NULL))
-  GWI_BB(gwi_oper_add(gwi, opck_fptr_impl))
-  GWI_BB(gwi_oper_emi(gwi, opem_fptr_impl))
-  GWI_BB(gwi_oper_end(gwi, "@implicit", NULL))
   GWI_BB(gwi_oper_ini(gwi, NULL, (m_str)OP_ANY_TYPE, NULL))
   GWI_BB(gwi_oper_add(gwi, opck_spork))
   GWI_BB(gwi_oper_emi(gwi, opem_spork))
diff --git a/src/lib/lib_func.cnano b/src/lib/lib_func.cnano
deleted file mode 100644 (file)
index d524d5c..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-#require Std
-#require Math
-#require Modules
-
-enum Pitch { C, D, E, F, G, A, B }
-
-class MusicObject {
-  fun UGen update() {}
-  fun UGen onStart() {}
-  fun UGen onEnd() {}
-}
-
-var SinOsc osc;
-
-class MyTone extends MusicObject {
-  var float freq;
-
-  fun UGen onStart() {
-    freq => osc.freq;
-    return osc => dac;
-  }
-
-  fun UGen onEnd() {
-    return osc =< dac;
-  }
-}
-
-fun MyTone tone(float freq) {
-  var MyTone t;
-  660 => t.freq;
-  return t;
-}
-
-class Note extends MusicObject {
-  var Pitch pitch;
-  var int accidental;
-  var int octave;
-
-  
-  fun int toMidi() {
-    var int p;
-
-    match (pitch) {
-      case C: 0 => p;
-      case D: 2 => p; 
-      case E: 4 => p;
-      case F: 5 => p;
-      case G: 7 => p;
-      case A: 9 => p;
-      case B: 11 => p;
-    }
-
-    return p + (12 * (octave+1)) + accidental;
-  }
-
-  fun UGen onStart() {
-    toMidi() => Std.mtof => osc.freq;
-    return osc => dac;
-  }
-
-  fun UGen onEnd() {
-    osc =< dac;
-  }
-}
-
-fun Note note(Pitch pitch, int accidental, int octave) {
-  var Note n;
-  A => n.pitch;
-  0 => n.accidental;
-  4 => n.octave;
-  return n;
-}
-
-class Coord {
-  var dur start;
-  var dur end;
-}
-
-fun Coord coord(dur start, dur end) {
-  const Coord c;
-  start => c.start;
-  end => c.end;
-  return c;
-}
-
-class TLEvent {
-  fun dur getStart() {}
-  fun void doIt() {}
-}
-
-class StartTLEvent extends TLEvent {
-  var dur start;
-  var MusicObject obj;
-  fun dur getStart() { return start; }
-  fun void doIt() {
-    obj.onStart();
-  }
-}
-
-fun StartTLEvent startevent(dur start, MusicObject obj) {
-  const StartTLEvent evt;
-  start => evt.start;
-  obj @=> evt.obj;
-  return evt;
-}
-
-class EndTLEvent extends TLEvent {
-  var dur start;
-  var MusicObject obj;
-  fun dur getStart() { return start; }
-  fun void doIt() {
-    obj.onEnd();
-  }
-}
-
-fun EndTLEvent endevent(dur start, MusicObject obj) {
-  const EndTLEvent evt;
-  start => evt.start;
-  obj @=> evt.obj;
-  return evt;
-}
-
-class DTimeline {
-  var TLEvent events[0];
-
-  fun void add(TLEvent event) {
-    for (0 => var int i; i < events.size(); ++i) {
-      if (event.getStart() < events[i].getStart()) {
-        for (events.size()-1 => var int j; j >= i; --j) {
-          events[j-1] @=> const TLEvent temp;
-          events[j] @=> events[j-1];
-          temp @=> events[j];
-        }
-        return;
-      }
-    }
-    events << event;
-  }
-
-  fun void perform() {
-    0::second => var dur current;
-    foreach(evt:events) {
-      evt.getStart() - current => now;
-      evt.getStart() => current;
-      evt.doIt();
-    }
-  }
-}
-
-class Frame {
-  var int test;
-  var Coord coord;
-  var MusicObject objs[0];
-}
-
-class Timeline {
-  const Frame frames[0];
-
-  fun void add(Coord c, MusicObject obj) {
-    var Frame toAdd;
-    for (0 => var int i; i < frames.size(); ++i) {
-      if ((c.start >= frames[i].coord.start) && (c.start <= frames[i].coord.start) 
-           && (c.end >= frames[i].coord.end) && (c.end <= frames[i].coord.end)) {
-        frames[i].objs << obj;
-        return;
-      }
-    }
-    var Coord c2;
-    c.start => c2.start;
-    c.end => c2.end;
-    toAdd.objs << obj;
-    c2 @=> toAdd.coord;
-    frames << toAdd;
-  }
-
-  fun DTimeline toDTimeline() {
-    var DTimeline theTL;
-    foreach(frame:frames) {
-      foreach(obj:frame.objs) {
-        theTL.add(startevent(frame.coord.start, obj));
-        theTL.add(endevent(frame.coord.end, obj));
-      }
-    }
-    return theTL;
-  }
-
-  fun void perform() {
-    this.toDTimeline().perform();
-  }
-}
-
-var Timeline t;
-t.add(coord(0::second, 2::second), note(A,0,4));
-t.add(coord(2::second,4::second), note(C,1,5));
-<<< t.frames[0].objs.size() >>>;
-t.perform();
index 64cd45f381ac25fc8d13ca391e7171b8ae0e8485..1a9fec85673351bf99e9b582d0f08bdbf1ca0a1a 100644 (file)
@@ -66,7 +66,7 @@ ANN void __release(const M_Object o, const VM_Shred shred) {
   MemPool p = shred->info->mp;
   Type t = o->type_ref;
   do {
-    if(!t->nspc || is_special(t) || tflag(t, tflag_udef))
+    if(!t->nspc || isa(t, shred->info->vm->gwion->type[et_union]) > 0)
       continue;
     struct scope_iter iter = { t->nspc->info->value, 0, 0 };\
     Value v;
@@ -111,7 +111,7 @@ static ID_CHECK(opck_this) {
   if(env->func && !vflag(env->func->value_ref, vflag_member))
       ERR_O(exp_self(prim)->pos, _("keyword 'this' cannot be used inside static functions..."))
   if(env->func && !strcmp(s_name(env->func->def->base->xid), "@gack"))
-    return force_type(env, get_gack(env->class_def->info->parent)); // get_gack ?
+    return get_gack(env->class_def->info->parent); // get_gack ?
   return env->class_def;
 }
 
index cb57147c674b33c69cc0d4755449675b0fa65ca5..0c8a21c70e9b0eb14e38b37a3bdec55daab72d4e 100644 (file)
@@ -31,98 +31,43 @@ static INSTR(name##Object) {                     \
 
 describe_logical(Eq,  ==)
 describe_logical(Neq, !=)
-static inline m_bool nonnull_check(const Type l, const Type r) {
-  return !tflag(l, tflag_nonnull) && tflag(r, tflag_nonnull);
-}
-
-ANN static inline Type check_nonnull(const Env env, const Type l, const Type r,
-      const m_str action, const loc_t pos) {
-  if(tflag(r, tflag_nonnull)) {
-    if(isa(l, env->gwion->type[et_null]) > 0)
-      ERR_N(pos, _("can't %s '%s' to '%s'"), action, l->name, r->name);
-    if(isa(l, unflag_type(r)) < 0)
-      ERR_N(pos, _("can't %s '%s' to '%s'"), action, l->name, r->name);
-    return r->info->parent;
-  }
-  if(l != env->gwion->type[et_null] && isa(l, r) < 0)
-    ERR_N(pos, _("can't %s '%s' to '%s'"), action, l->name, r->name);
-  return r;
-}
 
 static OP_CHECK(at_object) {
   const Exp_Binary* bin = (Exp_Binary*)data;
-  const Type l = bin->lhs->info->type;
-  const Type r = bin->rhs->info->type;
-  if(opck_rassign(env, data, mut) == env->gwion->type[et_null])
-    return env->gwion->type[et_null];
-  if(check_nonnull(env, l, r, "assign", exp_self(bin)->pos) == env->gwion->type[et_null])
-    return env->gwion->type[et_null];
+  if(opck_rassign(env, data, mut) == env->gwion->type[et_error])
+    return env->gwion->type[et_error];
   if(bin->rhs->exp_type == ae_exp_decl)
     SET_FLAG(bin->rhs->d.exp_decl.td, ref);
   exp_setvar(bin->rhs, 1);
-  return r;
-}
-
-/*static*/ OP_EMIT(opem_at_object) {
-  const Exp_Binary* bin = (Exp_Binary*)data;
-  const Type l = bin->lhs->info->type;
-  const Type r = bin->rhs->info->type;
-  if(nonnull_check(l, r)) {
-    const Instr instr = emit_add_instr(emit, GWOP_EXCEPT);
-    instr->m_val = SZ_INT;
-  }
-  return emit_add_instr(emit, ObjectAssign);
+  CHECK_BO(isa(bin->lhs->info->type , bin->rhs->info->type))
+  return bin->rhs->info->type;
 }
 
 static OP_CHECK(opck_object_cast) {
   const Exp_Cast* cast = (Exp_Cast*)data;
-  const Type l = cast->exp->info->type;
-  const Type r = exp_self(cast)->info->type;
-  if(check_nonnull(env, l, r, "cast", exp_self(cast)->pos) == env->gwion->type[et_null])
-    return env->gwion->type[et_null];
-  return force_type(env, r);
-}
-
-static OP_EMIT(opem_object_cast) {
-  const Exp_Cast* cast = (Exp_Cast*)data;
-  const Type l = cast->exp->info->type;
-  const Type r = exp_self(cast)->info->type;
-  if(nonnull_check(l, r))
-    emit_add_instr(emit, GWOP_EXCEPT);
-  return (Instr)GW_OK;
+  const Type to = known_type(env, cast->td);
+  if(isa(cast->exp->info->type, to) < 0) {
+    if(isa(to, cast->exp->info->type) > 0)
+      ERR_N(exp_self(cast)->pos, _("can't upcast '%s' to '%s'"), cast->exp->info->type->name, to->name)
+    ERR_N(exp_self(cast)->pos, _("can't cast '%s' to '%s'"), cast->exp->info->type->name, to->name)
+  }
+  return exp_self(cast)->info->type;
 }
 
 static OP_CHECK(opck_implicit_null2obj) {
   const struct Implicit* imp = (struct Implicit*)data;
-  const Type l = imp->e->info->type;
-  const Type r = imp->t;
-  if(check_nonnull(env, l, r, "implicitly cast", imp->e->pos) == env->gwion->type[et_null])
-    return env->gwion->type[et_null];
   return imp->t;
 }
 
 static OP_EMIT(opem_implicit_null2obj) {
-  const struct Implicit* imp = (struct Implicit*)data;
-  const Type l = imp->e->info->type;
-  const Type r = imp->t;
-  if(nonnull_check(l, r))
-    emit_add_instr(emit, GWOP_EXCEPT);
   return (Instr)GW_OK;
 }
 
-static OP_CHECK(opck_object_not) {
-  const Exp_Unary* unary = (Exp_Unary*)data;
-  const Type t = unary->exp->info->type;
-  if(tflag(t, tflag_nonnull))
-    ERR_N(unary->exp->pos, "expression is known to be nonnull");
-  return unary->exp->info->type;
-}
-
 ANN /*static*/ Type scan_class(const Env env, const Type t, const Type_Decl * td);
 
 static Type opck_object_scan(const Env env, const struct TemplateScan *ts) {
   if(ts->td->types)
-    return scan_class(env, ts->t, ts->td) ?: env->gwion->type[et_null];
+    return scan_class(env, ts->t, ts->td) ?: env->gwion->type[et_error];
   ERR_N(td_pos(ts->td), _("you must provide template types for type '%s'"), ts->t->name)
 }
 
@@ -159,7 +104,7 @@ ANN static void emit_member_func(const Emitter emit, const Exp_Dot* member) {
   if(f->def->base->tmpl)
     emit_add_instr(emit, DotTmplVal);
 else
-  if(is_class(emit->gwion, member->t_base) || tflag(member->base->info->type, tflag_force)) {
+  if(is_class(emit->gwion, member->t_base) || member->base->exp_type == ae_exp_cast) {
     const Instr func_i = emit_add_instr(emit, f->code ? RegPushImm : SetFunc);
     func_i->m_val = (m_uint)f->code ?: (m_uint)f;
     return;
@@ -217,7 +162,7 @@ OP_CHECK(opck_object_dot) {
           _("class '%s' has no member '%s'"), the_base->name, str);
     if(member->t_base->nspc)
       did_you_mean_type(the_base, str);
-    return env->gwion->type[et_null];
+    return env->gwion->type[et_error];
   }
   CHECK_BN(not_from_owner_class(env, the_base, value, exp_self(member)->pos))
   if(!env->class_def || isa(env->class_def, value->from->owner_class) < 0) {
@@ -245,8 +190,6 @@ OP_EMIT(opem_object_dot) {
        !is_fptr(emit->gwion, exp_self(member)->info->type)))) {
     if(!tflag(t_base, tflag_struct))
       CHECK_BO(emit_exp(emit, member->base))
-    if(isa(member->t_base, emit->env->gwion->type[et_object]) > 0)
-      emit_except(emit, member->t_base);
   }
   if(isa(exp_self(member)->info->type, emit->gwion->type[et_function]) > 0 && !is_fptr(emit->gwion, exp_self(member)->info->type))
          emit_member_func(emit, member);
@@ -351,33 +294,22 @@ ANN static OP_EMIT(opem_option_setn) {
 ANN static OP_EMIT(opem_option_not) {
   Exp_Unary *unary = (Exp_Unary*)data;
   const Instr pop = emit_add_instr(emit, RegPop);
-  pop->m_val = unary->exp->info->type->nspc->info->offset - sizeof(uint16_t)*2;
-  const Instr set = emit_add_instr(emit, Reg2Reg);
-  set->m_val = -sizeof(uint16_t)*2;
-  set->m_val2 = unary->exp->info->type->nspc->info->offset - sizeof(uint16_t)*2;
+  pop->m_val = unary->exp->info->type->size - SZ_INT;
   return emit_add_instr(emit, IntNot);
 }
 
 ANN static OP_EMIT(opem_option_cond) {
   Exp exp = (Exp)data;
-  const Instr set = emit_add_instr(emit, Reg2Reg);
-  set->m_val = -exp->info->type->size;
-  set->m_val2 = -sizeof(uint16_t)*2;
-  const Instr  pop2 = emit_add_instr(emit, RegPop);
-  pop2->m_val = exp->info->type->nspc->info->offset - sizeof(uint16_t)*2;
-  const Instr instr = emit_add_instr(emit, BranchEqInt);
-  return instr;
+  const Instr pop = emit_add_instr(emit, RegPop);
+  pop->m_val = exp->info->type->size - SZ_INT;
+  return emit_add_instr(emit, BranchEqInt);
 }
 
 ANN static OP_EMIT(opem_option_uncond) {
   Exp exp = (Exp)data;
-  const Instr set = emit_add_instr(emit, Reg2Reg);
-  set->m_val = -exp->info->type->size;
-  set->m_val2 = -sizeof(uint16_t)*2;
-  const Instr  pop2 = emit_add_instr(emit, RegPop);
-  pop2->m_val = exp->info->type->size - sizeof(uint16_t)*2;
-  const Instr instr = emit_add_instr(emit, BranchNeqInt);
-  return instr;
+  const Instr pop = emit_add_instr(emit, RegPop);
+  pop->m_val = exp->info->type->size - SZ_INT;
+  return emit_add_instr(emit, BranchNeqInt);
 }
 
 
@@ -403,7 +335,7 @@ ANN static m_bool scantmpl_union_def(const Env env, struct tmpl_info *info) {
        .op=insert_symbol(env->gwion->st, "@=>"), .pos=info->td->pos };
       CHECK_BB(add_op(env->gwion, &opi1))
       const struct Op_Func opfunc2 = { .ck=opck_option_setn, .em=opem_option_setn };
-      struct Op_Import opi2 = { .lhs=env->gwion->type[et_null], .rhs=udef->type, .ret=udef->type, .func=&opfunc2,
+      struct Op_Import opi2 = { .lhs=env->gwion->type[et_error], .rhs=udef->type, .ret=udef->type, .func=&opfunc2,
        .op=insert_symbol(env->gwion->st, "@=>"), .pos=info->td->pos };
       CHECK_BB(add_op(env->gwion, &opi2))
       const struct Op_Func opfunc3 = { .em=opem_option_not };
@@ -442,11 +374,24 @@ ANN Type scan_class(const Env env, const Type t, const Type_Decl *td) {
   struct tmpl_info info = { .base=t, .td=td, .list=t->info->cdef->base.tmpl->list  };
   const Type exists = tmpl_exists(env, &info);
   if(exists)
-    return exists != env->gwion->type[et_null] ? exists : NULL;
+    return exists != env->gwion->type[et_error] ? exists : NULL;
   struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)scan0_cdef,
     .scope=env->scope->depth, .flag=tflag_scan0 };
+//  CHECK_BO(envset_push(&es, t->info->owner_class, t->info->ctx ? t->info->ctx->nspc : env->curr))
+//const Nspc former = env->curr;
+//if(env->class_def)
+//const Type cdef = env->class_def;
   CHECK_BO(envset_push(&es, t->info->owner_class, t->info->ctx ? t->info->ctx->nspc : env->curr))
+//  CHECK_BO(envset_push(&es, t->info->owner_class, t->info->owner))
+/*{
+nspc_push_type(env->gwion->mp, env->curr);
+  Type_List tl = td->types;
+  do {
+    nspc_add_type(env->curr, tl->td->xid, nspc_lookup_type0(former, tl->td->xid));
+  } while((tl = tl->next));
+}*/
   const Type ret = _scan_class(env, &info);
+//nspc_pop_type(env->gwion->mp, env->curr);
   if(es.run)
     envset_pop(&es, t->info->owner_class);
   return ret;
@@ -485,42 +430,23 @@ ANN void struct_release(const VM_Shred shred, const Type base, const m_bit *ptr)
 }
 
 GWION_IMPORT(object_op) {
-  const Type t_null  = gwi_mk_type(gwi, "@null",  SZ_INT, NULL);
-  gwi->gwion->type[et_null] = t_null;
-  GWI_BB(gwi_set_global_type(gwi, t_null, et_null))
+  const Type t_error  = gwi_mk_type(gwi, "@error",  0, NULL);
+  gwi->gwion->type[et_error] = t_error;
+  GWI_BB(gwi_set_global_type(gwi, t_error, et_error))
   GWI_BB(gwi_oper_cond(gwi, "Object", BranchEqInt, BranchNeqInt))
   GWI_BB(gwi_oper_ini(gwi, "Object", "Object", NULL))
   GWI_BB(gwi_oper_add(gwi, at_object))
-  GWI_BB(gwi_oper_emi(gwi, opem_at_object))
-  GWI_BB(gwi_oper_end(gwi, "@=>", NULL))
-  GWI_BB(gwi_oper_ini(gwi, "@null", "Object", NULL))
-  GWI_BB(gwi_oper_add(gwi, at_object))
-  GWI_BB(gwi_oper_emi(gwi, opem_at_object))
-  GWI_BB(gwi_oper_end(gwi, "@=>", NULL))
+  GWI_BB(gwi_oper_end(gwi, "@=>", ObjectAssign))
   GWI_BB(gwi_oper_ini(gwi, "Object", "Object", "int"))
   GWI_BB(gwi_oper_end(gwi, "==",  EqObject))
   GWI_BB(gwi_oper_end(gwi, "!=", NeqObject))
   GWI_BB(gwi_oper_add(gwi, opck_object_cast))
-  GWI_BB(gwi_oper_emi(gwi, opem_object_cast))
   GWI_BB(gwi_oper_end(gwi, "$", NULL))
   GWI_BB(gwi_oper_add(gwi, opck_implicit_null2obj))
   GWI_BB(gwi_oper_emi(gwi, opem_implicit_null2obj))
   GWI_BB(gwi_oper_end(gwi, "@implicit", NULL))
-  GWI_BB(gwi_oper_ini(gwi, "@null", "Object", NULL))
-  GWI_BB(gwi_oper_add(gwi, opck_implicit_null2obj))
-  GWI_BB(gwi_oper_end(gwi, "@implicit", NULL))
-  GWI_BB(gwi_oper_ini(gwi, "@null", "Object", NULL))
-  GWI_BB(gwi_oper_add(gwi, opck_object_cast))
-  GWI_BB(gwi_oper_emi(gwi, opem_object_cast))
-  GWI_BB(gwi_oper_end(gwi, "$", NULL))
-  GWI_BB(gwi_oper_ini(gwi, NULL, "Object", "bool"))
-  GWI_BB(gwi_oper_add(gwi, opck_unary_meta2)) // this is suspicious
-  GWI_BB(gwi_oper_add(gwi, opck_object_not))
-  GWI_BB(gwi_oper_end(gwi, "!", IntNot))
   GWI_BB(gwi_oper_ini(gwi, "@Compound", NULL, NULL))
   GWI_BB(gwi_oper_add(gwi, opck_struct_scan))
   GWI_BB(gwi_oper_end(gwi, "@scan", NULL))
-  gwi_item_ini(gwi, "@null", "null");
-  gwi_item_end(gwi, 0, NULL);
   return GW_OK;
 }
index 439bbc05462d6db3390f2e801fd2f6d444803bd0..baa7462aef7cb4ea6e87f340429c56891237306c 100644 (file)
@@ -13,7 +13,7 @@
 OP_CHECK(opck_basic_cast) {
   const Exp_Cast* cast = (Exp_Cast*)data;
   return isa(cast->exp->info->type, exp_self(cast)->info->type) > 0 ?
-     exp_self(cast)->info->type : env->gwion->type[et_null];
+     exp_self(cast)->info->type : env->gwion->type[et_error];
 }
 
 OP_CHECK(opck_usr_implicit) {
@@ -34,8 +34,8 @@ OP_CHECK(opck_const_rhs) {
 
 OP_CHECK(opck_rassign) {
   const Exp_Binary* bin = (Exp_Binary*)data;
-  if(opck_const_rhs(env, data, mut) == env->gwion->type[et_null])
-    return env->gwion->type[et_null];
+  if(opck_const_rhs(env, data, mut) == env->gwion->type[et_error])
+    return env->gwion->type[et_error];
   exp_setvar(bin->rhs, 1);
   return bin->rhs->info->type;
 }
index 2dbbcba9e644a8d5bfef42424fe8fb1d01cc96ea..af90500049e8bf4554ca60dd80389744e4a905ca 100644 (file)
@@ -137,7 +137,7 @@ static OP_CHECK(opck_cast_f2i) {
 }
 
 static OP_CHECK(opck_implicit_f2i) {
-  return env->gwion->type[et_null];
+  return env->gwion->type[et_error];
 }
 
 static OP_CHECK(opck_cast_i2f) {
index 4e5d2f3d4fb1e689f9f768e23130b9dd927cd3f4..eefea3b7a609778658e2c9fa575c5ed215b101d0 100644 (file)
@@ -30,16 +30,14 @@ static OP_CHECK(opck_ptr_assign) {
   exp_setvar(bin->rhs, 1);
   Type t = bin->lhs->info->type;
   do {
-//    t = unflag_type(t);
     Type u = bin->rhs->info->type;
     do {
-//      u = unflag_type(u);
       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));
   } while((t = t->info->parent));
-  return env->gwion->type[et_null];
+  return env->gwion->type[et_error];
 }
 
 static INSTR(instr_ptr_assign) {
index db68d0ed4a1fe588ab5538033fa600edaf9a18a0..56cc864da2fc30b14e2923b1f11322d23be231bf 100644 (file)
 #include "gwi.h"
 #include "gack.h"
 
-ANN static void push_string(const VM_Shred shred, const M_Object obj, const m_str c) {
-  STRING(obj) = s_name(insert_symbol(shred->info->vm->gwion->st, c));
-  *(M_Object*)REG(-SZ_INT) = (M_Object)obj;
-  _release(obj, shred);
-}
-
 #define describe_string_logical(name, action)    \
 static INSTR(String_##name) {                    \
   POP_REG(shred, SZ_INT);                        \
@@ -33,14 +27,6 @@ static INSTR(String_##name) {                    \
 describe_string_logical(eq, (lhs && rhs && STRING(lhs) == STRING(rhs)) || (!lhs && !rhs))
 describe_string_logical(neq, !(lhs && rhs && STRING(lhs) == STRING(rhs)) || (!lhs && !rhs))
 
-static INSTR(String_Assign) {
-  POP_REG(shred, SZ_INT);
-  const M_Object lhs = *(M_Object*)REG(-SZ_INT);
-  const M_Object rhs = *(M_Object*)REG(0);
-  release(lhs, shred);
-  push_string(shred, rhs, lhs ? STRING(lhs) : "");
-}
-
 static CTOR(string_ctor) {
   STRING(o) = "";
 }
@@ -437,11 +423,11 @@ GWION_IMPORT(string) {
   GWI_BB(gwi_func_end(gwi, string_findStart, ae_flag_none))
 
   gwi_func_ini(gwi, "int", "find");
-  gwi_func_arg(gwi, "nonnull string", "str");
+  gwi_func_arg(gwi, "string", "str");
   GWI_BB(gwi_func_end(gwi, string_findStr, ae_flag_none))
 
   gwi_func_ini(gwi, "int", "find");
-  gwi_func_arg(gwi, "nonnull string", "str");
+  gwi_func_arg(gwi, "string", "str");
   gwi_func_arg(gwi, "int", "pos");
   GWI_BB(gwi_func_end(gwi, string_findStrStart, ae_flag_none))
 
@@ -455,11 +441,11 @@ GWION_IMPORT(string) {
   GWI_BB(gwi_func_end(gwi, string_rfindStart, ae_flag_none))
 
   gwi_func_ini(gwi, "int", "rfind");
-  gwi_func_arg(gwi, "nonnull string", "str");
+  gwi_func_arg(gwi, "string", "str");
   GWI_BB(gwi_func_end(gwi, string_rfindStr, ae_flag_none))
 
   gwi_func_ini(gwi, "int", "rfind");
-  gwi_func_arg(gwi, "nonnull string", "str");
+  gwi_func_arg(gwi, "string", "str");
   gwi_func_arg(gwi, "int", "pos");
   GWI_BB(gwi_func_end(gwi, string_rfindStrStart, ae_flag_none))
 
@@ -470,15 +456,11 @@ GWION_IMPORT(string) {
 
   GWI_BB(gwi_class_end(gwi))
 
-  GWI_BB(gwi_oper_ini(gwi, "string",  "nonnull string", "nonnull string"))
-  GWI_BB(gwi_oper_add(gwi, opck_const_rhs))
-  GWI_BB(gwi_oper_end(gwi, "=>",      String_Assign))
-
   GWI_BB(gwi_oper_ini(gwi, "string",  "string", "bool"))
   GWI_BB(gwi_oper_end(gwi, "==",       String_eq))
   GWI_BB(gwi_oper_end(gwi, "!=",       String_neq))
 
-  GWI_BB(gwi_oper_ini(gwi, "int", "nonnull string", "nonnull string"))
+  GWI_BB(gwi_oper_ini(gwi, "int", "string", "string"))
   GWI_BB(gwi_oper_end(gwi, "@slice", StringSlice))
 
   struct SpecialId_ spid = { .ck=check_funcpp, .exec=RegPushMe, .is_const=1 };
index b34d1b39eade455ae7add3b0e8a8696d13c12391..70939a1ecfb52528344295366e288441bc3e7101 100644 (file)
@@ -399,25 +399,25 @@ GWION_IMPORT(ugen) {
   GWI_BB(gwi_func_end(gwi, ugen_get_last, ae_flag_none))
   GWI_BB(gwi_class_end(gwi))
 
-  GWI_BB(gwi_oper_ini(gwi, "nonnull UGen", "nonnull UGen", "nonnull UGen"))
+  GWI_BB(gwi_oper_ini(gwi, "UGen", "UGen", "UGen"))
   _CHECK_OP("=>", chuck_ugen, UgenConnect)
   _CHECK_OP("=<", chuck_ugen, UgenDisconnect)
   _CHECK_OP(":=>", chuck_ugen, TrigConnect)
   _CHECK_OP(":=<", chuck_ugen, TrigDisconnect)
 
-  GWI_BB(gwi_oper_ini(gwi, "nonnull UGen[]", "nonnull UGen[]", "nonnull UGen[]"))
+  GWI_BB(gwi_oper_ini(gwi, "UGen[]", "UGen[]", "UGen[]"))
   _CHECK_OP("=>", chuck_ugen, UgenAAConnect)
   _CHECK_OP("=<", chuck_ugen, UgenAADisconnect)
   _CHECK_OP(":=>", chuck_ugen, TrigAAConnect)
   _CHECK_OP(":=<", chuck_ugen, TrigAADisconnect)
 
-  GWI_BB(gwi_oper_ini(gwi, "nonnull UGen", "nonnull UGen[]", "nonnull UGen[]"))
+  GWI_BB(gwi_oper_ini(gwi, "UGen", "UGen[]", "UGen[]"))
   _CHECK_OP("=>", chuck_ugen, UgenUAConnect)
   _CHECK_OP("=<", chuck_ugen, UgenUADisconnect)
   _CHECK_OP(":=>", chuck_ugen, TrigUAConnect)
   _CHECK_OP(":=<", chuck_ugen, TrigUADisconnect)
 
-  GWI_BB(gwi_oper_ini(gwi, "nonnull UGen[]", "nonnull UGen", "nonnull UGen"))
+  GWI_BB(gwi_oper_ini(gwi, "UGen[]", "UGen", "UGen"))
   _CHECK_OP("=>", chuck_ugen, UgenAUConnect)
   _CHECK_OP("=<", chuck_ugen, UgenAUDisconnect)
   _CHECK_OP(":=>", chuck_ugen, TrigAUConnect)
index 653c6e09353889935c1e9e1313cd78c0eb128783..b3ab05046f46f365f548031c469824b6f64381fa 100644 (file)
@@ -118,7 +118,7 @@ static INSTR(VarargCast) {
   const Type t = (Type)instr->m_val,
              u = (Type)vector_at(&arg->t, arg->i);
   if(isa(u, t) > 0 ||
-      (u == shred->info->vm->gwion->type[et_null] &&
+      (u == shred->info->vm->gwion->type[et_error] &&
        isa(t, shred->info->vm->gwion->type[et_object]) > 0)) {
     for(m_uint i = 0; i < t->size; i += SZ_INT)
       *(m_uint*)REG(i - SZ_INT) = *(m_uint*)(arg->d + arg->o + i);
@@ -142,7 +142,7 @@ static FREEARG(freearg_vararg) {
 
 static ID_CHECK(idck_vararg) {
   if(env->func && fbflag(env->func->def->base, fbflag_variadic))
-    return nonnul_type(env, exp_self(prim)->info->type);
+    return exp_self(prim)->info->type;
   ERR_O(exp_self(prim)->pos, _("'vararg' must be used inside variadic function"))
 }
 
@@ -178,7 +178,7 @@ GWION_IMPORT(vararg) {
   GWI_BB(gwi_class_end(gwi))
   SET_FLAG(t_vararg, abstract | ae_flag_final);
   gwi->gwion->type[et_vararg] = t_vararg;
-  GWI_BB(gwi_oper_ini(gwi, "nonnull Vararg", (m_str)OP_ANY_TYPE, NULL))
+  GWI_BB(gwi_oper_ini(gwi, "Vararg", (m_str)OP_ANY_TYPE, NULL))
   GWI_BB(gwi_oper_add(gwi, opck_vararg_cast))
   GWI_BB(gwi_oper_emi(gwi, opem_vararg_cast))
   GWI_BB(gwi_oper_end(gwi, "$", NULL))
index 1c0e857f4ec753e1b8d1e670724e92431e7522ed..9fa666a4a7f94714745b94c2b6b357a3368cdc41 100644 (file)
@@ -350,8 +350,7 @@ ANN static Type check_prim_typeof(const Env env, const Exp *exp) {
   const Exp e = *exp;
   DECL_OO(const Type, t, = check_exp(env, e))
   CHECK_BO(inferable(env, t, (*exp)->pos))
-  const Type force = force_type(env, t);
-  return type_class(env->gwion, force);
+  return type_class(env->gwion, t);
 }
 
 ANN static Type check_prim_interp(const Env env, const Exp* exp) {
@@ -687,16 +686,15 @@ ANN static Type check_lambda_call(const Env env, const Exp_Call *exp) {
 
 ANN m_bool func_check(const Env env, const Exp_Call *exp) {
   CHECK_OB(check_exp(env, exp->func))
-  const Type t = actual_type(env->gwion, unflag_type(exp->func->info->type));
+  const Type t = actual_type(env->gwion, exp->func->info->type);
   struct Op_Import opi = { .op=insert_symbol("@func_check"),
   .rhs=t, .pos=exp_self(exp)->pos, .data=(uintptr_t)exp, .op_type=op_exp };
   CHECK_NB(op_check(env, &opi)) // doesn't really return NULL
-  return exp_self(exp)->info->type != env->gwion->type[et_null] ?
+  return exp_self(exp)->info->type != env->gwion->type[et_error] ?
     GW_OK : GW_ERROR;
 }
 
 ANN Type check_exp_call1(const Env env, const Exp_Call *exp) {
-//  CHECK_OO(check_exp(env, exp->func))
   CHECK_BO(func_check(env, exp))
   const Type t = actual_type(env->gwion, exp->func->info->type);
   if(isa(t, env->gwion->type[et_function]) < 0) {
@@ -777,7 +775,7 @@ ANN static m_bool predefined_call(const Env env, const Type t, const loc_t pos)
 ANN static Type check_exp_call(const Env env, Exp_Call* exp) {
   if(exp->tmpl) {
     CHECK_BO(func_check(env, exp))
-    const Type t = actual_type(env->gwion, unflag_type(exp->func->info->type));
+    const Type t = actual_type(env->gwion, exp->func->info->type);
     if(isa(t, env->gwion->type[et_function]) < 0)
        return check_exp_call1(env, exp);
     if(exp->args)
@@ -921,7 +919,7 @@ ANN static m_bool do_stmt_each(const Env env, const Stmt_Each stmt) {
     if(depth)
       ptr = array_type(env, ptr, depth);
     char c[15 + strlen(ptr->name)];
-    sprintf(c, "nonnull Ptr:[%s]", ptr->name);
+    sprintf(c, "Ptr:[%s]", ptr->name);
     ptr = str2type(env->gwion, c, stmt->exp->pos);
     const Type base = get_type(ptr);
     CHECK_BB(ensure_traverse(env, base))
@@ -1026,11 +1024,47 @@ ANN m_bool check_union_decl(const Env env, const Union_Def udef) {
   return GW_OK;
 }
 
+static OP_CHECK(opck_union_is) {
+  Exp_Call *call = (Exp_Call*)data; 
+  Exp exp = call->args;
+  if(exp->exp_type != ae_exp_primary && exp->d.prim.prim_type != ae_prim_id)
+    ERR_N(exp->pos, "FFI variadic arguments must be of FFI type CHANGE ME");
+  const Value v = find_value(call->func->info->type->info->owner_class, exp->d.prim.d.var);
+  if(!v)
+    ERR_N(exp->pos, "'%s' has no member '%s'", call->func->info->type->info->owner_class, exp->d.prim.d.var);
+  exp->d.prim.prim_type = ae_prim_num;
+  exp->d.prim.d.num = v->from->offset;
+  return NULL;
+}
+
+/*static*/ MFUN(union_is) {
+ *(m_uint*)RETURN = *(m_uint*)MEM(SZ_INT) == *(m_uint*)o->data;
+}
+
 ANN m_bool check_union_def(const Env env, const Union_Def udef) {
   if(tmpl_base(udef->tmpl)) // there's a func for this
     return GW_OK;
   const m_uint scope = env_push_type(env, udef->type);
   const m_bool ret = check_union_decl(env, udef);
+
+  Type_Decl *td = new_type_decl(env->gwion->mp, insert_symbol("bool"), loc_cpy(env->gwion->mp, udef->pos));
+//  Type_Decl *arg_td = new_type_decl(env->gwion->mp, insert_symbol(), loc_cpy(env->gwion->mp, udef->pos));
+  Type_Decl *arg_td = new_type_decl(env->gwion->mp, insert_symbol("int"), loc_cpy(env->gwion->mp, udef->pos));;
+  Var_Decl var = new_var_decl(env->gwion->mp, insert_symbol("arg"), NULL, loc_cpy(env->gwion->mp, udef->pos));
+  Arg_List args = new_arg_list(env->gwion->mp, arg_td, var, NULL);
+  Func_Base *fb = new_func_base(env->gwion->mp, td, insert_symbol("is"), args, ae_flag_none);
+  Func_Def fdef = new_func_def(env->gwion->mp, fb, NULL, loc_cpy(env->gwion->mp, udef->pos));
+  CHECK_BB(traverse_func_def(env, fdef)) // use ret
+  builtin_func(env->gwion->mp, fb->func, union_is);
+
+  const m_uint oscope = env_push(env, udef->type->info->owner_class, udef->type->info->owner);
+  const struct Op_Func opfunc = { .ck=opck_union_is };
+  const struct Op_Import opi = { .rhs=fb->func->value_ref->type,
+      .func=&opfunc, .data=(uintptr_t)fb->func, .pos=udef->pos, .op=insert_symbol("@func_check") };
+  CHECK_BB(add_op(env->gwion, &opi))
+  env_pop(env, oscope);
+//  set_vflag(fb->func->value_ref, vflag_builtin);
+
   env_pop(env, scope);
   set_tflag(udef->type, tflag_check);
   return ret;
index 640261f30c356ae16621c4d18b92d2b245f1bf0a..d518171105a8f3479a922c0f0b5916a2d2c1a276 100644 (file)
@@ -49,8 +49,6 @@ ANN static Type op_parent(const Env env, const Type t) {
 static m_bool op_match(const restrict Type t, const restrict Type mo) {
   if(t == OP_ANY_TYPE || mo == OP_ANY_TYPE)
     return GW_OK;
-  if(t && mo)
-    return unflag_type(t) == unflag_type(mo);
   return t == mo;
 }
 
@@ -168,72 +166,12 @@ ANN static void set_nspc(struct Op_Import *opi, const Nspc nspc) {
     exp_self((union exp_data*)opi->data)->info->nspc = nspc;
 }
 
-ANN static inline void set_nonnull(const Type t, const Exp exp) {
-  if(t != OP_ANY_TYPE && tflag(t, tflag_nonnull))
-    exp_setnonnull(exp, 1);
-}
-
-ANN static void nn_implicit(const M_Operator *mo, const struct Op_Import *opi) {
-  const struct Implicit *a = (struct Implicit*)opi->data;
-  set_nonnull(mo->lhs, a->e);
-}
-
-ANN static void nn_exp(const M_Operator *mo, const struct Op_Import *opi) {
-  const Exp a = (Exp)opi->data;
-  set_nonnull(mo->rhs, a); // rhs ???
-}
-
-ANN static void nn_dot(const M_Operator *mo, const struct Op_Import *opi) {
-  const Exp_Dot *a = (Exp_Dot*)opi->data;
-  set_nonnull(mo->lhs, a->base);
-}
-
-ANN static void nn_array(const M_Operator *mo, const struct Op_Import *opi) {
-  const Array_Sub a = (Array_Sub)opi->data;
-  set_nonnull(mo->lhs, a->exp);
-}
-
-ANN static void nn_binary(const M_Operator *mo, const struct Op_Import *opi) {
-  const Exp_Binary *a = (Exp_Binary*)opi->data;
-  set_nonnull(mo->lhs, a->lhs);
-  set_nonnull(mo->rhs, a->rhs);
-}
-
-ANN static void nn_cast(const M_Operator *mo, const struct Op_Import *opi) {
-  const Exp_Cast *a = (Exp_Cast*)opi->data;
-  set_nonnull(mo->lhs, a->exp);
-}
-
-ANN static void nn_postfix(const M_Operator *mo, const struct Op_Import *opi) {
-  const Exp_Postfix *a = (Exp_Postfix*)opi->data;
-  set_nonnull(mo->lhs, a->exp);
-}
-
-ANN static void nn_unary(const M_Operator *mo, const struct Op_Import *opi) {
-  const Exp_Unary *a = (Exp_Unary*)opi->data;
-  set_nonnull(mo->rhs, a->exp);
-}
-
-ANN static void nn_scan(const M_Operator *mo NUSED, const struct Op_Import *opi NUSED) {
-}
-
-typedef void (*nn_f)(const M_Operator *mo, const struct Op_Import *opi);
-static const nn_f nn_func[] = {
-  nn_implicit, nn_exp, nn_dot, nn_array,
-  nn_binary, nn_cast, nn_postfix, nn_unary, nn_scan
-};
-
-ANN static void opi_nonnull(const M_Operator *mo, const struct Op_Import *opi) {
-  nn_func[opi->op_type](mo, opi);
-}
-
 ANN static Type op_check_inner(struct OpChecker* ock) {
   Type t, r = ock->opi->rhs;
   do {
     const M_Operator* mo;
     const Vector v = (Vector)map_get(ock->map, (vtype)ock->opi->op);
     if(v && (mo = operator_find(v, ock->opi->lhs, r))) {
-      opi_nonnull(mo, ock->opi);
       if((mo->ck && (t = mo->ck(ock->env, (void*)ock->opi->data, &ock->mut))))
         return t;
       else
@@ -253,7 +191,7 @@ ANN Type op_check(const Env env, struct Op_Import* opi) {
         struct OpChecker ock = { env, &nspc->info->op_map, &opi2, 0 };
         const Type ret = op_check_inner(&ock);
         if(ret) {
-          if(ret == env->gwion->type[et_null])
+          if(ret == env->gwion->type[et_error])
             break;
           if(!ock.mut)
             set_nspc(&opi2, nspc);
index 54b21a8ce9bc99fd29de7efaa997d45b40aa79b0..374c5c35cc039904acc87c282c9e6bbd15d0a021 100644 (file)
@@ -578,8 +578,6 @@ ANN static m_bool scan1_parent(const Env env, const Class_Def cdef) {
   CHECK_BB(ensure_scan1(env, parent))
   if(type_ref(parent))
     ERR_B(pos, _("can't use ref type in class extend"))
-  if(tflag(parent, tflag_nonnull))
-    ERR_B(pos, _("can't use nonnull type in class extend"))
   return GW_OK;
 }
 
index 39a491eb9fca1dbefc2b15a8ab755f808ee66f7b..7230326cfff51a214b6f601357cd881bda1b74a2 100644 (file)
@@ -41,16 +41,10 @@ scanx_body(const Env e, const Class_Def c, const _exp_func f, void* d) {
   return ret;
 }
 
-__attribute__((returns_nonnull))
-ANN Type unflag_type(const Type t) {
-  const Type type = !tflag(t, tflag_nonnull) ? t : t->info->parent;
-  return !tflag(type, tflag_force) ? type : type->info->parent;
-}
-
 __attribute__((returns_nonnull))
 ANN Type get_type(const Type t) {
   const Type type = !t->array_depth ? t : array_base(t);
-  return unflag_type(type);
+  return type;
 }
 
 ANN m_bool scanx_cdef(const Env env, void* opt, const Type base,
index fae410c5218088a3fc65d6d43a82a549ce08c431..d8af4d293bc81b4e3445d615509b49b0cb98ad27 100644 (file)
@@ -5,6 +5,14 @@
 #include "traverse.h"
 #include "parse.h"
 
+ANN static Type option(const Env env, Type_Decl* td) {
+  struct Type_List_ tl = { .td=td };
+  Type_Decl option_td = { .xid=insert_symbol("Option"), .types=&tl };
+  UNSET_FLAG(td, optionnal);
+  const Type ret = known_type(env, &option_td);
+  SET_FLAG(td, optionnal);
+  return ret;
+}
 
 ANN static Type resolve(const Env env, Type_Decl* td) {
   DECL_OO(const Type, base, = find_type(env, td))
@@ -12,14 +20,7 @@ ANN static Type resolve(const Env env, Type_Decl* td) {
     ERR_O(td_pos(td), _("type '%s' is invalid"), base->name)
   DECL_OO(const Type, t, = scan_type(env, base, td))
   const Type ret = !td->array ? t : array_type(env, t, td->array->depth);
-  if(GET_FLAG(td, nonnull)) {
-    if(isa(ret, env->gwion->type[et_void]) > 0)
-      ERR_O(td_pos(td), _("void types can't be nonnull."))
-    if(isa(ret, env->gwion->type[et_object]) < 0 && isa(ret, env->gwion->type[et_fptr]) < 0)
-      return ret;
-    return nonnul_type(env, ret);
-  }
-  return ret;
+  return !GET_FLAG(td, optionnal) ? ret : option(env, td);
 }
 
 struct td_info {
diff --git a/tests/UsrUgen/null_tick.gw b/tests/UsrUgen/null_tick.gw
deleted file mode 100644 (file)
index 91d5280..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#! [contains] NullTickException
-funcdef float ptr_t(float);
-var ptr_t ptr ~= var UsrUGen u;
diff --git a/tests/bug/Tester.gw b/tests/bug/Tester.gw
deleted file mode 100644 (file)
index 4c6f180..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-class Tester
-{
-       fun int assert_equal:[A](string description, A a, A b){ if(a == b) return 0; return 1; }
-       fun int assert_not_equal:[A](string description, A a, A b){ if(a != b) return 0; return 1; }
-}
-
-var Tester t;
-var Object o;
-ref Object oref;
-"test" => var string s;
-#!<<< t.assert_equal("test", 1, 1) >>>;
-#!<<< t.assert_equal("test", 2, 1) >>>;
-<<< t.assert_equal(s, 1, 1) >>>;
-<<< t.assert_equal(s, 2, 1 + 1) >>>;
-<<< t.assert_equal(s, 2, 1) >>>;
-<<< t.assert_equal(s, o, o) >>>;
-<<< t.assert_equal(s, o, null) >>>;
-<<< t.assert_equal(s, null $ Object, null) >>>;
-<<< t.assert_equal(s, oref, null) >>>;
-<<< t.assert_not_equal(s, 1, 1) >>>;
-<<< t.assert_not_equal(s, 2, 1 + 1) >>>;
-<<< t.assert_not_equal(s, 2, 1) >>>;
-<<< t.assert_not_equal(s, o, o) >>>;
-<<< t.assert_not_equal(s, o, null) >>>;
-<<< t.assert_not_equal(s, null $ Object, null) >>>;
-<<< t.assert_not_equal(s, oref, null) >>>;
index 0af41e4ba3456ec1f62dff35b136c8677952165c..ab5dbe37d9d1457315ecc70978def518c8db0959 100644 (file)
@@ -1,2 +1,2 @@
 #! [contains] contains incompatible types
-[null, 1];
+[new Object, 1];
diff --git a/tests/error/array_multi_except.gw b/tests/error/array_multi_except.gw
deleted file mode 100644 (file)
index 3ad377c..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-#! [contains] NullPtrException
-var int i[1][1];
-null @=> i[0];
-<<< i[0][0] >>>;
diff --git a/tests/error/connect_except.gw b/tests/error/connect_except.gw
deleted file mode 100644 (file)
index 084f50b..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#! [contains] NullPtrException
-ref UGen u;
-adc => u;
diff --git a/tests/error/empty_member_ptr.gw b/tests/error/empty_member_ptr.gw
deleted file mode 100644 (file)
index 4e83d5c..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#! [contains] NullPtrException
-class C
-{
-       funcdef void test();
-       var test t;
-}
-<<< var C c >>>;
-<<< c.t >>>;
-c.t();
diff --git a/tests/error/empty_obj_data.gw b/tests/error/empty_obj_data.gw
deleted file mode 100644 (file)
index c4d18b6..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#! [contains] NullPtrException
-class C
-{
-       var int i;
-}
-
-ref C c;
-c.i;
diff --git a/tests/error/ev.gw b/tests/error/ev.gw
deleted file mode 100644 (file)
index 1508bd6..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#! [contains] NullPtrException
-ref Event e;
-e => now;
diff --git a/tests/error/fail_assign.gw b/tests/error/fail_assign.gw
deleted file mode 100644 (file)
index cd1db1a..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#! [contains] can't assign
-class C extends Event{}
-var Event e @=> var C o;
index cf68a27dd36a6c04cc06187fdd697e667f9b8772..af01059841bf295e0c9a55143d5b67c3b73b9228 100644 (file)
@@ -1,2 +1,2 @@
 #! [contains] non-callable value
-null();
+1();
diff --git a/tests/error/func_ptr_empty.gw b/tests/error/func_ptr_empty.gw
deleted file mode 100644 (file)
index 19debcc..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-#! [contains] NullPtrException
-funcdef void Test();
-var Test test;
-test();
index 2cc6d0456b3e8f86b4a9ea6a7ed856cab29129bb..2da42533fb5235afc3a598b99fdfde3e3e06ce1a 100644 (file)
@@ -1,2 +1,2 @@
 #! [contains] incompatible types
-maybe ? null : 1;
+maybe ? 2.1 : 1;
diff --git a/tests/error/non_public_typedef_global_scope.gw b/tests/error/non_public_typedef_global_scope.gw
deleted file mode 100644 (file)
index ac05dd2..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#! [contains] NullPtrException
-class C {
-  funcdef void t_ptr();
-}
-var C.t_ptr ptr;
-ptr();
diff --git a/tests/error/nonnull_class_extend.gw b/tests/error/nonnull_class_extend.gw
deleted file mode 100644 (file)
index 77dd193..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-#! [contains] can't use nonnull type in class extend
-class C extends nonnull Object {
-
-}
diff --git a/tests/error/not_nn.gw b/tests/error/not_nn.gw
deleted file mode 100644 (file)
index 748b8ff..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#! [contains] expression is known to be nonnull
-nonnull Object o;
-<<< (!o) >>>;
diff --git a/tests/error/null_array_access.gw b/tests/error/null_array_access.gw
deleted file mode 100644 (file)
index 108472f..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#! [contains] NullPtrException
-var int i[];
-i[0];
diff --git a/tests/error/null_array_access_multi.gw b/tests/error/null_array_access_multi.gw
deleted file mode 100644 (file)
index 4995d84..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#! [contains] NullPtrException
-var int i[][];
-i[0][0];
diff --git a/tests/error/null_auto.gw b/tests/error/null_auto.gw
deleted file mode 100644 (file)
index ddcbbe6..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-#! [contains] NullPtrException
-var int i[];
-foreach(a : i)
- <<< a >>>;
index dfccfc344701e7d76faab1fc5e04345d1284b39c..153a42cebaa2f74be97450b8c8a52e5f2998cc90 100644 (file)
@@ -1,3 +1,3 @@
 #! [contains] no match found for operator
 var Object o;
-null +=> o;
+1 +=> o;
index 788a6ade503cdc7cd1b1ac471b2182ec807e5799..ef81d7c388db23a503958513e5c416b3200bc280 100644 (file)
@@ -1,5 +1,4 @@
 #! [contains] unknown_type
-union U
-{
+union U {
        unknown_type unknown_variable;
-};
+}
index eb82798034fe6bb88f46350f9363b89f02d2ab61..14d9af9f64ee60d77fa8cd50607278bcc0c15af8 100644 (file)
@@ -1,4 +1,4 @@
 #! [contains] Hello, interpolation! 1
 1 => var int my;
-"Hello, interpolation! ${ my }" => var string s;
+"Hello, interpolation! ${ my }" @=> var string s;
 <<< s >>>;
index ea7ac1296b3ffbe5a94437b7cad7616b33eb6fac..d3657fcf2fc07c2dd54d5f95708cf9ee3c5058d0 100644 (file)
@@ -1 +1 @@
-new Object @=> nonnull Object o;
+new Object @=> var Object? o;
diff --git a/tests/nonnull/cast_non_null.gw b/tests/nonnull/cast_non_null.gw
deleted file mode 100644 (file)
index 0087c85..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-ref Object o;
-o $ nonnull Event;
diff --git a/tests/nonnull/cast_non_null2.gw b/tests/nonnull/cast_non_null2.gw
deleted file mode 100644 (file)
index 4dbedf5..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-ref Object o;
-o $ Object;
diff --git a/tests/nonnull/dynamic_implicit_nonnull.gw b/tests/nonnull/dynamic_implicit_nonnull.gw
deleted file mode 100644 (file)
index 0ebff9b..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-fun void test(nonnull Object o) { <<< o >>>; }
-
-ref Object o => test;
diff --git a/tests/nonnull/nonnull2nullable.gw b/tests/nonnull/nonnull2nullable.gw
deleted file mode 100644 (file)
index f9c6956..0000000
+++ /dev/null
@@ -1 +0,0 @@
-nonnull Object o @=> ref Object p;
diff --git a/tests/nonnull/nonnull_assign_nonnull.gw b/tests/nonnull/nonnull_assign_nonnull.gw
deleted file mode 100644 (file)
index f61c76c..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-nonnull Object o, p;
-o @=> p;
diff --git a/tests/nonnull/nonnull_at_nonnull.gw b/tests/nonnull/nonnull_at_nonnull.gw
deleted file mode 100644 (file)
index 9bfe9ba..0000000
+++ /dev/null
@@ -1 +0,0 @@
-new nonnull Object @=> nonnull Object o;
diff --git a/tests/nonnull/nonnull_cast_nonnull.gw b/tests/nonnull/nonnull_cast_nonnull.gw
deleted file mode 100644 (file)
index cd1e47d..0000000
+++ /dev/null
@@ -1 +0,0 @@
-(nonnull Object o) $ nonnull Object;
diff --git a/tests/nonnull/nonnull_decl.gw b/tests/nonnull/nonnull_decl.gw
deleted file mode 100644 (file)
index 59f539e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-nonnull Object o;
diff --git a/tests/nonnull/nonnull_decl_ref_assign.gw b/tests/nonnull/nonnull_decl_ref_assign.gw
deleted file mode 100644 (file)
index 89a9aaf..0000000
+++ /dev/null
@@ -1 +0,0 @@
-new Object @=> nonnull ref Object o;
diff --git a/tests/nonnull/nonnull_err_cast_dynamic.gw b/tests/nonnull/nonnull_err_cast_dynamic.gw
deleted file mode 100644 (file)
index 58524f5..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#! [contains] NullPtrException
-ref Object o;
-<<< o $ nonnull Object >>>;
diff --git a/tests/nonnull/nonnull_err_dynamic.gw b/tests/nonnull/nonnull_err_dynamic.gw
deleted file mode 100644 (file)
index 31fc112..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-#! [contains} NullPtrException
-fun void test(nonnull Object o) {
-  <<< o >>>;
-}
-ref Object o => test;
diff --git a/tests/nonnull/nonnull_err_static_cast.gw b/tests/nonnull/nonnull_err_static_cast.gw
deleted file mode 100644 (file)
index 95cd395..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#! [contains] NullPtrException
-ref Object ref_object;
-<<< ref_object $ nonnull Object >>>;
diff --git a/tests/nonnull/nonnull_impl_nonnull.gw b/tests/nonnull/nonnull_impl_nonnull.gw
deleted file mode 100644 (file)
index f8e288a..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-fun void test(nonnull Object o) { <<< o >>>; }
-nonnull Object o => test;
diff --git a/tests/nonnull/nonnull_implicit_nonnull.gw b/tests/nonnull/nonnull_implicit_nonnull.gw
deleted file mode 100644 (file)
index f8e288a..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-fun void test(nonnull Object o) { <<< o >>>; }
-nonnull Object o => test;
diff --git a/tests/nonnull/normal_at_nonnull.gw b/tests/nonnull/normal_at_nonnull.gw
deleted file mode 100644 (file)
index ea7ac12..0000000
+++ /dev/null
@@ -1 +0,0 @@
-new Object @=> nonnull Object o;
diff --git a/tests/nonnull/normal_cast_nonnull.gw b/tests/nonnull/normal_cast_nonnull.gw
deleted file mode 100644 (file)
index c630d98..0000000
+++ /dev/null
@@ -1 +0,0 @@
-new Object $ nonnull Object;
diff --git a/tests/nonnull/normal_impl_nonnull.gw b/tests/nonnull/normal_impl_nonnull.gw
deleted file mode 100644 (file)
index 6d30b14..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-fun void test(nonnull Object o) { <<< o >>>; }
-new Object => test;
diff --git a/tests/nonnull/null_at_nonnull.gw b/tests/nonnull/null_at_nonnull.gw
deleted file mode 100644 (file)
index adc5ded..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#! [contains] can't assign
-null @=> nonnull Object o;
diff --git a/tests/nonnull/null_cast_nonnull.gw b/tests/nonnull/null_cast_nonnull.gw
deleted file mode 100644 (file)
index d2e5056..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#! [contains] can't cast
-null $ nonnull Object;
diff --git a/tests/nonnull/null_impl_nonnull.gw b/tests/nonnull/null_impl_nonnull.gw
deleted file mode 100644 (file)
index 3c2fbca..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#! [contains] can't implicitly cast
-fun void test(nonnull Object o) { <<< o >>>; }
-null => test;
diff --git a/tests/nonnull/ref.gw b/tests/nonnull/ref.gw
deleted file mode 100644 (file)
index ea7ac12..0000000
+++ /dev/null
@@ -1 +0,0 @@
-new Object @=> nonnull Object o;
diff --git a/tests/nonnull/ref_at_nonnull.gw b/tests/nonnull/ref_at_nonnull.gw
deleted file mode 100644 (file)
index db626b4..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#! [contains] NullPtrException
-ref Object o @=> nonnull Object p;
diff --git a/tests/nonnull/ref_cast_nonnull.gw b/tests/nonnull/ref_cast_nonnull.gw
deleted file mode 100644 (file)
index 6f63edb..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#! [contains] NullPtrException
-(ref Object o) $ nonnull Object;
diff --git a/tests/nonnull/ref_impl_nonnull.gw b/tests/nonnull/ref_impl_nonnull.gw
deleted file mode 100644 (file)
index 003d9a2..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#! [contains] NullPtrException
-fun void test(nonnull Object o) { <<< o >>>; }
-ref Object o => test;
diff --git a/tests/nonnull/ref_nonnull.gw b/tests/nonnull/ref_nonnull.gw
deleted file mode 100644 (file)
index 1ff7a38..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#! [contains] NullPtrException
-ref Object a @=> nonnull Object o;
-<<< o >>>;
diff --git a/tests/nonnull/static_implicit_nonnull.gw b/tests/nonnull/static_implicit_nonnull.gw
deleted file mode 100644 (file)
index 3f657ac..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-#! [contains] can't implicitly cast
-fun void test(nonnull Object o) { <<< o >>>; }
-
-null => test;
diff --git a/tests/nonnull/void_nonnull.gw b/tests/nonnull/void_nonnull.gw
deleted file mode 100644 (file)
index 7952f23..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#! [contains] void types can't be nonnull
-nonnull void i;
index f2b95b86ee40914980b72ec737c0f7eb0fdd88d3..14ace8085bdae309a0f5d9f105a3f48b15fbc849 100644 (file)
@@ -6,12 +6,3 @@
 
 <<< s0 != s0 >>>;
 <<< s0 != s1 >>>;
-
-<<< null == s0 >>>;
-<<< null != s0 >>>;
-
-<<< s0 == null >>>;
-<<< s0 != null >>>;
-
-<<< null == null >>>;
-<<< null != null >>>;
diff --git a/tests/tree/call_nonnull.gw b/tests/tree/call_nonnull.gw
deleted file mode 100644 (file)
index 49ba318..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-funcdef void test_t:[A]();
-nonnull test_t t;
-t:[int]();
index 8cb564e0a8bab40ed5af9878834d44214a79dbe6..38ff83aefd29cd1116daca9f1de2a97fb3614bfe 100644 (file)
@@ -5,4 +5,3 @@ var Event ev;
 ev @=> ref Event e;
 new Event @=> e;
 ev @=> e;
-null @=> e;
index 6a7374e8bd72d4afb68affc1957ee2af63d08857..ae8180a636e86e52800362d29e0e913bbdb9d8e7 100644 (file)
@@ -1,4 +1,4 @@
-typedef int[2]Type;
-nonnull Type type;
+typedef int[2] Type;
+Type type;
 <<<type>>>;
 foreach(ref a : type);
index 92fb715bcdca95476f3acc9e15ff5ce0c6a2e3bf..989af2a5ce1eed5bcdb32f93f6a284dc2ee4eae8 100644 (file)
@@ -1,3 +1,3 @@
 fun void test(int i, ...) {}
 
-test(1, 2.3, null);
+test(1, 2.3, new Object);