ADD: native functions.
parent
e5c388a38e
commit
314fbc0bd6
|
@ -3,4 +3,6 @@ EXPR ::=
|
||||||
bool
|
bool
|
||||||
| ident
|
| ident
|
||||||
| VARDECL
|
| VARDECL
|
||||||
|
| FUNCALL
|
||||||
VARDECL ::= opar decl ident EXPR cpar
|
VARDECL ::= opar decl ident EXPR cpar
|
||||||
|
FUNCALL ::= opar ident EXPR* cpar
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
#include "../src/Loader.hpp"
|
||||||
|
|
||||||
|
extern "C" void lib(grino::Loader& loader)
|
||||||
|
{
|
||||||
|
loader.add_native("dump", [](auto args){
|
||||||
|
std::string sep;
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
|
for (auto arg: args)
|
||||||
|
{
|
||||||
|
ss << sep << arg->string();
|
||||||
|
sep = " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << ss.str() << std::endl;
|
||||||
|
|
||||||
|
return grino::Value::make_nil();
|
||||||
|
});
|
||||||
|
}
|
15
meson.build
15
meson.build
|
@ -6,8 +6,11 @@ project('grino',
|
||||||
'cpp_std=c++17'
|
'cpp_std=c++17'
|
||||||
])
|
])
|
||||||
|
|
||||||
|
grino_libdir = get_option('prefix') / get_option('libdir') / 'grino'
|
||||||
|
|
||||||
conf = configuration_data()
|
conf = configuration_data()
|
||||||
conf.set('version', meson.project_version())
|
conf.set('version', meson.project_version())
|
||||||
|
conf.set('libdir', grino_libdir)
|
||||||
|
|
||||||
configure_file(input: 'src/config.in.hpp',
|
configure_file(input: 'src/config.in.hpp',
|
||||||
output: 'config.hpp',
|
output: 'config.hpp',
|
||||||
|
@ -24,11 +27,23 @@ grino_src = static_library('grino',
|
||||||
'src/Program.cpp',
|
'src/Program.cpp',
|
||||||
'src/VM.cpp',
|
'src/VM.cpp',
|
||||||
'src/Value.cpp',
|
'src/Value.cpp',
|
||||||
|
'src/Function.cpp',
|
||||||
'src/SymTable.cpp',
|
'src/SymTable.cpp',
|
||||||
|
'src/Loader.cpp',
|
||||||
])
|
])
|
||||||
|
|
||||||
grino_dep = declare_dependency(link_with: grino_src)
|
grino_dep = declare_dependency(link_with: grino_src)
|
||||||
|
|
||||||
|
shared_library('grino_core',
|
||||||
|
sources: [
|
||||||
|
'lib/core.cpp'
|
||||||
|
],
|
||||||
|
dependencies: [
|
||||||
|
grino_dep
|
||||||
|
],
|
||||||
|
install: true,
|
||||||
|
install_dir: grino_libdir)
|
||||||
|
|
||||||
executable('grino',
|
executable('grino',
|
||||||
sources: [
|
sources: [
|
||||||
'src/main.cpp'
|
'src/main.cpp'
|
||||||
|
|
|
@ -28,6 +28,16 @@ namespace grino
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case NODE_FUNCALL: {
|
||||||
|
|
||||||
|
for (size_t i=0; i<node->size(); i++)
|
||||||
|
{
|
||||||
|
compile(node->child(i).lock(), program);
|
||||||
|
}
|
||||||
|
|
||||||
|
program.push_instr(OPCODE_CALL, node->size() - 1);
|
||||||
|
} break;
|
||||||
|
|
||||||
case NODE_BOOL: {
|
case NODE_BOOL: {
|
||||||
std::string repr = node->repr();
|
std::string repr = node->repr();
|
||||||
auto value = Value::make_bool(repr == "true");
|
auto value = Value::make_bool(repr == "true");
|
||||||
|
@ -58,7 +68,14 @@ namespace grino
|
||||||
m_logger.log<compile_error>(LOG_ERROR, node->loc(), ss.str());
|
m_logger.log<compile_error>(LOG_ERROR, node->loc(), ss.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (entry->is_object)
|
||||||
|
{
|
||||||
|
program.push_instr(OPCODE_LOAD_OBJ, entry->addr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
program.push_instr(OPCODE_LOAD_LOCAL, entry->addr);
|
program.push_instr(OPCODE_LOAD_LOCAL, entry->addr);
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
#include "Function.hpp"
|
||||||
|
#include "Value.hpp"
|
||||||
|
|
||||||
|
namespace grino
|
||||||
|
{
|
||||||
|
/*explicit*/ Function::Function(native_t native)
|
||||||
|
: m_native { native }
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*virtual*/ Function::~Function()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
value_t Function::call(args_t args)
|
||||||
|
{
|
||||||
|
assert(m_native);
|
||||||
|
return m_native(args);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
#ifndef grino_FUNCTION_HPP
|
||||||
|
#define grino_FUNCTION_HPP
|
||||||
|
|
||||||
|
#include "commons.hpp"
|
||||||
|
|
||||||
|
namespace grino
|
||||||
|
{
|
||||||
|
class Value;
|
||||||
|
|
||||||
|
using value_t = std::shared_ptr<Value>;
|
||||||
|
using args_t = std::vector<value_t>;
|
||||||
|
using native_t = std::function<value_t(args_t)>;
|
||||||
|
|
||||||
|
class Function
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit Function(native_t native);
|
||||||
|
virtual ~Function();
|
||||||
|
|
||||||
|
value_t call(args_t args);
|
||||||
|
|
||||||
|
private:
|
||||||
|
native_t m_native;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,45 @@
|
||||||
|
#include "Loader.hpp"
|
||||||
|
#include "Function.hpp"
|
||||||
|
#include "src/config.in.hpp"
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
|
namespace grino
|
||||||
|
{
|
||||||
|
/*explicit*/ Loader::Loader(VM& vm, SymTable& sym_table)
|
||||||
|
: m_vm { vm }
|
||||||
|
, m_sym_table { sym_table }
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*virtual*/ Loader::~Loader()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Loader::load_libraries()
|
||||||
|
{
|
||||||
|
for (auto entry: std::filesystem::directory_iterator(GRINO_LIBDIR))
|
||||||
|
{
|
||||||
|
if (entry.path().has_extension()
|
||||||
|
&& entry.path().extension() == ".so")
|
||||||
|
{
|
||||||
|
load_library(entry.path());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Loader::load_library(std::filesystem::path path)
|
||||||
|
{
|
||||||
|
void* handle = dlopen(path.string().c_str(), RTLD_NOW);
|
||||||
|
typedef void(*libfun)(Loader&);
|
||||||
|
libfun f = (libfun) dlsym(handle, "lib");
|
||||||
|
|
||||||
|
f(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Loader::add_native(std::string const& name, native_t native)
|
||||||
|
{
|
||||||
|
size_t addr = m_vm.heap_size();
|
||||||
|
m_vm.set_heap(addr, grino::Value::make_native_function(native));
|
||||||
|
m_sym_table.declare_object(grino::Loc {"???", 1}, name, addr);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
#ifndef grino_LOADER_HPP
|
||||||
|
#define grino_LOADER_HPP
|
||||||
|
|
||||||
|
#include "commons.hpp"
|
||||||
|
#include "VM.hpp"
|
||||||
|
#include "SymTable.hpp"
|
||||||
|
|
||||||
|
namespace grino
|
||||||
|
{
|
||||||
|
class Loader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit Loader(VM& vm, SymTable& sym_table);
|
||||||
|
virtual ~Loader();
|
||||||
|
|
||||||
|
void load_libraries();
|
||||||
|
void load_library(std::filesystem::path path);
|
||||||
|
void add_native(std::string const& name, native_t native);
|
||||||
|
|
||||||
|
private:
|
||||||
|
VM& m_vm;
|
||||||
|
SymTable& m_sym_table;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -8,6 +8,7 @@
|
||||||
G(NODE_MODULE), \
|
G(NODE_MODULE), \
|
||||||
G(NODE_BOOL), \
|
G(NODE_BOOL), \
|
||||||
G(NODE_VARDECL), \
|
G(NODE_VARDECL), \
|
||||||
|
G(NODE_FUNCALL), \
|
||||||
G(NODE_IDENT), \
|
G(NODE_IDENT), \
|
||||||
G(NODE_OPAR), \
|
G(NODE_OPAR), \
|
||||||
G(NODE_CPAR), \
|
G(NODE_CPAR), \
|
||||||
|
|
|
@ -117,7 +117,12 @@ namespace grino
|
||||||
|
|
||||||
std::shared_ptr<Node> Parser::parse_expr()
|
std::shared_ptr<Node> Parser::parse_expr()
|
||||||
{
|
{
|
||||||
if (type_is(NODE_OPAR))
|
if (type_is({NODE_OPAR, NODE_IDENT}))
|
||||||
|
{
|
||||||
|
return parse_funcall();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type_is({NODE_OPAR, NODE_DECL}))
|
||||||
{
|
{
|
||||||
return parse_vardecl();
|
return parse_vardecl();
|
||||||
}
|
}
|
||||||
|
@ -151,4 +156,21 @@ namespace grino
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Node> Parser::parse_funcall()
|
||||||
|
{
|
||||||
|
consume(NODE_OPAR);
|
||||||
|
|
||||||
|
auto node = make_node(NODE_FUNCALL);
|
||||||
|
node->add_child(consume(NODE_IDENT));
|
||||||
|
|
||||||
|
while (!type_is(NODE_CPAR))
|
||||||
|
{
|
||||||
|
node->add_child(parse_expr());
|
||||||
|
}
|
||||||
|
|
||||||
|
consume(NODE_CPAR);
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ namespace grino
|
||||||
std::shared_ptr<Node> parse_module();
|
std::shared_ptr<Node> parse_module();
|
||||||
std::shared_ptr<Node> parse_expr();
|
std::shared_ptr<Node> parse_expr();
|
||||||
std::shared_ptr<Node> parse_vardecl();
|
std::shared_ptr<Node> parse_vardecl();
|
||||||
|
std::shared_ptr<Node> parse_funcall();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,11 +23,19 @@ namespace grino
|
||||||
SymEntry entry;
|
SymEntry entry;
|
||||||
entry.addr = addr;
|
entry.addr = addr;
|
||||||
entry.name = name;
|
entry.name = name;
|
||||||
entry.is_global = false;
|
entry.is_object = false;
|
||||||
|
|
||||||
m_entries.push_back(entry);
|
m_entries.push_back(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SymTable::declare_object(Loc const& loc,
|
||||||
|
std::string const& name,
|
||||||
|
size_t addr)
|
||||||
|
{
|
||||||
|
declare(loc, name, addr);
|
||||||
|
m_entries.back().is_object = true;
|
||||||
|
}
|
||||||
|
|
||||||
std::optional<SymEntry> SymTable::find(std::string const& name)
|
std::optional<SymEntry> SymTable::find(std::string const& name)
|
||||||
{
|
{
|
||||||
for (size_t i=0; i<m_entries.size(); i++)
|
for (size_t i=0; i<m_entries.size(); i++)
|
||||||
|
|
|
@ -8,8 +8,8 @@ namespace grino
|
||||||
{
|
{
|
||||||
struct SymEntry {
|
struct SymEntry {
|
||||||
std::string name;
|
std::string name;
|
||||||
bool is_global;
|
bool is_object; /* object are on the heap instead of the stack */
|
||||||
size_t addr;
|
size_t addr; /* address on the heap if object, local address otherwise */
|
||||||
};
|
};
|
||||||
|
|
||||||
GRINO_ERROR(symbolic_error);
|
GRINO_ERROR(symbolic_error);
|
||||||
|
@ -21,6 +21,8 @@ namespace grino
|
||||||
virtual ~SymTable();
|
virtual ~SymTable();
|
||||||
|
|
||||||
void declare(Loc const& loc, std::string const& name, size_t addr);
|
void declare(Loc const& loc, std::string const& name, size_t addr);
|
||||||
|
void declare_object(Loc const& loc, std::string const& name, size_t addr);
|
||||||
|
|
||||||
std::optional<SymEntry> find(std::string const& name);
|
std::optional<SymEntry> find(std::string const& name);
|
||||||
|
|
||||||
std::string string() const;
|
std::string string() const;
|
||||||
|
|
63
src/VM.cpp
63
src/VM.cpp
|
@ -48,6 +48,34 @@ namespace grino
|
||||||
m_pc++;
|
m_pc++;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case OPCODE_LOAD_OBJ: {
|
||||||
|
size_t addr = *instr.param;
|
||||||
|
auto ref = Value::make_ref(addr);
|
||||||
|
push(program.push_constant(ref));
|
||||||
|
m_pc++;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case OPCODE_CALL: {
|
||||||
|
size_t const N = *instr.param;
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<Value>> args;
|
||||||
|
|
||||||
|
for (size_t i=0; i<N; i++)
|
||||||
|
{
|
||||||
|
args.insert(std::begin(args), program.constant(pop()));
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ref = program.constant(pop())->as_ref();
|
||||||
|
auto fun = heap(ref)->as_function();
|
||||||
|
|
||||||
|
auto ret = fun->call(args);
|
||||||
|
|
||||||
|
push(program.push_constant(ret));
|
||||||
|
|
||||||
|
m_pc++;
|
||||||
|
|
||||||
|
} break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
std::cerr << "cannot execute unknown opcode "
|
std::cerr << "cannot execute unknown opcode "
|
||||||
<< OpcodeTypeStr[instr.opcode]
|
<< OpcodeTypeStr[instr.opcode]
|
||||||
|
@ -69,6 +97,29 @@ namespace grino
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::shared_ptr<Value> VM::local(size_t addr) const
|
||||||
|
{
|
||||||
|
return m_frames.back().locals.at(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VM::set_local(size_t addr,
|
||||||
|
std::shared_ptr<Value> value)
|
||||||
|
{
|
||||||
|
m_frames.back().locals[addr] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Value> VM::heap(size_t addr) const
|
||||||
|
{
|
||||||
|
return m_heap.at(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VM::set_heap(size_t addr,
|
||||||
|
std::shared_ptr<Value> value)
|
||||||
|
{
|
||||||
|
m_heap[addr] = value;
|
||||||
|
}
|
||||||
|
|
||||||
void VM::push(size_t addr)
|
void VM::push(size_t addr)
|
||||||
{
|
{
|
||||||
if (m_sp >= STACK_SIZE)
|
if (m_sp >= STACK_SIZE)
|
||||||
|
@ -97,16 +148,4 @@ namespace grino
|
||||||
size_t addr = m_stack[m_sp - 1];
|
size_t addr = m_stack[m_sp - 1];
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Value> VM::local(size_t addr) const
|
|
||||||
{
|
|
||||||
return m_frames.back().locals.at(addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void VM::set_local(size_t addr,
|
|
||||||
std::shared_ptr<Value> value)
|
|
||||||
{
|
|
||||||
m_frames.back().locals[addr] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
16
src/VM.hpp
16
src/VM.hpp
|
@ -21,12 +21,23 @@ namespace grino
|
||||||
explicit VM(Logger& logger);
|
explicit VM(Logger& logger);
|
||||||
virtual ~VM();
|
virtual ~VM();
|
||||||
|
|
||||||
|
size_t heap_size() const { return m_heap.size(); }
|
||||||
|
|
||||||
void run(Program& program);
|
void run(Program& program);
|
||||||
|
|
||||||
std::string string() const;
|
std::string string() const;
|
||||||
|
|
||||||
|
std::shared_ptr<Value> local(size_t addr) const;
|
||||||
|
void set_local(size_t addr,
|
||||||
|
std::shared_ptr<Value> value);
|
||||||
|
|
||||||
|
std::shared_ptr<Value> heap(size_t addr) const;
|
||||||
|
void set_heap(size_t addr,
|
||||||
|
std::shared_ptr<Value> value);
|
||||||
private:
|
private:
|
||||||
Logger& m_logger;
|
Logger& m_logger;
|
||||||
std::array<size_t, STACK_SIZE> m_stack;
|
std::array<size_t, STACK_SIZE> m_stack;
|
||||||
|
std::unordered_map<size_t, std::shared_ptr<Value>> m_heap;
|
||||||
std::vector<Frame> m_frames;
|
std::vector<Frame> m_frames;
|
||||||
|
|
||||||
size_t m_sp; /* stack pointer */
|
size_t m_sp; /* stack pointer */
|
||||||
|
@ -36,9 +47,8 @@ namespace grino
|
||||||
void push(size_t addr);
|
void push(size_t addr);
|
||||||
size_t pop();
|
size_t pop();
|
||||||
size_t top();
|
size_t top();
|
||||||
std::shared_ptr<Value> local(size_t addr) const;
|
|
||||||
void set_local(size_t addr,
|
|
||||||
std::shared_ptr<Value> value);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,13 +17,31 @@ namespace grino
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*static*/
|
||||||
|
std::shared_ptr<Value> Value::make_native_function(native_t val)
|
||||||
|
{
|
||||||
|
auto value = std::make_shared<Value>();
|
||||||
|
value->m_type = TYPE_FUNCTION;
|
||||||
|
value->m_function_val = std::make_shared<Function>(val);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static*/ std::shared_ptr<Value> Value::make_ref(size_t val)
|
||||||
|
{
|
||||||
|
auto value = std::make_shared<Value>();
|
||||||
|
value->m_type = TYPE_REF;
|
||||||
|
value->m_ref_val = val;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
std::string Value::string() const
|
std::string Value::string() const
|
||||||
{
|
{
|
||||||
switch (m_type)
|
switch (m_type)
|
||||||
{
|
{
|
||||||
case TYPE_NIL: return "<nil>";
|
case TYPE_NIL: return "<nil>";
|
||||||
case TYPE_BOOL: return *m_bool_val ? "true" : "false";
|
case TYPE_BOOL: return *m_bool_val ? "true" : "false";
|
||||||
|
case TYPE_FUNCTION: return "<function>";
|
||||||
|
case TYPE_REF: return "&" + std::to_string(*m_ref_val);
|
||||||
default:
|
default:
|
||||||
std::cerr << "cannot stringify value "
|
std::cerr << "cannot stringify value "
|
||||||
<< TypeTypeStr[m_type] << std::endl;
|
<< TypeTypeStr[m_type] << std::endl;
|
||||||
|
@ -39,6 +57,7 @@ namespace grino
|
||||||
{
|
{
|
||||||
case TYPE_NIL: return true;
|
case TYPE_NIL: return true;
|
||||||
case TYPE_BOOL: return *m_bool_val == *other.m_bool_val;
|
case TYPE_BOOL: return *m_bool_val == *other.m_bool_val;
|
||||||
|
case TYPE_REF: return *m_ref_val == *other.m_ref_val;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
std::cerr << "cannot compare equality with value "
|
std::cerr << "cannot compare equality with value "
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "commons.hpp"
|
#include "commons.hpp"
|
||||||
#include "types.hpp"
|
#include "types.hpp"
|
||||||
|
#include "Function.hpp"
|
||||||
|
|
||||||
namespace grino
|
namespace grino
|
||||||
{
|
{
|
||||||
|
@ -11,12 +12,16 @@ namespace grino
|
||||||
public:
|
public:
|
||||||
static std::shared_ptr<Value> make_nil();
|
static std::shared_ptr<Value> make_nil();
|
||||||
static std::shared_ptr<Value> make_bool(bool val);
|
static std::shared_ptr<Value> make_bool(bool val);
|
||||||
|
static std::shared_ptr<Value> make_native_function(native_t val);
|
||||||
|
static std::shared_ptr<Value> make_ref(size_t val);
|
||||||
|
|
||||||
explicit Value() = default;
|
explicit Value() = default;
|
||||||
virtual ~Value() = default;
|
virtual ~Value() = default;
|
||||||
|
|
||||||
TypeType type() const { return m_type; }
|
TypeType type() const { return m_type; }
|
||||||
bool as_bool() const { return *m_bool_val; }
|
bool as_bool() const { return *m_bool_val; }
|
||||||
|
std::shared_ptr<Function> as_function() const { return m_function_val; }
|
||||||
|
size_t as_ref() const { return *m_ref_val; }
|
||||||
|
|
||||||
std::string string() const;
|
std::string string() const;
|
||||||
bool equals(Value const& other) const;
|
bool equals(Value const& other) const;
|
||||||
|
@ -24,6 +29,8 @@ namespace grino
|
||||||
private:
|
private:
|
||||||
TypeType m_type = TYPE_NIL;
|
TypeType m_type = TYPE_NIL;
|
||||||
std::optional<bool> m_bool_val;
|
std::optional<bool> m_bool_val;
|
||||||
|
std::shared_ptr<Function> m_function_val;
|
||||||
|
std::optional<size_t> m_ref_val;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
#ifndef grino_CONFIG_IN_HPP
|
#ifndef grino_CONFIG_IN_HPP
|
||||||
#define grino_CONFIG_IN_HPP
|
#define grino_CONFIG_IN_HPP
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
#define GRINO_VERSION "@version@"
|
#define GRINO_VERSION "@version@"
|
||||||
|
#define GRINO_LIBDIR std::filesystem::path {"@libdir@"}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "VM.hpp"
|
#include "VM.hpp"
|
||||||
#include "Logger.hpp"
|
#include "Logger.hpp"
|
||||||
#include "src/SymTable.hpp"
|
#include "src/SymTable.hpp"
|
||||||
|
#include "Loader.hpp"
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
@ -74,7 +75,12 @@ int main(int argc, char** argv)
|
||||||
std::cout << "--- ast ---" << std::endl;
|
std::cout << "--- ast ---" << std::endl;
|
||||||
std::cout << ast->string() << std::endl;
|
std::cout << ast->string() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
grino::SymTable sym_table {logger};
|
grino::SymTable sym_table {logger};
|
||||||
|
grino::VM vm {logger};
|
||||||
|
|
||||||
|
grino::Loader loader {vm, sym_table};
|
||||||
|
loader.load_libraries();
|
||||||
|
|
||||||
grino::Compiler compiler {logger, sym_table};
|
grino::Compiler compiler {logger, sym_table};
|
||||||
grino::Program program;
|
grino::Program program;
|
||||||
|
@ -86,8 +92,6 @@ int main(int argc, char** argv)
|
||||||
std::cout << program.string() << std::endl;
|
std::cout << program.string() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
grino::VM vm {logger};
|
|
||||||
|
|
||||||
vm.run(program);
|
vm.run(program);
|
||||||
|
|
||||||
if (debug_mode)
|
if (debug_mode)
|
||||||
|
|
|
@ -8,7 +8,11 @@
|
||||||
G(OPCODE_LOAD_CONST), \
|
G(OPCODE_LOAD_CONST), \
|
||||||
G(OPCODE_POP), \
|
G(OPCODE_POP), \
|
||||||
G(OPCODE_LOAD_LOCAL), \
|
G(OPCODE_LOAD_LOCAL), \
|
||||||
G(OPCODE_STORE_LOCAL)
|
G(OPCODE_STORE_LOCAL), \
|
||||||
|
G(OPCODE_LOAD_OBJ), \
|
||||||
|
G(OPCODE_STORE_OBJ), \
|
||||||
|
G(OPCODE_CALL), \
|
||||||
|
G(OPCODE_RET),
|
||||||
|
|
||||||
namespace grino
|
namespace grino
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,7 +5,9 @@
|
||||||
|
|
||||||
#define TYPES(G) \
|
#define TYPES(G) \
|
||||||
G(TYPE_NIL), \
|
G(TYPE_NIL), \
|
||||||
G(TYPE_BOOL)
|
G(TYPE_BOOL), \
|
||||||
|
G(TYPE_FUNCTION), \
|
||||||
|
G(TYPE_REF)
|
||||||
|
|
||||||
namespace grino
|
namespace grino
|
||||||
{
|
{
|
||||||
|
|
|
@ -39,3 +39,12 @@ TEST_CASE_METHOD(ParserTest, "Parser_vardecl")
|
||||||
test_parse("MODULE(VARDECL(IDENT[hello],IDENT[world]))",
|
test_parse("MODULE(VARDECL(IDENT[hello],IDENT[world]))",
|
||||||
"($ hello world)");
|
"($ hello world)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE_METHOD(ParserTest, "Parser_funcall")
|
||||||
|
{
|
||||||
|
test_parse("MODULE(FUNCALL(IDENT[hello]))",
|
||||||
|
"(hello)");
|
||||||
|
|
||||||
|
test_parse("MODULE(FUNCALL(IDENT[f],BOOL[false],BOOL[true]))",
|
||||||
|
"(f false true)");
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue