// rasm-core/src/parser/ast.rs
//
//! # AST (Abstract Syntax Tree)
//!
//! Программа на ассемблере — это плоский список утверждений (Statement).
//! Никаких вложенных блоков, никаких функций с телами — только строка за строкой.
use crate::{
    isa::{Instruction, directive::Directive},
    str_pool::StrId,
};

/// Корень AST. Содержит все Statement-ы программы в том порядке, в котором
/// они встретились в исходном коде.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct AST {
    pub program: Vec<Statement>,
}

impl AST {
    pub fn new() -> Self {
        Self {
            program: Vec::new(),
        }
    }
}

impl Default for AST {
    fn default() -> Self {
        Self::new()
    }
}

/// Одна логическая единица программы (обычно — одна строка).
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Statement {
    /// Определение метки: `main:` или `.loop_start:`
    Label(StrId),

    /// Процессорная инструкция: `mov rax, rbx`, `syscall`, `ret`
    Instruction(Instruction),

    /// Директива компилятора: `.text`, `.global _start`, `.quad 42`
    Directive(Directive),
}

/// Константное выражение, вычисляемое во время сборки.
/// Используется, например, для: `BASE + 0x10` или `1 << 4`.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ConstExpr {
    Immediate(i64),
    Symbol(StrId),
    BinaryOp {
        op: BinOp,
        left: Box<ConstExpr>,
        right: Box<ConstExpr>,
    },
}

/// Арифметические операции, поддерживаемые в константных выражениях.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum BinOp {
    Add,
    Sub,
    Mul,
    Div,
}
