using System.Collections.Immutable; namespace XDLCompiler; /// public interface INamedNode { string? Name { get; } } /// public interface IAttributableNode { ImmutableArray Attributes { get; } } /// Base class for all syntax nodes. public abstract record SyntaxNode { /// Accepts a visitor for traversing the syntax tree public abstract void Accept(ISyntaxVisitor visitor); } public sealed record ImportNode(StringLiteralNode FileName) : SyntaxNode { /// public override void Accept(ISyntaxVisitor visitor) => visitor.Visit(this); } /// A syntax node representing an attribute. public sealed record AttributeNode(ImmutableArray Arguments, string Name) : SyntaxNode, INamedNode { /// public override void Accept(ISyntaxVisitor visitor) => visitor.Visit(this); } public abstract record TypeDeclarationNode( ImmutableArray Attributes, string? Name, ImmutableArray BaseTypes, ImmutableArray Members, bool IsConst = false, string? Namespace = null) : TypeNode(IsConst), IAttributableNode, INamedNode { public abstract string DeclarationType { get; } } public sealed record EnumMemberNode( ImmutableArray Attributes, string Name, ExpressionNode? Value) : MemberNode(Attributes, Name) { /// public override void Accept(ISyntaxVisitor visitor) => visitor.Visit(this); } public sealed record EnumNode( ImmutableArray Attributes, string? Name, ImmutableArray BaseTypes, ImmutableArray EnumMembers, bool IsConst = false, string? Namespace = null) : TypeDeclarationNode(Attributes, Name, BaseTypes, [..EnumMembers], IsConst, Namespace) { /// public override string DeclarationType => "enum"; /// public override void Accept(ISyntaxVisitor visitor) => visitor.Visit(this); } public sealed record InterfaceNode( ImmutableArray Attributes, string Name, ImmutableArray BaseTypes, ImmutableArray Members, bool IsConst = false, string? Namespace = null) : TypeDeclarationNode(Attributes, Name, BaseTypes, Members, IsConst, Namespace) { /// public override string DeclarationType => "interface"; /// public override void Accept(ISyntaxVisitor visitor) => visitor.Visit(this); } public sealed record UnionNode( ImmutableArray Attributes, string? Name, ImmutableArray BaseTypes, ImmutableArray Members, bool IsConst = false, string? Namespace = null) : TypeDeclarationNode(Attributes, Name, BaseTypes, Members, IsConst, Namespace) { /// public override string DeclarationType => "union"; /// public override void Accept(ISyntaxVisitor visitor) => visitor.Visit(this); } public sealed record StructNode( ImmutableArray Attributes, string? Name, ImmutableArray BaseTypes, ImmutableArray Members, bool IsConst = false, string? Namespace = null) : TypeDeclarationNode(Attributes, Name, BaseTypes, Members, IsConst, Namespace) { /// public override string DeclarationType => "struct"; /// public override void Accept(ISyntaxVisitor visitor) => visitor.Visit(this); } public sealed record ClassNode( ImmutableArray Attributes, string? Name, ImmutableArray BaseTypes, ImmutableArray Members, bool IsConst = false, string? Namespace = null) : TypeDeclarationNode(Attributes, Name, BaseTypes, Members, IsConst, Namespace) { /// public override string DeclarationType => "class"; /// public override void Accept(ISyntaxVisitor visitor) => visitor.Visit(this); } /// Represents a base type in a type hierarchy. public sealed record BaseTypeNode(ImmutableArray Attributes, string Name) : SyntaxNode, IAttributableNode, INamedNode { /// public override void Accept(ISyntaxVisitor visitor) => visitor.Visit(this); } /// Base class for nodes representing members of a type. public abstract record MemberNode(ImmutableArray Attributes, string? Name, bool IsStatic = false) : SyntaxNode, IAttributableNode, INamedNode { } public sealed record MemberBlockNode(ImmutableArray Attributes, ImmutableArray Members) : MemberNode(Attributes, string.Empty, false) { /// public override void Accept(ISyntaxVisitor visitor) => visitor.Visit(this); } /// A syntax node representing a field on a type. public sealed record FieldNode(ImmutableArray Attributes, string? Name, TypeNode Type, ExpressionNode? BitWidth, bool IsStatic = false) : MemberNode(Attributes, Name, IsStatic) { /// public override void Accept(ISyntaxVisitor visitor) => visitor.Visit(this); } public sealed record MethodTypeNode( TypeNode ReturnType, ImmutableArray Parameters, bool IsConst = false) : TypeNode(IsConst) { /// public override void Accept(ISyntaxVisitor visitor) => visitor.Visit(this); } /// A syntax node representing a method on a type. public sealed record MethodNode( ImmutableArray Attributes, string Name, MethodTypeNode Signature, bool IsStatic = false, bool ForceInline = false) : MemberNode(Attributes, Name, IsStatic) { /// public override void Accept(ISyntaxVisitor visitor) => visitor.Visit(this); } /// A dummy node representing the end of a member block, for member enumeration. public sealed record MemberBlockEndNode(MemberBlockNode Block) : MemberNode([], null) { public override void Accept(ISyntaxVisitor visitor) { } } /// A syntax mode representing a method parameter. public sealed record ParameterNode(ImmutableArray Attributes, TypeNode Type, string? Name) : SyntaxNode, IAttributableNode, INamedNode { /// public override void Accept(ISyntaxVisitor visitor) => visitor.Visit(this); } /// Base class for all type reference nodes. public abstract record TypeNode(bool IsConst = false) : SyntaxNode { } /// A syntax node representing a reference to a named type. public sealed record NamedTypeNode(string Name, bool IsConst = false) : TypeNode(IsConst), INamedNode { /// public override void Accept(ISyntaxVisitor visitor) => visitor.Visit(this); } public abstract record PointerOrReferenceTypeNode(TypeNode ElementType, bool IsConst = false) : TypeNode(IsConst) { } /// A syntax node representing a typed pointer. public sealed record PointerTypeNode(TypeNode ElementType, bool IsConst = false) : PointerOrReferenceTypeNode(ElementType, IsConst) { /// public override void Accept(ISyntaxVisitor visitor) => visitor.Visit(this); } /// A syntax node representing a typed reference. public sealed record ReferenceTypeNode(TypeNode ElementType, bool IsConst = false) : PointerOrReferenceTypeNode(ElementType, IsConst) { /// public override void Accept(ISyntaxVisitor visitor) => visitor.Visit(this); } public sealed record ArrayTypeNode(TypeNode ElementType, ExpressionNode? Length, bool IsConst = false) : TypeNode(IsConst) { /// public override void Accept(ISyntaxVisitor visitor) => visitor.Visit(this); } /// Base class for all expression nodes. public abstract record ExpressionNode : SyntaxNode { /// Evaluates a constant expression. public abstract object Evaluate(); } public abstract record LiteralNode : ExpressionNode { } public sealed record StringLiteralNode(string Value) : LiteralNode { /// public override object Evaluate() => ToString(); /// public override void Accept(ISyntaxVisitor visitor) => visitor.Visit(this); /// public override string ToString() => Value[1..^1]; // TODO: escape chars } public sealed record IntegerLiteralNode(long Value) : LiteralNode { /// public override object Evaluate() => Value; /// public override void Accept(ISyntaxVisitor visitor) => visitor.Visit(this); } public sealed record IdentifierExpressionNode(string Name) : ExpressionNode { /// public override object Evaluate() => Name; /// public override void Accept(ISyntaxVisitor visitor) => visitor.Visit(this); } public abstract record UnaryExpressionNode(ExpressionNode Operand) : ExpressionNode { } public sealed record UnaryNegationNode(ExpressionNode Operand) : UnaryExpressionNode(Operand) { /// public override object Evaluate() => -(long)Operand.Evaluate(); /// public override void Accept(ISyntaxVisitor visitor) => visitor.Visit(this); }