From 43a8c0c113aa3fb90405dadb3e1978d5dd997883 Mon Sep 17 00:00:00 2001 From: bog Date: Wed, 13 Sep 2023 23:14:49 +0200 Subject: [PATCH] ADD: native modules can be declared from libs shared libraries. --- lib/core.cpp | 1 + src/Compiler.cpp | 24 ++++++++++++++++++++++-- src/Loader.cpp | 37 ++++++++++++++++--------------------- src/Loader.hpp | 3 +-- src/Module.cpp | 22 ++++++++++++++++------ src/Module.hpp | 7 ++++++- src/VM.cpp | 25 +++++++++++++++++++++---- src/opcodes.hpp | 1 + 8 files changed, 84 insertions(+), 36 deletions(-) diff --git a/lib/core.cpp b/lib/core.cpp index 907deee..4527ab4 100644 --- a/lib/core.cpp +++ b/lib/core.cpp @@ -2,6 +2,7 @@ #include "src/Logger.hpp" #include "src/Value.hpp" #include "src/opcodes.hpp" +#include "../src/Module.hpp" GRINO_ERROR(assertion_error); diff --git a/src/Compiler.cpp b/src/Compiler.cpp index 39bef19..b1a74bf 100644 --- a/src/Compiler.cpp +++ b/src/Compiler.cpp @@ -36,8 +36,28 @@ namespace grino std::string name = node->child(0).lock()->repr(); name = name.substr(1, name.size() - 2); - program.push_value(Value::make_string(node->loc(), name)); - program.push_instr(OPCODE_MK_MOD); + if (name.substr(0, 2) == "./") + { + auto path = std::filesystem::path(name); + + if (!path.has_extension()) + { + name += ".gri"; + } + + program.push_value(Value::make_string(node->loc(), name)); + program.push_instr(OPCODE_MK_MOD); + } + else + { + auto entry = sym.find_no_scope(name); + assert(entry); + assert(entry->is_object); + + program.push_value(Value::make_string(node->loc(), name)); + program.push_instr(OPCODE_LOAD_MOD, entry->addr); + } + } break; case NODE_NS: { diff --git a/src/Loader.cpp b/src/Loader.cpp index 72d156d..ad26e46 100644 --- a/src/Loader.cpp +++ b/src/Loader.cpp @@ -4,6 +4,7 @@ #include #include "Lexer.hpp" #include "Parser.hpp" +#include "Module.hpp" namespace grino { @@ -43,26 +44,6 @@ namespace grino return deps; } - std::shared_ptr - Loader::user_module(std::filesystem::path path) - { - std::string source; - { - std::ifstream file { path }; - assert(file); - std::string line; - - while (std::getline(file, line)) - { source += line + (file.eof() ? "" : "\n"); } - } - - Logger logger; - Lexer lexer {logger, path}; - Parser parser {logger, lexer}; - - return parser.parse(source); - } - void Loader::load_libraries() { for (auto entry: std::filesystem::directory_iterator(GRINO_LIBDIR)) @@ -84,10 +65,24 @@ namespace grino f(*this); } + std::shared_ptr Loader::add_module(std::string const& name) + { + auto mod = std::make_shared(name); + Loc loc {"modules/" + name, 1}; + + auto val = Value::make_module(loc, mod); + + size_t addr = m_vm.heap_size(); + m_vm.set_heap(addr, val); + m_sym_table.declare_object(loc, name, addr, 0); + + return mod; + } + void Loader::add_native(std::string const& name, native_t native) { size_t addr = m_vm.heap_size(); - grino::Loc loc {"???", 0}; + grino::Loc loc {"natives/" + name, 0}; m_vm.set_heap(addr, grino::Value::make_native_function(loc, native)); m_sym_table.declare_object(loc, name, addr, 0); diff --git a/src/Loader.hpp b/src/Loader.hpp index cf6c01d..fb275ef 100644 --- a/src/Loader.hpp +++ b/src/Loader.hpp @@ -20,11 +20,10 @@ namespace grino std::vector dependencies(std::shared_ptr node); - std::shared_ptr user_module(std::filesystem::path path); - void load_libraries(); void load_library(std::filesystem::path path); + std::shared_ptr add_module(std::string const& name); void add_native(std::string const& name, native_t native); void add_static(std::string const& name, static_fun_t fun); diff --git a/src/Module.cpp b/src/Module.cpp index ea66579..ea4116a 100644 --- a/src/Module.cpp +++ b/src/Module.cpp @@ -13,6 +13,8 @@ namespace grino , m_program { std::make_shared()} , m_sym_table { std::make_shared(m_logger)} , m_vm { std::make_shared(m_logger, *m_program)} + , m_compiler { std::make_shared(m_logger, m_addr)} + , m_loader { std::make_shared(*m_vm, *m_compiler, *m_sym_table)} { } @@ -36,23 +38,31 @@ namespace grino Parser parser {m_logger, lexer}; auto ast = parser.parse(source); - Addr addr; - Compiler compiler {m_logger, addr}; + m_vm = std::make_shared(m_logger, *m_program); - Loader loader {*m_vm, compiler, *m_sym_table}; - loader.load_libraries(); + m_loader = std::make_shared(*m_vm, *m_compiler, *m_sym_table); + m_loader->load_libraries(); - compiler.compile(ast, *m_program, *m_sym_table); + m_compiler->compile(ast, *m_program, *m_sym_table); m_vm->run(); } + void Module::load_native() + { + m_loader->load_libraries(); + } + std::shared_ptr Module::find(std::string const& name) { auto entry = m_sym_table->find_no_scope(name); assert(entry); - assert(entry->is_object == false); + + if (entry->is_object) + { + return m_vm->heap(entry->addr); + } return m_vm->local(entry->addr); } diff --git a/src/Module.hpp b/src/Module.hpp index 2f11802..a433b6b 100644 --- a/src/Module.hpp +++ b/src/Module.hpp @@ -5,6 +5,7 @@ #include "Program.hpp" #include "SymTable.hpp" #include "VM.hpp" +#include "Loader.hpp" namespace grino { @@ -16,7 +17,8 @@ namespace grino std::string name() const { return m_name; } void load(); - + void load_native(); + std::shared_ptr loader() const { return m_loader; } std::shared_ptr find(std::string const& name); std::shared_ptr from_heap(size_t addr); @@ -27,6 +29,9 @@ namespace grino std::shared_ptr m_program; std::shared_ptr m_sym_table; std::shared_ptr m_vm; + Addr m_addr; + std::shared_ptr m_compiler; + std::shared_ptr m_loader; }; } diff --git a/src/VM.cpp b/src/VM.cpp index d1e37b8..e56f69c 100644 --- a/src/VM.cpp +++ b/src/VM.cpp @@ -34,12 +34,13 @@ namespace grino switch (instr.opcode) { case OPCODE_MK_MOD: { - auto path = std::filesystem::path(program() - .constant(pop()) - ->as_string()); + std::string path_str = program().constant(pop())->as_string(); + auto path = std::filesystem::path(path_str); auto mod = std::make_shared(path); + mod->load(); + size_t addr = heap_size(); Loc loc {"???", 0}; @@ -51,6 +52,15 @@ namespace grino m_pc++; } break; + case OPCODE_LOAD_MOD: { + std::string name = program().constant(pop())->as_string(); + size_t heap_addr = *instr.param; + + Loc loc {"???", 0}; + push(program().push_constant(Value::make_ref(loc, heap_addr))); + m_pc++; + } break; + case OPCODE_LOAD_NS: { std::string var = program().constant(pop())->as_string(); size_t ref_val = program().constant(pop())->as_ref(); @@ -66,6 +76,14 @@ namespace grino set_heap(addr, heap_val); val = Value::make_ref(heap_val->loc(), addr); } + else if (val->type() == TYPE_FUNCTION + || val->type() == TYPE_ARRAY + || val->type() == TYPE_MODULE) + { + size_t addr = heap_size(); + set_heap(addr, val); + val = Value::make_ref(mod->loc(), addr); + } push(program().push_constant(val)); @@ -357,7 +375,6 @@ namespace grino return ss.str(); } - std::shared_ptr VM::local(size_t addr) const { auto itr = m_frames.back().locals.find(addr); diff --git a/src/opcodes.hpp b/src/opcodes.hpp index d106ed8..6202016 100644 --- a/src/opcodes.hpp +++ b/src/opcodes.hpp @@ -19,6 +19,7 @@ G(OPCODE_MK_FUN), \ G(OPCODE_MK_ARRAY), \ G(OPCODE_MK_MOD), \ + G(OPCODE_LOAD_MOD), \ G(OPCODE_LOAD_NS), namespace grino