]> Nishi Git Mirror - gwion.git/commitdiff
Fix Flags
authorfennecdjay <fennecdjay@gwion.tk>
Mon, 2 Nov 2020 11:45:02 +0000 (12:45 +0100)
committerfennecdjay <fennecdjay@gwion.tk>
Mon, 2 Nov 2020 11:45:02 +0000 (12:45 +0100)
61 files changed:
include/env/envset.h
include/env/func.h
include/env/type.h
include/env/value.h
include/import/checker.h
include/instr.h
include/parse.h
include/vm.h
po/fr/gwion.mo [new file with mode: 0644]
src/clean.c
src/emit/emit.c
src/emit/emitter.c
src/env/env.c
src/env/env_utils.c
src/env/envset.c
src/env/func.c
src/env/nspc.c
src/env/type.c
src/env/type_special.c
src/env/value.c
src/gwion.c
src/import/import_cdef.c
src/import/import_enum.c
src/import/import_fdef.c
src/import/import_internals.c
src/import/import_item.c
src/import/import_special.c
src/import/import_udef.c
src/lib/engine.c
src/lib/event.c
src/lib/instr.c
src/lib/lib_func.c
src/lib/object.c
src/lib/object_op.c
src/lib/ptr.c
src/lib/shred.c
src/lib/ugen.c
src/lib/vararg.c
src/parse/check.c
src/parse/func_operator.c
src/parse/func_resolve_tmpl.c
src/parse/operator.c
src/parse/scan0.c
src/parse/scan1.c
src/parse/scan2.c
src/parse/scanx.c
src/parse/stage.c
src/parse/template.c
src/parse/traverse.c
src/vm/gack.c
src/vm/vm.c
src/vm/vm_code.c
tests/error/final_func.gw [new file with mode: 0644]
tests/error/final_inherit.gw [new file with mode: 0644]
tests/error/must_abstract0.gw [new file with mode: 0644]
tests/error/must_abstract1.gw [new file with mode: 0644]
tests/error/no_inherit.gw [deleted file]
tests/fork/fork_call.gw
tests/import/class_template.c
tests/import/class_template_invalid.c
tests/import/variadic.c

index 1e11c9b9311f87cada5675dff664ccd32e542322..c9838df6997cf489ac20854d805c6f63d3bc2add 100644 (file)
@@ -7,7 +7,7 @@ struct EnvSet {
   const envset_func func;
   const void *data;
   const m_int scope;
-  const ae_flag flag;
+  const enum tflag flag;
   m_bool run;
 };
 
index 5375b0a630e26a86fbbfdb43b568542bad144582..fa2d3ea2a9fc1b7bee30dc5a6c31b5e9e5347740 100644 (file)
@@ -1,5 +1,14 @@
 #ifndef __FUNC
 #define __FUNC
+
+enum fflag {
+  fflag_none  = 1 << 0,
+  fflag_pure  = 1 << 1,
+  fflag_ftmpl = 1 << 2,
+  fflag_tmpl  = 1 << 3,
+  fflag_valid = 1 << 4,
+} __attribute__((packed));
+
 struct Func_ {
   m_str name;
   Func_Def def;
@@ -9,9 +18,34 @@ struct Func_ {
   size_t vt_index;
   HAS_OBJ
   ae_flag flag;
+  enum fflag fflag;
 };
 
+static inline int fflag(const Func f, const enum fflag flag) {
+  return (f->fflag & flag) == flag;
+}
+#ifndef __cplusplus
+static inline void set_fflag(const Func f, const enum fflag flag) {
+  f->fflag |= flag;
+}
+
+static inline void unset_fflag(const Func f, const enum fflag flag) {
+  f->fflag &= ~flag;
+}
+#else
+static inline void set_fflag(const Func f, const enum fflag flag) {
+  const auto ff = f->fflag | flag;
+  f->fflag = static_cast<enum fflag>(ff);
+}
+
+static inline void unset_fflag(const Func f, const enum fflag flag) {
+  const auto ff = f->fflag & ~flag;
+  f->fflag = static_cast<enum fflag>(ff);
+}
+#endif
+
 ANEW ANN Func new_func(MemPool, const m_str, const Func_Def);
 ANN2(1,2) Symbol func_symbol(const Env, const m_str, const m_str, const m_str, const m_uint);
 ANN m_bool check_lambda(const Env, const Type, Exp_Lambda*);
+ANN void builtin_func(const MemPool mp, const Func f, void* func_ptr);
 #endif
index 0ff7e13ffd7dc8a00ecebfc5f816de40a54c945c..dd8b49bb21d4162edd0c7b1b5afc5f6e9a6178b9 100644 (file)
@@ -5,7 +5,10 @@ struct TypeInfo_ {
   Type parent;
   Nspc owner;
   Type owner_class;
-  Class_Def def;
+  union {
+    Union_Def udef;
+    Class_Def cdef;
+  };
   union type_data {
     Func      func;
     Type      base_type;
@@ -15,6 +18,29 @@ struct TypeInfo_ {
   struct Context_ *ctx;
 };
 
+enum tflag {
+  tflag_none    = 1 << 0,
+  tflag_scan0   = 1 << 1,//
+  tflag_scan1   = 1 << 2,//
+  tflag_scan2   = 1 << 3,//
+  tflag_check   = 1 << 4,//
+  tflag_emit    = 1 << 5,//
+  tflag_infer   = 1 << 6,
+  tflag_empty   = 1 << 7,
+  tflag_ftmpl   = 1 << 8,
+  tflag_ntmpl   = 1 << 9, // do NOT need types
+  tflag_ctmpl   = 1 << 10, // child template
+  tflag_udef    = 1 << 11,
+  tflag_cdef    = 1 << 12,
+  tflag_struct  = 1 << 13,
+  tflag_ctor    = 1 << 14,
+  tflag_dtor    = 1 << 15,
+  tflag_tmpl    = 1 << 16,
+  tflag_typedef = 1 << 17,
+  tflag_nonnull = 1 << 18,
+  tflag_force   = 1 << 19,
+} __attribute__((packed));
+
 struct Type_ {
   m_str     name;
   Nspc      nspc;
@@ -24,8 +50,25 @@ struct Type_ {
   size_t array_depth;
   HAS_OBJ
   ae_flag flag;
+  enum tflag tflag;
 };
 
+ANN static inline int tflag(const Type t, const enum tflag flag) {
+  return (t->tflag & flag) == flag;
+}
+static inline int safe_tflag(const Type t, const enum tflag flag) {
+  return t ? ((t->tflag & flag) == flag) : 0;
+}
+#ifndef __cplusplus
+ANN static inline void set_tflag(const Type t, const enum tflag flag) {
+  t->tflag |= flag;
+}
+#else
+ANN static inline void set_tflag(const Type t, const enum tflag flag) {
+  auto ff = t->tflag | flag;
+  t->tflag = static_cast<enum tflag>(ff);
+}
+#endif
 ANN2(1,3) ANEW Type new_type(MemPool, const m_uint xid, const m_str name, const Type);
 ANEW ANN Type type_copy(MemPool, const Type type);
 ANN m_str get_type_name(const Env, const Type t, const m_uint);
@@ -59,7 +102,7 @@ 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 GET_FLAG(t, nonnull) || GET_FLAG(t, force);
+  return tflag(t, tflag_nonnull) || tflag(t, tflag_force);
 }
 
 typedef enum {
index 2f592d39ceee25ac32032a659f166a46ce86fcc4..00f98d37bd51019c845aa832115495fa58368695 100644 (file)
@@ -7,6 +7,20 @@ struct ValueFrom_ {
   size_t offset;
 };
 
+enum vflag {
+  vflag_none  = 1 << 0,
+  vflag_func  = 1 << 1,
+  vflag_union = 1 << 2,
+  vflag_enum  = 1 << 3,
+  vflag_freeme  = 1 << 4,
+  vflag_fglobal  = 1 << 5,
+  vflag_valid    = 1 << 6,
+  vflag_direct    = 1 << 7,
+  vflag_builtin    = 1 << 8,
+  vflag_member   = 1 << 9
+//  vflag_used = 1 << 3
+} __attribute__((packed));
+
 struct Value_ {
   Type type;
   m_str name;
@@ -17,8 +31,24 @@ struct Value_ {
   } d;
   HAS_OBJ
   ae_flag flag;
+  enum vflag vflag;
 };
 
+static inline int vflag(const Value v, const enum vflag flag) {
+  return (v->vflag & flag) == flag;
+}
+
+#ifndef __cplusplus
+static inline void set_vflag(const Value v, const enum vflag flag) {
+  v->vflag |= flag;
+}
+#else
+static inline void set_vflag(const Value v, const enum vflag flag) {
+  auto ff = v->vflag | flag;
+  v->vflag = static_cast<enum vflag>(ff);
+}
+#endif
+
 ANEW ANN Value new_value(MemPool p, const Type type, const m_str name);
 ANN void valuefrom(const Env, struct ValueFrom_*);
 #endif
index 3b1cc6ccb54cb90af787638b7f6f2c243f4974a4..5ef1d61aab9e830b4cb1356b38f75c96cc5a6872 100644 (file)
@@ -31,6 +31,7 @@ typedef struct ImportCK { // name_checker ?
     ID_List curr;// enum
   };
   ae_flag flag; // ????
+  uint variadic;
   enum importck_type type;
 } ImportCK;
 
index fa9b48529c2939e612d7b1982b96ccb6a874ceec..5e260639d9a5f9e32243304e43ef8529e90f586e 100644 (file)
@@ -63,6 +63,7 @@ struct dottmpl_ {
   Nspc owner;
   size_t vt_index;
   Type_List tl;
+  void* xfun;// (type is f_xfun)
 };
 ANN void free_dottmpl(struct dottmpl_*);
 ANN m_bool traverse_dot_tmpl(const Emitter emit, const struct dottmpl_ *dt);
index 6288998451bb3fc14ac1c6c5bedfc3ec934f1c8a..394a5314e76faac61aa4f23c40bb88b43ae65fc4 100644 (file)
@@ -48,7 +48,7 @@ ANN static m_bool prefix##_stmt_##name(const Env env, const type stmt) { \
 
 ANN m_uint union_push(const Env, const Union_Def);
 ANN void union_pop(const Env, const Union_Def, const m_uint);
-ANN void union_flag(const Union_Def, const ae_flag);
+ANN void union_flag(const Union_Def, const enum tflag);
 ANN m_bool check_stmt(const Env env, const Stmt stmt);
 
 typedef m_bool (*_exp_func)(const void*, const void*);
@@ -58,25 +58,19 @@ static inline ANN m_bool env_body(const Env env, const Class_Def cdef, const _ex
 }
 #define env_body(a,b,c) env_body(a,b,(_exp_func)c)
 
-ANN m_bool scanx_cdef(const Env, void *,const Class_Def,
+ANN m_bool scanx_cdef(const Env, void *, const Type,
   const _exp_func f_cdef, const _exp_func f_union);
 
-#define xxx_cdef(prefix)                                                  \
-static inline m_bool prefix##_cdef(const Env env, const Class_Def cdef) { \
-  return scanx_cdef(env, env, cdef,                                       \
-      (_exp_func)prefix##_class_def, (_exp_func)prefix##_union_def);      \
+#define xxx_cdef(prefix)                                             \
+static inline m_bool prefix##_cdef(const Env env, const Type t) {    \
+  return scanx_cdef(env, env, t,                                     \
+      (_exp_func)prefix##_class_def, (_exp_func)prefix##_union_def); \
 }
 
-#define xxx_cdef_flag(prefix)                                             \
-static inline m_bool prefix##_cdef(const Env env, const Class_Def cdef) { \
-  SET_FLAG(cdef, prefix);                                                 \
-  return scanx_cdef(env, env, cdef,                                       \
-      (_exp_func)prefix##_class_def, (_exp_func)prefix##_union_def);      \
-}
-xxx_cdef_flag(scan0)
-xxx_cdef_flag(scan1)
-xxx_cdef_flag(scan2)
-xxx_cdef_flag(check)
+xxx_cdef(scan0)
+xxx_cdef(scan1)
+xxx_cdef(scan2)
+xxx_cdef(check)
 xxx_cdef(traverse)
 
 ANN m_bool scanx_fdef(const Env, void *, const Func_Def, const _exp_func);
index cd7d7a100ec3c6c02c391acb0e21cc5a833c228c..7eefb167cc2a1b3e2ea60e686b7a1e5360dfbfc9 100644 (file)
@@ -13,6 +13,7 @@ struct VM_Code_ {
   m_str name;
   HAS_OBJ
   ae_flag flag;
+  int builtin;
 };
 
 typedef struct Shreduler_* Shreduler;
@@ -60,7 +61,7 @@ struct VM_Shred_ {
   struct ShredTick_ * tick;
   struct ShredInfo_ * info;
 };
-ANN2(1,5) ANEW VM_Code new_vm_code(MemPool p, const Vector instr, const m_uint stack_depth, const ae_flag, const m_str name);
+ANN2(1,5) ANEW VM_Code new_vm_code(MemPool p, const Vector instr, const m_uint stack_depth, const int builtin, const m_str name);
 
 ANN VM_Shred shreduler_get(const Shreduler s) __attribute__((hot));
 ANN void shreduler_remove(const Shreduler s, const VM_Shred out, const m_bool erase)__attribute__((hot));
diff --git a/po/fr/gwion.mo b/po/fr/gwion.mo
new file mode 100644 (file)
index 0000000..6c5906d
Binary files /dev/null and b/po/fr/gwion.mo differ
index a3bc2dbf3c923921f3f2090993ba2e017aaa2a80..b037f5413f5b6776b6a4c2bd8f4c6eeb97bad462 100644 (file)
@@ -278,7 +278,7 @@ ANN static void clean_func_base(Clean *a, Func_Base *b) {
 ANN static void clean_func_def(Clean *a, Func_Def b) {
   clean_func_base(a, b->base);
   ++a->scope;
-  if(b->d.code && !GET_FLAG(b->base, builtin))
+  if(b->d.code && !(b->base->func && vflag(b->base->func->value_ref, vflag_builtin)))
     clean_stmt(a, b->d.code);
   else
     b->d.code = NULL;
index 2792173156ac2dd96e1a629820358aac02f23b1e..42234bb80fdec1f2d79704d8aa8bd99bd56e2123 100644 (file)
@@ -85,7 +85,7 @@ ANN static void struct_pop(const Emitter emit, const Type type, const m_uint off
     if(isa(t, emit->gwion->type[et_object]) > 0) {
       const Instr instr = emit_add_instr(emit, ObjectRelease);
       instr->m_val = offset + vector_at(&type->e->tuple->offset, i);
-    } else if(GET_FLAG(t, struct))
+    } else if(tflag(t, tflag_struct))
       struct_pop(emit, t, offset + vector_at(&type->e->tuple->offset, i));
   }
 }
@@ -94,7 +94,7 @@ ANN static m_int frame_pop(const Emitter emit) {
   Frame *frame = emit->code->frame;
   DECL_OB(const Local*, l, = (Local*)vector_pop(&frame->stack))
   frame->curr_offset -= l->type->size;
-  if(GET_FLAG(l->type, struct)) {
+  if(tflag(l->type, tflag_struct)) {
     struct_pop(emit, l->type, l->offset);
     return frame_pop(emit);
   }
@@ -166,7 +166,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) && GET_FLAG(t, ctor))
+  if(!is_special(t) && tflag(t, tflag_ctor))
     emit_ext_ctor(emit, t);
 }
 
@@ -174,8 +174,8 @@ ANN static void emit_pre_ctor(const Emitter emit, const Type type) {
   if(type->e->parent)
     emit_pre_ctor(emit, type->e->parent);
   maybe_ctor(emit, type);
-  if(GET_FLAG(type, typedef) && type->e->parent->array_depth)
-    emit_array_extend(emit, type->e->parent, type->e->def->base.ext->array->exp);
+  if(tflag(type, tflag_typedef) && type->e->parent->array_depth)
+    emit_array_extend(emit, type->e->parent, type->e->cdef->base.ext->array->exp);
 }
 
 #define regxxx(name, instr) \
@@ -203,12 +203,12 @@ ANN static void emit_pre_constructor_array(const Emitter emit, const Type type)
   const m_uint start_index = emit_code_size(emit);
   const Instr top = emit_add_instr(emit, ArrayTop);
   top->m_val2 = (m_uint)type;
-  if(GET_FLAG(type, struct)) {
+  if(tflag(type, tflag_struct)) {
     const Instr instr = emit_add_instr(emit, ArrayStruct);
     instr->m_val = type->size;
   }
   emit_pre_ctor(emit, type);
-  if(!GET_FLAG(type, struct))
+  if(!tflag(type, tflag_struct))
     emit_add_instr(emit, ArrayBottom);
   else
     regpop(emit, SZ_INT);
@@ -345,7 +345,7 @@ ANN static m_bool emit_symbol_owned(const Emitter emit, const Symbol *data) {
 
 ANN static m_bool emit_symbol_builtin(const Emitter emit, const Symbol *data) {
   const Value v = prim_self(data)->value;
-  if(GET_FLAG(v, union)) {
+  if(vflag(v, vflag_direct)) {
     const m_uint size = v->type->size;
     const Instr instr = emit_kind(emit, size, exp_getvar(prim_exp(data)), dotstatic);
     instr->m_val = (m_uint)v->d.ptr;
@@ -374,10 +374,10 @@ ANN static m_bool _emit_symbol(const Emitter emit, const Symbol *data) {
   }
   if(v->from->owner_class)
     return emit_symbol_owned(emit, data);
-  if(GET_FLAG(v, builtin) || GET_FLAG(v, union) || GET_FLAG(v, enum))
+  if(vflag(v, vflag_builtin) || vflag(v, vflag_direct) || vflag(v, vflag_enum))
     return emit_symbol_builtin(emit, data);
   const m_uint size = v->type->size;
-  const Instr instr = emit_kind(emit, size, exp_getvar(prim_exp(data)), !GET_FLAG(v, global) ? regpushmem : regpushbase);
+  const Instr instr = emit_kind(emit, size, exp_getvar(prim_exp(data)), !vflag(v, vflag_fglobal) ? regpushmem : regpushbase);
   instr->m_val  = v->from->offset;
   return GW_OK;
 }
@@ -437,7 +437,7 @@ ANN static m_bool emit_prim_range(const Emitter emit, Range **data) {
 }
 
 ANN m_bool emit_array_access(const Emitter emit, struct ArrayAccessInfo *const info) {
-  if(GET_FLAG(info->array.type, typedef)) {
+  if(tflag(info->array.type, tflag_typedef)) {
     info->array.type = info->array.type->e->parent;
     return emit_array_access(emit, info);
   }
@@ -557,7 +557,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 && !GET_FLAG(e->info->type, force))
+    if(isobj && !tflag(e->info->type, tflag_force))
       emit_add_instr(emit, GackType);
     const Instr instr = emit_add_instr(emit, Gack);
     instr->m_val = emit_code_offset(emit);
@@ -612,7 +612,7 @@ ANN static m_bool decl_static(const Emitter emit, const Var_Decl var_decl, const
 }
 
 ANN static inline int struct_ctor(const Value v) {
-  return GET_FLAG(v->type, struct) && v->type->nspc->pre_ctor;
+  return tflag(v->type, tflag_struct) && v->type->nspc->pre_ctor;
 }
 
 ANN static void decl_expand(const Emitter emit, const Type t) {
@@ -654,21 +654,21 @@ ANN static m_bool emit_exp_decl_non_static(const Emitter emit, const Exp_Decl *d
   const m_bool is_array = (array && array->exp) /*|| GET_FLAG(decl->td, force)*/;
   const m_bool is_obj = isa(type, emit->gwion->type[et_object]) > 0;
   const uint emit_addr = (!is_obj || (is_ref && !is_array)) ? emit_var : 1;
-  if(is_obj && (is_array || !is_ref) && !GET_FLAG(v, ref))
+  if(is_obj && (is_array || !is_ref) && !GET_FLAG(decl->td, ref))
     CHECK_BB(emit_instantiate_object(emit, type, array, is_ref))
   f_instr *exec = (f_instr*)allocmember;
-  if(!GET_FLAG(v, member)) {
+  if(!vflag(v, vflag_member)) {
     v->from->offset = emit_local(emit, type);
     exec = (f_instr*)(allocword);
-    if(GET_FLAG(v, ref)) { // ref or emit_var ?
+    if(GET_FLAG(decl->td, ref)) { // ref or emit_var ?
       const Instr clean = emit_add_instr(emit, MemSetImm);
       clean->m_val = v->from->offset;
     }
   }
-  const Instr instr = !(SAFE_FLAG(emit->env->class_def, struct) && !emit->env->scope->depth) ?
+  const Instr instr = !(safe_tflag(emit->env->class_def, tflag_struct) && !emit->env->scope->depth) ?
     emit_kind(emit, v->type->size, !struct_ctor(v) ? emit_addr : 1, exec) : emit_struct_decl(emit, v, !struct_ctor(v) ? emit_addr : 1);
   instr->m_val = v->from->offset;
-  if(is_obj && (is_array || !is_ref) && !GET_FLAG(v, ref)) {
+  if(is_obj && (is_array || !is_ref) && !GET_FLAG(decl->td, ref)) {
     if(!emit_var)
       emit_add_instr(emit, Assign);
     else {
@@ -677,7 +677,7 @@ ANN static m_bool emit_exp_decl_non_static(const Emitter emit, const Exp_Decl *d
       instr->m_val = -SZ_INT;
     }
     const size_t missing_depth = type->array_depth - (array ? array->depth : 0);
-    if(missing_depth && !GET_FLAG(decl->td, force)) {
+    if(missing_depth) {
       const Instr push = emit_add_instr(emit, Reg2Reg);
       push->m_val = -(missing_depth) * SZ_INT;
     }
@@ -694,17 +694,18 @@ ANN static m_bool emit_exp_decl_global(const Emitter emit, const Exp_Decl *decl,
   const m_bool is_array = array && array->exp;
   const m_bool is_obj = isa(type, emit->gwion->type[et_object]) > 0;
   const uint emit_addr = (!is_obj || (is_ref && !is_array)) ? emit_var : 1;
-  if(is_obj && (is_array || !is_ref) && !GET_FLAG(v, ref))
+  if(is_obj && (is_array || !is_ref) && !GET_FLAG(decl->td, ref))
     CHECK_BB(emit_instantiate_object(emit, type, array, is_ref))
   const Instr instr = emit_kind(emit, v->type->size, !struct_ctor(v) ? emit_addr : 1, dotstatic);
   v->d.ptr = mp_calloc2(emit->gwion->mp, v->type->size);
-  SET_FLAG(v, union);
+if(isa(type, emit->gwion->type[et_union]) < 0)
+  set_vflag(v, vflag_direct);// mpalloc
   instr->m_val = (m_uint)v->d.ptr;
   instr->m_val2 = v->type->size;
-  if(is_obj && (is_array || !is_ref) && !GET_FLAG(v, ref)) {
+  if(is_obj && (is_array || !is_ref) && !GET_FLAG(decl->td, ref)) {
     const Instr assign = emit_add_instr(emit, Assign);
     const size_t missing_depth = type->array_depth - (array ? array->depth : 0);
-    if(missing_depth && !GET_FLAG(decl->td, force)) {
+    if(missing_depth) {
       const Instr push = emit_add_instr(emit, Reg2Reg);
       push->m_val = -(missing_depth) * SZ_INT;
     }
@@ -716,11 +717,11 @@ ANN static m_bool emit_exp_decl_global(const Emitter emit, const Exp_Decl *decl,
 }
 
 ANN static m_bool emit_class_def(const Emitter, const Class_Def);
-ANN static m_bool emit_cdef(const Emitter, const Class_Def);
+ANN static m_bool emit_cdef(const Emitter, const Type);
 
 ANN static inline m_bool ensure_emit(const Emitter emit, const Type t) {
   struct EnvSet es = { .env=emit->env, .data=emit, .func=(_exp_func)emit_cdef,
-    .scope=emit->env->scope->depth, .flag=ae_flag_emit };
+    .scope=emit->env->scope->depth, .flag=tflag_emit };
   return envset_run(&es, t);
 }
 
@@ -743,7 +744,7 @@ ANN static m_bool emit_decl(const Emitter emit, const Exp_Decl* decl) {
 
 ANN /*static */m_bool emit_exp_decl(const Emitter emit, const Exp_Decl* decl) {
   const Type t = get_type(decl->type);
-  if(!GET_FLAG(t, emit) && t->e->def)
+  if(!tflag(t, tflag_emit))
     CHECK_BB(ensure_emit(emit, t))
   const m_bool global = GET_FLAG(decl->td, global);
   const m_uint scope = !global ? emit->env->scope->depth : emit_push_global(emit);
@@ -792,7 +793,7 @@ ANN static m_bool emit_func_args(const Emitter emit, const Exp_Call* exp_call) {
     CHECK_BB(emit_exp(emit, exp_call->args))
     emit_exp_addref(emit, exp_call->args, -exp_totalsize(exp_call->args));
   }
-  if(exp_call->m_func && GET_FLAG(exp_call->m_func->def->base, variadic))
+  if(exp_call->m_func && fbflag(exp_call->m_func->def->base, fbflag_variadic))
     emit_func_arg_vararg(emit, exp_call);
   return GW_OK;
 }
@@ -817,7 +818,7 @@ ANN static m_bool emit_exp_call(const Emitter emit, const Exp_Call* exp_call) {
     const Instr instr = emit_add_instr(emit, Reg2RegAddr);
     instr->m_val = -SZ_INT;
     instr->m_val2 = -SZ_INT;
-  } else if(!exp_call->m_func && GET_FLAG(e->info->type, struct))
+  } else if(!exp_call->m_func && tflag(e->info->type, tflag_struct))
     regpop(emit, SZ_INT);
   return GW_OK;
 }
@@ -905,7 +906,7 @@ ANN static inline m_bool traverse_emit_func_def(const Emitter emit, const Func_D
 ANN m_bool traverse_dot_tmpl(const Emitter emit, const struct dottmpl_ *dt) {
   const m_uint scope = emit->env->scope->depth;
   struct EnvSet es = { .env=emit->env, .data=emit, .func=(_exp_func)emit_cdef,
-    .scope=scope, .flag=ae_flag_emit };
+    .scope=scope, .flag=tflag_emit };
   CHECK_BB(envset_push(&es, dt->owner_class, dt->owner))
   (void)emit_push(emit, dt->owner_class, dt->owner);
   const m_bool ret = traverse_emit_func_def(emit, dt->def);
@@ -945,7 +946,7 @@ ANN static m_bool emit_template_code(const Emitter emit, const Func f) {
   const Value v = f->value_ref;
   const size_t scope = emit->env->scope->depth;
   struct EnvSet es = { .env=emit->env, .data=emit, .func=(_exp_func)emit_cdef,
-    .scope=scope, .flag=ae_flag_emit };
+    .scope=scope, .flag=tflag_emit };
   CHECK_BB(envset_push(&es, v->from->owner_class, v->from->owner))
   (void)emit_push(emit, v->from->owner_class, v->from->owner);
   const m_bool ret = emit_func_def(emit, f->def);
@@ -988,7 +989,7 @@ ANN static Instr get_prelude(const Emitter emit, const Func f) {
 }
 
 ANN static void emit_args(const Emitter emit, const Func f) {
-  const m_uint member = GET_FLAG(f, member) ? SZ_INT : 0;
+  const m_uint member = vflag(f->value_ref, vflag_member) ? SZ_INT : 0;
   if((f->def->stack_depth - member) == SZ_INT) {
     const Instr instr = emit_add_instr(emit, Reg2Mem);
     instr->m_val = member;
@@ -1042,7 +1043,7 @@ ANN static m_bool me_arg(MemoizeEmitter *me) {
 ANN static Instr emit_call(const Emitter emit, const Func f) {
   const Instr prelude = get_prelude(emit, f);
   prelude->m_val = f->def->stack_depth;
-  const m_uint member = GET_FLAG(f, member) ? SZ_INT : 0;
+  const m_uint member = vflag(f->value_ref, vflag_member) ? SZ_INT : 0;
   if(member) {
     const Instr instr = emit_add_instr(emit, Reg2Mem);
     instr->m_val2 = f->def->stack_depth - SZ_INT;
@@ -1056,8 +1057,9 @@ ANN static Instr emit_call(const Emitter emit, const Func f) {
 }
 
 ANN Instr emit_exp_call1(const Emitter emit, const Func f) {
-  if(!f->code || (GET_FLAG(f, ref) && !GET_FLAG(f, builtin))) {
-    if(GET_FLAG(f, template) && !is_fptr(emit->gwion, f->value_ref->type)) {
+  const int tmpl = fflag(f, fflag_tmpl);
+  if(!f->code || (fflag(f, fflag_ftmpl) && !vflag(f->value_ref, vflag_builtin))) {
+    if(tmpl && !is_fptr(emit->gwion, f->value_ref->type)) {
       if(emit->env->func != f)
         CHECK_BO(emit_template_code(emit, f))
       else { // recursive function. (maybe should be used only for global funcs)
@@ -1068,7 +1070,7 @@ ANN Instr emit_exp_call1(const Emitter emit, const Func f) {
         back->m_val = 0;
       }
     } else if(emit->env->func != f && !f->value_ref->from->owner_class && !f->code && !is_fptr(emit->gwion, f->value_ref->type)) {
-      if(GET_FLAG(f->def->base, op)) {
+      if(fbflag(f->def->base, fbflag_op)) {
         const Instr back = (Instr)vector_back(&emit->code->instr);
         back->m_val = (m_uint)f;
       } else {
@@ -1079,8 +1081,8 @@ ANN Instr emit_exp_call1(const Emitter emit, const Func f) {
         instr->m_val2 = -SZ_INT;
       }
     }
-  } else if((f->value_ref->from->owner_class && GET_FLAG(f->value_ref->from->owner_class, struct)) ||
-        !f->value_ref->from->owner_class || (GET_FLAG(f, template) &&
+  } else if((f->value_ref->from->owner_class && tflag(f->value_ref->from->owner_class, tflag_struct)) ||
+        !f->value_ref->from->owner_class || (tmpl &&
         !is_fptr(emit->gwion, f->value_ref->type)))
     push_func_code(emit, f);
   else if(vector_size(&emit->code->instr)) {
@@ -1088,7 +1090,7 @@ ANN Instr emit_exp_call1(const Emitter emit, const Func f) {
     if((f_instr)(m_uint)back->opcode == DotFunc || (f_instr)(m_uint)back->opcode == DotStaticFunc)
       back->m_val = f->vt_index;
   }
-  if(vector_size(&emit->code->instr) && GET_FLAG(f, member) &&
+  if(vector_size(&emit->code->instr) && vflag(f->value_ref, vflag_member) &&
         is_fptr(emit->gwion, f->value_ref->type)) {
     const Instr back = (Instr)vector_back(&emit->code->instr);
     m_bit exec = back->opcode;
@@ -1133,11 +1135,6 @@ static inline void stack_alloc(const Emitter emit) { // maybe vararg could use t
   emit->code->stack_depth += SZ_INT;
 }
 
-static inline void stack_alloc_this(const Emitter emit) {
-  SET_FLAG(emit->code, member);
-  stack_alloc(emit);
-}
-
 static m_bool scoped_stmt(const Emitter emit, const Stmt stmt, const m_bool pop) {
   ++emit->env->scope->depth;
   emit_push_scope(emit);
@@ -1167,8 +1164,6 @@ static void push_spork_code(const Emitter emit, const m_str prefix, const loc_t
 }
 
 ANN static m_bool call_spork_func(const Emitter emit, const Exp_Call *exp) {
-  if(GET_FLAG(exp->m_func, member))
-    SET_FLAG(emit->code, member);
   return emit_exp_call1(emit, exp->m_func) ? GW_OK : GW_ERROR;
 }
 
@@ -1184,8 +1179,8 @@ struct Sporker {
 ANN static m_bool spork_prepare_code(const Emitter emit, const struct Sporker *sp) {
   emit_add_instr(emit, RegPushImm);
   push_spork_code(emit, sp->is_spork ? SPORK_CODE_PREFIX : FORK_CODE_PREFIX, sp->code->pos);
-  if(SAFE_FLAG(emit->env->func, member))
-    stack_alloc_this(emit);
+  if(emit->env->func && vflag(emit->env->func->value_ref, vflag_member))
+    stack_alloc(emit);
   return scoped_stmt(emit, sp->code, 0);
 }
 
@@ -1212,7 +1207,7 @@ ANN void spork_code(const Emitter emit, const struct Sporker *sp) {
 
 ANN void spork_func(const Emitter emit, const struct Sporker *sp) {
   const Func f = sp->exp->d.exp_call.m_func;
-  if(GET_FLAG(f, member) && is_fptr(emit->gwion, f->value_ref->type)) {
+  if(vflag(f->value_ref, vflag_member) && is_fptr(emit->gwion, f->value_ref->type)) {
     regpush(emit, SZ_INT*2);
     // (re-)emit owner
     if(sp->exp->d.exp_call.func->exp_type == ae_exp_dot)
@@ -1263,7 +1258,7 @@ ANN Instr emit_exp_spork(const Emitter emit, const Exp_Unary* unary) {
 ANN static m_bool emit_exp_unary(const Emitter emit, const Exp_Unary* unary) {
   const Type t = exp_self(unary)->info->type;
   const Type base = get_type(actual_type(emit->gwion, t));
-  if(base->e->def && !GET_FLAG(base, emit))
+  if(base->e->cdef && !tflag(base, tflag_emit)) // ???
     CHECK_BB(ensure_emit(emit, base))
   // no pos ?
   struct Op_Import opi = { .op=unary->op, .data=(uintptr_t)unary, .op_type=op_unary };
@@ -1307,7 +1302,7 @@ ANN static m_bool emit_exp_if(const Emitter emit, const Exp_If* exp_if) {
 
 ANN static m_bool emit_lambda(const Emitter emit, const Exp_Lambda * lambda) {
   CHECK_BB(emit_func_def(emit, lambda->def))
-  if(GET_FLAG(lambda->def->base, member) && !exp_getvar(exp_self(lambda)))
+  if(vflag(lambda->def->base->func->value_ref, vflag_member) && !exp_getvar(exp_self(lambda)))
     emit_add_instr(emit, RegPushMem);
   regpushi(emit, (m_uint)lambda->def->base->func->code);
   return GW_OK;
@@ -1319,7 +1314,7 @@ ANN static m_bool emit_exp_lambda(const Emitter emit, const Exp_Lambda * lambda)
     return GW_OK;
   }
   struct EnvSet es = { .env=emit->env, .data=emit, .func=(_exp_func)emit_cdef,
-    .scope=emit->env->scope->depth, .flag=ae_flag_emit };
+    .scope=emit->env->scope->depth, .flag=tflag_emit };
   CHECK_BB(envset_push(&es, lambda->owner, lambda->def->base->func->value_ref->from->owner))
   const m_bool ret = emit_lambda(emit, lambda);
   if(es.run)
@@ -1340,7 +1335,7 @@ ANN static void struct_addref(const Emitter emit, const Type type,
       const Instr instr = emit_addref(emit, emit_var);
       instr->m_val = size;
       instr->m_val2 = vector_at(&type->e->tuple->offset, i);
-    } else if(GET_FLAG(t, struct))
+    } else if(tflag(t, tflag_struct))
       struct_addref(emit, t, size, offset + vector_at(&type->e->tuple->offset, i), emit_var);
   }
 }
@@ -1357,7 +1352,7 @@ ANN2(1) static void emit_exp_addref1(const Emitter emit, /* const */Exp exp, m_i
     (exp->info->cast_to ? isa(exp->info->cast_to, emit->gwion->type[et_object]) > 0 : 1)) {
     const Instr instr = emit_addref(emit, exp_getvar(exp));
     instr->m_val = size;
-  } else if(GET_FLAG(exp->info->type, struct)) // check cast_to ?
+  } else if(tflag(exp->info->type, tflag_struct)) // check cast_to ?
     struct_addref(emit, exp->info->type, size, 0, exp_getvar(exp));
 }
 
@@ -1617,7 +1612,7 @@ ANN static m_bool emit_stmt_jump(const Emitter emit, const Stmt_Jump stmt) {
 }
 
 ANN static m_bool emit_type_def(const Emitter emit, const Type_Def tdef) {
-  return tdef->type->e->def ? emit_class_def(emit, tdef->type->e->def) : GW_OK;
+  return tdef->type->e->cdef ? emit_class_def(emit, tdef->type->e->cdef) : GW_OK;
 }
 
 ANN static m_bool emit_enum_def(const Emitter emit, const Enum_Def edef) {
@@ -1670,8 +1665,7 @@ ANN static m_bool emit_union_def(const Emitter emit, const Union_Def udef) {
     if(global) {
       const M_Object o = new_object(emit->gwion->mp, NULL, udef->value->type);
       udef->value->d.ptr = (m_uint*)o;
-      SET_FLAG(udef->value, builtin);
-      UNSET_FLAG(udef->value, union);
+      set_vflag(udef->value, vflag_builtin);
     }
     scope = emit_push_type(emit, udef->value->type);
   } else if(udef->type_xid) {
@@ -1682,22 +1676,20 @@ ANN static m_bool emit_union_def(const Emitter emit, const Union_Def udef) {
     void* ptr = (void*)xcalloc(1, udef->s);
     l = udef->l;
     udef->value->d.ptr = ptr;
-    SET_FLAG(udef->value, enum);
-    SET_FLAG(udef->value, dtor);
+    udef->value->vflag |= (vflag_enum | vflag_freeme);
     do {
       Var_Decl_List list = l->self->d.exp_decl.list;
       list->self->value->d.ptr = ptr;
-      SET_FLAG(list->self->value, union);
+      set_vflag(list->self->value, vflag_direct);// xcalloc
     } while((l = l->next));
-    SET_FLAG(udef->l->self->d.exp_decl.list->self->value, enum);
-    SET_FLAG(udef->l->self->d.exp_decl.list->self->value, dtor);
+    udef->l->self->d.exp_decl.list->self->value->vflag |= (vflag_enum | vflag_freeme);
   }
   if(udef->xid)
     regpop(emit, SZ_INT);
   emit_union_offset(udef->l, udef->o);
   if(udef->xid || udef->type_xid || global)
     emit_pop(emit, scope);
-  union_flag(udef, ae_flag_emit);
+  union_flag(udef, tflag_emit);
   return GW_OK;
 }
 
@@ -1895,7 +1887,7 @@ ANN static void emit_func_def_return(const Emitter emit) {
     instr->m_val = val;
   }
   vector_clear(&emit->code->stack_return);
-  if(emit->info->memoize && GET_FLAG(emit->env->func, pure)) {
+  if(emit->info->memoize && fflag(emit->env->func, fflag_pure)) {
     const Instr instr = emit_add_instr(emit, MemoizeStore);
     instr->m_val = emit->env->func->def->stack_depth;
   }
@@ -1917,7 +1909,7 @@ ANN static VM_Code emit_internal(const Emitter emit, const Func f) {
 }
 
 ANN static VM_Code emit_func_def_code(const Emitter emit, const Func func) {
-  if(GET_FLAG(func->def->base, typedef))
+  if(fbflag(func->def->base, fbflag_internal))
     return emit_internal(emit, func);
   else
     return finalyze(emit, FuncReturn);
@@ -1926,7 +1918,7 @@ ANN static VM_Code emit_func_def_code(const Emitter emit, const Func func) {
 ANN static m_bool emit_func_def_body(const Emitter emit, const Func_Def fdef) {
   if(fdef->base->args)
     emit_func_def_args(emit, fdef->base->args);
-  if(GET_FLAG(fdef->base, variadic))
+  if(fbflag(fdef->base, fbflag_variadic))
     stack_alloc(emit);
   if(fdef->d.code)
     CHECK_BB(scoped_stmt(emit, fdef->d.code, 1))
@@ -1990,7 +1982,7 @@ ANN static m_bool emit_memoize(const Emitter emit, const Func_Def fdef) {
 }
 
 ANN static m_bool emit_fdef(const Emitter emit, const Func_Def fdef) {
-  if(emit->info->memoize && GET_FLAG(fdef->base->func, pure))
+  if(emit->info->memoize && fflag(fdef->base->func, fflag_pure))
     CHECK_BB(emit_memoize(emit, fdef))
   CHECK_BB(emit_func_def_body(emit, fdef))
   emit_func_def_return(emit);
@@ -2008,7 +2000,7 @@ ANN static void emit_fdef_finish(const Emitter emit, const Func_Def fdef) {
   func->code = emit_func_def_code(emit, func);
   if(fdef_is_file_global(emit, fdef))
     emit_func_def_global(emit, func->value_ref);
-  if(emit->info->memoize && GET_FLAG(func, pure))
+  if(emit->info->memoize && fflag(func, fflag_pure))
     func->code->memoize = memoize_ini(emit, func);
 }
 
@@ -2018,13 +2010,13 @@ ANN static m_bool emit_func_def(const Emitter emit, const Func_Def f) {
   const Func former = emit->env->func;
   if(func->code || tmpl_base(fdef->base->tmpl))
     return GW_OK;
-  if(SAFE_FLAG(emit->env->class_def, builtin) && GET_FLAG(emit->env->class_def, template))
+  if(vflag(func->value_ref, vflag_builtin) && safe_tflag(emit->env->class_def, tflag_tmpl))
     return GW_OK;
   if(fdef_is_file_global(emit, fdef))
     func->value_ref->from->offset = emit_local(emit, emit->gwion->type[et_int]);
   emit_func_def_init(emit, func);
-  if(GET_FLAG(func, member))
-    stack_alloc_this(emit);
+  if(vflag(func->value_ref, vflag_member))
+    stack_alloc(emit);
   emit->env->func = func;
   emit_push_scope(emit);
   if(!strcmp(s_name(fdef->base->xid), "@gack")) {
@@ -2050,25 +2042,20 @@ ANN Code* emit_class_code(const Emitter emit, const m_str name) {
   char c[len];
   snprintf(c, len, "class %s", name);
   emit_push_code(emit, c);
-  stack_alloc_this(emit);
+  stack_alloc(emit);
   return emit->code;
 }
 
 ANN static m_bool emit_parent(const Emitter emit, const Class_Def cdef) {
   const Type parent = cdef->base.type->e->parent;
-  return !GET_FLAG(parent, emit) ? ensure_emit(emit, parent) : GW_OK;
+  return !tflag(parent, tflag_emit) ? ensure_emit(emit, parent) : GW_OK;
 }
 
-ANN static inline m_bool emit_cdef(const Emitter emit, const Class_Def cdef) {
-  return scanx_cdef(emit->env, emit, cdef,
+ANN static inline m_bool emit_cdef(const Emitter emit, const Type t) {
+  return scanx_cdef(emit->env, emit, t,
       (_exp_func)emit_class_def, (_exp_func)emit_union_def);
 }
 
-ANN void emit_class_finish(const Emitter emit, const Nspc nspc) {
-  nspc->pre_ctor = finalyze(emit, FuncReturn);
-  SET_FLAG(nspc->pre_ctor, ctor);
-}
-
 ANN static m_bool cdef_parent(const Emitter emit, const Class_Def cdef) {
   if(cdef->base.tmpl && cdef->base.tmpl->list)
     CHECK_BB(template_push_types(emit->env, cdef->base.tmpl))
@@ -2082,18 +2069,18 @@ ANN static m_bool emit_class_def(const Emitter emit, const Class_Def cdef) {
   if(tmpl_base(cdef->base.tmpl))
     return GW_OK;
   const Type t = cdef->base.type;
-  if(GET_FLAG(t, emit))
+  if(tflag(t, tflag_emit))
     return GW_OK;
-  SET_FLAG(t, emit);
-  if(t->e->owner_class && !GET_FLAG(t->e->owner_class, emit))
+  set_tflag(t, tflag_emit);
+  if(t->e->owner_class && !tflag(t->e->owner_class, tflag_emit))
     CHECK_BB(ensure_emit(emit, t->e->owner_class))
-  if(cdef->base.ext && t->e->parent->e->def && !GET_FLAG(t->e->parent, emit))
+  if(cdef->base.ext && t->e->parent->e->cdef && !tflag(t->e->parent, tflag_emit)) // ?????
     CHECK_BB(cdef_parent(emit, cdef))
   nspc_allocdata(emit->gwion->mp, t->nspc);
   if(cdef->body) {
     emit_class_code(emit, t->name);
     if(scanx_body(emit->env, cdef, (_exp_func)emit_section, emit) > 0)
-      emit_class_finish(emit, t->nspc);
+      t->nspc->pre_ctor = finalyze(emit, FuncReturn);
     else {
       free_code(emit->gwion->mp, emit->code);
       emit_pop_code(emit);
index 6520d9fa35eefc8cf9a6b20e9a7593df5354e444..142e1b212d87b0f054cda8bad7eabda039a0d64d 100644 (file)
@@ -9,8 +9,7 @@
 
 static ANEW ANN VM_Code emit_code(const Emitter emit) {
   Code* const c = emit->code;
-  const VM_Code code = new_vm_code(emit->gwion->mp, &c->instr, c->stack_depth,
-      c->flag, c->name);
+  const VM_Code code = new_vm_code(emit->gwion->mp, &c->instr, c->stack_depth, 0, c->name);
   return code;
 }
 
index e5360419dc386eafb5e3cd63f0d7eb19f31a0329..0dcda890bf5714e2cb22cd1035d03c5fce4b3a3d 100644 (file)
@@ -82,11 +82,11 @@ ANN void env_add_type(const Env env, const Type type) {
   const Type v_type = type_copy(env->gwion->mp, env->gwion->type[et_class]);
   ADD_REF(v_type);
   v_type->e->d.base_type = type;
-  SET_FLAG(type, builtin);
   const Symbol sym = insert_symbol(type->name);
   nspc_add_type_front(env->curr, sym, type);
   const Value v = new_value(env->gwion->mp, v_type, s_name(sym));
-  SET_FLAG(v, valid | ae_flag_const | ae_flag_global | ae_flag_builtin);
+  SET_FLAG(v, const | ae_flag_global);
+  set_vflag(v, vflag_valid | vflag_builtin);
   nspc_add_value(env->curr, insert_symbol(type->name), v);
   v->from->owner = type->e->owner = env->curr;
   v->from->owner_class = type->e->owner_class = env->class_def; // t owner_class ?
index ce6ab3d309e0ff68d272e3b634db9dc81ef313d3..a3661a4543b90f365b2698ec66cdc899b96e3237 100644 (file)
@@ -73,7 +73,7 @@ ANN static Type class_type(const Env env, const Type base) {
   t->e->parent = t_class;
   t->e->ctx = base->e->ctx;
   t->e->d.base_type = base;
-  SET_FLAG(t, infer);
+  set_tflag(t, tflag_infer);
   return t;
 }
 
@@ -82,7 +82,8 @@ ANN Value mk_class(const Env env, const Type base) {
   const Symbol sym = insert_symbol(base->name);
   const Value v = new_value(env->gwion->mp, t, s_name(sym));
   valuefrom(env, v->from);
-  SET_FLAG(v, const | ae_flag_valid);
+  SET_FLAG(v, const);
+  set_vflag(v, vflag_valid);
   nspc_add_value_front(base->e->owner, sym, v);
   return v;
 }
index 26efc742c6082dd9c054b1d96c2d5e202e07c022..5bfa468c72bc0fb354063309952dbead016ed8a3 100644 (file)
@@ -18,14 +18,15 @@ ANN static void check(struct EnvSet *es, const Type t) {
 }
 
 ANN static m_bool push(struct EnvSet *es, const Type t) {
+  es->env->scope->depth = 0;
   if(t->e->owner_class)
     CHECK_BB(push(es, t->e->owner_class))
   else
     env_push(es->env, NULL, t->e->ctx ? t->e->ctx->nspc : es->env->curr);
-  if(es->func && !(t->flag & es->flag))
-    CHECK_BB(es->func((void*)es->data, t->e->def))
-  if(GET_FLAG(t, template))
-    CHECK_BB(template_push_types(es->env, t->e->def->base.tmpl))
+  if(es->func && !(t->tflag & es->flag))
+    CHECK_BB(es->func((void*)es->data, t))
+  if(tflag(t, tflag_tmpl))
+    CHECK_BB(template_push_types(es->env, t->e->cdef->base.tmpl)) // incorrect templates
   env_push_type((void*)es->env, t);
   return GW_OK;
 }
@@ -46,7 +47,7 @@ ANN2(1) void envset_pop(struct EnvSet *es, const Type t) {
   env_pop(es->env, es->scope);
   if(!t)
     return;
-  if(GET_FLAG(t, template))
+  if(tflag(t, tflag_tmpl))
     nspc_pop_type(es->env->gwion->mp, es->env->curr);
   if(t->e->owner_class)
     envset_pop(es, t->e->owner_class);
@@ -58,8 +59,9 @@ ANN m_bool envset_run(struct EnvSet *es, const Type t) {
   check(es, t);
   if(es->run)
     CHECK_BB(push(es, t->e->owner_class))
-  const m_bool ret = !(t->flag & es->flag) ?
-    es->func(es->data, t->e->def) : GW_OK;
+  const m_bool ret = t->e->cdef &&
+    !(t->tflag & es->flag) ?
+        es->func(es->data, t) : GW_OK;
   if(es->run)
     envset_pop(es, t->e->owner_class);
   return ret;
index a1bda1022a2eb6afc64ae73798c5bf44d8e8935a..05944b085426312ee64e167132c8e60f8301c4e8 100644 (file)
@@ -6,7 +6,8 @@
 #include "clean.h"
 
 ANN static void free_func(Func a, Gwion gwion) {
-  if(GET_FLAG(a, template))
+//  if(GET_FLAG(a, template))
+  if(fflag(a, fflag_tmpl))
     func_def_cleaner(gwion, a->def);
   if(a->code)
     REM_REF(a->code, gwion);
@@ -34,3 +35,9 @@ ANN2(1,2) Symbol func_symbol(const Env env, const m_str nspc, const m_str base,
     i, nspc))
   return insert_symbol(env->gwion->st, name);
 }
+
+ANN void builtin_func(const MemPool mp, const Func f, void* func_ptr) {
+  set_vflag(f->value_ref, vflag_builtin);
+  f->code = new_vm_code(mp, NULL, f->def->stack_depth, 1, f->name);
+  f->code->native_func = (m_uint)func_ptr;
+}
index 27743ccd678762e5a789e196e0d0345f3083bf5c..b0c6cdc87182e6875d47bb6e17c98fffbc276a81 100644 (file)
@@ -13,8 +13,8 @@ ANN void nspc_commit(const Nspc nspc) {
 }
 
 ANN static inline void nspc_release_object(const Nspc a, Value value, Gwion gwion) {
-  if(!GET_FLAG(value, pure) && ((GET_FLAG(value, static) && a->info->class_data) ||
-    (value->d.ptr && GET_FLAG(value, builtin)))) {
+  if(!vflag(value, vflag_union) && ((GET_FLAG(value, static) && a->info->class_data) ||
+    (value->d.ptr && vflag(value, vflag_builtin)))) {
     const M_Object obj = value->d.ptr ? (M_Object)value->d.ptr :
         *(M_Object*)(a->info->class_data + value->from->offset);
        release(obj, gwion->vm->cleaner_shred);
@@ -22,15 +22,15 @@ ANN static inline void nspc_release_object(const Nspc a, Value value, Gwion gwio
 }
 
 ANN2(1,3) static inline void nspc_release_struct(const Nspc a, Value value, Gwion gwion) {
-  if(!SAFE_FLAG(value, pure) && ((SAFE_FLAG(value, static) && a->info->class_data) ||
-    (SAFE_FLAG(value, builtin) && value->d.ptr))) {
+  if(value && !vflag(value, vflag_union) && ((GET_FLAG(value, static) && a->info->class_data) ||
+    (vflag(value, vflag_builtin) && value->d.ptr))) {
     const m_bit *ptr = (value && value->d.ptr) ? (m_bit*)value->d.ptr:
         (m_bit*)(a->info->class_data + value->from->offset);
     for(m_uint i = 0; i < vector_size(&value->type->e->tuple->types); ++i) {
       const Type t = (Type)vector_at(&value->type->e->tuple->types, i);
       if(isa(t, gwion->type[et_object]) > 0)
         release(*(M_Object*)(ptr + vector_at(&value->type->e->tuple->offset, i)), gwion->vm->cleaner_shred);
-      else if(GET_FLAG(t, struct))
+      else if(tflag(t, tflag_struct))
         nspc_release_struct(t->nspc, NULL, gwion);
     }
   }
@@ -42,7 +42,7 @@ ANN static void free_nspc_value(const Nspc a, Gwion gwion) {
   while(scope_iter(&iter, &v) > 0) {
     if(isa(v->type, gwion->type[et_object]) > 0)
       nspc_release_object(a, v, gwion);
-    else if(GET_FLAG(v->type, struct))
+    else if(tflag(v->type, tflag_struct))
       nspc_release_struct(a, v, gwion);
     REM_REF(v, gwion);
   }
index bc6e3126688f4c33e4303547e944ac4c6f105000..61c1d50828d3fccb887c91c7a9c54e5354a1e2c4 100644 (file)
@@ -9,22 +9,15 @@
 #include "object.h"
 
 ANN static inline m_bool freeable(const Type a) {
-  return !GET_FLAG(a, nonnull) && GET_FLAG(a, template);
+  return !(tflag(a, tflag_force) || tflag(a, tflag_nonnull)) && (tflag(a, tflag_tmpl) ||GET_FLAG(a, global));
 }
 
 ANN static void free_type(Type a, Gwion gwion) {
   if(freeable(a)) {
-    if(GET_FLAG(a, union)) {
-      if(a->e->def->union_def) {
-        if(!GET_FLAG(a, pure))
-          free_union_def(gwion->mp, a->e->def->union_def);
-        else
-          free_decl_list(gwion->mp, a->e->def->list);
-      }
-      a->e->def->union_def = NULL;
-    }
-    if(a->e->def)
-      class_def_cleaner(gwion, a->e->def);
+    if(tflag(a, tflag_udef))
+      free_union_def(gwion->mp, a->e->udef);
+    if(tflag(a, tflag_cdef))
+      class_def_cleaner(gwion, a->e->cdef);
   }
   if(a->nspc)
     REM_REF(a->nspc, gwion);
@@ -32,6 +25,7 @@ ANN static void free_type(Type a, Gwion gwion) {
     free_tupleform(a->e->tuple, gwion);
   mp_free(gwion->mp, TypeInfo, a->e);
   mp_free(gwion->mp, Type, a);
+
 }
 
 Type new_type(MemPool p, const m_uint xid, const m_str name, const Type parent) {
@@ -79,7 +73,7 @@ describe_find(value, Value)
 //describe_find(func,  Func)
 
 ANN Type typedef_base(Type t) {
-  while(GET_FLAG(t, typedef))
+  while(tflag(t, tflag_typedef))
     t = t->e->parent;
   return t;
 }
@@ -116,11 +110,10 @@ ANN Type array_type(const Env env, const Type src, const m_uint depth) {
     inherit(t);
     t->nspc->info->class_data_size = SZ_INT;
     nspc_allocdata(env->gwion->mp, t->nspc);
-    *(f_release**)(t->nspc->info->class_data) = (depth > 1 || !GET_FLAG(src, struct)) ?
+    *(f_release**)(t->nspc->info->class_data) = (depth > 1 || !tflag(src, tflag_struct)) ?
       object_release : struct_release;
   } else
   ADD_REF((t->nspc = env->gwion->type[et_array]->nspc))
-  SET_FLAG(t, valid);
   mk_class(env, t);
   nspc_add_type_front(src->e->owner, sym, t);
   return t;
@@ -128,15 +121,15 @@ ANN Type array_type(const Env env, const Type src, const m_uint depth) {
 
 ANN m_bool type_ref(Type t) {
   do {
-    if(GET_FLAG(t, empty))
+    if(tflag(t, tflag_empty))
       return GW_OK;
-    if(GET_FLAG(t, typedef) && t->e->def)
-      if(t->e->def->base.ext && t->e->def->base.ext->array) {
-        if(!t->e->def->base.ext->array->exp)
+    if(tflag(t, tflag_typedef) && t->e->cdef)
+      if(t->e->cdef->base.ext && t->e->cdef->base.ext->array) {
+        if(!t->e->cdef->base.ext->array->exp)
           return GW_OK;
         else {
           const Type type = t->e->parent->e->d.base_type;
-          if(SAFE_FLAG(type, empty))
+          if(tflag(type, tflag_empty))
             return GW_OK;
         }
       }
index 9a7c8143021bf7e44cc61c4da211a219d466c72c..668667ecff28501071b8890eedead944cc787463 100644 (file)
@@ -6,12 +6,12 @@
 
 static m_str const special_name[] = { "^nonnull", "^force" };
 #define SPECIAL_LEN strlen(special_name[0]) + strlen(special_name[1])
-static const ae_flag special_flag[] = { ae_flag_nonnull, ae_flag_force };
+static const enum tflag special_flag[] = { tflag_nonnull, tflag_force };
 
 typedef struct {
   const Type    type;
   Symbol  name;
-  ae_flag flag;
+  enum tflag flag;
   uint st_type;
 } SpecialType;
 
@@ -21,20 +21,21 @@ ANN static Type specialtype_create(const Env env, const SpecialType *s) {
   if(t->nspc)
     ADD_REF(t->nspc)
   t->name = s_name(s->name);
-  t->flag = s->type->flag | s->flag;
+  t->flag = s->type->flag;
+  t->tflag |= s->type->tflag | s->flag;
   t->e->parent = unflag_type(s->type);
   nspc_add_type_front(s->type->e->owner, s->name, t);
   mk_class(env, t);
   return t;
 }
 
-static inline int get_flag(const Type t, const ae_flag flag) {
-  return (t->flag & flag) == flag;
+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 ae_flag flag = special_flag[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;
index 13cfdd6cc2b5c8a2990511b1611a1d6e58554a15..217b399bd52013ffd5b823cc4a5d0c31c7b8c07f 100644 (file)
@@ -6,11 +6,11 @@
 
 ANN static void free_value(Value a, Gwion gwion) {
   const Type t = a->type;
-  if(!GET_FLAG(a, func) && a->d.ptr && !GET_FLAG(a, union) &&
-      !(GET_FLAG(a, enum) && GET_FLAG(a, builtin) && a->from->owner_class)
+  if(!vflag(a, vflag_func) && a->d.ptr && !vflag(a, vflag_direct) &&
+      !(vflag(a, vflag_enum) && vflag(a, vflag_builtin) && a->from->owner_class)
       && isa(t, gwion->type[et_object]) < 0)
    _mp_free(gwion->mp, t->size, a->d.ptr);
-  else if(GET_FLAG(a, enum) && GET_FLAG(a, dtor))
+  else if(vflag(a, vflag_freeme))
     xfree(a->d.ptr);
   if(is_class(gwion, t))
     REM_REF(t, gwion)
index dfd4363a5f2b994b3cd8a30338f48c1fddb2d86b..99036808199d944d85e5c0beea27d92eab2ac59b 100644 (file)
@@ -44,7 +44,7 @@ ANN static inline void gwion_compile(const Gwion gwion, const Vector v) {
 }
 
 ANN static void gwion_cleaner(const Gwion gwion) {
-  const VM_Code code = new_vm_code(gwion->mp, NULL, 0, ae_flag_builtin, "in code dtor");
+  const VM_Code code = new_vm_code(gwion->mp, NULL, 0, 1, "in code dtor");
   gwion->vm->cleaner_shred = new_vm_shred(gwion->mp, code);
   vm_ini_shred(gwion->vm, gwion->vm->cleaner_shred);
 }
index e04f80066b8ca2463d9d1a424876fa5709e21ea4..aaa39879fc97cd9e189bdf5025c8be5298026123 100644 (file)
 #include "specialid.h"
 #include "template.h"
 
-ANN static m_bool mk_xtor(MemPool p, const Type type, const m_uint d, const ae_flag e) {
-  VM_Code* code = e == ae_flag_ctor ? &type->nspc->pre_ctor : &type->nspc->dtor;
+ANN static m_bool mk_xtor(MemPool p, const Type type, const m_uint d, const enum tflag e) {
+  VM_Code* code = e == tflag_ctor ? &type->nspc->pre_ctor : &type->nspc->dtor;
   const m_str name = type->name;
-  *code = new_vm_code(p, NULL, SZ_INT, e | ae_flag_member | ae_flag_builtin, name);
+  *code = new_vm_code(p, NULL, SZ_INT, 1, name);
   (*code)->native_func = (m_uint)d;
-  type->flag |= e;
+  type->tflag |= e;
   return GW_OK;
 }
 
 ANN2(1,2) static inline m_bool class_parent(const Env env, Type t) {
   do {
-    if(GET_FLAG(t, valid))
+    if(tflag(t, tflag_check))
       break;
-    if(t->e->def)
-      CHECK_BB(traverse_class_def(env, t->e->def))
+    if(t->e->cdef)
+      CHECK_BB(traverse_class_def(env, t->e->cdef))
   } while((t = t->e->parent));
   return GW_OK;
 }
@@ -43,20 +43,19 @@ ANN2(1,2) static void import_class_ini(const Env env, const Type t) {
     inherit(t);
   t->e->owner = env->curr;
   t->e->owner_class = env->class_def;
-  SET_FLAG(t, valid);
   env_push_type(env, t);
 }
 
 ANN2(1) void gwi_class_xtor(const Gwi gwi, const f_xtor ctor, const f_xtor dtor) {
   const Type t = gwi->gwion->env->class_def;
   if(ctor)
-    mk_xtor(gwi->gwion->mp, t, (m_uint)ctor, ae_flag_ctor);
+    mk_xtor(gwi->gwion->mp, t, (m_uint)ctor, tflag_ctor);
   if(dtor)
-    mk_xtor(gwi->gwion->mp, t, (m_uint)dtor, ae_flag_dtor);
+    mk_xtor(gwi->gwion->mp, t, (m_uint)dtor, tflag_dtor);
 }
 
 ANN static inline void gwi_type_flag(const Type t) {
-  SET_FLAG(t, scan1 | ae_flag_scan2 | ae_flag_check | ae_flag_emit);
+  set_tflag(t, tflag_scan0 | tflag_scan1 | tflag_scan2 | tflag_check | tflag_emit);
 }
 
 ANN static Type type_finish(const Gwi gwi, const Type t) {
@@ -80,7 +79,7 @@ ANN2(1,2) Type gwi_class_ini(const Gwi gwi, const m_str name, const m_str parent
     CHECK_BO(template_push_types(gwi->gwion->env, tmpl))
   const Type base = find_type(gwi->gwion->env, td);
   const Type_List tl = td->types;
-  if(GET_FLAG(base, unary))
+  if(tflag(base, tflag_ntmpl))
     td->types = NULL;
   const Type p = !td->types ? handle_class(gwi, td) : NULL;
   td->types = tl;
@@ -88,15 +87,15 @@ ANN2(1,2) Type gwi_class_ini(const Gwi gwi, const m_str name, const m_str parent
     nspc_pop_type(gwi->gwion->mp, gwi->gwion->env->curr);
   CHECK_OO(p)
   const Type t = new_type(gwi->gwion->mp, ++gwi->gwion->env->scope->type_xid, s_name(ck.sym), p);
-  t->e->def = new_class_def(gwi->gwion->mp, 0, ck.sym, td, NULL, loc(gwi));
-  t->e->def->base.tmpl = tmpl;
-  t->e->def->base.type = t;
+  t->e->cdef = new_class_def(gwi->gwion->mp, 0, ck.sym, td, NULL, loc(gwi));
+  t->e->cdef->base.tmpl = tmpl;
+  t->e->cdef->base.type = t;
   t->e->tuple = new_tupleform(gwi->gwion->mp, p);
   t->e->parent = p;
   if(td->array)
-    SET_FLAG(t, typedef);
+    set_tflag(t, tflag_typedef);
   if(ck.tmpl)
-    SET_FLAG(t, template);
+    set_tflag(t, tflag_tmpl);
   else
     gwi_type_flag(t);
   return type_finish(gwi, t);
@@ -107,7 +106,7 @@ ANN Type gwi_struct_ini(const Gwi gwi, const m_str name) {
   const Type t = new_type(gwi->gwion->mp, ++gwi->gwion->env->scope->type_xid, name, gwi->gwion->type[et_compound]);
   t->e->tuple = new_tupleform(gwi->gwion->mp, NULL);
   gwi_type_flag(t);
-  SET_FLAG(t, struct);
+  set_tflag(t, tflag_struct);
   return type_finish(gwi, t);
 }
 
index ee398e3759c534322595850ddf6167488517e11a..1607e576736668099a5b7ec637d3f45ddfc7b480 100644 (file)
@@ -65,7 +65,7 @@ ANN static void import_enum_end(const Gwi gwi, const Vector v) {
   for(m_uint i = 0; i < vector_size(v); i++) {
     const Value value = (Value)vector_at(v, i);
     const m_uint addr = vector_at(&ck->v, i);
-    SET_FLAG(value, builtin);
+    set_vflag(value, vflag_builtin);
 //    ADD_REF(value->type); // what ?
     if(!gwi->gwion->env->class_def)
       value->d.ptr = (m_uint*)(addr ? addr : i);
index 9fdf808c20569a6294af0ede917643ee09d6ddd5..cb4f500149a78405387cca03f22dc6f5f2c8447d 100644 (file)
@@ -40,7 +40,9 @@ ANN Arg_List make_dll_arg_list(const Vector v) {
 
 ANEW ANN static Func_Base* gwi_func_base(const Gwi gwi, ImportCK *ck) {
   const Arg_List arg_list = make_dll_arg_list(&gwi->ck->v);
-  Func_Base *base = new_func_base(gwi->gwion->mp, ck->td, ck->sym, arg_list, ck->flag | ae_flag_builtin);
+  Func_Base *base = new_func_base(gwi->gwion->mp, ck->td, ck->sym, arg_list, ck->flag);
+  if(ck->variadic)
+    base->fbflag |= fbflag_variadic;
   ck->td = NULL;
   if(ck->tmpl) {
     base->tmpl = gwi_tmpl(gwi);
@@ -52,9 +54,6 @@ ANEW ANN static Func_Base* gwi_func_base(const Gwi gwi, ImportCK *ck) {
 ANEW ANN static Func_Def import_fdef(const Gwi gwi, ImportCK *ck) {
   Func_Base* base = gwi_func_base(gwi, ck);
   const Func_Def fdef = new_func_def(gwi->gwion->mp, base, NULL, loc(gwi));
-  fdef->d.dl_func_ptr = (void*)(m_uint)ck->addr;
-  if(base->tmpl)
-    SET_FLAG(fdef->base, template);
   return fdef;
 }
 
@@ -72,10 +71,11 @@ ANN static m_bool error_fdef(const Gwi gwi, const Func_Def fdef) {
 
 ANN m_int gwi_func_valid(const Gwi gwi, ImportCK *ck) {
   const Func_Def fdef = import_fdef(gwi, ck);
-  if(SAFE_FLAG(gwi->gwion->env->class_def, template))
+  if(safe_tflag(gwi->gwion->env->class_def, tflag_tmpl))
     /*return*/ section_fdef(gwi, fdef);
   if(traverse_func_def(gwi->gwion->env, fdef) < 0)
     return error_fdef(gwi, fdef);
+  builtin_func(gwi->gwion->mp, fdef->base->func, ck->addr);
   ck_end(gwi);
   return GW_OK;
 }
@@ -91,6 +91,12 @@ ANN m_int gwi_func_end(const Gwi gwi, const f_xfun addr, const ae_flag flag) {
 
 ANN m_int gwi_func_arg(const Gwi gwi, const restrict m_str t, const restrict m_str n) {
   CHECK_BB(ck_ok(gwi, ck_fdef))
+  if(gwi->ck->variadic)
+    GWI_ERR_B(_("already decalred as variadic"));
+  if(!strcmp(n, "...")) {
+    gwi->ck->variadic = 1;
+    return GW_OK;
+  }
   DECL_OB(Type_Decl*, td, = gwi_str2decl(gwi, t))
   const Var_Decl var = gwi_str2var(gwi, n);
   if(var) {
@@ -118,7 +124,7 @@ ANN Type gwi_fptr_end(const Gwi gwi, const ae_flag flag) {
   // what happens if it is in a template class ?
   const m_bool ret = traverse_fptr_def(gwi->gwion->env, fptr);
   if(fptr->base->func) // is it needed ?
-    SET_FLAG(fptr->base->func, builtin);
+    set_vflag(fptr->base->func->value_ref, vflag_builtin);
   const Type t = ret > 0 ? fptr->type : NULL;
   free_fptr_def(gwi->gwion->mp, fptr);
   if(fptr->type)
index 8f0f85f8491d2b681806bd8e5932999cfc5c60e3..659c49782446b224d0de12f83fb16b899bd224fa 100644 (file)
@@ -11,7 +11,7 @@
 #include "gwi.h"
 
 void gwi_body(const Gwi gwi, const Ast body) {
-  const Class_Def cdef = gwi->gwion->env->class_def->e->def;
+  const Class_Def cdef = gwi->gwion->env->class_def->e->cdef;
   if(!cdef->body)
     cdef->body = body;
   else
index 5d5ed543db7cd402330f3c6652f579d1fd5423b6..3639445f1461a367a94640877f7ff1583d857d71 100644 (file)
@@ -35,11 +35,13 @@ ANN2(1) m_int gwi_item_end(const Gwi gwi, const ae_flag flag, const m_uint* addr
   const Env env = gwi->gwion->env;
   gwi->ck->exp->d.exp_decl.list->self->addr = (m_uint*)addr;
   gwi->ck->exp->d.exp_decl.td->flag = flag;
-  if(env->class_def && GET_FLAG(env->class_def, template))
+  if(env->class_def && tflag(env->class_def, tflag_tmpl))
     return gwi_item_tmpl(gwi);
   CHECK_BB(traverse_exp(env, gwi->ck->exp))
   const Value value = gwi->ck->exp->d.exp_decl.list->self->value;
-  SET_FLAG(value, builtin);
+  set_vflag(value, vflag_builtin);
+  if(!env->class_def)
+    SET_FLAG(value, global);
   const m_uint offset = value->from->offset;
   free_exp(gwi->gwion->mp, gwi->ck->exp);
   ck_end(gwi);
index f4f2e4144ceb4bc176864c2c169283ee5123c36a..36fd29671055a254d3e8d92859e63ff9ad23db90 100644 (file)
@@ -43,9 +43,8 @@ ANN void gwi_set_loc(const Gwi gwi, const m_str file, const uint line) {
 }
 
 ANN static m_bool mk_gack(MemPool p, const Type type, const f_gack d) {
-  const VM_Code code = new_vm_code(p, NULL, SZ_INT, ae_flag_member | ae_flag_builtin, "@gack");
+  const VM_Code code = new_vm_code(p, NULL, SZ_INT, 1, "@gack");
   code->native_func = (m_uint)d;
-  SET_FLAG(code, builtin);
   type->e->gack = code;
   return GW_OK;
 }
index 73f8f06160901248656d77f8bc4f0a8a36d0b86f..aaa603ff69ec412d3a555173a96a864daa9a139d 100644 (file)
@@ -51,7 +51,7 @@ ANN static Type union_type(const Gwi gwi, const Union_Def udef) {
       gwi->gwion->env->class_def->nspc->info->offset =
        udef->o + udef->s;
   if(udef->xid || !udef->type_xid) {
-    SET_FLAG(udef->value, builtin);
+    set_vflag(udef->value, vflag_builtin);
     const M_Object o = new_object(gwi->gwion->mp, NULL, udef->value->type);
     udef->value->d.ptr = (m_uint*)o;
    return udef->value->type;
@@ -75,7 +75,7 @@ ANN Type gwi_union_end(const Gwi gwi, const ae_flag flag) {
     gwi->ck->tmpl = NULL;
   }
   const Type t = union_type(gwi, udef);
-  if(!SAFE_FLAG(t, template))
+  if(!safe_tflag(t, tflag_tmpl))
     free_union_def(gwi->gwion->mp, udef);
   ck_end(gwi);
   return t;
index 35d3b45466e6eb29540d867de8425cab0644635d..3a7c36f0a5c13eeaa29547674fed8006176c8bbb 100644 (file)
@@ -74,6 +74,7 @@ OP_CHECK(opck_object_dot);
 OP_EMIT(opem_object_dot);
 ANN static m_bool import_core_libs(const Gwi gwi) {
   const Type t_class = gwi_mk_type(gwi, "@Class", SZ_INT, NULL);
+  set_tflag(t_class, tflag_infer);
   GWI_BB(gwi_set_global_type(gwi, t_class, et_class))
   GWI_BB(gwi_gack(gwi, t_class, gack_class)) // not working yet
   GWI_BB(gwi_add_type(gwi, t_class))
@@ -84,9 +85,8 @@ ANN static m_bool import_core_libs(const Gwi gwi) {
   const Type t_undefined = gwi_mk_type(gwi, "@Undefined", SZ_INT, NULL);
   GWI_BB(gwi_set_global_type(gwi, t_undefined, et_undefined))
   const Type t_auto = gwi_mk_type(gwi, "auto", SZ_INT, NULL);
-  SET_FLAG(t_auto, infer);
+  set_tflag(t_auto, tflag_infer);
   GWI_BB(gwi_set_global_type(gwi, t_auto, et_auto))
-  SET_FLAG(t_class, infer);
   const Type t_void  = gwi_mk_type(gwi, "void", 0, NULL);
   GWI_BB(gwi_gack(gwi, t_void, gack_void))
   GWI_BB(gwi_set_global_type(gwi, t_void, et_void))
@@ -125,7 +125,7 @@ ANN static m_bool import_core_libs(const Gwi gwi) {
   GWI_BB(gwi_gack(gwi, t_fptr, gack_fptr))
   GWI_BB(gwi_set_global_type(gwi, t_fptr, et_fptr))
   const Type t_lambda = gwi_mk_type(gwi, "@lambda", SZ_INT, "@function");
-  SET_FLAG(t_lambda, infer);
+  set_tflag(t_lambda, tflag_infer);
   GWI_BB(gwi_set_global_type(gwi, t_lambda, et_lambda))
 
   GWI_BB(gwi_typedef_ini(gwi, "int", "@internal"))
index 2f56dd16abba165d8be2ec677bc7db505946a78a..2c3818f40730d941acae6aa6d36e895511cd227c 100644 (file)
@@ -58,7 +58,7 @@ GWION_IMPORT(event) {
   gwi->gwion->type[et_event] = t_event; // use func
 
   GWI_BB(gwi_item_ini(gwi, "@internal", "@shreds"))
-  GWI_BB(gwi_item_end(gwi, ae_flag_member, NULL))
+  GWI_BB(gwi_item_end(gwi, ae_flag_none, NULL))
   GWI_BB(gwi_func_ini(gwi, "void", "signal"))
   GWI_BB(gwi_func_end(gwi, event_signal, ae_flag_none))
   GWI_BB(gwi_func_ini(gwi, "void", "broadcast"))
index 587b1fa4e75df60729f884da1e88d887b9101321..b1e9ef76fb29f6f23bce6c2a122802e701b519bb 100644 (file)
@@ -37,19 +37,26 @@ ANN static Func_Def from_base(const Env env, struct dottmpl_ *const dt, const Ns
   DECL_OO(const Value, v, = nspc_lookup_value0(nspc, sym) ?: nspc_lookup_value0(nspc, fdef->base->xid))
   if(isa(v->type, env->gwion->type[et_class]) > 0)
     return NULL;
+  if(vflag(v, vflag_builtin)) {
+    dt->xfun = v->d.func_ref->def->d.dl_func_ptr;
+    v->d.func_ref->def->d.dl_func_ptr = NULL;
+  }
   const Func_Def def = cpy_func_def(env->gwion->mp, v->d.func_ref->def);
+  if(vflag(v, vflag_builtin))
+    v->d.func_ref->def->d.dl_func_ptr = dt->xfun;
   def->base->tmpl->call = cpy_type_list(env->gwion->mp, dt->tl);
   def->base->tmpl->base = dt->vt_index;
   dt->def = def;
   dt->owner = v->from->owner;
   dt->owner_class = v->from->owner_class;
-  SET_FLAG(def->base, template);
   return def;
 }
 
 ANN static Func_Def traverse_tmpl(const Emitter emit, struct dottmpl_ *const dt, const Nspc nspc) {
   DECL_OO(const Func_Def, def, = from_base(emit->env, dt, nspc))
   CHECK_BO(traverse_dot_tmpl(emit, dt))
+  if(dt->xfun)
+    builtin_func(emit->gwion->mp, def->base->func, dt->xfun);
   return def;
 }
 
@@ -83,7 +90,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 = !GET_FLAG(o->type_ref, nonnull) ? o->type_ref : o->type_ref->e->parent;
+  Type t = !tflag(o->type_ref, tflag_nonnull) ? o->type_ref : o->type_ref->e->parent;
   do {
     const Emitter emit = shred->info->vm->gwion->emit;
     emit->env->name = "runtime";
@@ -94,7 +101,7 @@ INSTR(DotTmpl) {
     if(f) {
       if(!f->code)
         break;
-      if(GET_FLAG(f, member))
+      if(vflag(f->value_ref, vflag_member))
         shred->reg += SZ_INT;
       *(VM_Code*)(shred->reg-SZ_INT) = f->code;
       return;
@@ -103,7 +110,7 @@ INSTR(DotTmpl) {
       if(!def)
         continue;
       const Func f = def->base->func;
-      if(GET_FLAG(f, member))
+      if(vflag(f->value_ref, vflag_member))
         shred->reg += SZ_INT;
       *(VM_Code*)(shred->reg-SZ_INT) = f->code;
       return;
index 526c1df2496813d2b0e86a8a3b6297d3a33192b0..2f0d97bebd00b8c888090ab384c4f13792e6ec2b 100644 (file)
@@ -34,7 +34,7 @@ static OP_EMIT(opem_func_assign) {
   if(bin->rhs->info->type->e->d.func->def->base->tmpl)
     fptr_instr(emit, bin->lhs->info->type->e->d.func, 2);
   const Instr instr = emit_add_instr(emit, int_r_assign);
-  if(!is_fptr(emit->gwion, bin->lhs->info->type) && GET_FLAG(bin->rhs->info->type->e->d.func, member)) {
+  if(!is_fptr(emit->gwion, bin->lhs->info->type) && vflag(bin->rhs->info->type->e->d.func->value_ref, vflag_member)) {
     const Instr pop = emit_add_instr(emit, RegPop);
     pop->m_val = SZ_INT;
     const Instr cpy = emit_add_instr(emit, Reg2Reg);
@@ -95,10 +95,10 @@ ANN static m_bool fptr_check(const Env env, struct FptrInfo *info) {
       ERR_B(info->pos, _("can't assign non member function to member function pointer"))
   } else if(l_type && isa(r_type, l_type) < 0)
       ERR_B(info->pos, _("can't assign member function to a pointer of an other class"))
-  if(GET_FLAG(info->rhs, member)) {
-    if(!GET_FLAG(info->lhs, member))
+  if(vflag(info->rhs->value_ref, vflag_member)) {
+    if(!vflag(info->lhs->value_ref, vflag_member))
       ERR_B(info->pos, _("can't assign static function to member function pointer"))
-  } else if(GET_FLAG(info->lhs, member))
+  } else if(vflag(info->lhs->value_ref, vflag_member))
       ERR_B(info->pos, _("can't assign member function to static function pointer"))
   return GW_OK;
 }
@@ -110,8 +110,8 @@ ANN static inline m_bool fptr_rettype(const Env env, struct FptrInfo *info) {
 }
 
 ANN static inline m_bool fptr_arity(struct FptrInfo *info) {
-  return GET_FLAG(info->lhs->def->base, variadic) ==
-         GET_FLAG(info->rhs->def->base, variadic);
+  return fbflag(info->lhs->def->base, fbflag_variadic) ==
+         fbflag(info->rhs->def->base, fbflag_variadic);
 }
 
 ANN static Type fptr_type(const Env env, struct FptrInfo *info) {
@@ -152,7 +152,6 @@ ANN static m_bool _check_lambda(const Env env, Exp_Lambda *l, const Func_Def def
     ERR_B(exp_self(l)->pos, _("argument number does not match for lambda"))
   l->def->base->flag = def->base->flag;
   l->def->base->td = cpy_type_decl(env->gwion->mp, def->base->td);
-  SET_FLAG(l->def->base, abstract); // mark as non immediate lambda
   map_set(&env->curr->info->func->map, (m_uint)l->def->base, env->scope->depth);
   const m_bool ret = check_traverse_fdef(env, l->def);
   map_remove(&env->curr->info->func->map, (m_uint)l->def->base);
@@ -168,7 +167,7 @@ ANN static m_bool _check_lambda(const Env env, Exp_Lambda *l, const Func_Def def
 ANN m_bool check_lambda(const Env env, const Type t, Exp_Lambda *l) {
   const Func_Def fdef = t->e->d.func->def;
   struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)check_cdef,
-    .scope=env->scope->depth, .flag=ae_flag_check };
+    .scope=env->scope->depth, .flag=tflag_check };
   l->owner = t->e->owner_class;
   CHECK_BB(envset_push(&es, l->owner, t->e->owner))
   const m_bool ret = _check_lambda(env, l, fdef);
@@ -182,7 +181,7 @@ 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 = GET_FLAG(info->exp->info->type, nonnull);
+    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);
@@ -256,8 +255,8 @@ static void member_fptr(const Emitter emit) {
 }
 
 static int is_member(const Type from, const Type to) {
-  return GET_FLAG(from->e->d.func, member) &&
-    !(GET_FLAG(from, nonnull) || GET_FLAG(to, nonnull));
+  return vflag(from->e->d.func->value_ref, vflag_member) &&
+    !(tflag(from, tflag_nonnull) || tflag(to, tflag_nonnull));
 }
 
 static OP_EMIT(opem_fptr_cast) {
@@ -303,7 +302,14 @@ ANN static Type fork_type(const Env env, const Exp_Unary* unary) {
     return env->gwion->type[et_fork];
   char c[21 + strlen(t->name)];
   sprintf(c, "nonnull TypedFork:[%s]", t->name);
-  return str2type(env->gwion, c, exp_self(unary)->pos);
+  const Type fork = env->gwion->type[et_fork];
+  UNSET_FLAG(fork, final);
+  const Type typed = str2type(env->gwion, "TypedFork", exp_self(unary)->pos);
+  UNSET_FLAG(typed, final);
+  const Type ret = str2type(env->gwion, c, exp_self(unary)->pos);
+  SET_FLAG(typed, final);
+  SET_FLAG(fork, final);
+  return ret;
 }
 
 static OP_CHECK(opck_spork) {
index b8a2bf32ce7b89c6dcd287d84768c064762b46da..d434b41d7d46cfef233c9234a729b6aab9c9b511 100644 (file)
@@ -70,11 +70,11 @@ ANN void __release(const M_Object o, const VM_Shred shred) {
     struct scope_iter iter = { t->nspc->info->value, 0, 0 };\
     Value v;
     while(scope_iter(&iter, &v) > 0) {
-      if(!GET_FLAG(v, static) && !GET_FLAG(v, pure) &&
+      if(!GET_FLAG(v, static) && !vflag(v, vflag_union) &&
           isa(v->type, shred->info->vm->gwion->type[et_object]) > 0)
         release(*(M_Object*)(o->data + v->from->offset), shred);
-      else if(GET_FLAG(v->type, struct) &&
-            !GET_FLAG(v, static) && !GET_FLAG(v, pure) && v->type->e->tuple) {
+      else if(tflag(v->type, tflag_struct) &&
+            !GET_FLAG(v, static) && !vflag(v, vflag_union) && v->type->e->tuple) {
         const TupleForm tf = v->type->e->tuple;
         for(m_uint i = 0; i < vector_size(&tf->types); ++i) {
           const m_bit *data = o->data + v->from->offset;
@@ -84,8 +84,9 @@ ANN void __release(const M_Object o, const VM_Shred shred) {
         }
       }
     }
-    if(GET_FLAG(t, dtor) && t->nspc->dtor) {
-      if(GET_FLAG(t->nspc->dtor, builtin))
+    if(tflag(t, tflag_dtor) && t->nspc->dtor) {
+    // check flag for array types
+      if(t->nspc->dtor->builtin)
         ((f_xtor)t->nspc->dtor->native_func)(o, NULL, shred);
       else {
         o->type_ref = t;
@@ -106,7 +107,7 @@ ANN void free_object(MemPool p, const M_Object o) {
 static ID_CHECK(opck_this) {
   if(!env->class_def)
     ERR_O(exp_self(prim)->pos, _("keyword 'this' can be used only inside class definition..."))
-  if(env->func && !GET_FLAG(env->func, member))
+  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->e->parent)); // get_gack ?
@@ -114,7 +115,7 @@ static ID_CHECK(opck_this) {
 }
 
 static ID_EMIT(opem_this) {
-  if(!exp_getvar(exp_self(prim)) && GET_FLAG(exp_self(prim)->info->type, struct)) {
+  if(!exp_getvar(exp_self(prim)) && tflag(exp_self(prim)->info->type, tflag_struct)) {
     const Instr instr = emit_add_instr(emit, RegPushMemDeref);
     instr->m_val2 = emit->env->class_def->size;
     return (Instr)GW_OK;
index 3b15c4ee1683cf41f65e3d89d5acac2a678f031a..66a8b70dbaaa747d183e73d1a70efdb163f38fe3 100644 (file)
@@ -32,12 +32,12 @@ static INSTR(name##Object) {                     \
 describe_logical(Eq,  ==)
 describe_logical(Neq, !=)
 static inline m_bool nonnull_check(const Type l, const Type r) {
-  return !GET_FLAG(l, nonnull) && GET_FLAG(r, nonnull);
+  return !tflag(l, tflag_nonnull) && tflag(r, tflag_nonnull);
 }
 
 static inline Type check_nonnull(const Env env, const Type l, const Type r,
       const m_str action, const loc_t pos) {
-  if(GET_FLAG(r, nonnull)) {
+  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, r) < 0)
@@ -57,10 +57,8 @@ static OP_CHECK(at_object) {
     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(bin->rhs->exp_type == ae_exp_decl) {
+  if(bin->rhs->exp_type == ae_exp_decl)
     SET_FLAG(bin->rhs->d.exp_decl.td, ref);
-    SET_FLAG(bin->rhs->d.exp_decl.list->self->value, ref);
-  }
   exp_setvar(bin->rhs, 1);
   return r;
 }
@@ -139,7 +137,7 @@ ANN static void emit_dot_static_data(const Emitter emit, const Value v, const ui
 
 static const f_instr regpushimm[] = { RegPushImm, RegPushImm2, RegPushImm3, RegPushImm4 };
 ANN static void emit_dot_static_import_data(const Emitter emit, const Value v, const uint emit_addr) {
-  if(v->d.ptr && GET_FLAG(v, builtin) && GET_FLAG(v, const)) {
+  if(v->d.ptr && vflag(v, vflag_builtin) && GET_FLAG(v, const)) {
     const m_uint size = v->type->size;
     const Instr instr = emit_kind(emit, size, emit_addr, regpushimm);
     instr->m_val = (m_uint)v->d.ptr;
@@ -154,7 +152,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) || GET_FLAG(member->base->info->type, force)) {
+  if(is_class(emit->gwion, member->t_base) || tflag(member->base->info->type, tflag_force)) {
     const Instr func_i = emit_add_instr(emit, f->code ? RegPushImm : SetFunc);
     func_i->m_val = (m_uint)f->code ?: (m_uint)f;
     return;
@@ -162,7 +160,7 @@ else
 //  if(f->def->base->tmpl)
 //    emit_add_instr(emit, DotTmplVal);
   else {
-    if(GET_FLAG(member->t_base, struct)) {
+    if(tflag(member->t_base, tflag_struct)) {
       if(!GET_FLAG(f->def->base, static)) {
         exp_setvar(member->base, 1);
         emit_exp(emit, member->base);
@@ -171,7 +169,7 @@ else
     func_i->m_val = (m_uint)f->code ?: (m_uint)f;
       return;
     }
-    const Instr instr = emit_add_instr(emit, GET_FLAG(f, member) ? DotFunc : DotStaticFunc);
+    const Instr instr = emit_add_instr(emit, vflag(f->value_ref, vflag_member) ? DotFunc : DotStaticFunc);
     instr->m_val = f->vt_index;
   }
   return;
@@ -222,7 +220,7 @@ OP_CHECK(opck_object_dot) {
     else if(GET_FLAG(value, protect))
       exp_setprot(exp_self(member), 1);
   }
-  if(base_static && GET_FLAG(value, member))
+  if(base_static && vflag(value, vflag_member))
     ERR_N(exp_self(member)->pos,
           _("cannot access member '%s.%s' without object instance..."),
           the_base->name, str)
@@ -235,18 +233,18 @@ OP_EMIT(opem_object_dot) {
   const Exp_Dot *member = (Exp_Dot*)data;
   const Type t_base = actual_type(emit->gwion, member->t_base);
   const Value value = find_value(t_base, member->xid);
-  if(!is_class(emit->gwion, member->t_base) && (GET_FLAG(value, member) ||
+  if(!is_class(emit->gwion, member->t_base) && (vflag(value, vflag_member) ||
        (isa(exp_self(member)->info->type, emit->gwion->type[et_function]) > 0 &&
        !is_fptr(emit->gwion, exp_self(member)->info->type)))) {
-    if(!GET_FLAG(t_base, struct))
+    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);
-  else if(GET_FLAG(value, member)) {
-    if(!GET_FLAG(t_base, struct))
+  else if(vflag(value, vflag_member)) {
+    if(!tflag(t_base, tflag_struct))
       emit_member(emit, value, exp_getvar(exp_self(member)));
     else {
 //      exp_setvar(member->base, exp_getvar(exp_self(member)));
@@ -264,8 +262,12 @@ OP_EMIT(opem_object_dot) {
 }
 
 struct tmpl_info {
-  const  Class_Def cdef;
+//  const  Class_Def cdef;
+  Symbol           name;
+  ID_List          list;
   Type_List        call;
+  Type             ret;
+  Type             base;
   struct Vector_   type;
   struct Vector_   size;
   uint8_t index;
@@ -279,14 +281,15 @@ ANN static inline size_t tmpl_set(struct tmpl_info* info, const Type t) {
 }
 
 ANN static ssize_t template_size(const Env env, struct tmpl_info* info) {
-  ID_List base = info->cdef->base.tmpl->list;
+  ID_List base = info->list; // ???
   Type_List call = info->call;
   size_t size = 0;
   do {
     DECL_OB(const Type, t, = known_type(env, call->td))
     size += tmpl_set(info, t);
   } while((call = call->next) && (base = base->next) && ++size);
-  size += tmpl_set(info, info->cdef->base.type);
+//  } while((call = call->next) && ++size);
+  size += tmpl_set(info, info->base);
   return size + 4;
 }
 
@@ -313,16 +316,15 @@ ANN static void template_name(struct tmpl_info* info, m_str s) {
   *str = '\0';
 }
 
-ANEW ANN static Symbol template_id(const Env env, const Class_Def c, const Type_List call) {
-  struct tmpl_info info = { .cdef=c, .call=call };
-  vector_init(&info.type);
-  vector_init(&info.size);
-  ssize_t sz = template_size(env, &info);
+ANEW ANN static Symbol template_id(const Env env, struct tmpl_info* info) {
+  vector_init(&info->type);
+  vector_init(&info->size);
+  ssize_t sz = template_size(env, info);
   char name[sz];
   if(sz > GW_ERROR)
-    template_name(&info, name);
-  vector_release(&info.type);
-  vector_release(&info.size);
+    template_name(info, name);
+  vector_release(&info->type);
+  vector_release(&info->size);
   return sz > GW_ERROR ? insert_symbol(env->gwion->st, name) : NULL;
 }
 
@@ -331,64 +333,70 @@ ANN static m_bool template_match(ID_List base, Type_List call) {
   return !call ? GW_OK : GW_ERROR;
 }
 
-ANN static Class_Def template_class(const Env env, const Class_Def def, const Type_List call) {
-  DECL_OO(const Symbol, name, = template_id(env, def, call))
+ANN static Type tmpl_exists(const Env env, const Symbol name) {
   if(env->class_def && name == insert_symbol(env->gwion->st, env->class_def->name))
-     return env->class_def->e->def;
-  const Type t = nspc_lookup_type1(env->curr, name);
-  if(t)
-    return t->e->def;
-  const Class_Def c = cpy_class_def(env->gwion->mp, def);
-  c->base.xid = name;
-  SET_FLAG(c, template | ae_flag_ref);
-  UNSET_FLAG(c, scan0 | ae_flag_scan1 | ae_flag_scan2 |
-    ae_flag_check | ae_flag_emit | ae_flag_valid);
-  return c;
-}
-
-ANN static m_bool class2udef(const Env env, const Class_Def a, const Type t) {
-  a->union_def = new_union_def(env->gwion->mp, cpy_decl_list(env->gwion->mp, a->list),
-    loc_cpy(env->gwion->mp, t->e->def->pos));
-  a->union_def->type_xid = a->base.xid;
-  if(GET_FLAG(t, global))
-    SET_FLAG(a->union_def, global);
-  CHECK_BB(scan0_union_def(env, a->union_def))
-  a->base.type = a->union_def->type;
-  a->base.type->e->def = a;
-  a->union_def->tmpl = cpy_tmpl(env->gwion->mp, a->base.tmpl);
-  return GW_OK;
+     return env->class_def;
+  return nspc_lookup_type1(env->curr, name);
+}
+
+ANN static m_bool scantmpl_class_def(const Env env, struct tmpl_info *info) {
+  const Class_Def c = info->base->e->cdef;
+  const Class_Def cdef = new_class_def(env->gwion->mp, c->flag, info->name, c->base.ext ? cpy_type_decl(env->gwion->mp, c->base.ext) : NULL,
+      c->body ?cpy_ast(env->gwion->mp, c->body) : NULL,
+    loc_cpy(env->gwion->mp, c->pos));
+  cdef->base.tmpl = mk_tmpl(env, c->base.tmpl, info->call);
+  const m_bool ret = scan0_class_def(env, cdef);
+  if((info->ret = cdef->base.type)) {
+    info->ret->e->cdef = cdef;
+    set_tflag(info->ret, tflag_cdef);
+    set_tflag(info->ret, tflag_ctmpl);
+  } else
+    free_class_def(env->gwion->mp, cdef);
+  return ret;
+}
+
+ANN static m_bool scantmpl_union_def(const Env env, struct tmpl_info *info) {
+  const Union_Def u = info->base->e->udef;
+  const Union_Def udef = new_union_def(env->gwion->mp, cpy_decl_list(env->gwion->mp, u->l),
+    loc_cpy(env->gwion->mp, u->pos));
+  udef->type_xid = info->name;
+  udef->tmpl = mk_tmpl(env, u->tmpl, info->call);
+  if(GET_FLAG(info->base, global))
+    SET_FLAG(udef, global);
+  const m_bool ret = scan0_union_def(env, udef);
+  if(udef->type) {
+    udef->type->e->udef = udef;// mark as udef
+    info->ret = udef->type;
+    set_tflag(info->ret, tflag_udef);
+//    set_tflag(info->ret, tflag_tmpl);
+  } else
+    free_union_def(env->gwion->mp, udef);
+  return ret;
 }
 
-ANN static m_bool _scan_class(const Env env, const Type t, const Class_Def a) {
-  if(t->e->parent !=  env->gwion->type[et_union])
-    CHECK_BB(scan0_class_def(env, a))
+ANN static Type _scan_class(const Env env, struct tmpl_info *info) {
+  if(info->base->e->parent !=  env->gwion->type[et_union])
+    CHECK_BO(scantmpl_class_def(env, info))
   else
-    CHECK_BB(class2udef(env, a, t))
-  SET_FLAG(a->base.type, template);
-  if(GET_FLAG(t, builtin))
-    SET_FLAG(a->base.type, builtin);
-  return GW_OK;
+    CHECK_BO(scantmpl_union_def(env, info))
+  return info->ret;
 }
 
 ANN Type scan_class(const Env env, const Type t, const Type_Decl* td) {
-  if(template_match(t->e->def->base.tmpl->list, td->types) < 0)
-   ERR_O(td->pos, _("invalid template types number"))
-  DECL_OO(const Class_Def, a, = template_class(env, t->e->def, td->types))
-  if(a->base.type)
-    return a->base.type;
+  if(template_match(t->e->cdef->base.tmpl->list, td->types) < 0) // invalid template
+    ERR_O(td->pos, _("invalid template types number"))
+  struct tmpl_info info = { .base=t, .call=td->types, .list=t->e->cdef->base.tmpl->list  };
+  DECL_OO(const Symbol, name, = info.name = template_id(env, &info))
+  const Type exists = tmpl_exists(env, name);
+  if(exists)
+    return exists;
   struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)scan0_cdef,
-    .scope=env->scope->depth, .flag=ae_flag_scan0 };
-//  CHECK_BO(envset_push(&es, t->e->owner_class, env->context ? env->context->nspc : env->curr))
+    .scope=env->scope->depth, .flag=tflag_scan0 };
   CHECK_BO(envset_push(&es, t->e->owner_class, t->e->ctx ? t->e->ctx->nspc : env->curr))
-  a->base.tmpl = mk_tmpl(env, t->e->def->base.tmpl, td->types);
-  const m_bool ret = _scan_class(env, t, a);
+  const Type ret = _scan_class(env, &info);
   if(es.run)
     envset_pop(&es, t->e->owner_class);
-  if(ret > 0)
-    return a->base.type;
-  if(!a->base.type)
-    free_class_def(env->gwion->mp, a);
-  return NULL;
+  return ret;
 }
 
 ANN static inline Symbol dot_symbol(SymTable *st, const Value v) {
@@ -416,7 +424,7 @@ ANN void struct_release(const VM_Shred shred, const Type base, const m_bit *ptr)
     if(isa(t, shred->info->vm->gwion->type[et_compound]) < 0)
       continue;
     const m_uint offset = vector_at(offsets, i);
-    if(!GET_FLAG(t, struct))
+    if(!tflag(t, tflag_struct))
       release(*(M_Object*)(ptr + offset), shred);
     else
       struct_release(shred, t, *(m_bit**)(ptr + offset));
index 2012bf5ba45c6830c69a41a0f108f9c922aeb37f..fa4378ddce6d941d2e30f6d29a5b9c5b5074db05 100644 (file)
@@ -59,7 +59,7 @@ static OP_CHECK(opck_ptr_cast) {
     ERR_N(exp_self(cast)->pos, "'Ptr' needs types to cast")
   DECL_ON(const Type, t, = known_type(env, cast->td))
   const Type _t = get_type(t);
-  if(_t->e->def && !GET_FLAG(_t, check))
+  if(_t->e->cdef && !tflag(_t, tflag_check))
     CHECK_BN(ensure_traverse(env, _t))
   const Type to = known_type(env, cast->td->types->td);
   if(isa(cast->exp->info->type, to) > 0)
@@ -78,8 +78,8 @@ static OP_CHECK(opck_ptr_implicit) {
     e->info->cast_to = imp->t;
     exp_setvar(e, 1);
     const Type t = get_type(imp->t);
-    if(!GET_FLAG(t, check))
-      CHECK_BN(traverse_class_def(env, t->e->def))
+    if(!tflag(t, tflag_check))
+      CHECK_BN(traverse_class_def(env, t->e->cdef))
     return imp->t;
   }
   return NULL;
@@ -139,14 +139,16 @@ static DTOR(ptr_struct_dtor) {
 static OP_CHECK(opck_ptr_scan) {
   struct TemplateScan *ts = (struct TemplateScan*)data;
   DECL_ON(const Type, t, = (Type)scan_class(env, ts->t, ts->td))
-  const Type base = known_type(env, t->e->def->base.tmpl->call->td);
+set_tflag(t, tflag_tmpl);
+//if(!tflag(t, tflag_scan1))exit(3);
+  const Type base = known_type(env, t->e->cdef->base.tmpl->call->td);
   if(isa(base, env->gwion->type[et_compound]) > 0 && !t->nspc->dtor) {
-    t->nspc->dtor = new_vm_code(env->gwion->mp, NULL, SZ_INT, ae_flag_member | ae_flag_builtin, "@PtrDtor");
-    if(!GET_FLAG(t, struct))
+    t->nspc->dtor = new_vm_code(env->gwion->mp, NULL, SZ_INT, 1, "@PtrDtor");
+    if(!tflag(t, tflag_struct))
       t->nspc->dtor->native_func = (m_uint)ptr_object_dtor;
     else
       t->nspc->dtor->native_func = (m_uint)ptr_struct_dtor;
-    SET_FLAG(t, dtor);
+    set_tflag(t, tflag_dtor);
   }
   return t;
 }
@@ -154,7 +156,8 @@ static OP_CHECK(opck_ptr_scan) {
 GWION_IMPORT(ptr) {
   const Type _t_ptr = gwi_class_ini(gwi, "@Ptr", NULL);
   GWI_BB(gwi_class_end(gwi))
-  SET_FLAG(_t_ptr, unary);
+  set_tflag(_t_ptr, tflag_ntmpl);
+//  set_tflag(_t_ptr, tflag_tmpl);
   GWI_BB(gwi_oper_ini(gwi, "@Ptr", NULL, NULL))
   GWI_BB(gwi_oper_add(gwi, opck_ptr_scan))
   GWI_BB(gwi_oper_end(gwi, "@scan", NULL))
@@ -163,7 +166,8 @@ GWION_IMPORT(ptr) {
   GWI_BB(gwi_item_ini(gwi, "@internal", "@val"))
   GWI_BB(gwi_item_end(gwi, 0, NULL))
   GWI_BB(gwi_class_end(gwi))
-  SET_FLAG(t_ptr, unary);
+  set_tflag(t_ptr, tflag_ntmpl);
+//  set_tflag(t_ptr, tflag_tmpl);
   GWI_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, "nonnull Ptr", NULL))
   GWI_BB(gwi_oper_add(gwi, opck_ptr_assign))
   GWI_BB(gwi_oper_end(gwi, ":=>", instr_ptr_assign))
index 9dc20c4ba0abc20ef3c714964d178c13514ff3fe..aeac54873374f1688f07a016b9fa22ec64cb9a4e 100644 (file)
@@ -373,13 +373,12 @@ GWION_IMPORT(shred) {
   gwi_func_ini(gwi, "float", "get_now");
   GWI_BB(gwi_func_end(gwi, shred_now, ae_flag_none))
   GWI_BB(gwi_class_end(gwi))
+  SET_FLAG(t_shred, abstract | ae_flag_final);
   gwi_set_global_type(gwi, t_shred, et_shred);
 
   struct SpecialId_ spid = { .type=t_shred, .exec=RegPushMe, .is_const=1 };
   gwi_specialid(gwi, "me", &spid);
 
-  SET_FLAG(t_shred, abstract);
-
   const Type t_fork= gwi_class_ini(gwi,  "Fork", "Shred");
   gwi_class_xtor(gwi, NULL, fork_dtor);
   gwi->gwion->type[et_fork] = t_fork;
@@ -401,13 +400,13 @@ GWION_IMPORT(shred) {
   gwi_func_ini(gwi, "void", "test_cancel");
   GWI_BB(gwi_func_end(gwi, fork_test_cancel, ae_flag_none))
   GWI_BB(gwi_class_end(gwi))
-  SET_FLAG((t_fork), abstract);
+  SET_FLAG(t_fork, abstract | ae_flag_final);
 
   const Type t_typed = gwi_class_ini(gwi,  "TypedFork:[A]", "Fork");
   gwi_item_ini(gwi, "A", "retval");
   GWI_BB((gwi_item_end(gwi, ae_flag_const, NULL)))
   GWI_BB(gwi_class_end(gwi))
-  SET_FLAG((t_typed), abstract);
-
+  SET_FLAG(t_typed, abstract | ae_flag_final);
+  set_tflag(t_typed, tflag_ntmpl);
   return GW_OK;
 }
index ff9231a1c84d788da4e2d178fd4da1df41b0bb6c..a948cc8ebd6e4491a632e531f20cd04679b9ea79 100644 (file)
@@ -321,7 +321,7 @@ GWION_IMPORT(ugen) {
   gwi->gwion->type[et_ugen] = t_ugen; // use func
 
   GWI_BB(gwi_item_ini(gwi, "@internal", "@ugen"))
-  GWI_BB(gwi_item_end(gwi, ae_flag_member, NULL))
+  GWI_BB(gwi_item_end(gwi, ae_flag_none, NULL))
 
   GWI_BB(gwi_func_ini(gwi, "UGen", "chan"))
   GWI_BB(gwi_func_arg(gwi, "int", "arg0"))
index 2b748cd2cf2ce1554ba280af4017bdae65b3a8fb..2a3b13b968806573978a538dd243fc7b4da4e19c 100644 (file)
@@ -31,7 +31,7 @@ static DTOR(vararg_dtor) {
       const Type t = (Type)vector_at(&arg->t, i);
       if(isa(t, shred->info->vm->gwion->type[et_object]) > 0)
         release(*(M_Object*)(arg->d + offset), shred);
-      else if(GET_FLAG(t, struct))
+      else if(tflag(t, tflag_struct))
         struct_release(shred, t, *(m_bit**)(arg->d + offset));
       offset += t->size;
     }
@@ -137,7 +137,7 @@ static FREEARG(freearg_vararg) {
 }
 
 static ID_CHECK(idck_vararg) {
-  if(env->func && GET_FLAG(env->func->def->base, variadic))
+  if(env->func && fbflag(env->func->def->base, fbflag_variadic))
     return nonnul_type(env, exp_self(prim)->info->type);
   ERR_O(exp_self(prim)->pos, _("'vararg' must be used inside variadic function"))
 }
index 3620034191097919733bf3e7077d3fa0c388ac7a..4d0650fad99cff64d496509e9826bc6f5f045665 100644 (file)
@@ -56,20 +56,20 @@ ANN static inline m_bool check_exp_decl_parent(const Env env, const Var_Decl var
   return GW_OK;
 }
 
-#define describe_check_decl(a, b)                                 \
+#define describe_check_decl(a, b, flag)                           \
 ANN static inline void decl_##a(const Env env, const Value v) {   \
-  const Nspc nspc = env->curr;\
-  SET_FLAG(v, a);                                                 \
+  const Nspc nspc = env->curr;                                    \
+  flag;                                                           \
   v->from->offset = nspc->info->b;                                \
   nspc->info->b += v->type->size;                                 \
 }
-describe_check_decl(member, offset)
-describe_check_decl(static, class_data_size)
+describe_check_decl(member, offset, v->vflag |= vflag_member)
+describe_check_decl(static, class_data_size, SET_FLAG(v, static))
 
 ANN static m_bool check_fptr_decl(const Env env, const Var_Decl var) {
   const Value v    = var->value;
   Type t = v->type;
-  while(GET_FLAG(t, typedef))
+  while(tflag(t, tflag_typedef))
     t = t->e->parent;
   if(!t->e->d.func)
     return GW_ERROR;
@@ -79,7 +79,7 @@ ANN static m_bool check_fptr_decl(const Env env, const Var_Decl var) {
   const Type type = func->value_ref->from->owner_class;
   if(type && isa(type, env->class_def) < 0 && !GET_FLAG(func, global))
     ERR_B(var->pos, _("can't use non global fptr of other class."))
-  if(GET_FLAG(func, member) && GET_FLAG(v, static))
+  if(vflag(func->value_ref, vflag_member) && GET_FLAG(v, static))
       ERR_B(var->pos, _("can't use static variables for member function."))
   return GW_OK;
 }
@@ -91,9 +91,6 @@ ANN static inline m_bool check_td_exp(const Env env, Type_Decl *td) {
 ANN Type check_td(const Env env, Type_Decl *td) {
   CHECK_BO(check_td_exp(env, td))
   const Type t = actual_type(env->gwion, td->exp->info->type);
-  assert(t);
-  if(GET_FLAG(t, template) && !GET_FLAG(t, ref))
-    ERR_O(td_pos(td), _("type '%s' needs template types"), t->name)
   td->xid = insert_symbol("auto");
   return t;
 }
@@ -115,7 +112,7 @@ ANN static m_bool check_var(const Env env, const Var_Decl var) {
 ANN static m_bool check_var_td(const Env env, const Var_Decl var, Type_Decl *const td) {
   const Value v = var->value;
   if(env->class_def)  {
-    if(GET_FLAG(td, member)) {
+    if(vflag(v, vflag_member)) {
       decl_member(env, v);
       if(env->class_def->e->tuple)
         tuple_info(env, v);
@@ -133,7 +130,8 @@ ANN static m_bool check_decl(const Env env, const Exp_Decl *decl) {
     CHECK_BB(check_var_td(env, var, decl->td))
     if(is_fptr(env->gwion, decl->type))
       CHECK_BB(check_fptr_decl(env, var))
-    SET_FLAG(var->value, valid | ae_flag_used);
+    set_vflag(var->value, vflag_valid);
+    //set_vflag(var->value, vflag_used));
     nspc_add_value(env->curr, var->xid, var->value);
   } while((list = list->next));
   return GW_OK;
@@ -141,18 +139,18 @@ ANN static m_bool check_decl(const Env env, const Exp_Decl *decl) {
 
 ANN static inline m_bool ensure_check(const Env env, const Type t) {
   struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)check_cdef,
-    .scope=env->scope->depth, .flag=ae_flag_check };
+    .scope=env->scope->depth, .flag=tflag_check };
   return envset_run(&es, t);
 }
 
 ANN m_bool ensure_traverse(const Env env, const Type t) {
   struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)traverse_cdef,
-    .scope=env->scope->depth, .flag=ae_flag_check };
+    .scope=env->scope->depth, .flag=tflag_check };
   return envset_run(&es, t);
 }
 
 ANN static inline m_bool inferable(const Env env, const Type t, const loc_t pos) {
-  if(!GET_FLAG(t, infer))
+  if(!tflag(t, tflag_infer))
     return GW_OK;
   ERR_B(pos, _("can't infer type."))
 }
@@ -170,7 +168,7 @@ ANN Type check_exp_decl(const Env env, const Exp_Decl* decl) {
   {
     const Type t = get_type(decl->type);
     CHECK_BO(inferable(env, t, td_pos(decl->td)))
-    if(!GET_FLAG(t, check) && t->e->def)
+    if(!tflag(t, tflag_check))
       CHECK_BO(ensure_check(env, t))
   }
   const m_bool global = GET_FLAG(decl->td, global);
@@ -252,13 +250,13 @@ ANN static Value check_non_res_value(const Env env, const Symbol *data) {
       CHECK_BO(not_from_owner_class(env, env->class_def, value, prim_pos(data)))
     const Value v = value ?: find_value(env->class_def, var);
     if(v) {
-      if(env->func && GET_FLAG(env->func->def->base, static) && GET_FLAG(v, member))
+      if(env->func && GET_FLAG(env->func->def->base, static) && vflag(v, vflag_member))
         ERR_O(prim_pos(data),
               _("non-static member '%s' used from static function."), s_name(var))
     }
     return v;
   } else if(SAFE_FLAG(env->class_def, global) || (env->func && GET_FLAG(env->func->def->base, global))) {
-    if(!SAFE_FLAG(value, abstract))
+    if(!value || !GET_FLAG(value, global))
       ERR_O(prim_pos(data),
             _("non-global variable '%s' used from global function/class."), s_name(var))
   }
@@ -282,7 +280,7 @@ ANN static m_bool lambda_valid(const Env env, const Exp_Primary* exp) {
   const Symbol sym = insert_symbol(val->name);
   const Vector vec = (Vector)&env->curr->info->value->ptr;
   const m_uint scope = map_get(&env->curr->info->func->map, (m_uint)env->func->def->base);
-  if(GET_FLAG(val, abstract))
+  if(GET_FLAG(val, global))
     return GW_OK;
   if(val->from->owner_class && isa(val->from->owner_class, env->class_def) > 0)
     return GW_OK;
@@ -298,7 +296,7 @@ ANN static m_bool lambda_valid(const Env env, const Exp_Primary* exp) {
 ANN static Type prim_id_non_res(const Env env, const Symbol *data) {
   const Symbol sym = *data;
   const Value v = check_non_res_value(env, data);
-  if(!v || !GET_FLAG(v, valid) || (v->from->ctx && v->from->ctx->error)) {
+  if(!v || !vflag(v, vflag_valid) || (v->from->ctx && v->from->ctx->error)) {
     env_err(env, prim_pos(data),
           _("variable %s not legit at this point."), s_name(sym));
     if(v)
@@ -307,12 +305,12 @@ ANN static Type prim_id_non_res(const Env env, const Symbol *data) {
   }
   prim_self(data)->value = v;
   if(env->func) {
-    if(GET_FLAG(env->func->def->base, abstract))
+    if(isa(env->func->value_ref->type, env->gwion->type[et_lambda]) > 0)
       CHECK_BO(lambda_valid(env, prim_self(data)))
-  if(env->func && !GET_FLAG(v, const) && v->from->owner)
-    UNSET_FLAG(env->func, pure);
+    if(env->func && !GET_FLAG(v, const) && v->from->owner)
+      unset_fflag(env->func, fflag_pure);
   }
-  SET_FLAG(v, used);
+  //v->vflag |= used;
   if(GET_FLAG(v, const))
     exp_setmeta(prim_exp(data), 1);
   if(v->from->owner_class) {
@@ -353,7 +351,7 @@ ANN static Type check_prim_interp(const Env env, const Exp* exp) {
 
 ANN static Type check_prim_hack(const Env env, const Exp *data) {
   if(env->func)
-    UNSET_FLAG(env->func, pure);
+      unset_fflag(env->func, fflag_pure);
   CHECK_OO(check_prim_interp(env, data))
   return env->gwion->type[et_gack];
 }
@@ -442,7 +440,7 @@ ANN2(1,2) static Func find_func_match_actual(const Env env, Func func, const Exp
     Arg_List e1 = func->def->base->args;
     while(e) {
       if(!e1) {
-        if(GET_FLAG(func->def->base, variadic))
+        if(fbflag(func->def->base, fbflag_variadic))
           return func;
         CHECK_OO(func->next);
         return find_func_match_actual(env, func->next, args, implicit, specific);
@@ -482,7 +480,7 @@ ANN2(1, 2) Func find_func_match(const Env env, const Func up, const Exp exp) {
 ANN m_bool check_traverse_fdef(const Env env, const Func_Def fdef) {
   struct Vector_ v = {};
   const m_uint scope = env->scope->depth;
-  env->scope->depth = 1;
+  env->scope->depth = 0;
   vector_init(&v);
   while(vector_size((Vector)&env->curr->info->value->ptr) > 1)
     vector_add(&v, vector_pop((Vector)&env->curr->info->value->ptr));
@@ -502,9 +500,9 @@ ANN static m_bool check_func_args(const Env env, Arg_List arg_list) {
       CHECK_OB((arg_list->type = v->type = check_td(env, arg_list->td)))
 // TODO: use coumpound instead of object?
     if(isa(v->type, env->gwion->type[et_object]) > 0 || isa(v->type, env->gwion->type[et_function]) > 0)
-      UNSET_FLAG(env->func, pure);
+      unset_fflag(env->func, fflag_pure);
     CHECK_BB(already_defined(env, decl->xid, decl->pos))
-    SET_FLAG(v, valid);
+    set_vflag(v, vflag_valid);
     nspc_add_value(env->curr, decl->xid, v);
   } while((arg_list = arg_list->next));
   return GW_OK;
@@ -586,9 +584,9 @@ ANN static Type check_predefined(const Env env, Exp_Call *exp, const Value v, co
   DECL_OO(const Func, func, = v->d.func_ref ?: predefined_func(env, v, exp, tm))
   if(!fdef->base->ret_type) { // template fptr
     struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)check_cdef,
-      .scope=env->scope->depth, .flag=ae_flag_check };
+      .scope=env->scope->depth, .flag=tflag_check };
     CHECK_BO(envset_push(&es, v->from->owner_class, v->from->owner))
-    SET_FLAG(func->def->base, typedef);
+    func->def->base->fbflag |= fbflag_internal;
     const m_bool ret = check_traverse_fdef(env, func->def);
     if(es.run)
       envset_pop(&es, v->from->owner_class);
@@ -654,7 +652,7 @@ ANN static Type check_lambda_call(const Env env, const Exp_Call *exp) {
     ERR_O(exp_self(exp)->pos, _("argument number does not match for lambda"))
   CHECK_BO(check_traverse_fdef(env, l->def))
   if(env->class_def)
-    SET_FLAG(l->def->base, member);
+    set_vflag(l->def->base->func->value_ref, vflag_member);
   ((Exp_Call*)exp)->m_func = l->def->base->func;
   return l->def->base->ret_type ?: (l->def->base->ret_type = env->gwion->type[et_void]);
 }
@@ -673,14 +671,14 @@ ANN Type check_exp_call1(const Env env, const Exp_Call *exp) {
   }
   if(exp->func->info->type == env->gwion->type[et_lambda])
     return check_lambda_call(env, exp);
-  if(GET_FLAG(exp->func->info->type->e->d.func, ref)) {
+  if(fflag(exp->func->info->type->e->d.func, fflag_ftmpl)) {
     const Value value = exp->func->info->type->e->d.func->value_ref;
-    if(value->from->owner_class && !GET_FLAG(value->from->owner_class, check))
+    if(value->from->owner_class && !tflag(value->from->owner_class, tflag_check))
       CHECK_BO(ensure_traverse(env, value->from->owner_class))
   }
   if(exp->args)
     CHECK_OO(check_exp(env, exp->args))
-  if(GET_FLAG(exp->func->info->type, func))
+  if(tflag(exp->func->info->type, tflag_ftmpl))
     return check_exp_call_template(env, (Exp_Call*)exp);
   const Func func = find_func_match(env, exp->func->info->type->e->d.func, exp->args);
   if((exp_self(exp)->d.exp_call.m_func = func)) {
@@ -730,7 +728,7 @@ ANN static m_bool predefined_call(const Env env, const Type t, const loc_t pos)
   env_err(env, pos, _("Type '%s' has '%s' as pre-defined types."),
       t->name, str);
   free_mstr(env->gwion->mp, str);
-  if(GET_FLAG(t, typedef)) {
+  if(tflag(t, tflag_typedef)) {
     loc_header(t->e->d.func->def->pos, env->name);
     gw_err(_("from definition:\n"));
     loc_err(t->e->d.func->def->pos, env->name);
@@ -769,7 +767,7 @@ ANN static Type check_exp_unary(const Env env, const Exp_Unary* unary) {
     return NULL;
   DECL_OO(const Type, ret, = op_check(env, &opi))
   const Type t = get_type(actual_type(env->gwion, ret));
-  if(t->e->def && !GET_FLAG(t, check))
+  if(!tflag(t, tflag_check))
     CHECK_BO(ensure_traverse(env, t))
   return ret;
 }
@@ -806,7 +804,7 @@ ANN static Type check_exp_dot(const Env env, Exp_Dot* member) {
 }
 
 ANN m_bool check_type_def(const Env env, const Type_Def tdef) {
-  return tdef->type->e->def ? check_class_def(env, tdef->type->e->def) : GW_OK;
+  return tdef->type->e->cdef ? check_class_def(env, tdef->type->e->cdef) : GW_OK;
 }
 ANN static Type check_exp_lambda(const Env env,
     const Exp_If* exp_if NUSED) { return env->gwion->type[et_lambda]; }
@@ -818,8 +816,8 @@ ANN Type check_exp(const Env env, const Exp exp) {
   do {
     CHECK_OO((curr->info->type = check_exp_func[curr->exp_type](env, &curr->d)))
     if(env->func && isa(curr->info->type, env->gwion->type[et_lambda]) < 0 && isa(curr->info->type, env->gwion->type[et_function]) > 0 &&
-        !GET_FLAG(curr->info->type->e->d.func, pure))
-      UNSET_FLAG(env->func, pure);
+        !fflag(curr->info->type->e->d.func, fflag_pure))
+      unset_fflag(env->func, fflag_pure);
   } while((curr = curr->next));
   return exp->info->type;
 }
@@ -874,7 +872,7 @@ ANN static inline m_bool for_empty(const Env env, const Stmt_For stmt) {
 
 ANN static m_bool do_stmt_each(const Env env, const Stmt_Each stmt) {
   DECL_OB(Type, t, = check_exp(env, stmt->exp))
-  while(GET_FLAG(t, typedef))
+  while(tflag(t, tflag_typedef))
     t = t->e->parent;
   Type ptr = array_base(t);
   const m_uint depth = t->array_depth - 1;
@@ -888,12 +886,12 @@ ANN static m_bool do_stmt_each(const Env env, const Stmt_Each stmt) {
     sprintf(c, "nonnull Ptr:[%s]", ptr->name);
     ptr = str2type(env->gwion, c, stmt->exp->pos);
     const Type base = get_type(ptr);
-    if(!GET_FLAG(base, check))
+    if(!tflag(base, tflag_check))
       CHECK_BB(ensure_traverse(env, base))
   }
   t = (!stmt->is_ptr && depth) ? array_type(env, ptr, depth) : ptr;
   stmt->v = new_value(env->gwion->mp, t, s_name(stmt->sym));
-  SET_FLAG(stmt->v, valid);
+  set_vflag(stmt->v, vflag_valid);
   nspc_add_value(env->curr, stmt->sym, stmt->v);
   return check_conts(env, stmt_self(stmt), stmt->body);
 }
@@ -980,7 +978,7 @@ ANN m_bool check_union_decl(const Env env, const Union_Def udef) {
   do {
     CHECK_OB(check_exp(env, l->self))
     Var_Decl_List list = l->self->d.exp_decl.list;
-    do SET_FLAG(list->self->value, pure);
+    do set_vflag(list->self->value, vflag_union);
     while((list = list->next));
     if(l->self->info->type->size > udef->s)
       udef->s = l->self->info->type->size;
@@ -1012,8 +1010,7 @@ ANN m_bool check_union_def(const Env env, const Union_Def udef) {
   if(!udef->xid && !udef->type_xid && env->class_def && !GET_FLAG(udef, static))
     env->class_def->nspc->info->offset = udef->o + udef->s;
   union_pop(env, udef, scope);
-  union_flag(udef, ae_flag_check);
-  union_flag(udef, ae_flag_valid);
+  union_flag(udef, tflag_check);
   return ret;
 }
 
@@ -1025,7 +1022,7 @@ ANN static Value match_value(const Env env, const Exp_Primary* prim, const m_uin
   const Symbol sym = prim->d.var;
   const Value v = new_value(env->gwion->mp,
      ((Exp)VKEY(&env->scope->match->map, i))->info->type, s_name(sym));
-  SET_FLAG(v, valid);
+  set_vflag(v, vflag_valid);
   nspc_add_value(env->curr, sym, v);
   VVAL(&env->scope->match->map, i) = (vtype)v;
   return v;
@@ -1128,6 +1125,8 @@ ANN static m_bool check_stmt_list(const Env env, Stmt_List l) {
 }
 
 ANN static m_bool check_signature_match(const Env env, const Func_Def fdef, const Func parent) {
+  if(GET_FLAG(parent->def->base, final))
+    ERR_B(td_pos(fdef->base->td), _("can't override final function '%s'\n"), parent->name)
   if(GET_FLAG(parent->def->base, static) != GET_FLAG(fdef->base, static)) {
     const m_str c_name  = fdef->base->func->value_ref->from->owner_class->name;
     const m_str p_name = parent->value_ref->from->owner_class->name;
@@ -1212,11 +1211,8 @@ ANN static m_bool check_func_def_override(const Env env, const Func_Def fdef) {
 ANN m_bool check_fdef(const Env env, const Func_Def fdef) {
   if(fdef->base->args)
     CHECK_BB(check_func_args(env, fdef->base->args))
-  if(!GET_FLAG(fdef->base, builtin)) {
-    if(fdef->d.code)
-      CHECK_BB(check_stmt_code(env, &fdef->d.code->d.stmt_code))
-  } else
-    fdef->base->func->code->stack_depth = fdef->stack_depth;
+  if(fdef->d.code)
+    CHECK_BB(check_stmt_code(env, &fdef->d.code->d.stmt_code))
   return GW_OK;
 }
 
@@ -1239,18 +1235,18 @@ ANN m_bool check_func_def(const Env env, const Func_Def f) {
   ++env->scope->depth;
   nspc_push_value(env->gwion->mp, env->curr);
   struct Op_Import opi = { };
-  if(GET_FLAG(fdef->base, op)) {
+  if(fbflag(fdef->base, fbflag_op)) {
     func_operator(f, &opi);
     operator_suspend(env->curr, &opi);
   }
   const m_bool ret = scanx_fdef(env, env, fdef, (_exp_func)check_fdef);
-  if(GET_FLAG(fdef->base, op))
+  if(fbflag(fdef->base, fbflag_op))
     operator_resume(&opi);
   nspc_pop_value(env->gwion->mp, env->curr);
   --env->scope->depth;
   env->func = former;
   if(ret > 0)
-    SET_FLAG(fdef->base, valid);
+    set_fflag(fdef->base->func, fflag_valid);
   if(GET_FLAG(fdef->base, global))
     env_pop(env,scope);
   return ret;
@@ -1264,10 +1260,11 @@ ANN static m_bool check_parent(const Env env, const Class_Def cdef) {
   const Type_Decl *td = cdef->base.ext;
   if(td->array)
     CHECK_BB(check_subscripts(env, td->array, 1))
-  if(parent->e->def && !GET_FLAG(parent, check))
+  if(!tflag(parent, tflag_check))
     CHECK_BB(ensure_check(env, parent))
-  if(GET_FLAG(parent, typedef))
-    SET_FLAG(cdef->base.type, typedef);
+  if(tflag(parent, tflag_typedef)) {
+    set_tflag(cdef->base.type, tflag_typedef);
+  }
   return GW_OK;
 }
 
@@ -1280,23 +1277,36 @@ ANN static m_bool cdef_parent(const Env env, const Class_Def cdef) {
   return ret;
 }
 
+ANN m_bool check_abstract(const Env env, const Class_Def cdef) {
+  if(!cdef->base.type->nspc->info->vtable.ptr)
+    return GW_OK;
+  for(m_uint i = 0; i < vector_size(&cdef->base.type->nspc->info->vtable); ++i) {
+    Func f = (Func)vector_at(&cdef->base.type->nspc->info->vtable, i);
+    if(GET_FLAG(f->def->base, abstract))
+      ERR_B(cdef->pos, _("'%s' must be declared 'abstract'"), s_name(cdef->base.xid))
+  }
+  return GW_OK;
+}
+
 ANN m_bool check_class_def(const Env env, const Class_Def cdef) {
   if(tmpl_base(cdef->base.tmpl))
     return GW_OK;
   const Type t = cdef->base.type;
-  if(t->e->owner_class && !GET_FLAG(t->e->owner_class, check))
+  if(t->e->owner_class && !tflag(t->e->owner_class, tflag_check))
     CHECK_BB(ensure_check(env, t->e->owner_class))
-  if(GET_FLAG(t, check))return GW_OK;
-  SET_FLAG(t, check);
+  if(tflag(t, tflag_check))
+    return GW_OK;
+  set_tflag(t, tflag_check);
   if(cdef->base.ext)
     CHECK_BB(cdef_parent(env, cdef))
-  if(!GET_FLAG(cdef, struct))
+  if(!tflag(t, tflag_struct))
     inherit(t);
   if(cdef->body) {
     CHECK_BB(env_body(env, cdef, check_section))
-    SET_FLAG(t, ctor);
+    set_tflag(t, tflag_ctor);
   }
-  SET_FLAG(t, valid);
+  if(!GET_FLAG(cdef, abstract))
+    CHECK_BB(check_abstract(env, cdef))
   return GW_OK;
 }
 
index 75af75108c950ca373ecdc8161eaa191ed387574..2d794a8dc4e37efe6f0e9bb5a2863a708caa2a31 100644 (file)
@@ -10,7 +10,7 @@
 ANN void func_operator(const Func_Def fdef, struct Op_Import *opi) {
   opi->op =fdef->base->xid;
   const m_str str = s_name(fdef->base->xid);
-  const uint is_unary = GET_FLAG(fdef->base, unary) +
+  const uint is_unary = fbflag(fdef->base, fbflag_unary) +
     (!strcmp(str, "@conditionnal") || !strcmp(str, "@unconditionnal"));
   const Arg_List args = fdef->base->args;
   opi->lhs = is_unary ? NULL :
index bb5a606320e9e9318df98fc7b9d20325e7919ce3..ca3c573c0329ecf1e4fbe80d322f39251f90ab08 100644 (file)
@@ -40,7 +40,7 @@ ANN static m_bool check_call(const Env env, const Exp_Call* exp) {
 }
 
 ANN static Func ensure_tmpl(const Env env, const Func_Def fdef, const Exp_Call *exp) {
-  const m_bool ret = GET_FLAG(fdef->base, valid) || check_traverse_fdef(env, fdef) > 0;
+  const m_bool ret = (fdef->base->func && fflag(fdef->base->func, fflag_valid)) || check_traverse_fdef(env, fdef) > 0;
   if(ret) {
     const Func f = fdef->base->func;
     const Func next = f->next;
@@ -48,7 +48,8 @@ ANN static Func ensure_tmpl(const Env env, const Func_Def fdef, const Exp_Call *
     const Func func = find_func_match(env, f, exp->args);
     f->next = next;
     if(func) {
-      SET_FLAG(func, valid | ae_flag_template);
+      set_fflag(func, fflag_tmpl);
+      set_fflag(func, fflag_valid);
       return func;
     }
   }
@@ -65,7 +66,7 @@ ANN static Func fptr_match(const Env env, struct ResolverArgs* f_ptr_args) {
   if(exists)
     return exists->e->d.func;
 
-  Func m_func = f_ptr_args->m_func; 
+  Func m_func = f_ptr_args->m_func;
   Func_Def base = v->d.func_ref ? v->d.func_ref->def : exp->func->info->type->e->d.func->def;
   Func_Base *fbase = cpy_func_base(env->gwion->mp, base->base);
   fbase->xid = sym;
@@ -92,7 +93,7 @@ ANN static Func func_match(const Env env, struct ResolverArgs* f_ptr_args) {
   const Value v = f_ptr_args->v;
   const m_str tmpl_name = f_ptr_args->tmpl_name;
   const Exp_Call *exp = f_ptr_args->e;
-  Func m_func = f_ptr_args->m_func; 
+  Func m_func = f_ptr_args->m_func;
   Type_List types = f_ptr_args->types;
   for(m_uint i = 0; i < v->from->offset + 1; ++i) {
     const Value exists = template_get_ready(env, v, tmpl_name, i);
@@ -110,12 +111,9 @@ ANN static Func func_match(const Env env, struct ResolverArgs* f_ptr_args) {
       const Value value = template_get_ready(env, v, "template", i);
       if(!value)
         continue;
-      if(GET_FLAG(v, builtin)) {
-        SET_FLAG(value, builtin);
-        SET_FLAG(value->d.func_ref, builtin);
-      }
+      if(vflag(v, vflag_builtin))
+        set_vflag(value, vflag_builtin);
       const Func_Def fdef = (Func_Def)cpy_func_def(env->gwion->mp, value->d.func_ref->def);
-      SET_FLAG(fdef->base, template);
       fdef->base->tmpl->call = cpy_type_list(env->gwion->mp, types);
       fdef->base->tmpl->base = i;
       if((m_func = ensure_tmpl(env, fdef, exp))) {
@@ -136,7 +134,7 @@ ANN static Func _find_template_match(const Env env, const Value v, const Exp_Cal
   DECL_OO(const m_str, tmpl_name, = tl2str(env, types))
   const m_uint scope = env->scope->depth;
   struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)check_cdef,
-    .scope=scope, .flag=ae_flag_check };
+    .scope=scope, .flag=tflag_check };
   struct ResolverArgs f_ptr_args = {.v = v, .e = exp, .tmpl_name = tmpl_name, m_func =  m_func, .types = types};
   CHECK_BO(envset_push(&es, v->from->owner_class, v->from->owner))
   (void)env_push(env, v->from->owner_class, v->from->owner);
index 5b89942cb3c3380a9ef60655e6d8d0a85e514377..fa3c27b72b9ee24916934648a111304bcf3c39ed 100644 (file)
@@ -35,7 +35,7 @@ ANN void free_op_map(Map map, struct Gwion_ *gwion) {
 }
 
 ANN static Type op_parent(const Env env, const Type t) {
-  if(GET_FLAG(t, template) && GET_FLAG(t, ref)) {
+  if(tflag(t, tflag_ctmpl)) {
     const Type type = typedef_base(t);
     char name[strlen(type->name) + 1];
     strcpy(name, type->name);
@@ -50,7 +50,6 @@ 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;
   Type type = t;
-  while(SAFE_FLAG(type, template) && type->e->def && type->e->def->base.tmpl && type->e->def->base.tmpl->call) type = type->e->parent;
   if((type && mo && mo->xid == type->xid) || (!type && !mo))
     return GW_OK;
   return 0;
@@ -179,7 +178,7 @@ ANN static void set_nspc(struct Op_Import *opi, const Nspc nspc) {
 }
 
 ANN static inline void set_nonnull(const Type t, const Exp exp) {
-  if(t != OP_ANY_TYPE && GET_FLAG(t, nonnull))
+  if(t != OP_ANY_TYPE && tflag(t, tflag_nonnull))
     exp_setnonnull(exp, 1);
 }
 
index 6047da5f12b0c323dcd21411bbba626622146414..6317cba44ffad46eaadbe84283dd4ac9208aff16 100644 (file)
@@ -42,18 +42,16 @@ ANN static void fptr_assign(const Env env, const Fptr_Def fptr) {
     SET_FLAG(fptr->base->func, global);
     SET_FLAG(def->base, global);
   } else if(!GET_FLAG(fptr->base, static)) {
-    SET_FLAG(fptr->value, member);
-    SET_FLAG(fptr->base->func, member);
-    SET_FLAG(def->base, member);
+    set_vflag(fptr->value, vflag_member);
+    set_vflag(fptr->base->func->value_ref, vflag_member);
     def->stack_depth += SZ_INT;
   } else {
     SET_FLAG(fptr->value, static);
     SET_FLAG(fptr->base->func, static);
     SET_FLAG(def->base, static);
   }
-  if(GET_FLAG(def->base, variadic))
+  if(fbflag(def->base, fbflag_variadic))
     def->stack_depth += SZ_INT;
-  fptr->value->from->owner_class = env->class_def;
 }
 
 static void fptr_def(const Env env, const Fptr_Def fptr) {
@@ -78,14 +76,14 @@ ANN m_bool scan0_fptr_def(const Env env, const Fptr_Def fptr) {
   if(GET_FLAG(fptr->base, global))
     context_global(env);
   t->nspc = new_nspc(env->gwion->mp, name);
-  t->flag = fptr->base->flag;
+  t->flag |= fptr->base->flag;
   fptr->type = t;
   fptr->value = mk_class(env, t);
   valuefrom(env, fptr->value->from);
   fptr_def(env, fptr);
   if(env->class_def)
     fptr_assign(env, fptr);
-  SET_FLAG(fptr->value, func);
+  set_vflag(fptr->value, vflag_func);
   add_type(env, t->e->owner, t);
   mk_class(env, t);
   ADD_REF(t);
@@ -127,14 +125,14 @@ ANN static void typedef_simple(const Env env, const Type_Def tdef, const Type ba
   tdef->type = t;
   if(base->nspc)
     ADD_REF((t->nspc = base->nspc));
-  t->flag = tdef->ext->flag | ae_flag_valid;
+  t->flag = tdef->ext->flag;
   scan0_implicit_similar(env, t, base);
   if(tdef->ext->array && !tdef->ext->array->exp)
-    SET_FLAG(t, empty);
+    set_tflag(t, tflag_empty);
 }
 
 ANN static m_bool typedef_complex(const Env env, const Type_Def tdef, const Type base) {
-  const ae_flag flag = base->e->def ? base->e->def->flag : 0;
+  const ae_flag flag = base->e->cdef ? base->e->cdef->flag : 0;
   const Class_Def cdef = new_class_def(env->gwion->mp, flag, tdef->xid,
        cpy_type_decl(env->gwion->mp, tdef->ext), NULL,
        loc_cpy(env->gwion->mp, td_pos(tdef->ext)));
@@ -152,7 +150,7 @@ ANN static void typedef_fptr(const Env env, const Type_Def tdef, const Type base
   add_type(env, env->curr, tdef->type);
   mk_class(env, tdef->type);
   if(base->e->d.func->def->base->tmpl)
-    SET_FLAG(tdef->type, func);
+    set_tflag(tdef->type, tflag_ftmpl);
 }
 
 ANN m_bool scan0_type_def(const Env env, const Type_Def tdef) {
@@ -166,7 +164,7 @@ ANN m_bool scan0_type_def(const Env env, const Type_Def tdef) {
       CHECK_BB(typedef_complex(env, tdef, base))
   } else
     typedef_fptr(env, tdef, base);
-  SET_FLAG(tdef->type, typedef);
+  set_tflag(tdef->type, tflag_typedef);
   return GW_OK;
 }
 
@@ -226,33 +224,26 @@ ANN static Type union_type(const Env env, const Symbol s, const m_bool add) {
   add_type(env, env->curr, t);
   if(add)
     mk_class(env, t);
-  SET_FLAG(t, union);
   return t;
 }
 
 ANN static void union_tmpl(const Env env, const Union_Def udef) {
   if(tmpl_base(udef->tmpl)) {
-    assert(udef->type_xid);
-    const Class_Def cdef = new_class_def(env->gwion->mp, udef->flag, udef->type_xid,
-        NULL, (Ast)cpy_decl_list(env->gwion->mp, udef->l), loc_cpy(env->gwion->mp, udef->pos));
-    udef->type->e->def = cdef;
-    cdef->base.tmpl = cpy_tmpl(env->gwion->mp, udef->tmpl);
-    cdef->base.type = udef->type;
-    SET_FLAG(cdef, union);
-    SET_FLAG(udef->type, pure);
-    SET_FLAG(udef, template);
-    SET_FLAG(udef->type, template);
+    const Union_Def u = cpy_union_def(env->gwion->mp, udef);
+    u->type = udef->type;
+    udef->type->e->udef = u;
+    set_tflag(u->type, tflag_tmpl);
+    set_tflag(u->type, tflag_udef);
   }
   if(GET_FLAG(udef, global))
     SET_FLAG(udef->type, global);
-  SET_FLAG(udef->type, union);
 }
 
 ANN static Value union_value(const Env env, const Type t, const Symbol sym) {
   const Value v = new_value(env->gwion->mp, t, s_name(sym));
   valuefrom(env, v->from);
   nspc_add_value(env->curr, sym, v);
-  SET_FLAG(v, valid | ae_flag_pure);
+  set_vflag(v, vflag_union);
   return v;
 }
 
@@ -270,15 +261,12 @@ ANN m_bool scan0_union_def(const Env env, const Union_Def udef) {
     udef->value = union_value(env, t, udef->xid);
     udef->value->flag |= udef->flag;
     SET_ACCESS(udef, t);
-    if(env->class_def && !GET_FLAG(udef, static)) {
-      SET_FLAG(udef->value, member);
-      SET_FLAG(udef, member);
-    }
+    if(env->class_def && !GET_FLAG(udef, static))
+      set_vflag(udef->value, vflag_member);
   } else if(udef->type_xid) {
     CHECK_BB(scan0_defined(env, udef->type_xid, udef->pos))
     udef->type = union_type(env, udef->type_xid, 1);
     SET_ACCESS(udef, udef->type);
-    SET_FLAG(udef->type, valid);
   } else {
     const Symbol sym = scan0_sym(env, "union", udef->pos);
     CHECK_BB(scan0_defined(env, sym, udef->pos))
@@ -291,7 +279,7 @@ ANN m_bool scan0_union_def(const Env env, const Union_Def udef) {
     union_tmpl(env, udef);
   if(GET_FLAG(udef, global))
     env_pop(env, scope);
-  union_flag(udef, ae_flag_scan0);
+  union_flag(udef, tflag_scan0);
   return GW_OK;
 }
 
@@ -303,12 +291,10 @@ ANN static m_bool scan0_class_def_pre(const Env env, const Class_Def cdef) {
 }
 
 ANN static void cdef_flag(const Class_Def cdef, const Type t) {
-  if(cdef->base.tmpl) {
-    SET_FLAG(t, template);
-    SET_FLAG(cdef, template);
-  }
+  if(cdef->base.tmpl)
+    set_tflag(t, tflag_tmpl);
   if(cdef->base.ext && cdef->base.ext->array)
-    SET_FLAG(t, typedef);
+    set_tflag(t, tflag_typedef);
 }
 
 ANN static Type get_parent_base(const Env env, Type_Decl *td) {
@@ -322,15 +308,15 @@ ANN static Type get_parent_base(const Env env, Type_Decl *td) {
   return t;
 }
 
-ANN static Type check_abstract(const Env env, Type_Decl *td) {
+ANN static inline Type scan0_final(const Env env, Type_Decl *td) {
   DECL_OO(const Type, t, = known_type(env, td))
-  if(!GET_FLAG(t, abstract)) // could be final
+  if(!GET_FLAG(t, final))
     return t;
-  ERR_O(td_pos(td), _("can't inherit from abstract parent class '%s'\n."), t->name);
+  ERR_O(td_pos(td), _("can't inherit from final parent class '%s'\n."), t->name);
 }
 
 ANN static Type get_parent(const Env env, const Class_Def cdef) {
-  if(GET_FLAG(cdef, struct))
+  if(cflag(cdef, cflag_struct))
     return env->gwion->type[et_compound];
   if(!cdef->base.ext)
     return env->gwion->type[et_object];
@@ -338,7 +324,7 @@ ANN static Type get_parent(const Env env, const Class_Def cdef) {
     return get_parent_base(env, cdef->base.ext);
   if(cdef->base.tmpl)
     template_push_types(env, cdef->base.tmpl);
-  const Type t = check_abstract(env, cdef->base.ext);
+  const Type t = scan0_final(env, cdef->base.ext);
   if(cdef->base.tmpl)
     nspc_pop_type(env->gwion->mp, env->curr);
   return t ?: (Type)GW_ERROR;
@@ -350,19 +336,21 @@ ANN static Type scan0_class_def_init(const Env env, const Class_Def cdef) {
   if(parent == (Type)GW_ERROR)
     return NULL;
   const Type t = scan0_type(env, ++env->scope->type_xid, s_name(cdef->base.xid), parent);
-  if(GET_FLAG(cdef, struct))
-    SET_FLAG(t, struct);
+//  if(GET_FLAG(parent, abstract))
+//    SET_FLAG(t, abstract);
+  if(cflag(cdef, cflag_struct))
+    t->flag |= tflag_struct;
   t->e->tuple = new_tupleform(env->gwion->mp, parent);
   t->e->owner = env->curr;
   t->e->owner_class = env->class_def;
   t->nspc = new_nspc(env->gwion->mp, t->name);
   t->nspc->parent = env->curr;
-  t->e->def = cdef;
-  t->flag = cdef->flag;
+  t->e->cdef = cdef;
+  t->flag |= cdef->flag;
   add_type(env, t->e->owner, t);
   cdef_flag(cdef, t);
   if(cdef->base.ext && cdef->base.ext->array)
-    SET_FLAG(t, typedef);
+    set_tflag(t, tflag_typedef);
   return t;
 }
 
@@ -378,7 +366,7 @@ HANDLE_SECTION_FUNC(scan0, m_bool, Env)
 
 ANN static m_bool scan0_class_def_inner(const Env env, const Class_Def cdef) {
   CHECK_OB((cdef->base.type = scan0_class_def_init(env, cdef)))
-  SET_FLAG(cdef->base.type, scan0);
+  set_tflag(cdef->base.type, tflag_scan0);
   if(cdef->body)
     CHECK_BB(env_body(env, cdef, scan0_section))
   (void)mk_class(env, cdef->base.type);
@@ -386,9 +374,9 @@ ANN static m_bool scan0_class_def_inner(const Env env, const Class_Def cdef) {
 }
 
 ANN m_bool scan0_class_def(const Env env, const Class_Def c) {
-  const Class_Def cdef = !tmpl_base(c->base.tmpl) ?
-    c : cpy_class_def(env->gwion->mp, c);
-  if(GET_FLAG(cdef, global)) {
+  const int cpy = tmpl_base(c->base.tmpl) || GET_FLAG(c, global);
+  const Class_Def cdef = !cpy ? c : cpy_class_def(env->gwion->mp, c);
+  if(GET_FLAG(cdef, global)) { // could be updated
     vector_add(&env->scope->nspc_stack, (vtype)env->curr);
     env->curr = env->global_nspc;
     context_global(env);
@@ -397,11 +385,13 @@ ANN m_bool scan0_class_def(const Env env, const Class_Def c) {
     scan0_class_def_inner(env, cdef) : GW_ERROR;
   if(GET_FLAG(cdef, global))
     env->curr = (Nspc)vector_pop(&env->scope->nspc_stack);
-  CHECK_BB(ret)
-  if(GET_FLAG(cdef, global) || (cdef->base.tmpl && !cdef->base.tmpl->call))
+  if(cpy && cdef->base.type) {
     c->base.type = cdef->base.type;
-  SET_FLAG(cdef->base.type, scan0);
-  return GW_OK;
+    c->base.type->e->cdef = cdef;
+    set_tflag(c->base.type, tflag_cdef);
+    set_tflag(cdef->base.type, tflag_scan0);// redundant
+  }
+  return ret;
 }
 
 ANN m_bool scan0_ast(const Env env, Ast ast) {
index 350c9239dcb9bf371eaf625dd486303e8b6c01bf..f52c2d0160ddb4c2aeffec6a42ccbf4bba2fd7f9 100644 (file)
@@ -25,7 +25,7 @@ ANN static inline m_bool type_cyclic(const Env env, const Type t, const Type_Dec
 
 ANN static inline m_bool ensure_scan1(const Env env, const Type t) {
   struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)scan1_cdef,
-    .scope=env->scope->depth, .flag=ae_flag_scan1 };
+    .scope=env->scope->depth, .flag=tflag_scan1 };
   return envset_run(&es, t);
 }
 
@@ -34,7 +34,7 @@ ANN static Type scan1_type(const Env env, Type_Decl* td) {
   const Type t = get_type(type);
   if(!env->func && env->class_def && !GET_FLAG(td, ref))
     CHECK_BO(type_cyclic(env, t, td))
-  if(!GET_FLAG(t, scan1) && t->e->def)
+  if(!tflag(t, tflag_scan1))
     CHECK_BO(ensure_scan1(env, t))
   return type;
 }
@@ -52,8 +52,6 @@ ANN static Type scan1_exp_decl_type(const Env env, Exp_Decl* decl) {
   DECL_OO(const Type ,t, = void_type(env, decl->td))
   if(decl->td->xid == insert_symbol("auto") && decl->type)
     return decl->type;
-  if(!env->scope->depth && env->class_def && !GET_FLAG(decl->td, static))
-    SET_FLAG(decl->td, member);
   if(GET_FLAG(t, private) && t->e->owner != env->curr)
     ERR_O(exp_self(decl)->pos, _("can't use private type %s"), t->name)
   if(GET_FLAG(t, protect) && (!env->class_def || isa(t, env->class_def) < 0))
@@ -77,7 +75,7 @@ ANN static m_bool scan1_decl(const Env env, const Exp_Decl* decl) {
     CHECK_BB(isres(env, var->xid, exp_self(decl)->pos))
     Type t = decl->type;
     CHECK_BB(scan1_defined(env, var))
-    if(var->array) {
+   if(var->array) {
       if(var->array->exp) {
         if(GET_FLAG(decl->td, ref))
           ERR_B(var->array->exp->pos, _("ref array must not have array expression.\n"
@@ -92,23 +90,26 @@ ANN static m_bool scan1_decl(const Env env, const Exp_Decl* decl) {
         ERR_B(exp_self(decl)->pos, _("Type '%s' is abstract, declare as ref. (use @)"), t->name)
     }
     const Value v = var->value = var->value ?: new_value(env->gwion->mp, t, s_name(var->xid));
-    if(SAFE_FLAG(env->class_def, struct) && !GET_FLAG(decl->td, static)) {
+// rewrite logic
+    if(!env->scope->depth && env->class_def && !GET_FLAG(decl->td, static))
+      set_vflag(v, vflag_member);
+  if(safe_tflag(env->class_def, tflag_struct) && !GET_FLAG(decl->td, static)) {
       v->from->offset = env->class_def->size;
       env->class_def->size += t->size;
     }
     nspc_add_value(env->curr, var->xid, v);
-    v->flag = decl->td->flag;
+    v->flag |= decl->td->flag;
     v->type = t;
     if(var->array && !var->array->exp)
-      SET_FLAG(v, ref);
+      SET_FLAG(decl->td, ref);
     if(env->class_def) {
       if(env->class_def->e->tuple)
         tuple_contains(env, v);
     } else if(!env->scope->depth)
-      SET_FLAG(v, global);
+      set_vflag(v, vflag_fglobal);// file global
     v->d.ptr = var->addr;
     if(GET_FLAG(decl->td, global))
-      SET_FLAG(v, abstract);
+      SET_FLAG(v, global);
     if(!env->scope->depth)
       valuefrom(env, v->from);
   } while((list = list->next));
@@ -127,8 +128,6 @@ ANN m_bool scan1_exp_decl(const Env env, const Exp_Decl* decl) {
   CHECK_BB(env_storage(env, decl->td->flag, exp_self(decl)->pos))
   ((Exp_Decl*)decl)->type = scan1_exp_decl_type(env, (Exp_Decl*)decl);
   CHECK_OB(decl->type)
-  if(GET_FLAG(decl->type, const))
-    exp_setmeta(exp_self(decl), 1);
   const m_bool global = GET_FLAG(decl->td, global);
   if(global) {
     if(env->context)
@@ -319,7 +318,9 @@ ANN m_bool scan1_enum_def(const Env env, const Enum_Def edef) {
       SET_ACCESS(edef, v)
       SET_ACCESS(edef, edef->t)
     }
-    SET_FLAG(v, const | ae_flag_enum | ae_flag_valid);
+    SET_FLAG(v, const);
+    set_vflag(v, vflag_valid);
+    set_vflag(v, vflag_enum);
     nspc_add_value(edef->t->e->owner, list->xid, v);
     vector_add(&edef->values, (vtype)v);
   } while((list = list->next));
@@ -331,8 +332,10 @@ ANN static Value arg_value(const Env env, const Arg_List list) {
   const Value v = new_value(env->gwion->mp, list->type, var->xid ? s_name(var->xid) : (m_str)__func__);
   if(var->array)
     v->type = list->type = array_type(env, list->type, var->array->depth);
-  if(list->td)
-    v->flag = list->td->flag | ae_flag_abstract;
+  if(list->td) {
+    v->flag = list->td->flag;
+//    SET_FLAG(v, global); ???
+  }
   return v;
 }
 
@@ -386,19 +389,17 @@ ANN m_bool scan1_fptr_def(const Env env, const Fptr_Def fptr) {
 ANN m_bool scan1_type_def(const Env env, const Type_Def tdef) {
   if(!tdef->type)
     tdef->type = nspc_lookup_type0(env->curr, tdef->xid);
-  if(!tdef->type->e->def)return GW_OK;
-  return !is_fptr(env->gwion, tdef->type) ? scan1_cdef(env, tdef->type->e->def) : GW_OK;
+  if(!tdef->type->e->cdef)return GW_OK;
+  return !is_fptr(env->gwion, tdef->type) ? scan1_cdef(env, tdef->type) : GW_OK;
 }
 
 ANN static m_bool scan1_union_def_action(const Env env, const Union_Def udef,
     const Decl_List l) {
   const Exp_Decl decl = l->self->d.exp_decl;
-  SET_FLAG(decl.td, valid | udef->flag);
+  decl.td->flag |= udef->flag;
   const m_bool global = GET_FLAG(udef, global);
   if(global)
     UNSET_FLAG(decl.td, global);
-  if(GET_FLAG(udef, member))
-    SET_FLAG(decl.td, member);
   else if(GET_FLAG(udef, static))
     SET_FLAG(decl.td, static);
   CHECK_BB(scan1_exp(env, l->self))
@@ -437,7 +438,7 @@ ANN m_bool scan1_union_def(const Env env, const Union_Def udef) {
   }
   const m_bool ret = scan1_union_def_inner(env, udef);
   union_pop(env, udef, scope);
-  union_flag(udef, ae_flag_scan1);
+  union_flag(udef, tflag_scan1);
   return ret;
 }
 
@@ -530,11 +531,10 @@ ANN static m_bool scan1_fdef_args(const Env env, Arg_List list) {
 
 ANN m_bool scan1_fbody(const Env env, const Func_Def fdef) {
   if(fdef->base->args) {
-    if(!GET_FLAG(fdef->base, builtin))
-      CHECK_BB(scan1_fdef_args(env, fdef->base->args))
+    CHECK_BB(scan1_fdef_args(env, fdef->base->args))
     CHECK_BB(scan1_args(env, fdef->base->args))
   }
-  if(!GET_FLAG(fdef->base, builtin) && fdef->d.code && fdef->d.code->d.stmt_code.stmt_list)
+  if(fdef->d.code && fdef->d.code->d.stmt_code.stmt_list)
     CHECK_BB(scan1_stmt_list(env, fdef->d.code->d.stmt_code.stmt_list))
   return GW_OK;
 }
@@ -542,9 +542,9 @@ ANN m_bool scan1_fbody(const Env env, const Func_Def fdef) {
 ANN m_bool scan1_fdef(const Env env, const Func_Def fdef) {
   if(fdef->base->td)
     CHECK_OB((fdef->base->ret_type = known_type(env, fdef->base->td)))
-  if(GET_FLAG(fdef->base, typedef))
+  if(fbflag(fdef->base, fbflag_internal))
     CHECK_BB(scan_internal(env, fdef->base))
-  else if(GET_FLAG(fdef->base, op) && env->class_def)
+  else if(fbflag(fdef->base, fbflag_op) && env->class_def)
     SET_FLAG(fdef->base, static);
   RET_NSPC(scan1_fbody(env, fdef))
   return GW_OK;
@@ -592,13 +592,16 @@ ANN static m_bool scan1_parent(const Env env, const Class_Def cdef) {
   if(cdef->base.ext->array)
     CHECK_BB(scan1_exp(env, cdef->base.ext->array->exp))
   DECL_OB(const Type , parent, = scan1_get_parent(env, &cdef->base))
+//  if(GET_FLAG(parent, abstract)) // could be final
+//SET_FLAG(cdef->base.type, abstract);
+//    ERR_B(td_pos(cdef->base.ext), _("can't inherit from abstract parent class '%s'\n."), parent->name);
   if(isa(parent, env->gwion->type[et_object]) < 0)
     ERR_B(pos, _("cannot extend primitive type '%s'"), parent->name)
-  if(parent->e->def && !GET_FLAG(parent, scan1))
+  if(!tflag(parent, tflag_scan1))
     CHECK_BB(ensure_scan1(env, parent))
   if(type_ref(parent))
     ERR_B(pos, _("can't use ref type in class extend"))
-  if(GET_FLAG(parent, nonnull))
+  if(tflag(parent, tflag_nonnull))
     ERR_B(pos, _("can't use nonnull type in class extend"))
   return GW_OK;
 }
@@ -616,12 +619,11 @@ ANN m_bool scan1_class_def(const Env env, const Class_Def cdef) {
   if(tmpl_base(cdef->base.tmpl))
     return GW_OK;
   const Type t = cdef->base.type;
-  if(GET_FLAG(t, scan1))
+  if(tflag(t, tflag_scan1))
     return GW_OK;
-  SET_FLAG(t, scan1);
-  if(t->e->owner_class && !GET_FLAG(t->e->owner_class, scan1))
+  set_tflag(t, tflag_scan1);
+  if(t->e->owner_class && !tflag(t->e->owner_class, tflag_scan1))
     CHECK_BB(ensure_scan1(env, t->e->owner_class))
-  SET_FLAG(cdef->base.type, scan1);
   if(cdef->base.ext)
     CHECK_BB(cdef_parent(env, cdef))
   if(cdef->body)
index 2bb5b4a828dfbfc0fa58763265b7bdf1bc96c386..cfdbb07b19c8b67b889a5e67a6f470f33f55f756 100644 (file)
@@ -15,13 +15,13 @@ ANN static m_bool scan2_stmt_list(const Env, Stmt_List);
 
 ANN static inline m_bool ensure_scan2(const Env env, const Type t) {
   struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)scan2_cdef,
-    .scope=env->scope->depth, .flag=ae_flag_scan2 };
+    .scope=env->scope->depth, .flag=tflag_scan2 };
   return envset_run(&es, t);
 }
 
 ANN static m_bool scan2_decl(const Env env, const Exp_Decl* decl) {
   const Type t = get_type(decl->type);
-  if(t->e->def && !GET_FLAG(t, scan2))
+  if(!tflag(t, tflag_scan2))
     CHECK_BB(ensure_scan2(env, t))
   Var_Decl_List list = decl->list;
   do {
@@ -56,15 +56,17 @@ ANN static m_bool scan2_args(const Func_Def f) {
 ANN static Value scan2_func_assign(const Env env, const Func_Def d,
     const Func f, const Value v) {
   valuefrom(env, v->from);
-  SET_FLAG(v, func | ae_flag_const);
+  SET_FLAG(v, const);
+  set_vflag(v, vflag_func);
   if(!env->class_def)
-    SET_FLAG(v, global);
+    set_vflag(v, vflag_fglobal);
   else {
-    if(GET_FLAG(f, member))
-      SET_FLAG(v, member);
-    else SET_FLAG(v, static);
+    if(GET_FLAG(d->base, static))
+      SET_FLAG(v, static);
+    else
+      set_vflag(v, vflag_member);
     SET_ACCESS(d->base, v)
 }
+ }
   d->base->func = v->d.func_ref = f;
   return f->value_ref = v;
 }
@@ -77,13 +79,13 @@ ANN m_bool scan2_fptr_def(const Env env NUSED, const Fptr_Def fptr) {
       RET_NSPC(scan2_args(def))
     }
   } else
-    SET_FLAG(fptr->type, func);
+    set_tflag(fptr->type, tflag_ftmpl);
   return GW_OK;
 }
 
 ANN m_bool scan2_type_def(const Env env, const Type_Def tdef) {
-  if(!tdef->type->e->def) return GW_OK;
-  return !is_fptr(env->gwion, tdef->type) ? scan2_class_def(env, tdef->type->e->def) : GW_OK;
+  if(!tdef->type->e->cdef) return GW_OK;
+  return !is_fptr(env->gwion, tdef->type) ? scan2_class_def(env, tdef->type->e->cdef) : GW_OK;
 }
 
 ANN static inline Value prim_value(const Env env, const Symbol s) {
@@ -105,11 +107,11 @@ ANN static inline m_bool scan2_prim(const Env env, const Exp_Primary* prim) {
   if(prim->prim_type == ae_prim_hack || prim->prim_type == ae_prim_typeof ||
         prim->prim_type == ae_prim_interp)
     CHECK_BB(scan2_exp(env, prim->d.exp))
-  else if(prim->prim_type == ae_prim_id) {
+/*  else if(prim->prim_type == ae_prim_id) {
     const Value v = prim_value(env, prim->d.var);
     if(v)
-      SET_FLAG(v, used);
-  } else if(prim->prim_type == ae_prim_array && prim->d.array->exp)
+      v->vflag |= used;
+  } */else if(prim->prim_type == ae_prim_array && prim->d.array->exp)
     return scan2_exp(env, prim->d.array->exp);
   else if(prim->prim_type == ae_prim_range)
     return scan2_range(env, prim->d.range);
@@ -130,7 +132,7 @@ ANN static m_bool multi_decl(const Env env, const Exp e, const Symbol op) {
   if(e->exp_type == ae_exp_decl) {
     if(e->d.exp_decl.list->next)
       ERR_B(e->pos, _("cant '%s' from/to a multi-variable declaration."), s_name(op))
-    SET_FLAG(e->d.exp_decl.list->self->value, used);
+//    set_vflag(e->d.exp_decl.list->self->value, vflag_used);
   }
   return GW_OK;
 }
@@ -270,7 +272,7 @@ ANN m_bool scan2_union_def(const Env env, const Union_Def udef) {
   const m_uint scope = union_push(env, udef);
   const m_bool ret = scan2_union_decl(env, udef->l);
   union_pop(env, udef, scope);
-  union_flag(udef, ae_flag_scan2);
+  union_flag(udef, tflag_scan2);
   return ret;
 }
 
@@ -300,13 +302,17 @@ ANN static m_bool scan2_stmt_list(const Env env, Stmt_List list) {
 }
 
 ANN static m_bool scan2_func_def_overload(const Env env, const Func_Def f, const Value overload) {
-  const m_bool base = tmpl_base(f->base->tmpl);
-  const m_bool tmpl = GET_FLAG(overload, template);
+  const m_bool fptr = is_fptr(env->gwion, overload->type);
   if(isa(overload->type, env->gwion->type[et_function]) < 0 || is_fptr(env->gwion, overload->type)) {
-    if(!GET_FLAG(f->base, typedef))
+    if(!fbflag(f->base, fbflag_internal))
       ERR_B(f->pos, _("function name '%s' is already used by another value"), overload->name)
   }
-  if((!tmpl && base) || (tmpl && !base && !GET_FLAG(f->base, template)))
+  const Func obase = !fptr ? overload->d.func_ref : overload->type->e->d.base_type->e->d.func;
+  if(GET_FLAG(obase->def->base, final))
+    ERR_B(f->pos, _("can't overload final function %s"), overload->name)
+  const m_bool base = tmpl_base(f->base->tmpl);
+  const m_bool tmpl = fflag(obase, fflag_tmpl);
+  if((!tmpl && base) || (tmpl && !base && !f->base->tmpl))
     ERR_B(f->pos, _("must overload template function with template"))
   return GW_OK;
 }
@@ -314,10 +320,8 @@ ANN static m_bool scan2_func_def_overload(const Env env, const Func_Def f, const
 ANN static Func scan_new_func(const Env env, const Func_Def f, const m_str name) {
   const Func func = new_func(env->gwion->mp, name, f);
   if(env->class_def) {
-    if(GET_FLAG(env->class_def, template))
-      SET_FLAG(func, ref);
-    if(!GET_FLAG(f->base, static))
-      SET_FLAG(func, member);
+    if(tflag(env->class_def, tflag_tmpl))
+      set_fflag(func, fflag_ftmpl);
   }
   return func;
 }
@@ -330,8 +334,6 @@ ANN static Type func_type(const Env env, const Func func) {
   t->name = func->name;
   t->e->owner = env->curr;
   t->e->owner_class = env->class_def;
-  if(GET_FLAG(func, member))
-    t->size += SZ_INT;
   t->e->d.func = func;
   return t;
 }
@@ -349,23 +351,20 @@ ANN2(1,2) static Value func_value(const Env env, const Func f,
     f->next = overload->d.func_ref->next;
     overload->d.func_ref->next = f;
   }
+  if(env->class_def && !GET_FLAG(f->def->base, static)) {
+    t->size += SZ_INT;
+    set_vflag(v, vflag_member);
+  }
   return v;
 }
 
-ANN static m_bool scan2_func_def_builtin(MemPool p, const Func func, const m_str name) {
-  SET_FLAG(func, builtin);
-  SET_FLAG(func->value_ref, builtin);
-  func->code = new_vm_code(p, NULL, func->def->stack_depth, func->flag, name);
-  func->code->native_func = (m_uint)func->def->d.dl_func_ptr;
-  return GW_OK;
-}
-
 ANN2(1, 2) static m_bool scan2_fdef_tmpl(const Env env, const Func_Def f, const Value overload) {
   const m_str name = s_name(f->base->xid);
   const Func func = scan_new_func(env, f, name);
   const Value value = func_value(env, func, overload);
-  SET_FLAG(value, valid | ae_flag_template);
-  SET_FLAG(value->type, func); // the only types with func flag, name could be better
+  set_fflag(func, fflag_tmpl);
+  set_vflag(value, vflag_valid);
+  set_tflag(value->type, tflag_ftmpl); // the only types with func flag, name could be better
   Type type = env->class_def;
   Nspc nspc = env->curr;
   uint i = 0;
@@ -404,11 +403,6 @@ ANN2(1, 2) static m_bool scan2_fdef_tmpl(const Env env, const Func_Def f, const
     nspc_add_func(env->curr, f->base->xid, func);
   } else
     func->vt_index = ++overload->from->offset;
-  if(GET_FLAG(f->base, builtin)) {
-    CHECK_BB(scan2_func_def_builtin(env->gwion->mp, func, func->name))
-    SET_FLAG(func, builtin);
-    SET_FLAG(value, builtin);
-  }
   return GW_OK;
 }
 
@@ -432,10 +426,9 @@ ANN static m_bool scan2_func_def_code(const Env env, const Func_Def f) {
 }
 
 ANN static void scan2_func_def_flag(const Env env, const Func_Def f) {
-  if(!GET_FLAG(f->base, builtin))
-    SET_FLAG(f->base->func, pure);
+  set_fflag(f->base->func, fflag_pure);
   if(f->base->xid == insert_symbol("@dtor"))
-    SET_FLAG(env->class_def, dtor);
+    set_tflag(env->class_def, tflag_dtor);
 }
 
 ANN static m_str func_tmpl_name(const Env env, const Func_Def f) {
@@ -472,8 +465,6 @@ ANN2(1,2,4) static Value func_create(const Env env, const Func_Def f,
   nspc_add_func(env->curr, insert_symbol(func->name), func);
   const Value v = func_value(env, func, overload);
   scan2_func_def_flag(env, f);
-  if(GET_FLAG(f->base, builtin))
-    CHECK_BO(scan2_func_def_builtin(env->gwion->mp, func, func->name))
   nspc_add_value(env->curr, insert_symbol(func->name), v);
   return v;
 }
@@ -497,12 +488,12 @@ ANN2(1,2) m_bool scan2_fdef_std(const Env env, const Func_Def f, const Value ove
     f->base->func = base;
   if(f->base->args)
     CHECK_BB(scan2_args(f))
-  if(!GET_FLAG(f->base, builtin) && f->d.code)
+  if(f->d.code)
     CHECK_BB(scan2_func_def_code(env, f))
   if(!base) {
-    if(GET_FLAG(f->base, op))
+    if(fbflag(f->base, fbflag_op))
       CHECK_BB(scan2_func_def_op(env, f))
-    SET_FLAG(f->base->func->value_ref, valid);
+    set_vflag(f->base->func->value_ref, vflag_valid);
   }
   return GW_OK;
 }
@@ -541,7 +532,7 @@ ANN m_bool scan2_func_def(const Env env, const Func_Def fdef) {
     fdef : scan2_cpy_fdef(env, fdef);
   const m_uint scope = !GET_FLAG(f->base, global) ? env->scope->depth : env_push_global(env);
   f->stack_depth = (env->class_def && !GET_FLAG(f->base, static) && !GET_FLAG(f->base, global)) ? SZ_INT : 0;
-  if(GET_FLAG(f->base, variadic))
+  if(fbflag(f->base, fbflag_variadic))
     f->stack_depth += SZ_INT;
   const m_bool ret = scanx_fdef(env, env, f, (_exp_func)scan2_fdef);
   if(GET_FLAG(f->base, global))
@@ -556,7 +547,7 @@ HANDLE_SECTION_FUNC(scan2, m_bool, Env)
 
 ANN static m_bool scan2_parent(const Env env, const Class_Def cdef) {
   const Type parent = cdef->base.type->e->parent;
-  if(parent->e->def && !GET_FLAG(parent, scan2))
+  if(!tflag(parent, tflag_scan2))
     CHECK_BB(ensure_scan2(env, parent))
   if(cdef->base.ext->array)
     CHECK_BB(scan2_exp(env, cdef->base.ext->array->exp))
@@ -576,10 +567,11 @@ ANN m_bool scan2_class_def(const Env env, const Class_Def cdef) {
   if(tmpl_base(cdef->base.tmpl))
     return GW_OK;
   const Type t = cdef->base.type;
-  if(GET_FLAG(t, scan2))return GW_OK;
-  if(t->e->owner_class && !GET_FLAG(t->e->owner_class, scan2))
+  if(tflag(t, tflag_scan2))
+    return GW_OK;
+  if(t->e->owner_class && !tflag(t->e->owner_class, tflag_scan2))
     CHECK_BB(ensure_scan2(env, t->e->owner_class))
-  SET_FLAG(t, scan2);
+  set_tflag(t, tflag_scan2);
   if(cdef->base.ext)
     CHECK_BB(cdef_parent(env, cdef))
   if(cdef->body)
index c4eaa03127780d107e451af6f890e3d780b77a35..45345b921c0ddc517f85c9323fa617c06c75736e 100644 (file)
@@ -43,8 +43,8 @@ scanx_body(const Env e, const Class_Def c, const _exp_func f, void* d) {
 
 __attribute__((returns_nonnull))
 ANN Type unflag_type(const Type t) {
-  const Type type = !GET_FLAG(t, nonnull) ? t : t->e->parent;
-  return !GET_FLAG(type, force) ? type : type->e->parent;
+  const Type type = !tflag(t, tflag_nonnull) ? t : t->e->parent;
+  return !tflag(type, tflag_force) ? type : type->e->parent;
 }
 
 __attribute__((returns_nonnull))
@@ -53,14 +53,12 @@ ANN Type get_type(const Type t) {
   return unflag_type(type);
 }
 
-ANN m_bool scanx_cdef(const Env env, void* opt, const Class_Def cdef,
+ANN m_bool scanx_cdef(const Env env, void* opt, const Type base,
     const _exp_func f_cdef, const _exp_func f_union) {
-  const Type t = get_type(cdef->base.type);
+  const Type t = get_type(base);
   if(t->e->parent !=  env->gwion->type[et_union])
-     return f_cdef(opt, t->e->def);
-  CHECK_BB(template_push_types(env, t->e->def->base.tmpl))
-  const m_bool ret = f_union(opt, t->e->def->union_def);
-  nspc_pop_type(env->gwion->mp, env->curr);
+     return f_cdef(opt, t->e->cdef);
+  const m_bool ret = f_union(opt, t->e->udef);
   return ret;
 }
 
index 784e298aca2f08c2f9ac361a86d3656859c1b360..84c1dad52a17c0aaf16096f21cd1bed52404bc97 100644 (file)
@@ -14,8 +14,8 @@ ANN void union_pop(const Env env, const Union_Def udef, const m_uint scope) {
     env_pop(env, scope);
 }
 
-ANN void union_flag(const Union_Def udef, const ae_flag flag) {
+ANN void union_flag(const Union_Def udef, const enum tflag flag) {
   const Type type = udef->xid || !udef->type_xid ?
     udef->value->type : udef->type;
-  type->flag |= flag;
+  type->tflag |= flag;
 }
index 3042d0e7b1f32cda7022c4c7018c4df5e87efdd0..dac9f8c8a7517aa6d10939f4752be8197fb9da2a 100644 (file)
@@ -35,8 +35,8 @@ ANN static m_bool push_types(const Env env, const Tmpl *tmpl) {
 ANN static m_bool _template_push(const Env env, const Type t) {
   if(t->e->owner_class)
     CHECK_BB(template_push(env, t->e->owner_class))
-  if(GET_FLAG(t, template))
-    return push_types(env, t->e->def->base.tmpl);
+  if(tflag(t, tflag_tmpl))
+    return push_types(env, t->e->cdef->base.tmpl); // incorrect
   return GW_OK;
 }
 
@@ -69,12 +69,17 @@ static ANN Type scan_func(const Env env, const Type t, const Type_Decl* td) {
   ADD_REF(ret->nspc)
   ret->e->parent = t;
   ret->name = s_name(sym);
-  SET_FLAG(ret, func);
+  set_tflag(ret, tflag_ftmpl);
   nspc_add_type_front(t->e->owner, sym, ret);
+  void* func_ptr = t->e->d.func->def->d.dl_func_ptr;
+  if(vflag(t->e->d.func->value_ref, vflag_builtin))
+    t->e->d.func->def->d.dl_func_ptr = NULL;
   const Func_Def def = cpy_func_def(env->gwion->mp, t->e->d.func->def);
   const Func func = ret->e->d.func = new_func(env->gwion->mp, s_name(sym), def);
   const Value value = new_value(env->gwion->mp, ret, s_name(sym));
   func->flag = def->base->flag;
+  if(vflag(t->e->d.func->value_ref, vflag_member))
+    set_vflag(value, vflag_member);
   value->d.func_ref = func;
   value->from->owner = t->e->owner;
   value->from->owner_class = t->e->owner_class;
@@ -82,6 +87,10 @@ static ANN Type scan_func(const Env env, const Type t, const Type_Decl* td) {
   func->def->base->tmpl = mk_tmpl(env, t->e->d.func->def->base->tmpl, td->types);
   def->base->func = func;
   nspc_add_value_front(t->e->owner, sym, value);
+  if(vflag(t->e->d.func->value_ref, vflag_builtin)) {
+    builtin_func(env->gwion->mp, func, func_ptr);
+    t->e->d.func->def->d.dl_func_ptr = func_ptr;
+  }
   return ret;
 }
 
@@ -93,8 +102,8 @@ static ANN Type maybe_func(const Env env, const Type t, const Type_Decl* td) {
 }
 
 ANN Type _scan_type(const Env env, const Type t, Type_Decl* td) {
-  if(GET_FLAG(t, template) && isa(t, env->gwion->type[et_function]) < 0) {
-    if(GET_FLAG(t, ref) || (GET_FLAG(t, unary) && !td->types))
+  if(tflag(t, tflag_tmpl) && isa(t, env->gwion->type[et_function]) < 0) {
+    if(tflag(t, tflag_ctmpl) || (tflag(t, tflag_ntmpl) && !td->types))
       return t;
     struct TemplateScan ts = { .t=t, .td=td };
     struct Op_Import opi = { .op=insert_symbol("@scan"), .lhs=t, .data=(uintptr_t)&ts, .pos=td_pos(td), .op_type=op_scan };
@@ -118,7 +127,7 @@ ANN Type scan_type(const Env env, const Type t, Type_Decl* td) {
     if(!owner->nspc)
       ERR_O(td_pos(td), "type '%s' has no namespace", owner->name)
     struct EnvSet es = { .env=env, .data=env,
-      .scope=env->scope->depth, .flag=ae_flag_none };
+      .scope=env->scope->depth, .flag=tflag_none };
     envset_push(&es, owner, owner->nspc);
     (void)env_push(env, owner, owner->nspc);// TODO: is this needed?
     const Type ret = scan_type(env, t, td->next);
index deac0f86e5c101cc66328bbf7f277ed7aa8337b9..6e37aab56a1d8a4a6546d16fc977759eb2a589a8 100644 (file)
@@ -58,11 +58,11 @@ ANN m_bool traverse_type_def(const Env env, const Type_Def def) {
 
 ANN m_bool traverse_class_def(const Env env, const Class_Def def) {
   const Type t = def->base.type;
-  if(!GET_FLAG(t, scan1))
+  if(!tflag(t, tflag_scan1))
     CHECK_BB(scan1_class_def(env, def))
-  if(!GET_FLAG(t, scan2))
+  if(!tflag(t, tflag_scan2))
     CHECK_BB(scan2_class_def(env, def))
-  if(!GET_FLAG(t, valid))
+  if(!tflag(t, tflag_check))
     return check_class_def(env, def);
   return GW_OK;
 }
index 203dbee3e4a5eec719355d09976ba1f1a38874f0..d6f0885312bd0b34851bfea2701a82e875125aac 100644 (file)
@@ -59,13 +59,13 @@ ANN static void prepare_call(const VM_Shred shred, const m_uint offset) {
 ANN void gack(const VM_Shred shred, const m_uint offset) {
   const Type t = *(Type*)shred->reg;
   const VM_Code code = get_gack(t)->e->gack;
-  if(GET_FLAG(code, builtin)) {
+  if(code->builtin) {
     const m_uint sz = *(m_uint*)(shred->reg + SZ_INT);
     ((f_gack)code->native_func)(t, (shred->reg - sz), shred);
     POP_REG(shred, sz);
   } else {
     prepare_call(shred, offset);
-    if(GET_FLAG(t, struct))
+    if(tflag(t, tflag_struct))
       *(void**)(shred->mem) = (void*)(shred->reg - t->size);
     else
       *(M_Object*)(shred->mem) = *(M_Object*)(shred->reg - SZ_INT);
index 3027e6ec539e5120489cd8d23cdcfb553b4c2777..4d3432322746db3236e9eef9cf6f7cf20445b99c 100644 (file)
@@ -612,7 +612,7 @@ setcode:
 PRAGMA_PUSH()
   reg -= SZ_INT;
   a.code = *(VM_Code*)reg;
-  if(!GET_FLAG((VM_Code)a.code, builtin)) {
+  if(!a.code->builtin) {
     register const m_uint push = *(m_uint*)(reg + SZ_INT) + *(m_uint*)(mem-SZ_INT);
     mem += push;
     *(m_uint*)  mem = push;mem += SZ_INT;
index f376fe6525621fcd41d5fceb7b48675f78cdf3b4..8c0b8c5252556972c2eb8d977e1ebeb574a169e7 100644 (file)
@@ -29,7 +29,7 @@ ANN static void _free_code_instr(const Vector v, const Gwion gwion) {
 ANN static void free_vm_code(VM_Code a, Gwion gwion) {
   if(a->memoize)
     memoize_end(gwion->mp, a->memoize);
-  if(!GET_FLAG(a, builtin)) {
+  if(!a->builtin) {
     _mp_free(gwion->mp, vector_size(a->instr) * SZ_INT, a->bytecode);
     _free_code_instr(a->instr, gwion);
   }
@@ -58,7 +58,7 @@ ANN static m_bit* tobytecode(MemPool p, const VM_Code code) {
 
 
 VM_Code new_vm_code(MemPool p, const Vector instr, const m_uint stack_depth,
-    const ae_flag flag, const m_str name) {
+    const int builtin, const m_str name) {
   VM_Code code           = mp_calloc(p, VM_Code);
   if(instr) {
     code->instr            = vector_copy(p, instr);
@@ -66,7 +66,7 @@ VM_Code new_vm_code(MemPool p, const Vector instr, const m_uint stack_depth,
   }
   code->name             = mstrdup(p, name);
   code->stack_depth      = stack_depth;
-  code->flag = flag;
+  code->builtin = builtin;
   code->ref = new_refcount(p, free_vm_code);
   return code;
 }
diff --git a/tests/error/final_func.gw b/tests/error/final_func.gw
new file mode 100644 (file)
index 0000000..581632f
--- /dev/null
@@ -0,0 +1,9 @@
+#! [contains] override final
+class C {
+  fun final void test() { <<< "final" >>>;}
+}
+
+class D extends C {
+  fun void test() { <<< "final" >>>;}
+}
+var D d;
diff --git a/tests/error/final_inherit.gw b/tests/error/final_inherit.gw
new file mode 100644 (file)
index 0000000..f021b02
--- /dev/null
@@ -0,0 +1,4 @@
+#! [contains] inherit from final parent
+class final C {}
+
+class D extends C {}
diff --git a/tests/error/must_abstract0.gw b/tests/error/must_abstract0.gw
new file mode 100644 (file)
index 0000000..88b7552
--- /dev/null
@@ -0,0 +1,3 @@
+class C {
+  fun abstract void test(int i);
+}
diff --git a/tests/error/must_abstract1.gw b/tests/error/must_abstract1.gw
new file mode 100644 (file)
index 0000000..121854a
--- /dev/null
@@ -0,0 +1,6 @@
+#! [contains] must be declared 'abstract'
+class abstract C {
+  fun abstract void test(int i);
+}
+
+class D extends C {}
diff --git a/tests/error/no_inherit.gw b/tests/error/no_inherit.gw
deleted file mode 100644 (file)
index d37f627..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#! [contains] can't inherit
-class C extends TypedFork:[int] {
-
-}
-
-var C c;
-c.exit();
index 9164468b6680758e25cee75908c6cda24c901827..0178f87935bae8f6f4f903caa431347ed9b58b64 100644 (file)
@@ -2,7 +2,7 @@ fun int test() {
   return 12;
 }
 
-fork test() @=> ref TypedFork:[int] sh;
+fork test() @=> ref auto sh;
 <<< typeof(sh) >>>;
 sh.ev => now;
 <<< sh.retval >>>;
index d7ea42972276a0406a325e74accec5da689186d2..e8124a8a3e3354bc4d99807a325ed2c595310197 100644 (file)
@@ -28,9 +28,9 @@ GWION_IMPORT(class_template) {
   GWI_OB(gwi_class_ini(gwi, ":[A,B]ClassTemplate", NULL))
   gwi_class_xtor(gwi, class_template_ctor, NULL);
     GWI_BB(gwi_item_ini(gwi, "A[]", "key"))
-    GWI_BB((o_map_key = gwi_item_end(gwi, ae_flag_member | ae_flag_template, NULL)))
+    GWI_BB((o_map_key = gwi_item_end(gwi, ae_flag_none, NULL)))
     GWI_BB(gwi_item_ini(gwi, "B[]", "value"))
-    GWI_BB((o_map_value = gwi_item_end(gwi, ae_flag_member, NULL)))
+    GWI_BB((o_map_value = gwi_item_end(gwi, ae_flag_none, NULL)))
    GWI_BB(gwi_func_ini(gwi, "int", ":[C,D]test"))
    GWI_BB(gwi_func_end(gwi, (f_xfun)1, ae_flag_none))
 
index fdd14dea759e658fbe55a665bb0d620709a2215e..0ef547e3899c8a28abe89a32ddd7a875eb009ff1 100644 (file)
@@ -17,9 +17,9 @@ static m_int o_map_value;
 GWION_IMPORT(class_template) {
   GWI_OB(gwi_class_ini(gwi, "ClassTemplate:[A,B]", NULL))
     GWI_BB(gwi_item_ini(gwi, "A[]", "key"))
-    GWI_BB((o_map_key = gwi_item_end(gwi, ae_flag_member | ae_flag_template, NULL)))
+    GWI_BB((o_map_key = gwi_item_end(gwi, ae_flag_none, NULL)))
     GWI_BB(gwi_item_ini(gwi, "B[]", "value"))
-    GWI_BB((o_map_value = gwi_item_end(gwi, ae_flag_member, NULL)))
+    GWI_BB((o_map_value = gwi_item_end(gwi, ae_flag_none, NULL)))
    GWI_BB(gwi_func_ini(gwi, "int", "test:[C,D]"))
    GWI_BB(gwi_func_end(gwi, (f_xfun)1, ae_flag_none))
 
index 4d398a6520a5a08897f60e6d715289a80506b119..a34b3e2f7ac0d4064f6e87508542ced42b3d3098 100644 (file)
@@ -42,7 +42,8 @@ GWION_IMPORT(variadic test) {
   GWI_OB(gwi_class_ini(gwi, "Variadic", NULL))
   GWI_BB(gwi_func_ini(gwi, "void", "member"))
   GWI_BB(gwi_func_arg(gwi, "string", "format"))
-  GWI_BB(gwi_func_end(gwi, m_variadic, ae_flag_variadic))
+  GWI_BB(gwi_func_arg(gwi, "does not matter", "..."))
+  GWI_BB(gwi_func_end(gwi, m_variadic, ae_flag_none))
   GWI_BB(gwi_func_ini(gwi, "void", "test"))
   GWI_BB(gwi_func_end(gwi, m_test, ae_flag_none))
   GWI_BB(gwi_class_end(gwi))