]> Nishi Git Mirror - gwion.git/commitdiff
:fire: named parameters
authorfennecdjay <fennecdjay@gmail.com>
Thu, 7 Nov 2024 10:14:53 +0000 (11:14 +0100)
committerfennecdjay <fennecdjay@gmail.com>
Thu, 7 Nov 2024 10:14:53 +0000 (11:14 +0100)
21 files changed:
ast
include/parse.h
src/clean.c
src/emit/emit.c
src/import/import_checker.c
src/import/import_oper.c
src/lib/deep_equal.c
src/lib/object_op.c
src/lib/opfunc.c
src/lib/prim.c
src/lib/sift.c
src/lib/union.c
src/parse/check.c
src/parse/operator.c
src/parse/scan0.c
src/parse/scan1.c
src/parse/scan2.c
src/parse/template.c
src/parse/validate.c
src/sema/default_arg.c
src/sema/sema.c

diff --git a/ast b/ast
index 4a237db7d547d5b132ffcdb4489ed67126e67e69..bf2ac162a45d024461ed046fb4af500566a10f54 160000 (submodule)
--- a/ast
+++ b/ast
@@ -1 +1 @@
-Subproject commit 4a237db7d547d5b132ffcdb4489ed67126e67e69
+Subproject commit bf2ac162a45d024461ed046fb4af500566a10f54
index 4d2a25292bcb529b587ab4f25203c0d2dab0db55..c321a1e32d2b5157b48a28681d12cbbe5a5c56f3 100644 (file)
@@ -169,7 +169,7 @@ ANN bool abstract_array(const Env env, const Array_Sub array);
 ANN static inline bool is_static_call(const Gwion gwion, Exp* e) {
   if (e->exp_type != ae_exp_dot) return true;
   const Exp_Dot *member = &e->d.exp_dot;
-  if(unlikely(!strcmp(s_name(member->xid), "new"))) return true;
+  if(unlikely(!strcmp(s_name(member->tag.sym), "new"))) return true;
   return GET_FLAG(e->type, final) ||
          GET_FLAG(member->base->type, final) ||
          is_class(gwion, member->base->type) ||
index e66ea2e60748d64096008c7ede6eaa77f8c3fcb8..85cfa780654a75f7edfeded8e91dae296d5b6533 100644 (file)
@@ -132,6 +132,10 @@ ANN static void clean_exp_td(Clean *a, Type_Decl **b) {
   clean_type_decl(a, *b);
 }
 
+ANN static void clean_exp_named(Clean *a, Exp_Named *b) {
+  clean_exp(a, b->exp);
+}
+
 DECL_EXP_FUNC(clean, void, Clean *)
 ANN static void clean_exp(Clean *a, Exp* b) {
   clean_exp_func[b->exp_type](a, &b->d);
index 20678f406fe0f4c14ee8dceb0f4c6ab8c4f13ca5..72146263b97ed1de72c14058a513f91d347e34bc 100644 (file)
@@ -18,7 +18,6 @@
 #include "match.h"
 #include "specialid.h"
 #include "looper.h"
-#include "shreduler_private.h"
 
 #undef insert_symbol
 #define insert_symbol(a) insert_symbol(emit->gwion->st, (a))
@@ -1909,9 +1908,13 @@ ANN static bool emit_exp_td(const Emitter emit, Type_Decl *td) {
   return true;
 }
 
+ANN static bool emit_exp_named(const Emitter emit, Exp_Named *exp) {
+//  gw_out("these should be changed in verify pass");
+  return emit_exp(emit, exp->exp);
+}
 DECL_EXP_FUNC(emit, bool, Emitter)
 
-ANN2(1) /*static */ bool emit_exp(const Emitter emit, /* const */ Exp* e) {
+ANN2(1) bool emit_exp(const Emitter emit, /* const */ Exp* e) {
   Exp* exp = e;
   do {
     if (emit->info->debug){
index 9ea38f163603ec3930f33e710bc8cae81470602f..b3ac3acd40b6287008db344edc4048df3ca747a7 100644 (file)
@@ -320,7 +320,7 @@ ANN Exp* td2exp(const MemPool mp, const Type_Decl *td) {
   Exp* base = new_prim_id(mp, td->tag.sym, td->tag.loc);
   Type_Decl *next = td->next;
   while(next) {
-    base = new_exp_dot(mp, base, next->tag.sym, td->tag.loc);
+    base = new_exp_dot(mp, base, next->tag, td->tag.loc);
     next = next->next;
   }
   return base;
@@ -358,7 +358,7 @@ ANEW ANN m_str type2str(const Gwion gwion, const Type t,
 
 ANEW ANN m_str tl2str(const Gwion gwion, const TmplArg_List tl,
                       const loc_t loc NUSED) {
-  struct GwfmtState ls = {.minimize=true, .ppa = gwion->ppa};
+  struct GwfmtState ls = {.minimize=true, .ppa = gwion->ppa, .color=false};
   gwfmt_state_init(&ls);
   text_init(&ls.text, gwion->mp);
   Gwfmt gwfmter = {.mp = gwion->mp, .st = gwion->st, .ls = &ls, .line = 1, .last = cht_nl };
index 1f6e1afb11b5ac4bc591824cc5265f3eb7db087d..33ed1811e53c2e47347ad09d6820c011bd01f21d 100644 (file)
@@ -1,6 +1,3 @@
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
 #include "gwion_util.h"
 #include "gwion_ast.h"
 #include "gwion_env.h"
@@ -13,8 +10,6 @@
 #include "operator.h"
 #include "import.h"
 #include "gwi.h"
-#include "mpool.h"
-#include "specialid.h"
 
 ANN static Type _get_type(const Gwi gwi, const m_str s) {
   if (s == (m_str)OP_ANY_TYPE) return OP_ANY_TYPE;
@@ -30,7 +25,8 @@ static bool import_op(const Gwi gwi, struct OperCK *const op, const f_instr f) {
   const Type lhs = gwi_get_type(gwi, op->lhs), rhs = gwi_get_type(gwi, op->rhs),
              ret              = gwi_get_type(gwi, op->ret);
   const struct Op_Func opfunc = {
-      .ck = op->ck, .em = op->em, .effect = {.ptr = op->effect.ptr}};
+      .ck = op->ck, .em = op->em,
+      .effect = {.ptr = op->effect.ptr}};
   const struct Op_Import opi = {.lhs  = lhs,
                                 .rhs  = rhs,
                                 .ret  = ret,
@@ -52,7 +48,7 @@ bool gwi_oper_ini(const Gwi gwi, const restrict m_str l,
   return true;
 }
 
-ANN bool gwi_oper_add(const Gwi gwi, Type (*ck)(Env, void *)) {
+ANN bool gwi_oper_add(const Gwi gwi, const opck ck) {
   gwi->oper->ck = ck;
   return true;
 }
index f442dd0b0a2aa79970aa34f1f339772f5dfbc3f8..f6538275ca52c53452ec5c69a488104a0e67c4a9 100644 (file)
@@ -69,17 +69,20 @@ ANN static inline void check_deep_equal_exp(const Env env, Exp* e, const Vector
     exp_setvar(e, true);
 }
 
-#define MK_DOT(_data, _exp, _value)                           \
-  {                                                           \
-    .d = {                                                    \
-      .exp_dot = {                                            \
-        .base = _exp,                                         \
-        .xid = insert_symbol(_data->gwion->st, _value->name)  \
-      }                                                       \
-    },                                                        \
-    .type = _value->type,                                     \
-    .exp_type = ae_exp_dot,                                   \
-    .loc = _exp->loc                                          \
+#define MK_DOT(_data, _exp, _value)                             \
+  {                                                             \
+    .d = {                                                      \
+      .exp_dot = {                                              \
+        .base = _exp,                                           \
+        .tag = {                                                \
+          .sym = insert_symbol(_data->gwion->st, _value->name), \
+          .loc = _exp->loc                                      \
+        }                                                       \
+      }                                                         \
+    },                                                          \
+    .type = _value->type,                                       \
+    .exp_type = ae_exp_dot,                                     \
+    .loc = _exp->loc                                            \
   }
 
 #define MK_BIN(_lhs, _rhs, _bin)                         \
index 99a591fbc6c308e3006565ff148f76c2152faff7..41a948962dcda9e861d1c5cd16ee2c12726c209e 100644 (file)
@@ -173,13 +173,13 @@ ANN static inline void emit_struct_data(const Emitter emit, const Value v,
 
 ANN static inline Value get_value(const Env env, const Exp_Dot *member,
                                   const Type t) {
-  const Value value = find_value(t, member->xid);
+  const Value value = find_value(t, member->tag.sym);
   if (value)
     return value;
   if (env->func && env->func->def->base->values)
-    return upvalues_lookup(env->func->def->base->values, member->xid);
+    return upvalues_lookup(env->func->def->base->values, member->tag.sym);
   if(t->info->values)
-    return (Value)scope_lookup1(t->info->values, (m_uint)member->xid);
+    return (Value)scope_lookup1(t->info->values, (m_uint)member->tag.sym);
   return NULL;
 }
 
@@ -200,20 +200,20 @@ ANN static bool member_access(const Env env, Exp* exp, const Value value) {
 OP_CHECK(opck_object_dot) {
   Exp_Dot *const member      = (Exp_Dot *)data;
   Exp* self = exp_self(member);
-  const m_str  str         = s_name(member->xid);
+  const m_str  str         = s_name(member->tag.sym);
   const bool   base_static = is_class(env->gwion, member->base->type);
   const Type   the_base =
       base_static ? _class_base(member->base->type) : member->base->type;
   const Value value = get_value(env, member, the_base);
   if (!value) {
-    const Value v = nspc_lookup_value1(env->curr, member->xid);
+    const Value v = nspc_lookup_value1(env->curr, member->tag.sym);
     if(v) {
       if (self->is_call) {
         if (is_func(env->gwion, v->type) && (!v->from->owner_class || isa(the_base, v->from->owner_class))) // is_callable needs type
           return v->type;
       }
     }
-    env_err(env, self->loc, _("class '%s' has no member '%s'"),
+    env_err(env, member->tag.loc, _("class '%s' has no member '%s'"),
             the_base->name, str);
     if (member->base->type->nspc) did_you_mean_type(the_base, str);
     return env->gwion->type[et_error];
@@ -237,7 +237,7 @@ ANN static Type member_type(const Gwion gwion, const Type base) {
 OP_EMIT(opem_object_dot) {
   const Exp_Dot *member = (Exp_Dot *)data;
   const Type     t_base = member_type(emit->gwion, member->base->type);
-  const Value    value  = find_value(t_base, member->xid);
+  const Value    value  = find_value(t_base, member->tag.sym);
   if (is_class(emit->gwion, value->type)) {
     emit_pushimm(emit, (m_uint)value->type);
     return true;
index 794ca80b6b2236011946790ebdb9e046a29e2dab..0c22f1501c0254635cb91a63528832b9fd340116 100644 (file)
@@ -73,7 +73,7 @@ OP_CHECK(opck_rassign) {
   const Exp_Binary *bin = (Exp_Binary *)data;
   if (opck_const_rhs(env, data) == env->gwion->type[et_error])
     return env->gwion->type[et_error];
-  exp_setvar(bin->rhs, 1);
+  exp_setvar(bin->rhs, true);
   return bin->rhs->type;
 }
 
@@ -140,7 +140,7 @@ OP_CHECK(opck_new) {
     Exp* args   = cpy_exp(env->gwion->mp, unary->ctor.exp);
     Exp* base   = new_exp_unary2(env->gwion->mp, unary->op, unary->ctor.td, unary->ctor.exp, self->loc);
     base->type = t;
-    Exp* func   = new_exp_dot(env->gwion->mp, base, insert_symbol("new"), self->loc);
+    Exp* func   = new_exp_dot(env->gwion->mp, base, MK_TAG(insert_symbol("new"), self->loc), self->loc);
     self->d.exp_call.func = func;
     self->d.exp_call.args = args;
     self->d.exp_call.tmpl = NULL;
index ebb41be34e94e23956692f0e54b93efec1d725fb..1a3144eb7fb711686919a47b0a9ebed6b14150bf 100644 (file)
@@ -497,7 +497,7 @@ static inline int is_now(const Env env, Exp* exp) {
 static OP_CHECK(opck_now) {
   const Exp_Binary *bin = (Exp_Binary *)data;
   if (!is_now(env, bin->rhs)) CHECK_NN(opck_const_rhs(env, data));
-  exp_setvar(bin->rhs, 1);
+  exp_setvar(bin->rhs, true);
   return bin->rhs->type;
 }
 
index f64ce856c47a114edaa46b94a7adff698de00b25..fefff660439a8b7b47cd996ccaf27689ccca5e38 100644 (file)
@@ -37,7 +37,7 @@ static OP_CHECK(opck_ctrl) {
   Exp* exp = exp_self(data);
 
   Exp* func = cpy_exp(mp, exp);
-  Exp* dot = new_exp_dot(mp, func->d.exp_binary.lhs, insert_symbol(env->gwion->st, "last"), func->loc);
+  Exp* dot = new_exp_dot(mp, func->d.exp_binary.lhs, MK_TAG(insert_symbol(env->gwion->st, "last"), func->loc), func->loc);
   Exp* call = new_exp_call(mp, dot, NULL, func->loc);
   func->d.exp_binary.lhs = call;
   func->d.exp_binary.op = chuck;
index d92848980581e7f2d0144f4288cadec4ac1895ed..a2b8d9addd45ba3f5378f4407dd4e2602692541c 100644 (file)
@@ -31,22 +31,105 @@ static INSTR(UnionIndex) {
   // probs exosts already
   *(m_uint*)REG(-SZ_INT) = **(m_uint**)REG(-SZ_INT);
 }
+
+static bool needs_reset(const Env env, const Exp *base) {
+  return base->cast_to
+//    && isa(base->cast_t
+    && strcmp(*(m_str*)base->cast_to->nspc->class_data, env->curr->name);
+}
+
+// TODO: put in header, check other uses
+OP_CHECK(opck_object_dot);
+
+OP_EMIT(opem_setunion_implicit) { exit(19);}
+
+OP_CHECK(opck_setunion_class) {
+  struct TemplateScan *ts      = (struct TemplateScan *)data;
+  const Type base = known_type(env, mp_vector_at(ts->td->types, TmplArg, 0)->d.td);
+  const m_str name = mp_vector_at(ts->td->types, TmplArg, 1)->d.exp->d.prim.d.string.data;
+  char buf[256];
+  snprintf(buf, 256, "FlowType:[%s,\"%s\",\"%s\"]",
+           base->name, name, env->curr->name); // vector_at 1
+  const Type t = type_copy(env->gwion->mp, base);
+  t->name = s_name(insert_symbol(env->gwion->st, buf));
+  t->info->parent = ts->t; // check if not set by copy
+  t->info->base_type = base;
+  t->nspc = new_nspc(env->gwion->mp, t->name);
+  t->nspc->class_data_size = 16;
+  nspc_allocdata(env->gwion->mp, t->nspc);
+  *(m_str*)t->nspc->class_data = s_name(insert_symbol(env->gwion->st, name));
+  *(m_str*)(t->nspc->class_data+SZ_INT) = s_name(insert_symbol(env->gwion->st, env->name));
+  return t;
+}
+
+OP_CHECK(opck_setunion_implicit) {
+  exit(87);
+}
+
+static Value find_dot_value(const Env env, const Exp *exp) {
+//  if(exp->exp_type == ae_exp_dot)
+//    return find_dot_value(
+  if(exp->exp_type == ae_exp_primary && exp->d.prim.prim_type == ae_prim_id)
+    return nspc_lookup_value1(env->curr, exp->d.prim.d.var);
+  return NULL;
+}
+
+static OP_CHECK(opck_setunion_dot) { 
+  const Exp_Dot *member = (Exp_Dot *)data;
+  const Type set_t = member->base->type;
+  const Type t = member->base->type->info->base_type;
+  member->base->type = t;
+  const Type ret = opck_object_dot(env, data);
+  member->base->type = set_t;
+  return ret;
+}
+
+static OP_CHECK(opck_setunion_dot2) {
+  puts(__func__);
+  const Exp_Dot *member = (Exp_Dot *)data;
+  puts(member->base->type->name);
+  const m_str name = *(m_str*)member->base->type->nspc->class_data;
+  if(!exp_getvar(exp_self(member)) && strcmp(s_name(member->tag.sym), name)) {
+    // change member->base->loc to member->tag.loc
+    char buf[256];
+    sprintf(buf, "expected {G}%s{0}", name);
+    gwlog_error("invalid union access", buf, env->name, member->base->loc, 0);
+    return env->gwion->type[et_error];
+  }
+  member->base->type = member->base->type->info->base_type;
+  return exp_self(member)->type;
+}
+
+static OP_CHECK(opck_union_dot) {
+  const Exp_Dot *member = (Exp_Dot *)data;
+  find_dot_value(env, member->base);
+  DECL_NN(const Type, ret, = opck_object_dot(env, data));
+/*
+  char buf[256];
+  snprintf(buf, 256, "FlowType:[%s,\"%s\",\"%s\"]",
+           member->base->type->name, s_name(member->xid), env->curr->name);
+  const Value v = find_dot_value(env, member->base);
+  if(v)
+    v->type = str2type(env->gwion, buf, member->base->loc);
+*/
+  return ret;
+}
+
 static OP_EMIT(opem_union_dot) {
   const Exp_Dot *member = (Exp_Dot *)data;
-  const Map      map    = &member->base->type->nspc->info->value->map;
   exp_setvar(member->base, true);
   CHECK_B(emit_exp(emit, member->base));
   if (is_func(emit->gwion, exp_self(member)->type)) { // is_callable? can only be a func
     emit_pushimm(emit, (m_uint)exp_self(member)->type->info->func->code);
     return true;
   }
-  if (!strcmp(s_name(member->xid), "index")) {
-    //emit_add_instr(emit, DotMember);
+  if (!strcmp(s_name(member->tag.sym), "index")) {
     emit_add_instr(emit, UnionIndex);
     return true;
   }
+  const Map      map    = &member->base->type->nspc->info->value->map;
   for (m_uint i = 0; i < map_size(map); ++i) {
-    if (VKEY(map, i) == (m_uint)member->xid) {
+    if (VKEY(map, i) == (m_uint)member->tag.sym) {
       const Value v         = (Value)VVAL(map, i);
       const uint  emit_addr = exp_getvar(exp_self(member));
       emit_unionmember(emit, i, v->type->size, emit_addr);
@@ -88,7 +171,7 @@ static OP_CHECK(opck_union_is) {
       Exp* exp_args  = call->args;
       e->exp_type         = ae_exp_binary;
       e->d.exp_binary.lhs = cpy_exp(env->gwion->mp, exp_func);
-      e->d.exp_binary.lhs->d.exp_dot.xid =
+      e->d.exp_binary.lhs->d.exp_dot.tag.sym =
           insert_symbol(env->gwion->st, "index");
       //      e->d.exp_binary.rhs = new_prim_int(env->gwion->mp, i+1, e->loc);
       e->d.exp_binary.rhs = new_prim_int(env->gwion->mp, i, e->loc);
index 8bfa07ff2082d7c3666768ce6f4c60340b5ee0c8..8af1b75a3db486a0d3e6a861997fd588d665995f 100644 (file)
@@ -378,7 +378,7 @@ ANN static Type prim_owned(const Env env, const Symbol *data) {
   exp->d.exp_dot.base = base;
   base->d.prim.value = v->from->owner_class->info->value;
 //  base->type = v->from->owner_class;
-  exp->d.exp_dot.xid  = *data;
+  exp->d.exp_dot.tag.sym  = *data;
   return check_exp(env, exp);
 }
 
@@ -410,7 +410,7 @@ ANN static Type prim_id_non_res(const Env env, const Symbol *data) {
             exp->exp_type = ae_exp_dot;
             Type_Decl *td = cpy_type_decl(env->gwion->mp, using->d.td);
             exp->d.exp_dot.base = new_exp_td(env->gwion->mp, td, exp->loc);
-            exp->d.exp_dot.xid = insert_symbol(value->name);
+            exp->d.exp_dot.tag.sym = insert_symbol(value->name);
             return check_exp(env, exp);
           }
         } else if(sym == using->tag.sym) {
@@ -643,7 +643,7 @@ ANN static Func call2ufcs(const Env env, Exp_Call *call, const Value v) {
   call->args                   = this;
   call->func->type             = v->type;
   call->func->d.prim.value     = v;
-  call->func->d.prim.d.var     = call->func->d.exp_dot.xid;
+  call->func->d.prim.d.var     = call->func->d.exp_dot.tag.sym;
   call->func->exp_type         = ae_exp_primary;
   call->func->d.prim.prim_type = ae_prim_id;
   CHECK_O(check_exp_call(env, call));
@@ -657,7 +657,7 @@ ANN static Func ufcs(const Env env, const Func up, Exp_Call *const call) {
   return NULL;
 }
 
-ANN Func find_func_match(const Env env, const Func up, Exp_Call *const call) {
+static ANN Func find_func_match_normal(const Env env, const Func up, Exp_Call *const call) {
   Func      func;
   Exp* exp = call->args;
   Exp* args =
@@ -672,6 +672,110 @@ ANN Func find_func_match(const Env env, const Func up, Exp_Call *const call) {
              : NULL;
 }
 
+ANN bool call_has_named_args(Exp_Call *call, uint32_t *nargs) {
+  Exp *exp = call->args;
+  bool ret = false;
+  do {
+    if(exp->exp_type == ae_exp_named)
+      ret = true;
+    (*nargs)++;
+  } while ((exp = exp->next));
+  return ret;
+}
+
+struct NamedChecker {
+  MP_Vector *call_list;
+  MP_Vector *named;
+  MP_Vector *unnamed;
+  uint32_t  nargs;
+};
+
+static ANN Func __find_func_match_named(const Env env, const Func up, Exp_Call *const call, const struct NamedChecker *nc) {
+  const MP_Vector *args = up->def->base->args;
+  if(!args || nc->nargs != args->len) {
+    return NULL;
+  }
+
+  uint32_t nnamed = 0;
+  uint32_t nunnamed = 0;
+  for(uint32_t i = 0; i < args->len; i++) {
+    bool found = false;
+    Arg *arg = mp_vector_at(args, Arg, i);
+    for(uint32_t j = 0; j < nc->named->len; j++) {
+      Exp *exp = *mp_vector_at(nc->named, Exp*, j);
+      if(arg->var.vd.tag.sym == exp->d.exp_named.tag.sym) {
+        mp_vector_set(nc->call_list, Exp*, i, exp);
+        nnamed++;
+        found = true;
+        break;
+      }
+    }
+    if(!found && nunnamed < nc->unnamed->len)
+      mp_vector_set(nc->call_list, Exp*, i, *mp_vector_at(nc->unnamed, Exp*,nunnamed++));
+  }
+  if((nunnamed + nnamed) != nc->nargs) return NULL;
+  for(uint32_t i = 1; i < nc->call_list->len; i++) {
+    (*mp_vector_at(nc->call_list, Exp*, i-1))->next = 
+    *mp_vector_at(nc->call_list, Exp*, i);
+  }
+  (*mp_vector_at(nc->call_list, Exp*, nc->call_list->len-1))->next = NULL;
+  call->args = *mp_vector_at(nc->call_list, Exp*, 0);
+  return find_func_match_normal(env, up, call);
+}
+
+static ANN Func _find_func_match_named(const Env env, const Func up, Exp_Call *const call, const struct NamedChecker *nc) {
+  Func ret = __find_func_match_named(env, up, call, nc);
+  if(ret) return ret;
+  if(!up->next) return NULL;
+  return _find_func_match_named(env, up->next, call, nc);
+}
+
+static ANN Func find_func_match_named(const Env env, const Func up, Exp_Call *const call, const uint32_t nargs) {
+  struct NamedChecker nc = {
+    .call_list = new_mp_vector(env->gwion->mp, Exp*, nargs),
+    .named = new_mp_vector(env->gwion->mp, Exp*, 0),
+    .unnamed = new_mp_vector(env->gwion->mp, Exp*, 0),
+    .nargs = nargs,
+  };
+  MP_Vector *arg_list = new_mp_vector(env->gwion->mp, Exp*, nargs);
+  Exp *exp = call->args;
+  uint32_t i = 0;
+  do {
+    mp_vector_set(arg_list, Exp*, i, exp);
+    if(exp->exp_type == ae_exp_named) {
+      exp->d.exp_named.is_arg = true;
+      mp_vector_add(env->gwion->mp, &nc.named, Exp*, exp);
+    } else
+      mp_vector_add(env->gwion->mp, &nc.unnamed, Exp*, exp);
+    i++;
+  } while((exp = exp->next));
+
+  const Func ret = _find_func_match_named(env, up, call, &nc);
+
+  if(!ret) {
+    for(uint32_t i = 1; i < arg_list->len; i++) {
+      (*mp_vector_at(arg_list, Exp*, i-1))->next = 
+        *mp_vector_at(arg_list, Exp*, i);
+    }
+    (*mp_vector_at(arg_list, Exp*, arg_list->len-1))->next = NULL;
+    call->args = (*mp_vector_at(arg_list, Exp*, 0));
+  }
+
+  free_mp_vector(env->gwion->mp, Exp*, arg_list);
+  free_mp_vector(env->gwion->mp, Exp*, nc.call_list);
+  free_mp_vector(env->gwion->mp, Exp*, nc.named);
+  free_mp_vector(env->gwion->mp, Exp*, nc.unnamed);
+
+  return ret;
+}
+
+ANN Func find_func_match(const Env env, const Func up, Exp_Call *const call) {
+  uint32_t nargs = 0;
+  if(!call->args || !call_has_named_args(call, &nargs))
+    return find_func_match_normal(env, up, call);
+  return find_func_match_named(env, up, call, nargs);
+}
+
 ANN bool check_traverse_fdef(const Env env, const Func_Def fdef) {
   struct Vector_ v     = {};
   const m_uint scope   = env->scope->depth;
@@ -713,8 +817,11 @@ ANN static inline Exp* next_arg_exp(const Exp *e) {
 }
 
 ANN static void print_current_args(Exp* e) {
-  do gw_err(" {G}%s{0}", e->type ? e->type->name : "<Unknown>");
-  while ((e = next_arg_exp(e)));
+  do {
+    if (e->exp_type == ae_exp_named)
+      gw_err(" {B}%s{0} =", s_name(e->d.exp_named.tag.sym));
+    gw_err(" {G}%s{0}", e->type ? e->type->name : "<Unknown>");
+  } while ((e = next_arg_exp(e)));
   gw_err("\n");
 }
 
@@ -1045,7 +1152,7 @@ ANN static Type call_return(const Env env, Exp_Call *const exp,
   return NULL;
 }
 
-ANN Type _check_exp_call1(const Env env, Exp_Call *const exp) {
+static ANN Type _check_exp_call1(const Env env, Exp_Call *const exp) {
   DECL_O(const Type, t, = call_type(env, exp));
   if (t == env->gwion->type[et_op]) return check_op_call(env, exp);
   if (!t->info->func) // TODO: effects?
@@ -1109,6 +1216,7 @@ ANN static Type check_exp_binary(const Env env, const Exp_Binary *bin) {
                          bin->rhs->d.exp_decl.type == env->gwion->type[et_auto];
   if (is_auto) bin->rhs->d.exp_decl.type = bin->lhs->type;
   // allow foo => new C to mean new C(foo)
+  // do we actually still need that?
   if(bin->op == insert_symbol("=>") &&
      bin->rhs->exp_type == ae_exp_unary && bin->rhs->d.exp_unary.unary_type == unary_td &&
      !bin->rhs->d.exp_unary.ctor.td->array &&
@@ -1368,6 +1476,9 @@ ANN static Type check_exp_td(const Env env, Type_Decl **td) {
   return t;
 }
 
+ANN static Type check_exp_named(const Env env, Exp_Named *exp_named) {
+  return check_exp(env, exp_named->exp);
+}
 DECL_EXP_FUNC(check, Type, Env)
 
 ANN Type check_exp(const Env env, Exp* exp) {
index c1ac396edef154597dab978d6472fbfe85769d98..256c52c33b2369d2a5096191cb6f406b6b20e506 100644 (file)
@@ -172,9 +172,6 @@ ANN bool add_op(const Gwion gwion, const struct Op_Import *opi) {
       CHECK_B(op_exist(&ock, n));
     }
   } while ((n = n->parent));
-  // Nspc nspc = gwion->env->context
-  //   ? gwion->env->context->nspc
-  //   : gwion->env->curr;
   const Nspc nspc = get_nspc(gwion->env);
   if (!nspc->operators)
     nspc->operators = mp_calloc(gwion->mp, NspcOp);
@@ -208,7 +205,7 @@ ANN static Type op_check_inner(const Env env, struct OpChecker *ock,
                                               ock->opi->lhs, r)
                              : operator_find((Vector)&VVAL(ock->map, idx),
                                              ock->opi->lhs, r))) {
-      if ((mo->ck && (t = mo->ck(ock->env, (void *)ock->opi->data)))) {
+     if ((mo->ck && (t = mo->ck(ock->env, (void *)ock->opi->data)))) {
         ock->effect.ptr = mo->effect.ptr;
         return t;
       } else
@@ -296,6 +293,7 @@ ANN static Type op_check_tmpl(const Env env, struct Op_Import *opi) {
   return NULL;
 }
 
+// TODO: maybe should return M_Operator*?
 ANN void* op_get(const Env env, struct Op_Import *opi) {
   for (int i = 0; i < 2; ++i) {
     Nspc nspc = env->curr;
@@ -395,8 +393,6 @@ ANN Type op_check(const Env env, struct Op_Import *opi) {
 }
 
 ANN bool operator_set_func(const Env env, const struct Op_Import *opi) {
-  //const Nspc   nspc = ((Func)opi->data)->value_ref->from->owner;
-  //const Nspc   nspc = ((Func)opi->data)->value_ref->from->ctx->nspc;
   const Nspc   nspc = get_nspc(env);
   const m_int  idx  = map_index(&nspc->operators->map, (vtype)opi->op);
   const Vector v    = (Vector)&VVAL(&nspc->operators->map, idx);
index 6730933370617ea7ec0bb59d0320a7c1e6ef886a..d9d69c30a6fa674dec28bacef5286a71f4915171 100644 (file)
@@ -280,6 +280,7 @@ ANN static void union_tmpl(const Env env, const Union_Def udef) {
 
 ANN bool scan0_union_def(const Env env, const Union_Def udef) {
   bool global = false;
+  bool ok = true;
   CHECK_B(scan0_global(env, udef->flag, udef->tag.loc, &global));
   CHECK_B(scan0_defined(env, udef->tag));
   udef->type   = union_type(env, udef->tag.sym, udef->tag.loc);
@@ -287,7 +288,7 @@ ANN bool scan0_union_def(const Env env, const Union_Def udef) {
   if (udef->tmpl) union_tmpl(env, udef);
   if (global) env_pop(env, 0);
   set_tflag(udef->type, tflag_scan0);
-  return true;
+  return ok;
 }
 
 ANN static inline void cdef_flag(const Class_Def cdef, const Type t) {
index e84225ba1a83a4253e6dd7be07fdd584b0edcf6c..ac2388d9cbc31b41286000836a728335b3195412 100644 (file)
@@ -144,7 +144,7 @@ ANN static bool scan1_decl(const Env env, Exp_Decl *const decl) {
       SET_FLAG(v, global);
     else if(env->context)
     set_vflag(v, vflag_fglobal); // file global
-  } else if (GET_FLAG(decl->var.td, global))
+  } else if (GET_FLAG(decl->var.td, global)) // wait we can have globals in a scope ?
     SET_FLAG(v, global);
   nspc_add_value(env->curr, vd->tag.sym, v);
   ((Exp_Decl *)decl)->type = decl->var.vd.value->type;
@@ -250,6 +250,11 @@ ANN static inline bool scan1_exp_unary(const restrict Env env,
 
 #define scan1_exp_lambda dummy_func
 #define scan1_exp_td     dummy_func
+
+ANN static bool scan1_exp_named(const Env env, Exp_Named *named) {
+  return scan1_exp(env, named->exp);
+}
+
 HANDLE_EXP_FUNC(scan1, bool, Env)
 
 ANN static inline bool _scan1_stmt_match_case(const restrict Env env,
@@ -410,6 +415,19 @@ ANN static inline bool scan1_stmt_exp(const Env env, const Stmt_Exp stmt) {
   return stmt->val ? scan1_exp(env, stmt->val) : 1;
 }
 
+ANN static void enum_value(const Env env, const Enum_Def edef,
+                           const Tag tag, const m_int value, m_int *last) {
+  const Value v = new_value(env, edef->type, tag);
+  v->d.num = value;
+  *last = v->d.num + 1;
+  valuefrom(env, v->from);
+  nspc_add_value(env->curr, tag.sym, v);
+  SET_FLAG(v, static | ae_flag_const);
+  SET_ACCESS(edef, v)
+  SET_ACCESS(edef, edef->type)
+  set_vflag(v, vflag_builtin);
+}
+
 ANN bool scan1_enum_def(const Env env, const Enum_Def edef) {
   const Type t = edef->type;
   t->nspc = new_nspc(env->gwion->mp, t->name);
@@ -418,15 +436,11 @@ ANN bool scan1_enum_def(const Env env, const Enum_Def edef) {
   m_int last = 0;
   for(uint32_t i = 0; i < list->len; i++) {
     EnumValue ev = *mp_vector_at(list, EnumValue, i);
-    const Value v = new_value(env, t, ev.tag);
-    v->d.num = (ev.set ? ev.gwint.num : last);
-    last = v->d.num + 1;
-    valuefrom(env, v->from);
-    nspc_add_value(env->curr, ev.tag.sym, v);
-    SET_FLAG(v, static | ae_flag_const);
-    SET_ACCESS(edef, v)
-    SET_ACCESS(edef, t)
-    set_vflag(v, vflag_builtin);
+    CHECK_B(can_define(env, ev.tag.sym, ev.tag.loc));
+    const m_int value = !ev.set
+      ? last
+      : ev.gwint.num;
+    enum_value(env, edef, ev.tag, value, &last);
   }
   env_pop(env, scope);
   return true;
@@ -550,17 +564,13 @@ ANN bool scan1_type_def(const Env env, const Type_Def tdef) {
 
 ANN static inline bool scan1_union_def_inner_loop(const Env env,
                                                     Union_Def udef) {
-  nspc_allocdata(env->gwion->mp, udef->type->nspc);
-  Variable_List  l  = udef->l;
   m_uint      sz = 0;
-  const Symbol sym = insert_symbol("@index");
-  const Value v = new_value(env, env->gwion->type[et_int], MK_TAG(sym, udef->tag.loc));
-  nspc_add_value_front(env->curr, sym, v);
-  valuefrom(env, v->from);
   bool ok = true;
+  Variable_List  l  = udef->l;
   for(uint32_t i = 0; i < l->len; i++) {
     Variable *um = mp_vector_at(l, Variable, i);
     if (nspc_lookup_value0(env->curr, um->vd.tag.sym)) {
+      // TODO: use already_declared
       ERR_OK(ok, um->vd.tag.loc, _("'%s' already declared in union"), s_name(um->vd.tag.sym));
       continue;
     }
@@ -885,8 +895,8 @@ ANN static bool scan1_class_def_body(const Env env, const Class_Def cdef) {
   }
 //  return 
 // check for previous errors?
-cdef->base.type->error = !env_body(env, cdef, scan1_section);
-return true;
+  cdef->base.type->error = !env_body(env, cdef, scan1_section);
+  return true;
 }
 
 ANN static bool scan1_class_tmpl(const Env env, const Class_Def c) {
index f29862813b68e654be0d09fbcb2e3a7edcefbee5..74659e0dff4b821b6c740aa7357b71f73cd2a54d 100644 (file)
@@ -210,6 +210,10 @@ ANN static inline bool scan2_stmt_match(const restrict Env env,
   RET_NSPC(_scan2_stmt_match(env, stmt))
 }
 
+ANN static bool scan2_exp_named(const Env env, Exp_Named *named) {
+  return scan2_exp(env, named->exp);
+}
+
 #define scan2_exp_lambda dummy_func
 #define scan2_exp_td     dummy_func
 HANDLE_EXP_FUNC(scan2, bool, Env)
index bbe51d68f11de51bf4c284fb261cc4cc6169e952..00e7772a26af629fa9ed8aaa379e19537300c309 100644 (file)
@@ -202,7 +202,7 @@ ANN2(1,2) bool check_tmpl(const Env env, const TmplArg_List tl, const Specialize
          if(t) {
            targ->type = tmplarg_exp;
            Exp* e = new_exp_td(env->gwion->mp, base, base->tag.loc);
-           targ->d.exp = new_exp_dot(env->gwion->mp, e, last->tag.sym, base->tag.loc);
+           targ->d.exp = new_exp_dot(env->gwion->mp, e, last->tag, base->tag.loc);
            free_type_decl(env->gwion->mp, last);
            i--;
            continue;
index 7ccf6cfd4e339cac71134f8455e3dc8159df2f49..72dd24a1049dc820ce4ffc4f2e0ee132044d4f0d 100644 (file)
@@ -228,6 +228,14 @@ ANN static bool validate_exp_td(Validate *a, Type_Decl *b) {
   return validate_type_decl(a, b);
 }
 
+ANN static bool validate_exp_named(Validate *a, Exp_Named *b) {
+  if(!b->is_arg) {
+    env_err(a->env, exp_self(b)->loc, "named expression not in a function call");
+    return false;
+  }
+  return validate_exp(a, b->exp);
+}
+
 DECL_EXP_FUNC(validate, bool, Validate*)
 ANN static bool validate_exp(Validate *a, Exp* b) {
   bool ret = true;
index 338bec923ccb661c3a359e0e02740659ada39be3..b159c69f29439ba176bf7776b331d16b7f800abf 100644 (file)
@@ -51,7 +51,7 @@ ANN static Stmt_List new_code(const Sema *sema, Func_Base *base, const uint32_t
   SymTable *st = sema->st;
   Exp* dbase  = new_prim_id(p, insert_symbol(st, "this"), base->tag.loc);
   const Symbol sym = insert_symbol(st, "new");
-  Exp* func  = new_exp_dot(p, dbase, sym, base->tag.loc);
+  Exp* func  = new_exp_dot(p, dbase, MK_TAG(sym, base->tag.loc), base->tag.loc);
   return code(p, func, base->args, max, ae_stmt_exp);
 }
 
index c1d96a3603fec40714ed41bc87922304c6934fd3..004c57d5d97da92243c04bfc358defad4cf46454 100644 (file)
@@ -250,6 +250,10 @@ ANN static bool sema_exp_td(Sema *a, Type_Decl *b) {
   return type_decl_array_empty(a, b, "in `type declaration` expression");
 }
 
+ANN static bool sema_exp_named(Sema *a, Exp_Named *b) { 
+  return sema_exp(a, b->exp);
+}
+
 DECL_EXP_FUNC(sema, bool, Sema*)
 ANN static bool sema_exp(Sema *a, Exp* b) {
   bool ok = sema_exp_func[b->exp_type](a, &b->d);
@@ -542,7 +546,7 @@ ANN static bool sema_stmt_spread(Sema *a, Spread_Def b) {
     MP_Vector *result = new_mp_vector(a->mp, Stmt, base->len + stmt_list->len - 1);
     // store the first part of the list in it
     // TODO: use memcpy
-    // or berrer, use the above function to just start at part two
+    // or better, use the above function to just start at part two
     for(uint32_t i = 0; i < index; i++) {
       Stmt stmt = *mp_vector_at(base, Stmt, i);
       mp_vector_set(result, Stmt, i, stmt);
@@ -767,6 +771,11 @@ ANN static bool sema_enum_def(Sema *a, Enum_Def b) {
 
 // TODO: rename l
 ANN static bool sema_union_def(Sema *a, Union_Def b) {
+  if(!b->l->len) {
+    gwlog_error(_("unions can't be empty"), NULL,
+              a->filename, b->tag.loc, 0);
+    return false;
+  }
   bool ok = true;
   for(uint32_t i = 0; i < b->l->len; i++) {
     Variable *c = mp_vector_at(b->l, Variable, i);