]> Nishi Git Mirror - gwion.git/commitdiff
cleaning
authorJérémie Astor <fennecdjay@gmail.com>
Wed, 16 Mar 2022 16:05:40 +0000 (17:05 +0100)
committerJérémie Astor <fennecdjay@gmail.com>
Wed, 16 Mar 2022 16:06:10 +0000 (17:06 +0100)
59 files changed:
include/arg.h
include/clean.h
include/emit.h
include/env/type.h
include/gwion.h
include/import/checker.h
include/import/internals.h
include/operator.h
include/pass.h
include/plug.h
include/traverse.h
plug
src/arg.c
src/clean.c
src/compile.c
src/emit/emit.c
src/env/context.c
src/env/env.c
src/env/env_utils.c
src/gwion.c
src/import/import_cdef.c
src/import/import_checker.c
src/import/import_enum.c
src/import/import_fdef.c
src/import/import_internals.c
src/import/import_item.c
src/import/import_udef.c
src/lib/array.c
src/lib/dict.c
src/lib/lib_func.c
src/lib/modules.c
src/lib/object_op.c
src/lib/ptr.c
src/lib/ref.c
src/lib/shred.c
src/lib/tmpl_info.c
src/main.c
src/parse/check.c
src/parse/check_traits.c
src/parse/compat_func.c
src/parse/func_operator.c
src/parse/func_resolve_tmpl.c
src/parse/operator.c
src/parse/scan0.c
src/parse/scan1.c
src/parse/scan2.c
src/parse/scanx.c
src/parse/template.c
src/parse/traverse.c
src/parse/type_decl.c
src/pass.c
src/plug.c
src/vm/vm.c
tests/error/invalid_exp_format.gw [deleted file]
tests/error/ptr_assign_invalid.gw
tests/new/test.gw [deleted file]
tests/new/test2.gw [deleted file]
tests/plug/pass.c
util

index 7542fc12c67e244cc985fe03045f5c2a683f1a51..93bfca89269007ffe70a1cee9544a56cd76313aa 100644 (file)
@@ -7,7 +7,7 @@ enum COLOR {
   COLOR_ALWAYS,
 } __attribute__((packed));
 
-typedef struct Arg_ {
+typedef struct CliArg_ {
   struct CArg        arg;
   struct Map_        mod;
   struct Vector_     add;
@@ -17,9 +17,9 @@ typedef struct Arg_ {
   bool               loop;
   bool               quit;
   enum COLOR         color;
-} Arg;
+} CliArg;
 
-ANN void   arg_release(Arg *);
-ANN m_bool arg_parse(const Gwion, Arg *);
-ANN void   arg_compile(const Gwion, Arg *);
+ANN void   arg_release(CliArg *);
+ANN m_bool arg_parse(const Gwion, CliArg *);
+ANN void   arg_compile(const Gwion, CliArg *);
 #endif
index 2fda18fd6c4907f8819581a18c4c5a4090797ce7..c5647836ece6a375e1032b5719a4f81a82c73cae 100644 (file)
@@ -11,7 +11,6 @@ typedef struct {
 } Clean;
 
 ANN static void clean_array_sub(Clean *a, Array_Sub b);
-ANN static void clean_id_list(Clean *a, ID_List b);
 ANN static void clean_type_list(Clean *a, Type_List b);
 ANN static void clean_tmpl(Clean *a, Tmpl *b);
 ANN static void clean_range(Clean *a, Range *b);
index eff902412fa5b8fb753bdf702f29155355571f07..c3d2db31d09b6777650f5082a6e8d12e9be47dc0 100644 (file)
@@ -58,7 +58,7 @@ struct Emitter_ {
 
 ANEW ANN Emitter new_emitter(MemPool);
 ANN void         free_emitter(MemPool, Emitter);
-ANN m_bool       emit_ast(const Env env, Ast ast);
+ANN m_bool       emit_ast(const Env env, Ast *ast);
 ANN m_bool       emit_func_def(const Emitter emit, const Func_Def fdef);
 ANN m_bool emit_exp_call1(const Emitter, const Func, const bool is_static);
 ANN2(1)
index 6da3ef18060195e81e0a5e2cec5af4a30d133fa2..e0b58c85b9647d475344665bddc86ce96a52ad63 100644 (file)
@@ -98,21 +98,22 @@ __attribute__((returns_nonnull)) ANN static inline Type get_gack(Type t) {
 // trait helpers
 ANN static inline bool has_trait(const Type t, const Symbol trait) {
   ID_List list = t->info->traits;
-  while (list) {
-    if (list->xid == trait) return true;
-    list = list->next;
+  for(uint32_t i = 0; i < list->len; i++) {
+    Symbol xid = *mp_vector_at(list, Symbol, i);
+    if (xid == trait) return true;
   }
   return false;
 }
 
-ANN static inline ID_List miss_traits(const Type t, const Specialized_List sl) {
-  ID_List traits = sl->traits;
-  while (traits) {
-    if (!has_trait(t, traits->xid)) return traits;
-    traits = traits->next;
+ANN static inline Symbol miss_traits(const Type t, const Specialized *spec) {
+  ID_List traits = spec->traits;
+  for(uint32_t i = 0; i < traits->len; i++) {
+    Symbol xid = *mp_vector_at(traits, Symbol, i);
+    if (!has_trait(t, xid)) return xid;
   }
   return NULL;
 }
+
 typedef enum {
   et_void,
   et_int,
index 041333b8e305b90e00cc4ad3b3338521959091e0..5fdf4b33f079b92680ee7fdf3447022b2b4b59db 100644 (file)
@@ -2,6 +2,7 @@
 #define __GWION
 
 // typedef struct Gwion_* Gwion;
+#include "arg.h"
 #include "plug.h"
 #include "driver.h"
 #include "gwiondata.h"
@@ -18,7 +19,7 @@ struct Gwion_ {
   struct PPArg_ *    ppa;
 };
 
-ANN m_bool gwion_ini(const Gwion, struct Arg_ *);
+ANN m_bool gwion_ini(const Gwion, CliArg*);
 ANN VM * gwion_cpy(const VM *);
 ANN void gwion_run(const Gwion gwion);
 ANN void gwion_end(const Gwion gwion);
index 26b7d0e87d5066c609b31a71713747e083b71fb9..480447498b72175f1a236d2b44d232733cd8e643 100644 (file)
@@ -18,6 +18,7 @@ typedef struct ImportCK { // name_checker ?
   union {
     Union_List     list; // union
     struct Vector_ v;
+    MP_Vector *mpv;
     //    ID_List curr;// enum
   };
   union {
@@ -44,8 +45,7 @@ ANN m_bool check_typename_def(const Gwi gwi, struct ImportCK *ck);
 
 ANN Symbol        str2sym(const Gwion, const m_str, const loc_t);
 ANN ID_List       str2symlist(const Gwion, const m_str, const loc_t);
-ANN Var_Decl      str2var(const Gwion, const m_str, const loc_t);
-ANN Var_Decl_List str2varlist(const Gwion, const m_str, const loc_t);
+ANN m_bool str2var(const Gwion, Var_Decl, const m_str, const loc_t);
 ANN Type_Decl *str2td(const Gwion, const m_str, const loc_t);
 ANN Type       str2type(const Gwion, const m_str, const loc_t);
 
@@ -63,8 +63,7 @@ ANN static inline Type_Decl *type2td(const Gwion gwion, const Type t,
 
 #define gwi_str2sym(gwi, path)     str2sym(gwi->gwion, path, gwi->loc)
 #define gwi_str2symlist(gwi, path) str2symlist(gwi->gwion, path, gwi->loc)
-#define gwi_str2var(gwi, path)     str2var(gwi->gwion, path, gwi->loc)
-#define gwi_str2varlist(gwi, path) str2varlist(gwi->gwion, path, gwi->loc)
+#define gwi_str2var(gwi, decl, path)     str2var(gwi->gwion, decl, path, gwi->loc)
 #define gwi_str2td(gwi, path)      str2td(gwi->gwion, path, gwi->loc)
 #define gwi_str2type(gwi, path)    str2type(gwi->gwion, path, gwi->loc)
 
index 0c476ec56c63ce9ec6d8e5f10f4daf8819a2ef03..2a665d590470df01224bf0402fa209b14aa0f28b 100644 (file)
@@ -36,7 +36,7 @@
     return NULL;                                                               \
   }
 
-ANN void gwi_body(const Gwi, const Ast);
+ANN void gwi_body(const Gwi, const Section*);
 
 ANN Exp make_exp(const Gwi gwi, const m_str type, const m_str name);
 
index cda04f19b601c96d9c8b0d61387e1ddff5e11647..5f3b012df9c466585760491c45af66d3eb51c3d7 100644 (file)
@@ -92,8 +92,10 @@ ANN static inline void operator_resume(struct Op_Import *opi) {
 }
 
 ANN static inline void set_decl_ref(const Exp e) {
-  if (e->exp_type == ae_exp_decl)
-    SET_FLAG(e->d.exp_decl.list->self->value, late);
+  if (e->exp_type == ae_exp_decl) {
+    Var_Decl vd = mp_vector_at(e->d.exp_decl.list, struct Var_Decl_, 0);
+    SET_FLAG(vd->value, late);
+  }
 }
 
 ANN void func_operator(const Func_Def fdef, struct Op_Import *opi);
index 631a229f1068e4a038d106ebaadfad232e6f9ef9..813da10e2fce9a5c304e9b2fc2385043a61bf152 100644 (file)
@@ -2,7 +2,7 @@
 #define __GWIONPASS
 
 typedef union __attribute__((__transparent_union__)) {
-  struct Ast_ *ast;
+  Ast    *ast;
   m_bool *     ret;
 } PassArg;
 
index adb913bc585acebe04da24bc6be8a74240d67d8c..18ade2d7b18c8677640d9f6ae9e724f52db8a99d 100644 (file)
@@ -8,7 +8,7 @@ ANN void   free_plug(const struct Gwion_ *);
 ANN void * get_module(const struct Gwion_ *, const m_str);
 ANN void   set_module(const struct Gwion_ *gwion, const m_str name,
                       void *const ptr);
-ANN m_bool plugin_ini(struct Gwion_ *gwion, const m_str iname);
+ANN m_bool plugin_ini(struct Gwion_ *gwion, const m_str iname, const loc_t);
 
 #define GWIMPORT_NAME import
 #define GWMODINI_NAME gwmodini
index 69dfa68038ed6598b2e519fe68538979d137c799..4941b92baf3a30caea463be40b6a7a40ccbc19f7 100644 (file)
@@ -1,6 +1,6 @@
 #ifndef __TRAVERSE
 #define __TRAVERSE
-ANN m_bool traverse_ast(const Env, const Ast);
+ANN m_bool traverse_ast(const Env, const Ast*);
 ANN m_bool traverse_class_def(const Env, const Class_Def);
 ANN m_bool traverse_func_def(const Env, const Func_Def);
 ANN m_bool traverse_union_def(const Env, const Union_Def);
@@ -9,10 +9,10 @@ ANN m_bool traverse_fptr_def(const Env, const Fptr_Def);
 ANN m_bool traverse_type_def(const Env env, const Type_Def);
 ANN m_bool traverse_exp(const Env, const Exp);
 
-ANN m_bool scan0_ast(const Env, Ast);
-ANN m_bool scan1_ast(const Env, Ast);
-ANN m_bool scan2_ast(const Env, Ast);
-ANN m_bool check_ast(const Env, Ast);
+ANN m_bool scan0_ast(const Env, Ast*);
+ANN m_bool scan1_ast(const Env, Ast*);
+ANN m_bool scan2_ast(const Env, Ast*);
+ANN m_bool check_ast(const Env, Ast*);
 
 ANN m_bool scan1_exp(const Env, const Exp);
 ANN m_bool scan2_exp(const Env, const Exp);
diff --git a/plug b/plug
index a7f57ef9dec1fa797ab295adf89d8509d7a636dc..7121bd4bd7ba6429999b1c54f68d9c3edbfd416b 160000 (submodule)
--- a/plug
+++ b/plug
@@ -1 +1 @@
-Subproject commit a7f57ef9dec1fa797ab295adf89d8509d7a636dc
+Subproject commit 7121bd4bd7ba6429999b1c54f68d9c3edbfd416b
index 5c3bcda5de129867ea727b29be92bdca8ab0569a..b3be4ea23426bfb602e1b1f26e88068b5629add1 100644 (file)
--- a/src/arg.c
+++ b/src/arg.c
@@ -1,3 +1,4 @@
+#include <errno.h>
 #include "gwion_util.h"
 #include "gwion_ast.h"
 #include "gwion_env.h"
@@ -67,7 +68,7 @@ enum arg_type {
   ARG_CDOC,
 };
 
-ANN static void arg_init(Arg *arg) {
+ANN static void arg_init(CliArg *arg) {
   map_init(&arg->mod);
   vector_init(&arg->add);
   vector_init(&arg->lib);
@@ -76,7 +77,7 @@ ANN static void arg_init(Arg *arg) {
   arg->color = COLOR_AUTO;
 }
 
-ANN void arg_release(Arg *arg) {
+ANN void arg_release(CliArg *arg) {
   map_release(&arg->mod);
   vector_release(&arg->add);
   xfree((m_str)vector_front(&arg->lib));
@@ -88,7 +89,13 @@ ANN void arg_release(Arg *arg) {
 static inline bool str2bool(const char *str) {
   if (!str || !strcmp(str, "true")) return true;
   if (!strcmp(str, "false")) return false;
-  return atoi(str) ? true : false;
+  char *rem = NULL;
+  long opt = strtol(str, &rem, 10);
+  if(rem || errno == EINVAL) {
+    gw_err("invalid argument for boolean option, setting to `false`\n");
+    return false;
+  }
+  return !!opt;
 }
 
 ANN static inline void get_debug(const Gwion gwion, const char *dbg) {
@@ -106,7 +113,7 @@ ANN static inline void get_cdoc(const Gwion gwion, const char *cdoc) {
   gwion_set_cdoc(gwion, is_cdoc);
 }
 
-ANN void arg_compile(const Gwion gwion, Arg *arg) {
+ANN void arg_compile(const Gwion gwion, CliArg *arg) {
   const Vector v = &arg->add;
   for (m_uint i = 0; i < vector_size(v); i++) {
     switch (vector_at(v, i)) {
@@ -202,7 +209,7 @@ static void setup_options(cmdapp_t *app, cmdopt_t *opt) {
              &opt[CDOC]);
 }
 
-static inline void add2arg(Arg *const arg, const char *data,
+static inline void add2arg(CliArg *const arg, const char *data,
                            const enum arg_type type) {
   vector_add(&arg->add, type);
   vector_add(&arg->add, (vtype)data);
@@ -238,7 +245,7 @@ ANN static Vector get_config(const char *name) {
 
 struct ArgInternal {
   const Gwion gwion;
-  Arg *       arg;
+  CliArg     *arg;
 };
 
 ANN m_bool _arg_parse(struct ArgInternal *arg);
@@ -259,7 +266,7 @@ ANN static void config_parse(struct ArgInternal *arg, const char *name) {
 
 static void myproc(void *data, cmdopt_t *option, const char *arg) {
   struct ArgInternal *arg_int = data;
-  Arg *               _arg    = arg_int->arg;
+  CliArg *            _arg    = arg_int->arg;
   if (arg) {
     if (!_arg->arg.idx)
       _arg->arg.idx++;
@@ -372,7 +379,7 @@ ANN static void config_default(struct ArgInternal *arg) {
   config_parse(arg, c);
 }
 
-ANN m_bool arg_parse(const Gwion gwion, Arg *a) {
+ANN m_bool arg_parse(const Gwion gwion, CliArg *a) {
   struct ArgInternal arg = {.gwion = gwion, .arg = a};
   arg_init(a);
 #ifdef __FUZZING
index a990904dd515cf49fcd663008dd9a38d4e635187..2c4aeed8ebd322ad2e41c6005ccf20ab9c897d2f 100644 (file)
@@ -10,18 +10,14 @@ ANN static void clean_array_sub(Clean *a, Array_Sub b) {
   if (b->exp) clean_exp(a, b->exp);
 }
 
-ANN static void clean_id_list(Clean *a, ID_List b) {
-  if (b->next) clean_id_list(a, b->next);
-}
-
-ANN static void clean_specialized_list(Clean *a, Specialized_List b) {
-  if (b->traits) clean_id_list(a, b->traits);
-  if (b->next) clean_specialized_list(a, b->next);
-}
+#define clean_id_list(a, b) {}
+#define clean_specialized_list(a, b) {}
 
 ANN static void clean_type_list(Clean *a, Type_List b) {
-  clean_type_decl(a, b->td);
-  if (b->next) clean_type_list(a, b->next);
+  for(uint32_t i = 0; i < b->len; i++) {
+    Type_Decl *td = *mp_vector_at(b, Type_Decl*, i);
+    clean_type_decl(a, td);
+  }
 }
 
 ANN static void clean_tmpl(Clean *a, Tmpl *b) {
@@ -37,6 +33,7 @@ ANN static void clean_range(Clean *a, Range *b) {
 ANN static void clean_type_decl(Clean *a, Type_Decl *b) {
   if (b->array) clean_array_sub(a, b->array);
   if (b->types) clean_type_list(a, b->types);
+  if (b->fptr) clean_fptr_def(a, b->fptr);
   if (b->next) clean_type_decl(a, b->next);
 }
 
@@ -55,8 +52,10 @@ ANN static void clean_var_decl(Clean *a, Var_Decl b) {
 }
 
 ANN static void clean_var_decl_list(Clean *a, Var_Decl_List b) {
-  clean_var_decl(a, b->self);
-  if (b->next) clean_var_decl_list(a, b->next);
+  for(uint32_t i = 0; i < b->len; i++) {
+    Var_Decl vd = mp_vector_at(b, struct Var_Decl_, i);
+    clean_var_decl(a, vd);
+  }
 }
 
 ANN static void clean_exp_decl(Clean *a, Exp_Decl *b) {
@@ -163,7 +162,6 @@ ANN static void clean_stmt_each(Clean *a, Stmt_Each b) {
   ++a->scope;
   clean_exp(a, b->exp);
   clean_stmt(a, b->body);
-//  if (b->v) value_remref(b->v, a->gwion);
   if (b->v) mp_free(a->gwion->mp, Value, b->v);
   if (b->idx) clean_idx(a, b->idx);
   --a->scope;
@@ -202,16 +200,22 @@ ANN static void clean_stmt_return(Clean *a, Stmt_Exp b) {
 }
 
 ANN static void clean_case_list(Clean *a, Stmt_List b) {
-  clean_stmt_case(a, &b->stmt->d.stmt_match);
-  if (b->next) clean_case_list(a, b->next);
+  for(m_uint i = 0; i < b->len; i++) {
+    const m_uint offset = i * sizeof(struct Stmt_);
+    const Stmt stmt = (Stmt)(b->ptr + offset);
+    clean_stmt_case(a, &stmt->d.stmt_match);
+  }
 }
 
 ANN static void clean_handler_list(Clean *a, Handler_List b) {
   ++a->scope;
-  clean_stmt(a, b->stmt);
+  for(uint32_t i = 0; i < b->len; i++) {
+    Handler *handler = mp_vector_at(b, Handler, i);
+    clean_stmt(a, handler->stmt);
+  }
   --a->scope;
-  if (b->next) clean_handler_list(a, b->next);
 }
+
 ANN static void clean_stmt_try(Clean *a, Stmt_Try b) {
   ++a->scope;
   clean_stmt(a, b->stmt);
@@ -252,14 +256,19 @@ ANN static void clean_stmt(Clean *a, Stmt b) {
 }
 
 ANN static void clean_arg_list(Clean *a, Arg_List b) {
-  if (b->td) clean_type_decl(a, b->td);
-  clean_var_decl(a, b->var_decl);
-  if (b->next) clean_arg_list(a, b->next);
+  for(uint32_t i = 0; i < b->len; i++) {
+    Arg *arg = (Arg*)(b->ptr + i * sizeof(Arg));
+    if (arg->td) clean_type_decl(a, arg->td);
+    clean_var_decl(a, &arg->var_decl);
+  }
 }
 
 ANN static void clean_stmt_list(Clean *a, Stmt_List b) {
-  clean_stmt(a, b->stmt);
-  if (b->next) clean_stmt_list(a, b->next);
+  for(m_uint i = 0; i < b->len; i++) {
+    const m_uint offset = i * sizeof(struct Stmt_);
+    const Stmt stmt = (Stmt)(b->ptr + offset);
+    clean_stmt(a, stmt);
+  }
 }
 
 ANN static void clean_func_base(Clean *a, Func_Base *b) {
@@ -302,14 +311,17 @@ ANN void class_def_cleaner(const Gwion gwion, Class_Def b) {
   free_class_def(gwion->mp, b);
 }
 
-ANN static void clean_enum_def(Clean *a, Enum_Def b) {
+ANN static void clean_enum_def(Clean *a NUSED, Enum_Def b) {
   clean_id_list(a, b->list);
   if (b->values.ptr) vector_release(&b->values);
 }
 
 ANN static void clean_union_list(Clean *a, Union_List b) {
-  clean_type_decl(a, b->td);
-  if (b->next) clean_union_list(a, b->next);
+  for(uint32_t i = 0; i < b->len; i++) {
+    Union_Member *tgt = mp_vector_at(b, Union_Member, i);
+    clean_type_decl(a, tgt->td);
+    clean_var_decl(a, &tgt->vd);
+  }
 }
 
 ANN static void clean_union_def(Clean *a, Union_Def b) {
@@ -343,8 +355,10 @@ ANN static inline void clean_section(Clean *a, Section *b) {
 }
 
 ANN static void clean_ast(Clean *a, Ast b) {
-  clean_section(a, b->section);
-  if (b->next) clean_ast(a, b->next);
+  for(m_uint i = 0; i < b->len; i++) {
+    const m_uint offset = i * sizeof(Section);
+    clean_section(a, (Section*)(b->ptr + offset));
+  }
 }
 
 ANN void ast_cleaner(const Gwion gwion, Ast b) {
index ad22aa572aba0b67f3b1b549d60e99831fd3773a..2974fdef081ac0de3d1a59a259bb3c7c20eb5593 100644 (file)
@@ -7,7 +7,6 @@
 #include "compile.h"
 #include "gwion.h"
 #include "pass.h"
-#include "clean.h"
 
 enum compile_type { COMPILE_NAME, COMPILE_MSTR, COMPILE_FILE };
 
@@ -96,7 +95,7 @@ ANN static inline m_bool _passes(struct Gwion_ *gwion, struct Compiler *c) {
   for (m_uint i = 0; i < vector_size(&gwion->data->passes->vec); ++i) {
     const compilation_pass pass =
         (compilation_pass)vector_at(&gwion->data->passes->vec, i);
-    CHECK_BB(pass(gwion->env, c->ast));
+    CHECK_BB(pass(gwion->env, &c->ast));
   }
   return GW_OK;
 }
@@ -107,15 +106,12 @@ ANN static inline m_bool passes(struct Gwion_ *gwion, struct Compiler *c) {
   env_reset(env);
   load_context(ctx, env);
   const m_bool ret = _passes(gwion, c);
+  ctx->tree = c->ast;
   if (ret > 0) //{
     nspc_commit(env->curr);
   if (ret > 0 || env->context->global)
     vector_add(&env->scope->known_ctx, (vtype)ctx);
   else { // nspc_rollback(env->global_nspc);
-    if (!ctx->error) {
-      gw_err(_("{-}while compiling file `{0}{/}%s{-}`{0}\n"), c->base);
-      ctx->error = 1;
-    }
     context_remref(ctx, env->gwion);
   }
   unload_context(ctx, env);
@@ -127,7 +123,6 @@ ANN static inline m_bool _check(struct Gwion_ *gwion, struct Compiler *c) {
   CHECK_OB((c->ast = parse(&arg)));
   gwion->env->name = c->name;
   const m_bool ret = passes(gwion, c);
-  if (!arg.global) ast_cleaner(gwion, c->ast);
   return ret;
 }
 
index 06795e20538cf7dec411b042add973238ecdcd96..635a4b78156b4efb2ec7427b2f445ad4d0393acb 100644 (file)
@@ -562,7 +562,8 @@ ANN static m_bool _emit_symbol(const Emitter emit, const Symbol *data) {
     } else {
       const Instr instr = emit_add_instr(emit, RegPushMemDeref);
       instr->m_val      = v->from->offset;
-      instr->m_val2     = v->type->size;
+      const Type t = (Type)vector_front(&v->type->info->tuple->contains);
+      instr->m_val2     = t->size;
     }
     return GW_OK;
   }
@@ -857,15 +858,19 @@ ANN static m_bool emit_prim_str(const Emitter emit, const struct AstString *str)
 #define emit_prim_nil (void *)dummy_func
 
 ANN static void interp_multi(const Emitter emit, const Exp e) {
-  Var_Decl_List list     = e->d.exp_decl.list;
   const bool    emit_var = exp_getvar(e);
   m_uint        offset   = 0;
-  while ((list = list->next))
-    offset += !emit_var ? list->self->value->type->size : SZ_INT;
+  Var_Decl_List list     = e->d.exp_decl.list;
+  for(uint32_t i = 1; i < list->len; i++) {
+    Var_Decl vd = mp_vector_at(list, struct Var_Decl_, i);
+    offset += !emit_var ? vd->value->type->size : SZ_INT;
+  }
   if (offset) regpop(emit, offset);
 }
 
-ANN static inline void interp_size(const Emitter emit, const Type t) {
+ANN static inline void interp_size(const Emitter emit, const Exp e) {
+  const Type t = !tflag(e->type, tflag_ref) || safe_tflag(e->cast_to, tflag_ref) ?
+    e->type : (Type)vector_front(&e->type->info->tuple->contains);
   const Instr instr = regseti(emit, t->size);
   instr->m_val2     = SZ_INT;
 }
@@ -882,8 +887,12 @@ ANN /*static*/ m_bool emit_interp(const Emitter emit, const Exp exp) {
     }
     if (e->exp_type == ae_exp_decl) // why only objects?
       interp_multi(emit, e);
-    regseti(emit, (m_uint)e->type);
-    interp_size(emit, e->type);
+    if(tflag(e->type, tflag_ref) && !safe_tflag(e->cast_to, tflag_ref)) {
+      const Type t = (Type)vector_front(&e->type->info->tuple->contains);
+      regseti(emit, (m_uint)t);
+    } else
+      regseti(emit, (m_uint)e->type);
+    interp_size(emit, e);
     const m_bool isobj = isa(e->type, emit->gwion->type[et_object]) > 0;
     if (isobj && e->exp_type != ae_exp_cast && !GET_FLAG(e->type, final)) emit_add_instr(emit, GackType);
     const Instr instr = emit_add_instr(emit, Gack);
@@ -1018,7 +1027,7 @@ ANN static m_uint decl_non_static_offset(const Emitter emit, const Exp_Decl *dec
 
 ANN static m_bool emit_exp_decl_non_static(const Emitter   emit,
                                            const Exp_Decl *decl,
-                                           const Var_Decl  var_decl,
+                                           const Var_Decl var_decl,
                                            const uint      is_ref,
                                            const uint      emit_var) {
   const Value     v        = var_decl->value;
@@ -1117,31 +1126,32 @@ ANN static m_bool emit_decl(const Emitter emit, const Exp_Decl *decl) {
   const uint    var    = exp_getvar(exp_self(decl));
   const uint    ref    = GET_FLAG(decl->td, late) || type_ref(decl->type);
   Var_Decl_List list   = decl->list;
-  do {
-    const Value v = list->self->value;
+  for(uint32_t i = 0; i < list->len; i++) {
+    Var_Decl vd = mp_vector_at(list, struct Var_Decl_, i);
+    const Value v = vd->value;
     const uint  r = ref || GET_FLAG(v, late);
     if (GET_FLAG(decl->td, static))
-      CHECK_BB(emit_exp_decl_static(emit, decl, list->self, r, var));
+      CHECK_BB(emit_exp_decl_static(emit, decl, vd, r, var));
     else if (!global)
-      CHECK_BB(emit_exp_decl_non_static(emit, decl, list->self, r, var));
+      CHECK_BB(emit_exp_decl_non_static(emit, decl, vd, r, var));
     else
-      CHECK_BB(emit_exp_decl_global(emit, decl, list->self, r, var));
-    if (tflag(list->self->value->type, tflag_contract) &&
+      CHECK_BB(emit_exp_decl_global(emit, decl, vd, r, var));
+    if (tflag(v->type, tflag_contract) &&
         !exp_getvar(exp_self(decl))) {
-      const Type       t   = list->self->value->type;
+      const Type       t   = v->type;
       struct Op_Import opi = {.lhs = t->info->base_type,
                               .op  = insert_symbol("@implicit"),
                               .rhs = t};
       CHECK_BB(op_emit(emit, &opi));
     }
-    set_late(emit->gwion, decl, list->self);
+    set_late(emit->gwion, decl, vd);
     if (!exp_self(decl)->emit_var && GET_FLAG(array_base_simple(v->type), abstract) && !GET_FLAG(decl->td, late) &&
-        GET_FLAG(v, late) && late_array(decl->td, list->self)
+        GET_FLAG(v, late) && late_array(decl->td, vd)
         && GET_FLAG(v->type, abstract)) {
       env_warn(emit->env, decl->td->pos, _("Type '%s' is abstract, use {+G}late{0} instead of {G+}%s{0}"),
                v->type->name, !GET_FLAG(decl->td, const) ? "var" : "const");
     }
-  } while ((list = list->next));
+  }
   return GW_OK;
 }
 
@@ -1152,23 +1162,28 @@ ANN /*static */ m_bool emit_exp_decl(const Emitter emit, const Exp_Decl *decl) {
   const m_uint scope =
       !global ? emit->env->scope->depth : emit_push_global(emit);
   const m_bool ret = emit_decl(emit, decl);
-
   if (global) emit_pop(emit, scope);
   return ret;
 }
 
+
+// see take exp
+Exp nth_exp(Exp e, uint32_t n) {
+  for(uint32_t i = 0; i < n; i++)
+    e = e->next;
+  return e;
+}
+
 ANN static m_uint vararg_size(const Gwion gwion, const Exp_Call *exp_call,
                               const Vector kinds) {
-  Exp        e    = exp_call->args;
   const Type t    = actual_type(gwion, exp_call->func->type);
   Arg_List   l    = t->info->func->def->base->args;
+  Exp        e    = l ? nth_exp(exp_call->args, l->len) : exp_call->args;
+//  Exp        e    = l ? take_exp(exp_call->args, l->len - 1) : exp_call->args;
   m_uint     size = 0;
   while (e) {
-    if (!l) {
-      size += e->type->size;
-      vector_add(kinds, (vtype)e->type); // ->size
-    } else
-      l = l->next;
+    size += e->type->size;
+    vector_add(kinds, (vtype)e->type); // ->size
     e = e->next;
   }
   return size;
@@ -1378,21 +1393,32 @@ ANN static m_bool emit_exp_call(const Emitter emit, const Exp_Call *exp_call) {
   return GW_OK;
 }
 
-ANN static m_uint get_decl_size(Var_Decl_List a, bool emit_addr) {
+ANN static m_uint get_decl_size(Var_Decl_List list, bool emit_addr) {
   m_uint size = 0;
-  do // if(GET_FLAG(a->self->value, used))
-    size += !emit_addr ? a->self->value->type->size : SZ_INT;
-  while ((a = a->next));
+  for(uint32_t i = 0; i < list->len; i++) {
+    Var_Decl vd = mp_vector_at(list, struct Var_Decl_, i);
+    // if(GET_FLAG(vd->value, used))
+    size += !emit_addr ? vd->value->type->size : SZ_INT;
+  }
   return size;
 }
 
+ANN static m_uint get_type_size(const Exp e) {
+  if(tflag(e->type, tflag_ref)&& !safe_tflag(e->cast_to, tflag_ref)) {
+    const Type base =(Type)vector_front(&e->type->info->tuple->contains);
+    return base->size;
+  }
+  return e->type->size;
+}
+
 ANN static m_uint pop_exp_size(Exp e) {
   const bool emit_addr = exp_getvar(e);
   m_uint     size      = 0;
   do {
     size += (e->exp_type == ae_exp_decl
                  ? get_decl_size(e->d.exp_decl.list, emit_addr)
-             : !emit_addr ? e->type->size
+             : !emit_addr ? get_type_size(e)
+//             : !emit_addr ? e->type->size
                           : SZ_INT);
   } while ((e = e->next));
   return size;
@@ -1406,10 +1432,10 @@ ANN static inline void pop_exp(const Emitter emit, Exp e) {
 ANN static inline m_bool emit_exp_pop_next(const Emitter emit, Exp e) {
   CHECK_BB(emit_exp(emit, e));
   if (e->exp_type == ae_exp_decl) {
-    Var_Decl_List list = e->d.exp_decl.list->next;
-    while (list) {
-      regpop(emit, !exp_getvar(e) ? list->self->value->type->size : SZ_INT);
-      list = list->next;
+    Var_Decl_List list = e->d.exp_decl.list;
+    for(uint32_t i = 1; i < list->len; i++) {
+      Var_Decl vd = mp_vector_at(list, struct Var_Decl_, i);
+      regpop(emit, !exp_getvar(e) ? vd->value->type->size : SZ_INT);
     }
   }
   if (e->next) pop_exp(emit, e->next);
@@ -1471,6 +1497,7 @@ ANN m_bool traverse_dot_tmpl(const Emitter emit, const struct dottmpl_ *dt) {
   if (es.run) envset_pop(&es, dt->owner_class);
   emit_pop(emit, scope);
   emit->env->scope->shadowing = shadowing;
+  if(ret > 0) set_fflag(dt->def->base->func, fflag_tmpl);
   return ret;
 }
 
@@ -1589,7 +1616,7 @@ ANN static Instr me_push(const MemoizeEmitter *me, const m_uint sz) {
   return instr;
 }
 
-static m_bool me_cmp(MemoizeEmitter *me, const Arg_List arg) {
+static m_bool me_cmp(MemoizeEmitter *me, const Arg *arg) {
   const Emitter    emit = me->emit;
   const Symbol     sym  = insert_symbol("?=");
   struct Exp_      lhs  = {
@@ -1632,15 +1659,16 @@ static m_bool me_cmp(MemoizeEmitter *me, const Arg_List arg) {
 }
 
 ANN static m_bool me_arg(MemoizeEmitter *me) {
-  Arg_List arg = me->fdef->base->args;
-  do {
+  Arg_List args = me->fdef->base->args;
+  for(uint32_t i = 0; i < args->len; i++) {
+    Arg *arg = (Arg*)(args->ptr + i * sizeof(Arg));
     const m_uint sz = arg->type->size;
     (void)me_push(me, sz);
     const Instr instr = me_push(me, sz);
     instr->m_val += me->offset + SZ_INT * 2;
     CHECK_BB(me_cmp(me, arg));
-    me->arg_offset += arg->type->size;
-  } while ((arg = arg->next));
+    me->arg_offset += arg->type->size; // sz?
+  }
   return GW_OK;
 }
 
@@ -2111,7 +2139,8 @@ ANN2(1) /*static */ m_bool emit_exp(const Emitter emit, /* const */ Exp e) {
         (e->cast_to ? isa(e->cast_to, emit->gwion->type[et_object]) > 0 : 1) &&
         e->exp_type == ae_exp_decl && GET_FLAG(e->d.exp_decl.td, late) &&
         exp_getuse(e) && !exp_getvar(e) &&
-        GET_FLAG(e->d.exp_decl.list->self->value, late)) {
+        GET_FLAG((mp_vector_at(e->d.exp_decl.list, struct Var_Decl_, 0))->value, late)) {
+//        GET_FLAG(e->d.exp_decl.list->self->value, late)) {
       //         e->exp_type == ae_exp_decl && !exp_getvar(e)) {
 //      const Instr instr = emit_add_instr(emit, GWOP_EXCEPT);
       const Instr instr = emit_add_instr(emit, fast_except);
@@ -2147,10 +2176,10 @@ ANN static m_bool emit_stmt_if(const Emitter emit, const Stmt_If stmt) {
 }
 
 ANN static m_bool emit_stmt_code(const Emitter emit, const Stmt_Code stmt) {
+  if(!stmt->stmt_list) return GW_OK;
   emit_push_scope(emit);
   ++emit->env->scope->depth;
-  const m_bool ret =
-      stmt->stmt_list ? emit_stmt_list(emit, stmt->stmt_list) : 1;
+  const m_bool ret =  emit_stmt_list(emit, stmt->stmt_list);
   emit_pop_scope(emit);
   --emit->env->scope->depth;
   return ret;
@@ -2410,7 +2439,7 @@ ANN static m_bool _emit_stmt_each(const Emitter emit, const Stmt_Each stmt,
   const m_uint key_offset = /*!stmt->idx
      ? */emit_local(emit, emit->gwion->type[et_int])
      /*: emit_local(emit, stmt->idx->v->type)*/;
-  const m_uint val_offset = emit_local(emit, stmt->v->type);
+  const m_uint val_offset = emit_localn(emit, stmt->v->type); // localn ?
   const Instr tomem     = emit_add_instr(emit, Reg2Mem);
   tomem->m_val          = arr_offset;
   const Instr loop_idx  = emit_add_instr(emit, MemSetImm);
@@ -2429,7 +2458,7 @@ ANN static m_bool _emit_stmt_each(const Emitter emit, const Stmt_Each stmt,
                         .roll   = each_op,
                         .unroll = each_op,
                         .idx    = stmt->idx,
-.init = false
+                        .init = false
                         };
   if (n) {
     loop.offset -= SZ_INT;
@@ -2563,14 +2592,17 @@ ANN static inline void try_goto_indexes(const Vector v, const m_uint pc) {
 }
 
 ANN static inline m_bool emit_handler_list(const restrict Emitter emit,
-                                           const Handler_List     handler,
+                                           const Handler_List     handlers,
                                            const Vector           v) {
-  const Instr instr = emit_add_instr(emit, HandleEffect);
-  instr->m_val2     = (m_uint)handler->xid;
-  CHECK_BB(scoped_stmt(emit, handler->stmt, 1));
-  if (handler->next) CHECK_BB(emit_handler_list(emit, handler->next, v));
-  emit_try_goto(emit, v);
-  instr->m_val = emit_code_size(emit);
+  for(uint32_t i = 0; i < handlers->len; i++) {
+    Handler *handler = mp_vector_at(handlers, Handler, i);
+    const Instr instr = emit_add_instr(emit, HandleEffect);
+    instr->m_val2     = (m_uint)handler->xid;
+    CHECK_BB(scoped_stmt(emit, handler->stmt, 1));
+  //if (handler->next) CHECK_BB(emit_handler_list(emit, handler->next, v));
+    emit_try_goto(emit, v);
+    instr->m_val = emit_code_size(emit);
+  }
   return GW_OK;
 }
 
@@ -2748,8 +2780,11 @@ ANN static inline void match_unvec(struct Match_ *const match,
 }
 
 ANN static m_bool emit_stmt_cases(const Emitter emit, Stmt_List list) {
-  do CHECK_BB(emit_stmt_match_case(emit, &list->stmt->d.stmt_match));
-  while ((list = list->next));
+  for(m_uint i = 0; i < list->len; i++) {
+    const m_uint offset = i * sizeof(struct Stmt_);
+    const Stmt stmt = (Stmt)(list->ptr + offset);
+    CHECK_BB(emit_stmt_match_case(emit, &stmt->d.stmt_match));
+  }
   return GW_OK;
 }
 
@@ -2809,8 +2844,11 @@ ANN static m_bool emit_stmt(const Emitter emit, const Stmt stmt,
 }
 
 ANN static m_bool emit_stmt_list(const Emitter emit, Stmt_List l) {
-  do CHECK_BB(emit_stmt(emit, l->stmt, 1));
-  while ((l = l->next));
+  for(m_uint i = 0; i < l->len; i++) {
+    const m_uint offset = i * sizeof(struct Stmt_);
+    const Stmt stmt = (Stmt)(l->ptr + offset);
+    CHECK_BB(emit_stmt(emit, stmt, 1));
+  }
   return GW_OK;
 }
 
@@ -2827,13 +2865,14 @@ ANN static inline void emit_func_def_init(const Emitter emit, const Func func) {
   emit_push_code(emit, func->name);
 }
 
-ANN static void emit_func_def_args(const Emitter emit, Arg_List a) {
-  do {
-    const Type type = a->var_decl->value->type;
+ANN static void emit_func_def_args(const Emitter emit, Arg_List args) {
+  for(uint32_t i = 0; i < args->len; i++) {
+    Arg *arg = (Arg*)(args->ptr + i * sizeof(Arg));
+    const Type type = arg->var_decl.value->type;
     emit->code->stack_depth += type->size;
-    a->var_decl->value->from->offset = emit_localn(emit, type);
-    emit_debug(emit, a->var_decl->value);
-  } while ((a = a->next));
+    arg->var_decl.value->from->offset = emit_localn(emit, type);
+    emit_debug(emit, arg->var_decl.value);
+  }
 }
 
 ANN static m_bool emit_func_def_return(const Emitter emit) {
@@ -3023,8 +3062,10 @@ ANN static m_bool emit_extend_def(const Emitter emit, const Extend_Def xdef);
 HANDLE_SECTION_FUNC(emit, m_bool, Emitter)
 
 ANN static inline m_bool emit_ast_inner(const Emitter emit, Ast ast) {
-  do CHECK_BB(emit_section(emit, ast->section));
-  while ((ast = ast->next));
+  for(m_uint i = 0; i < ast->len; i++) {
+    const m_uint offset = i * sizeof(struct Section_);
+    CHECK_BB(emit_section(emit, (Section*)(ast->ptr + offset)));
+  }
   return emit_defers(emit);
 }
 
@@ -3107,12 +3148,12 @@ ANN static inline void emit_clear(const Emitter emit) {
   emit->vararg_offset = 0;
 }
 
-ANN m_bool emit_ast(const Env env, Ast ast) {
+ANN m_bool emit_ast(const Env env, Ast *ast) {
   const Emitter emit  = env->gwion->emit;
   emit_clear(emit);
   emit->code          = new_code(emit, emit->env->name);
   emit_push_scope(emit);
-  const m_bool ret = emit_ast_inner(emit, ast);
+  const m_bool ret = emit_ast_inner(emit, *ast);
   emit_pop_scope(emit);
   if (ret > 0)
     emit->info->code = finalyze(emit, EOC);
index 9cf288f5d4b3046b7520d37fa34aa713f24a80b2..641633c71918abebd430f412324e618664599d4a 100644 (file)
@@ -3,14 +3,16 @@
 #include "gwion_env.h"
 #include "vm.h"
 #include "gwion.h"
+#include "clean.h"
 
 ANN void free_context(const Context a, Gwion gwion) {
   nspc_remref(a->nspc, gwion);
   free_mstr(gwion->mp, a->name);
+  ast_cleaner(gwion, a->tree);
   mp_free(gwion->mp, Context, a);
 }
 
-ANN2(2) Context new_context(MemPool p, const Ast ast, const m_str str) {
+ANN2(1,3) Context new_context(MemPool p, const Ast ast, const m_str str) {
   const Context context = mp_calloc(p, Context);
   context->name         = mstrdup(p, str);
   context->nspc         = new_nspc(p, context->name);
index 0813904b498145db9d58a429e6b6fa3cd7ac1bc2..b22310c614cf80db756c2f58009d66d8152b7a65 100644 (file)
@@ -7,7 +7,7 @@
 #include "traverse.h"
 #include "vm.h"
 #include "parse.h"
-#include "clean.h"
+//#include "clean.h"
 
 ANN static struct Env_Scope_ *new_envscope(MemPool p) {
   struct Env_Scope_ *a = mp_calloc(p, Env_Scope);
@@ -48,7 +48,7 @@ ANN void release_ctx(struct Env_Scope_ *a, struct Gwion_ *gwion) {
   const m_uint size = vector_size(&a->known_ctx);
   for (m_uint i = size + 1; --i;) {
     const Context ctx = (Context)vector_at(&a->known_ctx, i - 1);
-    if (!ctx->error && ctx->global) ast_cleaner(gwion, ctx->tree);
+//    if (!ctx->error && ctx->global) ast_cleaner(gwion, ctx->tree);
     context_remref(ctx, gwion);
   }
 }
index f415c8817581517474dc5b3027e3b16aa41ea15b..d23f9f69f8d21768a39059092f922437106be17c 100644 (file)
@@ -53,11 +53,10 @@ ANN Type find_initial(const Env env, const Symbol xid) {
 #undef RETURN_TYPE
 
 ANN Type find_type(const Env env, Type_Decl *path) {
-  DECL_OO(const Type, type, = find_initial(env, path->xid));
+  DECL_OO(Type, type, = find_initial(env, path->xid));
   while ((path = path->next) && type && type->nspc) {
     const Nspc nspc  = type->nspc;
-    const Type child = find_in_parent(type, path->xid);
-    if (!child)
+    if(!(type = find_in_parent(type, path->xid)))
       ERR_O(path->pos, _("...(cannot find class '%s' in nspc '%s')"),
             s_name(path->xid), nspc->name)
   }
index 42ba80b1f37394e76a371adfcab5668684d0aeb0..483d8bb81fb806ab17e68cd6c556c45df184d249 100644 (file)
@@ -57,7 +57,7 @@ ANN static void gwion_core(const Gwion gwion) {
   gwion->vm->gwion = gwion->emit->gwion = gwion->env->gwion = gwion;
 }
 
-ANN static m_bool gwion_ok(const Gwion gwion, Arg *arg) {
+ANN static m_bool gwion_ok(const Gwion gwion, CliArg *arg) {
   CHECK_BB(plug_ini(gwion, &arg->lib));
   shreduler_set_loop(gwion->vm->shreduler, arg->loop);
   if (gwion_audio(gwion) > 0) {
@@ -81,7 +81,7 @@ ANN static void doc_mode(const Gwion gwion) {
   vector_release(&v);
 }
 
-ANN m_bool gwion_ini(const Gwion gwion, Arg *arg) {
+ANN m_bool gwion_ini(const Gwion gwion, CliArg *arg) {
 #ifdef USE_GETTEXT
   setlocale(LC_ALL, NULL);
   bindtextdomain(GWION_PACKAGE, LOCALE_INFO);
index 4d128883b76eb586a5117dd9fe2322599807cccd..0133f0ac5c7423231db21e1499e6f0291ea9fc45 100644 (file)
@@ -35,12 +35,11 @@ ANN2(1, 2) static void import_class_ini(const Env env, const Type t) {
 }
 
 ANN2(1) void add_template(const Env env, const Type t) {
-  Tmpl *tmpl = t->info->cdef->base.tmpl;
-  if (tmpl) {
-    nspc_push_type(env->gwion->mp, env->curr); //
-    Specialized_List il = tmpl->list;
-    do nspc_add_type(env->curr, il->xid, env->gwion->type[et_auto]);
-    while ((il = il->next));
+  nspc_push_type(env->gwion->mp, env->curr); //
+  Specialized_List sl = t->info->cdef->base.tmpl->list;
+  for(uint32_t i = 0; i < sl->len; i++) {
+    Specialized *spec = mp_vector_at(sl, Specialized, i);
+    nspc_add_type(env->curr, spec->xid, env->gwion->type[et_auto]);
   }
 }
 
@@ -62,6 +61,7 @@ ANN static Type type_finish(const Gwi gwi, const Type t) {
   if (t->info->cdef && t->info->cdef->base.tmpl) {
     gwi->tmpls++;
     add_template(gwi->gwion->env, t);
+    set_tflag(t, tflag_cdef);
   }
   if (gwi->gwion->data->cdoc && t->info->cdef) {
     lint_indent(gwi->lint);
index ae7c1fce1bae462fe475b99367ba56b0669e3baf..d8861dcf1c0d6267a3e926ced0b5dd15885a3763 100644 (file)
@@ -69,44 +69,41 @@ ANN Symbol str2sym(const Gwion gwion, const m_str path, const loc_t pos) {
   struct td_checker tdc = {.str = path, .pos = pos};
   return _str2sym(gwion, &tdc, path);
 }
-
+/*
 // only in enum.c
 ANN ID_List str2symlist(const Gwion gwion, const m_str path, const loc_t pos) {
   DECL_OO(const Symbol, sym, = str2sym(gwion, path, pos));
   return new_id_list(gwion->mp, sym);
 }
-
-ANN Var_Decl str2var(const Gwion gwion, const m_str path, const loc_t pos) {
+*/
+ANN m_bool str2var(const Gwion gwion, Var_Decl vd, const m_str path, const loc_t pos) {
   struct td_checker tdc = {.str = path, .pos = pos};
-  DECL_OO(const Symbol, sym, = __str2sym(gwion, &tdc));
+  DECL_OB(const Symbol, sym, = __str2sym(gwion, &tdc));
   struct AC ac = {.str = tdc.str, .pos = pos};
-  CHECK_BO(ac_run(gwion, &ac));
-  const Array_Sub array = ac.depth ? mk_array(gwion->mp, &ac) : NULL;
-  return new_var_decl(gwion->mp, sym, array, pos);
-}
-
-// only in udef.c
-ANN Var_Decl_List str2varlist(const Gwion gwion, const m_str path,
-                              const loc_t pos) {
-  DECL_OO(const Var_Decl, var, = str2var(gwion, path, pos));
-  return new_var_decl_list(gwion->mp, var, NULL);
+  CHECK_BB(ac_run(gwion, &ac));
+  vd->xid = sym;
+  vd->value = NULL;
+  vd->array = ac.depth ? mk_array(gwion->mp, &ac) : NULL;
+  vd->pos = pos;
+  return GW_OK;
 }
 
 #define SPEC_ERROR (Specialized_List) GW_ERROR
-ANN static Specialized_List _tmpl_list(const Gwion        gwion,
-                                       struct td_checker *tdc) {
+ANN static bool _tmpl_list(const Gwion        gwion,
+                                       struct td_checker *tdc, Specialized_List *sl) {
   DECL_OO(const Symbol, sym, = __str2sym(gwion, tdc));
-  Specialized_List next = NULL;
+  // TODO: handle traits?
+  Specialized spec = {
+    .xid = sym,
+    .pos = tdc->pos
+  };
+  mp_vector_add(gwion->mp, sl, Specialized, spec);
   if (*tdc->str == ',') {
     ++tdc->str;
-    if (!(next = _tmpl_list(gwion, tdc)) || next == SPEC_ERROR)
-      return SPEC_ERROR;
+    if (!_tmpl_list(gwion, tdc, sl))
+      return false;
   }
-  // TODO: handle traits?
-  const Specialized_List list =
-      new_specialized_list(gwion->mp, sym, NULL, tdc->pos);
-  list->next = next;
-  return list;
+  return true;
 }
 
 ANN static Specialized_List __tmpl_list(const Gwion        gwion,
@@ -114,14 +111,12 @@ ANN static Specialized_List __tmpl_list(const Gwion        gwion,
   if (tdc->str[0] != ':') return NULL;
   if (tdc->str[1] != '[') return SPEC_ERROR;
   tdc->str += 2;
-  const Specialized_List list = _tmpl_list(gwion, tdc);
-  if (list == SPEC_ERROR) return SPEC_ERROR;
-  if (tdc->str[0] != ']') { // unfinished template
-    if (list) free_specialized_list(gwion->mp, list);
-    return SPEC_ERROR;
+  Specialized_List sl = new_mp_vector(gwion->mp, sizeof(Specialized), 0);
+  if(!_tmpl_list(gwion, tdc, &sl) || tdc->str[0] != ']') {
+    free_specialized_list(gwion->mp, sl);
   }
   ++tdc->str;
-  return list;
+  return sl;
 }
 
 ANN m_bool check_typename_def(const Gwi gwi, ImportCK *ck) {
@@ -135,18 +130,16 @@ ANN m_bool check_typename_def(const Gwi gwi, ImportCK *ck) {
 }
 
 ANN static Type_Decl *_str2td(const Gwion gwion, struct td_checker *tdc);
-ANN Type_List         __str2tl(const Gwion gwion, struct td_checker *tdc) {
+ANN bool str2tl(const Gwion gwion, struct td_checker *tdc, Type_List *tl) {
   Type_Decl *td = _str2td(gwion, tdc);
-  if (!td) GWION_ERR_O(tdc->pos, "invalid types");
-  Type_List next = NULL;
+  if (!td) GWION_ERR_B(tdc->pos, "invalid types");
+  mp_vector_add(gwion->mp, tl, Type_Decl*, td);
   if (*tdc->str == ',') {
     ++tdc->str;
-    if (!(next = __str2tl(gwion, tdc))) {
-      free_type_decl(gwion->mp, td);
-      return NULL;
-    }
+    if (!str2tl(gwion, tdc, tl))
+      return false;
   }
-  return new_type_list(gwion->mp, td, next);
+  return true;
 }
 
 ANN static Type_List td_tmpl(const Gwion gwion, struct td_checker *tdc) {
@@ -157,8 +150,11 @@ ANN static Type_List td_tmpl(const Gwion gwion, struct td_checker *tdc) {
     return (Type_List)GW_ERROR;
   }
   ++tdc->str;
-  Type_List tl = __str2tl(gwion, tdc);
-  if (!tl) return (Type_List)GW_ERROR;
+  Type_List tl = new_mp_vector(gwion->mp, sizeof(Type_Decl*), 0);
+  if (!str2tl(gwion, tdc, &tl)) {
+    free_type_list(gwion->mp, tl);
+    return (Type_List)GW_ERROR;
+  }
   if (tdc->str[0] != ']') {
     free_type_list(gwion->mp, tl);
     GWION_ERR(tdc->pos, "unfinished template");
@@ -237,11 +233,12 @@ ANN static void td_fullname(const Env env, GwText *text, const Type t) {
 
 ANN static m_bool td_info_run(const Env env, struct td_info *info) {
   Type_List tl = info->tl;
-  do {
-    DECL_OB(const Type, t, = known_type(env, tl->td));
+  for(uint32_t i = 0; i < tl->len; i++) {
+    if (i) text_add(&info->text, ",");
+    Type_Decl *td = *mp_vector_at(tl, Type_Decl*, i);
+    DECL_OB(const Type, t, = known_type(env, td));
     td_fullname(env, &info->text, t);
-    if (tl->next) text_add(&info->text, ",");
-  } while ((tl = tl->next));
+  }
   return GW_OK;
 }
 
index c47ca50a843f161a625b907a07cbfb9b9bffc5ca..4ec441ff8b90cd1de97f448c09de566a4d7b490f 100644 (file)
@@ -24,25 +24,20 @@ ANN m_int gwi_enum_ini(const Gwi gwi, const m_str type) {
   CHECK_BB(ck_ini(gwi, ck_edef));
   CHECK_OB((gwi->ck->xid = gwi_str2sym(gwi, type)));
   vector_init(&gwi->ck->v);
+  gwi->ck->tmpl = new_mp_vector(gwi->gwion->mp, sizeof(Symbol), 0);
   return GW_OK;
 }
-
+/*
 // adds the id_list to the enum
 // change that algo?
 ANN static void add2list(struct ImportCK *ck, const ID_List list) {
-  if (!ck->tmpl)
-    ck->tmpl = list;
-  else
+  if (!ck->tmpl) {
+    ck->tmpl = new_mp_vector(list, ;
+  } else {
     ck->curr->next = list;
+  }
   ck->curr = list;
 }
-/*
-void Append(DL_Enum* d, const ID_List list) {
-  List* next = &d->base;
-  while (*next != NULL) next = &(*next)->Next;
-  *next = list;
-  next->next = NULL;
-}
 */
 //! add an enum entry
 //! \arg the importer
@@ -50,8 +45,11 @@ void Append(DL_Enum* d, const ID_List list) {
 //! TODO: change return type to m_bool
 ANN m_int gwi_enum_add(const Gwi gwi, const m_str name, const m_uint i) {
   CHECK_BB(ck_ok(gwi, ck_edef));
-  DECL_OB(const ID_List, list, = gwi_str2symlist(gwi, name));
-  add2list(gwi->ck, list);
+//  DECL_OB(const ID_List, list, = gwi_str2symlist(gwi, name));
+
+  DECL_OB(const Symbol, xid, = gwi_str2sym(gwi, name));
+  mp_vector_add(gwi->gwion->mp, &gwi->ck->tmpl, Symbol, xid);
+//  add2list(gwi->ck, list);
   vector_add(&gwi->ck->v, (vtype)i);
   return GW_OK;
 }
index 234fc378ccb2c5e57d134c8dd0bd149cab65b0cc..4a1109e3416925bef57cb12e9fc87a9db6fccd16 100644 (file)
@@ -22,7 +22,7 @@ static m_bool dl_func_init(const Gwi gwi, const restrict m_str t,
   gwi->ck->name = n;
   CHECK_BB(check_typename_def(gwi, gwi->ck));
   CHECK_OB((gwi->ck->td = gwi_str2td(gwi, t)));
-  vector_init(&gwi->ck->v);
+  gwi->ck->mpv = new_mp_vector(gwi->gwion->mp, sizeof(Arg), 0);
   return GW_OK;
 }
 
@@ -31,18 +31,9 @@ ANN m_int gwi_func_ini(const Gwi gwi, const restrict m_str t,
   return dl_func_init(gwi, t, n);
 }
 
-ANN Arg_List make_dll_arg_list(const Vector v) {
-  Arg_List base = (Arg_List)vector_front(v), arg_list = base;
-  for (m_uint i = 1; i < vector_size(v); ++i)
-    arg_list = (arg_list->next = (Arg_List)vector_at(v, i));
-  vector_release(v);
-  v->ptr = NULL;
-  return base;
-}
-
 ANEW ANN static Func_Base *gwi_func_base(const Gwi gwi, ImportCK *ck) {
-  const Arg_List arg_list = make_dll_arg_list(&gwi->ck->v);
-  Func_Base *    base = new_func_base(gwi->gwion->mp, ck->td, ck->sym, arg_list,
+  Arg_List args = gwi->ck->mpv->len ? cpy_arg_list(gwi->gwion->mp, gwi->ck->mpv) : NULL;
+  Func_Base *    base = new_func_base(gwi->gwion->mp, ck->td, ck->sym, args,
                                   ck->flag, gwi->loc);
   if (ck->variadic) base->fbflag |= fbflag_variadic;
   ck->td = NULL;
@@ -69,9 +60,13 @@ ANEW ANN static Func_Def import_fdef(const Gwi gwi, ImportCK *ck) {
 }
 
 ANN static m_bool section_fdef(const Gwi gwi, const Func_Def fdef) {
-  Section * section = new_section_func_def(gwi->gwion->mp, fdef);
-  const Ast body    = new_ast(gwi->gwion->mp, section, NULL);
-  gwi_body(gwi, body);
+//  Section * section = new_section_func_def(gwi->gwion->mp, fdef);
+//  const Ast body    = new_ast(gwi->gwion->mp, section, NULL);
+  Section section = (Section) {
+    .section_type = ae_section_func,
+    .d = { .func_def = fdef }
+  };
+  gwi_body(gwi, &section);
   return GW_OK;
 }
 
@@ -115,10 +110,10 @@ ANN m_int gwi_func_arg(const Gwi gwi, const restrict m_str t,
     return GW_OK;
   }
   DECL_OB(Type_Decl *, td, = gwi_str2td(gwi, t));
-  const Var_Decl var = gwi_str2var(gwi, n);
-  if (var) {
-    const Arg_List arg = new_arg_list(gwi->gwion->mp, td, var, NULL);
-    vector_add(&gwi->ck->v, (vtype)arg);
+  struct Var_Decl_ var;
+  if(gwi_str2var(gwi, &var, n) > 0) {
+    Arg arg = { .td = td, .var_decl = var };
+    mp_vector_add(gwi->gwion->mp, &gwi->ck->mpv, Arg, arg);
     return GW_OK;
   }
   free_type_decl(gwi->gwion->mp, td); // ???
@@ -136,9 +131,14 @@ ANN static Fptr_Def import_fptr(const Gwi gwi) {
 }
 
 ANN static m_bool section_fptr(const Gwi gwi, const Fptr_Def fdef) {
-  Section * section = new_section_fptr_def(gwi->gwion->mp, fdef);
-  const Ast body    = new_ast(gwi->gwion->mp, section, NULL);
-  gwi_body(gwi, body);
+  Section section = (Section) {
+    .section_type = ae_section_fptr,
+    .d = { .fptr_def = fdef }
+  };
+  gwi_body(gwi, &section);
+//  Section * section = new_section_fptr_def(gwi->gwion->mp, fdef);
+//  const Ast body    = new_ast(gwi->gwion->mp, section, NULL);
+//  gwi_body(gwi, body);
   return GW_OK;
 }
 
@@ -168,13 +168,6 @@ ANN Type gwi_fptr_end(const Gwi gwi, const ae_flag flag) {
 
 ANN void ck_clean_fdef(MemPool mp, ImportCK *ck) {
   if (ck->td) free_type_decl(mp, ck->td);
-  if (ck->v.ptr) {
-    for (m_uint i = 0; i < vector_size(&ck->v); ++i) {
-      Arg_List list = (Arg_List)vector_at(&ck->v, i);
-      list->next    = NULL;
-      free_arg_list(mp, list);
-    }
-    vector_release(&ck->v);
-  }
+  free_arg_list(mp, ck->mpv);
   if (ck->tmpl) free_id_list(mp, ck->tmpl);
 }
index 4937755332e3686dcbedc8ac0b64e5c695f3b615..795884e1f3e773a41d28c2ed78c957d188d5c0aa 100644 (file)
 #include "import.h"
 #include "gwi.h"
 
-void gwi_body(const Gwi gwi, const Ast body) {
+void gwi_body(const Gwi gwi, const Section *section) {
   const Class_Def cdef = gwi->gwion->env->class_def->info->cdef;
-  if (!cdef->body)
-    cdef->body = body;
-  else
-    gwi->body->next = body;
-  gwi->body = body;
+  if (!cdef->body) {
+    mp_vector_first(gwi->gwion->mp, a, Section, *section);
+    cdef->body = a;
+  } else {
+    mp_vector_add(gwi->gwion->mp, &cdef->body, Section, (*section));
+  }
 }
 
 ANN void gwi_reset(const Gwi gwi) {
@@ -48,3 +49,4 @@ ANN m_bool gwi_run(const Gwion gwion, m_bool (*f)(const Gwi)) {
   //  gwion->env->context = ctx;
   return ret;
 }
+
index 2d9bd42b14ac59ecbcdd725cacb48ec0805c6371..886b4e974ac746d7c0da71f0ab8ca63e11092549 100644 (file)
@@ -18,12 +18,20 @@ ANN m_int gwi_item_ini(const Gwi gwi, const restrict m_str type,
 }
 
 ANN static m_int gwi_item_tmpl(const Gwi gwi) {
-  const MemPool   mp    = gwi->gwion->mp;
-  const Stmt      stmt  = new_stmt_exp(mp, ae_stmt_exp, gwi->ck->exp, gwi->loc);
-  const Stmt_List slist = new_stmt_list(mp, stmt, NULL);
-  Section *       section = new_section_stmt_list(mp, slist);
-  const Ast       body    = new_ast(mp, section, NULL);
-  gwi_body(gwi, body);
+  mp_vector_first(gwi->gwion->mp, slist, struct Stmt_,
+    ((struct Stmt_) {
+      .stmt_type = ae_stmt_exp,
+      .d = { .stmt_exp = { .val = gwi->ck->exp } },
+      .pos = gwi->loc
+    }));
+  Section section = (Section) {
+    .section_type = ae_section_stmt,
+    .d = { .stmt_list = slist }
+  };
+//  Section *       section = new_section_stmt_list(mp, slist);
+//  const Ast       body    = new_ast(mp, section, NULL);
+//  gwi_body(gwi, body);
+  gwi_body(gwi, &section);
   mp_free2(gwi->gwion->mp, sizeof(ImportCK), gwi->ck);
   gwi->ck = NULL;
   return GW_OK;
@@ -44,7 +52,7 @@ m_int gwi_item_end(const Gwi gwi, const ae_flag flag, union value_data addr) {
   if (env->class_def && tflag(env->class_def, tflag_tmpl))
     return gwi_item_tmpl(gwi);
   CHECK_BB(traverse_exp(env, gwi->ck->exp));
-  const Value value = gwi->ck->exp->d.exp_decl.list->self->value;
+  const Value value = (mp_vector_at(gwi->ck->exp->d.exp_decl.list, struct Var_Decl_, 0))->value;
   value->d          = addr;
   set_vflag(value, vflag_builtin);
   if (!env->class_def) SET_FLAG(value, global);
index 3fe217f2aa2b89c6b9414841558b2dadfe58b563..cc1932efc77709fcf69f486c9c8656edf0cd566f 100644 (file)
 // move me
 ANN Exp make_exp(const Gwi gwi, const m_str type, const m_str name) {
   DECL_OO(Type_Decl *, td, = gwi_str2td(gwi, type));
-  const Var_Decl_List vlist = gwi_str2varlist(gwi, name);
-  if (vlist) return new_exp_decl(gwi->gwion->mp, td, vlist, gwi->loc);
-  free_type_decl(gwi->gwion->mp, td);
-  return NULL;
+  struct Var_Decl_ vd;
+  if(gwi_str2var(gwi, &vd, name) < 0) {
+    free_type_decl(gwi->gwion->mp, td);
+    return NULL;
+  }
+  const Var_Decl_List list = new_mp_vector(gwi->gwion->mp, sizeof(struct Var_Decl_), 1);
+  mp_vector_set(list, struct Var_Decl_, 0, vd);
+  return new_exp_decl(gwi->gwion->mp, td, list, gwi->loc);
 }
 
 ANN m_int gwi_union_ini(const Gwi gwi, const m_str name) {
   CHECK_BB(ck_ini(gwi, ck_udef));
   gwi->ck->name = name;
   CHECK_BB(check_typename_def(gwi, gwi->ck));
+  gwi->ck->mpv = new_mp_vector(gwi->gwion->mp, sizeof(Union_Member), 0);
   return GW_OK;
 }
 
@@ -35,9 +40,11 @@ ANN m_int gwi_union_add(const Gwi gwi, const restrict m_str type,
   CHECK_BB(ck_ok(gwi, ck_udef));
   DECL_OB(Type_Decl *, td, = str2td(gwi->gwion, type, gwi->loc));
   DECL_OB(const Symbol, xid, = str2sym(gwi->gwion, name, gwi->loc));
-  const Union_List l = new_union_list(gwi->gwion->mp, td, xid, gwi->loc);
-  l->next            = gwi->ck->list;
-  gwi->ck->list      = l;
+  Union_Member um = { .td = td, .vd = { .xid = xid, .pos = gwi->loc } };
+  mp_vector_add(gwi->gwion->mp, &gwi->ck->list, Union_Member, um);
+//  const Union_List l = new_union_list(gwi->gwion->mp, td, xid, gwi->loc);
+//  l->next            = gwi->ck->list;
+//  gwi->ck->list      = l;
   return GW_OK;
 }
 
@@ -61,8 +68,8 @@ ANN static Type union_type(const Gwi gwi, const Union_Def udef) {
 
 ANN Type gwi_union_end(const Gwi gwi, const ae_flag flag) {
   CHECK_BO(ck_ok(gwi, ck_udef));
-  if (!gwi->ck->list) GWI_ERR_O(_("union is empty"));
-  const Union_Def udef = new_union_def(gwi->gwion->mp, gwi->ck->list, gwi->loc);
+  if (!gwi->ck->mpv->len) GWI_ERR_O(_("union is empty"));
+  const Union_Def udef = new_union_def(gwi->gwion->mp, gwi->ck->mpv, gwi->loc);
   gwi->ck->list        = NULL;
   udef->flag           = flag;
   udef->xid            = gwi->ck->sym;
@@ -77,6 +84,6 @@ ANN Type gwi_union_end(const Gwi gwi, const ae_flag flag) {
 }
 
 ANN void ck_clean_udef(MemPool mp, ImportCK *ck) {
-  if (ck->list) free_union_list(mp, ck->list);
+  if (ck->mpv) free_mp_vector(mp, sizeof(Union_Member), ck->mpv);
   if (ck->tmpl) free_id_list(mp, ck->tmpl);
 }
index e4a8d9b655f66f3798dd5180bde35062efe8abeb..edbbdcc019145d5a4bb44fe957cbe046e9765f1c 100644 (file)
@@ -14,6 +14,7 @@
 #include "gwi.h"
 #include "emit.h"
 #include "looper.h"
+
 static DTOR(array_dtor) {
   if (*(void **)(o->data + SZ_INT)) xfree(*(void **)(o->data + SZ_INT));
   struct M_Vector_ *a = ARRAY(o);
@@ -119,15 +120,15 @@ static OP_CHECK(opck_array_at) {
       ERR_N(exp_self(bin)->pos, _("array depths do not match."));
   }
   if (bin->rhs->exp_type == ae_exp_decl) {
-    if (bin->rhs->d.exp_decl.list->self->array &&
-        bin->rhs->d.exp_decl.list->self->array->exp)
+    Var_Decl vd = mp_vector_at(bin->rhs->d.exp_decl.list, struct Var_Decl_, 0);
+    if (vd->array &&
+        vd->array->exp)
       ERR_N(exp_self(bin)->pos,
             _("do not provide array for 'xxx => declaration'."));
+    SET_FLAG(vd->value, late);
   }
   bin->rhs->ref = bin->lhs;
 //  bin->rhs->data = bin->lhs;
-  if(bin->rhs->exp_type == ae_exp_decl)
-    SET_FLAG(bin->rhs->d.exp_decl.list->self->value, late);
   exp_setvar(bin->rhs, 1);
   return bin->rhs->type;
 }
@@ -412,8 +413,7 @@ ANN static inline void _init(const VM_Shred shred, const struct VM_Code_ *code,
   frame->code            = shred->code;
   frame->offset          = offset;
   frame->index           = 0;
-  *(m_uint *)REG(SZ_INT) =
-      offset; // + sizeof(frame_t);// + shred->code->stack_depth;
+  *(m_uint *)REG(SZ_INT) = offset;
   shred->code = (VM_Code)code;
   shred->pc   = 0;
   shredule(shred->tick->shreduler, shred, 0);
@@ -421,7 +421,7 @@ ANN static inline void _init(const VM_Shred shred, const struct VM_Code_ *code,
 
 ANN static inline void _next(const VM_Shred shred, const m_uint offset) {
   shred->pc         = 0;
-  *(m_uint *)REG(0) = offset; // + sizeof(frame_t);
+  *(m_uint *)REG(0) = offset;
   POP_REG(shred, SZ_INT);
 }
 
@@ -641,7 +641,7 @@ static OP_CHECK(opck_array_scan) {
   const Type           t_array = env->gwion->type[et_array];
   const Class_Def      c       = t_array->info->cdef;
   DECL_ON(const Type, base,
-          = ts->t != t_array ? ts->t : known_type(env, ts->td->types->td));
+          = ts->t != t_array ? ts->t : known_type(env, *mp_vector_at(ts->td->types, Type_Decl*, 0)));
   if (base->size == 0) {
     gwerr_basic("Can't use type of size 0 as array base", NULL, NULL,
                 "/dev/null", (loc_t) {}, 0);
@@ -667,8 +667,8 @@ static OP_CHECK(opck_array_scan) {
   cdef->base.ext        = type2td(env->gwion, t_array, (loc_t) {});
   cdef->base.xid        = sym;
   cdef->base.tmpl->base = 1; // could store depth here?
-  cdef->base.tmpl->call = new_type_list(
-      env->gwion->mp, type2td(env->gwion, base, (loc_t) {}), NULL);
+  cdef->base.tmpl->call = new_mp_vector(env->gwion->mp, sizeof(Type_Decl*), 1);
+  mp_vector_set(cdef->base.tmpl->call, Type_Decl*, 0, type2td(env->gwion, base, (loc_t) {}));
   const Context ctx  = env->context;
   env->context       = base->info->value->from->ctx;
   const m_uint scope = env_push(env, base->info->value->from->owner_class,
index cd0dba2a8a185c3d38e6ab1c2dcf6247ef10ef0a..0e85c398e9dbbaa8c562890f45dced617f06a926 100644 (file)
@@ -624,10 +624,9 @@ static OP_CHECK(opck_dict_scan) {
       .base = ts->t, .td = ts->td, .list = ts->t->info->cdef->base.tmpl->list};
   const Type  exists = tmpl_exists(env, &info);
   if (exists) return exists != env->gwion->type[et_error] ? exists : NULL;
-  CHECK_ON(ts->td->types);
-  DECL_ON(const Type, key, = known_type(env, ts->td->types->td));
-  CHECK_ON(ts->td->types->next);
-  DECL_ON(const Type, val, = known_type(env, ts->td->types->next->td));
+  if(!ts->td->types || ts->td->types->len != 2) return env->gwion->type[et_error];
+  DECL_ON(const Type, key, = known_type(env, *mp_vector_at(ts->td->types, Type_Decl*, 0)));
+  DECL_ON(const Type, val, = known_type(env, *mp_vector_at(ts->td->types, Type_Decl*, 1)));
   if(tflag(key, tflag_ref) || tflag(val, tflag_ref))
     ERR_N(ts->td->pos, "can't use Ref:[] in dicts");
   const Class_Def cdef  = cpy_class_def(env->gwion->mp, env->gwion->type[et_dict]->info->cdef);
index 641730efb0ce567efeee523b7a59060432f5ae54..2ff080fcfca6889a99cd46e28ae256ef6397ab33 100644 (file)
@@ -118,12 +118,12 @@ ANN static void _fptr_tmpl_push(const Env env, const Func f) {
   if (!tmpl) return;
   Type_List tl = tmpl->call;
   if (!tl) return;
-  Specialized_List il = tmpl->list;
-  while (il) {
-    const Type t = known_type(env, tl->td);
-    nspc_add_type(env->curr, il->xid, t);
-    il = il->next;
-    tl = tl->next;
+  Specialized_List sl = tmpl->list;
+  for(uint32_t i = 0; i < sl->len; i++) {
+    Specialized *spec = mp_vector_at(sl, Specialized, i);
+    Type_Decl *td = *mp_vector_at(tl, Type_Decl*, i);
+    const Type t = known_type(env, td);
+    nspc_add_type(env->curr, spec->xid, t);
   }
 }
 
@@ -148,26 +148,30 @@ static m_bool td_match(const Env env, Type_Decl *id[2]) {
   return t1 == env->gwion->type[et_auto] ? GW_OK : GW_ERROR;
 }
 
+ANN static inline bool handle_global(Func_Base *a, Func_Base *b) {
+  return (!b->func->value_ref->from->owner_class &&
+      (!GET_FLAG(a, global) && a->func->value_ref->from->owner_class));
+}
+
 ANN static m_bool fptr_args(const Env env, Func_Base *base[2]) {
-  Arg_List arg0 = base[0]->args, arg1 = base[1]->args;
-  if(!base[0]->func->value_ref->from->owner_class &&
-      (!GET_FLAG(base[1], global) && base[1]->func->value_ref->from->owner_class))
-    arg0 = arg0->next;
-  if(!base[1]->func->value_ref->from->owner_class &&
-      (!GET_FLAG(base[0], global) && base[0]->func->value_ref->from->owner_class))
-    arg1 = arg1->next;
-  while (arg0) {
-    CHECK_OB(arg1);
+  Arg_List args0 = base[0]->args, args1 = base[1]->args;
+  const bool offset0 = handle_global(base[0], base[1]);
+  const bool offset1 = handle_global(base[1], base[0]);
+  const uint32_t len0 = args0 ? args0->len : 0;
+  const uint32_t len1 = args1 ? args1->len : 0;
+  if(len0 - offset0 != len1 - offset1)
+    return GW_ERROR;
+  for(uint32_t i = 0; i < len1 - offset0; i++) {
+    const Arg *arg0 = (Arg*)(args0->ptr + (i + offset0) * sizeof(Arg));
+    const Arg *arg1 = (Arg*)(args1->ptr + (i + offset1) * sizeof(Arg));
     if (arg0->type && arg1->type)
       CHECK_BB(isa(arg0->type, arg1->type));
-    else {
+    else if(!tmpl_base(base[0]->tmpl) && !tmpl_base(base[1]->tmpl)){
       Type_Decl *td[2] = {arg0->td, arg1->td};
       CHECK_BB(td_match(env, td));
     }
-    arg0 = arg0->next;
-    arg1 = arg1->next;
   }
-  return !arg1 ? GW_OK : GW_ERROR;
+  return GW_OK;
 }
 
 ANN static bool fptr_effects(const Env env, struct FptrInfo *info) {
@@ -195,15 +199,21 @@ ANN static m_bool fptr_check(const Env env, struct FptrInfo *info) {
           _("can't resolve operator"))
   const Type l_type = info->lhs->value_ref->from->owner_class;
   const Type r_type = info->rhs->value_ref->from->owner_class;
+  const Arg *l_arg = info->lhs->def->base->args ? mp_vector_at(info->lhs->def->base->args, Arg, 0) : NULL;
+  const Arg *r_arg = info->rhs->def->base->args ? mp_vector_at(info->rhs->def->base->args, Arg, 0) : NULL;
+// added when parsing bases template
+  const Type l_this = l_arg && l_arg->var_decl.value ? l_arg->var_decl.value->type : NULL;
+  const Type r_this = r_arg && r_arg->var_decl.value? r_arg->var_decl.value->type : NULL;
+
   if (!r_type && l_type) {
     if (/*!GET_FLAG(info->lhs, global) && */(!info->rhs->def->base->args ||
-isa(l_type, info->rhs->def->base->args->var_decl->value->type) < 0)
+isa(l_type, r_this) < 0)
 )
     ERR_B(info->pos,
           _("can't assign member function to non member function pointer"))
   } else if (!l_type && r_type) {
     if (!GET_FLAG(info->rhs, global) && (!info->lhs->def->base->args ||
-isa(r_type, info->lhs->def->base->args->var_decl->value->type) < 0)
+isa(r_type, l_this) < 0)
 )
       ERR_B(info->pos,
             _("can't assign non member function to member function pointer"))
@@ -265,24 +275,29 @@ ANN static Type fptr_type(const Env env, struct FptrInfo *info) {
 
 ANN static m_bool _check_lambda(const Env env, Exp_Lambda *l,
                                 const Func_Def def) {
-  // if(l->def->base->func)return GW_OK;
+//   if(l->def->base->func) return GW_OK;
+  Arg_List bases = def->base->args;
+  Arg_List args = l->def->base->args;
+  // arity match
+  if ((bases ? bases->len : 0) != (args ? args->len : 0))
+    ERR_B(exp_self(l)->pos, _("argument number does not match for lambda"))
   const bool is_tmpl =
       safe_tflag(def->base->func->value_ref->from->owner_class, tflag_tmpl);
   if (is_tmpl)
     template_push_types(
         env,
         def->base->func->value_ref->from->owner_class->info->cdef->base.tmpl);
-  Arg_List base = def->base->args, arg = l->def->base->args;
-  while (base && arg) {
-    arg->td = type2td(env->gwion, known_type(env, base->td), exp_self(l)->pos);
-    base    = base->next;
-    arg     = arg->next;
+  if(bases) {
+    for(uint32_t i = 0; i < bases->len; i++) {
+      Arg *base = (Arg*)(bases->ptr + i * sizeof(Arg));
+      Arg *arg  = (Arg*)(args->ptr + i * sizeof(Arg));
+      arg->td = type2td(env->gwion, known_type(env, base->td), exp_self(l)->pos);
+    }
+
   }
   l->def->base->td =
       type2td(env->gwion, known_type(env, def->base->td), exp_self(l)->pos);
   if (is_tmpl) nspc_pop_type(env->gwion->mp, env->curr);
-  if (base || arg)
-    ERR_B(exp_self(l)->pos, _("argument number does not match for lambda"))
   l->def->base->flag = def->base->flag;
   //  if(GET_FLAG(def->base, global) && !l->owner &&
   //  def->base->func->value_ref->from->owner_class)
@@ -307,6 +322,14 @@ ANN static m_bool _check_lambda(const Env env, Exp_Lambda *l,
   }
 
   if(ret < 0) {
+    if(args) {
+      for(uint32_t i = 0; i < bases->len; i++) {
+        Arg *arg  = (Arg*)(args->ptr + i * sizeof(Arg));
+        free_value(arg->var_decl.value, env->gwion);
+        arg->var_decl.value = NULL;
+      }
+    }
+/*
     Arg_List args = l->def->base->args;
     while(args) {
       if(!args->var_decl->value) break;
@@ -314,7 +337,7 @@ ANN static m_bool _check_lambda(const Env env, Exp_Lambda *l,
       args->var_decl->value = NULL;
       args = args->next;
     }
-
+*/
   }
   return ret;
 }
@@ -363,7 +386,8 @@ static OP_CHECK(opck_auto_fptr) {
   const Type   t      = fptr_def->type;
   free_fptr_def(env->gwion->mp, fptr_def);
 //  type_remref(t, env->gwion);
-  bin->rhs->d.exp_decl.list->self->value->type = bin->rhs->type =
+    Var_Decl vd = mp_vector_at(bin->rhs->d.exp_decl.list, struct Var_Decl_, 0);
+  vd->value->type = bin->rhs->type =
       bin->rhs->d.exp_decl.type                = t;
   exp_setvar(bin->rhs, 1);
   return ret > 0 ? t : env->gwion->type[et_error];
@@ -371,8 +395,10 @@ static OP_CHECK(opck_auto_fptr) {
 
 static OP_CHECK(opck_fptr_at) {
   Exp_Binary *bin = (Exp_Binary *)data;
-  if (bin->rhs->exp_type == ae_exp_decl)
-    UNSET_FLAG(bin->rhs->d.exp_decl.list->self->value, late);
+  if (bin->rhs->exp_type == ae_exp_decl) {
+    Var_Decl vd = mp_vector_at(bin->rhs->d.exp_decl.list, struct Var_Decl_, 0);
+    UNSET_FLAG(vd->value, late);
+  }
   if (bin->lhs->exp_type == ae_exp_td)
     ERR_N(bin->lhs->pos, "can't use type_decl expression");
   //    UNSET_FLAG(bin->rhs->d.exp_decl.list->self->value, late);
@@ -483,30 +509,40 @@ ANN Type check_op_call(const Env env, Exp_Call *const exp) {
 
 static m_bool op_impl_narg(const Env env, const Func_Def fdef,
                            const loc_t loc) {
+/*
   m_uint   narg = 0;
   Arg_List arg  = fdef->base->args;
   while (arg) {
     narg++;
     arg = arg->next;
   }
-  if (narg == 2) return GW_OK;
+*/
+  Arg_List arg  = fdef->base->args;
+  if (!arg && arg->len == 2) return GW_OK;
   op_narg_err(env, fdef, loc);
   return GW_ERROR;
 }
 
 static inline void op_impl_ensure_types(const Env env, const Func func) {
-  Arg_List   arg = func->def->base->args;
   const bool owner_tmpl =
       safe_tflag(func->value_ref->from->owner_class, tflag_tmpl);
-  const bool func_tmpl = fflag(func, fflag_tmpl);
   if (owner_tmpl)
     template_push_types(
         env, func->value_ref->from->owner_class->info->cdef->base.tmpl);
+  const bool func_tmpl = fflag(func, fflag_tmpl);
   if (func_tmpl) template_push_types(env, func->def->base->tmpl);
+
+  Arg_List args = func->def->base->args;
+  for(uint32_t i = 0; i < args->len; i++) {
+    Arg *arg = (Arg*)(args->ptr + i * sizeof(Arg));
+    if (!arg->type) arg->type = known_type(env, arg->td);
+  }
+/*
   while (arg) {
     if (!arg->type) arg->type = known_type(env, arg->td);
     arg = arg->next;
   }
+*/
   if (!func->def->base->ret_type)
     func->def->base->ret_type = known_type(env, func->def->base->td);
   if (owner_tmpl) nspc_pop_type(env->gwion->mp, env->curr);
@@ -521,16 +557,18 @@ static OP_CHECK(opck_op_impl) {
   op_impl_ensure_types(env, func);
   const Symbol lhs_sym = insert_symbol("@lhs");
   const Symbol rhs_sym = insert_symbol("@rhs");
+  const Arg *arg0 = (Arg*)(func->def->base->args->ptr);
+  const Arg *arg1 = (Arg*)(func->def->base->args->ptr + sizeof(Arg));
   struct Exp_  _lhs    = {
       .d        = {.prim = {.d = {.var = lhs_sym}, .prim_type = ae_prim_id}},
       .exp_type = ae_exp_primary,
-      .type     = func->def->base->args->type,
-      .pos      = func->def->base->args->td->pos};
+      .type     = arg0->type,
+      .pos      = arg0->td->pos};
   struct Exp_ _rhs = {
       .d        = {.prim = {.d = {.var = rhs_sym}, .prim_type = ae_prim_id}},
       .exp_type = ae_exp_primary,
-      .type     = func->def->base->args->next->type,
-      .pos      = func->def->base->args->next->td->pos};
+      .type     = arg1->type,
+      .pos      = arg1->td->pos};
   struct Exp_ self = {.pos = impl->e->pos};
   //  Exp_Binary _bin = { .lhs=&_lhs, .op=impl->e->d.prim.d.var, .rhs=&_rhs };//
   //  .lhs=func->def->base->args // TODO
@@ -538,8 +576,8 @@ static OP_CHECK(opck_op_impl) {
   self.d.exp_binary.rhs = &_rhs;
   self.d.exp_binary.op  = impl->e->d.prim.d.var;
   struct Op_Import opi  = {.op   = impl->e->d.prim.d.var,
-                          .lhs  = func->def->base->args->type,
-                          .rhs  = func->def->base->args->next->type,
+                          .lhs  = arg0->type,
+                          .rhs  = arg1->type,
                           .data = (uintptr_t)&self.d.exp_binary,
                           .pos  = impl->e->pos};
   vector_add(&env->scope->effects, 0);
@@ -568,9 +606,10 @@ static OP_CHECK(opck_op_impl) {
     }
   }
   const Arg_List args = cpy_arg_list(env->gwion->mp, func->def->base->args);
-  // beware shadowing ?
-  args->var_decl->xid       = lhs_sym;
-  args->next->var_decl->xid = rhs_sym;
+  Arg *larg0 = (Arg*)(args->ptr);
+  Arg *larg1 = (Arg*)(args->ptr + sizeof(Arg));
+  larg0->var_decl.xid       = rhs_sym;
+  larg1->var_decl.xid = rhs_sym;
   Func_Base *base =
       new_func_base(env->gwion->mp, type2td(env->gwion, t, impl->e->pos),
                     impl->e->d.prim.d.var, args, ae_flag_none, impl->e->pos);
@@ -584,15 +623,17 @@ static OP_CHECK(opck_op_impl) {
     m_vector_release(eff);
   }
   const Exp lhs =
-      new_prim_id(env->gwion->mp, args->var_decl->xid, impl->e->pos);
+      new_prim_id(env->gwion->mp, larg0->var_decl.xid, impl->e->pos);
   const Exp rhs =
-      new_prim_id(env->gwion->mp, args->next->var_decl->xid, impl->e->pos);
+      new_prim_id(env->gwion->mp, larg1->var_decl.xid, impl->e->pos);
   const Exp  bin = new_exp_binary(env->gwion->mp, lhs, impl->e->d.prim.d.var,
                                  rhs, impl->e->pos);
-  const Stmt stmt =
-      new_stmt_exp(env->gwion->mp, ae_stmt_return, bin, impl->e->pos);
-  const Stmt_List list = new_stmt_list(env->gwion->mp, stmt, NULL);
-  const Stmt      code = new_stmt_code(env->gwion->mp, list, impl->e->pos);
+  mp_vector_first(env->gwion->mp, slist, struct Stmt_,
+    ((struct Stmt_) {
+    .stmt_type = ae_stmt_return, .d = { .stmt_exp = { .val = bin }},
+    .pos = impl->e->pos
+  }));
+  const Stmt      code = new_stmt_code(env->gwion->mp, slist, impl->e->pos);
   const Func_Def  def  = new_func_def(env->gwion->mp, base, code);
   def->base->xid       = impl->e->d.prim.d.var;
   const m_uint scope   = env_push(env, NULL, opi.nspc);
@@ -618,10 +659,12 @@ static OP_EMIT(opem_op_impl) {
 ANN Type check_exp_unary_spork(const Env env, const Stmt code);
 
 ANN static void fork_exp(const Env env, const Exp_Unary *unary) {
-  const Stmt stmt =
-      new_stmt_exp(env->gwion->mp, ae_stmt_exp, unary->exp, unary->exp->pos);
-  const Stmt_List list = new_stmt_list(env->gwion->mp, stmt, NULL);
-  const Stmt      code = new_stmt_code(env->gwion->mp, list, unary->exp->pos);
+  mp_vector_first(env->gwion->mp, slist, struct Stmt_,
+    ((struct Stmt_) {
+      .stmt_type = ae_stmt_exp, .d = { .stmt_exp = { .val = unary->exp, } },
+      .pos = unary->exp->pos
+  }));
+  const Stmt      code = new_stmt_code(env->gwion->mp, slist, unary->exp->pos);
   ((Exp_Unary *)unary)->exp        = NULL;
   ((Exp_Unary *)unary)->code       = code;
   ((Exp_Unary *)unary)->unary_type = unary_code;
index 76bffd3d924b2bc88107cbbdd9cabce8bb8122cb..21f8e0ea841a3566b7775682ea1b6a40f6d1373b 100644 (file)
@@ -205,10 +205,10 @@ static DTOR(usrugen_dtor) {
 static OP_CHECK(opck_usrugen) {
   Exp_Binary *   bin = (Exp_Binary *)data;
   const Arg_List arg = bin->lhs->type->info->func->def->base->args;
-  if (!arg || arg->next)
+  if (!arg || arg->len > 1)
     ERR_N(exp_self(bin)->pos,
           _("Tick function take one and only one argument"));
-  if (isa(arg->type, env->gwion->type[et_float]) < 0)
+  if (isa(((Arg*)(arg->ptr))->type, env->gwion->type[et_float]) < 0)
     ERR_N(exp_self(bin)->pos,
           _("Tick functions argument must be of type float"));
   if (isa(bin->lhs->type->info->func->def->base->ret_type,
index d4c5d8d3f55892b8078cce640b13137154f2d108..c882f56dfcde3cea463498111ae3606d7c600381 100644 (file)
@@ -30,8 +30,10 @@ static OP_CHECK(opck_object_at) {
   const Exp_Binary *bin = (Exp_Binary *)data;
   if (opck_rassign(env, data) == env->gwion->type[et_error])
     return env->gwion->type[et_error];
-  if (bin->rhs->exp_type == ae_exp_decl)
-    SET_FLAG(bin->rhs->d.exp_decl.list->self->value, late);
+  if (bin->rhs->exp_type == ae_exp_decl) {
+    Var_Decl vd = mp_vector_at(bin->rhs->d.exp_decl.list, struct Var_Decl_, 0);
+    SET_FLAG(vd->value, late);
+  }
   exp_setvar(bin->rhs, 1);
   CHECK_BO(isa(bin->lhs->type, bin->rhs->type));
   bin->lhs->ref = bin->rhs;
@@ -285,7 +287,8 @@ ANN static m_bool scantmpl_class_def(const Env env, struct tmpl_info *info) {
   const Class_Def cdef = new_class_def(
       env->gwion->mp, c->flag, info->name,
       c->base.ext ? cpy_type_decl(env->gwion->mp, c->base.ext) : NULL,
-      c->body ? cpy_ast(env->gwion->mp, c->body) : NULL, c->pos);
+      NULL, c->pos);
+  if(c->body) cdef->body = cpy_ast(env->gwion->mp, c->body);
   cdef->cflag      = c->cflag;
   cdef->base.tmpl  = mk_tmpl(env, c->base.tmpl, info->td->types);
   const m_bool ret = scan0_class_def(env, cdef);
@@ -325,11 +328,12 @@ ANN static Type _scan_class(const Env env, struct tmpl_info *info) {
 
 ANN Type tmpl_exists(const Env env, struct tmpl_info *const info);
 
-ANN bool tmpl_global(const Env env, Type_List call) {
-  do {
-    if(!type_global(env, known_type(env, call->td)))
+ANN bool tmpl_global(const Env env, Type_List tl) {
+  for(uint32_t i = 0; i < tl->len; i++) {
+    Type_Decl *td = *mp_vector_at(tl, Type_Decl*, i);
+    if(!type_global(env, known_type(env, td)))
       return false;
-  } while((call = call->next));
+  };
   return true;
 }
 
index bdc2cc7dcde78258ad1777ff0d992479579d5753..ce0ab9b1d6f60e8f78e41bfb706bdab067630feb 100644 (file)
@@ -23,7 +23,7 @@ static m_bool ptr_access(const Env env, const Exp e) {
 
 ANN static inline Type ptr_base(const Env env, const Type t) {
   return (Type)vector_front(&t->info->tuple->types);
-  return known_type(env, t->info->cdef->base.tmpl->call->td);
+//  return known_type(env, *mp_vector_at(t->info->cdef->base.tmpl->call, Type_Decl*, 0));
 }
 
 static OP_CHECK(opck_ptr_assign) {
@@ -37,11 +37,10 @@ static OP_CHECK(opck_ptr_assign) {
     Type u = bin->rhs->type;
     do {
       const Type base = ptr_base(env, u);
-//      if (isa(t, base) > 0) return t;
       if (isa(t, base) > 0) return bin->rhs->type;
     } while ((u = u->info->parent) && u->info->cdef->base.tmpl->call);
   } while ((t = t->info->parent));
-  return env->gwion->type[et_error];
+  ERR_N(exp_self(bin)->pos, "can't assign to pointer");
 }
 
 static OP_EMIT(opem_ptr_assign) {
@@ -60,12 +59,12 @@ static OP_CHECK(opck_ptr_deref) {
 
 static OP_CHECK(opck_ptr_cast) {
   const Exp_Cast *cast = (Exp_Cast *)data;
-  if (!cast->td->types || !cast->td->types->td)
+  if (!cast->td->types || !cast->td->types->len)
     ERR_N(exp_self(cast)->pos, "'Ptr' needs types to cast");
   DECL_ON(const Type, t, = known_type(env, cast->td));
   if (t->info->cdef && !tflag(t, tflag_check))
     CHECK_BN(ensure_traverse(env, t));
-  const Type to = known_type(env, cast->td->types->td);
+  const Type to = known_type(env, *mp_vector_at(cast->td->types, Type_Decl*, 0));
   exp_setvar(cast->exp, 1);
   if (isa(cast->exp->type, to) > 0) return t;
   ERR_N(exp_self(cast)->pos, "invalid pointer cast");
@@ -135,7 +134,7 @@ static DTOR(ptr_struct_dtor) {
                                 base->info->value->from->owner_class,
                                 base->info->value->from->owner);
   const Type   t     = known_type(shred->info->vm->gwion->env,
-                            base->info->cdef->base.tmpl->call->td);
+                            *mp_vector_at(base->info->cdef->base.tmpl->call, Type_Decl*, 0));
   env_pop(shred->info->vm->gwion->env, scope);
   struct_release(shred, t, *(m_bit **)o);
 }
@@ -146,7 +145,7 @@ static OP_CHECK(opck_ptr_scan) {
       .base = ts->t, .td = ts->td, .list = ts->t->info->cdef->base.tmpl->list};
   const Type exists = tmpl_exists(env, &info);
   if (exists) return exists != env->gwion->type[et_error] ? exists : NULL;
-  const Type base = known_type(env, ts->td->types->td);
+  const Type base = known_type(env, *mp_vector_at(ts->td->types, Type_Decl*, 0));
   const Type t    = new_type(env->gwion->mp, s_name(info.name), base);
   t->size = SZ_INT;
   t->info->parent = env->gwion->type[et_ptr];
index 5bef6aa2047147e51fdc945fc2059aef5ef6f04f..67a1b24554f8be48ae0743efad21349f09b77e70 100644 (file)
@@ -145,7 +145,7 @@ static OP_CHECK(opck_ref_scan) {
       .base = ts->t, .td = ts->td, .list = ts->t->info->cdef->base.tmpl->list};
   const Type exists = tmpl_exists(env, &info);
   if (exists) return exists != env->gwion->type[et_error] ? exists : NULL;
-  const Type base = known_type(env, ts->td->types->td);
+  const Type base = known_type(env, *mp_vector_at(ts->td->types, Type_Decl*, 0));
   const Type t    = new_type(env->gwion->mp, s_name(info.name), base);
   t->size = SZ_INT;
   SET_FLAG(t, abstract | ae_flag_final);
index 067a5faa04d79cc4758db6f451b10e6f153ae939..441d421c7c22b89482f63ea3577cf216423fb241 100644 (file)
@@ -421,7 +421,7 @@ GWION_IMPORT(shred) {
 
   const Type t_typed = gwi_class_ini(gwi, "TypedFork:[A]", "Fork");
   gwi_item_ini(gwi, "A", "retval");
-  GWI_BB((gwi_item_end(gwi, ae_flag_const, num, 0)))
+  GWI_BB(gwi_item_end(gwi, ae_flag_const, num, 0))
   GWI_BB(gwi_class_end(gwi))
   SET_FLAG(t_typed, abstract | ae_flag_final);
   return GW_OK;
index 0b88412f48f54f758dde0e06f2f8dc0132da7ef3..4b294af51c72f3108da31ed498367bee303536da 100644 (file)
@@ -70,10 +70,15 @@ ANEW ANN static Symbol template_id(const Env               env,
   return sym;
 }
 
-ANN static m_bool template_match(Specialized_List base, Type_List call) {
-  while ((call = call->next) && (base = base->next))
-    ;
-  return !call ? GW_OK : GW_ERROR;
+ANN static m_bool template_match(Specialized_List sl, Type_List tl) {
+//  uint32_t i = 0;
+//  while ((call = call->next)) i++;
+//&& (base = base->next))
+//  while ((call = call->next) && (base = base->next))
+//    ;
+//  return i = base->len ? GW_OK : GW_ERROR;
+//  return !call ? GW_OK : GW_ERROR;
+  return tl->len >= sl->len;
 }
 
 ANN static Type _tmpl_exists(const Env env, const Symbol name) {
index 225f62546c8562ccc25f67ad90be513ba0ac74d9..1a0a5f4f75a927050376063e66cb0c1e8cdf7f87 100644 (file)
@@ -41,7 +41,7 @@ int main(int argc, char **argv) {
 #else
 
 int main(int argc, char **argv) {
-  Arg arg = {.arg = {.argc = argc, .argv = argv}, .loop = false};
+  CliArg arg = {.arg = {.argc = argc, .argv = argv}, .loop = false};
   signal(SIGINT, sig);
   signal(SIGTERM, sig);
   struct Gwion_ gwion = {};
index 3dc5526d240a87df2f0c450a03840c28ea55a279..8fe93b99966a45f7a2f60134f31df51e2c9584bc 100644 (file)
@@ -119,14 +119,14 @@ ANN static inline void valid_value(const Env env, const Symbol xid, const Value
 
 ANN static m_bool check_decl(const Env env, const Exp_Decl *decl) {
   Var_Decl_List list = decl->list;
-  do {
-    const Var_Decl var = list->self;
-    CHECK_BB(check_var(env, var));
-    CHECK_BB(check_var_td(env, var, decl->td));
-    if (is_fptr(env->gwion, decl->type)) CHECK_BB(check_fptr_decl(env, var));
-    valid_value(env, var->xid, var->value);
+  for(uint32_t i = 0; i < list->len; i++) {
+    const Var_Decl vd = mp_vector_at(list, struct Var_Decl_, i);
+    CHECK_BB(check_var(env, vd));
+    CHECK_BB(check_var_td(env, vd, decl->td));
+    if (is_fptr(env->gwion, decl->type)) CHECK_BB(check_fptr_decl(env, vd));
+    valid_value(env, vd->xid, vd->value);
     // set_vflag(var->value, vflag_used));
-  } while ((list = list->next));
+  }
   return GW_OK;
 }
 
@@ -179,7 +179,7 @@ ANN Type check_exp_decl(const Env env, const Exp_Decl *decl) {
   const m_bool ret    = check_decl(env, decl);
   if (global) env_pop(env, scope);
   env_weight(env, 1 + isa(decl->type, env->gwion->type[et_object]) > 0);
-  return ret > 0 ? decl->list->self->value->type : NULL;
+  return ret > 0 ? (mp_vector_at(decl->list, struct Var_Decl_, 0))->value->type : NULL;
 }
 
 ANN static m_bool check_collection(const Env env, Type type, const Exp e,
@@ -477,13 +477,12 @@ ANN static inline Type type_list_base(const Gwion gwion, const Type type) {
     type : type_list_base_func(type);
 }
 
-ANN static Type_List mk_type_list(const Env env, const Arg_List arg,
+ANN static Type_Decl* mk_td(const Env env, const Arg *arg,
                                   const Type type, const loc_t pos) {
   const Type base = type_list_base(env->gwion, type);
   const Type t    = !arg->td->array ?
           base : array_type(env, base, arg->td->array->depth);
-  Type_Decl *td   = type2td(env->gwion, t, pos);
-  return new_type_list(env->gwion->mp, td, NULL);
+  return type2td(env->gwion, t, pos);
 }
 
 ANN static inline bool func_match_inner(const Env env, const Exp e,
@@ -495,39 +494,41 @@ ANN static inline bool func_match_inner(const Env env, const Exp e,
 }
 
 ANN2(1, 2)
-static Func find_func_match_actual(const Env env, Func func, const Exp args,
+static Func find_func_match_actual(const Env env, Func func, const Exp exp,
                                    const bool implicit, const bool specific) {
   do {
-    Exp      e  = args;
-    Arg_List e1 = func->def->base->args;
+    Exp e = exp;
+    Arg_List args = func->def->base->args;
+    m_uint i = 0;
+    const m_uint args_len = args ? args->len : 0;
     while (e) {
       e->cast_to = NULL;
       if (!e->type) // investigate
         return NULL;
-      if (tflag(e->type, tflag_ref) && isa(e->type, e1->type) > 0) {
-        if(!e->cast_to)e->cast_to = e1->type;
-      }
-      if (!e1) {
+// rewrite
+      Arg *arg = i < args_len ? mp_vector_at(args, Arg, i++) : NULL;
+      if (!arg) {
         if (fbflag(func->def->base, fbflag_variadic)) return func;
         CHECK_OO(func->next);
-        return find_func_match_actual(env, func->next, args, implicit,
+        return find_func_match_actual(env, func->next, exp, implicit,
                                       specific);
       }
-      if (e1->type == env->gwion->type[et_auto] ||
+      if (tflag(e->type, tflag_ref) && isa(e->type, arg->type) > 0) {
+        if(!e->cast_to)e->cast_to = arg->type;
+      }
+      if (arg->type == env->gwion->type[et_auto] ||
           (func->def->base->tmpl &&
            is_fptr(env->gwion, func->value_ref->type) > 0)) {
         const Type owner = func->value_ref->from->owner_class;
         if (owner) CHECK_BO(template_push(env, owner));
-        e1->type = known_type(env, e1->td);
+        arg->type = known_type(env, arg->td);
         if (owner) nspc_pop_type(env->gwion->mp, env->curr);
-        CHECK_OO(e1->type);
+        CHECK_OO(arg->type);
       }
-      if (!func_match_inner(env, e, e1->type, implicit, specific)) break;
+      if (!func_match_inner(env, e, arg->type, implicit, specific)) break;
       e  = e->next;
-      e1 = e1->next;
     }
-    if (!e1) return func;
-//    if (!e && !e1) return func;
+    if (!e && args_len == i) return func;
   } while ((func = func->next));
   return NULL;
 }
@@ -584,13 +585,14 @@ ANN m_bool check_traverse_fdef(const Env env, const Func_Def fdef) {
   return ret;
 }
 
-ANN static m_bool check_func_args(const Env env, Arg_List arg_list) {
-  do {
-    const Var_Decl decl = arg_list->var_decl;
+ANN static m_bool check_func_args(const Env env, Arg_List args) {
+  for(uint32_t i = 0; i < args->len; i++) {
+    Arg *arg = mp_vector_at(args, Arg, i);
+    const Var_Decl decl = &arg->var_decl;
     const Value    v    = decl->value;
     CHECK_BB(already_defined(env, decl->xid, decl->pos));
     valid_value(env, decl->xid, v);
-  } while ((arg_list = arg_list->next));
+  }
   return GW_OK;
 }
 
@@ -600,7 +602,8 @@ ANN static m_bool check_func_args(const Env env, Arg_List arg_list) {
     if (next) gw_err(", ");                                                    \
     return next;                                                               \
   }
-next_arg(Exp) next_arg(Arg_List);
+next_arg(Exp)
+//next_arg(Arg_List);
 
 ANN static void print_current_args(Exp e) {
   gw_err(_("and not\n  "));
@@ -609,11 +612,14 @@ ANN static void print_current_args(Exp e) {
   gw_err("\n");
 }
 
-ANN static void print_arg(Arg_List e) {
-  do
-    gw_err("{G}%s{0} {/}%s{0}", e->type ? e->type->name : NULL,
-           e->var_decl->xid ? s_name(e->var_decl->xid) : "");
-  while ((e = next_arg_Arg_List(e)));
+ANN static void print_arg(Arg_List args) {
+  for(uint32_t i = 0; i < args->len; i++) {
+    Arg *arg = mp_vector_at(args, Arg, i);
+    gw_err("{G}%s{0} {/}%s{0}", arg->type ? arg->type->name : NULL,
+           arg->var_decl.xid ? s_name(arg->var_decl.xid) : "");
+    if(i < args->len - 1) gw_err(", ");
+  }
+//  while ((e = next_arg_Arg_List(e)));
 }
 
 ANN2(1)
@@ -640,13 +646,6 @@ static void function_alternative(const Env env, const Type f, const Exp args,
   env_set_error(env);
 }
 
-ANN static m_uint get_type_number(Specialized_List list) {
-  m_uint type_number = 0;
-  do ++type_number;
-  while ((list = list->next));
-  return type_number;
-}
-
 ANN static Func get_template_func(const Env env, Exp_Call *const func,
                                   const Value v) {
   const Func f = find_template_match(env, v, func);
@@ -699,32 +698,33 @@ ANN static Type check_predefined(const Env env, Exp_Call *exp, const Value v,
 ANN static Type_List check_template_args(const Env env, Exp_Call *exp,
                                          const Tmpl *tm, const Func_Def fdef) {
   m_uint       args_number = 0;
-  const m_uint type_number = get_type_number(tm->list);
-  Type_List    tl[type_number];
-  tl[0]                 = NULL;
-  Specialized_List list = tm->list;
-  while (list) {
-    Arg_List arg          = fdef->base->args;
+  const m_uint type_number = tm->list->len;
+  Type_List    tl = new_mp_vector(env->gwion->mp, sizeof(Type_Decl*), type_number);
+  Specialized_List sl = tm->list;
+  for(uint32_t i = 0; i < sl->len; i++) {
+    Specialized *spec = mp_vector_at(sl, Specialized, i);
+    Arg_List args          = fdef->base->args;
+    const uint32_t args_len = args ? args->len : 0;
     Exp      template_arg = exp->args;
-    while (arg && template_arg) {
-      if (list->xid == arg->td->xid) {
+    uint32_t count = 0;
+    while (count < args_len && template_arg) {
+      Arg *arg = mp_vector_at(args, Arg, count);
+      if (spec->xid == arg->td->xid) {
         if  (isa(template_arg->type, env->gwion->type[et_lambda]) > 0 &&
              !template_arg->type->info->func)
           break;
-        tl[args_number] =
-            mk_type_list(env, arg, template_arg->type, fdef->base->pos);
-        if (args_number) tl[args_number - 1]->next = tl[args_number];
+        mp_vector_set(tl, Type_Decl*, args_number,
+          mk_td(env, arg, template_arg->type, fdef->base->pos));
         ++args_number;
         break;
       }
-      arg          = arg->next;
+      count++;
       template_arg = template_arg->next;
     }
-    list = list->next;
   }
   if (args_number < type_number) // TODO: free type_list
     ERR_O(exp->func->pos, _("not able to guess types for template call."))
-  return tl[0];
+  return tl;
 }
 
 ANN static Type check_exp_call_template(const Env env, Exp_Call *exp) {
@@ -745,8 +745,20 @@ ANN static Type check_exp_call_template(const Env env, Exp_Call *exp) {
 ANN static Type check_lambda_call(const Env env, const Exp_Call *exp) {
   if (exp->args) CHECK_OO(check_exp(env, exp->args));
   Exp_Lambda *l   = &exp->func->d.exp_lambda;
-  Arg_List    arg = l->def->base->args;
+  Arg_List    args = l->def->base->args;
   Exp         e   = exp->args;
+  for(uint32_t i = 0; i < (args ? args->len : 0); i++) {
+    if(!e)
+      ERR_O(exp_self(exp)->pos, _("argument number does not match for lambda"))
+    Arg *arg = mp_vector_at(args, Arg, i);
+    arg->type = e->type;
+    if(is_class(env->gwion, arg->type))
+      type_addref(arg->type);
+    e = e->next;
+  }
+  if(e)
+     ERR_O(exp_self(exp)->pos, _("argument number does not match for lambda"))
+/*
   while (arg && e) {
     arg->type = e->type;
     if(is_class(env->gwion, arg->type))
@@ -756,6 +768,7 @@ ANN static Type check_lambda_call(const Env env, const Exp_Call *exp) {
   }
   if (arg || e)
     ERR_O(exp_self(exp)->pos, _("argument number does not match for lambda"))
+*/
   l->def->base->values = env->curr->info->value;
   const m_bool ret     = traverse_func_def(env, l->def);
   if (l->def->base->func) {
@@ -865,7 +878,7 @@ ANN static Type check_exp_binary(const Env env, const Exp_Binary *bin) {
   if (is_auto) {
     assert(bin->rhs->type == bin->lhs->type);
 //    bin->rhs->type = bin->lhs->type;
-    set_vflag(bin->rhs->d.exp_decl.list->self->value, vflag_assigned);
+    set_vflag((mp_vector_at(bin->rhs->d.exp_decl.list, struct Var_Decl_, 0))->value, vflag_assigned);
   }
   struct Op_Import opi = {.op   = bin->op,
                           .lhs  = bin->lhs->type,
@@ -876,7 +889,7 @@ ANN static Type check_exp_binary(const Env env, const Exp_Binary *bin) {
   exp_setuse(bin->rhs, 1);
   const Type ret = op_check(env, &opi);
   if (!ret && is_auto && exp_self(bin)->exp_type == ae_exp_binary)
-    bin->rhs->d.exp_decl.list->self->value->type = env->gwion->type[et_auto];
+    (mp_vector_at(bin->rhs->d.exp_decl.list, struct Var_Decl_, 0))->value->type = env->gwion->type[et_auto];
   return ret;
 }
 
@@ -1032,10 +1045,11 @@ const Func f = exp_self(call)->type->info->func;
 ANN m_bool check_type_def(const Env env, const Type_Def tdef) {
   if (tdef->when) {
     set_tflag(tdef->type, tflag_contract);
-    const Var_Decl decl = new_var_decl(env->gwion->mp, insert_symbol("self"),
-                                       NULL, tdef->when->pos);
-    const Arg_List args = new_arg_list(
-        env->gwion->mp, cpy_type_decl(env->gwion->mp, tdef->ext), decl, NULL);
+    struct Var_Decl_ decl = { .xid = insert_symbol("self"), .pos = tdef->when->pos };
+    Type_Decl *td = cpy_type_decl(env->gwion->mp, tdef->ext);
+    mp_vector_first(env->gwion->mp, args, Arg, ((Arg) { .td = td, .var_decl = decl }));
+//    const Arg_List args = new_arg_list(
+//        env->gwion->mp, cpy_type_decl(env->gwion->mp, tdef->ext), decl, NULL);
     Func_Base *fb = new_func_base(
         env->gwion->mp, type2td(env->gwion, tdef->type, tdef->pos),
         insert_symbol("@implicit"), args, ae_flag_none, tdef->pos);
@@ -1044,17 +1058,26 @@ ANN m_bool check_type_def(const Env env, const Type_Def tdef) {
                                    tdef->when->pos);
     const Exp when   = cpy_exp(env->gwion->mp, tdef->when);
     when->next       = helper;
-    const Stmt stmt =
-        new_stmt_exp(env->gwion->mp, ae_stmt_exp, when, when->pos);
-    const Stmt_List body =
-        new_stmt_list(env->gwion->mp, stmt, NULL); // ret_list);
+//    const Stmt stmt =
+//        new_stmt_exp(env->gwion->mp, ae_stmt_exp, when, when->pos);
+//    const Stmt_List body =
+//        new_stmt_list(env->gwion->mp, stmt, NULL); // ret_list);
+//  Stmt_List body;
+  mp_vector_first(env->gwion->mp, body, struct Stmt_,
+   ((struct Stmt_) {
+    .stmt_type = ae_stmt_exp, .d = { .stmt_exp = { .val = when }},
+    .pos = when->pos
+  }));
     const Stmt     code = new_stmt_code(env->gwion->mp, body, when->pos);
     const Func_Def fdef = new_func_def(env->gwion->mp, fb, code);
-    CHECK_BB(traverse_func_def(env, fdef));
-    const Exp predicate = stmt->d.stmt_exp.val;
-    if (isa(predicate->type, env->gwion->type[et_bool]) < 0) {
-      char explain[strlen(predicate->type->name) + 20];
-      sprintf(explain, "found `{/+}%s{0}`", predicate->type->name);
+    if(traverse_func_def(env, fdef) < 0) {
+      free_mp_vector(env->gwion->mp, sizeof(struct Stmt_), body);
+      return GW_ERROR;
+    }
+    if (isa(when->type, env->gwion->type[et_bool]) < 0) {
+      free_mp_vector(env->gwion->mp, sizeof(struct Stmt_), body);
+      char explain[strlen(when->type->name) + 20];
+      sprintf(explain, "found `{/+}%s{0}`", when->type->name);
       gwerr_basic("Invalid `{/+}when{0}` predicate expression type", explain,
                   "use `{/+}bool{0}`", env->name, when->pos, 0);
       char from[strlen(tdef->type->name) + 39];
@@ -1076,11 +1099,12 @@ ANN m_bool check_type_def(const Env env, const Type_Def tdef) {
     const Exp ret_id =
         new_prim_id(env->gwion->mp, insert_symbol("self"), when->pos);
     ret_id->d.prim.value = new_value(env->gwion->mp, tdef->type, "self");
-    const Stmt ret =
-        new_stmt_exp(env->gwion->mp, ae_stmt_return, ret_id, when->pos);
-    const Stmt_List ret_list = new_stmt_list(env->gwion->mp, ret, NULL);
+    struct Stmt_ ret = {
+      .stmt_type = ae_stmt_return, .d = { .stmt_exp = { .val = ret_id }},
+      .pos = when->pos
+    };
+    mp_vector_add(env->gwion->mp, &fdef->d.code->d.stmt_code.stmt_list, struct Stmt_, ret);
     ret_id->type             = tdef->type;
-    body->next               = ret_list;
     tdef->when_def           = fdef;
   }
   return (!is_fptr(env->gwion, tdef->type) && tdef->type->info->cdef)
@@ -1121,8 +1145,10 @@ ANN Type check_exp(const Env env, const Exp exp) {
 ANN m_bool check_enum_def(const Env env, const Enum_Def edef) {
   const m_uint scope = env_push_type(env, edef->t);
   ID_List list = edef->list;
-  do decl_static(env, nspc_lookup_value0(env->curr, list->xid));
-  while ((list = list->next));
+  for(uint32_t i = 0; i < list->len; i++) {
+    Symbol xid = *mp_vector_at(list, Symbol, i);
+    decl_static(env, nspc_lookup_value0(env->curr, xid));
+  }
   env_pop(env, scope);
   nspc_allocdata(env->gwion->mp, edef->t->nspc);
   return GW_OK;
@@ -1274,8 +1300,9 @@ ANN static m_bool check_stmt_return(const Env env, const Stmt_Exp stmt) {
     ERR_B(stmt->val->pos, _("Can't use type `{+G}%s{+G}` for return"),
           ret_type->name);
   if (stmt->val) {
+    Arg *arg = mp_vector_at(env->func->def->base->args, Arg, 0);
     if (env->func->def->base->xid == insert_symbol("@implicit") &&
-        ret_type == env->func->def->base->args->type)
+        ret_type == arg->type)
       ERR_B(stmt_self(stmt)->pos,
             _("can't use implicit casting while defining it"))
     if (check_implicit(env, stmt->val, env->func->def->base->ret_type) > 0)
@@ -1380,16 +1407,34 @@ ANN static m_bool check_stmt_case(const Env env, const Stmt_Match stmt) {
     RET_NSPC(_check_stmt_case(env, stmt))}
 
 ANN static m_bool case_loop(const Env env, const Stmt_Match stmt) {
-  Stmt_List list = stmt->list;
-  do CHECK_BB(check_stmt_case(env, &list->stmt->d.stmt_match));
-  while ((list = list->next));
+  for(m_uint i = 0; i < stmt->list->len; i++) {
+    const m_uint offset = i * sizeof(struct Stmt_);
+    const Stmt s = (Stmt)(stmt->list->ptr + offset);
+    CHECK_BB(check_stmt_case(env, &s->d.stmt_match));
+  }
   return GW_OK;
 }
 
+ANN static inline m_bool check_handler(const restrict Env env,
+                                            const Handler *handler) {
+  RET_NSPC(check_stmt(env, handler->stmt));
+}
+
 ANN static inline m_bool check_handler_list(const restrict Env env,
-                                            const Handler_List handler) {
-  if (handler->next) CHECK_BB(check_handler_list(env, handler->next));
-  RET_NSPC(check_stmt(env, handler->stmt))
+                                            const Handler_List handlers) {
+  for(uint32_t i = 0; i < handlers->len; i++) {
+    Handler *handler = mp_vector_at(handlers, Handler, i);
+    CHECK_BB(check_handler(env, handler));
+  }
+  return GW_OK;
+}
+
+ANN static inline bool find_handler(const Handler_List handlers, const Symbol xid) {
+  for(uint32_t i = 0; i < handlers->len; i++) {
+    Handler *handler = mp_vector_at(handlers, Handler, i);
+    if(xid == handler->xid) return true;
+  }
+  return false;
 }
 
 ANN static inline m_bool check_stmt_try_start(const restrict Env env,
@@ -1405,14 +1450,7 @@ ANN static inline m_bool check_stmt_try_start(const restrict Env env,
     for (m_uint i = 0; i < m_vector_size(v); i++) {
       struct ScopeEffect eff;
       m_vector_get(v, i, &eff);
-      Handler_List handler = stmt->handler;
-      bool         found   = false;
-      do { // check there is no duplicate handler
-        if (eff.sym == handler->xid) {
-          found = true;
-          break;
-        }
-      } while ((handler = handler->next));
+      bool         found   = find_handler(stmt->handler, eff.sym);
       if (!found) env_add_effect(env, eff.sym, eff.pos);
     }
     m_vector_release(v);
@@ -1469,8 +1507,11 @@ ANN m_bool check_stmt(const Env env, const Stmt stmt) {
 }
 
 ANN static m_bool check_stmt_list(const Env env, Stmt_List l) {
-  do CHECK_BB(check_stmt(env, l->stmt));
-  while ((l = l->next));
+  for(m_uint i = 0; i < l->len; i++) {
+    const m_uint offset = i * sizeof(struct Stmt_);
+    const Stmt s = (Stmt)(l->ptr + offset);
+    CHECK_BB(check_stmt(env, s));
+  }
   return GW_OK;
 }
 
@@ -1622,7 +1663,7 @@ ANN m_bool _check_func_def(const Env env, const Func_Def f) {
   if(fflag(func, fflag_valid))return GW_OK;
   set_fflag(func, fflag_valid);
   assert(func == fdef->base->func);
-  if (env->class_def)
+  if (env->class_def && !strstr(func->name, "lambda:"))
     CHECK_BB(check_parent_match(env, fdef));
   if (tmpl_base(fdef->base->tmpl)) return GW_OK;
   Value override = NULL;
@@ -1686,7 +1727,7 @@ ANN m_bool check_func_def(const Env env, const Func_Def fdef) {
 ANN static m_bool check_extend_def(const Env env, const Extend_Def xdef) {
   CHECK_BB(ensure_check(env, xdef->t));
   CHECK_BB(extend_push(env, xdef->t));
-  const m_bool ret = check_ast(env, xdef->body);
+  const m_bool ret = check_ast(env, &xdef->body);
   extend_pop(env, xdef->t);
   return ret;
 }
@@ -1694,29 +1735,36 @@ 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;
+//  while (ast) {
+//    Section *section = ast->section;
+  for(m_uint i = 0; i < ast->len; i++) {
+    const m_uint offset = i * sizeof(Section);
+    Section * section = (Section*)(ast->ptr + offset);
     if (section->section_type == ae_section_stmt) {
-      Stmt_List list = section->d.stmt_list;
-      while (list) {
-        const Stmt stmt = list->stmt;
+  Stmt_List l = section->d.stmt_list;
+  for(m_uint i = 0; i < l->len; i++) {
+    const m_uint offset = i * sizeof(struct Stmt_);
+    const Stmt stmt = (Stmt)(l->ptr + offset);
+//      Stmt_List list = section->d.stmt_list;
+//      while (list) {
+//        const Stmt stmt = list->stmt;
         if (stmt->stmt_type == ae_stmt_exp) {
           CHECK_BB(traverse_exp(env, stmt->d.stmt_exp.val));
           Var_Decl_List list = stmt->d.stmt_exp.val->d.exp_decl.list;
-          while (list) {
-            const Value value = list->self->value;
+          for(uint32_t i = 0; i < list->len; i++) {
+            Var_Decl vd = mp_vector_at(list, struct Var_Decl_, i);
+            const Value value = vd->value;
             valuefrom(env, value->from,
-                      list->self->pos); // we do not need owner
+                      vd->pos); // we do not need owner
             if (!trait->requested_values.ptr)
               vector_init(&trait->requested_values);
             vector_add(&trait->requested_values, (m_uint)value);
-            list = list->next;
           }
         }
-        list = list->next;
+//        list = list->next;
       }
     }
-    ast = ast->next;
+//    ast = ast->next;
   }
   return GW_OK;
 }
@@ -1753,7 +1801,7 @@ ANN m_bool check_abstract(const Env env, const Class_Def cdef) {
   bool err = false;
   for (m_uint i = 0; i < vector_size(&cdef->base.type->nspc->vtable); ++i) {
     const Func f = (Func)vector_at(&cdef->base.type->nspc->vtable, i);
-    if (f && f->def->base && GET_FLAG(f->def->base, abstract)) {
+   if (f && f->def->base && GET_FLAG(f->def->base, abstract)) {
       if (!err) {
         err = true;
         gwerr_basic(_("missing function definition"),
@@ -1791,32 +1839,37 @@ ANN static m_bool check_body(const Env env, Section *const section) {
 }
 
 ANN static bool class_def_has_body(const Env env, Ast ast) {
-  do {
-    const Section *section = ast->section;
+//  do {
+  for(m_uint i = 0; i < ast->len; i++) {
+    const m_uint offset = i * sizeof(Section);
+//    const Section *section = ast->section;
+    const Section *section = (Section*)(ast->ptr + offset);
     if (section->section_type == ae_section_stmt) {
-      Stmt_List list = section->d.stmt_list;
-      do {
-        const Stmt stmt = list->stmt;
+      Stmt_List l = section->d.stmt_list;
+      for(m_uint i = 0; i < l->len; i++) {
+        const m_uint offset = i * sizeof(struct Stmt_);
+        const Stmt stmt = (Stmt)(l->ptr + offset);
         if (stmt->stmt_type == ae_stmt_pp) continue;
         if (stmt->stmt_type == ae_stmt_exp) {
           const Exp exp = stmt->d.stmt_exp.val;
           if (!exp) continue;
           if (exp->exp_type != ae_exp_decl) return true;
           if (GET_FLAG(exp->d.exp_decl.td, late)) continue;
-          Var_Decl_List dlist = exp->d.exp_decl.list;
-          do {
-            if (GET_FLAG(dlist->self->value, late)) continue;
-            if (isa(dlist->self->value->type, env->gwion->type[et_compound]) >
+          Var_Decl_List list = exp->d.exp_decl.list;
+          for(uint32_t i = 0; i < list->len; i++) {
+            Var_Decl vd = mp_vector_at(list, struct Var_Decl_, i);
+            if (GET_FLAG(vd->value, late)) continue;
+            if (isa(vd->value->type, env->gwion->type[et_compound]) >
                 0)
-              //            if(tflag(dlist->self->value->type, tflag_ctor) ||
-              //                     dlist->self->value->type->array_depth)
+              //            if(tflag(vd->value->type, tflag_ctor) ||
+              //                     cd->value->type->array_depth)
               return true;
-          } while ((dlist = dlist->next));
+          }
         } else
           return true;
-      } while ((list = list->next));
+      } //while ((list = list->next));
     }
-  } while ((ast = ast->next));
+  } //while ((ast = ast->next));
   return false;
 }
 
@@ -1913,12 +1966,7 @@ ANN static m_bool _check_class_def(const Env env, const Class_Def cdef) {
   if (!GET_FLAG(cdef, abstract)) CHECK_BB(check_abstract(env, cdef));
   if (cdef->traits) {
     ID_List list        = cdef->traits;
-    bool    value_error = false;
-    do
-      if (!check_trait_requests(env, t, list)) value_error = true;
-    while ((list = list->next));
-
-    if (value_error) {
+    if (!check_trait_requests(env, t, list)) {
       env->class_def = t;
       env_error_footer(env);
       env_set_error(env);
@@ -1961,9 +2009,13 @@ ANN static inline void check_unhandled(const Env env) {
   vector_pop(v);
 }
 
-ANN m_bool check_ast(const Env env, Ast ast) {
-  do CHECK_BB(check_section(env, ast->section));
-  while ((ast = ast->next));
+ANN m_bool check_ast(const Env env, Ast *ast) {
+  Ast a = *ast;
+  for(m_uint i = 0; i < a->len; i++) {
+    const m_uint offset = i * sizeof(Section);
+    Section * section = (Section*)(a->ptr + offset);
+    CHECK_BB(check_section(env, section));
+  }
   check_unhandled(env);
   return GW_OK;
 }
index ce467006c0be3978801549b84316ecd6b718b56e..aba6c009a847a69521c440736be8017bc98680f5 100644 (file)
@@ -79,11 +79,12 @@ ANN static bool request_fun(const Env env, const Type t,
     const m_bool   ret   = traverse_func_def(env, cpy);
     env_pop(env, scope);
     if (ret > 0) {
-      Section * section = new_section_func_def(env->gwion->mp, cpy);
-      const Ast ast     = new_ast(env->gwion->mp, section, NULL);
-      Ast       last    = t->info->cdef->body;
-      while (last->next) last = last->next;
-      last->next = ast;
+      Section section = (Section) {
+        .section_type = ae_section_func,
+        .d = { .func_def = cpy }
+      };
+      // ensure body?
+      mp_vector_add(env->gwion->mp, &t->info->cdef->body, Section, section);
       return true;
     } else
       free_func_def(env->gwion->mp, cpy);
@@ -105,31 +106,44 @@ ANN static bool check_trait_functions(const Env env, const Type t,
   }
   return error;
 }
-
+/*
 ANN2(1, 2)
 static inline bool trait_nodup(Type t, const Symbol trait, ID_List list) {
   bool nodup = true;
   do {
-    while (list) {
-      if (trait == list->xid) nodup = false;
-      list = list->next;
+    for(uint32_t i = 0; i < list->len; i++) {
+      Symbol xid = *mp_vector_at(list, Symbol, i);
+      if (trait == xid) nodup = false;
     }
   } while ((t = t->info->parent));
   return nodup;
 }
+*/
+ANN bool trait_nodup(const ID_List list, const uint32_t i) {
+  Symbol fst = *mp_vector_at(list, Symbol, i);
+  for(uint32_t j = i; j < list->len; j++) {
+    Symbol snd = *mp_vector_at(list, Symbol, j);
+    if (fst == snd) return false;
+  }
+  return true;
+}
 
 ANN bool check_trait_requests(const Env env, const Type t, const ID_List list) {
-  const Trait trait = nspc_lookup_trait1(env->curr, list->xid);
-  if (!trait_nodup(t, list->xid, list->next)) {
-    gwerr_secondary("duplicated trait", trait->filename, trait->loc);
+  for(uint32_t i = 0; i < list->len; i++) {
+    Symbol xid = *mp_vector_at(list, Symbol, i);
+    const Trait trait = nspc_lookup_trait1(env->curr, xid);
+    if (!trait_nodup(list, i)) {
+      gwerr_secondary("duplicated trait", trait->filename, trait->loc);
+      env_set_error(env);
+      return false;
+    }
+    const bool value_error = trait->requested_values.ptr  ? check_trait_variables(env, t, trait) : false;
+    const bool funcs_error = trait->requested_funcs.ptr ? check_trait_functions(env, t, trait) : false;
+    if (!value_error && !funcs_error) continue;
+    const Value request = (Value)vector_front(&trait->requested_values);
+    gwerr_secondary("from trait", request->from->filename, trait->loc);
     env_set_error(env);
     return false;
   }
-  const bool value_error = trait->requested_values.ptr  ? check_trait_variables(env, t, trait) : false;
-  const bool funcs_error = trait->requested_funcs.ptr ? check_trait_functions(env, t, trait) : false;
-  if (!value_error && !funcs_error) return true;
-  const Value request = (Value)vector_front(&trait->requested_values);
-  gwerr_secondary("from trait", request->from->filename, trait->loc);
-  env_set_error(env);
-  return false;
+  return true;
 }
index 03d956ad057df2f42a296bbdb398d1f30ed6dfc3..6b59d49c915980332c572d9b2b1a670a816ed088 100644 (file)
@@ -4,14 +4,18 @@
 
 ANN m_bool compat_func(const restrict Func_Def lhs,
                        const restrict Func_Def rhs) {
-  Arg_List e1 = lhs->base->args;
-  Arg_List e2 = rhs->base->args;
-
-  while (e1 && e2) {
-    if (e1->type != e2->type) return GW_ERROR;
-    e1 = e1->next;
-    e2 = e2->next;
+  Arg_List args0 = lhs->base->args;
+  Arg_List args1 = rhs->base->args;
+  if(!args0 && !args1)
+    return GW_OK;
+  if((!args0 && args1) || (args0 && !args1))
+    return GW_ERROR;
+  if(args0->len != args1->len)
+    return GW_ERROR;
+  for(uint32_t i = 0; i < args0->len; i++) {
+    Arg *arg0 = mp_vector_at(args0, Arg, i);
+    Arg *arg1 = mp_vector_at(args1, Arg, i);
+    if (arg0->type != arg1->type) return GW_ERROR;
   }
-  if (e1 || e2) return GW_ERROR;
   return GW_OK;
 }
index 4020f08c09ad64bf57365d019a852b02c0a9b940..a9984d9bff2ac4c5d54f33c308914d42b67c89a9 100644 (file)
@@ -14,11 +14,13 @@ ANN void func_operator(const Func_Def fdef, struct Op_Import *opi) {
       fbflag(fdef->base, fbflag_unary) +
       (!strcmp(str, "@conditional") || !strcmp(str, "@unconditional"));
   const Arg_List args = fdef->base->args;
-  opi->lhs = is_unary ? NULL : args ? args->var_decl->value->type : NULL;
+  Arg *arg0 = args ? mp_vector_at(args, Arg, 0) : NULL;
+  Arg *arg1 = (args && args->len >= 2) ? mp_vector_at(args, Arg, 1) : NULL;
+  opi->lhs = is_unary ? NULL : args ? arg0->var_decl.value->type : NULL;
   if (strcmp(str, "@implicit"))
-    opi->rhs = args ? is_unary ? args->var_decl->value->type
-                               : (args->next ? args->next->var_decl->value->type
-                                             : NULL)
+//    opi->rhs = args ? is_unary ? arg0->var_decl->value->type
+    opi->rhs = args ? is_unary ? (arg0 ? arg0->var_decl.value->type : NULL)
+                               : (arg1 ? arg1->var_decl.value->type : NULL)
                     : NULL;
   else
     opi->rhs = fdef->base->ret_type;
index 0ffbbad5b86f78ca89f3c873827256b92dd6c37e..4bc8c8a8140d51074587080d307b8dbf49f9d3a3 100644 (file)
@@ -35,6 +35,7 @@ tmpl_valid(const Env env, const Func_Def fdef /*, Exp_Call *const exp*/) {
   //  CHECK_BO(template_push_types(env, &tmpl));;
   const bool ret = check_traverse_fdef(env, fdef) > 0;
   //  nspc_pop_type(env->gwion->mp, env->curr);
+  if(!ret)free_func_def(env->gwion->mp, fdef);
   return ret;
 }
 
@@ -105,7 +106,6 @@ ANN static Func create_tmpl(const Env env, struct ResolverArgs *ra,
   fdef->base->tmpl->call = cpy_type_list(env->gwion->mp, ra->types);
   fdef->base->tmpl->base = i;
   const Func func        = ensure_tmpl(env, fdef, ra->e);
-  if (!func && !fdef->base->func) free_func_def(env->gwion->mp, fdef);
   if (func && vflag(ra->v, vflag_builtin)) {
     builtin_func(env->gwion->mp, func, (void*)ra->v->d.func_ref->code->native_func);
     set_vflag(func->value_ref, vflag_builtin);
@@ -165,10 +165,13 @@ ANN static Func _find_template_match(const Env env, const Value v,
   DECL_OO(const Func, f, = __find_template_match(env, v, exp));
   Type_List        tl = exp->tmpl->call;
   Specialized_List sl = f->def->base->tmpl->list;
-  while (tl) {
-    DECL_OO(const Type, t, = known_type(env, tl->td));
-    if (miss_traits(t, sl)) return NULL;
-    tl = tl->next;
+  for(uint32_t i = 0; i < tl->len; i++) {
+    Type_Decl *td = *mp_vector_at(tl, Type_Decl*, i);
+    DECL_OO(const Type, t, = known_type(env, td));
+    if(t->info->traits) {
+      Specialized * spec = mp_vector_at(sl, Specialized, i);
+      if (miss_traits(t, spec)) return NULL;
+    }
   }
   return f;
 }
index 8186a23a170f84d99584aac14948f84ddf2d34cf..ec73bd33df7f0a4c2111a1507f45aa8b4f078a10 100644 (file)
@@ -186,7 +186,7 @@ ANN static Type op_check_inner(const Env env, struct OpChecker *ock,
   } while (r && (r = op_parent(env, r)));
   return NULL;
 }
-
+/*
 //! check if type matches for template operator
 ANN bool _tmpl_match(const Env env, const Type t, Type_Decl *const td,
                      Specialized_List *slp) {
@@ -198,48 +198,55 @@ ANN bool _tmpl_match(const Env env, const Type t, Type_Decl *const td,
   const Type base = known_type(env, td);
   return base ? isa(t, base) > 0 : false;
 }
+*/
+//! check if type matches for template operator
+ANN2(1,2,3) bool _tmpl_match(const Env env, const Type t, Type_Decl *const td,
+                     Specialized *spec, uint32_t *idx) {
+  if (spec && !td->next && !td->types && td->xid == spec->xid) {
+    (*idx)++;
+    return true;
+  }
+  const Type base = known_type(env, td);
+  return base ? isa(t, base) > 0 : false;
+}
 
 //! check Func_Base matches for template operator
-// usage of `is_class` is supicious rn
 ANN bool tmpl_match(const Env env, const struct Op_Import *opi,
                     Func_Base *const base) {
   Specialized_List sl  = base->tmpl->list;
-  const Arg_List   arg = base->args;
+  const Arg_List   args = base->args;
+  Arg *arg0 = mp_vector_at(args, Arg, 0);
+  Arg *arg1 = mp_vector_at(args, Arg, 1);
+  uint32_t idx = 0;
   if (opi->lhs) {
-    if (!_tmpl_match(env, opi->lhs, arg->td, &sl)) return false;
+    if (!_tmpl_match(env, opi->lhs, arg0->td, mp_vector_at(sl, Specialized, idx), &idx)) return false;
     if (fbflag(base, fbflag_postfix)) return !!opi->rhs;
     if (!fbflag(base, fbflag_unary)) {
       if (!opi->rhs) return false;
-      if (!_tmpl_match(env, opi->rhs, arg->next->td, &sl)) return false;
+      if (!_tmpl_match(env, opi->rhs, arg1->td, mp_vector_at(sl, Specialized, idx), &idx)) return false;
     } else if (opi->rhs)
       return false;
   } else {
     if (!fbflag(base, fbflag_unary) ||
-        !_tmpl_match(env, opi->rhs, arg->td, &sl))
+        !_tmpl_match(env, opi->rhs, arg0->td, mp_vector_at(sl, Specialized, idx), &idx))
       return false;
   }
   return true;
 }
 
-//! make template operator Type_List
-ANN2(1, 2)
-static Type_List op_type_list(const Env env, const Type t, const Type_List next,
-                              const loc_t loc) {
-  Type_Decl *const td0 = type2td(env->gwion, t, loc);
-  return new_type_list(env->gwion->mp, td0, next);
-}
-
 //! make template operator Func_def
 ANN Type op_def(const Env env, struct Op_Import *const opi,
                 const Func_Def fdef) {
   const Func_Def tmpl_fdef    = cpy_func_def(env->gwion->mp, fdef);
   tmpl_fdef->base->tmpl->base = 0;
+  tmpl_fdef->base->tmpl->call = new_mp_vector(env->gwion->mp,
+    sizeof(Type_Decl*), !!opi->lhs + !!opi->rhs);
   if (opi->lhs) {
-    Type_List next =
-        opi->rhs ? op_type_list(env, opi->rhs, NULL, opi->pos) : NULL;
-    tmpl_fdef->base->tmpl->call = op_type_list(env, opi->lhs, next, opi->pos);
+     mp_vector_set(tmpl_fdef->base->tmpl->call, Type_Decl*, 0, type2td(env->gwion, opi->lhs, opi->pos));
+     if(opi->rhs)
+       mp_vector_set(tmpl_fdef->base->tmpl->call, Type_Decl*, 1, type2td(env->gwion, opi->rhs, opi->pos));
   } else
-    tmpl_fdef->base->tmpl->call = op_type_list(env, opi->rhs, NULL, opi->pos);
+     mp_vector_set(tmpl_fdef->base->tmpl->call, Type_Decl*, 0, type2td(env->gwion, opi->rhs, opi->pos));
   if (traverse_func_def(env, tmpl_fdef) < 0) {
     if (!tmpl_fdef->base->func) func_def_cleaner(env->gwion, tmpl_fdef);
     return NULL;
index 06e7aa2d0eff2abb08fa0fcac3a16294ae88a0b6..c2d07e5f676363c7c624071c8b6e94e7d13de06e 100644 (file)
@@ -285,8 +285,8 @@ ANN m_bool scan0_union_def(const Env env, const Union_Def udef) {
   CHECK_BB(scan0_defined(env, udef->xid, udef->pos));
   udef->type   = union_type(env, udef->xid, udef->pos);
   Union_List l = udef->l;
-  do udef->type->nspc->offset += SZ_INT;
-  while ((l = l->next));
+//  do udef->type->nspc->offset += SZ_INT;
+//  while ((l = l->next));
   udef->type->nspc->offset += SZ_INT;
   SET_ACCESS(udef, udef->type);
   if (udef->tmpl) union_tmpl(env, udef);
@@ -335,14 +335,15 @@ ANN static Type cdef_parent(const Env env, const Class_Def cdef) {
 }
 
 ANN static m_bool find_traits(const Env env, ID_List traits, const loc_t pos) {
-  do {
-    if (!nspc_lookup_trait1(env->curr, traits->xid)) {
+  for(uint32_t i = 0; i < traits->len; i++) {
+    Symbol xid = *mp_vector_at(traits, Symbol, i);
+    if (!nspc_lookup_trait1(env->curr, xid)) {
       gwerr_basic(_("can't find trait"), NULL, NULL, env->name, pos, 0);
-      did_you_mean_trait(env->curr, s_name(traits->xid));
+      did_you_mean_trait(env->curr, s_name(xid));
       env_set_error(env);
       return GW_ERROR;
     }
-  } while ((traits = traits->next));
+  }
   return GW_OK;
 }
 
@@ -361,77 +362,73 @@ ANN static Type scan0_class_def_init(const Env env, const Class_Def cdef) {
   t->nspc->parent = env->curr;
   t->info->cdef   = cdef;
   t->flag |= cdef->flag;
-  //  add_type(env, t->info->value->from->owner, t);
+  //add_type(env, t->info->value->from->owner, t);
   cdef_flag(cdef, t);
   return t;
 }
 
-ANN static m_bool scan0_stmt_list(const Env env, Stmt_List list) {
-  do
-    if (list->stmt->stmt_type == ae_stmt_pp) {
-      if (list->stmt->d.stmt_pp.pp_type == ae_pp_include)
-        env->name = list->stmt->d.stmt_pp.data;
-      else if (list->stmt->d.stmt_pp.pp_type == ae_pp_import)
-        CHECK_BB(plugin_ini(env->gwion, list->stmt->d.stmt_pp.data));
+ANN static m_bool scan0_stmt_list(const Env env, Stmt_List l) {
+  for(m_uint i = 0; i < l->len; i++) {
+    const m_uint offset = i * sizeof(struct Stmt_);
+    const Stmt stmt = (Stmt)(l->ptr + offset);
+    if (stmt->stmt_type == ae_stmt_pp) {
+      if (stmt->d.stmt_pp.pp_type == ae_pp_include)
+        env->name = stmt->d.stmt_pp.data;
+      else if (stmt->d.stmt_pp.pp_type == ae_pp_import)
+        CHECK_BB(plugin_ini(env->gwion, stmt->d.stmt_pp.data, stmt->pos));
     }
-  while ((list = list->next));
+  }
   return GW_OK;
 }
 
-//#define scan0_func_def dummy_func
-
-ANN static m_bool fdef_defaults(const Func_Def fdef) {
-  Arg_List list = fdef->base->args;
-  while (list) {
-    if (list->exp) return true;
-    list = list->next;
+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;
   }
-  return false;
-}
-
-ANN static Exp arglist2exp(MemPool p, Arg_List arg, const Exp default_arg) {
-  Exp exp = new_prim_id(p, arg->var_decl->xid, arg->var_decl->pos);
-  if (arg->next)
-    exp->next = arglist2exp(p, arg->next, default_arg);
-  else
-    exp->next = cpy_exp(p, default_arg);
-  return exp;
-}
-
-ANN2(1,2) static Ast scan0_func_def_default(const MemPool p, const Ast ast,
-                                            const Ast next) {
-  const Func_Def base_fdef = ast->section->d.func_def;
-  Arg_List       base_arg = base_fdef->base->args, former = NULL;
-  while (base_arg) {
-    if (!base_arg->next && base_arg->exp) {
-      if (former) former->next = NULL;
-      // use cpy_func_base?
-      Func_Base *base = new_func_base(
-          p, base_fdef->base->td ? cpy_type_decl(p, base_fdef->base->td) : NULL, base_fdef->base->xid,
-          former ? cpy_arg_list(p, base_fdef->base->args) : NULL,
-          base_fdef->base->flag, base_fdef->base->pos);
-      const Exp efunc =
-          new_prim_id(p, base_fdef->base->xid, base_fdef->base->pos);
-      Exp        arg_exp = former
-                               ? arglist2exp(p, base_fdef->base->args, base_arg->exp)
-                               : cpy_exp(p, base_arg->exp);
-      const Exp  ecall = new_exp_call(p, efunc, arg_exp, base_fdef->base->pos);
-      const Stmt code =
-          new_stmt_exp(p, ae_stmt_return, ecall, base_fdef->base->pos);
-      const Stmt_List slist = new_stmt_list(p, code, NULL);
-      const Stmt      body  = new_stmt_code(p, slist, base_fdef->base->pos);
-      const Func_Def  fdef  = new_func_def(p, base, body);
-      Section *       new_section = new_section_func_def(p, fdef);
-      if (former) former->next = base_arg;
-      const Ast tmp_ast = new_ast(p, new_section, NULL);
-      ast->next         = scan0_func_def_default(p, tmp_ast, next);
-      return ast;
-    }
-    former   = base_arg;
-    base_arg = base_arg->next;
+  // 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);
+    mp_vector_first(p, slist, struct Stmt_,
+      ((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);
   }
-  ast->next = next;
-  return ast;
+  args->len = len;
 }
 
 #define scan0_func_def dummy_func
@@ -443,12 +440,14 @@ ANN static m_bool scan0_extend_def(const Env env, const Extend_Def xdef) {
   if (GET_FLAG(t, final)) // TODO: add type initial declaration
     ERR_B(xdef->td->pos, _("can't extend final type"))
   Ast ast = xdef->body;
-  do {
-    if (ast->section->section_type == ae_section_func &&
-        GET_FLAG(ast->section->d.func_def->base, abstract))
-      ERR_B(ast->section->d.func_def->base->pos,
+  for(m_uint i = 0; i < ast->len; i++) {
+    const m_uint offset = i * sizeof(Section);
+    Section * section = (Section*)(ast->ptr + offset);
+    if (section->section_type == ae_section_func &&
+        GET_FLAG(section->d.func_def->base, abstract))
+      ERR_B(section->d.func_def->base->pos,
             _("can't use {/+}abstract{0} functions in {+/}extends{0}"))
-  } while ((ast = ast->next));
+  }
   xdef->t = t;
   return GW_OK;
 }
@@ -460,14 +459,15 @@ ANN static m_bool _scan0_trait_def(const Env env, const Trait_Def pdef) {
   trait->filename   = env->name;
   nspc_add_trait(env->curr, pdef->xid, trait);
   Ast ast = pdef->body;
-  while (ast) {
-    Section *section = ast->section;
+  if(!ast) return GW_OK; // ???
+  for(m_uint i = 0; i < ast->len; i++) {
+    const m_uint offset = i * sizeof(Section);
+    Section *section = (Section*)(ast->ptr + offset);
     if (section->section_type == ae_section_func) {
       const Func_Def fdef = section->d.func_def;
       if (!trait->requested_funcs.ptr) vector_init(&trait->requested_funcs);
       vector_add(&trait->requested_funcs, (m_uint)fdef);
     }
-    ast = ast->next;
   }
   return GW_OK;
 }
@@ -525,15 +525,26 @@ ANN m_bool scan0_class_def(const Env env, const Class_Def c) {
   return ret;
 }
 
-ANN m_bool scan0_ast(const Env env, Ast ast) {
-  Ast next;
-  do {
-    next = ast->next;
-    CHECK_BB(scan0_section(env, ast->section));
-    if (ast->section->section_type != ae_section_func ||
-        !fdef_defaults(ast->section->d.func_def))
+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++) {
+    const m_uint offset = i * sizeof(Section);
+    Section * section = (Section*)(a->ptr + offset);
+    CHECK_BB(scan0_section(env, section));
+
+    if (section->section_type != ae_section_func ||
+        !fbflag(section->d.func_def->base, fbflag_default))
       continue;
-    (void)scan0_func_def_default(env->gwion->mp, ast, ast->next);
-  } while ((ast = next));
+    scan0_func_def_default(env->gwion->mp, section, &acc);
+
+  }
+
+  for(m_uint i = 0; i < acc->len; i++) {
+    Section *section = (Section*)(acc->ptr + i * sizeof(Section));
+    mp_vector_add(env->gwion->mp, ast, Section, *section);
+  }
+  free_mp_vector(env->gwion->mp, sizeof(Section), acc);
+
   return GW_OK;
 }
index 88989cca688b34225c5903118686e1e289a9f188..c9609aa02d84a7f289f038d0f1ede4f025944022 100644 (file)
@@ -101,34 +101,33 @@ static inline bool array_ref2(const Array_Sub array) {
 }
 
 ANN static m_bool scan1_decl(const Env env, const Exp_Decl *decl) {
-  Var_Decl_List list     = decl->list;
   const bool    decl_ref = array_ref(decl->td->array);
-  do {
-    const Var_Decl var = list->self;
-    CHECK_BB(isres(env, var->xid, exp_self(decl)->pos));
+  Var_Decl_List list     = decl->list;
+  for(uint32_t i = 0; i < list->len; i++) {
+    const Var_Decl vd = mp_vector_at(list, struct Var_Decl_, i);
+    CHECK_BB(isres(env, vd->xid, exp_self(decl)->pos));
     Type t = decl->type;
-    CHECK_BB(scan1_defined(env, var));
-    if (var->array) {
-      if (var->array->exp) CHECK_BB(scan1_exp(env, var->array->exp));
-      CHECK_OB((t = array_type(env, decl->type, var->array->depth)));
+    CHECK_BB(scan1_defined(env, vd));
+    if (vd->array) {
+      if (vd->array->exp) CHECK_BB(scan1_exp(env, vd->array->exp));
+      CHECK_OB((t = array_type(env, decl->type, vd->array->depth)));
     }
     const Type base = array_base_simple(t);
-
     if ((!GET_FLAG(decl->td, late) && GET_FLAG(base, abstract)) &&
-        (array_ref2(var->array) ||
+        (array_ref2(vd->array) ||
         array_ref2(decl->td->array)))
-      ERR_B(var->pos, _("arrays of abstract type '%s' must be declared empty"),
+      ERR_B(vd->pos, _("arrays of abstract type '%s' must be declared empty"),
             base->name);
 
-    const Value v = var->value =
-        var->value ?: new_value(env->gwion->mp, t, s_name(var->xid));
-    nspc_add_value(env->curr, var->xid, v);
+    const Value v = vd->value =
+        vd->value ?: new_value(env->gwion->mp, t, s_name(vd->xid));
+    nspc_add_value(env->curr, vd->xid, v);
     if (GET_FLAG(t, abstract) && !GET_FLAG(decl->td, late)) SET_FLAG(v, late);
     v->type = t;
-    if (decl_ref || array_ref(var->array)) SET_FLAG(v, late);
+    if (decl_ref || array_ref(vd->array)) SET_FLAG(v, late);
     v->flag |= decl->td->flag;
     if (!env->scope->depth) {
-      valuefrom(env, v->from, var->pos);
+      valuefrom(env, v->from, vd->pos);
       if (env->class_def) {
         if (env->class_def->info->tuple) tuple_contains(env, v);
         if (!GET_FLAG(decl->td, static)) {
@@ -144,12 +143,13 @@ ANN static m_bool scan1_decl(const Env env, const Exp_Decl *decl) {
         set_vflag(v, vflag_fglobal); // file global
     } else if (GET_FLAG(decl->td, global))
       SET_FLAG(v, global);
-    else if(v->type != env->gwion->type[et_auto] && (v->type != env->class_def || env->scope->depth)) {
+//    else if(v->type != env->gwion->type[et_auto] && (v->type != env->class_def || env->scope->depth)) {
+    else if(v->type != env->gwion->type[et_auto] && (v->type != env->class_def)) {
       type_addref(v->type);
       set_vflag(v, vflag_inner); // file global
     }
-  } while ((list = list->next));
-  ((Exp_Decl *)decl)->type = decl->list->self->value->type;
+  }
+  ((Exp_Decl *)decl)->type = (mp_vector_at(decl->list, struct Var_Decl_, 0))->value->type;
   return GW_OK;
 }
 
@@ -296,9 +296,12 @@ ANN static inline m_bool scan1_stmt_match_case(const restrict Env env,
 ANN static inline m_bool
     _scan1_stmt_match(const restrict Env env, const Stmt_Match stmt) {
   if (stmt->where) CHECK_BB(scan1_stmt(env, stmt->where));
-  Stmt_List list = stmt->list;
-  do CHECK_BB(scan1_stmt_match_case(env, &list->stmt->d.stmt_match));
-  while ((list = list->next));
+  Stmt_List l = stmt->list;
+  for(m_uint i = 0; i < l->len; i++) {
+    const m_uint offset = i * sizeof(struct Stmt_);
+    const Stmt s = (Stmt)(l->ptr + offset);
+    CHECK_BB(scan1_stmt_match_case(env, &s->d.stmt_match));
+  }
   return GW_OK;
 }
 
@@ -308,10 +311,18 @@ ANN static inline m_bool scan1_stmt_match(const restrict Env env,
   RET_NSPC(_scan1_stmt_match(env, stmt))
 }
 
+ANN static inline m_bool scan1_handler(const restrict Env env,
+                                            const Handler *handler) {
+  RET_NSPC(scan1_stmt(env, handler->stmt));
+}
+
 ANN static inline m_bool scan1_handler_list(const restrict Env env,
-                                            const Handler_List handler) {
-  if (handler->next) CHECK_BB(scan1_handler_list(env, handler->next));
-  RET_NSPC(scan1_stmt(env, handler->stmt))
+                                            const Handler_List handlers) {
+  for(uint32_t i = 0; i < handlers->len; i++) {
+    Handler * handler = mp_vector_at(handlers, Handler, i);
+    CHECK_BB(scan1_handler(env, handler));
+  }
+  return GW_OK;
 }
 
 ANN static inline m_bool scan1_stmt_try(const restrict Env env,
@@ -391,8 +402,9 @@ ANN m_bool scan1_enum_def(const Env env, const Enum_Def edef) {
   const Nspc nspc = edef->t->nspc;
   const m_uint scope = env_push_type(env, edef->t);
   ID_List list = edef->list;
-  do {
-    const Value v = new_value(env->gwion->mp, edef->t, s_name(list->xid));
+  for(uint32_t i = 0; i < list->len; i++) {
+    Symbol xid = *mp_vector_at(list, Symbol, i);
+    const Value v = new_value(env->gwion->mp, edef->t, s_name(xid));
     valuefrom(env, v->from, edef->pos);
     if (env->class_def) {
       SET_FLAG(v, static);
@@ -402,38 +414,39 @@ ANN m_bool scan1_enum_def(const Env env, const Enum_Def edef) {
       set_vflag(v, vflag_builtin);
     SET_FLAG(v, const);
     set_vflag(v, vflag_valid);
-    nspc_add_value(nspc, list->xid, v);
+    nspc_add_value(nspc, xid, v);
     vector_add(&edef->values, (vtype)v);
-  } while ((list = list->next));
+  }
   env_pop(env, scope);
   return GW_OK;
 }
 
-ANN static Value arg_value(const Env env, const Arg_List list) {
-  const Var_Decl var = list->var_decl;
-  const Value    v   = new_value(env->gwion->mp, list->type,
-                            var->xid ? s_name(var->xid) : (m_str) __func__);
-  if (var->array)
-    v->type = list->type = array_type(env, list->type, var->array->depth);
-  if (list->td) {
-    v->flag = list->td->flag;
+ANN static Value arg_value(const Env env, Arg *const arg) {
+  const Var_Decl vd = &arg->var_decl;
+  const Value    v   = new_value(env->gwion->mp, arg->type,
+                            vd->xid ? s_name(vd->xid) : (m_str) __func__);
+  if (vd->array)
+    v->type = arg->type = array_type(env, arg->type, vd->array->depth);
+  if (arg->td) {
+    v->flag = arg->td->flag;
     //    SET_FLAG(v, global); ???
   }
   return v;
 }
 
-ANN static m_bool scan1_args(const Env env, Arg_List list) {
-  do {
-    const Var_Decl var = list->var_decl;
-    if (var->xid) CHECK_BB(isres(env, var->xid, var->pos));
-    if (list->td) {
-      SET_FLAG(list->td, late);
-      CHECK_OB((list->type = void_type(env, list->td)));
-      UNSET_FLAG(list->td, late);
+ANN static m_bool scan1_args(const Env env, Arg_List args) {
+  for(uint32_t i = 0; i < args->len; i++) {
+    Arg *arg = mp_vector_at(args, Arg, i);
+    const Var_Decl vd = &arg->var_decl;
+    if (vd->xid) CHECK_BB(isres(env, vd->xid, vd->pos));
+    if (arg->td) {
+      SET_FLAG(arg->td, late);
+      CHECK_OB((arg->type = void_type(env, arg->td)));
+      UNSET_FLAG(arg->td, late);
     }
-    var->value = arg_value(env, list);
-    if (var->xid) nspc_add_value(env->curr, var->xid, var->value);
-  } while ((list = list->next));
+    vd->value = arg_value(env, arg);
+    if (vd->xid) nspc_add_value(env->curr, vd->xid, vd->value);
+  }
   return GW_OK;
 }
 
@@ -445,14 +458,18 @@ ANN static Type scan1_noret(const Env env, const Func_Base *base) {
 }
 
 ANN static m_bool _scan1_fbase_tmpl(const Env env, Func_Base *base) {
-  Specialized_List id = base->tmpl->list;
-  do nspc_add_type(env->curr, id->xid, env->gwion->type[et_auto]);
-  while ((id = id->next));
+  Specialized_List sl = base->tmpl->list;
+  for(uint32_t i = 0; i < sl->len; i++) {
+    Specialized *spec = mp_vector_at(sl, Specialized, i);
+    nspc_add_type(env->curr, spec->xid, env->gwion->type[et_auto]);
+  }
   CHECK_OB((base->ret_type = scan1_noret(env, base)));
   if (base->args) {
-    Arg_List arg = base->args;
-    do CHECK_OB(known_type(env, arg->td));
-    while ((arg = arg->next));
+    Arg_List args = base->args;
+    for(uint32_t i = 0; i < args->len; i++) {
+      Arg *arg = mp_vector_at(args, Arg, i);
+      CHECK_OB(known_type(env, arg->td));
+    }
   }
   return GW_OK;
 }
@@ -467,12 +484,15 @@ ANN static m_bool scan1_fbase_tmpl(const Env env, Func_Base *const base) {
 ANN static m_bool scan1_fdef_base_tmpl(const Env env, const Func_Def fdef) {
   Func_Base *const base = fdef->base;
   if (!fbflag(base, fbflag_op)) return scan1_fbase_tmpl(env, base);
-  Arg_List         arg = fdef->base->args;
-  Specialized_List sl  = fdef->base->tmpl->list;
-  do {
-    if (!arg->td->next && sl && arg->td->xid == sl->xid) { sl = sl->next; }
-  } while ((arg = arg->next));
-  if (sl) ERR_B(base->pos, "too many template types for operator");
+  Arg_List         args = fdef->base->args;
+  Specialized_List sl   = fdef->base->tmpl->list;
+  uint32_t j = 0;
+  for(uint32_t i = 0; i < args->len; i++) {
+    Arg *arg = mp_vector_at(args, Arg, i);
+    Specialized *spec = mp_vector_at(sl, Specialized, j);
+    if (!arg->td->next && spec && arg->td->xid == spec->xid) { j++; }
+  }
+  if (j < sl->len) ERR_B(base->pos, "too many template types for operator");
   const Vector v = &env->curr->info->op_tmpl;
   if (!v->ptr) vector_init(v);
   vector_add(v, (m_uint)cpy_func_def(env->gwion->mp, fdef));
@@ -508,19 +528,17 @@ ANN static inline m_bool scan1_union_def_inner_loop(const Env env,
   const Value v = new_value(env->gwion->mp, env->gwion->type[et_int], "@index");
   nspc_add_value_front(env->curr, insert_symbol("@index"), v);
   valuefrom(env, v->from, udef->pos);
-  do {
-    DECL_OB(const Type, t, = known_type(env, l->td));
-    if (nspc_lookup_value0(env->curr, l->xid))
-      ERR_B(l->pos, _("'%s' already declared in union"), s_name(l->xid))
-    const Value v = new_value(env->gwion->mp, t, s_name(l->xid));
-//    if (!tflag(t, tflag_scan1)) // ???
-      tuple_contains(env, v);   // ???
-//    v->from->offset = SZ_INT;
-    v->from->offset = v->type->size;
+  for(uint32_t i = 0; i < l->len; i++) {
+    Union_Member *um = mp_vector_at(l, Union_Member, i);
+    DECL_OB(const Type, t, = known_type(env, um->td));
+    if (nspc_lookup_value0(env->curr, um->vd.xid))
+      ERR_B(um->vd.pos, _("'%s' already declared in union"), s_name(um->vd.xid))
+    const Value v = new_value(env->gwion->mp, t, s_name(um->vd.xid));
+    tuple_contains(env, v);
     valuefrom(env, v->from, udef->pos);
-    nspc_add_value_front(env->curr, l->xid, v);
+    nspc_add_value_front(env->curr, um->vd.xid, v);
     if (t->size > sz) sz = t->size;
-  } while ((l = l->next));
+  }
   udef->type->nspc->offset = SZ_INT + sz;
   return GW_OK;
 }
@@ -565,6 +583,12 @@ ANN static inline m_bool scan1_stmt(const Env env, const Stmt stmt) {
 }
 
 ANN static m_bool scan1_stmt_list(const Env env, Stmt_List l) {
+  for(m_uint i = 0; i < l->len; i++) {
+    const m_uint offset = i * sizeof(struct Stmt_);
+    const Stmt s = (Stmt)(l->ptr + offset);
+    CHECK_BB(scan1_stmt(env, s));
+  }
+/*
   do {
     CHECK_BB(scan1_stmt(env, l->stmt));
     if (l->next) {
@@ -583,6 +607,7 @@ ANN static m_bool scan1_stmt_list(const Env env, Stmt_List l) {
       }
     }
   } while ((l = l->next));
+*/
   return GW_OK;
 }
 
@@ -599,7 +624,7 @@ ANN static m_bool class_internal(const Env env, const Func_Base *base) {
 
 ANN static inline m_bool scan_internal_arg(const Env        env,
                                            const Func_Base *base) {
-  if (base->args && !base->args->next) return GW_OK;
+  if (base->args->len == 1) return GW_OK;
   assert(base->td);
   ERR_B(base->td->pos, _("'%s' must have one (and only one) argument"),
         s_name(base->xid))
@@ -629,9 +654,11 @@ ANN static m_bool scan_internal(const Env env, const Func_Base *base) {
   return GW_OK;
 }
 
-ANN static m_bool scan1_fdef_args(const Env env, Arg_List list) {
-  do CHECK_BB(shadow_arg(env, list->var_decl->xid, list->var_decl->pos));
-  while ((list = list->next));
+ANN static m_bool scan1_fdef_args(const Env env, Arg_List args) {
+  for(uint32_t i = 0; i < args->len; i++) {
+    Arg *arg = mp_vector_at(args, Arg, i);
+    CHECK_BB(shadow_arg(env, arg->var_decl.xid, arg->var_decl.pos));
+  }
   return GW_OK;
 }
 
@@ -700,7 +727,7 @@ ANN m_bool scan1_func_def(const Env env, const Func_Def fdef) {
 ANN static m_bool scan1_extend_def(const Env env, const Extend_Def xdef) {
   CHECK_BB(ensure_scan1(env, xdef->t));
   CHECK_BB(extend_push(env, xdef->t));
-  const m_bool ret = scan1_ast(env, xdef->body);
+  const m_bool ret = scan1_ast(env, &xdef->body);
   extend_pop(env, xdef->t);
   return ret;
 }
@@ -751,8 +778,12 @@ ANN m_bool scan1_class_def(const Env env, const Class_Def cdef) {
   return GW_OK;
 }
 
-ANN m_bool scan1_ast(const Env env, Ast ast) {
-  do CHECK_BB(scan1_section(env, ast->section));
-  while ((ast = ast->next));
+ANN m_bool scan1_ast(const Env env, Ast *ast) {
+  Ast a = *ast;
+  for(m_uint i = 0; i < a->len; i++) {
+    const m_uint offset = i * sizeof(Section);
+    Section *section = (Section*)(a->ptr + offset);
+    CHECK_BB(scan1_section(env, section));
+  }
   return GW_OK;
 }
index a8390b00c646d25e0302f5188694d41688b5d930..86f233d90d49a934e97033fff46d41f49e539cb8 100644 (file)
@@ -29,12 +29,12 @@ ANN static m_bool scan2_decl(const Env env, const Exp_Decl *decl) {
   const Type t = decl->type;
   CHECK_BB(ensure_scan2(env, t));
   Var_Decl_List list = decl->list;
-  do {
-    const Var_Decl var   = list->self;
-    const Exp      array = var->array ? var->array->exp : NULL;
+  for(uint32_t i = 0; i < list->len; i++) {
+    const Var_Decl vd   = mp_vector_at(list, struct Var_Decl_, i);
+    const Exp array = vd->array ? vd->array->exp : NULL;
     if (array) CHECK_BB(scan2_exp(env, array));
-    nspc_add_value(env->curr, var->xid, var->value);
-  } while ((list = list->next));
+    nspc_add_value(env->curr, vd->xid, vd->value);
+  }
   return GW_OK;
 }
 
@@ -46,15 +46,16 @@ ANN m_bool scan2_exp_decl(const Env env, const Exp_Decl *decl) {
   return ret;
 }
 
-ANN static m_bool scan2_args(const Func_Def f) {
-  Arg_List   list   = f->base->args;
+ANN static m_bool scan2_args(const Env env, const Func_Def f) {
+  Arg_List   args   = f->base->args;
   const bool global = GET_FLAG(f->base, global);
-  do {
-    const Value v   = list->var_decl->value;
+  for(uint32_t i = 0; i < args->len; i++) {
+    Arg *arg = mp_vector_at(args, Arg, i);
+    const Value v   = arg->var_decl.value;
     v->from->offset = f->stack_depth;
     f->stack_depth += v->type->size;
     if (global) SET_FLAG(v, global);
-  } while ((list = list->next));
+  }
   return GW_OK;
 }
 
@@ -79,7 +80,7 @@ ANN static Value scan2_func_assign(const Env env, const Func_Def d,
 ANN m_bool scan2_fptr_def(const Env env NUSED, const Fptr_Def fptr) {
   if (!tmpl_base(fptr->base->tmpl)) {
     const Func_Def def = fptr->type->info->func->def;
-    if (def->base->args) { RET_NSPC(scan2_args(def)) }
+    if (def->base->args) { RET_NSPC(scan2_args(env, def)) }
   } else
     set_tflag(fptr->type, tflag_ftmpl);
   return GW_OK;
@@ -128,7 +129,7 @@ ANN static inline m_bool scan2_exp_slice(const Env env, const Exp_Slice *exp) {
 
 ANN static m_bool multi_decl(const Env env, const Exp e, const Symbol op) {
   if (e->exp_type == ae_exp_decl) {
-    if (e->d.exp_decl.list->next)
+    if (e->d.exp_decl.list->len > 1)
       ERR_B(e->pos, _("cant '%s' from/to a multi-variable declaration."),
             s_name(op))
     //    set_vflag(e->d.exp_decl.list->self->value, vflag_used);
@@ -194,16 +195,27 @@ ANN static inline m_bool scan2_stmt_match_case(const restrict Env env,
 ANN static inline m_bool
     _scan2_stmt_match(const restrict Env env, const Stmt_Match stmt) {
   if (stmt->where) CHECK_BB(scan2_stmt(env, stmt->where));
-  Stmt_List list = stmt->list;
-  do CHECK_BB(scan2_stmt_match_case(env, &list->stmt->d.stmt_match));
-  while ((list = list->next));
+  Stmt_List l = stmt->list;
+  for(m_uint i = 0; i < l->len; i++) {
+    const m_uint offset = i * sizeof(struct Stmt_);
+    const Stmt s = (Stmt)(l->ptr + offset);
+    CHECK_BB(scan2_stmt_match_case(env, &s->d.stmt_match));
+  }
   return GW_OK;
 }
 
+ANN static inline m_bool scan2_handler(const restrict Env env,
+                                            const Handler *handler) {
+  RET_NSPC(scan2_stmt(env, handler->stmt));
+}
+
 ANN static inline m_bool scan2_handler_list(const restrict Env env,
-                                            const Handler_List handler) {
-  if (handler->next) CHECK_BB(scan2_handler_list(env, handler->next));
-  RET_NSPC(scan2_stmt(env, handler->stmt))
+                                            const Handler_List handlers) {
+  for(uint32_t i = 0; i < handlers->len; i++) {
+    Handler * handler = mp_vector_at(handlers, Handler, i);
+    CHECK_BB(scan2_handler(env, handler));
+  }
+  return GW_OK;
 }
 
 ANN static inline m_bool scan2_stmt_try(const restrict Env env,
@@ -277,9 +289,12 @@ ANN static m_bool scan2_stmt(const Env env, const Stmt stmt) {
   return scan2_stmt_func[stmt->stmt_type](env, &stmt->d);
 }
 
-ANN static m_bool scan2_stmt_list(const Env env, Stmt_List list) {
-  do CHECK_BB(scan2_stmt(env, list->stmt));
-  while ((list = list->next));
+ANN static m_bool scan2_stmt_list(const Env env, Stmt_List l) {
+  for(m_uint i = 0; i < l->len; i++) {
+    const m_uint offset = i * sizeof(struct Stmt_);
+    const Stmt s = (Stmt)(l->ptr + offset);
+    CHECK_BB(scan2_stmt(env, s));
+  }
   return GW_OK;
 }
 
@@ -390,9 +405,11 @@ static m_bool scan2_fdef_tmpl(const Env env, const Func_Def f,
               func_symbol(env, env->curr->name, name, "template", ff->vt_index);
           nspc_add_value(env->curr, sym, value);
           if (!overload) {
-            value_addref(value);
+//            value_addref(value);
             nspc_add_value(env->curr, f->base->xid, value);
+//    nspc_add_func(env->curr, f->base->xid, func);
           }
+    nspc_add_func(env->curr, sym, func);
           func->vt_index = ff->vt_index;
           return GW_OK;
         }
@@ -402,10 +419,11 @@ static m_bool scan2_fdef_tmpl(const Env env, const Func_Def f,
   --i;
   const Symbol sym = func_symbol(env, env->curr->name, name, "template", i);
   nspc_add_value(env->curr, sym, value);
+nspc_add_func(env->curr, sym, func);
   if (!overload) {
-    value_addref(value);
+//    value_addref(value);
     nspc_add_value(env->curr, f->base->xid, value);
-    nspc_add_func(env->curr, f->base->xid, func);
+//    nspc_add_func(env->curr, f->base->xid, func);
   } else
     func->vt_index = ++overload->from->offset;
   return GW_OK;
@@ -442,15 +460,17 @@ ANN static void scan2_func_def_flag(const Env env, const Func_Def f) {
 ANN static m_str func_tmpl_name(const Env env, const Func_Def f) {
   const m_str      name = s_name(f->base->xid);
   struct Vector_   v;
-  Specialized_List id   = f->base->tmpl->list;
+  Specialized_List sl   = f->base->tmpl->list;
   m_uint           tlen = 0;
   vector_init(&v);
-  do {
-    const Type t = nspc_lookup_type0(env->curr, id->xid);
+  for(uint32_t i = 0; i < sl->len; i++) {
+    Specialized * spec = mp_vector_at(sl, Specialized, i);
+    const Type t = nspc_lookup_type0(env->curr, spec->xid);
     if (!t) return NULL;
     vector_add(&v, (vtype)t);
     tlen += strlen(t->name);
-  } while ((id = id->next) && ++tlen);
+    ++tlen;
+  } //while ((id = id->next) && ++tlen);
   char  tmpl_name[tlen + 2];
   m_str str = tmpl_name;
   for (m_uint i = 0; i < vector_size(&v); ++i) {
@@ -496,7 +516,7 @@ m_bool scan2_fdef_std(const Env env, const Func_Def f, const Value overload) {
     CHECK_OB(func_create(env, f, overload, name));
   else
     f->base->func = base;
-  if (f->base->args) CHECK_BB(scan2_args(f));
+  if (f->base->args) CHECK_BB(scan2_args(env, f));
   if (!f->builtin && f->d.code) CHECK_BB(scan2_func_def_code(env, f));
   if (!base) {
     if (fbflag(f->base, fbflag_op)) CHECK_BB(scan2_func_def_op(env, f));
@@ -528,12 +548,12 @@ __attribute__((returns_nonnull)) static ANN Func_Def
 scan2_cpy_fdef(const Env env, const Func_Def fdef) {
   const Func_Def f  = cpy_func_def(env->gwion->mp, fdef);
   f->base->ret_type = fdef->base->ret_type;
-  Arg_List a = f->base->args, b = fdef->base->args;
-  while (a) {
-    a->var_decl->value = b->var_decl->value;
-    a->type            = b->type;
-    a                  = a->next;
-    b                  = b->next;
+  Arg_List args0 = f->base->args, args1 = fdef->base->args;
+  for(uint32_t i = 0; i < (args0 ? args0->len : 0); i++) {
+    Arg *arg0 = mp_vector_at(args0, Arg, i);
+    Arg *arg1 = mp_vector_at(args1, Arg, i);
+    arg0->var_decl.value = arg1->var_decl.value;
+    arg0->type            = arg1->type;
   }
   scan1_func_def(env, f);
   return f;
@@ -581,7 +601,7 @@ ANN m_bool scan2_func_def(const Env env, const Func_Def fdef) {
 ANN static m_bool scan2_extend_def(const Env env, const Extend_Def xdef) {
   CHECK_BB(ensure_scan2(env, xdef->t));
   CHECK_BB(extend_push(env, xdef->t));
-  const m_bool ret = scan2_ast(env, xdef->body);
+  const m_bool ret = scan2_ast(env, &xdef->body);
   extend_pop(env, xdef->t);
   return ret;
 }
@@ -618,8 +638,12 @@ ANN m_bool scan2_class_def(const Env env, const Class_Def cdef) {
   return GW_OK;
 }
 
-ANN m_bool scan2_ast(const Env env, Ast ast) {
-  do CHECK_BB(scan2_section(env, ast->section));
-  while ((ast = ast->next));
+ANN m_bool scan2_ast(const Env env, Ast *ast) {
+  Ast a = *ast;
+  for(m_uint i = 0; i < a->len; i++) {
+    const m_uint offset = i * sizeof(Section);
+    Section *section = (Section*)(a->ptr + offset);
+    CHECK_BB(scan2_section(env, section));
+  }
   return GW_OK;
 }
index 487f65bbf28db44283d8a6d089c689451b9f6db6..bc65f34a55b3d9f2d3b958e25efd92895b05a349 100644 (file)
@@ -7,8 +7,11 @@
 #include "parse.h"
 
 ANN static inline m_bool _body(const Env e, Ast b, const _exp_func f) {
-  do CHECK_BB(f(e, b->section));
-  while ((b = b->next));
+  for(m_uint i = 0; i < b->len; i++) {
+    const m_uint offset = i * sizeof(Section);
+    Section *section = (Section*)(b->ptr + offset);
+    CHECK_BB(f(e, section));
+  }
   return GW_OK;
 }
 
index 0a72a547c5b119f9dcf4287fdb77c0c2bdcf632d..789ec175f4ada08e406ab284b308ca9af101f3e0 100644 (file)
 
 ANN static m_bool _push_types(const Env env, const Nspc nspc,
                               const Tmpl *tmpl) {
-  Specialized_List list = tmpl->list;
-  Type_List        call = tmpl->call;
-  do {
-    if (!call) break;
-    const Type t = call->td ? known_type(env, call->td) : NULL;
+  Specialized_List sl = tmpl->list;
+  Type_List        tl = tmpl->call;
+  if(!tl) return GW_OK;
+  for(uint32_t i = 0; i < sl->len; i++) {
+    if (i >= tl->len) return GW_OK;
+    Type_Decl *td = *mp_vector_at(tl, Type_Decl*, i);
+//    const Type t = td ? known_type(env, td) : NULL;
+    const Type t = known_type(env, td);
     if (!t) return GW_OK;
-    nspc_add_type(nspc, list->xid, t);
-    call = call->next;
-  } while ((list = list->next));
-  return !call ? GW_OK : GW_ERROR;
+    Specialized *spec = mp_vector_at(sl, Specialized, i);
+    nspc_add_type(nspc, spec->xid, t);
+  };
+  return tl->len == sl->len ? GW_OK : GW_ERROR;
 }
 
 ANN static m_bool push_types(const Env env, const Nspc nspc, const Tmpl *tmpl) {
@@ -127,16 +130,17 @@ ANN Type _scan_type(const Env env, const Type t, Type_Decl *td) {
     Type_List           tl = td->types;
     Specialized_List    sl = t->info->cdef->base.tmpl
         ? t->info->cdef->base.tmpl->list : NULL;
-
-    while (tl && sl) {
-      DECL_OO(const Type, t, = known_type(env, tl->td));
-      ID_List missing = miss_traits(t, sl);
-      if (missing) {
-        ERR_O(tl->td->pos, "does not implement requested trait '{/}%s{0}'",
-              s_name(missing->xid));
+    for(uint32_t i = 0; i < tl->len; i++) {
+      Type_Decl *td = *mp_vector_at(tl, Type_Decl*, i);
+      DECL_OO(const Type, t, = known_type(env, td));
+      Specialized *spec = mp_vector_at(sl, Specialized, i);
+      if(spec->traits) {
+        Symbol missing = miss_traits(t, spec);
+        if (missing) {
+          ERR_O(td->pos, "does not implement requested trait '{/}%s{0}'",
+                s_name(missing));
+        }
       }
-      tl = tl->next;
-      sl = sl->next;
     }
     struct Op_Import opi = {.op   = insert_symbol("@scan"),
                             .lhs  = t,
index c9d36fb8a67d3742cb5839683d82b9325b86d62d..4289cacbb7c6154d6628881bae6f45f74e4b20cd 100644 (file)
@@ -3,7 +3,7 @@
 #include "gwion_env.h"
 #include "traverse.h"
 
-ANN m_bool traverse_ast(const Env env, const Ast ast) {
+ANN m_bool traverse_ast(const Env env, const Ast *ast) {
   CHECK_BB(scan0_ast(env, ast));
   CHECK_BB(scan1_ast(env, ast));
   CHECK_BB(scan2_ast(env, ast));
index a71d20e1b0b059444e9121d9775008226de2a332..33b74385816734bb6c39a48bece494bcb5234f3f 100644 (file)
@@ -6,10 +6,13 @@
 #include "parse.h"
 
 ANN static Type _option(const Env env, Type_Decl *td, const uint8_t n) {
-  struct Type_List_ tl  = {.td = td};
+  Type_List tl  = new_mp_vector(env->gwion->mp, sizeof(Type_Decl*), 1);
+  mp_vector_set(tl, Type_Decl*, 0, td);
   Type_Decl         tmp = {
-      .xid = insert_symbol("Option"), .types = &tl, .pos = td->pos};
-  return !(n - 1) ? known_type(env, &tmp) : _option(env, &tmp, n - 1);
+      .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, sizeof(Type_Decl*), tl);
+  return t;
 }
 
 ANN static Type option(const Env env, Type_Decl *td) {
@@ -21,9 +24,12 @@ ANN static Type option(const Env env, Type_Decl *td) {
 }
 
 ANN static Type _ref(const Env env, Type_Decl *td) {
-  struct Type_List_ tl = {.td = td};
-  Type_Decl tmp = {.xid = insert_symbol("Ref"), .types = &tl, .pos = td->pos};
-  return known_type(env, &tmp);
+  Type_List tl  = new_mp_vector(env->gwion->mp, sizeof(Type_Decl*), 1);
+  mp_vector_set(tl, Type_Decl*, 0, td);
+  Type_Decl tmp = {.xid = insert_symbol("Ref"), .types = tl, .pos = td->pos};
+  const Type t = known_type(env, &tmp);
+  free_mp_vector(env->gwion->mp, sizeof(Type_Decl*), tl);
+  return t;
 }
 
 ANN static inline Type ref(const Env env, Type_Decl *td) {
index 7daaba71107e096be2c682328f34c76c48da5533..e077012ff85304d8f311d484a7479e24ceb94df7 100644 (file)
@@ -33,6 +33,12 @@ ANN m_bool pass_set(const Gwion gwion, const Vector passes) {
     const compilation_pass pass =
         (compilation_pass)map_get(&gwion->data->passes->map, (vtype)sym);
     if (!pass) {
+/*
+if(!strcmp(name, "none")) {
+  vector_clear(v);
+  return GW_OK;
+}
+*/
       gw_err("Failed to set compilation passes, back to default\n");
       pass_default(gwion);
       return GW_ERROR;
index 7a4ff55a27450ce419d9694b6db0aaa608c01ec9..cd6437626d08ba7c8fbbf99a97e0b7cd0bc4d44b 100644 (file)
@@ -137,20 +137,20 @@ ANN void plug_run(const struct Gwion_ *gwion, const Map mod) {
   }
 }
 
-ANN static m_bool dependencies(struct Gwion_ *gwion, const Plug plug) {
+ANN static m_bool dependencies(struct Gwion_ *gwion, const Plug plug, const loc_t loc) {
   const gwdeps dep = DLSYM(plug->dl, gwdeps, GWDEPEND_NAME);
   if (dep) {
     m_str *const base = dep();
     m_str *      deps = base;
     while (*deps) {
-      CHECK_BB(plugin_ini(gwion, *deps));
+      CHECK_BB(plugin_ini(gwion, *deps, loc));
       ++deps;
     }
   }
   return GW_OK;
 }
 
-ANN static m_bool _plugin_ini(struct Gwion_ *gwion, const m_str iname) {
+ANN static m_bool _plugin_ini(struct Gwion_ *gwion, const m_str iname, const loc_t loc) {
   const Map map = &gwion->data->plug;
   for (m_uint i = 0; i < map_size(map); ++i) {
     const Plug   plug = (Plug)VVAL(map, i);
@@ -168,7 +168,7 @@ ANN static m_bool _plugin_ini(struct Gwion_ *gwion, const m_str iname) {
       plug->imp = 1;
       const bool cdoc = gwion->data->cdoc;
       gwion->data->cdoc = 0;
-      CHECK_BB(dependencies(gwion, plug));
+      CHECK_BB(dependencies(gwion, plug, loc));
       gwion->data->cdoc = cdoc;
       const m_uint scope = env_push_global(gwion->env);
       const m_str  name  = gwion->env->name;
@@ -179,16 +179,18 @@ ANN static m_bool _plugin_ini(struct Gwion_ *gwion, const m_str iname) {
       return ret;
     }
   }
-  gw_err("no such plugin '%s'\n", iname);
   return GW_ERROR;
 }
 
-ANN m_bool plugin_ini(struct Gwion_ *gwion, const m_str iname) {
-  const Context ctx   = gwion->env->context;
+ANN m_bool plugin_ini(struct Gwion_ *gwion, const m_str iname, const loc_t loc) {
+  const Env env = gwion->env;
+  const Context ctx   = env->context;
   gwion->env->context = NULL;
-  const m_bool ret    = _plugin_ini(gwion, iname);
+  const m_bool ret    = _plugin_ini(gwion, iname, loc);
   gwion->env->context = ctx;
-  return ret;
+  if(ret > 0) return GW_OK;
+  env_err(env, loc, "no such plugin\n");
+  return GW_ERROR;
 }
 
 ANN m_bool driver_ini(const struct Gwion_ *gwion) {
index 94defc6644d0eeecfc63f41a16dd79c978ed58c6..1d82e31d2e85c56045b5d0379a8531c93853dca2 100644 (file)
@@ -542,7 +542,7 @@ vm_prepare(const VM *vm, m_bit *prepare_code) { // lgtm [cpp/use-of-goto]
       reg += SZ_INT;
       DISPATCH()
     regpushmemderef:
-      memcpy(reg, *(m_uint **)(mem + IVAL), VAL2);
+      memcpy(reg, *(m_bit **)(mem + IVAL), VAL2);
       reg += VAL2;
       DISPATCH()
     pushnow:
@@ -1019,9 +1019,12 @@ vm_prepare(const VM *vm, m_bit *prepare_code) { // lgtm [cpp/use-of-goto]
       DISPATCH()
     autoloop: {
       const M_Vector array = ARRAY(*(M_Object *)(mem + VAL2 - SZ_INT));
-      *(m_bit **)(mem + VAL2 + SZ_INT) =
-          m_vector_addr(array, ++*(m_uint *)(mem + VAL2));
-      BRANCH_DISPATCH(m_vector_size(array) == *(m_uint *)(mem + VAL2));
+      const bool end = ++*(m_uint *)(mem + VAL2) == m_vector_size(array);
+      if(!end) {
+        *(m_bit **)(mem + VAL2 + SZ_INT) =
+            m_vector_addr(array, *(m_uint *)(mem + VAL2));
+      }
+      BRANCH_DISPATCH(end);
     }
     arraytop:
       if (*(m_uint *)(reg - SZ_INT * 2) < *(m_uint *)(reg - SZ_INT))
@@ -1201,8 +1204,10 @@ vm_prepare(const VM *vm, m_bit *prepare_code) { // lgtm [cpp/use-of-goto]
       DISPATCH()
     gackend : {
       m_str str = *(m_str *)(reg - SZ_INT);
-      if (!VAL)
+      if (!VAL) {
         gw_out("%s\n", str);
+fflush(stdout);
+}
       else
         *(M_Object *)(reg - SZ_INT) = new_string(vm->gwion, str);
       if (str) mp_free2(vm->gwion->mp, strlen(str), str);
diff --git a/tests/error/invalid_exp_format.gw b/tests/error/invalid_exp_format.gw
deleted file mode 100644 (file)
index d88acbe..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#! [contains] invalid format for expression
-1,(2,3);
index 5bab97e04c3a1187b18ec507667b2aa7974376cf..0ac8fb4c234c59e7e1d3642eeac151d9dc783705 100644 (file)
@@ -1,3 +1,4 @@
+#! [contains] can't assign to pointer
 class C {}
 
 class D extends C {}
diff --git a/tests/new/test.gw b/tests/new/test.gw
deleted file mode 100644 (file)
index 27c37c0..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-class C {
-  funptr static void func_t:[A](A a);
-  fun static void myfunc:[A](A a) { <<< a >>>; }
-  myfunc @=> var static func_t ptr;
-  ptr(1);
-}
-
-var C c;
diff --git a/tests/new/test2.gw b/tests/new/test2.gw
deleted file mode 100644 (file)
index a4c174e..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-class C:[A] {
-  funptr static void func_t:[A](A a);
-  fun static void myfunc:[A](A a) { <<< a >>>; }
-  myfunc @=> var static func_t ptr;
-  ptr(1);
-}
-
-var C:[int] c;
index fd52f6fa353fa4db8e081e09a6fa849ddbd7c8f6..5b64aea6135566a77ad4e2510cb5a676eab1129f 100644 (file)
@@ -9,7 +9,7 @@
 #include "import.h"
 #include "gwi.h"
 
-ANN static m_bool pass(Env nv NUSED, Ast ast NUSED) { return GW_OK; }
+ANN static m_bool pass(Env nv NUSED, Ast *ast NUSED) { return GW_OK; }
 
 GWION_IMPORT(array_test) {
   gwi_register_pass(gwi, "dummy", pass);
diff --git a/util b/util
index 186bade285100f2da04033429640b95d2f72cb2f..620ab68b3234178145f080e370b9ff5c0cede772 160000 (submodule)
--- a/util
+++ b/util
@@ -1 +1 @@
-Subproject commit 186bade285100f2da04033429640b95d2f72cb2f
+Subproject commit 620ab68b3234178145f080e370b9ff5c0cede772