From: fennecdjay Date: Mon, 2 Nov 2020 11:45:02 +0000 (+0100) Subject: Fix Flags X-Git-Tag: nightly~1219 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=73b500fff343bcb33e7256f7dbac6a3d9b5a9b01;p=gwion.git Fix Flags --- diff --git a/include/env/envset.h b/include/env/envset.h index 1e11c9b9..c9838df6 100644 --- a/include/env/envset.h +++ b/include/env/envset.h @@ -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; }; diff --git a/include/env/func.h b/include/env/func.h index 5375b0a6..fa2d3ea2 100644 --- a/include/env/func.h +++ b/include/env/func.h @@ -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(ff); +} + +static inline void unset_fflag(const Func f, const enum fflag flag) { + const auto ff = f->fflag & ~flag; + f->fflag = static_cast(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 diff --git a/include/env/type.h b/include/env/type.h index 0ff7e13f..dd8b49bb 100644 --- a/include/env/type.h +++ b/include/env/type.h @@ -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(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 { diff --git a/include/env/value.h b/include/env/value.h index 2f592d39..00f98d37 100644 --- a/include/env/value.h +++ b/include/env/value.h @@ -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(ff); +} +#endif + ANEW ANN Value new_value(MemPool p, const Type type, const m_str name); ANN void valuefrom(const Env, struct ValueFrom_*); #endif diff --git a/include/import/checker.h b/include/import/checker.h index 3b1cc6cc..5ef1d61a 100644 --- a/include/import/checker.h +++ b/include/import/checker.h @@ -31,6 +31,7 @@ typedef struct ImportCK { // name_checker ? ID_List curr;// enum }; ae_flag flag; // ???? + uint variadic; enum importck_type type; } ImportCK; diff --git a/include/instr.h b/include/instr.h index fa9b4852..5e260639 100644 --- a/include/instr.h +++ b/include/instr.h @@ -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); diff --git a/include/parse.h b/include/parse.h index 62889984..394a5314 100644 --- a/include/parse.h +++ b/include/parse.h @@ -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); diff --git a/include/vm.h b/include/vm.h index cd7d7a10..7eefb167 100644 --- a/include/vm.h +++ b/include/vm.h @@ -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 index 00000000..6c5906d1 Binary files /dev/null and b/po/fr/gwion.mo differ diff --git a/src/clean.c b/src/clean.c index a3bc2dbf..b037f541 100644 --- a/src/clean.c +++ b/src/clean.c @@ -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; diff --git a/src/emit/emit.c b/src/emit/emit.c index 27921731..42234bb8 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -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); diff --git a/src/emit/emitter.c b/src/emit/emitter.c index 6520d9fa..142e1b21 100644 --- a/src/emit/emitter.c +++ b/src/emit/emitter.c @@ -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; } diff --git a/src/env/env.c b/src/env/env.c index e5360419..0dcda890 100644 --- a/src/env/env.c +++ b/src/env/env.c @@ -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 ? diff --git a/src/env/env_utils.c b/src/env/env_utils.c index ce6ab3d3..a3661a45 100644 --- a/src/env/env_utils.c +++ b/src/env/env_utils.c @@ -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; } diff --git a/src/env/envset.c b/src/env/envset.c index 26efc742..5bfa468c 100644 --- a/src/env/envset.c +++ b/src/env/envset.c @@ -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; diff --git a/src/env/func.c b/src/env/func.c index a1bda102..05944b08 100644 --- a/src/env/func.c +++ b/src/env/func.c @@ -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; +} diff --git a/src/env/nspc.c b/src/env/nspc.c index 27743ccd..b0c6cdc8 100644 --- a/src/env/nspc.c +++ b/src/env/nspc.c @@ -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); } diff --git a/src/env/type.c b/src/env/type.c index bc6e3126..61c1d508 100644 --- a/src/env/type.c +++ b/src/env/type.c @@ -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; } } diff --git a/src/env/type_special.c b/src/env/type_special.c index 9a7c8143..668667ec 100644 --- a/src/env/type_special.c +++ b/src/env/type_special.c @@ -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; diff --git a/src/env/value.c b/src/env/value.c index 13cfdd6c..217b399b 100644 --- a/src/env/value.c +++ b/src/env/value.c @@ -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) diff --git a/src/gwion.c b/src/gwion.c index dfd4363a..99036808 100644 --- a/src/gwion.c +++ b/src/gwion.c @@ -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); } diff --git a/src/import/import_cdef.c b/src/import/import_cdef.c index e04f8006..aaa39879 100644 --- a/src/import/import_cdef.c +++ b/src/import/import_cdef.c @@ -17,21 +17,21 @@ #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); } diff --git a/src/import/import_enum.c b/src/import/import_enum.c index ee398e37..1607e576 100644 --- a/src/import/import_enum.c +++ b/src/import/import_enum.c @@ -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); diff --git a/src/import/import_fdef.c b/src/import/import_fdef.c index 9fdf808c..cb4f5001 100644 --- a/src/import/import_fdef.c +++ b/src/import/import_fdef.c @@ -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) diff --git a/src/import/import_internals.c b/src/import/import_internals.c index 8f0f85f8..659c4978 100644 --- a/src/import/import_internals.c +++ b/src/import/import_internals.c @@ -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 diff --git a/src/import/import_item.c b/src/import/import_item.c index 5d5ed543..3639445f 100644 --- a/src/import/import_item.c +++ b/src/import/import_item.c @@ -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); diff --git a/src/import/import_special.c b/src/import/import_special.c index f4f2e414..36fd2967 100644 --- a/src/import/import_special.c +++ b/src/import/import_special.c @@ -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; } diff --git a/src/import/import_udef.c b/src/import/import_udef.c index 73f8f061..aaa603ff 100644 --- a/src/import/import_udef.c +++ b/src/import/import_udef.c @@ -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; diff --git a/src/lib/engine.c b/src/lib/engine.c index 35d3b454..3a7c36f0 100644 --- a/src/lib/engine.c +++ b/src/lib/engine.c @@ -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")) diff --git a/src/lib/event.c b/src/lib/event.c index 2f56dd16..2c3818f4 100644 --- a/src/lib/event.c +++ b/src/lib/event.c @@ -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")) diff --git a/src/lib/instr.c b/src/lib/instr.c index 587b1fa4..b1e9ef76 100644 --- a/src/lib/instr.c +++ b/src/lib/instr.c @@ -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; diff --git a/src/lib/lib_func.c b/src/lib/lib_func.c index 526c1df2..2f0d97be 100644 --- a/src/lib/lib_func.c +++ b/src/lib/lib_func.c @@ -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) { diff --git a/src/lib/object.c b/src/lib/object.c index b8a2bf32..d434b41d 100644 --- a/src/lib/object.c +++ b/src/lib/object.c @@ -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; diff --git a/src/lib/object_op.c b/src/lib/object_op.c index 3b15c4ee..66a8b70d 100644 --- a/src/lib/object_op.c +++ b/src/lib/object_op.c @@ -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)); diff --git a/src/lib/ptr.c b/src/lib/ptr.c index 2012bf5b..fa4378dd 100644 --- a/src/lib/ptr.c +++ b/src/lib/ptr.c @@ -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)) diff --git a/src/lib/shred.c b/src/lib/shred.c index 9dc20c4b..aeac5487 100644 --- a/src/lib/shred.c +++ b/src/lib/shred.c @@ -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; } diff --git a/src/lib/ugen.c b/src/lib/ugen.c index ff9231a1..a948cc8e 100644 --- a/src/lib/ugen.c +++ b/src/lib/ugen.c @@ -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")) diff --git a/src/lib/vararg.c b/src/lib/vararg.c index 2b748cd2..2a3b13b9 100644 --- a/src/lib/vararg.c +++ b/src/lib/vararg.c @@ -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")) } diff --git a/src/parse/check.c b/src/parse/check.c index 36200341..4d0650fa 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -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; } diff --git a/src/parse/func_operator.c b/src/parse/func_operator.c index 75af7510..2d794a8d 100644 --- a/src/parse/func_operator.c +++ b/src/parse/func_operator.c @@ -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 : diff --git a/src/parse/func_resolve_tmpl.c b/src/parse/func_resolve_tmpl.c index bb5a6063..ca3c573c 100644 --- a/src/parse/func_resolve_tmpl.c +++ b/src/parse/func_resolve_tmpl.c @@ -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); diff --git a/src/parse/operator.c b/src/parse/operator.c index 5b89942c..fa3c27b7 100644 --- a/src/parse/operator.c +++ b/src/parse/operator.c @@ -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); } diff --git a/src/parse/scan0.c b/src/parse/scan0.c index 6047da5f..6317cba4 100644 --- a/src/parse/scan0.c +++ b/src/parse/scan0.c @@ -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) { diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 350c9239..f52c2d01 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -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) diff --git a/src/parse/scan2.c b/src/parse/scan2.c index 2bb5b4a8..cfdbb07b 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -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) diff --git a/src/parse/scanx.c b/src/parse/scanx.c index c4eaa031..45345b92 100644 --- a/src/parse/scanx.c +++ b/src/parse/scanx.c @@ -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; } diff --git a/src/parse/stage.c b/src/parse/stage.c index 784e298a..84c1dad5 100644 --- a/src/parse/stage.c +++ b/src/parse/stage.c @@ -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; } diff --git a/src/parse/template.c b/src/parse/template.c index 3042d0e7..dac9f8c8 100644 --- a/src/parse/template.c +++ b/src/parse/template.c @@ -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); diff --git a/src/parse/traverse.c b/src/parse/traverse.c index deac0f86..6e37aab5 100644 --- a/src/parse/traverse.c +++ b/src/parse/traverse.c @@ -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; } diff --git a/src/vm/gack.c b/src/vm/gack.c index 203dbee3..d6f08853 100644 --- a/src/vm/gack.c +++ b/src/vm/gack.c @@ -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); diff --git a/src/vm/vm.c b/src/vm/vm.c index 3027e6ec..4d343232 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -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; diff --git a/src/vm/vm_code.c b/src/vm/vm_code.c index f376fe65..8c0b8c52 100644 --- a/src/vm/vm_code.c +++ b/src/vm/vm_code.c @@ -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 index 00000000..581632ff --- /dev/null +++ b/tests/error/final_func.gw @@ -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 index 00000000..f021b02b --- /dev/null +++ b/tests/error/final_inherit.gw @@ -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 index 00000000..88b75523 --- /dev/null +++ b/tests/error/must_abstract0.gw @@ -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 index 00000000..121854aa --- /dev/null +++ b/tests/error/must_abstract1.gw @@ -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 index d37f6278..00000000 --- a/tests/error/no_inherit.gw +++ /dev/null @@ -1,7 +0,0 @@ -#! [contains] can't inherit -class C extends TypedFork:[int] { - -} - -var C c; -c.exit(); diff --git a/tests/fork/fork_call.gw b/tests/fork/fork_call.gw index 9164468b..0178f879 100644 --- a/tests/fork/fork_call.gw +++ b/tests/fork/fork_call.gw @@ -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 >>>; diff --git a/tests/import/class_template.c b/tests/import/class_template.c index d7ea4297..e8124a8a 100644 --- a/tests/import/class_template.c +++ b/tests/import/class_template.c @@ -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)) diff --git a/tests/import/class_template_invalid.c b/tests/import/class_template_invalid.c index fdd14dea..0ef547e3 100644 --- a/tests/import/class_template_invalid.c +++ b/tests/import/class_template_invalid.c @@ -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)) diff --git a/tests/import/variadic.c b/tests/import/variadic.c index 4d398a65..a34b3e2f 100644 --- a/tests/import/variadic.c +++ b/tests/import/variadic.c @@ -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))