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;
}
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;
}
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;
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;
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;
}
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;
}
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);
}
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);
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;
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;
}
}
}
+ 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);
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;
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;
}
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));
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;
}