Compare commits

..

5 Commits

Author SHA1 Message Date
bog f63cbf4cea ADD: blocks. 2023-09-19 12:50:12 +02:00
bog 820d26491a ADD: now expose module to macros. 2023-09-19 11:29:23 +02:00
bog 073cbb4618 ADD: vardecl. 2023-09-19 06:38:14 +02:00
bog 0aa9ebd952 ADD: test script. 2023-09-18 19:32:16 +02:00
bog ee1b52cae1 ADD: native macros and assert-fail macro. 2023-09-18 19:08:32 +02:00
24 changed files with 485 additions and 80 deletions

20
examples/block.zn Normal file
View File

@ -0,0 +1,20 @@
($ a 2)
(assert= 2 a)
(:
($ a 9)
(assert= 9 a)
(:
($ a 42)
(assert= 42 a)
)
(assert= 9 a)
)
(assert= 2 a)
(:($ b 43))
(assert-fail b)

43
examples/run.sh Executable file
View File

@ -0,0 +1,43 @@
#!/usr/bin/env bash
TOTAL=0
SUCCESS=0
for file in `find -name "*.zn"`
do
NAME=$(basename $file | cut -d'.' -f1)
MSG=$(zarn "$file" 2>&1 > /dev/null)
STATUS=$?
echo -en "\e[34m$NAME ... \e[0m"
if [ $STATUS -eq 0 ]
then
echo -e "\e[32mok\e[0m"
SUCCESS=$(($SUCCESS + 1))
else
echo -e "\e[31mko\e[0m"
echo "$MSG"
fi
TOTAL=$((TOTAL + 1))
done
FAILURE=$(($TOTAL - $SUCCESS))
if [ $SUCCESS -eq $TOTAL ]
then
echo -e "\e[32m======== All tests passed ========\e[0m"
else
echo -e "\e[31m======== $FAILURE tests failed ========\e[0m"
fi
echo -e "\e[0mok:\t$SUCCESS\e[0m"
echo -e "\e[0mko:\t$FAILURE\e[0m"
if [ $SUCCESS -eq $TOTAL ]
then
echo -e "\e[32mTOTAL:\t$TOTAL\e[0m"
else
echo -e "\e[31mTOTAL:\t$TOTAL\e[0m"
fi

8
examples/vardecl.zn Normal file
View File

@ -0,0 +1,8 @@
(assert-fail a)
($ a 34)
(assert-fail (a))
(assert= 34 a)
($ b ($ c 9))
(assert= 9 b)
(assert= 9 c)

View File

@ -2,6 +2,8 @@
#define COMMON_HPP #define COMMON_HPP
#include "../src/Zarn.hpp" #include "../src/Zarn.hpp"
#include "../src/Module.hpp"
using namespace zn; using namespace zn;
#define STDARGS std::vector<std::shared_ptr<Constant>> #define STDARGS std::vector<std::shared_ptr<Constant>>

54
libstd/macro.cpp Normal file
View File

@ -0,0 +1,54 @@
#include "macro.hpp"
void assert_fail(Node const& node, Module& mod)
{
try
{
mod.static_pass().execute(*node.child_at(1));
mod.compiler().compile(*node.child_at(1), mod.program());
Loc loc = node.loc();
std::cerr << loc.file_path().string() << ":" << loc.line();
std::cerr << " ASSERTION FAILED" << std::endl;
exit(-1);
}
catch (std::exception const&)
{
}
size_t addr = mod.program().add_constant(std::make_shared<Constant>
(TYPE_NIL, node.loc(), 0));
mod.program().append(OPCODE_LOAD_CONST, addr);
}
void declare(Node const& node, Module &mod)
{
std::string ident = node.child_at(1)->repr();
mod.compiler().compile(*node.child_at(2), mod.program());
auto entry = mod.sym().find_any(ident);
assert(entry);
size_t addr = mod.sym().gen_addr();
mod.sym().declare(ident, addr, entry->scope);
mod.program().append(OPCODE_STORE_LOCAL, addr);
}
void block(Node const& node, Module& mod)
{
mod.sym().enter_scope();
for (size_t i=1; i<node.size(); i++)
{
mod.static_pass().execute(*node.child_at(i));
mod.compiler().compile(*node.child_at(i), mod.program());
if (i != node.size() - 1)
{
mod.program().append(OPCODE_POP);
}
}
mod.sym().leave_scope();
}

12
libstd/macro.hpp Normal file
View File

@ -0,0 +1,12 @@
#ifndef MACRO_HPP
#define MACRO_HPP
#include "common.hpp"
void assert_fail(Node const& node, Module& mod);
void declare(Node const& node, Module& mod);
void block(Node const& node, Module& mod);
#endif

View File

@ -1,5 +1,7 @@
#include "common.hpp" #include "common.hpp"
#include "fun.hpp" #include "fun.hpp"
#include "macro.hpp"
#include "../src/types.hpp"
extern "C" void lib(Zarn& zarn) extern "C" void lib(Zarn& zarn)
{ {
@ -16,4 +18,8 @@ extern "C" void lib(Zarn& zarn)
->param_any() ->param_any()
->ret(TYPE_NIL), ->ret(TYPE_NIL),
assert_eq); assert_eq);
zarn.register_macro("assert-fail", assert_fail);
zarn.register_macro("$", declare);
zarn.register_macro(":", block);
} }

View File

@ -37,6 +37,7 @@ zarn_lib = shared_library('zarn',
'src/SymTable.cpp', 'src/SymTable.cpp',
'src/NativeFunction.cpp', 'src/NativeFunction.cpp',
'src/Prototype.cpp', 'src/Prototype.cpp',
'src/NativeMacro.cpp',
'src/Zarn.cpp', 'src/Zarn.cpp',
], ],
install: true) install: true)
@ -49,6 +50,7 @@ shared_library('zarn-std',
sources: [ sources: [
'libstd/std.cpp', 'libstd/std.cpp',
'libstd/fun.cpp', 'libstd/fun.cpp',
'libstd/macro.cpp',
], ],
dependencies: [ dependencies: [
zarn_dep zarn_dep

View File

@ -1,11 +1,16 @@
#include "Compiler.hpp" #include "Compiler.hpp"
#include "src/Node.hpp" #include "Module.hpp"
#include "src/Program.hpp" #include "Node.hpp"
#include "Program.hpp"
#include "NativeMacro.hpp"
namespace zn namespace zn
{ {
/*explicit*/ Compiler::Compiler(Logger& logger, SymTable& sym) /*explicit*/ Compiler::Compiler(Module& mod,
: m_logger { logger } Logger& logger,
SymTable& sym)
: m_mod { mod }
, m_logger { logger }
, m_sym { sym } , m_sym { sym }
{ {
} }
@ -14,6 +19,11 @@ namespace zn
{ {
} }
void Compiler::add_macro(std::shared_ptr<NativeMacro> macro)
{
m_macros.push_back(macro);
}
void Compiler::compile(Node const& node, Program& program) void Compiler::compile(Node const& node, Program& program)
{ {
switch (node.type()) switch (node.type())
@ -31,12 +41,44 @@ namespace zn
// FUNCTION STUFF // FUNCTION STUFF
// ============== // ==============
case NODE_CALL: { case NODE_CALL: {
for (size_t i=0; i<node.size(); i++) std::string ident = node.child_at(0)->repr();
{ auto sym = m_sym.find(ident);
compile(*node.child_at(i), program);
}
program.append(OPCODE_CALL_NATIVE, node.size() - 1); if (sym)
{
for (size_t i=0; i<node.size(); i++)
{
compile(*node.child_at(i), program);
}
program.append(OPCODE_CALL_NATIVE, node.size() - 1);
}
else
{
bool found_macro = false;
for (auto macro: m_macros)
{
if (macro->name() == ident)
{
macro->execute(node, m_mod);
found_macro = true;
break;
}
}
if (!found_macro)
{
std::stringstream ss;
ss << "cannot call undefined function '"
<< ident
<< "'";
m_logger.log<compile_error>(LOG_ERROR,
node.loc(),
ss.str());
}
}
} break; } break;
// VALUES // VALUES
@ -44,19 +86,30 @@ namespace zn
case NODE_IDENT: { case NODE_IDENT: {
std::string ident = node.repr(); std::string ident = node.repr();
auto sym = m_sym.find(ident); auto sym = m_sym.find(ident);
assert(sym);
if (!sym)
{
std::stringstream ss;
ss << "cannot use undefined variable '"
<< ident
<< "'";
m_logger.log<compile_error>(LOG_ERROR,
node.loc(),
ss.str());
}
if (sym->prototype) if (sym->prototype)
{ {
auto ref = std::make_shared<Constant>(TYPE_REF, auto ref = std::make_shared<Constant>(TYPE_REF,
node.loc(), node.loc(),
(int) sym->addr); (int) *sym->addr);
size_t val = program.add_constant(ref); size_t val = program.add_constant(ref);
program.append(OPCODE_LOAD_CONST, val); program.append(OPCODE_LOAD_CONST, val);
} }
else else
{ {
program.append(OPCODE_LOAD_LOCAL, sym->addr); program.append(OPCODE_LOAD_LOCAL, *sym->addr);
} }
} break; } break;

View File

@ -11,17 +11,23 @@ namespace zn
{ {
ZN_ERROR(compile_error); ZN_ERROR(compile_error);
class NativeMacro;
class Module;
class Compiler class Compiler
{ {
public: public:
explicit Compiler(Logger& logger, SymTable& sym); explicit Compiler(Module& mod, Logger& logger, SymTable& sym);
virtual ~Compiler(); virtual ~Compiler();
void add_macro(std::shared_ptr<NativeMacro> macro);
void compile(Node const& node, Program& program); void compile(Node const& node, Program& program);
private: private:
Module& m_mod;
Logger& m_logger; Logger& m_logger;
SymTable& m_sym; SymTable& m_sym;
std::vector<std::shared_ptr<NativeMacro>> m_macros;
}; };
} }

View File

@ -31,6 +31,10 @@ namespace zn
{ {
case TYPE_NIL: return "<nil>"; case TYPE_NIL: return "<nil>";
case TYPE_INT: return std::to_string(std::get<int>(*m_value)); case TYPE_INT: return std::to_string(std::get<int>(*m_value));
case TYPE_REF: {
return "<ref " + std::to_string(std::get<int>(*m_value)) + ">";
} break;
default: { default: {
std::cerr << "cannot stringify " std::cerr << "cannot stringify "
<< (TypeStr[m_type] + strlen("TYPE_")) << (TypeStr[m_type] + strlen("TYPE_"))

View File

@ -1,4 +1,5 @@
#include "Module.hpp" #include "Module.hpp"
#include "Zarn.hpp"
#include "Lexer.hpp" #include "Lexer.hpp"
#include "Parser.hpp" #include "Parser.hpp"
#include "Program.hpp" #include "Program.hpp"
@ -48,11 +49,8 @@ namespace zn
m_zarn.load_std_library(); m_zarn.load_std_library();
StaticPass static_pass { m_logger, m_sym }; m_static_pass.execute(*ast);
static_pass.execute(*ast); m_compiler.compile(*ast, m_program);
Compiler compiler { m_logger, m_sym };
compiler.compile(*ast, m_program);
m_vm.execute(m_program); m_vm.execute(m_program);
} }

View File

@ -6,6 +6,8 @@
#include "VM.hpp" #include "VM.hpp"
#include "Program.hpp" #include "Program.hpp"
#include "SymTable.hpp" #include "SymTable.hpp"
#include "StaticPass.hpp"
#include "Compiler.hpp"
#include "Zarn.hpp" #include "Zarn.hpp"
namespace zn namespace zn
@ -18,6 +20,12 @@ namespace zn
explicit Module(Logger& logger); explicit Module(Logger& logger);
virtual ~Module(); virtual ~Module();
Compiler& compiler() { return m_compiler; }
StaticPass& static_pass() { return m_static_pass; }
Program& program() { return m_program; }
SymTable& sym() { return m_sym; }
void load_from_file(std::filesystem::path file_path); void load_from_file(std::filesystem::path file_path);
std::string string() const; std::string string() const;
@ -27,7 +35,9 @@ namespace zn
Program m_program; Program m_program;
VM m_vm { m_program }; VM m_vm { m_program };
SymTable m_sym; SymTable m_sym;
Zarn m_zarn {m_sym, m_vm}; StaticPass m_static_pass {m_logger, m_sym};
Compiler m_compiler {*this, m_logger, m_sym};
Zarn m_zarn {m_compiler, m_sym, m_vm};
}; };
} }

21
src/NativeMacro.cpp Normal file
View File

@ -0,0 +1,21 @@
#include "NativeMacro.hpp"
namespace zn
{
/*explicit*/ NativeMacro::NativeMacro(std::string const& name,
native_macro_t macro)
: m_name { name }
, m_macro { macro }
{
}
/*virtual*/ NativeMacro::~NativeMacro()
{
}
void NativeMacro::execute(Node const& node,
Module& mod)
{
m_macro(node, mod);
}
}

36
src/NativeMacro.hpp Normal file
View File

@ -0,0 +1,36 @@
#ifndef zn_NATIVEMACRO_HPP
#define zn_NATIVEMACRO_HPP
#include "common.hpp"
#include "Compiler.hpp"
#include "SymTable.hpp"
#include "Node.hpp"
namespace zn
{
class Module;
using native_macro_t = std::function<void
(Node const&,
Module&)>;
class NativeMacro
{
public:
explicit NativeMacro(std::string const& name, native_macro_t macro);
virtual ~NativeMacro();
std::string name() const { return m_name; }
void execute(Node const& node,
Module&);
private:
std::string m_name;
native_macro_t m_macro;
};
}
#endif

View File

@ -27,19 +27,33 @@ namespace zn
case NODE_CALL: { case NODE_CALL: {
std::string ident = node.child_at(0)->repr(); std::string ident = node.child_at(0)->repr();
auto sym = m_sym.find(ident); auto sym = m_sym.find_any(ident);
if (ident == "$")
{
std::string varname = node.child_at(1)->repr();
auto vartype = execute(*node.child_at(2));
m_sym.prepare(varname, *vartype.type);
return vartype;
}
if (sym == std::nullopt) if (sym == std::nullopt)
{ {
m_logger.log<static_error>(LOG_ERROR, return TypeSlot {TYPE_NIL, TAG_ANY};
node.loc(),
"cannot call unknown function '"
+ ident
+ "'");
} }
auto proto = sym->prototype; auto proto = sym->prototype;
assert(proto);
if (!proto)
{
std::stringstream ss;
ss << "cannot call a none function variable '"
<< ident
<< "'";
m_logger.log<static_error>(LOG_ERROR, node.loc(), ss.str());
}
if (proto->get_param_count() != node.size() - 1 if (proto->get_param_count() != node.size() - 1
&& proto->get_param(proto->get_param_count() - 1).tag && proto->get_param(proto->get_param_count() - 1).tag
@ -79,6 +93,19 @@ namespace zn
return proto->get_ret(); return proto->get_ret();
} break; } break;
case NODE_IDENT: {
std::string ident = node.repr();
auto sym = m_sym.find_any(ident);
if (sym) assert(sym->scope <= m_sym.scope());
if (sym == std::nullopt)
{
std::stringstream ss;
ss << "undeclared var '" << ident << "'";
m_logger.log<static_error>(LOG_ERROR, node.loc(), ss.str());
}
return TypeSlot {sym->type};
} break;
case NODE_INT: { case NODE_INT: {
return TypeSlot {TYPE_INT}; return TypeSlot {TYPE_INT};
} break; } break;

View File

@ -17,6 +17,7 @@ namespace zn
virtual ~StaticPass(); virtual ~StaticPass();
TypeSlot execute(Node const& node); TypeSlot execute(Node const& node);
private: private:
Logger& m_logger; Logger& m_logger;
SymTable& m_sym; SymTable& m_sym;

View File

@ -10,28 +10,115 @@ namespace zn
{ {
} }
void SymTable::declare(std::string const& name, size_t addr) void SymTable::prepare(std::string const& name, Type type)
{ {
m_syms.push_back(Sym {name, addr}); m_syms.push_back(Sym {name, std::nullopt, type, nullptr, m_scope});
}
void SymTable::declare(std::string const& name,
size_t addr,
int scope)
{
auto itr = std::find_if(std::begin(m_syms),
std::end(m_syms),
[name, scope](auto const& sym){
return sym.name == name
&& sym.scope == scope;
});
if (itr == std::end(m_syms))
{
abort();
}
itr->addr = addr;
} }
void SymTable::declare_function(std::string const& name, void SymTable::declare_function(std::string const& name,
size_t addr, size_t addr,
std::shared_ptr<Prototype> prototype) std::shared_ptr<Prototype> prototype)
{ {
m_syms.push_back(Sym {name, addr, prototype}); m_syms.push_back(Sym {name, addr, TYPE_FUNCTION, prototype, m_scope});
} }
std::optional<Sym> SymTable::find(std::string const& name) std::optional<Sym> SymTable::find(std::string const& name)
{ {
std::optional<size_t> best;
for (size_t i=0; i<m_syms.size(); i++) for (size_t i=0; i<m_syms.size(); i++)
{ {
if (name == m_syms[i].name) if (name == m_syms[i].name
&& m_syms[i].addr
&& (best == std::nullopt ||
(m_syms[i].scope > m_syms[*best].scope
&& m_syms[*best].scope < m_scope)))
{ {
return m_syms[i]; best = i;
} }
} }
if (best)
{
return m_syms[*best];
}
return std::nullopt; return std::nullopt;
} }
std::optional<Sym> SymTable::find_any(std::string const& name)
{
std::optional<size_t> best;
for (size_t i=0; i<m_syms.size(); i++)
{
if (name == m_syms[i].name
&& m_syms[i].scope <= m_scope
&& (best == std::nullopt ||
(m_syms[i].scope > m_syms[*best].scope
&& m_syms[*best].scope <= m_scope)))
{
best = i;
}
}
if (best)
{
return m_syms[*best];
}
return std::nullopt;
}
size_t SymTable::gen_addr()
{
static size_t addr = 0;
addr++;
return addr;
}
void SymTable::enter_scope()
{
m_scope++;
}
void SymTable::leave_scope()
{
m_scope--;
}
std::string SymTable::string() const
{
std::stringstream ss;
ss << "======== " << m_scope << " ========\n";
for (auto sym: m_syms)
{
ss << sym.scope << "\t" << sym.name << " "
<< (sym.addr ? "[" + std::to_string(*sym.addr) + "]" : "[nil]")
<< "\n";
}
return ss.str();
}
} }

View File

@ -3,13 +3,16 @@
#include "common.hpp" #include "common.hpp"
#include "Prototype.hpp" #include "Prototype.hpp"
#include "Node.hpp"
namespace zn namespace zn
{ {
struct Sym { struct Sym {
std::string name; std::string name;
size_t addr; std::optional<size_t> addr;
Type type;
std::shared_ptr<Prototype> prototype = nullptr; std::shared_ptr<Prototype> prototype = nullptr;
int scope = 0;
}; };
class SymTable class SymTable
@ -18,16 +21,30 @@ namespace zn
explicit SymTable(); explicit SymTable();
virtual ~SymTable(); virtual ~SymTable();
void declare(std::string const& name, size_t addr); int scope() const { return m_scope; }
size_t size() const { return m_syms.size(); }
void prepare(std::string const& name, Type type);
void declare(std::string const& name,
size_t addr,
int scope);
void declare_function(std::string const& name, void declare_function(std::string const& name,
size_t addr, size_t addr,
std::shared_ptr<Prototype> prototype); std::shared_ptr<Prototype> prototype);
std::optional<Sym> find(std::string const& name); std::optional<Sym> find(std::string const& name);
std::optional<Sym> find_any(std::string const& name);
size_t gen_addr();
void enter_scope();
void leave_scope();
std::string string() const;
private: private:
std::vector<Sym> m_syms; std::vector<Sym> m_syms;
int m_scope = 0;
}; };
} }

View File

@ -35,8 +35,14 @@ namespace zn
} break; } break;
case OPCODE_LOAD_LOCAL: { case OPCODE_LOAD_LOCAL: {
auto constant = frame().locals[to_vm_addr(param)]; auto constant = load_local(param);
push(program.add_constant(constant)); size_t addr = program.add_constant(constant);
push(addr);
m_pc++;
} break;
case OPCODE_STORE_LOCAL: {
store_local(param, frame().program.constant(top()));
m_pc++; m_pc++;
} break; } break;
@ -97,17 +103,14 @@ namespace zn
size_t VM::store_local(int index, std::shared_ptr<Constant> constant) size_t VM::store_local(int index, std::shared_ptr<Constant> constant)
{ {
frame().locals.push_back(constant); frame().locals[index] = constant;
size_t addr = frame().locals.size() - 1; size_t addr = frame().locals.size() - 1;
m_addr_mapping[index] = addr;
return addr; return addr;
} }
std::shared_ptr<Constant> VM::load_local(int index) const std::shared_ptr<Constant> VM::load_local(int index) const
{ {
size_t addr = to_vm_addr(index); return m_frames.back().locals.at(index);
assert(addr < m_frames.back().locals.size());
return m_frames.back().locals[addr];
} }
size_t VM::store_global(global_var_t var) size_t VM::store_global(global_var_t var)
@ -116,26 +119,6 @@ namespace zn
return m_globals.size() - 1; return m_globals.size() - 1;
} }
size_t VM::to_vm_addr(int user_addr) const
{
return m_addr_mapping.at(user_addr);
}
int VM::to_user_addr(size_t vm_addr) const
{
for (auto const& entry: m_addr_mapping)
{
if (entry.second == vm_addr)
{
return entry.first;
}
}
std::cerr << "cannot find user addr of '"
<< vm_addr << "'" << std::endl;
abort();
}
Frame& VM::frame() Frame& VM::frame()
{ {
return m_frames.back(); return m_frames.back();
@ -153,4 +136,11 @@ namespace zn
m_stack.pop_back(); m_stack.pop_back();
return value; return value;
} }
int VM::top()
{
assert(m_stack.size() > 0);
int value = m_stack.back();
return value;
}
} }

View File

@ -9,7 +9,7 @@ namespace zn
{ {
struct Frame { struct Frame {
Program& program; Program& program;
std::vector<std::shared_ptr<Constant>> locals; std::unordered_map<int, std::shared_ptr<Constant>> locals;
}; };
using global_var_t = std::variant<std::shared_ptr<NativeFunction>>; using global_var_t = std::variant<std::shared_ptr<NativeFunction>>;
@ -30,19 +30,16 @@ namespace zn
size_t store_global(global_var_t var); size_t store_global(global_var_t var);
size_t to_vm_addr(int user_addr) const;
int to_user_addr(size_t vm_addr) const;
private: private:
std::vector<Frame> m_frames; std::vector<Frame> m_frames;
std::vector<int> m_stack; std::vector<int> m_stack;
std::vector<global_var_t> m_globals; std::vector<global_var_t> m_globals;
std::unordered_map<int, size_t> m_addr_mapping;
size_t m_pc = 0; size_t m_pc = 0;
Frame& frame(); Frame& frame();
void push(int value); void push(int value);
int pop(); int pop();
int top();
}; };
} }

View File

@ -4,18 +4,19 @@
namespace zn namespace zn
{ {
/*explicit*/ Zarn::Zarn(SymTable& sym, VM& vm) /*explicit*/ Zarn::Zarn(Compiler& compiler, SymTable& sym, VM& vm)
: m_sym { sym } : m_compiler { compiler }
, m_sym { sym }
, m_vm { vm } , m_vm { vm }
{ {
} }
/*virtual*/ Zarn::~Zarn() /*virtual*/ Zarn::~Zarn()
{ {
for (void* handler: m_handlers) //for (void* handler: m_handlers)
{ // {
// dlclose(handler); // // dlclose(handler);
} // }
m_handlers.clear(); m_handlers.clear();
} }
@ -27,12 +28,16 @@ namespace zn
auto func = std::make_shared<NativeFunction>(prototype, body); auto func = std::make_shared<NativeFunction>(prototype, body);
int addr = m_vm.store_global(func); int addr = m_vm.store_global(func);
m_sym.declare_function(name, addr, prototype); m_sym.declare_function(name, addr, prototype);
// auto ref = std::make_shared<Constant>(TYPE_REF, addr);
// m_vm.store_local(0, ref);
// m_sym.declare_function(name, 0, prototype);
} }
void Zarn::register_macro(std::string const& name,
native_macro_t macro)
{
auto m = std::make_shared<NativeMacro>(name, macro);
m_compiler.add_macro(m);
}
void Zarn::load_std_library() void Zarn::load_std_library()
{ {
load_library(ZN_LIBDIR / "libzarn-std.so"); load_library(ZN_LIBDIR / "libzarn-std.so");

View File

@ -4,22 +4,27 @@
#include "common.hpp" #include "common.hpp"
#include "SymTable.hpp" #include "SymTable.hpp"
#include "VM.hpp" #include "VM.hpp"
#include "NativeMacro.hpp"
namespace zn namespace zn
{ {
class Zarn class Zarn
{ {
public: public:
explicit Zarn(SymTable& sym, VM& vm); explicit Zarn(Compiler& compiler, SymTable& sym, VM& vm);
virtual ~Zarn(); virtual ~Zarn();
void register_function(std::string const& name, void register_function(std::string const& name,
std::shared_ptr<Prototype> prototype, std::shared_ptr<Prototype> prototype,
native_fn_t body); native_fn_t body);
void register_macro(std::string const& name,
native_macro_t macro);
void load_std_library(); void load_std_library();
void load_library(std::filesystem::path lib_path); void load_library(std::filesystem::path lib_path);
private: private:
Compiler& m_compiler;
SymTable& m_sym; SymTable& m_sym;
VM& m_vm; VM& m_vm;
std::vector<void*> m_handlers; std::vector<void*> m_handlers;

View File

@ -3,10 +3,11 @@
#include "common.hpp" #include "common.hpp"
#define TYPES(G) \ #define TYPES(G) \
G(TYPE_NIL), \ G(TYPE_NIL), \
G(TYPE_INT), \ G(TYPE_INT), \
G(TYPE_REF) G(TYPE_REF), \
G(TYPE_FUNCTION)
namespace zn namespace zn
{ {