2023-08-30 18:06:26 +00:00
|
|
|
#include "TypeResolver.hpp"
|
2023-09-01 20:38:12 +00:00
|
|
|
#include "FunTy.hpp"
|
2023-08-30 18:06:26 +00:00
|
|
|
|
|
|
|
namespace roza
|
|
|
|
{
|
|
|
|
/*explicit*/ TypeResolver::TypeResolver(StatusLog& log)
|
|
|
|
: m_log { log }
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
/*virtual*/ TypeResolver::~TypeResolver()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2023-08-31 19:25:00 +00:00
|
|
|
std::shared_ptr<Type> TypeResolver::find(std::shared_ptr<Node> root,
|
|
|
|
SymTable const& sym)
|
2023-08-30 18:06:26 +00:00
|
|
|
{
|
|
|
|
switch (root->type())
|
|
|
|
{
|
2023-08-30 22:31:19 +00:00
|
|
|
case NODE_PROG: {
|
2023-08-31 19:25:00 +00:00
|
|
|
return find(root->child(root->size() - 1), sym);
|
|
|
|
} break;
|
|
|
|
|
2023-09-01 20:38:12 +00:00
|
|
|
case NODE_CALL: {
|
|
|
|
auto fun = sym.find(root->child(0)->repr()).node;
|
|
|
|
return find(fun->child(1), sym);
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case NODE_RET: {
|
|
|
|
return find(root->child(0), sym);
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case NODE_FUN: {
|
|
|
|
auto params = root->child(0);
|
|
|
|
auto ret = root->child(1);
|
|
|
|
auto ty = std::make_shared<FunTy>();
|
|
|
|
|
|
|
|
for (size_t i=0; i<params->size(); i++)
|
|
|
|
{
|
|
|
|
ty->add_input(find(params->child(i)->child(1), sym));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ret->size() > 0)
|
|
|
|
{
|
|
|
|
ty->set_output(find(ret->child(0), sym));
|
|
|
|
}
|
|
|
|
|
|
|
|
return ty;
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case NODE_TYPE: {
|
|
|
|
if (root->repr() == "nil") { return std::make_shared<Type>(TY_NIL); }
|
|
|
|
if (root->repr() == "int") { return std::make_shared<Type>(TY_INT); }
|
|
|
|
if (root->repr() == "bool") { return std::make_shared<Type>(TY_BOOL); }
|
|
|
|
|
|
|
|
if (root->repr() == "fun")
|
|
|
|
{
|
|
|
|
auto ty = std::make_shared<FunTy>();
|
|
|
|
|
|
|
|
if (root->size() > 0)
|
|
|
|
{
|
|
|
|
for (size_t i=0; i<root->size() - 1; i++)
|
|
|
|
{
|
|
|
|
ty->add_input(find(root->child(i), sym));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (root->size() > 0)
|
|
|
|
{
|
|
|
|
ty->set_output(find(root->child(root->size()-1), sym));
|
|
|
|
}
|
|
|
|
|
|
|
|
return ty;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_log.fatal(root->loc(), "cannot find type of '" + root->repr() + "'");
|
|
|
|
} break;
|
|
|
|
|
2023-08-31 19:25:00 +00:00
|
|
|
case NODE_IDENT: {
|
|
|
|
std::string name = root->repr();
|
|
|
|
SymEntry const& entry = sym.find(name);
|
|
|
|
return find(entry.node, sym);
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case NODE_CONSTDECL:
|
|
|
|
case NODE_VARDECL: {
|
|
|
|
auto ty = find(root->child(1), sym);
|
2023-08-30 18:06:26 +00:00
|
|
|
} break;
|
|
|
|
|
|
|
|
case NODE_INT: {
|
|
|
|
return std::make_shared<Type>(BaseType::TY_INT);
|
|
|
|
} break;
|
|
|
|
|
2023-08-31 09:37:13 +00:00
|
|
|
case NODE_EQ:
|
|
|
|
case NODE_NE:
|
|
|
|
case NODE_LT:
|
|
|
|
case NODE_LE:
|
|
|
|
case NODE_GT:
|
|
|
|
case NODE_GE:
|
2023-08-31 09:07:03 +00:00
|
|
|
case NODE_IMP:
|
|
|
|
case NODE_AND:
|
|
|
|
case NODE_OR:
|
|
|
|
case NODE_NOT:
|
|
|
|
case NODE_BOOL: {
|
|
|
|
return std::make_shared<Type>(BaseType::TY_BOOL);
|
|
|
|
} break;
|
|
|
|
|
2023-08-30 22:31:19 +00:00
|
|
|
case NODE_ADD:
|
|
|
|
case NODE_SUB:
|
|
|
|
case NODE_MUL:
|
|
|
|
case NODE_DIV:
|
|
|
|
case NODE_MOD:
|
|
|
|
case NODE_POW:
|
|
|
|
case NODE_UADD:
|
|
|
|
case NODE_USUB:{
|
2023-08-31 19:25:00 +00:00
|
|
|
return find(root->child(0), sym);
|
2023-08-30 22:31:19 +00:00
|
|
|
} break;
|
|
|
|
|
2023-08-30 18:06:26 +00:00
|
|
|
default:
|
|
|
|
m_log.fatal(root->loc(), "cannot find type of node '" + root->string() + "'");
|
|
|
|
}
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
}
|