// FILE: src/parser/ast.rs

#[derive(Debug, Clone, PartialEq)]
pub enum Stmt {
    ImportSo {
        path: String,
        line: usize,
        col: usize,
    },
    Assignment {
        left: Expr,
        right: Expr,
        line: usize,
        col: usize,
    },
    AssignmentDestructure {
        pattern: DestructurePattern,
        right: Expr,
        line: usize,
        col: usize,
    },
    AssignmentScoped {
        left: Expr,
        right: Expr,
        line: usize,
        col: usize,
    },
    ExprStmt {
        expr: Expr,
        line: usize,
        col: usize,
    },
}

#[derive(Debug, Clone, PartialEq)]
pub enum DestructurePattern {
    Keyed(Vec<String>),
    Tuple(Vec<String>),
}

#[derive(Debug, Clone, PartialEq)]
pub enum Expr {
    Number {
        value: i32,
        line: usize,
        col: usize,
    },
    NumberFloat {
        value: f64,
        line: usize,
        col: usize,
    },
    StrLit {
        value: String,
        line: usize,
        col: usize,
    },
    Bool {
        value: bool,
        line: usize,
        col: usize,
    },
    Ident {
        name: String,
        line: usize,
        col: usize,
    },
    Placeholder {
        line: usize,
        col: usize,
    },
    BracketedArray {
        items: Vec<Expr>,
        line: usize,
        col: usize,
    },
    KeyedArray {
        pairs: Vec<(String, Expr)>,
        line: usize,
        col: usize,
    },
    FunctionCall {
        callee: Box<Expr>,
        args: Vec<Expr>,
        line: usize,
        col: usize,
    },
    Index {
        base: Box<Expr>,
        index: Box<Expr>,
        line: usize,
        col: usize,
    },
    Gt {
        left: Box<Expr>,
        right: Box<Expr>,
        line: usize,
        col: usize,
    },
    Lt {
        left: Box<Expr>,
        right: Box<Expr>,
        line: usize,
        col: usize,
    },
    EqEq {
        left: Box<Expr>,
        right: Box<Expr>,
        line: usize,
        col: usize,
    },
    Le {
        left: Box<Expr>,
        right: Box<Expr>,
        line: usize,
        col: usize,
    },
    Ge {
        left: Box<Expr>,
        right: Box<Expr>,
        line: usize,
        col: usize,
    },
    Add {
        left: Box<Expr>,
        right: Box<Expr>,
        line: usize,
        col: usize,
    },
    Sub {
        left: Box<Expr>,
        right: Box<Expr>,
        line: usize,
        col: usize,
    },
    Mul {
        left: Box<Expr>,
        right: Box<Expr>,
        line: usize,
        col: usize,
    },
    Div {
        left: Box<Expr>,
        right: Box<Expr>,
        line: usize,
        col: usize,
    },
    Mod {
        left: Box<Expr>,
        right: Box<Expr>,
        line: usize,
        col: usize,
    },
    Ternary {
        cond: Box<Expr>,
        if_true: Box<Expr>,
        if_false: Box<Expr>,
        line: usize,
        col: usize,
    },
    InlineLambdaAST {
        params: Vec<crate::parser::types::LambdaParam>,
        body: Box<Expr>,
        line: usize,
        col: usize,
    },
    Block {
        stmts: Vec<Stmt>,
        line: usize,
        col: usize,
    },
    UnaryMinus {
        expr: Box<Expr>,
        line: usize,
        col: usize,
    },
    AndAnd {
        left: Box<Expr>,
        right: Box<Expr>,
        line: usize,
        col: usize,
    },
    UnaryNot {
        expr: Box<Expr>,
        line: usize,
        col: usize,
    },
    Ne {
        left: Box<Expr>,
        right: Box<Expr>,
        line: usize,
        col: usize,
    },
    BitAnd {
        left: Box<Expr>,
        right: Box<Expr>,
        line: usize,
        col: usize,
    },
    OrOr {
        left: Box<Expr>,
        right: Box<Expr>,
        line: usize,
        col: usize,
    },
    Shl {
        left: Box<Expr>,
        right: Box<Expr>,
        line: usize,
        col: usize,
    },
    Shr {
        left: Box<Expr>,
        right: Box<Expr>,
        line: usize,
        col: usize,
    },
    BitXor {
        left: Box<Expr>,
        right: Box<Expr>,
        line: usize,
        col: usize,
    },
    BitTilde {
        left: Box<Expr>,
        right: Box<Expr>,
        line: usize,
        col: usize,
    },
    BitOr {
        left: Box<Expr>,
        right: Box<Expr>,
        line: usize,
        col: usize,
    },
    Ref {
        expr: Box<Expr>,
        line: usize,
        col: usize,
    },
}
