ADD: set core macro.

main
bog 2023-09-22 14:17:21 +02:00
parent 70d0ba241c
commit 9591d6c176
16 changed files with 134 additions and 46 deletions

21
examples/set.fk Normal file
View File

@ -0,0 +1,21 @@
($ a 32)
(! a 54)
(assert= 54 a)
(:
($ a 12)
(! a 99)
(assert= 99 a)
)
(assert= 54 a)
($ f (-> (x) (+ 2 x)))
(assert= 5 (f 3))
(! f (-> (x) (* x 4)))
(assert= 12 (f 3))

View File

@ -4,11 +4,13 @@
#include <cmath> #include <cmath>
#include "../src/Module.hpp" #include "../src/Module.hpp"
#include "../src/Constant.hpp" #include "../src/Constant.hpp"
#include "../src/SymTable.hpp"
using namespace fk; using namespace fk;
#define STDARGS std::vector<std::shared_ptr<Constant>> #define STDARGS std::vector<std::shared_ptr<Constant>>
#define STDRET std::shared_ptr<Constant> #define STDRET std::shared_ptr<Constant>
#define STDSYM std::shared_ptr<SymTable>
FK_ERROR(assert_error); FK_ERROR(assert_error);

View File

@ -20,7 +20,7 @@
namespace fkstd namespace fkstd
{ {
STDRET assert_eq(Loc loc, STDARGS args) STDRET assert_eq(Loc loc, Module&, STDARGS args)
{ {
auto oracle = args[0]; auto oracle = args[0];
auto expr = args[1]; auto expr = args[1];
@ -40,7 +40,7 @@ namespace fkstd
return std::make_shared<Constant>(TYPE_BOOL, true, loc); return std::make_shared<Constant>(TYPE_BOOL, true, loc);
} }
STDRET println(Loc loc, STDARGS args) STDRET println(Loc loc, Module&, STDARGS args)
{ {
std::string sep; std::string sep;
@ -60,7 +60,7 @@ namespace fkstd
return std::make_shared<Constant>(TYPE_INT, 0, loc); return std::make_shared<Constant>(TYPE_INT, 0, loc);
} }
STDRET add_int(Loc loc, STDARGS args) STDRET add_int(Loc loc, Module&, STDARGS args)
{ {
int result = 0; int result = 0;
@ -72,7 +72,7 @@ namespace fkstd
return std::make_shared<Constant>(TYPE_INT, result, loc); return std::make_shared<Constant>(TYPE_INT, result, loc);
} }
STDRET sub_int(Loc loc, STDARGS args) STDRET sub_int(Loc loc, Module&, STDARGS args)
{ {
if (args.empty()) if (args.empty())
{ {
@ -96,7 +96,7 @@ namespace fkstd
return std::make_shared<Constant>(TYPE_INT, result, loc); return std::make_shared<Constant>(TYPE_INT, result, loc);
} }
STDRET mul_int(Loc loc, STDARGS args) STDRET mul_int(Loc loc, Module&, STDARGS args)
{ {
int result = 1; int result = 1;
@ -108,7 +108,7 @@ namespace fkstd
return std::make_shared<Constant>(TYPE_INT, result, loc); return std::make_shared<Constant>(TYPE_INT, result, loc);
} }
STDRET div_int(Loc loc, STDARGS args) STDRET div_int(Loc loc, Module&, STDARGS args)
{ {
if (args.empty()) if (args.empty())
{ {
@ -132,7 +132,7 @@ namespace fkstd
return std::make_shared<Constant>(TYPE_INT, result, loc); return std::make_shared<Constant>(TYPE_INT, result, loc);
} }
STDRET mod_int(Loc loc, STDARGS args) STDRET mod_int(Loc loc, Module&, STDARGS args)
{ {
if (args.empty()) if (args.empty())
{ {
@ -149,7 +149,7 @@ namespace fkstd
return std::make_shared<Constant>(TYPE_INT, result, loc); return std::make_shared<Constant>(TYPE_INT, result, loc);
} }
STDRET pow_int(Loc loc, STDARGS args) STDRET pow_int(Loc loc, Module&, STDARGS args)
{ {
if (args.empty()) if (args.empty())
{ {
@ -166,32 +166,32 @@ namespace fkstd
return std::make_shared<Constant>(TYPE_INT, result, loc); return std::make_shared<Constant>(TYPE_INT, result, loc);
} }
STDRET lt(Loc loc, STDARGS args) STDRET lt(Loc loc, Module&, STDARGS args)
{ {
NUM_BINOP(<); NUM_BINOP(<);
} }
STDRET le(Loc loc, STDARGS args) STDRET le(Loc loc, Module&, STDARGS args)
{ {
NUM_BINOP(<=); NUM_BINOP(<=);
} }
STDRET gt(Loc loc, STDARGS args) STDRET gt(Loc loc, Module&, STDARGS args)
{ {
NUM_BINOP(>); NUM_BINOP(>);
} }
STDRET ge(Loc loc, STDARGS args) STDRET ge(Loc loc, Module&, STDARGS args)
{ {
NUM_BINOP(>=); NUM_BINOP(>=);
} }
STDRET eq(Loc loc, STDARGS args) STDRET eq(Loc loc, Module&, STDARGS args)
{ {
NUM_BINOP(==); NUM_BINOP(==);
} }
STDRET ne(Loc loc, STDARGS args) STDRET ne(Loc loc, Module&, STDARGS args)
{ {
NUM_BINOP(!=); NUM_BINOP(!=);
} }

View File

@ -4,22 +4,24 @@
namespace fkstd namespace fkstd
{ {
STDRET assert_eq(Loc loc, STDARGS args); STDRET set(Loc loc, Module& mod, STDARGS args);
STDRET println(Loc loc, STDARGS args);
STDRET add_int(Loc loc, STDARGS args); STDRET assert_eq(Loc loc, Module& mod, STDARGS args);
STDRET sub_int(Loc loc, STDARGS args); STDRET println(Loc loc, Module& mod, STDARGS args);
STDRET mul_int(Loc loc, STDARGS args);
STDRET div_int(Loc loc, STDARGS args);
STDRET mod_int(Loc loc, STDARGS args);
STDRET pow_int(Loc loc, STDARGS args);
STDRET lt(Loc loc, STDARGS args); STDRET add_int(Loc loc, Module& mod, STDARGS args);
STDRET le(Loc loc, STDARGS args); STDRET sub_int(Loc loc, Module& mod, STDARGS args);
STDRET gt(Loc loc, STDARGS args); STDRET mul_int(Loc loc, Module& mod, STDARGS args);
STDRET ge(Loc loc, STDARGS args); STDRET div_int(Loc loc, Module& mod, STDARGS args);
STDRET eq(Loc loc, STDARGS args); STDRET mod_int(Loc loc, Module& mod, STDARGS args);
STDRET ne(Loc loc, STDARGS args); STDRET pow_int(Loc loc, Module& mod, STDARGS args);
STDRET lt(Loc loc, Module& mod, STDARGS args);
STDRET le(Loc loc, Module& mod, STDARGS args);
STDRET gt(Loc loc, Module& mod, STDARGS args);
STDRET ge(Loc loc, Module& mod, STDARGS args);
STDRET eq(Loc loc, Module& mod, STDARGS args);
STDRET ne(Loc loc, Module& mod, STDARGS args);
} }
#endif #endif

View File

@ -2,11 +2,11 @@
#include "fun.hpp" #include "fun.hpp"
#include "macro.hpp" #include "macro.hpp"
Module* glob_mod; Module* _module;
extern "C" void lib(Module& mod) extern "C" void lib(Module& mod)
{ {
glob_mod = &mod; _module = &mod;
mod.register_function("assert=", fkstd::assert_eq); mod.register_function("assert=", fkstd::assert_eq);
mod.register_function("println", fkstd::println); mod.register_function("println", fkstd::println);
mod.register_function("+", fkstd::add_int); mod.register_function("+", fkstd::add_int);
@ -22,6 +22,7 @@ extern "C" void lib(Module& mod)
mod.register_function("=", fkstd::eq); mod.register_function("=", fkstd::eq);
mod.register_function("<>", fkstd::ne); mod.register_function("<>", fkstd::ne);
mod.register_macro("!", fkstd::set_addr);
mod.register_macro("assert-static-fail", fkstd::assert_static_fail); mod.register_macro("assert-static-fail", fkstd::assert_static_fail);
mod.register_macro(":", fkstd::block); mod.register_macro(":", fkstd::block);
mod.register_macro("$", fkstd::decl); mod.register_macro("$", fkstd::decl);

View File

@ -3,6 +3,17 @@
namespace fkstd namespace fkstd
{ {
void set_addr(Compiler& compiler,
std::shared_ptr<Node> node,
std::shared_ptr<Program> program)
{
auto ident = node->child(1)->repr();
compiler.compile_prog(node->child(2), program);
auto entry = compiler.sym()->find(ident);
program->add(OP_STORE_LOCAL, entry->addr());
}
void assert_static_fail(Compiler& compiler, void assert_static_fail(Compiler& compiler,
std::shared_ptr<Node> node, std::shared_ptr<Node> node,
std::shared_ptr<Program> program) std::shared_ptr<Program> program)

View File

@ -4,6 +4,10 @@
namespace fkstd namespace fkstd
{ {
void set_addr(Compiler& compiler,
std::shared_ptr<Node> node,
std::shared_ptr<Program> program);
void assert_static_fail(Compiler& compiler, void assert_static_fail(Compiler& compiler,
std::shared_ptr<Node> node, std::shared_ptr<Node> node,
std::shared_ptr<Program> program); std::shared_ptr<Program> program);

View File

@ -20,9 +20,9 @@ namespace fk
import_std(); import_std();
m_source = load_sources(); m_source = load_sources();
m_ast = m_parser->parse(m_source); m_ast = m_parser->parse(m_source);
m_program = m_compiler->compile(m_ast);
auto program = m_compiler->compile(m_ast); m_vm->mount(m_program);
m_vm->mount(program);
m_vm->run(); m_vm->run();
} }

View File

@ -18,6 +18,8 @@ namespace fk
explicit Module(std::filesystem::path source_path); explicit Module(std::filesystem::path source_path);
virtual ~Module(); virtual ~Module();
std::shared_ptr<Program> program() const { return m_program; }
std::shared_ptr<SymTable> sym() const { return m_sym; }
std::shared_ptr<VM> vm() const { return m_vm; } std::shared_ptr<VM> vm() const { return m_vm; }
void build(); void build();
@ -37,8 +39,8 @@ namespace fk
std::shared_ptr<SymTable> m_sym = std::make_shared<SymTable>(); std::shared_ptr<SymTable> m_sym = std::make_shared<SymTable>();
std::shared_ptr<Compiler> m_compiler = std::make_shared<Compiler>(m_sym); std::shared_ptr<Compiler> m_compiler = std::make_shared<Compiler>(m_sym);
std::shared_ptr<Node> m_ast; std::shared_ptr<Node> m_ast;
std::shared_ptr<VM> m_vm = std::make_shared<VM>(); std::shared_ptr<VM> m_vm = std::make_shared<VM>(*this);
std::shared_ptr<Program> m_program = std::make_shared<Program>();
std::string load_sources(); std::string load_sources();
}; };
} }

View File

@ -1,4 +1,5 @@
#include "NativeFunction.hpp" #include "NativeFunction.hpp"
#include "Module.hpp"
namespace fk namespace fk
{ {
@ -13,8 +14,9 @@ namespace fk
std::shared_ptr<Constant> std::shared_ptr<Constant>
NativeFunction::call(Loc const& loc, NativeFunction::call(Loc const& loc,
Module& mod,
std::vector<std::shared_ptr<Constant>> args) std::vector<std::shared_ptr<Constant>> args)
{ {
return m_native(loc, args); return m_native(loc, mod, args);
} }
} }

View File

@ -6,8 +6,12 @@
namespace fk namespace fk
{ {
class Module;
using native_t = std::function using native_t = std::function
<std::shared_ptr<Constant>(Loc, std::vector<std::shared_ptr<Constant>>)>; <std::shared_ptr<Constant>(Loc,
Module&,
std::vector<std::shared_ptr<Constant>>)>;
class NativeFunction class NativeFunction
{ {
@ -16,7 +20,9 @@ namespace fk
virtual ~NativeFunction(); virtual ~NativeFunction();
std::shared_ptr<Constant> std::shared_ptr<Constant>
call(Loc const& loc, std::vector<std::shared_ptr<Constant>> args); call(Loc const& loc,
Module& mod,
std::vector<std::shared_ptr<Constant>> args);
private: private:
native_t m_native; native_t m_native;

View File

@ -7,6 +7,7 @@ namespace fk
{ {
class Compiler; class Compiler;
class Program; class Program;
class SymTable;
class Node; class Node;
using macro_t = std::function<void(Compiler&, using macro_t = std::function<void(Compiler&,

View File

@ -51,14 +51,26 @@ namespace fk
} }
std::optional<SymEntry> SymTable::find(std::string const& name) std::optional<SymEntry> SymTable::find(std::string const& name)
{
auto idx = find_idx(name);
if (!idx) { return std::nullopt; }
return m_entries[*idx];
}
std::optional<size_t> SymTable::find_idx(std::string const& name)
{ {
std::optional<SymEntry> result; std::optional<SymEntry> result;
size_t i=0;
std::optional<size_t> idx;
for (auto& entry: m_entries) for (auto& entry: m_entries)
{ {
if (entry.name() == name && entry.is_global()) if (entry.name() == name && entry.is_global())
{ {
result = entry; result = entry;
idx = i;
} }
else if (entry.name() == name else if (entry.name() == name
&& entry.scope() <= m_scope && entry.scope() <= m_scope
@ -68,10 +80,29 @@ namespace fk
entry.scope() > result->scope())) entry.scope() > result->scope()))
{ {
result = entry; result = entry;
} idx = i;
} }
return result; i++;
}
return idx;
}
void SymTable::set(std::string const& name, addr_t addr)
{
if (auto idx = find_idx(name);
idx)
{
m_entries[*idx].set_addr(addr);
}
else
{
std::cerr << "cannot set value to '"
<< name
<< "'" << std::endl;
abort();
}
} }
std::string SymTable::string() const std::string SymTable::string() const

View File

@ -23,6 +23,8 @@ namespace fk
Loc const& loc); Loc const& loc);
std::optional<SymEntry> find(std::string const& name); std::optional<SymEntry> find(std::string const& name);
std::optional<size_t> find_idx(std::string const& name);
void set(std::string const& name, addr_t addr);
std::string string() const; std::string string() const;

View File

@ -4,7 +4,8 @@
namespace fk namespace fk
{ {
/*explicit*/ VM::VM() /*explicit*/ VM::VM(Module& mod)
: m_mod { mod }
{ {
} }
@ -150,7 +151,7 @@ namespace fk
auto fun = std::get<std::shared_ptr<NativeFunction>> auto fun = std::get<std::shared_ptr<NativeFunction>>
(load_global(ref)); (load_global(ref));
push(frame().program->add(fun->call(loc, args))); push(frame().program->add(fun->call(loc, m_mod, args)));
m_pc++; m_pc++;
} break; } break;

View File

@ -18,11 +18,12 @@ namespace fk
size_t stack_sz; size_t stack_sz;
std::unordered_map<addr_t, std::shared_ptr<Constant>> locals; std::unordered_map<addr_t, std::shared_ptr<Constant>> locals;
}; };
class Module;
class VM class VM
{ {
public: public:
explicit VM(); explicit VM(Module& mod);
virtual ~VM(); virtual ~VM();
Frame& frame() { return m_frames.back(); } Frame& frame() { return m_frames.back(); }
@ -57,6 +58,7 @@ namespace fk
Loc const& loc); Loc const& loc);
private: private:
Module& m_mod;
addr_t m_pc = 0; addr_t m_pc = 0;
std::vector<Frame> m_frames; std::vector<Frame> m_frames;
std::vector<addr_t> m_stack; std::vector<addr_t> m_stack;