ADD: more type checking.
parent
e12ff96943
commit
792ef70df9
21
lib/cast.hpp
21
lib/cast.hpp
|
@ -1,4 +1,5 @@
|
||||||
#include "commons.hpp"
|
#include "commons.hpp"
|
||||||
|
#include "src/Prototype.hpp"
|
||||||
|
|
||||||
extern "C" void lib_cast(grino::Loader& loader)
|
extern "C" void lib_cast(grino::Loader& loader)
|
||||||
{
|
{
|
||||||
|
@ -7,20 +8,32 @@ extern "C" void lib_cast(grino::Loader& loader)
|
||||||
loader.add_native("stoi", [loc](auto args){
|
loader.add_native("stoi", [loc](auto args){
|
||||||
std::string value = args[0]->as_string();
|
std::string value = args[0]->as_string();
|
||||||
return grino::Value::make_int(loc, std::stoi(value));
|
return grino::Value::make_int(loc, std::stoi(value));
|
||||||
});
|
}, std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot>{
|
||||||
|
grino::TypeSlot {grino::HINT_CAT_PARAM, grino::TYPE_STRING},
|
||||||
|
grino::TypeSlot {grino::HINT_CAT_RETURN, grino::TYPE_INT}
|
||||||
|
}));
|
||||||
|
|
||||||
loader.add_native("itos", [loc](auto args){
|
loader.add_native("itos", [loc](auto args){
|
||||||
int value = args[0]->as_int();
|
int value = args[0]->as_int();
|
||||||
return grino::Value::make_string(loc, std::to_string(value));
|
return grino::Value::make_string(loc, std::to_string(value));
|
||||||
});
|
}, std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot>{
|
||||||
|
grino::TypeSlot {grino::HINT_CAT_PARAM, grino::TYPE_INT},
|
||||||
|
grino::TypeSlot {grino::HINT_CAT_RETURN, grino::TYPE_STRING}
|
||||||
|
}));
|
||||||
|
|
||||||
loader.add_native("stof", [loc](auto args){
|
loader.add_native("stof", [loc](auto args){
|
||||||
std::string value = args[0]->as_string();
|
std::string value = args[0]->as_string();
|
||||||
return grino::Value::make_int(loc, std::stof(value));
|
return grino::Value::make_int(loc, std::stof(value));
|
||||||
});
|
}, std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot>{
|
||||||
|
grino::TypeSlot {grino::HINT_CAT_PARAM, grino::TYPE_STRING},
|
||||||
|
grino::TypeSlot {grino::HINT_CAT_RETURN, grino::TYPE_FLOAT}
|
||||||
|
}));
|
||||||
|
|
||||||
loader.add_native("ftos", [loc](auto args){
|
loader.add_native("ftos", [loc](auto args){
|
||||||
float value = args[0]->as_float();
|
float value = args[0]->as_float();
|
||||||
return grino::Value::make_string(loc, std::to_string(value));
|
return grino::Value::make_string(loc, std::to_string(value));
|
||||||
});
|
}, std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot>{
|
||||||
|
grino::TypeSlot {grino::HINT_CAT_PARAM, grino::TYPE_FLOAT},
|
||||||
|
grino::TypeSlot {grino::HINT_CAT_RETURN, grino::TYPE_STRING}
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
95
lib/core.cpp
95
lib/core.cpp
|
@ -45,8 +45,8 @@ extern "C" void lib_collection(grino::Loader& loader)
|
||||||
|
|
||||||
return f(args[0], idxs);
|
return f(args[0], idxs);
|
||||||
}, std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot>{
|
}, std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot>{
|
||||||
grino::TypeSlot {grino::HINT_CAT_PARAM, grino::TYPE_INT},
|
grino::TypeSlot {grino::HINT_CAT_VARIADIC_PARAM, grino::TYPE_NIL,
|
||||||
grino::TypeSlot {grino::HINT_CAT_PARAM, grino::TYPE_NIL, grino::HINT_ANY},
|
grino::HINT_ANY},
|
||||||
grino::TypeSlot {grino::HINT_CAT_RETURN, grino::TYPE_NIL, grino::HINT_ANY},
|
grino::TypeSlot {grino::HINT_CAT_RETURN, grino::TYPE_NIL, grino::HINT_ANY},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -63,7 +63,11 @@ extern "C" void lib_collection(grino::Loader& loader)
|
||||||
auto& array = array_val->as_array();
|
auto& array = array_val->as_array();
|
||||||
|
|
||||||
return grino::Value::make_bool(array_val->loc(), array.empty());
|
return grino::Value::make_bool(array_val->loc(), array.empty());
|
||||||
});
|
}, std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot> {
|
||||||
|
{grino::TypeSlot {grino::HINT_CAT_PARAM, grino::TYPE_NIL,
|
||||||
|
grino::HINT_ANY}},
|
||||||
|
{grino::TypeSlot {grino::HINT_CAT_RETURN, grino::TYPE_BOOL}}
|
||||||
|
}));
|
||||||
|
|
||||||
loader.add_native("len", [&loader](auto args){
|
loader.add_native("len", [&loader](auto args){
|
||||||
auto val = args[0];
|
auto val = args[0];
|
||||||
|
@ -78,7 +82,12 @@ extern "C" void lib_collection(grino::Loader& loader)
|
||||||
auto& array = array_val->as_array();
|
auto& array = array_val->as_array();
|
||||||
|
|
||||||
return grino::Value::make_int(array_val->loc(), array.size());
|
return grino::Value::make_int(array_val->loc(), array.size());
|
||||||
});
|
}, std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot> {
|
||||||
|
{grino::TypeSlot {grino::HINT_CAT_PARAM,
|
||||||
|
grino::TYPE_NIL,
|
||||||
|
grino::HINT_ANY}},
|
||||||
|
{grino::TypeSlot {grino::HINT_CAT_RETURN, grino::TYPE_INT}}
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void lib_array(grino::Loader& loader)
|
extern "C" void lib_array(grino::Loader& loader)
|
||||||
|
@ -90,7 +99,13 @@ extern "C" void lib_array(grino::Loader& loader)
|
||||||
auto& array = array_val->as_array();
|
auto& array = array_val->as_array();
|
||||||
|
|
||||||
return array[0];
|
return array[0];
|
||||||
});
|
}, std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot> {
|
||||||
|
{grino::TypeSlot {grino::HINT_CAT_PARAM,
|
||||||
|
grino::TYPE_ARRAY,
|
||||||
|
grino::HINT_NONE}},
|
||||||
|
{grino::TypeSlot {grino::HINT_CAT_RETURN, grino::TYPE_NIL,
|
||||||
|
grino::HINT_ANY}}
|
||||||
|
}));
|
||||||
|
|
||||||
loader.add_native("tail", [&loader](auto args){
|
loader.add_native("tail", [&loader](auto args){
|
||||||
auto ref_val = args[0];
|
auto ref_val = args[0];
|
||||||
|
@ -109,7 +124,13 @@ extern "C" void lib_array(grino::Loader& loader)
|
||||||
loader.vm().set_heap(addr, res);
|
loader.vm().set_heap(addr, res);
|
||||||
|
|
||||||
return grino::Value::make_ref(array_val->loc(), addr);
|
return grino::Value::make_ref(array_val->loc(), addr);
|
||||||
});
|
}, std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot> {
|
||||||
|
{grino::TypeSlot {grino::HINT_CAT_PARAM,
|
||||||
|
grino::TYPE_ARRAY,
|
||||||
|
grino::HINT_NONE}},
|
||||||
|
{grino::TypeSlot {grino::HINT_CAT_RETURN, grino::TYPE_ARRAY,
|
||||||
|
grino::HINT_NONE}}
|
||||||
|
}));
|
||||||
|
|
||||||
loader.add_native("cons", [&loader](auto args){
|
loader.add_native("cons", [&loader](auto args){
|
||||||
auto ref_val = args[1];
|
auto ref_val = args[1];
|
||||||
|
@ -124,7 +145,16 @@ extern "C" void lib_array(grino::Loader& loader)
|
||||||
loader.vm().set_heap(addr, res);
|
loader.vm().set_heap(addr, res);
|
||||||
|
|
||||||
return grino::Value::make_ref(array_val->loc(), addr);
|
return grino::Value::make_ref(array_val->loc(), addr);
|
||||||
});
|
}, std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot> {
|
||||||
|
{grino::TypeSlot {grino::HINT_CAT_PARAM,
|
||||||
|
grino::TYPE_NIL,
|
||||||
|
grino::HINT_ANY}},
|
||||||
|
{grino::TypeSlot {grino::HINT_CAT_PARAM,
|
||||||
|
grino::TYPE_ARRAY,
|
||||||
|
grino::HINT_NONE}},
|
||||||
|
{grino::TypeSlot {grino::HINT_CAT_RETURN, grino::TYPE_ARRAY,
|
||||||
|
grino::HINT_NONE}}
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void lib_flow_control(grino::Loader& loader)
|
extern "C" void lib_flow_control(grino::Loader& loader)
|
||||||
|
@ -147,9 +177,13 @@ extern "C" void lib_flow_control(grino::Loader& loader)
|
||||||
|
|
||||||
prog.set_param(br, prog.size());
|
prog.set_param(br, prog.size());
|
||||||
}, std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot> {{
|
}, std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot> {{
|
||||||
|
grino::TypeSlot {grino::HINT_CAT_VARIADIC_PARAM,
|
||||||
|
grino::TYPE_NIL,
|
||||||
|
grino::HINT_ANY},
|
||||||
|
|
||||||
grino::TypeSlot {grino::HINT_CAT_RETURN,
|
grino::TypeSlot {grino::HINT_CAT_RETURN,
|
||||||
grino::TYPE_NIL,
|
grino::TYPE_NIL,
|
||||||
grino::HINT_NONE},
|
grino::HINT_ANY},
|
||||||
}}));
|
}}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,7 +345,7 @@ extern "C" void lib_float(grino::Loader& loader)
|
||||||
auto var_proto =
|
auto var_proto =
|
||||||
std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot>{
|
std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot>{
|
||||||
grino::TypeSlot {grino::HINT_CAT_VARIADIC_PARAM, grino::TYPE_FLOAT},
|
grino::TypeSlot {grino::HINT_CAT_VARIADIC_PARAM, grino::TYPE_FLOAT},
|
||||||
grino::TypeSlot {grino::HINT_CAT_RETURN, grino::TYPE_INT},
|
grino::TypeSlot {grino::HINT_CAT_RETURN, grino::TYPE_FLOAT},
|
||||||
});
|
});
|
||||||
|
|
||||||
loader.add_native("+.", [](auto args){
|
loader.add_native("+.", [](auto args){
|
||||||
|
@ -463,8 +497,10 @@ extern "C" void lib_cmp(grino::Loader& loader)
|
||||||
{
|
{
|
||||||
auto var_proto =
|
auto var_proto =
|
||||||
std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot>{
|
std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot>{
|
||||||
grino::TypeSlot {grino::HINT_CAT_PARAM, grino::TYPE_INT},
|
grino::TypeSlot {grino::HINT_CAT_PARAM, grino::TYPE_INT,
|
||||||
grino::TypeSlot {grino::HINT_CAT_PARAM, grino::TYPE_INT},
|
grino::HINT_ANY},
|
||||||
|
grino::TypeSlot {grino::HINT_CAT_PARAM, grino::TYPE_INT,
|
||||||
|
grino::HINT_SAME},
|
||||||
grino::TypeSlot {grino::HINT_CAT_RETURN, grino::TYPE_BOOL},
|
grino::TypeSlot {grino::HINT_CAT_RETURN, grino::TYPE_BOOL},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -647,6 +683,8 @@ extern "C" void lib_bool(grino::Loader& loader)
|
||||||
|
|
||||||
extern "C" void lib_assert(grino::Loader& loader)
|
extern "C" void lib_assert(grino::Loader& loader)
|
||||||
{
|
{
|
||||||
|
grino::Loc loc {"core/assert"};
|
||||||
|
|
||||||
loader.add_native("assert", [](auto args){
|
loader.add_native("assert", [](auto args){
|
||||||
|
|
||||||
for (auto value: args)
|
for (auto value: args)
|
||||||
|
@ -662,11 +700,12 @@ extern "C" void lib_assert(grino::Loader& loader)
|
||||||
|
|
||||||
return grino::Value::make_bool(args.front()->loc(), true);
|
return grino::Value::make_bool(args.front()->loc(), true);
|
||||||
}, std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot> {{
|
}, std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot> {{
|
||||||
grino::TypeSlot {grino::HINT_CAT_PARAM, grino::TYPE_BOOL},
|
grino::TypeSlot {grino::HINT_CAT_PARAM, grino::TYPE_NIL,
|
||||||
|
grino::HINT_ANY},
|
||||||
grino::TypeSlot {grino::HINT_CAT_RETURN, grino::TYPE_NIL}
|
grino::TypeSlot {grino::HINT_CAT_RETURN, grino::TYPE_NIL}
|
||||||
}}));
|
}}));
|
||||||
|
|
||||||
loader.add_native("assert=", [](auto args){
|
loader.add_native("assert=", [loc](auto args){
|
||||||
auto lhs = args.front();
|
auto lhs = args.front();
|
||||||
|
|
||||||
for (size_t i=1; i<args.size(); i++)
|
for (size_t i=1; i<args.size(); i++)
|
||||||
|
@ -689,7 +728,13 @@ extern "C" void lib_assert(grino::Loader& loader)
|
||||||
}
|
}
|
||||||
|
|
||||||
return grino::Value::make_bool(args.front()->loc(), true);
|
return grino::Value::make_bool(args.front()->loc(), true);
|
||||||
});
|
}, std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot> {{
|
||||||
|
grino::TypeSlot {grino::HINT_CAT_PARAM, grino::TYPE_NIL,
|
||||||
|
grino::HINT_ANY},
|
||||||
|
grino::TypeSlot {grino::HINT_CAT_PARAM, grino::TYPE_NIL,
|
||||||
|
grino::HINT_SAME},
|
||||||
|
grino::TypeSlot {grino::HINT_CAT_RETURN, grino::TYPE_NIL}
|
||||||
|
}}));
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void lib_string(grino::Loader& loader)
|
extern "C" void lib_string(grino::Loader& loader)
|
||||||
|
@ -705,18 +750,28 @@ extern "C" void lib_string(grino::Loader& loader)
|
||||||
}
|
}
|
||||||
|
|
||||||
return grino::Value::make_string(args[0]->loc(), result);
|
return grino::Value::make_string(args[0]->loc(), result);
|
||||||
});
|
}, std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot> {
|
||||||
|
{grino::TypeSlot {grino::HINT_CAT_PARAM, grino::TYPE_STRING}},
|
||||||
|
{grino::TypeSlot {grino::HINT_CAT_PARAM, grino::TYPE_INT}},
|
||||||
|
{grino::TypeSlot {grino::HINT_CAT_RETURN, grino::TYPE_STRING}}
|
||||||
|
}));
|
||||||
|
|
||||||
loader.add_native("cat", [](auto args) {
|
loader.add_native("cat", [](auto args) {
|
||||||
std::string result;
|
std::string result;
|
||||||
|
|
||||||
for (auto arg: args)
|
for (auto arg: args)
|
||||||
|
{
|
||||||
|
if (arg->type() == grino::TYPE_STRING)
|
||||||
{
|
{
|
||||||
result += arg->as_string();
|
result += arg->as_string();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return grino::Value::make_string(args[0]->loc(), result);
|
return grino::Value::make_string(args[0]->loc(), result);
|
||||||
});
|
}, std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot> {
|
||||||
|
{grino::TypeSlot {grino::HINT_CAT_VARIADIC_PARAM, grino::TYPE_STRING}},
|
||||||
|
{grino::TypeSlot {grino::HINT_CAT_RETURN, grino::TYPE_STRING}}
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void lib(grino::Loader& loader)
|
extern "C" void lib(grino::Loader& loader)
|
||||||
|
@ -745,7 +800,13 @@ extern "C" void lib(grino::Loader& loader)
|
||||||
std::cout << ss.str() << std::endl;
|
std::cout << ss.str() << std::endl;
|
||||||
|
|
||||||
return grino::Value::make_nil(args.back()->loc());
|
return grino::Value::make_nil(args.back()->loc());
|
||||||
});
|
}, std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot>{
|
||||||
|
{grino::TypeSlot {grino::HINT_CAT_VARIADIC_PARAM,
|
||||||
|
grino::TYPE_NIL,
|
||||||
|
grino::HINT_ANY}},
|
||||||
|
|
||||||
|
{grino::TypeSlot {grino::HINT_CAT_RETURN, grino::TYPE_NIL}}
|
||||||
|
}));
|
||||||
|
|
||||||
loader.add_static("set!", [](auto& compiler,
|
loader.add_static("set!", [](auto& compiler,
|
||||||
auto node,
|
auto node,
|
||||||
|
|
|
@ -11,7 +11,11 @@ extern "C" void lib_io(grino::Loader& loader)
|
||||||
std::cout << arg->string();
|
std::cout << arg->string();
|
||||||
}
|
}
|
||||||
return grino::Value::make_nil(grino::Loc {"io"});
|
return grino::Value::make_nil(grino::Loc {"io"});
|
||||||
});
|
}, std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot>{
|
||||||
|
grino::TypeSlot {grino::HINT_CAT_VARIADIC_PARAM, grino::TYPE_NIL,
|
||||||
|
grino::HINT_ANY},
|
||||||
|
grino::TypeSlot {grino::HINT_CAT_RETURN, grino::TYPE_NIL, grino::HINT_ANY},
|
||||||
|
}));
|
||||||
|
|
||||||
mod->loader()->add_native("println", [](auto args){
|
mod->loader()->add_native("println", [](auto args){
|
||||||
for (auto arg: args)
|
for (auto arg: args)
|
||||||
|
@ -20,12 +24,18 @@ extern "C" void lib_io(grino::Loader& loader)
|
||||||
}
|
}
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
return grino::Value::make_nil(grino::Loc {"io"});
|
return grino::Value::make_nil(grino::Loc {"io"});
|
||||||
});
|
}, std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot>{
|
||||||
|
grino::TypeSlot {grino::HINT_CAT_VARIADIC_PARAM, grino::TYPE_NIL,
|
||||||
|
grino::HINT_ANY},
|
||||||
|
grino::TypeSlot {grino::HINT_CAT_RETURN, grino::TYPE_NIL, grino::HINT_ANY},
|
||||||
|
}));
|
||||||
|
|
||||||
mod->loader()->add_native("read", [](auto args){
|
mod->loader()->add_native("read", [](auto args){
|
||||||
std::string value;
|
std::string value;
|
||||||
std::cin >> value;
|
std::cin >> value;
|
||||||
|
|
||||||
return grino::Value::make_string(grino::Loc {"io"}, value);
|
return grino::Value::make_string(grino::Loc {"io"}, value);
|
||||||
});
|
}, std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot>{
|
||||||
|
grino::TypeSlot {grino::HINT_CAT_RETURN, grino::TYPE_STRING},
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,9 @@ extern "C" void lib_rand(grino::Loader& loader)
|
||||||
std::uniform_real_distribution<float> urd(0.0f, 1.0f);
|
std::uniform_real_distribution<float> urd(0.0f, 1.0f);
|
||||||
|
|
||||||
return grino::Value::make_float(loc, urd(r));
|
return grino::Value::make_float(loc, urd(r));
|
||||||
});
|
}, std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot>{
|
||||||
|
grino::TypeSlot {grino::HINT_CAT_RETURN, grino::TYPE_FLOAT},
|
||||||
|
}));
|
||||||
|
|
||||||
mod->loader()->add_native("range", [loc](auto args){
|
mod->loader()->add_native("range", [loc](auto args){
|
||||||
std::mt19937 r;
|
std::mt19937 r;
|
||||||
|
@ -29,5 +31,9 @@ extern "C" void lib_rand(grino::Loader& loader)
|
||||||
std::uniform_int_distribution<int> dist(from, to);
|
std::uniform_int_distribution<int> dist(from, to);
|
||||||
|
|
||||||
return grino::Value::make_int(loc, dist(r));
|
return grino::Value::make_int(loc, dist(r));
|
||||||
});
|
}, std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot>{
|
||||||
|
grino::TypeSlot {grino::HINT_CAT_PARAM, grino::TYPE_INT},
|
||||||
|
grino::TypeSlot {grino::HINT_CAT_PARAM, grino::TYPE_INT},
|
||||||
|
grino::TypeSlot {grino::HINT_CAT_RETURN, grino::TYPE_INT},
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,14 @@ namespace grino
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto entry = sym.find_no_scope(name);
|
auto entry = sym.find_no_scope(name);
|
||||||
|
|
||||||
|
if (!entry)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "cannot import unknown module '" << name << "'";
|
||||||
|
m_logger.log<compile_error>(LOG_ERROR, node->loc(), ss.str());
|
||||||
|
}
|
||||||
|
|
||||||
assert(entry);
|
assert(entry);
|
||||||
assert(entry->is_object);
|
assert(entry->is_object);
|
||||||
|
|
||||||
|
|
|
@ -93,15 +93,6 @@ namespace grino
|
||||||
return mod;
|
return mod;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Loader::add_native(std::string const& name, native_t native)
|
|
||||||
{
|
|
||||||
size_t addr = m_vm.heap_size();
|
|
||||||
grino::Loc loc {"natives/" + name, 0};
|
|
||||||
|
|
||||||
m_vm.set_heap(addr, grino::Value::make_native_function(loc, native));
|
|
||||||
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,8 +26,6 @@ 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_native(std::string const& name, native_t native);
|
|
||||||
|
|
||||||
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);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "StaticPass.hpp"
|
#include "StaticPass.hpp"
|
||||||
#include "src/Prototype.hpp"
|
#include "src/Prototype.hpp"
|
||||||
#include "StaticFunction.hpp"
|
#include "StaticFunction.hpp"
|
||||||
|
#include "src/types.hpp"
|
||||||
|
|
||||||
namespace grino
|
namespace grino
|
||||||
{
|
{
|
||||||
|
@ -17,18 +18,19 @@ namespace grino
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeType StaticPass::check(std::shared_ptr<Node> node)
|
TypeSlot StaticPass::check(std::shared_ptr<Node> node)
|
||||||
{
|
{
|
||||||
switch (node->type())
|
switch (node->type())
|
||||||
{
|
{
|
||||||
case NODE_ARRAY:
|
|
||||||
case NODE_BLOCK: {
|
case NODE_BLOCK: {
|
||||||
|
TypeSlot res;
|
||||||
|
|
||||||
for (size_t i=0; i<node->size(); i++)
|
for (size_t i=0; i<node->size(); i++)
|
||||||
{
|
{
|
||||||
check(node->child(i).lock());
|
res = check(node->child(i).lock());
|
||||||
}
|
}
|
||||||
|
|
||||||
return TYPE_NIL;
|
return res;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case NODE_MODULE: {
|
case NODE_MODULE: {
|
||||||
|
@ -37,23 +39,31 @@ namespace grino
|
||||||
check(node->child(i).lock());
|
check(node->child(i).lock());
|
||||||
}
|
}
|
||||||
|
|
||||||
return TYPE_MODULE;
|
return TypeSlot{HINT_CAT_RETURN, TYPE_MODULE};
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case NODE_NS: {
|
||||||
|
return TypeSlot{HINT_CAT_RETURN, TYPE_NIL, HINT_ANY};
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case NODE_ARRAY: {
|
||||||
|
return TypeSlot{HINT_CAT_RETURN, TYPE_ARRAY};
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case NODE_INT: {
|
case NODE_INT: {
|
||||||
return TYPE_INT;
|
return TypeSlot{HINT_CAT_RETURN, TYPE_INT};
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case NODE_FLOAT: {
|
case NODE_FLOAT: {
|
||||||
return TYPE_FLOAT;
|
return TypeSlot{HINT_CAT_RETURN, TYPE_FLOAT};
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case NODE_BOOL: {
|
case NODE_BOOL: {
|
||||||
return TYPE_BOOL;
|
return TypeSlot{HINT_CAT_RETURN, TYPE_BOOL};
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case NODE_STRING: {
|
case NODE_STRING: {
|
||||||
return TYPE_STRING;
|
return TypeSlot{HINT_CAT_RETURN, TYPE_STRING};
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case NODE_IDENT: {
|
case NODE_IDENT: {
|
||||||
|
@ -62,11 +72,11 @@ namespace grino
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case NODE_LAMBDA: {
|
case NODE_LAMBDA: {
|
||||||
return TYPE_FUNCTION;
|
return TypeSlot{HINT_CAT_RETURN, TYPE_FUNCTION};
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case NODE_IMPORT: {
|
case NODE_IMPORT: {
|
||||||
return TYPE_MODULE;
|
return TypeSlot{HINT_CAT_RETURN, TYPE_MODULE};
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case NODE_VARDECL: {
|
case NODE_VARDECL: {
|
||||||
|
@ -105,14 +115,20 @@ namespace grino
|
||||||
{
|
{
|
||||||
auto param_ty = check(node->child(i).lock());
|
auto param_ty = check(node->child(i).lock());
|
||||||
|
|
||||||
if (param_ty != ty
|
if (param_ty.hint == HINT_ANY)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (param_ty.type != ty
|
||||||
|
&& param_ty.hint != HINT_ANY
|
||||||
&& var_params.back().hint != HINT_ANY)
|
&& var_params.back().hint != HINT_ANY)
|
||||||
{
|
{
|
||||||
error(ty, param_ty, node->loc());
|
error(ty, param_ty.type, node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return rets[0].type;
|
return TypeSlot {HINT_CAT_RETURN, rets[0].type, rets[0].hint};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params.size() != node->size() - 1)
|
if (params.size() != node->size() - 1)
|
||||||
|
@ -128,35 +144,41 @@ namespace grino
|
||||||
.log<static_error>(LOG_ERROR, node->loc(), ss.str());
|
.log<static_error>(LOG_ERROR, node->loc(), ss.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<TypeType> ty;
|
std::vector<TypeSlot> ty;
|
||||||
|
|
||||||
for (size_t i=1; i<node->size(); i++)
|
for (size_t i=1; i<node->size(); i++)
|
||||||
{
|
{
|
||||||
TypeType param_ty = check(node->child(i).lock());
|
auto param_ty = check(node->child(i).lock());
|
||||||
ty.push_back(param_ty);
|
ty.push_back(param_ty);
|
||||||
|
|
||||||
if (proto->hint(i - 1) == HINT_ANY)
|
if (proto->hint(i - 1) == HINT_ANY
|
||||||
|
|| param_ty.hint == HINT_ANY)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool same_err = (i > 1 && proto->hint(i - 1) == HINT_SAME)
|
bool same_err = (i > 1 && proto->hint(i - 1) == HINT_SAME)
|
||||||
&& ty.back() != ty.at(ty.size() - 2);
|
&& ty.back().type != ty.at(ty.size() - 2).type;
|
||||||
|
|
||||||
|
if (same_err)
|
||||||
|
{
|
||||||
|
error(ty.at(ty.size() - 2).type, ty.back().type, node);
|
||||||
|
}
|
||||||
|
|
||||||
bool normal_err = proto->hint(i - 1) == HINT_NONE
|
bool normal_err = proto->hint(i - 1) == HINT_NONE
|
||||||
&& param_ty != proto->type(i - 1);
|
&& param_ty.type != proto->type(i - 1);
|
||||||
|
|
||||||
if (same_err || normal_err)
|
if (normal_err)
|
||||||
{
|
{
|
||||||
error(proto->type(i - 1), param_ty, node->loc());
|
error(proto->type(i - 1), param_ty.type, node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(rets.size() > 0);
|
assert(rets.size() > 0);
|
||||||
return rets[0].type;
|
return TypeSlot { HINT_CAT_RETURN, rets[0].type, rets[0].hint};
|
||||||
}
|
}
|
||||||
|
|
||||||
return TYPE_NIL;
|
return TypeSlot{HINT_CAT_RETURN, TYPE_NIL, HINT_ANY};
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -168,16 +190,19 @@ namespace grino
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
void StaticPass::error(TypeType lhs, TypeType rhs, Loc const& loc)
|
void StaticPass::error(TypeType lhs, TypeType rhs,
|
||||||
|
std::shared_ptr<Node> node)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "type mismatch, expected '"
|
ss << "type mismatch in '"
|
||||||
|
<< GRINO_TRIM(NodeTypeStr[node->type()], "NODE_")
|
||||||
|
<< "', expected '"
|
||||||
<< GRINO_TRIM(TypeTypeStr[lhs], "TYPE_")
|
<< GRINO_TRIM(TypeTypeStr[lhs], "TYPE_")
|
||||||
<< "', got '"
|
<< "', got '"
|
||||||
<< GRINO_TRIM(TypeTypeStr[rhs], "TYPE_")
|
<< GRINO_TRIM(TypeTypeStr[rhs], "TYPE_")
|
||||||
<< "'";
|
<< "'";
|
||||||
|
|
||||||
m_logger
|
m_logger
|
||||||
.log<static_error>(LOG_ERROR, loc, ss.str());
|
.log<static_error>(LOG_ERROR, node->loc(), ss.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,15 +17,15 @@ namespace grino
|
||||||
explicit StaticPass(Logger& logger, Compiler& compiler, SymTable& sym);
|
explicit StaticPass(Logger& logger, Compiler& compiler, SymTable& sym);
|
||||||
virtual ~StaticPass();
|
virtual ~StaticPass();
|
||||||
|
|
||||||
TypeType check(std::shared_ptr<Node> node);
|
TypeSlot check(std::shared_ptr<Node> node);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Logger& m_logger;
|
Logger& m_logger;
|
||||||
Compiler& m_compiler;
|
Compiler& m_compiler;
|
||||||
SymTable& m_sym;
|
SymTable& m_sym;
|
||||||
std::unordered_map<std::string, TypeType> m_types;
|
std::unordered_map<std::string, TypeSlot> m_types;
|
||||||
|
|
||||||
void error(TypeType lhs, TypeType rhs, Loc const& loc);
|
void error(TypeType lhs, TypeType rhs, std::shared_ptr<Node> node);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue