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
|
// get function
|
||||||
auto name = node.children[0].getIdentifier();
|
auto name = node.children[0].getIdentifier();
|
||||||
if (!name.has_value()) {
|
if (!name.has_value()) {
|
||||||
@@ -408,23 +408,34 @@ namespace Solstice {
|
|||||||
|
|
||||||
auto& function = functions[*name];
|
auto& function = functions[*name];
|
||||||
|
|
||||||
// get types we are calling with
|
std::vector<PossibleType> args;
|
||||||
std::vector<Type> args;
|
|
||||||
|
// narrow types based on function
|
||||||
for (auto& child : node.children[1].children) {
|
for (auto& child : node.children[1].children) {
|
||||||
checkNodeType(child);
|
checkNodeType(child);
|
||||||
auto childType = child.ptype.getOnlyType();
|
args.push_back(child.ptype);
|
||||||
if (!childType.has_value()) {
|
}
|
||||||
throw std::runtime_error("cannot call function with ambiguous type");
|
|
||||||
|
// 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]}};
|
||||||
}
|
}
|
||||||
args.push_back(*childType);
|
|
||||||
}
|
}
|
||||||
|
if (!found) {
|
||||||
// find argument type
|
throw std::runtime_error("no matching overload found for function " + *name);
|
||||||
if (function.returnTypes.find(args) == function.returnTypes.end()) {
|
|
||||||
throw std::runtime_error("no matching function call to " + *name);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
node.ptype = {{function.returnTypes[args]}};
|
void TypeChecker::checkFunctionCallNodeType(Node& node) {
|
||||||
|
narrowFunctionCallNode(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeChecker::checkSetNodeType(Node& node) {
|
void TypeChecker::checkSetNodeType(Node& node) {
|
||||||
|
|||||||
Reference in New Issue
Block a user