using NubLang.Syntax; namespace NubLang.Ast; public abstract record Node(List Tokens) { public abstract IEnumerable Children(); public IEnumerable Descendants() { foreach (var child in Children()) { foreach (var descendant in child.DescendantsAndSelf()) { yield return descendant; } } } public IEnumerable DescendantsAndSelf() { yield return this; foreach (var descendant in Descendants()) { yield return descendant; } } } #region Definitions public abstract record DefinitionNode(List Tokens, string Module, string Name) : Node(Tokens); public record FuncParameterNode(List Tokens, string Name, NubType Type) : Node(Tokens) { public override IEnumerable Children() { return []; } } public record FuncPrototypeNode(List Tokens, string Module, string Name, string? ExternSymbol, List Parameters, NubType ReturnType) : Node(Tokens) { public override IEnumerable Children() { return Parameters; } } public record FuncNode(List Tokens, FuncPrototypeNode Prototype, BlockNode? Body) : DefinitionNode(Tokens, Prototype.Module, Prototype.Name) { public override IEnumerable Children() { yield return Prototype; if (Body != null) { yield return Body; } } } #endregion #region Statements public abstract record StatementNode(List Tokens) : Node(Tokens); public abstract record TerminalStatementNode(List Tokens) : StatementNode(Tokens); public record BlockNode(List Tokens, List Statements) : StatementNode(Tokens) { public override IEnumerable Children() { return Statements; } } public record StatementFuncCallNode(List Tokens, FuncCallNode FuncCall) : StatementNode(Tokens) { public override IEnumerable Children() { yield return FuncCall; } } public record ReturnNode(List Tokens, ExpressionNode? Value) : TerminalStatementNode(Tokens) { public override IEnumerable Children() { if (Value != null) yield return Value; } } public record AssignmentNode(List Tokens, LValueExpressionNode Target, ExpressionNode Value) : StatementNode(Tokens) { public override IEnumerable Children() { yield return Target; yield return Value; } } public record IfNode(List Tokens, ExpressionNode Condition, BlockNode Body, Variant? Else) : StatementNode(Tokens) { public override IEnumerable Children() { yield return Condition; yield return Body; if (Else.HasValue) { yield return Else.Value.Match(x => x, x => x); } } } public record VariableDeclarationNode(List Tokens, string Name, ExpressionNode? Assignment, NubType Type) : StatementNode(Tokens) { public override IEnumerable Children() { if (Assignment != null) yield return Assignment; } } public record ContinueNode(List Tokens) : TerminalStatementNode(Tokens) { public override IEnumerable Children() { return []; } } public record BreakNode(List Tokens) : TerminalStatementNode(Tokens) { public override IEnumerable Children() { return []; } } public record WhileNode(List Tokens, ExpressionNode Condition, BlockNode Body) : StatementNode(Tokens) { public override IEnumerable Children() { yield return Condition; yield return Body; } } public record ForSliceNode(List Tokens, string ElementName, string? IndexName, ExpressionNode Target, BlockNode Body) : StatementNode(Tokens) { public override IEnumerable Children() { yield return Target; yield return Body; } } public record ForConstArrayNode(List Tokens, string ElementName, string? IndexName, ExpressionNode Target, BlockNode Body) : StatementNode(Tokens) { public override IEnumerable Children() { yield return Target; yield return Body; } } public record DeferNode(List Tokens, StatementNode Statement) : StatementNode(Tokens) { public override IEnumerable Children() { yield return Statement; } } #endregion #region Expressions public enum UnaryOperator { Negate, Invert } public enum BinaryOperator { Equal, NotEqual, GreaterThan, GreaterThanOrEqual, LessThan, LessThanOrEqual, LogicalAnd, LogicalOr, Plus, Minus, Multiply, Divide, Modulo, LeftShift, RightShift, BitwiseAnd, BitwiseXor, BitwiseOr } public abstract record ExpressionNode(List Tokens, NubType Type) : Node(Tokens); public abstract record LValueExpressionNode(List Tokens, NubType Type) : ExpressionNode(Tokens, Type); public abstract record RValueExpressionNode(List Tokens, NubType Type) : ExpressionNode(Tokens, Type); public abstract record IntermediateExpression(List Tokens) : ExpressionNode(Tokens, new NubVoidType()); public record StringLiteralNode(List Tokens, string Value) : RValueExpressionNode(Tokens, new NubStringType()) { public override IEnumerable Children() { return []; } } public record CStringLiteralNode(List Tokens, string Value) : RValueExpressionNode(Tokens, new NubCStringType()) { public override IEnumerable Children() { return []; } } public record I8LiteralNode(List Tokens, sbyte Value) : RValueExpressionNode(Tokens, new NubIntType(true, 8)) { public override IEnumerable Children() { return []; } } public record I16LiteralNode(List Tokens, short Value) : RValueExpressionNode(Tokens, new NubIntType(true, 16)) { public override IEnumerable Children() { return []; } } public record I32LiteralNode(List Tokens, int Value) : RValueExpressionNode(Tokens, new NubIntType(true, 32)) { public override IEnumerable Children() { return []; } } public record I64LiteralNode(List Tokens, long Value) : RValueExpressionNode(Tokens, new NubIntType(true, 64)) { public override IEnumerable Children() { return []; } } public record U8LiteralNode(List Tokens, byte Value) : RValueExpressionNode(Tokens, new NubIntType(false, 8)) { public override IEnumerable Children() { return []; } } public record U16LiteralNode(List Tokens, ushort Value) : RValueExpressionNode(Tokens, new NubIntType(false, 16)) { public override IEnumerable Children() { return []; } } public record U32LiteralNode(List Tokens, uint Value) : RValueExpressionNode(Tokens, new NubIntType(false, 32)) { public override IEnumerable Children() { return []; } } public record U64LiteralNode(List Tokens, ulong Value) : RValueExpressionNode(Tokens, new NubIntType(false, 64)) { public override IEnumerable Children() { return []; } } public record Float32LiteralNode(List Tokens, float Value) : RValueExpressionNode(Tokens, new NubFloatType(32)) { public override IEnumerable Children() { return []; } } public record Float64LiteralNode(List Tokens, double Value) : RValueExpressionNode(Tokens, new NubFloatType(64)) { public override IEnumerable Children() { return []; } } public record BoolLiteralNode(List Tokens, NubType Type, bool Value) : RValueExpressionNode(Tokens, Type) { public override IEnumerable Children() { return []; } } public record BinaryExpressionNode(List Tokens, NubType Type, ExpressionNode Left, BinaryOperator Operator, ExpressionNode Right) : RValueExpressionNode(Tokens, Type) { public override IEnumerable Children() { yield return Left; yield return Right; } } public record UnaryExpressionNode(List Tokens, NubType Type, UnaryOperator Operator, ExpressionNode Operand) : RValueExpressionNode(Tokens, Type) { public override IEnumerable Children() { yield return Operand; } } public record FuncCallNode(List Tokens, NubType Type, ExpressionNode Expression, List Parameters) : RValueExpressionNode(Tokens, Type) { public override IEnumerable Children() { yield return Expression; foreach (var expressionNode in Parameters) { yield return expressionNode; } } } public record VariableIdentifierNode(List Tokens, NubType Type, string Name) : LValueExpressionNode(Tokens, Type) { public override IEnumerable Children() { return []; } } public record FuncIdentifierNode(List Tokens, NubType Type, string Module, string Name, string? ExternSymbol) : RValueExpressionNode(Tokens, Type) { public override IEnumerable Children() { return []; } } public record ArrayInitializerNode(List Tokens, NubType Type, List Values) : RValueExpressionNode(Tokens, Type) { public override IEnumerable Children() { return Values; } } public record ConstArrayInitializerNode(List Tokens, NubType Type, List Values) : RValueExpressionNode(Tokens, Type) { public override IEnumerable Children() { return Values; } } public record ArrayIndexAccessNode(List Tokens, NubType Type, ExpressionNode Target, ExpressionNode Index) : LValueExpressionNode(Tokens, Type) { public override IEnumerable Children() { yield return Target; yield return Index; } } public record ConstArrayIndexAccessNode(List Tokens, NubType Type, ExpressionNode Target, ExpressionNode Index) : LValueExpressionNode(Tokens, Type) { public override IEnumerable Children() { yield return Target; yield return Index; } } public record SliceIndexAccessNode(List Tokens, NubType Type, ExpressionNode Target, ExpressionNode Index) : LValueExpressionNode(Tokens, Type) { public override IEnumerable Children() { yield return Target; yield return Index; } } public record AddressOfNode(List Tokens, NubType Type, LValueExpressionNode LValue) : RValueExpressionNode(Tokens, Type) { public override IEnumerable Children() { yield return LValue; } } public record StructFieldAccessNode(List Tokens, NubType Type, ExpressionNode Target, string Field) : LValueExpressionNode(Tokens, Type) { public override IEnumerable Children() { yield return Target; } } public record StructInitializerNode(List Tokens, NubType Type, Dictionary Initializers) : RValueExpressionNode(Tokens, Type) { public override IEnumerable Children() { foreach (var initializer in Initializers) { yield return initializer.Value; } } } public record DereferenceNode(List Tokens, NubType Type, ExpressionNode Target) : LValueExpressionNode(Tokens, Type) { public override IEnumerable Children() { yield return Target; } } public record ConvertIntNode(List Tokens, ExpressionNode Value, int StartWidth, int TargetWidth, bool StartSignedness, bool TargetSignedness) : RValueExpressionNode(Tokens, new NubIntType(TargetSignedness, TargetWidth)) { public override IEnumerable Children() { yield return Value; } } public record ConvertFloatNode(List Tokens, ExpressionNode Value, int StartWidth, int TargetWidth) : RValueExpressionNode(Tokens, new NubFloatType(TargetWidth)) { public override IEnumerable Children() { yield return Value; } } public record ConvertCStringToStringNode(List Tokens, ExpressionNode Value) : RValueExpressionNode(Tokens, new NubStringType()) { public override IEnumerable Children() { yield return Value; } } public record SizeBuiltinNode(List Tokens, NubType Type, NubType TargetType) : RValueExpressionNode(Tokens, Type) { public override IEnumerable Children() { return []; } } public record FloatToIntBuiltinNode(List Tokens, NubType Type, ExpressionNode Value, NubFloatType ValueType, NubIntType TargetType) : RValueExpressionNode(Tokens, Type) { public override IEnumerable Children() { yield return Value; } } public record ConstArrayToSliceNode(List Tokens, NubType Type, ExpressionNode Array) : RValueExpressionNode(Tokens, Type) { public override IEnumerable Children() { yield return Array; } } public record EnumReferenceIntermediateNode(List Tokens, string Module, string Name) : IntermediateExpression(Tokens) { public override IEnumerable Children() { return []; } } #endregion