parent
792ef70df9
commit
f393d6d7f7
|
@ -88,11 +88,21 @@ namespace grino
|
||||||
|
|
||||||
size_t addr = m_vm.heap_size();
|
size_t addr = m_vm.heap_size();
|
||||||
m_vm.set_heap(addr, val);
|
m_vm.set_heap(addr, val);
|
||||||
m_sym_table.declare_object(loc, name, addr, 0);
|
m_sym_table.declare_module(loc, name, addr, 0, mod->sym_table());
|
||||||
|
|
||||||
return mod;
|
return mod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Loader::add_var(std::string const& name,
|
||||||
|
std::shared_ptr<Value> val)
|
||||||
|
{
|
||||||
|
size_t addr = m_vm.heap_size();
|
||||||
|
grino::Loc loc {"natives/" + name, 0};
|
||||||
|
m_vm.set_heap(addr, val);
|
||||||
|
|
||||||
|
m_sym_table.declare_object(loc, name, addr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
void Loader::add_native(std::string const& name,
|
void Loader::add_native(std::string const& name,
|
||||||
native_t native,
|
native_t native,
|
||||||
std::shared_ptr<Prototype> prototype)
|
std::shared_ptr<Prototype> prototype)
|
||||||
|
|
|
@ -26,6 +26,10 @@ namespace grino
|
||||||
void load_library(std::filesystem::path path);
|
void load_library(std::filesystem::path path);
|
||||||
|
|
||||||
std::shared_ptr<Module> add_module(std::string const& name);
|
std::shared_ptr<Module> add_module(std::string const& name);
|
||||||
|
|
||||||
|
void add_var(std::string const& name,
|
||||||
|
std::shared_ptr<Value> val);
|
||||||
|
|
||||||
void add_native(std::string const& name,
|
void add_native(std::string const& name,
|
||||||
native_t native,
|
native_t native,
|
||||||
std::shared_ptr<Prototype> prototype);
|
std::shared_ptr<Prototype> prototype);
|
||||||
|
|
|
@ -18,6 +18,7 @@ namespace grino
|
||||||
std::string name() const { return m_name; }
|
std::string name() const { return m_name; }
|
||||||
void load();
|
void load();
|
||||||
void load_native();
|
void load_native();
|
||||||
|
std::shared_ptr<SymTable> sym_table() const { return m_sym_table; }
|
||||||
std::shared_ptr<Loader> loader() const { return m_loader; }
|
std::shared_ptr<Loader> loader() const { return m_loader; }
|
||||||
std::shared_ptr<Value> find(std::string const& name);
|
std::shared_ptr<Value> find(std::string const& name);
|
||||||
std::shared_ptr<Value> from_heap(size_t addr);
|
std::shared_ptr<Value> from_heap(size_t addr);
|
||||||
|
|
|
@ -20,6 +20,7 @@ namespace grino
|
||||||
|
|
||||||
|
|
||||||
size_t size() const { return m_instrs.size(); }
|
size_t size() const { return m_instrs.size(); }
|
||||||
|
size_t constant_size() const { return m_constants.size(); }
|
||||||
|
|
||||||
Instr get(size_t index) const;
|
Instr get(size_t index) const;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
#include "StaticPass.hpp"
|
#include "StaticPass.hpp"
|
||||||
#include "src/Prototype.hpp"
|
#include "src/Prototype.hpp"
|
||||||
#include "StaticFunction.hpp"
|
#include "StaticFunction.hpp"
|
||||||
|
#include "Module.hpp"
|
||||||
#include "src/types.hpp"
|
#include "src/types.hpp"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace grino
|
namespace grino
|
||||||
{
|
{
|
||||||
|
@ -83,6 +85,13 @@ namespace grino
|
||||||
std::string ident = node->child(0).lock()->repr();
|
std::string ident = node->child(0).lock()->repr();
|
||||||
auto res = check(node->child(1).lock());
|
auto res = check(node->child(1).lock());
|
||||||
m_types[ident] = res;
|
m_types[ident] = res;
|
||||||
|
|
||||||
|
if (node->child(1).lock()->type() == NODE_IMPORT)
|
||||||
|
{
|
||||||
|
auto name = node->child(1).lock()->child(0).lock()->repr();
|
||||||
|
name = name.substr(1, name.size() - 2);
|
||||||
|
m_mod_names[ident] = name;
|
||||||
|
}
|
||||||
return res;
|
return res;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
@ -99,6 +108,43 @@ namespace grino
|
||||||
{
|
{
|
||||||
proto = m_compiler.static_func(ident)->prototype();
|
proto = m_compiler.static_func(ident)->prototype();
|
||||||
}
|
}
|
||||||
|
else if (node->child(0).lock()->type() == NODE_NS)
|
||||||
|
{
|
||||||
|
std::string mod_name
|
||||||
|
= node->child(0).lock()->child(0).lock()->repr();
|
||||||
|
|
||||||
|
std::string var_name
|
||||||
|
= node->child(0).lock()->child(1).lock()->repr();
|
||||||
|
|
||||||
|
auto mod_entry = m_sym.find_no_scope(mod_name);
|
||||||
|
std::shared_ptr<SymTable> mod_sym;
|
||||||
|
|
||||||
|
if (!mod_entry)
|
||||||
|
{
|
||||||
|
std::filesystem::path name = mod_name;
|
||||||
|
|
||||||
|
auto full_name = std::filesystem::path(m_mod_names[mod_name]);
|
||||||
|
|
||||||
|
if (!full_name.has_extension())
|
||||||
|
{
|
||||||
|
full_name += ".gri";
|
||||||
|
}
|
||||||
|
|
||||||
|
auto mod = std::make_shared<Module>(full_name);
|
||||||
|
mod->load();
|
||||||
|
|
||||||
|
auto entry = mod->sym_table()->find_no_scope(var_name);
|
||||||
|
assert(entry);
|
||||||
|
proto = entry->prototype;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mod_sym = mod_entry->mod;
|
||||||
|
|
||||||
|
auto entry = mod_sym->find_no_scope(var_name);
|
||||||
|
proto = entry->prototype;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (proto)
|
if (proto)
|
||||||
{
|
{
|
||||||
|
@ -139,7 +185,7 @@ namespace grino
|
||||||
<< "' got '"
|
<< "' got '"
|
||||||
<< (node->size() - 1)
|
<< (node->size() - 1)
|
||||||
<< "'";
|
<< "'";
|
||||||
std::cout << node->string() << std::endl;
|
|
||||||
m_logger
|
m_logger
|
||||||
.log<static_error>(LOG_ERROR, node->loc(), ss.str());
|
.log<static_error>(LOG_ERROR, node->loc(), ss.str());
|
||||||
}
|
}
|
||||||
|
@ -158,7 +204,9 @@ namespace grino
|
||||||
}
|
}
|
||||||
|
|
||||||
bool same_err = (i > 1 && proto->hint(i - 1) == HINT_SAME)
|
bool same_err = (i > 1 && proto->hint(i - 1) == HINT_SAME)
|
||||||
&& ty.back().type != ty.at(ty.size() - 2).type;
|
&& ty.back().type != ty.at(ty.size() - 2).type
|
||||||
|
&& ty.back().hint != HINT_ANY
|
||||||
|
&& ty.at(ty.size() - 2).hint != HINT_ANY;
|
||||||
|
|
||||||
if (same_err)
|
if (same_err)
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,6 +23,7 @@ namespace grino
|
||||||
Logger& m_logger;
|
Logger& m_logger;
|
||||||
Compiler& m_compiler;
|
Compiler& m_compiler;
|
||||||
SymTable& m_sym;
|
SymTable& m_sym;
|
||||||
|
std::unordered_map<std::string, std::string> m_mod_names;
|
||||||
std::unordered_map<std::string, TypeSlot> m_types;
|
std::unordered_map<std::string, TypeSlot> m_types;
|
||||||
|
|
||||||
void error(TypeType lhs, TypeType rhs, std::shared_ptr<Node> node);
|
void error(TypeType lhs, TypeType rhs, std::shared_ptr<Node> node);
|
||||||
|
|
|
@ -49,6 +49,14 @@ namespace grino
|
||||||
m_entries.back().prototype = prototype;
|
m_entries.back().prototype = prototype;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SymTable::declare_module(Loc const& loc, std::string const& name,
|
||||||
|
size_t addr,
|
||||||
|
size_t scope, std::shared_ptr<SymTable> sym)
|
||||||
|
{
|
||||||
|
declare_object(loc, name, addr, scope);
|
||||||
|
m_entries.back().mod = sym;
|
||||||
|
}
|
||||||
|
|
||||||
std::optional<SymEntry> SymTable::find(std::string const& name, size_t scope)
|
std::optional<SymEntry> SymTable::find(std::string const& name, size_t scope)
|
||||||
{
|
{
|
||||||
std::optional<SymEntry> entry;
|
std::optional<SymEntry> entry;
|
||||||
|
|
|
@ -8,12 +8,15 @@
|
||||||
|
|
||||||
namespace grino
|
namespace grino
|
||||||
{
|
{
|
||||||
|
class SymTable;
|
||||||
|
|
||||||
struct SymEntry {
|
struct SymEntry {
|
||||||
std::string name;
|
std::string name;
|
||||||
bool is_object; /* object are on the heap instead of the stack */
|
bool is_object; /* object are on the heap instead of the stack */
|
||||||
size_t addr; /* address on the heap if object, local address otherwise */
|
size_t addr; /* address on the heap if object, local address otherwise */
|
||||||
size_t scope;
|
size_t scope;
|
||||||
std::shared_ptr<Prototype> prototype; /* only used by functions */
|
std::shared_ptr<Prototype> prototype; /* only used by functions */
|
||||||
|
std::shared_ptr<SymTable> mod; /* only used by modules */
|
||||||
};
|
};
|
||||||
|
|
||||||
GRINO_ERROR(symbolic_error);
|
GRINO_ERROR(symbolic_error);
|
||||||
|
@ -33,6 +36,9 @@ namespace grino
|
||||||
void declare_function(Loc const& loc, std::string const& name, size_t addr,
|
void declare_function(Loc const& loc, std::string const& name, size_t addr,
|
||||||
size_t scope, std::shared_ptr<Prototype> prototype);
|
size_t scope, std::shared_ptr<Prototype> prototype);
|
||||||
|
|
||||||
|
void declare_module(Loc const& loc, std::string const& name, size_t addr,
|
||||||
|
size_t scope, std::shared_ptr<SymTable> sym);
|
||||||
|
|
||||||
std::optional<SymEntry> find(std::string const& name, size_t scope);
|
std::optional<SymEntry> find(std::string const& name, size_t scope);
|
||||||
std::optional<SymEntry> find_no_scope(std::string const& name);
|
std::optional<SymEntry> find_no_scope(std::string const& name);
|
||||||
|
|
||||||
|
|
29
src/VM.cpp
29
src/VM.cpp
|
@ -130,9 +130,13 @@ namespace grino
|
||||||
{
|
{
|
||||||
for (auto const& entry: m_frames.at(m_frames.size() - 1).locals)
|
for (auto const& entry: m_frames.at(m_frames.size() - 1).locals)
|
||||||
{
|
{
|
||||||
fun_val->as_function()
|
auto cpy = Value::try_copy(fun_val->loc(), entry.second);
|
||||||
->set_env(entry.first,
|
|
||||||
Value::make_copy(fun_val->loc(), entry.second));
|
if (cpy)
|
||||||
|
{
|
||||||
|
fun_val->as_function()
|
||||||
|
->set_env(entry.first, cpy);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,8 +202,12 @@ namespace grino
|
||||||
|
|
||||||
if (fun && fun->has_env(addr))
|
if (fun && fun->has_env(addr))
|
||||||
{
|
{
|
||||||
fun->set_env(addr, Value::make_copy(value->loc(), value));
|
auto cpy = Value::try_copy(value->loc(), value);
|
||||||
found = true;
|
if (cpy)
|
||||||
|
{
|
||||||
|
fun->set_env(addr, cpy);
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -212,9 +220,12 @@ namespace grino
|
||||||
{
|
{
|
||||||
if (fun)
|
if (fun)
|
||||||
{
|
{
|
||||||
fun->set_env(itr->first,
|
auto cpy = Value::try_copy(itr->second->loc(),
|
||||||
Value::make_copy(itr->second->loc(),
|
itr->second);
|
||||||
itr->second));
|
if (cpy)
|
||||||
|
{
|
||||||
|
fun->set_env(itr->first, cpy);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
found = true;
|
found = true;
|
||||||
|
@ -265,7 +276,7 @@ namespace grino
|
||||||
if (fun)
|
if (fun)
|
||||||
{
|
{
|
||||||
fun->set_env(itr2->first,
|
fun->set_env(itr2->first,
|
||||||
Value::make_copy(itr2->second->loc(),
|
Value::try_copy(itr2->second->loc(),
|
||||||
itr2->second));
|
itr2->second));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,8 +81,8 @@ namespace grino
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static*/
|
/*static*/
|
||||||
std::shared_ptr<Value> Value::make_copy(Loc const& loc,
|
std::shared_ptr<Value> Value::try_copy(Loc const& loc,
|
||||||
std::shared_ptr<Value> val)
|
std::shared_ptr<Value> val)
|
||||||
{
|
{
|
||||||
switch (val->type())
|
switch (val->type())
|
||||||
{
|
{
|
||||||
|
@ -98,6 +98,10 @@ namespace grino
|
||||||
return Value::make_ref(loc, val->as_ref());
|
return Value::make_ref(loc, val->as_ref());
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case TYPE_PROGRAM: {
|
||||||
|
return nullptr;
|
||||||
|
} break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
std::cerr << "cannot copy unknown value " <<
|
std::cerr << "cannot copy unknown value " <<
|
||||||
TypeTypeStr[val->type()] << std::endl;
|
TypeTypeStr[val->type()] << std::endl;
|
||||||
|
|
|
@ -38,8 +38,8 @@ namespace grino
|
||||||
static std::shared_ptr<Value> make_program(Loc const& loc,
|
static std::shared_ptr<Value> make_program(Loc const& loc,
|
||||||
std::shared_ptr<Program> val);
|
std::shared_ptr<Program> val);
|
||||||
|
|
||||||
static std::shared_ptr<Value> make_copy(Loc const& loc,
|
static std::shared_ptr<Value> try_copy(Loc const& loc,
|
||||||
std::shared_ptr<Value> val);
|
std::shared_ptr<Value> val);
|
||||||
|
|
||||||
static std::shared_ptr<Value> make_array(Loc const& loc,
|
static std::shared_ptr<Value> make_array(Loc const& loc,
|
||||||
val_array_t val);
|
val_array_t val);
|
||||||
|
|
|
@ -60,7 +60,6 @@ void run(char* const source_name,
|
||||||
}
|
}
|
||||||
|
|
||||||
loader.load_libraries();
|
loader.load_libraries();
|
||||||
|
|
||||||
grino::StaticPass static_pass {logger, compiler, sym_table};
|
grino::StaticPass static_pass {logger, compiler, sym_table};
|
||||||
static_pass.check(ast);
|
static_pass.check(ast);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue