]> Nishi Git Mirror - gwion.git/commitdiff
New plug system (#220)
authorJérémie Astor <fennecdjay@gmail.com>
Sun, 8 Nov 2020 22:55:15 +0000 (23:55 +0100)
committerGitHub <noreply@github.com>
Sun, 8 Nov 2020 22:55:15 +0000 (23:55 +0100)
* Fix Flags

* Fix Flags

* :art: Introduce '#require'

* :art: Move tests

* :art: Small fixes

* :white_check_mark: Update tests (parralel lib testing)

* :white_check_mark: Thorough plug testing

* :art: Improve vararg import

* :art: Improve plug API

* :bug: Fix structs

* :art: Improve plug API

* :white_check_mark: Test struct import

* :white_check_mark: Some string tests

* :white_check_mark: test string find

* :art: Rework string lib

* :art: Add strings.h (Windows)

* :art: Update plug

* :wrench: Ignore coverage files

* :art: Use strstr family

* :art: Update

* :art: Update macro arguments system

* :art: Remove uselss defines

* :wrench: Coverage cleaning

* :wrench: Improve build system

* :art: Improve ARC

* :wrench: Fix coverage

* :wrench: Fix coverage

* :art: Remove useless code

* :art: Typo

* :art: Improve import system

256 files changed:
.github/workflows/coverage.yml
.gitignore
Makefile
ast
include/arg.h
include/engine.h
include/env/context.h
include/env/envset.h
include/env/func.h
include/env/nspc.h
include/env/oo.h
include/env/type.h
include/env/value.h
include/gwi.h
include/gwiondata.h
include/import/cdef.h
include/import/checker.h
include/instr.h
include/parse.h
include/plug.h
include/vm.h
plug
po/fr/gwion.mo [new file with mode: 0644]
scripts/test.sh
src/arg.c
src/clean.c
src/compile.c
src/emit/emit.c
src/emit/emitter.c
src/env/context.c
src/env/env.c
src/env/env_utils.c
src/env/envset.c
src/env/func.c
src/env/nspc.c
src/env/tupleform.c
src/env/type.c
src/env/type_special.c
src/env/value.c
src/gwion.c
src/gwiondata.c
src/import/import_cdef.c
src/import/import_checker.c
src/import/import_enum.c
src/import/import_fdef.c
src/import/import_internals.c
src/import/import_item.c
src/import/import_special.c
src/import/import_tdef.c
src/import/import_udef.c
src/lib/engine.c
src/lib/event.c
src/lib/instr.c
src/lib/lib_func.c
src/lib/modules.c
src/lib/object.c
src/lib/object_op.c
src/lib/ptr.c
src/lib/shred.c
src/lib/string.c
src/lib/ugen.c
src/lib/vararg.c
src/parse/check.c
src/parse/func_operator.c
src/parse/func_resolve_tmpl.c
src/parse/operator.c
src/parse/scan0.c
src/parse/scan1.c
src/parse/scan2.c
src/parse/scanx.c
src/parse/stage.c
src/parse/template.c
src/parse/traverse.c
src/plug.c
src/vm/gack.c
src/vm/vm.c
src/vm/vm_code.c
src/vm/vm_shred.c
tests/driver/Makefile [moved from tests/import/Makefile with 100% similarity]
tests/driver/non_driver.c [new file with mode: 0644]
tests/driver/simple_driver.c [moved from tests/import/driver.c with 53% similarity]
tests/error/final_func.gw [new file with mode: 0644]
tests/error/final_inherit.gw [new file with mode: 0644]
tests/error/must_abstract0.gw [new file with mode: 0644]
tests/error/must_abstract1.gw [new file with mode: 0644]
tests/error/no_inherit.gw [deleted file]
tests/error/require_fail.gw [new file with mode: 0644]
tests/fork/fork_call.gw
tests/import/specialid_emit.gw [deleted file]
tests/module/Makefile [new file with mode: 0644]
tests/module/basic_module.c [moved from tests/import/basic_module.c with 93% similarity]
tests/module/get_module.c [moved from tests/import/get_module.c with 71% similarity]
tests/module/get_module.gw [new file with mode: 0644]
tests/module/module.c [moved from tests/import/module.c with 92% similarity]
tests/plug/Makefile [new file with mode: 0644]
tests/plug/array.c [moved from tests/import/array.c with 100% similarity]
tests/plug/array.gw [new file with mode: 0644]
tests/plug/array_in_var_name.c [moved from tests/import/array_in_var_name.c with 100% similarity]
tests/plug/array_in_var_name.gw [new file with mode: 0644]
tests/plug/array_in_var_name_fail.c [moved from tests/import/array_in_var_name_fail.c with 100% similarity]
tests/plug/array_in_var_name_fail.gw [new file with mode: 0644]
tests/plug/array_incoherent_in_var_name.c [moved from tests/import/array_incoherent_in_var_name.c with 100% similarity]
tests/plug/array_incoherent_in_var_name.gw [new file with mode: 0644]
tests/plug/array_invalid_in_var_name.c [moved from tests/import/array_invalid_in_var_name.c with 100% similarity]
tests/plug/array_invalid_in_var_name.gw [new file with mode: 0644]
tests/plug/callback.c [moved from tests/import/callback.c with 100% similarity]
tests/plug/callback.gw [new file with mode: 0644]
tests/plug/callback.gwold [moved from tests/import/callback.gwold with 100% similarity]
tests/plug/callback2.gw [moved from tests/import/callback2.gw with 100% similarity]
tests/plug/class_template.c [moved from tests/import/class_template.c with 89% similarity]
tests/plug/class_template.gw [moved from tests/import/class_template.gw with 67% similarity]
tests/plug/class_template_fail.c [moved from tests/import/class_template_fail.c with 100% similarity]
tests/plug/class_template_fail.gw [new file with mode: 0644]
tests/plug/class_template_invalid.c [moved from tests/import/class_template_invalid.c with 84% similarity]
tests/plug/class_template_invalid.gw [new file with mode: 0644]
tests/plug/compile_file.c [moved from tests/import/compile_file.c with 100% similarity]
tests/plug/compile_file.gw [new file with mode: 0644]
tests/plug/compile_string.c [moved from tests/import/compile_string.c with 100% similarity]
tests/plug/compile_string.gw [new file with mode: 0644]
tests/plug/coverage.c [moved from tests/import/coverage.c with 100% similarity]
tests/plug/coverage.gw [moved from tests/import/coverage.gw with 88% similarity]
tests/plug/deps.c [new file with mode: 0644]
tests/plug/deps.gw [new file with mode: 0644]
tests/plug/empty_union.c [moved from tests/import/empty_union.c with 100% similarity]
tests/plug/empty_union.gw [new file with mode: 0644]
tests/plug/end_class.c [moved from tests/import/end_class.c with 100% similarity]
tests/plug/end_class.gw [new file with mode: 0644]
tests/plug/enum.c [moved from tests/import/enum.c with 100% similarity]
tests/plug/enum.gw [moved from tests/import/enum.gw with 98% similarity]
tests/plug/enum_fail.c [moved from tests/import/enum_fail.c with 100% similarity]
tests/plug/enum_fail.gw [new file with mode: 0644]
tests/plug/enum_fail2.c [moved from tests/import/enum_fail2.c with 100% similarity]
tests/plug/enum_fail2.gw [new file with mode: 0644]
tests/plug/enum_fail3.c [moved from tests/import/enum_fail3.c with 100% similarity]
tests/plug/enum_fail3.gw [new file with mode: 0644]
tests/plug/extend_array.c [moved from tests/import/extend_array.c with 100% similarity]
tests/plug/extend_array.gw [moved from tests/import/extend_array.gw with 67% similarity]
tests/plug/fail_on_next_arg.c [moved from tests/import/fail_on_next_arg.c with 100% similarity]
tests/plug/fail_on_next_arg.gw [new file with mode: 0644]
tests/plug/fail_on_next_arg2.c [moved from tests/import/fail_on_next_arg2.c with 100% similarity]
tests/plug/fail_on_next_arg2.gw [new file with mode: 0644]
tests/plug/fptr.c [moved from tests/import/fptr.c with 100% similarity]
tests/plug/fptr.gw [moved from tests/import/fptr.gw with 94% similarity]
tests/plug/fptr_tmpl.c [moved from tests/import/fptr_tmpl.c with 100% similarity]
tests/plug/fptr_tmpl.gw [new file with mode: 0644]
tests/plug/fptr_tmpl_fail.c [moved from tests/import/fptr_tmpl_fail.c with 100% similarity]
tests/plug/fptr_tmpl_fail.gw [new file with mode: 0644]
tests/plug/func_fail.c [moved from tests/import/func_fail.c with 100% similarity]
tests/plug/func_fail.gw [new file with mode: 0644]
tests/plug/func_fail2.c [moved from tests/import/func_fail2.c with 100% similarity]
tests/plug/func_fail2.gw [new file with mode: 0644]
tests/plug/func_fail3.c [moved from tests/import/func_fail3.c with 100% similarity]
tests/plug/func_fail3.gw [new file with mode: 0644]
tests/plug/func_fail4.c [moved from tests/import/func_fail4.c with 100% similarity]
tests/plug/func_fail4.gw [new file with mode: 0644]
tests/plug/func_subscript_not_empty.c [moved from tests/import/func_subscript_not_empty.c with 100% similarity]
tests/plug/func_subscript_not_empty.gw [new file with mode: 0644]
tests/plug/func_tmpl.c [moved from tests/import/func_tmpl.c with 100% similarity]
tests/plug/func_tmpl.gw [moved from tests/import/func_tmpl.gw with 55% similarity]
tests/plug/func_tmpl_fail.c [moved from tests/import/func_tmpl_fail.c with 100% similarity]
tests/plug/func_tmpl_fail.gw [new file with mode: 0644]
tests/plug/func_too_many_arg.c [moved from tests/import/func_too_many_arg.c with 100% similarity]
tests/plug/func_too_many_arg.gw [new file with mode: 0644]
tests/plug/global_func.c [moved from tests/import/global_func.c with 100% similarity]
tests/plug/global_func.gw [moved from tests/import/global_func.gw with 61% similarity]
tests/plug/global_var.c [moved from tests/import/global_var.c with 100% similarity]
tests/plug/global_var.gw [moved from tests/import/global_var.gw with 73% similarity]
tests/plug/invalid_arg.c [moved from tests/import/invalid_arg.c with 100% similarity]
tests/plug/invalid_arg.gw [new file with mode: 0644]
tests/plug/invalid_array.c [moved from tests/import/invalid_array.c with 100% similarity]
tests/plug/invalid_array.gw [new file with mode: 0644]
tests/plug/invalid_func.c [moved from tests/import/invalid_func.c with 100% similarity]
tests/plug/invalid_func.gw [new file with mode: 0644]
tests/plug/invalid_names.c [moved from tests/import/invalid_names.c with 100% similarity]
tests/plug/invalid_names.gw [new file with mode: 0644]
tests/plug/invalid_names0.c [moved from tests/import/invalid_names0.c with 100% similarity]
tests/plug/invalid_names0.gw [new file with mode: 0644]
tests/plug/invalid_names1.c [moved from tests/import/invalid_names1.c with 100% similarity]
tests/plug/invalid_names1.gw [new file with mode: 0644]
tests/plug/invalid_names2.c [moved from tests/import/invalid_names2.c with 100% similarity]
tests/plug/invalid_names2.gw [new file with mode: 0644]
tests/plug/invalid_names3.c [moved from tests/import/invalid_names3.c with 100% similarity]
tests/plug/invalid_names3.gw [new file with mode: 0644]
tests/plug/invalid_type1.c [moved from tests/import/invalid_type1.c with 100% similarity]
tests/plug/invalid_type1.gw [new file with mode: 0644]
tests/plug/invalid_type2.c [moved from tests/import/invalid_type2.c with 100% similarity]
tests/plug/invalid_type2.gw [new file with mode: 0644]
tests/plug/invalid_type3.c [moved from tests/import/invalid_type3.c with 100% similarity]
tests/plug/invalid_type3.gw [new file with mode: 0644]
tests/plug/map2.gw [moved from tests/import/map2.gw with 100% similarity]
tests/plug/mk_type_array.c [moved from tests/import/mk_type_array.c with 100% similarity]
tests/plug/mk_type_array.gw [new file with mode: 0644]
tests/plug/no_import.c [moved from tests/import/no_import.c with 100% similarity]
tests/plug/no_import.gw [new file with mode: 0644]
tests/plug/not_importing.c [moved from tests/import/not_importing.c with 100% similarity]
tests/plug/not_importing.gw [new file with mode: 0644]
tests/plug/op_already_imported.c [moved from tests/import/op_already_imported.c with 99% similarity]
tests/plug/op_already_imported.gw [moved from tests/import/op_already_imported.gw with 59% similarity]
tests/plug/pass.c [moved from tests/import/pass.c with 100% similarity]
tests/plug/pass.gw [new file with mode: 0644]
tests/plug/rm_me.gw [moved from tests/import/rm_me.gw with 100% similarity]
tests/plug/specialid_emit.c [moved from tests/import/specialid_emit.c with 100% similarity]
tests/plug/specialid_emit.gw [new file with mode: 0644]
tests/plug/static_string.c [moved from tests/import/static_string.c with 100% similarity]
tests/plug/static_string.gw [moved from tests/import/static_string.gw with 65% similarity]
tests/plug/str2decl.c [moved from tests/import/str2decl.c with 100% similarity]
tests/plug/str2decl.gw [new file with mode: 0644]
tests/plug/str2list_fail.c [moved from tests/import/str2list_fail.c with 100% similarity]
tests/plug/str2list_fail.gw [new file with mode: 0644]
tests/plug/struct.c [new file with mode: 0644]
tests/plug/struct.gw [new file with mode: 0644]
tests/plug/template_arg.c [moved from tests/import/template_arg.c with 100% similarity]
tests/plug/template_arg.gw [new file with mode: 0644]
tests/plug/trig.c [moved from tests/import/trig.c with 100% similarity]
tests/plug/trig.gw [moved from tests/import/trig.gw with 89% similarity]
tests/plug/typedef.c [moved from tests/import/typedef.c with 100% similarity]
tests/plug/typedef.gw [moved from tests/import/typedef.gw with 81% similarity]
tests/plug/typedef_fail.c [moved from tests/import/typedef_fail.c with 100% similarity]
tests/plug/typedef_fail.gw [new file with mode: 0644]
tests/plug/typedef_tmpl.c [moved from tests/import/typedef_tmpl.c with 100% similarity]
tests/plug/typedef_tmpl.gw [new file with mode: 0644]
tests/plug/ugen_connect.c [moved from tests/import/ugen_connect.c with 100% similarity]
tests/plug/ugen_connect.gw [new file with mode: 0644]
tests/plug/union.c [moved from tests/import/union.c with 100% similarity]
tests/plug/union.gw [moved from tests/import/union.gw with 89% similarity]
tests/plug/union_fail_exp.c [moved from tests/import/union_fail_exp.c with 100% similarity]
tests/plug/union_fail_exp.gw [new file with mode: 0644]
tests/plug/union_member.c [moved from tests/import/union_member.c with 100% similarity]
tests/plug/union_member.gw [new file with mode: 0644]
tests/plug/union_name.c [moved from tests/import/union_name.c with 100% similarity]
tests/plug/union_name.gw [moved from tests/import/union_name.gw with 64% similarity]
tests/plug/union_tmpl.c [moved from tests/import/union_tmpl.c with 100% similarity]
tests/plug/union_tmpl.gw [moved from tests/import/union_tmpl.gw with 64% similarity]
tests/plug/union_tmpl_fail.c [moved from tests/import/union_tmpl_fail.c with 100% similarity]
tests/plug/union_tmpl_fail.gw [new file with mode: 0644]
tests/plug/union_tmpl_fail2.c [moved from tests/import/union_tmpl_fail2.c with 100% similarity]
tests/plug/union_tmpl_fail2.gw [new file with mode: 0644]
tests/plug/union_tmpl_fail3.c [moved from tests/import/union_tmpl_fail3.c with 100% similarity]
tests/plug/union_tmpl_fail3.gw [new file with mode: 0644]
tests/plug/variadic.c [moved from tests/import/variadic.c with 91% similarity]
tests/plug/variadic.gw [moved from tests/import/variadic.gw with 94% similarity]
tests/plug/vm_remove.c [moved from tests/import/vm_remove.c with 100% similarity]
tests/plug/vm_remove.gw [moved from tests/import/vm_remove.gw with 50% similarity]
tests/sh/import.sh
tests/sh/opt.sh
tests/string/charAt.gw [new file with mode: 0644]
tests/string/eq.gw
tests/string/find.gw [new file with mode: 0644]
tests/string/lower.gw [new file with mode: 0644]
tests/string/ltrim.gw [new file with mode: 0644]
tests/string/rtrim.gw [new file with mode: 0644]
tests/string/size.gw [new file with mode: 0644]
tests/string/trim.gw [new file with mode: 0644]
tests/string/upper.gw [new file with mode: 0644]
tests/struct/struct_template.gw
util

index a84ad3dc8f4126b5a6282a12bf4765e2408f2e54..08164c6ff87a6f5b4f211c9c98bcd2e23af1fa7c 100644 (file)
@@ -80,17 +80,12 @@ jobs:
         cd gwion-coverage-report
         bash badge.sh
 
-    - name: Make html mail
-      uses: docker://pandoc/core:2.9
-      with:
-        args: "--from gfm --to html -o diff.html gwion-coverage-report/diff.md"
-
     - name: Push Report
       if: github.event_name == 'push'
       run: |
         branch=$(basename ${{ github.event.ref }})
-        cp diff.html gwion-coverage-report/html/$branch
         cd gwion-coverage-report
+        cp diff.md html/$branch
         git config --local user.email "action@github.com"
         git config --local user.name "GitHub Action"
         git remote set-url origin https://${{ secrets.COVERAGE_TOKEN }}@github.com/Gwion/gwion-coverage-report.git
index 29ba8fb9cf802485b5000ed2eadfb6cfba45c174..1783da30d8766557f8e81acea04b6b05c8cae289 100644 (file)
@@ -10,3 +10,5 @@ mkdocs.yml
 *.a
 *.o
 *.so
+*.gcda
+*.gcno
index a5e21942a0612435fd7e30665cc839c83e566681..bf82589d295033898a1b7bf75f3583c42c1ab960 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -11,13 +11,12 @@ SEVERITY ?= 10
 GWION_TEST_DIR ?= /tmp
 
 GWION_PACKAGE=gwion
-CFLAGS += -DGWION_PACKAGE='"${GWION_PACKAGE}"'
 
 src := $(wildcard src/*.c)
 src += $(wildcard src/*/*.c)
 
 test_dir_all := $(wildcard tests/*)
-test_ignore = tests/import
+test_ignore = tests/plug test/driver tests/module
 test_dir := $(filter-out $(test_ignore), $(test_dir_all))
 test_dir += examples
 
diff --git a/ast b/ast
index 7a595b66afa08bb840222b7297e08e030e2232eb..f75d51f0b87497057ccf739063a1a6b58fe3da2f 160000 (submodule)
--- a/ast
+++ b/ast
@@ -1 +1 @@
-Subproject commit 7a595b66afa08bb840222b7297e08e030e2232eb
+Subproject commit f75d51f0b87497057ccf739063a1a6b58fe3da2f
index ae9746ad8af4ed9ce957a7e287b7b329c0892f94..dfaf85870d0796b6e634a7d58b6bcb2e6b522dd0 100644 (file)
@@ -3,15 +3,15 @@
 
 typedef struct Arg_ {
   struct CArg    arg;
+  struct Map_    mod;
   struct Vector_ add;
   struct Vector_ lib;
-  struct Vector_ mod;
   struct Vector_ config;
   struct SoundInfo_ *si;
   m_bool loop;
-  m_bool read_stdin;
 } Arg;
 
 ANN void arg_release(Arg*);
 ANN m_bool arg_parse(const Gwion, Arg*);
+ANN void arg_compile(const Gwion, Arg*);
 #endif
index 728d16e6fcca4522044785bed4f3d59fd32abe5c..4d1c008c8aef41fd175648874d66da52af8f219b 100644 (file)
@@ -1,4 +1,4 @@
 #ifndef __ENGINE
 #define __ENGINE
-ANN m_bool type_engine_init(const Gwion gwion, const Vector);
+ANN m_bool type_engine_init(const Gwion gwion);
 #endif
index 61c3fa61bfb7331121974a263107fb40d0e6afd2..53a1280010f95541acf01e5121ef27f1d32b1341 100644 (file)
@@ -6,12 +6,15 @@ struct Context_ {
   Ast         tree;
   Nspc        nspc;
   struct Map_ lbls;
-  HAS_OBJ
+  uint16_t ref;
   m_bool error;
   m_bool global;
 };
 
-ANN2(2) ANEW Context new_context(MemPool p, const Ast, const m_str);
+ANN void free_context(const Context, struct Gwion_*const);
+ANN static inline void context_addref(const Context c) { ++c->ref; }
+ANN static inline void context_remref(const Context c, struct Gwion_ *const gwion) { if(!--c->ref) free_context(c, gwion); }
+ANN2(1,3) ANEW Context new_context(MemPool p, const Ast, const m_str);
 ANN void load_context(const Context, const Env);
 ANN void unload_context(const Context, const Env);
 #endif
index 1e11c9b9311f87cada5675dff664ccd32e542322..c9838df6997cf489ac20854d805c6f63d3bc2add 100644 (file)
@@ -7,7 +7,7 @@ struct EnvSet {
   const envset_func func;
   const void *data;
   const m_int scope;
-  const ae_flag flag;
+  const enum tflag flag;
   m_bool run;
 };
 
index 5375b0a630e26a86fbbfdb43b568542bad144582..e28a706ef74db777cf549bdd574c16f511e8d97d 100644 (file)
@@ -1,5 +1,14 @@
 #ifndef __FUNC
 #define __FUNC
+
+enum fflag {
+  fflag_none  = 1 << 0,
+  fflag_pure  = 1 << 1,
+  fflag_ftmpl = 1 << 2,
+  fflag_tmpl  = 1 << 3,
+  fflag_valid = 1 << 4,
+} __attribute__((packed));
+
 struct Func_ {
   m_str name;
   Func_Def def;
@@ -7,11 +16,40 @@ struct Func_ {
   Value value_ref;
   Func next;
   size_t vt_index;
-  HAS_OBJ
+  uint16_t ref;
   ae_flag flag;
+  enum fflag fflag;
 };
 
+ANN void free_func(const Func, struct Gwion_*const);
+ANN static inline void func_addref(const Func f) { ++f->ref; }
+ANN static inline void func_remref(const Func f, struct Gwion_ *const gwion) { if(!--f->ref) free_func(f, gwion); }
+
+static inline int fflag(const Func f, const enum fflag flag) {
+  return (f->fflag & flag) == flag;
+}
+#ifndef __cplusplus
+static inline void set_fflag(const Func f, const enum fflag flag) {
+  f->fflag |= flag;
+}
+
+static inline void unset_fflag(const Func f, const enum fflag flag) {
+  f->fflag &= ~flag;
+}
+#else
+static inline void set_fflag(const Func f, const enum fflag flag) {
+  const auto ff = f->fflag | flag;
+  f->fflag = static_cast<enum fflag>(ff);
+}
+
+static inline void unset_fflag(const Func f, const enum fflag flag) {
+  const auto ff = f->fflag & ~flag;
+  f->fflag = static_cast<enum fflag>(ff);
+}
+#endif
+
 ANEW ANN Func new_func(MemPool, const m_str, const Func_Def);
 ANN2(1,2) Symbol func_symbol(const Env, const m_str, const m_str, const m_str, const m_uint);
 ANN m_bool check_lambda(const Env, const Type, Exp_Lambda*);
+ANN void builtin_func(const MemPool mp, const Func f, void* func_ptr);
 #endif
index 9ce2f4f7f09a4fc4f5010d6208188a21e3ceeeea..1a70d73277a050fababb1704627362a7a903f881 100644 (file)
@@ -17,9 +17,12 @@ struct Nspc_ {
   struct VM_Code_*   pre_ctor;
   struct VM_Code_*   dtor;
   struct NspcInfo_* info;
-  HAS_OBJ
+  uint16_t ref;
 };
 
+ANN void free_nspc(const Nspc, struct Gwion_*const);
+ANN static inline void nspc_addref(const Nspc  n) { ++n->ref; }
+ANN static inline void nspc_remref(const Nspc n, struct Gwion_ *const gwion) { if(!--n->ref) free_nspc(n, gwion); }
 extern ANEW ANN Nspc new_nspc(MemPool p, const m_str name);
 
 extern ANN void nspc_commit(const Nspc);
index 1dc06485eee42d062bb3c7ec80860495233a39f2..92f8034309f51f0d8ab90229da9d90e9c517b36d 100644 (file)
@@ -1,30 +1,11 @@
 #ifndef __OO
 #define __OO
 
+typedef struct Gwion_      * Gwion;
+
 typedef struct Type_      * Type;
 typedef struct Nspc_      * Nspc;
 typedef struct Value_     * Value;
 typedef struct Func_      * Func;
 
-typedef struct RefCount_ {
-  void (*free)(void*,void*);
-  uint16_t count; // could be an unsigned short
-} RefCount;
-
-#define HAS_OBJ RefCount* ref;
-ANN static inline RefCount* new_refcount(MemPool mp, void(*free)(void*,void*)) {
-  RefCount *ref = (RefCount*)mp_calloc(mp, RefCount);
-  ref->count = 1;
-  ref->free= free;
-  return ref;
-}
-#define new_refcount(a, b) new_refcount(a, (void(*)(void*,void*))b)
-ANN static inline void rem_ref(MemPool mp, RefCount* a, void* ptr, void *gwion) {
-  if(--a->count)
-    return;
-  a->free(ptr, gwion);
-  mp_free(mp, RefCount, a);
-}
-#define ADD_REF(a)    { ++(a)->ref->count; }
-#define REM_REF(a, b)    { rem_ref(((Gwion)(b))->mp, (a)->ref, (a), (b)); }
 #endif
index 0ff7e13ffd7dc8a00ecebfc5f816de40a54c945c..5314dbb8b9b54389d2914e343d4ee4b460e7dad3 100644 (file)
@@ -5,7 +5,10 @@ struct TypeInfo_ {
   Type parent;
   Nspc owner;
   Type owner_class;
-  Class_Def def;
+  union {
+    Union_Def udef;
+    Class_Def cdef;
+  };
   union type_data {
     Func      func;
     Type      base_type;
@@ -15,6 +18,29 @@ struct TypeInfo_ {
   struct Context_ *ctx;
 };
 
+enum tflag {
+  tflag_none    = 1 << 0,
+  tflag_scan0   = 1 << 1,//
+  tflag_scan1   = 1 << 2,//
+  tflag_scan2   = 1 << 3,//
+  tflag_check   = 1 << 4,//
+  tflag_emit    = 1 << 5,//
+  tflag_infer   = 1 << 6,
+  tflag_empty   = 1 << 7,
+  tflag_ftmpl   = 1 << 8,
+  tflag_ntmpl   = 1 << 9, // do NOT need types
+  tflag_ctmpl   = 1 << 10, // child template
+  tflag_udef    = 1 << 11,
+  tflag_cdef    = 1 << 12,
+  tflag_struct  = 1 << 13,
+  tflag_ctor    = 1 << 14,
+  tflag_dtor    = 1 << 15,
+  tflag_tmpl    = 1 << 16,
+  tflag_typedef = 1 << 17,
+  tflag_nonnull = 1 << 18,
+  tflag_force   = 1 << 19,
+} __attribute__((packed));
+
 struct Type_ {
   m_str     name;
   Nspc      nspc;
@@ -22,10 +48,30 @@ struct Type_ {
   size_t xid;
   size_t size;
   size_t array_depth;
-  HAS_OBJ
+  uint16_t ref;
   ae_flag flag;
+  enum tflag tflag;
 };
 
+ANN void free_type(const Type, struct Gwion_*const);
+ANN static inline void type_addref(const Type t) { ++t->ref; }
+ANN static inline void type_remref(const Type t, struct Gwion_ *const gwion) { if(!--t->ref) free_type(t, gwion); }
+ANN static inline int tflag(const Type t, const enum tflag flag) {
+  return (t->tflag & flag) == flag;
+}
+static inline int safe_tflag(const Type t, const enum tflag flag) {
+  return t ? ((t->tflag & flag) == flag) : 0;
+}
+#ifndef __cplusplus
+ANN static inline void set_tflag(const Type t, const enum tflag flag) {
+  t->tflag |= flag;
+}
+#else
+ANN static inline void set_tflag(const Type t, const enum tflag flag) {
+  auto ff = t->tflag | flag;
+  t->tflag = static_cast<enum tflag>(ff);
+}
+#endif
 ANN2(1,3) ANEW Type new_type(MemPool, const m_uint xid, const m_str name, const Type);
 ANEW ANN Type type_copy(MemPool, const Type type);
 ANN m_str get_type_name(const Env, const Type t, const m_uint);
@@ -59,7 +105,7 @@ ANN Type unflag_type(const Type t);
 __attribute__((returns_nonnull))
 ANN Type get_type(const Type t);
 ANN static inline int is_special(const Type t) {
-  return GET_FLAG(t, nonnull) || GET_FLAG(t, force);
+  return tflag(t, tflag_nonnull) || tflag(t, tflag_force);
 }
 
 typedef enum {
index 2f592d39ceee25ac32032a659f166a46ce86fcc4..c3b334337fc9b2dff74277511c5301aa2dc6e688 100644 (file)
@@ -7,6 +7,20 @@ struct ValueFrom_ {
   size_t offset;
 };
 
+enum vflag {
+  vflag_none  = 1 << 0,
+  vflag_func  = 1 << 1,
+  vflag_union = 1 << 2,
+  vflag_enum  = 1 << 3,
+  vflag_freeme  = 1 << 4,
+  vflag_fglobal  = 1 << 5,
+  vflag_valid    = 1 << 6,
+  vflag_direct    = 1 << 7,
+  vflag_builtin    = 1 << 8,
+  vflag_member   = 1 << 9
+//  vflag_used = 1 << 3
+} __attribute__((packed));
+
 struct Value_ {
   Type type;
   m_str name;
@@ -15,10 +29,29 @@ struct Value_ {
     m_uint* ptr;
     Func func_ref;
   } d;
-  HAS_OBJ
+  uint16_t ref;
   ae_flag flag;
+  enum vflag vflag;
 };
 
+ANN void free_value(const Value, struct Gwion_*const);
+ANN static inline void value_addref(const Value v) { ++v->ref; }
+ANN static inline void value_remref(const Value v, struct Gwion_ *const gwion) { if(!--v->ref) free_value(v, gwion); }
+static inline int vflag(const Value v, const enum vflag flag) {
+  return (v->vflag & flag) == flag;
+}
+
+#ifndef __cplusplus
+static inline void set_vflag(const Value v, const enum vflag flag) {
+  v->vflag |= flag;
+}
+#else
+static inline void set_vflag(const Value v, const enum vflag flag) {
+  auto ff = v->vflag | flag;
+  v->vflag = static_cast<enum vflag>(ff);
+}
+#endif
+
 ANEW ANN Value new_value(MemPool p, const Type type, const m_str name);
 ANN void valuefrom(const Env, struct ValueFrom_*);
 #endif
index 6cee9bca6b9c08c7d952db13b2ee8f5c5770077d..d20124fdfbb3ea517289cf0abe6914f88cbbe292 100644 (file)
@@ -4,7 +4,7 @@
 #define loc(gwi) loc_cpy(gwi->gwion->mp, gwi->loc)
 
 struct Gwi_ {
-  struct Gwion_* gwion;
+  struct Gwion_ *const gwion;
   Ast body;
   struct ImportCK *ck;
   struct OperCK *oper; // _misc
@@ -15,4 +15,6 @@ struct Gwi_ {
 static inline Tmpl* gwi_tmpl(const Gwi gwi) {
   return new_tmpl_base(gwi->gwion->mp, gwi->ck->tmpl);
 }
+
+ANN m_bool gwi_run(const Gwion gwion, m_bool (*f)(const Gwi));
 #endif
index 046f15b7a718d8c7bb2af794ca4c31874ac42059..eccc3d15d9d0fb735ce487921e0048374b8671bc 100644 (file)
@@ -8,7 +8,7 @@ typedef struct GwionData_ {
   struct Vector_ child2;
   struct Vector_ reserved;
   struct Passes_  *passes;
-  PlugInfo* plug;
+  struct Map_ plug;
 } GwionData;
 
 ANN GwionData* new_gwiondata(MemPool);
index 25722edcfc6bcb0d7ec3248c2c74c30afbc661d0..3cdb9728fae791eea50f5c2562f489bbed82d804 100644 (file)
@@ -4,5 +4,6 @@ ANN2(1,2) Type gwi_class_ini(const Gwi gwi, const m_str, const m_str parent);
 ANN2(1,2) Type gwi_struct_ini(const Gwi gwi, const m_str);
 ANN2(1) void gwi_class_xtor(const Gwi gwi, const f_xtor ctor, const f_xtor dtor);
 ANN m_int gwi_class_end(const Gwi gwi);
+#define gwi_struct_end(a) gwi_class_end(a)
 ANN void inherit(const Type);
 #endif
index 3b1cc6ccb54cb90af787638b7f6f2c243f4974a4..5ef1d61aab9e830b4cb1356b38f75c96cc5a6872 100644 (file)
@@ -31,6 +31,7 @@ typedef struct ImportCK { // name_checker ?
     ID_List curr;// enum
   };
   ae_flag flag; // ????
+  uint variadic;
   enum importck_type type;
 } ImportCK;
 
index fa9b48529c2939e612d7b1982b96ccb6a874ceec..5e260639d9a5f9e32243304e43ef8529e90f586e 100644 (file)
@@ -63,6 +63,7 @@ struct dottmpl_ {
   Nspc owner;
   size_t vt_index;
   Type_List tl;
+  void* xfun;// (type is f_xfun)
 };
 ANN void free_dottmpl(struct dottmpl_*);
 ANN m_bool traverse_dot_tmpl(const Emitter emit, const struct dottmpl_ *dt);
index 6288998451bb3fc14ac1c6c5bedfc3ec934f1c8a..394a5314e76faac61aa4f23c40bb88b43ae65fc4 100644 (file)
@@ -48,7 +48,7 @@ ANN static m_bool prefix##_stmt_##name(const Env env, const type stmt) { \
 
 ANN m_uint union_push(const Env, const Union_Def);
 ANN void union_pop(const Env, const Union_Def, const m_uint);
-ANN void union_flag(const Union_Def, const ae_flag);
+ANN void union_flag(const Union_Def, const enum tflag);
 ANN m_bool check_stmt(const Env env, const Stmt stmt);
 
 typedef m_bool (*_exp_func)(const void*, const void*);
@@ -58,25 +58,19 @@ static inline ANN m_bool env_body(const Env env, const Class_Def cdef, const _ex
 }
 #define env_body(a,b,c) env_body(a,b,(_exp_func)c)
 
-ANN m_bool scanx_cdef(const Env, void *,const Class_Def,
+ANN m_bool scanx_cdef(const Env, void *, const Type,
   const _exp_func f_cdef, const _exp_func f_union);
 
-#define xxx_cdef(prefix)                                                  \
-static inline m_bool prefix##_cdef(const Env env, const Class_Def cdef) { \
-  return scanx_cdef(env, env, cdef,                                       \
-      (_exp_func)prefix##_class_def, (_exp_func)prefix##_union_def);      \
+#define xxx_cdef(prefix)                                             \
+static inline m_bool prefix##_cdef(const Env env, const Type t) {    \
+  return scanx_cdef(env, env, t,                                     \
+      (_exp_func)prefix##_class_def, (_exp_func)prefix##_union_def); \
 }
 
-#define xxx_cdef_flag(prefix)                                             \
-static inline m_bool prefix##_cdef(const Env env, const Class_Def cdef) { \
-  SET_FLAG(cdef, prefix);                                                 \
-  return scanx_cdef(env, env, cdef,                                       \
-      (_exp_func)prefix##_class_def, (_exp_func)prefix##_union_def);      \
-}
-xxx_cdef_flag(scan0)
-xxx_cdef_flag(scan1)
-xxx_cdef_flag(scan2)
-xxx_cdef_flag(check)
+xxx_cdef(scan0)
+xxx_cdef(scan1)
+xxx_cdef(scan2)
+xxx_cdef(check)
 xxx_cdef(traverse)
 
 ANN m_bool scanx_fdef(const Env, void *, const Func_Def, const _exp_func);
index 2065ae5d9aa47aa57a85e51da829500d91208cf9..bc258ac2751789064ba3efb0acd86fe33ea70ae6 100644 (file)
@@ -1,30 +1,22 @@
 #ifndef __PLUG
 #define __PLUG
 
-enum plug_t {
-  GWPLUG_DL,
-  GWPLUG_IMPORT,
-  GWPLUG_MODULE,
-  GWPLUG_LAST
-};
-
-typedef struct PlugInfo_ {
-  struct Map_ drv;
-  struct Vector_ vec[GWPLUG_LAST];
-} PlugInfo;
-
-ANN PlugInfo* new_pluginfo(MemPool, Vector);
-ANN void plug_run(const struct Gwion_*, const Vector);
+ANN m_bool plug_ini(const struct Gwion_*, const Vector);
+ANN m_bool driver_ini(const struct Gwion_*);
+ANN void plug_run(const struct Gwion_*, const Map);
 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);
+
 #define GWIMPORT_NAME    import
-#define GWMODSTR_NAME  gwmodstr
 #define GWMODINI_NAME  gwmodini
 #define GWMODEND_NAME  gwmodend
-#define GWDRIVER_NAME  gwmodend
-#define GWMODSTR(a) m_str GWMODSTR_NAME() { return #a; }
+#define GWDRIVER_NAME  gwdriver
+#define GWDEPEND_NAME  gwdepend
 #define GWMODINI(a)  ANN2(1) void* GWMODINI_NAME(const struct Gwion_ *gwion NUSED, const Vector args NUSED)
 #define GWMODEND(a)  ANN void  GWMODEND_NAME(const struct Gwion_ *gwion NUSED, void* self NUSED)
 #define GWDRIVER(a)  ANN void  GWDRIVER_NAME(DriverData* d)
+#define GWDEPEND     ANN m_str const* GWDEPEND_NAME(void)
 
 #endif
index cd7d7a100ec3c6c02c391acb0e21cc5a833c228c..6dd7c9293e80717f951f12b689d8cd8b18810787 100644 (file)
@@ -11,8 +11,9 @@ struct VM_Code_ {
   size_t stack_depth;
   void* memoize;
   m_str name;
-  HAS_OBJ
+  uint16_t ref;
   ae_flag flag;
+  int builtin;
 };
 
 typedef struct Shreduler_* Shreduler;
@@ -60,7 +61,11 @@ struct VM_Shred_ {
   struct ShredTick_ * tick;
   struct ShredInfo_ * info;
 };
-ANN2(1,5) ANEW VM_Code new_vm_code(MemPool p, const Vector instr, const m_uint stack_depth, const ae_flag, const m_str name);
+
+ANN void free_vm_code(const VM_Code, struct Gwion_*const);
+ANN static inline void vmcode_addref(const VM_Code c) { ++c->ref; }
+ANN static inline void vmcode_remref(const VM_Code c, struct Gwion_ *const gwion) { if(!--c->ref) free_vm_code(c, gwion); }
+ANN2(1,5) ANEW VM_Code new_vm_code(MemPool p, const Vector instr, const m_uint stack_depth, const int builtin, const m_str name);
 
 ANN VM_Shred shreduler_get(const Shreduler s) __attribute__((hot));
 ANN void shreduler_remove(const Shreduler s, const VM_Shred out, const m_bool erase)__attribute__((hot));
diff --git a/plug b/plug
index 3004e1d43e8cdfae9a4cdabaa372ab6e936e634c..300d07d9139a2580ade87bed2e23961c241116df 160000 (submodule)
--- a/plug
+++ b/plug
@@ -1 +1 @@
-Subproject commit 3004e1d43e8cdfae9a4cdabaa372ab6e936e634c
+Subproject commit 300d07d9139a2580ade87bed2e23961c241116df
diff --git a/po/fr/gwion.mo b/po/fr/gwion.mo
new file mode 100644 (file)
index 0000000..6c5906d
Binary files /dev/null and b/po/fr/gwion.mo differ
index f02f8bad68a601623b5e11c447edbf2b93254612..3cde06d20587af1f4b63fc03ed055eee1d43e6a6 100644 (file)
@@ -230,8 +230,8 @@ test_dir() {
   grep '\.sh' <<< "$(ls "$1")" &> /dev/null && found=1
   if [ "$found" -eq 1 ]
   then
-    local old_async=$async
-    async=0;
+#    local old_async=$async
+#    async=0;
     #          [ -f ${GWION_TEST_DIR}/${GWION_TEST_PREFIX}bailout ] && exit 1
     for file in "$1"/*.sh
     do
@@ -242,7 +242,7 @@ test_dir() {
       bash "$file" "$((n))"
       n=$((n+count))
     done
-    async=$old_async
+#    async=$old_async
   fi
 }
 
index 36e90dd29f38c6711869978b998ac53e9afd4aac..dd340388081362dedf74a807b84604e3d394051e 100644 (file)
--- a/src/arg.c
+++ b/src/arg.c
@@ -6,6 +6,7 @@
 #include "gwion.h"
 #include "arg.h"
 #include "pass.h"
+#include "compile.h"
 
 #define GWIONRC ".gwionrc"
 
@@ -30,23 +31,54 @@ ANN static m_str plug_dir(void) {
   return plug_dir;
 }
 
+enum arg_type {
+  ARG_FILE,
+  ARG_STDIN,
+  ARG_DEFINE,
+  ARG_UNDEF,
+  ARG_INCLUDE
+};
+
 ANN static void arg_init(Arg* arg) {
+  map_init(&arg->mod);
   vector_init(&arg->add);
   vector_init(&arg->lib);
-  vector_init(&arg->mod);
   vector_init(&arg->config);
   vector_add(&arg->lib, (vtype)plug_dir());
 }
 
 ANN void arg_release(Arg* arg) {
+  map_release(&arg->mod);
   vector_release(&arg->add);
   xfree((m_str)vector_front(&arg->lib));
   vector_release(&arg->lib);
-  vector_release(&arg->mod);
   config_end(&arg->config);
   vector_release(&arg->config);
 }
 
+ANN void arg_compile(const Gwion gwion, Arg *arg) {
+  const Vector v = &arg->add;
+  for(m_uint i = 0; i < vector_size(v); i++) {
+    switch(vector_at(v, i)) {
+      case ARG_FILE:
+        compile_filename(gwion, (m_str)VPTR(v, ++i));
+        break;
+      case ARG_STDIN:
+        compile_file(gwion, "stdin", stdin);
+        break;
+      case ARG_DEFINE:
+        pparg_add(gwion->ppa, (m_str)VPTR(v, ++i));
+        break;
+      case ARG_UNDEF:
+        pparg_rem(gwion->ppa, (m_str)VPTR(v, ++i));
+        break;
+      case ARG_INCLUDE:
+        pparg_inc(gwion->ppa, (m_str)VPTR(v, ++i));
+        break;
+    }
+  }
+}
+
 static const char usage[] =
 "usage: Gwion <options>\n"
 "  -h              : this help\n"
@@ -72,6 +104,15 @@ ANN2(1) static inline void arg_set_pass(const Gwion gwion, const m_str str) {
   free_vector(gwion->mp, v);
 }
 
+ANN2(1) static void module_arg(const Map map, m_str str) {
+  m_str val = strchr(str, '=');
+  if(val) {
+    *val = '\0';
+    ++val;
+  }
+  map_set(map, (vtype)str, (vtype)val);
+}
+
 ANN m_bool _arg_parse(const Gwion gwion, Arg* arg) {
   struct CArg *ca = &arg->arg;
   for(ca->idx = 1; ca->idx < ca->argc; ++ca->idx) {
@@ -91,7 +132,7 @@ ANN m_bool _arg_parse(const Gwion gwion, Arg* arg) {
           break;
         case 'm':
           CHECK_OB((tmp = option_argument(ca)))
-          vector_add(&arg->mod, (vtype)tmp);
+          module_arg(&arg->mod, tmp);
           break;
         case 'l':
           CHECK_OB((tmp = option_argument(ca)))
@@ -118,14 +159,32 @@ ANN m_bool _arg_parse(const Gwion gwion, Arg* arg) {
           arg_set_pass(gwion, tmp);
           break;
         case '\0':
-          arg->read_stdin = !arg->read_stdin;
+          vector_add(&arg->add, (vtype)ARG_STDIN);
+          break;
+        case 'D':
+          CHECK_OB((tmp = option_argument(ca)))
+          vector_add(&arg->add, (vtype)ARG_DEFINE);
+          vector_add(&arg->add, (vtype)tmp);
+          break;
+        case 'U':
+          CHECK_OB((tmp = option_argument(ca)))
+          vector_add(&arg->add, (vtype)ARG_UNDEF);
+          vector_add(&arg->add, (vtype)tmp);
+          break;
+        case 'I':
+          CHECK_OB((tmp = option_argument(ca)))
+          vector_add(&arg->add, (vtype)ARG_INCLUDE);
+          vector_add(&arg->add, (vtype)tmp);
           break;
         default:
           gw_err(_("invalid arguments"));
           return GW_ERROR;
       }
     } else
+{
+      vector_add(&arg->add, (vtype)ARG_FILE);
       vector_add(&arg->add, (vtype)ca->argv[ca->idx]);
+}
   }
   return GW_OK;
 }
index a3bc2dbf3c923921f3f2090993ba2e017aaa2a80..5d64b36ed5afb756e770be09597c91b7ce6dd6ca 100644 (file)
@@ -62,7 +62,7 @@ ANN static void clean_var_decl(Clean *a, Var_Decl b) {
   if(b->array)
     clean_array_sub(a, b->array);
   if(a->scope && b->value)
-    REM_REF(b->value, a->gwion)
+    value_remref(b->value, a->gwion);
 }
 
 ANN static void clean_var_decl_list(Clean *a, Var_Decl_List b) {
@@ -171,7 +171,7 @@ ANN static void clean_stmt_each(Clean *a, Stmt_Each b) {
   clean_exp(a, b->exp);
   clean_stmt(a, b->body);
   if(b->v)
-    REM_REF(b->v, a->gwion)
+    value_remref(b->v, a->gwion);
   --a->scope;
 }
 
@@ -278,7 +278,7 @@ ANN static void clean_func_base(Clean *a, Func_Base *b) {
 ANN static void clean_func_def(Clean *a, Func_Def b) {
   clean_func_base(a, b->base);
   ++a->scope;
-  if(b->d.code && !GET_FLAG(b->base, builtin))
+  if(b->d.code && !(b->base->func && vflag(b->base->func->value_ref, vflag_builtin)))
     clean_stmt(a, b->d.code);
   else
     b->d.code = NULL;
@@ -316,7 +316,7 @@ ANN static void clean_union_def(Clean *a, Union_Def b) {
 ANN static void clean_fptr_def(Clean *a, Fptr_Def b) {
   clean_func_base(a, b->base);
   if(b->type)
-    REM_REF(b->type, a->gwion)
+    type_remref(b->type, a->gwion);
 }
 
 ANN static void clean_type_def(Clean *a, Type_Def b) {
index 9c1644a5424d9a1d8084f6f09df66de6480a3475..4227f17dd8331645e6810e2a458008e4a0ea9285 100644 (file)
@@ -117,7 +117,6 @@ ANN static inline m_bool _check(struct Gwion_* gwion, struct Compiler* c) {
 }
 
 ANN static m_uint _compile(struct Gwion_* gwion, struct Compiler* c) {
-//  CHECK_BB(compiler_open(gwion->mp, c))
   if(compiler_open(gwion->mp, c) < 0)
     return 0;
   if(_check(gwion, c) < 0) {
index 2792173156ac2dd96e1a629820358aac02f23b1e..5155219c219b3efc6f134a0cc13b4ec136fe80dd 100644 (file)
@@ -85,7 +85,7 @@ ANN static void struct_pop(const Emitter emit, const Type type, const m_uint off
     if(isa(t, emit->gwion->type[et_object]) > 0) {
       const Instr instr = emit_add_instr(emit, ObjectRelease);
       instr->m_val = offset + vector_at(&type->e->tuple->offset, i);
-    } else if(GET_FLAG(t, struct))
+    } else if(tflag(t, tflag_struct))
       struct_pop(emit, t, offset + vector_at(&type->e->tuple->offset, i));
   }
 }
@@ -94,7 +94,7 @@ ANN static m_int frame_pop(const Emitter emit) {
   Frame *frame = emit->code->frame;
   DECL_OB(const Local*, l, = (Local*)vector_pop(&frame->stack))
   frame->curr_offset -= l->type->size;
-  if(GET_FLAG(l->type, struct)) {
+  if(tflag(l->type, tflag_struct)) {
     struct_pop(emit, l->type, l->offset);
     return frame_pop(emit);
   }
@@ -166,7 +166,7 @@ ANN m_uint emit_local(const Emitter emit, const Type t) {
 ANN void emit_ext_ctor(const Emitter emit, const Type t);
 
 ANN static inline void maybe_ctor(const Emitter emit, const Type t) {
-  if(!is_special(t) && GET_FLAG(t, ctor))
+  if(!is_special(t) && tflag(t, tflag_ctor))
     emit_ext_ctor(emit, t);
 }
 
@@ -174,8 +174,8 @@ ANN static void emit_pre_ctor(const Emitter emit, const Type type) {
   if(type->e->parent)
     emit_pre_ctor(emit, type->e->parent);
   maybe_ctor(emit, type);
-  if(GET_FLAG(type, typedef) && type->e->parent->array_depth)
-    emit_array_extend(emit, type->e->parent, type->e->def->base.ext->array->exp);
+  if(tflag(type, tflag_typedef) && type->e->parent->array_depth)
+    emit_array_extend(emit, type->e->parent, type->e->cdef->base.ext->array->exp);
 }
 
 #define regxxx(name, instr) \
@@ -203,12 +203,12 @@ ANN static void emit_pre_constructor_array(const Emitter emit, const Type type)
   const m_uint start_index = emit_code_size(emit);
   const Instr top = emit_add_instr(emit, ArrayTop);
   top->m_val2 = (m_uint)type;
-  if(GET_FLAG(type, struct)) {
+  if(tflag(type, tflag_struct)) {
     const Instr instr = emit_add_instr(emit, ArrayStruct);
     instr->m_val = type->size;
   }
   emit_pre_ctor(emit, type);
-  if(!GET_FLAG(type, struct))
+  if(!tflag(type, tflag_struct))
     emit_add_instr(emit, ArrayBottom);
   else
     regpop(emit, SZ_INT);
@@ -345,7 +345,7 @@ ANN static m_bool emit_symbol_owned(const Emitter emit, const Symbol *data) {
 
 ANN static m_bool emit_symbol_builtin(const Emitter emit, const Symbol *data) {
   const Value v = prim_self(data)->value;
-  if(GET_FLAG(v, union)) {
+  if(vflag(v, vflag_direct)) {
     const m_uint size = v->type->size;
     const Instr instr = emit_kind(emit, size, exp_getvar(prim_exp(data)), dotstatic);
     instr->m_val = (m_uint)v->d.ptr;
@@ -374,10 +374,10 @@ ANN static m_bool _emit_symbol(const Emitter emit, const Symbol *data) {
   }
   if(v->from->owner_class)
     return emit_symbol_owned(emit, data);
-  if(GET_FLAG(v, builtin) || GET_FLAG(v, union) || GET_FLAG(v, enum))
+  if(vflag(v, vflag_builtin) || vflag(v, vflag_direct) || vflag(v, vflag_enum))
     return emit_symbol_builtin(emit, data);
   const m_uint size = v->type->size;
-  const Instr instr = emit_kind(emit, size, exp_getvar(prim_exp(data)), !GET_FLAG(v, global) ? regpushmem : regpushbase);
+  const Instr instr = emit_kind(emit, size, exp_getvar(prim_exp(data)), !vflag(v, vflag_fglobal) ? regpushmem : regpushbase);
   instr->m_val  = v->from->offset;
   return GW_OK;
 }
@@ -437,7 +437,7 @@ ANN static m_bool emit_prim_range(const Emitter emit, Range **data) {
 }
 
 ANN m_bool emit_array_access(const Emitter emit, struct ArrayAccessInfo *const info) {
-  if(GET_FLAG(info->array.type, typedef)) {
+  if(tflag(info->array.type, tflag_typedef)) {
     info->array.type = info->array.type->e->parent;
     return emit_array_access(emit, info);
   }
@@ -557,7 +557,7 @@ ANN static m_bool emit_interp(const Emitter emit, const Exp exp) {
     regseti(emit, (m_uint)e->info->type);
     interp_size(emit, e->info->type);
     const m_bool isobj = isa(e->info->type, emit->gwion->type[et_object]) > 0;
-    if(isobj && !GET_FLAG(e->info->type, force))
+    if(isobj && !tflag(e->info->type, tflag_force))
       emit_add_instr(emit, GackType);
     const Instr instr = emit_add_instr(emit, Gack);
     instr->m_val = emit_code_offset(emit);
@@ -612,7 +612,7 @@ ANN static m_bool decl_static(const Emitter emit, const Var_Decl var_decl, const
 }
 
 ANN static inline int struct_ctor(const Value v) {
-  return GET_FLAG(v->type, struct) && v->type->nspc->pre_ctor;
+  return tflag(v->type, tflag_struct) && v->type->nspc->pre_ctor;
 }
 
 ANN static void decl_expand(const Emitter emit, const Type t) {
@@ -654,21 +654,21 @@ ANN static m_bool emit_exp_decl_non_static(const Emitter emit, const Exp_Decl *d
   const m_bool is_array = (array && array->exp) /*|| GET_FLAG(decl->td, force)*/;
   const m_bool is_obj = isa(type, emit->gwion->type[et_object]) > 0;
   const uint emit_addr = (!is_obj || (is_ref && !is_array)) ? emit_var : 1;
-  if(is_obj && (is_array || !is_ref) && !GET_FLAG(v, ref))
+  if(is_obj && (is_array || !is_ref) && !GET_FLAG(decl->td, ref))
     CHECK_BB(emit_instantiate_object(emit, type, array, is_ref))
   f_instr *exec = (f_instr*)allocmember;
-  if(!GET_FLAG(v, member)) {
+  if(!vflag(v, vflag_member)) {
     v->from->offset = emit_local(emit, type);
     exec = (f_instr*)(allocword);
-    if(GET_FLAG(v, ref)) { // ref or emit_var ?
+    if(GET_FLAG(decl->td, ref)) { // ref or emit_var ?
       const Instr clean = emit_add_instr(emit, MemSetImm);
       clean->m_val = v->from->offset;
     }
   }
-  const Instr instr = !(SAFE_FLAG(emit->env->class_def, struct) && !emit->env->scope->depth) ?
+  const Instr instr = !(safe_tflag(emit->env->class_def, tflag_struct) && !emit->env->scope->depth) ?
     emit_kind(emit, v->type->size, !struct_ctor(v) ? emit_addr : 1, exec) : emit_struct_decl(emit, v, !struct_ctor(v) ? emit_addr : 1);
   instr->m_val = v->from->offset;
-  if(is_obj && (is_array || !is_ref) && !GET_FLAG(v, ref)) {
+  if(is_obj && (is_array || !is_ref) && !GET_FLAG(decl->td, ref)) {
     if(!emit_var)
       emit_add_instr(emit, Assign);
     else {
@@ -677,7 +677,7 @@ ANN static m_bool emit_exp_decl_non_static(const Emitter emit, const Exp_Decl *d
       instr->m_val = -SZ_INT;
     }
     const size_t missing_depth = type->array_depth - (array ? array->depth : 0);
-    if(missing_depth && !GET_FLAG(decl->td, force)) {
+    if(missing_depth) {
       const Instr push = emit_add_instr(emit, Reg2Reg);
       push->m_val = -(missing_depth) * SZ_INT;
     }
@@ -694,17 +694,18 @@ ANN static m_bool emit_exp_decl_global(const Emitter emit, const Exp_Decl *decl,
   const m_bool is_array = array && array->exp;
   const m_bool is_obj = isa(type, emit->gwion->type[et_object]) > 0;
   const uint emit_addr = (!is_obj || (is_ref && !is_array)) ? emit_var : 1;
-  if(is_obj && (is_array || !is_ref) && !GET_FLAG(v, ref))
+  if(is_obj && (is_array || !is_ref) && !GET_FLAG(decl->td, ref))
     CHECK_BB(emit_instantiate_object(emit, type, array, is_ref))
   const Instr instr = emit_kind(emit, v->type->size, !struct_ctor(v) ? emit_addr : 1, dotstatic);
   v->d.ptr = mp_calloc2(emit->gwion->mp, v->type->size);
-  SET_FLAG(v, union);
+if(isa(type, emit->gwion->type[et_union]) < 0)
+  set_vflag(v, vflag_direct);// mpalloc
   instr->m_val = (m_uint)v->d.ptr;
   instr->m_val2 = v->type->size;
-  if(is_obj && (is_array || !is_ref) && !GET_FLAG(v, ref)) {
+  if(is_obj && (is_array || !is_ref) && !GET_FLAG(decl->td, ref)) {
     const Instr assign = emit_add_instr(emit, Assign);
     const size_t missing_depth = type->array_depth - (array ? array->depth : 0);
-    if(missing_depth && !GET_FLAG(decl->td, force)) {
+    if(missing_depth) {
       const Instr push = emit_add_instr(emit, Reg2Reg);
       push->m_val = -(missing_depth) * SZ_INT;
     }
@@ -716,11 +717,11 @@ ANN static m_bool emit_exp_decl_global(const Emitter emit, const Exp_Decl *decl,
 }
 
 ANN static m_bool emit_class_def(const Emitter, const Class_Def);
-ANN static m_bool emit_cdef(const Emitter, const Class_Def);
+ANN static m_bool emit_cdef(const Emitter, const Type);
 
 ANN static inline m_bool ensure_emit(const Emitter emit, const Type t) {
   struct EnvSet es = { .env=emit->env, .data=emit, .func=(_exp_func)emit_cdef,
-    .scope=emit->env->scope->depth, .flag=ae_flag_emit };
+    .scope=emit->env->scope->depth, .flag=tflag_emit };
   return envset_run(&es, t);
 }
 
@@ -743,7 +744,7 @@ ANN static m_bool emit_decl(const Emitter emit, const Exp_Decl* decl) {
 
 ANN /*static */m_bool emit_exp_decl(const Emitter emit, const Exp_Decl* decl) {
   const Type t = get_type(decl->type);
-  if(!GET_FLAG(t, emit) && t->e->def)
+  if(!tflag(t, tflag_emit))
     CHECK_BB(ensure_emit(emit, t))
   const m_bool global = GET_FLAG(decl->td, global);
   const m_uint scope = !global ? emit->env->scope->depth : emit_push_global(emit);
@@ -792,7 +793,7 @@ ANN static m_bool emit_func_args(const Emitter emit, const Exp_Call* exp_call) {
     CHECK_BB(emit_exp(emit, exp_call->args))
     emit_exp_addref(emit, exp_call->args, -exp_totalsize(exp_call->args));
   }
-  if(exp_call->m_func && GET_FLAG(exp_call->m_func->def->base, variadic))
+  if(exp_call->m_func && fbflag(exp_call->m_func->def->base, fbflag_variadic))
     emit_func_arg_vararg(emit, exp_call);
   return GW_OK;
 }
@@ -817,7 +818,7 @@ ANN static m_bool emit_exp_call(const Emitter emit, const Exp_Call* exp_call) {
     const Instr instr = emit_add_instr(emit, Reg2RegAddr);
     instr->m_val = -SZ_INT;
     instr->m_val2 = -SZ_INT;
-  } else if(!exp_call->m_func && GET_FLAG(e->info->type, struct))
+  } else if(!exp_call->m_func && tflag(e->info->type, tflag_struct))
     regpop(emit, SZ_INT);
   return GW_OK;
 }
@@ -905,7 +906,7 @@ ANN static inline m_bool traverse_emit_func_def(const Emitter emit, const Func_D
 ANN m_bool traverse_dot_tmpl(const Emitter emit, const struct dottmpl_ *dt) {
   const m_uint scope = emit->env->scope->depth;
   struct EnvSet es = { .env=emit->env, .data=emit, .func=(_exp_func)emit_cdef,
-    .scope=scope, .flag=ae_flag_emit };
+    .scope=scope, .flag=tflag_emit };
   CHECK_BB(envset_push(&es, dt->owner_class, dt->owner))
   (void)emit_push(emit, dt->owner_class, dt->owner);
   const m_bool ret = traverse_emit_func_def(emit, dt->def);
@@ -945,7 +946,7 @@ ANN static m_bool emit_template_code(const Emitter emit, const Func f) {
   const Value v = f->value_ref;
   const size_t scope = emit->env->scope->depth;
   struct EnvSet es = { .env=emit->env, .data=emit, .func=(_exp_func)emit_cdef,
-    .scope=scope, .flag=ae_flag_emit };
+    .scope=scope, .flag=tflag_emit };
   CHECK_BB(envset_push(&es, v->from->owner_class, v->from->owner))
   (void)emit_push(emit, v->from->owner_class, v->from->owner);
   const m_bool ret = emit_func_def(emit, f->def);
@@ -988,7 +989,7 @@ ANN static Instr get_prelude(const Emitter emit, const Func f) {
 }
 
 ANN static void emit_args(const Emitter emit, const Func f) {
-  const m_uint member = GET_FLAG(f, member) ? SZ_INT : 0;
+  const m_uint member = vflag(f->value_ref, vflag_member) ? SZ_INT : 0;
   if((f->def->stack_depth - member) == SZ_INT) {
     const Instr instr = emit_add_instr(emit, Reg2Mem);
     instr->m_val = member;
@@ -1042,7 +1043,7 @@ ANN static m_bool me_arg(MemoizeEmitter *me) {
 ANN static Instr emit_call(const Emitter emit, const Func f) {
   const Instr prelude = get_prelude(emit, f);
   prelude->m_val = f->def->stack_depth;
-  const m_uint member = GET_FLAG(f, member) ? SZ_INT : 0;
+  const m_uint member = vflag(f->value_ref, vflag_member) ? SZ_INT : 0;
   if(member) {
     const Instr instr = emit_add_instr(emit, Reg2Mem);
     instr->m_val2 = f->def->stack_depth - SZ_INT;
@@ -1056,8 +1057,9 @@ ANN static Instr emit_call(const Emitter emit, const Func f) {
 }
 
 ANN Instr emit_exp_call1(const Emitter emit, const Func f) {
-  if(!f->code || (GET_FLAG(f, ref) && !GET_FLAG(f, builtin))) {
-    if(GET_FLAG(f, template) && !is_fptr(emit->gwion, f->value_ref->type)) {
+  const int tmpl = fflag(f, fflag_tmpl);
+  if(!f->code || (fflag(f, fflag_ftmpl) && !vflag(f->value_ref, vflag_builtin))) {
+    if(tmpl && !is_fptr(emit->gwion, f->value_ref->type)) {
       if(emit->env->func != f)
         CHECK_BO(emit_template_code(emit, f))
       else { // recursive function. (maybe should be used only for global funcs)
@@ -1068,7 +1070,7 @@ ANN Instr emit_exp_call1(const Emitter emit, const Func f) {
         back->m_val = 0;
       }
     } else if(emit->env->func != f && !f->value_ref->from->owner_class && !f->code && !is_fptr(emit->gwion, f->value_ref->type)) {
-      if(GET_FLAG(f->def->base, op)) {
+      if(fbflag(f->def->base, fbflag_op)) {
         const Instr back = (Instr)vector_back(&emit->code->instr);
         back->m_val = (m_uint)f;
       } else {
@@ -1079,8 +1081,8 @@ ANN Instr emit_exp_call1(const Emitter emit, const Func f) {
         instr->m_val2 = -SZ_INT;
       }
     }
-  } else if((f->value_ref->from->owner_class && GET_FLAG(f->value_ref->from->owner_class, struct)) ||
-        !f->value_ref->from->owner_class || (GET_FLAG(f, template) &&
+  } else if((f->value_ref->from->owner_class && tflag(f->value_ref->from->owner_class, tflag_struct)) ||
+        !f->value_ref->from->owner_class || (tmpl &&
         !is_fptr(emit->gwion, f->value_ref->type)))
     push_func_code(emit, f);
   else if(vector_size(&emit->code->instr)) {
@@ -1088,7 +1090,7 @@ ANN Instr emit_exp_call1(const Emitter emit, const Func f) {
     if((f_instr)(m_uint)back->opcode == DotFunc || (f_instr)(m_uint)back->opcode == DotStaticFunc)
       back->m_val = f->vt_index;
   }
-  if(vector_size(&emit->code->instr) && GET_FLAG(f, member) &&
+  if(vector_size(&emit->code->instr) && vflag(f->value_ref, vflag_member) &&
         is_fptr(emit->gwion, f->value_ref->type)) {
     const Instr back = (Instr)vector_back(&emit->code->instr);
     m_bit exec = back->opcode;
@@ -1133,11 +1135,6 @@ static inline void stack_alloc(const Emitter emit) { // maybe vararg could use t
   emit->code->stack_depth += SZ_INT;
 }
 
-static inline void stack_alloc_this(const Emitter emit) {
-  SET_FLAG(emit->code, member);
-  stack_alloc(emit);
-}
-
 static m_bool scoped_stmt(const Emitter emit, const Stmt stmt, const m_bool pop) {
   ++emit->env->scope->depth;
   emit_push_scope(emit);
@@ -1167,8 +1164,6 @@ static void push_spork_code(const Emitter emit, const m_str prefix, const loc_t
 }
 
 ANN static m_bool call_spork_func(const Emitter emit, const Exp_Call *exp) {
-  if(GET_FLAG(exp->m_func, member))
-    SET_FLAG(emit->code, member);
   return emit_exp_call1(emit, exp->m_func) ? GW_OK : GW_ERROR;
 }
 
@@ -1184,8 +1179,8 @@ struct Sporker {
 ANN static m_bool spork_prepare_code(const Emitter emit, const struct Sporker *sp) {
   emit_add_instr(emit, RegPushImm);
   push_spork_code(emit, sp->is_spork ? SPORK_CODE_PREFIX : FORK_CODE_PREFIX, sp->code->pos);
-  if(SAFE_FLAG(emit->env->func, member))
-    stack_alloc_this(emit);
+  if(emit->env->func && vflag(emit->env->func->value_ref, vflag_member))
+    stack_alloc(emit);
   return scoped_stmt(emit, sp->code, 0);
 }
 
@@ -1212,7 +1207,7 @@ ANN void spork_code(const Emitter emit, const struct Sporker *sp) {
 
 ANN void spork_func(const Emitter emit, const struct Sporker *sp) {
   const Func f = sp->exp->d.exp_call.m_func;
-  if(GET_FLAG(f, member) && is_fptr(emit->gwion, f->value_ref->type)) {
+  if(vflag(f->value_ref, vflag_member) && is_fptr(emit->gwion, f->value_ref->type)) {
     regpush(emit, SZ_INT*2);
     // (re-)emit owner
     if(sp->exp->d.exp_call.func->exp_type == ae_exp_dot)
@@ -1263,7 +1258,7 @@ ANN Instr emit_exp_spork(const Emitter emit, const Exp_Unary* unary) {
 ANN static m_bool emit_exp_unary(const Emitter emit, const Exp_Unary* unary) {
   const Type t = exp_self(unary)->info->type;
   const Type base = get_type(actual_type(emit->gwion, t));
-  if(base->e->def && !GET_FLAG(base, emit))
+  if(base->e->cdef && !tflag(base, tflag_emit)) // ???
     CHECK_BB(ensure_emit(emit, base))
   // no pos ?
   struct Op_Import opi = { .op=unary->op, .data=(uintptr_t)unary, .op_type=op_unary };
@@ -1307,7 +1302,7 @@ ANN static m_bool emit_exp_if(const Emitter emit, const Exp_If* exp_if) {
 
 ANN static m_bool emit_lambda(const Emitter emit, const Exp_Lambda * lambda) {
   CHECK_BB(emit_func_def(emit, lambda->def))
-  if(GET_FLAG(lambda->def->base, member) && !exp_getvar(exp_self(lambda)))
+  if(vflag(lambda->def->base->func->value_ref, vflag_member) && !exp_getvar(exp_self(lambda)))
     emit_add_instr(emit, RegPushMem);
   regpushi(emit, (m_uint)lambda->def->base->func->code);
   return GW_OK;
@@ -1319,7 +1314,7 @@ ANN static m_bool emit_exp_lambda(const Emitter emit, const Exp_Lambda * lambda)
     return GW_OK;
   }
   struct EnvSet es = { .env=emit->env, .data=emit, .func=(_exp_func)emit_cdef,
-    .scope=emit->env->scope->depth, .flag=ae_flag_emit };
+    .scope=emit->env->scope->depth, .flag=tflag_emit };
   CHECK_BB(envset_push(&es, lambda->owner, lambda->def->base->func->value_ref->from->owner))
   const m_bool ret = emit_lambda(emit, lambda);
   if(es.run)
@@ -1340,7 +1335,7 @@ ANN static void struct_addref(const Emitter emit, const Type type,
       const Instr instr = emit_addref(emit, emit_var);
       instr->m_val = size;
       instr->m_val2 = vector_at(&type->e->tuple->offset, i);
-    } else if(GET_FLAG(t, struct))
+    } else if(tflag(t, tflag_struct))
       struct_addref(emit, t, size, offset + vector_at(&type->e->tuple->offset, i), emit_var);
   }
 }
@@ -1357,7 +1352,7 @@ ANN2(1) static void emit_exp_addref1(const Emitter emit, /* const */Exp exp, m_i
     (exp->info->cast_to ? isa(exp->info->cast_to, emit->gwion->type[et_object]) > 0 : 1)) {
     const Instr instr = emit_addref(emit, exp_getvar(exp));
     instr->m_val = size;
-  } else if(GET_FLAG(exp->info->type, struct)) // check cast_to ?
+  } else if(tflag(exp->info->type, tflag_struct)) // check cast_to ?
     struct_addref(emit, exp->info->type, size, 0, exp_getvar(exp));
 }
 
@@ -1617,7 +1612,7 @@ ANN static m_bool emit_stmt_jump(const Emitter emit, const Stmt_Jump stmt) {
 }
 
 ANN static m_bool emit_type_def(const Emitter emit, const Type_Def tdef) {
-  return tdef->type->e->def ? emit_class_def(emit, tdef->type->e->def) : GW_OK;
+  return tdef->type->e->cdef ? emit_class_def(emit, tdef->type->e->cdef) : GW_OK;
 }
 
 ANN static m_bool emit_enum_def(const Emitter emit, const Enum_Def edef) {
@@ -1670,8 +1665,7 @@ ANN static m_bool emit_union_def(const Emitter emit, const Union_Def udef) {
     if(global) {
       const M_Object o = new_object(emit->gwion->mp, NULL, udef->value->type);
       udef->value->d.ptr = (m_uint*)o;
-      SET_FLAG(udef->value, builtin);
-      UNSET_FLAG(udef->value, union);
+      set_vflag(udef->value, vflag_builtin);
     }
     scope = emit_push_type(emit, udef->value->type);
   } else if(udef->type_xid) {
@@ -1682,22 +1676,20 @@ ANN static m_bool emit_union_def(const Emitter emit, const Union_Def udef) {
     void* ptr = (void*)xcalloc(1, udef->s);
     l = udef->l;
     udef->value->d.ptr = ptr;
-    SET_FLAG(udef->value, enum);
-    SET_FLAG(udef->value, dtor);
+    udef->value->vflag |= (vflag_enum | vflag_freeme);
     do {
       Var_Decl_List list = l->self->d.exp_decl.list;
       list->self->value->d.ptr = ptr;
-      SET_FLAG(list->self->value, union);
+      set_vflag(list->self->value, vflag_direct);// xcalloc
     } while((l = l->next));
-    SET_FLAG(udef->l->self->d.exp_decl.list->self->value, enum);
-    SET_FLAG(udef->l->self->d.exp_decl.list->self->value, dtor);
+    udef->l->self->d.exp_decl.list->self->value->vflag |= (vflag_enum | vflag_freeme);
   }
   if(udef->xid)
     regpop(emit, SZ_INT);
   emit_union_offset(udef->l, udef->o);
   if(udef->xid || udef->type_xid || global)
     emit_pop(emit, scope);
-  union_flag(udef, ae_flag_emit);
+  union_flag(udef, tflag_emit);
   return GW_OK;
 }
 
@@ -1895,7 +1887,7 @@ ANN static void emit_func_def_return(const Emitter emit) {
     instr->m_val = val;
   }
   vector_clear(&emit->code->stack_return);
-  if(emit->info->memoize && GET_FLAG(emit->env->func, pure)) {
+  if(emit->info->memoize && fflag(emit->env->func, fflag_pure)) {
     const Instr instr = emit_add_instr(emit, MemoizeStore);
     instr->m_val = emit->env->func->def->stack_depth;
   }
@@ -1904,7 +1896,7 @@ ANN static void emit_func_def_return(const Emitter emit) {
 ANN static VM_Code emit_internal(const Emitter emit, const Func f) {
   if(f->def->base->xid == insert_symbol("@dtor")) {
     emit->env->class_def->nspc->dtor = f->code = finalyze(emit, DTOR_EOC);
-    ADD_REF(f->code)
+    vmcode_addref(f->code);
     return f->code;
   } else if(f->def->base->xid == insert_symbol("@gack")) {
     regpop(emit, SZ_INT + f->value_ref->from->owner_class->size);
@@ -1917,7 +1909,7 @@ ANN static VM_Code emit_internal(const Emitter emit, const Func f) {
 }
 
 ANN static VM_Code emit_func_def_code(const Emitter emit, const Func func) {
-  if(GET_FLAG(func->def->base, typedef))
+  if(fbflag(func->def->base, fbflag_internal))
     return emit_internal(emit, func);
   else
     return finalyze(emit, FuncReturn);
@@ -1926,7 +1918,7 @@ ANN static VM_Code emit_func_def_code(const Emitter emit, const Func func) {
 ANN static m_bool emit_func_def_body(const Emitter emit, const Func_Def fdef) {
   if(fdef->base->args)
     emit_func_def_args(emit, fdef->base->args);
-  if(GET_FLAG(fdef->base, variadic))
+  if(fbflag(fdef->base, fbflag_variadic))
     stack_alloc(emit);
   if(fdef->d.code)
     CHECK_BB(scoped_stmt(emit, fdef->d.code, 1))
@@ -1990,7 +1982,7 @@ ANN static m_bool emit_memoize(const Emitter emit, const Func_Def fdef) {
 }
 
 ANN static m_bool emit_fdef(const Emitter emit, const Func_Def fdef) {
-  if(emit->info->memoize && GET_FLAG(fdef->base->func, pure))
+  if(emit->info->memoize && fflag(fdef->base->func, fflag_pure))
     CHECK_BB(emit_memoize(emit, fdef))
   CHECK_BB(emit_func_def_body(emit, fdef))
   emit_func_def_return(emit);
@@ -2008,7 +2000,7 @@ ANN static void emit_fdef_finish(const Emitter emit, const Func_Def fdef) {
   func->code = emit_func_def_code(emit, func);
   if(fdef_is_file_global(emit, fdef))
     emit_func_def_global(emit, func->value_ref);
-  if(emit->info->memoize && GET_FLAG(func, pure))
+  if(emit->info->memoize && fflag(func, fflag_pure))
     func->code->memoize = memoize_ini(emit, func);
 }
 
@@ -2018,13 +2010,13 @@ ANN static m_bool emit_func_def(const Emitter emit, const Func_Def f) {
   const Func former = emit->env->func;
   if(func->code || tmpl_base(fdef->base->tmpl))
     return GW_OK;
-  if(SAFE_FLAG(emit->env->class_def, builtin) && GET_FLAG(emit->env->class_def, template))
+  if(vflag(func->value_ref, vflag_builtin) && safe_tflag(emit->env->class_def, tflag_tmpl))
     return GW_OK;
   if(fdef_is_file_global(emit, fdef))
     func->value_ref->from->offset = emit_local(emit, emit->gwion->type[et_int]);
   emit_func_def_init(emit, func);
-  if(GET_FLAG(func, member))
-    stack_alloc_this(emit);
+  if(vflag(func->value_ref, vflag_member))
+    stack_alloc(emit);
   emit->env->func = func;
   emit_push_scope(emit);
   if(!strcmp(s_name(fdef->base->xid), "@gack")) {
@@ -2050,25 +2042,20 @@ ANN Code* emit_class_code(const Emitter emit, const m_str name) {
   char c[len];
   snprintf(c, len, "class %s", name);
   emit_push_code(emit, c);
-  stack_alloc_this(emit);
+  stack_alloc(emit);
   return emit->code;
 }
 
 ANN static m_bool emit_parent(const Emitter emit, const Class_Def cdef) {
   const Type parent = cdef->base.type->e->parent;
-  return !GET_FLAG(parent, emit) ? ensure_emit(emit, parent) : GW_OK;
+  return !tflag(parent, tflag_emit) ? ensure_emit(emit, parent) : GW_OK;
 }
 
-ANN static inline m_bool emit_cdef(const Emitter emit, const Class_Def cdef) {
-  return scanx_cdef(emit->env, emit, cdef,
+ANN static inline m_bool emit_cdef(const Emitter emit, const Type t) {
+  return scanx_cdef(emit->env, emit, t,
       (_exp_func)emit_class_def, (_exp_func)emit_union_def);
 }
 
-ANN void emit_class_finish(const Emitter emit, const Nspc nspc) {
-  nspc->pre_ctor = finalyze(emit, FuncReturn);
-  SET_FLAG(nspc->pre_ctor, ctor);
-}
-
 ANN static m_bool cdef_parent(const Emitter emit, const Class_Def cdef) {
   if(cdef->base.tmpl && cdef->base.tmpl->list)
     CHECK_BB(template_push_types(emit->env, cdef->base.tmpl))
@@ -2082,18 +2069,18 @@ ANN static m_bool emit_class_def(const Emitter emit, const Class_Def cdef) {
   if(tmpl_base(cdef->base.tmpl))
     return GW_OK;
   const Type t = cdef->base.type;
-  if(GET_FLAG(t, emit))
+  if(tflag(t, tflag_emit))
     return GW_OK;
-  SET_FLAG(t, emit);
-  if(t->e->owner_class && !GET_FLAG(t->e->owner_class, emit))
+  set_tflag(t, tflag_emit);
+  if(t->e->owner_class && !tflag(t->e->owner_class, tflag_emit))
     CHECK_BB(ensure_emit(emit, t->e->owner_class))
-  if(cdef->base.ext && t->e->parent->e->def && !GET_FLAG(t->e->parent, emit))
+  if(cdef->base.ext && t->e->parent->e->cdef && !tflag(t->e->parent, tflag_emit)) // ?????
     CHECK_BB(cdef_parent(emit, cdef))
   nspc_allocdata(emit->gwion->mp, t->nspc);
   if(cdef->body) {
     emit_class_code(emit, t->name);
     if(scanx_body(emit->env, cdef, (_exp_func)emit_section, emit) > 0)
-      emit_class_finish(emit, t->nspc);
+      t->nspc->pre_ctor = finalyze(emit, FuncReturn);
     else {
       free_code(emit->gwion->mp, emit->code);
       emit_pop_code(emit);
index 6520d9fa35eefc8cf9a6b20e9a7593df5354e444..142e1b212d87b0f054cda8bad7eabda039a0d64d 100644 (file)
@@ -9,8 +9,7 @@
 
 static ANEW ANN VM_Code emit_code(const Emitter emit) {
   Code* const c = emit->code;
-  const VM_Code code = new_vm_code(emit->gwion->mp, &c->instr, c->stack_depth,
-      c->flag, c->name);
+  const VM_Code code = new_vm_code(emit->gwion->mp, &c->instr, c->stack_depth, 0, c->name);
   return code;
 }
 
index 6cf65e9001885474932b70a2597f5e45dba513ae..c78d522e65f26fe0658211d78ed78f5ad7082f41 100644 (file)
@@ -4,8 +4,8 @@
 #include "vm.h"
 #include "gwion.h"
 
-ANN static void free_context(const Context a, Gwion gwion) {
-  REM_REF(a->nspc, gwion)
+ANN void free_context(const Context a, Gwion gwion) {
+  nspc_remref(a->nspc, gwion);
   free_mstr(gwion->mp, a->name);
   mp_free(gwion->mp, Context, a);
 }
@@ -15,12 +15,12 @@ ANN2(2) Context new_context(MemPool p, const Ast ast, const m_str str) {
   context->name = mstrdup(p, str);
   context->nspc = new_nspc(p, context->name);
   context->tree = ast;
-  context->ref = new_refcount(p, free_context);
+  context->ref = 1;
   return context;
 }
 
 ANN void load_context(const Context context, const Env env) {
-  ADD_REF((env->context = context))
+  context_addref((env->context = context));
   vector_add(&env->scope->nspc_stack, (vtype)env->curr);
   context->nspc->parent = env->curr;
   env->curr = context->nspc;
@@ -33,6 +33,6 @@ ANN void unload_context(const Context context, const Env env) {
       free_map(env->gwion->mp, (Map)map_at(&context->lbls, i));
     map_release(&context->lbls);
   }
-  REM_REF(context, env->gwion)
+  context_remref(context, env->gwion);
   env->curr = (Nspc)vector_pop(&env->scope->nspc_stack);
 }
index e5360419dc386eafb5e3cd63f0d7eb19f31a0329..b4729d3d284c24f5ce29edb83bf15f23024491d5 100644 (file)
@@ -43,7 +43,7 @@ ANN void env_reset(const Env env) {
 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;)
-    REM_REF((Context)vector_at(&a->known_ctx, i - 1), gwion);
+    context_remref((Context)vector_at(&a->known_ctx, i - 1), gwion);
 }
 
 ANN static void free_env_scope(struct Env_Scope_  *a, Gwion gwion) {
@@ -79,17 +79,14 @@ ANN void env_pop(const Env env, const m_uint scope) {
 }
 
 ANN void env_add_type(const Env env, const Type type) {
-  const Type v_type = type_copy(env->gwion->mp, env->gwion->type[et_class]);
-  ADD_REF(v_type);
-  v_type->e->d.base_type = type;
-  SET_FLAG(type, builtin);
+  type->e->owner = env->curr;
+  type->e->owner_class = env->class_def; // t owner_class ?
   const Symbol sym = insert_symbol(type->name);
   nspc_add_type_front(env->curr, sym, type);
-  const Value v = new_value(env->gwion->mp, v_type, s_name(sym));
-  SET_FLAG(v, valid | ae_flag_const | ae_flag_global | ae_flag_builtin);
-  nspc_add_value(env->curr, insert_symbol(type->name), v);
-  v->from->owner = type->e->owner = env->curr;
-  v->from->owner_class = type->e->owner_class = env->class_def; // t owner_class ?
+  const Value v = mk_class(env, type);
+  SET_FLAG(v, global);
+  set_vflag(v, vflag_builtin);
+  set_tflag(type, tflag_scan0 | tflag_scan1 | tflag_scan2 | tflag_check | tflag_emit);
   type->xid = ++env->scope->type_xid;
 }
 
@@ -108,7 +105,7 @@ ANN m_bool type_engine_clean_prog(const Env env, m_bool *r) {
   if(ret > 0 || env->context->global)
     vector_add(&env->scope->known_ctx, (vtype)ctx);
   else //nspc_rollback(env->global_nspc);
-    REM_REF(ctx, env->gwion);
+    context_remref(ctx, env->gwion);
   unload_context(ctx, env);
   return ret;
 }
index ce6ab3d309e0ff68d272e3b634db9dc81ef313d3..a3661a4543b90f365b2698ec66cdc899b96e3237 100644 (file)
@@ -73,7 +73,7 @@ ANN static Type class_type(const Env env, const Type base) {
   t->e->parent = t_class;
   t->e->ctx = base->e->ctx;
   t->e->d.base_type = base;
-  SET_FLAG(t, infer);
+  set_tflag(t, tflag_infer);
   return t;
 }
 
@@ -82,7 +82,8 @@ ANN Value mk_class(const Env env, const Type base) {
   const Symbol sym = insert_symbol(base->name);
   const Value v = new_value(env->gwion->mp, t, s_name(sym));
   valuefrom(env, v->from);
-  SET_FLAG(v, const | ae_flag_valid);
+  SET_FLAG(v, const);
+  set_vflag(v, vflag_valid);
   nspc_add_value_front(base->e->owner, sym, v);
   return v;
 }
index 26efc742c6082dd9c054b1d96c2d5e202e07c022..5bfa468c72bc0fb354063309952dbead016ed8a3 100644 (file)
@@ -18,14 +18,15 @@ ANN static void check(struct EnvSet *es, const Type t) {
 }
 
 ANN static m_bool push(struct EnvSet *es, const Type t) {
+  es->env->scope->depth = 0;
   if(t->e->owner_class)
     CHECK_BB(push(es, t->e->owner_class))
   else
     env_push(es->env, NULL, t->e->ctx ? t->e->ctx->nspc : es->env->curr);
-  if(es->func && !(t->flag & es->flag))
-    CHECK_BB(es->func((void*)es->data, t->e->def))
-  if(GET_FLAG(t, template))
-    CHECK_BB(template_push_types(es->env, t->e->def->base.tmpl))
+  if(es->func && !(t->tflag & es->flag))
+    CHECK_BB(es->func((void*)es->data, t))
+  if(tflag(t, tflag_tmpl))
+    CHECK_BB(template_push_types(es->env, t->e->cdef->base.tmpl)) // incorrect templates
   env_push_type((void*)es->env, t);
   return GW_OK;
 }
@@ -46,7 +47,7 @@ ANN2(1) void envset_pop(struct EnvSet *es, const Type t) {
   env_pop(es->env, es->scope);
   if(!t)
     return;
-  if(GET_FLAG(t, template))
+  if(tflag(t, tflag_tmpl))
     nspc_pop_type(es->env->gwion->mp, es->env->curr);
   if(t->e->owner_class)
     envset_pop(es, t->e->owner_class);
@@ -58,8 +59,9 @@ ANN m_bool envset_run(struct EnvSet *es, const Type t) {
   check(es, t);
   if(es->run)
     CHECK_BB(push(es, t->e->owner_class))
-  const m_bool ret = !(t->flag & es->flag) ?
-    es->func(es->data, t->e->def) : GW_OK;
+  const m_bool ret = t->e->cdef &&
+    !(t->tflag & es->flag) ?
+        es->func(es->data, t) : GW_OK;
   if(es->run)
     envset_pop(es, t->e->owner_class);
   return ret;
index a1bda1022a2eb6afc64ae73798c5bf44d8e8935a..6417d2a3b53d563cb6accb41eca085016a7ddde1 100644 (file)
@@ -5,11 +5,11 @@
 #include "gwion.h"
 #include "clean.h"
 
-ANN static void free_func(Func a, Gwion gwion) {
-  if(GET_FLAG(a, template))
+ANN void free_func(Func a, Gwion gwion) {
+  if(fflag(a, fflag_tmpl))
     func_def_cleaner(gwion, a->def);
   if(a->code)
-    REM_REF(a->code, gwion);
+    vmcode_remref(a->code, gwion);
   mp_free(gwion->mp, Func, a);
 }
 
@@ -17,7 +17,7 @@ ANN Func new_func(MemPool p, const m_str name, const Func_Def def) {
   Func func = mp_calloc(p, Func);
   func->name = name;
   func->def = def;
-  func->ref = new_refcount(p, free_func);
+  func->ref = 1;
   return func;
 }
 
@@ -34,3 +34,9 @@ ANN2(1,2) Symbol func_symbol(const Env env, const m_str nspc, const m_str base,
     i, nspc))
   return insert_symbol(env->gwion->st, name);
 }
+
+ANN void builtin_func(const MemPool mp, const Func f, void* func_ptr) {
+  set_vflag(f->value_ref, vflag_builtin);
+  f->code = new_vm_code(mp, NULL, f->def->stack_depth, 1, f->name);
+  f->code->native_func = (m_uint)func_ptr;
+}
index 27743ccd678762e5a789e196e0d0345f3083bf5c..c92cd7bd05d983719607d83fa4b0bc3f1607c3c8 100644 (file)
@@ -13,8 +13,8 @@ ANN void nspc_commit(const Nspc nspc) {
 }
 
 ANN static inline void nspc_release_object(const Nspc a, Value value, Gwion gwion) {
-  if(!GET_FLAG(value, pure) && ((GET_FLAG(value, static) && a->info->class_data) ||
-    (value->d.ptr && GET_FLAG(value, builtin)))) {
+  if(!vflag(value, vflag_union) && ((GET_FLAG(value, static) && a->info->class_data) ||
+    (value->d.ptr && vflag(value, vflag_builtin)))) {
     const M_Object obj = value->d.ptr ? (M_Object)value->d.ptr :
         *(M_Object*)(a->info->class_data + value->from->offset);
        release(obj, gwion->vm->cleaner_shred);
@@ -22,15 +22,15 @@ ANN static inline void nspc_release_object(const Nspc a, Value value, Gwion gwio
 }
 
 ANN2(1,3) static inline void nspc_release_struct(const Nspc a, Value value, Gwion gwion) {
-  if(!SAFE_FLAG(value, pure) && ((SAFE_FLAG(value, static) && a->info->class_data) ||
-    (SAFE_FLAG(value, builtin) && value->d.ptr))) {
+  if(value && !vflag(value, vflag_union) && ((GET_FLAG(value, static) && a->info->class_data) ||
+    (vflag(value, vflag_builtin) && value->d.ptr))) {
     const m_bit *ptr = (value && value->d.ptr) ? (m_bit*)value->d.ptr:
         (m_bit*)(a->info->class_data + value->from->offset);
     for(m_uint i = 0; i < vector_size(&value->type->e->tuple->types); ++i) {
       const Type t = (Type)vector_at(&value->type->e->tuple->types, i);
       if(isa(t, gwion->type[et_object]) > 0)
         release(*(M_Object*)(ptr + vector_at(&value->type->e->tuple->offset, i)), gwion->vm->cleaner_shred);
-      else if(GET_FLAG(t, struct))
+      else if(tflag(t, tflag_struct))
         nspc_release_struct(t->nspc, NULL, gwion);
     }
   }
@@ -42,9 +42,9 @@ ANN static void free_nspc_value(const Nspc a, Gwion gwion) {
   while(scope_iter(&iter, &v) > 0) {
     if(isa(v->type, gwion->type[et_object]) > 0)
       nspc_release_object(a, v, gwion);
-    else if(GET_FLAG(v->type, struct))
+    else if(tflag(v->type, tflag_struct))
       nspc_release_struct(a, v, gwion);
-    REM_REF(v, gwion);
+    value_remref(v, gwion);
   }
   free_scope(gwion->mp, a->info->value);
 }
@@ -54,14 +54,14 @@ ANN static void nspc_free_##b(Nspc n, Gwion gwion) {\
   struct scope_iter iter = { n->info->b, 0, 0 };\
   A a;\
   while(scope_iter(&iter, &a) > 0) \
-    REM_REF(a, gwion);\
+    b##_remref(a, gwion);\
   free_scope(gwion->mp, n->info->b);\
 }
 
 describe_nspc_free(Func, func)
 describe_nspc_free(Type, type)
 
-ANN static void free_nspc(Nspc a, Gwion gwion) {
+ANN void free_nspc(const Nspc a, const Gwion gwion) {
   free_nspc_value(a, gwion);
   nspc_free_func(a, gwion);
   if(a->info->op_map.ptr)
@@ -73,9 +73,9 @@ ANN static void free_nspc(Nspc a, Gwion gwion) {
     vector_release(&a->info->vtable);
   mp_free(gwion->mp, NspcInfo, a->info);
   if(a->pre_ctor)
-    REM_REF(a->pre_ctor, gwion);
+    vmcode_remref(a->pre_ctor, gwion);
   if(a->dtor)
-    REM_REF(a->dtor, gwion);
+    vmcode_remref(a->dtor, gwion);
   mp_free(gwion->mp, Nspc, a);
 }
 
@@ -86,6 +86,6 @@ ANN Nspc new_nspc(MemPool p, const m_str name) {
   a->info->value = new_scope(p);
   a->info->type = new_scope(p);
   a->info->func = new_scope(p);
-  a->ref = new_refcount(p, free_nspc);
+  a->ref = 1;
   return a;
 }
index 511ed68a27abcb29c4454c1d4b365b04acb71a7e..82fe1df278c3970e9747dc41372fab1dcdedad0c 100644 (file)
@@ -28,7 +28,7 @@ ANN void tuple_contains(const Env env, const Value value) {
   const Vector v = &env->class_def->e->tuple->contains;
   const m_int idx = vector_size(v) ? vector_find(v, (vtype)t) : -1;
   if(idx == -1) {
-    ADD_REF(t);
+    type_addref(t);
     vector_add(v, (vtype)t);
   }
 }
@@ -58,7 +58,7 @@ ANN2(1) TupleForm new_tupleform(MemPool p, const Type parent_type) {
 
 ANN void free_tupleform(const TupleForm tuple, const struct Gwion_ *gwion) {
   for(m_uint i = 0; i < vector_size(&tuple->contains); ++i)
-    REM_REF((Type)vector_at(&tuple->contains, i), (void*)gwion);
+    type_remref((Type)vector_at(&tuple->contains, i), (void*)gwion);
   vector_release(&tuple->contains);
   vector_release(&tuple->types);
   vector_release(&tuple->offset);
index bc6e3126688f4c33e4303547e944ac4c6f105000..9da87fe0ac06f475dc1ff1e8c7ddecbec435515b 100644 (file)
@@ -9,29 +9,23 @@
 #include "object.h"
 
 ANN static inline m_bool freeable(const Type a) {
-  return !GET_FLAG(a, nonnull) && GET_FLAG(a, template);
+  return !(tflag(a, tflag_force) || tflag(a, tflag_nonnull)) && (tflag(a, tflag_tmpl) ||GET_FLAG(a, global));
 }
 
-ANN static void free_type(Type a, Gwion gwion) {
+ANN void free_type(const Type a, struct Gwion_ *const gwion) {
   if(freeable(a)) {
-    if(GET_FLAG(a, union)) {
-      if(a->e->def->union_def) {
-        if(!GET_FLAG(a, pure))
-          free_union_def(gwion->mp, a->e->def->union_def);
-        else
-          free_decl_list(gwion->mp, a->e->def->list);
-      }
-      a->e->def->union_def = NULL;
-    }
-    if(a->e->def)
-      class_def_cleaner(gwion, a->e->def);
+    if(tflag(a, tflag_udef))
+      free_union_def(gwion->mp, a->e->udef);
+    if(tflag(a, tflag_cdef))
+      class_def_cleaner(gwion, a->e->cdef);
   }
   if(a->nspc)
-    REM_REF(a->nspc, gwion);
+    nspc_remref(a->nspc, gwion);
   if(a->e->tuple)
     free_tupleform(a->e->tuple, gwion);
   mp_free(gwion->mp, TypeInfo, a->e);
   mp_free(gwion->mp, Type, a);
+
 }
 
 Type new_type(MemPool p, const m_uint xid, const m_str name, const Type parent) {
@@ -42,7 +36,7 @@ Type new_type(MemPool p, const m_uint xid, const m_str name, const Type parent)
   type->e->parent = parent;
   if(parent)
     type->size = parent->size;
-  type->ref = new_refcount(p, free_type);
+  type->ref = 1;
   return type;
 }
 
@@ -79,7 +73,7 @@ describe_find(value, Value)
 //describe_find(func,  Func)
 
 ANN Type typedef_base(Type t) {
-  while(GET_FLAG(t, typedef))
+  while(tflag(t, tflag_typedef))
     t = t->e->parent;
   return t;
 }
@@ -116,11 +110,10 @@ ANN Type array_type(const Env env, const Type src, const m_uint depth) {
     inherit(t);
     t->nspc->info->class_data_size = SZ_INT;
     nspc_allocdata(env->gwion->mp, t->nspc);
-    *(f_release**)(t->nspc->info->class_data) = (depth > 1 || !GET_FLAG(src, struct)) ?
+    *(f_release**)(t->nspc->info->class_data) = (depth > 1 || !tflag(src, tflag_struct)) ?
       object_release : struct_release;
   } else
-  ADD_REF((t->nspc = env->gwion->type[et_array]->nspc))
-  SET_FLAG(t, valid);
+  nspc_addref((t->nspc = env->gwion->type[et_array]->nspc));
   mk_class(env, t);
   nspc_add_type_front(src->e->owner, sym, t);
   return t;
@@ -128,15 +121,15 @@ ANN Type array_type(const Env env, const Type src, const m_uint depth) {
 
 ANN m_bool type_ref(Type t) {
   do {
-    if(GET_FLAG(t, empty))
+    if(tflag(t, tflag_empty))
       return GW_OK;
-    if(GET_FLAG(t, typedef) && t->e->def)
-      if(t->e->def->base.ext && t->e->def->base.ext->array) {
-        if(!t->e->def->base.ext->array->exp)
+    if(tflag(t, tflag_typedef) && t->e->cdef)
+      if(t->e->cdef->base.ext && t->e->cdef->base.ext->array) {
+        if(!t->e->cdef->base.ext->array->exp)
           return GW_OK;
         else {
           const Type type = t->e->parent->e->d.base_type;
-          if(SAFE_FLAG(type, empty))
+          if(tflag(type, tflag_empty))
             return GW_OK;
         }
       }
index 9a7c8143021bf7e44cc61c4da211a219d466c72c..05db3f35a8834313d5b2c45de96790f7f6c8d8de 100644 (file)
@@ -6,12 +6,12 @@
 
 static m_str const special_name[] = { "^nonnull", "^force" };
 #define SPECIAL_LEN strlen(special_name[0]) + strlen(special_name[1])
-static const ae_flag special_flag[] = { ae_flag_nonnull, ae_flag_force };
+static const enum tflag special_flag[] = { tflag_nonnull, tflag_force };
 
 typedef struct {
   const Type    type;
   Symbol  name;
-  ae_flag flag;
+  enum tflag flag;
   uint st_type;
 } SpecialType;
 
@@ -19,22 +19,23 @@ typedef struct {
 ANN static Type specialtype_create(const Env env, const SpecialType *s) {
   const Type t = type_copy(env->gwion->mp, s->type);
   if(t->nspc)
-    ADD_REF(t->nspc)
+    nspc_addref(t->nspc);
   t->name = s_name(s->name);
-  t->flag = s->type->flag | s->flag;
+  t->flag = s->type->flag;
+  t->tflag |= s->type->tflag | s->flag;
   t->e->parent = unflag_type(s->type);
   nspc_add_type_front(s->type->e->owner, s->name, t);
   mk_class(env, t);
   return t;
 }
 
-static inline int get_flag(const Type t, const ae_flag flag) {
-  return (t->flag & flag) == flag;
+static inline int get_flag(const Type t, const enum tflag flag) {
+  return (t->tflag & flag) == flag;
 }
 
 
 ANN static void specialtype_flag(SpecialType *s, m_str c, const uint i) {
-  const ae_flag flag = special_flag[i];
+  const enum tflag flag = special_flag[i];
   if(i == s->st_type || get_flag(s->type, flag)) {
     strcat(c, special_name[i]);
     s->flag |= flag;
index 13cfdd6cc2b5c8a2990511b1611a1d6e58554a15..dfbf80b8d77fe90c0772792a2da2d0125c59a333 100644 (file)
@@ -4,16 +4,16 @@
 #include "vm.h"
 #include "gwion.h"
 
-ANN static void free_value(Value a, Gwion gwion) {
+ANN void free_value(Value a, Gwion gwion) {
   const Type t = a->type;
-  if(!GET_FLAG(a, func) && a->d.ptr && !GET_FLAG(a, union) &&
-      !(GET_FLAG(a, enum) && GET_FLAG(a, builtin) && a->from->owner_class)
+  if(!vflag(a, vflag_func) && a->d.ptr && !vflag(a, vflag_direct) &&
+      !(vflag(a, vflag_enum) && vflag(a, vflag_builtin) && a->from->owner_class)
       && isa(t, gwion->type[et_object]) < 0)
    _mp_free(gwion->mp, t->size, a->d.ptr);
-  else if(GET_FLAG(a, enum) && GET_FLAG(a, dtor))
+  else if(vflag(a, vflag_freeme))
     xfree(a->d.ptr);
   if(is_class(gwion, t))
-    REM_REF(t, gwion)
+    type_remref(t, gwion);
   mp_free(gwion->mp, ValueFrom, a->from);
   mp_free(gwion->mp, Value, a);
 }
@@ -23,7 +23,7 @@ ANN Value new_value(MemPool p, const Type type, const m_str name) {
   a->from = mp_calloc(p, ValueFrom);
   a->type       = type;
   a->name       = name;
-  a->ref = new_refcount(p, free_value);
+  a->ref = 1;
   return a;
 }
 
index dfd4363a5f2b994b3cd8a30338f48c1fddb2d86b..f4284dccd45a121170754718574de111a0f974b9 100644 (file)
 #include "pass.h" // fork_clean
 #include "shreduler_private.h"
 
-ANN static void driver_arg(const Gwion gwion, Driver *di) {
-  for(m_uint i = 0; i < map_size(&gwion->data->plug->drv); ++i) {
-    const m_str name = (m_str)VKEY(&gwion->data->plug->drv, i);
-    const size_t len = strlen(name);
-    if(!strncmp(name, di->si->arg, len)) {
-      di->func = (f_bbqset)VVAL(&gwion->data->plug->drv, i);
-      break;
-    }
-  }
-}
-
 ANN m_bool gwion_audio(const Gwion gwion) {
   Driver *const di = gwion->vm->bbq;
   if(di->si->arg)
-    driver_arg(gwion, di);
+    driver_ini(gwion);
   di->func(di->driver);
   CHECK_BB(di->driver->ini(gwion->vm, di));
   driver_alloc(di);
@@ -35,16 +24,11 @@ ANN m_bool gwion_audio(const Gwion gwion) {
 }
 
 ANN static inline m_bool gwion_engine(const Gwion gwion) {
-  return type_engine_init(gwion, &gwion->data->plug->vec[GWPLUG_IMPORT]) > 0;
-}
-
-ANN static inline void gwion_compile(const Gwion gwion, const Vector v) {
-  for(m_uint i = 0; i < vector_size(v); i++)
-    compile_filename(gwion, (m_str)vector_at(v, i));
+  return type_engine_init(gwion) > 0;
 }
 
 ANN static void gwion_cleaner(const Gwion gwion) {
-  const VM_Code code = new_vm_code(gwion->mp, NULL, 0, ae_flag_builtin, "in code dtor");
+  const VM_Code code = new_vm_code(gwion->mp, NULL, 0, 1, "in code dtor");
   gwion->vm->cleaner_shred = new_vm_shred(gwion->mp, code);
   vm_ini_shred(gwion->vm, gwion->vm->cleaner_shred);
 }
@@ -72,15 +56,13 @@ ANN static void gwion_core(const Gwion gwion) {
 }
 
 ANN static m_bool gwion_ok(const Gwion gwion, Arg* arg) {
-  gwion->data->plug = new_pluginfo(gwion->mp, &arg->lib);
+  CHECK_BB(plug_ini(gwion, &arg->lib))
   shreduler_set_loop(gwion->vm->shreduler, arg->loop);
   if(gwion_audio(gwion) > 0) {
     plug_run(gwion, &arg->mod);
     if(gwion_engine(gwion)) {
       gwion_cleaner(gwion);
-      gwion_compile(gwion, &arg->add);
-      if(arg->read_stdin)
-        compile_file(gwion, "stdin", stdin);
+      (void)arg_compile(gwion, arg);
       return GW_OK;
     }
   }
@@ -185,6 +167,6 @@ ANN void push_global(struct Gwion_ *gwion, const m_str name) {
 
 ANN Nspc pop_global(struct Gwion_ *gwion) {
   const Nspc nspc = gwion->env->global_nspc->parent;
-  REM_REF(gwion->env->global_nspc, gwion)
+  nspc_remref(gwion->env->global_nspc, gwion);
   return gwion->env->curr = gwion->env->global_nspc = nspc;
 }
index 5f74b69726626c07f160fba06a0bdd01ecf31ed6..a85cd6a5acf6f476f440807957be9d5fc943f6db 100644 (file)
@@ -48,7 +48,7 @@ ANN void free_gwiondata(const struct Gwion_ *gwion) {
   map_release(&data->id);
   vector_release(&data->reserved);
   free_passes(gwion->mp, data->passes);
-  if(data->plug)
+  if(data->plug.ptr)
     free_plug(gwion);
   free_gwiondata_cpy(gwion->mp, data);
 }
index e04f80066b8ca2463d9d1a424876fa5709e21ea4..aaa39879fc97cd9e189bdf5025c8be5298026123 100644 (file)
 #include "specialid.h"
 #include "template.h"
 
-ANN static m_bool mk_xtor(MemPool p, const Type type, const m_uint d, const ae_flag e) {
-  VM_Code* code = e == ae_flag_ctor ? &type->nspc->pre_ctor : &type->nspc->dtor;
+ANN static m_bool mk_xtor(MemPool p, const Type type, const m_uint d, const enum tflag e) {
+  VM_Code* code = e == tflag_ctor ? &type->nspc->pre_ctor : &type->nspc->dtor;
   const m_str name = type->name;
-  *code = new_vm_code(p, NULL, SZ_INT, e | ae_flag_member | ae_flag_builtin, name);
+  *code = new_vm_code(p, NULL, SZ_INT, 1, name);
   (*code)->native_func = (m_uint)d;
-  type->flag |= e;
+  type->tflag |= e;
   return GW_OK;
 }
 
 ANN2(1,2) static inline m_bool class_parent(const Env env, Type t) {
   do {
-    if(GET_FLAG(t, valid))
+    if(tflag(t, tflag_check))
       break;
-    if(t->e->def)
-      CHECK_BB(traverse_class_def(env, t->e->def))
+    if(t->e->cdef)
+      CHECK_BB(traverse_class_def(env, t->e->cdef))
   } while((t = t->e->parent));
   return GW_OK;
 }
@@ -43,20 +43,19 @@ ANN2(1,2) static void import_class_ini(const Env env, const Type t) {
     inherit(t);
   t->e->owner = env->curr;
   t->e->owner_class = env->class_def;
-  SET_FLAG(t, valid);
   env_push_type(env, t);
 }
 
 ANN2(1) void gwi_class_xtor(const Gwi gwi, const f_xtor ctor, const f_xtor dtor) {
   const Type t = gwi->gwion->env->class_def;
   if(ctor)
-    mk_xtor(gwi->gwion->mp, t, (m_uint)ctor, ae_flag_ctor);
+    mk_xtor(gwi->gwion->mp, t, (m_uint)ctor, tflag_ctor);
   if(dtor)
-    mk_xtor(gwi->gwion->mp, t, (m_uint)dtor, ae_flag_dtor);
+    mk_xtor(gwi->gwion->mp, t, (m_uint)dtor, tflag_dtor);
 }
 
 ANN static inline void gwi_type_flag(const Type t) {
-  SET_FLAG(t, scan1 | ae_flag_scan2 | ae_flag_check | ae_flag_emit);
+  set_tflag(t, tflag_scan0 | tflag_scan1 | tflag_scan2 | tflag_check | tflag_emit);
 }
 
 ANN static Type type_finish(const Gwi gwi, const Type t) {
@@ -80,7 +79,7 @@ ANN2(1,2) Type gwi_class_ini(const Gwi gwi, const m_str name, const m_str parent
     CHECK_BO(template_push_types(gwi->gwion->env, tmpl))
   const Type base = find_type(gwi->gwion->env, td);
   const Type_List tl = td->types;
-  if(GET_FLAG(base, unary))
+  if(tflag(base, tflag_ntmpl))
     td->types = NULL;
   const Type p = !td->types ? handle_class(gwi, td) : NULL;
   td->types = tl;
@@ -88,15 +87,15 @@ ANN2(1,2) Type gwi_class_ini(const Gwi gwi, const m_str name, const m_str parent
     nspc_pop_type(gwi->gwion->mp, gwi->gwion->env->curr);
   CHECK_OO(p)
   const Type t = new_type(gwi->gwion->mp, ++gwi->gwion->env->scope->type_xid, s_name(ck.sym), p);
-  t->e->def = new_class_def(gwi->gwion->mp, 0, ck.sym, td, NULL, loc(gwi));
-  t->e->def->base.tmpl = tmpl;
-  t->e->def->base.type = t;
+  t->e->cdef = new_class_def(gwi->gwion->mp, 0, ck.sym, td, NULL, loc(gwi));
+  t->e->cdef->base.tmpl = tmpl;
+  t->e->cdef->base.type = t;
   t->e->tuple = new_tupleform(gwi->gwion->mp, p);
   t->e->parent = p;
   if(td->array)
-    SET_FLAG(t, typedef);
+    set_tflag(t, tflag_typedef);
   if(ck.tmpl)
-    SET_FLAG(t, template);
+    set_tflag(t, tflag_tmpl);
   else
     gwi_type_flag(t);
   return type_finish(gwi, t);
@@ -107,7 +106,7 @@ ANN Type gwi_struct_ini(const Gwi gwi, const m_str name) {
   const Type t = new_type(gwi->gwion->mp, ++gwi->gwion->env->scope->type_xid, name, gwi->gwion->type[et_compound]);
   t->e->tuple = new_tupleform(gwi->gwion->mp, NULL);
   gwi_type_flag(t);
-  SET_FLAG(t, struct);
+  set_tflag(t, tflag_struct);
   return type_finish(gwi, t);
 }
 
index efd1db709a20cb78101a334a1d9c968dbaf46c27..4b556234350facf0914176921ffa3e2784c944ba 100644 (file)
@@ -218,10 +218,8 @@ ANN Type_Decl* str2decl(const Gwion gwion, const m_str str, const loc_t pos) {
 ANN Type str2type(const Gwion gwion, const m_str str, const loc_t pos) {
   DECL_OO(Type_Decl *, td, = str2decl(gwion, str, pos))
   const Type t = known_type(gwion->env, td);
-  if(t)
-    return t;
   free_type_decl(gwion->mp, td);
-  return NULL;
+  return t;
 }
 
 ANN static inline m_bool ac_finish(const Gwion gwion, const struct AC *ac) {
index ee398e3759c534322595850ddf6167488517e11a..1607e576736668099a5b7ec637d3f45ddfc7b480 100644 (file)
@@ -65,7 +65,7 @@ ANN static void import_enum_end(const Gwi gwi, const Vector v) {
   for(m_uint i = 0; i < vector_size(v); i++) {
     const Value value = (Value)vector_at(v, i);
     const m_uint addr = vector_at(&ck->v, i);
-    SET_FLAG(value, builtin);
+    set_vflag(value, vflag_builtin);
 //    ADD_REF(value->type); // what ?
     if(!gwi->gwion->env->class_def)
       value->d.ptr = (m_uint*)(addr ? addr : i);
index 9fdf808c20569a6294af0ede917643ee09d6ddd5..32d2a8c3cc5e19f940aef5ea52a542257d226bda 100644 (file)
@@ -40,7 +40,9 @@ ANN Arg_List make_dll_arg_list(const Vector v) {
 
 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, ck->flag | ae_flag_builtin);
+  Func_Base *base = new_func_base(gwi->gwion->mp, ck->td, ck->sym, arg_list, ck->flag);
+  if(ck->variadic)
+    base->fbflag |= fbflag_variadic;
   ck->td = NULL;
   if(ck->tmpl) {
     base->tmpl = gwi_tmpl(gwi);
@@ -52,9 +54,6 @@ ANEW ANN static Func_Base* gwi_func_base(const Gwi gwi, ImportCK *ck) {
 ANEW ANN static Func_Def import_fdef(const Gwi gwi, ImportCK *ck) {
   Func_Base* base = gwi_func_base(gwi, ck);
   const Func_Def fdef = new_func_def(gwi->gwion->mp, base, NULL, loc(gwi));
-  fdef->d.dl_func_ptr = (void*)(m_uint)ck->addr;
-  if(base->tmpl)
-    SET_FLAG(fdef->base, template);
   return fdef;
 }
 
@@ -72,10 +71,11 @@ ANN static m_bool error_fdef(const Gwi gwi, const Func_Def fdef) {
 
 ANN m_int gwi_func_valid(const Gwi gwi, ImportCK *ck) {
   const Func_Def fdef = import_fdef(gwi, ck);
-  if(SAFE_FLAG(gwi->gwion->env->class_def, template))
+  if(safe_tflag(gwi->gwion->env->class_def, tflag_tmpl))
     /*return*/ section_fdef(gwi, fdef);
   if(traverse_func_def(gwi->gwion->env, fdef) < 0)
     return error_fdef(gwi, fdef);
+  builtin_func(gwi->gwion->mp, fdef->base->func, ck->addr);
   ck_end(gwi);
   return GW_OK;
 }
@@ -91,6 +91,12 @@ ANN m_int gwi_func_end(const Gwi gwi, const f_xfun addr, const ae_flag flag) {
 
 ANN m_int gwi_func_arg(const Gwi gwi, const restrict m_str t, const restrict m_str n) {
   CHECK_BB(ck_ok(gwi, ck_fdef))
+  if(gwi->ck->variadic)
+    GWI_ERR_B(_("already declared as variadic"));
+  if(!strcmp(n, "...")) {
+    gwi->ck->variadic = 1;
+    return GW_OK;
+  }
   DECL_OB(Type_Decl*, td, = gwi_str2decl(gwi, t))
   const Var_Decl var = gwi_str2var(gwi, n);
   if(var) {
@@ -98,7 +104,7 @@ ANN m_int gwi_func_arg(const Gwi gwi, const restrict m_str t, const restrict m_s
     vector_add(&gwi->ck->v, (vtype)arg);
     return GW_OK;
   }
-  free_type_decl(gwi->gwion->mp, td);
+  free_type_decl(gwi->gwion->mp, td); // ???
   return GW_ERROR;
 }
 
@@ -118,11 +124,11 @@ ANN Type gwi_fptr_end(const Gwi gwi, const ae_flag flag) {
   // what happens if it is in a template class ?
   const m_bool ret = traverse_fptr_def(gwi->gwion->env, fptr);
   if(fptr->base->func) // is it needed ?
-    SET_FLAG(fptr->base->func, builtin);
+    set_vflag(fptr->base->func->value_ref, vflag_builtin);
   const Type t = ret > 0 ? fptr->type : NULL;
   free_fptr_def(gwi->gwion->mp, fptr);
   if(fptr->type)
-    REM_REF(fptr->type, gwi->gwion)
+    type_remref(fptr->type, gwi->gwion);
   ck_end(gwi);
   return t;
 }
index 8f0f85f8491d2b681806bd8e5932999cfc5c60e3..56292c207fe05ea257108d255cc18b327abfb30c 100644 (file)
@@ -11,7 +11,7 @@
 #include "gwi.h"
 
 void gwi_body(const Gwi gwi, const Ast body) {
-  const Class_Def cdef = gwi->gwion->env->class_def->e->def;
+  const Class_Def cdef = gwi->gwion->env->class_def->e->cdef;
   if(!cdef->body)
     cdef->body = body;
   else
@@ -27,3 +27,15 @@ ANN void gwi_reset(const Gwi gwi) {
   }
   env_reset(gwi->gwion->env);
 }
+
+ANN m_bool gwi_run(const Gwion gwion, m_bool (*f)(const Gwi)) {
+   const m_str name = gwion->env->name;
+   struct loc_t_ loc = {};
+   OperCK oper = {};
+   struct Gwi_ gwi = { .gwion=gwion, .loc=&loc, .oper=&oper };
+   const m_bool ret = f(&gwi);
+   if(ret < 0)
+     gwi_reset(&gwi);
+   gwion->env->name = name;
+   return ret;
+}
index 5d5ed543db7cd402330f3c6652f579d1fd5423b6..3639445f1461a367a94640877f7ff1583d857d71 100644 (file)
@@ -35,11 +35,13 @@ ANN2(1) m_int gwi_item_end(const Gwi gwi, const ae_flag flag, const m_uint* addr
   const Env env = gwi->gwion->env;
   gwi->ck->exp->d.exp_decl.list->self->addr = (m_uint*)addr;
   gwi->ck->exp->d.exp_decl.td->flag = flag;
-  if(env->class_def && GET_FLAG(env->class_def, template))
+  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;
-  SET_FLAG(value, builtin);
+  set_vflag(value, vflag_builtin);
+  if(!env->class_def)
+    SET_FLAG(value, global);
   const m_uint offset = value->from->offset;
   free_exp(gwi->gwion->mp, gwi->ck->exp);
   ck_end(gwi);
index f4f2e4144ceb4bc176864c2c169283ee5123c36a..36fd29671055a254d3e8d92859e63ff9ad23db90 100644 (file)
@@ -43,9 +43,8 @@ ANN void gwi_set_loc(const Gwi gwi, const m_str file, const uint line) {
 }
 
 ANN static m_bool mk_gack(MemPool p, const Type type, const f_gack d) {
-  const VM_Code code = new_vm_code(p, NULL, SZ_INT, ae_flag_member | ae_flag_builtin, "@gack");
+  const VM_Code code = new_vm_code(p, NULL, SZ_INT, 1, "@gack");
   code->native_func = (m_uint)d;
-  SET_FLAG(code, builtin);
   type->e->gack = code;
   return GW_OK;
 }
index 32006abc9f4d317bf73cb9cce9f606a253d37e0d..cfd2b7bf53e2c0a60a1f05b515233bf7da542dbf 100644 (file)
@@ -34,6 +34,7 @@ ANN Type gwi_typedef_end(const Gwi gwi, const ae_flag flag) {
   gwi->ck->tmpl = NULL;
   const m_bool ret = traverse_type_def(gwi->gwion->env, tdef);
   const Type t = tdef->type;
+  set_tflag(t, tflag_scan0 | tflag_scan1 | tflag_scan2 | tflag_check | tflag_emit);
   free_type_def(gwi->gwion->mp, tdef);
   ck_end(gwi);
   return ret > 0 ? t : NULL;
index 73f8f06160901248656d77f8bc4f0a8a36d0b86f..aaa603ff69ec412d3a555173a96a864daa9a139d 100644 (file)
@@ -51,7 +51,7 @@ ANN static Type union_type(const Gwi gwi, const Union_Def udef) {
       gwi->gwion->env->class_def->nspc->info->offset =
        udef->o + udef->s;
   if(udef->xid || !udef->type_xid) {
-    SET_FLAG(udef->value, builtin);
+    set_vflag(udef->value, vflag_builtin);
     const M_Object o = new_object(gwi->gwion->mp, NULL, udef->value->type);
     udef->value->d.ptr = (m_uint*)o;
    return udef->value->type;
@@ -75,7 +75,7 @@ ANN Type gwi_union_end(const Gwi gwi, const ae_flag flag) {
     gwi->ck->tmpl = NULL;
   }
   const Type t = union_type(gwi, udef);
-  if(!SAFE_FLAG(t, template))
+  if(!safe_tflag(t, tflag_tmpl))
     free_union_def(gwi->gwion->mp, udef);
   ck_end(gwi);
   return t;
index 35d3b45466e6eb29540d867de8425cab0644635d..9d55f6ebf4081e9625847f78a5b5e2e58f3dfcb3 100644 (file)
@@ -74,9 +74,9 @@ OP_CHECK(opck_object_dot);
 OP_EMIT(opem_object_dot);
 ANN static m_bool import_core_libs(const Gwi gwi) {
   const Type t_class = gwi_mk_type(gwi, "@Class", SZ_INT, NULL);
+  set_tflag(t_class, tflag_infer);
   GWI_BB(gwi_set_global_type(gwi, t_class, et_class))
   GWI_BB(gwi_gack(gwi, t_class, gack_class)) // not working yet
-  GWI_BB(gwi_add_type(gwi, t_class))
   GWI_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, (m_str)OP_ANY_TYPE, NULL))
   GWI_BB(gwi_oper_add(gwi, opck_object_dot))
   GWI_BB(gwi_oper_emi(gwi, opem_object_dot))
@@ -84,9 +84,8 @@ ANN static m_bool import_core_libs(const Gwi gwi) {
   const Type t_undefined = gwi_mk_type(gwi, "@Undefined", SZ_INT, NULL);
   GWI_BB(gwi_set_global_type(gwi, t_undefined, et_undefined))
   const Type t_auto = gwi_mk_type(gwi, "auto", SZ_INT, NULL);
-  SET_FLAG(t_auto, infer);
+  set_tflag(t_auto, tflag_infer);
   GWI_BB(gwi_set_global_type(gwi, t_auto, et_auto))
-  SET_FLAG(t_class, infer);
   const Type t_void  = gwi_mk_type(gwi, "void", 0, NULL);
   GWI_BB(gwi_gack(gwi, t_void, gack_void))
   GWI_BB(gwi_set_global_type(gwi, t_void, et_void))
@@ -125,7 +124,7 @@ ANN static m_bool import_core_libs(const Gwi gwi) {
   GWI_BB(gwi_gack(gwi, t_fptr, gack_fptr))
   GWI_BB(gwi_set_global_type(gwi, t_fptr, et_fptr))
   const Type t_lambda = gwi_mk_type(gwi, "@lambda", SZ_INT, "@function");
-  SET_FLAG(t_lambda, infer);
+  set_tflag(t_lambda, tflag_infer);
   GWI_BB(gwi_set_global_type(gwi, t_lambda, et_lambda))
 
   GWI_BB(gwi_typedef_ini(gwi, "int", "@internal"))
@@ -164,19 +163,9 @@ ANN static m_bool import_core_libs(const Gwi gwi) {
   return GW_OK;
 }
 
-ANN m_bool type_engine_init(const Gwion gwion, const Vector plug_dirs) {
+ANN m_bool type_engine_init(const Gwion gwion) {
   gwion->env->name = "[builtin]";
-  struct loc_t_ loc = {};
-  OperCK oper = {};
-  struct Gwi_ gwi = { .gwion=gwion, .loc=&loc, .oper=&oper };
-  CHECK_BB(import_core_libs(&gwi))
-  push_global(gwion, "[plugins]");
-  gwion->env->name = "[imported]";
-  for(m_uint i = 0; i < vector_size(plug_dirs); ++i) {
-    m_bool (*import)(Gwi) = (m_bool(*)(Gwi))vector_at(plug_dirs, i);
-    if(import && import(&gwi) < 0)
-      gwi_reset(&gwi);
-  }
+  CHECK_BB(gwi_run(gwion, import_core_libs))
   push_global(gwion, "[user]");
   return GW_OK;
 }
index 2f56dd16abba165d8be2ec677bc7db505946a78a..2c3818f40730d941acae6aa6d36e895511cd227c 100644 (file)
@@ -58,7 +58,7 @@ GWION_IMPORT(event) {
   gwi->gwion->type[et_event] = t_event; // use func
 
   GWI_BB(gwi_item_ini(gwi, "@internal", "@shreds"))
-  GWI_BB(gwi_item_end(gwi, ae_flag_member, NULL))
+  GWI_BB(gwi_item_end(gwi, ae_flag_none, NULL))
   GWI_BB(gwi_func_ini(gwi, "void", "signal"))
   GWI_BB(gwi_func_end(gwi, event_signal, ae_flag_none))
   GWI_BB(gwi_func_ini(gwi, "void", "broadcast"))
index 587b1fa4e75df60729f884da1e88d887b9101321..b1e9ef76fb29f6f23bce6c2a122802e701b519bb 100644 (file)
@@ -37,19 +37,26 @@ ANN static Func_Def from_base(const Env env, struct dottmpl_ *const dt, const Ns
   DECL_OO(const Value, v, = nspc_lookup_value0(nspc, sym) ?: nspc_lookup_value0(nspc, fdef->base->xid))
   if(isa(v->type, env->gwion->type[et_class]) > 0)
     return NULL;
+  if(vflag(v, vflag_builtin)) {
+    dt->xfun = v->d.func_ref->def->d.dl_func_ptr;
+    v->d.func_ref->def->d.dl_func_ptr = NULL;
+  }
   const Func_Def def = cpy_func_def(env->gwion->mp, v->d.func_ref->def);
+  if(vflag(v, vflag_builtin))
+    v->d.func_ref->def->d.dl_func_ptr = dt->xfun;
   def->base->tmpl->call = cpy_type_list(env->gwion->mp, dt->tl);
   def->base->tmpl->base = dt->vt_index;
   dt->def = def;
   dt->owner = v->from->owner;
   dt->owner_class = v->from->owner_class;
-  SET_FLAG(def->base, template);
   return def;
 }
 
 ANN static Func_Def traverse_tmpl(const Emitter emit, struct dottmpl_ *const dt, const Nspc nspc) {
   DECL_OO(const Func_Def, def, = from_base(emit->env, dt, nspc))
   CHECK_BO(traverse_dot_tmpl(emit, dt))
+  if(dt->xfun)
+    builtin_func(emit->gwion->mp, def->base->func, dt->xfun);
   return def;
 }
 
@@ -83,7 +90,7 @@ INSTR(DotTmpl) {
   struct dottmpl_ *dt = (struct dottmpl_*)instr->m_val;
   const m_str name = dt->name;
   const M_Object o = *(M_Object*)REG(-SZ_INT);
-  Type t = !GET_FLAG(o->type_ref, nonnull) ? o->type_ref : o->type_ref->e->parent;
+  Type t = !tflag(o->type_ref, tflag_nonnull) ? o->type_ref : o->type_ref->e->parent;
   do {
     const Emitter emit = shred->info->vm->gwion->emit;
     emit->env->name = "runtime";
@@ -94,7 +101,7 @@ INSTR(DotTmpl) {
     if(f) {
       if(!f->code)
         break;
-      if(GET_FLAG(f, member))
+      if(vflag(f->value_ref, vflag_member))
         shred->reg += SZ_INT;
       *(VM_Code*)(shred->reg-SZ_INT) = f->code;
       return;
@@ -103,7 +110,7 @@ INSTR(DotTmpl) {
       if(!def)
         continue;
       const Func f = def->base->func;
-      if(GET_FLAG(f, member))
+      if(vflag(f->value_ref, vflag_member))
         shred->reg += SZ_INT;
       *(VM_Code*)(shred->reg-SZ_INT) = f->code;
       return;
index 526c1df2496813d2b0e86a8a3b6297d3a33192b0..9781373c297fa5c8885547decd223de7664005b4 100644 (file)
@@ -34,7 +34,7 @@ static OP_EMIT(opem_func_assign) {
   if(bin->rhs->info->type->e->d.func->def->base->tmpl)
     fptr_instr(emit, bin->lhs->info->type->e->d.func, 2);
   const Instr instr = emit_add_instr(emit, int_r_assign);
-  if(!is_fptr(emit->gwion, bin->lhs->info->type) && GET_FLAG(bin->rhs->info->type->e->d.func, member)) {
+  if(!is_fptr(emit->gwion, bin->lhs->info->type) && vflag(bin->rhs->info->type->e->d.func->value_ref, vflag_member)) {
     const Instr pop = emit_add_instr(emit, RegPop);
     pop->m_val = SZ_INT;
     const Instr cpy = emit_add_instr(emit, Reg2Reg);
@@ -95,10 +95,10 @@ ANN static m_bool fptr_check(const Env env, struct FptrInfo *info) {
       ERR_B(info->pos, _("can't assign non member function to member function pointer"))
   } else if(l_type && isa(r_type, l_type) < 0)
       ERR_B(info->pos, _("can't assign member function to a pointer of an other class"))
-  if(GET_FLAG(info->rhs, member)) {
-    if(!GET_FLAG(info->lhs, member))
+  if(vflag(info->rhs->value_ref, vflag_member)) {
+    if(!vflag(info->lhs->value_ref, vflag_member))
       ERR_B(info->pos, _("can't assign static function to member function pointer"))
-  } else if(GET_FLAG(info->lhs, member))
+  } else if(vflag(info->lhs->value_ref, vflag_member))
       ERR_B(info->pos, _("can't assign member function to static function pointer"))
   return GW_OK;
 }
@@ -110,8 +110,8 @@ ANN static inline m_bool fptr_rettype(const Env env, struct FptrInfo *info) {
 }
 
 ANN static inline m_bool fptr_arity(struct FptrInfo *info) {
-  return GET_FLAG(info->lhs->def->base, variadic) ==
-         GET_FLAG(info->rhs->def->base, variadic);
+  return fbflag(info->lhs->def->base, fbflag_variadic) ==
+         fbflag(info->rhs->def->base, fbflag_variadic);
 }
 
 ANN static Type fptr_type(const Env env, struct FptrInfo *info) {
@@ -152,7 +152,6 @@ ANN static m_bool _check_lambda(const Env env, Exp_Lambda *l, const Func_Def def
     ERR_B(exp_self(l)->pos, _("argument number does not match for lambda"))
   l->def->base->flag = def->base->flag;
   l->def->base->td = cpy_type_decl(env->gwion->mp, def->base->td);
-  SET_FLAG(l->def->base, abstract); // mark as non immediate lambda
   map_set(&env->curr->info->func->map, (m_uint)l->def->base, env->scope->depth);
   const m_bool ret = check_traverse_fdef(env, l->def);
   map_remove(&env->curr->info->func->map, (m_uint)l->def->base);
@@ -168,7 +167,7 @@ ANN static m_bool _check_lambda(const Env env, Exp_Lambda *l, const Func_Def def
 ANN m_bool check_lambda(const Env env, const Type t, Exp_Lambda *l) {
   const Func_Def fdef = t->e->d.func->def;
   struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)check_cdef,
-    .scope=env->scope->depth, .flag=ae_flag_check };
+    .scope=env->scope->depth, .flag=tflag_check };
   l->owner = t->e->owner_class;
   CHECK_BB(envset_push(&es, l->owner, t->e->owner))
   const m_bool ret = _check_lambda(env, l, fdef);
@@ -182,7 +181,7 @@ ANN m_bool check_lambda(const Env env, const Type t, Exp_Lambda *l) {
 
 ANN static m_bool fptr_do(const Env env, struct FptrInfo *info) {
   if(isa(info->exp->info->type, env->gwion->type[et_lambda]) < 0) {
-    m_bool nonnull = GET_FLAG(info->exp->info->type, nonnull);
+    m_bool nonnull = tflag(info->exp->info->type, tflag_nonnull);
     CHECK_BB(fptr_check(env, info))
     DECL_OB(const Type, t, = fptr_type(env, info))
     info->exp->info->type = !nonnull ? t : nonnul_type(env, t);
@@ -208,7 +207,7 @@ static OP_CHECK(opck_auto_fptr) {
   const m_bool ret = traverse_fptr_def(env, fptr_def);
   const Type t = fptr_def->type;
   free_fptr_def(env->gwion->mp, fptr_def);
-  REM_REF(t, env->gwion)
+  type_remref(t, env->gwion);
   bin->rhs->d.exp_decl.list->self->value->type = bin->rhs->info->type = bin->rhs->d.exp_decl.type = t;
   exp_setvar(bin->rhs, 1);
   return ret > 0 ? t : env->gwion->type[et_null];
@@ -256,8 +255,8 @@ static void member_fptr(const Emitter emit) {
 }
 
 static int is_member(const Type from, const Type to) {
-  return GET_FLAG(from->e->d.func, member) &&
-    !(GET_FLAG(from, nonnull) || GET_FLAG(to, nonnull));
+  return vflag(from->e->d.func->value_ref, vflag_member) &&
+    !(tflag(from, tflag_nonnull) || tflag(to, tflag_nonnull));
 }
 
 static OP_EMIT(opem_fptr_cast) {
@@ -303,7 +302,14 @@ ANN static Type fork_type(const Env env, const Exp_Unary* unary) {
     return env->gwion->type[et_fork];
   char c[21 + strlen(t->name)];
   sprintf(c, "nonnull TypedFork:[%s]", t->name);
-  return str2type(env->gwion, c, exp_self(unary)->pos);
+  const Type fork = env->gwion->type[et_fork];
+  UNSET_FLAG(fork, final);
+  const Type typed = str2type(env->gwion, "TypedFork", exp_self(unary)->pos);
+  UNSET_FLAG(typed, final);
+  const Type ret = str2type(env->gwion, c, exp_self(unary)->pos);
+  SET_FLAG(typed, final);
+  SET_FLAG(fork, final);
+  return ret;
 }
 
 static OP_CHECK(opck_spork) {
@@ -330,7 +336,7 @@ static OP_EMIT(opem_spork) {
 }
 
 static FREEARG(freearg_xork) {
-  REM_REF((VM_Code)instr->m_val, gwion)
+  vmcode_remref((VM_Code)instr->m_val, gwion);
 }
 
 static FREEARG(freearg_dottmpl) {
index 76e20ae5a6bdec0f12135827c68080bd1981a0a5..8a1af0bbcb79ccfe261f59deffed1210620d05eb 100644 (file)
@@ -259,7 +259,7 @@ static INSTR(UsrUGenTick) {
   if(!code)
     Except(shred, "[NullTickException]");
   uu->shred = new_vm_shred(shred->info->vm->gwion->mp, *(VM_Code*)(shred->reg-offset));
-  ADD_REF(*(VM_Code*)(shred->reg - offset));
+  vmcode_addref(*(VM_Code*)(shred->reg - offset));
   uu->shred->info->vm = shred->info->vm;
   code_prepare(uu->shred->code);
   shreduler_ini(uu->shred->info->vm->shreduler, uu->shred);
index b8a2bf32ce7b89c6dcd287d84768c064762b46da..2d08cb34138d25e9aa6ab2df7e4bb858e2b3c2b7 100644 (file)
@@ -53,7 +53,7 @@ M_Object new_string2(const struct Gwion_ *gwion, const VM_Shred shred, const m_s
 
 ANN static void handle_dtor(const M_Object o, const VM_Shred shred) {
   const VM_Shred sh = new_vm_shred(shred->info->mp, o->type_ref->nspc->dtor);
-  ADD_REF(o->type_ref->nspc->dtor);
+  vmcode_addref(o->type_ref->nspc->dtor);
   sh->base = shred->base;
   *(M_Object*)sh->mem = o;
   vm_add_shred(shred->info->vm, sh);
@@ -70,11 +70,11 @@ ANN void __release(const M_Object o, const VM_Shred shred) {
     struct scope_iter iter = { t->nspc->info->value, 0, 0 };\
     Value v;
     while(scope_iter(&iter, &v) > 0) {
-      if(!GET_FLAG(v, static) && !GET_FLAG(v, pure) &&
+      if(!GET_FLAG(v, static) && !vflag(v, vflag_union) &&
           isa(v->type, shred->info->vm->gwion->type[et_object]) > 0)
         release(*(M_Object*)(o->data + v->from->offset), shred);
-      else if(GET_FLAG(v->type, struct) &&
-            !GET_FLAG(v, static) && !GET_FLAG(v, pure) && v->type->e->tuple) {
+      else if(tflag(v->type, tflag_struct) &&
+            !GET_FLAG(v, static) && !vflag(v, vflag_union) && v->type->e->tuple) {
         const TupleForm tf = v->type->e->tuple;
         for(m_uint i = 0; i < vector_size(&tf->types); ++i) {
           const m_bit *data = o->data + v->from->offset;
@@ -84,8 +84,9 @@ ANN void __release(const M_Object o, const VM_Shred shred) {
         }
       }
     }
-    if(GET_FLAG(t, dtor) && t->nspc->dtor) {
-      if(GET_FLAG(t->nspc->dtor, builtin))
+    if(tflag(t, tflag_dtor) && t->nspc->dtor) {
+    // check flag for array types
+      if(t->nspc->dtor->builtin)
         ((f_xtor)t->nspc->dtor->native_func)(o, NULL, shred);
       else {
         o->type_ref = t;
@@ -106,7 +107,7 @@ ANN void free_object(MemPool p, const M_Object o) {
 static ID_CHECK(opck_this) {
   if(!env->class_def)
     ERR_O(exp_self(prim)->pos, _("keyword 'this' can be used only inside class definition..."))
-  if(env->func && !GET_FLAG(env->func, member))
+  if(env->func && !vflag(env->func->value_ref, vflag_member))
       ERR_O(exp_self(prim)->pos, _("keyword 'this' cannot be used inside static functions..."))
   if(env->func && !strcmp(s_name(env->func->def->base->xid), "@gack"))
     return force_type(env, get_gack(env->class_def->e->parent)); // get_gack ?
@@ -114,7 +115,7 @@ static ID_CHECK(opck_this) {
 }
 
 static ID_EMIT(opem_this) {
-  if(!exp_getvar(exp_self(prim)) && GET_FLAG(exp_self(prim)->info->type, struct)) {
+  if(!exp_getvar(exp_self(prim)) && tflag(exp_self(prim)->info->type, tflag_struct)) {
     const Instr instr = emit_add_instr(emit, RegPushMemDeref);
     instr->m_val2 = emit->env->class_def->size;
     return (Instr)GW_OK;
index 3b15c4ee1683cf41f65e3d89d5acac2a678f031a..66a8b70dbaaa747d183e73d1a70efdb163f38fe3 100644 (file)
@@ -32,12 +32,12 @@ static INSTR(name##Object) {                     \
 describe_logical(Eq,  ==)
 describe_logical(Neq, !=)
 static inline m_bool nonnull_check(const Type l, const Type r) {
-  return !GET_FLAG(l, nonnull) && GET_FLAG(r, nonnull);
+  return !tflag(l, tflag_nonnull) && tflag(r, tflag_nonnull);
 }
 
 static inline Type check_nonnull(const Env env, const Type l, const Type r,
       const m_str action, const loc_t pos) {
-  if(GET_FLAG(r, nonnull)) {
+  if(tflag(r, tflag_nonnull)) {
     if(isa(l, env->gwion->type[et_null]) > 0)
       ERR_N(pos, _("can't %s '%s' to '%s'"), action, l->name, r->name);
     if(isa(l, r) < 0)
@@ -57,10 +57,8 @@ static OP_CHECK(at_object) {
     return env->gwion->type[et_null];
   if(check_nonnull(env, l, r, "assign", exp_self(bin)->pos) == env->gwion->type[et_null])
     return env->gwion->type[et_null];
-  if(bin->rhs->exp_type == ae_exp_decl) {
+  if(bin->rhs->exp_type == ae_exp_decl)
     SET_FLAG(bin->rhs->d.exp_decl.td, ref);
-    SET_FLAG(bin->rhs->d.exp_decl.list->self->value, ref);
-  }
   exp_setvar(bin->rhs, 1);
   return r;
 }
@@ -139,7 +137,7 @@ ANN static void emit_dot_static_data(const Emitter emit, const Value v, const ui
 
 static const f_instr regpushimm[] = { RegPushImm, RegPushImm2, RegPushImm3, RegPushImm4 };
 ANN static void emit_dot_static_import_data(const Emitter emit, const Value v, const uint emit_addr) {
-  if(v->d.ptr && GET_FLAG(v, builtin) && GET_FLAG(v, const)) {
+  if(v->d.ptr && vflag(v, vflag_builtin) && GET_FLAG(v, const)) {
     const m_uint size = v->type->size;
     const Instr instr = emit_kind(emit, size, emit_addr, regpushimm);
     instr->m_val = (m_uint)v->d.ptr;
@@ -154,7 +152,7 @@ ANN static void emit_member_func(const Emitter emit, const Exp_Dot* member) {
   if(f->def->base->tmpl)
     emit_add_instr(emit, DotTmplVal);
 else
-  if(is_class(emit->gwion, member->t_base) || GET_FLAG(member->base->info->type, force)) {
+  if(is_class(emit->gwion, member->t_base) || tflag(member->base->info->type, tflag_force)) {
     const Instr func_i = emit_add_instr(emit, f->code ? RegPushImm : SetFunc);
     func_i->m_val = (m_uint)f->code ?: (m_uint)f;
     return;
@@ -162,7 +160,7 @@ else
 //  if(f->def->base->tmpl)
 //    emit_add_instr(emit, DotTmplVal);
   else {
-    if(GET_FLAG(member->t_base, struct)) {
+    if(tflag(member->t_base, tflag_struct)) {
       if(!GET_FLAG(f->def->base, static)) {
         exp_setvar(member->base, 1);
         emit_exp(emit, member->base);
@@ -171,7 +169,7 @@ else
     func_i->m_val = (m_uint)f->code ?: (m_uint)f;
       return;
     }
-    const Instr instr = emit_add_instr(emit, GET_FLAG(f, member) ? DotFunc : DotStaticFunc);
+    const Instr instr = emit_add_instr(emit, vflag(f->value_ref, vflag_member) ? DotFunc : DotStaticFunc);
     instr->m_val = f->vt_index;
   }
   return;
@@ -222,7 +220,7 @@ OP_CHECK(opck_object_dot) {
     else if(GET_FLAG(value, protect))
       exp_setprot(exp_self(member), 1);
   }
-  if(base_static && GET_FLAG(value, member))
+  if(base_static && vflag(value, vflag_member))
     ERR_N(exp_self(member)->pos,
           _("cannot access member '%s.%s' without object instance..."),
           the_base->name, str)
@@ -235,18 +233,18 @@ OP_EMIT(opem_object_dot) {
   const Exp_Dot *member = (Exp_Dot*)data;
   const Type t_base = actual_type(emit->gwion, member->t_base);
   const Value value = find_value(t_base, member->xid);
-  if(!is_class(emit->gwion, member->t_base) && (GET_FLAG(value, member) ||
+  if(!is_class(emit->gwion, member->t_base) && (vflag(value, vflag_member) ||
        (isa(exp_self(member)->info->type, emit->gwion->type[et_function]) > 0 &&
        !is_fptr(emit->gwion, exp_self(member)->info->type)))) {
-    if(!GET_FLAG(t_base, struct))
+    if(!tflag(t_base, tflag_struct))
       CHECK_BO(emit_exp(emit, member->base))
     if(isa(member->t_base, emit->env->gwion->type[et_object]) > 0)
       emit_except(emit, member->t_base);
   }
   if(isa(exp_self(member)->info->type, emit->gwion->type[et_function]) > 0 && !is_fptr(emit->gwion, exp_self(member)->info->type))
          emit_member_func(emit, member);
-  else if(GET_FLAG(value, member)) {
-    if(!GET_FLAG(t_base, struct))
+  else if(vflag(value, vflag_member)) {
+    if(!tflag(t_base, tflag_struct))
       emit_member(emit, value, exp_getvar(exp_self(member)));
     else {
 //      exp_setvar(member->base, exp_getvar(exp_self(member)));
@@ -264,8 +262,12 @@ OP_EMIT(opem_object_dot) {
 }
 
 struct tmpl_info {
-  const  Class_Def cdef;
+//  const  Class_Def cdef;
+  Symbol           name;
+  ID_List          list;
   Type_List        call;
+  Type             ret;
+  Type             base;
   struct Vector_   type;
   struct Vector_   size;
   uint8_t index;
@@ -279,14 +281,15 @@ ANN static inline size_t tmpl_set(struct tmpl_info* info, const Type t) {
 }
 
 ANN static ssize_t template_size(const Env env, struct tmpl_info* info) {
-  ID_List base = info->cdef->base.tmpl->list;
+  ID_List base = info->list; // ???
   Type_List call = info->call;
   size_t size = 0;
   do {
     DECL_OB(const Type, t, = known_type(env, call->td))
     size += tmpl_set(info, t);
   } while((call = call->next) && (base = base->next) && ++size);
-  size += tmpl_set(info, info->cdef->base.type);
+//  } while((call = call->next) && ++size);
+  size += tmpl_set(info, info->base);
   return size + 4;
 }
 
@@ -313,16 +316,15 @@ ANN static void template_name(struct tmpl_info* info, m_str s) {
   *str = '\0';
 }
 
-ANEW ANN static Symbol template_id(const Env env, const Class_Def c, const Type_List call) {
-  struct tmpl_info info = { .cdef=c, .call=call };
-  vector_init(&info.type);
-  vector_init(&info.size);
-  ssize_t sz = template_size(env, &info);
+ANEW ANN static Symbol template_id(const Env env, struct tmpl_info* info) {
+  vector_init(&info->type);
+  vector_init(&info->size);
+  ssize_t sz = template_size(env, info);
   char name[sz];
   if(sz > GW_ERROR)
-    template_name(&info, name);
-  vector_release(&info.type);
-  vector_release(&info.size);
+    template_name(info, name);
+  vector_release(&info->type);
+  vector_release(&info->size);
   return sz > GW_ERROR ? insert_symbol(env->gwion->st, name) : NULL;
 }
 
@@ -331,64 +333,70 @@ ANN static m_bool template_match(ID_List base, Type_List call) {
   return !call ? GW_OK : GW_ERROR;
 }
 
-ANN static Class_Def template_class(const Env env, const Class_Def def, const Type_List call) {
-  DECL_OO(const Symbol, name, = template_id(env, def, call))
+ANN static Type tmpl_exists(const Env env, const Symbol name) {
   if(env->class_def && name == insert_symbol(env->gwion->st, env->class_def->name))
-     return env->class_def->e->def;
-  const Type t = nspc_lookup_type1(env->curr, name);
-  if(t)
-    return t->e->def;
-  const Class_Def c = cpy_class_def(env->gwion->mp, def);
-  c->base.xid = name;
-  SET_FLAG(c, template | ae_flag_ref);
-  UNSET_FLAG(c, scan0 | ae_flag_scan1 | ae_flag_scan2 |
-    ae_flag_check | ae_flag_emit | ae_flag_valid);
-  return c;
-}
-
-ANN static m_bool class2udef(const Env env, const Class_Def a, const Type t) {
-  a->union_def = new_union_def(env->gwion->mp, cpy_decl_list(env->gwion->mp, a->list),
-    loc_cpy(env->gwion->mp, t->e->def->pos));
-  a->union_def->type_xid = a->base.xid;
-  if(GET_FLAG(t, global))
-    SET_FLAG(a->union_def, global);
-  CHECK_BB(scan0_union_def(env, a->union_def))
-  a->base.type = a->union_def->type;
-  a->base.type->e->def = a;
-  a->union_def->tmpl = cpy_tmpl(env->gwion->mp, a->base.tmpl);
-  return GW_OK;
+     return env->class_def;
+  return nspc_lookup_type1(env->curr, name);
+}
+
+ANN static m_bool scantmpl_class_def(const Env env, struct tmpl_info *info) {
+  const Class_Def c = info->base->e->cdef;
+  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,
+    loc_cpy(env->gwion->mp, c->pos));
+  cdef->base.tmpl = mk_tmpl(env, c->base.tmpl, info->call);
+  const m_bool ret = scan0_class_def(env, cdef);
+  if((info->ret = cdef->base.type)) {
+    info->ret->e->cdef = cdef;
+    set_tflag(info->ret, tflag_cdef);
+    set_tflag(info->ret, tflag_ctmpl);
+  } else
+    free_class_def(env->gwion->mp, cdef);
+  return ret;
+}
+
+ANN static m_bool scantmpl_union_def(const Env env, struct tmpl_info *info) {
+  const Union_Def u = info->base->e->udef;
+  const Union_Def udef = new_union_def(env->gwion->mp, cpy_decl_list(env->gwion->mp, u->l),
+    loc_cpy(env->gwion->mp, u->pos));
+  udef->type_xid = info->name;
+  udef->tmpl = mk_tmpl(env, u->tmpl, info->call);
+  if(GET_FLAG(info->base, global))
+    SET_FLAG(udef, global);
+  const m_bool ret = scan0_union_def(env, udef);
+  if(udef->type) {
+    udef->type->e->udef = udef;// mark as udef
+    info->ret = udef->type;
+    set_tflag(info->ret, tflag_udef);
+//    set_tflag(info->ret, tflag_tmpl);
+  } else
+    free_union_def(env->gwion->mp, udef);
+  return ret;
 }
 
-ANN static m_bool _scan_class(const Env env, const Type t, const Class_Def a) {
-  if(t->e->parent !=  env->gwion->type[et_union])
-    CHECK_BB(scan0_class_def(env, a))
+ANN static Type _scan_class(const Env env, struct tmpl_info *info) {
+  if(info->base->e->parent !=  env->gwion->type[et_union])
+    CHECK_BO(scantmpl_class_def(env, info))
   else
-    CHECK_BB(class2udef(env, a, t))
-  SET_FLAG(a->base.type, template);
-  if(GET_FLAG(t, builtin))
-    SET_FLAG(a->base.type, builtin);
-  return GW_OK;
+    CHECK_BO(scantmpl_union_def(env, info))
+  return info->ret;
 }
 
 ANN Type scan_class(const Env env, const Type t, const Type_Decl* td) {
-  if(template_match(t->e->def->base.tmpl->list, td->types) < 0)
-   ERR_O(td->pos, _("invalid template types number"))
-  DECL_OO(const Class_Def, a, = template_class(env, t->e->def, td->types))
-  if(a->base.type)
-    return a->base.type;
+  if(template_match(t->e->cdef->base.tmpl->list, td->types) < 0) // invalid template
+    ERR_O(td->pos, _("invalid template types number"))
+  struct tmpl_info info = { .base=t, .call=td->types, .list=t->e->cdef->base.tmpl->list  };
+  DECL_OO(const Symbol, name, = info.name = template_id(env, &info))
+  const Type exists = tmpl_exists(env, name);
+  if(exists)
+    return exists;
   struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)scan0_cdef,
-    .scope=env->scope->depth, .flag=ae_flag_scan0 };
-//  CHECK_BO(envset_push(&es, t->e->owner_class, env->context ? env->context->nspc : env->curr))
+    .scope=env->scope->depth, .flag=tflag_scan0 };
   CHECK_BO(envset_push(&es, t->e->owner_class, t->e->ctx ? t->e->ctx->nspc : env->curr))
-  a->base.tmpl = mk_tmpl(env, t->e->def->base.tmpl, td->types);
-  const m_bool ret = _scan_class(env, t, a);
+  const Type ret = _scan_class(env, &info);
   if(es.run)
     envset_pop(&es, t->e->owner_class);
-  if(ret > 0)
-    return a->base.type;
-  if(!a->base.type)
-    free_class_def(env->gwion->mp, a);
-  return NULL;
+  return ret;
 }
 
 ANN static inline Symbol dot_symbol(SymTable *st, const Value v) {
@@ -416,7 +424,7 @@ ANN void struct_release(const VM_Shred shred, const Type base, const m_bit *ptr)
     if(isa(t, shred->info->vm->gwion->type[et_compound]) < 0)
       continue;
     const m_uint offset = vector_at(offsets, i);
-    if(!GET_FLAG(t, struct))
+    if(!tflag(t, tflag_struct))
       release(*(M_Object*)(ptr + offset), shred);
     else
       struct_release(shred, t, *(m_bit**)(ptr + offset));
index 2012bf5ba45c6830c69a41a0f108f9c922aeb37f..fa4378ddce6d941d2e30f6d29a5b9c5b5074db05 100644 (file)
@@ -59,7 +59,7 @@ static OP_CHECK(opck_ptr_cast) {
     ERR_N(exp_self(cast)->pos, "'Ptr' needs types to cast")
   DECL_ON(const Type, t, = known_type(env, cast->td))
   const Type _t = get_type(t);
-  if(_t->e->def && !GET_FLAG(_t, check))
+  if(_t->e->cdef && !tflag(_t, tflag_check))
     CHECK_BN(ensure_traverse(env, _t))
   const Type to = known_type(env, cast->td->types->td);
   if(isa(cast->exp->info->type, to) > 0)
@@ -78,8 +78,8 @@ static OP_CHECK(opck_ptr_implicit) {
     e->info->cast_to = imp->t;
     exp_setvar(e, 1);
     const Type t = get_type(imp->t);
-    if(!GET_FLAG(t, check))
-      CHECK_BN(traverse_class_def(env, t->e->def))
+    if(!tflag(t, tflag_check))
+      CHECK_BN(traverse_class_def(env, t->e->cdef))
     return imp->t;
   }
   return NULL;
@@ -139,14 +139,16 @@ static DTOR(ptr_struct_dtor) {
 static OP_CHECK(opck_ptr_scan) {
   struct TemplateScan *ts = (struct TemplateScan*)data;
   DECL_ON(const Type, t, = (Type)scan_class(env, ts->t, ts->td))
-  const Type base = known_type(env, t->e->def->base.tmpl->call->td);
+set_tflag(t, tflag_tmpl);
+//if(!tflag(t, tflag_scan1))exit(3);
+  const Type base = known_type(env, t->e->cdef->base.tmpl->call->td);
   if(isa(base, env->gwion->type[et_compound]) > 0 && !t->nspc->dtor) {
-    t->nspc->dtor = new_vm_code(env->gwion->mp, NULL, SZ_INT, ae_flag_member | ae_flag_builtin, "@PtrDtor");
-    if(!GET_FLAG(t, struct))
+    t->nspc->dtor = new_vm_code(env->gwion->mp, NULL, SZ_INT, 1, "@PtrDtor");
+    if(!tflag(t, tflag_struct))
       t->nspc->dtor->native_func = (m_uint)ptr_object_dtor;
     else
       t->nspc->dtor->native_func = (m_uint)ptr_struct_dtor;
-    SET_FLAG(t, dtor);
+    set_tflag(t, tflag_dtor);
   }
   return t;
 }
@@ -154,7 +156,8 @@ static OP_CHECK(opck_ptr_scan) {
 GWION_IMPORT(ptr) {
   const Type _t_ptr = gwi_class_ini(gwi, "@Ptr", NULL);
   GWI_BB(gwi_class_end(gwi))
-  SET_FLAG(_t_ptr, unary);
+  set_tflag(_t_ptr, tflag_ntmpl);
+//  set_tflag(_t_ptr, tflag_tmpl);
   GWI_BB(gwi_oper_ini(gwi, "@Ptr", NULL, NULL))
   GWI_BB(gwi_oper_add(gwi, opck_ptr_scan))
   GWI_BB(gwi_oper_end(gwi, "@scan", NULL))
@@ -163,7 +166,8 @@ GWION_IMPORT(ptr) {
   GWI_BB(gwi_item_ini(gwi, "@internal", "@val"))
   GWI_BB(gwi_item_end(gwi, 0, NULL))
   GWI_BB(gwi_class_end(gwi))
-  SET_FLAG(t_ptr, unary);
+  set_tflag(t_ptr, tflag_ntmpl);
+//  set_tflag(t_ptr, tflag_tmpl);
   GWI_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, "nonnull Ptr", NULL))
   GWI_BB(gwi_oper_add(gwi, opck_ptr_assign))
   GWI_BB(gwi_oper_end(gwi, ":=>", instr_ptr_assign))
index 9dc20c4ba0abc20ef3c714964d178c13514ff3fe..a9c9ddcb605a39b9038720364d9618466059397c 100644 (file)
@@ -22,7 +22,7 @@ static m_int o_fork_thread, o_fork_cond, o_fork_mutex, o_shred_cancel, o_fork_do
 
 VM_Shred new_shred_base(const VM_Shred shred, const VM_Code code) {
   const VM_Shred sh = new_vm_shred(shred->info->mp, code);
-  ADD_REF(code)
+  vmcode_addref(code);
   sh->base = shred->base;
   return sh;
 }
@@ -197,7 +197,7 @@ static DTOR(fork_dtor) {
   if(!parent->gwion->data->child2.ptr)
     vector_init(&parent->gwion->data->child2);
   vector_add(&parent->gwion->data->child2, (vtype)ME(o)->info->vm->gwion);
-  REM_REF(ME(o)->code, ME(o)->info->vm->gwion);
+  vmcode_remref(ME(o)->code, ME(o)->info->vm->gwion);
   MUTEX_UNLOCK(parent->shreduler->mutex);
 }
 
@@ -373,13 +373,12 @@ GWION_IMPORT(shred) {
   gwi_func_ini(gwi, "float", "get_now");
   GWI_BB(gwi_func_end(gwi, shred_now, ae_flag_none))
   GWI_BB(gwi_class_end(gwi))
-  gwi_set_global_type(gwi, t_shred, et_shred);
+  SET_FLAG(t_shred, abstract | ae_flag_final);
+  gwi->gwion->type[et_shred] = t_shred;
 
   struct SpecialId_ spid = { .type=t_shred, .exec=RegPushMe, .is_const=1 };
   gwi_specialid(gwi, "me", &spid);
 
-  SET_FLAG(t_shred, abstract);
-
   const Type t_fork= gwi_class_ini(gwi,  "Fork", "Shred");
   gwi_class_xtor(gwi, NULL, fork_dtor);
   gwi->gwion->type[et_fork] = t_fork;
@@ -401,13 +400,13 @@ GWION_IMPORT(shred) {
   gwi_func_ini(gwi, "void", "test_cancel");
   GWI_BB(gwi_func_end(gwi, fork_test_cancel, ae_flag_none))
   GWI_BB(gwi_class_end(gwi))
-  SET_FLAG((t_fork), abstract);
+  SET_FLAG(t_fork, abstract | ae_flag_final);
 
   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, NULL)))
   GWI_BB(gwi_class_end(gwi))
-  SET_FLAG((t_typed), abstract);
-
+  SET_FLAG(t_typed, abstract | ae_flag_final);
+  set_tflag(t_typed, tflag_ntmpl);
   return GW_OK;
 }
index 98422c1fbd8e5c6ff68a1f243cce28dbfb7649b6..db68d0ed4a1fe588ab5538033fa600edaf9a18a0 100644 (file)
@@ -261,180 +261,99 @@ static MFUN(string_replaceN) {
 }
 
 static MFUN(string_find) {
-  const m_str str = STRING(o);
-  m_int i = 0, ret = -1;
-  char arg = *(m_int*)MEM(SZ_INT);
-  while(str[i] != '\0') {
-    if(str[i] == arg) {
-      ret = i;
-      break;
-    }
-    i++;
-  }
-  *(m_uint*)RETURN = ret;
+  const m_str base = STRING(o);
+  char c = *(m_int*)MEM(SZ_INT);
+  char *str = strchr(base, c);
+  *(m_uint*)RETURN = str ? str - base : -1;
 }
 
 static MFUN(string_findStart) {
-  const m_str str = STRING(o);
-  const char pos = *(m_int*)MEM(SZ_INT);
-  const char arg = *(m_int*)MEM(SZ_INT * 2);
-  m_int i = pos, ret = -1;
-  if(!strlen(str)) {
-    *(M_Object*)RETURN = NULL;
-    return;
-  }
-  while(str[i] != '\0') {
-    if(str[i] == arg) {
-      ret = i;
-      break;
-    }
-    i++;
-  }
-  *(m_uint*)RETURN = ret;
+  const m_str base = STRING(o);
+  const size_t sz = strlen(base);
+  const char pos = *(m_int*)MEM(SZ_INT *2);
+  if(pos >= 0 && (size_t)pos < sz) {
+    const char arg = *(m_int*)MEM(SZ_INT);
+    char *str = strchr(base + pos, arg);
+    *(m_uint*)RETURN = str ? str - pos - base : -1;
+  } else
+    *(m_uint*)RETURN = -1;
 }
 
 static MFUN(string_findStr) {
-  if(!strlen(STRING(o))) {
-    *(M_Object*)RETURN = NULL;
-    return;
-  }
-  char str[strlen(STRING(o)) + 1];
-  strcpy(str, STRING(o));
-  m_int ret = -1;
+  const m_str base = STRING(o);
+  const size_t sz = strlen(base);
   const M_Object obj = *(M_Object*)MEM(SZ_INT);
-  if(!obj) {
-    *(m_uint*)RETURN = 0;
-    return;
-  }
-  const m_str arg = STRING(obj);
-  const m_int len  = strlen(str);
-  m_int i = 0;
-  const m_int arg_len = strlen(arg);
-  while(i < len) {
-    if(!strncmp(str + i, arg, arg_len)) {
-      ret = i;
-      break;
-    }
-    i++;
-  }
+  if(sz) {
+    const m_str arg = STRING(obj);
+    const m_str str = strstr(base, arg);
+    *(m_uint*)RETURN = str ? str - base : -1;
+  } else
+    *(m_uint*)RETURN = -1;
   release(obj, shred);
-  *(m_uint*)RETURN = ret;
 }
 
 static MFUN(string_findStrStart) {
-  if(!strlen(STRING(o))) {
-    *(M_Object*)RETURN = NULL;
-    return;
-  }
-  char str[strlen(STRING(o)) + 1];
-  strcpy(str, STRING(o));
-  m_int ret = -1;
-  const m_int start = *(m_int*)MEM(SZ_INT);
-  const M_Object obj = *(M_Object*)MEM(SZ_INT * 2);
-  if(!obj) {
-    *(M_Object*)RETURN = NULL;
-    return;
-  }
-  const m_str arg = STRING(obj);
-  const m_int len  = strlen(str);
-  m_int i = start;
-  const m_int arg_len = strlen(arg);
-  while(i < len) {
-    if(!strncmp(str + i, arg, arg_len)) {
-      ret = i;
-      break;
-    }
-    i++;
-  }
+  const m_str base = STRING(o);
+  const size_t sz = strlen(base);
+  const char pos = *(m_int*)MEM(SZ_INT*2);
+  const M_Object obj = *(M_Object*)MEM(SZ_INT);
+  if(pos >= 0 && (size_t)pos < sz) {
+    const m_str arg = STRING(obj);
+    const m_str str = strstr(base + pos, arg);
+    *(m_uint*)RETURN = str ? str - pos- base : -1;
+  } else
+    *(m_uint*)RETURN = -1;
   release(obj, shred);
-  *(m_uint*)RETURN = ret;
 }
 
 static MFUN(string_rfind) {
-  const m_str str = STRING(o);
-  m_int i = strlen(str) - 1, ret = -1;
-  const char arg = *(m_int*)MEM(SZ_INT);
-  while(i > -1 && str[i] != '\0') {
-    if(str[i] == arg) {
-      ret = i;
-      break;
-    }
-    i--;
-  }
-  *(m_uint*)RETURN = ret;
+  const m_str base = STRING(o);
+  char c = *(m_int*)MEM(SZ_INT);
+  char *str = strrchr(base, c);
+  *(m_uint*)RETURN = str ? str - base : -1;
 }
 
 static MFUN(string_rfindStart) {
-  if(!strlen(STRING(o))) {
-    *(M_Object*)RETURN = NULL;
-    return;
-  }
-  char str[strlen(STRING(o)) + 1];
-  strcpy(str, STRING(o));
+  const m_str base = STRING(o);
+  const size_t sz = strlen(base);
   const char pos = *(m_int*)MEM(SZ_INT);
-  const char arg = *(m_int*)MEM(SZ_INT * 2);
-  m_int i = pos, ret = -1;
-  while(i > 0 && str[i] != '\0') {
-    if(str[i] == arg) {
-      ret = i;
-      break;
-    }
-    i--;
-  }
-  *(m_uint*)RETURN = ret;
+  if(pos >= 0 && (size_t)pos < sz) {
+    const char arg = *(m_int*)MEM(SZ_INT * 2);
+    char *str = strrchr(base + pos, arg);
+    *(m_uint*)RETURN = str ? str - pos - base : -1;
+  } else
+    *(m_uint*)RETURN = -1;
 }
 
 static MFUN(string_rfindStr) {
-  if(!strlen(STRING(o))) {
-    *(M_Object*)RETURN = NULL;
-    return;
-  }
-  char str[strlen(STRING(o)) + 1];
-  strcpy(str, STRING(o));
-  m_int ret = -1;
+  const m_str base = STRING(o);
+  const size_t sz = strlen(base);
   const M_Object obj = *(M_Object*)MEM(SZ_INT);
-  const m_str arg = STRING(o);
-  const m_int len  = strlen(str);
-  m_int i = len - 1;
-  const m_int arg_len = strlen(arg);
-  while(i) {
-    if(!strncmp(str + i, arg, arg_len)) {
-      ret = i;
-      break;
-    }
-    i--;
-  }
+  if(sz) {
+    const m_str arg = STRING(obj);
+    m_str tmp = base, str = NULL;
+    while((tmp = strstr(tmp, arg)))
+      str = tmp++;
+    *(m_uint*)RETURN = str ? str - base : -1;
+  } else
+    *(m_uint*)RETURN = -1;
   release(obj, shred);
-  *(m_uint*)RETURN = ret;
 }
 
 static MFUN(string_rfindStrStart) {
-  if(!strlen(STRING(o))) {
-    *(M_Object*)RETURN = NULL;
-    return;
-  }
-  char str[strlen(STRING(o)) + 1];
-  strcpy(str, STRING(o));
-  m_int ret = -1;
-  m_int start = *(m_int*)MEM(SZ_INT);
+  const m_str base = STRING(o);
+  const size_t sz = strlen(base);
+  const char pos = *(m_int*)MEM(SZ_INT *2);
   const M_Object obj = *(M_Object*)MEM(SZ_INT * 2);
-  if(!obj) {
-    *(m_uint*)RETURN = 0;
-    return;
-  }
-  m_str arg = STRING(obj);
-
-  m_int i = start;
-  const m_int arg_len = strlen(arg);
-  while(i > -1) {
-    if(!strncmp(str + i, arg, arg_len)) {
-      ret = i;
-      break;
-    }
-    i--;
-  }
+  if(sz) {
+    const m_str arg = STRING(obj);
+    m_str tmp = base + pos, str = NULL;
+    while((tmp = strstr(tmp, arg)))
+      str = tmp++;
+    *(m_uint*)RETURN = str ? str - pos - base : -1;
+  } else
+    *(m_uint*)RETURN = -1;
   release(obj, shred);
-  *(m_uint*)RETURN = ret;
 }
 
 static MFUN(string_erase) {
@@ -458,9 +377,9 @@ static MFUN(string_erase) {
 
 GWION_IMPORT(string) {
   const Type t_string = gwi_class_ini(gwi, "string", NULL);
+  gwi->gwion->type[et_string] = t_string; // use func
   gwi_class_xtor(gwi, string_ctor, NULL);
   GWI_BB(gwi_gack(gwi, t_string, gack_string))
-  gwi->gwion->type[et_string] = t_string; // use func
 
   gwi_item_ini(gwi, "@internal", "@data");
   GWI_BB(gwi_item_end(gwi,   ae_flag_const, NULL))
@@ -483,11 +402,11 @@ GWION_IMPORT(string) {
   gwi_func_ini(gwi, "string", "trim");
   GWI_BB(gwi_func_end(gwi, string_trim, ae_flag_none))
 
-  gwi_func_ini(gwi, "int", "charAt");
+  gwi_func_ini(gwi, "char", "charAt");
   gwi_func_arg(gwi, "int", "pos");
   GWI_BB(gwi_func_end(gwi, string_charAt, ae_flag_none))
 
-  gwi_func_ini(gwi, "int", "charAt");
+  gwi_func_ini(gwi, "char", "charAt");
   gwi_func_arg(gwi, "int", "pos");
   gwi_func_arg(gwi, "char", "c");
   GWI_BB(gwi_func_end(gwi, string_setCharAt, ae_flag_none))
@@ -513,17 +432,17 @@ GWION_IMPORT(string) {
   GWI_BB(gwi_func_end(gwi, string_find, ae_flag_none))
 
   gwi_func_ini(gwi, "int", "find");
-  gwi_func_arg(gwi, "int", "pos");
   gwi_func_arg(gwi, "char", "c");
+  gwi_func_arg(gwi, "int", "pos");
   GWI_BB(gwi_func_end(gwi, string_findStart, ae_flag_none))
 
   gwi_func_ini(gwi, "int", "find");
-  gwi_func_arg(gwi, "string", "str");
+  gwi_func_arg(gwi, "nonnull string", "str");
   GWI_BB(gwi_func_end(gwi, string_findStr, ae_flag_none))
 
   gwi_func_ini(gwi, "int", "find");
+  gwi_func_arg(gwi, "nonnull string", "str");
   gwi_func_arg(gwi, "int", "pos");
-  gwi_func_arg(gwi, "string", "str");
   GWI_BB(gwi_func_end(gwi, string_findStrStart, ae_flag_none))
 
   gwi_func_ini(gwi, "int", "rfind");
@@ -531,17 +450,17 @@ GWION_IMPORT(string) {
   GWI_BB(gwi_func_end(gwi, string_rfind, ae_flag_none))
 
   gwi_func_ini(gwi, "int", "rfind");
-  gwi_func_arg(gwi, "int", "pos");
   gwi_func_arg(gwi, "char", "c");
+  gwi_func_arg(gwi, "int", "pos");
   GWI_BB(gwi_func_end(gwi, string_rfindStart, ae_flag_none))
 
   gwi_func_ini(gwi, "int", "rfind");
-  gwi_func_arg(gwi, "string", "str");
+  gwi_func_arg(gwi, "nonnull string", "str");
   GWI_BB(gwi_func_end(gwi, string_rfindStr, ae_flag_none))
 
   gwi_func_ini(gwi, "int", "rfind");
+  gwi_func_arg(gwi, "nonnull string", "str");
   gwi_func_arg(gwi, "int", "pos");
-  gwi_func_arg(gwi, "string", "str");
   GWI_BB(gwi_func_end(gwi, string_rfindStrStart, ae_flag_none))
 
   gwi_func_ini(gwi, "void", "erase");
index ff9231a1c84d788da4e2d178fd4da1df41b0bb6c..a948cc8ebd6e4491a632e531f20cd04679b9ea79 100644 (file)
@@ -321,7 +321,7 @@ GWION_IMPORT(ugen) {
   gwi->gwion->type[et_ugen] = t_ugen; // use func
 
   GWI_BB(gwi_item_ini(gwi, "@internal", "@ugen"))
-  GWI_BB(gwi_item_end(gwi, ae_flag_member, NULL))
+  GWI_BB(gwi_item_end(gwi, ae_flag_none, NULL))
 
   GWI_BB(gwi_func_ini(gwi, "UGen", "chan"))
   GWI_BB(gwi_func_arg(gwi, "int", "arg0"))
index 2b748cd2cf2ce1554ba280af4017bdae65b3a8fb..41177b4832ea6bc157e3a6db5e99e43fce97a2b5 100644 (file)
@@ -31,7 +31,7 @@ static DTOR(vararg_dtor) {
       const Type t = (Type)vector_at(&arg->t, i);
       if(isa(t, shred->info->vm->gwion->type[et_object]) > 0)
         release(*(M_Object*)(arg->d + offset), shred);
-      else if(GET_FLAG(t, struct))
+      else if(tflag(t, tflag_struct))
         struct_release(shred, t, *(m_bit**)(arg->d + offset));
       offset += t->size;
     }
@@ -137,7 +137,7 @@ static FREEARG(freearg_vararg) {
 }
 
 static ID_CHECK(idck_vararg) {
-  if(env->func && GET_FLAG(env->func->def->base, variadic))
+  if(env->func && fbflag(env->func->def->base, fbflag_variadic))
     return nonnul_type(env, exp_self(prim)->info->type);
   ERR_O(exp_self(prim)->pos, _("'vararg' must be used inside variadic function"))
 }
@@ -163,17 +163,17 @@ GWION_IMPORT(vararg) {
   const Type t_vararg  = gwi_class_ini(gwi, "Vararg", "Object");
   gwi_class_xtor(gwi, NULL, vararg_dtor);
   gwi_gack(gwi, t_vararg, gack_vararg);
-  CHECK_BB(gwi_item_ini(gwi, "@internal", "@data"))
-  CHECK_BB(gwi_item_end(gwi, ae_flag_none, NULL))
-  CHECK_BB(gwi_item_ini(gwi, "int", "@inLoop"))
-  CHECK_BB(gwi_item_end(gwi, ae_flag_none, NULL))
-  CHECK_BB(gwi_item_ini(gwi, "int", "@len"))
-  CHECK_BB(gwi_item_end(gwi, ae_flag_none, NULL))
-  CHECK_BB(gwi_func_ini(gwi, "Vararg", "cpy"))
-  CHECK_BB(gwi_func_end(gwi, mfun_vararg_cpy, ae_flag_none))
+  GWI_BB(gwi_item_ini(gwi, "@internal", "@data"))
+  GWI_BB(gwi_item_end(gwi, ae_flag_none, NULL))
+  GWI_BB(gwi_item_ini(gwi, "int", "@inLoop"))
+  GWI_BB(gwi_item_end(gwi, ae_flag_none, NULL))
+  GWI_BB(gwi_item_ini(gwi, "int", "@len"))
+  GWI_BB(gwi_item_end(gwi, ae_flag_none, NULL))
+  GWI_BB(gwi_func_ini(gwi, "Vararg", "cpy"))
+  GWI_BB(gwi_func_end(gwi, mfun_vararg_cpy, ae_flag_none))
   GWI_BB(gwi_class_end(gwi))
-  SET_FLAG(t_vararg, abstract);
-  CHECK_BB(gwi_set_global_type(gwi, t_vararg, et_vararg))
+  SET_FLAG(t_vararg, abstract | ae_flag_final);
+  gwi->gwion->type[et_vararg] = t_vararg;
   GWI_BB(gwi_oper_ini(gwi, "nonnull Vararg", (m_str)OP_ANY_TYPE, NULL))
   GWI_BB(gwi_oper_add(gwi, opck_vararg_cast))
   GWI_BB(gwi_oper_emi(gwi, opem_vararg_cast))
index 3620034191097919733bf3e7077d3fa0c388ac7a..4d0650fad99cff64d496509e9826bc6f5f045665 100644 (file)
@@ -56,20 +56,20 @@ ANN static inline m_bool check_exp_decl_parent(const Env env, const Var_Decl var
   return GW_OK;
 }
 
-#define describe_check_decl(a, b)                                 \
+#define describe_check_decl(a, b, flag)                           \
 ANN static inline void decl_##a(const Env env, const Value v) {   \
-  const Nspc nspc = env->curr;\
-  SET_FLAG(v, a);                                                 \
+  const Nspc nspc = env->curr;                                    \
+  flag;                                                           \
   v->from->offset = nspc->info->b;                                \
   nspc->info->b += v->type->size;                                 \
 }
-describe_check_decl(member, offset)
-describe_check_decl(static, class_data_size)
+describe_check_decl(member, offset, v->vflag |= vflag_member)
+describe_check_decl(static, class_data_size, SET_FLAG(v, static))
 
 ANN static m_bool check_fptr_decl(const Env env, const Var_Decl var) {
   const Value v    = var->value;
   Type t = v->type;
-  while(GET_FLAG(t, typedef))
+  while(tflag(t, tflag_typedef))
     t = t->e->parent;
   if(!t->e->d.func)
     return GW_ERROR;
@@ -79,7 +79,7 @@ ANN static m_bool check_fptr_decl(const Env env, const Var_Decl var) {
   const Type type = func->value_ref->from->owner_class;
   if(type && isa(type, env->class_def) < 0 && !GET_FLAG(func, global))
     ERR_B(var->pos, _("can't use non global fptr of other class."))
-  if(GET_FLAG(func, member) && GET_FLAG(v, static))
+  if(vflag(func->value_ref, vflag_member) && GET_FLAG(v, static))
       ERR_B(var->pos, _("can't use static variables for member function."))
   return GW_OK;
 }
@@ -91,9 +91,6 @@ ANN static inline m_bool check_td_exp(const Env env, Type_Decl *td) {
 ANN Type check_td(const Env env, Type_Decl *td) {
   CHECK_BO(check_td_exp(env, td))
   const Type t = actual_type(env->gwion, td->exp->info->type);
-  assert(t);
-  if(GET_FLAG(t, template) && !GET_FLAG(t, ref))
-    ERR_O(td_pos(td), _("type '%s' needs template types"), t->name)
   td->xid = insert_symbol("auto");
   return t;
 }
@@ -115,7 +112,7 @@ ANN static m_bool check_var(const Env env, const Var_Decl var) {
 ANN static m_bool check_var_td(const Env env, const Var_Decl var, Type_Decl *const td) {
   const Value v = var->value;
   if(env->class_def)  {
-    if(GET_FLAG(td, member)) {
+    if(vflag(v, vflag_member)) {
       decl_member(env, v);
       if(env->class_def->e->tuple)
         tuple_info(env, v);
@@ -133,7 +130,8 @@ ANN static m_bool check_decl(const Env env, const Exp_Decl *decl) {
     CHECK_BB(check_var_td(env, var, decl->td))
     if(is_fptr(env->gwion, decl->type))
       CHECK_BB(check_fptr_decl(env, var))
-    SET_FLAG(var->value, valid | ae_flag_used);
+    set_vflag(var->value, vflag_valid);
+    //set_vflag(var->value, vflag_used));
     nspc_add_value(env->curr, var->xid, var->value);
   } while((list = list->next));
   return GW_OK;
@@ -141,18 +139,18 @@ ANN static m_bool check_decl(const Env env, const Exp_Decl *decl) {
 
 ANN static inline m_bool ensure_check(const Env env, const Type t) {
   struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)check_cdef,
-    .scope=env->scope->depth, .flag=ae_flag_check };
+    .scope=env->scope->depth, .flag=tflag_check };
   return envset_run(&es, t);
 }
 
 ANN m_bool ensure_traverse(const Env env, const Type t) {
   struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)traverse_cdef,
-    .scope=env->scope->depth, .flag=ae_flag_check };
+    .scope=env->scope->depth, .flag=tflag_check };
   return envset_run(&es, t);
 }
 
 ANN static inline m_bool inferable(const Env env, const Type t, const loc_t pos) {
-  if(!GET_FLAG(t, infer))
+  if(!tflag(t, tflag_infer))
     return GW_OK;
   ERR_B(pos, _("can't infer type."))
 }
@@ -170,7 +168,7 @@ ANN Type check_exp_decl(const Env env, const Exp_Decl* decl) {
   {
     const Type t = get_type(decl->type);
     CHECK_BO(inferable(env, t, td_pos(decl->td)))
-    if(!GET_FLAG(t, check) && t->e->def)
+    if(!tflag(t, tflag_check))
       CHECK_BO(ensure_check(env, t))
   }
   const m_bool global = GET_FLAG(decl->td, global);
@@ -252,13 +250,13 @@ ANN static Value check_non_res_value(const Env env, const Symbol *data) {
       CHECK_BO(not_from_owner_class(env, env->class_def, value, prim_pos(data)))
     const Value v = value ?: find_value(env->class_def, var);
     if(v) {
-      if(env->func && GET_FLAG(env->func->def->base, static) && GET_FLAG(v, member))
+      if(env->func && GET_FLAG(env->func->def->base, static) && vflag(v, vflag_member))
         ERR_O(prim_pos(data),
               _("non-static member '%s' used from static function."), s_name(var))
     }
     return v;
   } else if(SAFE_FLAG(env->class_def, global) || (env->func && GET_FLAG(env->func->def->base, global))) {
-    if(!SAFE_FLAG(value, abstract))
+    if(!value || !GET_FLAG(value, global))
       ERR_O(prim_pos(data),
             _("non-global variable '%s' used from global function/class."), s_name(var))
   }
@@ -282,7 +280,7 @@ ANN static m_bool lambda_valid(const Env env, const Exp_Primary* exp) {
   const Symbol sym = insert_symbol(val->name);
   const Vector vec = (Vector)&env->curr->info->value->ptr;
   const m_uint scope = map_get(&env->curr->info->func->map, (m_uint)env->func->def->base);
-  if(GET_FLAG(val, abstract))
+  if(GET_FLAG(val, global))
     return GW_OK;
   if(val->from->owner_class && isa(val->from->owner_class, env->class_def) > 0)
     return GW_OK;
@@ -298,7 +296,7 @@ ANN static m_bool lambda_valid(const Env env, const Exp_Primary* exp) {
 ANN static Type prim_id_non_res(const Env env, const Symbol *data) {
   const Symbol sym = *data;
   const Value v = check_non_res_value(env, data);
-  if(!v || !GET_FLAG(v, valid) || (v->from->ctx && v->from->ctx->error)) {
+  if(!v || !vflag(v, vflag_valid) || (v->from->ctx && v->from->ctx->error)) {
     env_err(env, prim_pos(data),
           _("variable %s not legit at this point."), s_name(sym));
     if(v)
@@ -307,12 +305,12 @@ ANN static Type prim_id_non_res(const Env env, const Symbol *data) {
   }
   prim_self(data)->value = v;
   if(env->func) {
-    if(GET_FLAG(env->func->def->base, abstract))
+    if(isa(env->func->value_ref->type, env->gwion->type[et_lambda]) > 0)
       CHECK_BO(lambda_valid(env, prim_self(data)))
-  if(env->func && !GET_FLAG(v, const) && v->from->owner)
-    UNSET_FLAG(env->func, pure);
+    if(env->func && !GET_FLAG(v, const) && v->from->owner)
+      unset_fflag(env->func, fflag_pure);
   }
-  SET_FLAG(v, used);
+  //v->vflag |= used;
   if(GET_FLAG(v, const))
     exp_setmeta(prim_exp(data), 1);
   if(v->from->owner_class) {
@@ -353,7 +351,7 @@ ANN static Type check_prim_interp(const Env env, const Exp* exp) {
 
 ANN static Type check_prim_hack(const Env env, const Exp *data) {
   if(env->func)
-    UNSET_FLAG(env->func, pure);
+      unset_fflag(env->func, fflag_pure);
   CHECK_OO(check_prim_interp(env, data))
   return env->gwion->type[et_gack];
 }
@@ -442,7 +440,7 @@ ANN2(1,2) static Func find_func_match_actual(const Env env, Func func, const Exp
     Arg_List e1 = func->def->base->args;
     while(e) {
       if(!e1) {
-        if(GET_FLAG(func->def->base, variadic))
+        if(fbflag(func->def->base, fbflag_variadic))
           return func;
         CHECK_OO(func->next);
         return find_func_match_actual(env, func->next, args, implicit, specific);
@@ -482,7 +480,7 @@ ANN2(1, 2) Func find_func_match(const Env env, const Func up, const Exp exp) {
 ANN m_bool check_traverse_fdef(const Env env, const Func_Def fdef) {
   struct Vector_ v = {};
   const m_uint scope = env->scope->depth;
-  env->scope->depth = 1;
+  env->scope->depth = 0;
   vector_init(&v);
   while(vector_size((Vector)&env->curr->info->value->ptr) > 1)
     vector_add(&v, vector_pop((Vector)&env->curr->info->value->ptr));
@@ -502,9 +500,9 @@ ANN static m_bool check_func_args(const Env env, Arg_List arg_list) {
       CHECK_OB((arg_list->type = v->type = check_td(env, arg_list->td)))
 // TODO: use coumpound instead of object?
     if(isa(v->type, env->gwion->type[et_object]) > 0 || isa(v->type, env->gwion->type[et_function]) > 0)
-      UNSET_FLAG(env->func, pure);
+      unset_fflag(env->func, fflag_pure);
     CHECK_BB(already_defined(env, decl->xid, decl->pos))
-    SET_FLAG(v, valid);
+    set_vflag(v, vflag_valid);
     nspc_add_value(env->curr, decl->xid, v);
   } while((arg_list = arg_list->next));
   return GW_OK;
@@ -586,9 +584,9 @@ ANN static Type check_predefined(const Env env, Exp_Call *exp, const Value v, co
   DECL_OO(const Func, func, = v->d.func_ref ?: predefined_func(env, v, exp, tm))
   if(!fdef->base->ret_type) { // template fptr
     struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)check_cdef,
-      .scope=env->scope->depth, .flag=ae_flag_check };
+      .scope=env->scope->depth, .flag=tflag_check };
     CHECK_BO(envset_push(&es, v->from->owner_class, v->from->owner))
-    SET_FLAG(func->def->base, typedef);
+    func->def->base->fbflag |= fbflag_internal;
     const m_bool ret = check_traverse_fdef(env, func->def);
     if(es.run)
       envset_pop(&es, v->from->owner_class);
@@ -654,7 +652,7 @@ ANN static Type check_lambda_call(const Env env, const Exp_Call *exp) {
     ERR_O(exp_self(exp)->pos, _("argument number does not match for lambda"))
   CHECK_BO(check_traverse_fdef(env, l->def))
   if(env->class_def)
-    SET_FLAG(l->def->base, member);
+    set_vflag(l->def->base->func->value_ref, vflag_member);
   ((Exp_Call*)exp)->m_func = l->def->base->func;
   return l->def->base->ret_type ?: (l->def->base->ret_type = env->gwion->type[et_void]);
 }
@@ -673,14 +671,14 @@ ANN Type check_exp_call1(const Env env, const Exp_Call *exp) {
   }
   if(exp->func->info->type == env->gwion->type[et_lambda])
     return check_lambda_call(env, exp);
-  if(GET_FLAG(exp->func->info->type->e->d.func, ref)) {
+  if(fflag(exp->func->info->type->e->d.func, fflag_ftmpl)) {
     const Value value = exp->func->info->type->e->d.func->value_ref;
-    if(value->from->owner_class && !GET_FLAG(value->from->owner_class, check))
+    if(value->from->owner_class && !tflag(value->from->owner_class, tflag_check))
       CHECK_BO(ensure_traverse(env, value->from->owner_class))
   }
   if(exp->args)
     CHECK_OO(check_exp(env, exp->args))
-  if(GET_FLAG(exp->func->info->type, func))
+  if(tflag(exp->func->info->type, tflag_ftmpl))
     return check_exp_call_template(env, (Exp_Call*)exp);
   const Func func = find_func_match(env, exp->func->info->type->e->d.func, exp->args);
   if((exp_self(exp)->d.exp_call.m_func = func)) {
@@ -730,7 +728,7 @@ ANN static m_bool predefined_call(const Env env, const Type t, const loc_t pos)
   env_err(env, pos, _("Type '%s' has '%s' as pre-defined types."),
       t->name, str);
   free_mstr(env->gwion->mp, str);
-  if(GET_FLAG(t, typedef)) {
+  if(tflag(t, tflag_typedef)) {
     loc_header(t->e->d.func->def->pos, env->name);
     gw_err(_("from definition:\n"));
     loc_err(t->e->d.func->def->pos, env->name);
@@ -769,7 +767,7 @@ ANN static Type check_exp_unary(const Env env, const Exp_Unary* unary) {
     return NULL;
   DECL_OO(const Type, ret, = op_check(env, &opi))
   const Type t = get_type(actual_type(env->gwion, ret));
-  if(t->e->def && !GET_FLAG(t, check))
+  if(!tflag(t, tflag_check))
     CHECK_BO(ensure_traverse(env, t))
   return ret;
 }
@@ -806,7 +804,7 @@ ANN static Type check_exp_dot(const Env env, Exp_Dot* member) {
 }
 
 ANN m_bool check_type_def(const Env env, const Type_Def tdef) {
-  return tdef->type->e->def ? check_class_def(env, tdef->type->e->def) : GW_OK;
+  return tdef->type->e->cdef ? check_class_def(env, tdef->type->e->cdef) : GW_OK;
 }
 ANN static Type check_exp_lambda(const Env env,
     const Exp_If* exp_if NUSED) { return env->gwion->type[et_lambda]; }
@@ -818,8 +816,8 @@ ANN Type check_exp(const Env env, const Exp exp) {
   do {
     CHECK_OO((curr->info->type = check_exp_func[curr->exp_type](env, &curr->d)))
     if(env->func && isa(curr->info->type, env->gwion->type[et_lambda]) < 0 && isa(curr->info->type, env->gwion->type[et_function]) > 0 &&
-        !GET_FLAG(curr->info->type->e->d.func, pure))
-      UNSET_FLAG(env->func, pure);
+        !fflag(curr->info->type->e->d.func, fflag_pure))
+      unset_fflag(env->func, fflag_pure);
   } while((curr = curr->next));
   return exp->info->type;
 }
@@ -874,7 +872,7 @@ ANN static inline m_bool for_empty(const Env env, const Stmt_For stmt) {
 
 ANN static m_bool do_stmt_each(const Env env, const Stmt_Each stmt) {
   DECL_OB(Type, t, = check_exp(env, stmt->exp))
-  while(GET_FLAG(t, typedef))
+  while(tflag(t, tflag_typedef))
     t = t->e->parent;
   Type ptr = array_base(t);
   const m_uint depth = t->array_depth - 1;
@@ -888,12 +886,12 @@ ANN static m_bool do_stmt_each(const Env env, const Stmt_Each stmt) {
     sprintf(c, "nonnull Ptr:[%s]", ptr->name);
     ptr = str2type(env->gwion, c, stmt->exp->pos);
     const Type base = get_type(ptr);
-    if(!GET_FLAG(base, check))
+    if(!tflag(base, tflag_check))
       CHECK_BB(ensure_traverse(env, base))
   }
   t = (!stmt->is_ptr && depth) ? array_type(env, ptr, depth) : ptr;
   stmt->v = new_value(env->gwion->mp, t, s_name(stmt->sym));
-  SET_FLAG(stmt->v, valid);
+  set_vflag(stmt->v, vflag_valid);
   nspc_add_value(env->curr, stmt->sym, stmt->v);
   return check_conts(env, stmt_self(stmt), stmt->body);
 }
@@ -980,7 +978,7 @@ ANN m_bool check_union_decl(const Env env, const Union_Def udef) {
   do {
     CHECK_OB(check_exp(env, l->self))
     Var_Decl_List list = l->self->d.exp_decl.list;
-    do SET_FLAG(list->self->value, pure);
+    do set_vflag(list->self->value, vflag_union);
     while((list = list->next));
     if(l->self->info->type->size > udef->s)
       udef->s = l->self->info->type->size;
@@ -1012,8 +1010,7 @@ ANN m_bool check_union_def(const Env env, const Union_Def udef) {
   if(!udef->xid && !udef->type_xid && env->class_def && !GET_FLAG(udef, static))
     env->class_def->nspc->info->offset = udef->o + udef->s;
   union_pop(env, udef, scope);
-  union_flag(udef, ae_flag_check);
-  union_flag(udef, ae_flag_valid);
+  union_flag(udef, tflag_check);
   return ret;
 }
 
@@ -1025,7 +1022,7 @@ ANN static Value match_value(const Env env, const Exp_Primary* prim, const m_uin
   const Symbol sym = prim->d.var;
   const Value v = new_value(env->gwion->mp,
      ((Exp)VKEY(&env->scope->match->map, i))->info->type, s_name(sym));
-  SET_FLAG(v, valid);
+  set_vflag(v, vflag_valid);
   nspc_add_value(env->curr, sym, v);
   VVAL(&env->scope->match->map, i) = (vtype)v;
   return v;
@@ -1128,6 +1125,8 @@ ANN static m_bool check_stmt_list(const Env env, Stmt_List l) {
 }
 
 ANN static m_bool check_signature_match(const Env env, const Func_Def fdef, const Func parent) {
+  if(GET_FLAG(parent->def->base, final))
+    ERR_B(td_pos(fdef->base->td), _("can't override final function '%s'\n"), parent->name)
   if(GET_FLAG(parent->def->base, static) != GET_FLAG(fdef->base, static)) {
     const m_str c_name  = fdef->base->func->value_ref->from->owner_class->name;
     const m_str p_name = parent->value_ref->from->owner_class->name;
@@ -1212,11 +1211,8 @@ ANN static m_bool check_func_def_override(const Env env, const Func_Def fdef) {
 ANN m_bool check_fdef(const Env env, const Func_Def fdef) {
   if(fdef->base->args)
     CHECK_BB(check_func_args(env, fdef->base->args))
-  if(!GET_FLAG(fdef->base, builtin)) {
-    if(fdef->d.code)
-      CHECK_BB(check_stmt_code(env, &fdef->d.code->d.stmt_code))
-  } else
-    fdef->base->func->code->stack_depth = fdef->stack_depth;
+  if(fdef->d.code)
+    CHECK_BB(check_stmt_code(env, &fdef->d.code->d.stmt_code))
   return GW_OK;
 }
 
@@ -1239,18 +1235,18 @@ ANN m_bool check_func_def(const Env env, const Func_Def f) {
   ++env->scope->depth;
   nspc_push_value(env->gwion->mp, env->curr);
   struct Op_Import opi = { };
-  if(GET_FLAG(fdef->base, op)) {
+  if(fbflag(fdef->base, fbflag_op)) {
     func_operator(f, &opi);
     operator_suspend(env->curr, &opi);
   }
   const m_bool ret = scanx_fdef(env, env, fdef, (_exp_func)check_fdef);
-  if(GET_FLAG(fdef->base, op))
+  if(fbflag(fdef->base, fbflag_op))
     operator_resume(&opi);
   nspc_pop_value(env->gwion->mp, env->curr);
   --env->scope->depth;
   env->func = former;
   if(ret > 0)
-    SET_FLAG(fdef->base, valid);
+    set_fflag(fdef->base->func, fflag_valid);
   if(GET_FLAG(fdef->base, global))
     env_pop(env,scope);
   return ret;
@@ -1264,10 +1260,11 @@ ANN static m_bool check_parent(const Env env, const Class_Def cdef) {
   const Type_Decl *td = cdef->base.ext;
   if(td->array)
     CHECK_BB(check_subscripts(env, td->array, 1))
-  if(parent->e->def && !GET_FLAG(parent, check))
+  if(!tflag(parent, tflag_check))
     CHECK_BB(ensure_check(env, parent))
-  if(GET_FLAG(parent, typedef))
-    SET_FLAG(cdef->base.type, typedef);
+  if(tflag(parent, tflag_typedef)) {
+    set_tflag(cdef->base.type, tflag_typedef);
+  }
   return GW_OK;
 }
 
@@ -1280,23 +1277,36 @@ ANN static m_bool cdef_parent(const Env env, const Class_Def cdef) {
   return ret;
 }
 
+ANN m_bool check_abstract(const Env env, const Class_Def cdef) {
+  if(!cdef->base.type->nspc->info->vtable.ptr)
+    return GW_OK;
+  for(m_uint i = 0; i < vector_size(&cdef->base.type->nspc->info->vtable); ++i) {
+    Func f = (Func)vector_at(&cdef->base.type->nspc->info->vtable, i);
+    if(GET_FLAG(f->def->base, abstract))
+      ERR_B(cdef->pos, _("'%s' must be declared 'abstract'"), s_name(cdef->base.xid))
+  }
+  return GW_OK;
+}
+
 ANN m_bool check_class_def(const Env env, const Class_Def cdef) {
   if(tmpl_base(cdef->base.tmpl))
     return GW_OK;
   const Type t = cdef->base.type;
-  if(t->e->owner_class && !GET_FLAG(t->e->owner_class, check))
+  if(t->e->owner_class && !tflag(t->e->owner_class, tflag_check))
     CHECK_BB(ensure_check(env, t->e->owner_class))
-  if(GET_FLAG(t, check))return GW_OK;
-  SET_FLAG(t, check);
+  if(tflag(t, tflag_check))
+    return GW_OK;
+  set_tflag(t, tflag_check);
   if(cdef->base.ext)
     CHECK_BB(cdef_parent(env, cdef))
-  if(!GET_FLAG(cdef, struct))
+  if(!tflag(t, tflag_struct))
     inherit(t);
   if(cdef->body) {
     CHECK_BB(env_body(env, cdef, check_section))
-    SET_FLAG(t, ctor);
+    set_tflag(t, tflag_ctor);
   }
-  SET_FLAG(t, valid);
+  if(!GET_FLAG(cdef, abstract))
+    CHECK_BB(check_abstract(env, cdef))
   return GW_OK;
 }
 
index 75af75108c950ca373ecdc8161eaa191ed387574..2d794a8dc4e37efe6f0e9bb5a2863a708caa2a31 100644 (file)
@@ -10,7 +10,7 @@
 ANN void func_operator(const Func_Def fdef, struct Op_Import *opi) {
   opi->op =fdef->base->xid;
   const m_str str = s_name(fdef->base->xid);
-  const uint is_unary = GET_FLAG(fdef->base, unary) +
+  const uint is_unary = fbflag(fdef->base, fbflag_unary) +
     (!strcmp(str, "@conditionnal") || !strcmp(str, "@unconditionnal"));
   const Arg_List args = fdef->base->args;
   opi->lhs = is_unary ? NULL :
index bb5a606320e9e9318df98fc7b9d20325e7919ce3..e62b98f78f9169e84f2266f1e2ac1ff17c3906cb 100644 (file)
@@ -40,7 +40,7 @@ ANN static m_bool check_call(const Env env, const Exp_Call* exp) {
 }
 
 ANN static Func ensure_tmpl(const Env env, const Func_Def fdef, const Exp_Call *exp) {
-  const m_bool ret = GET_FLAG(fdef->base, valid) || check_traverse_fdef(env, fdef) > 0;
+  const m_bool ret = (fdef->base->func && fflag(fdef->base->func, fflag_valid)) || check_traverse_fdef(env, fdef) > 0;
   if(ret) {
     const Func f = fdef->base->func;
     const Func next = f->next;
@@ -48,7 +48,8 @@ ANN static Func ensure_tmpl(const Env env, const Func_Def fdef, const Exp_Call *
     const Func func = find_func_match(env, f, exp->args);
     f->next = next;
     if(func) {
-      SET_FLAG(func, valid | ae_flag_template);
+      set_fflag(func, fflag_tmpl);
+      set_fflag(func, fflag_valid);
       return func;
     }
   }
@@ -65,7 +66,7 @@ ANN static Func fptr_match(const Env env, struct ResolverArgs* f_ptr_args) {
   if(exists)
     return exists->e->d.func;
 
-  Func m_func = f_ptr_args->m_func; 
+  Func m_func = f_ptr_args->m_func;
   Func_Def base = v->d.func_ref ? v->d.func_ref->def : exp->func->info->type->e->d.func->def;
   Func_Base *fbase = cpy_func_base(env->gwion->mp, base->base);
   fbase->xid = sym;
@@ -82,7 +83,7 @@ ANN static Func fptr_match(const Env env, struct ResolverArgs* f_ptr_args) {
         nspc_add_type_front(v->from->owner, sym, actual_type(env->gwion, m_func->value_ref->type));
     }
     if(fptr->type)
-      REM_REF(fptr->type, env->gwion)
+      type_remref(fptr->type, env->gwion);
     free_fptr_def(env->gwion->mp, fptr);
   }
   return m_func;
@@ -92,7 +93,7 @@ ANN static Func func_match(const Env env, struct ResolverArgs* f_ptr_args) {
   const Value v = f_ptr_args->v;
   const m_str tmpl_name = f_ptr_args->tmpl_name;
   const Exp_Call *exp = f_ptr_args->e;
-  Func m_func = f_ptr_args->m_func; 
+  Func m_func = f_ptr_args->m_func;
   Type_List types = f_ptr_args->types;
   for(m_uint i = 0; i < v->from->offset + 1; ++i) {
     const Value exists = template_get_ready(env, v, tmpl_name, i);
@@ -110,12 +111,9 @@ ANN static Func func_match(const Env env, struct ResolverArgs* f_ptr_args) {
       const Value value = template_get_ready(env, v, "template", i);
       if(!value)
         continue;
-      if(GET_FLAG(v, builtin)) {
-        SET_FLAG(value, builtin);
-        SET_FLAG(value->d.func_ref, builtin);
-      }
+      if(vflag(v, vflag_builtin))
+        set_vflag(value, vflag_builtin);
       const Func_Def fdef = (Func_Def)cpy_func_def(env->gwion->mp, value->d.func_ref->def);
-      SET_FLAG(fdef->base, template);
       fdef->base->tmpl->call = cpy_type_list(env->gwion->mp, types);
       fdef->base->tmpl->base = i;
       if((m_func = ensure_tmpl(env, fdef, exp))) {
@@ -136,7 +134,7 @@ ANN static Func _find_template_match(const Env env, const Value v, const Exp_Cal
   DECL_OO(const m_str, tmpl_name, = tl2str(env, types))
   const m_uint scope = env->scope->depth;
   struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)check_cdef,
-    .scope=scope, .flag=ae_flag_check };
+    .scope=scope, .flag=tflag_check };
   struct ResolverArgs f_ptr_args = {.v = v, .e = exp, .tmpl_name = tmpl_name, m_func =  m_func, .types = types};
   CHECK_BO(envset_push(&es, v->from->owner_class, v->from->owner))
   (void)env_push(env, v->from->owner_class, v->from->owner);
index 5b89942cb3c3380a9ef60655e6d8d0a85e514377..fa3c27b72b9ee24916934648a111304bcf3c39ed 100644 (file)
@@ -35,7 +35,7 @@ ANN void free_op_map(Map map, struct Gwion_ *gwion) {
 }
 
 ANN static Type op_parent(const Env env, const Type t) {
-  if(GET_FLAG(t, template) && GET_FLAG(t, ref)) {
+  if(tflag(t, tflag_ctmpl)) {
     const Type type = typedef_base(t);
     char name[strlen(type->name) + 1];
     strcpy(name, type->name);
@@ -50,7 +50,6 @@ static m_bool op_match(const restrict Type t, const restrict Type mo) {
   if(t == OP_ANY_TYPE || mo == OP_ANY_TYPE)
     return GW_OK;
   Type type = t;
-  while(SAFE_FLAG(type, template) && type->e->def && type->e->def->base.tmpl && type->e->def->base.tmpl->call) type = type->e->parent;
   if((type && mo && mo->xid == type->xid) || (!type && !mo))
     return GW_OK;
   return 0;
@@ -179,7 +178,7 @@ ANN static void set_nspc(struct Op_Import *opi, const Nspc nspc) {
 }
 
 ANN static inline void set_nonnull(const Type t, const Exp exp) {
-  if(t != OP_ANY_TYPE && GET_FLAG(t, nonnull))
+  if(t != OP_ANY_TYPE && tflag(t, tflag_nonnull))
     exp_setnonnull(exp, 1);
 }
 
index 6047da5f12b0c323dcd21411bbba626622146414..30ace78f7d1ef8400884b0450d9156e084241511 100644 (file)
@@ -42,18 +42,16 @@ ANN static void fptr_assign(const Env env, const Fptr_Def fptr) {
     SET_FLAG(fptr->base->func, global);
     SET_FLAG(def->base, global);
   } else if(!GET_FLAG(fptr->base, static)) {
-    SET_FLAG(fptr->value, member);
-    SET_FLAG(fptr->base->func, member);
-    SET_FLAG(def->base, member);
+    set_vflag(fptr->value, vflag_member);
+    set_vflag(fptr->base->func->value_ref, vflag_member);
     def->stack_depth += SZ_INT;
   } else {
     SET_FLAG(fptr->value, static);
     SET_FLAG(fptr->base->func, static);
     SET_FLAG(def->base, static);
   }
-  if(GET_FLAG(def->base, variadic))
+  if(fbflag(def->base, fbflag_variadic))
     def->stack_depth += SZ_INT;
-  fptr->value->from->owner_class = env->class_def;
 }
 
 static void fptr_def(const Env env, const Fptr_Def fptr) {
@@ -78,17 +76,17 @@ ANN m_bool scan0_fptr_def(const Env env, const Fptr_Def fptr) {
   if(GET_FLAG(fptr->base, global))
     context_global(env);
   t->nspc = new_nspc(env->gwion->mp, name);
-  t->flag = fptr->base->flag;
+  t->flag |= fptr->base->flag;
   fptr->type = t;
   fptr->value = mk_class(env, t);
   valuefrom(env, fptr->value->from);
   fptr_def(env, fptr);
   if(env->class_def)
     fptr_assign(env, fptr);
-  SET_FLAG(fptr->value, func);
+  set_vflag(fptr->value, vflag_func);
   add_type(env, t->e->owner, t);
   mk_class(env, t);
-  ADD_REF(t);
+  type_addref(t);
   return GW_OK;
 }
 
@@ -126,15 +124,15 @@ ANN static void typedef_simple(const Env env, const Type_Def tdef, const Type ba
   t->e->owner_class = env->class_def;
   tdef->type = t;
   if(base->nspc)
-    ADD_REF((t->nspc = base->nspc));
-  t->flag = tdef->ext->flag | ae_flag_valid;
+    nspc_addref((t->nspc = base->nspc));
+  t->flag = tdef->ext->flag;
   scan0_implicit_similar(env, t, base);
   if(tdef->ext->array && !tdef->ext->array->exp)
-    SET_FLAG(t, empty);
+    set_tflag(t, tflag_empty);
 }
 
 ANN static m_bool typedef_complex(const Env env, const Type_Def tdef, const Type base) {
-  const ae_flag flag = base->e->def ? base->e->def->flag : 0;
+  const ae_flag flag = base->e->cdef ? base->e->cdef->flag : 0;
   const Class_Def cdef = new_class_def(env->gwion->mp, flag, tdef->xid,
        cpy_type_decl(env->gwion->mp, tdef->ext), NULL,
        loc_cpy(env->gwion->mp, td_pos(tdef->ext)));
@@ -146,13 +144,13 @@ ANN static m_bool typedef_complex(const Env env, const Type_Def tdef, const Type
 
 ANN static void typedef_fptr(const Env env, const Type_Def tdef, const Type base) {
   tdef->type = type_copy(env->gwion->mp, base);
-  ADD_REF(tdef->type->nspc)
+  nspc_addref(tdef->type->nspc);
   tdef->type->name = s_name(tdef->xid);
   tdef->type->e->parent = base;
   add_type(env, env->curr, tdef->type);
   mk_class(env, tdef->type);
   if(base->e->d.func->def->base->tmpl)
-    SET_FLAG(tdef->type, func);
+    set_tflag(tdef->type, tflag_ftmpl);
 }
 
 ANN m_bool scan0_type_def(const Env env, const Type_Def tdef) {
@@ -166,7 +164,7 @@ ANN m_bool scan0_type_def(const Env env, const Type_Def tdef) {
       CHECK_BB(typedef_complex(env, tdef, base))
   } else
     typedef_fptr(env, tdef, base);
-  SET_FLAG(tdef->type, typedef);
+  set_tflag(tdef->type, tflag_typedef);
   return GW_OK;
 }
 
@@ -226,33 +224,26 @@ ANN static Type union_type(const Env env, const Symbol s, const m_bool add) {
   add_type(env, env->curr, t);
   if(add)
     mk_class(env, t);
-  SET_FLAG(t, union);
   return t;
 }
 
 ANN static void union_tmpl(const Env env, const Union_Def udef) {
   if(tmpl_base(udef->tmpl)) {
-    assert(udef->type_xid);
-    const Class_Def cdef = new_class_def(env->gwion->mp, udef->flag, udef->type_xid,
-        NULL, (Ast)cpy_decl_list(env->gwion->mp, udef->l), loc_cpy(env->gwion->mp, udef->pos));
-    udef->type->e->def = cdef;
-    cdef->base.tmpl = cpy_tmpl(env->gwion->mp, udef->tmpl);
-    cdef->base.type = udef->type;
-    SET_FLAG(cdef, union);
-    SET_FLAG(udef->type, pure);
-    SET_FLAG(udef, template);
-    SET_FLAG(udef->type, template);
+    const Union_Def u = cpy_union_def(env->gwion->mp, udef);
+    u->type = udef->type;
+    udef->type->e->udef = u;
+    set_tflag(u->type, tflag_tmpl);
+    set_tflag(u->type, tflag_udef);
   }
   if(GET_FLAG(udef, global))
     SET_FLAG(udef->type, global);
-  SET_FLAG(udef->type, union);
 }
 
 ANN static Value union_value(const Env env, const Type t, const Symbol sym) {
   const Value v = new_value(env->gwion->mp, t, s_name(sym));
   valuefrom(env, v->from);
   nspc_add_value(env->curr, sym, v);
-  SET_FLAG(v, valid | ae_flag_pure);
+  set_vflag(v, vflag_union);
   return v;
 }
 
@@ -270,15 +261,12 @@ ANN m_bool scan0_union_def(const Env env, const Union_Def udef) {
     udef->value = union_value(env, t, udef->xid);
     udef->value->flag |= udef->flag;
     SET_ACCESS(udef, t);
-    if(env->class_def && !GET_FLAG(udef, static)) {
-      SET_FLAG(udef->value, member);
-      SET_FLAG(udef, member);
-    }
+    if(env->class_def && !GET_FLAG(udef, static))
+      set_vflag(udef->value, vflag_member);
   } else if(udef->type_xid) {
     CHECK_BB(scan0_defined(env, udef->type_xid, udef->pos))
     udef->type = union_type(env, udef->type_xid, 1);
     SET_ACCESS(udef, udef->type);
-    SET_FLAG(udef->type, valid);
   } else {
     const Symbol sym = scan0_sym(env, "union", udef->pos);
     CHECK_BB(scan0_defined(env, sym, udef->pos))
@@ -291,7 +279,7 @@ ANN m_bool scan0_union_def(const Env env, const Union_Def udef) {
     union_tmpl(env, udef);
   if(GET_FLAG(udef, global))
     env_pop(env, scope);
-  union_flag(udef, ae_flag_scan0);
+  union_flag(udef, tflag_scan0);
   return GW_OK;
 }
 
@@ -303,12 +291,10 @@ ANN static m_bool scan0_class_def_pre(const Env env, const Class_Def cdef) {
 }
 
 ANN static void cdef_flag(const Class_Def cdef, const Type t) {
-  if(cdef->base.tmpl) {
-    SET_FLAG(t, template);
-    SET_FLAG(cdef, template);
-  }
+  if(cdef->base.tmpl)
+    set_tflag(t, tflag_tmpl);
   if(cdef->base.ext && cdef->base.ext->array)
-    SET_FLAG(t, typedef);
+    set_tflag(t, tflag_typedef);
 }
 
 ANN static Type get_parent_base(const Env env, Type_Decl *td) {
@@ -322,15 +308,15 @@ ANN static Type get_parent_base(const Env env, Type_Decl *td) {
   return t;
 }
 
-ANN static Type check_abstract(const Env env, Type_Decl *td) {
+ANN static inline Type scan0_final(const Env env, Type_Decl *td) {
   DECL_OO(const Type, t, = known_type(env, td))
-  if(!GET_FLAG(t, abstract)) // could be final
+  if(!GET_FLAG(t, final))
     return t;
-  ERR_O(td_pos(td), _("can't inherit from abstract parent class '%s'\n."), t->name);
+  ERR_O(td_pos(td), _("can't inherit from final parent class '%s'\n."), t->name);
 }
 
 ANN static Type get_parent(const Env env, const Class_Def cdef) {
-  if(GET_FLAG(cdef, struct))
+  if(cflag(cdef, cflag_struct))
     return env->gwion->type[et_compound];
   if(!cdef->base.ext)
     return env->gwion->type[et_object];
@@ -338,7 +324,7 @@ ANN static Type get_parent(const Env env, const Class_Def cdef) {
     return get_parent_base(env, cdef->base.ext);
   if(cdef->base.tmpl)
     template_push_types(env, cdef->base.tmpl);
-  const Type t = check_abstract(env, cdef->base.ext);
+  const Type t = scan0_final(env, cdef->base.ext);
   if(cdef->base.tmpl)
     nspc_pop_type(env->gwion->mp, env->curr);
   return t ?: (Type)GW_ERROR;
@@ -350,26 +336,29 @@ ANN static Type scan0_class_def_init(const Env env, const Class_Def cdef) {
   if(parent == (Type)GW_ERROR)
     return NULL;
   const Type t = scan0_type(env, ++env->scope->type_xid, s_name(cdef->base.xid), parent);
-  if(GET_FLAG(cdef, struct))
-    SET_FLAG(t, struct);
+  if(cflag(cdef, cflag_struct))
+    set_tflag(t, tflag_struct);
   t->e->tuple = new_tupleform(env->gwion->mp, parent);
   t->e->owner = env->curr;
   t->e->owner_class = env->class_def;
   t->nspc = new_nspc(env->gwion->mp, t->name);
   t->nspc->parent = env->curr;
-  t->e->def = cdef;
-  t->flag = cdef->flag;
+  t->e->cdef = cdef;
+  t->flag |= cdef->flag;
   add_type(env, t->e->owner, t);
   cdef_flag(cdef, t);
   if(cdef->base.ext && cdef->base.ext->array)
-    SET_FLAG(t, typedef);
+    set_tflag(t, tflag_typedef);
   return t;
 }
 
 ANN static m_bool scan0_stmt_list(const Env env, Stmt_List list) {
-  do if(list->stmt->stmt_type == ae_stmt_pp && list->stmt->d.stmt_pp.pp_type == ae_pp_include)
-    env->name = list->stmt->d.stmt_pp.data;
-  while((list = list->next));
+  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_require)
+      CHECK_BB(plugin_ini(env->gwion, list->stmt->d.stmt_pp.data))
+  } while((list = list->next));
   return GW_OK;
 }
 
@@ -378,7 +367,7 @@ HANDLE_SECTION_FUNC(scan0, m_bool, Env)
 
 ANN static m_bool scan0_class_def_inner(const Env env, const Class_Def cdef) {
   CHECK_OB((cdef->base.type = scan0_class_def_init(env, cdef)))
-  SET_FLAG(cdef->base.type, scan0);
+  set_tflag(cdef->base.type, tflag_scan0);
   if(cdef->body)
     CHECK_BB(env_body(env, cdef, scan0_section))
   (void)mk_class(env, cdef->base.type);
@@ -386,9 +375,9 @@ ANN static m_bool scan0_class_def_inner(const Env env, const Class_Def cdef) {
 }
 
 ANN m_bool scan0_class_def(const Env env, const Class_Def c) {
-  const Class_Def cdef = !tmpl_base(c->base.tmpl) ?
-    c : cpy_class_def(env->gwion->mp, c);
-  if(GET_FLAG(cdef, global)) {
+  const int cpy = tmpl_base(c->base.tmpl) || GET_FLAG(c, global);
+  const Class_Def cdef = !cpy ? c : cpy_class_def(env->gwion->mp, c);
+  if(GET_FLAG(cdef, global)) { // could be updated
     vector_add(&env->scope->nspc_stack, (vtype)env->curr);
     env->curr = env->global_nspc;
     context_global(env);
@@ -397,11 +386,13 @@ ANN m_bool scan0_class_def(const Env env, const Class_Def c) {
     scan0_class_def_inner(env, cdef) : GW_ERROR;
   if(GET_FLAG(cdef, global))
     env->curr = (Nspc)vector_pop(&env->scope->nspc_stack);
-  CHECK_BB(ret)
-  if(GET_FLAG(cdef, global) || (cdef->base.tmpl && !cdef->base.tmpl->call))
+  if(cpy && cdef->base.type) {
     c->base.type = cdef->base.type;
-  SET_FLAG(cdef->base.type, scan0);
-  return GW_OK;
+    c->base.type->e->cdef = cdef;
+    set_tflag(c->base.type, tflag_cdef);
+    set_tflag(cdef->base.type, tflag_scan0);// redundant
+  }
+  return ret;
 }
 
 ANN m_bool scan0_ast(const Env env, Ast ast) {
index 350c9239dcb9bf371eaf625dd486303e8b6c01bf..da0e8d3a24ea7eb160d188ac845b7aca1a9e016c 100644 (file)
@@ -25,7 +25,7 @@ ANN static inline m_bool type_cyclic(const Env env, const Type t, const Type_Dec
 
 ANN static inline m_bool ensure_scan1(const Env env, const Type t) {
   struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)scan1_cdef,
-    .scope=env->scope->depth, .flag=ae_flag_scan1 };
+    .scope=env->scope->depth, .flag=tflag_scan1 };
   return envset_run(&es, t);
 }
 
@@ -34,7 +34,7 @@ ANN static Type scan1_type(const Env env, Type_Decl* td) {
   const Type t = get_type(type);
   if(!env->func && env->class_def && !GET_FLAG(td, ref))
     CHECK_BO(type_cyclic(env, t, td))
-  if(!GET_FLAG(t, scan1) && t->e->def)
+  if(!tflag(t, tflag_scan1))
     CHECK_BO(ensure_scan1(env, t))
   return type;
 }
@@ -52,8 +52,6 @@ ANN static Type scan1_exp_decl_type(const Env env, Exp_Decl* decl) {
   DECL_OO(const Type ,t, = void_type(env, decl->td))
   if(decl->td->xid == insert_symbol("auto") && decl->type)
     return decl->type;
-  if(!env->scope->depth && env->class_def && !GET_FLAG(decl->td, static))
-    SET_FLAG(decl->td, member);
   if(GET_FLAG(t, private) && t->e->owner != env->curr)
     ERR_O(exp_self(decl)->pos, _("can't use private type %s"), t->name)
   if(GET_FLAG(t, protect) && (!env->class_def || isa(t, env->class_def) < 0))
@@ -77,7 +75,7 @@ ANN static m_bool scan1_decl(const Env env, const Exp_Decl* decl) {
     CHECK_BB(isres(env, var->xid, exp_self(decl)->pos))
     Type t = decl->type;
     CHECK_BB(scan1_defined(env, var))
-    if(var->array) {
+   if(var->array) {
       if(var->array->exp) {
         if(GET_FLAG(decl->td, ref))
           ERR_B(var->array->exp->pos, _("ref array must not have array expression.\n"
@@ -92,23 +90,26 @@ ANN static m_bool scan1_decl(const Env env, const Exp_Decl* decl) {
         ERR_B(exp_self(decl)->pos, _("Type '%s' is abstract, declare as ref. (use @)"), t->name)
     }
     const Value v = var->value = var->value ?: new_value(env->gwion->mp, t, s_name(var->xid));
-    if(SAFE_FLAG(env->class_def, struct) && !GET_FLAG(decl->td, static)) {
+// rewrite logic
+    if(!env->scope->depth && env->class_def && !GET_FLAG(decl->td, static))
+      set_vflag(v, vflag_member);
+  if(safe_tflag(env->class_def, tflag_struct) && !GET_FLAG(decl->td, static)) {
       v->from->offset = env->class_def->size;
       env->class_def->size += t->size;
     }
     nspc_add_value(env->curr, var->xid, v);
-    v->flag = decl->td->flag;
+    v->flag |= decl->td->flag;
     v->type = t;
     if(var->array && !var->array->exp)
-      SET_FLAG(v, ref);
+      SET_FLAG(decl->td, ref);
     if(env->class_def) {
       if(env->class_def->e->tuple)
         tuple_contains(env, v);
     } else if(!env->scope->depth)
-      SET_FLAG(v, global);
+      set_vflag(v, vflag_fglobal);// file global
     v->d.ptr = var->addr;
     if(GET_FLAG(decl->td, global))
-      SET_FLAG(v, abstract);
+      SET_FLAG(v, global);
     if(!env->scope->depth)
       valuefrom(env, v->from);
   } while((list = list->next));
@@ -127,8 +128,6 @@ ANN m_bool scan1_exp_decl(const Env env, const Exp_Decl* decl) {
   CHECK_BB(env_storage(env, decl->td->flag, exp_self(decl)->pos))
   ((Exp_Decl*)decl)->type = scan1_exp_decl_type(env, (Exp_Decl*)decl);
   CHECK_OB(decl->type)
-  if(GET_FLAG(decl->type, const))
-    exp_setmeta(exp_self(decl), 1);
   const m_bool global = GET_FLAG(decl->td, global);
   if(global) {
     if(env->context)
@@ -319,7 +318,9 @@ ANN m_bool scan1_enum_def(const Env env, const Enum_Def edef) {
       SET_ACCESS(edef, v)
       SET_ACCESS(edef, edef->t)
     }
-    SET_FLAG(v, const | ae_flag_enum | ae_flag_valid);
+    SET_FLAG(v, const);
+    set_vflag(v, vflag_valid);
+    set_vflag(v, vflag_enum);
     nspc_add_value(edef->t->e->owner, list->xid, v);
     vector_add(&edef->values, (vtype)v);
   } while((list = list->next));
@@ -331,8 +332,10 @@ ANN static Value arg_value(const Env env, const Arg_List list) {
   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 | ae_flag_abstract;
+  if(list->td) {
+    v->flag = list->td->flag;
+//    SET_FLAG(v, global); ???
+  }
   return v;
 }
 
@@ -386,25 +389,23 @@ ANN m_bool scan1_fptr_def(const Env env, const Fptr_Def fptr) {
 ANN m_bool scan1_type_def(const Env env, const Type_Def tdef) {
   if(!tdef->type)
     tdef->type = nspc_lookup_type0(env->curr, tdef->xid);
-  if(!tdef->type->e->def)return GW_OK;
-  return !is_fptr(env->gwion, tdef->type) ? scan1_cdef(env, tdef->type->e->def) : GW_OK;
+  if(!tdef->type->e->cdef)return GW_OK;
+  return !is_fptr(env->gwion, tdef->type) ? scan1_cdef(env, tdef->type) : GW_OK;
 }
 
 ANN static m_bool scan1_union_def_action(const Env env, const Union_Def udef,
     const Decl_List l) {
   const Exp_Decl decl = l->self->d.exp_decl;
-  SET_FLAG(decl.td, valid | udef->flag);
+  decl.td->flag |= udef->flag;
   const m_bool global = GET_FLAG(udef, global);
   if(global)
     UNSET_FLAG(decl.td, global);
-  if(GET_FLAG(udef, member))
-    SET_FLAG(decl.td, member);
   else if(GET_FLAG(udef, static))
     SET_FLAG(decl.td, static);
   CHECK_BB(scan1_exp(env, l->self))
 
   Var_Decl_List list = decl.list;
-  do ADD_REF(list->self->value)
+  do value_addref(list->self->value);
   while((list = list->next));
 
   if(global)
@@ -437,7 +438,7 @@ ANN m_bool scan1_union_def(const Env env, const Union_Def udef) {
   }
   const m_bool ret = scan1_union_def_inner(env, udef);
   union_pop(env, udef, scope);
-  union_flag(udef, ae_flag_scan1);
+  union_flag(udef, tflag_scan1);
   return ret;
 }
 
@@ -530,11 +531,10 @@ ANN static m_bool scan1_fdef_args(const Env env, Arg_List list) {
 
 ANN m_bool scan1_fbody(const Env env, const Func_Def fdef) {
   if(fdef->base->args) {
-    if(!GET_FLAG(fdef->base, builtin))
-      CHECK_BB(scan1_fdef_args(env, fdef->base->args))
+    CHECK_BB(scan1_fdef_args(env, fdef->base->args))
     CHECK_BB(scan1_args(env, fdef->base->args))
   }
-  if(!GET_FLAG(fdef->base, builtin) && fdef->d.code && fdef->d.code->d.stmt_code.stmt_list)
+  if(fdef->d.code && fdef->d.code->d.stmt_code.stmt_list)
     CHECK_BB(scan1_stmt_list(env, fdef->d.code->d.stmt_code.stmt_list))
   return GW_OK;
 }
@@ -542,9 +542,9 @@ ANN m_bool scan1_fbody(const Env env, const Func_Def fdef) {
 ANN m_bool scan1_fdef(const Env env, const Func_Def fdef) {
   if(fdef->base->td)
     CHECK_OB((fdef->base->ret_type = known_type(env, fdef->base->td)))
-  if(GET_FLAG(fdef->base, typedef))
+  if(fbflag(fdef->base, fbflag_internal))
     CHECK_BB(scan_internal(env, fdef->base))
-  else if(GET_FLAG(fdef->base, op) && env->class_def)
+  else if(fbflag(fdef->base, fbflag_op) && env->class_def)
     SET_FLAG(fdef->base, static);
   RET_NSPC(scan1_fbody(env, fdef))
   return GW_OK;
@@ -592,13 +592,16 @@ ANN static m_bool scan1_parent(const Env env, const Class_Def cdef) {
   if(cdef->base.ext->array)
     CHECK_BB(scan1_exp(env, cdef->base.ext->array->exp))
   DECL_OB(const Type , parent, = scan1_get_parent(env, &cdef->base))
+//  if(GET_FLAG(parent, abstract)) // could be final
+//SET_FLAG(cdef->base.type, abstract);
+//    ERR_B(td_pos(cdef->base.ext), _("can't inherit from abstract parent class '%s'\n."), parent->name);
   if(isa(parent, env->gwion->type[et_object]) < 0)
     ERR_B(pos, _("cannot extend primitive type '%s'"), parent->name)
-  if(parent->e->def && !GET_FLAG(parent, scan1))
+  if(!tflag(parent, tflag_scan1))
     CHECK_BB(ensure_scan1(env, parent))
   if(type_ref(parent))
     ERR_B(pos, _("can't use ref type in class extend"))
-  if(GET_FLAG(parent, nonnull))
+  if(tflag(parent, tflag_nonnull))
     ERR_B(pos, _("can't use nonnull type in class extend"))
   return GW_OK;
 }
@@ -616,12 +619,11 @@ ANN m_bool scan1_class_def(const Env env, const Class_Def cdef) {
   if(tmpl_base(cdef->base.tmpl))
     return GW_OK;
   const Type t = cdef->base.type;
-  if(GET_FLAG(t, scan1))
+  if(tflag(t, tflag_scan1))
     return GW_OK;
-  SET_FLAG(t, scan1);
-  if(t->e->owner_class && !GET_FLAG(t->e->owner_class, scan1))
+  set_tflag(t, tflag_scan1);
+  if(t->e->owner_class && !tflag(t->e->owner_class, tflag_scan1))
     CHECK_BB(ensure_scan1(env, t->e->owner_class))
-  SET_FLAG(cdef->base.type, scan1);
   if(cdef->base.ext)
     CHECK_BB(cdef_parent(env, cdef))
   if(cdef->body)
index 2bb5b4a828dfbfc0fa58763265b7bdf1bc96c386..618dbc10faee92d56a3fab99827edb7d680f2a50 100644 (file)
@@ -15,13 +15,13 @@ ANN static m_bool scan2_stmt_list(const Env, Stmt_List);
 
 ANN static inline m_bool ensure_scan2(const Env env, const Type t) {
   struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)scan2_cdef,
-    .scope=env->scope->depth, .flag=ae_flag_scan2 };
+    .scope=env->scope->depth, .flag=tflag_scan2 };
   return envset_run(&es, t);
 }
 
 ANN static m_bool scan2_decl(const Env env, const Exp_Decl* decl) {
   const Type t = get_type(decl->type);
-  if(t->e->def && !GET_FLAG(t, scan2))
+  if(!tflag(t, tflag_scan2))
     CHECK_BB(ensure_scan2(env, t))
   Var_Decl_List list = decl->list;
   do {
@@ -56,15 +56,17 @@ ANN static m_bool scan2_args(const Func_Def f) {
 ANN static Value scan2_func_assign(const Env env, const Func_Def d,
     const Func f, const Value v) {
   valuefrom(env, v->from);
-  SET_FLAG(v, func | ae_flag_const);
+  SET_FLAG(v, const);
+  set_vflag(v, vflag_func);
   if(!env->class_def)
-    SET_FLAG(v, global);
+    set_vflag(v, vflag_fglobal);
   else {
-    if(GET_FLAG(f, member))
-      SET_FLAG(v, member);
-    else SET_FLAG(v, static);
+    if(GET_FLAG(d->base, static))
+      SET_FLAG(v, static);
+    else
+      set_vflag(v, vflag_member);
     SET_ACCESS(d->base, v)
 }
+ }
   d->base->func = v->d.func_ref = f;
   return f->value_ref = v;
 }
@@ -77,13 +79,13 @@ ANN m_bool scan2_fptr_def(const Env env NUSED, const Fptr_Def fptr) {
       RET_NSPC(scan2_args(def))
     }
   } else
-    SET_FLAG(fptr->type, func);
+    set_tflag(fptr->type, tflag_ftmpl);
   return GW_OK;
 }
 
 ANN m_bool scan2_type_def(const Env env, const Type_Def tdef) {
-  if(!tdef->type->e->def) return GW_OK;
-  return !is_fptr(env->gwion, tdef->type) ? scan2_class_def(env, tdef->type->e->def) : GW_OK;
+  if(!tdef->type->e->cdef) return GW_OK;
+  return !is_fptr(env->gwion, tdef->type) ? scan2_class_def(env, tdef->type->e->cdef) : GW_OK;
 }
 
 ANN static inline Value prim_value(const Env env, const Symbol s) {
@@ -105,11 +107,11 @@ ANN static inline m_bool scan2_prim(const Env env, const Exp_Primary* prim) {
   if(prim->prim_type == ae_prim_hack || prim->prim_type == ae_prim_typeof ||
         prim->prim_type == ae_prim_interp)
     CHECK_BB(scan2_exp(env, prim->d.exp))
-  else if(prim->prim_type == ae_prim_id) {
+/*  else if(prim->prim_type == ae_prim_id) {
     const Value v = prim_value(env, prim->d.var);
     if(v)
-      SET_FLAG(v, used);
-  } else if(prim->prim_type == ae_prim_array && prim->d.array->exp)
+      v->vflag |= used;
+  } */else if(prim->prim_type == ae_prim_array && prim->d.array->exp)
     return scan2_exp(env, prim->d.array->exp);
   else if(prim->prim_type == ae_prim_range)
     return scan2_range(env, prim->d.range);
@@ -130,7 +132,7 @@ 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)
       ERR_B(e->pos, _("cant '%s' from/to a multi-variable declaration."), s_name(op))
-    SET_FLAG(e->d.exp_decl.list->self->value, used);
+//    set_vflag(e->d.exp_decl.list->self->value, vflag_used);
   }
   return GW_OK;
 }
@@ -270,7 +272,7 @@ ANN m_bool scan2_union_def(const Env env, const Union_Def udef) {
   const m_uint scope = union_push(env, udef);
   const m_bool ret = scan2_union_decl(env, udef->l);
   union_pop(env, udef, scope);
-  union_flag(udef, ae_flag_scan2);
+  union_flag(udef, tflag_scan2);
   return ret;
 }
 
@@ -300,13 +302,17 @@ ANN static m_bool scan2_stmt_list(const Env env, Stmt_List list) {
 }
 
 ANN static m_bool scan2_func_def_overload(const Env env, const Func_Def f, const Value overload) {
-  const m_bool base = tmpl_base(f->base->tmpl);
-  const m_bool tmpl = GET_FLAG(overload, template);
+  const m_bool fptr = is_fptr(env->gwion, overload->type);
   if(isa(overload->type, env->gwion->type[et_function]) < 0 || is_fptr(env->gwion, overload->type)) {
-    if(!GET_FLAG(f->base, typedef))
+    if(!fbflag(f->base, fbflag_internal))
       ERR_B(f->pos, _("function name '%s' is already used by another value"), overload->name)
   }
-  if((!tmpl && base) || (tmpl && !base && !GET_FLAG(f->base, template)))
+  const Func obase = !fptr ? overload->d.func_ref : overload->type->e->d.base_type->e->d.func;
+  if(GET_FLAG(obase->def->base, final))
+    ERR_B(f->pos, _("can't overload final function %s"), overload->name)
+  const m_bool base = tmpl_base(f->base->tmpl);
+  const m_bool tmpl = fflag(obase, fflag_tmpl);
+  if((!tmpl && base) || (tmpl && !base && !f->base->tmpl))
     ERR_B(f->pos, _("must overload template function with template"))
   return GW_OK;
 }
@@ -314,10 +320,8 @@ ANN static m_bool scan2_func_def_overload(const Env env, const Func_Def f, const
 ANN static Func scan_new_func(const Env env, const Func_Def f, const m_str name) {
   const Func func = new_func(env->gwion->mp, name, f);
   if(env->class_def) {
-    if(GET_FLAG(env->class_def, template))
-      SET_FLAG(func, ref);
-    if(!GET_FLAG(f->base, static))
-      SET_FLAG(func, member);
+    if(tflag(env->class_def, tflag_tmpl))
+      set_fflag(func, fflag_ftmpl);
   }
   return func;
 }
@@ -330,8 +334,6 @@ ANN static Type func_type(const Env env, const Func func) {
   t->name = func->name;
   t->e->owner = env->curr;
   t->e->owner_class = env->class_def;
-  if(GET_FLAG(func, member))
-    t->size += SZ_INT;
   t->e->d.func = func;
   return t;
 }
@@ -343,29 +345,26 @@ ANN2(1,2) static Value func_value(const Env env, const Func f,
   valuefrom(env, v->from);
   CHECK_OO(scan2_func_assign(env, f->def, f, v))
   if(!overload) {
-    ADD_REF(v);
+    value_addref(v);
     nspc_add_value_front(env->curr, f->def->base->xid, v);
   } else if(overload->d.func_ref) {
     f->next = overload->d.func_ref->next;
     overload->d.func_ref->next = f;
   }
+  if(env->class_def && !GET_FLAG(f->def->base, static)) {
+    t->size += SZ_INT;
+    set_vflag(v, vflag_member);
+  }
   return v;
 }
 
-ANN static m_bool scan2_func_def_builtin(MemPool p, const Func func, const m_str name) {
-  SET_FLAG(func, builtin);
-  SET_FLAG(func->value_ref, builtin);
-  func->code = new_vm_code(p, NULL, func->def->stack_depth, func->flag, name);
-  func->code->native_func = (m_uint)func->def->d.dl_func_ptr;
-  return GW_OK;
-}
-
 ANN2(1, 2) static m_bool scan2_fdef_tmpl(const Env env, const Func_Def f, const Value overload) {
   const m_str name = s_name(f->base->xid);
   const Func func = scan_new_func(env, f, name);
   const Value value = func_value(env, func, overload);
-  SET_FLAG(value, valid | ae_flag_template);
-  SET_FLAG(value->type, func); // the only types with func flag, name could be better
+  set_fflag(func, fflag_tmpl);
+  set_vflag(value, vflag_valid);
+  set_tflag(value->type, tflag_ftmpl); // the only types with func flag, name could be better
   Type type = env->class_def;
   Nspc nspc = env->curr;
   uint i = 0;
@@ -386,7 +385,7 @@ ANN2(1, 2) static m_bool scan2_fdef_tmpl(const Env env, const Func_Def f, const
             "template", ff->vt_index);
           nspc_add_value(env->curr, sym, value);
           if(!overload) {
-            ADD_REF(value)
+            value_addref(value);
             nspc_add_value(env->curr, f->base->xid, value);
           }
           func->vt_index = ff->vt_index;
@@ -399,16 +398,11 @@ ANN2(1, 2) static m_bool scan2_fdef_tmpl(const Env env, const Func_Def f, const
   const Symbol sym = func_symbol(env, env->curr->name, name, "template", i);
   nspc_add_value(env->curr, sym, value);
   if(!overload) {
-    ADD_REF(value)
+    value_addref(value);
     nspc_add_value(env->curr, f->base->xid, value);
     nspc_add_func(env->curr, f->base->xid, func);
   } else
     func->vt_index = ++overload->from->offset;
-  if(GET_FLAG(f->base, builtin)) {
-    CHECK_BB(scan2_func_def_builtin(env->gwion->mp, func, func->name))
-    SET_FLAG(func, builtin);
-    SET_FLAG(value, builtin);
-  }
   return GW_OK;
 }
 
@@ -432,10 +426,9 @@ ANN static m_bool scan2_func_def_code(const Env env, const Func_Def f) {
 }
 
 ANN static void scan2_func_def_flag(const Env env, const Func_Def f) {
-  if(!GET_FLAG(f->base, builtin))
-    SET_FLAG(f->base->func, pure);
+  set_fflag(f->base->func, fflag_pure);
   if(f->base->xid == insert_symbol("@dtor"))
-    SET_FLAG(env->class_def, dtor);
+    set_tflag(env->class_def, tflag_dtor);
 }
 
 ANN static m_str func_tmpl_name(const Env env, const Func_Def f) {
@@ -472,8 +465,6 @@ ANN2(1,2,4) static Value func_create(const Env env, const Func_Def f,
   nspc_add_func(env->curr, insert_symbol(func->name), func);
   const Value v = func_value(env, func, overload);
   scan2_func_def_flag(env, f);
-  if(GET_FLAG(f->base, builtin))
-    CHECK_BO(scan2_func_def_builtin(env->gwion->mp, func, func->name))
   nspc_add_value(env->curr, insert_symbol(func->name), v);
   return v;
 }
@@ -497,12 +488,12 @@ ANN2(1,2) m_bool scan2_fdef_std(const Env env, const Func_Def f, const Value ove
     f->base->func = base;
   if(f->base->args)
     CHECK_BB(scan2_args(f))
-  if(!GET_FLAG(f->base, builtin) && f->d.code)
+  if(f->d.code)
     CHECK_BB(scan2_func_def_code(env, f))
   if(!base) {
-    if(GET_FLAG(f->base, op))
+    if(fbflag(f->base, fbflag_op))
       CHECK_BB(scan2_func_def_op(env, f))
-    SET_FLAG(f->base->func->value_ref, valid);
+    set_vflag(f->base->func->value_ref, vflag_valid);
   }
   return GW_OK;
 }
@@ -541,7 +532,7 @@ ANN m_bool scan2_func_def(const Env env, const Func_Def fdef) {
     fdef : scan2_cpy_fdef(env, fdef);
   const m_uint scope = !GET_FLAG(f->base, global) ? env->scope->depth : env_push_global(env);
   f->stack_depth = (env->class_def && !GET_FLAG(f->base, static) && !GET_FLAG(f->base, global)) ? SZ_INT : 0;
-  if(GET_FLAG(f->base, variadic))
+  if(fbflag(f->base, fbflag_variadic))
     f->stack_depth += SZ_INT;
   const m_bool ret = scanx_fdef(env, env, f, (_exp_func)scan2_fdef);
   if(GET_FLAG(f->base, global))
@@ -556,7 +547,7 @@ HANDLE_SECTION_FUNC(scan2, m_bool, Env)
 
 ANN static m_bool scan2_parent(const Env env, const Class_Def cdef) {
   const Type parent = cdef->base.type->e->parent;
-  if(parent->e->def && !GET_FLAG(parent, scan2))
+  if(!tflag(parent, tflag_scan2))
     CHECK_BB(ensure_scan2(env, parent))
   if(cdef->base.ext->array)
     CHECK_BB(scan2_exp(env, cdef->base.ext->array->exp))
@@ -576,10 +567,11 @@ ANN m_bool scan2_class_def(const Env env, const Class_Def cdef) {
   if(tmpl_base(cdef->base.tmpl))
     return GW_OK;
   const Type t = cdef->base.type;
-  if(GET_FLAG(t, scan2))return GW_OK;
-  if(t->e->owner_class && !GET_FLAG(t->e->owner_class, scan2))
+  if(tflag(t, tflag_scan2))
+    return GW_OK;
+  if(t->e->owner_class && !tflag(t->e->owner_class, tflag_scan2))
     CHECK_BB(ensure_scan2(env, t->e->owner_class))
-  SET_FLAG(t, scan2);
+  set_tflag(t, tflag_scan2);
   if(cdef->base.ext)
     CHECK_BB(cdef_parent(env, cdef))
   if(cdef->body)
index c4eaa03127780d107e451af6f890e3d780b77a35..45345b921c0ddc517f85c9323fa617c06c75736e 100644 (file)
@@ -43,8 +43,8 @@ scanx_body(const Env e, const Class_Def c, const _exp_func f, void* d) {
 
 __attribute__((returns_nonnull))
 ANN Type unflag_type(const Type t) {
-  const Type type = !GET_FLAG(t, nonnull) ? t : t->e->parent;
-  return !GET_FLAG(type, force) ? type : type->e->parent;
+  const Type type = !tflag(t, tflag_nonnull) ? t : t->e->parent;
+  return !tflag(type, tflag_force) ? type : type->e->parent;
 }
 
 __attribute__((returns_nonnull))
@@ -53,14 +53,12 @@ ANN Type get_type(const Type t) {
   return unflag_type(type);
 }
 
-ANN m_bool scanx_cdef(const Env env, void* opt, const Class_Def cdef,
+ANN m_bool scanx_cdef(const Env env, void* opt, const Type base,
     const _exp_func f_cdef, const _exp_func f_union) {
-  const Type t = get_type(cdef->base.type);
+  const Type t = get_type(base);
   if(t->e->parent !=  env->gwion->type[et_union])
-     return f_cdef(opt, t->e->def);
-  CHECK_BB(template_push_types(env, t->e->def->base.tmpl))
-  const m_bool ret = f_union(opt, t->e->def->union_def);
-  nspc_pop_type(env->gwion->mp, env->curr);
+     return f_cdef(opt, t->e->cdef);
+  const m_bool ret = f_union(opt, t->e->udef);
   return ret;
 }
 
index 784e298aca2f08c2f9ac361a86d3656859c1b360..84c1dad52a17c0aaf16096f21cd1bed52404bc97 100644 (file)
@@ -14,8 +14,8 @@ ANN void union_pop(const Env env, const Union_Def udef, const m_uint scope) {
     env_pop(env, scope);
 }
 
-ANN void union_flag(const Union_Def udef, const ae_flag flag) {
+ANN void union_flag(const Union_Def udef, const enum tflag flag) {
   const Type type = udef->xid || !udef->type_xid ?
     udef->value->type : udef->type;
-  type->flag |= flag;
+  type->tflag |= flag;
 }
index 3042d0e7b1f32cda7022c4c7018c4df5e87efdd0..63c159c3cba48067c5a768e5ecc4b91bc4f444ee 100644 (file)
@@ -35,8 +35,8 @@ ANN static m_bool push_types(const Env env, const Tmpl *tmpl) {
 ANN static m_bool _template_push(const Env env, const Type t) {
   if(t->e->owner_class)
     CHECK_BB(template_push(env, t->e->owner_class))
-  if(GET_FLAG(t, template))
-    return push_types(env, t->e->def->base.tmpl);
+  if(tflag(t, tflag_tmpl))
+    return push_types(env, t->e->cdef->base.tmpl); // incorrect
   return GW_OK;
 }
 
@@ -66,15 +66,19 @@ static ANN Type scan_func(const Env env, const Type t, const Type_Decl* td) {
   if(base_type)
     return base_type;
   const Type ret = type_copy(env->gwion->mp, t);
-  ADD_REF(ret->nspc)
   ret->e->parent = t;
   ret->name = s_name(sym);
-  SET_FLAG(ret, func);
+  set_tflag(ret, tflag_ftmpl);
   nspc_add_type_front(t->e->owner, sym, ret);
+  void* func_ptr = t->e->d.func->def->d.dl_func_ptr;
+  if(vflag(t->e->d.func->value_ref, vflag_builtin))
+    t->e->d.func->def->d.dl_func_ptr = NULL;
   const Func_Def def = cpy_func_def(env->gwion->mp, t->e->d.func->def);
   const Func func = ret->e->d.func = new_func(env->gwion->mp, s_name(sym), def);
   const Value value = new_value(env->gwion->mp, ret, s_name(sym));
   func->flag = def->base->flag;
+  if(vflag(t->e->d.func->value_ref, vflag_member))
+    set_vflag(value, vflag_member);
   value->d.func_ref = func;
   value->from->owner = t->e->owner;
   value->from->owner_class = t->e->owner_class;
@@ -82,6 +86,10 @@ static ANN Type scan_func(const Env env, const Type t, const Type_Decl* td) {
   func->def->base->tmpl = mk_tmpl(env, t->e->d.func->def->base->tmpl, td->types);
   def->base->func = func;
   nspc_add_value_front(t->e->owner, sym, value);
+  if(vflag(t->e->d.func->value_ref, vflag_builtin)) {
+    builtin_func(env->gwion->mp, func, func_ptr);
+    t->e->d.func->def->d.dl_func_ptr = func_ptr;
+  }
   return ret;
 }
 
@@ -93,8 +101,8 @@ static ANN Type maybe_func(const Env env, const Type t, const Type_Decl* td) {
 }
 
 ANN Type _scan_type(const Env env, const Type t, Type_Decl* td) {
-  if(GET_FLAG(t, template) && isa(t, env->gwion->type[et_function]) < 0) {
-    if(GET_FLAG(t, ref) || (GET_FLAG(t, unary) && !td->types))
+  if(tflag(t, tflag_tmpl) && isa(t, env->gwion->type[et_function]) < 0) {
+    if(tflag(t, tflag_ctmpl) || (tflag(t, tflag_ntmpl) && !td->types))
       return t;
     struct TemplateScan ts = { .t=t, .td=td };
     struct Op_Import opi = { .op=insert_symbol("@scan"), .lhs=t, .data=(uintptr_t)&ts, .pos=td_pos(td), .op_type=op_scan };
@@ -118,7 +126,7 @@ ANN Type scan_type(const Env env, const Type t, Type_Decl* td) {
     if(!owner->nspc)
       ERR_O(td_pos(td), "type '%s' has no namespace", owner->name)
     struct EnvSet es = { .env=env, .data=env,
-      .scope=env->scope->depth, .flag=ae_flag_none };
+      .scope=env->scope->depth, .flag=tflag_none };
     envset_push(&es, owner, owner->nspc);
     (void)env_push(env, owner, owner->nspc);// TODO: is this needed?
     const Type ret = scan_type(env, t, td->next);
index deac0f86e5c101cc66328bbf7f277ed7aa8337b9..6e37aab56a1d8a4a6546d16fc977759eb2a589a8 100644 (file)
@@ -58,11 +58,11 @@ ANN m_bool traverse_type_def(const Env env, const Type_Def def) {
 
 ANN m_bool traverse_class_def(const Env env, const Class_Def def) {
   const Type t = def->base.type;
-  if(!GET_FLAG(t, scan1))
+  if(!tflag(t, tflag_scan1))
     CHECK_BB(scan1_class_def(env, def))
-  if(!GET_FLAG(t, scan2))
+  if(!tflag(t, tflag_scan2))
     CHECK_BB(scan2_class_def(env, def))
-  if(!GET_FLAG(t, valid))
+  if(!tflag(t, tflag_check))
     return check_class_def(env, def);
   return GW_OK;
 }
index 75724b18b9b537464d73810bab8e0f1781cd3f1f..eeaceeca34c82f474456a20f7768b76e88e26da4 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef BUILD_ON_WINDOWS
 #include <glob.h>
 #include <dlfcn.h>
+#include <limits.h>
 #else
 #include <windows.h>
 #endif
 #include "instr.h"
 #include "object.h"
 #include "import.h"
+#include "gwi.h"
 
-typedef m_bool (*import)(Gwi);
-typedef m_str  (*modstr)(void);
+typedef m_bool (*plugin)(Gwi);
 typedef void*  (*modini)(const struct Gwion_*, const Vector);
-typedef void*  (*modrun)(const struct Gwion_*, void*);
 typedef void*  (*modend)(const struct Gwion_*, void*);
+typedef m_str* (*gwdeps)(void);
 
-struct Plug_ {
-  m_str name;
-  modini ini;
-  modend end;
-  void* self;
-};
 #define STR_EXPAND(tok) #tok
 #define STR(tok) STR_EXPAND(tok)
 #ifndef BUILD_ON_WINDOWS
@@ -44,53 +39,32 @@ struct Plug_ {
 
 struct PlugHandle {
   MemPool mp;
-  PlugInfo* pi;
-  void *dl;
-  m_str file;
-  m_str name;
+  Map map;
+  size_t len;
 };
 
-ANN static struct Plug_* new_plug(MemPool p, const modini ini) {
+typedef struct Plug_ {
+  void *dl;
+  void *self;
+  int imp;
+} *Plug;
+
+ANN static struct Plug_* new_plug(MemPool p, void *dl) {
   struct Plug_ *plug = mp_calloc(p, Plug);
-  plug->ini  = ini;
+  plug->dl  = dl;
   return plug;
 }
 
-ANN static void plug_import(struct PlugHandle *h) {
-  const import imp = DLSYM(h->dl, import, GWIMPORT_NAME);
-  if(imp)
-    vector_add(&h->pi->vec[GWPLUG_IMPORT], (vtype)imp);
-}
-
-ANN static void plug_module(struct PlugHandle *h) {
-  const modini ini = DLSYM(h->dl, modini, GWMODINI_NAME);
-  if(ini) {
-    struct Plug_ *plug = new_plug(h->mp, ini);
-    plug->name = h->name;
-    plug->end  = DLSYM(h->dl, modend, GWMODEND_NAME);
-    vector_add(&h->pi->vec[GWPLUG_MODULE], (vtype)plug);
-  }
-}
-
-ANN static void plug_driver(struct PlugHandle *h) {
-  const f_bbqset drv = DLSYM(h->dl, f_bbqset, GWDRIVER_NAME);
-  if(drv)
-    map_set(&h->pi->drv, (vtype)h->name, (vtype)drv);
-}
-
-ANN static inline m_str plug_name(struct PlugHandle *h) {
-  const modstr str = DLSYM(h->dl, modstr, GWMODSTR_NAME);
-  return str ? str() : NULL;
-}
-
 ANN static void plug_get(struct PlugHandle *h, const m_str c) {
-  h->dl = DLOPEN(c, RTLD_LAZY | RTLD_GLOBAL);
-  if(h->dl) {
-    vector_add(&h->pi->vec[GWPLUG_DL], (vtype)h->dl);
-    h->name = plug_name(h);
-    plug_import(h);
-    plug_module(h);
-    plug_driver(h);
+  void *dl = DLOPEN(c, RTLD_LAZY | RTLD_GLOBAL);
+  const m_str pname = c + h->len + 1;
+  const size_t sz = strlen(pname) - 3;
+  char name[PATH_MAX];
+  memcpy(name, pname, sz);
+  name[sz] = '\0';
+  if(dl) {
+    Plug plug = new_plug(h->mp, dl);
+    map_set(h->map, (vtype)strdup(name), (vtype)plug);
   } else
     gw_err(_("error in %s."), DLERROR());
 }
@@ -113,99 +87,140 @@ ANN static void plug_get_all(struct PlugHandle *h, const m_str name) {
     strcpy(c, name);
     strcpy(c + strlen(name) - 4, filedata.cFileName);
     plug_get(h, c);
-  } while(FindNextFile(file,&filedata));
+  } while(FindNextFile(file, &filedata));
   FindClose(file);
 #endif
 }
 
-ANN2(1) static void* pp_ini(const struct Gwion_ *gwion, const Vector v) {
-  pparg_run(gwion->ppa, v);
-  return NULL;
-}
-
-ANN static void register_pp(const struct PlugHandle* h) {
-  struct Plug_ *plug = new_plug(h->mp, pp_ini);
-  plug->name = "pp";
-  vector_add(&h->pi->vec[GWPLUG_MODULE], (vtype)plug);
-}
-
-ANN PlugInfo* new_pluginfo(MemPool p, const Vector list) {
-  PlugInfo *pi = (PlugInfo*)mp_calloc(p, PlugInfo);
-  for(m_uint i = 0; i < GWPLUG_LAST; ++i)
-    vector_init(&pi->vec[i]);
-  map_init(&pi->drv);
-  struct PlugHandle h = { .mp=p, .pi=pi };
-  register_pp(&h);
+ANN m_bool plug_ini(const struct Gwion_ *gwion, const Vector list) {
+  const Map map = &gwion->data->plug;
+  map_init(map);
+  struct PlugHandle h = { .mp=gwion->mp, .map=map };
   for(m_uint i = 0; i < vector_size(list); i++) {
     const m_str dir = (m_str)vector_at(list, i);
-    char name[strlen(dir) + 6];
+    h.len = strlen(dir);
+    char name[PATH_MAX];
     sprintf(name, "%s/*.so", dir);
     plug_get_all(&h, name);
   }
-  return pi;
+  return GW_OK;
 }
 
-ANN static void plug_free_module(const struct Gwion_* gwion, const Vector v) {
-  for(m_uint i = 0; i < vector_size(v); ++i) {
-    struct Plug_ *plug = (struct Plug_*)vector_at(v, i);
-    if(plug->end)
-      plug->end(gwion, plug->self);
-    mp_free(gwion->mp, Plug, plug);
+void free_plug(const struct Gwion_ *gwion) {
+  const Map map = &gwion->data->plug;
+  for(m_uint i = 0; i < map_size(map); ++i) {
+    const Plug plug = (Plug)VVAL(map, i);
+    const modend end = DLSYM(plug->dl, modend, GWMODEND_NAME);
+    if(end)
+      end(gwion, plug->self);
+    free((m_str)VKEY(map, i));
+    DLCLOSE(plug->dl);
   }
+  map_release(map);
 }
 
-ANN static inline void plug_free_dls(const Vector v) {
+ANN static void plug_free_arg(MemPool p, const Vector v) {
   for(m_uint i = 0; i < vector_size(v); ++i)
-    DLCLOSE((void*)vector_at(v, i));
-}
-
-void free_plug(const struct Gwion_ *gwion) {
-  PlugInfo *p = gwion->data->plug;
-  struct Vector_ * const v = p->vec;
-  plug_free_module(gwion, &v[GWPLUG_MODULE]);
-  plug_free_dls(&v[GWPLUG_DL]);
-  for(m_uint i = 0; i < GWPLUG_LAST; ++i)
-    vector_release(&v[i]);
-  map_release(&p->drv);
-  mp_free(gwion->mp, PlugInfo, p);
+    free_mstr(p, (m_str)vector_at(v, i));
+  free_vector(p, v);
 }
 
-ANN static Vector get_arg(MemPool p, const m_str name, const Vector v) {
-  const size_t len = strlen(name);
-  for(m_uint i = vector_size(v) + 1; --i;) {
-    const m_str str = (m_str)vector_at(v, i - 1);
-    if(!strncmp(name, str, len)) {
-      vector_rem(v, i-1);
-      const m_str arg = strchr(str, '=');
-      return arg ? split_args(p, arg+1) : NULL;
+ANN void set_module(const struct Gwion_ *gwion, const m_str name, void *const ptr) {
+  const Map map = &gwion->data->plug;
+  for(m_uint j = 0; j < map_size(map); ++j) {
+    if(!strcmp(name, (m_str)VKEY(map, j))) {
+      Plug plug = (Plug)VVAL(map, j);
+      plug->self = ptr;
+      return;
     }
   }
-  return NULL;
 }
 
-ANN static void plug_free_arg(MemPool p, const Vector v) {
-  for(m_uint i = 0; i < vector_size(v); ++i)
-    free_mstr(p, (m_str)vector_at(v, i));
-  free_vector(p, v);
+ANN void plug_run(const struct Gwion_ *gwion, const Map mod) {
+  const Map map = &gwion->data->plug;
+  for(m_uint i = 0; i < map_size(mod); ++i) {
+    const m_str name = (m_str)VKEY(mod, i);
+    const m_str opt = (m_str)VVAL(mod, i);
+    for(m_uint j = 0; j < map_size(map); ++j) {
+      if(!strcmp(name, (m_str)VKEY(map, j))) {
+        Plug plug = (Plug)VVAL(map, j);
+        const Vector arg = opt ? split_args(gwion->mp, opt) : NULL;
+        const modini ini = DLSYM(plug->dl, modini, GWMODINI_NAME);
+        plug->self = ini(gwion, arg);
+        if(arg)
+          plug_free_arg(gwion->mp, arg);
+      }
+    }
+  }
 }
 
-ANN void plug_run(const struct Gwion_ *gwion, const Vector args) {
-  const Vector v = &gwion->data->plug->vec[GWPLUG_MODULE];
-  for(m_uint i = 0; i < vector_size(v); ++i) {
-    struct Plug_ *plug = (struct Plug_*)vector_at(v, i);
-    const Vector arg = get_arg(gwion->mp, plug->name, args);
-    plug->self = plug->ini(gwion, arg);
-    if(arg)
-      plug_free_arg(gwion->mp, arg);
+ANN static m_bool dependencies(struct Gwion_ *gwion, const Plug plug) {
+  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))
+      ++deps;
+    }
   }
+  return GW_OK;
+}
+
+ANN m_bool plugin_ini(struct Gwion_ *gwion, const m_str iname) {
+  const Map map = &gwion->data->plug;
+  for(m_uint i = 0; i < map_size(map); ++i) {
+    const Plug plug = (Plug)VVAL(map, i);
+    const m_str name = (m_str)VKEY(map, i);
+    if(!strcmp(name, iname)) {
+      if(plug->imp)
+        return GW_OK;
+      const plugin imp = DLSYM(plug->dl, plugin, GWIMPORT_NAME);
+      if(!imp)
+        break;
+      plug->imp = 1;
+      CHECK_BB(dependencies(gwion, plug))
+      const m_uint scope = env_push_global(gwion->env);
+      const m_bool ret = gwi_run(gwion, imp);
+      env_pop(gwion->env, scope);
+      return ret;
+    }
+  }
+  gw_err("no such plugin '%s'\n", iname);
+  return GW_ERROR;
+}
+
+ANN m_bool driver_ini(const struct Gwion_ *gwion) {
+  const Map map = &gwion->data->plug;
+  m_str dname = gwion->vm->bbq->si->arg;
+  m_str opt = strchr(dname, '=');
+  const char c = opt ? *opt : '\0';
+  if(opt)
+    *opt = '\0';
+  for(m_uint i = 0; i < map_size(map); ++i) {
+    const m_str name = (m_str)VKEY(map, i);
+    if(!strcmp(name, dname)) {
+      const Plug plug = (Plug)VVAL(map, i);
+      const f_bbqset drv = DLSYM(plug->dl, f_bbqset, GWDRIVER_NAME);
+      if(!drv)
+        break;
+      gwion->vm->bbq->func = drv;
+      if(opt)
+        *opt = c;
+      return GW_OK;
+    }
+  }
+  gw_err("can't find driver '%s'\n", dname);
+  return GW_ERROR;
 }
 
 ANN void* get_module(const struct Gwion_ *gwion, const m_str name) {
-  const Vector v = &gwion->data->plug->vec[GWPLUG_MODULE];
-  for(m_uint i = 0; i < vector_size(v); ++i) {
-    struct Plug_ *plug = (struct Plug_*)vector_at(v, i);
-    if(!strcmp(name, plug->name))
+  const Map map = &gwion->data->plug;
+  for(m_uint i = 0; i < map_size(map); ++i) {
+    if(!strcmp(name, (m_str)VKEY(map, i))) {
+      const Plug plug = (Plug)VVAL(map, i);
       return plug->self;
+    }
   }
   return NULL;
 }
index 203dbee3e4a5eec719355d09976ba1f1a38874f0..d6f0885312bd0b34851bfea2701a82e875125aac 100644 (file)
@@ -59,13 +59,13 @@ ANN static void prepare_call(const VM_Shred shred, const m_uint offset) {
 ANN void gack(const VM_Shred shred, const m_uint offset) {
   const Type t = *(Type*)shred->reg;
   const VM_Code code = get_gack(t)->e->gack;
-  if(GET_FLAG(code, builtin)) {
+  if(code->builtin) {
     const m_uint sz = *(m_uint*)(shred->reg + SZ_INT);
     ((f_gack)code->native_func)(t, (shred->reg - sz), shred);
     POP_REG(shred, sz);
   } else {
     prepare_call(shred, offset);
-    if(GET_FLAG(t, struct))
+    if(tflag(t, tflag_struct))
       *(void**)(shred->mem) = (void*)(shred->reg - t->size);
     else
       *(M_Object*)(shred->mem) = *(M_Object*)(shred->reg - SZ_INT);
index 3027e6ec539e5120489cd8d23cdcfb553b4c2777..4d3432322746db3236e9eef9cf6f7cf20445b99c 100644 (file)
@@ -612,7 +612,7 @@ setcode:
 PRAGMA_PUSH()
   reg -= SZ_INT;
   a.code = *(VM_Code*)reg;
-  if(!GET_FLAG((VM_Code)a.code, builtin)) {
+  if(!a.code->builtin) {
     register const m_uint push = *(m_uint*)(reg + SZ_INT) + *(m_uint*)(mem-SZ_INT);
     mem += push;
     *(m_uint*)  mem = push;mem += SZ_INT;
index f376fe6525621fcd41d5fceb7b48675f78cdf3b4..3851a5b05c6dc10cba497c77552e6e72b792b08a 100644 (file)
@@ -26,10 +26,10 @@ ANN static void _free_code_instr(const Vector v, const Gwion gwion) {
   free_vector(gwion->mp, v);
 }
 
-ANN static void free_vm_code(VM_Code a, Gwion gwion) {
+ANN void free_vm_code(VM_Code a, Gwion gwion) {
   if(a->memoize)
     memoize_end(gwion->mp, a->memoize);
-  if(!GET_FLAG(a, builtin)) {
+  if(!a->builtin) {
     _mp_free(gwion->mp, vector_size(a->instr) * SZ_INT, a->bytecode);
     _free_code_instr(a->instr, gwion);
   }
@@ -58,7 +58,7 @@ ANN static m_bit* tobytecode(MemPool p, const VM_Code code) {
 
 
 VM_Code new_vm_code(MemPool p, const Vector instr, const m_uint stack_depth,
-    const ae_flag flag, const m_str name) {
+    const int builtin, const m_str name) {
   VM_Code code           = mp_calloc(p, VM_Code);
   if(instr) {
     code->instr            = vector_copy(p, instr);
@@ -66,8 +66,8 @@ VM_Code new_vm_code(MemPool p, const Vector instr, const m_uint stack_depth,
   }
   code->name             = mstrdup(p, name);
   code->stack_depth      = stack_depth;
-  code->flag = flag;
-  code->ref = new_refcount(p, free_vm_code);
+  code->builtin = builtin;
+  code->ref = 1;
   return code;
 }
 
index eca7b796684182a8aeadc011151c6517996bac23..52795e6cfdfb4ddd6016e77931384f78d915fd19 100644 (file)
@@ -45,7 +45,7 @@ void free_vm_shred(VM_Shred shred) {
   for(m_uint i = vector_size(&shred->gc) + 1; --i;)
     release((M_Object)vector_at(&shred->gc, i - 1), shred);
   vector_release(&shred->gc);
-  REM_REF(shred->info->orig, shred->info->vm->gwion);
+  vmcode_remref(shred->info->orig, shred->info->vm->gwion);
   const MemPool mp = shred->info->mp;
   mp_free(mp, ShredTick, shred->tick);
   free_shredinfo(mp, shred->info);
similarity index 100%
rename from tests/import/Makefile
rename to tests/driver/Makefile
diff --git a/tests/driver/non_driver.c b/tests/driver/non_driver.c
new file mode 100644 (file)
index 0000000..2c020b3
--- /dev/null
@@ -0,0 +1,14 @@
+#include "gwion_util.h"
+#include "gwion_ast.h"
+#include "gwion_env.h"
+#include "vm.h"
+#include "gwion.h"
+#include "operator.h"
+#include "object.h"
+#include "instr.h"
+#include "import.h"
+
+GWION_IMPORT(end_class) {
+  (void)gwi;
+  return GW_OK;
+}
similarity index 53%
rename from tests/import/driver.c
rename to tests/driver/simple_driver.c
index 7f1628e55d13150b9ceb8e50e0a9b00b7205b489..22c2bccfdb7cd633c3a6a2f0753d7cd16774d757 100644 (file)
@@ -8,23 +8,21 @@
 #include "gwion.h"
 #include "plug.h"
 
-static DRVRUN(driver_test_run) {
+static DRVRUN(simple_driver_run) {
   while(di->is_running) {
     di->run(vm);
     ++di->pos;
   }
 }
 
-static DRVINI(driver_test_ini) {
+static DRVINI(simple_driver_ini) {
   return GW_OK;
 }
 
-static DRVDEL(driver_test_del) {}
+static DRVDEL(simple_driver_del) {}
 
-GWMODSTR(driver_test);
-
-GWDRIVER(driver_test) {
-  d->ini = driver_test_ini;
-  d->run = driver_test_run;
-  d->del = driver_test_del;
+GWDRIVER(driver) {
+  d->ini = simple_driver_ini;
+  d->run = simple_driver_run;
+  d->del = simple_driver_del;
 }
diff --git a/tests/error/final_func.gw b/tests/error/final_func.gw
new file mode 100644 (file)
index 0000000..581632f
--- /dev/null
@@ -0,0 +1,9 @@
+#! [contains] override final
+class C {
+  fun final void test() { <<< "final" >>>;}
+}
+
+class D extends C {
+  fun void test() { <<< "final" >>>;}
+}
+var D d;
diff --git a/tests/error/final_inherit.gw b/tests/error/final_inherit.gw
new file mode 100644 (file)
index 0000000..f021b02
--- /dev/null
@@ -0,0 +1,4 @@
+#! [contains] inherit from final parent
+class final C {}
+
+class D extends C {}
diff --git a/tests/error/must_abstract0.gw b/tests/error/must_abstract0.gw
new file mode 100644 (file)
index 0000000..88b7552
--- /dev/null
@@ -0,0 +1,3 @@
+class C {
+  fun abstract void test(int i);
+}
diff --git a/tests/error/must_abstract1.gw b/tests/error/must_abstract1.gw
new file mode 100644 (file)
index 0000000..121854a
--- /dev/null
@@ -0,0 +1,6 @@
+#! [contains] must be declared 'abstract'
+class abstract C {
+  fun abstract void test(int i);
+}
+
+class D extends C {}
diff --git a/tests/error/no_inherit.gw b/tests/error/no_inherit.gw
deleted file mode 100644 (file)
index d37f627..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#! [contains] can't inherit
-class C extends TypedFork:[int] {
-
-}
-
-var C c;
-c.exit();
diff --git a/tests/error/require_fail.gw b/tests/error/require_fail.gw
new file mode 100644 (file)
index 0000000..01646ae
--- /dev/null
@@ -0,0 +1,4 @@
+#require NonExisting
+
+var ftbl f;
+<<< var SinOsc s >>>;
index 9164468b6680758e25cee75908c6cda24c901827..0178f87935bae8f6f4f903caa431347ed9b58b64 100644 (file)
@@ -2,7 +2,7 @@ fun int test() {
   return 12;
 }
 
-fork test() @=> ref TypedFork:[int] sh;
+fork test() @=> ref auto sh;
 <<< typeof(sh) >>>;
 sh.ev => now;
 <<< sh.retval >>>;
diff --git a/tests/import/specialid_emit.gw b/tests/import/specialid_emit.gw
deleted file mode 100644 (file)
index ae20073..0000000
+++ /dev/null
@@ -1 +0,0 @@
-<<< testid >>>;
diff --git a/tests/module/Makefile b/tests/module/Makefile
new file mode 100644 (file)
index 0000000..6327be1
--- /dev/null
@@ -0,0 +1,43 @@
+INC      = -I../../include -I../../util/include -I../../ast/include
+CC       ?= gcc
+
+NAME := ${NAME}
+SRC = ${NAME}.c
+OBJ = $(SRC:.c=.o)
+CFLAGS += -std=c99 ${INC} -Wall -Wextra -g -Og
+
+# os specific
+ifeq ($(shell uname), Darwin)
+LDFLAGS += -bundle -undefined dynamic_lookup
+else
+ifeq ($(shell uname), Linux)
+LDFLAGS += -shared
+else
+LDFLAGS += -shared -lpsapi -fPIC -Wl,--export-all -Wl,--enable-auto-import
+LDFLAGS += -L../../ -lgwion
+LDLAGS += ../../libgwion.dll.a
+LDLAGS += ../../libgwion.a
+endif
+endif
+
+all: ${NAME}.so
+
+
+${NAME}.so: ${OBJ}
+ifeq (${USE_LD}, 1)
+       ${LD} $^ -o ${NAME}.so ${LDFLAGS}
+else
+       ${CC} $^ -o ${NAME}.so ${LDFLAGS}
+endif
+
+clean:
+       rm -f ${OBJ} ${NAME}.so
+
+.c.o:
+       ${CC} -fPIC ${CFLAGS} -c $< -o $(<:.c=.o) -g
+
+install: ${NAME}.so
+       install ${NAME}.so ${GWION_ADD_DIR}
+
+uninstall:
+       rm ${GWION_ADD_DIR}/${NAME}.so
similarity index 93%
rename from tests/import/basic_module.c
rename to tests/module/basic_module.c
index 11a37841593b90c1cebc723433cce84ffe52f050..18d05fce2f98bea5d337562a30c2e1645940f2eb 100644 (file)
@@ -4,8 +4,6 @@
 #include "vm.h"
 #include "gwion.h"
 
-GWMODSTR(basic_module)
-
 GWMODINI(basic_module) {
   puts("ini module");
   if(args) {
similarity index 71%
rename from tests/import/get_module.c
rename to tests/module/get_module.c
index d4d11e622d27ecc819a31cda23c5d7bf5984f10e..3a27ad0538e351d22daf3a1ed3daa341e0a19ee6 100644 (file)
 #include "gwi.h"
 #include "plug.h"
 
-GWMODSTR(dummy_module);
-
-GWMODINI(dummy_module) {
+GWMODINI(get_module) {
   puts(__func__);
-  return (void*)2; // we need to return something
+  return NULL;
 }
-GWMODEND(dummy_module) {
+
+GWMODEND(get_module) {
   puts(__func__);
 }
 
 GWION_IMPORT(dummy_module) {
-  CHECK_OB(get_module(gwi->gwion, "dummy_module"))
+  set_module(gwi->gwion, "get_module", (void*)1);
+  CHECK_OB(get_module(gwi->gwion, "get_module"))
   puts("test passed");
   get_module(gwi->gwion, "non_existant_module");
   return GW_OK;
diff --git a/tests/module/get_module.gw b/tests/module/get_module.gw
new file mode 100644 (file)
index 0000000..ef38782
--- /dev/null
@@ -0,0 +1,2 @@
+#require get_module
+<<< __file__ >>>;
similarity index 92%
rename from tests/import/module.c
rename to tests/module/module.c
index d65ee7542647a377c73576a934011ea29583e7e4..77ead7d7ae8dc74f048881871b3e15648ff4a253 100644 (file)
@@ -8,8 +8,6 @@
 #include "gwion.h"
 #include "plug.h"
 
-GWMODSTR(dummy_module);
-
 GWMODINI(dummy_module) {
   puts(__func__);
   return NULL;
diff --git a/tests/plug/Makefile b/tests/plug/Makefile
new file mode 100644 (file)
index 0000000..6327be1
--- /dev/null
@@ -0,0 +1,43 @@
+INC      = -I../../include -I../../util/include -I../../ast/include
+CC       ?= gcc
+
+NAME := ${NAME}
+SRC = ${NAME}.c
+OBJ = $(SRC:.c=.o)
+CFLAGS += -std=c99 ${INC} -Wall -Wextra -g -Og
+
+# os specific
+ifeq ($(shell uname), Darwin)
+LDFLAGS += -bundle -undefined dynamic_lookup
+else
+ifeq ($(shell uname), Linux)
+LDFLAGS += -shared
+else
+LDFLAGS += -shared -lpsapi -fPIC -Wl,--export-all -Wl,--enable-auto-import
+LDFLAGS += -L../../ -lgwion
+LDLAGS += ../../libgwion.dll.a
+LDLAGS += ../../libgwion.a
+endif
+endif
+
+all: ${NAME}.so
+
+
+${NAME}.so: ${OBJ}
+ifeq (${USE_LD}, 1)
+       ${LD} $^ -o ${NAME}.so ${LDFLAGS}
+else
+       ${CC} $^ -o ${NAME}.so ${LDFLAGS}
+endif
+
+clean:
+       rm -f ${OBJ} ${NAME}.so
+
+.c.o:
+       ${CC} -fPIC ${CFLAGS} -c $< -o $(<:.c=.o) -g
+
+install: ${NAME}.so
+       install ${NAME}.so ${GWION_ADD_DIR}
+
+uninstall:
+       rm ${GWION_ADD_DIR}/${NAME}.so
similarity index 100%
rename from tests/import/array.c
rename to tests/plug/array.c
diff --git a/tests/plug/array.gw b/tests/plug/array.gw
new file mode 100644 (file)
index 0000000..8958ace
--- /dev/null
@@ -0,0 +1,2 @@
+#require array
+<<< __file__ >>>;
diff --git a/tests/plug/array_in_var_name.gw b/tests/plug/array_in_var_name.gw
new file mode 100644 (file)
index 0000000..c6e79b5
--- /dev/null
@@ -0,0 +1,2 @@
+#require array_in_var_name
+<<< __file__ >>>;
diff --git a/tests/plug/array_in_var_name_fail.gw b/tests/plug/array_in_var_name_fail.gw
new file mode 100644 (file)
index 0000000..122ac5f
--- /dev/null
@@ -0,0 +1,2 @@
+#require array_in_var_name_fail
+<<< __file__ >>>;
diff --git a/tests/plug/array_incoherent_in_var_name.gw b/tests/plug/array_incoherent_in_var_name.gw
new file mode 100644 (file)
index 0000000..a7e9493
--- /dev/null
@@ -0,0 +1,2 @@
+#require array_incoherent_in_var_name
+<<< __file__ >>>;
diff --git a/tests/plug/array_invalid_in_var_name.gw b/tests/plug/array_invalid_in_var_name.gw
new file mode 100644 (file)
index 0000000..0d9b749
--- /dev/null
@@ -0,0 +1,2 @@
+#require array_invalid_in_var_name
+<<< __file__ >>>;
diff --git a/tests/plug/callback.gw b/tests/plug/callback.gw
new file mode 100644 (file)
index 0000000..832778b
--- /dev/null
@@ -0,0 +1,2 @@
+#require callback
+<<< __file__ >>>;
similarity index 89%
rename from tests/import/class_template.c
rename to tests/plug/class_template.c
index d7ea42972276a0406a325e74accec5da689186d2..e8124a8a3e3354bc4d99807a325ed2c595310197 100644 (file)
@@ -28,9 +28,9 @@ GWION_IMPORT(class_template) {
   GWI_OB(gwi_class_ini(gwi, ":[A,B]ClassTemplate", NULL))
   gwi_class_xtor(gwi, class_template_ctor, NULL);
     GWI_BB(gwi_item_ini(gwi, "A[]", "key"))
-    GWI_BB((o_map_key = gwi_item_end(gwi, ae_flag_member | ae_flag_template, NULL)))
+    GWI_BB((o_map_key = gwi_item_end(gwi, ae_flag_none, NULL)))
     GWI_BB(gwi_item_ini(gwi, "B[]", "value"))
-    GWI_BB((o_map_value = gwi_item_end(gwi, ae_flag_member, NULL)))
+    GWI_BB((o_map_value = gwi_item_end(gwi, ae_flag_none, NULL)))
    GWI_BB(gwi_func_ini(gwi, "int", ":[C,D]test"))
    GWI_BB(gwi_func_end(gwi, (f_xfun)1, ae_flag_none))
 
similarity index 67%
rename from tests/import/class_template.gw
rename to tests/plug/class_template.gw
index 384326902fc33e3a145aedcad2a515d171ea5cb1..264e0021ee3e91921bcc9359cabc165ec1edcaec 100644 (file)
@@ -1,2 +1,3 @@
+#require class_template
 var ClassTemplate:[int, int] ct;
 <<< ct.key >>>;
diff --git a/tests/plug/class_template_fail.gw b/tests/plug/class_template_fail.gw
new file mode 100644 (file)
index 0000000..c07b0f8
--- /dev/null
@@ -0,0 +1,2 @@
+#require class_template_fail
+<<< __file__ >>>;
similarity index 84%
rename from tests/import/class_template_invalid.c
rename to tests/plug/class_template_invalid.c
index fdd14dea759e658fbe55a665bb0d620709a2215e..0ef547e3899c8a28abe89a32ddd7a875eb009ff1 100644 (file)
@@ -17,9 +17,9 @@ static m_int o_map_value;
 GWION_IMPORT(class_template) {
   GWI_OB(gwi_class_ini(gwi, "ClassTemplate:[A,B]", NULL))
     GWI_BB(gwi_item_ini(gwi, "A[]", "key"))
-    GWI_BB((o_map_key = gwi_item_end(gwi, ae_flag_member | ae_flag_template, NULL)))
+    GWI_BB((o_map_key = gwi_item_end(gwi, ae_flag_none, NULL)))
     GWI_BB(gwi_item_ini(gwi, "B[]", "value"))
-    GWI_BB((o_map_value = gwi_item_end(gwi, ae_flag_member, NULL)))
+    GWI_BB((o_map_value = gwi_item_end(gwi, ae_flag_none, NULL)))
    GWI_BB(gwi_func_ini(gwi, "int", "test:[C,D]"))
    GWI_BB(gwi_func_end(gwi, (f_xfun)1, ae_flag_none))
 
diff --git a/tests/plug/class_template_invalid.gw b/tests/plug/class_template_invalid.gw
new file mode 100644 (file)
index 0000000..55d995a
--- /dev/null
@@ -0,0 +1,2 @@
+#require class_template_invalid
+<<< __file__ >>>;
diff --git a/tests/plug/compile_file.gw b/tests/plug/compile_file.gw
new file mode 100644 (file)
index 0000000..ed03ba6
--- /dev/null
@@ -0,0 +1,2 @@
+#require compile_file
+<<< __file__ >>>;
diff --git a/tests/plug/compile_string.gw b/tests/plug/compile_string.gw
new file mode 100644 (file)
index 0000000..b6ea861
--- /dev/null
@@ -0,0 +1,2 @@
+#require compile_string
+<<< __file__ >>>;
similarity index 88%
rename from tests/import/coverage.gw
rename to tests/plug/coverage.gw
index 99b0ccf1b3089a04fe3f59c601a2205049656fdb..973b043488827bd06913b577c26821e064e43c6a 100644 (file)
@@ -1,3 +1,6 @@
+#require coverage
+#require coverage
+
 <<< var float f >>>;
 var Coverage c;
 c.s_i;
diff --git a/tests/plug/deps.c b/tests/plug/deps.c
new file mode 100644 (file)
index 0000000..7f57c64
--- /dev/null
@@ -0,0 +1,18 @@
+#include "gwion_util.h"
+#include "gwion_ast.h"
+#include "gwion_env.h"
+#include "vm.h"
+#include "object.h"
+#include "instr.h"
+#include "gwion.h"
+#include "operator.h"
+#include "import.h"
+#include "gwi.h"
+
+GWION_IMPORT(deps) {
+  (void)gwi;
+  return GW_OK;
+}
+
+static const m_str deps[] = { "array", NULL };
+GWDEPEND { return deps; }
diff --git a/tests/plug/deps.gw b/tests/plug/deps.gw
new file mode 100644 (file)
index 0000000..eda3576
--- /dev/null
@@ -0,0 +1,3 @@
+#require deps
+
+<<< __file__ >>>;
diff --git a/tests/plug/empty_union.gw b/tests/plug/empty_union.gw
new file mode 100644 (file)
index 0000000..6fb2d2c
--- /dev/null
@@ -0,0 +1,2 @@
+#require empty_union
+<<< __file__ >>>;
diff --git a/tests/plug/end_class.gw b/tests/plug/end_class.gw
new file mode 100644 (file)
index 0000000..ff98b7f
--- /dev/null
@@ -0,0 +1,2 @@
+#require end_class
+<<< __file__ >>>;
similarity index 100%
rename from tests/import/enum.c
rename to tests/plug/enum.c
similarity index 98%
rename from tests/import/enum.gw
rename to tests/plug/enum.gw
index 0d8ddb596797b644e8b687818c5a2d47d98b475e..a2682e7c01f446d9ce318a98257fd04b35db8b45 100644 (file)
@@ -1,3 +1,4 @@
+#require enum
 #! untyped global enum
 <<< ENUM0 >>>;
 <<< ENUM1 >>>;
diff --git a/tests/plug/enum_fail.gw b/tests/plug/enum_fail.gw
new file mode 100644 (file)
index 0000000..8fc0048
--- /dev/null
@@ -0,0 +1,2 @@
+#require enum_fail
+<<< __file__ >>>;
diff --git a/tests/plug/enum_fail2.gw b/tests/plug/enum_fail2.gw
new file mode 100644 (file)
index 0000000..d48ebc5
--- /dev/null
@@ -0,0 +1,2 @@
+#require enum_fail2
+<<< __file__ >>>;
diff --git a/tests/plug/enum_fail3.gw b/tests/plug/enum_fail3.gw
new file mode 100644 (file)
index 0000000..8379ec6
--- /dev/null
@@ -0,0 +1,2 @@
+#require enum_fail3
+<<< __file__ >>>;
similarity index 67%
rename from tests/import/extend_array.gw
rename to tests/plug/extend_array.gw
index d99718ce8a0ff7df29b2df81a60deaf8bea64dd4..67843c25b69c216bb55cf20dfcc541367590d454 100644 (file)
@@ -1,3 +1,4 @@
+#require extend_array
 var ArrayExt a;
 <<< a >>>;
 <<< a.size() >>>;
diff --git a/tests/plug/fail_on_next_arg.gw b/tests/plug/fail_on_next_arg.gw
new file mode 100644 (file)
index 0000000..3bb8dae
--- /dev/null
@@ -0,0 +1,2 @@
+#require fail_on_next_arg
+<<< __file__ >>>;
diff --git a/tests/plug/fail_on_next_arg2.gw b/tests/plug/fail_on_next_arg2.gw
new file mode 100644 (file)
index 0000000..fc189c8
--- /dev/null
@@ -0,0 +1,2 @@
+#require fail_on_next_arg2
+<<< __file__ >>>;
similarity index 100%
rename from tests/import/fptr.c
rename to tests/plug/fptr.c
similarity index 94%
rename from tests/import/fptr.gw
rename to tests/plug/fptr.gw
index 0acefb39c2ee03f12ccfe39a368affee040d630b..a427bc71e964317a1131698d2b45c79813a0b479 100644 (file)
@@ -1,3 +1,4 @@
+#require fptr
 fun void test(){ <<< "test" >>>; }
 var PtrType ptr;
 test();
@@ -10,4 +11,3 @@ FuncTypedef.test_func();
 var FuncTypedef.PtrType _ptr;
 <<< FuncTypedef.ptr >>>;
 FuncTypedef.ptr();
-
diff --git a/tests/plug/fptr_tmpl.gw b/tests/plug/fptr_tmpl.gw
new file mode 100644 (file)
index 0000000..c67df8a
--- /dev/null
@@ -0,0 +1,2 @@
+#require fptr_tmpl
+<<< __file__ >>>;
diff --git a/tests/plug/fptr_tmpl_fail.gw b/tests/plug/fptr_tmpl_fail.gw
new file mode 100644 (file)
index 0000000..24e8571
--- /dev/null
@@ -0,0 +1,2 @@
+#require fptr_tmpl_fail
+<<< __file__ >>>;
diff --git a/tests/plug/func_fail.gw b/tests/plug/func_fail.gw
new file mode 100644 (file)
index 0000000..5edc24f
--- /dev/null
@@ -0,0 +1,2 @@
+#require func_fail
+<<< __file__ >>>;
diff --git a/tests/plug/func_fail2.gw b/tests/plug/func_fail2.gw
new file mode 100644 (file)
index 0000000..c2dc943
--- /dev/null
@@ -0,0 +1,2 @@
+#require func_fail2
+<<< __file__ >>>;
diff --git a/tests/plug/func_fail3.gw b/tests/plug/func_fail3.gw
new file mode 100644 (file)
index 0000000..331e470
--- /dev/null
@@ -0,0 +1,2 @@
+#require func_fail3
+<<< __file__ >>>;
diff --git a/tests/plug/func_fail4.gw b/tests/plug/func_fail4.gw
new file mode 100644 (file)
index 0000000..631c2a1
--- /dev/null
@@ -0,0 +1,2 @@
+#require func_fail4
+<<< __file__ >>>;
diff --git a/tests/plug/func_subscript_not_empty.gw b/tests/plug/func_subscript_not_empty.gw
new file mode 100644 (file)
index 0000000..cfeeab1
--- /dev/null
@@ -0,0 +1,2 @@
+#require func_subscript_not_empty
+<<< __file__ >>>;
similarity index 55%
rename from tests/import/func_tmpl.gw
rename to tests/plug/func_tmpl.gw
index 5916a402c734bfe9cedee4df9a0ee28e4c06b30f..83974670a5362e4e122a1816ad3c63dd108885bb 100644 (file)
@@ -1,2 +1,3 @@
+#require func_tmpl
 test:[int](1);
 test(1);
diff --git a/tests/plug/func_tmpl_fail.gw b/tests/plug/func_tmpl_fail.gw
new file mode 100644 (file)
index 0000000..1979793
--- /dev/null
@@ -0,0 +1,2 @@
+#require func_tmpl_fail
+<<< __file__ >>>;
diff --git a/tests/plug/func_too_many_arg.gw b/tests/plug/func_too_many_arg.gw
new file mode 100644 (file)
index 0000000..b011054
--- /dev/null
@@ -0,0 +1,2 @@
+#require func_too_many_arg
+<<< __file__ >>>;
similarity index 61%
rename from tests/import/global_func.gw
rename to tests/plug/global_func.gw
index c4a561228b6d6ef187c296213fb9ac940336b52d..607031798cc5f5656dcd17ae75d6fd1d6d240552 100644 (file)
@@ -1,3 +1,3 @@
+#require global_func
 <<< test >>>;
 <<< 1 => test >>>;
-
similarity index 73%
rename from tests/import/global_var.gw
rename to tests/plug/global_var.gw
index 3e401b0c3af2f749df96a57e9a972f51c7416bf6..91f4674f056259daa96f7ff10339db421a5a2ba1 100644 (file)
@@ -1,3 +1,4 @@
+#require global_var
 <<< i >>>;
 <<< "other test" => i >>>;
 <<< 12 => f >>>;
diff --git a/tests/plug/invalid_arg.gw b/tests/plug/invalid_arg.gw
new file mode 100644 (file)
index 0000000..9223e11
--- /dev/null
@@ -0,0 +1,2 @@
+#require invalid_arg
+<<< __file__ >>>;
diff --git a/tests/plug/invalid_array.gw b/tests/plug/invalid_array.gw
new file mode 100644 (file)
index 0000000..0fd80fb
--- /dev/null
@@ -0,0 +1,2 @@
+#require invalid_array
+<<< __file__ >>>;
diff --git a/tests/plug/invalid_func.gw b/tests/plug/invalid_func.gw
new file mode 100644 (file)
index 0000000..2fc7ae7
--- /dev/null
@@ -0,0 +1,2 @@
+#require invalid_func
+<<< __file__ >>>;
diff --git a/tests/plug/invalid_names.gw b/tests/plug/invalid_names.gw
new file mode 100644 (file)
index 0000000..6bc7172
--- /dev/null
@@ -0,0 +1,2 @@
+#require invalid_names
+<<< __file__ >>>;
diff --git a/tests/plug/invalid_names0.gw b/tests/plug/invalid_names0.gw
new file mode 100644 (file)
index 0000000..76e1027
--- /dev/null
@@ -0,0 +1,2 @@
+#require invalid_names0
+<<< __file__ >>>;
diff --git a/tests/plug/invalid_names1.gw b/tests/plug/invalid_names1.gw
new file mode 100644 (file)
index 0000000..b2dc86c
--- /dev/null
@@ -0,0 +1,2 @@
+#require invalid_names1
+<<< __file__ >>>;
diff --git a/tests/plug/invalid_names2.gw b/tests/plug/invalid_names2.gw
new file mode 100644 (file)
index 0000000..6be95ab
--- /dev/null
@@ -0,0 +1,2 @@
+#require invalid_names2
+<<< __file__ >>>;
diff --git a/tests/plug/invalid_names3.gw b/tests/plug/invalid_names3.gw
new file mode 100644 (file)
index 0000000..234a3b4
--- /dev/null
@@ -0,0 +1,2 @@
+#require invalid_names3
+<<< __file__ >>>;
diff --git a/tests/plug/invalid_type1.gw b/tests/plug/invalid_type1.gw
new file mode 100644 (file)
index 0000000..0e7cd1f
--- /dev/null
@@ -0,0 +1,2 @@
+#require invalid_type1
+<<< __file__ >>>;
diff --git a/tests/plug/invalid_type2.gw b/tests/plug/invalid_type2.gw
new file mode 100644 (file)
index 0000000..62325e5
--- /dev/null
@@ -0,0 +1,2 @@
+#require invalid_type2
+<<< __file__ >>>;
diff --git a/tests/plug/invalid_type3.gw b/tests/plug/invalid_type3.gw
new file mode 100644 (file)
index 0000000..d7413bb
--- /dev/null
@@ -0,0 +1,2 @@
+#require invalid_type3
+<<< __file__ >>>;
similarity index 100%
rename from tests/import/map2.gw
rename to tests/plug/map2.gw
diff --git a/tests/plug/mk_type_array.gw b/tests/plug/mk_type_array.gw
new file mode 100644 (file)
index 0000000..28fda93
--- /dev/null
@@ -0,0 +1,2 @@
+#require mk_type_array
+<<< __file__ >>>;
diff --git a/tests/plug/no_import.gw b/tests/plug/no_import.gw
new file mode 100644 (file)
index 0000000..dd07581
--- /dev/null
@@ -0,0 +1,2 @@
+#require no_import
+<<< __file__ >>>;
diff --git a/tests/plug/not_importing.gw b/tests/plug/not_importing.gw
new file mode 100644 (file)
index 0000000..933e07b
--- /dev/null
@@ -0,0 +1,2 @@
+#require not_importing
+<<< __file__ >>>;
similarity index 99%
rename from tests/import/op_already_imported.c
rename to tests/plug/op_already_imported.c
index 0454a3f1ad40917de42b1c6bb3534a14f0860f38..4a527ec757a5f8d9dc8499db0469e328292141c4 100644 (file)
@@ -11,7 +11,6 @@
 #include "import.h"
 #include "gwi.h"
 
-
 GWION_IMPORT(op_already_imported) {
   GWI_BB(gwi_oper_ini(gwi, "int", "int", "int"))
   GWI_BB(gwi_oper_end(gwi, "=>", NULL))
similarity index 59%
rename from tests/import/op_already_imported.gw
rename to tests/plug/op_already_imported.gw
index 2bfc227d69c812ae23ed37a96028cbb925d3845f..9cd444064d431c894698202224fe1cf67835dc83 100644 (file)
@@ -1,2 +1,3 @@
+#require op_already_imported
 #! [contains] already imported
 <<< 1 >>>;
similarity index 100%
rename from tests/import/pass.c
rename to tests/plug/pass.c
diff --git a/tests/plug/pass.gw b/tests/plug/pass.gw
new file mode 100644 (file)
index 0000000..233e1f2
--- /dev/null
@@ -0,0 +1,2 @@
+#require pass
+<<< __file__ >>>;
similarity index 100%
rename from tests/import/rm_me.gw
rename to tests/plug/rm_me.gw
diff --git a/tests/plug/specialid_emit.gw b/tests/plug/specialid_emit.gw
new file mode 100644 (file)
index 0000000..0eec0eb
--- /dev/null
@@ -0,0 +1,2 @@
+#require specialid_emit
+<<< testid >>>;
similarity index 65%
rename from tests/import/static_string.gw
rename to tests/plug/static_string.gw
index dc3f911a511e3bccf500d338e930d16079c82853..f94a3bd50fe775d83d6f0e6b340b7d106fde76e7 100644 (file)
@@ -1,2 +1,3 @@
+#require static_string
 #!<<< StaticString.self >>>;
 <<< self >>>;
diff --git a/tests/plug/str2decl.gw b/tests/plug/str2decl.gw
new file mode 100644 (file)
index 0000000..9532ca7
--- /dev/null
@@ -0,0 +1,2 @@
+#require str2decl
+<<< __file__ >>>;
diff --git a/tests/plug/str2list_fail.gw b/tests/plug/str2list_fail.gw
new file mode 100644 (file)
index 0000000..57d8127
--- /dev/null
@@ -0,0 +1,2 @@
+#require str2list_fail
+<<< __file__ >>>;
diff --git a/tests/plug/struct.c b/tests/plug/struct.c
new file mode 100644 (file)
index 0000000..0f95038
--- /dev/null
@@ -0,0 +1,43 @@
+#include "gwion_util.h"
+#include "gwion_ast.h"
+#include "gwion_env.h"
+#include "vm.h"
+#include "object.h"
+#include "instr.h"
+#include "gwion.h"
+#include "operator.h"
+#include "import.h"
+#include "gwi.h"
+
+SFUN(coverage_int)     { *(m_uint*)RETURN    = 0; }
+SFUN(coverage_float)   { *(m_float*)RETURN   = 0; }
+
+GWION_IMPORT(coverage) {
+  GWI_OB(gwi_struct_ini(gwi, "Struct"))
+  GWI_BB(gwi_func_ini(gwi, "int", "i"))
+  GWI_BB(gwi_func_end(gwi, coverage_int, ae_flag_static))
+  GWI_BB(gwi_func_ini(gwi, "float", "f"))
+  GWI_BB(gwi_func_end(gwi, coverage_float, ae_flag_static))
+
+  ALLOC_PTR(gwi->gwion->mp, i, m_uint, 5);
+  GWI_BB(gwi_item_ini(gwi,"int", "s_i"))
+  GWI_BB(gwi_item_end(gwi, ae_flag_static, i))
+
+  ALLOC_PTR(gwi->gwion->mp, f, m_float, 2.1);
+  GWI_BB(gwi_item_ini(gwi,"int", "s_f"))
+  GWI_BB(gwi_item_end(gwi, ae_flag_static, (void*)f))
+
+  ALLOC_PTR(gwi->gwion->mp, ci, m_uint, 5);
+  GWI_BB(gwi_item_ini(gwi,"int", "sc_i"))
+  GWI_BB(gwi_item_end(gwi, ae_flag_static | ae_flag_const, ci))
+
+  ALLOC_PTR(gwi->gwion->mp, cf, m_float, 2.1);
+  GWI_BB(gwi_item_ini(gwi,"float", "sc_f"))
+  GWI_BB(gwi_item_end(gwi, ae_flag_static | ae_flag_const, (void*)cf))
+
+  GWI_BB(gwi_item_ini(gwi,"int[][]", "test_array"))
+  GWI_BB(gwi_item_end(gwi, ae_flag_none, NULL))
+
+  GWI_BB(gwi_struct_end(gwi))
+  return GW_OK;
+}
diff --git a/tests/plug/struct.gw b/tests/plug/struct.gw
new file mode 100644 (file)
index 0000000..d3ecf58
--- /dev/null
@@ -0,0 +1,18 @@
+#require struct
+
+<<< var float f >>>;
+var Struct c;
+c.s_i;
+<<<  Coverage.i()  >>>;
+<<<  Coverage.f()  >>>;
+
+<<< Coverage.s_i  >>>;
+<<< Coverage.s_f  >>>;
+
+<<< Coverage.sc_i  >>>;
+<<< Coverage.sc_f  >>>;
+
+<<<  1 => Coverage.s_i  >>>;
+<<<  1.2 => Coverage.s_f  >>>;
+
+<<< c.test_array[0][0] >>>;
diff --git a/tests/plug/template_arg.gw b/tests/plug/template_arg.gw
new file mode 100644 (file)
index 0000000..b65012f
--- /dev/null
@@ -0,0 +1,2 @@
+#require template_arg
+<<< __file__ >>>;
similarity index 100%
rename from tests/import/trig.c
rename to tests/plug/trig.c
similarity index 89%
rename from tests/import/trig.gw
rename to tests/plug/trig.gw
index cbc5f36ee81a9b5faf1dbe41ab9c84314e847fc1..849d12aae3b4c1ea60d0d4f591c3b2a81e086baa 100644 (file)
@@ -1,3 +1,4 @@
+#require trig
 var Trig trig => dac;
 adc :=> trig;
 adc :=< trig;
similarity index 100%
rename from tests/import/typedef.c
rename to tests/plug/typedef.c
similarity index 81%
rename from tests/import/typedef.gw
rename to tests/plug/typedef.gw
index ea3d603e49c92afd93d0c109efa092af6a3a2824..8a3ec9b26eef4c90b9b9a10587af8e5fea857f44 100644 (file)
@@ -1,3 +1,4 @@
+#require typedef
 var Typedef t;
 #!fun int test(int i) { <<< i >>>; }
 #!test @=> t;
diff --git a/tests/plug/typedef_fail.gw b/tests/plug/typedef_fail.gw
new file mode 100644 (file)
index 0000000..c1b0f5e
--- /dev/null
@@ -0,0 +1,2 @@
+#require typedef_fail
+<<< __file__ >>>;
diff --git a/tests/plug/typedef_tmpl.gw b/tests/plug/typedef_tmpl.gw
new file mode 100644 (file)
index 0000000..c98fc08
--- /dev/null
@@ -0,0 +1,2 @@
+#require typedef_tmpl
+<<< __file__ >>>;
diff --git a/tests/plug/ugen_connect.gw b/tests/plug/ugen_connect.gw
new file mode 100644 (file)
index 0000000..cf2a999
--- /dev/null
@@ -0,0 +1,2 @@
+#require ugen_connect
+<<< __file__ >>>;
similarity index 100%
rename from tests/import/union.c
rename to tests/plug/union.c
similarity index 89%
rename from tests/import/union.gw
rename to tests/plug/union.gw
index d32885dec09ee45a65f92eeccc6158b2b200f7c0..591ef1cf493289785688478c2179716d9ddbcc66 100644 (file)
@@ -1,3 +1,4 @@
+#require union
 var Union u;
 <<< u.i >>>;
 <<< 12 => u.f >>>;
diff --git a/tests/plug/union_fail_exp.gw b/tests/plug/union_fail_exp.gw
new file mode 100644 (file)
index 0000000..27d1a69
--- /dev/null
@@ -0,0 +1,2 @@
+#require union_fail_exp
+<<< __file__ >>>;
diff --git a/tests/plug/union_member.gw b/tests/plug/union_member.gw
new file mode 100644 (file)
index 0000000..a743ff4
--- /dev/null
@@ -0,0 +1,2 @@
+#require union_member
+<<< __file__ >>>;
similarity index 64%
rename from tests/import/union_name.gw
rename to tests/plug/union_name.gw
index c5ad1d057a0bb7af5eb80e9b742bc4e3561bcf53..38216c55453331253e79211611249da42f3e1e8e 100644 (file)
@@ -1,2 +1,3 @@
+#require union_name
 <<< my_union >>>;
 <<<my_union.i>>>;
similarity index 64%
rename from tests/import/union_tmpl.gw
rename to tests/plug/union_tmpl.gw
index 5d6c0c60103d037d1c76bae23107e4fddd38dcc4..a7ac5d4dc30b26bcb0854fc4b39c306af7a4ea2a 100644 (file)
@@ -1,2 +1,3 @@
+#require union_tmpl
 <<< var U:[Event] u>>>;
 <<< u.a >>>;
diff --git a/tests/plug/union_tmpl_fail.gw b/tests/plug/union_tmpl_fail.gw
new file mode 100644 (file)
index 0000000..c70c688
--- /dev/null
@@ -0,0 +1,2 @@
+#require union_tmpl_fail
+<<< __file__ >>>;
diff --git a/tests/plug/union_tmpl_fail2.gw b/tests/plug/union_tmpl_fail2.gw
new file mode 100644 (file)
index 0000000..06566c7
--- /dev/null
@@ -0,0 +1,2 @@
+#require union_tmpl_fail2
+<<< __file__ >>>;
diff --git a/tests/plug/union_tmpl_fail3.gw b/tests/plug/union_tmpl_fail3.gw
new file mode 100644 (file)
index 0000000..b888fa1
--- /dev/null
@@ -0,0 +1,2 @@
+#require union_tmpl_fail3
+<<< __file__ >>>;
similarity index 91%
rename from tests/import/variadic.c
rename to tests/plug/variadic.c
index 4d398a6520a5a08897f60e6d715289a80506b119..a34b3e2f7ac0d4064f6e87508542ced42b3d3098 100644 (file)
@@ -42,7 +42,8 @@ GWION_IMPORT(variadic test) {
   GWI_OB(gwi_class_ini(gwi, "Variadic", NULL))
   GWI_BB(gwi_func_ini(gwi, "void", "member"))
   GWI_BB(gwi_func_arg(gwi, "string", "format"))
-  GWI_BB(gwi_func_end(gwi, m_variadic, ae_flag_variadic))
+  GWI_BB(gwi_func_arg(gwi, "does not matter", "..."))
+  GWI_BB(gwi_func_end(gwi, m_variadic, ae_flag_none))
   GWI_BB(gwi_func_ini(gwi, "void", "test"))
   GWI_BB(gwi_func_end(gwi, m_test, ae_flag_none))
   GWI_BB(gwi_class_end(gwi))
similarity index 94%
rename from tests/import/variadic.gw
rename to tests/plug/variadic.gw
index 3213c303cfdb70ed10c56d598768a30640f3fff8..48f8b5758200c06a95a33cf42bae6daf699034b0 100644 (file)
@@ -1,3 +1,4 @@
+#require variadic
 <<< "test builtin variadic fun" >>>;
 var Variadic v;
 "iiii" => var string format;
similarity index 50%
rename from tests/import/vm_remove.gw
rename to tests/plug/vm_remove.gw
index 31429431ad344e5f86b4d94c60ec606391d614c0..85078c1a15c6b3a4d7c8aedb69427de28d4a7553 100644 (file)
@@ -1,2 +1,3 @@
+#require vm_remove
 test(12);
 test(1);
index 3687b21cdb48db473a84eb135d6e74417f8973f7..93aacb3f09aaedab4193c9d2ef18e136aeca3cf2 100644 (file)
@@ -1,5 +1,5 @@
 #!/bin/bash
-# [test] #77
+# [test] #79
 
 n=0
 [ "$1" ] && n="$1"
@@ -12,13 +12,13 @@ source tests/sh/test.sh
 export GWION_ADD_DIR
 
 test_plugin() {
-       export NAME=$"$1"
-       export PRG=$"../../gwion"
-       export SUPP=$"../../scripts/supp"
+       export NAME="$1"
+       export PRG="../../gwion"
+       export SUPP="../../scripts/supp"
        make
   if [ -f "$NAME.gw" ]
-  then  GWOPT+=-p. test_gw "$NAME.gw" "$n"
-  else  GWOPT+=-p. test_gw "no_file" "$n"
+  then  GWOPT+="-p." test_gw "$NAME.gw" "$n"
+  else  GWOPT+="-p." test_gw "no_file" "$n"
   fi
   make clean
        N=$(printf "% 4i" "$n")
@@ -36,13 +36,31 @@ rm "empty.so"
 
 
 BASE_DIR="$PWD"
-cd tests/import || exit
+pushd tests/plug || exit
 for test_file in *.c
 do test_plugin "$(basename "$test_file" .c)"
 done
+PRG="../../gwion" make NAME="array"
+test_plugin "deps" "$n"
+make NAME="array" clean
+popd
 
-DRIVER="driver_test:arg" test_plugin driver
-MODULE="dummy_module=with,some,argument" test_plugin module
+
+pushd tests/driver || exit
+for test_file in *.c
+do
+ NAME="$(basename "$test_file" .c)"
+ DRIVER="$NAME=some_arg" test_plugin "$(basename "$test_file" .c)"
+done
+popd || exit
+
+pushd tests/module || exit
+for test_file in *.c
+do
+ NAME="$(basename "$test_file" .c)"
+ MODULE="$NAME=some_arg" test_plugin "$NAME"
+done
+popd || exit
 
 # clean
 rm -f ./*.gcda ./*.gcno vgcore.* ./*.o ./*.so
index 796fc58e372e65ea5e3ce737267233c7e57e32a0..4cf3e21dca5428d7002aa94f7e1b2dfe6bc6fcc3 100644 (file)
@@ -1,5 +1,5 @@
 #!/bin/bash
-# [test] #20
+# [test] #21
 
 n=0
 [ "$1" ] && n="$1"
@@ -50,12 +50,12 @@ run "$n" "arg is a directory" "-p src" "file"
 
 # config
 n=$((n+1))
-RC=tmp_gwionrc
-cat << EOF >> "$RC"
+RC=./tmp_gwionrc
+cat << EOF > "$RC"
 -p.
 -l0
 EOF
-run "$n" "config" "-c $RC" "file"
+run "$n" "config" "-c$RC" "file"
 rm "$RC"
 
 # loop
@@ -78,6 +78,10 @@ run "$n" "no pass" "-g nopass" "file"
 n=$((n+1))
 run "$n" "option needs argument" "-p" "file"
 
+# option needs argument
+n=$((n+1))
+echo "<<< __file__ >>>;" | run "$n" "stdin" "-" "file"
+
 # invalid global type
 n=$((n+1))
 run "$n" "invalid global type" "examples/complex/invalid_type0.gw examples/complex/invalid_type1.gw" "file"
diff --git a/tests/string/charAt.gw b/tests/string/charAt.gw
new file mode 100644 (file)
index 0000000..93eb65a
--- /dev/null
@@ -0,0 +1,7 @@
+<<< "".charAt(-1) >>>;
+<<< "".charAt(2) >>>;
+<<< "  test String  ".charAt(2) >>>;
+
+<<< "test".charAt(-1, 'c') >>>;
+<<< "test".charAt(12, 'c') >>>;
+<<< "test".charAt(2, 'c') >>>;
index 14ace8085bdae309a0f5d9f105a3f48b15fbc849..f2b95b86ee40914980b72ec737c0f7eb0fdd88d3 100644 (file)
@@ -6,3 +6,12 @@
 
 <<< s0 != s0 >>>;
 <<< s0 != s1 >>>;
+
+<<< null == s0 >>>;
+<<< null != s0 >>>;
+
+<<< s0 == null >>>;
+<<< s0 != null >>>;
+
+<<< null == null >>>;
+<<< null != null >>>;
diff --git a/tests/string/find.gw b/tests/string/find.gw
new file mode 100644 (file)
index 0000000..6c42cca
--- /dev/null
@@ -0,0 +1,26 @@
+<<< "test".find('e') >>>;
+<<< "test".find('a') >>>;
+<<< "".find('a') >>>;
+
+<<< "test".find(-1, 'e') >>>;
+<<< "test".find(0, 'e') >>>;
+<<< "test".find(1, 'a') >>>;
+<<< "".find(1, 'a') >>>;
+
+<<< "test".find("es") >>>;
+<<< "test".find("a") >>>;
+<<< "".find("") >>>;
+
+<<< "test".find(-1, "es") >>>;
+<<< "test".find(0, "es") >>>;
+<<< "test".find(1, "a") >>>;
+<<< "".find(1, "") >>>;
+
+<<< "test".rfind("es") >>>;
+<<< "test".rfind("a") >>>;
+<<< "".rfind("") >>>;
+
+<<< "test".rfind(-1, "es") >>>;
+<<< "test".rfind(0, "e") >>>;
+<<< "test".rfind(1, "a") >>>;
+<<< "".rfind(1, "") >>>;
diff --git a/tests/string/lower.gw b/tests/string/lower.gw
new file mode 100644 (file)
index 0000000..9336a2b
--- /dev/null
@@ -0,0 +1 @@
+<<< "Test String".lower() >>>;
diff --git a/tests/string/ltrim.gw b/tests/string/ltrim.gw
new file mode 100644 (file)
index 0000000..937fcb1
--- /dev/null
@@ -0,0 +1,2 @@
+<<< "".ltrim() >>>;
+<<< "  test String  ".ltrim() >>>;
diff --git a/tests/string/rtrim.gw b/tests/string/rtrim.gw
new file mode 100644 (file)
index 0000000..cf0645c
--- /dev/null
@@ -0,0 +1,2 @@
+<<< "".rtrim() >>>;
+<<< "  test String  ".rtrim() >>>;
diff --git a/tests/string/size.gw b/tests/string/size.gw
new file mode 100644 (file)
index 0000000..3f7539a
--- /dev/null
@@ -0,0 +1 @@
+<<< "test".size() >>>;
diff --git a/tests/string/trim.gw b/tests/string/trim.gw
new file mode 100644 (file)
index 0000000..32adde6
--- /dev/null
@@ -0,0 +1,2 @@
+<<< "".trim() >>>;
+<<< "  test String  ".trim() >>>;
diff --git a/tests/string/upper.gw b/tests/string/upper.gw
new file mode 100644 (file)
index 0000000..f8081c9
--- /dev/null
@@ -0,0 +1 @@
+<<< "test String".upper() >>>;
index c9291cc23345c6590b718bd7fb876cbc2e5c1f34..a0b14b71c28f23c683d26d3d6b50ab259117f97c 100644 (file)
@@ -3,8 +3,8 @@ struct S:[A] {
   var A a1;
 }
 
-var D:[int] si;
-var D:[float] sf;
+var S:[int] si;
+var S:[float] sf;
 
 <<< si.a0 >>>;
 <<< sf.a0 >>>;
diff --git a/util b/util
index 45dd762586ca0cda722a07baef5077e9460c9442..3566515fee16924098da38bf99deb669cd617d5b 160000 (submodule)
--- a/util
+++ b/util
@@ -1 +1 @@
-Subproject commit 45dd762586ca0cda722a07baef5077e9460c9442
+Subproject commit 3566515fee16924098da38bf99deb669cd617d5b