]> Nishi Git Mirror - gwion.git/commitdiff
:art: default args, and more
authorJérémie Astor <fennecdjay@gmail.com>
Tue, 5 Apr 2022 19:48:31 +0000 (21:48 +0200)
committerJérémie Astor <fennecdjay@gmail.com>
Tue, 5 Apr 2022 19:48:31 +0000 (21:48 +0200)
Makefile
ast
include/default_args.h [new file with mode: 0644]
include/env/func.h
src/arg.c
src/env/type.c
src/lib/object_op.c
src/parse/check.c
src/parse/default_arg.c [new file with mode: 0644]
src/parse/scan0.c
src/parse/scan2.c

index 02d8fd2ec3775da94c885141560669a867d0215c..4d192ae4ba691e0c7502d36f7c6823bed54420e1 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -60,7 +60,9 @@ CFLAGS += -Wno-pedantic
 
 CFLAGS += -DGWION_BUILTIN
 
-all: options-show ${GWLIBS} src/main.o
+all: options-show ${PRG}
+
+${PRG}: ${GWLIBS} src/main.o
        @$(info link ${PRG})
        @${CC} src/main.o -o ${PRG} ${LDFLAGS} ${LIBS}
 
@@ -149,7 +151,7 @@ uninstall: translation-uninstall
        @rm ${DESTDIR}/${PREFIX}/include/gwion/*.h
        @rmdir --ignore-fail-on-non-empty ${DESTDIR}/${PREFIX}/include/gwion
 
-test:
+test: ${PRG}
        @bash scripts/test.sh ${test_dir}
 
 scan:
diff --git a/ast b/ast
index c02c76b8d22fdf40fd407861e625b6e741f64ffc..1f60e2df75ddd542a0cdf1853c37d5b685bf9641 160000 (submodule)
--- a/ast
+++ b/ast
@@ -1 +1 @@
-Subproject commit c02c76b8d22fdf40fd407861e625b6e741f64ffc
+Subproject commit 1f60e2df75ddd542a0cdf1853c37d5b685bf9641
diff --git a/include/default_args.h b/include/default_args.h
new file mode 100644 (file)
index 0000000..3e1e178
--- /dev/null
@@ -0,0 +1,4 @@
+#ifndef __DEFAULT_ARGS
+#define __DEFAULT_ARGS
+ANN void default_args(const Env, const Section *, Ast *acc);
+#endif
index 34f6362440c9c8d5bf9ae92e92b21a338eea9629..286a47732ffbb0ef1f9d266fbc7feb5135517034 100644 (file)
@@ -9,7 +9,6 @@ enum fflag {
   fflag_valid  = 1 << 4,
   fflag_emit   = 1 << 5,
   fflag_return = 1 << 6,
-  fflag_recurs = 1 << 7,
 } __attribute__((packed));
 
 struct Func_ {
index 8f1e453a84aaa9e1d5b945a4d4f29a75b636fbe4..4a9d2b8c10117587c530c0c559f0ec844ebeb016 100644 (file)
--- a/src/arg.c
+++ b/src/arg.c
@@ -40,7 +40,7 @@ enum {
 ANN static inline void config_end(const Vector config) {
   for (m_uint i = 0; i < vector_size(config); ++i) {
     const Vector v = (Vector)vector_at(config, i);
-    for (m_uint i = 1; i < vector_size(v); ++i) xfree((m_str)vector_at(v, i));
+    for (m_uint i = 0; i < vector_size(v); ++i) xfree((m_str)vector_at(v, i));
     vector_release(v);
     xfree(v);
   }
index 8801e95e9ad19dddaee82e3483736b8f14e74585..577bf69d87dc4ee8d5fef46bb4d7527501397274 100644 (file)
@@ -22,8 +22,8 @@ ANN void free_type(const Type a, struct Gwion_ *const gwion) {
     else if (tflag(a, tflag_cdef))
       class_def_cleaner(gwion, a->info->cdef);
   }
-  if (tflag(a, tflag_cdef) && a->info->parent)
-    type_remref(a->info->parent, gwion);
+//  if (tflag(a, tflag_cdef) && a->info->parent)
+//    type_remref(a->info->parent, gwion);
   if (a->effects.ptr) vector_release(&a->effects);
   if (a->nspc) nspc_remref(a->nspc, gwion);
   if (a->info->tuple) free_tupleform(a->info->tuple, gwion);
index 36ab071b6855b9dde88bb20ae64a394116383d70..055aacb27dc37cd531c576e3559e15d2408c904a 100644 (file)
@@ -172,6 +172,16 @@ ANN static inline Value get_value(const Env env, const Exp_Dot *member,
   return NULL;
 }
 
+ANN static Type class_type(const Env env, const Exp_Dot *member, const Type base) {
+  const Type parent = actual_type(env->gwion, base);
+  if(!tflag(parent, tflag_tmpl)) return parent;
+  Type_Decl td = {
+       .xid=insert_symbol(env->gwion->st, parent->name),
+       .types = member->is_call->tmpl ? member->is_call->tmpl->call : NULL
+  };
+  return known_type(env, &td);
+}
+
 OP_CHECK(opck_object_dot) {
   Exp_Dot *const member      = (Exp_Dot *)data;
   const m_str    str         = s_name(member->xid);
@@ -192,12 +202,11 @@ OP_CHECK(opck_object_dot) {
       if (is_func(env->gwion, v->type) && (!v->from->owner_class || isa(the_base, v->from->owner_class) > 0))
         return v->type;
     if (is_class(env->gwion, v->type)) {
-       const Type parent = actual_type(env->gwion, v->type);
-       if (isa(the_base, parent) > 0 && parent->nspc) { // beware templates
+       DECL_OO(const Type, parent, = class_type(env, member, v->type));
+       if (isa(the_base, parent) > 0 && parent->nspc) {
           const Symbol sym = insert_symbol(env->gwion->st, "new");
           const Value ret = nspc_lookup_value1(parent->nspc, sym);
           member->xid = sym;
-//          member->base->type = parent;
           if(ret)
             return ret->type;
         }
index d93ab1c601e9ec0364068448f253d951f3cdd460..8f1426dc98d26f8516520c69638ee7ffb437ccbc 100644 (file)
@@ -787,7 +787,7 @@ ANN static Type check_lambda_call(const Env env, const Exp_Call *exp) {
 
 ANN m_bool func_check(const Env env, Exp_Call *const exp) {
   if(exp->func->exp_type == ae_exp_dot)
-    exp->func->d.exp_dot.is_call = true;
+    exp->func->d.exp_dot.is_call = exp;
   CHECK_OB(check_exp(env, exp->func));
   if (exp->func->exp_type == ae_exp_decl)
     ERR_B(exp->func->pos, _("Can't call late function pointer at declaration "
@@ -863,7 +863,7 @@ ANN Type check_exp_call1(const Env env, Exp_Call *const exp) {
       }
     exp->func->type = func->value_ref->type;
     call_add_effect(env, func, exp->func->pos);
-    if (func == env->func) set_fflag(env->func, fflag_recurs);
+//    if (func == env->func) set_fflag(env->func, fflag_recurs);
     return func->def->base->ret_type != env->gwion->type[et_auto] ?
       func->def->base->ret_type : exp->func->d.exp_dot.base->type;
   }
@@ -943,6 +943,26 @@ ANN2(1) static inline bool curried(const Env env, Exp exp) {
   return false;
 }
 
+ANN static Type check_exp_call_tmpl(const Env env, Exp_Call *exp, const Type t) {
+  if(isa(t, env->gwion->type[et_lambda]) > 0)
+    if  (!t->info->func)
+      ERR_O(exp->func->pos, _("invalid lambda use."))
+  if (exp->args) CHECK_OO(check_exp(env, exp->args));
+  if (!t->info->func->def->base->tmpl)
+    ERR_O(exp_self(exp)->pos, _("template call of non-template function."))
+  if (t->info->func->def->base->tmpl->call) {
+    if (env->func == t->info->func) {
+      exp->func->type = env->func->value_ref->type;
+      return env->func->def->base->ret_type;
+    } else
+      CHECK_BO(predefined_call(env, t, exp_self(exp)->pos));
+  }
+  const Value v = type_value(env->gwion, t);
+  DECL_OO(const Func, f, = find_template_match(env, v, exp));
+  exp->func->type = f->value_ref->type;
+  return f->def->base->ret_type;
+}
+
 ANN static Type check_exp_call(const Env env, Exp_Call *exp) {
   if (exp->apms && curried(env, exp->args))
     return env->gwion->type[et_curry];
@@ -951,23 +971,8 @@ ANN static Type check_exp_call(const Env env, Exp_Call *exp) {
     if (!ret) return exp_self(exp)->type;
     const Type t = actual_type(env->gwion, exp->func->type);
     if (!is_func(env->gwion, t)) return check_exp_call1(env, exp);
-    if(isa(t, env->gwion->type[et_lambda]) > 0)
-      if  (!t->info->func)
-        ERR_O(exp->func->pos, _("invalid lambda use."))
-    if (exp->args) CHECK_OO(check_exp(env, exp->args));
-    if (!t->info->func->def->base->tmpl)
-      ERR_O(exp_self(exp)->pos, _("template call of non-template function."))
-    if (t->info->func->def->base->tmpl->call) {
-      if (env->func == t->info->func) {
-        exp->func->type = env->func->value_ref->type;
-        return env->func->def->base->ret_type;
-      } else
-        CHECK_BO(predefined_call(env, t, exp_self(exp)->pos));
-    }
-    const Value v = type_value(env->gwion, t);
-    DECL_OO(const Func, f, = find_template_match(env, v, exp));
-    exp->func->type = f->value_ref->type;
-    return f->def->base->ret_type;
+    if(strcmp("new", s_name(t->info->func->def->base->xid)))
+      return check_exp_call_tmpl(env, exp, t);
   }
   return check_exp_call1(env, exp);
 }
@@ -1736,8 +1741,6 @@ ANN static m_bool check_extend_def(const Env env, const Extend_Def xdef) {
 ANN static m_bool _check_trait_def(const Env env, const Trait_Def pdef) {
   const Trait trait = nspc_lookup_trait1(env->curr, pdef->xid);
   Ast         ast   = pdef->body;
-//  while (ast) {
-//    Section *section = ast->section;
   for(m_uint i = 0; i < ast->len; i++) {
     Section * section = mp_vector_at(ast, Section, i);
     if (section->section_type == ae_section_stmt) {
@@ -1757,10 +1760,8 @@ ANN static m_bool _check_trait_def(const Env env, const Trait_Def pdef) {
             vector_add(&trait->requested_values, (m_uint)value);
           }
         }
-//        list = list->next;
       }
     }
-//    ast = ast->next;
   }
   return GW_OK;
 }
diff --git a/src/parse/default_arg.c b/src/parse/default_arg.c
new file mode 100644 (file)
index 0000000..8e6dba6
--- /dev/null
@@ -0,0 +1,78 @@
+#include "gwion_util.h"
+#include "gwion_ast.h"
+#include "gwion_env.h"
+#include "vm.h"
+#include "gwion.h"
+#include "traverse.h"
+
+ANN static Exp mk_default_args(const MemPool p, const Arg_List args, const uint32_t max) {
+  Exp exp = NULL, base_exp = NULL;
+  for(uint32_t i = 0; i < args->len; i++) {
+    Arg *arg = mp_vector_at(args, Arg, i);
+    const Exp arg_exp = new_prim_id(p, arg->var_decl.xid, arg->var_decl.pos);
+    if(exp)
+      exp = (exp->next = arg_exp);
+    else
+      base_exp = exp = arg_exp;
+  }
+  // now add default args
+  for(uint32_t i = args->len; i < max; i++) {
+    Arg *arg = mp_vector_at(args, Arg, i);
+    const Exp arg_exp = cpy_exp(p, arg->exp);
+    if(exp)
+      exp = (exp->next = arg_exp);
+    else
+      base_exp = exp = arg_exp;
+  }
+  return base_exp;
+}
+
+ANN static Stmt_List std_code(const MemPool p, Func_Base *base, const Arg_List args, const uint32_t len) {
+  const Exp efunc = new_prim_id(p, base->xid, base->pos);
+  const Exp exp_arg = mk_default_args(p, args, len);
+  const Exp ecall = new_exp_call(p, efunc, exp_arg, base->pos);
+  Stmt_List slist = new_mp_vector(p, sizeof(struct Stmt_), 1);
+  mp_vector_set(slist, struct Stmt_, 0,
+    ((struct Stmt_) {
+      .stmt_type = ae_stmt_return, .d = { .stmt_exp = { .val = ecall }},
+      .pos = base->pos
+  }));
+  return slist;
+}
+
+ANN static Stmt_List new_code(const Env env, Func_Base *base, const Arg_List args, const uint32_t len) {
+  const MemPool p = env->gwion->mp;
+  const Exp dbase  = new_prim_id(p, insert_symbol(env->gwion->st, "this"), base->pos);
+  const Exp dot  = new_exp_dot(p, dbase, insert_symbol(env->gwion->st, env->class_def->name), base->pos);
+  const Exp exp_args = mk_default_args(p, args, len);
+  const Exp ecall = new_exp_call(p, dot, exp_args, base->pos);
+  Stmt_List slist = new_mp_vector(p, sizeof(struct Stmt_), 1);
+  mp_vector_set(slist, struct Stmt_, 0,
+    ((struct Stmt_) {
+      .stmt_type = ae_stmt_exp, .d = { .stmt_exp = { .val = ecall }},
+      .pos = base->pos
+  }));
+  return slist;
+}
+
+ANN void default_args(const Env env, const Section *s, Ast *acc) {
+  const MemPool p = env->gwion->mp;
+  const Func_Def base_fdef = s->d.func_def;
+  Arg_List       args = base_fdef->base->args;
+  uint32_t len = args->len;
+  while(args->len--) {
+    Arg *arg = mp_vector_at(args, Arg, args->len);
+    if(!arg->exp) break;
+    Func_Base *const base = cpy_func_base(p, base_fdef->base);
+    Stmt_List slist = strcmp("new", s_name(base->xid))
+        ? std_code(env->gwion->mp, base, args, len)
+        : new_code(env, base, args, len);
+    const Stmt      body  = new_stmt_code(p, slist, base->pos);
+    const Func_Def  fdef  = new_func_def(p, base, body);
+    scan1_func_def(env, fdef);
+    scan2_func_def(env, fdef);
+    Section section = MK_SECTION(func, func_def, fdef);
+    mp_vector_add(p, acc, Section, section);
+  }
+  args->len = len;
+}
index 1c8eb9c6c62516f52ad7ca40a6e030524475fce0..99feeb4724d0ae47b5b9a6ecb6bf3cdf2201c4e5 100644 (file)
@@ -348,7 +348,7 @@ ANN static Type scan0_class_def_init(const Env env, const Class_Def cdef) {
   CHECK_BO(scan0_defined(env, cdef->base.xid, cdef->pos));
   const Type parent = cdef_parent(env, cdef);
   if (parent == (Type)GW_ERROR) return NULL;
-  if(parent) type_addref(parent);
+  //if(parent) type_addref(parent);
   if (cdef->traits) CHECK_BO(find_traits(env, cdef->traits, cdef->pos));
   const Type t = scan0_type(env, s_name(cdef->base.xid), parent);
   if (cflag(cdef, cflag_struct)) {
@@ -378,57 +378,6 @@ ANN static m_bool scan0_stmt_list(const Env env, Stmt_List l) {
   return GW_OK;
 }
 
-ANN static Exp mk_default_args(const MemPool p, const Arg_List args, const uint32_t max) {
-  Exp exp = NULL, base_exp = NULL;
-  for(uint32_t i = 0; i < args->len; i++) {
-    Arg *arg = mp_vector_at(args, Arg, i);
-    const Exp arg_exp = new_prim_id(p, arg->var_decl.xid, arg->var_decl.pos);
-    if(exp)
-      exp = (exp->next = arg_exp);
-    else
-      base_exp = exp = arg_exp;
-  }
-  // now add default args
-  for(uint32_t i = args->len; i < max; i++) {
-    Arg *arg = mp_vector_at(args, Arg, i);
-    const Exp arg_exp = cpy_exp(p, arg->exp);
-    if(exp)
-      exp = (exp->next = arg_exp);
-    else
-      base_exp = exp = arg_exp;
-  }
-  return base_exp;
-}
-
-ANN2(1) static void scan0_func_def_default(const MemPool p, const Section *s,
-                                            Ast *acc) {
-  const Func_Def base_fdef = s->d.func_def;
-  Arg_List       args = base_fdef->base->args;
-  const uint32_t len = args->len;
-  while(args->len--) {
-    Arg *arg = mp_vector_at(args, Arg, args->len);
-    if(!arg->exp) break;
-    Func_Base *base = new_func_base(
-        p, base_fdef->base->td ? cpy_type_decl(p, base_fdef->base->td) : NULL, base_fdef->base->xid,
-        cpy_arg_list(p, args),
-        base_fdef->base->flag, base_fdef->base->pos);
-    const Exp efunc = new_prim_id(p, base->xid, base->pos);
-    const Exp exp_arg = mk_default_args(p, args, len);
-    const Exp ecall = new_exp_call(p, efunc, exp_arg, base->pos);
-    Stmt_List slist = new_mp_vector(p, sizeof(struct Stmt_), 1);
-    mp_vector_set(slist, struct Stmt_, 0,
-      ((struct Stmt_) {
-        .stmt_type = ae_stmt_return, .d = { .stmt_exp = { .val = ecall }},
-        .pos = base_fdef->base->pos
-    }));
-    const Stmt      body  = new_stmt_code(p, slist, base->pos);
-    const Func_Def  fdef  = new_func_def(p, base, body);
-    Section       section = MK_SECTION(func, func_def, fdef);
-    mp_vector_add(p, acc, Section, section);
-  }
-  args->len = len;
-}
-
 #define scan0_func_def dummy_func
 
 ANN static m_bool scan0_extend_def(const Env env, const Extend_Def xdef) {
@@ -490,9 +439,9 @@ ANN static m_bool scan0_class_def_inner(const Env env, const Class_Def cdef) {
   set_tflag(cdef->base.type, tflag_scan0);
   (void)mk_class(env, cdef->base.type, cdef->pos);
   add_type(env, cdef->base.type->info->value->from->owner, cdef->base.type);
-  const m_uint scope = env_push(env, cdef->base.type->info->value->from->owner_class, cdef->base.type->info->value->from->owner);
+//  const m_uint scope = env_push(env, cdef->base.type->info->value->from->owner_class, cdef->base.type->info->value->from->owner);
   const m_bool ret = cdef->body ? env_body(env, cdef, scan0_section) : GW_OK;
-  env_pop(env, scope);
+//  env_pop(env, scope);
   return ret;
 }
 
@@ -523,23 +472,9 @@ ANN m_bool scan0_class_def(const Env env, const Class_Def c) {
 
 ANN m_bool scan0_ast(const Env env, Ast *ast) {
   Ast a = *ast;
-  Ast acc = new_mp_vector(env->gwion->mp, sizeof(Section), 0);
   for(m_uint i = 0; i < a->len; i++) {
     Section * section = mp_vector_at(a, Section, i);
     CHECK_BB(scan0_section(env, section));
-
-    if (section->section_type != ae_section_func ||
-        !fbflag(section->d.func_def->base, fbflag_default))
-      continue;
-    scan0_func_def_default(env->gwion->mp, section, &acc);
-
   }
-
-  for(m_uint i = 0; i < acc->len; i++) {
-    Section * section = mp_vector_at(acc, Section, i);
-    mp_vector_add(env->gwion->mp, ast, Section, *section);
-  }
-  free_mp_vector(env->gwion->mp, sizeof(Section), acc);
-
   return GW_OK;
 }
index da9eff7ee9284243654160c5197301ecad36399e..d497130187584f88fee8a97b4fd22b505efde1c8 100644 (file)
@@ -10,6 +10,7 @@
 #include "object.h"
 #include "instr.h"
 #include "import.h"
+#include "default_args.h"
 
 ANN static m_bool scan2_stmt(const Env, const Stmt);
 ANN static m_bool scan2_stmt_list(const Env, Stmt_List);
@@ -145,7 +146,7 @@ ANN static inline m_bool scan2_exp_binary(const Env         env,
                                           const Exp_Binary *bin) {
   CHECK_BB(scan2_exp(env, bin->lhs));
   CHECK_BB(scan2_exp(env, bin->rhs));
-if(bin->rhs->exp_type == ae_exp_call)bin->rhs->d.exp_call.apms = true;
+  if(bin->rhs->exp_type == ae_exp_call)bin->rhs->d.exp_call.apms = true;
   CHECK_BB(multi_decl(env, bin->lhs, bin->op));
   return multi_decl(env, bin->rhs, bin->op);
 }
@@ -511,13 +512,11 @@ static m_str func_name(const Env env, const Func_Def f, const Value v) {
 
 ANN2(1, 2)
 m_bool scan2_fdef_std(const Env env, const Func_Def f, const Value overload) {
-  const m_str name = func_name(env, f, overload ?: NULL);
+  const m_str name = func_name(env, f, overload);
   if (!name) return GW_ERROR;
   const Func base = f->base->func;
   if (!base)
     CHECK_OB(func_create(env, f, overload, name));
-  else
-    f->base->func = base;
   if (f->base->args) CHECK_BB(scan2_args(f));
   if (!f->builtin && f->d.code) CHECK_BB(scan2_func_def_code(env, f));
   if (!base) {
@@ -637,15 +636,37 @@ ANN m_bool scan2_class_def(const Env env, const Class_Def cdef) {
   if (tflag(t, tflag_scan2)) return GW_OK;
   set_tflag(t, tflag_scan2);
   if (c->base.ext) CHECK_BB(cdef_parent(env, c));
-  if (c->body) CHECK_BB(env_body(env, c, scan2_section));
+  if (c->body) {
+    const m_uint scope = env_push_type(env, t);
+    const Tmpl *tmpl = cdef->base.tmpl;
+    if(tmpl && tmpl->call && tmpl->call != (Type_List)1 && tmpl->list)
+      template_push_types(env, tmpl);
+    const m_bool ret = scan2_ast(env, &c->body);
+    if(tmpl && tmpl->call && tmpl->call != (Type_List)1 && tmpl->list)
+      nspc_pop_type(env->gwion->mp, env->curr);
+    env_pop(env, scope);
+    return ret;
+  }
   return GW_OK;
 }
 
 ANN m_bool scan2_ast(const Env env, Ast *ast) {
   Ast a = *ast;
+  Ast acc = new_mp_vector(env->gwion->mp, sizeof(Section), 0);
+  m_bool ret = GW_OK;
   for(m_uint i = 0; i < a->len; i++) {
     Section *section = mp_vector_at(a, Section, i);
-    CHECK_BB(scan2_section(env, section));
+    if((ret = scan2_section(env, section)) < 0) break;
+    if (section->section_type == ae_section_func &&
+        fbflag(section->d.func_def->base, fbflag_default)) {
+      mp_vector_add(env->gwion->mp, &acc, Section, *section);
+    }
   }
-  return GW_OK;
+
+  for(uint32_t i = 0; i < acc->len; i++) {
+    Section * section = mp_vector_at(acc, Section, i);
+    default_args(env, section, ast);
+  }
+  free_mp_vector(env->gwion->mp, sizeof(Section), acc);
+  return ret;
 }