]> Nishi Git Mirror - gwion.git/commitdiff
:art: Update
authorfennecdjay <fennecdjay@gmail.com>
Thu, 15 Sep 2022 14:30:28 +0000 (16:30 +0200)
committerfennecdjay <fennecdjay@gmail.com>
Thu, 15 Sep 2022 14:30:28 +0000 (16:30 +0200)
src/emit/emit.c
src/env/context.c
src/env/nspc.c
src/import/import_cdef.c
src/lib/object_op.c
src/parse/check.c
src/parse/scan1.c

index 80198c798e1df01e148e05848363ea8e7fe99a76..4c661453990ff205c5f1a45e8edf04d1ebaaec2b 100644 (file)
@@ -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;
 }
index fc0b5aa40760164ca09a60b7996434f1f93085bc..760e68170f21ffd17c68430d803e884af6fc9604 100644 (file)
@@ -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);
index 5c17cf08f501c5a7a852a22a748c3dea384cb512..83439b7cc96221e72f319e86d80bcee1c1c1af1c 100644 (file)
@@ -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);
index 03860ac4dfbe23b604111f235eef0c40849e8101..811a2e3721e34bf6644951a62078b6d65edc1a76 100644 (file)
@@ -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;
index 3f61a2dbcf0fe3b4189487c8bb49374de01cbd15..e7f709fad89d97e165844cc9c1af81b45d50d21e 100644 (file)
@@ -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);
index 99914bf15b55f98df557230281f413379f012d1f..656528b23e88ae1145c2ad296ba7184fd7bb59af 100644 (file)
@@ -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));
index 232d171bd60cead45fccd12e91558fab9b2083a3..190b42ee9ef7d4a88f0f44713e5bbfc48ecff65c 100644 (file)
@@ -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;
 }