]> Nishi Git Mirror - gwion.git/commitdiff
:art: Improve type checking
authorJérémie Astor <astor.jeremie@wanadoo.fr>
Mon, 1 Jun 2020 17:04:08 +0000 (19:04 +0200)
committerJérémie Astor <astor.jeremie@wanadoo.fr>
Mon, 1 Jun 2020 17:04:08 +0000 (19:04 +0200)
src/emit/emit.c
src/env/type.c
src/parse/check.c

index 0545d4b03bc1d262d05853b4c05021c5605a5efd..5940ff3a4162a73e82850bfa3aea66a26001ebc0 100644 (file)
@@ -1214,6 +1214,9 @@ ANN Instr emit_exp_spork(const Emitter emit, const Exp_Unary* unary) {
 
 ANN static m_bool emit_exp_unary(const Emitter emit, const Exp_Unary* unary) {
 // no pos ?
+  const Type t = exp_self(unary)->info->type;
+  if(t->e->def && !GET_FLAG(t, emit))
+    CHECK_BB(ensure_emit(emit, t))
   struct Op_Import opi = { .op=unary->op, .data=(uintptr_t)unary, .op_type=op_unary };
   if(unary->op != insert_symbol("spork") && unary->op != insert_symbol("fork") && unary->exp) {
     CHECK_BB(emit_exp_pop_next(emit, unary->exp))
index 2597dd5cb08eb6da80d733df5c19c21304c1e940..a8eede9111179ad059ca57c5a8073904a6d2efcf 100644 (file)
@@ -47,14 +47,13 @@ Type new_type(MemPool p, const m_uint xid, const m_str name, const Type parent)
 
 ANN Type type_copy(MemPool p, const Type type) {
   const Type a = new_type(p, type->xid, type->name, type->e->parent);
-  a->nspc          = type->nspc;
+  a->nspc           = type->nspc;
   a->e->owner       = type->e->owner;
   a->e->owner_class = type->e->owner_class;
-  a->size          = type->size;
-  a->e->d.base_type   = type->e->d.base_type;
-  a->array_depth   = type->array_depth;
-  a->e->def           = type->e->def;
-  a->e->gack           = type->e->gack;
+  a->size           = type->size;
+  a->e->d.base_type = type->e->d.base_type;
+  a->array_depth    = type->array_depth;
+  a->e->gack        = type->e->gack;
   return a;
 }
 
index 617f7996d5bcc430346c9a1396b3cf1b1f3c7b23..f118fa86039917f54a04edbe02f5b44b77559b86 100644 (file)
@@ -152,6 +152,12 @@ ANN static inline m_bool ensure_check(const Env env, const Type t) {
   return envset_run(&es, t);
 }
 
+ANN static inline m_bool ensure_traverse(const Env env, const Type t) {
+  struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)traverse_cdef,
+    .scope=env->scope->depth, .flag=ae_flag_check };
+  return envset_run(&es, t);
+}
+
 ANN static inline m_bool inferable(const Env env, const Type t, const loc_t pos) {
   if(!GET_FLAG(t, infer))
     return GW_OK;
@@ -865,7 +871,11 @@ ANN static Type check_exp_unary(const Env env, const Exp_Unary* unary) {
     .data=(uintptr_t)unary, .pos=exp_self(unary)->pos, .op_type=op_unary };
   if(unary->exp && !opi.rhs)
     return NULL;
-  return op_check(env, &opi);
+  DECL_OO(const Type, ret, = op_check(env, &opi))
+  const Type t = get_type(actual_type(env->gwion, ret));
+  if(t->e->def && !GET_FLAG(t, check))
+    CHECK_BO(ensure_traverse(env, t))
+  return ret;
 }
 
 ANN static Type _flow(const Env env, const Exp e, const m_bool b) {