This commit is contained in:
nub31
2026-02-26 20:57:25 +01:00
parent 3323d760e8
commit b7dc77cb1c
3 changed files with 37 additions and 40 deletions

View File

@@ -301,13 +301,13 @@ public class Generator
{
foreach (var @case in statement.Cases)
{
var tag = enumInfo.Variants.ToList().FindIndex(x => x.Name == @case.Type.Ident);
var tag = enumInfo.Variants.ToList().FindIndex(x => x.Name == @case.Variant.Ident);
writer.WriteLine($"case {tag}:");
writer.WriteLine("{");
using (writer.Indent())
{
writer.WriteLine($"auto {@case.VariableName.Ident} = {target}.{@case.Type.Ident};");
writer.WriteLine($"auto {@case.VariableName.Ident} = {target}.{@case.Variant.Ident};");
EmitStatement(@case.Body);
}
writer.WriteLine("}");

View File

@@ -191,9 +191,22 @@ public class TypeChecker
if (target.Type is not NubTypeEnum enumType)
throw BasicError("A match statement can only be used on enum types", target);
if (!moduleGraph.TryResolveType(enumType.Module, enumType.Name, enumType.Module == currentModule, out var info))
throw BasicError($"Type '{enumType}' not found", target);
if (info is not Module.TypeInfoEnum enumInfo)
throw BasicError($"Type '{enumType}' is not an enum", target);
var uncoveredCases = enumInfo.Variants.Select(x => x.Name).ToList();
var cases = new List<TypedNodeStatementMatch.Case>();
foreach (var @case in statement.Cases)
{
if (!enumInfo.Variants.Any(x => x.Name == @case.Variant.Ident))
throw BasicError($"Enum type'{enumType}' does not have a variant named '{@case.Variant.Ident}'", @case.Variant);
uncoveredCases.Remove(@case.Variant.Ident);
using (scope.EnterScope())
{
scope.DeclareIdentifier(@case.VariableName.Ident, NubTypeEnumVariant.Get(NubTypeEnum.Get(enumType.Module, enumType.Name), @case.Variant.Ident));
@@ -202,6 +215,9 @@ public class TypeChecker
}
}
if (uncoveredCases.Any())
throw BasicError($"Match statement does not cover the following cases: {string.Join(", ", uncoveredCases)}", statement);
return new TypedNodeStatementMatch(statement.Tokens, target, cases);
}
@@ -791,7 +807,7 @@ public class TypedNodeStatementMatch(List<Token> tokens, TypedNodeExpression tar
public class Case(List<Token> tokens, TokenIdent type, TokenIdent variableName, TypedNodeStatement body) : Node(tokens)
{
public TokenIdent Type { get; } = type;
public TokenIdent Variant { get; } = type;
public TokenIdent VariableName { get; } = variableName;
public TypedNodeStatement Body { get; } = body;
}