Skip to main content

ling/parser/
ast.rs

1// src/parser/ast.rs
2
3#[derive(Debug, Clone)]
4pub struct Program {
5    pub items: Vec<Item>,
6}
7
8#[derive(Debug, Clone)]
9pub enum Item {
10    Bind(String, Expr),
11    Fn(FnDef),
12    Mod(String, Vec<Item>),
13    TypeAlias(String, String), // type Name = RawType
14    /// `form Name { field, field, ... }` — record/struct definition.
15    /// Field types are parsed but ignored at runtime; only names (in order) survive.
16    Struct(String, Vec<String>),
17    /// `choose Name { Variant, Variant(a, b), ... }` — sum type / enum.
18    /// Each variant carries its name and payload arity (field names are ignored).
19    Enum(String, Vec<EnumVariant>),
20    /// `use "path/to/module"` or `use "path" as ns`
21    Use {
22        path: String,
23        alias: Option<String>,
24    },
25}
26
27#[derive(Debug, Clone)]
28pub struct EnumVariant {
29    pub name: String,
30    pub arity: usize,
31}
32
33#[derive(Debug, Clone)]
34pub struct FnDef {
35    pub name: String,
36    pub is_async: bool,
37    pub params: Vec<String>, // just names; types are parsed but ignored
38    pub body: Vec<Stmt>,
39}
40
41// ─── Expressions ─────────────────────────────────────────────────────────────
42
43#[derive(Debug, Clone)]
44pub enum Expr {
45    Str(String),
46    Number(f64),
47    Bool(bool),
48    Unit,
49    Ident(String),
50    /// `do { stmts }` or anonymous block `{ stmts }`
51    Do(Vec<Stmt>),
52    /// `if cond { then } (else if cond { elif })* (else { else_body })?`
53    If {
54        cond: Box<Expr>,
55        then: Vec<Stmt>,
56        elseifs: Vec<(Expr, Vec<Stmt>)>,
57        else_body: Option<Vec<Stmt>>,
58    },
59    /// `for name in iterable { body }`
60    For {
61        var: String,
62        iter: Box<Expr>,
63        body: Vec<Stmt>,
64    },
65    /// `while cond { body }` / `ขณะที่ cond { body }`
66    While {
67        cond: Box<Expr>,
68        body: Vec<Stmt>,
69    },
70    /// `match expr { arms }`
71    Match(Box<Expr>, Vec<MatchArm>),
72    /// Normal call: `expr(args)`
73    Call(Box<Expr>, Vec<Expr>),
74    /// Method call: `receiver.method(args)`
75    MethodCall {
76        receiver: Box<Expr>,
77        method: String,
78        args: Vec<Expr>,
79    },
80    /// Path like `Mod::fn` or just chained idents; resolved at runtime
81    Path(Vec<String>),
82    /// `lo..hi`
83    Range(Box<Expr>, Box<Expr>),
84    /// `&expr`
85    Ref(Box<Expr>),
86    /// `await expr`
87    Await(Box<Expr>),
88    /// Binary operation
89    BinOp(BinOp, Box<Expr>, Box<Expr>),
90    /// Array/Vec literal `[a, b, c]`
91    Array(Vec<Expr>),
92    /// `expr[idx]`
93    Index(Box<Expr>, Box<Expr>),
94    /// Closure `|| expr` or `|args| expr`
95    Closure(Vec<String>, Box<Expr>),
96    /// Inline assembly: `asm!("instruction")` or `asm!("指令")`
97    Asm(String),
98}
99
100#[derive(Debug, Clone, PartialEq)]
101pub enum BinOp {
102    Add,
103    Sub,
104    Mul,
105    Div,
106    Rem,
107    Eq,
108    Ne,
109    Lt,
110    Gt,
111    Le,
112    Ge,
113    And,
114    Or,
115}
116
117// ─── Statements ──────────────────────────────────────────────────────────────
118
119#[derive(Debug, Clone)]
120pub enum Stmt {
121    Bind(String, Expr),
122    Expr(Expr),
123    Return(Expr),
124}
125
126// ─── Match arms ──────────────────────────────────────────────────────────────
127
128#[derive(Debug, Clone)]
129pub struct MatchArm {
130    pub pattern: Pattern,
131    pub body: Expr,
132}
133
134#[derive(Debug, Clone)]
135pub enum Pattern {
136    Wildcard,
137    Str(String),
138    Number(f64),
139    Bool(bool),
140    Ident(String),
141    /// Ok(inner), Bad(inner), 好(inner), 坏(inner)
142    Constructor(String, Option<Box<Pattern>>),
143    /// User enum variant: `Circle(r)`, `Pair(a, b)`, or nullary `Origin()`.
144    Variant(String, Vec<Pattern>),
145}