ADD: native modules can be declared from libs shared libraries.
parent
078877aa26
commit
43a8c0c113
|
@ -2,6 +2,7 @@
|
||||||
#include "src/Logger.hpp"
|
#include "src/Logger.hpp"
|
||||||
#include "src/Value.hpp"
|
#include "src/Value.hpp"
|
||||||
#include "src/opcodes.hpp"
|
#include "src/opcodes.hpp"
|
||||||
|
#include "../src/Module.hpp"
|
||||||
|
|
||||||
GRINO_ERROR(assertion_error);
|
GRINO_ERROR(assertion_error);
|
||||||
|
|
||||||
|
|
|
@ -36,8 +36,28 @@ namespace grino
|
||||||
std::string name = node->child(0).lock()->repr();
|
std::string name = node->child(0).lock()->repr();
|
||||||
name = name.substr(1, name.size() - 2);
|
name = name.substr(1, name.size() - 2);
|
||||||
|
|
||||||
program.push_value(Value::make_string(node->loc(), name));
|
if (name.substr(0, 2) == "./")
|
||||||
program.push_instr(OPCODE_MK_MOD);
|
{
|
||||||
|
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;
|
} break;
|
||||||
|
|
||||||
case NODE_NS: {
|
case NODE_NS: {
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#include "Lexer.hpp"
|
#include "Lexer.hpp"
|
||||||
#include "Parser.hpp"
|
#include "Parser.hpp"
|
||||||
|
#include "Module.hpp"
|
||||||
|
|
||||||
namespace grino
|
namespace grino
|
||||||
{
|
{
|
||||||
|
@ -43,26 +44,6 @@ namespace grino
|
||||||
return deps;
|
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()
|
void Loader::load_libraries()
|
||||||
{
|
{
|
||||||
for (auto entry: std::filesystem::directory_iterator(GRINO_LIBDIR))
|
for (auto entry: std::filesystem::directory_iterator(GRINO_LIBDIR))
|
||||||
|
@ -84,10 +65,24 @@ namespace grino
|
||||||
f(*this);
|
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)
|
void Loader::add_native(std::string const& name, native_t native)
|
||||||
{
|
{
|
||||||
size_t addr = m_vm.heap_size();
|
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_vm.set_heap(addr, grino::Value::make_native_function(loc, native));
|
||||||
m_sym_table.declare_object(loc, name, addr, 0);
|
m_sym_table.declare_object(loc, name, addr, 0);
|
||||||
|
|
|
@ -20,11 +20,10 @@ namespace grino
|
||||||
std::vector<std::filesystem::path>
|
std::vector<std::filesystem::path>
|
||||||
dependencies(std::shared_ptr<Node> node);
|
dependencies(std::shared_ptr<Node> node);
|
||||||
|
|
||||||
std::shared_ptr<Node> user_module(std::filesystem::path path);
|
|
||||||
|
|
||||||
void load_libraries();
|
void load_libraries();
|
||||||
void load_library(std::filesystem::path path);
|
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_native(std::string const& name, native_t native);
|
||||||
void add_static(std::string const& name, static_fun_t fun);
|
void add_static(std::string const& name, static_fun_t fun);
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,8 @@ namespace grino
|
||||||
, m_program { std::make_shared<Program>()}
|
, m_program { std::make_shared<Program>()}
|
||||||
, m_sym_table { std::make_shared<SymTable>(m_logger)}
|
, m_sym_table { std::make_shared<SymTable>(m_logger)}
|
||||||
, m_vm { std::make_shared<VM>(m_logger, *m_program)}
|
, 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};
|
Parser parser {m_logger, lexer};
|
||||||
|
|
||||||
auto ast = parser.parse(source);
|
auto ast = parser.parse(source);
|
||||||
Addr addr;
|
|
||||||
Compiler compiler {m_logger, addr};
|
|
||||||
m_vm = std::make_shared<VM>(m_logger, *m_program);
|
m_vm = std::make_shared<VM>(m_logger, *m_program);
|
||||||
|
|
||||||
Loader loader {*m_vm, compiler, *m_sym_table};
|
m_loader = std::make_shared<Loader>(*m_vm, *m_compiler, *m_sym_table);
|
||||||
loader.load_libraries();
|
m_loader->load_libraries();
|
||||||
|
|
||||||
compiler.compile(ast, *m_program, *m_sym_table);
|
m_compiler->compile(ast, *m_program, *m_sym_table);
|
||||||
|
|
||||||
m_vm->run();
|
m_vm->run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Module::load_native()
|
||||||
|
{
|
||||||
|
m_loader->load_libraries();
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<Value> Module::find(std::string const& name)
|
std::shared_ptr<Value> Module::find(std::string const& name)
|
||||||
{
|
{
|
||||||
auto entry = m_sym_table->find_no_scope(name);
|
auto entry = m_sym_table->find_no_scope(name);
|
||||||
assert(entry);
|
assert(entry);
|
||||||
assert(entry->is_object == false);
|
|
||||||
|
if (entry->is_object)
|
||||||
|
{
|
||||||
|
return m_vm->heap(entry->addr);
|
||||||
|
}
|
||||||
|
|
||||||
return m_vm->local(entry->addr);
|
return m_vm->local(entry->addr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "Program.hpp"
|
#include "Program.hpp"
|
||||||
#include "SymTable.hpp"
|
#include "SymTable.hpp"
|
||||||
#include "VM.hpp"
|
#include "VM.hpp"
|
||||||
|
#include "Loader.hpp"
|
||||||
|
|
||||||
namespace grino
|
namespace grino
|
||||||
{
|
{
|
||||||
|
@ -16,7 +17,8 @@ namespace grino
|
||||||
|
|
||||||
std::string name() const { return m_name; }
|
std::string name() const { return m_name; }
|
||||||
void load();
|
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> find(std::string const& name);
|
||||||
std::shared_ptr<Value> from_heap(size_t addr);
|
std::shared_ptr<Value> from_heap(size_t addr);
|
||||||
|
|
||||||
|
@ -27,6 +29,9 @@ namespace grino
|
||||||
std::shared_ptr<Program> m_program;
|
std::shared_ptr<Program> m_program;
|
||||||
std::shared_ptr<SymTable> m_sym_table;
|
std::shared_ptr<SymTable> m_sym_table;
|
||||||
std::shared_ptr<VM> m_vm;
|
std::shared_ptr<VM> m_vm;
|
||||||
|
Addr m_addr;
|
||||||
|
std::shared_ptr<Compiler> m_compiler;
|
||||||
|
std::shared_ptr<Loader> m_loader;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
25
src/VM.cpp
25
src/VM.cpp
|
@ -34,12 +34,13 @@ namespace grino
|
||||||
switch (instr.opcode)
|
switch (instr.opcode)
|
||||||
{
|
{
|
||||||
case OPCODE_MK_MOD: {
|
case OPCODE_MK_MOD: {
|
||||||
auto path = std::filesystem::path(program()
|
std::string path_str = program().constant(pop())->as_string();
|
||||||
.constant(pop())
|
auto path = std::filesystem::path(path_str);
|
||||||
->as_string());
|
|
||||||
|
|
||||||
auto mod = std::make_shared<Module>(path);
|
auto mod = std::make_shared<Module>(path);
|
||||||
|
|
||||||
mod->load();
|
mod->load();
|
||||||
|
|
||||||
size_t addr = heap_size();
|
size_t addr = heap_size();
|
||||||
|
|
||||||
Loc loc {"???", 0};
|
Loc loc {"???", 0};
|
||||||
|
@ -51,6 +52,15 @@ namespace grino
|
||||||
m_pc++;
|
m_pc++;
|
||||||
} break;
|
} 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: {
|
case OPCODE_LOAD_NS: {
|
||||||
std::string var = program().constant(pop())->as_string();
|
std::string var = program().constant(pop())->as_string();
|
||||||
size_t ref_val = program().constant(pop())->as_ref();
|
size_t ref_val = program().constant(pop())->as_ref();
|
||||||
|
@ -66,6 +76,14 @@ namespace grino
|
||||||
set_heap(addr, heap_val);
|
set_heap(addr, heap_val);
|
||||||
val = Value::make_ref(heap_val->loc(), addr);
|
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));
|
push(program().push_constant(val));
|
||||||
|
|
||||||
|
@ -357,7 +375,6 @@ namespace grino
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::shared_ptr<Value> VM::local(size_t addr) const
|
std::shared_ptr<Value> VM::local(size_t addr) const
|
||||||
{
|
{
|
||||||
auto itr = m_frames.back().locals.find(addr);
|
auto itr = m_frames.back().locals.find(addr);
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
G(OPCODE_MK_FUN), \
|
G(OPCODE_MK_FUN), \
|
||||||
G(OPCODE_MK_ARRAY), \
|
G(OPCODE_MK_ARRAY), \
|
||||||
G(OPCODE_MK_MOD), \
|
G(OPCODE_MK_MOD), \
|
||||||
|
G(OPCODE_LOAD_MOD), \
|
||||||
G(OPCODE_LOAD_NS),
|
G(OPCODE_LOAD_NS),
|
||||||
|
|
||||||
namespace grino
|
namespace grino
|
||||||
|
|
Loading…
Reference in New Issue