Files
newsolstice/src/typechecker/typechecker.hpp

97 lines
2.7 KiB
C++
Raw Normal View History

2026-08-01 22:12:05 +10:00
#pragma once
#include "type.hpp"
#include "../parser/parser.hpp"
#include <string>
#include <unordered_map>
namespace Solstice {
2026-08-02 18:03:31 +10:00
enum class Narrowing {
None,
Left,
Right,
Both
};
2026-08-01 22:12:05 +10:00
class TypeChecker {
2026-08-02 15:14:43 +10:00
std::unordered_map<std::string, PossibleType> variables;
2026-08-01 22:12:05 +10:00
std::unordered_map<std::string, Type> types;
2026-08-03 08:15:48 +10:00
std::unordered_map<std::string, Function> functions;
2026-08-01 22:12:05 +10:00
std::unordered_map<TypePair, Type> addOverloads;
std::unordered_map<TypePair, Type> subtractOverloads;
std::unordered_map<TypePair, Type> multiplyOverloads;
std::unordered_map<TypePair, Type> divideOverloads;
std::unordered_map<TypePair, Type> equalOverloads;
std::unordered_map<TypePair, Type> notEqualOverloads;
std::unordered_map<TypePair, Type> greaterThanOverloads;
std::unordered_map<TypePair, Type> lesserThanOverloads;
2026-08-02 15:14:43 +10:00
Node* input;
2026-08-01 22:12:05 +10:00
2026-08-02 14:09:38 +10:00
bool inFunction = false;
2026-08-01 22:12:05 +10:00
void initOverloads();
2026-08-02 08:59:18 +10:00
void checkLiteralNodeType(Node& node);
void checkIdentifierNodeType(Node& node);
void checkTupleNodeType(Node& node);
2026-08-02 14:09:38 +10:00
void checkBindNodeType(Node& node);
void checkFunctionBindNodeType(Node& node);
void checkSetNodeType(Node& node);
void checkCodeBlockType(Node& node);
2026-08-02 18:03:31 +10:00
Narrowing doesNodeChildrenNeedNarrowing(Node& node);
void narrowBinaryNode(Node& node, std::unordered_map<TypePair, Type>& overloads);
2026-08-03 20:03:54 +10:00
void narrowFunctionCallNode(Node& node);
2026-08-02 18:03:31 +10:00
void checkFunctionCallNodeType(Node& node);
2026-08-02 15:14:43 +10:00
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);
2026-08-02 08:59:18 +10:00
void checkNodeType(Node& node);
2026-08-01 22:12:05 +10:00
public:
TypeChecker() = delete;
2026-08-02 15:14:43 +10:00
TypeChecker(Node& node) : input(&node) {
2026-08-01 22:12:05 +10:00
initOverloads();
}
2026-08-02 15:14:43 +10:00
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;
}
2026-08-01 22:12:05 +10:00
void checkTypes();
2026-08-03 08:15:48 +10:00
const Function* getFunction(const std::string& name) const {
auto it = functions.find(name);
if (it == functions.end()) {
return nullptr;
}
return &it->second;
}
2026-08-01 22:12:05 +10:00
};
}