From: Jérémie Astor Date: Tue, 19 Jan 2021 14:58:29 +0000 (+0100) Subject: :art: Arrat:[T] X-Git-Tag: nightly~1039 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=34533009a0f70779ffcf136e7f10c8c026e305cd;p=gwion.git :art: Arrat:[T] --- diff --git a/ast b/ast index 21e5a7e3..2b7ad3f0 160000 --- a/ast +++ b/ast @@ -1 +1 @@ -Subproject commit 21e5a7e33d5c13c56f61322c7b40fa2c6603f3b6 +Subproject commit 2b7ad3f0e5b241640e7be0576332e3fec0296662 diff --git a/include/emit.h b/include/emit.h index a144705d..00a88035 100644 --- a/include/emit.h +++ b/include/emit.h @@ -19,7 +19,8 @@ struct EmitterInfo_ { char *escape; VM_Code (*emit_code)(const Emitter); VM_Code code; - m_bool memoize; + uint memoize; +// uint unroll; }; struct Emitter_ { diff --git a/include/env/nspc.h b/include/env/nspc.h index 1cf9b65a..3ea6d7e0 100644 --- a/include/env/nspc.h +++ b/include/env/nspc.h @@ -73,8 +73,8 @@ ANN void did_you_mean_type(const Type, const char*); #define did_you_mean_type(a, b) if(strlen(b) < DID_YOU_MEAN_LIMIT) did_you_mean_type(a,b); ANN static inline void nspc_allocdata(MemPool mp, const Nspc nspc) { - if(nspc->info->class_data_size) -// nspc->info->class_data = (m_bit*)xcalloc(1, nspc->info->class_data_size); + if(nspc->info->class_data_size) { nspc->info->class_data = (m_bit*)mp_calloc2(mp, nspc->info->class_data_size); + } } #endif diff --git a/include/env/type.h b/include/env/type.h index 68bbec1f..00283758 100644 --- a/include/env/type.h +++ b/include/env/type.h @@ -9,8 +9,8 @@ struct TypeInfo_ { Union_Def udef; Class_Def cdef; Func func; - Type base_type; }; + Type base_type; struct TupleForm_* tuple; struct VM_Code_ *gack; struct Context_ *ctx; @@ -57,8 +57,6 @@ ANN m_bool isa(const Type, const Type) __attribute__((pure)); ANN m_bool isres(const Env, const Symbol, const loc_t pos); ANN Type array_type(const Env, const Type, const m_uint); ANN Type find_common_anc(const Type, const Type) __attribute__((pure)); -ANN m_uint id_list_len(ID_List); -ANN void type_path(const m_str, const ID_List); ANN Type typedef_base(Type) __attribute__((pure)); ANN Type array_base(Type) __attribute__((pure)); ANN m_bool type_ref(Type) __attribute__((pure)); @@ -66,6 +64,10 @@ ANN Type actual_type(const struct Gwion_* gwion, const Type t); ANN static inline m_uint env_push_type(const Env env, const Type type) { return env_push(env, type, type->nspc); } ANN m_bool is_fptr(const struct Gwion_*, const Type t); ANN m_bool is_class(const struct Gwion_*, const Type t); +ANN __attribute__((returns_nonnull)) +static inline Type _class_base(Type t) { + return t->info->base_type; +} ANN m_uint get_depth(const Type type); ANN void inherit(const Type); @@ -77,13 +79,10 @@ ANN static inline Type get_gack(Type t) { return t; // unreachable } -__attribute__((returns_nonnull)) -ANN Type get_type(const Type t); - typedef enum { et_void, et_int, et_bool, et_char, et_float, et_error, et_compound, et_object, et_shred, et_fork, et_event, et_ugen, et_string, et_ptr, et_array, et_gack, - et_function, et_fptr, et_vararg, et_lambda, et_class, et_union, et_undefined, et_auto, et_none, + et_function, et_fptr, et_vararg, et_lambda, et_class, et_union, et_auto, et_none, MAX_TYPE } type_enum; #endif diff --git a/include/env/value.h b/include/env/value.h index 6d845011..066cbbd7 100644 --- a/include/env/value.h +++ b/include/env/value.h @@ -19,13 +19,13 @@ enum vflag { // vflag_used = 1 << 3 } __attribute__((packed)); -union __attribute__((transparent_union)) value_data { +union value_data { m_uint num; m_float fnum; m_uint* ptr; struct M_Object_ *obj; Func func_ref; -} __attribute__((transparent_union)); +}; struct Value_ { Type type; diff --git a/include/gwi.h b/include/gwi.h index 08dd3f74..fbac94e4 100644 --- a/include/gwi.h +++ b/include/gwi.h @@ -6,6 +6,7 @@ struct Gwi_ { Ast body; struct ImportCK *ck; struct OperCK *oper; // _misc + uint tmpls; loc_t loc; }; diff --git a/include/operator.h b/include/operator.h index 7f08b7fd..1ab598f0 100644 --- a/include/operator.h +++ b/include/operator.h @@ -65,10 +65,8 @@ ANN static inline void operator_resume(struct Op_Import *opi) { } ANN static inline void set_decl_ref(const Exp e) { - if(e->exp_type == ae_exp_decl) { - SET_FLAG(e->d.exp_decl.td, late); + if(e->exp_type == ae_exp_decl) SET_FLAG(e->d.exp_decl.list->self->value, late); - } } diff --git a/src/emit/emit.c b/src/emit/emit.c index 2cc84734..d4b3924e 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -294,10 +294,10 @@ ANEW ANN static ArrayInfo* new_arrayinfo(const Emitter emit, const Type t) { const Type base = array_base(t); ArrayInfo* info = mp_calloc(emit->gwion->mp, ArrayInfo); vector_init(&info->type); - for(m_uint i = 1; i < t->array_depth; ++i) + info->depth = get_depth(t); + for(long i = 1; i < info->depth; ++i) vector_add(&info->type, (vtype)array_type(emit->env, base, i)); vector_add(&info->type, (vtype)t); - info->depth = !tflag(t, tflag_typedef) ? t->array_depth : t->info->parent->array_depth; info->base = base; return info; } @@ -311,7 +311,7 @@ ANN static inline void arrayinfo_ctor(const Emitter emit, ArrayInfo *info) { } ANN2(1,2) static ArrayInfo* emit_array_extend_inner(const Emitter emit, const Type t, const Exp e, const uint is_ref) { - CHECK_BO(extend_indices(emit, e, t->array_depth)) + CHECK_BO(extend_indices(emit, e, get_depth(t))) ArrayInfo* info = new_arrayinfo(emit, t); const Instr alloc = emit_add_instr(emit, ArrayAlloc); alloc->m_val = (m_uint)info; @@ -501,7 +501,7 @@ ANN static m_bool emit_prim_array(const Emitter emit, const Array_Sub *data) { regseti(emit, count); const Instr instr = emit_add_instr(emit, ArrayInit); instr->m_val = (m_uint)type; - instr->m_val2 = type->array_depth == 1 ? array_base(type)->size : SZ_INT; + instr->m_val2 = array_base(type)->size; emit_gc(emit, -SZ_INT); emit_notpure(emit); return GW_OK; @@ -806,12 +806,11 @@ ANN static m_bool emit_class_def(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) { - const Type base = get_type(t); - if(tflag(base, tflag_emit) || !(tflag(base, tflag_cdef) || tflag(base, tflag_udef))) + if(tflag(t, tflag_emit) || !(tflag(t, tflag_cdef) || tflag(t, tflag_udef))) return GW_OK;//clean callers struct EnvSet es = { .env=emit->env, .data=emit, .func=(_exp_func)emit_cdef, .scope=emit->env->scope->depth, .flag=tflag_emit }; - return envset_run(&es, base); + return envset_run(&es, t); } ANN static m_bool emit_decl(const Emitter emit, const Exp_Decl* decl) { @@ -828,15 +827,15 @@ ANN static m_bool emit_decl(const Emitter emit, const Exp_Decl* decl) { CHECK_BB(emit_exp_decl_non_static(emit, decl, list->self, r, var)) else CHECK_BB(emit_exp_decl_global(emit, decl, list->self, r, var)) - if(GET_FLAG(v->type, abstract) && !GET_FLAG(decl->td, late) && GET_FLAG(v, late)) { - env_warn(emit->env, decl->td->pos, _("Type '%s' is abstract, use late"), v->type->name); + if(GET_FLAG(array_base(v->type), abstract) && !GET_FLAG(decl->td, late) && GET_FLAG(v, late)) { + env_warn(emit->env, decl->td->pos, _("Type '%s' is abstract, use late"), v->type->name); } } while((list = list->next)); return GW_OK; } ANN /*static */m_bool emit_exp_decl(const Emitter emit, const Exp_Decl* decl) { - const Type t = get_type(decl->type); + const Type t = decl->type; 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); @@ -1332,7 +1331,7 @@ ANN m_bool 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)->type; - const Type base = get_type(actual_type(emit->gwion, t)); + const Type base = actual_type(emit->gwion, t); CHECK_BB(ensure_emit(emit, base)) // no pos ? struct Op_Import opi = { .op=unary->op, .data=(uintptr_t)unary, .op_type=op_unary }; @@ -1435,7 +1434,7 @@ ANN static m_bool emit_exp_lambda(const Emitter emit, const Exp_Lambda * lambda) } ANN static m_bool emit_exp_td(const Emitter emit, Type_Decl* td) { - regpushi(emit, (m_uint)exp_self(td)->type->info->base_type); + regpushi(emit, (m_uint)_class_base(exp_self(td)->type)); return GW_OK; } @@ -1450,11 +1449,10 @@ ANN2(1) /*static */m_bool emit_exp(const Emitter emit, /* const */Exp e) { CHECK_BB(emit_implicit_cast(emit, exp, exp->cast_to)) if(isa(e->type, emit->gwion->type[et_object]) > 0 && (e->cast_to ? isa(e->cast_to, emit->gwion->type[et_object]) > 0 : 1) && - e->exp_type == ae_exp_decl && GET_FLAG(e->d.exp_decl.td, late) && !exp_getvar(e)) { + e->exp_type == ae_exp_decl && GET_FLAG(e->d.exp_decl.td, late) && exp_getuse(e) && !exp_getvar(e)) { const Instr instr = emit_add_instr(emit, GWOP_EXCEPT); instr->m_val = -SZ_INT; } - } while((exp = exp->next)); return GW_OK; } diff --git a/src/env/type.c b/src/env/type.c index ff93ad87..cb09c10e 100644 --- a/src/env/type.c +++ b/src/env/type.c @@ -45,7 +45,6 @@ ANN Type type_copy(MemPool p, const Type type) { a->info->owner = type->info->owner; a->info->owner_class = type->info->owner_class; a->size = type->size; - a->info->base_type = type->info->base_type; a->array_depth = type->array_depth; a->info->gack = type->info->gack; return a; @@ -79,14 +78,16 @@ ANN Type typedef_base(Type t) { ANN Type array_base(Type type) { const Type t = typedef_base(type); - return t->array_depth ? t->info->base_type : t; +// return t->array_depth ? t->info->base_type : t; + return t->array_depth ? array_base(t->info->base_type) : t; } -ANN static Symbol array_sym(const Env env, const Type src, const m_uint depth) { - size_t len = strlen(src->name); +ANN /*static */Symbol array_sym(const Env env, const Type src, const m_uint depth) { + const Type t = array_base(src); + size_t len = strlen(t->name); char name[len + 2* depth + 1]; - strcpy(name, src->name); - m_uint i = depth + 1; + strcpy(name, t->name); + m_uint i = src->array_depth + depth + 1; while(--i) { strcpy(name+len, "[]"); len += 2; @@ -94,29 +95,19 @@ ANN static Symbol array_sym(const Env env, const Type src, const m_uint depth) { return insert_symbol(name); } +#include "instr.h" +#include "operator.h" +#include "import.h" ANN Type array_type(const Env env, const Type src, const m_uint depth) { const Symbol sym = array_sym(env, src, depth); const Type type = nspc_lookup_type1(src->info->owner, sym); if(type) return type; - const Type parent = src->info->parent ? - array_type(env, src->info->parent, depth) : env->gwion->type[et_array]; - const Type t = new_type(env->gwion->mp, s_name(sym), parent); - t->array_depth = depth + src->array_depth; - t->info->base_type = array_base(src) ?: src; - t->info->owner = src->info->owner; - if(depth > 1 || isa(src, env->gwion->type[et_compound]) > 0) { - t->nspc = new_nspc(env->gwion->mp, s_name(sym)); - 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 || !tflag(src, tflag_struct)) ? - object_release : struct_release; - } else - nspc_addref((t->nspc = parent->nspc)); - mk_class(env, t); - nspc_add_type_front(src->info->owner, sym, t); - return t; + const size_t tdepth = depth + src->array_depth; + const Type base = tdepth > 1 ? array_type(env, src, tdepth-1) : src; + struct TemplateScan ts = { .t=base, /*.td=td*/ }; + struct Op_Import opi = { .op=insert_symbol("@scan"), .lhs=env->gwion->type[et_array], .data=(uintptr_t)&ts, .op_type=op_scan }; + return op_check(env, &opi); } ANN m_bool type_ref(Type t) { diff --git a/src/import/import_cdef.c b/src/import/import_cdef.c index 8d936416..6ca93ef0 100644 --- a/src/import/import_cdef.c +++ b/src/import/import_cdef.c @@ -36,6 +36,16 @@ ANN2(1,2) static void import_class_ini(const Env env, const Type t) { env_push_type(env, t); } +ANN2(1) void add_template(const Env env, const Type t) { + Tmpl* tmpl = t->info->cdef->base.tmpl; + if(tmpl) { + nspc_push_type(env->gwion->mp, env->curr);// + ID_List il = tmpl->list; + do nspc_add_type(env->curr, il->xid, env->gwion->type[et_auto]); + while((il = il->next)); + } +} + 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) @@ -51,6 +61,10 @@ ANN static inline void gwi_type_flag(const Type t) { ANN static Type type_finish(const Gwi gwi, const Type t) { gwi_add_type(gwi, t); import_class_ini(gwi->gwion->env, t); + if(t->info->cdef && t->info->cdef->base.tmpl) { + gwi->tmpls++; + add_template(gwi->gwion->env, t); + } return t; } @@ -108,6 +122,11 @@ ANN m_int gwi_class_end(const Gwi gwi) { if(!gwi->gwion->env->class_def) GWI_ERR_B(_("import: too many class_end called.")) nspc_allocdata(gwi->gwion->mp, gwi->gwion->env->class_def->nspc); + const Type t = gwi->gwion->env->class_def; + if(tflag(t, tflag_tmpl)) { + --gwi->tmpls; + nspc_pop_type(gwi->gwion->mp, gwi->gwion->env->curr); + } env_pop(gwi->gwion->env, 0); return GW_OK; } diff --git a/src/import/import_checker.c b/src/import/import_checker.c index 1fbfc6b8..3e46de79 100644 --- a/src/import/import_checker.c +++ b/src/import/import_checker.c @@ -245,8 +245,10 @@ ANN static m_bool td_info_run(const Env env, struct td_info* info) { ANEW ANN m_str type2str(const Gwion gwion, const Type t, const loc_t pos NUSED) { GwText text = { .mp=gwion->mp }; - if(t->info->owner_class) + if(t->info->owner_class) { td_fullname(gwion->env, &text, t->info->owner_class); + text_add(&text, "."); + } text_add(&text, t->name); return text.str; } diff --git a/src/import/import_fdef.c b/src/import/import_fdef.c index f8b39276..8ecb4cbe 100644 --- a/src/import/import_fdef.c +++ b/src/import/import_fdef.c @@ -72,11 +72,10 @@ 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_tflag(gwi->gwion->env->class_def, tflag_tmpl)) - /*return*/ section_fdef(gwi, fdef); + 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; } @@ -84,9 +83,9 @@ ANN m_int gwi_func_end(const Gwi gwi, const f_xfun addr, const ae_flag flag) { CHECK_BB(ck_ok(gwi, ck_fdef)) gwi->ck->addr = addr; gwi->ck->flag = flag; - if(gwi_func_valid(gwi, gwi->ck) > 0) - return GW_OK; - return GW_ERROR; + const m_bool ret = gwi_func_valid(gwi, gwi->ck); + ck_end(gwi); + return ret; } ANN m_int gwi_func_arg(const Gwi gwi, const restrict m_str t, const restrict m_str n) { diff --git a/src/lib/array.c b/src/lib/array.c index ddcdf9c9..d5a1a13b 100644 --- a/src/lib/array.c +++ b/src/lib/array.c @@ -48,24 +48,29 @@ void free_m_vector(MemPool p, M_Vector a) { } static DTOR(array_dtor) { - const Type t = o->type_ref; if(*(void**)(o->data + SZ_INT)) xfree(*(void**)(o->data + SZ_INT)); struct M_Vector_* a = ARRAY(o); - if(!a) - return; - if(t->nspc->info->class_data_size) { - for(m_uint i = 0; i < ARRAY_LEN(a); ++i) - (*(f_release**)t->nspc->info->class_data)(shred, array_base(t), ARRAY_PTR(a) + i * ARRAY_SIZE(a)); - } free_m_vector(shred->info->mp, a); } +static DTOR(array_dtor_obj) { + struct M_Vector_* a = ARRAY(o); + for(m_uint i = 0; i < ARRAY_LEN(a); ++i) + release(*(M_Object*)(ARRAY_PTR(a) + i * SZ_INT), shred); +} + +static DTOR(array_dtor_struct) { + struct M_Vector_* a = ARRAY(o); + for(m_uint i = 0; i < ARRAY_LEN(a); ++i) + struct_release(shred, array_base(o->type_ref), &*(m_bit*)(ARRAY_PTR(a) + i * SZ_INT)); +} + ANN M_Object new_array(MemPool p, const Type t, const m_uint length) { const M_Object a = new_object(p, NULL, t); const m_uint depth = !tflag(t, tflag_typedef) ? t->array_depth : t->info->parent->array_depth; const m_uint size = depth > 1 ? SZ_INT : array_base(t)->size; - ARRAY(a) = new_m_vector(p, size,length); + ARRAY(a) = new_m_vector(p, size, length); return a; } @@ -111,16 +116,76 @@ ANN void m_vector_rem(const M_Vector v, m_uint index) { } static MFUN(vm_vector_rem) { + const m_int index = *(m_int*)(shred->mem + SZ_INT); + const M_Vector v = ARRAY(o); + if(index < 0 || (m_uint)index >= ARRAY_LEN(v)) + return; + m_vector_rem(v, (vtype)index); +} + +static MFUN(vm_vector_rem_obj) { + const m_int index = *(m_int*)(shred->mem + SZ_INT); + const M_Vector v = ARRAY(o); + if(index < 0 || (m_uint)index >= ARRAY_LEN(v)) + return; + release(*(M_Object*)(ARRAY_PTR(v) + index * ARRAY_SIZE(v)), shred); + m_vector_rem(v, (vtype)index); +} + +static MFUN(vm_vector_rem_struct) { const m_int index = *(m_int*)(shred->mem + SZ_INT); const M_Vector v = ARRAY(o); if(index < 0 || (m_uint)index >= ARRAY_LEN(v)) return; const Type t = o->type_ref; - if(t->nspc->info->class_data_size) - (*(f_release**)t->nspc->info->class_data)(shred, array_base(t), ARRAY_PTR(v) + index * ARRAY_SIZE(v)); + struct_release(shred, array_base(t), ARRAY_PTR(v) + index * ARRAY_SIZE(v)); m_vector_rem(v, (vtype)index); } +static MFUN(vm_vector_insert) { + const m_int index = *(m_int*)(shred->mem + SZ_INT); + const M_Vector v = ARRAY(o); + if(index < 0 || (m_uint)index > ARRAY_LEN(v)) + return; + const size_t size = ARRAY_SIZE(v); + if(++ARRAY_LEN(v) >= ARRAY_CAP(v)) { + const m_uint cap = ARRAY_CAP(v) *=2; + v->ptr = (m_bit*)xrealloc(v->ptr, ARRAY_OFFSET + cap * size); + } + memmove(ARRAY_PTR(v) + (index+1) * size, ARRAY_PTR(v) + index*size, (ARRAY_LEN(v) - index + 1)* size); + memcpy(ARRAY_PTR(v) + index*size, shred->mem + SZ_INT*2, size); +} + +static MFUN(vm_vector_insert_obj) { + const m_int index = *(m_int*)(shred->mem + SZ_INT); + const M_Vector v = ARRAY(o); + if(index < 0 || (m_uint)index > ARRAY_LEN(v)) + return; + const size_t size = SZ_INT; + if(++ARRAY_LEN(v) >= ARRAY_CAP(v)) { + const m_uint cap = ARRAY_CAP(v) *=2; + v->ptr = (m_bit*)xrealloc(v->ptr, ARRAY_OFFSET + cap * size); + } + memmove(ARRAY_PTR(v) + (index+1) *size, ARRAY_PTR(v) + index*size, (ARRAY_LEN(v) - index + 1)* size); + memcpy(ARRAY_PTR(v) + index*size, shred->mem + SZ_INT*2, size); + ++(*(M_Object*)(shred->mem + SZ_INT*2))->ref; +} + +static MFUN(vm_vector_insert_struct) { + const m_int index = *(m_int*)(shred->mem + SZ_INT); + const M_Vector v = ARRAY(o); + if(index < 0 || (m_uint)index > ARRAY_LEN(v)) + return; + const size_t size = ARRAY_SIZE(v); + if(++ARRAY_LEN(v) >= ARRAY_CAP(v)) { + const m_uint cap = ARRAY_CAP(v) *=2; + v->ptr = (m_bit*)xrealloc(v->ptr, ARRAY_OFFSET + cap * size); + } + memmove(ARRAY_PTR(v) + (index+1) *size, ARRAY_PTR(v) + index*size, (ARRAY_LEN(v) - index + 1)* size); + memcpy(ARRAY_PTR(v) + index*size, shred->mem + SZ_INT*2, size); + struct_addref(shred->info->vm->gwion, array_base(o->type_ref), shred->mem + SZ_INT*2); +} + ANN m_bit* m_vector_addr(const M_Vector v, const m_uint i) { return &*(m_bit*)(ARRAY_PTR(v) + i * ARRAY_SIZE(v)); } @@ -137,16 +202,10 @@ static MFUN(vm_vector_cap) { *(m_uint*)RETURN = ARRAY_CAP(ARRAY(o)); } -ANN static Type get_array_type(Type t) { - while(t->array_depth && t->info->base_type) - t = t->info->base_type; - return t; -} - #define ARRAY_OPCK(a, b, pos) \ - const Type l = get_array_type(a->type); \ - const Type r = get_array_type(b->type); \ - if(isa(l, r) < 0) \ + const Type l = array_base(a->type); \ + const Type r = array_base(b->type); \ + if(isa(r, l) < 0) \ ERR_N(pos, _("array types do not match.")) static OP_CHECK(opck_array_at) { @@ -169,9 +228,9 @@ static OP_CHECK(opck_array_at) { ANN static Type check_array_shift(const Env env, const Exp a, const Exp b, const m_str str, const loc_t pos) { - if(a->type == env->gwion->type[et_error] && +/* if(a->type == env->gwion->type[et_error] && b->type->array_depth > 1) - return a->type; + return a->type;*/ ARRAY_OPCK(a, b, pos) if(a->type->array_depth == b->type->array_depth + 1) return a->type; @@ -264,8 +323,8 @@ static OP_EMIT(opem_array_sl) { // check me. use common ancestor maybe static OP_CHECK(opck_array_cast) { const Exp_Cast* cast = (Exp_Cast*)data; - Type l = array_base(cast->exp->type); - Type r = array_base(exp_self(cast)->type); + const Type l = array_base(cast->exp->type); + const Type r = array_base(exp_self(cast)->type); if(get_depth(cast->exp->type) == get_depth(exp_self(cast)->type) && isa(l->info->base_type, r->info->base_type) > 0) return l; return NULL; @@ -389,8 +448,66 @@ static OP_EMIT(opem_array_access) { return exp ? emit_array_access(emit, info) : GW_ERROR; } +ANN /*static */Symbol array_sym(const Env env, const Type src, const m_uint depth); +#include "template.h" +static OP_CHECK(opck_array_scan) { + struct TemplateScan *ts = (struct TemplateScan*)data; + const Type t_array = env->gwion->type[et_array]; + const Class_Def c = t_array->info->cdef; + const Type base = ts->t != t_array ? + ts->t : known_type(env, ts->td->types->td); + const Symbol sym = array_sym(env, array_base(base), base->array_depth + 1); + const Type type = nspc_lookup_type1(base->info->owner, sym); + if(type) + return type; + const Class_Def cdef = cpy_class_def(env->gwion->mp, c); + cdef->base.ext = type2td(env->gwion, t_array, (loc_t){}); + cdef->base.xid = sym; + cdef->base.tmpl->base = 1; // could store depth here? + cdef->base.tmpl->call = new_type_list(env->gwion->mp, type2td(env->gwion, base, (loc_t){}), NULL); + const m_uint scope = env_push(env, NULL, base->info->owner); + (void)scan0_class_def(env, cdef); + const Type t = cdef->base.type; + (void)traverse_cdef(env, t); + env_pop(env, scope); + if(GET_FLAG(base, abstract)) + SET_FLAG(t, abstract); + else + UNSET_FLAG(t, abstract); + set_tflag(t, tflag_emit); + t->array_depth = base->array_depth + 1; + t->info->base_type = array_base(base); + set_tflag(t, tflag_cdef | tflag_tmpl); + void* rem = isa(base, env->gwion->type[et_compound]) > 0 ? + !tflag(base, tflag_struct) ? vm_vector_rem_obj : vm_vector_rem_struct : vm_vector_rem; + builtin_func(env->gwion->mp, (Func)vector_at(&t->nspc->info->vtable, 0), rem); + void* insert = isa(base, env->gwion->type[et_compound]) > 0 ? + !tflag(base, tflag_struct) ? vm_vector_insert_obj : vm_vector_insert_struct : vm_vector_insert; + builtin_func(env->gwion->mp, (Func)vector_at(&t->nspc->info->vtable, 1), insert); + builtin_func(env->gwion->mp, (Func)vector_at(&t->nspc->info->vtable, 2), vm_vector_size); + builtin_func(env->gwion->mp, (Func)vector_at(&t->nspc->info->vtable, 3), vm_vector_depth); + builtin_func(env->gwion->mp, (Func)vector_at(&t->nspc->info->vtable, 4), vm_vector_cap); + if(isa(base, env->gwion->type[et_compound]) > 0) { + t->nspc->dtor = new_vmcode(env->gwion->mp, NULL, SZ_INT, 1, "array component dtor"); + set_tflag(t, tflag_dtor); + t->nspc->dtor->native_func = (m_uint) (!tflag(base, tflag_struct) ? + array_dtor_obj : array_dtor_struct); + } + unset_tflag(t, tflag_ctor); + return t; +} + +static OP_CHECK(opck_array_implicit) { + const struct Implicit* imp = (struct Implicit*)data; + if(imp->t->array_depth != imp->e->type->array_depth) + return env->gwion->type[et_error]; + if(isa(array_base(imp->e->type), array_base(imp->t)) < 0) + return env->gwion->type[et_error]; + return imp->t; +} + GWION_IMPORT(array) { - const Type t_array = gwi_class_ini(gwi, "@Array", NULL); + const Type t_array = gwi_class_ini(gwi, "Array:[T]", "Object"); gwi->gwion->type[et_array] = t_array; gwi_class_xtor(gwi, NULL, array_dtor); GWI_BB(gwi_item_ini(gwi, "@internal", "@array")) @@ -398,6 +515,16 @@ GWION_IMPORT(array) { GWI_BB(gwi_item_ini(gwi, "@internal", "@ctor_data")) GWI_BB(gwi_item_end(gwi, 0, num, 0)) + // put functions using T first + GWI_BB(gwi_func_ini(gwi, "bool", "remove")) + GWI_BB(gwi_func_arg(gwi, "int", "index")) + GWI_BB(gwi_func_end(gwi, vm_vector_rem, ae_flag_none)) + + GWI_BB(gwi_func_ini(gwi, "bool", "insert")) + GWI_BB(gwi_func_arg(gwi, "int", "index")) + GWI_BB(gwi_func_arg(gwi, "T", "data")) + GWI_BB(gwi_func_end(gwi, vm_vector_insert, ae_flag_none)) + GWI_BB(gwi_func_ini(gwi, "int", "size")) GWI_BB(gwi_func_end(gwi, vm_vector_size, ae_flag_none)) GWI_BB(gwi_func_ini(gwi, "int", "depth")) @@ -406,33 +533,34 @@ GWION_IMPORT(array) { GWI_BB(gwi_func_ini(gwi, "int", "cap")) GWI_BB(gwi_func_end(gwi, vm_vector_cap, ae_flag_none)) - GWI_BB(gwi_func_ini(gwi, "int", "remove")) - GWI_BB(gwi_func_arg(gwi, "int", "index")) - GWI_BB(gwi_func_end(gwi, vm_vector_rem, ae_flag_none)) - GWI_BB(gwi_class_end(gwi)) - GWI_BB(gwi_oper_ini(gwi, "@Array", "@Array", NULL)) + GWI_BB(gwi_oper_ini(gwi, "Array", "Array", NULL)) GWI_BB(gwi_oper_add(gwi, opck_array_at)) GWI_BB(gwi_oper_end(gwi, "@=>", NULL)) - GWI_BB(gwi_oper_ini(gwi, "@Array", (m_str)OP_ANY_TYPE, NULL)) + GWI_BB(gwi_oper_add(gwi, opck_array_implicit)) + GWI_BB(gwi_oper_end(gwi, "@implicit", NULL)) + GWI_BB(gwi_oper_ini(gwi, "Array", (m_str)OP_ANY_TYPE, NULL)) GWI_BB(gwi_oper_add(gwi, opck_array_sl)) GWI_BB(gwi_oper_emi(gwi, opem_array_sl)) GWI_BB(gwi_oper_end(gwi, "<<", NULL)) - GWI_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, "@Array", NULL)) + GWI_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, "Array", NULL)) GWI_BB(gwi_oper_add(gwi, opck_array_sr)) GWI_BB(gwi_oper_emi(gwi, opem_array_sr)) GWI_BB(gwi_oper_end(gwi, ">>", NULL)) - GWI_BB(gwi_oper_ini(gwi, "@Array", "@Array", NULL)) + GWI_BB(gwi_oper_ini(gwi, "Array", "Array", NULL)) GWI_BB(gwi_oper_add(gwi, opck_array_cast)) GWI_BB(gwi_oper_end(gwi, "$", NULL)) - GWI_BB(gwi_oper_ini(gwi, "int", "@Array", "int")) + GWI_BB(gwi_oper_ini(gwi, "int", "Array", "int")) GWI_BB(gwi_oper_add(gwi, opck_array_slice)) GWI_BB(gwi_oper_emi(gwi, opem_array_slice)) GWI_BB(gwi_oper_end(gwi, "@slice", NULL)) - GWI_BB(gwi_oper_ini(gwi, "int", "@Array", NULL)) + GWI_BB(gwi_oper_ini(gwi, "int", "Array", NULL)) GWI_BB(gwi_oper_add(gwi, opck_array)) GWI_BB(gwi_oper_emi(gwi, opem_array_access)) GWI_BB(gwi_oper_end(gwi, "@array", NULL)) + GWI_BB(gwi_oper_ini(gwi, "Array", NULL, NULL)) + GWI_BB(gwi_oper_add(gwi, opck_array_scan)) + GWI_BB(gwi_oper_end(gwi, "@scan", NULL)) gwi_register_freearg(gwi, ArrayAlloc, freearg_array); return GW_OK; } diff --git a/src/lib/engine.c b/src/lib/engine.c index ec85614c..a4e6d336 100644 --- a/src/lib/engine.c +++ b/src/lib/engine.c @@ -79,8 +79,6 @@ ANN static m_bool import_core_libs(const Gwi gwi) { GWI_BB(gwi_set_global_type(gwi, t_class, et_class)) GWI_BB(gwi_gack(gwi, t_class, gack_class)) - 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_tflag(t_auto, tflag_infer); GWI_BB(gwi_set_global_type(gwi, t_auto, et_auto)) @@ -110,7 +108,7 @@ ANN static m_bool import_core_libs(const Gwi gwi) { struct SpecialId_ spid = { .type=t_now, .exec=RegPushNow, .is_const=1 }; gwi_specialid(gwi, "now", &spid); - const Type t_compound = gwi_mk_type(gwi, "@Compound", 0, NULL); + const Type t_compound = gwi_mk_type(gwi, "@Compound", SZ_INT, NULL); GWI_BB(gwi_gack(gwi, t_compound, gack_compound)) GWI_BB(gwi_set_global_type(gwi, t_compound, et_compound)) diff --git a/src/lib/instr.c b/src/lib/instr.c index f022ddb1..c4f63f43 100644 --- a/src/lib/instr.c +++ b/src/lib/instr.c @@ -27,7 +27,7 @@ ANN static Func_Def from_base(const Env env, struct dottmpl_ *const dt, const Ns const Symbol sym = func_symbol(env, nspc->name, s_name(fdef->base->xid), "template", dt->base->base->tmpl->base); 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) + if(is_class(env->gwion, v->type)) return NULL; if(vflag(v, vflag_builtin)) { dt->xfun = v->d.func_ref->def->d.dl_func_ptr; diff --git a/src/lib/lib_func.c b/src/lib/lib_func.c index 55ba5e94..6ea745ec 100644 --- a/src/lib/lib_func.c +++ b/src/lib/lib_func.c @@ -56,8 +56,8 @@ ANN static m_bool fptr_tmpl_push(const Env env, struct FptrInfo *info) { t1 = info->rhs->def->base->tmpl->list; nspc_push_type(env->gwion->mp, env->curr); while(t0) { - nspc_add_type(env->curr, t0->xid, env->gwion->type[et_undefined]); - nspc_add_type(env->curr, t1->xid, env->gwion->type[et_undefined]); + nspc_add_type(env->curr, t0->xid, env->gwion->type[et_auto]); + nspc_add_type(env->curr, t1->xid, env->gwion->type[et_auto]); t0 = t0->next; t1 = t1->next; } diff --git a/src/lib/object.c b/src/lib/object.c index fcea517f..be66223d 100644 --- a/src/lib/object.c +++ b/src/lib/object.c @@ -76,8 +76,7 @@ ANN void __release(const M_Object o, const VM_Shred shred) { compound_release(shred, v->type, o->data + v->from->offset); } } - if(tflag(t, tflag_dtor) && t->nspc->dtor) { - // check flag for array types + if(tflag(t, tflag_dtor)) { if(t->nspc->dtor->builtin) ((f_xtor)t->nspc->dtor->native_func)(o, NULL, shred); else { diff --git a/src/lib/object_op.c b/src/lib/object_op.c index 5d88e83e..5daf42e4 100644 --- a/src/lib/object_op.c +++ b/src/lib/object_op.c @@ -56,15 +56,6 @@ static OP_CHECK(opck_object_cast) { return exp_self(cast)->type; } -static OP_CHECK(opck_implicit_null2obj) { - const struct Implicit* imp = (struct Implicit*)data; - return imp->t; -} - -static OP_EMIT(opem_implicit_null2obj) { - return GW_OK; -} - ANN /*static*/ Type scan_class(const Env env, const Type t, const Type_Decl * td); static Type opck_object_scan(const Env env, const struct TemplateScan *ts) { @@ -162,7 +153,7 @@ OP_CHECK(opck_object_dot) { const Exp_Dot *member = (Exp_Dot*)data; const m_str str = s_name(member->xid); const m_bool base_static = is_class(env->gwion, member->base->type); - const Type the_base = base_static ? member->base->type->info->base_type : member->base->type; + const Type the_base = base_static ? _class_base(member->base->type) : member->base->type; // if(!the_base->nspc) // ERR_N(&member->base->pos, // _("type '%s' does not have members - invalid use in dot expression of %s"), @@ -231,7 +222,7 @@ OP_EMIT(opem_object_dot) { ANN static m_bool scantmpl_class_def(const Env env, struct tmpl_info *info) { const Class_Def c = info->base->info->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, c->pos); + c->body ? cpy_ast(env->gwion->mp, c->body) : NULL, c->pos); cdef->cflag = c->cflag; cdef->base.tmpl = mk_tmpl(env, c->base.tmpl, info->td->types); const m_bool ret = scan0_class_def(env, cdef); @@ -325,9 +316,9 @@ GWION_IMPORT(object_op) { GWI_BB(gwi_oper_end(gwi, "!=", NeqObject)) GWI_BB(gwi_oper_add(gwi, opck_object_cast)) GWI_BB(gwi_oper_end(gwi, "$", NULL)) - GWI_BB(gwi_oper_add(gwi, opck_implicit_null2obj)) - GWI_BB(gwi_oper_emi(gwi, opem_implicit_null2obj)) - GWI_BB(gwi_oper_end(gwi, "@implicit", NULL)) +//. GWI_BB(gwi_oper_add(gwi, opck_implicit_null2obj)) +// GWI_BB(gwi_oper_emi(gwi, opem_implicit_null2obj)) +// GWI_BB(gwi_oper_end(gwi, "@implicit", NULL)) GWI_BB(gwi_oper_ini(gwi, NULL, "Object", "bool")) GWI_BB(gwi_oper_emi(gwi, opem_not_object)) GWI_BB(gwi_oper_end(gwi, "!", IntNot)) diff --git a/src/lib/ptr.c b/src/lib/ptr.c index 896c3cdb..7f2ac1c9 100644 --- a/src/lib/ptr.c +++ b/src/lib/ptr.c @@ -63,9 +63,8 @@ static OP_CHECK(opck_ptr_cast) { if(!cast->td->types || !cast->td->types->td) 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->info->cdef && !tflag(_t, tflag_check)) - CHECK_BN(ensure_traverse(env, _t)) + if(t->info->cdef && !tflag(t, tflag_check)) + CHECK_BN(ensure_traverse(env, t)) const Type to = known_type(env, cast->td->types->td); exp_setvar(cast->exp, 1); if(isa(cast->exp->type, to) > 0) @@ -82,7 +81,7 @@ static OP_CHECK(opck_ptr_implicit) { if(access) ERR_N(e->pos, _("can't cast %s value to Ptr"), access); exp_setvar(e, 1); - const Type t = get_type(imp->t); + const Type t = imp->t; if(!tflag(t, tflag_check)) CHECK_BN(traverse_class_def(env, t->info->cdef)) return imp->t; diff --git a/src/parse/check.c b/src/parse/check.c index fb2a0cfa..7680c1bb 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -103,9 +103,11 @@ ANN static m_bool check_var_td(const Env env, const Var_Decl var, Type_Decl *con return GW_OK; } -ANN static void set_late(const Gwion gwion, const Exp_Decl *decl, const Value v) { - if(!exp_getvar(exp_self(decl)) && (GET_FLAG(v->type, abstract) || - GET_FLAG(decl->td, late) || is_fptr(gwion, v->type))) { +ANN static void set_late(const Gwion gwion, const Exp_Decl *decl, const Var_Decl var) { + const Value v = var->value; + const uint array_ref = (decl->td->array && !decl->td->array->exp) || (var->array && !var->array->exp); + if(!exp_getvar(exp_self(decl)) && (GET_FLAG(array_base(v->type), abstract) || + GET_FLAG(decl->td, late) || is_fptr(gwion, v->type) || array_ref)) { SET_FLAG(v, late); } else UNSET_FLAG(v, late); @@ -119,7 +121,7 @@ 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_late(env->gwion, decl, list->self->value); + set_late(env->gwion, decl, list->self); set_vflag(var->value, vflag_valid); //set_vflag(var->value, vflag_used)); nspc_add_value(env->curr, var->xid, var->value); @@ -128,21 +130,19 @@ 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) { - const Type base = get_type(t); - if(tflag(base, tflag_check) || !(tflag(base, tflag_cdef) || tflag(base, tflag_udef))) + if(tflag(t, tflag_check) || !(tflag(t, tflag_cdef) || tflag(t, tflag_udef))) return GW_OK; struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)check_cdef, .scope=env->scope->depth, .flag=tflag_check }; - return envset_run(&es, base); + return envset_run(&es, t); } ANN m_bool ensure_traverse(const Env env, const Type t) { - const Type base = get_type(t); - if(tflag(base, tflag_check) || !(tflag(base, tflag_cdef) || tflag(base, tflag_udef))) + if(tflag(t, tflag_check) || !(tflag(t, tflag_cdef) || tflag(t, tflag_udef))) return GW_OK; struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)traverse_cdef, .scope=env->scope->depth, .flag=tflag_check }; - return envset_run(&es, base); + return envset_run(&es, t); } ANN static inline m_bool inferable(const Env env, const Type t, const loc_t pos) { @@ -161,9 +161,8 @@ ANN Type check_exp_decl(const Env env, const Exp_Decl* decl) { if(!decl->type) ERR_O(decl->td->pos, _("can't find type")); { - const Type t = get_type(decl->type); - CHECK_BO(inferable(env, t, decl->td->pos)) - CHECK_BO(ensure_check(env, t)) + CHECK_BO(inferable(env, decl->type, decl->td->pos)) + CHECK_BO(ensure_check(env, decl->type)) } const m_bool global = GET_FLAG(decl->td, global); const m_uint scope = !global ? env->scope->depth : env_push_global(env); @@ -438,7 +437,7 @@ ANN2(1,2) static Func find_func_match_actual(const Env env, Func func, const Exp CHECK_OO(func->next); return find_func_match_actual(env, func->next, args, implicit, specific); } - if(e1->type == env->gwion->type[et_undefined] || + if(e1->type == env->gwion->type[et_auto] || (func->def->base->tmpl && is_fptr(env->gwion, func->value_ref->type) > 0)) { const Type owner = func->value_ref->from->owner_class; if(owner) @@ -720,6 +719,8 @@ ANN static Type check_exp_binary(const Env env, const Exp_Binary* bin) { const Type ret = op_check(env, &opi); if(!ret && is_auto && exp_self(bin)->exp_type == ae_exp_binary) bin->rhs->d.exp_decl.list->self->value->type = env->gwion->type[et_auto]; + exp_setuse(bin->lhs, 1); + exp_setuse(bin->rhs, 1); return ret; } @@ -735,6 +736,7 @@ ANN static Type check_exp_post(const Env env, const Exp_Postfix* post) { struct Op_Import opi = { .op=post->op, .lhs=check_exp(env, post->exp), .data=(uintptr_t)post, .pos=exp_self(post)->pos, .op_type=op_postfix }; CHECK_OO(opi.lhs) + exp_setuse(post->exp, 1); const Type t = op_check(env, &opi); if(t && isa(t, env->gwion->type[et_object]) < 0) exp_setmeta(exp_self(post), 1); @@ -784,12 +786,14 @@ ANN static Type check_exp_call(const Env env, Exp_Call* exp) { ANN static Type check_exp_unary(const Env env, const Exp_Unary* unary) { const Type rhs = unary->unary_type == unary_exp ? check_exp(env, unary->exp) : NULL; - if(unary->unary_type == unary_exp) + if(unary->unary_type == unary_exp) { CHECK_OO(rhs) + exp_setuse(unary->exp, 1); + } struct Op_Import opi = { .op=unary->op, .rhs=rhs, .data=(uintptr_t)unary, .pos=exp_self(unary)->pos, .op_type=op_unary }; DECL_OO(const Type, ret, = op_check(env, &opi)) - const Type t = get_type(actual_type(env->gwion, ret)); + const Type t = actual_type(env->gwion, ret); CHECK_BO(ensure_traverse(env, t)) return ret; } @@ -911,13 +915,12 @@ ANN static inline Type foreach_type(const Env env, const Exp exp) { } ANN static m_bool do_stmt_each(const Env env, const Stmt_Each stmt) { - DECL_OB(const Type, ptr, = foreach_type(env, stmt->exp)) - const Type base = get_type(ptr); + DECL_OB(const Type, base, = foreach_type(env, stmt->exp)) CHECK_BB(ensure_traverse(env, base)) - char c[15 + strlen(ptr->name)]; - sprintf(c, "@Foreach:[%s]", ptr->name); + char c[15 + strlen(base->name)]; + sprintf(c, "@Foreach:[%s]", base->name); const Type ret = str2type(env->gwion, c, stmt->exp->pos); - if(ptr->array_depth) + if(base->array_depth) set_tflag(ret, tflag_typedef); stmt->v = new_value(env->gwion->mp, ret, s_name(stmt->sym)); set_vflag(stmt->v, vflag_valid); @@ -1246,12 +1249,13 @@ HANDLE_SECTION_FUNC(check, m_bool, Env) ANN static m_bool check_parent(const Env env, const Class_Def cdef) { const Type parent = cdef->base.type->info->parent; const Type_Decl *td = cdef->base.ext; - if(td->array) +// if(td->array) + if(td->array && td->array->exp) CHECK_BB(check_subscripts(env, td->array, 1)) CHECK_BB(ensure_check(env, parent)) - if(tflag(parent, tflag_typedef)) { - set_tflag(cdef->base.type, tflag_typedef); - } +// if(tflag(parent, tflag_typedef)) { +// set_tflag(cdef->base.type, tflag_typedef); +// } return GW_OK; } diff --git a/src/parse/operator.c b/src/parse/operator.c index 670847b6..027e357d 100644 --- a/src/parse/operator.c +++ b/src/parse/operator.c @@ -134,6 +134,13 @@ ANN m_bool add_op(const Gwion gwion, const struct Op_Import* opi) { return GW_OK; } +ANN static inline Type op_parent(const Env env, const Type t) { + const size_t depth = t->array_depth; + return !depth || !array_base(t)->info->parent ? + t->info->parent : + array_type(env, array_base(t)->info->parent, depth); +} + ANN static Type op_check_inner(struct OpChecker* ock, const uint i) { Type t, r = ock->opi->rhs; do { @@ -165,7 +172,7 @@ for(int i = 0; i < 2; ++i) { return NULL; return ret; } - } while(l && (l = l->info->parent)); + } while(l && (l = op_parent(env, l))); } while((nspc = nspc->parent)); } if(opi->op == insert_symbol(env->gwion->st, "$") && opi->rhs == opi->lhs) @@ -222,8 +229,8 @@ ANN m_bool op_emit(const Emitter emit, const struct Op_Import* opi) { } else if(mo->func || mo->instr) return handle_instr(emit, mo); } - } while(r && (r = r->info->parent)); - } while(l && (l = l->info->parent)); + } while(r && (r = op_parent(emit->env, r))); + } while(l && (l = op_parent(emit->env, l))); } while((nspc = nspc->parent)); } return GW_ERROR; diff --git a/src/parse/scan0.c b/src/parse/scan0.c index 1b96133e..2972a5a9 100644 --- a/src/parse/scan0.c +++ b/src/parse/scan0.c @@ -312,8 +312,10 @@ 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, s_name(cdef->base.xid), parent); - if(cflag(cdef, cflag_struct)) + if(cflag(cdef, cflag_struct)) { + t->size = 0; set_tflag(t, tflag_struct); + } t->info->tuple = new_tupleform(env->gwion->mp, parent); t->info->owner = env->curr; t->info->owner_class = env->class_def; @@ -366,7 +368,6 @@ ANN m_bool scan0_class_def(const Env env, const Class_Def c) { c->base.type = cdef->base.type; c->base.type->info->cdef = cdef; set_tflag(c->base.type, tflag_cdef); - set_tflag(cdef->base.type, tflag_scan0);// redundant } return ret; } diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 14ac1bd3..d644ee85 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -24,21 +24,19 @@ 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) { - const Type base = get_type(t); - if(tflag(base, tflag_scan1) || !(tflag(base, tflag_cdef) || tflag(base, tflag_udef))) + if(tflag(t, tflag_scan1) || !(tflag(t, tflag_cdef) || tflag(t, tflag_udef))) return GW_OK; struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)scan1_cdef, .scope=env->scope->depth, .flag=tflag_scan1 }; - return envset_run(&es, base); + return envset_run(&es, t); } ANN static Type scan1_type(const Env env, Type_Decl* td) { - DECL_OO(const Type, type, = known_type(env, td)) - const Type t = get_type(type); + DECL_OO(const Type, t, = known_type(env, td)) if(!env->func && env->class_def && !GET_FLAG(td, late)) CHECK_BO(type_cyclic(env, t, td)) CHECK_BO(ensure_scan1(env, t)) - return type; + return t; } ANN static Type void_type(const Env env, Type_Decl* td) { @@ -76,6 +74,7 @@ static inline uint array_ref(const Array_Sub array) { ANN static m_bool scan1_decl(const Env env, const Exp_Decl* decl) { Var_Decl_List list = decl->list; + const uint decl_ref = array_ref(decl->td->array); do { const Var_Decl var = list->self; CHECK_BB(isres(env, var->xid, exp_self(decl)->pos)) @@ -86,7 +85,7 @@ ANN static m_bool scan1_decl(const Env env, const Exp_Decl* decl) { CHECK_BB(scan1_exp(env, var->array->exp)) t = array_type(env, decl->type, var->array->depth); } - if(t->array_depth && GET_FLAG(array_base(t), abstract) && ((var->array && var->array->exp) + if(GET_FLAG(array_base(t), abstract) && ((var->array && var->array->exp) || (decl->td->array && decl->td->array->exp))) ERR_B(var->pos, _("arrays of abstract type '%s' must be declared empty"), array_base(t)->name); @@ -95,8 +94,8 @@ ANN static m_bool scan1_decl(const Env env, const Exp_Decl* decl) { if(GET_FLAG(t, abstract) && !GET_FLAG(decl->td, late)) SET_FLAG(v, late); v->type = t; - if(array_ref(var->array)) - SET_FLAG(decl->td, late); + if(decl_ref || array_ref(var->array)) + SET_FLAG(v, late); v->flag |= decl->td->flag; if(!env->scope->depth) { valuefrom(env, v->from); @@ -130,8 +129,6 @@ ANN int is_global(const Nspc nspc, Nspc global) { 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); - if(array_ref(decl->td->array)) - SET_FLAG(decl->td, late); CHECK_OB(decl->type) const m_bool global = GET_FLAG(decl->td, global); if(global) { @@ -360,7 +357,7 @@ ANN static m_bool scan1_args(const Env env, Arg_List list) { ANN static m_bool _scan1_fdef_base_tmpl(const Env env, Func_Base *base) { ID_List id = base->tmpl->list; - do nspc_add_type(env->curr, id->xid, env->gwion->type[et_undefined]); + do nspc_add_type(env->curr, id->xid, env->gwion->type[et_auto]); while((id = id->next)); CHECK_OB((base->ret_type = known_type(env, base->td))) if(base->args) { @@ -594,7 +591,7 @@ ANN static Type scan1_get_parent(const Env env, const Type_Def tdef) { ANN static m_bool scan1_parent(const Env env, const Class_Def cdef) { const loc_t pos = cdef->base.ext->pos; - if(cdef->base.ext->array) + if(cdef->base.ext->array && cdef->base.ext->array->exp) CHECK_BB(scan1_exp(env, cdef->base.ext->array->exp)) DECL_OB(const Type , parent, = scan1_get_parent(env, &cdef->base)) if(isa(parent, env->gwion->type[et_object]) < 0) diff --git a/src/parse/scan2.c b/src/parse/scan2.c index af5ed0fc..7407540f 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -15,16 +15,15 @@ ANN static m_bool scan2_stmt(const Env, const Stmt); ANN static m_bool scan2_stmt_list(const Env, Stmt_List); ANN static inline m_bool ensure_scan2(const Env env, const Type t) { - const Type base = get_type(t); - if(tflag(base, tflag_scan2) || !(tflag(base, tflag_cdef) || tflag(base, tflag_udef))) + if(tflag(t, tflag_scan2) || !(tflag(t, tflag_cdef) || tflag(t, tflag_udef))) return GW_OK; struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)scan2_cdef, .scope=env->scope->depth, .flag=tflag_scan2 }; - return envset_run(&es, base); + 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); + const Type t = decl->type; CHECK_BB(ensure_scan2(env, t)) Var_Decl_List list = decl->list; do { @@ -272,7 +271,7 @@ ANN static m_bool scan2_func_def_overload(const Env env, const Func_Def f, const if(!fbflag(f->base, fbflag_internal)) ERR_B(f->pos, _("function name '%s' is already used by another value"), overload->name) } - const Func obase = !fptr ? overload->d.func_ref : overload->type->info->base_type->info->func; + const Func obase = !fptr ? overload->d.func_ref : _class_base(overload->type)->info->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); @@ -526,7 +525,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->info->parent; CHECK_BB(ensure_scan2(env, parent)) - if(cdef->base.ext->array) + if(cdef->base.ext->array && cdef->base.ext->array->exp) CHECK_BB(scan2_exp(env, cdef->base.ext->array->exp)) return GW_OK; } diff --git a/src/parse/scanx.c b/src/parse/scanx.c index 7230326c..2f5ef8a1 100644 --- a/src/parse/scanx.c +++ b/src/parse/scanx.c @@ -41,15 +41,8 @@ scanx_body(const Env e, const Class_Def c, const _exp_func f, void* d) { return ret; } -__attribute__((returns_nonnull)) -ANN Type get_type(const Type t) { - const Type type = !t->array_depth ? t : array_base(t); - return type; -} - -ANN m_bool scanx_cdef(const Env env, void* opt, const Type base, +ANN m_bool scanx_cdef(const Env env, void* opt, const Type t, const _exp_func f_cdef, const _exp_func f_union) { - const Type t = get_type(base); if(t->info->parent != env->gwion->type[et_union]) return f_cdef(opt, t->info->cdef); const m_bool ret = f_union(opt, t->info->udef); diff --git a/src/parse/template.c b/src/parse/template.c index 28f0f5d0..85babe9b 100644 --- a/src/parse/template.c +++ b/src/parse/template.c @@ -104,11 +104,7 @@ ANN Type _scan_type(const Env env, const Type t, Type_Decl* td) { return op_check(env, &opi); } else if(td->types) return maybe_func(env, t, td); - Type_Decl *next = td->next; - td->next = NULL; - const Type ret = find_type(env, td); - td->next = next; - return ret; + return find_type(env, td); } ANN Type scan_type(const Env env, const Type t, Type_Decl* td) {