From: fennecdjay Date: Thu, 15 Sep 2022 14:30:28 +0000 (+0200) Subject: :art: Update X-Git-Tag: nightly~253 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=8f2b1edaa02b47f499321fadbbffb22e9c71d36b;p=gwion.git :art: Update --- diff --git a/src/emit/emit.c b/src/emit/emit.c index 80198c79..4c661453 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -1120,12 +1120,24 @@ ANN static m_bool emit_decl(const Emitter emit, Exp_Decl *const decl) { CHECK_BB(op_emit(emit, &opi)); } set_late(decl, vd); - if (!decl->args && !exp_self(decl)->emit_var && GET_FLAG(array_base_simple(v->type), abstract) && !GET_FLAG(decl->td, late) && + if (!decl->args && !exp_getvar(exp_self(decl)) && GET_FLAG(array_base_simple(v->type), abstract) && !GET_FLAG(decl->td, late) && GET_FLAG(v, late) && late_array(decl->td) && GET_FLAG(v->type, abstract)) { env_warn(emit->env, decl->td->pos, _("Type '%s' is abstract, use {+G}late{0} instead of {G+}%s{0}"), v->type->name, !GET_FLAG(decl->td, const) ? "var" : "const"); + if(v->type->nspc->vtable.ptr) { + const Vector vec = &v->type->nspc->vtable; + for(m_uint i = 0; i < vector_size(vec); i++) { + const Func f = (Func)vector_at(vec, i); + if(!strcmp(s_name(f->def->base->xid), "new")) { + gw_err(_("maybe use a constructor?\n")); + break; + } + } + } } + if(GET_FLAG(v, late) && exp_getuse(exp_self(decl))) + emit_add_instr(emit, GWOP_EXCEPT); return GW_OK; } @@ -1456,8 +1468,10 @@ static inline m_bool push_func_code(const Emitter emit, const Func f) { return GW_OK; } const Instr instr = (Instr)vector_back(&emit->code->instr); - instr->opcode = eRegPushImm; - instr->m_val = (m_uint)f->code; + if(f->code) { + instr->opcode = eRegPushImm; + instr->m_val = (m_uint)f->code; + } return GW_OK; } @@ -1485,7 +1499,7 @@ ANN static void tmpl_prelude(const Emitter emit, const Func f) { ANN static Instr get_prelude(const Emitter emit, const Func f, const bool is_static) { - if (f != emit->env->func || (!is_static && strcmp(s_name(f->def->base->xid), "new"))) { + if (f != emit->env->func || !is_static) { const Instr instr = emit_add_instr(emit, SetCode); instr->udata.one = 1; return instr; @@ -1612,7 +1626,7 @@ ANN static void emit_fptr_call(const Emitter emit, const Func f) { ANN static void call_finish(const Emitter emit, const Func f, const bool is_static) { const m_uint offset = emit_code_offset(emit); - if (f != emit->env->func || !is_static) + if (f != emit->env->func || !is_static || strcmp(s_name(f->def->base->xid), "new")) regseti(emit, offset); const Instr instr = emit_call(emit, f, is_static); instr->m_val = f->def->base->ret_type->size; @@ -2046,7 +2060,7 @@ ANN static inline m_bool emit_stmt_continue(const Emitter emit, vector_add(&emit->code->stack_cont, (vtype)emit_add_instr(emit, Goto)); else if (stmt->idx) { if (emit_jump_index(emit, &emit->code->stack_cont, stmt->idx) < 0) - ERR_B(stmt_self(stmt)->pos, _("to many jumps required.")) + ERR_B(stmt_self(stmt)->pos, _("too many jumps required.")) } return GW_OK; } @@ -2058,7 +2072,7 @@ ANN static inline m_bool emit_stmt_break(const Emitter emit, vector_add(&emit->code->stack_break, (vtype)emit_add_instr(emit, Goto)); else if (stmt->idx) { if (emit_jump_index(emit, &emit->code->stack_break, stmt->idx) < 0) - ERR_B(stmt_self(stmt)->pos, _("to many jumps required.")) + ERR_B(stmt_self(stmt)->pos, _("too many jumps required.")) } return GW_OK; } diff --git a/src/env/context.c b/src/env/context.c index fc0b5aa4..760e6817 100644 --- a/src/env/context.c +++ b/src/env/context.c @@ -7,7 +7,8 @@ ANN void free_context(const Context a, Gwion gwion) { const Nspc global = a->nspc->parent; - nspc_remref(a->nspc, gwion); + if(!a->error) // this is quite a hack + nspc_remref(a->nspc, gwion); if(a->error) nspc_remref(global, gwion); free_mstr(gwion->mp, a->name); ast_cleaner(gwion, a->tree); diff --git a/src/env/nspc.c b/src/env/nspc.c index 5c17cf08..83439b7c 100644 --- a/src/env/nspc.c +++ b/src/env/nspc.c @@ -45,6 +45,7 @@ static inline void nspc_release_struct(const Nspc a, Value value, Gwion gwion) { } static inline void _free_nspc_value(const Nspc a, const Value v, Gwion gwion) { + if(v->from->ctx && v->from->ctx->error) return; // this is quite a hack if (isa(v->type, gwion->type[et_compound]) > 0 ) { if (!tflag(v->type, tflag_struct)) nspc_release_object(a, v, gwion); diff --git a/src/import/import_cdef.c b/src/import/import_cdef.c index 03860ac4..811a2e37 100644 --- a/src/import/import_cdef.c +++ b/src/import/import_cdef.c @@ -81,7 +81,7 @@ Type gwi_class_ini(const Gwi gwi, const m_str name, const m_str parent) { DECL_OO(Type_Decl *, td, = gwi_str2td(gwi, parent ?: "Object")); Tmpl *tmpl = ck.sl ? new_tmpl(gwi->gwion->mp, ck.sl) : NULL; if (tmpl) CHECK_BO(template_push_types(gwi->gwion->env, tmpl)); - const Type base = find_type(gwi->gwion->env, td); + DECL_OO(const Type, base, = known_type(gwi->gwion->env, td)); const Type_List tl = td->types; if (tflag(base, tflag_ntmpl)) td->types = NULL; const Type p = !td->types ? known_type(gwi->gwion->env, td) : NULL; diff --git a/src/lib/object_op.c b/src/lib/object_op.c index 3f61a2db..e7f709fa 100644 --- a/src/lib/object_op.c +++ b/src/lib/object_op.c @@ -148,7 +148,7 @@ ANN static void emit_member_func(const Emitter emit, const Exp_Dot *member) { return; } } else if (is_static_call(emit, exp_self(member))) { - if (member->is_call && f == emit->env->func) return; + if (member->is_call && f == emit->env->func && strcmp(s_name(f->def->base->xid), "new")) return; const Instr func_i = emit_add_instr(emit, f->code ? RegPushImm : SetFunc); func_i->m_val = (m_uint)f->code ?: (m_uint)f; return; @@ -252,6 +252,7 @@ OP_CHECK(opck_object_dot) { } } } + if(isa(the_base, v->type->info->base_type) > 0) return v->type->info->base_type; env_err(env, exp_self(member)->pos, _("class '%s' has no member '%s'"), the_base->name, str); if (member->base->type->nspc) did_you_mean_type(the_base, str); diff --git a/src/parse/check.c b/src/parse/check.c index 99914bf1..656528b2 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -101,6 +101,8 @@ ANN static m_bool check_decl(const Env env, const Exp_Decl *decl) { const Var_Decl *vd = &decl->vd; CHECK_BB(check_var(env, vd)); CHECK_BB(check_var_td(env, vd, decl->td)); + if(decl->td->array && decl->td->array->exp && !decl->args && GET_FLAG(array_base(decl->type), abstract)) + ERR_B(decl->td->pos, "declaration of abstract type arrays needs lambda"); valid_value(env, vd->xid, vd->value); // set_vflag(var->value, vflag_used)); return GW_OK; @@ -253,8 +255,9 @@ ANN static Type check_prim_dict(const Env env, Exp *data) { ANN m_bool not_from_owner_class(const Env env, const Type t, const Value v, const loc_t pos) { if (!v->from->owner_class || isa(t, v->from->owner_class) < 0) { - ERR_B(pos, _("'%s' from owner namespace '%s' used in '%s'."), v->name, - v->from->owner ? v->from->owner->name : "?", t->name) + if(!is_class(env->gwion, v->type)) + ERR_B(pos, _("'%s' from owner namespace '%s' used in '%s'."), v->name, + v->from->owner ? v->from->owner->name : "?", t->name) } return GW_OK; } @@ -264,6 +267,11 @@ ANN static inline Value get_value(const Env env, const Symbol sym) { if(value) { if (!value->from->owner_class || isa(env->class_def, value->from->owner_class) > 0) return value; + if(env->class_def) { + if (isa(env->class_def, value->from->owner_class) > 0 || value == env->class_def->info->value) + return value; + + } } if (env->func && env->func->def->base->values) { DECL_OO(const Value, v, = upvalues_lookup(env->func->def->base->values, sym)); diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 232d171b..190b42ee 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -683,13 +683,6 @@ ANN static m_bool _scan1_func_def(const Env env, const Func_Def fdef) { env_set_error(env, true); return GW_ERROR; } - - if(!strcmp(s_name(fdef->base->xid), "new")) { - if(!env->class_def) - ERR_B(fdef->base->pos, _("{G+}new{0} operator must be set inside {C+}class{0}")); - SET_FLAG(env->class_def, abstract); - } - return ret; }