FIX: closures.
parent
d973241ae2
commit
58a2c69634
|
@ -59,11 +59,10 @@ 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, addr);
|
program->add(OP_STORE_LOCAL, entry.addr());
|
||||||
}
|
}
|
||||||
|
|
||||||
void block(Compiler& compiler,
|
void block(Compiler& compiler,
|
||||||
|
|
|
@ -76,19 +76,17 @@ namespace fk
|
||||||
case NODE_VARDECL: {
|
case NODE_VARDECL: {
|
||||||
std::string ident = node->child(0)->repr();
|
std::string ident = node->child(0)->repr();
|
||||||
auto rhs = node->child(1);
|
auto rhs = node->child(1);
|
||||||
next_addr();
|
|
||||||
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, m_addr);
|
prog->add(OP_STORE_LOCAL, entry.addr());
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case NODE_ARRAY: {
|
case NODE_ARRAY: {
|
||||||
|
@ -158,14 +156,15 @@ 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();
|
||||||
m_sym->declare_local(ident, i, node->loc());
|
auto entry = m_sym->declare_local(ident, node->loc());
|
||||||
}
|
}
|
||||||
|
|
||||||
m_sym->declare_local(func_name, params->size(),
|
m_sym->declare_local(func_name, node->loc());
|
||||||
node->loc());
|
|
||||||
|
|
||||||
Compiler compiler {m_mod, m_sym};
|
Compiler compiler {m_mod, m_sym};
|
||||||
for (auto e: m_macros)
|
for (auto e: m_macros)
|
||||||
|
@ -183,6 +182,10 @@ 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;
|
||||||
|
|
||||||
|
@ -306,7 +309,6 @@ namespace fk
|
||||||
prog->add(OP_LOAD_GLOBAL, entry->addr());
|
prog->add(OP_LOAD_GLOBAL, entry->addr());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case NODE_INT: {
|
case NODE_INT: {
|
||||||
|
@ -355,10 +357,4 @@ namespace fk
|
||||||
assert(m_decl_stack.empty() == false);
|
assert(m_decl_stack.empty() == false);
|
||||||
m_decl_stack.pop_back();
|
m_decl_stack.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
addr_t Compiler::next_addr()
|
|
||||||
{
|
|
||||||
m_addr++;
|
|
||||||
return m_addr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,11 +44,8 @@ namespace fk
|
||||||
void push_decl(std::string const& ident);
|
void push_decl(std::string const& ident);
|
||||||
void pop_decl();
|
void pop_decl();
|
||||||
|
|
||||||
addr_t next_addr();
|
|
||||||
|
|
||||||
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,
|
||||||
|
|
|
@ -16,18 +16,23 @@ namespace fk
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
|
||||||
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;
|
||||||
std::shared_ptr<SymTable> m_sym = std::make_shared<SymTable>();
|
addr_t m_base_addr = 0;
|
||||||
|
|
||||||
|
//std::shared_ptr<SymTable> m_sym = std::make_shared<SymTable>();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,6 @@ 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);
|
||||||
|
@ -31,13 +30,13 @@ namespace fk
|
||||||
}
|
}
|
||||||
|
|
||||||
SymEntry e {name,
|
SymEntry e {name,
|
||||||
addr,
|
m_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();
|
||||||
|
@ -47,7 +46,7 @@ namespace fk
|
||||||
addr_t addr,
|
addr_t addr,
|
||||||
Loc const& loc)
|
Loc const& loc)
|
||||||
{
|
{
|
||||||
return declare_local(name, addr, loc).set_global(true);
|
return declare_local(name, loc).set_global(true).set_addr(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<SymEntry> SymTable::find(std::string const& name)
|
std::optional<SymEntry> SymTable::find(std::string const& 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,
|
||||||
|
@ -42,6 +42,7 @@ 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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
86
src/VM.cpp
86
src/VM.cpp
|
@ -31,41 +31,6 @@ 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;
|
||||||
|
|
||||||
|
@ -217,16 +182,29 @@ namespace fk
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case OP_LOAD_CLOSURE: {
|
case OP_LOAD_CLOSURE: {
|
||||||
if (frame().lambda && frame().lambda->has_env(instr.param))
|
std::shared_ptr<Lambda> lambda;
|
||||||
|
|
||||||
|
for (size_t i=0; i<m_frames.size(); i++)
|
||||||
{
|
{
|
||||||
auto val = frame().lambda->get_env(instr.param);
|
size_t k = m_frames.size() - 1 - i;
|
||||||
|
|
||||||
|
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::cout << "noooo" << std::endl;
|
||||||
m_pc++;
|
m_pc++;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
@ -260,21 +238,16 @@ 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());
|
||||||
|
|
||||||
/*if (m_frames.size() >= 1)
|
|
||||||
{
|
|
||||||
for (auto e: m_frames.back().locals)
|
|
||||||
{
|
|
||||||
lambda->add_env(e.first, e.second);
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
for (auto const& f: m_frames)
|
for (auto const& f: m_frames)
|
||||||
{
|
{
|
||||||
for (auto e: f.locals)
|
for (auto e: f.locals)
|
||||||
|
@ -341,8 +314,9 @@ 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(ref_val->loc(),
|
auto res = fun->call(ref_val->loc(), m_mod, args);
|
||||||
m_mod, args)));
|
|
||||||
|
push(frame().program->add(res));
|
||||||
m_pc++;
|
m_pc++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -362,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(i, args[i]);
|
store_local(lambda->base_addr() + i, args[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
store_local(args.size(), self);
|
store_local(lambda->base_addr() + args.size(), self);
|
||||||
|
|
||||||
m_pc = 0;
|
m_pc = 0;
|
||||||
} break;
|
} break;
|
||||||
|
@ -390,6 +364,7 @@ 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;
|
||||||
|
|
||||||
|
@ -436,13 +411,14 @@ namespace fk
|
||||||
|
|
||||||
for (size_t i=0; i<args.size(); i++)
|
for (size_t i=0; i<args.size(); i++)
|
||||||
{
|
{
|
||||||
store_local(i, args[i]);
|
store_local(lambda->base_addr() + 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;
|
||||||
|
|
||||||
|
@ -541,10 +517,10 @@ namespace fk
|
||||||
|
|
||||||
for (size_t i=0; i<args.size(); i++)
|
for (size_t i=0; i<args.size(); i++)
|
||||||
{
|
{
|
||||||
store_local(i, args[i]);
|
store_local(lambda->base_addr() + i, args[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
store_local(args.size(), self);
|
store_local(lambda->base_addr() + args.size(), self);
|
||||||
|
|
||||||
m_pc = 0;
|
m_pc = 0;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue