This commit is contained in:
nub31
2026-03-01 18:14:54 +01:00
parent 5f4a4172bf
commit 2b7eb56895
9 changed files with 192 additions and 138 deletions

View File

@@ -1,5 +1,7 @@
using System.Diagnostics;
using System.Security.Principal;
using System.Text;
using Microsoft.VisualBasic;
namespace Compiler;
@@ -260,7 +262,12 @@ public class Generator
throw new UnreachableException();
foreach (var variant in enumInfo.Variants)
EmitTypeDefinitionIfNotEmitted(variant.Type);
{
if (variant.Type is not null)
{
EmitTypeDefinitionIfNotEmitted(variant.Type);
}
}
writer.WriteLine($"struct {NameMangler.Mangle(enumType.Module, enumType.Name, enumType)}");
writer.WriteLine("{");
@@ -273,7 +280,10 @@ public class Generator
{
foreach (var variant in enumInfo.Variants)
{
writer.WriteLine($"{CType(variant.Type, variant.Name)};");
if (variant.Type is not null)
{
writer.WriteLine($"{CType(variant.Type, variant.Name)};");
}
}
}
writer.WriteLine("};");
@@ -453,7 +463,12 @@ public class Generator
using (writer.Indent())
{
PushScope();
writer.WriteLine($"{CType(variantInfo.Type, @case.VariableName.Ident)} = {target}.{@case.Variant.Ident};");
if (@case.VariableName != null)
{
Debug.Assert(variantInfo.Type is not null);
writer.WriteLine($"{CType(variantInfo.Type, @case.VariableName.Ident)} = {target}.{@case.Variant.Ident};");
}
EmitStatement(@case.Body);
PopScope();
writer.WriteLine("break;");
@@ -474,7 +489,7 @@ public class Generator
TypedNodeExpressionIntLiteral expression => expression.Value.Value.ToString(),
TypedNodeExpressionStringLiteral expression => EmitExpressionStringLiteral(expression),
TypedNodeExpressionStructLiteral expression => EmitExpressionStructLiteral(expression),
TypedNodeExpressionEnumLiteral expression => EmitExpressionEnumLiteral(expression),
TypedNodeExpressionNewNamedType expression => EmitNodeExpressionNewNamedType(expression),
TypedNodeExpressionStructMemberAccess expression => EmitExpressionMemberAccess(expression),
TypedNodeExpressionStringLength expression => EmitExpressionStringLength(expression),
TypedNodeExpressionStringPointer expression => EmitExpressionStringPointer(expression),
@@ -563,25 +578,35 @@ public class Generator
return name;
}
private string EmitExpressionEnumLiteral(TypedNodeExpressionEnumLiteral expression)
private string EmitNodeExpressionNewNamedType(TypedNodeExpressionNewNamedType expression)
{
var name = TmpName();
scopes.Peek().DeconstructableNames.Add((name, expression.Type));
switch (expression.Type)
{
case NubTypeEnumVariant enumVariantType:
{
var name = TmpName();
scopes.Peek().DeconstructableNames.Add((name, expression.Type));
var enumVariantType = (NubTypeEnumVariant)expression.Type;
if (!moduleGraph.TryResolveType(enumVariantType.EnumType.Module, enumVariantType.EnumType.Name, true, out var info))
throw new UnreachableException();
if (!moduleGraph.TryResolveType(enumVariantType.EnumType.Module, enumVariantType.EnumType.Name, true, out var info))
throw new UnreachableException();
var enumInfo = (Module.TypeInfoEnum)info;
var tag = enumInfo.Variants.ToList().FindIndex(x => x.Name == enumVariantType.Variant);
var enumInfo = (Module.TypeInfoEnum)info;
var tag = enumInfo.Variants.ToList().FindIndex(x => x.Name == enumVariantType.Variant);
var value = EmitExpression(expression.Value);
EmitCopyConstructor(value, expression.Value.Type);
var value = EmitExpression(expression.Value);
EmitCopyConstructor(value, expression.Value.Type);
writer.WriteLine($"{CType(expression.Type, name)} = ({CType(expression.Type)}){{ .tag = {tag}, .{enumVariantType.Variant} = {value} }};");
writer.WriteLine($"{CType(expression.Type, name)} = ({CType(expression.Type)}){{ .tag = {tag}, .{enumVariantType.Variant} = {value} }};");
return name;
return name;
}
case NubTypeStruct structType:
{
return EmitExpression(expression.Value);
}
default:
throw new UnreachableException();
}
}
private string EmitExpressionMemberAccess(TypedNodeExpressionStructMemberAccess expression)
@@ -710,14 +735,17 @@ public class Generator
{
Module.TypeInfoEnum.Variant variant = enumInfo.Variants[i];
writer.WriteLine($"case {i}:");
writer.WriteLine("{");
using (writer.Indent())
if (variant.Type is not null)
{
EmitCopyConstructor($"{value}.{variant.Name}", variant.Type);
writer.WriteLine("break;");
writer.WriteLine($"case {i}:");
writer.WriteLine("{");
using (writer.Indent())
{
EmitCopyConstructor($"{value}.{variant.Name}", variant.Type);
writer.WriteLine("break;");
}
writer.WriteLine("}");
}
writer.WriteLine("}");
}
}
writer.WriteLine("}");
@@ -729,8 +757,9 @@ public class Generator
throw new UnreachableException();
var variant = enumInfo.Variants.First(x => x.Name == enumVariantType.Variant);
if (variant.Type is not null)
EmitCopyConstructor($"{value}.{variant.Name}", variant.Type);
EmitCopyConstructor($"{value}.{variant.Name}", variant.Type);
break;
}
}
@@ -776,15 +805,17 @@ public class Generator
for (int i = 0; i < enumInfo.Variants.Count; i++)
{
var variant = enumInfo.Variants[i];
writer.WriteLine($"case {i}:");
writer.WriteLine("{");
using (writer.Indent())
if (variant.Type is not null)
{
EmitCopyDestructor($"{value}.{variant.Name}", variant.Type);
writer.WriteLine("break;");
writer.WriteLine($"case {i}:");
writer.WriteLine("{");
using (writer.Indent())
{
EmitCopyDestructor($"{value}.{variant.Name}", variant.Type);
writer.WriteLine("break;");
}
writer.WriteLine("}");
}
writer.WriteLine("}");
}
}
writer.WriteLine("}");
@@ -796,8 +827,9 @@ public class Generator
throw new UnreachableException();
var variant = enumInfo.Variants.First(x => x.Name == enumVariantType.Variant);
if (variant.Type is not null)
EmitCopyDestructor($"{value}.{variant.Name}", variant.Type);
EmitCopyDestructor($"{value}.{variant.Name}", variant.Type);
break;
}
}