aether/
ast.rs

1// src/ast.rs
2//! Abstract Syntax Tree (AST) definitions for Aether
3//!
4//! This module defines the structure of Aether programs as a tree of nodes.
5
6/// Binary operators
7#[derive(Debug, Clone, PartialEq)]
8pub enum BinOp {
9    // Arithmetic
10    Add,      // +
11    Subtract, // -
12    Multiply, // *
13    Divide,   // /
14    Modulo,   // %
15
16    // Comparison
17    Equal,        // ==
18    NotEqual,     // !=
19    Less,         // <
20    LessEqual,    // <=
21    Greater,      // >
22    GreaterEqual, // >=
23
24    // Logical
25    And, // &&
26    Or,  // ||
27}
28
29/// Unary operators
30#[derive(Debug, Clone, PartialEq)]
31pub enum UnaryOp {
32    Minus, // -
33    Not,   // !
34}
35
36/// Expressions - things that evaluate to values
37#[derive(Debug, Clone, PartialEq)]
38pub enum Expr {
39    // Literals
40    Number(f64),
41    BigInteger(String), // 大整数字面量
42    String(String),
43    Boolean(bool),
44    Null,
45
46    // Identifier (variable reference)
47    Identifier(String),
48
49    // Binary operation: (left op right)
50    Binary {
51        left: Box<Expr>,
52        op: BinOp,
53        right: Box<Expr>,
54    },
55
56    // Unary operation: (op expr)
57    Unary {
58        op: UnaryOp,
59        expr: Box<Expr>,
60    },
61
62    // Function call: FUNC(arg1, arg2, ...)
63    Call {
64        func: Box<Expr>,
65        args: Vec<Expr>,
66    },
67
68    // Array literal: [1, 2, 3]
69    Array(Vec<Expr>),
70
71    // Dictionary literal: {key: value, ...}
72    Dict(Vec<(String, Expr)>),
73
74    // Array/Dict access: array[index] or dict[key]
75    Index {
76        object: Box<Expr>,
77        index: Box<Expr>,
78    },
79
80    // If expression (can return value)
81    If {
82        condition: Box<Expr>,
83        then_branch: Vec<Stmt>,
84        elif_branches: Vec<(Expr, Vec<Stmt>)>, // (condition, body) pairs
85        else_branch: Option<Vec<Stmt>>,
86    },
87
88    // Anonymous function
89    Lambda {
90        params: Vec<String>,
91        body: Vec<Stmt>,
92    },
93}
94
95/// Statements - things that perform actions
96#[derive(Debug, Clone, PartialEq)]
97pub enum Stmt {
98    // Variable assignment: Set NAME value
99    Set {
100        name: String,
101        value: Expr,
102    },
103
104    // Index assignment: Set OBJECT[INDEX] value (for arrays and dicts)
105    SetIndex {
106        object: Box<Expr>,
107        index: Box<Expr>,
108        value: Expr,
109    },
110
111    // Function definition: Func NAME (params) { body }
112    FuncDef {
113        name: String,
114        params: Vec<String>,
115        body: Vec<Stmt>,
116    },
117
118    // Generator definition: Generator NAME (params) { body }
119    GeneratorDef {
120        name: String,
121        params: Vec<String>,
122        body: Vec<Stmt>,
123    },
124
125    // Lazy variable: Lazy NAME (expr)
126    LazyDef {
127        name: String,
128        expr: Expr,
129    },
130
131    // Return statement: Return expr
132    Return(Expr),
133
134    // Yield statement (for generators): Yield expr
135    Yield(Expr),
136
137    // Break statement: Break (exit loop)
138    Break,
139
140    // Continue statement: Continue (skip to next iteration)
141    Continue,
142
143    // While loop: While (condition) { body }
144    While {
145        condition: Expr,
146        body: Vec<Stmt>,
147    },
148
149    // For loop: For VAR In ITERABLE { body }
150    For {
151        var: String,
152        iterable: Expr,
153        body: Vec<Stmt>,
154    },
155
156    // For loop with index: For INDEX, VAR In ITERABLE { body }
157    ForIndexed {
158        index_var: String,
159        value_var: String,
160        iterable: Expr,
161        body: Vec<Stmt>,
162    },
163
164    // Switch statement: Switch (expr) { Case val: body ... Default: body }
165    Switch {
166        expr: Expr,
167        cases: Vec<(Expr, Vec<Stmt>)>,
168        default: Option<Vec<Stmt>>,
169    },
170
171    // Import statement:
172    // - Named imports: Import {NAME1, NAME2} From PATH
173    // - Named import with alias: Import NAME As ALIAS From PATH
174    // - Namespace import: Import NS From PATH  (bind module exports as Dict to NS)
175    Import {
176        names: Vec<String>,
177        path: String,
178        aliases: Vec<Option<String>>, // Optional aliases (As NAME)
179        namespace: Option<String>,    // Namespace binding name
180    },
181
182    // Export statement: Export NAME
183    Export(String),
184
185    // Throw statement: Throw message
186    Throw(Expr),
187
188    // Expression statement (expression as statement)
189    Expression(Expr),
190}
191
192/// A complete program is a list of statements
193pub type Program = Vec<Stmt>;
194
195impl Expr {
196    /// Helper to create a binary expression
197    pub fn binary(left: Expr, op: BinOp, right: Expr) -> Self {
198        Expr::Binary {
199            left: Box::new(left),
200            op,
201            right: Box::new(right),
202        }
203    }
204
205    /// Helper to create a unary expression
206    pub fn unary(op: UnaryOp, expr: Expr) -> Self {
207        Expr::Unary {
208            op,
209            expr: Box::new(expr),
210        }
211    }
212
213    /// Helper to create a function call
214    pub fn call(func: Expr, args: Vec<Expr>) -> Self {
215        Expr::Call {
216            func: Box::new(func),
217            args,
218        }
219    }
220
221    /// Helper to create an index expression
222    pub fn index(object: Expr, index: Expr) -> Self {
223        Expr::Index {
224            object: Box::new(object),
225            index: Box::new(index),
226        }
227    }
228}
229
230impl std::fmt::Display for BinOp {
231    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
232        match self {
233            BinOp::Add => write!(f, "+"),
234            BinOp::Subtract => write!(f, "-"),
235            BinOp::Multiply => write!(f, "*"),
236            BinOp::Divide => write!(f, "/"),
237            BinOp::Modulo => write!(f, "%"),
238            BinOp::Equal => write!(f, "=="),
239            BinOp::NotEqual => write!(f, "!="),
240            BinOp::Less => write!(f, "<"),
241            BinOp::LessEqual => write!(f, "<="),
242            BinOp::Greater => write!(f, ">"),
243            BinOp::GreaterEqual => write!(f, ">="),
244            BinOp::And => write!(f, "&&"),
245            BinOp::Or => write!(f, "||"),
246        }
247    }
248}
249
250impl std::fmt::Display for UnaryOp {
251    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
252        match self {
253            UnaryOp::Minus => write!(f, "-"),
254            UnaryOp::Not => write!(f, "!"),
255        }
256    }
257}