FIX: now using unique addresses.

main
bog 2023-09-12 17:37:52 +02:00
parent d5fb25046e
commit 83f1cc97b9
11 changed files with 84 additions and 23 deletions

View File

@ -31,6 +31,7 @@ grino_src = static_library('grino',
'src/StaticFunction.cpp',
'src/SymTable.cpp',
'src/Loader.cpp',
'src/Addr.cpp',
])
grino_dep = declare_dependency(link_with: grino_src)

19
src/Addr.cpp Normal file
View File

@ -0,0 +1,19 @@
#include "Addr.hpp"
namespace grino
{
/*explicit*/ Addr::Addr()
{
}
/*virtual*/ Addr::~Addr()
{
}
size_t Addr::gen()
{
size_t addr = m_addr;
m_addr++;
return addr;
}
}

22
src/Addr.hpp Normal file
View File

@ -0,0 +1,22 @@
#ifndef grino_ADDR_HPP
#define grino_ADDR_HPP
#include "commons.hpp"
namespace grino
{
class Addr
{
public:
explicit Addr();
virtual ~Addr();
size_t current() const { return m_addr; }
size_t gen();
private:
size_t m_addr = 1;
};
}
#endif

View File

@ -6,8 +6,9 @@
namespace grino
{
/*explicit*/ Compiler::Compiler(Logger& logger)
/*explicit*/ Compiler::Compiler(Logger& logger, Addr& addr)
: m_logger { logger }
, m_addr { addr }
{
enter_scope();
}
@ -85,12 +86,13 @@ namespace grino
auto params = node->child(0).lock();
enter_scope(true);
size_t base_addr = m_addr.current();
for (size_t i=0; i<params->size(); i++)
{
auto param = params->child(i).lock();
std::string ident = param->repr();
sym.declare(param->loc(), ident, get_local_address(),
sym.declare(param->loc(), ident, m_addr.gen(),
m_scope.size());
}
@ -101,11 +103,12 @@ namespace grino
name = m_decl_context.back();
}
sym.declare(node->loc(), name, get_local_address(),
sym.declare(node->loc(), name, m_addr.gen(),
m_scope.size());
auto prog = std::make_shared<Program>();
auto body = node->child(1).lock();
compile(body, *prog, sym);
prog->push_instr(OPCODE_RET);
@ -114,7 +117,7 @@ namespace grino
sym.purge(m_scope.size());
program.push_value(Value::make_program(node->loc(), prog));
program.push_instr(OPCODE_MK_FUN);
program.push_instr(OPCODE_MK_FUN, base_addr);
} break;
case NODE_BOOL: {
@ -136,7 +139,7 @@ namespace grino
case NODE_VARDECL: {
std::string ident = node->child(0).lock()->repr();
auto expr = node->child(1).lock();
size_t address = get_local_address();
size_t address = m_addr.gen();
m_decl_context.push_back(ident);
compile(expr, program, sym);
@ -186,12 +189,6 @@ namespace grino
m_statics[name] = fun;
}
size_t Compiler::get_local_address()
{
m_scope.back() += 1;
return m_scope.back() - 1;
}
void Compiler::enter_scope(bool reset)
{
if (m_scope.empty() || reset)

View File

@ -5,6 +5,7 @@
#include "Logger.hpp"
#include "Node.hpp"
#include "src/mutils.hpp"
#include "Addr.hpp"
namespace grino
{
@ -17,7 +18,7 @@ namespace grino
class Compiler
{
public:
explicit Compiler(Logger& logger);
explicit Compiler(Logger& logger, Addr& addr);
virtual ~Compiler();
size_t scope() const { return m_scope.size(); }
@ -31,13 +32,13 @@ namespace grino
private:
Logger& m_logger;
Addr& m_addr;
std::unordered_map<std::string,
std::shared_ptr<StaticFunction>> m_statics;
std::vector<size_t> m_scope;
std::vector<std::string> m_decl_context;
size_t get_local_address();
void enter_scope(bool reset=false);
void leave_scope();
};

View File

@ -9,8 +9,10 @@ namespace grino
{
}
/*explicit*/ Function::Function(std::shared_ptr<Program> prog)
/*explicit*/ Function::Function(std::shared_ptr<Program> prog,
size_t base_addr)
: m_prog { prog }
, m_base_addr { base_addr }
{
}

View File

@ -16,9 +16,11 @@ namespace grino
{
public:
explicit Function(native_t native);
explicit Function(std::shared_ptr<Program> prog);
explicit Function(std::shared_ptr<Program> prog, size_t base_addr);
virtual ~Function();
size_t base_addr() const { return m_base_addr; }
bool is_native() const;
std::shared_ptr<Program> program() const;
value_t call(args_t args);
@ -30,6 +32,7 @@ namespace grino
native_t m_native;
std::shared_ptr<Program> m_prog;
std::unordered_map<size_t, std::shared_ptr<Value>> m_env;
size_t m_base_addr = 0;
};
}

View File

@ -47,7 +47,8 @@ namespace grino
auto prog_val = program().constant(pop());
auto prog = prog_val->as_program();
auto fun_val = Value::make_function(prog_val->loc(), prog);
auto fun_val = Value::make_function(prog_val->loc(),
prog, *instr.param);
// closure
if (m_frames.size() > 0)
@ -172,12 +173,14 @@ namespace grino
frame.program = fun->program().get();
m_frames.push_back(frame);
size_t base_addr = fun->base_addr();
for (size_t i=0; i<args.size(); i++)
{
set_local(i, args[i]);
set_local(base_addr + i, args[i]);
}
set_local(args.size(), ref_val);
set_local(base_addr + args.size(), ref_val);
m_pc = 0;
}
@ -208,7 +211,14 @@ namespace grino
std::shared_ptr<Value> VM::local(size_t addr) const
{
return m_frames.back().locals.at(addr);
auto itr = m_frames.back().locals.find(addr);
if (itr == std::end(m_frames.back().locals))
{
std::cout << "cannot find address " << addr << std::endl;
}
return itr->second;
}
void VM::set_local(size_t addr,

View File

@ -38,11 +38,12 @@ namespace grino
/*static*/ std::shared_ptr<Value>
Value::make_function(Loc const& loc,
std::shared_ptr<Program> val)
std::shared_ptr<Program> val,
size_t base_addr)
{
auto value = std::make_shared<Value>(loc);
value->m_type = TYPE_FUNCTION;
value->m_function_val = std::make_shared<Function>(val);
value->m_function_val = std::make_shared<Function>(val, base_addr);
return value;
}

View File

@ -19,7 +19,9 @@ namespace grino
static std::shared_ptr<Value> make_native_function(Loc const& loc,
native_t val);
static std::shared_ptr<Value> make_function(Loc const& loc,
std::shared_ptr<Program> val);
std::shared_ptr<Program> val,
size_t base_addr);
static std::shared_ptr<Value> make_ref(Loc const& loc,
size_t val);

View File

@ -10,6 +10,7 @@
#include "Logger.hpp"
#include "src/SymTable.hpp"
#include "Loader.hpp"
#include "Addr.hpp"
void run(char** argv, bool debug_mode)
{
@ -37,8 +38,10 @@ void run(char** argv, bool debug_mode)
grino::SymTable sym_table {logger};
grino::Program program;
grino::Addr addr;
grino::VM vm {logger, program};
grino::Compiler compiler {logger};
grino::Compiler compiler {logger, addr};
grino::Loader loader {vm, compiler, sym_table};
loader.load_libraries();