FIX: closures.

main
bog 2023-09-26 10:33:34 +02:00
parent d973241ae2
commit 58a2c69634
7 changed files with 53 additions and 80 deletions

View File

@ -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,

View File

@ -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;
}
} }

View File

@ -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,

View File

@ -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>();
}; };
} }

View File

@ -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)

View File

@ -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;
}; };
} }

View File

@ -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;