ADD: more type checking.
parent
e12ff96943
commit
792ef70df9
21
lib/cast.hpp
21
lib/cast.hpp
|
@ -1,4 +1,5 @@
|
|||
#include "commons.hpp"
|
||||
#include "src/Prototype.hpp"
|
||||
|
||||
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){
|
||||
std::string value = args[0]->as_string();
|
||||
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){
|
||||
int value = args[0]->as_int();
|
||||
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){
|
||||
std::string value = args[0]->as_string();
|
||||
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){
|
||||
float value = args[0]->as_float();
|
||||
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);
|
||||
}, 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_NIL, grino::HINT_ANY},
|
||||
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},
|
||||
}));
|
||||
|
||||
|
@ -63,7 +63,11 @@ extern "C" void lib_collection(grino::Loader& loader)
|
|||
auto& array = array_val->as_array();
|
||||
|
||||
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){
|
||||
auto val = args[0];
|
||||
|
@ -78,7 +82,12 @@ extern "C" void lib_collection(grino::Loader& loader)
|
|||
auto& array = array_val->as_array();
|
||||
|
||||
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)
|
||||
|
@ -90,7 +99,13 @@ extern "C" void lib_array(grino::Loader& loader)
|
|||
auto& array = array_val->as_array();
|
||||
|
||||
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){
|
||||
auto ref_val = args[0];
|
||||
|
@ -109,7 +124,13 @@ extern "C" void lib_array(grino::Loader& loader)
|
|||
loader.vm().set_heap(addr, res);
|
||||
|
||||
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){
|
||||
auto ref_val = args[1];
|
||||
|
@ -124,7 +145,16 @@ extern "C" void lib_array(grino::Loader& loader)
|
|||
loader.vm().set_heap(addr, res);
|
||||
|
||||
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)
|
||||
|
@ -147,9 +177,13 @@ extern "C" void lib_flow_control(grino::Loader& loader)
|
|||
|
||||
prog.set_param(br, prog.size());
|
||||
}, 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_NONE},
|
||||
grino::HINT_ANY},
|
||||
}}));
|
||||
}
|
||||
|
||||
|
@ -311,7 +345,7 @@ extern "C" void lib_float(grino::Loader& loader)
|
|||
auto var_proto =
|
||||
std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot>{
|
||||
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){
|
||||
|
@ -463,8 +497,10 @@ extern "C" void lib_cmp(grino::Loader& loader)
|
|||
{
|
||||
auto var_proto =
|
||||
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},
|
||||
});
|
||||
|
||||
|
@ -647,6 +683,8 @@ extern "C" void lib_bool(grino::Loader& loader)
|
|||
|
||||
extern "C" void lib_assert(grino::Loader& loader)
|
||||
{
|
||||
grino::Loc loc {"core/assert"};
|
||||
|
||||
loader.add_native("assert", [](auto 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);
|
||||
}, 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}
|
||||
}}));
|
||||
|
||||
loader.add_native("assert=", [](auto args){
|
||||
loader.add_native("assert=", [loc](auto args){
|
||||
auto lhs = args.front();
|
||||
|
||||
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);
|
||||
});
|
||||
}, 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)
|
||||
|
@ -705,18 +750,28 @@ extern "C" void lib_string(grino::Loader& loader)
|
|||
}
|
||||
|
||||
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) {
|
||||
std::string result;
|
||||
|
||||
for (auto arg: args)
|
||||
{
|
||||
if (arg->type() == grino::TYPE_STRING)
|
||||
{
|
||||
result += arg->as_string();
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -745,7 +800,13 @@ extern "C" void lib(grino::Loader& loader)
|
|||
std::cout << ss.str() << std::endl;
|
||||
|
||||
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,
|
||||
auto node,
|
||||
|
|
|
@ -11,7 +11,11 @@ extern "C" void lib_io(grino::Loader& loader)
|
|||
std::cout << arg->string();
|
||||
}
|
||||
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){
|
||||
for (auto arg: args)
|
||||
|
@ -20,12 +24,18 @@ extern "C" void lib_io(grino::Loader& loader)
|
|||
}
|
||||
std::cout << std::endl;
|
||||
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){
|
||||
std::string value;
|
||||
std::cin >> 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);
|
||||
|
||||
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){
|
||||
std::mt19937 r;
|
||||
|
@ -29,5 +31,9 @@ extern "C" void lib_rand(grino::Loader& loader)
|
|||
std::uniform_int_distribution<int> dist(from, to);
|
||||
|
||||
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
|
||||
{
|
||||
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->is_object);
|
||||
|
||||
|
|
|
@ -93,15 +93,6 @@ namespace grino
|
|||
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,
|
||||
native_t native,
|
||||
std::shared_ptr<Prototype> prototype)
|
||||
|
|
|
@ -26,8 +26,6 @@ namespace grino
|
|||
void load_library(std::filesystem::path path);
|
||||
|
||||
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,
|
||||
native_t native,
|
||||
std::shared_ptr<Prototype> prototype);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "StaticPass.hpp"
|
||||
#include "src/Prototype.hpp"
|
||||
#include "StaticFunction.hpp"
|
||||
#include "src/types.hpp"
|
||||
|
||||
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())
|
||||
{
|
||||
case NODE_ARRAY:
|
||||
case NODE_BLOCK: {
|
||||
TypeSlot res;
|
||||
|
||||
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;
|
||||
|
||||
case NODE_MODULE: {
|
||||
|
@ -37,23 +39,31 @@ namespace grino
|
|||
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;
|
||||
|
||||
case NODE_INT: {
|
||||
return TYPE_INT;
|
||||
return TypeSlot{HINT_CAT_RETURN, TYPE_INT};
|
||||
} break;
|
||||
|
||||
case NODE_FLOAT: {
|
||||
return TYPE_FLOAT;
|
||||
return TypeSlot{HINT_CAT_RETURN, TYPE_FLOAT};
|
||||
} break;
|
||||
|
||||
case NODE_BOOL: {
|
||||
return TYPE_BOOL;
|
||||
return TypeSlot{HINT_CAT_RETURN, TYPE_BOOL};
|
||||
} break;
|
||||
|
||||
case NODE_STRING: {
|
||||
return TYPE_STRING;
|
||||
return TypeSlot{HINT_CAT_RETURN, TYPE_STRING};
|
||||
} break;
|
||||
|
||||
case NODE_IDENT: {
|
||||
|
@ -62,11 +72,11 @@ namespace grino
|
|||
} break;
|
||||
|
||||
case NODE_LAMBDA: {
|
||||
return TYPE_FUNCTION;
|
||||
return TypeSlot{HINT_CAT_RETURN, TYPE_FUNCTION};
|
||||
} break;
|
||||
|
||||
case NODE_IMPORT: {
|
||||
return TYPE_MODULE;
|
||||
return TypeSlot{HINT_CAT_RETURN, TYPE_MODULE};
|
||||
} break;
|
||||
|
||||
case NODE_VARDECL: {
|
||||
|
@ -105,14 +115,20 @@ namespace grino
|
|||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
|
@ -128,35 +144,41 @@ namespace grino
|
|||
.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++)
|
||||
{
|
||||
TypeType param_ty = check(node->child(i).lock());
|
||||
auto param_ty = check(node->child(i).lock());
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
&& 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);
|
||||
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;
|
||||
|
||||
default:
|
||||
|
@ -168,16 +190,19 @@ namespace grino
|
|||
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;
|
||||
ss << "type mismatch, expected '"
|
||||
ss << "type mismatch in '"
|
||||
<< GRINO_TRIM(NodeTypeStr[node->type()], "NODE_")
|
||||
<< "', expected '"
|
||||
<< GRINO_TRIM(TypeTypeStr[lhs], "TYPE_")
|
||||
<< "', got '"
|
||||
<< GRINO_TRIM(TypeTypeStr[rhs], "TYPE_")
|
||||
<< "'";
|
||||
|
||||
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);
|
||||
virtual ~StaticPass();
|
||||
|
||||
TypeType check(std::shared_ptr<Node> node);
|
||||
TypeSlot check(std::shared_ptr<Node> node);
|
||||
|
||||
private:
|
||||
Logger& m_logger;
|
||||
Compiler& m_compiler;
|
||||
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