]> Nishi Git Mirror - gwion.git/commitdiff
:art: Few fixes
authorJérémie Astor <fennecdjay@gmail.com>
Mon, 21 Dec 2020 23:39:56 +0000 (00:39 +0100)
committerJérémie Astor <fennecdjay@gmail.com>
Mon, 21 Dec 2020 23:39:56 +0000 (00:39 +0100)
src/emit/emit.c
src/lib/array.c
src/lib/engine.c
src/lib/lib_func.c
src/lib/object_op.c
src/lib/ptr.c
src/lib/union.c
src/parse/operator.c
src/parse/scan0.c
src/parse/scan1.c

index a0969d8e37a0f05f765c83237798136f1d0e1974..c7025c756c2ad696a3f5239bd240cb4e9d769c3c 100644 (file)
@@ -418,6 +418,10 @@ ANN static m_bool _emit_symbol(const Emitter emit, const Symbol *data) {
   const m_uint size = v->type->size;
   const Instr instr = emit_kind(emit, size, exp_getvar(prim_exp(data)), !vflag(v, vflag_fglobal) ? regpushmem : regpushbase);
   instr->m_val  = v->from->offset;
+  if(GET_FLAG(v, late) && !exp_getvar(prim_exp(data)) && isa(v->type, emit->gwion->type[et_object]) > 0) {
+    const Instr instr = emit_add_instr(emit, GWOP_EXCEPT);
+    instr->m_val = -SZ_INT;
+  }
   return GW_OK;
 }
 
@@ -1774,7 +1778,6 @@ ANN static m_bool emit_case_body(const Emitter emit, const struct Stmt_Match_* s
 
 ANN static m_bool case_value(const Emitter emit, const Exp base, const Exp e) {
   const Value v = e->d.prim.value;
-printf("base->type %s\n", base->type->name);
   v->from->offset = emit_local(emit, base->type);
   const Instr instr = emit_add_instr(emit, Reg2Mem4);
   instr->m_val = v->from->offset;
@@ -1837,10 +1840,11 @@ ANN static Symbol case_op(const Emitter emit, const Exp base, const Exp e, const
   CHECK_BO(op_emit(emit, &opi))
   const Instr instr = emit_add_instr(emit, BranchEqInt);
   vector_add(vec, (vtype)instr);
+  return CASE_PASS;
 }
 
 ANN static m_bool _emit_stmt_match_case(const Emitter emit, const struct Stmt_Match_* stmt,
-    const Vector v, struct Match_ *const match) {
+    const Vector v) {
   Exp e = stmt->cond;
   const Map map = &emit->env->scope->match->map;
   for(m_uint i = 0; i < map_size(map) && e; e = e->next, ++i) {
@@ -1848,18 +1852,16 @@ ANN static m_bool _emit_stmt_match_case(const Emitter emit, const struct Stmt_Ma
     const Symbol op = case_op(emit, base, e, v, 0);
     if(op != CASE_PASS)
       CHECK_BB(emit_case_head(emit, base, e, op, v))
-else puts("pass");
   }
   CHECK_BB(emit_case_body(emit, stmt))
   return GW_OK;
 }
 
-ANN static m_bool emit_stmt_match_case(const Emitter emit, const struct Stmt_Match_* stmt,
-      struct Match_ *match) {
+ANN static m_bool emit_stmt_match_case(const Emitter emit, const struct Stmt_Match_* stmt) {
   emit_push_scope(emit);
   struct Vector_ v;
   vector_init(&v);
-  const m_bool ret = _emit_stmt_match_case(emit, stmt, &v, match);
+  const m_bool ret = _emit_stmt_match_case(emit, stmt, &v);
   emit_pop_scope(emit);
   for(m_uint i = 0; i < vector_size(&v); ++i) {
     const Instr instr = (Instr)vector_at(&v, i);
@@ -1878,8 +1880,8 @@ ANN static inline void match_unvec(struct Match_ *const match, const m_uint pc)
   vector_release(vec);
 }
 
-ANN static m_bool emit_stmt_cases(const Emitter emit, Stmt_List list, struct Match_ *match) {
-  do CHECK_BB(emit_stmt_match_case(emit, &list->stmt->d.stmt_match, match))
+ANN static m_bool emit_stmt_cases(const Emitter emit, Stmt_List list) {
+  do CHECK_BB(emit_stmt_match_case(emit, &list->stmt->d.stmt_match))
   while((list = list->next));
   return GW_OK;
 }
@@ -1889,7 +1891,7 @@ ANN static m_bool emit_match(const Emitter emit, const struct Stmt_Match_* stmt)
     CHECK_BB(emit_stmt(emit, stmt->where, 1))
   MATCH_INI(emit->env->scope)
   vector_init(&m.vec);
-  const m_bool ret = emit_stmt_cases(emit, stmt->list, &m);
+  const m_bool ret = emit_stmt_cases(emit, stmt->list);
   match_unvec(&m, emit_code_size(emit));
   MATCH_END(emit->env->scope)
   return ret;
index b68dda408be93f5cb392ca654474286075557344..dd824abcb84c6e0c33529fc1115fab685ef3d822 100644 (file)
@@ -321,7 +321,7 @@ static OP_CHECK(opck_array) {
   const Array_Sub array = (Array_Sub)data;
   const Type t_int = env->gwion->type[et_int];
   Exp e = array->exp;
-  do CHECK_BO(check_implicit(env, e, t_int))
+  do CHECK_BN(check_implicit(env, e, t_int))
   while((e = e->next));
   const Type t = array->type->array_depth ? array->type : typedef_base(array->type);
   if(t->array_depth >= array->depth)
index 69a526b5e83b0e5a7ad5cc3a680e0e8e2c10db72..a073b049ad513762170c9417ffd11d6c0ac07bbb 100644 (file)
@@ -155,11 +155,11 @@ ANN static m_bool import_core_libs(const Gwi gwi) {
   GWI_BB(gwi_oper_end(gwi, ">",  instr_class_gt))
   GWI_BB(gwi_oper_end(gwi, "<=", instr_class_le))
   GWI_BB(gwi_oper_end(gwi, "<",  instr_class_lt))
-/*
+
   GWI_BB(gwi_oper_ini(gwi, NULL, (m_str)OP_ANY_TYPE, NULL))
   GWI_BB(gwi_oper_add(gwi, opck_basic_ctor))
   GWI_BB(gwi_oper_end(gwi, "@ctor", NULL))
-*/
+
   GWI_BB(gwi_oper_ini(gwi, "@Compound", (m_str)OP_ANY_TYPE, NULL))
   GWI_BB(gwi_oper_add(gwi, opck_object_dot))
   GWI_BB(gwi_oper_emi(gwi, opem_object_dot))
index 450c9c4f945b688d8c55ca4febf3cff69c696e2c..6e8937645d0588b366d88246d9b6e604c9a7b6cc 100644 (file)
@@ -176,7 +176,8 @@ ANN m_bool check_lambda(const Env env, const Type t, Exp_Lambda *l) {
 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))
-    CHECK_OB((info->exp->type = fptr_type(env, info)))
+    if(!(info->exp->type = fptr_type(env, info)))
+      ERR_B(info->lhs->def->pos, _("no match found"))
     return GW_OK;
   }
   Exp_Lambda *l = &info->exp->d.exp_lambda;
@@ -213,13 +214,13 @@ static OP_CHECK(opck_fptr_at) {
      bin->rhs->type->info->func->def->base->tmpl->call) {
     struct FptrInfo info = { bin->lhs->type->info->func, bin->rhs->type->info->parent->info->func,
       bin->lhs, exp_self(bin)->pos };
-    CHECK_BO(fptr_do(env, &info))
+    CHECK_BN(fptr_do(env, &info))
     exp_setvar(bin->rhs, 1);
     return bin->rhs->type;
   }
   struct FptrInfo info = { bin->lhs->type->info->func, bin->rhs->type->info->func,
       bin->lhs, exp_self(bin)->pos };
-  CHECK_BO(fptr_do(env, &info))
+  CHECK_BN(fptr_do(env, &info))
   exp_setvar(bin->rhs, 1);
   return bin->rhs->type;
 }
@@ -229,7 +230,7 @@ static OP_CHECK(opck_fptr_cast) {
   const Type t = exp_self(cast)->type;
   struct FptrInfo info = { cast->exp->type->info->func, t->info->func,
      cast->exp, exp_self(cast)->pos };
-  CHECK_BO(fptr_do(env, &info))
+  CHECK_BN(fptr_do(env, &info))
   return t;
 }
 
@@ -257,7 +258,7 @@ static OP_CHECK(opck_fptr_impl) {
   struct Implicit *impl = (struct Implicit*)data;
   struct FptrInfo info = { impl->e->type->info->func, impl->t->info->func,
       impl->e, impl->e->pos };
-  CHECK_BO(fptr_do(env, &info))
+  CHECK_BN(fptr_do(env, &info))
   return impl->t;
 }
 
@@ -313,7 +314,7 @@ static OP_CHECK(opck_spork) {
     const m_bool ret = check_stmt(env, unary->code);
     nspc_pop_value(env->gwion->mp, env->curr);
     --env->scope->depth;
-    CHECK_BO(ret)
+    CHECK_BN(ret)
     return env->gwion->type[unary->op == insert_symbol("spork") ? et_shred : et_fork];
   }
   ERR_O(exp_self(unary)->pos, _("only function calls can be sporked..."))
index 02e307ec58bfe9dc8d2c5efd0df1c49349ac3c45..932f87a32fd7da45021798def2d70db58121a19c 100644 (file)
@@ -36,7 +36,7 @@ static OP_CHECK(at_object) {
   if(bin->rhs->exp_type == ae_exp_decl)
     SET_FLAG(bin->rhs->d.exp_decl.td, late); // ???
   exp_setvar(bin->rhs, 1);
-  CHECK_BO(isa(bin->lhs->type , bin->rhs->type))
+  CHECK_BN(isa(bin->lhs->type , bin->rhs->type))
   return bin->rhs->type;
 }
 
index 616e7bf62d835f56579549489a95ff8be5c297f9..98e146b9002b551a57cca5134efc1e633eebeaeb 100644 (file)
@@ -28,8 +28,8 @@ ANN static inline Type ptr_base(const Env env, const Type t) {
 
 static OP_CHECK(opck_ptr_assign) {
   const Exp_Binary* bin = (Exp_Binary*)data;
-  CHECK_BO(ptr_access(env, bin->lhs))
-  CHECK_BO(ptr_access(env, bin->rhs))
+  CHECK_BN(ptr_access(env, bin->lhs))
+  CHECK_BN(ptr_access(env, bin->rhs))
   exp_setvar(bin->lhs, 1);
   exp_setvar(bin->rhs, 1);
   Type t = bin->lhs->type;
index fff775c1458a6539b47c9bfd8c66b46c26ee2e50..5f68019df8458284022839521fd46f8f22c94e19 100644 (file)
@@ -94,7 +94,7 @@ static OP_CHECK(opck_union_is) {
       free_exp(env->gwion->mp, exp_func);
       free_exp(env->gwion->mp, exp_args);
       e->d.exp_binary.op = insert_symbol(env->gwion->st, "==");
-      CHECK_OO(check_exp(env, e))
+      CHECK_ON(check_exp(env, e))
       return e->type;
     }
   }
@@ -111,7 +111,7 @@ static OP_CHECK(opck_union_ctor) {
   if(!name || !name->next || name->next->next)
     ERR_N(name->pos, "Union constructor takes two arguments, "
          "'id' and 'value'")
-  if(name->exp_type != ae_exp_primary ||
+    if(name->exp_type != ae_exp_primary ||
         name->d.prim.prim_type != ae_prim_id)
     return NULL;
     const Exp val = name->next;
@@ -137,7 +137,6 @@ static OP_CHECK(opck_union_ctor) {
 static INSTR(UnionCtor) {
   POP_REG(shred, instr->m_val2);
   POP_REG(shred, SZ_INT);
-  const Type t = *(Type*)REG(-SZ_INT*2);
   const m_uint index = *(m_uint*)REG(-SZ_INT);
   const M_Object o = *(M_Object*)REG(-SZ_INT) = new_object(shred->info->vm->gwion->mp, NULL, (Type)instr->m_val);
   *(m_uint*)o->data = index;// + 1;
@@ -148,7 +147,7 @@ static OP_EMIT(opem_union_ctor) {
   Exp_Call *call = (Exp_Call*)data;
   const Type base = actual_type(emit->gwion, call->func->type);
   const Instr instr = emit_add_instr(emit, UnionCtor);
-  instr->m_val = base;
+  instr->m_val = (m_uint)base;
   instr->m_val2 = call->args->next->type->size;
   return GW_OK;
 }
index 479dc5bb879e9c9899fc74155d9cc1480f99511c..2a7133a006d2d36db6257320e126d7ee42909f2c 100644 (file)
@@ -58,7 +58,7 @@ ANN2(1) static M_Operator* operator_find(const Vector v, const restrict Type lhs
 ANN2(1) static M_Operator* operator_find2(const Vector v, const restrict Type lhs, const restrict Type rhs) {
   for(m_uint i = vector_size(v) + 1; --i;) {
     M_Operator* mo = (M_Operator*)vector_at(v, i - 1);
-    if(lhs == mo->lhs && rhs == mo->rhs)
+    if(mo && lhs == mo->lhs && rhs == mo->rhs)
       return mo;
   }
   return NULL;
@@ -134,12 +134,12 @@ ANN m_bool add_op(const Gwion gwion, const struct Op_Import* opi) {
   return GW_OK;
 }
 
-ANN static Type op_check_inner(struct OpChecker* ock) {
+ANN static Type op_check_inner(struct OpChecker* ock, const uint i) {
   Type t, r = ock->opi->rhs;
   do {
     const M_Operator* mo;
     const Vector v = (Vector)map_get(ock->map, (vtype)ock->opi->op);
-    if(v && (mo = operator_find(v, ock->opi->lhs, r))) {
+    if(v && (mo = !i ? operator_find2(v, ock->opi->lhs, r) : operator_find(v, ock->opi->lhs, r))) {
       if((mo->ck && (t = mo->ck(ock->env, (void*)ock->opi->data))))
         return t;
       else
@@ -150,22 +150,24 @@ ANN static Type op_check_inner(struct OpChecker* ock) {
 }
 
 ANN Type op_check(const Env env, struct Op_Import* opi) {
+for(int i = 0; i < 2; ++i) {
   Nspc nspc = env->curr;
   do {
-    if(nspc->info->op_map.ptr) {
-      Type l = opi->lhs;
-      do {
-        struct Op_Import opi2 = { .op=opi->op, .lhs=l, .rhs=opi->rhs, .data=opi->data, .op_type=opi->op_type };
-        struct OpChecker ock = { env, &nspc->info->op_map, &opi2 };
-        const Type ret = op_check_inner(&ock);
-        if(ret) {
-          if(ret == env->gwion->type[et_error])
-            return NULL;
-          return ret;
-        }
-      } while(l && (l = l->info->parent));
-    }
+    if(!nspc->info->op_map.ptr)
+      continue;
+    Type l = opi->lhs;
+    do {
+      struct Op_Import opi2 = { .op=opi->op, .lhs=l, .rhs=opi->rhs, .data=opi->data, .op_type=opi->op_type };
+      struct OpChecker ock = { env, &nspc->info->op_map, &opi2 };
+      const Type ret = op_check_inner(&ock, i);
+      if(ret) {
+        if(ret == env->gwion->type[et_error])
+          return NULL;
+        return ret;
+      }
+    } while(l && (l = l->info->parent));
   } while((nspc = nspc->parent));
+}
   if(opi->op == insert_symbol(env->gwion->st, "$") && opi->rhs == opi->lhs)
     return opi->rhs;
   if(opi->op == insert_symbol(env->gwion->st, "@func_check"))
@@ -200,6 +202,7 @@ ANN static m_bool handle_instr(const Emitter emit, const M_Operator* mo) {
 }
 
 ANN m_bool op_emit(const Emitter emit, const struct Op_Import* opi) {
+  for(int i = 0; i < 2; ++i) {
   Nspc nspc = emit->env->class_def ? emit->env->curr : emit->env->context->nspc;
   do {
     if(!nspc->info->op_map.ptr)continue;
@@ -210,7 +213,7 @@ ANN m_bool op_emit(const Emitter emit, const struct Op_Import* opi) {
         const Vector v = (Vector)map_get(&nspc->info->op_map, (vtype)opi->op);
         if(!v)
           continue;
-        const M_Operator* mo = operator_find(v, l, r);
+        const M_Operator* mo = !i ? operator_find2(v, l, r) :operator_find(v, l, r);
         if(mo) {
           if(mo->em) {
             const m_bool ret = mo->em(emit, (void*)opi->data);
@@ -222,5 +225,6 @@ ANN m_bool op_emit(const Emitter emit, const struct Op_Import* opi) {
       } while(r && (r = r->info->parent));
     } while(l && (l = l->info->parent));
   } while((nspc = nspc->parent));
+  }
   return GW_ERROR;
 }
index 291dc8fef50c9fcb014bfea5d96685cfde37d7a3..c333eb713a1b5aff40b71ff70b457a02bb9996f6 100644 (file)
@@ -218,7 +218,9 @@ ANN static Type union_type(const Env env, const Symbol s) {
   t->info->tuple = new_tupleform(env->gwion->mp, NULL); // ???
   add_type(env, env->curr, t);
   mk_class(env, t);
-  SET_FLAG(t, final | ae_flag_abstract);
+  SET_FLAG(t, final);
+  if(strncmp(t->name, "Option", 6))
+    SET_FLAG(t, abstract);
   return t;
 }
 
index 0835087a0d82c6c2a2322933c3433ad27284159f..0789d086db66a717bc622a2e2d425e029b50e9f7 100644 (file)
@@ -85,8 +85,10 @@ ANN static m_bool scan1_decl(const Env env, const Exp_Decl* decl) {
       if(var->array->exp)
         CHECK_BB(scan1_exp(env, var->array->exp))
       t = array_type(env, decl->type, var->array->depth);
-    } else if(GET_FLAG(t, abstract) && !GET_FLAG(decl->td, late))
-      SET_FLAG(decl->td, late);
+    } else if(GET_FLAG(t, abstract) && !GET_FLAG(decl->td, late)) {
+        ERR_B(var->pos, "Type '%s' is abstract, use late")
+     // SET_FLAG(decl->td, late);
+    }
     const Value v = var->value = var->value ?: new_value(env->gwion->mp, t, s_name(var->xid));
 // rewrite logic
     if(!env->scope->depth && env->class_def && !GET_FLAG(decl->td, static))