...
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user