#pragma once #include "type.hpp" #include "../parser/parser.hpp" #include #include namespace Solstice { enum class Narrowing { None, Left, Right, Both }; class TypeChecker { std::unordered_map variables; std::unordered_map types; std::unordered_map functions; std::unordered_map addOverloads; std::unordered_map subtractOverloads; std::unordered_map multiplyOverloads; std::unordered_map divideOverloads; std::unordered_map equalOverloads; std::unordered_map notEqualOverloads; std::unordered_map greaterThanOverloads; std::unordered_map lesserThanOverloads; Node* input; bool inFunction = false; void initOverloads(); void checkLiteralNodeType(Node& node); void checkIdentifierNodeType(Node& node); void checkTupleNodeType(Node& node); void checkBindNodeType(Node& node); void checkFunctionBindNodeType(Node& node); void checkSetNodeType(Node& node); void checkCodeBlockType(Node& node); Narrowing doesNodeChildrenNeedNarrowing(Node& node); void narrowBinaryNode(Node& node, std::unordered_map& overloads); void narrowFunctionCallNode(Node& node); void checkAddType(Node& node); void checkSubtractType(Node& node); void checkMultiplyType(Node& node); void checkDivideType(Node& node); void checkEqualType(Node& node); void checkNotEqualType(Node& node); void checkGreaterThanType(Node& node); void checkLesserThanType(Node& node); void checkNodeType(Node& node); public: TypeChecker() = delete; TypeChecker(Node& node) : input(&node) { initOverloads(); } void setNode(Node& node) { input = &node; } // Only for use as a public function. void setVariable(const std::string& name, const Type& type) { variables[name] = {{type}}; } void setVariableUnknown(const std::string& name) { variables[name].unknownType = true; } void checkTypes(); const Function* getFunction(const std::string& name) const { auto it = functions.find(name); if (it == functions.end()) { return nullptr; } return &it->second; } }; }