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 { path: String, alias: Option<String> },
22}
23
24#[derive(Debug, Clone)]
25pub struct EnumVariant {
26    pub name: String,
27    pub arity: usize,
28}
29
30#[derive(Debug, Clone)]
31pub struct FnDef {
32    pub name: String,
33    pub is_async: bool,
34    pub params: Vec<String>,   // just names; types are parsed but ignored
35    pub body: Vec<Stmt>,
36}
37
38// ─── Expressions ─────────────────────────────────────────────────────────────
39
40#[derive(Debug, Clone)]
41pub enum Expr {
42    Str(String),
43    Number(f64),
44    Bool(bool),
45    Unit,
46    Ident(String),
47    /// `do { stmts }` or anonymous block `{ stmts }`
48    Do(Vec<Stmt>),
49    /// `if cond { then } (else if cond { elif })* (else { else_body })?`
50    If {
51        cond: Box<Expr>,
52        then: Vec<Stmt>,
53        elseifs: Vec<(Expr, Vec<Stmt>)>,
54        else_body: Option<Vec<Stmt>>,
55    },
56    /// `for name in iterable { body }`
57    For {
58        var: String,
59        iter: Box<Expr>,
60        body: Vec<Stmt>,
61    },
62    /// `while cond { body }` / `ขณะที่ cond { body }`
63    While {
64        cond: Box<Expr>,
65        body: Vec<Stmt>,
66    },
67    /// `match expr { arms }`
68    Match(Box<Expr>, Vec<MatchArm>),
69    /// Normal call: `expr(args)`
70    Call(Box<Expr>, Vec<Expr>),
71    /// Method call: `receiver.method(args)`
72    MethodCall {
73        receiver: Box<Expr>,
74        method: String,
75        args: Vec<Expr>,
76    },
77    /// Path like `Mod::fn` or just chained idents; resolved at runtime
78    Path(Vec<String>),
79    /// `lo..hi`
80    Range(Box<Expr>, Box<Expr>),
81    /// `&expr`
82    Ref(Box<Expr>),
83    /// `await expr`
84    Await(Box<Expr>),
85    /// Binary operation
86    BinOp(BinOp, Box<Expr>, Box<Expr>),
87    /// Array/Vec literal `[a, b, c]`
88    Array(Vec<Expr>),
89    /// `expr[idx]`
90    Index(Box<Expr>, Box<Expr>),
91    /// Closure `|| expr` or `|args| expr`
92    Closure(Vec<String>, Box<Expr>),
93}
94
95#[derive(Debug, Clone, PartialEq)]
96pub enum BinOp {
97    Add, Sub, Mul, Div, Rem,
98    Eq, Ne, Lt, Gt, Le, Ge,
99    And, Or,
100}
101
102// ─── Statements ──────────────────────────────────────────────────────────────
103
104#[derive(Debug, Clone)]
105pub enum Stmt {
106    Bind(String, Expr),
107    Expr(Expr),
108    Return(Expr),
109}
110
111// ─── Match arms ──────────────────────────────────────────────────────────────
112
113#[derive(Debug, Clone)]
114pub struct MatchArm {
115    pub pattern: Pattern,
116    pub body: Expr,
117}
118
119#[derive(Debug, Clone)]
120pub enum Pattern {
121    Wildcard,
122    Str(String),
123    Number(f64),
124    Bool(bool),
125    Ident(String),
126    /// Ok(inner), Bad(inner), 好(inner), 坏(inner)
127    Constructor(String, Option<Box<Pattern>>),
128    /// User enum variant: `Circle(r)`, `Pair(a, b)`, or nullary `Origin()`.
129    Variant(String, Vec<Pattern>),
130}