This commit is contained in:
nub31
2026-02-09 20:49:09 +01:00
parent 96670b1201
commit ab9bd6fd05
9 changed files with 300 additions and 176 deletions

View File

@@ -1,13 +1,13 @@
namespace Compiler;
public sealed class TypeChecker(string fileName, NodeDefinitionFunc function, TypeResolver typeResolver)
public sealed class TypeChecker(string fileName, NodeDefinitionFunc function, ModuleGraph moduleGraph)
{
public static TypedNodeDefinitionFunc? CheckFunction(string fileName, NodeDefinitionFunc function, TypeResolver typeResolver, out List<Diagnostic> diagnostics)
public static TypedNodeDefinitionFunc? CheckFunction(string fileName, NodeDefinitionFunc function, ModuleGraph moduleGraph, out List<Diagnostic> diagnostics)
{
return new TypeChecker(fileName, function, typeResolver).CheckFunction(out diagnostics);
return new TypeChecker(fileName, function, moduleGraph).CheckFunction(out diagnostics);
}
private Scope scope = new(null);
private readonly Scope scope = new(null);
private TypedNodeDefinitionFunc? CheckFunction(out List<Diagnostic> diagnostics)
{
@@ -42,7 +42,7 @@ public sealed class TypeChecker(string fileName, NodeDefinitionFunc function, Ty
try
{
returnType = typeResolver.Resolve(function.ReturnType);
returnType = ResolveType(function.ReturnType);
}
catch (CompileException e)
{
@@ -57,7 +57,7 @@ public sealed class TypeChecker(string fileName, NodeDefinitionFunc function, Ty
private TypedNodeDefinitionFunc.Param CheckDefinitionFuncParameter(NodeDefinitionFunc.Param node)
{
return new TypedNodeDefinitionFunc.Param(node.Tokens, node.Name, typeResolver.Resolve(node.Type));
return new TypedNodeDefinitionFunc.Param(node.Tokens, node.Name, ResolveType(node.Type));
}
private TypedNodeStatement CheckStatement(NodeStatement node)
@@ -102,7 +102,7 @@ public sealed class TypeChecker(string fileName, NodeDefinitionFunc function, Ty
private TypedNodeStatementVariableDeclaration CheckStatementVariableDeclaration(NodeStatementVariableDeclaration statement)
{
var type = typeResolver.Resolve(statement.Type);
var type = ResolveType(statement.Type);
var value = CheckExpression(statement.Value);
if (type != value.Type)
@@ -125,7 +125,8 @@ public sealed class TypeChecker(string fileName, NodeDefinitionFunc function, Ty
NodeExpressionBinary expression => CheckExpressionBinary(expression),
NodeExpressionUnary expression => CheckExpressionUnary(expression),
NodeExpressionBoolLiteral expression => CheckExpressionBoolLiteral(expression),
NodeExpressionIdent expression => CheckExpressionIdent(expression),
NodeExpressionLocalIdent expression => CheckExpressionIdent(expression),
NodeExpressionModuleIdent expression => CheckExpressionModuleIdent(expression),
NodeExpressionIntLiteral expression => CheckExpressionIntLiteral(expression),
NodeExpressionMemberAccess expression => CheckExpressionMemberAccess(expression),
NodeExpressionStringLiteral expression => CheckExpressionStringLiteral(expression),
@@ -272,13 +273,19 @@ public sealed class TypeChecker(string fileName, NodeDefinitionFunc function, Ty
return new TypedNodeExpressionBoolLiteral(expression.Tokens, new NubTypeBool(), expression.Value);
}
private TypedNodeExpressionIdent CheckExpressionIdent(NodeExpressionIdent expression)
private TypedNodeExpressionLocalIdent CheckExpressionIdent(NodeExpressionLocalIdent expression)
{
var type = scope.GetIdentifierType(expression.Value.Ident);
if (type == null)
throw new CompileException(Diagnostic.Error($"Identifier '{expression.Value.Ident}' is not declared").At(fileName, expression.Value).Build());
return new TypedNodeExpressionIdent(expression.Tokens, type, expression.Value);
return new TypedNodeExpressionLocalIdent(expression.Tokens, type, expression.Value);
}
private TypedNodeExpressionModuleIdent CheckExpressionModuleIdent(NodeExpressionModuleIdent expression)
{
var identifierType = moduleGraph.ResolveIdentifier(expression.Module.Ident, expression.Value.Ident);
return new TypedNodeExpressionModuleIdent(expression.Tokens, identifierType, expression.Module, expression.Value);
}
private TypedNodeExpressionIntLiteral CheckExpressionIntLiteral(NodeExpressionIntLiteral expression)
@@ -306,7 +313,7 @@ public sealed class TypeChecker(string fileName, NodeDefinitionFunc function, Ty
private TypedNodeExpressionStructLiteral CheckExpressionStructLiteral(NodeExpressionStructLiteral expression)
{
var type = typeResolver.GetNamedStruct(expression.Module.Ident, expression.Name.Ident);
var type = moduleGraph.ResolveStruct(expression.Module.Ident, expression.Name.Ident);
if (type == null)
throw new CompileException(Diagnostic.Error($"Undeclared struct '{expression.Module.Ident}::{expression.Name.Ident}'").At(fileName, expression.Name).Build());
@@ -327,6 +334,22 @@ public sealed class TypeChecker(string fileName, NodeDefinitionFunc function, Ty
return new TypedNodeExpressionStructLiteral(expression.Tokens, type, initializers);
}
private NubType ResolveType(NodeType node)
{
return node switch
{
NodeTypeBool type => new NubTypeBool(),
NodeTypeCustom type => moduleGraph.ResolveStruct(type.Module.Ident, type.Name.Ident),
NodeTypeFunc type => new NubTypeFunc(type.Parameters.Select(ResolveType).ToList(), ResolveType(type.ReturnType)),
NodeTypePointer type => new NubTypePointer(ResolveType(type.To)),
NodeTypeSInt type => new NubTypeSInt(type.Width),
NodeTypeUInt type => new NubTypeUInt(type.Width),
NodeTypeString type => new NubTypeString(),
NodeTypeVoid type => new NubTypeVoid(),
_ => throw new ArgumentOutOfRangeException(nameof(node))
};
}
private class Scope(Scope? parent)
{
private readonly Dictionary<string, NubType> identifiers = new();
@@ -366,18 +389,6 @@ public sealed class TypedNodeDefinitionFunc(List<Token> tokens, TokenIdent name,
}
}
public sealed class TypedNodeDefinitionStruct(List<Token> tokens, TokenIdent name, List<TypedNodeDefinitionStruct.Field> fields) : TypedNodeDefinition(tokens)
{
public readonly TokenIdent Name = name;
public readonly List<Field> Fields = fields;
public sealed class Field(List<Token> tokens, TokenIdent name, NubType type) : TypedNode(tokens)
{
public readonly TokenIdent Name = name;
public readonly NubType Type = type;
}
}
public abstract class TypedNodeStatement(List<Token> tokens) : TypedNode(tokens);
public sealed class TypedNodeStatementBlock(List<Token> tokens, List<TypedNodeStatement> statements) : TypedNodeStatement(tokens)
@@ -459,11 +470,17 @@ public sealed class TypedNodeExpressionMemberAccess(List<Token> tokens, NubType
public readonly TokenIdent Name = name;
}
public sealed class TypedNodeExpressionIdent(List<Token> tokens, NubType type, TokenIdent value) : TypedNodeExpression(tokens, type)
public sealed class TypedNodeExpressionLocalIdent(List<Token> tokens, NubType type, TokenIdent value) : TypedNodeExpression(tokens, type)
{
public readonly TokenIdent Value = value;
}
public sealed class TypedNodeExpressionModuleIdent(List<Token> tokens, NubType type, TokenIdent module, TokenIdent value) : TypedNodeExpression(tokens, type)
{
public readonly TokenIdent Module = module;
public readonly TokenIdent Value = value;
}
public sealed class TypedNodeExpressionBinary(List<Token> tokens, NubType type, TypedNodeExpression left, TypedNodeExpressionBinary.Op operation, TypedNodeExpression right) : TypedNodeExpression(tokens, type)
{
public readonly TypedNodeExpression Left = left;