From 58a2c6963463b380129ac74c070eb825aff9cfb6 Mon Sep 17 00:00:00 2001 From: bog Date: Tue, 26 Sep 2023 10:33:34 +0200 Subject: [PATCH] FIX: closures. --- libstd/macro.cpp | 3 +- src/Compiler.cpp | 22 +++++-------- src/Compiler.hpp | 3 -- src/Lambda.hpp | 9 +++-- src/SymTable.cpp | 7 ++-- src/SymTable.hpp | 3 +- src/VM.cpp | 86 +++++++++++++++++------------------------------- 7 files changed, 53 insertions(+), 80 deletions(-) diff --git a/libstd/macro.cpp b/libstd/macro.cpp index 3935e56..99000e5 100644 --- a/libstd/macro.cpp +++ b/libstd/macro.cpp @@ -59,11 +59,10 @@ namespace fkstd compiler.pop_decl(); auto entry = compiler.sym()->declare_local(ident, - addr, node->loc()) .set_node(rhs); - program->add(OP_STORE_LOCAL, addr); + program->add(OP_STORE_LOCAL, entry.addr()); } void block(Compiler& compiler, diff --git a/src/Compiler.cpp b/src/Compiler.cpp index a0fd9c7..30c8b8d 100644 --- a/src/Compiler.cpp +++ b/src/Compiler.cpp @@ -76,19 +76,17 @@ namespace fk case NODE_VARDECL: { std::string ident = node->child(0)->repr(); auto rhs = node->child(1); - next_addr(); push_decl(ident); compile_prog(rhs, prog); pop_decl(); auto entry = sym()->declare_local(ident, - m_addr, node->loc()) .set_is_array(rhs->type() == NODE_ARRAY) .set_node(rhs); - prog->add(OP_STORE_LOCAL, m_addr); + prog->add(OP_STORE_LOCAL, entry.addr()); } break; case NODE_ARRAY: { @@ -158,14 +156,15 @@ namespace fk m_sym->enter_scope(node); + int base_addr = m_sym->addr(); + for (size_t i=0; isize(); i++) { 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(), - node->loc()); + m_sym->declare_local(func_name, node->loc()); Compiler compiler {m_mod, m_sym}; for (auto e: m_macros) @@ -183,6 +182,10 @@ namespace fk program, node->loc()); prog->load_const(constant); + + prog->load_const(std::make_shared(TYPE_INT, + base_addr, + constant->loc())); prog->add(OP_MAKE_FUNCTION, params->size()); } break; @@ -306,7 +309,6 @@ namespace fk prog->add(OP_LOAD_GLOBAL, entry->addr()); break; } - } break; case NODE_INT: { @@ -355,10 +357,4 @@ namespace fk assert(m_decl_stack.empty() == false); m_decl_stack.pop_back(); } - - addr_t Compiler::next_addr() - { - m_addr++; - return m_addr; - } } diff --git a/src/Compiler.hpp b/src/Compiler.hpp index 51dfd50..6876c35 100644 --- a/src/Compiler.hpp +++ b/src/Compiler.hpp @@ -44,11 +44,8 @@ namespace fk void push_decl(std::string const& ident); void pop_decl(); - addr_t next_addr(); - private: Module& m_mod; - addr_t m_addr = 0; std::shared_ptr m_sym; std::vector m_decl_stack; std::unordered_map program() const { return m_program; } - std::shared_ptr sym() const { return m_sym; } bool has_env(addr_t addr) const; std::shared_ptr get_env(addr_t addr) const; void add_env(addr_t addr, std::shared_ptr constant); + private: std::shared_ptr m_program; std::unordered_map> m_env; size_t m_arity; - std::shared_ptr m_sym = std::make_shared(); + addr_t m_base_addr = 0; + + //std::shared_ptr m_sym = std::make_shared(); }; } diff --git a/src/SymTable.cpp b/src/SymTable.cpp index 1278bad..9882b0a 100644 --- a/src/SymTable.cpp +++ b/src/SymTable.cpp @@ -13,7 +13,6 @@ namespace fk } SymEntry& SymTable::declare_local(std::string const& name, - addr_t addr, Loc const& loc) { auto entry = find(name); @@ -31,13 +30,13 @@ namespace fk } SymEntry e {name, - addr, + m_addr, false, m_scope, m_parents.empty() ? nullptr : m_parents.back(), loc}; - + m_addr++; m_entries.push_back(e); return m_entries.back(); @@ -47,7 +46,7 @@ namespace fk addr_t addr, 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 SymTable::find(std::string const& name) diff --git a/src/SymTable.hpp b/src/SymTable.hpp index 2e38e95..b1bff50 100644 --- a/src/SymTable.hpp +++ b/src/SymTable.hpp @@ -14,10 +14,10 @@ namespace fk explicit SymTable(); virtual ~SymTable(); + size_t addr() const { return m_addr; } int scope() const { return m_scope; } SymEntry& declare_local(std::string const& name, - addr_t addr, Loc const& loc); SymEntry& declare_global(std::string const& name, @@ -42,6 +42,7 @@ namespace fk private: std::vector m_entries; int m_scope; + size_t m_addr = 12; std::vector> m_parents; }; } diff --git a/src/VM.cpp b/src/VM.cpp index 390b5ab..2ba0bdc 100644 --- a/src/VM.cpp +++ b/src/VM.cpp @@ -31,41 +31,6 @@ namespace fk switch (instr.opcode) { - /*case OP_DEREF: { - std::vector indexes; - - for (size_t i=0; iget_const(pop()); - int index = std::get(index_val->value()); - indexes.insert(std::begin(indexes), index); - } - - size_t ref = - std::get(frame().program - ->get_const(pop())->value()); - - std::shared_ptr val = - std::get>(load_global(ref)); - - for (size_t i=0; iat(indexes[i])->value(); - - size_t ref = std::get(ref_val); - - auto arr = - std::get>(load_global(ref)); - - val = arr; - - } - - push(frame().program->add(val->at(indexes.back()))); - - m_pc++; - } break;*/ - case OP_MAKE_ARRAY: { std::vector> data; @@ -217,16 +182,29 @@ namespace fk } break; case OP_LOAD_CLOSURE: { - if (frame().lambda && frame().lambda->has_env(instr.param)) + std::shared_ptr lambda; + + for (size_t i=0; iget_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); push(addr); m_pc++; break; } - + std::cout << "noooo" << std::endl; m_pc++; } break; @@ -260,21 +238,16 @@ namespace fk } break; case OP_MAKE_FUNCTION: { + int base_addr = + std::get(frame().program->get_const(pop())->value()); + auto p = frame().program->get_const(pop()); auto prog = std::get>(p->value()); auto lambda = std::make_shared(prog, instr.param); - + lambda->set_base_addr(base_addr); addr_t addr = store_global(lambda); auto ref = std::make_shared(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 e: f.locals) @@ -341,8 +314,9 @@ namespace fk auto fun = std::get> (load_global(ref)); - push(frame().program->add(fun->call(ref_val->loc(), - m_mod, args))); + auto res = fun->call(ref_val->loc(), m_mod, args); + + push(frame().program->add(res)); m_pc++; break; } @@ -362,10 +336,10 @@ namespace fk for (size_t i=0; ibase_addr() + i, args[i]); } - store_local(args.size(), self); + store_local(lambda->base_addr() + args.size(), self); m_pc = 0; } break; @@ -390,6 +364,7 @@ namespace fk auto value = frame().program->get_const(top()); assert(value); frame().locals[instr.param] = value; + m_pc++; } break; @@ -436,13 +411,14 @@ namespace fk for (size_t i=0; ibase_addr() + i, args[i]); } auto self = std::make_shared(TYPE_REF, static_cast(ref), loc); - store_local(args.size(), self); + + store_local(lambda->base_addr() + args.size(), self); m_pc = 0; @@ -541,10 +517,10 @@ namespace fk for (size_t i=0; ibase_addr() + i, args[i]); } - store_local(args.size(), self); + store_local(lambda->base_addr() + args.size(), self); m_pc = 0;