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);
}