From 649045b4952b69f3f376504312d473ce1216826a Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Thu, 17 Mar 2022 12:51:42 +0100 Subject: [PATCH] List2array (#237) * :art: clean_and_improve * :art: clean_and_improve ast * :wrench: some utils * fixfunctionnal * cleaning * submodules * Fix build * :art: cosmetics * :art: small template fix --- ast | 2 +- fmt | 2 +- include/arg.h | 10 +- include/clean.h | 1 - include/emit.h | 2 +- include/env/type.h | 17 +- include/gwion.h | 3 +- include/import/checker.h | 7 +- include/import/internals.h | 2 +- include/lang_private.h | 2 + include/operator.h | 6 +- include/pass.h | 2 +- include/plug.h | 2 +- include/traverse.h | 10 +- plug | 2 +- scripts/update.sh | 6 +- src/arg.c | 23 ++- src/clean.c | 66 ++++--- src/compile.c | 9 +- src/emit/emit.c | 181 ++++++++++------- src/env/context.c | 4 +- src/env/env.c | 4 +- src/env/env_utils.c | 5 +- src/gwion.c | 4 +- src/import/import_cdef.c | 12 +- src/import/import_checker.c | 85 ++++---- src/import/import_enum.c | 24 ++- src/import/import_fdef.c | 53 +++-- src/import/import_internals.c | 14 +- src/import/import_item.c | 22 ++- src/import/import_udef.c | 27 ++- src/lib/array.c | 37 ++-- src/lib/dict.c | 7 +- src/lib/engine.c | 57 +----- src/lib/lib_class.c | 63 ++++++ src/lib/lib_func.c | 159 +++++++++------ src/lib/lib_gack.c | 58 ++++++ src/lib/modules.c | 4 +- src/lib/object_op.c | 19 +- src/lib/ptr.c | 13 +- src/lib/ref.c | 2 +- src/lib/shred.c | 2 +- src/lib/tmpl_info.c | 13 +- src/main.c | 2 +- src/parse/check.c | 309 +++++++++++++++++------------- src/parse/check_traits.c | 52 +++-- src/parse/compat_func.c | 20 +- src/parse/func_operator.c | 10 +- src/parse/func_resolve_tmpl.c | 13 +- src/parse/operator.c | 43 +++-- src/parse/scan0.c | 176 ++++++++--------- src/parse/scan1.c | 186 ++++++++++-------- src/parse/scan2.c | 99 ++++++---- src/parse/scanx.c | 6 +- src/parse/template.c | 42 ++-- src/parse/traverse.c | 2 +- src/parse/type_decl.c | 18 +- src/pass.c | 6 + src/plug.c | 20 +- src/vm/vm.c | 15 +- tests/error/ptr_assign_invalid.gw | 1 + tests/new/test.gw | 8 - tests/new/test2.gw | 8 - tests/plug/pass.c | 2 +- util | 2 +- 65 files changed, 1208 insertions(+), 875 deletions(-) create mode 100644 src/lib/lib_class.c create mode 100644 src/lib/lib_gack.c delete mode 100644 tests/new/test.gw delete mode 100644 tests/new/test2.gw diff --git a/ast b/ast index 838b02ef..971a79a2 160000 --- a/ast +++ b/ast @@ -1 +1 @@ -Subproject commit 838b02ef57aece6809b723d2770a817d4213afef +Subproject commit 971a79a2f613db01129d7e52b4f738640bee00a9 diff --git a/fmt b/fmt index 8cc5ae30..30a6bb43 160000 --- a/fmt +++ b/fmt @@ -1 +1 @@ -Subproject commit 8cc5ae30b32e69bc8edd4419771eb8919d66c809 +Subproject commit 30a6bb43a53d74a3e81ccd923ae3a9bd8b6d1691 diff --git a/include/arg.h b/include/arg.h index 7542fc12..93bfca89 100644 --- a/include/arg.h +++ b/include/arg.h @@ -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 diff --git a/include/clean.h b/include/clean.h index 2fda18fd..c5647836 100644 --- a/include/clean.h +++ b/include/clean.h @@ -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); diff --git a/include/emit.h b/include/emit.h index eff90241..c3d2db31 100644 --- a/include/emit.h +++ b/include/emit.h @@ -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) diff --git a/include/env/type.h b/include/env/type.h index 6da3ef18..e0b58c85 100644 --- a/include/env/type.h +++ b/include/env/type.h @@ -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, diff --git a/include/gwion.h b/include/gwion.h index 041333b8..5fdf4b33 100644 --- a/include/gwion.h +++ b/include/gwion.h @@ -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); diff --git a/include/import/checker.h b/include/import/checker.h index 26b7d0e8..48044749 100644 --- a/include/import/checker.h +++ b/include/import/checker.h @@ -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) diff --git a/include/import/internals.h b/include/import/internals.h index 0c476ec5..2a665d59 100644 --- a/include/import/internals.h +++ b/include/import/internals.h @@ -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); diff --git a/include/lang_private.h b/include/lang_private.h index 734ba68e..c60954a6 100644 --- a/include/lang_private.h +++ b/include/lang_private.h @@ -1,5 +1,6 @@ #ifndef __LANG_PRIVATE #define __LANG_PRIVATE +ANN m_bool import_class(const Gwi gwi); ANN m_bool import_prim(const Gwi gwi); ANN m_bool import_object(const Gwi gwi); ANN m_bool import_vararg(const Gwi gwi); @@ -17,4 +18,5 @@ ANN m_bool import_union(const Gwi gwi); ANN m_bool import_ref(const Gwi gwi); ANN m_bool import_deep_equal(const Gwi gwi); ANN m_bool import_dict(const Gwi gwi); +ANN m_bool import_gack(const Gwi gwi); #endif diff --git a/include/operator.h b/include/operator.h index cda04f19..5f3b012d 100644 --- a/include/operator.h +++ b/include/operator.h @@ -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); diff --git a/include/pass.h b/include/pass.h index 631a229f..813da10e 100644 --- a/include/pass.h +++ b/include/pass.h @@ -2,7 +2,7 @@ #define __GWIONPASS typedef union __attribute__((__transparent_union__)) { - struct Ast_ *ast; + Ast *ast; m_bool * ret; } PassArg; diff --git a/include/plug.h b/include/plug.h index adb913bc..18ade2d7 100644 --- a/include/plug.h +++ b/include/plug.h @@ -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 diff --git a/include/traverse.h b/include/traverse.h index 69dfa680..4941b92b 100644 --- a/include/traverse.h +++ b/include/traverse.h @@ -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 a7f57ef9..7121bd4b 160000 --- a/plug +++ b/plug @@ -1 +1 @@ -Subproject commit a7f57ef9dec1fa797ab295adf89d8509d7a636dc +Subproject commit 7121bd4bd7ba6429999b1c54f68d9c3edbfd416b diff --git a/scripts/update.sh b/scripts/update.sh index e828a56e..e674a3a0 100644 --- a/scripts/update.sh +++ b/scripts/update.sh @@ -1,12 +1,10 @@ #!/bin/bash git pull -git submodule update --recursive --init +git submodule update make clean-all make -j make -C plug sudo make install -mkdir -p ~/.gwplug -rm -f ~/.gwplug/*.so for a in $(cat plug/list.txt) -do cp plug/$a/*.so ~/.gwplug +do cp plug/$a/*.so ~/gwplug done diff --git a/src/arg.c b/src/arg.c index 5c3bcda5..b3be4ea2 100644 --- a/src/arg.c +++ b/src/arg.c @@ -1,3 +1,4 @@ +#include #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 diff --git a/src/clean.c b/src/clean.c index a990904d..b8058983 100644 --- a/src/clean.c +++ b/src/clean.c @@ -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,21 @@ 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 Stmt stmt = mp_vector_at(b, struct Stmt_, i); + 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 +255,18 @@ 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 = mp_vector_at(b, Arg, i); + 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 Stmt stmt = mp_vector_at(b, struct Stmt_, i); + clean_stmt(a, stmt); + } } ANN static void clean_func_base(Clean *a, Func_Base *b) { @@ -302,14 +309,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 +353,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++) { + Section *section = mp_vector_at(b, Section, i); + clean_section(a, section); + } } ANN void ast_cleaner(const Gwion gwion, Ast b) { diff --git a/src/compile.c b/src/compile.c index ad22aa57..2974fdef 100644 --- a/src/compile.c +++ b/src/compile.c @@ -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; } diff --git a/src/emit/emit.c b/src/emit/emit.c index d2f528e4..5167adc5 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -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; } @@ -665,11 +666,12 @@ ANN static inline m_bool emit_exp_pop_next(const Emitter emit, Exp e); ANN static m_bool emit_range(const Emitter emit, Range *range) { if (range->start) - CHECK_BB(emit_exp_pop_next(emit, range->start)); +// CHECK_BB(emit_exp_pop_next(emit, range->start)); + CHECK_BB(emit_exp(emit, range->start)); else regpushi(emit, 0); if (range->end) - CHECK_BB(emit_exp_pop_next(emit, range->end)); + CHECK_BB(emit_exp(emit, range->end)); else regpushi(emit, -1); return GW_OK; @@ -856,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; } @@ -881,10 +887,14 @@ 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) emit_add_instr(emit, GackType); + 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); instr->m_val = emit_code_offset(emit); } while ((e = e->next = next)); @@ -1017,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; @@ -1116,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; } @@ -1151,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; @@ -1377,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; @@ -1405,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); @@ -1470,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; } @@ -1588,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 = { @@ -1631,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 = mp_vector_at(args, Arg, i); 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; } @@ -1938,7 +1967,8 @@ ANN static m_bool emit_implicit_cast(const Emitter emit, } ANN2(1,2) static Instr _flow(const Emitter emit, const Exp e, Instr *const instr, const bool b) { - CHECK_BO(emit_exp_pop_next(emit, e)); +// CHECK_BO(emit_exp_pop_next(emit, e)); + CHECK_BO(emit_exp(emit, e)); if(instr) *instr = emit_add_instr(emit, NoOp); // emit_exp_addref1(emit, e, -exp_size(e)); // ???? @@ -2109,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); @@ -2145,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; @@ -2173,7 +2204,7 @@ ANN static m_bool emit_stmt_return(const Emitter emit, const Stmt_Exp stmt) { if (stmt->val->exp_type == ae_exp_call && emit->env->func == f) return optimize_tail_call(emit, &stmt->val->d.exp_call); } - CHECK_BB(emit_exp_pop_next(emit, stmt->val)); + CHECK_BB(emit_exp(emit, stmt->val)); } vector_add(&emit->code->stack_return, (vtype)emit_add_instr(emit, Goto)); return GW_OK; @@ -2408,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); @@ -2427,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; @@ -2561,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; } @@ -2746,8 +2780,10 @@ 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 Stmt stmt = mp_vector_at(list, struct Stmt_, i); + CHECK_BB(emit_stmt_match_case(emit, &stmt->d.stmt_match)); + } return GW_OK; } @@ -2807,8 +2843,10 @@ 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 Stmt stmt = mp_vector_at(l, struct Stmt_, i); + CHECK_BB(emit_stmt(emit, stmt, 1)); + } return GW_OK; } @@ -2825,13 +2863,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 = mp_vector_at(args, Arg, i); + 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) { @@ -3021,8 +3060,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++) { + Section * section = mp_vector_at(ast, Section, i); + CHECK_BB(emit_section(emit, section)); + } return emit_defers(emit); } @@ -3105,12 +3146,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); diff --git a/src/env/context.c b/src/env/context.c index 9cf288f5..641633c7 100644 --- a/src/env/context.c +++ b/src/env/context.c @@ -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); diff --git a/src/env/env.c b/src/env/env.c index 0813904b..b22310c6 100644 --- a/src/env/env.c +++ b/src/env/env.c @@ -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); } } diff --git a/src/env/env_utils.c b/src/env/env_utils.c index f415c881..d23f9f69 100644 --- a/src/env/env_utils.c +++ b/src/env/env_utils.c @@ -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) } diff --git a/src/gwion.c b/src/gwion.c index 42ba80b1..483d8bb8 100644 --- a/src/gwion.c +++ b/src/gwion.c @@ -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); diff --git a/src/import/import_cdef.c b/src/import/import_cdef.c index 4d128883..0133f0ac 100644 --- a/src/import/import_cdef.c +++ b/src/import/import_cdef.c @@ -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); diff --git a/src/import/import_checker.c b/src/import/import_checker.c index ae7c1fce..d8861dcf 100644 --- a/src/import/import_checker.c +++ b/src/import/import_checker.c @@ -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; } diff --git a/src/import/import_enum.c b/src/import/import_enum.c index c47ca50a..4ec441ff 100644 --- a/src/import/import_enum.c +++ b/src/import/import_enum.c @@ -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; } diff --git a/src/import/import_fdef.c b/src/import/import_fdef.c index 234fc378..4a1109e3 100644 --- a/src/import/import_fdef.c +++ b/src/import/import_fdef.c @@ -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, §ion); 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, §ion); +// 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); } diff --git a/src/import/import_internals.c b/src/import/import_internals.c index 49377553..af161b4c 100644 --- a/src/import/import_internals.c +++ b/src/import/import_internals.c @@ -10,13 +10,14 @@ #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) { + cdef->body = new_mp_vector(gwi->gwion->mp, sizeof(Section), 1); + mp_vector_set(cdef->body, Section, 0, *section); + } 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; } + diff --git a/src/import/import_item.c b/src/import/import_item.c index 2d9bd42b..93fbdc67 100644 --- a/src/import/import_item.c +++ b/src/import/import_item.c @@ -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); + Stmt_List slist = new_mp_vector(gwi->gwion->mp, sizeof(struct Stmt_), 1); + mp_vector_set(slist, struct Stmt_, 0, ((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, §ion); 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); diff --git a/src/import/import_udef.c b/src/import/import_udef.c index 3fe217f2..cc1932ef 100644 --- a/src/import/import_udef.c +++ b/src/import/import_udef.c @@ -17,16 +17,21 @@ // 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); } diff --git a/src/lib/array.c b/src/lib/array.c index 2c5a9a89..edbbdcc0 100644 --- a/src/lib/array.c +++ b/src/lib/array.c @@ -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; } @@ -402,6 +403,7 @@ typedef struct FunctionalFrame { uint16_t pc; uint16_t offset; uint16_t index; + uint16_t ret_size; } FunctionalFrame; ANN static inline void _init(const VM_Shred shred, const struct VM_Code_ *code, @@ -411,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); @@ -420,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); } @@ -438,12 +439,14 @@ ANN static inline void _finish(const VM_Shred shred, #define MAP_CODE_OFFSET (sizeof(FunctionalFrame) + sizeof(struct frame_t)) static INSTR(map_run_ini) { + const VM_Code code = *(VM_Code*)REG(0); const m_uint offset = *(m_uint *)REG(SZ_INT); if (offset) PUSH_MEM(shred, offset); PUSH_REG(shred, SZ_INT); const M_Object self = *(M_Object *)MEM(0); const M_Vector array = ARRAY(self); FunctionalFrame *frame = &*(FunctionalFrame *)MEM(SZ_INT * 3); + frame->ret_size = code->ret_type->size; shred->pc++; shred->mem += MAP_CODE_OFFSET + SZ_INT; // work in a safe memory space m_vector_get(array, frame->index, &*(m_bit **)(shred->mem + SZ_INT * 2 + frame->offset + frame->code->stack_depth)); @@ -453,8 +456,8 @@ static INSTR(map_run_end) { shred->mem -= MAP_CODE_OFFSET + SZ_INT; const M_Object ret_obj = *(M_Object *)MEM(SZ_INT * 2); const M_Vector array = ARRAY(*(M_Object *)MEM(0)); - POP_REG(shred, ARRAY_SIZE(array)); FunctionalFrame *const frame = &*(FunctionalFrame *)MEM(SZ_INT * 3); + POP_REG(shred, frame->ret_size); m_vector_set(ARRAY(ret_obj), frame->index, shred->reg); if (++frame->index == ARRAY_LEN(array)) { _return(shred, frame); @@ -470,8 +473,8 @@ static INSTR(compactmap_run_end) { const M_Vector self_array = ARRAY(self); const M_Object ret_obj = *(M_Object *)MEM(SZ_INT * 2); const M_Vector ret_array = ARRAY(ret_obj); - POP_REG(shred, ARRAY_SIZE(ret_array)); FunctionalFrame *const frame = &*(FunctionalFrame *)MEM(SZ_INT * 3); + POP_REG(shred, frame->ret_size); const m_uint size = m_vector_size(self_array); const M_Object obj = *(M_Object *)REG(0); if (*(m_uint *)obj->data) @@ -558,26 +561,30 @@ static MFUN(vm_vector_count) { } static INSTR(foldl_run_ini) { + const VM_Code code = *(VM_Code*)REG(0); const m_uint offset = *(m_uint *)REG(SZ_INT); if (offset) PUSH_MEM(shred, offset); const M_Object self = *(M_Object *)MEM(0); *(m_uint *)(shred->reg + SZ_INT) = 0; PUSH_REG(shred, SZ_INT); shred->pc++; - const FunctionalFrame *frame = &*(FunctionalFrame *)MEM(SZ_INT * 3); + FunctionalFrame *const frame = &*(FunctionalFrame *)MEM(SZ_INT * 3); + frame->ret_size = code->ret_type->size; shred->mem += MAP_CODE_OFFSET + SZ_INT; // work in a safe memory space m_vector_get(ARRAY(self), frame->index, &*(m_bit **)(shred->mem + SZ_INT * 2 + frame->code->stack_depth)); } static INSTR(foldr_run_ini) { + const VM_Code code = *(VM_Code*)REG(0); const m_uint offset = *(m_uint *)REG(SZ_INT); if (offset) PUSH_MEM(shred, offset); const M_Object self = *(M_Object *)MEM(0); *(m_uint *)(shred->reg + SZ_INT) = 0; PUSH_REG(shred, SZ_INT); shred->pc++; - const FunctionalFrame *frame = &*(FunctionalFrame *)MEM(SZ_INT * 3); + FunctionalFrame *const frame = &*(FunctionalFrame *)MEM(SZ_INT * 3); + frame->ret_size = code->ret_type->size; shred->mem += MAP_CODE_OFFSET + SZ_INT; // work in a safe memory space const M_Vector array = ARRAY(self); m_vector_get(array, ARRAY_LEN(array) - frame->index - 1, @@ -591,7 +598,7 @@ static INSTR(fold_run_end) { const VM_Code code = *(VM_Code *)MEM(SZ_INT); const m_uint sz = code->stack_depth - ARRAY_SIZE(ARRAY(self)); const m_uint base_sz = code->stack_depth - sz; - POP_REG(shred, base_sz); + POP_REG(shred, base_sz); // ret_sz? if (++frame->index == ARRAY_LEN(ARRAY(self))) { POP_REG(shred, SZ_INT - base_sz); shred->pc = frame->pc; @@ -634,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); @@ -660,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, diff --git a/src/lib/dict.c b/src/lib/dict.c index cd0dba2a..0e85c398 100644 --- a/src/lib/dict.c +++ b/src/lib/dict.c @@ -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); diff --git a/src/lib/engine.c b/src/lib/engine.c index 15ee849f..5aafb051 100644 --- a/src/lib/engine.c +++ b/src/lib/engine.c @@ -21,8 +21,6 @@ static GACK(gack_class) { static GACK(gack_function) { INTERP_PRINTF("%s", t->name) } -static GACK(gack_gack) { INTERP_PRINTF("%s", *(m_str *)VALUE) } - static GACK(gack_fptr) { const VM_Code code = *(VM_Code *)VALUE; if (code) @@ -40,32 +38,9 @@ static GACK(gack_char) { INTERP_PRINTF("%c", *(char *)VALUE); } static GACK(gack_float) { INTERP_PRINTF("%.4f", *(m_float *)VALUE); } static GACK(gack_compound) { INTERP_PRINTF("%p", *(void **)VALUE); } -#define mk_class_instr(op, arg0, arg1, ...) \ - static INSTR(instr_class_##op) { \ - POP_REG(shred, SZ_INT); \ - const Type l = *(Type *)(shred->reg - SZ_INT); \ - const Type r = *(Type *)(shred->reg); \ - *(m_uint *)(shred->reg - SZ_INT) = isa(arg0, arg1) > 0 __VA_ARGS__; \ - } -mk_class_instr(ge, l, r) mk_class_instr(gt, l, r, &&l != r) - mk_class_instr(le, r, l) mk_class_instr(lt, r, l, &&l != r) - - OP_CHECK(opck_object_dot); -OP_EMIT(opem_object_dot); - -static OP_CHECK(opck_basic_ctor) { - const Exp_Call *call = (Exp_Call *)data; - ERR_N(exp_self(call)->pos, _("can't call a non-callable value")); -} -static OP_CHECK(opck_class_call) { - const Exp_Binary *bin = (Exp_Binary *)data; - Exp_Call call = {.func = bin->rhs, .args = bin->lhs}; - Exp e = exp_self(bin); - e->exp_type = ae_exp_call; - memcpy(&e->d.exp_call, &call, sizeof(Exp_Call)); - return check_exp_call1(env, &e->d.exp_call) ?: env->gwion->type[et_error]; -} +OP_CHECK(opck_object_dot); +OP_EMIT(opem_object_dot); static ID_CHECK(idck_predicate) { set_fflag(env->func, fflag_return); @@ -98,11 +73,6 @@ ANN static m_bool import_core_libs(const Gwi gwi) { GWI_BB(gwi_gack(gwi, t_void, gack_void)) GWI_BB(gwi_set_global_type(gwi, t_void, et_void)) - gwidoc(gwi, "a type for *pretty print*."); - const Type t_gack = gwi_mk_type(gwi, "@Gack", SZ_INT, NULL); - GWI_BB(gwi_gack(gwi, t_gack, gack_gack)) - GWI_BB(gwi_set_global_type(gwi, t_gack, et_gack)) - gwidoc(gwi, "integer type."); const Type t_int = gwi_mk_type(gwi, "int", SZ_INT, NULL); GWI_BB(gwi_gack(gwi, t_int, gack_int)) @@ -198,40 +168,23 @@ ANN static m_bool import_core_libs(const Gwi gwi) { GWI_BB(import_modules(gwi)) GWI_BB(import_ref(gwi)) - gwidoc(gwi, "Operators class types."); - GWI_BB(gwi_oper_ini(gwi, "Class", "Class", "bool")) - GWI_BB(gwi_oper_end(gwi, "==", int_eq)) - GWI_BB(gwi_oper_end(gwi, "!=", int_neq)) - GWI_BB(gwi_oper_end(gwi, ">=", instr_class_ge)) - GWI_BB(gwi_oper_end(gwi, ">", instr_class_gt)) - GWI_BB(gwi_oper_end(gwi, "<=", instr_class_le)) - GWI_BB(gwi_oper_end(gwi, "<", instr_class_lt)) - - gwidoc(gwi, "internal constructor operator."); - GWI_BB(gwi_oper_ini(gwi, NULL, (m_str)OP_ANY_TYPE, NULL)) - GWI_BB(gwi_oper_add(gwi, opck_basic_ctor)) - GWI_BB(gwi_oper_end(gwi, "@ctor", NULL)) - gwidoc(gwi, "allow member access."); GWI_BB(gwi_oper_ini(gwi, "@Compound", (m_str)OP_ANY_TYPE, NULL)) GWI_BB(gwi_oper_add(gwi, opck_object_dot)) GWI_BB(gwi_oper_emi(gwi, opem_object_dot)) GWI_BB(gwi_oper_end(gwi, "@dot", NULL)) + GWI_BB(import_class(gwi)) + gwidoc(gwi, "allow static access."); GWI_BB(gwi_oper_ini(gwi, "Class", (m_str)OP_ANY_TYPE, NULL)) GWI_BB(gwi_oper_add(gwi, opck_object_dot)) GWI_BB(gwi_oper_emi(gwi, opem_object_dot)) GWI_BB(gwi_oper_end(gwi, "@dot", NULL)) - - gwidoc(gwi, "Allow binary call to constructors."); - GWI_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, "Class", NULL)) - GWI_BB(gwi_oper_add(gwi, opck_class_call)) - GWI_BB(gwi_oper_end(gwi, "=>", NULL)) - GWI_BB(import_deep_equal(gwi)); GWI_BB(import_dict(gwi)); + GWI_BB(import_gack(gwi)); // seemed need at a point to ease liking gwi_enum_ini(gwi, "@hidden_enum"); diff --git a/src/lib/lib_class.c b/src/lib/lib_class.c new file mode 100644 index 00000000..322a683b --- /dev/null +++ b/src/lib/lib_class.c @@ -0,0 +1,63 @@ +#include "gwion_util.h" +#include "gwion_ast.h" +#include "gwion_env.h" +#include "vm.h" +#include "instr.h" +#include "emit.h" +#include "gwion.h" +#include "object.h" +#include "operator.h" +#include "import.h" +#include "gwi.h" +#include "gack.h" +#include "traverse.h" + +#define mk_class_instr(op, arg0, arg1, ...) \ + static INSTR(instr_class_##op) { \ + POP_REG(shred, SZ_INT); \ + const Type l = *(Type *)(shred->reg - SZ_INT); \ + const Type r = *(Type *)(shred->reg); \ + *(m_uint *)(shred->reg - SZ_INT) = isa(arg0, arg1) > 0 __VA_ARGS__; \ + } +mk_class_instr(ge, l, r) mk_class_instr(gt, l, r, &&l != r) +mk_class_instr(le, r, l) mk_class_instr(lt, r, l, &&l != r) + + +static OP_CHECK(opck_class_call) { + const Exp_Binary *bin = (Exp_Binary *)data; + Exp_Call call = {.func = bin->rhs, .args = bin->lhs}; + Exp e = exp_self(bin); + e->exp_type = ae_exp_call; + memcpy(&e->d.exp_call, &call, sizeof(Exp_Call)); + return check_exp_call1(env, &e->d.exp_call) ?: env->gwion->type[et_error]; +} + +static OP_CHECK(opck_basic_ctor) { + const Exp_Call *call = (Exp_Call *)data; +// change to *no know constructor for {+G}%s{0}*? + ERR_N(exp_self(call)->pos, _("can't call a non-callable value")); +} + +GWION_IMPORT(class) { + + gwidoc(gwi, "Operators class types."); + GWI_BB(gwi_oper_ini(gwi, "Class", "Class", "bool")) + GWI_BB(gwi_oper_end(gwi, "==", int_eq)) + GWI_BB(gwi_oper_end(gwi, "!=", int_neq)) + GWI_BB(gwi_oper_end(gwi, ">=", instr_class_ge)) + GWI_BB(gwi_oper_end(gwi, ">", instr_class_gt)) + GWI_BB(gwi_oper_end(gwi, "<=", instr_class_le)) + GWI_BB(gwi_oper_end(gwi, "<", instr_class_lt)) + + gwidoc(gwi, "Allow binary call to constructors."); + GWI_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, "Class", NULL)) + GWI_BB(gwi_oper_add(gwi, opck_class_call)) + GWI_BB(gwi_oper_end(gwi, "=>", NULL)) + + gwidoc(gwi, "internal constructor operator."); + GWI_BB(gwi_oper_ini(gwi, NULL, (m_str)OP_ANY_TYPE, NULL)) + GWI_BB(gwi_oper_add(gwi, opck_basic_ctor)) + GWI_BB(gwi_oper_end(gwi, "@ctor", NULL)) + + return GW_OK; +} diff --git a/src/lib/lib_func.c b/src/lib/lib_func.c index fb7291e6..b8c33a10 100644 --- a/src/lib/lib_func.c +++ b/src/lib/lib_func.c @@ -47,7 +47,7 @@ ANN static Exp order_curry(const Env env, Exp fn, const Exp _arg) { if (hole) { if (!arg) { if (base) free_exp(mp, base); - ERR_O(fn->pos, "no enough arguments for holes"); + ERR_O(fn->pos, "not enough arguments for holes"); } arg = arg->next; } @@ -76,9 +76,11 @@ static OP_CHECK(opck_curry) { e->exp_type = ae_exp_call; e->type = NULL; memcpy(&e->d.exp_call, &call, sizeof(Exp_Call)); + const MemPool mp = env->gwion->mp; free_exp(mp, base.args); free_exp(mp, lhs); + return check_exp_call1(env, &e->d.exp_call) ?: env->gwion->type[et_error]; } @@ -116,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); } } @@ -146,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 && - base[1]->func->value_ref->from->owner_class) - arg0 = arg0->next; - if(!base[1]->func->value_ref->from->owner_class && - 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) { @@ -193,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")) @@ -263,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 = mp_vector_at(bases, Arg, i); + Arg *arg = mp_vector_at(args, Arg, i); + 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) @@ -305,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 = mp_vector_at(args, Arg, i); + 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; @@ -312,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; } @@ -361,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]; @@ -369,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); @@ -481,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 = mp_vector_at(args, Arg, i); + 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); @@ -519,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 @@ -536,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); @@ -566,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); @@ -582,15 +623,18 @@ 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); + Stmt_List slist = new_mp_vector(env->gwion->mp, sizeof(struct Stmt_), 1); + mp_vector_set(slist, struct Stmt_, 0, + ((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); @@ -616,10 +660,13 @@ 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); + Stmt_List slist = new_mp_vector(env->gwion->mp, sizeof(struct Stmt_), 1); + mp_vector_set(slist, struct Stmt_, 0, + ((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; diff --git a/src/lib/lib_gack.c b/src/lib/lib_gack.c new file mode 100644 index 00000000..623b3f7a --- /dev/null +++ b/src/lib/lib_gack.c @@ -0,0 +1,58 @@ +#include "gwion_util.h" +#include "gwion_ast.h" +#include "gwion_env.h" +#include "vm.h" +#include "instr.h" +#include "emit.h" +#include "gwion.h" +#include "object.h" +#include "operator.h" +#include "import.h" +#include "gwi.h" +#include "gack.h" + +static GACK(gack_gack) { INTERP_PRINTF("%s", *(m_str *)VALUE) } + +static OP_CHECK(opck_gack_implicit) { + const struct Implicit *imp = (struct Implicit *)data; + return imp->t; +} + +static OP_EMIT(opem_gack_implicit) { + const struct Implicit *imp = (struct Implicit *)data; + const Type t = imp->e->d.prim.d.exp->cast_to ?: imp->e->d.prim.d.exp->type; + if(t == imp->t) { + const Instr cpy = emit_add_instr(emit, Reg2RegOther2); // kind + cpy->m_val2 = SZ_INT; + const Instr instr = emit_add_instr(emit, RegMove); + instr->m_val = imp->t->size - SZ_INT; + } else { + const Instr push = emit_add_instr(emit, RegMove); + push->m_val = SZ_INT; + struct Op_Import opi = {.lhs = t, + .op = insert_symbol(emit->gwion->st, "@implicit"), + .rhs = imp->t}; + CHECK_BB(op_emit(emit, &opi)); + const Instr pop = emit_add_instr(emit, RegMove); + pop->m_val = -SZ_INT; + const Instr cpy = emit_add_instr(emit, Reg2RegOther2); // kind + cpy->m_val = cpy->m_val2 = imp->t->size; + } + return GW_OK; +} + +GWION_IMPORT(gack) { + + gwidoc(gwi, "a type for *pretty print*."); + const Type t_gack = gwi_mk_type(gwi, "@Gack", SZ_INT, NULL); + GWI_BB(gwi_gack(gwi, t_gack, gack_gack)) + GWI_BB(gwi_set_global_type(gwi, t_gack, et_gack)); + + gwidoc(gwi, "@Gack implicit cast"); + GWI_BB(gwi_oper_ini(gwi, "@Gack", (m_str)OP_ANY_TYPE, NULL)) + GWI_BB(gwi_oper_add(gwi, opck_gack_implicit)) + GWI_BB(gwi_oper_emi(gwi, opem_gack_implicit)) + GWI_BB(gwi_oper_end(gwi, "@implicit", NULL)) + + return GW_OK; +} diff --git a/src/lib/modules.c b/src/lib/modules.c index 76bffd3d..21f8e0ea 100644 --- a/src/lib/modules.c +++ b/src/lib/modules.c @@ -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, diff --git a/src/lib/object_op.c b/src/lib/object_op.c index d4c5d8d3..b704b764 100644 --- a/src/lib/object_op.c +++ b/src/lib/object_op.c @@ -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; @@ -71,6 +73,7 @@ ANN /*static*/ Type scan_class(const Env env, const Type t, static OP_CHECK(opck_struct_scan) { struct TemplateScan *ts = (struct TemplateScan *)data; + if(ts->t->info->cdef->base.tmpl->call) return ts->t; return scan_class(env, ts->t, ts->td) ?: env->gwion->type[et_error]; } @@ -285,7 +288,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 +329,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; } diff --git a/src/lib/ptr.c b/src/lib/ptr.c index bdc2cc7d..ce0ab9b1 100644 --- a/src/lib/ptr.c +++ b/src/lib/ptr.c @@ -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]; diff --git a/src/lib/ref.c b/src/lib/ref.c index 5bef6aa2..67a1b245 100644 --- a/src/lib/ref.c +++ b/src/lib/ref.c @@ -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); diff --git a/src/lib/shred.c b/src/lib/shred.c index 067a5faa..441d421c 100644 --- a/src/lib/shred.c +++ b/src/lib/shred.c @@ -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; diff --git a/src/lib/tmpl_info.c b/src/lib/tmpl_info.c index 0b88412f..4b294af5 100644 --- a/src/lib/tmpl_info.c +++ b/src/lib/tmpl_info.c @@ -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) { diff --git a/src/main.c b/src/main.c index 225f6254..1a0a5f4f 100644 --- a/src/main.c +++ b/src/main.c @@ -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 = {}; diff --git a/src/parse/check.c b/src/parse/check.c index a59b4e8f..4b16d1e6 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -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, @@ -413,6 +413,7 @@ ANN static Type check_prim_hack(const Env env, const Exp *data) { CHECK_OO(check_prim_interp(env, data)); env_weight(env, 1); return env->gwion->type[et_gack]; +// return (*data)->type; } #define describe_prim_xxx(name, type) \ @@ -476,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, @@ -494,37 +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 && args_len == i) return func; } while ((func = func->next)); return NULL; } @@ -581,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; } @@ -597,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 ")); @@ -606,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) @@ -637,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); @@ -696,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) { @@ -742,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)) @@ -753,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) { @@ -860,8 +876,9 @@ ANN static Type check_exp_binary(const Env env, const Exp_Binary *bin) { if (is_auto) bin->rhs->d.exp_decl.type = bin->lhs->type; CHECK_OO(check_exp(env, bin->rhs)); if (is_auto) { - bin->rhs->type = bin->lhs->type; - set_vflag(bin->rhs->d.exp_decl.list->self->value, vflag_assigned); + assert(bin->rhs->type == bin->lhs->type); +// bin->rhs->type = bin->lhs->type; + 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, @@ -872,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; } @@ -916,7 +933,8 @@ ANN static m_bool predefined_call(const Env env, const Type t, ANN2(1) static inline bool curried(const Env env, Exp exp) { while (exp) { - if (is_hole(env, exp)) return true; + if (is_hole(env, exp)) + return true; exp = exp->next; } return false; @@ -1027,10 +1045,10 @@ 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); + Arg_List args = new_mp_vector(env->gwion->mp, sizeof(Arg), 1); + mp_vector_set(args, Arg, 0, ((Arg) { .td = td, .var_decl = decl })); 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); @@ -1039,17 +1057,22 @@ 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); + Stmt_List body = new_mp_vector(env->gwion->mp, sizeof(struct Stmt_), 1); + mp_vector_set(body, struct Stmt_, 0, + ((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]; @@ -1071,11 +1094,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) @@ -1116,8 +1140,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; @@ -1269,8 +1295,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) @@ -1375,16 +1402,33 @@ 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 Stmt s = mp_vector_at(stmt->list, struct Stmt_, i); + 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, @@ -1400,14 +1444,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); @@ -1464,8 +1501,10 @@ 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 Stmt s = mp_vector_at(l, struct Stmt_, i); + CHECK_BB(check_stmt(env, s)); + } return GW_OK; } @@ -1617,7 +1656,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; @@ -1681,7 +1720,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; } @@ -1689,29 +1728,31 @@ 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++) { + Section * section = mp_vector_at(ast, Section, i); 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 Stmt stmt = mp_vector_at(l, struct Stmt_, i); 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; } @@ -1748,7 +1789,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"), @@ -1786,32 +1827,34 @@ 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 Section *section = mp_vector_at(ast, Section, i); 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 Stmt stmt = mp_vector_at(l, struct Stmt_, i); 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; } @@ -1908,12 +1951,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); @@ -1956,9 +1994,12 @@ 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++) { + Section * section = mp_vector_at(a, Section, i); + CHECK_BB(check_section(env, section)); + } check_unhandled(env); return GW_OK; } diff --git a/src/parse/check_traits.c b/src/parse/check_traits.c index ce467006..aba6c009 100644 --- a/src/parse/check_traits.c +++ b/src/parse/check_traits.c @@ -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; } diff --git a/src/parse/compat_func.c b/src/parse/compat_func.c index 03d956ad..6b59d49c 100644 --- a/src/parse/compat_func.c +++ b/src/parse/compat_func.c @@ -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; } diff --git a/src/parse/func_operator.c b/src/parse/func_operator.c index 4020f08c..a9984d9b 100644 --- a/src/parse/func_operator.c +++ b/src/parse/func_operator.c @@ -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; diff --git a/src/parse/func_resolve_tmpl.c b/src/parse/func_resolve_tmpl.c index 0ffbbad5..4bc8c8a8 100644 --- a/src/parse/func_resolve_tmpl.c +++ b/src/parse/func_resolve_tmpl.c @@ -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; } diff --git a/src/parse/operator.c b/src/parse/operator.c index 8186a23a..ec73bd33 100644 --- a/src/parse/operator.c +++ b/src/parse/operator.c @@ -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; diff --git a/src/parse/scan0.c b/src/parse/scan0.c index 06e7aa2d..b5e41bd3 100644 --- a/src/parse/scan0.c +++ b/src/parse/scan0.c @@ -284,10 +284,6 @@ ANN m_bool scan0_union_def(const Env env, const Union_Def udef) { if (GET_FLAG(udef, global)) context_global(env); 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)); - udef->type->nspc->offset += SZ_INT; SET_ACCESS(udef, udef->type); if (udef->tmpl) union_tmpl(env, udef); if (global) env_pop(env, 0); @@ -335,14 +331,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 +358,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 Stmt stmt = mp_vector_at(l, struct Stmt_, i); + 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); + Stmt_List slist = new_mp_vector(p, sizeof(struct Stmt_), 1); + mp_vector_set(slist, struct Stmt_, 0, + ((struct Stmt_) { + .stmt_type = ae_stmt_return, .d = { .stmt_exp = { .val = ecall }}, + .pos = base_fdef->base->pos + })); + const Stmt body = new_stmt_code(p, slist, base->pos); + const Func_Def fdef = new_func_def(p, base, body); + Section section = MK_SECTION(func, func_def, fdef); + mp_vector_add(p, acc, Section, section); } - ast->next = next; - return ast; + args->len = len; } #define scan0_func_def dummy_func @@ -443,12 +436,13 @@ 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++) { + Section * section = mp_vector_at(ast, Section, i); + 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 +454,14 @@ 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++) { + Section *section = mp_vector_at(ast, Section, i); 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 +519,25 @@ 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++) { + Section * section = mp_vector_at(a, Section, i); + CHECK_BB(scan0_section(env, section)); + + if (section->section_type != ae_section_func || + !fbflag(section->d.func_def->base, fbflag_default)) continue; - (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 = mp_vector_at(acc, Section, i); + mp_vector_add(env->gwion->mp, ast, Section, *section); + } + free_mp_vector(env->gwion->mp, sizeof(Section), acc); + return GW_OK; } diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 88989cca..cc2d969c 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -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,11 @@ 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 Stmt s = mp_vector_at(l, struct Stmt_, i); + CHECK_BB(scan1_stmt_match_case(env, &s->d.stmt_match)); + } return GW_OK; } @@ -308,10 +310,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 +401,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 +413,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 +457,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 +483,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 +527,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 +582,11 @@ 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 Stmt s = mp_vector_at(l, struct Stmt_, i); + CHECK_BB(scan1_stmt(env, s)); + } +/* do { CHECK_BB(scan1_stmt(env, l->stmt)); if (l->next) { @@ -583,6 +605,7 @@ ANN static m_bool scan1_stmt_list(const Env env, Stmt_List l) { } } } while ((l = l->next)); +*/ return GW_OK; } @@ -599,7 +622,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 +652,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 +725,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 +776,11 @@ 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++) { + Section *section = mp_vector_at(a, Section, i); + CHECK_BB(scan1_section(env, section)); + } return GW_OK; } diff --git a/src/parse/scan2.c b/src/parse/scan2.c index a8390b00..6a426cd8 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -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,26 @@ 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 Stmt s = mp_vector_at(l, struct Stmt_, i); + 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 +288,11 @@ 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 Stmt s = mp_vector_at(l, struct Stmt_, i); + CHECK_BB(scan2_stmt(env, s)); + } return GW_OK; } @@ -390,9 +403,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 +417,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 +458,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 +514,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 +546,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 +599,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 +636,11 @@ 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++) { + Section *section = mp_vector_at(a, Section, i); + CHECK_BB(scan2_section(env, section)); + } return GW_OK; } diff --git a/src/parse/scanx.c b/src/parse/scanx.c index 487f65bb..03e0d992 100644 --- a/src/parse/scanx.c +++ b/src/parse/scanx.c @@ -7,8 +7,10 @@ #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++) { + Section *section = mp_vector_at(b, Section, i); + CHECK_BB(f(e, section)); + } return GW_OK; } diff --git a/src/parse/template.c b/src/parse/template.c index 0a72a547..00392f10 100644 --- a/src/parse/template.c +++ b/src/parse/template.c @@ -14,16 +14,19 @@ 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)); - } - tl = tl->next; - sl = sl->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)); + 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)); + } + } } struct Op_Import opi = {.op = insert_symbol("@scan"), .lhs = t, diff --git a/src/parse/traverse.c b/src/parse/traverse.c index c9d36fb8..4289cacb 100644 --- a/src/parse/traverse.c +++ b/src/parse/traverse.c @@ -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)); diff --git a/src/parse/type_decl.c b/src/parse/type_decl.c index a71d20e1..33b74385 100644 --- a/src/parse/type_decl.c +++ b/src/parse/type_decl.c @@ -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) { diff --git a/src/pass.c b/src/pass.c index 7daaba71..e077012f 100644 --- a/src/pass.c +++ b/src/pass.c @@ -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; diff --git a/src/plug.c b/src/plug.c index 7a4ff55a..cd643762 100644 --- a/src/plug.c +++ b/src/plug.c @@ -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) { diff --git a/src/vm/vm.c b/src/vm/vm.c index 94defc66..1d82e31d 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -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/ptr_assign_invalid.gw b/tests/error/ptr_assign_invalid.gw index 5bab97e0..0ac8fb4c 100644 --- a/tests/error/ptr_assign_invalid.gw +++ b/tests/error/ptr_assign_invalid.gw @@ -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 index 27c37c0e..00000000 --- a/tests/new/test.gw +++ /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 index a4c174e4..00000000 --- a/tests/new/test2.gw +++ /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; diff --git a/tests/plug/pass.c b/tests/plug/pass.c index fd52f6fa..5b64aea6 100644 --- a/tests/plug/pass.c +++ b/tests/plug/pass.c @@ -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 186bade2..923e360e 160000 --- a/util +++ b/util @@ -1 +1 @@ -Subproject commit 186bade285100f2da04033429640b95d2f72cb2f +Subproject commit 923e360e10f309a23cc36c50e9e0ca44f22bd2d4 -- 2.43.0