This commit is contained in:
nub31
2025-09-16 16:02:08 +02:00
parent 46432d2f8e
commit c9e34ae7e2
8 changed files with 130 additions and 36 deletions

View File

@@ -16,4 +16,6 @@ public record ContinueNode : StatementNode;
public record BreakNode : StatementNode;
public record WhileNode(ExpressionNode Condition, BlockNode Body) : StatementNode;
public record WhileNode(ExpressionNode Condition, BlockNode Body) : StatementNode;
public record ForArrayNode(ArrayTypeNode ArrayType, string ElementIdent, string? IndexIdent, ExpressionNode Target, BlockNode Body) : StatementNode;

View File

@@ -14,9 +14,6 @@ public sealed class TypeChecker
private readonly Stack<Scope> _scopes = [];
private readonly Stack<TypeNode> _funcReturnTypes = [];
private readonly List<Diagnostic> _diagnostics = [];
private readonly List<StructTypeNode> _referencedStructTypes = [];
private readonly List<DefinitionNode> _definitions = [];
private Scope Scope => _scopes.Peek();
@@ -29,27 +26,27 @@ public sealed class TypeChecker
.ToDictionary();
}
public List<DefinitionNode> Definitions => _definitions;
public List<Diagnostic> Diagnostics => _diagnostics;
public List<StructTypeNode> ReferencedStructTypes => _referencedStructTypes;
public List<DefinitionNode> Definitions { get; } = [];
public List<Diagnostic> Diagnostics { get; } = [];
public List<StructTypeNode> ReferencedStructTypes { get; } = [];
public void Check()
{
_scopes.Clear();
_funcReturnTypes.Clear();
_diagnostics.Clear();
_referencedStructTypes.Clear();
_definitions.Clear();
Diagnostics.Clear();
Definitions.Clear();
ReferencedStructTypes.Clear();
foreach (var definition in _syntaxTree.Definitions)
{
try
{
_definitions.Add(CheckDefinition(definition));
Definitions.Add(CheckDefinition(definition));
}
catch (TypeCheckerException e)
{
_diagnostics.Add(e.Diagnostic);
Diagnostics.Add(e.Diagnostic);
}
}
}
@@ -143,6 +140,7 @@ public sealed class TypeChecker
StatementExpressionSyntax statement => CheckStatementExpression(statement),
VariableDeclarationSyntax statement => CheckVariableDeclaration(statement),
WhileSyntax statement => CheckWhile(statement),
ForSyntax statement => CheckFor(statement),
_ => throw new ArgumentOutOfRangeException(nameof(node))
};
}
@@ -222,6 +220,31 @@ public sealed class TypeChecker
return new WhileNode(condition, body);
}
private StatementNode CheckFor(ForSyntax statement)
{
var target = CheckExpression(statement.Target);
switch (target.Type)
{
case ArrayTypeNode arrayType:
{
var scope = Scope.SubScope();
scope.Declare(new Identifier(statement.ElementIdent, arrayType.ElementType, IdentifierKind.FunctionParameter));
if (statement.IndexIdent != null)
{
scope.Declare(new Identifier(statement.ElementIdent, new IntTypeNode(true, 64), IdentifierKind.FunctionParameter));
}
var body = CheckBlock(statement.Body, scope);
return new ForArrayNode(arrayType, statement.ElementIdent, statement.IndexIdent, target, body);
}
default:
{
throw new TypeCheckerException(Diagnostic.Error($"Type {target.Type} is not an iterable target").Build());
}
}
}
private FuncSignatureNode CheckFuncSignature(FuncSignatureSyntax statement)
{
var parameters = new List<FuncParameterNode>();
@@ -659,7 +682,7 @@ public sealed class TypeChecker
var typeField = structType.Fields.FirstOrDefault(x => x.Name == initializer.Key);
if (typeField == null)
{
_diagnostics.AddRange(Diagnostic
Diagnostics.AddRange(Diagnostic
.Error($"Struct {structType.Name} does not have a field named {initializer.Key}")
.At(initializer.Value)
.Build());
@@ -764,7 +787,7 @@ public sealed class TypeChecker
result.Functions.Add(new StructTypeFunc(function.Name, type));
}
_referencedStructTypes.Add(result);
ReferencedStructTypes.Add(result);
return result;
}