Function call type checking and narrowing
This commit is contained in:
@@ -395,7 +395,7 @@ namespace Solstice {
|
||||
|
||||
}
|
||||
|
||||
void TypeChecker::checkFunctionCallNodeType(Node& node) {
|
||||
void TypeChecker::narrowFunctionCallNode(Node& node) {
|
||||
// get function
|
||||
auto name = node.children[0].getIdentifier();
|
||||
if (!name.has_value()) {
|
||||
@@ -408,23 +408,34 @@ namespace Solstice {
|
||||
|
||||
auto& function = functions[*name];
|
||||
|
||||
// get types we are calling with
|
||||
std::vector<Type> args;
|
||||
std::vector<PossibleType> args;
|
||||
|
||||
// narrow types based on function
|
||||
for (auto& child : node.children[1].children) {
|
||||
checkNodeType(child);
|
||||
auto childType = child.ptype.getOnlyType();
|
||||
if (!childType.has_value()) {
|
||||
throw std::runtime_error("cannot call function with ambiguous type");
|
||||
}
|
||||
args.push_back(*childType);
|
||||
args.push_back(child.ptype);
|
||||
}
|
||||
|
||||
// find argument type
|
||||
if (function.returnTypes.find(args) == function.returnTypes.end()) {
|
||||
throw std::runtime_error("no matching function call to " + *name);
|
||||
// get all possible combinations
|
||||
auto sets = doCartesianProductOnTypeSets(args);
|
||||
|
||||
bool found = false;
|
||||
for (const auto& set : sets) {
|
||||
if (function.returnTypes.find(set) != function.returnTypes.end()) {
|
||||
if (found) {
|
||||
throw std::runtime_error("conflicting function definitions");
|
||||
}
|
||||
found = true;
|
||||
node.ptype = {{function.returnTypes[set]}};
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
throw std::runtime_error("no matching overload found for function " + *name);
|
||||
}
|
||||
}
|
||||
|
||||
node.ptype = {{function.returnTypes[args]}};
|
||||
void TypeChecker::checkFunctionCallNodeType(Node& node) {
|
||||
narrowFunctionCallNode(node);
|
||||
}
|
||||
|
||||
void TypeChecker::checkSetNodeType(Node& node) {
|
||||
|
||||
Reference in New Issue
Block a user