From 6dd7bae8d837e7493c1f552522663b33740a611f Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Wed, 14 Apr 2021 00:32:29 +0200 Subject: [PATCH] :art: Add Array.map --- include/env/envset.h | 10 +++-- include/env/type.h | 4 +- include/gwion.h | 4 +- include/vm.h | 5 ++- src/compile.c | 6 ++- src/emit/emit.c | 17 ++++++-- src/env/env.c | 2 - src/env/env_utils.c | 4 +- src/env/envset.c | 21 +++++---- src/env/type.c | 5 +-- src/import/import_cdef.c | 2 - src/import/import_checker.c | 20 +++++++-- src/lib/array.c | 81 +++++++++++++++++++++++++++++++++-- src/lib/instr.c | 6 +++ src/lib/lib_func.c | 76 +++++++++++++++++++------------- src/lib/object_op.c | 6 +-- src/lib/ptr.c | 24 ++++++++--- src/lib/ref.c | 9 ++-- src/parse/check.c | 8 ++-- src/parse/func_resolve_tmpl.c | 18 +++++++- src/parse/scan0.c | 66 ++++++++++++++++------------ src/parse/scan1.c | 12 +++--- src/parse/scan2.c | 10 ++--- src/parse/template.c | 17 ++++---- src/parse/type_decl.c | 3 +- src/vm/vm_code.c | 3 +- tests/tree/class_template.gw | 1 + 27 files changed, 297 insertions(+), 143 deletions(-) diff --git a/include/env/envset.h b/include/env/envset.h index 7d840720..88f66929 100644 --- a/include/env/envset.h +++ b/include/env/envset.h @@ -16,14 +16,16 @@ ANN2(1,3) m_bool envset_push(struct EnvSet*, const Type, const Nspc); ANN2(1) void envset_pop(struct EnvSet*, const Type); ANN static inline m_bool extend_push(const Env env, const Type t) { - if(t->info->owner_class) - CHECK_BB(extend_push(env, t->info->owner_class)) + const Type owner = t->info->value->from->owner_class; + if(owner) + CHECK_BB(extend_push(env, owner)) return env_push_type(env, t); } ANN static inline void extend_pop(const Env env, const Type t) { env_pop(env, 0); - if(t->info->owner_class) - extend_pop(env, t->info->owner_class); + const Type owner = t->info->value->from->owner_class; + if(owner) + extend_pop(env, owner); } #endif diff --git a/include/env/type.h b/include/env/type.h index 00283758..dc87c89c 100644 --- a/include/env/type.h +++ b/include/env/type.h @@ -3,8 +3,7 @@ struct TypeInfo_ { Type parent; - Nspc owner; - Type owner_class; + Value value; union { Union_Def udef; Class_Def cdef; @@ -13,7 +12,6 @@ struct TypeInfo_ { Type base_type; struct TupleForm_* tuple; struct VM_Code_ *gack; - struct Context_ *ctx; }; enum tflag { diff --git a/include/gwion.h b/include/gwion.h index 9ee352d1..50610636 100644 --- a/include/gwion.h +++ b/include/gwion.h @@ -28,11 +28,11 @@ ANN void push_global(const Gwion gwion, const m_str name); ANN Nspc pop_global(const Gwion gwion); __attribute__((returns_nonnull)) ANN static inline Value type_value(const Gwion gwion, const Type t) { - return (Value)nspc_lookup_value1(t->info->owner, insert_symbol(gwion->st, t->name)); + return (Value)nspc_lookup_value1(t->info->value->from->owner, insert_symbol(gwion->st, t->name)); } __attribute__((returns_nonnull)) ANN static inline Type type_class(const Gwion gwion, const Type t) { - const Value v = nspc_lookup_value1(t->info->owner, insert_symbol(gwion->st, t->name)); + const Value v = nspc_lookup_value1(t->info->value->from->owner, insert_symbol(gwion->st, t->name)); return v->type; } #endif diff --git a/include/vm.h b/include/vm.h index 502a1c20..5fb074b8 100644 --- a/include/vm.h +++ b/include/vm.h @@ -17,13 +17,14 @@ struct VM_Code_ { m_uint native_func; }; size_t stack_depth; + struct Vector_ tmpl_types; void* memoize; Closure *closure; m_str name; uint16_t ref; ae_flag flag; - int builtin; - int callback; + bool builtin; + bool callback; }; typedef struct Shreduler_* Shreduler; diff --git a/src/compile.c b/src/compile.c index 7f1c0fd4..aa06e238 100644 --- a/src/compile.c +++ b/src/compile.c @@ -72,8 +72,10 @@ ANN static m_bool _compiler_open(struct Compiler* c) { ANN static int is_reg(const m_str path) { struct stat s; stat(path, &s); - return S_ISREG(s.st_mode) || !S_ISFIFO(s.st_mode); + return !S_ISDIR(s.st_mode) && + (S_ISREG(s.st_mode) || !S_ISFIFO(s.st_mode)); } + #else ANN static m_bool is_reg(const m_str path) { const DWORD dw = GetFileAttributes(path); @@ -86,7 +88,7 @@ ANN static inline m_bool compiler_open(MemPool p, struct Compiler* c) { char name[strlen(c->name) + 1]; strcpy(name, c->name); #ifndef __FUZZING__ - if(c->type == COMPILE_FILE && !is_reg(name)) { + if((c->type == COMPILE_FILE || c->type == COMPILE_NAME) && !is_reg(name)) { gw_err(_("'%s': is a not a regular file\n"), name); return GW_ERROR; } diff --git a/src/emit/emit.c b/src/emit/emit.c index 209b8c68..d2f81fc0 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -2259,8 +2259,18 @@ 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(vflag(func->value_ref, vflag_builtin) && safe_tflag(emit->env->class_def, tflag_tmpl)) + if(vflag(func->value_ref, vflag_builtin) && safe_tflag(emit->env->class_def, tflag_tmpl)) { + const Func base = nspc_lookup_func1(func->value_ref->from->owner, f->base->xid); + builtin_func(emit->gwion->mp, func, (f_xfun)base->code->native_func); + vector_init(&func->code->tmpl_types); + vector_add(&func->code->tmpl_types, (m_uint)fdef->base->ret_type); + Arg_List args = fdef->base->args; + while(args) { + vector_add(&func->code->tmpl_types, (m_uint)args->type); + args = args->next; + } return GW_OK; + } if(fdef_is_file_global(emit, fdef)) func->value_ref->from->offset = emit_local(emit, emit->gwion->type[et_int]); const uint global = GET_FLAG(f->base, global); @@ -2340,8 +2350,9 @@ ANN static m_bool emit_class_def(const Emitter emit, const Class_Def cdef) { if(tflag(t, tflag_emit)) return GW_OK; set_tflag(t, tflag_emit); - if(t->info->owner_class) - CHECK_BB(ensure_emit(emit, t->info->owner_class)) + const Type owner = t->info->value->from->owner_class; + if(owner) + CHECK_BB(ensure_emit(emit, owner)) if(cdef->base.ext && t->info->parent->info->cdef && !tflag(t->info->parent, tflag_emit)) // ????? CHECK_BB(cdef_parent(emit, cdef)) nspc_allocdata(emit->gwion->mp, t->nspc); diff --git a/src/env/env.c b/src/env/env.c index 947e4bb6..5eda5517 100644 --- a/src/env/env.c +++ b/src/env/env.c @@ -84,8 +84,6 @@ ANN void env_pop(const Env env, const m_uint scope) { } ANN void env_add_type(const Env env, const Type type, const loc_t loc) { - type->info->owner = env->curr; - type->info->owner_class = env->class_def; // t owner_class ? const Symbol sym = insert_symbol(type->name); nspc_add_type_front(env->curr, sym, type); const Value v = mk_class(env, type, loc); diff --git a/src/env/env_utils.c b/src/env/env_utils.c index 2bc610ca..5c195b00 100644 --- a/src/env/env_utils.c +++ b/src/env/env_utils.c @@ -67,7 +67,6 @@ ANN static Type class_type(const Env env, const Type base) { const Type t_class = env->gwion->type[et_class]; const Type t = type_copy(env->gwion->mp, t_class); t->info->parent = t_class; - t->info->ctx = base->info->ctx; t->info->base_type = base; set_tflag(t, tflag_infer); return t; @@ -80,7 +79,8 @@ ANN Value mk_class(const Env env, const Type base, const loc_t loc) { valuefrom(env, v->from, loc); SET_FLAG(v, const); set_vflag(v, vflag_valid); - nspc_add_value_front(base->info->owner, sym, v); + nspc_add_value_front(env->curr, sym, v); + t->info->value = base->info->value = v; return v; } diff --git a/src/env/envset.c b/src/env/envset.c index 4ee189dd..70cffea8 100644 --- a/src/env/envset.c +++ b/src/env/envset.c @@ -7,22 +7,23 @@ ANN static void check(struct EnvSet *es, const Type t) { const Vector v = &es->env->scope->class_stack; - Type owner = t->info->owner_class; + Type owner = t->info->value->from->owner_class; for(vtype i = vector_size(v) + 1; owner && --i;) { if(owner != (Type)vector_at(v, i - 1)) { es->run = 1; return; } - owner = owner->info->owner_class; + owner = owner->info->value->from->owner_class; } } ANN static m_bool push(struct EnvSet *es, const Type t) { es->env->scope->depth = 0; - if(t->info->owner_class) - CHECK_BB(push(es, t->info->owner_class)) + const Type owner_class = t->info->value->from->owner_class; + if(owner_class) + CHECK_BB(push(es, owner_class)) else - env_push(es->env, NULL, t->info->ctx ? t->info->ctx->nspc : es->env->curr); + env_push(es->env, NULL, t->info->value->from->ctx ? t->info->value->from->ctx->nspc : es->env->curr); if(es->func && !(t->tflag & es->flag)) CHECK_BB(es->func((void*)es->data, t)) if(tflag(t, tflag_tmpl)) @@ -49,20 +50,22 @@ ANN2(1) void envset_pop(struct EnvSet *es, const Type t) { return; if(tflag(t, tflag_tmpl)) nspc_pop_type(es->env->gwion->mp, es->env->curr); - if(t->info->owner_class) - envset_pop(es, t->info->owner_class); + const Type owner_class = t->info->value->from->owner_class; + if(owner_class) + envset_pop(es, owner_class); else env_pop(es->env, es->scope); } ANN m_bool envset_run(struct EnvSet *es, const Type t) { check(es, t); + const Type owner_class = t->info->value->from->owner_class; if(es->run) - CHECK_BB(push(es, t->info->owner_class)) + CHECK_BB(push(es, owner_class)) const m_bool ret = t->info->cdef && !(t->tflag & es->flag) ? es->func(es->data, t) : GW_OK; if(es->run) - envset_pop(es, t->info->owner_class); + envset_pop(es, owner_class); return ret; } diff --git a/src/env/type.c b/src/env/type.c index 4611b4ff..21caa228 100644 --- a/src/env/type.c +++ b/src/env/type.c @@ -41,9 +41,6 @@ Type new_type(MemPool p, const m_str name, const Type parent) { ANN Type type_copy(MemPool p, const Type type) { const Type a = new_type(p, type->name, type->info->parent); - a->nspc = type->nspc; - a->info->owner = type->info->owner; - a->info->owner_class = type->info->owner_class; a->size = type->size; a->array_depth = type->array_depth; a->info->gack = type->info->gack; @@ -101,7 +98,7 @@ ANN /*static */Symbol array_sym(const Env env, const Type src, const m_uint dept #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); + const Type type = nspc_lookup_type1(src->info->value->from->owner, sym); if(type) return type; const size_t tdepth = depth + src->array_depth; diff --git a/src/import/import_cdef.c b/src/import/import_cdef.c index 6ca93ef0..ce372094 100644 --- a/src/import/import_cdef.c +++ b/src/import/import_cdef.c @@ -31,8 +31,6 @@ ANN2(1,2) static void import_class_ini(const Env env, const Type t) { t->nspc->parent = env->curr; if(isa(t, env->gwion->type[et_object]) > 0) inherit(t); - t->info->owner = env->curr; - t->info->owner_class = env->class_def; env_push_type(env, t); } diff --git a/src/import/import_checker.c b/src/import/import_checker.c index 3e46de79..d1ceb775 100644 --- a/src/import/import_checker.c +++ b/src/import/import_checker.c @@ -174,7 +174,17 @@ ANN static Type_List td_tmpl(const Gwion gwion, struct td_checker *tdc) { return tl; } +ANN static inline uint get_n(struct td_checker *tdc, const char c) { + uint n = 0; + while(*tdc->str == c) { + n++; + ++tdc->str; + } + return n; +} + ANN static Type_Decl* _str2td(const Gwion gwion, struct td_checker *tdc) { + const uint ref = get_n(tdc, '&'); DECL_OO(const Symbol, sym, = __str2sym(gwion, tdc)) struct AC ac = { .str = tdc->str, .pos=tdc->pos }; CHECK_BO(ac_run(gwion, &ac)) @@ -182,6 +192,7 @@ ANN static Type_Decl* _str2td(const Gwion gwion, struct td_checker *tdc) { Type_List tl = td_tmpl(gwion, tdc); if(tl == (Type_List)GW_ERROR) return NULL; + const uint option = get_n(tdc, '?'); Type_Decl *next = NULL; if(*tdc->str == '.') { ++tdc->str; @@ -196,6 +207,8 @@ ANN static Type_Decl* _str2td(const Gwion gwion, struct td_checker *tdc) { Type_Decl *td = new_type_decl(gwion->mp, sym, tdc->pos); td->next = next; td->types = tl; + td->option = option; + td->ref = ref; if(ac.depth) td->array = mk_array(gwion->mp, &ac); return td; @@ -224,7 +237,7 @@ struct td_info { }; ANN static void td_fullname(const Env env, GwText *text, const Type t) { - const Type owner = t->info->owner_class; + const Type owner = t->info->value->from->owner_class; if(owner) { td_fullname(env, text, owner); text_add(text, "."); @@ -245,8 +258,9 @@ 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) { - td_fullname(gwion->env, &text, t->info->owner_class); + const Type owner = t->info->value->from->owner_class; + if(owner) { + td_fullname(gwion->env, &text, owner); text_add(&text, "."); } text_add(&text, t->name); diff --git a/src/lib/array.c b/src/lib/array.c index b0d4172b..06a3b578 100644 --- a/src/lib/array.c +++ b/src/lib/array.c @@ -426,6 +426,61 @@ static OP_EMIT(opem_array_access) { return exp ? emit_array_access(emit, info) : GW_ERROR; } +static m_bit map_byte[BYTECODE_SZ*4];// = { eOP_MAX, test }; +static const struct VM_Code_ map_run_code = { + .name = "map_run_code", + .stack_depth = SZ_INT, + .bytecode = map_byte +}; + +#define MAP_CODE_OFFSET SZ_INT*10 +static INSTR(test) { + *(VM_Code*)(shred->reg) = (*(VM_Code*)MEM(SZ_INT)); + *(VM_Code*)(shred->reg + SZ_INT) = 0; + PUSH_REG(shred, SZ_INT); + const M_Object self = *(M_Object*)MEM(0); + const M_Vector array = ARRAY(self); + const m_uint index = *(m_uint*)MEM(SZ_INT*5); + shred->pc++; + (*(m_uint*)MEM(SZ_INT*5))++; // increment the index + shred->mem += MAP_CODE_OFFSET; // work in a safe memory space + *(m_uint*)(shred->reg + SZ_INT) = 0; + *(m_uint*)(shred->mem-SZ_INT) = 0; + *(m_uint*)(shred->mem-SZ_INT*2) = 0; + *(VM_Code*)(shred->mem-SZ_INT*3) = (VM_Code)&map_run_code; + m_vector_get(array, index, &*(m_bit**)(shred->mem + SZ_INT*5)); +} + +static INSTR(test2) { + shred->mem -= MAP_CODE_OFFSET; + const M_Object ret_obj = *(M_Object*)MEM(SZ_INT*2); + const M_Vector array = ARRAY(ret_obj); + POP_REG(shred, ARRAY_SIZE(array)); + POP_REG(shred, SZ_INT); + const m_uint index = *(m_uint*)MEM(SZ_INT*5); + const m_uint size = m_vector_size(array); + m_vector_set(array, index - 1, &*(m_bit**)(shred->reg + SZ_INT)); + if(index == size) { + shred->pc = *(m_uint*)MEM(SZ_INT*3); + shred->code = *(VM_Code*)MEM(SZ_INT*4); + *(M_Object*)(shred->reg) = ret_obj; + shred->reg += SZ_INT; + } else + shred->pc = 0; + shredule(shred->tick->shreduler, shred, 0); +} + +static MFUN(vm_vector_map) { + const VM_Code code = *(VM_Code*)REG(SZ_INT*2); + const M_Object ret = *(M_Object*)MEM(SZ_INT*2) = *(M_Object*)RETURN = new_array(shred->info->vm->gwion->mp, (Type)vector_front(&code->tmpl_types), ARRAY_LEN(ARRAY(o))); + vector_add(&shred->gc, (m_uint)ret); + *(m_uint*)MEM(SZ_INT*3) = shred->pc; + *(VM_Code*)MEM(SZ_INT*4) = shred->code; + shred->code = (VM_Code)&map_run_code; + shred->pc = 0; + shredule(shred->tick->shreduler, shred, 0); +} + ANN /*static */Symbol array_sym(const Env env, const Type src, const m_uint depth); #include "template.h" static OP_CHECK(opck_array_scan) { @@ -435,7 +490,7 @@ static OP_CHECK(opck_array_scan) { 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); + const Type type = nspc_lookup_type1(base->info->value->from->owner, sym); if(type) return type; const Class_Def cdef = cpy_class_def(env->gwion->mp, c); @@ -444,8 +499,8 @@ static OP_CHECK(opck_array_scan) { 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 Context ctx = env->context; - env->context = base->info->ctx; - const m_uint scope = env_push(env, base->info->owner_class, base->info->owner); + env->context = base->info->value->from->ctx; + const m_uint scope = env_push(env, base->info->value->from->owner_class, base->info->value->from->owner); (void)scan0_class_def(env, cdef); const Type t = cdef->base.type; (void)traverse_cdef(env, t); @@ -469,6 +524,7 @@ static OP_CHECK(opck_array_scan) { 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); builtin_func(env->gwion->mp, (Func)vector_at(&t->nspc->info->vtable, 5), vm_vector_random); + builtin_func(env->gwion->mp, (Func)vector_at(&t->nspc->info->vtable, 6), vm_vector_map); 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); @@ -488,7 +544,18 @@ static OP_CHECK(opck_array_implicit) { return imp->t; } +static void prepare_map_run(void) { + *(unsigned*)map_byte = eOP_MAX; + *(f_instr*)(map_byte + SZ_INT*2) = test; + *(unsigned*)(map_byte+ BYTECODE_SZ) = eSetCode; + *(m_uint*)(map_byte + BYTECODE_SZ + SZ_INT*2) = 3; + *(unsigned*)(map_byte+ BYTECODE_SZ*2) = eOverflow; + *(unsigned*)(map_byte+ BYTECODE_SZ*3) = eOP_MAX; + *(f_instr*)(map_byte + BYTECODE_SZ*3 + SZ_INT*2) = test2; +} + GWION_IMPORT(array) { + prepare_map_run(); 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); @@ -497,6 +564,10 @@ GWION_IMPORT(array) { GWI_BB(gwi_item_ini(gwi, "@internal", "@ctor_data")) GWI_BB(gwi_item_end(gwi, 0, num, 0)) + GWI_BB(gwi_fptr_ini(gwi, "A", "map_t:[A]")) + GWI_BB(gwi_func_arg(gwi, "T", "elem")) + GWI_BB(gwi_fptr_end(gwi, ae_flag_global)) + // put functions using T first GWI_BB(gwi_func_ini(gwi, "bool", "remove")) GWI_BB(gwi_func_arg(gwi, "int", "index")) @@ -518,6 +589,10 @@ GWION_IMPORT(array) { GWI_BB(gwi_func_ini(gwi, "T", "random")) GWI_BB(gwi_func_end(gwi, vm_vector_random, ae_flag_none)) + GWI_BB(gwi_func_ini(gwi, "A[]", "map:[A]")) + GWI_BB(gwi_func_arg(gwi, "map_t:[A]", "data")) + GWI_BB(gwi_func_end(gwi, vm_vector_map, ae_flag_none)) + GWI_BB(gwi_class_end(gwi)) GWI_BB(gwi_oper_ini(gwi, "Array", "Array", NULL)) diff --git a/src/lib/instr.c b/src/lib/instr.c index c4f63f43..a8b91321 100644 --- a/src/lib/instr.c +++ b/src/lib/instr.c @@ -55,6 +55,12 @@ ANN static Func_Def traverse_tmpl(const Emitter emit, struct dottmpl_ *const dt, INSTR(GTmpl) { struct dottmpl_ *dt = (struct dottmpl_*)instr->m_val; const Func f = *(Func*)REG(-SZ_INT); + if(!f) + Except(shred, _("EmptyFuncPointerException")); +if(f->code) { + *(VM_Code*)(shred->reg -SZ_INT) = f->code; + return; +} const m_str name = f->name; const Emitter emit = shred->info->vm->gwion->emit; emit->env->name = "runtime"; diff --git a/src/lib/lib_func.c b/src/lib/lib_func.c index 93e08f06..30fb15ea 100644 --- a/src/lib/lib_func.c +++ b/src/lib/lib_func.c @@ -49,25 +49,40 @@ struct FptrInfo { const loc_t pos; }; +ANN static void _fptr_tmpl_push(const Env env, const Func f) { + ID_List il = f->def->base->tmpl ? f->def->base->tmpl->list : NULL; + if(il) { + Type_List tl = f->def->base->tmpl->call; + while(il) { + const Type t = tl ? known_type(env, tl->td) : env->gwion->type[et_auto]; + nspc_add_type(env->curr, il->xid, t); + il = il->next; + if(tl) + tl = tl->next; + } + } +} + ANN static m_bool fptr_tmpl_push(const Env env, struct FptrInfo *info) { if(!info->rhs->def->base->tmpl) return GW_OK; - ID_List t0 = info->lhs->def->base->tmpl->list, - 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_auto]); - nspc_add_type(env->curr, t1->xid, env->gwion->type[et_auto]); - t0 = t0->next; - t1 = t1->next; - } +// Type owner = info->rhs->value_ref->from->owner_class; +// while(owner) { +// owner = owner->info->value->from->owner_class; +// } + +// _fptr_tmpl_push(env, info->lhs); + _fptr_tmpl_push(env, info->rhs); return GW_OK; } static m_bool td_match(const Env env, Type_Decl *id[2]) { DECL_OB(const Type, t0, = known_type(env, id[0])) DECL_OB(const Type, t1, = known_type(env, id[1])) - return isa(t0, t1); + if(isa(t0, t1) > 0) + return GW_OK; + return t1 == env->gwion->type[et_auto]; } ANN static m_bool fptr_args(const Env env, Func_Base *base[2]) { @@ -83,8 +98,8 @@ ANN static m_bool fptr_args(const Env env, Func_Base *base[2]) { } ANN static m_bool fptr_check(const Env env, struct FptrInfo *info) { - if(!info->lhs->def->base->tmpl != !info->rhs->def->base->tmpl) - return GW_ERROR; +// if(!info->lhs->def->base->tmpl != !info->rhs->def->base->tmpl) +// return GW_ERROR; const Type l_type = info->lhs->value_ref->from->owner_class; const Type r_type = info->rhs->value_ref->from->owner_class; if(!r_type && l_type) @@ -122,20 +137,24 @@ ANN static Type fptr_type(const Env env, struct FptrInfo *info) { for(m_uint i = 0; i <= v->from->offset && !type; ++i) { const Symbol sym = (!info->lhs->def->base->tmpl || i != 0) ? func_symbol(env, nspc->name, c, stmpl, i) : info->lhs->def->base->xid; - if(!is_class(env->gwion, info->lhs->value_ref->type)) - CHECK_OO((info->lhs = nspc_lookup_func1(nspc, sym))) - else { + if(!is_class(env->gwion, info->lhs->value_ref->type)) { + if(!(info->lhs = nspc_lookup_func1(nspc, sym))) { + const Value v = nspc_lookup_value1(nspc, insert_symbol(c)); + if(isa(v->type, env->gwion->type[et_function]) < 0) + return NULL; + info->lhs = v->type->info->func; + } + } else { DECL_OO(const Type, t, = nspc_lookup_type1(nspc, info->lhs->def->base->xid)) info->lhs = actual_type(env->gwion, t)->info->func; } Func_Base *base[2] = { info->lhs->def->base, info->rhs->def->base }; - if(fptr_tmpl_push(env, info) > 0) { - if(fptr_rettype(env, info) > 0 && - fptr_arity(info) && fptr_args(env, base) > 0) + CHECK_BO(fptr_tmpl_push(env, info)) + if(fptr_rettype(env, info) > 0 && + fptr_arity(info) && fptr_args(env, base) > 0) type = actual_type(env->gwion, info->lhs->value_ref->type) ?: info->lhs->value_ref->type; - if(info->rhs->def->base->tmpl) - nspc_pop_type(env->gwion->mp, env->curr); - } + if(info->rhs->def->base->tmpl) + nspc_pop_type(env->gwion->mp, env->curr); } return type; } @@ -143,16 +162,18 @@ ANN static Type fptr_type(const Env env, struct FptrInfo *info) { ANN static m_bool _check_lambda(const Env env, Exp_Lambda *l, const Func_Def def) { Arg_List base = def->base->args, arg = l->def->base->args; while(base && arg) { - arg->td = base->td; +// arg->td = base->td; + arg->td = type2td(env->gwion, known_type(env, base->td), exp_self(l)->pos); +// arg->type = known_type(env, base->td); base = base->next; arg = arg->next; } if(base || arg) ERR_B(exp_self(l)->pos, _("argument number does not match for lambda")) l->def->base->flag = def->base->flag; - if(GET_FLAG(def->base, global) && !l->owner && def->base->func->value_ref->from->owner_class) +// if(GET_FLAG(def->base, global) && !l->owner && def->base->func->value_ref->from->owner_class) UNSET_FLAG(l->def->base, global); - l->def->base->td = cpy_type_decl(env->gwion->mp, def->base->td); + l->def->base->td = type2td(env->gwion, known_type(env, def->base->td), exp_self(l)->pos); l->def->base->values = env->curr->info->value; const m_bool ret = traverse_func_def(env, l->def); if(l->def->base->func) { @@ -161,18 +182,13 @@ ANN static m_bool _check_lambda(const Env env, Exp_Lambda *l, const Func_Def def env->curr->info->value = l->def->base->values; } } - arg = l->def->base->args; - while(arg) { - arg->td = NULL; - arg = arg->next; - } return ret; } ANN m_bool check_lambda(const Env env, const Type t, Exp_Lambda *l) { const Func_Def fdef = t->info->func->def; if(!GET_FLAG(t->info->func->value_ref, global)) - l->owner = t->info->owner_class; + l->owner = t->info->value->from->owner_class; CHECK_BB(_check_lambda(env, l, fdef)) exp_self(l)->type = l->def->base->func->value_ref->type; return GW_OK; @@ -182,7 +198,7 @@ ANN static m_bool fptr_do(const Env env, struct FptrInfo *info) { if(isa(info->exp->type, env->gwion->type[et_lambda]) < 0) { CHECK_BB(fptr_check(env, info)) if(!(info->exp->type = fptr_type(env, info))) - ERR_B(info->lhs->def->base->pos, _("no match found")) + ERR_B(info->pos, _("no match found")) return GW_OK; } Exp_Lambda *l = &info->exp->d.exp_lambda; diff --git a/src/lib/object_op.c b/src/lib/object_op.c index 31a4382c..7f3604bb 100644 --- a/src/lib/object_op.c +++ b/src/lib/object_op.c @@ -275,11 +275,11 @@ ANN Type scan_class(const Env env, const Type t, const Type_Decl *td) { return exists != env->gwion->type[et_error] ? exists : NULL; struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)scan0_cdef, .scope=env->scope->depth, .flag=tflag_scan0 }; - const Type _t = known_type(env, td->types->td); - CHECK_BO(envset_push(&es, _t->info->owner_class, _t->info->owner)) + const Type owner = t->info->value->from->owner_class; + CHECK_BO(envset_push(&es, owner, t->info->value->from->owner)) const Type ret = _scan_class(env, &info); if(es.run) - envset_pop(&es, _t->info->owner_class); + envset_pop(&es, owner); return ret; } diff --git a/src/lib/ptr.c b/src/lib/ptr.c index ebd6eb51..b981136f 100644 --- a/src/lib/ptr.c +++ b/src/lib/ptr.c @@ -23,6 +23,7 @@ static m_bool ptr_access(const Env env, const Exp e) { } ANN static inline Type ptr_base(const Env env, const Type t) { + return (Type)vector_front(&t->info->tuple->types); return known_type(env, t->info->cdef->base.tmpl->call->td); } @@ -81,9 +82,6 @@ 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 = imp->t; - if(!tflag(t, tflag_check)) - CHECK_BN(traverse_class_def(env, t->info->cdef)) return imp->t; } return NULL; @@ -136,17 +134,29 @@ static DTOR(ptr_object_dtor) { static DTOR(ptr_struct_dtor) { const Type base = *(Type*)(shred->mem + SZ_INT); - const m_uint scope = env_push(shred->info->vm->gwion->env, base->info->owner_class, base->info->owner); + const m_uint scope = env_push(shred->info->vm->gwion->env, base->info->value->from->owner_class, base->info->value->from->owner); const Type t = known_type(shred->info->vm->gwion->env, base->info->cdef->base.tmpl->call->td); env_pop(shred->info->vm->gwion->env, scope); struct_release(shred, t, *(m_bit**)o); } - +#include "tmpl_info.h" 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->info->cdef->base.tmpl->call->td); + struct tmpl_info info = { .base=ts->t, .td=ts->td, .list=ts->t->info->cdef->base.tmpl->list }; + const Type exists = tmpl_exists(env, &info); + if(exists) + return exists != env->gwion->type[et_error] ? exists : NULL; + const Type base = known_type(env, ts->td->types->td); + const Type t = new_type(env->gwion->mp, s_name(info.name), base); t->info->parent = env->gwion->type[et_ptr]; + SET_FLAG(t, abstract | ae_flag_final); + t->info->tuple = new_tupleform(env->gwion->mp, NULL); + t->nspc = new_nspc(env->gwion->mp, t->name); + vector_add(&t->info->tuple->types, (m_uint)base); + const m_uint scope = env_push(env, base->info->value->from->owner_class, base->info->value->from->owner); + mk_class(env, t, (loc_t){}); + env_pop(env, scope); + nspc_add_type_front(t->info->value->from->owner, info.name, t); if(isa(base, env->gwion->type[et_compound]) > 0) { t->nspc->dtor = new_vmcode(env->gwion->mp, NULL, SZ_INT, 1, "@PtrDtor"); if(!tflag(base, tflag_struct)) diff --git a/src/lib/ref.c b/src/lib/ref.c index cf0149a6..7bb9ce83 100644 --- a/src/lib/ref.c +++ b/src/lib/ref.c @@ -61,17 +61,14 @@ OP_CHECK(opck_foreach_scan) { return exists != env->gwion->type[et_error] ? exists : NULL; const Type base = known_type(env, ts->td->types->td); const Type t = new_type(env->gwion->mp, s_name(info.name), base); - t->info->owner = base->info->owner; - t->info->owner_class = base->info->owner_class; - t->info->ctx = base->info->ctx; SET_FLAG(t, abstract | ae_flag_final); set_tflag(t, tflag_infer); - const m_uint scope = env_push(env, base->info->owner_class, base->info->owner); -// mk_class(env, t, (loc_t){}); + const m_uint scope = env_push(env, base->info->value->from->owner_class, base->info->value->from->owner); + mk_class(env, t, (loc_t){}); base2ref(env, base, t); ref2base(env, t, base); env_pop(env, scope); - nspc_add_type_front(t->info->owner, info.name, t); + nspc_add_type_front(t->info->value->from->owner, info.name, t); return t; } diff --git a/src/parse/check.c b/src/parse/check.c index f5639c5c..48804f06 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -720,7 +720,7 @@ ANN m_bool func_check(const Env env, Exp_Call *const exp) { ERR_B(exp->func->pos, _("Can't call late function pointer at declaration site")) const Type t = actual_type(env->gwion, exp->func->type); if(isa(t, env->gwion->type[et_function]) > 0 && - exp->func->exp_type == ae_exp_dot && !t->info->owner_class) { + exp->func->exp_type == ae_exp_dot && !t->info->value->from->owner_class) { if(exp->args) CHECK_OB(check_exp(env, exp->args)) return call2ufcs(env, exp, t->info->func->value_ref) ? @@ -1421,7 +1421,7 @@ ANN m_bool check_abstract(const Env env, const Class_Def cdef) { bool err = false; 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)) { + if(f && GET_FLAG(f->def->base, abstract)) { if(!err) { err = true; gwerr_basic( @@ -1445,8 +1445,8 @@ ANN m_bool check_class_def(const Env env, const Class_Def cdef) { struct Op_Import opi = { .op=insert_symbol("@class_check"), .lhs=t, .data=(uintptr_t)cdef, .pos=cdef->pos }; CHECK_OB(op_check(env, &opi)) - if(t->info->owner_class) - CHECK_BB(ensure_check(env, t->info->owner_class)) + if(t->info->value->from->owner_class) + CHECK_BB(ensure_check(env, t->info->value->from->owner_class)) if(tflag(t, tflag_check)) return GW_OK; set_tflag(t, tflag_check); diff --git a/src/parse/func_resolve_tmpl.c b/src/parse/func_resolve_tmpl.c index d75db3b1..75ab3efd 100644 --- a/src/parse/func_resolve_tmpl.c +++ b/src/parse/func_resolve_tmpl.c @@ -35,10 +35,15 @@ ANN static inline m_bool tmpl_valid(const Env env, const Func_Def fdef) { ANN static Func ensure_tmpl(const Env env, const Func_Def fdef, Exp_Call *const exp) { if(!tmpl_valid(env, fdef)) return NULL; + if(exp->args && !exp->args->type) + return NULL; const Func f = fdef->base->func; const Func next = f->next; f->next = NULL; + const Tmpl tmpl = { .list=fdef->base->tmpl->list, .call=exp->tmpl->call }; + CHECK_BO(template_push_types(env, &tmpl)); const Func func = find_func_match(env, f, exp); + nspc_pop_type(env->gwion->mp, env->curr); f->next = next; if(func) set_fflag(func, fflag_tmpl | fflag_valid); @@ -84,14 +89,16 @@ ANN static Func create_tmpl(const Env env, struct ResolverArgs* ra, const m_uint const Value value = template_get_ready(env, ra->v, "template", i); if(!value) return NULL; + const Func_Def fdef = (Func_Def)cpy_func_def(env->gwion->mp, value->d.func_ref->def); if(vflag(ra->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); fdef->base->tmpl->call = cpy_type_list(env->gwion->mp, ra->types); fdef->base->tmpl->base = i; const Func func = ensure_tmpl(env, fdef, ra->e); if(!func && !fdef->base->func) free_func_def(env->gwion->mp, fdef); + if(func && vflag(ra->v, vflag_builtin)) + set_vflag(func->value_ref, vflag_builtin); return func; } @@ -115,11 +122,18 @@ ANN static Func find_tmpl(const Env env, const Value v, Exp_Call *const exp, con struct ResolverArgs ra = {.v = v, .e = exp, .tmpl_name = tmpl_name, .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); +if(v->from->owner_class && v->from->owner_class->info->cdef->base.tmpl) +(void)template_push_types(env, v->from->owner_class->info->cdef->base.tmpl); +//const Tmpl tmpl = { .list=v->frombase->tmpl->list, .call=ra->types }; +//CHECK_BO(template_push_types(env, &tmpl)); const Func m_func = !is_fptr(env->gwion, v->type) ? func_match(env, &ra) :fptr_match(env, &ra); +if(v->from->owner_class && v->from->owner_class->info->cdef->base.tmpl) +nspc_pop_type(env->gwion->mp, env->curr); +//nspc_pop_type(env->gwion->mp, env->curr); + env_pop(env, scope); if(es.run) envset_pop(&es, v->from->owner_class); - env_pop(env, scope); env->func = former; return m_func; } diff --git a/src/parse/scan0.c b/src/parse/scan0.c index 9c743131..039b1c3d 100644 --- a/src/parse/scan0.c +++ b/src/parse/scan0.c @@ -22,9 +22,7 @@ static inline void context_global(const Env env) { } static inline Type scan0_type(const Env env, const m_str name, const Type t) { - const Type type = new_type(env->gwion->mp, name, t); - type->info->ctx = env->context; - return type; + return new_type(env->gwion->mp, name, t); } ANN static inline m_bool scan0_defined(const Env env, const Symbol s, const loc_t pos) { @@ -69,22 +67,23 @@ ANN m_bool scan0_fptr_def(const Env env, const Fptr_Def fptr) { CHECK_BB(scan0_defined(env, fptr->base->xid, fptr->base->td->pos)); const m_str name = s_name(fptr->base->xid); const Type t = scan0_type(env, name, env->gwion->type[et_fptr]); - t->info->owner = !(!env->class_def && GET_FLAG(fptr->base, global)) ? - env->curr : env->global_nspc; - t->info->owner_class = env->class_def; - if(GET_FLAG(fptr->base, global)) - context_global(env); + const bool global = !env->class_def && GET_FLAG(fptr->base, global); t->nspc = new_nspc(env->gwion->mp, name); t->flag |= fptr->base->flag; fptr->type = t; + if(global) { + context_global(env); + env_push_global(env); + } fptr->value = mk_class(env, t, fptr->base->pos); + if(global) + env_pop(env, 0); valuefrom(env, fptr->value->from, fptr->base->pos); fptr_def(env, fptr); if(env->class_def) fptr_assign(env, fptr); set_vflag(fptr->value, vflag_func); - add_type(env, t->info->owner, t); - mk_class(env, t, fptr->base->pos); + add_type(env, t->info->value->from->owner, t); type_addref(t); return GW_OK; } @@ -119,14 +118,13 @@ ANN static void typedef_simple(const Env env, const Type_Def tdef, const Type ba if(GET_FLAG(tdef->ext, global)) context_global(env); add_type(env, nspc, t); - t->info->owner = nspc; - t->info->owner_class = env->class_def; tdef->type = t; if(base->nspc) nspc_addref((t->nspc = base->nspc)); t->flag = tdef->ext->flag; if(tdef->ext->array && !tdef->ext->array->exp) set_tflag(t, tflag_empty); + mk_class(env, tdef->type, tdef->pos); } ANN static m_bool typedef_complex(const Env env, const Type_Def tdef, const Type base) { @@ -136,13 +134,13 @@ ANN static m_bool typedef_complex(const Env env, const Type_Def tdef, const Type CHECK_BB(scan0_class_def(env, cdef)) tdef->type = cdef->base.type; cdef->base.tmpl = tdef->tmpl;// check cpy + mk_class(env, tdef->type, tdef->pos); return GW_OK; } ANN static void typedef_fptr(const Env env, const Type_Def tdef, const Type base) { tdef->type = type_copy(env->gwion->mp, base); tdef->type->info->func = base->info->func; - nspc_addref(tdef->type->nspc); tdef->type->name = s_name(tdef->xid); tdef->type->info->parent = base; add_type(env, env->curr, tdef->type); @@ -155,6 +153,11 @@ ANN m_bool scan0_type_def(const Env env, const Type_Def tdef) { CHECK_BB(env_access(env, tdef->ext->flag, tdef->ext->pos)) DECL_OB(const Type, base, = tdef->tmpl ? find_type(env, tdef->ext) : known_type(env, tdef->ext)) CHECK_BB(scan0_defined(env, tdef->xid, tdef->ext->pos)) + const bool global = GET_FLAG(tdef->ext, global); // TODO: handle global in class + if(global) { + context_global(env); + env_push_global(env); + } if(isa(base, env->gwion->type[et_function]) < 0) { if(!tdef->ext->types && (!tdef->ext->array || !tdef->ext->array->exp)) typedef_simple(env, tdef, base); @@ -164,6 +167,8 @@ ANN m_bool scan0_type_def(const Env env, const Type_Def tdef) { typedef_fptr(env, tdef, base); if(!tdef->distinct && !tdef->when) scan0_implicit_similar(env, tdef->type, base); + if(global) + env_pop(env, 0); set_tflag(tdef->type, tflag_typedef); return GW_OK; } @@ -185,11 +190,15 @@ ANN static Type enum_type(const Env env, const Enum_Def edef) { const Symbol sym = scan0_sym(env, "enum", edef->pos); t->name = edef->xid ? s_name(edef->xid) : s_name(sym); t->info->parent = env->gwion->type[et_int]; - const Nspc nspc = GET_FLAG(edef, global) ? env->global_nspc : env->curr; - t->info->owner = nspc; - t->info->owner_class = env->class_def; - add_type(env, nspc, t); + const bool global = GET_FLAG(edef, global); // TODO: handle global in class + if(global) { + context_global(env); + env_push_global(env); + } + add_type(env, env->curr, t); mk_class(env, t, edef->pos); + if(global) + env_pop(env, 0); // scan0_implicit_similar(env, t, env->gwion->type[et_int]); return t; } @@ -215,8 +224,7 @@ ANN static Type union_type(const Env env, const Symbol s, const loc_t loc) { const m_str name = s_name(s); const Type t = new_type(env->gwion->mp, name, env->gwion->type[et_union]); t->nspc = new_nspc(env->gwion->mp, name); - t->info->owner = t->nspc->parent = env->curr; - t->info->owner_class = env->class_def; + t->nspc->parent = env->curr; t->info->tuple = new_tupleform(env->gwion->mp, NULL); // ??? add_type(env, env->curr, t); mk_class(env, t, loc); @@ -241,8 +249,11 @@ ANN static void union_tmpl(const Env env, const Union_Def udef) { ANN m_bool scan0_union_def(const Env env, const Union_Def udef) { CHECK_BB(env_storage(env, udef->flag, udef->pos)) CHECK_BB(scan0_global(env, udef->flag, udef->pos)) - const m_uint scope = !GET_FLAG(udef, global) ? env->scope->depth : - env_push_global(env); + const bool global = GET_FLAG(udef, global); // TODO: handle global in class + if(global) { + context_global(env); + env_push_global(env); + } if(GET_FLAG(udef, global)) context_global(env); CHECK_BB(scan0_defined(env, udef->xid, udef->pos)) @@ -254,8 +265,8 @@ ANN m_bool scan0_union_def(const Env env, const Union_Def udef) { SET_ACCESS(udef, udef->type); if(udef->tmpl) union_tmpl(env, udef); - if(GET_FLAG(udef, global)) - env_pop(env, scope); + if(global) + env_pop(env, 0); set_tflag(udef->type, tflag_scan0); return GW_OK; } @@ -280,7 +291,7 @@ ANN static Type get_parent_base(const Env env, Type_Decl *td) { while(owner) { if(t == owner) ERR_O(td->pos, _("'%s' as parent inside itself\n."), owner->name); - owner = owner->info->owner_class; + owner = owner->info->value->from->owner_class; } return t; } @@ -318,13 +329,11 @@ ANN static Type scan0_class_def_init(const Env env, const Class_Def cdef) { 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; t->nspc = new_nspc(env->gwion->mp, t->name); t->nspc->parent = env->curr; t->info->cdef = cdef; t->flag |= cdef->flag; - add_type(env, t->info->owner, t); +// add_type(env, t->info->value->from->owner, t); cdef_flag(cdef, t); if(cdef->base.ext && cdef->base.ext->array) set_tflag(t, tflag_typedef); @@ -364,9 +373,10 @@ 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_tflag(cdef->base.type, tflag_scan0); + (void)mk_class(env, cdef->base.type, cdef->pos); + add_type(env, cdef->base.type->info->value->from->owner, cdef->base.type); if(cdef->body) CHECK_BB(env_body(env, cdef, scan0_section)) - (void)mk_class(env, cdef->base.type, cdef->pos); return GW_OK; } diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 683cda1e..62e507c6 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -19,7 +19,7 @@ ANN static inline m_bool type_cyclic(const Env env, const Type t, const Type_Dec ERR_B(td->pos, _("%s declared inside %s"), t->name, owner->name); parent = parent->info->parent; } - } while((owner = owner->info->owner_class)); + } while((owner = owner->info->value->from->owner_class)); return GW_OK; } @@ -52,7 +52,7 @@ 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(GET_FLAG(t, private) && t->info->owner != env->curr) + if(GET_FLAG(t, private) && t->info->value->from->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)) ERR_O(exp_self(decl)->pos, _("can't use protected type %s"), t->name) @@ -134,7 +134,7 @@ ANN m_bool scan1_exp_decl(const Env env, const Exp_Decl* decl) { if(global) { if(env->context) env->context->global = 1; - if(!is_global(decl->type->info->owner, env->global_nspc)) + if(!is_global(decl->type->info->value->from->owner, env->global_nspc)) ERR_B(exp_self(decl)->pos, _("type '%s' is not global"), decl->type->name) } const m_uint scope = !global ? env->scope->depth : env_push_global(env); @@ -332,7 +332,7 @@ ANN m_bool scan1_enum_def(const Env env, const Enum_Def edef) { set_vflag(v, vflag_builtin); SET_FLAG(v, const); set_vflag(v, vflag_valid); - nspc_add_value(edef->t->info->owner, list->xid, v); + nspc_add_value(edef->t->info->value->from->owner, list->xid, v); vector_add(&edef->values, (vtype)v); } while((list = list->next)); return GW_OK; @@ -643,8 +643,8 @@ ANN m_bool scan1_class_def(const Env env, const Class_Def cdef) { if(tflag(t, tflag_scan1)) return GW_OK; set_tflag(t, tflag_scan1); - if(t->info->owner_class) - CHECK_BB(ensure_scan1(env, t->info->owner_class)) + if(t->info->value->from->owner_class) + CHECK_BB(ensure_scan1(env, t->info->value->from->owner_class)) 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 1cdc281a..ef55a3ce 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -303,8 +303,6 @@ ANN static Type func_type(const Env env, const Func func) { const Type t = type_copy(env->gwion->mp, base); t->info->parent = base; t->name = func->name; - t->info->owner = env->curr; - t->info->owner_class = env->class_def; t->info->func = func; return t; } @@ -312,7 +310,7 @@ ANN static Type func_type(const Env env, const Func func) { ANN2(1,2) static Value func_value(const Env env, const Func f, const Value overload) { const Type t = func_type(env, f); - const Value v = new_value(env->gwion->mp, t, t->name); + const Value v = t->info->value = new_value(env->gwion->mp, t, t->name); valuefrom(env, v->from, f->def->base->pos); CHECK_OO(scan2_func_assign(env, f->def, f, v)) if(!overload) { @@ -511,7 +509,7 @@ static inline int is_cpy(const Func_Def fdef) { } ANN m_bool scan2_func_def(const Env env, const Func_Def fdef) { - if(GET_FLAG(fdef->base, global)) + if(GET_FLAG(fdef->base, global) && !env->class_def) env->context->global = 1; const Func_Def f = !is_cpy(fdef) ? fdef : scan2_cpy_fdef(env, fdef); @@ -562,8 +560,8 @@ ANN m_bool scan2_class_def(const Env env, const Class_Def cdef) { const Type t = cdef->base.type; if(tflag(t, tflag_scan2)) return GW_OK; - if(t->info->owner_class) - CHECK_BB(ensure_scan2(env, t->info->owner_class)) + if(t->info->value->from->owner_class) + CHECK_BB(ensure_scan2(env, t->info->value->from->owner_class)) set_tflag(t, tflag_scan2); if(cdef->base.ext) CHECK_BB(cdef_parent(env, cdef)) diff --git a/src/parse/template.c b/src/parse/template.c index fe787642..6d5610b4 100644 --- a/src/parse/template.c +++ b/src/parse/template.c @@ -28,8 +28,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->info->owner_class) - CHECK_BB(template_push(env, t->info->owner_class)) + if(t->info->value->from->owner_class) + CHECK_BB(template_push(env, t->info->value->from->owner_class)) if(tflag(t, tflag_tmpl)) return push_types(env, t->info->cdef->base.tmpl); // incorrect return GW_OK; @@ -55,16 +55,17 @@ ANN Tmpl* mk_tmpl(const Env env, const Tmpl *tm, const Type_List types) { static ANN Type scan_func(const Env env, const Type t, const Type_Decl* td) { DECL_OO(const m_str, tl_name, = tl2str(env->gwion, td->types, td->pos)) - const Symbol sym = func_symbol(env, t->info->owner->name, t->info->func->name, tl_name, 0); + const Symbol sym = func_symbol(env, t->info->value->from->owner->name, t->info->func->name, tl_name, 0); free_mstr(env->gwion->mp, tl_name); - const Type base_type = nspc_lookup_type1(t->info->owner, sym); + const Type base_type = nspc_lookup_type1(t->info->value->from->owner, sym); if(base_type) return base_type; const Type ret = type_copy(env->gwion->mp, t); ret->info->parent = t; + ret->info->value = t->info->func->value_ref; ret->name = s_name(sym); set_tflag(ret, tflag_ftmpl); - nspc_add_type_front(t->info->owner, sym, ret); + nspc_add_type_front(t->info->value->from->owner, sym, ret); void* func_ptr = t->info->func->def->d.dl_func_ptr; if(vflag(t->info->func->value_ref, vflag_builtin)) t->info->func->def->d.dl_func_ptr = NULL; @@ -75,12 +76,12 @@ static ANN Type scan_func(const Env env, const Type t, const Type_Decl* td) { if(vflag(t->info->func->value_ref, vflag_member)) set_vflag(value, vflag_member); value->d.func_ref = func; - value->from->owner = t->info->owner; - value->from->owner_class = t->info->owner_class; + value->from->owner = t->info->value->from->owner; +// value->from->owner_class = t->info->owner_class; func->value_ref = value; func->def->base->tmpl = mk_tmpl(env, t->info->func->def->base->tmpl, td->types); def->base->func = func; - nspc_add_value_front(t->info->owner, sym, value); + nspc_add_value_front(t->info->value->from->owner, sym, value); if(vflag(t->info->func->value_ref, vflag_builtin)) { builtin_func(env->gwion->mp, func, func_ptr); t->info->func->def->d.dl_func_ptr = func_ptr; diff --git a/src/parse/type_decl.c b/src/parse/type_decl.c index 712ad571..c9617e3e 100644 --- a/src/parse/type_decl.c +++ b/src/parse/type_decl.c @@ -34,7 +34,8 @@ ANN static Type resolve(const Env env, Type_Decl* td) { last = last->next; Array_Sub array = last->array; DECL_OO(const Type, base, = find_type(env, td)) - if(base->info->ctx && base->info->ctx->error) + const Context ctx = base->info->value->from->ctx; + if(ctx && ctx->error) ERR_O(td->pos, _("type '%s' is invalid"), base->name) DECL_OO(const Type, type, = scan_type(env, base, td)) const Type t = !td->ref ? type : ref(env, td); diff --git a/src/vm/vm_code.c b/src/vm/vm_code.c index f30e1a1b..3581d1bd 100644 --- a/src/vm/vm_code.c +++ b/src/vm/vm_code.c @@ -32,7 +32,8 @@ ANN void free_vmcode(VM_Code a, Gwion gwion) { free_code_instr(a->instr, gwion); } free_vector(gwion->mp, a->instr); - } + } else if(a->tmpl_types.ptr) + vector_release(&a->tmpl_types); free_mstr(gwion->mp, a->name); mp_free(gwion->mp , VM_Code, a); } diff --git a/tests/tree/class_template.gw b/tests/tree/class_template.gw index 5dbed0f8..2b8ecd53 100644 --- a/tests/tree/class_template.gw +++ b/tests/tree/class_template.gw @@ -3,6 +3,7 @@ class C:[A,B] { var B b; fun A test() { <<< "lol" >>>; + return a; } fun void test2:[C](C o) { <<< o >>>; -- 2.43.0