From 7a15964dccf8c5e3d033f3db8b96cc87e3414a86 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Sun, 8 Nov 2020 23:55:15 +0100 Subject: [PATCH] New plug system (#220) * 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 --- .github/workflows/coverage.yml | 7 +- .gitignore | 2 + Makefile | 3 +- ast | 2 +- include/arg.h | 4 +- include/engine.h | 2 +- include/env/context.h | 7 +- include/env/envset.h | 2 +- include/env/func.h | 40 ++- include/env/nspc.h | 5 +- include/env/oo.h | 23 +- include/env/type.h | 52 +++- include/env/value.h | 35 ++- include/gwi.h | 4 +- include/gwiondata.h | 2 +- include/import/cdef.h | 1 + include/import/checker.h | 1 + include/instr.h | 1 + include/parse.h | 26 +- include/plug.h | 26 +- include/vm.h | 9 +- plug | 2 +- po/fr/gwion.mo | Bin 0 -> 337 bytes scripts/test.sh | 6 +- src/arg.c | 67 ++++- src/clean.c | 8 +- src/compile.c | 1 - src/emit/emit.c | 157 ++++++----- src/emit/emitter.c | 3 +- src/env/context.c | 10 +- src/env/env.c | 19 +- src/env/env_utils.c | 5 +- src/env/envset.c | 16 +- src/env/func.c | 14 +- src/env/nspc.c | 24 +- src/env/tupleform.c | 4 +- src/env/type.c | 41 ++- src/env/type_special.c | 15 +- src/env/value.c | 12 +- src/gwion.c | 30 +-- src/gwiondata.c | 2 +- src/import/import_cdef.c | 35 ++- src/import/import_checker.c | 4 +- src/import/import_enum.c | 2 +- src/import/import_fdef.c | 22 +- src/import/import_internals.c | 14 +- src/import/import_item.c | 6 +- src/import/import_special.c | 3 +- src/import/import_tdef.c | 1 + src/import/import_udef.c | 4 +- src/lib/engine.c | 21 +- src/lib/event.c | 2 +- src/lib/instr.c | 15 +- src/lib/lib_func.c | 34 ++- src/lib/modules.c | 2 +- src/lib/object.c | 17 +- src/lib/object_op.c | 154 +++++------ src/lib/ptr.c | 22 +- src/lib/shred.c | 15 +- src/lib/string.c | 227 ++++++---------- src/lib/ugen.c | 2 +- src/lib/vararg.c | 24 +- src/parse/check.c | 138 +++++----- src/parse/func_operator.c | 2 +- src/parse/func_resolve_tmpl.c | 20 +- src/parse/operator.c | 5 +- src/parse/scan0.c | 111 ++++---- src/parse/scan1.c | 68 ++--- src/parse/scan2.c | 106 ++++---- src/parse/scanx.c | 14 +- src/parse/stage.c | 4 +- src/parse/template.c | 22 +- src/parse/traverse.c | 6 +- src/plug.c | 243 ++++++++++-------- src/vm/gack.c | 4 +- src/vm/vm.c | 2 +- src/vm/vm_code.c | 10 +- src/vm/vm_shred.c | 2 +- tests/{import => driver}/Makefile | 0 tests/driver/non_driver.c | 14 + .../driver.c => driver/simple_driver.c} | 16 +- tests/error/final_func.gw | 9 + tests/error/final_inherit.gw | 4 + tests/error/must_abstract0.gw | 3 + tests/error/must_abstract1.gw | 6 + tests/error/no_inherit.gw | 7 - tests/error/require_fail.gw | 4 + tests/fork/fork_call.gw | 2 +- tests/import/specialid_emit.gw | 1 - tests/module/Makefile | 43 ++++ tests/{import => module}/basic_module.c | 2 - tests/{import => module}/get_module.c | 12 +- tests/module/get_module.gw | 2 + tests/{import => module}/module.c | 2 - tests/plug/Makefile | 43 ++++ tests/{import => plug}/array.c | 0 tests/plug/array.gw | 2 + tests/{import => plug}/array_in_var_name.c | 0 tests/plug/array_in_var_name.gw | 2 + .../{import => plug}/array_in_var_name_fail.c | 0 tests/plug/array_in_var_name_fail.gw | 2 + .../array_incoherent_in_var_name.c | 0 tests/plug/array_incoherent_in_var_name.gw | 2 + .../array_invalid_in_var_name.c | 0 tests/plug/array_invalid_in_var_name.gw | 2 + tests/{import => plug}/callback.c | 0 tests/plug/callback.gw | 2 + tests/{import => plug}/callback.gwold | 0 tests/{import => plug}/callback2.gw | 0 tests/{import => plug}/class_template.c | 4 +- tests/{import => plug}/class_template.gw | 1 + tests/{import => plug}/class_template_fail.c | 0 tests/plug/class_template_fail.gw | 2 + .../{import => plug}/class_template_invalid.c | 4 +- tests/plug/class_template_invalid.gw | 2 + tests/{import => plug}/compile_file.c | 0 tests/plug/compile_file.gw | 2 + tests/{import => plug}/compile_string.c | 0 tests/plug/compile_string.gw | 2 + tests/{import => plug}/coverage.c | 0 tests/{import => plug}/coverage.gw | 3 + tests/plug/deps.c | 18 ++ tests/plug/deps.gw | 3 + tests/{import => plug}/empty_union.c | 0 tests/plug/empty_union.gw | 2 + tests/{import => plug}/end_class.c | 0 tests/plug/end_class.gw | 2 + tests/{import => plug}/enum.c | 0 tests/{import => plug}/enum.gw | 1 + tests/{import => plug}/enum_fail.c | 0 tests/plug/enum_fail.gw | 2 + tests/{import => plug}/enum_fail2.c | 0 tests/plug/enum_fail2.gw | 2 + tests/{import => plug}/enum_fail3.c | 0 tests/plug/enum_fail3.gw | 2 + tests/{import => plug}/extend_array.c | 0 tests/{import => plug}/extend_array.gw | 1 + tests/{import => plug}/fail_on_next_arg.c | 0 tests/plug/fail_on_next_arg.gw | 2 + tests/{import => plug}/fail_on_next_arg2.c | 0 tests/plug/fail_on_next_arg2.gw | 2 + tests/{import => plug}/fptr.c | 0 tests/{import => plug}/fptr.gw | 2 +- tests/{import => plug}/fptr_tmpl.c | 0 tests/plug/fptr_tmpl.gw | 2 + tests/{import => plug}/fptr_tmpl_fail.c | 0 tests/plug/fptr_tmpl_fail.gw | 2 + tests/{import => plug}/func_fail.c | 0 tests/plug/func_fail.gw | 2 + tests/{import => plug}/func_fail2.c | 0 tests/plug/func_fail2.gw | 2 + tests/{import => plug}/func_fail3.c | 0 tests/plug/func_fail3.gw | 2 + tests/{import => plug}/func_fail4.c | 0 tests/plug/func_fail4.gw | 2 + .../func_subscript_not_empty.c | 0 tests/plug/func_subscript_not_empty.gw | 2 + tests/{import => plug}/func_tmpl.c | 0 tests/{import => plug}/func_tmpl.gw | 1 + tests/{import => plug}/func_tmpl_fail.c | 0 tests/plug/func_tmpl_fail.gw | 2 + tests/{import => plug}/func_too_many_arg.c | 0 tests/plug/func_too_many_arg.gw | 2 + tests/{import => plug}/global_func.c | 0 tests/{import => plug}/global_func.gw | 2 +- tests/{import => plug}/global_var.c | 0 tests/{import => plug}/global_var.gw | 1 + tests/{import => plug}/invalid_arg.c | 0 tests/plug/invalid_arg.gw | 2 + tests/{import => plug}/invalid_array.c | 0 tests/plug/invalid_array.gw | 2 + tests/{import => plug}/invalid_func.c | 0 tests/plug/invalid_func.gw | 2 + tests/{import => plug}/invalid_names.c | 0 tests/plug/invalid_names.gw | 2 + tests/{import => plug}/invalid_names0.c | 0 tests/plug/invalid_names0.gw | 2 + tests/{import => plug}/invalid_names1.c | 0 tests/plug/invalid_names1.gw | 2 + tests/{import => plug}/invalid_names2.c | 0 tests/plug/invalid_names2.gw | 2 + tests/{import => plug}/invalid_names3.c | 0 tests/plug/invalid_names3.gw | 2 + tests/{import => plug}/invalid_type1.c | 0 tests/plug/invalid_type1.gw | 2 + tests/{import => plug}/invalid_type2.c | 0 tests/plug/invalid_type2.gw | 2 + tests/{import => plug}/invalid_type3.c | 0 tests/plug/invalid_type3.gw | 2 + tests/{import => plug}/map2.gw | 0 tests/{import => plug}/mk_type_array.c | 0 tests/plug/mk_type_array.gw | 2 + tests/{import => plug}/no_import.c | 0 tests/plug/no_import.gw | 2 + tests/{import => plug}/not_importing.c | 0 tests/plug/not_importing.gw | 2 + tests/{import => plug}/op_already_imported.c | 1 - tests/{import => plug}/op_already_imported.gw | 1 + tests/{import => plug}/pass.c | 0 tests/plug/pass.gw | 2 + tests/{import => plug}/rm_me.gw | 0 tests/{import => plug}/specialid_emit.c | 0 tests/plug/specialid_emit.gw | 2 + tests/{import => plug}/static_string.c | 0 tests/{import => plug}/static_string.gw | 1 + tests/{import => plug}/str2decl.c | 0 tests/plug/str2decl.gw | 2 + tests/{import => plug}/str2list_fail.c | 0 tests/plug/str2list_fail.gw | 2 + tests/plug/struct.c | 43 ++++ tests/plug/struct.gw | 18 ++ tests/{import => plug}/template_arg.c | 0 tests/plug/template_arg.gw | 2 + tests/{import => plug}/trig.c | 0 tests/{import => plug}/trig.gw | 1 + tests/{import => plug}/typedef.c | 0 tests/{import => plug}/typedef.gw | 1 + tests/{import => plug}/typedef_fail.c | 0 tests/plug/typedef_fail.gw | 2 + tests/{import => plug}/typedef_tmpl.c | 0 tests/plug/typedef_tmpl.gw | 2 + tests/{import => plug}/ugen_connect.c | 0 tests/plug/ugen_connect.gw | 2 + tests/{import => plug}/union.c | 0 tests/{import => plug}/union.gw | 1 + tests/{import => plug}/union_fail_exp.c | 0 tests/plug/union_fail_exp.gw | 2 + tests/{import => plug}/union_member.c | 0 tests/plug/union_member.gw | 2 + tests/{import => plug}/union_name.c | 0 tests/{import => plug}/union_name.gw | 1 + tests/{import => plug}/union_tmpl.c | 0 tests/{import => plug}/union_tmpl.gw | 1 + tests/{import => plug}/union_tmpl_fail.c | 0 tests/plug/union_tmpl_fail.gw | 2 + tests/{import => plug}/union_tmpl_fail2.c | 0 tests/plug/union_tmpl_fail2.gw | 2 + tests/{import => plug}/union_tmpl_fail3.c | 0 tests/plug/union_tmpl_fail3.gw | 2 + tests/{import => plug}/variadic.c | 3 +- tests/{import => plug}/variadic.gw | 1 + tests/{import => plug}/vm_remove.c | 0 tests/{import => plug}/vm_remove.gw | 1 + tests/sh/import.sh | 36 ++- tests/sh/opt.sh | 12 +- tests/string/charAt.gw | 7 + tests/string/eq.gw | 9 + tests/string/find.gw | 26 ++ tests/string/lower.gw | 1 + tests/string/ltrim.gw | 2 + tests/string/rtrim.gw | 2 + tests/string/size.gw | 1 + tests/string/trim.gw | 2 + tests/string/upper.gw | 1 + tests/struct/struct_template.gw | 4 +- util | 2 +- 256 files changed, 1523 insertions(+), 1046 deletions(-) create mode 100644 po/fr/gwion.mo rename tests/{import => driver}/Makefile (100%) create mode 100644 tests/driver/non_driver.c rename tests/{import/driver.c => driver/simple_driver.c} (53%) create mode 100644 tests/error/final_func.gw create mode 100644 tests/error/final_inherit.gw create mode 100644 tests/error/must_abstract0.gw create mode 100644 tests/error/must_abstract1.gw delete mode 100644 tests/error/no_inherit.gw create mode 100644 tests/error/require_fail.gw delete mode 100644 tests/import/specialid_emit.gw create mode 100644 tests/module/Makefile rename tests/{import => module}/basic_module.c (93%) rename tests/{import => module}/get_module.c (71%) create mode 100644 tests/module/get_module.gw rename tests/{import => module}/module.c (92%) create mode 100644 tests/plug/Makefile rename tests/{import => plug}/array.c (100%) create mode 100644 tests/plug/array.gw rename tests/{import => plug}/array_in_var_name.c (100%) create mode 100644 tests/plug/array_in_var_name.gw rename tests/{import => plug}/array_in_var_name_fail.c (100%) create mode 100644 tests/plug/array_in_var_name_fail.gw rename tests/{import => plug}/array_incoherent_in_var_name.c (100%) create mode 100644 tests/plug/array_incoherent_in_var_name.gw rename tests/{import => plug}/array_invalid_in_var_name.c (100%) create mode 100644 tests/plug/array_invalid_in_var_name.gw rename tests/{import => plug}/callback.c (100%) create mode 100644 tests/plug/callback.gw rename tests/{import => plug}/callback.gwold (100%) rename tests/{import => plug}/callback2.gw (100%) rename tests/{import => plug}/class_template.c (89%) rename tests/{import => plug}/class_template.gw (67%) rename tests/{import => plug}/class_template_fail.c (100%) create mode 100644 tests/plug/class_template_fail.gw rename tests/{import => plug}/class_template_invalid.c (84%) create mode 100644 tests/plug/class_template_invalid.gw rename tests/{import => plug}/compile_file.c (100%) create mode 100644 tests/plug/compile_file.gw rename tests/{import => plug}/compile_string.c (100%) create mode 100644 tests/plug/compile_string.gw rename tests/{import => plug}/coverage.c (100%) rename tests/{import => plug}/coverage.gw (88%) create mode 100644 tests/plug/deps.c create mode 100644 tests/plug/deps.gw rename tests/{import => plug}/empty_union.c (100%) create mode 100644 tests/plug/empty_union.gw rename tests/{import => plug}/end_class.c (100%) create mode 100644 tests/plug/end_class.gw rename tests/{import => plug}/enum.c (100%) rename tests/{import => plug}/enum.gw (98%) rename tests/{import => plug}/enum_fail.c (100%) create mode 100644 tests/plug/enum_fail.gw rename tests/{import => plug}/enum_fail2.c (100%) create mode 100644 tests/plug/enum_fail2.gw rename tests/{import => plug}/enum_fail3.c (100%) create mode 100644 tests/plug/enum_fail3.gw rename tests/{import => plug}/extend_array.c (100%) rename tests/{import => plug}/extend_array.gw (67%) rename tests/{import => plug}/fail_on_next_arg.c (100%) create mode 100644 tests/plug/fail_on_next_arg.gw rename tests/{import => plug}/fail_on_next_arg2.c (100%) create mode 100644 tests/plug/fail_on_next_arg2.gw rename tests/{import => plug}/fptr.c (100%) rename tests/{import => plug}/fptr.gw (94%) rename tests/{import => plug}/fptr_tmpl.c (100%) create mode 100644 tests/plug/fptr_tmpl.gw rename tests/{import => plug}/fptr_tmpl_fail.c (100%) create mode 100644 tests/plug/fptr_tmpl_fail.gw rename tests/{import => plug}/func_fail.c (100%) create mode 100644 tests/plug/func_fail.gw rename tests/{import => plug}/func_fail2.c (100%) create mode 100644 tests/plug/func_fail2.gw rename tests/{import => plug}/func_fail3.c (100%) create mode 100644 tests/plug/func_fail3.gw rename tests/{import => plug}/func_fail4.c (100%) create mode 100644 tests/plug/func_fail4.gw rename tests/{import => plug}/func_subscript_not_empty.c (100%) create mode 100644 tests/plug/func_subscript_not_empty.gw rename tests/{import => plug}/func_tmpl.c (100%) rename tests/{import => plug}/func_tmpl.gw (55%) rename tests/{import => plug}/func_tmpl_fail.c (100%) create mode 100644 tests/plug/func_tmpl_fail.gw rename tests/{import => plug}/func_too_many_arg.c (100%) create mode 100644 tests/plug/func_too_many_arg.gw rename tests/{import => plug}/global_func.c (100%) rename tests/{import => plug}/global_func.gw (61%) rename tests/{import => plug}/global_var.c (100%) rename tests/{import => plug}/global_var.gw (73%) rename tests/{import => plug}/invalid_arg.c (100%) create mode 100644 tests/plug/invalid_arg.gw rename tests/{import => plug}/invalid_array.c (100%) create mode 100644 tests/plug/invalid_array.gw rename tests/{import => plug}/invalid_func.c (100%) create mode 100644 tests/plug/invalid_func.gw rename tests/{import => plug}/invalid_names.c (100%) create mode 100644 tests/plug/invalid_names.gw rename tests/{import => plug}/invalid_names0.c (100%) create mode 100644 tests/plug/invalid_names0.gw rename tests/{import => plug}/invalid_names1.c (100%) create mode 100644 tests/plug/invalid_names1.gw rename tests/{import => plug}/invalid_names2.c (100%) create mode 100644 tests/plug/invalid_names2.gw rename tests/{import => plug}/invalid_names3.c (100%) create mode 100644 tests/plug/invalid_names3.gw rename tests/{import => plug}/invalid_type1.c (100%) create mode 100644 tests/plug/invalid_type1.gw rename tests/{import => plug}/invalid_type2.c (100%) create mode 100644 tests/plug/invalid_type2.gw rename tests/{import => plug}/invalid_type3.c (100%) create mode 100644 tests/plug/invalid_type3.gw rename tests/{import => plug}/map2.gw (100%) rename tests/{import => plug}/mk_type_array.c (100%) create mode 100644 tests/plug/mk_type_array.gw rename tests/{import => plug}/no_import.c (100%) create mode 100644 tests/plug/no_import.gw rename tests/{import => plug}/not_importing.c (100%) create mode 100644 tests/plug/not_importing.gw rename tests/{import => plug}/op_already_imported.c (99%) rename tests/{import => plug}/op_already_imported.gw (59%) rename tests/{import => plug}/pass.c (100%) create mode 100644 tests/plug/pass.gw rename tests/{import => plug}/rm_me.gw (100%) rename tests/{import => plug}/specialid_emit.c (100%) create mode 100644 tests/plug/specialid_emit.gw rename tests/{import => plug}/static_string.c (100%) rename tests/{import => plug}/static_string.gw (65%) rename tests/{import => plug}/str2decl.c (100%) create mode 100644 tests/plug/str2decl.gw rename tests/{import => plug}/str2list_fail.c (100%) create mode 100644 tests/plug/str2list_fail.gw create mode 100644 tests/plug/struct.c create mode 100644 tests/plug/struct.gw rename tests/{import => plug}/template_arg.c (100%) create mode 100644 tests/plug/template_arg.gw rename tests/{import => plug}/trig.c (100%) rename tests/{import => plug}/trig.gw (89%) rename tests/{import => plug}/typedef.c (100%) rename tests/{import => plug}/typedef.gw (81%) rename tests/{import => plug}/typedef_fail.c (100%) create mode 100644 tests/plug/typedef_fail.gw rename tests/{import => plug}/typedef_tmpl.c (100%) create mode 100644 tests/plug/typedef_tmpl.gw rename tests/{import => plug}/ugen_connect.c (100%) create mode 100644 tests/plug/ugen_connect.gw rename tests/{import => plug}/union.c (100%) rename tests/{import => plug}/union.gw (89%) rename tests/{import => plug}/union_fail_exp.c (100%) create mode 100644 tests/plug/union_fail_exp.gw rename tests/{import => plug}/union_member.c (100%) create mode 100644 tests/plug/union_member.gw rename tests/{import => plug}/union_name.c (100%) rename tests/{import => plug}/union_name.gw (64%) rename tests/{import => plug}/union_tmpl.c (100%) rename tests/{import => plug}/union_tmpl.gw (64%) rename tests/{import => plug}/union_tmpl_fail.c (100%) create mode 100644 tests/plug/union_tmpl_fail.gw rename tests/{import => plug}/union_tmpl_fail2.c (100%) create mode 100644 tests/plug/union_tmpl_fail2.gw rename tests/{import => plug}/union_tmpl_fail3.c (100%) create mode 100644 tests/plug/union_tmpl_fail3.gw rename tests/{import => plug}/variadic.c (91%) rename tests/{import => plug}/variadic.gw (94%) rename tests/{import => plug}/vm_remove.c (100%) rename tests/{import => plug}/vm_remove.gw (50%) create mode 100644 tests/string/charAt.gw create mode 100644 tests/string/find.gw create mode 100644 tests/string/lower.gw create mode 100644 tests/string/ltrim.gw create mode 100644 tests/string/rtrim.gw create mode 100644 tests/string/size.gw create mode 100644 tests/string/trim.gw create mode 100644 tests/string/upper.gw diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index a84ad3dc..08164c6f 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -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 diff --git a/.gitignore b/.gitignore index 29ba8fb9..1783da30 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,5 @@ mkdocs.yml *.a *.o *.so +*.gcda +*.gcno diff --git a/Makefile b/Makefile index a5e21942..bf82589d 100644 --- 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 7a595b66..f75d51f0 160000 --- a/ast +++ b/ast @@ -1 +1 @@ -Subproject commit 7a595b66afa08bb840222b7297e08e030e2232eb +Subproject commit f75d51f0b87497057ccf739063a1a6b58fe3da2f diff --git a/include/arg.h b/include/arg.h index ae9746ad..dfaf8587 100644 --- a/include/arg.h +++ b/include/arg.h @@ -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 diff --git a/include/engine.h b/include/engine.h index 728d16e6..4d1c008c 100644 --- a/include/engine.h +++ b/include/engine.h @@ -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 diff --git a/include/env/context.h b/include/env/context.h index 61c3fa61..53a12800 100644 --- a/include/env/context.h +++ b/include/env/context.h @@ -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 diff --git a/include/env/envset.h b/include/env/envset.h index 1e11c9b9..c9838df6 100644 --- a/include/env/envset.h +++ b/include/env/envset.h @@ -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; }; diff --git a/include/env/func.h b/include/env/func.h index 5375b0a6..e28a706e 100644 --- a/include/env/func.h +++ b/include/env/func.h @@ -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(ff); +} + +static inline void unset_fflag(const Func f, const enum fflag flag) { + const auto ff = f->fflag & ~flag; + f->fflag = static_cast(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 diff --git a/include/env/nspc.h b/include/env/nspc.h index 9ce2f4f7..1a70d732 100644 --- a/include/env/nspc.h +++ b/include/env/nspc.h @@ -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); diff --git a/include/env/oo.h b/include/env/oo.h index 1dc06485..92f80343 100644 --- a/include/env/oo.h +++ b/include/env/oo.h @@ -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 diff --git a/include/env/type.h b/include/env/type.h index 0ff7e13f..5314dbb8 100644 --- a/include/env/type.h +++ b/include/env/type.h @@ -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(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 { diff --git a/include/env/value.h b/include/env/value.h index 2f592d39..c3b33433 100644 --- a/include/env/value.h +++ b/include/env/value.h @@ -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(ff); +} +#endif + ANEW ANN Value new_value(MemPool p, const Type type, const m_str name); ANN void valuefrom(const Env, struct ValueFrom_*); #endif diff --git a/include/gwi.h b/include/gwi.h index 6cee9bca..d20124fd 100644 --- a/include/gwi.h +++ b/include/gwi.h @@ -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 diff --git a/include/gwiondata.h b/include/gwiondata.h index 046f15b7..eccc3d15 100644 --- a/include/gwiondata.h +++ b/include/gwiondata.h @@ -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); diff --git a/include/import/cdef.h b/include/import/cdef.h index 25722edc..3cdb9728 100644 --- a/include/import/cdef.h +++ b/include/import/cdef.h @@ -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 diff --git a/include/import/checker.h b/include/import/checker.h index 3b1cc6cc..5ef1d61a 100644 --- a/include/import/checker.h +++ b/include/import/checker.h @@ -31,6 +31,7 @@ typedef struct ImportCK { // name_checker ? ID_List curr;// enum }; ae_flag flag; // ???? + uint variadic; enum importck_type type; } ImportCK; diff --git a/include/instr.h b/include/instr.h index fa9b4852..5e260639 100644 --- a/include/instr.h +++ b/include/instr.h @@ -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); diff --git a/include/parse.h b/include/parse.h index 62889984..394a5314 100644 --- a/include/parse.h +++ b/include/parse.h @@ -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); diff --git a/include/plug.h b/include/plug.h index 2065ae5d..bc258ac2 100644 --- a/include/plug.h +++ b/include/plug.h @@ -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 diff --git a/include/vm.h b/include/vm.h index cd7d7a10..6dd7c929 100644 --- a/include/vm.h +++ b/include/vm.h @@ -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 3004e1d4..300d07d9 160000 --- 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 index 0000000000000000000000000000000000000000..6c5906d1cd061dff54de8b533942893de34efc9e GIT binary patch literal 337 zcmYL@Jx{|h5Qd9j%E-dP;DHUUz!pqFHI3Uw*h!U-O0b#M1fyU_j*H-j@b~yFTo(FD zk8Zg4bkFbc(a#8TfSe*{$RTop42h8wT;AXuI{#UD_pUbq(k-mD?~SvRtk~?4EjU^8 zqD=EFDs<<30NFQY3lF=dhsseBt#T;zrx|V_Q9)Dk#909{hlG)3PGx%joM$`|st-_k zW&2hI=P8-jLXeC}P9|KkR7_ct6ud0&v1*&0YBW?@eNZA;wx|b_i4fD)jGb@x9W;=s z /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 } diff --git a/src/arg.c b/src/arg.c index 36e90dd2..dd340388 100644 --- 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 \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; } diff --git a/src/clean.c b/src/clean.c index a3bc2dbf..5d64b36e 100644 --- a/src/clean.c +++ b/src/clean.c @@ -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) { diff --git a/src/compile.c b/src/compile.c index 9c1644a5..4227f17d 100644 --- a/src/compile.c +++ b/src/compile.c @@ -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) { diff --git a/src/emit/emit.c b/src/emit/emit.c index 27921731..5155219c 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -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); diff --git a/src/emit/emitter.c b/src/emit/emitter.c index 6520d9fa..142e1b21 100644 --- a/src/emit/emitter.c +++ b/src/emit/emitter.c @@ -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; } diff --git a/src/env/context.c b/src/env/context.c index 6cf65e90..c78d522e 100644 --- a/src/env/context.c +++ b/src/env/context.c @@ -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); } diff --git a/src/env/env.c b/src/env/env.c index e5360419..b4729d3d 100644 --- a/src/env/env.c +++ b/src/env/env.c @@ -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; } diff --git a/src/env/env_utils.c b/src/env/env_utils.c index ce6ab3d3..a3661a45 100644 --- a/src/env/env_utils.c +++ b/src/env/env_utils.c @@ -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; } diff --git a/src/env/envset.c b/src/env/envset.c index 26efc742..5bfa468c 100644 --- a/src/env/envset.c +++ b/src/env/envset.c @@ -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; diff --git a/src/env/func.c b/src/env/func.c index a1bda102..6417d2a3 100644 --- a/src/env/func.c +++ b/src/env/func.c @@ -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; +} diff --git a/src/env/nspc.c b/src/env/nspc.c index 27743ccd..c92cd7bd 100644 --- a/src/env/nspc.c +++ b/src/env/nspc.c @@ -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; } diff --git a/src/env/tupleform.c b/src/env/tupleform.c index 511ed68a..82fe1df2 100644 --- a/src/env/tupleform.c +++ b/src/env/tupleform.c @@ -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); diff --git a/src/env/type.c b/src/env/type.c index bc6e3126..9da87fe0 100644 --- a/src/env/type.c +++ b/src/env/type.c @@ -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; } } diff --git a/src/env/type_special.c b/src/env/type_special.c index 9a7c8143..05db3f35 100644 --- a/src/env/type_special.c +++ b/src/env/type_special.c @@ -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; diff --git a/src/env/value.c b/src/env/value.c index 13cfdd6c..dfbf80b8 100644 --- a/src/env/value.c +++ b/src/env/value.c @@ -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; } diff --git a/src/gwion.c b/src/gwion.c index dfd4363a..f4284dcc 100644 --- a/src/gwion.c +++ b/src/gwion.c @@ -13,21 +13,10 @@ #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; } diff --git a/src/gwiondata.c b/src/gwiondata.c index 5f74b697..a85cd6a5 100644 --- a/src/gwiondata.c +++ b/src/gwiondata.c @@ -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); } diff --git a/src/import/import_cdef.c b/src/import/import_cdef.c index e04f8006..aaa39879 100644 --- a/src/import/import_cdef.c +++ b/src/import/import_cdef.c @@ -17,21 +17,21 @@ #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); } diff --git a/src/import/import_checker.c b/src/import/import_checker.c index efd1db70..4b556234 100644 --- a/src/import/import_checker.c +++ b/src/import/import_checker.c @@ -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) { diff --git a/src/import/import_enum.c b/src/import/import_enum.c index ee398e37..1607e576 100644 --- a/src/import/import_enum.c +++ b/src/import/import_enum.c @@ -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); diff --git a/src/import/import_fdef.c b/src/import/import_fdef.c index 9fdf808c..32d2a8c3 100644 --- a/src/import/import_fdef.c +++ b/src/import/import_fdef.c @@ -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; } diff --git a/src/import/import_internals.c b/src/import/import_internals.c index 8f0f85f8..56292c20 100644 --- a/src/import/import_internals.c +++ b/src/import/import_internals.c @@ -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; +} diff --git a/src/import/import_item.c b/src/import/import_item.c index 5d5ed543..3639445f 100644 --- a/src/import/import_item.c +++ b/src/import/import_item.c @@ -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); diff --git a/src/import/import_special.c b/src/import/import_special.c index f4f2e414..36fd2967 100644 --- a/src/import/import_special.c +++ b/src/import/import_special.c @@ -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; } diff --git a/src/import/import_tdef.c b/src/import/import_tdef.c index 32006abc..cfd2b7bf 100644 --- a/src/import/import_tdef.c +++ b/src/import/import_tdef.c @@ -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; diff --git a/src/import/import_udef.c b/src/import/import_udef.c index 73f8f061..aaa603ff 100644 --- a/src/import/import_udef.c +++ b/src/import/import_udef.c @@ -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; diff --git a/src/lib/engine.c b/src/lib/engine.c index 35d3b454..9d55f6eb 100644 --- a/src/lib/engine.c +++ b/src/lib/engine.c @@ -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; } diff --git a/src/lib/event.c b/src/lib/event.c index 2f56dd16..2c3818f4 100644 --- a/src/lib/event.c +++ b/src/lib/event.c @@ -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")) diff --git a/src/lib/instr.c b/src/lib/instr.c index 587b1fa4..b1e9ef76 100644 --- a/src/lib/instr.c +++ b/src/lib/instr.c @@ -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; diff --git a/src/lib/lib_func.c b/src/lib/lib_func.c index 526c1df2..9781373c 100644 --- a/src/lib/lib_func.c +++ b/src/lib/lib_func.c @@ -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) { diff --git a/src/lib/modules.c b/src/lib/modules.c index 76e20ae5..8a1af0bb 100644 --- a/src/lib/modules.c +++ b/src/lib/modules.c @@ -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); diff --git a/src/lib/object.c b/src/lib/object.c index b8a2bf32..2d08cb34 100644 --- a/src/lib/object.c +++ b/src/lib/object.c @@ -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; diff --git a/src/lib/object_op.c b/src/lib/object_op.c index 3b15c4ee..66a8b70d 100644 --- a/src/lib/object_op.c +++ b/src/lib/object_op.c @@ -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)); diff --git a/src/lib/ptr.c b/src/lib/ptr.c index 2012bf5b..fa4378dd 100644 --- a/src/lib/ptr.c +++ b/src/lib/ptr.c @@ -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)) diff --git a/src/lib/shred.c b/src/lib/shred.c index 9dc20c4b..a9c9ddcb 100644 --- a/src/lib/shred.c +++ b/src/lib/shred.c @@ -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; } diff --git a/src/lib/string.c b/src/lib/string.c index 98422c1f..db68d0ed 100644 --- a/src/lib/string.c +++ b/src/lib/string.c @@ -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"); diff --git a/src/lib/ugen.c b/src/lib/ugen.c index ff9231a1..a948cc8e 100644 --- a/src/lib/ugen.c +++ b/src/lib/ugen.c @@ -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")) diff --git a/src/lib/vararg.c b/src/lib/vararg.c index 2b748cd2..41177b48 100644 --- a/src/lib/vararg.c +++ b/src/lib/vararg.c @@ -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)) diff --git a/src/parse/check.c b/src/parse/check.c index 36200341..4d0650fa 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -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; } diff --git a/src/parse/func_operator.c b/src/parse/func_operator.c index 75af7510..2d794a8d 100644 --- a/src/parse/func_operator.c +++ b/src/parse/func_operator.c @@ -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 : diff --git a/src/parse/func_resolve_tmpl.c b/src/parse/func_resolve_tmpl.c index bb5a6063..e62b98f7 100644 --- a/src/parse/func_resolve_tmpl.c +++ b/src/parse/func_resolve_tmpl.c @@ -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); diff --git a/src/parse/operator.c b/src/parse/operator.c index 5b89942c..fa3c27b7 100644 --- a/src/parse/operator.c +++ b/src/parse/operator.c @@ -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); } diff --git a/src/parse/scan0.c b/src/parse/scan0.c index 6047da5f..30ace78f 100644 --- a/src/parse/scan0.c +++ b/src/parse/scan0.c @@ -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) { diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 350c9239..da0e8d3a 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -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) diff --git a/src/parse/scan2.c b/src/parse/scan2.c index 2bb5b4a8..618dbc10 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -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) diff --git a/src/parse/scanx.c b/src/parse/scanx.c index c4eaa031..45345b92 100644 --- a/src/parse/scanx.c +++ b/src/parse/scanx.c @@ -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; } diff --git a/src/parse/stage.c b/src/parse/stage.c index 784e298a..84c1dad5 100644 --- a/src/parse/stage.c +++ b/src/parse/stage.c @@ -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; } diff --git a/src/parse/template.c b/src/parse/template.c index 3042d0e7..63c159c3 100644 --- a/src/parse/template.c +++ b/src/parse/template.c @@ -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); diff --git a/src/parse/traverse.c b/src/parse/traverse.c index deac0f86..6e37aab5 100644 --- a/src/parse/traverse.c +++ b/src/parse/traverse.c @@ -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; } diff --git a/src/plug.c b/src/plug.c index 75724b18..eeaceeca 100644 --- a/src/plug.c +++ b/src/plug.c @@ -1,6 +1,7 @@ #ifndef BUILD_ON_WINDOWS #include #include +#include #else #include #endif @@ -13,19 +14,13 @@ #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; } diff --git a/src/vm/gack.c b/src/vm/gack.c index 203dbee3..d6f08853 100644 --- a/src/vm/gack.c +++ b/src/vm/gack.c @@ -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); diff --git a/src/vm/vm.c b/src/vm/vm.c index 3027e6ec..4d343232 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -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; diff --git a/src/vm/vm_code.c b/src/vm/vm_code.c index f376fe65..3851a5b0 100644 --- a/src/vm/vm_code.c +++ b/src/vm/vm_code.c @@ -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; } diff --git a/src/vm/vm_shred.c b/src/vm/vm_shred.c index eca7b796..52795e6c 100644 --- a/src/vm/vm_shred.c +++ b/src/vm/vm_shred.c @@ -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); diff --git a/tests/import/Makefile b/tests/driver/Makefile 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 index 00000000..2c020b3b --- /dev/null +++ b/tests/driver/non_driver.c @@ -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; +} diff --git a/tests/import/driver.c b/tests/driver/simple_driver.c similarity index 53% rename from tests/import/driver.c rename to tests/driver/simple_driver.c index 7f1628e5..22c2bccf 100644 --- a/tests/import/driver.c +++ b/tests/driver/simple_driver.c @@ -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 index 00000000..581632ff --- /dev/null +++ b/tests/error/final_func.gw @@ -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 index 00000000..f021b02b --- /dev/null +++ b/tests/error/final_inherit.gw @@ -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 index 00000000..88b75523 --- /dev/null +++ b/tests/error/must_abstract0.gw @@ -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 index 00000000..121854aa --- /dev/null +++ b/tests/error/must_abstract1.gw @@ -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 index d37f6278..00000000 --- a/tests/error/no_inherit.gw +++ /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 index 00000000..01646ae7 --- /dev/null +++ b/tests/error/require_fail.gw @@ -0,0 +1,4 @@ +#require NonExisting + +var ftbl f; +<<< var SinOsc s >>>; diff --git a/tests/fork/fork_call.gw b/tests/fork/fork_call.gw index 9164468b..0178f879 100644 --- a/tests/fork/fork_call.gw +++ b/tests/fork/fork_call.gw @@ -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 index ae200733..00000000 --- a/tests/import/specialid_emit.gw +++ /dev/null @@ -1 +0,0 @@ -<<< testid >>>; diff --git a/tests/module/Makefile b/tests/module/Makefile new file mode 100644 index 00000000..6327be10 --- /dev/null +++ b/tests/module/Makefile @@ -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 diff --git a/tests/import/basic_module.c b/tests/module/basic_module.c similarity index 93% rename from tests/import/basic_module.c rename to tests/module/basic_module.c index 11a37841..18d05fce 100644 --- a/tests/import/basic_module.c +++ b/tests/module/basic_module.c @@ -4,8 +4,6 @@ #include "vm.h" #include "gwion.h" -GWMODSTR(basic_module) - GWMODINI(basic_module) { puts("ini module"); if(args) { diff --git a/tests/import/get_module.c b/tests/module/get_module.c similarity index 71% rename from tests/import/get_module.c rename to tests/module/get_module.c index d4d11e62..3a27ad05 100644 --- a/tests/import/get_module.c +++ b/tests/module/get_module.c @@ -13,18 +13,18 @@ #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 index 00000000..ef38782f --- /dev/null +++ b/tests/module/get_module.gw @@ -0,0 +1,2 @@ +#require get_module +<<< __file__ >>>; diff --git a/tests/import/module.c b/tests/module/module.c similarity index 92% rename from tests/import/module.c rename to tests/module/module.c index d65ee754..77ead7d7 100644 --- a/tests/import/module.c +++ b/tests/module/module.c @@ -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 index 00000000..6327be10 --- /dev/null +++ b/tests/plug/Makefile @@ -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 diff --git a/tests/import/array.c b/tests/plug/array.c 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 index 00000000..8958ace4 --- /dev/null +++ b/tests/plug/array.gw @@ -0,0 +1,2 @@ +#require array +<<< __file__ >>>; diff --git a/tests/import/array_in_var_name.c b/tests/plug/array_in_var_name.c similarity index 100% rename from tests/import/array_in_var_name.c rename to tests/plug/array_in_var_name.c diff --git a/tests/plug/array_in_var_name.gw b/tests/plug/array_in_var_name.gw new file mode 100644 index 00000000..c6e79b56 --- /dev/null +++ b/tests/plug/array_in_var_name.gw @@ -0,0 +1,2 @@ +#require array_in_var_name +<<< __file__ >>>; diff --git a/tests/import/array_in_var_name_fail.c b/tests/plug/array_in_var_name_fail.c similarity index 100% rename from tests/import/array_in_var_name_fail.c rename to tests/plug/array_in_var_name_fail.c diff --git a/tests/plug/array_in_var_name_fail.gw b/tests/plug/array_in_var_name_fail.gw new file mode 100644 index 00000000..122ac5fe --- /dev/null +++ b/tests/plug/array_in_var_name_fail.gw @@ -0,0 +1,2 @@ +#require array_in_var_name_fail +<<< __file__ >>>; diff --git a/tests/import/array_incoherent_in_var_name.c b/tests/plug/array_incoherent_in_var_name.c similarity index 100% rename from tests/import/array_incoherent_in_var_name.c rename to tests/plug/array_incoherent_in_var_name.c diff --git a/tests/plug/array_incoherent_in_var_name.gw b/tests/plug/array_incoherent_in_var_name.gw new file mode 100644 index 00000000..a7e9493b --- /dev/null +++ b/tests/plug/array_incoherent_in_var_name.gw @@ -0,0 +1,2 @@ +#require array_incoherent_in_var_name +<<< __file__ >>>; diff --git a/tests/import/array_invalid_in_var_name.c b/tests/plug/array_invalid_in_var_name.c similarity index 100% rename from tests/import/array_invalid_in_var_name.c rename to tests/plug/array_invalid_in_var_name.c diff --git a/tests/plug/array_invalid_in_var_name.gw b/tests/plug/array_invalid_in_var_name.gw new file mode 100644 index 00000000..0d9b7496 --- /dev/null +++ b/tests/plug/array_invalid_in_var_name.gw @@ -0,0 +1,2 @@ +#require array_invalid_in_var_name +<<< __file__ >>>; diff --git a/tests/import/callback.c b/tests/plug/callback.c similarity index 100% rename from tests/import/callback.c rename to tests/plug/callback.c diff --git a/tests/plug/callback.gw b/tests/plug/callback.gw new file mode 100644 index 00000000..832778b6 --- /dev/null +++ b/tests/plug/callback.gw @@ -0,0 +1,2 @@ +#require callback +<<< __file__ >>>; diff --git a/tests/import/callback.gwold b/tests/plug/callback.gwold similarity index 100% rename from tests/import/callback.gwold rename to tests/plug/callback.gwold diff --git a/tests/import/callback2.gw b/tests/plug/callback2.gw similarity index 100% rename from tests/import/callback2.gw rename to tests/plug/callback2.gw diff --git a/tests/import/class_template.c b/tests/plug/class_template.c similarity index 89% rename from tests/import/class_template.c rename to tests/plug/class_template.c index d7ea4297..e8124a8a 100644 --- a/tests/import/class_template.c +++ b/tests/plug/class_template.c @@ -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)) diff --git a/tests/import/class_template.gw b/tests/plug/class_template.gw similarity index 67% rename from tests/import/class_template.gw rename to tests/plug/class_template.gw index 38432690..264e0021 100644 --- a/tests/import/class_template.gw +++ b/tests/plug/class_template.gw @@ -1,2 +1,3 @@ +#require class_template var ClassTemplate:[int, int] ct; <<< ct.key >>>; diff --git a/tests/import/class_template_fail.c b/tests/plug/class_template_fail.c similarity index 100% rename from tests/import/class_template_fail.c rename to tests/plug/class_template_fail.c diff --git a/tests/plug/class_template_fail.gw b/tests/plug/class_template_fail.gw new file mode 100644 index 00000000..c07b0f83 --- /dev/null +++ b/tests/plug/class_template_fail.gw @@ -0,0 +1,2 @@ +#require class_template_fail +<<< __file__ >>>; diff --git a/tests/import/class_template_invalid.c b/tests/plug/class_template_invalid.c similarity index 84% rename from tests/import/class_template_invalid.c rename to tests/plug/class_template_invalid.c index fdd14dea..0ef547e3 100644 --- a/tests/import/class_template_invalid.c +++ b/tests/plug/class_template_invalid.c @@ -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 index 00000000..55d995a9 --- /dev/null +++ b/tests/plug/class_template_invalid.gw @@ -0,0 +1,2 @@ +#require class_template_invalid +<<< __file__ >>>; diff --git a/tests/import/compile_file.c b/tests/plug/compile_file.c similarity index 100% rename from tests/import/compile_file.c rename to tests/plug/compile_file.c diff --git a/tests/plug/compile_file.gw b/tests/plug/compile_file.gw new file mode 100644 index 00000000..ed03ba6a --- /dev/null +++ b/tests/plug/compile_file.gw @@ -0,0 +1,2 @@ +#require compile_file +<<< __file__ >>>; diff --git a/tests/import/compile_string.c b/tests/plug/compile_string.c similarity index 100% rename from tests/import/compile_string.c rename to tests/plug/compile_string.c diff --git a/tests/plug/compile_string.gw b/tests/plug/compile_string.gw new file mode 100644 index 00000000..b6ea861d --- /dev/null +++ b/tests/plug/compile_string.gw @@ -0,0 +1,2 @@ +#require compile_string +<<< __file__ >>>; diff --git a/tests/import/coverage.c b/tests/plug/coverage.c similarity index 100% rename from tests/import/coverage.c rename to tests/plug/coverage.c diff --git a/tests/import/coverage.gw b/tests/plug/coverage.gw similarity index 88% rename from tests/import/coverage.gw rename to tests/plug/coverage.gw index 99b0ccf1..973b0434 100644 --- a/tests/import/coverage.gw +++ b/tests/plug/coverage.gw @@ -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 index 00000000..7f57c641 --- /dev/null +++ b/tests/plug/deps.c @@ -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 index 00000000..eda35760 --- /dev/null +++ b/tests/plug/deps.gw @@ -0,0 +1,3 @@ +#require deps + +<<< __file__ >>>; diff --git a/tests/import/empty_union.c b/tests/plug/empty_union.c similarity index 100% rename from tests/import/empty_union.c rename to tests/plug/empty_union.c diff --git a/tests/plug/empty_union.gw b/tests/plug/empty_union.gw new file mode 100644 index 00000000..6fb2d2c2 --- /dev/null +++ b/tests/plug/empty_union.gw @@ -0,0 +1,2 @@ +#require empty_union +<<< __file__ >>>; diff --git a/tests/import/end_class.c b/tests/plug/end_class.c similarity index 100% rename from tests/import/end_class.c rename to tests/plug/end_class.c diff --git a/tests/plug/end_class.gw b/tests/plug/end_class.gw new file mode 100644 index 00000000..ff98b7fe --- /dev/null +++ b/tests/plug/end_class.gw @@ -0,0 +1,2 @@ +#require end_class +<<< __file__ >>>; diff --git a/tests/import/enum.c b/tests/plug/enum.c similarity index 100% rename from tests/import/enum.c rename to tests/plug/enum.c diff --git a/tests/import/enum.gw b/tests/plug/enum.gw similarity index 98% rename from tests/import/enum.gw rename to tests/plug/enum.gw index 0d8ddb59..a2682e7c 100644 --- a/tests/import/enum.gw +++ b/tests/plug/enum.gw @@ -1,3 +1,4 @@ +#require enum #! untyped global enum <<< ENUM0 >>>; <<< ENUM1 >>>; diff --git a/tests/import/enum_fail.c b/tests/plug/enum_fail.c similarity index 100% rename from tests/import/enum_fail.c rename to tests/plug/enum_fail.c diff --git a/tests/plug/enum_fail.gw b/tests/plug/enum_fail.gw new file mode 100644 index 00000000..8fc00484 --- /dev/null +++ b/tests/plug/enum_fail.gw @@ -0,0 +1,2 @@ +#require enum_fail +<<< __file__ >>>; diff --git a/tests/import/enum_fail2.c b/tests/plug/enum_fail2.c similarity index 100% rename from tests/import/enum_fail2.c rename to tests/plug/enum_fail2.c diff --git a/tests/plug/enum_fail2.gw b/tests/plug/enum_fail2.gw new file mode 100644 index 00000000..d48ebc5e --- /dev/null +++ b/tests/plug/enum_fail2.gw @@ -0,0 +1,2 @@ +#require enum_fail2 +<<< __file__ >>>; diff --git a/tests/import/enum_fail3.c b/tests/plug/enum_fail3.c similarity index 100% rename from tests/import/enum_fail3.c rename to tests/plug/enum_fail3.c diff --git a/tests/plug/enum_fail3.gw b/tests/plug/enum_fail3.gw new file mode 100644 index 00000000..8379ec6a --- /dev/null +++ b/tests/plug/enum_fail3.gw @@ -0,0 +1,2 @@ +#require enum_fail3 +<<< __file__ >>>; diff --git a/tests/import/extend_array.c b/tests/plug/extend_array.c similarity index 100% rename from tests/import/extend_array.c rename to tests/plug/extend_array.c diff --git a/tests/import/extend_array.gw b/tests/plug/extend_array.gw similarity index 67% rename from tests/import/extend_array.gw rename to tests/plug/extend_array.gw index d99718ce..67843c25 100644 --- a/tests/import/extend_array.gw +++ b/tests/plug/extend_array.gw @@ -1,3 +1,4 @@ +#require extend_array var ArrayExt a; <<< a >>>; <<< a.size() >>>; diff --git a/tests/import/fail_on_next_arg.c b/tests/plug/fail_on_next_arg.c similarity index 100% rename from tests/import/fail_on_next_arg.c rename to tests/plug/fail_on_next_arg.c diff --git a/tests/plug/fail_on_next_arg.gw b/tests/plug/fail_on_next_arg.gw new file mode 100644 index 00000000..3bb8daec --- /dev/null +++ b/tests/plug/fail_on_next_arg.gw @@ -0,0 +1,2 @@ +#require fail_on_next_arg +<<< __file__ >>>; diff --git a/tests/import/fail_on_next_arg2.c b/tests/plug/fail_on_next_arg2.c similarity index 100% rename from tests/import/fail_on_next_arg2.c rename to tests/plug/fail_on_next_arg2.c diff --git a/tests/plug/fail_on_next_arg2.gw b/tests/plug/fail_on_next_arg2.gw new file mode 100644 index 00000000..fc189c80 --- /dev/null +++ b/tests/plug/fail_on_next_arg2.gw @@ -0,0 +1,2 @@ +#require fail_on_next_arg2 +<<< __file__ >>>; diff --git a/tests/import/fptr.c b/tests/plug/fptr.c similarity index 100% rename from tests/import/fptr.c rename to tests/plug/fptr.c diff --git a/tests/import/fptr.gw b/tests/plug/fptr.gw similarity index 94% rename from tests/import/fptr.gw rename to tests/plug/fptr.gw index 0acefb39..a427bc71 100644 --- a/tests/import/fptr.gw +++ b/tests/plug/fptr.gw @@ -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/import/fptr_tmpl.c b/tests/plug/fptr_tmpl.c similarity index 100% rename from tests/import/fptr_tmpl.c rename to tests/plug/fptr_tmpl.c diff --git a/tests/plug/fptr_tmpl.gw b/tests/plug/fptr_tmpl.gw new file mode 100644 index 00000000..c67df8af --- /dev/null +++ b/tests/plug/fptr_tmpl.gw @@ -0,0 +1,2 @@ +#require fptr_tmpl +<<< __file__ >>>; diff --git a/tests/import/fptr_tmpl_fail.c b/tests/plug/fptr_tmpl_fail.c similarity index 100% rename from tests/import/fptr_tmpl_fail.c rename to tests/plug/fptr_tmpl_fail.c diff --git a/tests/plug/fptr_tmpl_fail.gw b/tests/plug/fptr_tmpl_fail.gw new file mode 100644 index 00000000..24e85719 --- /dev/null +++ b/tests/plug/fptr_tmpl_fail.gw @@ -0,0 +1,2 @@ +#require fptr_tmpl_fail +<<< __file__ >>>; diff --git a/tests/import/func_fail.c b/tests/plug/func_fail.c similarity index 100% rename from tests/import/func_fail.c rename to tests/plug/func_fail.c diff --git a/tests/plug/func_fail.gw b/tests/plug/func_fail.gw new file mode 100644 index 00000000..5edc24f9 --- /dev/null +++ b/tests/plug/func_fail.gw @@ -0,0 +1,2 @@ +#require func_fail +<<< __file__ >>>; diff --git a/tests/import/func_fail2.c b/tests/plug/func_fail2.c similarity index 100% rename from tests/import/func_fail2.c rename to tests/plug/func_fail2.c diff --git a/tests/plug/func_fail2.gw b/tests/plug/func_fail2.gw new file mode 100644 index 00000000..c2dc9433 --- /dev/null +++ b/tests/plug/func_fail2.gw @@ -0,0 +1,2 @@ +#require func_fail2 +<<< __file__ >>>; diff --git a/tests/import/func_fail3.c b/tests/plug/func_fail3.c similarity index 100% rename from tests/import/func_fail3.c rename to tests/plug/func_fail3.c diff --git a/tests/plug/func_fail3.gw b/tests/plug/func_fail3.gw new file mode 100644 index 00000000..331e4702 --- /dev/null +++ b/tests/plug/func_fail3.gw @@ -0,0 +1,2 @@ +#require func_fail3 +<<< __file__ >>>; diff --git a/tests/import/func_fail4.c b/tests/plug/func_fail4.c similarity index 100% rename from tests/import/func_fail4.c rename to tests/plug/func_fail4.c diff --git a/tests/plug/func_fail4.gw b/tests/plug/func_fail4.gw new file mode 100644 index 00000000..631c2a11 --- /dev/null +++ b/tests/plug/func_fail4.gw @@ -0,0 +1,2 @@ +#require func_fail4 +<<< __file__ >>>; diff --git a/tests/import/func_subscript_not_empty.c b/tests/plug/func_subscript_not_empty.c similarity index 100% rename from tests/import/func_subscript_not_empty.c rename to tests/plug/func_subscript_not_empty.c diff --git a/tests/plug/func_subscript_not_empty.gw b/tests/plug/func_subscript_not_empty.gw new file mode 100644 index 00000000..cfeeab17 --- /dev/null +++ b/tests/plug/func_subscript_not_empty.gw @@ -0,0 +1,2 @@ +#require func_subscript_not_empty +<<< __file__ >>>; diff --git a/tests/import/func_tmpl.c b/tests/plug/func_tmpl.c similarity index 100% rename from tests/import/func_tmpl.c rename to tests/plug/func_tmpl.c diff --git a/tests/import/func_tmpl.gw b/tests/plug/func_tmpl.gw similarity index 55% rename from tests/import/func_tmpl.gw rename to tests/plug/func_tmpl.gw index 5916a402..83974670 100644 --- a/tests/import/func_tmpl.gw +++ b/tests/plug/func_tmpl.gw @@ -1,2 +1,3 @@ +#require func_tmpl test:[int](1); test(1); diff --git a/tests/import/func_tmpl_fail.c b/tests/plug/func_tmpl_fail.c similarity index 100% rename from tests/import/func_tmpl_fail.c rename to tests/plug/func_tmpl_fail.c diff --git a/tests/plug/func_tmpl_fail.gw b/tests/plug/func_tmpl_fail.gw new file mode 100644 index 00000000..1979793f --- /dev/null +++ b/tests/plug/func_tmpl_fail.gw @@ -0,0 +1,2 @@ +#require func_tmpl_fail +<<< __file__ >>>; diff --git a/tests/import/func_too_many_arg.c b/tests/plug/func_too_many_arg.c similarity index 100% rename from tests/import/func_too_many_arg.c rename to tests/plug/func_too_many_arg.c diff --git a/tests/plug/func_too_many_arg.gw b/tests/plug/func_too_many_arg.gw new file mode 100644 index 00000000..b011054c --- /dev/null +++ b/tests/plug/func_too_many_arg.gw @@ -0,0 +1,2 @@ +#require func_too_many_arg +<<< __file__ >>>; diff --git a/tests/import/global_func.c b/tests/plug/global_func.c similarity index 100% rename from tests/import/global_func.c rename to tests/plug/global_func.c diff --git a/tests/import/global_func.gw b/tests/plug/global_func.gw similarity index 61% rename from tests/import/global_func.gw rename to tests/plug/global_func.gw index c4a56122..60703179 100644 --- a/tests/import/global_func.gw +++ b/tests/plug/global_func.gw @@ -1,3 +1,3 @@ +#require global_func <<< test >>>; <<< 1 => test >>>; - diff --git a/tests/import/global_var.c b/tests/plug/global_var.c similarity index 100% rename from tests/import/global_var.c rename to tests/plug/global_var.c diff --git a/tests/import/global_var.gw b/tests/plug/global_var.gw similarity index 73% rename from tests/import/global_var.gw rename to tests/plug/global_var.gw index 3e401b0c..91f4674f 100644 --- a/tests/import/global_var.gw +++ b/tests/plug/global_var.gw @@ -1,3 +1,4 @@ +#require global_var <<< i >>>; <<< "other test" => i >>>; <<< 12 => f >>>; diff --git a/tests/import/invalid_arg.c b/tests/plug/invalid_arg.c similarity index 100% rename from tests/import/invalid_arg.c rename to tests/plug/invalid_arg.c diff --git a/tests/plug/invalid_arg.gw b/tests/plug/invalid_arg.gw new file mode 100644 index 00000000..9223e112 --- /dev/null +++ b/tests/plug/invalid_arg.gw @@ -0,0 +1,2 @@ +#require invalid_arg +<<< __file__ >>>; diff --git a/tests/import/invalid_array.c b/tests/plug/invalid_array.c similarity index 100% rename from tests/import/invalid_array.c rename to tests/plug/invalid_array.c diff --git a/tests/plug/invalid_array.gw b/tests/plug/invalid_array.gw new file mode 100644 index 00000000..0fd80fbc --- /dev/null +++ b/tests/plug/invalid_array.gw @@ -0,0 +1,2 @@ +#require invalid_array +<<< __file__ >>>; diff --git a/tests/import/invalid_func.c b/tests/plug/invalid_func.c similarity index 100% rename from tests/import/invalid_func.c rename to tests/plug/invalid_func.c diff --git a/tests/plug/invalid_func.gw b/tests/plug/invalid_func.gw new file mode 100644 index 00000000..2fc7ae7e --- /dev/null +++ b/tests/plug/invalid_func.gw @@ -0,0 +1,2 @@ +#require invalid_func +<<< __file__ >>>; diff --git a/tests/import/invalid_names.c b/tests/plug/invalid_names.c similarity index 100% rename from tests/import/invalid_names.c rename to tests/plug/invalid_names.c diff --git a/tests/plug/invalid_names.gw b/tests/plug/invalid_names.gw new file mode 100644 index 00000000..6bc71724 --- /dev/null +++ b/tests/plug/invalid_names.gw @@ -0,0 +1,2 @@ +#require invalid_names +<<< __file__ >>>; diff --git a/tests/import/invalid_names0.c b/tests/plug/invalid_names0.c similarity index 100% rename from tests/import/invalid_names0.c rename to tests/plug/invalid_names0.c diff --git a/tests/plug/invalid_names0.gw b/tests/plug/invalid_names0.gw new file mode 100644 index 00000000..76e1027a --- /dev/null +++ b/tests/plug/invalid_names0.gw @@ -0,0 +1,2 @@ +#require invalid_names0 +<<< __file__ >>>; diff --git a/tests/import/invalid_names1.c b/tests/plug/invalid_names1.c similarity index 100% rename from tests/import/invalid_names1.c rename to tests/plug/invalid_names1.c diff --git a/tests/plug/invalid_names1.gw b/tests/plug/invalid_names1.gw new file mode 100644 index 00000000..b2dc86c2 --- /dev/null +++ b/tests/plug/invalid_names1.gw @@ -0,0 +1,2 @@ +#require invalid_names1 +<<< __file__ >>>; diff --git a/tests/import/invalid_names2.c b/tests/plug/invalid_names2.c similarity index 100% rename from tests/import/invalid_names2.c rename to tests/plug/invalid_names2.c diff --git a/tests/plug/invalid_names2.gw b/tests/plug/invalid_names2.gw new file mode 100644 index 00000000..6be95ab7 --- /dev/null +++ b/tests/plug/invalid_names2.gw @@ -0,0 +1,2 @@ +#require invalid_names2 +<<< __file__ >>>; diff --git a/tests/import/invalid_names3.c b/tests/plug/invalid_names3.c similarity index 100% rename from tests/import/invalid_names3.c rename to tests/plug/invalid_names3.c diff --git a/tests/plug/invalid_names3.gw b/tests/plug/invalid_names3.gw new file mode 100644 index 00000000..234a3b48 --- /dev/null +++ b/tests/plug/invalid_names3.gw @@ -0,0 +1,2 @@ +#require invalid_names3 +<<< __file__ >>>; diff --git a/tests/import/invalid_type1.c b/tests/plug/invalid_type1.c similarity index 100% rename from tests/import/invalid_type1.c rename to tests/plug/invalid_type1.c diff --git a/tests/plug/invalid_type1.gw b/tests/plug/invalid_type1.gw new file mode 100644 index 00000000..0e7cd1f9 --- /dev/null +++ b/tests/plug/invalid_type1.gw @@ -0,0 +1,2 @@ +#require invalid_type1 +<<< __file__ >>>; diff --git a/tests/import/invalid_type2.c b/tests/plug/invalid_type2.c similarity index 100% rename from tests/import/invalid_type2.c rename to tests/plug/invalid_type2.c diff --git a/tests/plug/invalid_type2.gw b/tests/plug/invalid_type2.gw new file mode 100644 index 00000000..62325e5b --- /dev/null +++ b/tests/plug/invalid_type2.gw @@ -0,0 +1,2 @@ +#require invalid_type2 +<<< __file__ >>>; diff --git a/tests/import/invalid_type3.c b/tests/plug/invalid_type3.c similarity index 100% rename from tests/import/invalid_type3.c rename to tests/plug/invalid_type3.c diff --git a/tests/plug/invalid_type3.gw b/tests/plug/invalid_type3.gw new file mode 100644 index 00000000..d7413bb5 --- /dev/null +++ b/tests/plug/invalid_type3.gw @@ -0,0 +1,2 @@ +#require invalid_type3 +<<< __file__ >>>; diff --git a/tests/import/map2.gw b/tests/plug/map2.gw similarity index 100% rename from tests/import/map2.gw rename to tests/plug/map2.gw diff --git a/tests/import/mk_type_array.c b/tests/plug/mk_type_array.c similarity index 100% rename from tests/import/mk_type_array.c rename to tests/plug/mk_type_array.c diff --git a/tests/plug/mk_type_array.gw b/tests/plug/mk_type_array.gw new file mode 100644 index 00000000..28fda930 --- /dev/null +++ b/tests/plug/mk_type_array.gw @@ -0,0 +1,2 @@ +#require mk_type_array +<<< __file__ >>>; diff --git a/tests/import/no_import.c b/tests/plug/no_import.c similarity index 100% rename from tests/import/no_import.c rename to tests/plug/no_import.c diff --git a/tests/plug/no_import.gw b/tests/plug/no_import.gw new file mode 100644 index 00000000..dd075818 --- /dev/null +++ b/tests/plug/no_import.gw @@ -0,0 +1,2 @@ +#require no_import +<<< __file__ >>>; diff --git a/tests/import/not_importing.c b/tests/plug/not_importing.c similarity index 100% rename from tests/import/not_importing.c rename to tests/plug/not_importing.c diff --git a/tests/plug/not_importing.gw b/tests/plug/not_importing.gw new file mode 100644 index 00000000..933e07b6 --- /dev/null +++ b/tests/plug/not_importing.gw @@ -0,0 +1,2 @@ +#require not_importing +<<< __file__ >>>; diff --git a/tests/import/op_already_imported.c b/tests/plug/op_already_imported.c similarity index 99% rename from tests/import/op_already_imported.c rename to tests/plug/op_already_imported.c index 0454a3f1..4a527ec7 100644 --- a/tests/import/op_already_imported.c +++ b/tests/plug/op_already_imported.c @@ -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)) diff --git a/tests/import/op_already_imported.gw b/tests/plug/op_already_imported.gw similarity index 59% rename from tests/import/op_already_imported.gw rename to tests/plug/op_already_imported.gw index 2bfc227d..9cd44406 100644 --- a/tests/import/op_already_imported.gw +++ b/tests/plug/op_already_imported.gw @@ -1,2 +1,3 @@ +#require op_already_imported #! [contains] already imported <<< 1 >>>; diff --git a/tests/import/pass.c b/tests/plug/pass.c 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 index 00000000..233e1f2e --- /dev/null +++ b/tests/plug/pass.gw @@ -0,0 +1,2 @@ +#require pass +<<< __file__ >>>; diff --git a/tests/import/rm_me.gw b/tests/plug/rm_me.gw similarity index 100% rename from tests/import/rm_me.gw rename to tests/plug/rm_me.gw diff --git a/tests/import/specialid_emit.c b/tests/plug/specialid_emit.c similarity index 100% rename from tests/import/specialid_emit.c rename to tests/plug/specialid_emit.c diff --git a/tests/plug/specialid_emit.gw b/tests/plug/specialid_emit.gw new file mode 100644 index 00000000..0eec0eba --- /dev/null +++ b/tests/plug/specialid_emit.gw @@ -0,0 +1,2 @@ +#require specialid_emit +<<< testid >>>; diff --git a/tests/import/static_string.c b/tests/plug/static_string.c similarity index 100% rename from tests/import/static_string.c rename to tests/plug/static_string.c diff --git a/tests/import/static_string.gw b/tests/plug/static_string.gw similarity index 65% rename from tests/import/static_string.gw rename to tests/plug/static_string.gw index dc3f911a..f94a3bd5 100644 --- a/tests/import/static_string.gw +++ b/tests/plug/static_string.gw @@ -1,2 +1,3 @@ +#require static_string #!<<< StaticString.self >>>; <<< self >>>; diff --git a/tests/import/str2decl.c b/tests/plug/str2decl.c similarity index 100% rename from tests/import/str2decl.c rename to tests/plug/str2decl.c diff --git a/tests/plug/str2decl.gw b/tests/plug/str2decl.gw new file mode 100644 index 00000000..9532ca7d --- /dev/null +++ b/tests/plug/str2decl.gw @@ -0,0 +1,2 @@ +#require str2decl +<<< __file__ >>>; diff --git a/tests/import/str2list_fail.c b/tests/plug/str2list_fail.c similarity index 100% rename from tests/import/str2list_fail.c rename to tests/plug/str2list_fail.c diff --git a/tests/plug/str2list_fail.gw b/tests/plug/str2list_fail.gw new file mode 100644 index 00000000..57d81272 --- /dev/null +++ b/tests/plug/str2list_fail.gw @@ -0,0 +1,2 @@ +#require str2list_fail +<<< __file__ >>>; diff --git a/tests/plug/struct.c b/tests/plug/struct.c new file mode 100644 index 00000000..0f95038c --- /dev/null +++ b/tests/plug/struct.c @@ -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 index 00000000..d3ecf582 --- /dev/null +++ b/tests/plug/struct.gw @@ -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/import/template_arg.c b/tests/plug/template_arg.c similarity index 100% rename from tests/import/template_arg.c rename to tests/plug/template_arg.c diff --git a/tests/plug/template_arg.gw b/tests/plug/template_arg.gw new file mode 100644 index 00000000..b65012fa --- /dev/null +++ b/tests/plug/template_arg.gw @@ -0,0 +1,2 @@ +#require template_arg +<<< __file__ >>>; diff --git a/tests/import/trig.c b/tests/plug/trig.c similarity index 100% rename from tests/import/trig.c rename to tests/plug/trig.c diff --git a/tests/import/trig.gw b/tests/plug/trig.gw similarity index 89% rename from tests/import/trig.gw rename to tests/plug/trig.gw index cbc5f36e..849d12aa 100644 --- a/tests/import/trig.gw +++ b/tests/plug/trig.gw @@ -1,3 +1,4 @@ +#require trig var Trig trig => dac; adc :=> trig; adc :=< trig; diff --git a/tests/import/typedef.c b/tests/plug/typedef.c similarity index 100% rename from tests/import/typedef.c rename to tests/plug/typedef.c diff --git a/tests/import/typedef.gw b/tests/plug/typedef.gw similarity index 81% rename from tests/import/typedef.gw rename to tests/plug/typedef.gw index ea3d603e..8a3ec9b2 100644 --- a/tests/import/typedef.gw +++ b/tests/plug/typedef.gw @@ -1,3 +1,4 @@ +#require typedef var Typedef t; #!fun int test(int i) { <<< i >>>; } #!test @=> t; diff --git a/tests/import/typedef_fail.c b/tests/plug/typedef_fail.c similarity index 100% rename from tests/import/typedef_fail.c rename to tests/plug/typedef_fail.c diff --git a/tests/plug/typedef_fail.gw b/tests/plug/typedef_fail.gw new file mode 100644 index 00000000..c1b0f5ec --- /dev/null +++ b/tests/plug/typedef_fail.gw @@ -0,0 +1,2 @@ +#require typedef_fail +<<< __file__ >>>; diff --git a/tests/import/typedef_tmpl.c b/tests/plug/typedef_tmpl.c similarity index 100% rename from tests/import/typedef_tmpl.c rename to tests/plug/typedef_tmpl.c diff --git a/tests/plug/typedef_tmpl.gw b/tests/plug/typedef_tmpl.gw new file mode 100644 index 00000000..c98fc082 --- /dev/null +++ b/tests/plug/typedef_tmpl.gw @@ -0,0 +1,2 @@ +#require typedef_tmpl +<<< __file__ >>>; diff --git a/tests/import/ugen_connect.c b/tests/plug/ugen_connect.c similarity index 100% rename from tests/import/ugen_connect.c rename to tests/plug/ugen_connect.c diff --git a/tests/plug/ugen_connect.gw b/tests/plug/ugen_connect.gw new file mode 100644 index 00000000..cf2a999d --- /dev/null +++ b/tests/plug/ugen_connect.gw @@ -0,0 +1,2 @@ +#require ugen_connect +<<< __file__ >>>; diff --git a/tests/import/union.c b/tests/plug/union.c similarity index 100% rename from tests/import/union.c rename to tests/plug/union.c diff --git a/tests/import/union.gw b/tests/plug/union.gw similarity index 89% rename from tests/import/union.gw rename to tests/plug/union.gw index d32885de..591ef1cf 100644 --- a/tests/import/union.gw +++ b/tests/plug/union.gw @@ -1,3 +1,4 @@ +#require union var Union u; <<< u.i >>>; <<< 12 => u.f >>>; diff --git a/tests/import/union_fail_exp.c b/tests/plug/union_fail_exp.c similarity index 100% rename from tests/import/union_fail_exp.c rename to tests/plug/union_fail_exp.c diff --git a/tests/plug/union_fail_exp.gw b/tests/plug/union_fail_exp.gw new file mode 100644 index 00000000..27d1a699 --- /dev/null +++ b/tests/plug/union_fail_exp.gw @@ -0,0 +1,2 @@ +#require union_fail_exp +<<< __file__ >>>; diff --git a/tests/import/union_member.c b/tests/plug/union_member.c similarity index 100% rename from tests/import/union_member.c rename to tests/plug/union_member.c diff --git a/tests/plug/union_member.gw b/tests/plug/union_member.gw new file mode 100644 index 00000000..a743ff4e --- /dev/null +++ b/tests/plug/union_member.gw @@ -0,0 +1,2 @@ +#require union_member +<<< __file__ >>>; diff --git a/tests/import/union_name.c b/tests/plug/union_name.c similarity index 100% rename from tests/import/union_name.c rename to tests/plug/union_name.c diff --git a/tests/import/union_name.gw b/tests/plug/union_name.gw similarity index 64% rename from tests/import/union_name.gw rename to tests/plug/union_name.gw index c5ad1d05..38216c55 100644 --- a/tests/import/union_name.gw +++ b/tests/plug/union_name.gw @@ -1,2 +1,3 @@ +#require union_name <<< my_union >>>; <<>>; diff --git a/tests/import/union_tmpl.c b/tests/plug/union_tmpl.c similarity index 100% rename from tests/import/union_tmpl.c rename to tests/plug/union_tmpl.c diff --git a/tests/import/union_tmpl.gw b/tests/plug/union_tmpl.gw similarity index 64% rename from tests/import/union_tmpl.gw rename to tests/plug/union_tmpl.gw index 5d6c0c60..a7ac5d4d 100644 --- a/tests/import/union_tmpl.gw +++ b/tests/plug/union_tmpl.gw @@ -1,2 +1,3 @@ +#require union_tmpl <<< var U:[Event] u>>>; <<< u.a >>>; diff --git a/tests/import/union_tmpl_fail.c b/tests/plug/union_tmpl_fail.c similarity index 100% rename from tests/import/union_tmpl_fail.c rename to tests/plug/union_tmpl_fail.c diff --git a/tests/plug/union_tmpl_fail.gw b/tests/plug/union_tmpl_fail.gw new file mode 100644 index 00000000..c70c688b --- /dev/null +++ b/tests/plug/union_tmpl_fail.gw @@ -0,0 +1,2 @@ +#require union_tmpl_fail +<<< __file__ >>>; diff --git a/tests/import/union_tmpl_fail2.c b/tests/plug/union_tmpl_fail2.c similarity index 100% rename from tests/import/union_tmpl_fail2.c rename to tests/plug/union_tmpl_fail2.c diff --git a/tests/plug/union_tmpl_fail2.gw b/tests/plug/union_tmpl_fail2.gw new file mode 100644 index 00000000..06566c78 --- /dev/null +++ b/tests/plug/union_tmpl_fail2.gw @@ -0,0 +1,2 @@ +#require union_tmpl_fail2 +<<< __file__ >>>; diff --git a/tests/import/union_tmpl_fail3.c b/tests/plug/union_tmpl_fail3.c similarity index 100% rename from tests/import/union_tmpl_fail3.c rename to tests/plug/union_tmpl_fail3.c diff --git a/tests/plug/union_tmpl_fail3.gw b/tests/plug/union_tmpl_fail3.gw new file mode 100644 index 00000000..b888fa14 --- /dev/null +++ b/tests/plug/union_tmpl_fail3.gw @@ -0,0 +1,2 @@ +#require union_tmpl_fail3 +<<< __file__ >>>; diff --git a/tests/import/variadic.c b/tests/plug/variadic.c similarity index 91% rename from tests/import/variadic.c rename to tests/plug/variadic.c index 4d398a65..a34b3e2f 100644 --- a/tests/import/variadic.c +++ b/tests/plug/variadic.c @@ -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)) diff --git a/tests/import/variadic.gw b/tests/plug/variadic.gw similarity index 94% rename from tests/import/variadic.gw rename to tests/plug/variadic.gw index 3213c303..48f8b575 100644 --- a/tests/import/variadic.gw +++ b/tests/plug/variadic.gw @@ -1,3 +1,4 @@ +#require variadic <<< "test builtin variadic fun" >>>; var Variadic v; "iiii" => var string format; diff --git a/tests/import/vm_remove.c b/tests/plug/vm_remove.c similarity index 100% rename from tests/import/vm_remove.c rename to tests/plug/vm_remove.c diff --git a/tests/import/vm_remove.gw b/tests/plug/vm_remove.gw similarity index 50% rename from tests/import/vm_remove.gw rename to tests/plug/vm_remove.gw index 31429431..85078c1a 100644 --- a/tests/import/vm_remove.gw +++ b/tests/plug/vm_remove.gw @@ -1,2 +1,3 @@ +#require vm_remove test(12); test(1); diff --git a/tests/sh/import.sh b/tests/sh/import.sh index 3687b21c..93aacb3f 100644 --- a/tests/sh/import.sh +++ b/tests/sh/import.sh @@ -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 diff --git a/tests/sh/opt.sh b/tests/sh/opt.sh index 796fc58e..4cf3e21d 100644 --- a/tests/sh/opt.sh +++ b/tests/sh/opt.sh @@ -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 index 00000000..93eb65ab --- /dev/null +++ b/tests/string/charAt.gw @@ -0,0 +1,7 @@ +<<< "".charAt(-1) >>>; +<<< "".charAt(2) >>>; +<<< " test String ".charAt(2) >>>; + +<<< "test".charAt(-1, 'c') >>>; +<<< "test".charAt(12, 'c') >>>; +<<< "test".charAt(2, 'c') >>>; diff --git a/tests/string/eq.gw b/tests/string/eq.gw index 14ace808..f2b95b86 100644 --- a/tests/string/eq.gw +++ b/tests/string/eq.gw @@ -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 index 00000000..6c42ccad --- /dev/null +++ b/tests/string/find.gw @@ -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 index 00000000..9336a2bf --- /dev/null +++ b/tests/string/lower.gw @@ -0,0 +1 @@ +<<< "Test String".lower() >>>; diff --git a/tests/string/ltrim.gw b/tests/string/ltrim.gw new file mode 100644 index 00000000..937fcb12 --- /dev/null +++ b/tests/string/ltrim.gw @@ -0,0 +1,2 @@ +<<< "".ltrim() >>>; +<<< " test String ".ltrim() >>>; diff --git a/tests/string/rtrim.gw b/tests/string/rtrim.gw new file mode 100644 index 00000000..cf0645c0 --- /dev/null +++ b/tests/string/rtrim.gw @@ -0,0 +1,2 @@ +<<< "".rtrim() >>>; +<<< " test String ".rtrim() >>>; diff --git a/tests/string/size.gw b/tests/string/size.gw new file mode 100644 index 00000000..3f7539a9 --- /dev/null +++ b/tests/string/size.gw @@ -0,0 +1 @@ +<<< "test".size() >>>; diff --git a/tests/string/trim.gw b/tests/string/trim.gw new file mode 100644 index 00000000..32adde6e --- /dev/null +++ b/tests/string/trim.gw @@ -0,0 +1,2 @@ +<<< "".trim() >>>; +<<< " test String ".trim() >>>; diff --git a/tests/string/upper.gw b/tests/string/upper.gw new file mode 100644 index 00000000..f8081c9b --- /dev/null +++ b/tests/string/upper.gw @@ -0,0 +1 @@ +<<< "test String".upper() >>>; diff --git a/tests/struct/struct_template.gw b/tests/struct/struct_template.gw index c9291cc2..a0b14b71 100644 --- a/tests/struct/struct_template.gw +++ b/tests/struct/struct_template.gw @@ -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 45dd7625..3566515f 160000 --- a/util +++ b/util @@ -1 +1 @@ -Subproject commit 45dd762586ca0cda722a07baef5077e9460c9442 +Subproject commit 3566515fee16924098da38bf99deb669cd617d5b -- 2.43.0