This commit is contained in:
nub31
2025-10-23 12:14:10 +02:00
parent a16bb959d3
commit a9e4b86e78
9 changed files with 601 additions and 26 deletions

View File

@@ -679,7 +679,7 @@ public sealed class TypeChecker
return new FuncCallNode(expression.Tokens, funcType.ReturnType, accessor, parameters);
}
private ExpressionNode CheckIdentifier(ExpressionSyntax expression, string moduleName, string name)
private ExpressionNode? CheckIdentifier(ExpressionSyntax expression, string moduleName, string name)
{
if (!_importedModules.TryGetValue(moduleName, out var module))
{
@@ -707,10 +707,7 @@ public sealed class TypeChecker
return new EnumReferenceIntermediateNode(expression.Tokens, moduleName, name);
}
throw new TypeCheckerException(Diagnostic
.Error($"No exported symbol {name} not found in module {moduleName}")
.At(expression)
.Build());
return null;
}
private ExpressionNode CheckLocalIdentifier(LocalIdentifierSyntax expression, NubType? _)
@@ -722,13 +719,31 @@ public sealed class TypeChecker
return new VariableIdentifierNode(expression.Tokens, scopeIdent.Type, expression.Name);
}
return CheckIdentifier(expression, Scope.Module, expression.Name);
var ident = CheckIdentifier(expression, Scope.Module, expression.Name);
if (ident == null)
{
throw new TypeCheckerException(Diagnostic
.Error($"There is no identifier named {expression.Name}")
.At(expression)
.Build());
}
return ident;
}
private ExpressionNode CheckModuleIdentifier(ModuleIdentifierSyntax expression, NubType? _)
{
// note(nub31): Unlike local identifiers, module identifiers does not look for local variables
return CheckIdentifier(expression, expression.Module, expression.Name);
var ident = CheckIdentifier(expression, expression.Module, expression.Name);
if (ident == null)
{
throw new TypeCheckerException(Diagnostic
.Error($"Module {expression.Module} does not export a member named {expression.Name}")
.At(expression)
.Build());
}
return ident;
}
private ExpressionNode CheckStringLiteral(StringLiteralSyntax expression, NubType? expectedType)
@@ -912,7 +927,14 @@ public sealed class TypeChecker
var statements = new List<StatementNode>();
foreach (var statement in node.Statements)
{
statements.Add(CheckStatement(statement));
try
{
statements.Add(CheckStatement(statement));
}
catch (TypeCheckerException e)
{
Diagnostics.Add(e.Diagnostic);
}
}
return new BlockNode(node.Tokens, statements);