A bunch more stuffs

This commit is contained in:
2026-08-02 14:09:38 +10:00
parent 437260438c
commit 16846d13bb
7 changed files with 187 additions and 7 deletions

View File

@@ -1,6 +1,7 @@
#include "typechecker.hpp"
#include "type.hpp"
#include <stdexcept>
#include <iostream>
namespace Solstice {
@@ -107,21 +108,84 @@ namespace Solstice {
throw std::runtime_error("unknown variable " + *identifier);
}
node.ptype = variables[*identifier];
node.ptype = {{variables[*identifier]}};
}
void TypeChecker::checkTupleNodeType(Node& node) {
for (auto& child : node.children) {
checkNodeType(child);
}
// TODO implemnt tuple type checking
}
void TypeChecker::checkBindNodeType(Node& node) {
auto id = node.children[0].getIdentifier();
if (!id.has_value()) {
throw std::runtime_error("FIXME identifier node does not contain identifier");
}
if (variables.find(*id) != variables.end()) {
throw std::runtime_error("Cannot overwrite existing bind/variable/function with new bind");
}
checkNodeType(node.children[1]);
auto nodeType = node.children[1].ptype.getOnlyType();
if (!nodeType.has_value()) {
throw std::runtime_error("cannot assign ambiguous type to name");
}
variables[*id] = *nodeType;
variables[*id].isConstant = true;
}
void TypeChecker::checkFunctionBindNodeType(Node& node) {
auto id = node.children[0].getIdentifier();
if (!id.has_value()) {
throw std::runtime_error("FIXME identifier node does not contain identifier");
}
if (variables.find(*id) != variables.end()) {
throw std::runtime_error("Cannot overwrite existing bind/variable/function with new function");
}
checkNodeType(node.children[1]);
auto nodeType = node.children[1].ptype.getOnlyType();
if (!nodeType.has_value()) {
throw std::runtime_error("cannot assign ambiguous type to name");
}
variables[*id] = *nodeType;
variables[*id].isConstant = true;
}
void TypeChecker::checkSetNodeType(Node& node) {
auto id = node.children[0].getIdentifier();
if (!id.has_value()) {
throw std::runtime_error("FIXME identifier node does not contain identifier");
}
if (variables.find(*id) != variables.end()) {
if (variables[*id].isConstant) {
throw std::runtime_error("cannot reassign existing bind");
}
}
if (!inFunction) {
throw std::runtime_error("mutable variables may only be used in functions");
}
checkNodeType(node.children[1]);
auto nodeType = node.children[1].ptype.getOnlyType();
if (!nodeType.has_value()) {
throw std::runtime_error("cannot assign ambiguous type to name");
}
variables[*id] = *nodeType;
}
void TypeChecker::checkCodeBlockType(Node& node) {}
void TypeChecker::checkNodeType(Node& node) {
switch (node.type) {
case NodeType::Root:
node.ptype = {{}}; // no possible types for root node
for (auto& child : node.children) {
checkNodeType(child);
}
break;
case NodeType::Literal:
checkLiteralNodeType(node);
@@ -135,6 +199,19 @@ namespace Solstice {
case NodeType::Tuple:
checkTupleNodeType(node);
break;
case NodeType::Bind:
checkBindNodeType(node);
break;
case NodeType::FunctionBind:
checkFunctionBindNodeType(node);
break;
case NodeType::Set:
checkSetNodeType(node);
break;
case NodeType::CodeBlock:
checkCodeBlockType(node);
break;
}
}