ADD: native macros.
parent
bcf12d19f7
commit
5fe53355b5
|
@ -9,4 +9,6 @@ using namespace fk;
|
|||
#define STDARGS std::vector<std::shared_ptr<Constant>>
|
||||
#define STDRET std::shared_ptr<Constant>
|
||||
|
||||
FK_ERROR(assert_error);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2,6 +2,26 @@
|
|||
|
||||
namespace fkstd
|
||||
{
|
||||
STDRET assert_eq(STDARGS args)
|
||||
{
|
||||
auto oracle = args[0];
|
||||
auto expr = args[1];
|
||||
|
||||
if (!oracle->equals(*expr))
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "assertion failed: expected '"
|
||||
<< oracle->string()
|
||||
<< "', got '"
|
||||
<< expr->string()
|
||||
<< "'";
|
||||
|
||||
oracle->loc().error<assert_error>(LOG_ERROR, ss.str());
|
||||
}
|
||||
|
||||
return std::make_shared<Constant>(TYPE_BOOL, true, oracle->loc());
|
||||
}
|
||||
|
||||
STDRET println(STDARGS args)
|
||||
{
|
||||
std::string sep;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
namespace fkstd
|
||||
{
|
||||
STDRET assert_eq(STDARGS args);
|
||||
STDRET println(STDARGS args);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
#include "commons.hpp"
|
||||
#include "fun.hpp"
|
||||
#include "macro.hpp"
|
||||
|
||||
extern "C" void lib(Module& mod)
|
||||
{
|
||||
mod.register_function("assert=", fkstd::assert_eq);
|
||||
mod.register_function("println", fkstd::println);
|
||||
|
||||
mod.register_macro("assert-static-fail", fkstd::assert_static_fail);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
#include "macro.hpp"
|
||||
|
||||
namespace fkstd
|
||||
{
|
||||
void assert_static_fail(Compiler& compiler,
|
||||
std::shared_ptr<Node> node,
|
||||
std::shared_ptr<Program> program)
|
||||
{
|
||||
try
|
||||
{
|
||||
compiler.compile_prog(node->child(1), program);
|
||||
}
|
||||
catch(std::exception const&)
|
||||
{
|
||||
program->load_const(std::make_shared<Constant>(TYPE_BOOL,
|
||||
true,
|
||||
node->loc()));
|
||||
return;
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "assertion failed";
|
||||
node->loc().error<assert_error>(LOG_ERROR, ss.str());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef fkstd_MACRO_HPP
|
||||
#define fkstd_MACRO_HPP
|
||||
#include "commons.hpp"
|
||||
|
||||
namespace fkstd
|
||||
{
|
||||
void assert_static_fail(Compiler& compiler,
|
||||
std::shared_ptr<Node> node,
|
||||
std::shared_ptr<Program> program);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -29,6 +29,7 @@ fakir_cpp = [
|
|||
'src/Parser.cpp',
|
||||
'src/Constant.cpp',
|
||||
'src/NativeFunction.cpp',
|
||||
'src/NativeMacro.cpp',
|
||||
'src/SymTable.cpp',
|
||||
'src/SymEntry.cpp',
|
||||
|
||||
|
@ -52,6 +53,7 @@ fakir_hpp = [
|
|||
'src/Program.hpp',
|
||||
'src/Module.hpp',
|
||||
'src/NativeFunction.hpp',
|
||||
'src/NativeMacro.hpp',
|
||||
'src/opcodes.hpp',
|
||||
'src/commons.hpp',
|
||||
'src/types.hpp',
|
||||
|
@ -74,6 +76,7 @@ shared_library('fakir-std',
|
|||
sources: [
|
||||
'libstd/lib.cpp',
|
||||
'libstd/fun.cpp',
|
||||
'libstd/macro.cpp',
|
||||
],
|
||||
dependencies: [
|
||||
fakir_dep
|
||||
|
|
|
@ -11,6 +11,12 @@ namespace fk
|
|||
{
|
||||
}
|
||||
|
||||
void Compiler::add_macro(std::string const& name,
|
||||
std::shared_ptr<NativeMacro> macro)
|
||||
{
|
||||
m_macros[name] = macro;
|
||||
}
|
||||
|
||||
std::shared_ptr<Program> Compiler::compile(std::shared_ptr<Node> node)
|
||||
{
|
||||
auto prog = std::make_shared<Program>();
|
||||
|
@ -33,12 +39,22 @@ namespace fk
|
|||
|
||||
case NODE_CALL: {
|
||||
std::string ident = node->child(0)->repr();
|
||||
for (size_t i=0; i<node->size(); i++)
|
||||
{
|
||||
compile_prog(node->child(i), prog);
|
||||
}
|
||||
|
||||
prog->add(OP_CALL_NATIVE, node->size() - 1);
|
||||
if (auto itr=m_macros.find(ident);
|
||||
itr != std::end(m_macros))
|
||||
{
|
||||
auto macro = itr->second;
|
||||
macro->call(*this, node, prog);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t i=0; i<node->size(); i++)
|
||||
{
|
||||
compile_prog(node->child(i), prog);
|
||||
}
|
||||
|
||||
prog->add(OP_CALL_NATIVE, node->size() - 1);
|
||||
}
|
||||
} break;
|
||||
|
||||
case NODE_IDENT: {
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "Program.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "SymTable.hpp"
|
||||
#include "NativeMacro.hpp"
|
||||
|
||||
namespace fk
|
||||
{
|
||||
|
@ -16,13 +17,19 @@ namespace fk
|
|||
explicit Compiler(std::shared_ptr<SymTable> sym);
|
||||
virtual ~Compiler();
|
||||
|
||||
std::shared_ptr<Program> compile(std::shared_ptr<Node> node);
|
||||
void add_macro(std::string const& name,
|
||||
std::shared_ptr<NativeMacro> macro);
|
||||
|
||||
private:
|
||||
std::shared_ptr<SymTable> m_sym;
|
||||
std::shared_ptr<Program> compile(std::shared_ptr<Node> node);
|
||||
|
||||
void compile_prog(std::shared_ptr<Node> node,
|
||||
std::shared_ptr<Program> prog);
|
||||
|
||||
private:
|
||||
std::shared_ptr<SymTable> m_sym;
|
||||
std::unordered_map<std::string,
|
||||
std::shared_ptr<NativeMacro>> m_macros;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "conf.hpp"
|
||||
#include "Module.hpp"
|
||||
#include "Loc.hpp"
|
||||
#include "NativeMacro.hpp"
|
||||
|
||||
namespace fk
|
||||
{
|
||||
|
@ -49,6 +50,12 @@ namespace fk
|
|||
m_sym->declare_global(name, addr, Loc {"extern"});
|
||||
}
|
||||
|
||||
void Module::register_macro(std::string const& name, macro_t macro)
|
||||
{
|
||||
auto m = std::make_shared<NativeMacro>(macro);
|
||||
m_compiler->add_macro(name, m);
|
||||
}
|
||||
|
||||
std::string Module::load_sources()
|
||||
{
|
||||
std::ifstream file { m_source_path };
|
||||
|
|
|
@ -24,6 +24,7 @@ namespace fk
|
|||
void import_library(std::filesystem::path lib_path);
|
||||
|
||||
void register_function(std::string const& name, native_t native);
|
||||
void register_macro(std::string const& name, macro_t macro);
|
||||
|
||||
private:
|
||||
std::filesystem::path m_source_path;
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
#include "NativeMacro.hpp"
|
||||
#include "Compiler.hpp"
|
||||
#include "Program.hpp"
|
||||
#include "Node.hpp"
|
||||
|
||||
namespace fk
|
||||
{
|
||||
/*explicit*/ NativeMacro::NativeMacro(macro_t macro)
|
||||
: m_macro { macro }
|
||||
{
|
||||
}
|
||||
|
||||
/*virtual*/ NativeMacro::~NativeMacro()
|
||||
{
|
||||
}
|
||||
|
||||
void NativeMacro::call(Compiler& compiler,
|
||||
std::shared_ptr<Node> node,
|
||||
std::shared_ptr<Program> program)
|
||||
{
|
||||
m_macro(compiler, node, program);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef fk_NATIVEMACRO_HPP
|
||||
#define fk_NATIVEMACRO_HPP
|
||||
|
||||
#include "commons.hpp"
|
||||
|
||||
namespace fk
|
||||
{
|
||||
class Compiler;
|
||||
class Program;
|
||||
class Node;
|
||||
|
||||
using macro_t = std::function<void(Compiler&,
|
||||
std::shared_ptr<Node>,
|
||||
std::shared_ptr<Program>)>;
|
||||
|
||||
class NativeMacro
|
||||
{
|
||||
public:
|
||||
explicit NativeMacro(macro_t macro);
|
||||
virtual ~NativeMacro();
|
||||
|
||||
void call(Compiler& compiler,
|
||||
std::shared_ptr<Node> node,
|
||||
std::shared_ptr<Program> program);
|
||||
private:
|
||||
macro_t m_macro;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
25
src/main.cpp
25
src/main.cpp
|
@ -5,10 +5,13 @@
|
|||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
bool debug_mode = false;
|
||||
|
||||
while (true)
|
||||
{
|
||||
static struct option options[] = {
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"debug", no_argument, 0, 'd'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
@ -34,6 +37,10 @@ int main(int argc, char** argv)
|
|||
return 0;
|
||||
} break;
|
||||
|
||||
case 'd': {
|
||||
debug_mode = true;
|
||||
} break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +56,23 @@ int main(int argc, char** argv)
|
|||
if (sources.size())
|
||||
{
|
||||
fk::Module mod {sources[0]};
|
||||
mod.build();
|
||||
|
||||
if (debug_mode)
|
||||
{
|
||||
mod.build();
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
mod.build();
|
||||
}
|
||||
catch(std::exception const& err)
|
||||
{
|
||||
std::cerr << err.what() << std::endl;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue