ADD: native modules can be declared from libs shared libraries.

main
bog 2023-09-13 23:14:49 +02:00
parent 078877aa26
commit 43a8c0c113
8 changed files with 84 additions and 36 deletions

View File

@ -2,6 +2,7 @@
#include "src/Logger.hpp"
#include "src/Value.hpp"
#include "src/opcodes.hpp"
#include "../src/Module.hpp"
GRINO_ERROR(assertion_error);

View File

@ -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: {

View File

@ -4,6 +4,7 @@
#include <dlfcn.h>
#include "Lexer.hpp"
#include "Parser.hpp"
#include "Module.hpp"
namespace grino
{
@ -43,26 +44,6 @@ namespace grino
return deps;
}
std::shared_ptr<Node>
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<Module> Loader::add_module(std::string const& name)
{
auto mod = std::make_shared<Module>(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);

View File

@ -20,11 +20,10 @@ namespace grino
std::vector<std::filesystem::path>
dependencies(std::shared_ptr<Node> node);
std::shared_ptr<Node> user_module(std::filesystem::path path);
void load_libraries();
void load_library(std::filesystem::path path);
std::shared_ptr<Module> 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);

View File

@ -13,6 +13,8 @@ namespace grino
, m_program { std::make_shared<Program>()}
, m_sym_table { std::make_shared<SymTable>(m_logger)}
, m_vm { std::make_shared<VM>(m_logger, *m_program)}
, m_compiler { std::make_shared<Compiler>(m_logger, m_addr)}
, m_loader { std::make_shared<Loader>(*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<VM>(m_logger, *m_program);
Loader loader {*m_vm, compiler, *m_sym_table};
loader.load_libraries();
m_loader = std::make_shared<Loader>(*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<Value> 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);
}

View File

@ -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> loader() const { return m_loader; }
std::shared_ptr<Value> find(std::string const& name);
std::shared_ptr<Value> from_heap(size_t addr);
@ -27,6 +29,9 @@ namespace grino
std::shared_ptr<Program> m_program;
std::shared_ptr<SymTable> m_sym_table;
std::shared_ptr<VM> m_vm;
Addr m_addr;
std::shared_ptr<Compiler> m_compiler;
std::shared_ptr<Loader> m_loader;
};
}

View File

@ -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<Module>(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<Value> VM::local(size_t addr) const
{
auto itr = m_frames.back().locals.find(addr);

View File

@ -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