]> Nishi Git Mirror - gwion.git/commitdiff
:art: Improve Operator checking
authorJérémie Astor <astor.jeremie@wanadoo.fr>
Sun, 10 May 2020 19:56:52 +0000 (21:56 +0200)
committerJérémie Astor <astor.jeremie@wanadoo.fr>
Sun, 10 May 2020 19:56:52 +0000 (21:56 +0200)
include/env/env.h
include/operator.h
src/lib/object.c
src/lib/object_op.c
src/parse/check.c
src/parse/operator.c
src/parse/scan0.c
src/parse/scan2.c
src/parse/type_decl.c

index 1615a0fd8414cfa30830d7e29bbcddf2d34c6561..231cd0783bc8fc226fffdc37798edc464b0c1f24 100644 (file)
@@ -43,6 +43,7 @@ ANEW ANN m_str tl2str(const Env, const Type_List); // in type_decl.c
 ANN m_bool compat_func(const __restrict__ Func_Def, const __restrict__ Func_Def);
 ANN Type known_type(const Env env, Type_Decl*);
 ANN Type type_nonnull(const Env env, const Type base);
+ANN Type force_type(const Env env, const Type t);
 ANN Type prim_ref(const Env env, const Type t, const Type_Decl* td);
 ANN m_bool env_access(const Env env, const ae_flag flag, const loc_t pos);
 ANN m_bool env_storage(const Env env, ae_flag flag, const loc_t pos);
index e6fc6c9da36767f1dd51587919edfe76c04ca9e3..51a12ccb83b5e2f7cc6124a6e2457ea5a3020b62 100644 (file)
@@ -56,10 +56,19 @@ ANN struct Instr_* op_emit(const Emitter, const struct Op_Import*);
 ANN m_bool operator_set_func(const struct Op_Import*);
 ANN void free_op_map(Map map, struct Gwion_* gwion);
 
+
+ANN void operator_suspend(const Nspc, struct Op_Import*);
+ANN static inline void operator_resume(struct Op_Import *opi) {
+  *(uintptr_t*)opi->ret = opi->data;
+}
+
 ANN static inline void set_decl_ref(const Exp e) {
   if(e->exp_type == ae_exp_decl) {
     SET_FLAG(e->d.exp_decl.td, ref);
     SET_FLAG(e->d.exp_decl.list->self->value, ref);
   }
 }
+
+
+ANN void func_operator(const Func_Def fdef, struct Op_Import *opi);
 #endif
index 4590ec5ff0ea60b4b4d8ec097f1dfee4fc8314a0..1b3df38ddb73fb509229230419042f1f656253f2 100644 (file)
@@ -115,6 +115,8 @@ static ID_CHECK(opck_this) {
   if(env->func && !strcmp(s_name(env->func->def->base->xid), "@gack") &&
        GET_FLAG(env->class_def, struct))
     ERR_O(exp_self(prim)->pos, _("can't use 'this' in struct @gack"))
+  if(env->func && !strcmp(s_name(env->func->def->base->xid), "@gack"))
+    return force_type(env, env->class_def->e->parent);
   return env->class_def;
 }
 
index 6a789a674b7108ca3194976f52038815f3ddfdf1..3541eb86434620224c32c6b47ab446bb7903f56e 100644 (file)
@@ -76,35 +76,13 @@ static OP_EMIT(opem_at_object) {
   return emit_add_instr(emit, ObjectAssign);
 }
 
-#define STR_FORCE ":force"
-#define STRLEN_FORCE strlen(STR_FORCE)
-
-static inline Type new_force_type(MemPool p, const Type t, const Symbol sym) {
-  const Type ret = type_copy(p, t);
-  if(ret->nspc)
-    ADD_REF(ret->nspc)
-  ret->name = s_name(sym);
-  ret->flag = t->flag | ae_flag_force;
-  nspc_add_type_front(t->e->owner, sym, ret);
-  return ret;
- }
-
-static Type get_force_type(const Env env, const Type t) {
-  const size_t len = strlen(t->name);
-  char name[len + STRLEN_FORCE + 2];
-  strcpy(name, t->name);
-  strcpy(name + len, STR_FORCE);
-  const Symbol sym = insert_symbol(env->gwion->st, name);
-  return nspc_lookup_type1(t->e->owner, sym) ?: new_force_type(env->gwion->mp, t, sym);
-}
-
 static OP_CHECK(opck_object_cast) {
   const Exp_Cast* cast = (Exp_Cast*)data;
   const Type l = cast->exp->info->type;
   const Type r = exp_self(cast)->info->type;
   if(check_nonnull(env, l, r, "cast", exp_self(cast)->pos) == env->gwion->type[et_null])
     return env->gwion->type[et_null];
-  return get_force_type(env, r);
+  return force_type(env, r);
 }
 
 static OP_EMIT(opem_object_cast) {
index da30da9abdac086666ed8e4bd313dff7640a435d..56fbd6463a8b93a872ddfcd4e12823b1d1e1efef 100644 (file)
@@ -1331,7 +1331,14 @@ ANN m_bool check_func_def(const Env env, const Func_Def f) {
   env->func = func;
   ++env->scope->depth;
   nspc_push_value(env->gwion->mp, env->curr);
+  struct Op_Import opi = { };
+  if(GET_FLAG(fdef, op)) {
+    func_operator(f, &opi);
+    operator_suspend(env->curr, &opi);
+  }
   const m_bool ret = scanx_fdef(env, env, fdef, (_exp_func)check_fdef);
+  if(GET_FLAG(fdef, op))
+    operator_resume(&opi);
   nspc_pop_value(env->gwion->mp, env->curr);
   --env->scope->depth;
   env->func = former;
index 15c2bdd79b17b52d047bc891711b8209680ac988..1d8b5eca3a77422cc3d18774a47ecb23e4dc86ce 100644 (file)
@@ -56,6 +56,8 @@ static m_bool op_match(const restrict Type t, const restrict Type mo) {
 ANN2(1) static M_Operator* operator_find(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(!mo)
+      continue;
     if(op_match(lhs, mo->lhs) && op_match(rhs, mo->rhs))
       return mo;
   }
@@ -79,6 +81,18 @@ ANN2(1) static M_Operator* operator_find2(const Vector v, const restrict Type lh
   return NULL;
 }
 
+ANN void operator_suspend(const Nspc n, struct Op_Import *opi) {
+  const Vector v = (Vector)map_get(&n->info->op_map, (vtype)opi->op);
+  for(m_uint i = vector_size(v) + 1; --i;) {
+    M_Operator* mo = (M_Operator*)vector_at(v, i - 1);
+    if(op_match2(opi->lhs, mo->lhs) && op_match2(opi->rhs, mo->rhs)) {
+      opi->data = (uintptr_t)mo;
+      opi->ret = (Type)&VPTR(v, i-1);
+      VPTR(v, i-1) = 0;
+      break;
+    }
+  }
+}
 
 ANN static M_Operator* new_mo(MemPool p, const struct Op_Import* opi) {
   M_Operator* mo = mp_calloc(p, M_Operator);
index a4ba62761a750114669aaa24b2acd1617643d8cb..ee022da98e6a585804749892fa5156774a6e4bda 100644 (file)
@@ -107,6 +107,7 @@ ANN m_bool scan0_fptr_def(const Env env, const Fptr_Def fptr) {
     fptr_assign(env, fptr);
   SET_FLAG(fptr->value, func);
   add_type(env, t->e->owner, t);
+  mk_class(env, t);
   return GW_OK;
 }
 
index 12a987a1baa545cf124522274b7841b0019057ca..31698025ed7f679fb3aace2ec406664a7b8a5c0c 100644 (file)
@@ -406,15 +406,10 @@ ANN2(1, 2) static m_bool scan2_fdef_tmpl(const Env env, const Func_Def f, const
 
 ANN static m_bool scan2_func_def_op(const Env env, const Func_Def f) {
   const m_str str = s_name(f->base->xid);
-  const uint is_unary = GET_FLAG(f, unary) + (!strcmp(str, "@conditionnal") || !strcmp(str, "@unconditionnal"));
-  const Type l = is_unary ? NULL :
-    f->base->args ? f->base->args->var_decl->value->type : NULL;
-  const Type r = f->base->args ? is_unary ? f->base->args->var_decl->value->type :
-    f->base->args->next ? f->base->args->next->var_decl->value->type :
-    f->base->ret_type : NULL;
   struct Op_Func opfunc = { .ck=strcmp(str, "@implicit") ? 0 : opck_usr_implicit };
-  struct Op_Import opi = { .op=f->base->xid, .lhs=l, .rhs=r, .ret=f->base->ret_type,
-                           .pos=f->pos, .data=(uintptr_t)f->base->func, .func=&opfunc };
+  struct Op_Import opi = { .ret=f->base->ret_type, .pos=f->pos,
+      .data=(uintptr_t)f->base->func, .func=&opfunc };
+  func_operator(f, &opi);
   CHECK_BB(add_op(env->gwion, &opi))
   operator_set_func(&opi);
   return GW_OK;
index ea9746d0ef3fc62ce1487f4dd5c8c3fc3a7903a6..9771edd95393e4c3a45c7bce7b945e1148bd44eb 100644 (file)
@@ -20,13 +20,33 @@ ANN Type type_nonnull(const Env env, const Type base) {
   if(t->nspc)
     ADD_REF(t->nspc)
   t->name = s_name(sym);
-  t->flag = base->flag;
-  SET_FLAG(t, nonnull);
+  t->flag = base->flag | ae_flag_nonnull;
   nspc_add_type_front(t->e->owner, sym, t);
-  mk_class(env, t);
   return t;
 }
 
+#define STR_FORCE ":force"
+#define STRLEN_FORCE strlen(STR_FORCE)
+
+ANN static inline Type new_force_type(MemPool p, const Type t, const Symbol sym) {
+  const Type ret = type_copy(p, t);
+  if(ret->nspc)
+    ADD_REF(ret->nspc)
+  ret->name = s_name(sym);
+  ret->flag = t->flag | ae_flag_force;
+  nspc_add_type_front(t->e->owner, sym, ret);
+  return ret;
+ }
+
+ANN Type force_type(const Env env, const Type t) {
+  const size_t len = strlen(t->name);
+  char name[len + STRLEN_FORCE + 2];
+  strcpy(name, t->name);
+  strcpy(name + len, STR_FORCE);
+  const Symbol sym = insert_symbol(name);
+  return nspc_lookup_type1(t->e->owner, sym) ?: new_force_type(env->gwion->mp, t, sym);
+}
+
 ANN Type type_decl_resolve(const Env env, Type_Decl* td) {
   DECL_OO(const Type, base, = find_type(env, td))
   if(base->e->ctx && base->e->ctx->error)