FIX: type checking and modules.

FIX: closure capture on non copyable objects.
main
bog 2023-09-15 20:36:16 +02:00
parent 792ef70df9
commit f393d6d7f7
12 changed files with 110 additions and 17 deletions

View File

@ -88,11 +88,21 @@ namespace grino
size_t addr = m_vm.heap_size();
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;
}
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,
native_t native,
std::shared_ptr<Prototype> prototype)

View File

@ -26,6 +26,10 @@ namespace grino
void load_library(std::filesystem::path path);
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,
native_t native,
std::shared_ptr<Prototype> prototype);

View File

@ -18,6 +18,7 @@ namespace grino
std::string name() const { return m_name; }
void load();
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<Value> find(std::string const& name);
std::shared_ptr<Value> from_heap(size_t addr);

View File

@ -20,6 +20,7 @@ namespace grino
size_t size() const { return m_instrs.size(); }
size_t constant_size() const { return m_constants.size(); }
Instr get(size_t index) const;

View File

@ -1,7 +1,9 @@
#include "StaticPass.hpp"
#include "src/Prototype.hpp"
#include "StaticFunction.hpp"
#include "Module.hpp"
#include "src/types.hpp"
#include <memory>
namespace grino
{
@ -83,6 +85,13 @@ namespace grino
std::string ident = node->child(0).lock()->repr();
auto res = check(node->child(1).lock());
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;
} break;
@ -99,6 +108,43 @@ namespace grino
{
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)
{
@ -139,7 +185,7 @@ namespace grino
<< "' got '"
<< (node->size() - 1)
<< "'";
std::cout << node->string() << std::endl;
m_logger
.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)
&& 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)
{

View File

@ -23,6 +23,7 @@ namespace grino
Logger& m_logger;
Compiler& m_compiler;
SymTable& m_sym;
std::unordered_map<std::string, std::string> m_mod_names;
std::unordered_map<std::string, TypeSlot> m_types;
void error(TypeType lhs, TypeType rhs, std::shared_ptr<Node> node);

View File

@ -49,6 +49,14 @@ namespace grino
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> entry;

View File

@ -8,12 +8,15 @@
namespace grino
{
class SymTable;
struct SymEntry {
std::string name;
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 scope;
std::shared_ptr<Prototype> prototype; /* only used by functions */
std::shared_ptr<SymTable> mod; /* only used by modules */
};
GRINO_ERROR(symbolic_error);
@ -33,6 +36,9 @@ namespace grino
void declare_function(Loc const& loc, std::string const& name, size_t addr,
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_no_scope(std::string const& name);

View File

@ -130,9 +130,13 @@ namespace grino
{
for (auto const& entry: m_frames.at(m_frames.size() - 1).locals)
{
fun_val->as_function()
->set_env(entry.first,
Value::make_copy(fun_val->loc(), entry.second));
auto cpy = Value::try_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))
{
fun->set_env(addr, Value::make_copy(value->loc(), value));
found = true;
auto cpy = Value::try_copy(value->loc(), value);
if (cpy)
{
fun->set_env(addr, cpy);
found = true;
}
}
else
{
@ -212,9 +220,12 @@ namespace grino
{
if (fun)
{
fun->set_env(itr->first,
Value::make_copy(itr->second->loc(),
itr->second));
auto cpy = Value::try_copy(itr->second->loc(),
itr->second);
if (cpy)
{
fun->set_env(itr->first, cpy);
}
}
found = true;
@ -265,7 +276,7 @@ namespace grino
if (fun)
{
fun->set_env(itr2->first,
Value::make_copy(itr2->second->loc(),
Value::try_copy(itr2->second->loc(),
itr2->second));
}

View File

@ -81,8 +81,8 @@ namespace grino
}
/*static*/
std::shared_ptr<Value> Value::make_copy(Loc const& loc,
std::shared_ptr<Value> val)
std::shared_ptr<Value> Value::try_copy(Loc const& loc,
std::shared_ptr<Value> val)
{
switch (val->type())
{
@ -98,6 +98,10 @@ namespace grino
return Value::make_ref(loc, val->as_ref());
} break;
case TYPE_PROGRAM: {
return nullptr;
} break;
default:
std::cerr << "cannot copy unknown value " <<
TypeTypeStr[val->type()] << std::endl;

View File

@ -38,8 +38,8 @@ namespace grino
static std::shared_ptr<Value> make_program(Loc const& loc,
std::shared_ptr<Program> val);
static std::shared_ptr<Value> make_copy(Loc const& loc,
std::shared_ptr<Value> val);
static std::shared_ptr<Value> try_copy(Loc const& loc,
std::shared_ptr<Value> val);
static std::shared_ptr<Value> make_array(Loc const& loc,
val_array_t val);

View File

@ -60,7 +60,6 @@ void run(char* const source_name,
}
loader.load_libraries();
grino::StaticPass static_pass {logger, compiler, sym_table};
static_pass.check(ast);