From d973241ae2932da3f8c8e54536944c380da102e0 Mon Sep 17 00:00:00 2001 From: bog Date: Mon, 25 Sep 2023 21:28:57 +0200 Subject: [PATCH] ADD: truncat function and fix some bugs related to the closure mechanism. --- examples/cast.fk | 1 + examples/closure.fk | 31 ++++++++++++++++++++++++++++++- libstd/commons.hpp | 5 +---- libstd/fun.cpp | 7 +++++++ libstd/fun.hpp | 1 + libstd/lib.cpp | 2 ++ meson.build | 4 ++++ src/Compiler.cpp | 27 ++++++++++++++++++++------- src/Compiler.hpp | 2 ++ src/Constant.cpp | 1 + src/Constant.hpp | 1 + src/Module.cpp | 7 ++++++- src/Module.hpp | 1 + src/SymTable.cpp | 16 ++++++++++++++++ src/SymTable.hpp | 2 ++ src/VM.cpp | 39 ++++++++++++++++++++++++++++++++++----- src/commons.hpp | 4 ++++ src/types.hpp | 2 +- 18 files changed, 134 insertions(+), 19 deletions(-) create mode 100644 examples/cast.fk diff --git a/examples/cast.fk b/examples/cast.fk new file mode 100644 index 0000000..46ddc92 --- /dev/null +++ b/examples/cast.fk @@ -0,0 +1 @@ +(assert= 8 (trunc 8.71)) \ No newline at end of file diff --git a/examples/closure.fk b/examples/closure.fk index 1dafd0b..aa065e8 100644 --- a/examples/closure.fk +++ b/examples/closure.fk @@ -13,4 +13,33 @@ (assert= 33 (b)) (assert= 6 (a)) (assert= 7 (a)) -(assert= 34 (b)) \ No newline at end of file +(assert= 34 (b)) + +($ (c) 42) + +($ (d) + (+ (c) 1)) + +(assert= 43 (d)) + + +($ hello 34) + +($ (i) + ($ (j) + ($ (k) + (println hello)))) + +(((i))) + +($ @m './mod2') + +($ (u) + ($ (v) + ($ (w) + (assert= 42 m::var) + (assert= 14 (m::fun 7)) + 259 ))) + +(assert= 42 ((-> () m::var))) +(assert= 259 (((u)))) diff --git a/libstd/commons.hpp b/libstd/commons.hpp index a79118a..3e97a98 100644 --- a/libstd/commons.hpp +++ b/libstd/commons.hpp @@ -2,16 +2,13 @@ #define fkstd_COMMONS_HPP #include +#include "../src/commons.hpp" #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); #endif diff --git a/libstd/fun.cpp b/libstd/fun.cpp index c86c8c9..84ed888 100644 --- a/libstd/fun.cpp +++ b/libstd/fun.cpp @@ -278,6 +278,13 @@ namespace fkstd return std::make_shared(TYPE_FLOAT, result, loc); } + STDRET trunc(Loc loc, Module&, STDARGS args) + { + float val = std::get(args[0]->value()); + int res = val; + return std::make_shared(TYPE_INT, res, loc); + } + STDRET lt(Loc loc, Module&, STDARGS args) { NUM_BINOP(<); diff --git a/libstd/fun.hpp b/libstd/fun.hpp index b7be0eb..e01d6e7 100644 --- a/libstd/fun.hpp +++ b/libstd/fun.hpp @@ -20,6 +20,7 @@ namespace fkstd STDRET div_float(Loc loc, Module& mod, STDARGS args); STDRET mod_float(Loc loc, Module& mod, STDARGS args); STDRET pow_float(Loc loc, Module& mod, STDARGS args); + STDRET trunc(Loc loc, Module& mod, STDARGS args); STDRET lt(Loc loc, Module& mod, STDARGS args); STDRET le(Loc loc, Module& mod, STDARGS args); diff --git a/libstd/lib.cpp b/libstd/lib.cpp index 00a2115..4a591f8 100644 --- a/libstd/lib.cpp +++ b/libstd/lib.cpp @@ -20,6 +20,8 @@ extern "C" void lib(Module& mod) mod.register_function("%.", fkstd::mod_float); mod.register_function("^.", fkstd::pow_float); + mod.register_function("trunc", fkstd::trunc); + mod.register_function("<", fkstd::lt); mod.register_function("<=", fkstd::le); mod.register_function(">", fkstd::gt); diff --git a/meson.build b/meson.build index 3e05de8..3c05327 100644 --- a/meson.build +++ b/meson.build @@ -63,10 +63,14 @@ fakir_hpp = [ 'src/types.hpp', ] +pkg = import('pkgconfig') + fakir_lib = shared_library('fakir', sources: fakir_cpp, install: true) +pkg.generate(fakir_lib, subdirs: ['fakir']) + install_headers(fakir_hpp, subdir: 'fakir') fakir_dep = declare_dependency( diff --git a/src/Compiler.cpp b/src/Compiler.cpp index a6bcefb..a0fd9c7 100644 --- a/src/Compiler.cpp +++ b/src/Compiler.cpp @@ -74,11 +74,9 @@ namespace fk } break; case NODE_VARDECL: { - m_addr++; - std::string ident = node->child(0)->repr(); auto rhs = node->child(1); - + next_addr(); push_decl(ident); compile_prog(rhs, prog); pop_decl(); @@ -86,11 +84,11 @@ namespace fk auto entry = sym()->declare_local(ident, m_addr, node->loc()) + .set_is_array(rhs->type() == NODE_ARRAY) .set_node(rhs); prog->add(OP_STORE_LOCAL, m_addr); - } break; case NODE_ARRAY: { @@ -114,9 +112,7 @@ namespace fk prog->load_const(std::make_shared(TYPE_STRING, var->repr(), node->loc())); - compile_prog(mod, prog); - prog->add(OP_LOAD_MOD); } break; @@ -271,7 +267,17 @@ namespace fk if (!entry) { - auto entry = m_sym->find_global(node->repr()); + auto entries = m_sym->find_all(node->repr()); + std::optional entry; + + for (SymEntry const& e: entries) + { + if (e.scope() <= m_sym->scope() + && (!entry || e.scope() < entry->scope())) + { + entry = e; + } + } if (entry) { @@ -293,10 +299,12 @@ namespace fk if (!entry->is_global()) { prog->add(OP_LOAD_LOCAL, entry->addr()); + break; } else { prog->add(OP_LOAD_GLOBAL, entry->addr()); + break; } } break; @@ -348,4 +356,9 @@ namespace fk m_decl_stack.pop_back(); } + addr_t Compiler::next_addr() + { + m_addr++; + return m_addr; + } } diff --git a/src/Compiler.hpp b/src/Compiler.hpp index 84e45e2..51dfd50 100644 --- a/src/Compiler.hpp +++ b/src/Compiler.hpp @@ -44,6 +44,8 @@ namespace fk void push_decl(std::string const& ident); void pop_decl(); + addr_t next_addr(); + private: Module& m_mod; addr_t m_addr = 0; diff --git a/src/Constant.cpp b/src/Constant.cpp index a44f259..fd51e5a 100644 --- a/src/Constant.cpp +++ b/src/Constant.cpp @@ -30,6 +30,7 @@ namespace fk case TYPE_STRING: return std::get(m_value); case TYPE_REF: return std::to_string(std::get(m_value)); case TYPE_PROGRAM: return ""; + case TYPE_CUSTOM: return ""; case TYPE_ARRAY: return std::get> (m_value)->string(); diff --git a/src/Constant.hpp b/src/Constant.hpp index 28912a2..feb91b0 100644 --- a/src/Constant.hpp +++ b/src/Constant.hpp @@ -15,6 +15,7 @@ namespace fk using constant_t = std::variant, diff --git a/src/Module.cpp b/src/Module.cpp index c99292f..fe1964a 100644 --- a/src/Module.cpp +++ b/src/Module.cpp @@ -17,10 +17,15 @@ namespace fk std::shared_ptr Module::get_mod(std::string const& name) { - assert(m_native_modules.find(name) != std::end(m_native_modules)); + assert(has_mod(name)); return m_native_modules[name]; } + bool Module::has_mod(std::string const& name) + { + return m_native_modules.find(name) != std::end(m_native_modules); + } + void Module::build() { import_std(); diff --git a/src/Module.hpp b/src/Module.hpp index 4363bff..b77ebf5 100644 --- a/src/Module.hpp +++ b/src/Module.hpp @@ -24,6 +24,7 @@ namespace fk std::shared_ptr vm() const { return m_vm; } std::shared_ptr get_mod(std::string const& name); + bool has_mod(std::string const& name); void build(); diff --git a/src/SymTable.cpp b/src/SymTable.cpp index ea029fc..1278bad 100644 --- a/src/SymTable.cpp +++ b/src/SymTable.cpp @@ -126,6 +126,22 @@ namespace fk return idx; } + std::vector SymTable::find_all(std::string const& name) + { + + std::vector res; + + for (auto e: m_entries) + { + if (e.name() == name) + { + res.push_back(e); + } + } + + return res; + } + void SymTable::set(std::string const& name, addr_t addr) { if (auto idx = find_idx(name); diff --git a/src/SymTable.hpp b/src/SymTable.hpp index 9353720..2e38e95 100644 --- a/src/SymTable.hpp +++ b/src/SymTable.hpp @@ -30,6 +30,8 @@ namespace fk std::optional find_global(std::string const& name); std::optional find_idx_global(std::string const& name); + std::vector find_all(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 8afeb5a..390b5ab 100644 --- a/src/VM.cpp +++ b/src/VM.cpp @@ -116,7 +116,24 @@ namespace fk std::filesystem::path path = std::get(path_val->value()); - auto mod = m_mod.get_mod(path); + auto alt_path = std::filesystem::path("/") + / "usr" / "lib" / ("lib" + + path.filename().string() + + ".so" ); + + std::shared_ptr mod; + + if (m_mod.has_mod(path)) + { + mod = m_mod.get_mod(path); + + } + else if (std::filesystem::exists(alt_path)) + { + mod = std::make_shared(alt_path); + mod->import_std(); + mod->import_library(alt_path); + } addr_t addr = store_global(mod); auto res = std::make_shared(TYPE_REF, addr, @@ -129,6 +146,7 @@ namespace fk case OP_LOAD_MOD: { addr_t mod_addr = pop(); auto mod_val = frame().program->get_const(mod_addr); + size_t mod_ref = std::get(mod_val->value()); @@ -203,8 +221,8 @@ namespace fk { auto val = frame().lambda->get_env(instr.param); addr_t addr = frame().program->add(val); - push(addr); + m_pc++; break; } @@ -249,12 +267,20 @@ namespace fk addr_t addr = store_global(lambda); auto ref = std::make_shared(TYPE_REF, addr, p->loc()); - if (m_frames.size() > 1) + /*if (m_frames.size() >= 1) { for (auto e: m_frames.back().locals) { lambda->add_env(e.first, e.second); } + }*/ + + for (auto const& f: m_frames) + { + for (auto e: f.locals) + { + lambda->add_env(e.first, e.second); + } } push(frame().program->add(ref)); @@ -495,9 +521,12 @@ namespace fk size_t ref, Loc const& loc) { - for (auto entry: parent.m_globals) + if (&parent != this) { - store_global(entry.first, entry.second); + for (auto entry: parent.m_globals) + { + store_global(entry.first, entry.second); + } } auto self = std::make_shared(TYPE_REF, diff --git a/src/commons.hpp b/src/commons.hpp index 9baf180..7cbad21 100644 --- a/src/commons.hpp +++ b/src/commons.hpp @@ -26,4 +26,8 @@ using addr_t = size_t; NAME (std::string const& what) : std::runtime_error(what ) {} \ } +#define STDARGS std::vector> +#define STDRET std::shared_ptr +#define STDSYM std::shared_ptr + #endif diff --git a/src/types.hpp b/src/types.hpp index 590a837..d193426 100644 --- a/src/types.hpp +++ b/src/types.hpp @@ -5,7 +5,7 @@ #define TYPES(G) G(TYPE_INT), G(TYPE_FLOAT), G(TYPE_BOOL), G(TYPE_STRING), \ G(TYPE_REF), G(TYPE_PROGRAM), G(TYPE_ARRAY), G(TYPE_NIL), \ - G(TYPE_FUNCTION) + G(TYPE_FUNCTION), G(TYPE_CUSTOM) namespace fk {