]> Nishi Git Mirror - gwion.git/commitdiff
:art: Option cosmetics
authorfennecdjay <fennecdjay@gmail.com>
Tue, 10 Jan 2023 13:00:03 +0000 (14:00 +0100)
committerfennecdjay <fennecdjay@gmail.com>
Tue, 10 Jan 2023 13:00:03 +0000 (14:00 +0100)
include/array.h
src/emit/emit.c
src/lib/array.c
src/lib/closure.c
src/lib/opfunc.c
src/parse/check.c
src/parse/type_decl.c

index db9dcb22e0d9d40c4e397d3931d2abd70bf526e1..7717f8cf6795d85a10f1e5bafcf55109c0dcd468 100644 (file)
@@ -22,4 +22,5 @@ typedef struct ArrayInfo_ {
 ANN Type   check_array_access(const Env env, const Array_Sub array);
 ANN m_bool emit_array_access(const Emitter                 emit,
                              struct ArrayAccessInfo *const info);
+ANN2(1,2) m_bool check_array_instance(const Env env, Type_Decl *td, const Exp args);
 #endif
index 7d7cb519256c932eb1c6b08f81844d94fc06045a..1b437e922b5c5fa3685f7ea1d79d4b7c03aa3335 100644 (file)
@@ -700,9 +700,11 @@ ANN m_bool emit_array_access(const Emitter                 emit,
                           .lhs  = info->array.exp->type,
                           .rhs  = info->array.type,
                           .data = (uintptr_t)info};
+/*
   if (!info->is_var &&
       (GET_FLAG(info->array.type, abstract) || type_ref(info->array.type)))
     emit_fast_except(emit, NULL, info->array.exp->pos);
+*/
   return op_emit(emit, &opi);
 }
 
index b812f0ccb3d61136de77d8c19c0c37fce231d7cb..fba2b6f8cb20fedb39f8208eee26c51823bb2958 100644 (file)
@@ -213,7 +213,7 @@ static OP_EMIT(opem_array_sr) {
     return emit_array_shift(emit, ArrayConcatRight);
   emit_regmove(emit, -SZ_INT);
   if (tflag(bin->lhs->type, tflag_compound))
-    emit_compound_addref(emit, bin->lhs->type, -SZ_INT*2, false);
+    emit_compound_addref(emit, bin->lhs->type, -SZ_INT - bin->lhs->type->size, false);
   (void)emit_add_instr(emit, ArrayAppendFront);
   return GW_OK;
 }
@@ -223,7 +223,7 @@ static OP_EMIT(opem_array_sl) {
   if (shift_match(bin->rhs->type,  bin->lhs->type))
     return emit_array_shift(emit, ArrayConcatLeft);
   if (tflag(bin->rhs->type, tflag_compound))
-    emit_compound_addref(emit, bin->rhs->type, -SZ_INT, false);
+    emit_compound_addref(emit, bin->rhs->type, -bin->rhs->type->size, false);
   emit_regmove(emit, -bin->rhs->type->size);
   emit_add_instr(emit, ArrayAppend);
   return GW_OK;
@@ -1108,3 +1108,20 @@ INSTR(ArrayAlloc) {
     *(m_uint *)REG(-SZ_INT)        = num_obj;
   }
 }
+
+ANN static bool last_is_zero(Exp e) {
+  while(e->next) e = e->next;
+  return exp_is_zero(e);
+}
+
+ANN2(1,2) m_bool check_array_instance(const Env env, Type_Decl *td, const Exp args) {
+  if (!last_is_zero(td->array->exp)) {
+    if (!args)
+      ERR_B(td->pos, "declaration of abstract type arrays needs lambda");
+  } else {
+    if(args)
+      gwerr_warn("array is empty", "no need to provide a lambda",
+          NULL, env->name, td->array->exp->pos);
+  }
+  return GW_OK;
+}
index 2b44e32e8f7fa8e3c9c2d13848872c2139394c15..b3922f78ce0cbe20a5c741b6d68bb7f33834c045 100644 (file)
@@ -71,11 +71,8 @@ static OP_CHECK(opck_func_call) {
 static OP_CHECK(opck_fptr_call) {
   Exp_Binary *bin  = (Exp_Binary *)data;
   const Type t = mk_call(env, exp_self(bin), bin->rhs, bin->lhs);
-  if (t == env->gwion->type[et_error]) {
-    gwerr_basic("no matching argument of funptr call", "invalid call", "did you mean to use {+}:=>{0}", env->name, exp_self(bin)->pos, 0);
-    env->context->error = true;
-    return env->gwion->type[et_error];
-  }
+  if (t == env->gwion->type[et_error])
+    gw_err("{-}did you mean to use {0}{+}:=>{0}{-}?{0}\n");
   return t;
 }
 
index 9818126312600b8c70998536b2f947fd57379682..67fdd2ff40d2d8c0487d6a54134f482e450a5eef 100644 (file)
@@ -10,6 +10,7 @@
 #include "parse.h"
 #include "operator.h"
 #include "import.h"
+#include "array.h"
 
 OP_CHECK(opck_basic_cast) {
   const Exp_Cast *cast = (Exp_Cast *)data;
@@ -120,7 +121,10 @@ OP_CHECK(opck_new) {
   DECL_ON(const Type, t, = known_type(env, unary->ctor.td));
   if(array && !unary->ctor.exp) {
     const Type base = array_base(t);
-    if(GET_FLAG(base, abstract)) CHECK_BN(abstract_array(env, array));
+    if(GET_FLAG(base, abstract))
+      CHECK_BN(abstract_array(env, array));
+    if(GET_FLAG(base, abstract))
+      CHECK_BN(check_array_instance(env, unary->ctor.td, unary->ctor.exp));
   }
   CHECK_BN(ensure_traverse(env, t));
   if (type_ref(t))
@@ -128,7 +132,9 @@ OP_CHECK(opck_new) {
   if (tflag(t, tflag_infer))
     ERR_N(unary->ctor.td->pos, _("can't use 'new' on '%s'\n"),
           t->name);
-  if (array) CHECK_BN(check_subscripts(env, array, 1));
+  if (array) {
+    CHECK_BN(check_subscripts(env, array, 1));
+  }
   if(unary->ctor.exp) {
     const Exp self   = exp_self(unary);
     const Exp args   = cpy_exp(env->gwion->mp, unary->ctor.exp);
index e34c31ecf3d9bdb798de0bb043a0e9ac5cd9d4f0..60ba8e9b69161d67377f2af3c072acc7a82ed0fe 100644 (file)
@@ -16,6 +16,7 @@
 #include "tmp_resolve.h"
 #include "partial.h"
 #include "spread.h"
+#include "array.h"
 
 ANN m_bool check_stmt_list(const Env env, Stmt_List list);
 ANN m_bool        check_class_def(const Env env, const Class_Def class_def);
@@ -119,10 +120,10 @@ 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) {
+  if (decl->td->array && decl->td->array->exp) {
     CHECK_BB(check_subscripts(env, decl->td->array, true));
-    if(!decl->args && GET_FLAG(array_base(decl->type), abstract))
-      ERR_B(decl->td->pos, "declaration of abstract type arrays needs lambda");
+    if (GET_FLAG(array_base(decl->type), abstract))
+      CHECK_BB(check_array_instance(env, decl->td, decl->args));
   }
   valid_value(env, vd->xid, vd->value);
   // set_vflag(var->value, vflag_used));
@@ -681,7 +682,8 @@ static void function_alternative(const Env env, const Type t, const Exp args,
     return;
   gwerr_basic("Argument type mismatch", "call site",
               "valid alternatives:", env->name, pos, 0);
-  Func up = isa(t, env->gwion->type[et_closure]) < 0
+  const bool is_closure = isa(t, env->gwion->type[et_closure]) < 0;
+  Func up = is_closure
           ?  t->info->func : closure_def(t)->base->func;
   do print_signature(up);
   while ((up = up->next));
@@ -1020,8 +1022,7 @@ ANN Type check_exp_call1(const Env env, Exp_Call *const exp) {
       if(t) return t;
     }
   }
-  if(is_func(env->gwion, exp->func->type))
-    function_alternative(env, exp->func->type, exp->args, exp->func->pos);
+  function_alternative(env, exp->func->type, exp->args, exp->func->pos);
   return NULL;
 }
 
index 22f4cede3be616f51f86493ad9ae42ef0da3d852..61e28dc9f47f13e0303c6981cf787c659ac8ed03 100644 (file)
 #include "import.h"
 
 ANN static Type _option(const Env env, Type_Decl *td, const uint8_t n) {
+  const Array_Sub array = td->array;
+  td->array = NULL;
   Type_List tl  = new_mp_vector(env->gwion->mp, Type_Decl*, 1);
   mp_vector_set(tl, Type_Decl*, 0, td);
   Type_Decl         tmp = {
       .xid = insert_symbol("Option"), .types = tl, .pos = td->pos};
   const Type t = !(n - 1) ? known_type(env, &tmp) : _option(env, &tmp, n - 1);
   free_mp_vector(env->gwion->mp, Type_Decl*, tl);
+  td->array = array;
   return t;
 }