From: Jérémie Astor Date: Sat, 16 May 2020 17:18:23 +0000 (+0200) Subject: :art: Gack and struct improvments X-Git-Tag: nightly~1562 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=73408844a037d49a296c2ea0294eacca8a9b8ed8;p=gwion.git :art: Gack and struct improvments --- diff --git a/include/env/type.h b/include/env/type.h index ff7284b0..bffe5aa4 100644 --- a/include/env/type.h +++ b/include/env/type.h @@ -44,9 +44,18 @@ ANN static inline m_uint env_push_type(const Env env, const Type type) { return ANN m_bool is_fptr(const struct Gwion_*, const Type t); ANN m_bool is_class(const struct Gwion_*, const Type t); ANN m_uint get_depth(const Type type); + +__attribute__((returns_nonnull)) +ANN static inline Type get_gack(Type t) { + do if(t->e->gack) + return t; + while((t = t->e->parent)); + return t; // unreachable +} + typedef enum { et_void, et_int, et_bool, et_char, et_float, - et_null, et_object, et_shred, et_fork, et_event, et_ugen, et_string, et_ptr, et_array, et_gack, + et_null, et_compound, et_object, et_shred, et_fork, et_event, et_ugen, et_string, et_ptr, et_array, et_gack, et_function, et_fptr, et_vararg, et_lambda, et_class, et_union, et_undefined, et_auto, MAX_TYPE } type_enum; diff --git a/src/emit/emit.c b/src/emit/emit.c index 284fc4b0..ced890f5 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -491,13 +491,6 @@ ANN static m_bool emit_prim_typeof(const Emitter emit, const Exp *exp) { return GW_OK; } -ANN static inline void struct_interp(const Emitter emit, const Exp e) { - if(GET_FLAG(e->info->type, struct) && !GET_FLAG(e->info->type, builtin)) { - exp_setvar(e, 1); - regpush(emit, e->info->type->size - SZ_INT); - } -} - ANN static void interp_multi(const Emitter emit, const Exp e) { Var_Decl_List list = e->d.exp_decl.list; const int emit_var = exp_getvar(e); @@ -510,13 +503,19 @@ ANN static void interp_multi(const Emitter emit, const Exp e) { regpop(emit, offset); } +ANN static void interp_size(const Emitter emit, const Type t) { + const m_uint sz = isa(t, emit->gwion->type[et_compound]) < 0 ? + t->size : SZ_INT; + const Instr instr = regseti(emit, sz); + instr->m_val2 = SZ_INT; +} + ANN static m_bool emit_interp(const Emitter emit, const Exp exp) { regpushi(emit, 0); Exp e = exp, next = NULL; do { next = e->next; e->next = NULL; - struct_interp(emit, e); if(emit_exp(emit, e) < 0) { e->next = next; return GW_ERROR; @@ -524,9 +523,13 @@ ANN static m_bool emit_interp(const Emitter emit, const Exp exp) { if(e->exp_type == ae_exp_decl) // why only objects? interp_multi(emit, e); regseti(emit, (m_uint)e->info->type); + interp_size(emit, e->info->type); +// regseti(emit, (m_uint)isa(e->info->type, emit->gwion->type[et_object]) > 0); const m_bool isobj = isa(e->info->type, emit->gwion->type[et_object]) > 0; - if(isobj && !GET_FLAG(e->info->type, force)) - emit_add_instr(emit, GackType); + if(isobj) { + if(!GET_FLAG(e->info->type, force)) + emit_add_instr(emit, GackType); + } const Instr instr = emit_add_instr(emit, Gack); instr->m_val = emit_code_offset(emit); } while((e = e->next = next)); @@ -537,6 +540,11 @@ ANN static m_bool emit_prim_hack(const Emitter emit, const Exp *exp) { CHECK_BB(emit_interp(emit, *exp)) if(!(emit->env->func && emit->env->func->def->base->xid == insert_symbol("@gack"))) emit_add_instr(emit, GackEnd); + else { + const Instr instr = emit_add_instr(emit, Reg2Mem); + instr->m_val = SZ_INT; + instr->m_val2 = -SZ_INT; + } return GW_OK; } @@ -575,11 +583,10 @@ ANN static m_bool decl_static(const Emitter emit, const Var_Decl var_decl, const } ANN static inline int struct_ctor(const Value v) { - return GET_FLAG(v->type, struct) && v->type->nspc->pre_ctor; + return GET_FLAG(v->type, struct); } ANN static void emit_struct_decl_finish(const Emitter emit, const Value v) { - emit_ext_ctor(emit, v->type->nspc->pre_ctor); const Instr instr = emit_add_instr(emit, Reg2RegDeref); instr->m_val = -SZ_INT; instr->m_val2 = v->type->size; @@ -591,14 +598,16 @@ ANN static m_bool emit_exp_decl_static(const Emitter emit, const Var_Decl var_de if(isa(v->type, emit->gwion->type[et_object]) > 0 && !is_ref) CHECK_BB(decl_static(emit, var_decl, 0)) CHECK_BB(emit_dot_static_data(emit, v, !struct_ctor(v) ? emit_addr : 1)) - if(!emit_addr && struct_ctor(v)) - emit_struct_decl_finish(emit, v); + if(struct_ctor(v) /* && !GET_FLAG(decl->td, ref) */) { + emit_ext_ctor(emit, v->type->nspc->pre_ctor); + if(!emit_addr) + emit_struct_decl_finish(emit, v); + } return GW_OK; } ANN static Instr emit_struct_decl(const Emitter emit, const Value v, const m_bool emit_addr) { emit_add_instr(emit, RegPushMem); -//regpushi(emit, 0); const Instr instr = emit_add_instr(emit, !emit_addr ? StructMember : StructMemberAddr); instr->m_val2 = v->from->offset; if(!emit_addr) @@ -624,16 +633,10 @@ ANN static m_bool emit_exp_decl_non_static(const Emitter emit, const Exp_Decl *d const Instr clean = emit_add_instr(emit, MemSetImm); clean->m_val = v->from->offset; } - if(!emit_addr && GET_FLAG(type, struct)) { - for(m_uint i = 0; i <= type->size; ++i) { - const Instr clean = emit_add_instr(emit, MemSetImm); - clean->m_val = v->from->offset + i; - } - } } const Instr instr = !(SAFE_FLAG(emit->env->class_def, struct) && !emit->env->scope->depth) ? emit_kind(emit, v->type->size, !struct_ctor(v) ? emit_addr : 1, exec) : emit_struct_decl(emit, v, emit_addr); - if((emit_addr || !GET_FLAG(v, member))) + if(!GET_FLAG(v, member)) instr->m_val = v->from->offset; if(is_obj && (is_array || !is_ref)) { emit_add_instr(emit, Assign); @@ -642,8 +645,15 @@ ANN static m_bool emit_exp_decl_non_static(const Emitter emit, const Exp_Decl *d const Instr push = emit_add_instr(emit, Reg2Reg); push->m_val = -(missing_depth) * SZ_INT; } - } else if(!emit_addr && struct_ctor(v)) - emit_struct_decl_finish(emit, v); + } else if(struct_ctor(v) /* && !GET_FLAG(decl->td, ref) */) { + if(GET_FLAG(v, member)) { + const Instr instr = emit_add_instr(emit, DotMember4); + instr->m_val = v->from->offset; + } + emit_ext_ctor(emit, v->type->nspc->pre_ctor); + if(!emit_addr) + emit_struct_decl_finish(emit, v); + } return GW_OK; } @@ -671,8 +681,11 @@ ANN static m_bool emit_exp_decl_global(const Emitter emit, const Exp_Decl *decl, } assign->m_val = emit_var; (void)emit_addref(emit, emit_var); - } else if(!emit_var && struct_ctor(v)) - emit_struct_decl_finish(emit, v); + } else if(struct_ctor(v) /* && !GET_FLAG(decl->td, ref) */) { + emit_ext_ctor(emit, v->type->nspc->pre_ctor); + if(!emit_addr) + emit_struct_decl_finish(emit, v); + } return GW_OK; } @@ -691,7 +704,7 @@ ANN static m_bool emit_decl(const Emitter emit, const Exp_Decl* decl) { const uint ref = GET_FLAG(decl->td, ref) || type_ref(decl->type); Var_Decl_List list = decl->list; do { - const uint r = (list->self->array && list->self->array->exp && ref) ? 0 : (uint)(GET_FLAG(list->self->value, ref) + ref); + const uint r = GET_FLAG(list->self->value, ref) + ref; if(GET_FLAG(decl->td, static)) CHECK_BB(emit_exp_decl_static(emit, list->self, r, var)) else if(!global) @@ -1817,7 +1830,9 @@ ANN static VM_Code emit_internal(const Emitter emit, const Func f) { ADD_REF(f->code) return f->code; } else if(f->def->base->xid == insert_symbol("@gack")) { - regpush(emit, SZ_INT); + regpop(emit, SZ_INT*2); + const Instr instr = emit_add_instr(emit, RegPushMem); + instr->m_val = SZ_INT; f->code = finalyze(emit, FuncReturn); return emit->env->class_def->e->gack = f->code; } @@ -1930,9 +1945,11 @@ ANN static m_bool emit_func_def(const Emitter emit, const Func_Def f) { emit->env->func = func; emit_push_scope(emit); - if(!strcmp(s_name(fdef->base->xid), "@gack") && - SAFE_FLAG(func->value_ref->from->owner_class, struct)) - regpop(emit, func->value_ref->from->owner_class->size - SZ_INT); + if(!strcmp(s_name(fdef->base->xid), "@gack")) { + emit_local(emit, emit->gwion->type[et_int]); + const Instr instr = emit_add_instr(emit, MemSetImm); + instr->m_val = SZ_INT; + } const m_bool ret = scanx_fdef(emit->env, emit, fdef, (_exp_func)emit_fdef); emit_pop_scope(emit); emit->env->func = former; @@ -1978,28 +1995,6 @@ ANN static m_bool cdef_parent(const Emitter emit, const Class_Def cdef) { return ret; } -ANN static inline int no_ctor(const Emitter emit, const Class_Def cdef) { - if(isa(cdef->base.type, emit->gwion->type[et_object]) > 0) - return 0; - Ast ast = cdef->body; - do { - if(ast->section->section_type == ae_section_stmt) { - Stmt_List list = ast->section->d.stmt_list; - do { - if(list->stmt->stmt_type != ae_stmt_exp || - !list->stmt->d.stmt_exp.val || list->stmt->d.stmt_exp.val->exp_type != ae_exp_decl) - return 0; - } while((list = list->next)); - } - } while((ast = ast->next)); - return 1; -} - -ANN static m_bool emit_struct_body2(const Emitter emit, Section *const section) { - return section->section_type != ae_section_stmt ? - emit_section(emit, section) : GW_OK; -} - ANN static m_bool emit_class_def(const Emitter emit, const Class_Def cdef) { if(tmpl_base(cdef->base.tmpl)) return GW_OK; @@ -2011,12 +2006,9 @@ ANN static m_bool emit_class_def(const Emitter emit, const Class_Def cdef) { SET_FLAG(t, emit); nspc_allocdata(emit->gwion->mp, t->nspc); if(cdef->body) { - if(!no_ctor(emit, cdef)) { - emit_class_code(emit, t->name); - CHECK_BB(scanx_body(emit->env, cdef, (_exp_func)emit_section, emit)) - emit_class_finish(emit, t->nspc); - } else - CHECK_BB(scanx_body(emit->env, cdef, (_exp_func)emit_struct_body2, emit)) + emit_class_code(emit, t->name); + CHECK_BB(scanx_body(emit->env, cdef, (_exp_func)emit_section, emit)) + emit_class_finish(emit, t->nspc); } return GW_OK; } diff --git a/src/env/env_utils.c b/src/env/env_utils.c index 2c64ecae..18fcfc05 100644 --- a/src/env/env_utils.c +++ b/src/env/env_utils.c @@ -104,3 +104,9 @@ ANN Value global_string(const Env env, const m_str str) { nspc_add_value_front(env->global_nspc, sym, value); return value; } + +ANN m_bool isres(const Env env, const Symbol xid, const loc_t pos) { + if(vector_find(&env->gwion->data->reserved, (vtype)xid) > -1) + ERR_B(pos, _("%s is reserved."), s_name(xid)); + return GW_OK; +} diff --git a/src/import/special.c b/src/import/special.c index e047257f..33d01cf7 100644 --- a/src/import/special.c +++ b/src/import/special.c @@ -45,6 +45,7 @@ ANN void gwi_set_loc(const Gwi gwi, const m_str file, const uint line) { ANN static m_bool mk_gack(MemPool p, const Type type, const f_gack d) { const VM_Code code = new_vm_code(p, NULL, SZ_INT, ae_flag_member | ae_flag_builtin, "@gack"); code->native_func = (m_uint)d; + SET_FLAG(code, builtin); type->e->gack = code; return GW_OK; } diff --git a/src/lib/array.c b/src/lib/array.c index d203d71e..8bbd0d8b 100644 --- a/src/lib/array.c +++ b/src/lib/array.c @@ -197,6 +197,7 @@ static OP_CHECK(opck_array_cast) { static OP_CHECK(opck_array_slice) { const Exp e = (Exp)data; exp_setmeta(exp_self(e), 1); + exp_setnonnull(e->d.exp_slice.base, 1); return e->d.exp_slice.base->info->type; } diff --git a/src/lib/engine.c b/src/lib/engine.c index 5e3c40f6..3407d96f 100644 --- a/src/lib/engine.c +++ b/src/lib/engine.c @@ -51,6 +51,9 @@ static GACK(gack_float) { INTERP_PRINTF("%.4f", *(m_float*)VALUE); } +static GACK(gack_compound) { + INTERP_PRINTF("%p", *(void**)VALUE); +} #define mk_class_instr(op, arg0, arg1, ...) \ static INSTR(instr_class_##op) { \ POP_REG(shred, SZ_INT); \ @@ -105,6 +108,9 @@ 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); + GWI_BB(gwi_gack(gwi, t_compound, gack_compound)) + GWI_BB(gwi_set_global_type(gwi, t_compound, et_compound)) GWI_BB(import_object(gwi)) GWI_BB(import_prim(gwi)) const Type t_function = gwi_mk_type(gwi, "@function", SZ_INT, NULL); diff --git a/src/lib/object.c b/src/lib/object.c index 48a2c4ac..77552845 100644 --- a/src/lib/object.c +++ b/src/lib/object.c @@ -79,9 +79,10 @@ ANN void __release(const M_Object o, const VM_Shred shred) { !GET_FLAG(v, static) && !GET_FLAG(v, pure)) { const TupleForm tf = v->type->e->tuple; for(m_uint i = 0; i < vector_size(&tf->types); ++i) { + const m_bit *data = o->data + v->from->offset; const Type t = (Type)vector_at(&tf->types, i); if(isa(t, shred->info->vm->gwion->type[et_object]) > 0) - release(*(M_Object*)(o->data + v->from->offset + vector_at(&tf->offset, i)), shred); + release(*(M_Object*)(data + vector_at(&tf->offset, i)), shred); } } } @@ -109,11 +110,8 @@ static ID_CHECK(opck_this) { ERR_O(exp_self(prim)->pos, _("keyword 'this' can be used only inside class definition...")) if(env->func && !GET_FLAG(env->func, member)) ERR_O(exp_self(prim)->pos, _("keyword 'this' cannot be used inside static functions...")) - if(env->func && !strcmp(s_name(env->func->def->base->xid), "@gack") && - GET_FLAG(env->class_def, struct)) - ERR_O(exp_self(prim)->pos, _("can't use 'this' in struct @gack")) if(env->func && !strcmp(s_name(env->func->def->base->xid), "@gack")) - return force_type(env, env->class_def->e->parent); + return force_type(env, get_gack(env->class_def->e->parent)); // get_gack ? return env->class_def; } @@ -126,17 +124,9 @@ static ID_EMIT(opem_this) { return emit_add_instr(emit, RegPushMem); } -static GACK(gack_object) { - INTERP_PRINTF("%p", *(M_Object*)VALUE); -} - GWION_IMPORT(object) { - const Type t_object = gwi_mk_type(gwi, "Object", SZ_INT, NULL); - gwi_add_type(gwi, t_object); - GWI_BB(gwi_gack(gwi, t_object, gack_object)) - SET_FLAG(t_object, valid); // should be set by gwi_add_type - gwi->gwion->type[et_object] = t_object; -// struct SpecialId_ spid = { .ck=check_this, .exec=RegPushMem, .is_const=1 }; + const Type t_object = gwi_mk_type(gwi, "Object", SZ_INT, "@Compound"); + gwi_set_global_type(gwi, t_object, et_object); struct SpecialId_ spid = { .ck=opck_this, .em=opem_this, .is_const=1 }; gwi_specialid(gwi, "this", &spid); return GW_OK; diff --git a/src/lib/object_op.c b/src/lib/object_op.c index a3c55f8d..2d1932e5 100644 --- a/src/lib/object_op.c +++ b/src/lib/object_op.c @@ -123,8 +123,7 @@ static Type opck_object_scan(const Env env, const struct TemplateScan *ts) { static OP_CHECK(opck_struct_scan) { struct TemplateScan *ts = (struct TemplateScan*)data; - return (isa(ts->t , env->gwion->type[et_object]) > 0 || GET_FLAG(ts->t, struct)) ? - opck_object_scan(env, ts) : env->gwion->type[et_null]; + return opck_object_scan(env, ts); } static const f_instr dotstatic[] = { DotStatic, DotStatic2, DotStatic3, RegPushImm }; @@ -238,7 +237,7 @@ OP_CHECK(opck_object_dot) { ERR_O(exp_self(member)->pos, _("cannot access member '%s.%s' without object instance..."), the_base->name, str) - if(GET_FLAG(value, const) || GET_FLAG(value, enum)) + if(GET_FLAG(value, const)) exp_setmeta(exp_self(member), 1); return value->type; } @@ -440,7 +439,7 @@ GWION_IMPORT(object_op) { GWI_BB(gwi_oper_ini(gwi, NULL, "Object", "bool")) GWI_BB(gwi_oper_add(gwi, opck_unary_meta2)) GWI_BB(gwi_oper_end(gwi, "!", IntNot)) - GWI_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, NULL, NULL)) + GWI_BB(gwi_oper_ini(gwi, "@Compound", NULL, NULL)) GWI_BB(gwi_oper_add(gwi, opck_struct_scan)) GWI_BB(gwi_oper_end(gwi, "@scan", NULL)) gwi_item_ini(gwi, "@null", "null"); diff --git a/src/parse/check.c b/src/parse/check.c index 830f6b53..67e824cd 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -311,13 +311,6 @@ ANN static Type check_prim_id(const Env env, const Symbol *data) { return prim_id_non_res(env, data); } -ANN static Type check_prim_hack(const Env env, const Exp *data) { - if(env->func) - UNSET_FLAG(env->func, pure); - CHECK_OO((check_exp(env, *data))) - return env->gwion->type[et_gack]; -} - ANN static Type check_prim_typeof(const Env env, const Exp *exp) { const Exp e = *exp; DECL_OO(const Type, t, = check_exp(env, e)) @@ -326,10 +319,19 @@ ANN static Type check_prim_typeof(const Env env, const Exp *exp) { ANN static Type check_prim_interp(const Env env, const Exp* exp) { CHECK_OO(check_exp(env, *exp)) + Exp e = *exp; + do if(GET_FLAG(e->info->type, struct)) + exp_setvar(e, 1); + while((e = e->next)); return env->gwion->type[et_string]; } - +ANN static Type check_prim_hack(const Env env, const Exp *data) { + if(env->func) + UNSET_FLAG(env->func, pure); + CHECK_OO(check_prim_interp(env, data)) + return env->gwion->type[et_gack]; +} #define describe_prim_xxx(name, type) \ ANN static Type check##_prim_##name(const Env env NUSED, const union prim_data* data NUSED) {\ @@ -785,7 +787,7 @@ ANN static Type check_exp_binary(const Env env, const Exp_Binary* bin) { struct Op_Import opi = { .op=bin->op, .lhs=bin->lhs->info->type, .rhs=bin->rhs->info->type, .data=(uintptr_t)bin, .pos=exp_self(bin)->pos, .op_type=op_binary }; const Type ret = op_check(env, &opi); - if(!ret && is_auto) + 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]; return ret; } @@ -825,7 +827,7 @@ ANN static Type check_exp_call(const Env env, Exp_Call* exp) { if(exp->tmpl) { CHECK_OO(check_exp(env, exp->func)) const Type t = actual_type(env->gwion, unflag_type(exp->func->info->type)); - const Value v = type_value(env->gwion, t); + const Value v = type_value(env->gwion, t) ?: t->e->d.func->value_ref; if(!GET_FLAG(v, func) && !GET_FLAG(exp->func->info->type, func) ) ERR_O(exp_self(exp)->pos, _("template call of non-function value.")) if(!v->d.func_ref || !v->d.func_ref->def->base->tmpl) diff --git a/src/parse/scan0.c b/src/parse/scan0.c index a1c4399f..445a8b55 100644 --- a/src/parse/scan0.c +++ b/src/parse/scan0.c @@ -310,7 +310,7 @@ ANN static Type get_parent_base(const Env env, Type_Decl *td) { ANN static Type get_parent(const Env env, const Class_Def cdef) { if(GET_FLAG(cdef, struct)) - return NULL; + return env->gwion->type[et_compound]; if(!cdef->base.ext) return env->gwion->type[et_object]; if(tmpl_base(cdef->base.tmpl)) @@ -329,10 +329,8 @@ ANN static Type scan0_class_def_init(const Env env, const Class_Def cdef) { if(parent == (Type)GW_ERROR) return NULL; const Type t = scan0_type(env, ++env->scope->type_xid, s_name(cdef->base.xid), parent); - if(GET_FLAG(cdef, struct)) { + if(GET_FLAG(cdef, struct)) SET_FLAG(t, struct); - t->e->gack = env->gwion->type[et_object]->e->gack; - } t->e->tuple = new_tupleform(env->gwion->mp, parent); t->e->owner = env->curr; t->e->owner_class = env->class_def; diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 3840d5fc..81efcb9f 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -26,11 +26,10 @@ ANN static inline m_bool ensure_scan1(const Env env, const Type t) { } ANN static m_bool type_recursive(const Env env, const Type_Decl *td, const Type t) { - if(env->class_def && !env->scope->depth) { - const m_int idx = vector_find(&env->scope->class_stack, (vtype)t); - if(!GET_FLAG(td, ref) && (idx > -1 || t == env->class_def)) - ERR_B(td_pos(td), _("%s declared inside %s\n. (make it a ref ?)"), - t->name, t == env->class_def ? "itself" : env->class_def->name); + if(!GET_FLAG(td, ref) && env->class_def && !env->scope->depth && + t == env->class_def) { + ERR_B(td_pos(td), _("%s declared inside %s\n. (make it a ref ?)"), + t->name, t == env->class_def ? "itself" : env->class_def->name); } return GW_OK; } @@ -46,7 +45,7 @@ ANN static Type scan1_type(const Env env, Type_Decl* td) { ANN static Type void_type(const Env env, Type_Decl* td) { DECL_OO(const Type, type, = scan1_type(env, td)) - if(isa(type, env->gwion->type[et_object]) > 0 || GET_FLAG(type, struct)) + if(isa(type, env->gwion->type[et_compound]) > 0) CHECK_BO(type_recursive(env, td, type)) if(type->size) return type; diff --git a/src/parse/scan2.c b/src/parse/scan2.c index b0a6c336..1624695e 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -298,9 +298,9 @@ ANN static m_bool scan2_func_def_overload(const Env env, const Func_Def f, const const m_bool base = tmpl_base(f->base->tmpl); const m_bool tmpl = GET_FLAG(overload, template); if(isa(overload->type, env->gwion->type[et_function]) < 0 || is_fptr(env->gwion, overload->type)) { - if(isa(actual_type(env->gwion, overload->type), env->gwion->type[et_function]) < 0) - ERR_B(f->pos, _("function name '%s' is already used by another value"), overload->name) -} + if(isa(actual_type(env->gwion, overload->type), env->gwion->type[et_function]) < 0) + ERR_B(f->pos, _("function name '%s' is already used by another value"), overload->name) + } if((!tmpl && base) || (tmpl && !base && !GET_FLAG(f, template))) ERR_B(f->pos, _("must overload template function with template")) return GW_OK; @@ -501,7 +501,7 @@ ANN2(1,2) m_bool scan2_fdef_std(const Env env, const Func_Def f, const Value ove } ANN m_bool scan2_fdef(const Env env, const Func_Def f) { - const Value overload = nspc_lookup_value0(env->curr, f->base->xid); + const Value overload = nspc_lookup_value2(env->curr, f->base->xid); if(overload) CHECK_BB(scan2_func_def_overload(env, f, overload)) return (!tmpl_base(f->base->tmpl) ? scan2_fdef_std : scan2_fdef_tmpl)(env, f, overload); diff --git a/src/parse/type_utils.c b/src/parse/type_utils.c deleted file mode 100644 index 5486ebb5..00000000 --- a/src/parse/type_utils.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "gwion_util.h" -#include "gwion_ast.h" -#include "gwion_env.h" -#include "vm.h" -#include "traverse.h" -#include "parse.h" - -ANN m_bool isres(const Env env, const Symbol xid, const loc_t pos) { - if(vector_find(&env->gwion->data->reserved, (vtype)xid) > -1) - ERR_B(pos, _("%s is reserved."), s_name(xid)); - return GW_OK; -} - -ANN m_uint id_list_len(ID_List l) { - m_uint len = 0; - do len += strlen(s_name(l->xid)); - while((l = l->next) && ++len); - return len + 1; -} - -ANN void type_path(const m_str str, ID_List l) { - m_str s = str; - do { - const m_str name = s_name(l->xid); - strcpy(s, name); - s += strlen(name); - if(l->next) - strcpy(s++, "."); - } while((l = l->next)); -} diff --git a/src/vm/gack.c b/src/vm/gack.c index 083d15a5..4a63cd07 100644 --- a/src/vm/gack.c +++ b/src/vm/gack.c @@ -46,14 +46,6 @@ ANN2(2) int gw_asprintf(MemPool mp, char **str, const char *fmt, ...) { return ret; } -__attribute__((returns_nonnull)) -ANN static inline VM_Code get_gack(Type t) { - do if(t->e->gack) - return t->e->gack; - while((t = t->e->parent)); - return t->e->gack; // unreachable -} - ANN static void prepare_call(const VM_Shred shred, const m_uint offset) { shred->mem += offset; *(m_uint*)(shred->mem + SZ_INT) = offset + SZ_INT; @@ -61,20 +53,20 @@ ANN static void prepare_call(const VM_Shred shred, const m_uint offset) { *(m_uint*)(shred->mem + SZ_INT*3) = shred->pc; *(m_uint*)(shred->mem + SZ_INT*4) = SZ_INT; shred->mem += SZ_INT*5; - *(M_Object*)(shred->mem)= *(M_Object*)(shred->reg - SZ_INT); + *(M_Object*)(shred->mem) = *(M_Object*)(shred->reg - SZ_INT); shred->pc = 0; } ANN void gack(const VM_Shred shred, const m_uint offset) { const Type t = *(Type*)shred->reg; - const VM_Code code = get_gack(t); + const VM_Code code = get_gack(t)->e->gack; if(GET_FLAG(code, builtin)) { - ((f_gack)code->native_func)(t, (shred->reg - t->size), shred); - POP_REG(shred, t->size); + const m_uint sz = *(m_uint*)(shred->reg + SZ_INT); + ((f_gack)code->native_func)(t, (shred->reg - sz), shred); + POP_REG(shred, sz); } else { prepare_call(shred, offset); shred->code = code; - POP_REG(shred, SZ_INT*2); } return; }