Skip to main content

virtual_rust/
ast.rs

1//! Abstract Syntax Tree (AST) types for the VirtualRust interpreter.
2//!
3//! The parser produces these AST nodes, and the interpreter walks them
4//! to execute the program.
5
6/// Type annotations supported in `let` bindings and function signatures.
7#[derive(Debug, Clone, PartialEq)]
8pub enum Type {
9    // Primitive integer types
10    I8,
11    I16,
12    I32,
13    I64,
14    I128,
15    U8,
16    U16,
17    U32,
18    U64,
19    U128,
20    // Floating-point types
21    F32,
22    F64,
23    // Other primitives
24    Bool,
25    Char,
26    String,
27    Usize,
28    Isize,
29    // Compound types
30    Array(Box<Type>, Option<usize>),
31    Vec(Box<Type>),
32    Tuple(Vec<Type>),
33    Option(Box<Type>),
34    Custom(String),
35    Unit,
36    Inferred,
37    /// `(inner_type, is_mutable)`
38    Reference(Box<Type>, bool),
39}
40
41/// An expression or statement in the AST.
42///
43/// In VirtualRust, everything is an expression — even `let` bindings,
44/// `if`/`while`/`for` control flow, and function definitions.
45#[derive(Debug, Clone)]
46pub enum Expr {
47    // ── Literals ─────────────────────────────────────────────────
48    IntLiteral(i64),
49    FloatLiteral(f64),
50    StringLiteral(String),
51    CharLiteral(char),
52    BoolLiteral(bool),
53
54    // ── Identifiers ──────────────────────────────────────────────
55    Ident(String),
56
57    // ── Operators ────────────────────────────────────────────────
58    BinaryOp {
59        left: Box<Expr>,
60        op: BinOp,
61        right: Box<Expr>,
62    },
63
64    // Unary operations
65    UnaryOp {
66        op: UnaryOp,
67        expr: Box<Expr>,
68    },
69
70    // ── Bindings & assignments ───────────────────────────────────
71    /// Simple assignment (`x = expr`).
72    Assign {
73        target: Box<Expr>,
74        value: Box<Expr>,
75    },
76
77    /// Compound assignment (`x += expr`, `x -= expr`, etc.).
78    CompoundAssign {
79        target: Box<Expr>,
80        op: BinOp,
81        value: Box<Expr>,
82    },
83
84    /// Variable declaration (`let [mut] name [: type] = expr`).
85    Let {
86        name: String,
87        mutable: bool,
88        type_ann: Option<Type>,
89        value: Option<Box<Expr>>,
90    },
91
92    // ── Control flow ─────────────────────────────────────────────
93    /// A `{ ... }` block of statements.
94    Block(Vec<Expr>),
95
96    /// `if condition { ... } [else { ... }]`
97    If {
98        condition: Box<Expr>,
99        then_block: Box<Expr>,
100        else_block: Option<Box<Expr>>,
101    },
102
103    // While loop
104    While {
105        condition: Box<Expr>,
106        body: Box<Expr>,
107    },
108
109    // Loop
110    Loop {
111        body: Box<Expr>,
112    },
113
114    // For loop
115    For {
116        var: String,
117        iterator: Box<Expr>,
118        body: Box<Expr>,
119    },
120
121    // Range expression
122    Range {
123        start: Option<Box<Expr>>,
124        end: Option<Box<Expr>>,
125        inclusive: bool,
126    },
127
128    // Break/Continue
129    Break(Option<Box<Expr>>),
130    Continue,
131
132    // Return
133    Return(Option<Box<Expr>>),
134
135    // ── Functions & closures ─────────────────────────────────────
136    /// Named function definition.
137    FnDef {
138        name: String,
139        params: Vec<(String, Type)>,
140        return_type: Option<Type>,
141        body: Box<Expr>,
142    },
143
144    // Function call
145    FnCall {
146        name: String,
147        args: Vec<Expr>,
148    },
149
150    // Method call
151    MethodCall {
152        object: Box<Expr>,
153        method: String,
154        args: Vec<Expr>,
155    },
156
157    // Macro call (println!, format!, etc.)
158    MacroCall {
159        name: String,
160        args: Vec<Expr>,
161    },
162
163    // ── Collections & access ─────────────────────────────────────
164    /// `[a, b, c]`
165    ArrayLiteral(Vec<Expr>),
166
167    /// `[expr; count]`
168    ArrayRepeat {
169        value: Box<Expr>,
170        count: Box<Expr>,
171    },
172
173    // Tuple literal
174    TupleLiteral(Vec<Expr>),
175
176    // Index access
177    Index {
178        object: Box<Expr>,
179        index: Box<Expr>,
180    },
181
182    // Field access
183    FieldAccess {
184        object: Box<Expr>,
185        field: String,
186    },
187
188    // ── Structs ───────────────────────────────────────────────────
189    /// `struct Name { ... }`
190    StructDef {
191        name: String,
192        fields: Vec<(String, Type)>,
193    },
194
195    // Struct instantiation
196    StructInit {
197        name: String,
198        fields: Vec<(String, Expr)>,
199    },
200
201    // ── Match ─────────────────────────────────────────────────────
202    /// `match expr { arms... }`
203    Match {
204        expr: Box<Expr>,
205        arms: Vec<MatchArm>,
206    },
207
208    // ── Type operations ─────────────────────────────────────────
209    /// `expr as Type`
210    TypeCast {
211        expr: Box<Expr>,
212        target_type: Type,
213    },
214
215    // ── Closures & references ────────────────────────────────────
216    /// `|params| body`
217    Closure {
218        params: Vec<(String, Option<Type>)>,
219        body: Box<Expr>,
220    },
221
222    /// `&expr` or `&mut expr`
223    Ref {
224        expr: Box<Expr>,
225        mutable: bool,
226    },
227
228    /// `*expr`
229    Deref(Box<Expr>),
230
231    /// `vec![...]`
232    VecMacro(Vec<Expr>),
233
234    /// The unit value `()`.
235    Unit,
236}
237
238/// Binary operators.
239#[derive(Debug, Clone, PartialEq)]
240pub enum BinOp {
241    Add,
242    Sub,
243    Mul,
244    Div,
245    Mod,
246    Eq,
247    NotEq,
248    Lt,
249    LtEq,
250    Gt,
251    GtEq,
252    And,
253    Or,
254    BitAnd,
255    BitOr,
256    BitXor,
257    Shl,
258    Shr,
259}
260
261/// Unary operators.
262#[derive(Debug, Clone, PartialEq)]
263pub enum UnaryOp {
264    Neg,
265    Not,
266}
267
268/// A single arm in a `match` expression.
269#[derive(Debug, Clone)]
270pub struct MatchArm {
271    pub pattern: Pattern,
272    pub body: Expr,
273}
274
275/// A pattern used in `match` arms.
276#[derive(Debug, Clone)]
277pub enum Pattern {
278    Literal(Expr),
279    Ident(String),
280    Wildcard,
281    Range {
282        start: Box<Expr>,
283        end: Box<Expr>,
284        inclusive: bool,
285    },
286    Or(Vec<Pattern>),
287}