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