namespace NubLang.TypeChecking.Node;

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(NubType Type) : Node;

public abstract record LValueExpressionNode(NubType Type) : ExpressionNode(Type);

public abstract record RValueExpressionNode(NubType Type) : ExpressionNode(Type);

public record StringLiteralNode(NubType Type, string Value) : RValueExpressionNode(Type);

public record CStringLiteralNode(NubType Type, string Value) : RValueExpressionNode(Type);

public record IntLiteralNode(NubType Type, long Value) : RValueExpressionNode(Type);

public record UIntLiteralNode(NubType Type, ulong Value) : RValueExpressionNode(Type);

public record Float32LiteralNode(NubType Type, float Value) : RValueExpressionNode(Type);

public record Float64LiteralNode(NubType Type, double Value) : RValueExpressionNode(Type);

public record BoolLiteralNode(NubType Type, bool Value) : RValueExpressionNode(Type);

public record BinaryExpressionNode(NubType Type, ExpressionNode Left, BinaryOperator Operator, ExpressionNode Right) : RValueExpressionNode(Type);

public record UnaryExpressionNode(NubType Type, UnaryOperator Operator, ExpressionNode Operand) : RValueExpressionNode(Type);

public record FuncCallNode(NubType Type, ExpressionNode Expression, List<ExpressionNode> Parameters) : RValueExpressionNode(Type);

public record StructFuncCallNode(NubType Type, string Module, string StructName, string FuncName, ExpressionNode StructExpression, List<ExpressionNode> Parameters) : RValueExpressionNode(Type);

public record LValueIdentifierNode(NubType Type, string Name) : LValueExpressionNode(Type);

public record RValueIdentifierNode(NubType Type, string Name) : RValueExpressionNode(Type);

public record FuncIdentifierNode(NubType Type, string Module, string Name, string? ExternSymbol) : RValueExpressionNode(Type);

public record ArrayInitializerNode(NubType Type, ExpressionNode Capacity, NubType ElementType) : RValueExpressionNode(Type);

public record ArrayIndexAccessNode(NubType Type, ExpressionNode Target, ExpressionNode Index) : LValueExpressionNode(Type);

public record AddressOfNode(NubType Type, LValueExpressionNode LValue) : RValueExpressionNode(Type);

public record StructFieldAccessNode(NubType Type, ExpressionNode Target, string Field) : LValueExpressionNode(Type);

public record StructInitializerNode(NubStructType StructType, Dictionary<string, ExpressionNode> Initializers) : RValueExpressionNode(StructType);

public record DereferenceNode(NubType Type, ExpressionNode Expression) : LValueExpressionNode(Type);

public record ConvertIntNode(NubType Type, ExpressionNode Value, NubIntType ValueType, NubIntType TargetType) : RValueExpressionNode(Type);

public record ConvertFloatNode(NubType Type, ExpressionNode Value, NubFloatType ValueType, NubFloatType TargetType) : RValueExpressionNode(Type);

public record SizeBuiltinNode(NubType Type, NubType TargetType) : RValueExpressionNode(Type);

public record FloatToIntBuiltinNode(NubType Type, ExpressionNode Value, NubFloatType ValueType, NubIntType TargetType) : RValueExpressionNode(Type);