From 9591d6c1765f7e24bf4c1677d99900f406237ff6 Mon Sep 17 00:00:00 2001 From: bog Date: Fri, 22 Sep 2023 14:17:21 +0200 Subject: [PATCH] ADD: set core macro. --- examples/set.fk | 21 +++++++++++++++++++++ libstd/commons.hpp | 2 ++ libstd/fun.cpp | 28 +++++++++++++-------------- libstd/fun.hpp | 30 +++++++++++++++-------------- libstd/lib.cpp | 5 +++-- libstd/macro.cpp | 11 +++++++++++ libstd/macro.hpp | 4 ++++ src/Module.cpp | 4 ++-- src/Module.hpp | 6 ++++-- src/NativeFunction.cpp | 4 +++- src/NativeFunction.hpp | 10 ++++++++-- src/NativeMacro.hpp | 1 + src/SymTable.cpp | 43 ++++++++++++++++++++++++++++++++++++------ src/SymTable.hpp | 2 ++ src/VM.cpp | 5 +++-- src/VM.hpp | 4 +++- 16 files changed, 134 insertions(+), 46 deletions(-) create mode 100644 examples/set.fk diff --git a/examples/set.fk b/examples/set.fk new file mode 100644 index 0000000..6f32e50 --- /dev/null +++ b/examples/set.fk @@ -0,0 +1,21 @@ +($ a 32) + +(! a 54) + +(assert= 54 a) + +(: + ($ a 12) + (! a 99) + (assert= 99 a) +) + +(assert= 54 a) + +($ f (-> (x) (+ 2 x))) + +(assert= 5 (f 3)) + +(! f (-> (x) (* x 4))) + +(assert= 12 (f 3)) \ No newline at end of file diff --git a/libstd/commons.hpp b/libstd/commons.hpp index ff957b5..a79118a 100644 --- a/libstd/commons.hpp +++ b/libstd/commons.hpp @@ -4,11 +4,13 @@ #include #include "../src/Module.hpp" #include "../src/Constant.hpp" +#include "../src/SymTable.hpp" using namespace fk; #define STDARGS std::vector> #define STDRET std::shared_ptr +#define STDSYM std::shared_ptr FK_ERROR(assert_error); diff --git a/libstd/fun.cpp b/libstd/fun.cpp index 07ab202..8734cb9 100644 --- a/libstd/fun.cpp +++ b/libstd/fun.cpp @@ -20,7 +20,7 @@ namespace fkstd { - STDRET assert_eq(Loc loc, STDARGS args) + STDRET assert_eq(Loc loc, Module&, STDARGS args) { auto oracle = args[0]; auto expr = args[1]; @@ -40,7 +40,7 @@ namespace fkstd return std::make_shared(TYPE_BOOL, true, loc); } - STDRET println(Loc loc, STDARGS args) + STDRET println(Loc loc, Module&, STDARGS args) { std::string sep; @@ -60,7 +60,7 @@ namespace fkstd return std::make_shared(TYPE_INT, 0, loc); } - STDRET add_int(Loc loc, STDARGS args) + STDRET add_int(Loc loc, Module&, STDARGS args) { int result = 0; @@ -72,7 +72,7 @@ namespace fkstd return std::make_shared(TYPE_INT, result, loc); } - STDRET sub_int(Loc loc, STDARGS args) + STDRET sub_int(Loc loc, Module&, STDARGS args) { if (args.empty()) { @@ -96,7 +96,7 @@ namespace fkstd return std::make_shared(TYPE_INT, result, loc); } - STDRET mul_int(Loc loc, STDARGS args) + STDRET mul_int(Loc loc, Module&, STDARGS args) { int result = 1; @@ -108,7 +108,7 @@ namespace fkstd return std::make_shared(TYPE_INT, result, loc); } - STDRET div_int(Loc loc, STDARGS args) + STDRET div_int(Loc loc, Module&, STDARGS args) { if (args.empty()) { @@ -132,7 +132,7 @@ namespace fkstd return std::make_shared(TYPE_INT, result, loc); } - STDRET mod_int(Loc loc, STDARGS args) + STDRET mod_int(Loc loc, Module&, STDARGS args) { if (args.empty()) { @@ -149,7 +149,7 @@ namespace fkstd return std::make_shared(TYPE_INT, result, loc); } - STDRET pow_int(Loc loc, STDARGS args) + STDRET pow_int(Loc loc, Module&, STDARGS args) { if (args.empty()) { @@ -166,32 +166,32 @@ namespace fkstd return std::make_shared(TYPE_INT, result, loc); } - STDRET lt(Loc loc, STDARGS args) + STDRET lt(Loc loc, Module&, STDARGS args) { NUM_BINOP(<); } - STDRET le(Loc loc, STDARGS args) + STDRET le(Loc loc, Module&, STDARGS args) { NUM_BINOP(<=); } - STDRET gt(Loc loc, STDARGS args) + STDRET gt(Loc loc, Module&, STDARGS args) { NUM_BINOP(>); } - STDRET ge(Loc loc, STDARGS args) + STDRET ge(Loc loc, Module&, STDARGS args) { NUM_BINOP(>=); } - STDRET eq(Loc loc, STDARGS args) + STDRET eq(Loc loc, Module&, STDARGS args) { NUM_BINOP(==); } - STDRET ne(Loc loc, STDARGS args) + STDRET ne(Loc loc, Module&, STDARGS args) { NUM_BINOP(!=); } diff --git a/libstd/fun.hpp b/libstd/fun.hpp index 8d3ecca..776ac77 100644 --- a/libstd/fun.hpp +++ b/libstd/fun.hpp @@ -4,22 +4,24 @@ namespace fkstd { - STDRET assert_eq(Loc loc, STDARGS args); - STDRET println(Loc loc, STDARGS args); + STDRET set(Loc loc, Module& mod, STDARGS args); - STDRET add_int(Loc loc, STDARGS args); - STDRET sub_int(Loc loc, STDARGS args); - STDRET mul_int(Loc loc, STDARGS args); - STDRET div_int(Loc loc, STDARGS args); - STDRET mod_int(Loc loc, STDARGS args); - STDRET pow_int(Loc loc, STDARGS args); + STDRET assert_eq(Loc loc, Module& mod, STDARGS args); + STDRET println(Loc loc, Module& mod, STDARGS args); - STDRET lt(Loc loc, STDARGS args); - STDRET le(Loc loc, STDARGS args); - STDRET gt(Loc loc, STDARGS args); - STDRET ge(Loc loc, STDARGS args); - STDRET eq(Loc loc, STDARGS args); - STDRET ne(Loc loc, STDARGS args); + STDRET add_int(Loc loc, Module& mod, STDARGS args); + STDRET sub_int(Loc loc, Module& mod, STDARGS args); + STDRET mul_int(Loc loc, Module& mod, STDARGS args); + STDRET div_int(Loc loc, Module& mod, STDARGS args); + STDRET mod_int(Loc loc, Module& mod, STDARGS args); + STDRET pow_int(Loc loc, Module& mod, STDARGS args); + + STDRET lt(Loc loc, Module& mod, STDARGS args); + STDRET le(Loc loc, Module& mod, STDARGS args); + STDRET gt(Loc loc, Module& mod, STDARGS args); + STDRET ge(Loc loc, Module& mod, STDARGS args); + STDRET eq(Loc loc, Module& mod, STDARGS args); + STDRET ne(Loc loc, Module& mod, STDARGS args); } #endif diff --git a/libstd/lib.cpp b/libstd/lib.cpp index 50a4b6c..b541584 100644 --- a/libstd/lib.cpp +++ b/libstd/lib.cpp @@ -2,11 +2,11 @@ #include "fun.hpp" #include "macro.hpp" -Module* glob_mod; +Module* _module; extern "C" void lib(Module& mod) { - glob_mod = &mod; + _module = &mod; mod.register_function("assert=", fkstd::assert_eq); mod.register_function("println", fkstd::println); mod.register_function("+", fkstd::add_int); @@ -22,6 +22,7 @@ extern "C" void lib(Module& mod) mod.register_function("=", fkstd::eq); mod.register_function("<>", fkstd::ne); + mod.register_macro("!", fkstd::set_addr); mod.register_macro("assert-static-fail", fkstd::assert_static_fail); mod.register_macro(":", fkstd::block); mod.register_macro("$", fkstd::decl); diff --git a/libstd/macro.cpp b/libstd/macro.cpp index 44206b9..4ed4fd7 100644 --- a/libstd/macro.cpp +++ b/libstd/macro.cpp @@ -3,6 +3,17 @@ namespace fkstd { + void set_addr(Compiler& compiler, + std::shared_ptr node, + std::shared_ptr program) + { + auto ident = node->child(1)->repr(); + compiler.compile_prog(node->child(2), program); + + auto entry = compiler.sym()->find(ident); + program->add(OP_STORE_LOCAL, entry->addr()); + } + void assert_static_fail(Compiler& compiler, std::shared_ptr node, std::shared_ptr program) diff --git a/libstd/macro.hpp b/libstd/macro.hpp index 0076488..79b27a8 100644 --- a/libstd/macro.hpp +++ b/libstd/macro.hpp @@ -4,6 +4,10 @@ namespace fkstd { + void set_addr(Compiler& compiler, + std::shared_ptr node, + std::shared_ptr program); + void assert_static_fail(Compiler& compiler, std::shared_ptr node, std::shared_ptr program); diff --git a/src/Module.cpp b/src/Module.cpp index 9666d03..686a86c 100644 --- a/src/Module.cpp +++ b/src/Module.cpp @@ -20,9 +20,9 @@ namespace fk import_std(); m_source = load_sources(); m_ast = m_parser->parse(m_source); + m_program = m_compiler->compile(m_ast); - auto program = m_compiler->compile(m_ast); - m_vm->mount(program); + m_vm->mount(m_program); m_vm->run(); } diff --git a/src/Module.hpp b/src/Module.hpp index bc5ae48..08a5de5 100644 --- a/src/Module.hpp +++ b/src/Module.hpp @@ -18,6 +18,8 @@ namespace fk explicit Module(std::filesystem::path source_path); virtual ~Module(); + std::shared_ptr program() const { return m_program; } + std::shared_ptr sym() const { return m_sym; } std::shared_ptr vm() const { return m_vm; } void build(); @@ -37,8 +39,8 @@ namespace fk std::shared_ptr m_sym = std::make_shared(); std::shared_ptr m_compiler = std::make_shared(m_sym); std::shared_ptr m_ast; - std::shared_ptr m_vm = std::make_shared(); - + std::shared_ptr m_vm = std::make_shared(*this); + std::shared_ptr m_program = std::make_shared(); std::string load_sources(); }; } diff --git a/src/NativeFunction.cpp b/src/NativeFunction.cpp index c1e23f3..cb3db43 100644 --- a/src/NativeFunction.cpp +++ b/src/NativeFunction.cpp @@ -1,4 +1,5 @@ #include "NativeFunction.hpp" +#include "Module.hpp" namespace fk { @@ -13,8 +14,9 @@ namespace fk std::shared_ptr NativeFunction::call(Loc const& loc, + Module& mod, std::vector> args) { - return m_native(loc, args); + return m_native(loc, mod, args); } } diff --git a/src/NativeFunction.hpp b/src/NativeFunction.hpp index 0a0cc5b..3813d7a 100644 --- a/src/NativeFunction.hpp +++ b/src/NativeFunction.hpp @@ -6,8 +6,12 @@ namespace fk { + class Module; + using native_t = std::function - (Loc, std::vector>)>; + (Loc, + Module&, + std::vector>)>; class NativeFunction { @@ -16,7 +20,9 @@ namespace fk virtual ~NativeFunction(); std::shared_ptr - call(Loc const& loc, std::vector> args); + call(Loc const& loc, + Module& mod, + std::vector> args); private: native_t m_native; diff --git a/src/NativeMacro.hpp b/src/NativeMacro.hpp index 2c3014e..fb46591 100644 --- a/src/NativeMacro.hpp +++ b/src/NativeMacro.hpp @@ -7,6 +7,7 @@ namespace fk { class Compiler; class Program; + class SymTable; class Node; using macro_t = std::function SymTable::find(std::string const& name) + { + auto idx = find_idx(name); + if (!idx) { return std::nullopt; } + + return m_entries[*idx]; + } + + std::optional SymTable::find_idx(std::string const& name) { std::optional result; + size_t i=0; + std::optional idx; + for (auto& entry: m_entries) { if (entry.name() == name && entry.is_global()) { result = entry; + idx = i; } else if (entry.name() == name - && entry.scope() <= m_scope - && ((entry.parent() == nullptr && m_parents.empty()) - || entry.parent() == m_parents.back()) - && (result == std::nullopt || - entry.scope() > result->scope())) + && entry.scope() <= m_scope + && ((entry.parent() == nullptr && m_parents.empty()) + || entry.parent() == m_parents.back()) + && (result == std::nullopt || + entry.scope() > result->scope())) { result = entry; + idx = i; } + + i++; } - return result; + return idx; + } + + void SymTable::set(std::string const& name, addr_t addr) + { + if (auto idx = find_idx(name); + idx) + { + m_entries[*idx].set_addr(addr); + } + else + { + std::cerr << "cannot set value to '" + << name + << "'" << std::endl; + abort(); + } } std::string SymTable::string() const diff --git a/src/SymTable.hpp b/src/SymTable.hpp index f487cc7..0564110 100644 --- a/src/SymTable.hpp +++ b/src/SymTable.hpp @@ -23,6 +23,8 @@ namespace fk Loc const& loc); std::optional find(std::string const& name); + std::optional find_idx(std::string const& name); + void set(std::string const& name, addr_t addr); std::string string() const; diff --git a/src/VM.cpp b/src/VM.cpp index 25c162c..6e93633 100644 --- a/src/VM.cpp +++ b/src/VM.cpp @@ -4,7 +4,8 @@ namespace fk { - /*explicit*/ VM::VM() + /*explicit*/ VM::VM(Module& mod) + : m_mod { mod } { } @@ -150,7 +151,7 @@ namespace fk auto fun = std::get> (load_global(ref)); - push(frame().program->add(fun->call(loc, args))); + push(frame().program->add(fun->call(loc, m_mod, args))); m_pc++; } break; diff --git a/src/VM.hpp b/src/VM.hpp index 505ef1d..2127783 100644 --- a/src/VM.hpp +++ b/src/VM.hpp @@ -18,11 +18,12 @@ namespace fk size_t stack_sz; std::unordered_map> locals; }; + class Module; class VM { public: - explicit VM(); + explicit VM(Module& mod); virtual ~VM(); Frame& frame() { return m_frames.back(); } @@ -57,6 +58,7 @@ namespace fk Loc const& loc); private: + Module& m_mod; addr_t m_pc = 0; std::vector m_frames; std::vector m_stack;