Compare commits
No commits in common. "5499e4569ec3a603cb57a2b42a5d297253f59813" and "f9f73dabd36a8e70c12ef0ced8b0b18ca8bf1b32" have entirely different histories.
5499e4569e
...
f9f73dabd3
|
@ -18,13 +18,3 @@
|
||||||
|
|
||||||
($ arr [2 'bim' produce false])
|
($ arr [2 'bim' produce false])
|
||||||
(assert= 6 (ref ((ref arr 2)) 2))
|
(assert= 6 (ref ((ref arr 2)) 2))
|
||||||
|
|
||||||
($ hello [2 4 6])
|
|
||||||
(assert= 4 (ref hello 1))
|
|
||||||
(ref! hello 1 12)
|
|
||||||
(assert= 12 (ref hello 1))
|
|
||||||
|
|
||||||
($ hello2 [[5 7][9 2]])
|
|
||||||
(assert= 9 (ref hello2 1 0))
|
|
||||||
(ref! (ref hello2 1) 0 34)
|
|
||||||
(assert= 34 (ref hello2 1 0))
|
|
|
@ -1 +0,0 @@
|
||||||
(assert= 8 (trunc 8.71))
|
|
|
@ -14,32 +14,3 @@
|
||||||
(assert= 6 (a))
|
(assert= 6 (a))
|
||||||
(assert= 7 (a))
|
(assert= 7 (a))
|
||||||
(assert= 34 (b))
|
(assert= 34 (b))
|
||||||
|
|
||||||
($ (c) 42)
|
|
||||||
|
|
||||||
($ (d)
|
|
||||||
(+ (c) 1))
|
|
||||||
|
|
||||||
(assert= 43 (d))
|
|
||||||
|
|
||||||
|
|
||||||
($ hello 34)
|
|
||||||
|
|
||||||
($ (i)
|
|
||||||
($ (j)
|
|
||||||
($ (k)
|
|
||||||
(println hello))))
|
|
||||||
|
|
||||||
(((i)))
|
|
||||||
|
|
||||||
($ @m './mod2')
|
|
||||||
|
|
||||||
($ (u)
|
|
||||||
($ (v)
|
|
||||||
($ (w)
|
|
||||||
(assert= 42 m::var)
|
|
||||||
(assert= 14 (m::fun 7))
|
|
||||||
259 )))
|
|
||||||
|
|
||||||
(assert= 42 ((-> () m::var)))
|
|
||||||
(assert= 259 (((u))))
|
|
||||||
|
|
|
@ -2,13 +2,16 @@
|
||||||
#define fkstd_COMMONS_HPP
|
#define fkstd_COMMONS_HPP
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include "../src/commons.hpp"
|
|
||||||
#include "../src/Module.hpp"
|
#include "../src/Module.hpp"
|
||||||
#include "../src/Constant.hpp"
|
#include "../src/Constant.hpp"
|
||||||
#include "../src/SymTable.hpp"
|
#include "../src/SymTable.hpp"
|
||||||
|
|
||||||
using namespace fk;
|
using namespace fk;
|
||||||
|
|
||||||
|
#define STDARGS std::vector<std::shared_ptr<Constant>>
|
||||||
|
#define STDRET std::shared_ptr<Constant>
|
||||||
|
#define STDSYM std::shared_ptr<SymTable>
|
||||||
|
|
||||||
FK_ERROR(assert_error);
|
FK_ERROR(assert_error);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -278,13 +278,6 @@ namespace fkstd
|
||||||
return std::make_shared<Constant>(TYPE_FLOAT, result, loc);
|
return std::make_shared<Constant>(TYPE_FLOAT, result, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
STDRET trunc(Loc loc, Module&, STDARGS args)
|
|
||||||
{
|
|
||||||
float val = std::get<float>(args[0]->value());
|
|
||||||
int res = val;
|
|
||||||
return std::make_shared<Constant>(TYPE_INT, res, loc);
|
|
||||||
}
|
|
||||||
|
|
||||||
STDRET lt(Loc loc, Module&, STDARGS args)
|
STDRET lt(Loc loc, Module&, STDARGS args)
|
||||||
{
|
{
|
||||||
NUM_BINOP(<);
|
NUM_BINOP(<);
|
||||||
|
@ -346,20 +339,6 @@ namespace fkstd
|
||||||
return val->at(std::get<int>(args.back()->value()));
|
return val->at(std::get<int>(args.back()->value()));
|
||||||
}
|
}
|
||||||
|
|
||||||
STDRET array_set(Loc, Module& mod, STDARGS args)
|
|
||||||
{
|
|
||||||
auto ref_val = args[0]->value();
|
|
||||||
size_t ref = std::get<size_t>(ref_val);
|
|
||||||
|
|
||||||
int index = std::get<int>(args[1]->value());
|
|
||||||
|
|
||||||
std::shared_ptr<Array> val =
|
|
||||||
std::get<std::shared_ptr<Array>>(mod.vm()->load_global(ref));
|
|
||||||
|
|
||||||
val->set(index, args[2]);
|
|
||||||
return args[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
STDRET string_cat(Loc loc, Module&, STDARGS args)
|
STDRET string_cat(Loc loc, Module&, STDARGS args)
|
||||||
{
|
{
|
||||||
if (args.empty())
|
if (args.empty())
|
||||||
|
|
|
@ -20,7 +20,6 @@ namespace fkstd
|
||||||
STDRET div_float(Loc loc, Module& mod, STDARGS args);
|
STDRET div_float(Loc loc, Module& mod, STDARGS args);
|
||||||
STDRET mod_float(Loc loc, Module& mod, STDARGS args);
|
STDRET mod_float(Loc loc, Module& mod, STDARGS args);
|
||||||
STDRET pow_float(Loc loc, Module& mod, STDARGS args);
|
STDRET pow_float(Loc loc, Module& mod, STDARGS args);
|
||||||
STDRET trunc(Loc loc, Module& mod, STDARGS args);
|
|
||||||
|
|
||||||
STDRET lt(Loc loc, Module& mod, STDARGS args);
|
STDRET lt(Loc loc, Module& mod, STDARGS args);
|
||||||
STDRET le(Loc loc, Module& mod, STDARGS args);
|
STDRET le(Loc loc, Module& mod, STDARGS args);
|
||||||
|
@ -31,7 +30,6 @@ namespace fkstd
|
||||||
|
|
||||||
STDRET bool_not(Loc loc, Module& mod, STDARGS args);
|
STDRET bool_not(Loc loc, Module& mod, STDARGS args);
|
||||||
STDRET array_ref(Loc loc, Module& mod, STDARGS args);
|
STDRET array_ref(Loc loc, Module& mod, STDARGS args);
|
||||||
STDRET array_set(Loc loc, Module& mod, STDARGS args);
|
|
||||||
|
|
||||||
STDRET string_cat(Loc loc, Module& mod, STDARGS args);
|
STDRET string_cat(Loc loc, Module& mod, STDARGS args);
|
||||||
STDRET string_dup(Loc loc, Module& mod, STDARGS args);
|
STDRET string_dup(Loc loc, Module& mod, STDARGS args);
|
||||||
|
|
|
@ -20,8 +20,6 @@ extern "C" void lib(Module& mod)
|
||||||
mod.register_function("%.", fkstd::mod_float);
|
mod.register_function("%.", fkstd::mod_float);
|
||||||
mod.register_function("^.", fkstd::pow_float);
|
mod.register_function("^.", fkstd::pow_float);
|
||||||
|
|
||||||
mod.register_function("trunc", fkstd::trunc);
|
|
||||||
|
|
||||||
mod.register_function("<", fkstd::lt);
|
mod.register_function("<", fkstd::lt);
|
||||||
mod.register_function("<=", fkstd::le);
|
mod.register_function("<=", fkstd::le);
|
||||||
mod.register_function(">", fkstd::gt);
|
mod.register_function(">", fkstd::gt);
|
||||||
|
@ -31,7 +29,6 @@ extern "C" void lib(Module& mod)
|
||||||
|
|
||||||
mod.register_function("not", fkstd::bool_not);
|
mod.register_function("not", fkstd::bool_not);
|
||||||
mod.register_function("ref", fkstd::array_ref);
|
mod.register_function("ref", fkstd::array_ref);
|
||||||
mod.register_function("ref!", fkstd::array_set);
|
|
||||||
mod.register_function("cat", fkstd::string_cat);
|
mod.register_function("cat", fkstd::string_cat);
|
||||||
mod.register_function("dup", fkstd::string_dup);
|
mod.register_function("dup", fkstd::string_dup);
|
||||||
mod.register_function("char-at", fkstd::char_at);
|
mod.register_function("char-at", fkstd::char_at);
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace fkstd
|
||||||
{
|
{
|
||||||
auto ident = node->child(1)->repr();
|
auto ident = node->child(1)->repr();
|
||||||
compiler.compile_prog(node->child(2), program);
|
compiler.compile_prog(node->child(2), program);
|
||||||
|
std::cout << "push " << node->child(2)->string() << std::endl;
|
||||||
auto entry = compiler.sym()->find(ident);
|
auto entry = compiler.sym()->find(ident);
|
||||||
|
|
||||||
if (entry)
|
if (entry)
|
||||||
|
@ -59,10 +59,11 @@ namespace fkstd
|
||||||
compiler.pop_decl();
|
compiler.pop_decl();
|
||||||
|
|
||||||
auto entry = compiler.sym()->declare_local(ident,
|
auto entry = compiler.sym()->declare_local(ident,
|
||||||
|
addr,
|
||||||
node->loc())
|
node->loc())
|
||||||
.set_node(rhs);
|
.set_node(rhs);
|
||||||
|
|
||||||
program->add(OP_STORE_LOCAL, entry.addr());
|
program->add(OP_STORE_LOCAL, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void block(Compiler& compiler,
|
void block(Compiler& compiler,
|
||||||
|
|
|
@ -63,14 +63,10 @@ fakir_hpp = [
|
||||||
'src/types.hpp',
|
'src/types.hpp',
|
||||||
]
|
]
|
||||||
|
|
||||||
pkg = import('pkgconfig')
|
|
||||||
|
|
||||||
fakir_lib = shared_library('fakir',
|
fakir_lib = shared_library('fakir',
|
||||||
sources: fakir_cpp,
|
sources: fakir_cpp,
|
||||||
install: true)
|
install: true)
|
||||||
|
|
||||||
pkg.generate(fakir_lib, subdirs: ['fakir'])
|
|
||||||
|
|
||||||
install_headers(fakir_hpp, subdir: 'fakir')
|
install_headers(fakir_hpp, subdir: 'fakir')
|
||||||
|
|
||||||
fakir_dep = declare_dependency(
|
fakir_dep = declare_dependency(
|
||||||
|
|
|
@ -22,12 +22,6 @@ namespace fk
|
||||||
return m_data.at(index);
|
return m_data.at(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Array::set(size_t index, std::shared_ptr<Constant> value)
|
|
||||||
{
|
|
||||||
assert(index < size());
|
|
||||||
m_data[index] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<Constant> Array::pop()
|
std::shared_ptr<Constant> Array::pop()
|
||||||
{
|
{
|
||||||
assert(size() > 0);
|
assert(size() > 0);
|
||||||
|
|
|
@ -17,7 +17,6 @@ namespace fk
|
||||||
|
|
||||||
void push(std::shared_ptr<Constant> constant);
|
void push(std::shared_ptr<Constant> constant);
|
||||||
std::shared_ptr<Constant> at(size_t index) const;
|
std::shared_ptr<Constant> at(size_t index) const;
|
||||||
void set(size_t index, std::shared_ptr<Constant> value);
|
|
||||||
std::shared_ptr<Constant> pop();
|
std::shared_ptr<Constant> pop();
|
||||||
|
|
||||||
std::string string() const;
|
std::string string() const;
|
||||||
|
|
|
@ -74,19 +74,23 @@ namespace fk
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case NODE_VARDECL: {
|
case NODE_VARDECL: {
|
||||||
|
m_addr++;
|
||||||
|
|
||||||
std::string ident = node->child(0)->repr();
|
std::string ident = node->child(0)->repr();
|
||||||
auto rhs = node->child(1);
|
auto rhs = node->child(1);
|
||||||
|
|
||||||
push_decl(ident);
|
push_decl(ident);
|
||||||
compile_prog(rhs, prog);
|
compile_prog(rhs, prog);
|
||||||
pop_decl();
|
pop_decl();
|
||||||
|
|
||||||
auto entry = sym()->declare_local(ident,
|
auto entry = sym()->declare_local(ident,
|
||||||
|
m_addr,
|
||||||
node->loc())
|
node->loc())
|
||||||
|
|
||||||
.set_is_array(rhs->type() == NODE_ARRAY)
|
.set_is_array(rhs->type() == NODE_ARRAY)
|
||||||
.set_node(rhs);
|
.set_node(rhs);
|
||||||
|
|
||||||
prog->add(OP_STORE_LOCAL, entry.addr());
|
prog->add(OP_STORE_LOCAL, m_addr);
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case NODE_ARRAY: {
|
case NODE_ARRAY: {
|
||||||
|
@ -110,7 +114,9 @@ namespace fk
|
||||||
prog->load_const(std::make_shared<Constant>(TYPE_STRING,
|
prog->load_const(std::make_shared<Constant>(TYPE_STRING,
|
||||||
var->repr(),
|
var->repr(),
|
||||||
node->loc()));
|
node->loc()));
|
||||||
|
|
||||||
compile_prog(mod, prog);
|
compile_prog(mod, prog);
|
||||||
|
|
||||||
prog->add(OP_LOAD_MOD);
|
prog->add(OP_LOAD_MOD);
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
@ -156,15 +162,14 @@ namespace fk
|
||||||
|
|
||||||
m_sym->enter_scope(node);
|
m_sym->enter_scope(node);
|
||||||
|
|
||||||
int base_addr = m_sym->addr();
|
|
||||||
|
|
||||||
for (size_t i=0; i<params->size(); i++)
|
for (size_t i=0; i<params->size(); i++)
|
||||||
{
|
{
|
||||||
std::string ident = params->child(i)->repr();
|
std::string ident = params->child(i)->repr();
|
||||||
auto entry = m_sym->declare_local(ident, node->loc());
|
m_sym->declare_local(ident, i, node->loc());
|
||||||
}
|
}
|
||||||
|
|
||||||
m_sym->declare_local(func_name, node->loc());
|
m_sym->declare_local(func_name, params->size(),
|
||||||
|
node->loc());
|
||||||
|
|
||||||
Compiler compiler {m_mod, m_sym};
|
Compiler compiler {m_mod, m_sym};
|
||||||
for (auto e: m_macros)
|
for (auto e: m_macros)
|
||||||
|
@ -182,10 +187,6 @@ namespace fk
|
||||||
program,
|
program,
|
||||||
node->loc());
|
node->loc());
|
||||||
prog->load_const(constant);
|
prog->load_const(constant);
|
||||||
|
|
||||||
prog->load_const(std::make_shared<Constant>(TYPE_INT,
|
|
||||||
base_addr,
|
|
||||||
constant->loc()));
|
|
||||||
prog->add(OP_MAKE_FUNCTION, params->size());
|
prog->add(OP_MAKE_FUNCTION, params->size());
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
@ -270,17 +271,7 @@ namespace fk
|
||||||
|
|
||||||
if (!entry)
|
if (!entry)
|
||||||
{
|
{
|
||||||
auto entries = m_sym->find_all(node->repr());
|
auto entry = m_sym->find_global(node->repr());
|
||||||
std::optional<SymEntry> entry;
|
|
||||||
|
|
||||||
for (SymEntry const& e: entries)
|
|
||||||
{
|
|
||||||
if (e.scope() <= m_sym->scope()
|
|
||||||
&& (!entry || e.scope() < entry->scope()))
|
|
||||||
{
|
|
||||||
entry = e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entry)
|
if (entry)
|
||||||
{
|
{
|
||||||
|
@ -302,13 +293,12 @@ namespace fk
|
||||||
if (!entry->is_global())
|
if (!entry->is_global())
|
||||||
{
|
{
|
||||||
prog->add(OP_LOAD_LOCAL, entry->addr());
|
prog->add(OP_LOAD_LOCAL, entry->addr());
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
prog->add(OP_LOAD_GLOBAL, entry->addr());
|
prog->add(OP_LOAD_GLOBAL, entry->addr());
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case NODE_INT: {
|
case NODE_INT: {
|
||||||
|
@ -357,4 +347,5 @@ namespace fk
|
||||||
assert(m_decl_stack.empty() == false);
|
assert(m_decl_stack.empty() == false);
|
||||||
m_decl_stack.pop_back();
|
m_decl_stack.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,7 @@ namespace fk
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Module& m_mod;
|
Module& m_mod;
|
||||||
|
addr_t m_addr = 0;
|
||||||
std::shared_ptr<SymTable> m_sym;
|
std::shared_ptr<SymTable> m_sym;
|
||||||
std::vector<std::string> m_decl_stack;
|
std::vector<std::string> m_decl_stack;
|
||||||
std::unordered_map<std::string,
|
std::unordered_map<std::string,
|
||||||
|
|
|
@ -30,7 +30,6 @@ namespace fk
|
||||||
case TYPE_STRING: return std::get<std::string>(m_value);
|
case TYPE_STRING: return std::get<std::string>(m_value);
|
||||||
case TYPE_REF: return std::to_string(std::get<size_t>(m_value));
|
case TYPE_REF: return std::to_string(std::get<size_t>(m_value));
|
||||||
case TYPE_PROGRAM: return "<program>";
|
case TYPE_PROGRAM: return "<program>";
|
||||||
case TYPE_CUSTOM: return "<custom>";
|
|
||||||
case TYPE_ARRAY: return std::get<std::shared_ptr<Array>>
|
case TYPE_ARRAY: return std::get<std::shared_ptr<Array>>
|
||||||
(m_value)->string();
|
(m_value)->string();
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,6 @@ namespace fk
|
||||||
using constant_t = std::variant<int,
|
using constant_t = std::variant<int,
|
||||||
float,
|
float,
|
||||||
bool,
|
bool,
|
||||||
void*,
|
|
||||||
std::string,
|
std::string,
|
||||||
size_t,
|
size_t,
|
||||||
std::shared_ptr<Program>,
|
std::shared_ptr<Program>,
|
||||||
|
|
|
@ -14,31 +14,20 @@ namespace fk
|
||||||
explicit Lambda(std::shared_ptr<Program> program, size_t arity);
|
explicit Lambda(std::shared_ptr<Program> program, size_t arity);
|
||||||
virtual ~Lambda();
|
virtual ~Lambda();
|
||||||
|
|
||||||
std::unordered_map<addr_t, std::shared_ptr<Constant>>
|
|
||||||
get_all_env() const { return m_env; }
|
|
||||||
|
|
||||||
size_t arity() const { return m_arity; }
|
size_t arity() const { return m_arity; }
|
||||||
|
|
||||||
addr_t base_addr() const { return m_base_addr; }
|
|
||||||
void set_base_addr(addr_t base) { m_base_addr = base; }
|
|
||||||
|
|
||||||
std::shared_ptr<Program> program() const { return m_program; }
|
std::shared_ptr<Program> program() const { return m_program; }
|
||||||
|
std::shared_ptr<SymTable> sym() const { return m_sym; }
|
||||||
|
|
||||||
bool has_env(addr_t addr) const;
|
bool has_env(addr_t addr) const;
|
||||||
|
|
||||||
|
|
||||||
std::shared_ptr<Constant> get_env(addr_t addr) const;
|
std::shared_ptr<Constant> get_env(addr_t addr) const;
|
||||||
void add_env(addr_t addr, std::shared_ptr<Constant> constant);
|
void add_env(addr_t addr, std::shared_ptr<Constant> constant);
|
||||||
size_t env_size() const { return m_env.size(); }
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<Program> m_program;
|
std::shared_ptr<Program> m_program;
|
||||||
std::unordered_map<addr_t, std::shared_ptr<Constant>> m_env;
|
std::unordered_map<addr_t, std::shared_ptr<Constant>> m_env;
|
||||||
size_t m_arity;
|
size_t m_arity;
|
||||||
addr_t m_base_addr = 0;
|
std::shared_ptr<SymTable> m_sym = std::make_shared<SymTable>();
|
||||||
|
|
||||||
//std::shared_ptr<SymTable> m_sym = std::make_shared<SymTable>();
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,15 +17,10 @@ namespace fk
|
||||||
|
|
||||||
std::shared_ptr<Module> Module::get_mod(std::string const& name)
|
std::shared_ptr<Module> Module::get_mod(std::string const& name)
|
||||||
{
|
{
|
||||||
assert(has_mod(name));
|
assert(m_native_modules.find(name) != std::end(m_native_modules));
|
||||||
return m_native_modules[name];
|
return m_native_modules[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Module::has_mod(std::string const& name)
|
|
||||||
{
|
|
||||||
return m_native_modules.find(name) != std::end(m_native_modules);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Module::build()
|
void Module::build()
|
||||||
{
|
{
|
||||||
import_std();
|
import_std();
|
||||||
|
|
|
@ -24,7 +24,6 @@ namespace fk
|
||||||
std::shared_ptr<VM> vm() const { return m_vm; }
|
std::shared_ptr<VM> vm() const { return m_vm; }
|
||||||
|
|
||||||
std::shared_ptr<Module> get_mod(std::string const& name);
|
std::shared_ptr<Module> get_mod(std::string const& name);
|
||||||
bool has_mod(std::string const& name);
|
|
||||||
|
|
||||||
void build();
|
void build();
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ namespace fk
|
||||||
}
|
}
|
||||||
|
|
||||||
SymEntry& SymTable::declare_local(std::string const& name,
|
SymEntry& SymTable::declare_local(std::string const& name,
|
||||||
|
addr_t addr,
|
||||||
Loc const& loc)
|
Loc const& loc)
|
||||||
{
|
{
|
||||||
auto entry = find(name);
|
auto entry = find(name);
|
||||||
|
@ -30,13 +31,13 @@ namespace fk
|
||||||
}
|
}
|
||||||
|
|
||||||
SymEntry e {name,
|
SymEntry e {name,
|
||||||
m_addr,
|
addr,
|
||||||
false,
|
false,
|
||||||
m_scope,
|
m_scope,
|
||||||
m_parents.empty() ?
|
m_parents.empty() ?
|
||||||
nullptr : m_parents.back(),
|
nullptr : m_parents.back(),
|
||||||
loc};
|
loc};
|
||||||
m_addr++;
|
|
||||||
m_entries.push_back(e);
|
m_entries.push_back(e);
|
||||||
|
|
||||||
return m_entries.back();
|
return m_entries.back();
|
||||||
|
@ -46,7 +47,7 @@ namespace fk
|
||||||
addr_t addr,
|
addr_t addr,
|
||||||
Loc const& loc)
|
Loc const& loc)
|
||||||
{
|
{
|
||||||
return declare_local(name, loc).set_global(true).set_addr(addr);
|
return declare_local(name, addr, loc).set_global(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<SymEntry> SymTable::find(std::string const& name)
|
std::optional<SymEntry> SymTable::find(std::string const& name)
|
||||||
|
@ -125,22 +126,6 @@ namespace fk
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<SymEntry> SymTable::find_all(std::string const& name)
|
|
||||||
{
|
|
||||||
|
|
||||||
std::vector<SymEntry> res;
|
|
||||||
|
|
||||||
for (auto e: m_entries)
|
|
||||||
{
|
|
||||||
if (e.name() == name)
|
|
||||||
{
|
|
||||||
res.push_back(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SymTable::set(std::string const& name, addr_t addr)
|
void SymTable::set(std::string const& name, addr_t addr)
|
||||||
{
|
{
|
||||||
if (auto idx = find_idx(name);
|
if (auto idx = find_idx(name);
|
||||||
|
|
|
@ -14,10 +14,10 @@ namespace fk
|
||||||
explicit SymTable();
|
explicit SymTable();
|
||||||
virtual ~SymTable();
|
virtual ~SymTable();
|
||||||
|
|
||||||
size_t addr() const { return m_addr; }
|
|
||||||
int scope() const { return m_scope; }
|
int scope() const { return m_scope; }
|
||||||
|
|
||||||
SymEntry& declare_local(std::string const& name,
|
SymEntry& declare_local(std::string const& name,
|
||||||
|
addr_t addr,
|
||||||
Loc const& loc);
|
Loc const& loc);
|
||||||
|
|
||||||
SymEntry& declare_global(std::string const& name,
|
SymEntry& declare_global(std::string const& name,
|
||||||
|
@ -30,8 +30,6 @@ namespace fk
|
||||||
std::optional<SymEntry> find_global(std::string const& name);
|
std::optional<SymEntry> find_global(std::string const& name);
|
||||||
std::optional<size_t> find_idx_global(std::string const& name);
|
std::optional<size_t> find_idx_global(std::string const& name);
|
||||||
|
|
||||||
std::vector<SymEntry> find_all(std::string const& name);
|
|
||||||
|
|
||||||
void set(std::string const& name, addr_t addr);
|
void set(std::string const& name, addr_t addr);
|
||||||
|
|
||||||
std::string string() const;
|
std::string string() const;
|
||||||
|
@ -42,7 +40,6 @@ namespace fk
|
||||||
private:
|
private:
|
||||||
std::vector<SymEntry> m_entries;
|
std::vector<SymEntry> m_entries;
|
||||||
int m_scope;
|
int m_scope;
|
||||||
size_t m_addr = 12;
|
|
||||||
std::vector<std::shared_ptr<Node>> m_parents;
|
std::vector<std::shared_ptr<Node>> m_parents;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
122
src/VM.cpp
122
src/VM.cpp
|
@ -31,6 +31,41 @@ namespace fk
|
||||||
|
|
||||||
switch (instr.opcode)
|
switch (instr.opcode)
|
||||||
{
|
{
|
||||||
|
/*case OP_DEREF: {
|
||||||
|
std::vector<int> indexes;
|
||||||
|
|
||||||
|
for (size_t i=0; i<instr.param; i++)
|
||||||
|
{
|
||||||
|
auto index_val = frame().program->get_const(pop());
|
||||||
|
int index = std::get<int>(index_val->value());
|
||||||
|
indexes.insert(std::begin(indexes), index);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ref =
|
||||||
|
std::get<size_t>(frame().program
|
||||||
|
->get_const(pop())->value());
|
||||||
|
|
||||||
|
std::shared_ptr<Array> val =
|
||||||
|
std::get<std::shared_ptr<Array>>(load_global(ref));
|
||||||
|
|
||||||
|
for (size_t i=0; i<indexes.size() - 1; i++)
|
||||||
|
{
|
||||||
|
auto ref_val = val->at(indexes[i])->value();
|
||||||
|
|
||||||
|
size_t ref = std::get<size_t>(ref_val);
|
||||||
|
|
||||||
|
auto arr =
|
||||||
|
std::get<std::shared_ptr<Array>>(load_global(ref));
|
||||||
|
|
||||||
|
val = arr;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
push(frame().program->add(val->at(indexes.back())));
|
||||||
|
|
||||||
|
m_pc++;
|
||||||
|
} break;*/
|
||||||
|
|
||||||
case OP_MAKE_ARRAY: {
|
case OP_MAKE_ARRAY: {
|
||||||
std::vector<std::shared_ptr<Constant>> data;
|
std::vector<std::shared_ptr<Constant>> data;
|
||||||
|
|
||||||
|
@ -81,24 +116,7 @@ namespace fk
|
||||||
std::filesystem::path path =
|
std::filesystem::path path =
|
||||||
std::get<std::string>(path_val->value());
|
std::get<std::string>(path_val->value());
|
||||||
|
|
||||||
auto alt_path = std::filesystem::path("/")
|
auto mod = m_mod.get_mod(path);
|
||||||
/ "usr" / "lib" / ("lib"
|
|
||||||
+ path.filename().string()
|
|
||||||
+ ".so" );
|
|
||||||
|
|
||||||
std::shared_ptr<Module> mod;
|
|
||||||
|
|
||||||
if (m_mod.has_mod(path))
|
|
||||||
{
|
|
||||||
mod = m_mod.get_mod(path);
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (std::filesystem::exists(alt_path))
|
|
||||||
{
|
|
||||||
mod = std::make_shared<Module>(alt_path);
|
|
||||||
mod->import_std();
|
|
||||||
mod->import_library(alt_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
addr_t addr = store_global(mod);
|
addr_t addr = store_global(mod);
|
||||||
auto res = std::make_shared<Constant>(TYPE_REF, addr,
|
auto res = std::make_shared<Constant>(TYPE_REF, addr,
|
||||||
|
@ -111,7 +129,6 @@ namespace fk
|
||||||
case OP_LOAD_MOD: {
|
case OP_LOAD_MOD: {
|
||||||
addr_t mod_addr = pop();
|
addr_t mod_addr = pop();
|
||||||
auto mod_val = frame().program->get_const(mod_addr);
|
auto mod_val = frame().program->get_const(mod_addr);
|
||||||
|
|
||||||
size_t mod_ref =
|
size_t mod_ref =
|
||||||
std::get<size_t>(mod_val->value());
|
std::get<size_t>(mod_val->value());
|
||||||
|
|
||||||
|
@ -182,33 +199,17 @@ namespace fk
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case OP_LOAD_CLOSURE: {
|
case OP_LOAD_CLOSURE: {
|
||||||
std::shared_ptr<Lambda> lambda;
|
if (frame().lambda && frame().lambda->has_env(instr.param))
|
||||||
|
|
||||||
for (size_t i=0; i<m_frames.size(); i++)
|
|
||||||
{
|
{
|
||||||
size_t k = m_frames.size() - 1 - i;
|
auto val = frame().lambda->get_env(instr.param);
|
||||||
|
|
||||||
if (m_frames[k].lambda->has_env(instr.param))
|
|
||||||
{
|
|
||||||
lambda = m_frames[k].lambda;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lambda)
|
|
||||||
{
|
|
||||||
auto val = lambda->get_env(instr.param);
|
|
||||||
addr_t addr = frame().program->add(val);
|
addr_t addr = frame().program->add(val);
|
||||||
push(addr);
|
|
||||||
|
|
||||||
|
push(addr);
|
||||||
m_pc++;
|
m_pc++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cerr << "cannot find addr '"
|
m_pc++;
|
||||||
<< instr.param
|
|
||||||
<< "'" << std::endl;
|
|
||||||
abort();
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case OP_NOT: {
|
case OP_NOT: {
|
||||||
|
@ -241,30 +242,19 @@ namespace fk
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case OP_MAKE_FUNCTION: {
|
case OP_MAKE_FUNCTION: {
|
||||||
int base_addr =
|
|
||||||
std::get<int>(frame().program->get_const(pop())->value());
|
|
||||||
|
|
||||||
auto p = frame().program->get_const(pop());
|
auto p = frame().program->get_const(pop());
|
||||||
auto prog = std::get<std::shared_ptr<Program>>(p->value());
|
auto prog = std::get<std::shared_ptr<Program>>(p->value());
|
||||||
auto lambda = std::make_shared<Lambda>(prog, instr.param);
|
auto lambda = std::make_shared<Lambda>(prog, instr.param);
|
||||||
lambda->set_base_addr(base_addr);
|
|
||||||
addr_t addr = store_global(lambda);
|
addr_t addr = store_global(lambda);
|
||||||
auto ref = std::make_shared<Constant>(TYPE_REF, addr, p->loc());
|
auto ref = std::make_shared<Constant>(TYPE_REF, addr, p->loc());
|
||||||
|
|
||||||
for (auto const& f: m_frames)
|
if (m_frames.size() > 1)
|
||||||
{
|
{
|
||||||
for (auto e: f.locals)
|
for (auto e: m_frames.back().locals)
|
||||||
{
|
{
|
||||||
lambda->add_env(e.first, e.second);
|
lambda->add_env(e.first, e.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f.lambda)
|
|
||||||
{
|
|
||||||
for (auto e: f.lambda->get_all_env())
|
|
||||||
{
|
|
||||||
lambda->add_env(e.first, e.second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
push(frame().program->add(ref));
|
push(frame().program->add(ref));
|
||||||
|
@ -325,9 +315,8 @@ namespace fk
|
||||||
auto fun = std::get<std::shared_ptr<NativeFunction>>
|
auto fun = std::get<std::shared_ptr<NativeFunction>>
|
||||||
(load_global(ref));
|
(load_global(ref));
|
||||||
|
|
||||||
auto res = fun->call(ref_val->loc(), m_mod, args);
|
push(frame().program->add(fun->call(ref_val->loc(),
|
||||||
|
m_mod, args)));
|
||||||
push(frame().program->add(res));
|
|
||||||
m_pc++;
|
m_pc++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -347,10 +336,10 @@ namespace fk
|
||||||
|
|
||||||
for (size_t i=0; i<args.size(); i++)
|
for (size_t i=0; i<args.size(); i++)
|
||||||
{
|
{
|
||||||
store_local(lambda->base_addr() + i, args[i]);
|
store_local(i, args[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
store_local(lambda->base_addr() + args.size(), self);
|
store_local(args.size(), self);
|
||||||
|
|
||||||
m_pc = 0;
|
m_pc = 0;
|
||||||
} break;
|
} break;
|
||||||
|
@ -375,7 +364,6 @@ namespace fk
|
||||||
auto value = frame().program->get_const(top());
|
auto value = frame().program->get_const(top());
|
||||||
assert(value);
|
assert(value);
|
||||||
frame().locals[instr.param] = value;
|
frame().locals[instr.param] = value;
|
||||||
|
|
||||||
m_pc++;
|
m_pc++;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
@ -422,14 +410,13 @@ namespace fk
|
||||||
|
|
||||||
for (size_t i=0; i<args.size(); i++)
|
for (size_t i=0; i<args.size(); i++)
|
||||||
{
|
{
|
||||||
store_local(lambda->base_addr() + i, args[i]);
|
store_local(i, args[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto self = std::make_shared<Constant>(TYPE_REF,
|
auto self = std::make_shared<Constant>(TYPE_REF,
|
||||||
static_cast<size_t>(ref),
|
static_cast<size_t>(ref),
|
||||||
loc);
|
loc);
|
||||||
|
store_local(args.size(), self);
|
||||||
store_local(lambda->base_addr() + args.size(), self);
|
|
||||||
|
|
||||||
m_pc = 0;
|
m_pc = 0;
|
||||||
|
|
||||||
|
@ -508,12 +495,9 @@ namespace fk
|
||||||
size_t ref,
|
size_t ref,
|
||||||
Loc const& loc)
|
Loc const& loc)
|
||||||
{
|
{
|
||||||
if (&parent != this)
|
for (auto entry: parent.m_globals)
|
||||||
{
|
{
|
||||||
for (auto entry: parent.m_globals)
|
store_global(entry.first, entry.second);
|
||||||
{
|
|
||||||
store_global(entry.first, entry.second);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto self = std::make_shared<Constant>(TYPE_REF,
|
auto self = std::make_shared<Constant>(TYPE_REF,
|
||||||
|
@ -528,10 +512,10 @@ namespace fk
|
||||||
|
|
||||||
for (size_t i=0; i<args.size(); i++)
|
for (size_t i=0; i<args.size(); i++)
|
||||||
{
|
{
|
||||||
store_local(lambda->base_addr() + i, args[i]);
|
store_local(i, args[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
store_local(lambda->base_addr() + args.size(), self);
|
store_local(args.size(), self);
|
||||||
|
|
||||||
m_pc = 0;
|
m_pc = 0;
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,4 @@ using addr_t = size_t;
|
||||||
NAME (std::string const& what) : std::runtime_error(what ) {} \
|
NAME (std::string const& what) : std::runtime_error(what ) {} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define STDARGS std::vector<std::shared_ptr<Constant>>
|
|
||||||
#define STDRET std::shared_ptr<Constant>
|
|
||||||
#define STDSYM std::shared_ptr<SymTable>
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
#define TYPES(G) G(TYPE_INT), G(TYPE_FLOAT), G(TYPE_BOOL), G(TYPE_STRING), \
|
#define TYPES(G) G(TYPE_INT), G(TYPE_FLOAT), G(TYPE_BOOL), G(TYPE_STRING), \
|
||||||
G(TYPE_REF), G(TYPE_PROGRAM), G(TYPE_ARRAY), G(TYPE_NIL), \
|
G(TYPE_REF), G(TYPE_PROGRAM), G(TYPE_ARRAY), G(TYPE_NIL), \
|
||||||
G(TYPE_FUNCTION), G(TYPE_CUSTOM)
|
G(TYPE_FUNCTION)
|
||||||
|
|
||||||
namespace fk
|
namespace fk
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue