diff --git a/src/typechecker/typechecker.cpp b/src/typechecker/typechecker.cpp index 16a820e..2f9db90 100644 --- a/src/typechecker/typechecker.cpp +++ b/src/typechecker/typechecker.cpp @@ -395,8 +395,36 @@ namespace Solstice { } - void TypeChecker::narrowFunctionCallNode(Node& node) { - + void TypeChecker::checkFunctionCallNodeType(Node& node) { + // get function + auto name = node.children[0].getIdentifier(); + if (!name.has_value()) { + throw std::runtime_error("identifier node does not contain identifier"); + } + + if (functions.find(*name) == functions.end()) { + throw std::runtime_error("unknown function " + *name); + } + + auto& function = functions[*name]; + + // get types we are calling with + std::vector args; + 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); + } + + // find argument type + 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::checkSetNodeType(Node& node) { @@ -562,6 +590,9 @@ namespace Solstice { case NodeType::LesserThan: checkLesserThanType(node); break; + case NodeType::FunctionCall: + checkFunctionCallNodeType(node); + break; } } diff --git a/src/typechecker/typechecker.hpp b/src/typechecker/typechecker.hpp index f94d1b9..df8ae19 100644 --- a/src/typechecker/typechecker.hpp +++ b/src/typechecker/typechecker.hpp @@ -49,6 +49,8 @@ namespace Solstice { void narrowBinaryNode(Node& node, std::unordered_map& overloads); void narrowFunctionCallNode(Node& node); + void checkFunctionCallNodeType(Node& node); + void checkAddType(Node& node); void checkSubtractType(Node& node); void checkMultiplyType(Node& node);