1use std::collections::HashMap;
4
5#[derive(Debug, Clone, PartialEq)]
8pub enum Expr {
9 Nil,
11 Bool(bool),
13 Int(i64),
15 Float(f64),
17 Str(String),
19 Vararg,
21 Ident(String),
23 Index { table: Box<Expr>, key: Box<Expr> },
25 Field { table: Box<Expr>, name: String },
27 Call { callee: Box<Expr>, args: Vec<Expr> },
29 MethodCall { obj: Box<Expr>, method: String, args: Vec<Expr> },
31 Unary { op: UnOp, expr: Box<Expr> },
33 Binary { op: BinOp, lhs: Box<Expr>, rhs: Box<Expr> },
35 TableCtor(Vec<TableField>),
37 FuncExpr { params: Vec<String>, vararg: bool, body: Vec<Stmt> },
39 Ternary { cond: Box<Expr>, then_val: Box<Expr>, else_val: Box<Expr> },
41}
42
43#[derive(Debug, Clone, PartialEq)]
44pub enum TableField {
45 ExprKey(Expr, Expr),
47 NameKey(String, Expr),
49 Value(Expr),
51}
52
53#[derive(Debug, Clone, Copy, PartialEq, Eq)]
54pub enum UnOp {
55 Neg, Not, Len, BitNot, }
60
61#[derive(Debug, Clone, Copy, PartialEq, Eq)]
62pub enum BinOp {
63 Add, Sub, Mul, Div, IDiv, Mod, Pow,
64 Concat, Eq, NotEq, Lt, LtEq, Gt, GtEq,
66 And, Or,
67 BitAnd, BitOr, BitXor, Shl, Shr,
68}
69
70impl BinOp {
71 pub fn precedence(self) -> u8 {
72 match self {
73 BinOp::Or => 1,
74 BinOp::And => 2,
75 BinOp::Eq | BinOp::NotEq
76 | BinOp::Lt | BinOp::LtEq
77 | BinOp::Gt | BinOp::GtEq => 3,
78 BinOp::Concat => 4,
79 BinOp::BitOr => 5,
80 BinOp::BitXor => 6,
81 BinOp::BitAnd => 7,
82 BinOp::Shl | BinOp::Shr => 8,
83 BinOp::Add | BinOp::Sub => 9,
84 BinOp::Mul | BinOp::Div
85 | BinOp::IDiv | BinOp::Mod => 10,
86 BinOp::Pow => 12,
87 }
88 }
89
90 pub fn is_right_assoc(self) -> bool {
91 matches!(self, BinOp::Pow | BinOp::Concat)
92 }
93}
94
95#[derive(Debug, Clone, PartialEq)]
98pub enum Stmt {
99 LocalDecl { name: String, init: Option<Expr> },
101 LocalMulti { names: Vec<String>, inits: Vec<Expr> },
103 Assign { target: Vec<Expr>, value: Vec<Expr> },
105 CompoundAssign { target: Expr, op: BinOp, value: Expr },
107 Call(Expr),
109 Do(Vec<Stmt>),
111 While { cond: Expr, body: Vec<Stmt> },
113 RepeatUntil { body: Vec<Stmt>, cond: Expr },
115 If { cond: Expr, then_body: Vec<Stmt>, elseif_branches: Vec<(Expr, Vec<Stmt>)>, else_body: Option<Vec<Stmt>> },
117 NumericFor { var: String, start: Expr, limit: Expr, step: Option<Expr>, body: Vec<Stmt> },
119 GenericFor { vars: Vec<String>, iter: Vec<Expr>, body: Vec<Stmt> },
121 FuncDecl { name: Vec<String>, params: Vec<String>, vararg: bool, body: Vec<Stmt> },
123 LocalFunc { name: String, params: Vec<String>, vararg: bool, body: Vec<Stmt> },
125 Return(Vec<Expr>),
127 Break,
129 Continue,
131 Match { expr: Expr, arms: Vec<MatchArm> },
133 Import { path: String, alias: Option<String> },
135 Export(String),
137 Expr(Expr),
139}
140
141#[derive(Debug, Clone, PartialEq)]
142pub struct MatchArm {
143 pub pattern: MatchPattern,
144 pub body: Vec<Stmt>,
145}
146
147#[derive(Debug, Clone, PartialEq)]
148pub enum MatchPattern {
149 Literal(Expr),
150 Ident(String),
151 Wildcard,
152 Table(Vec<(String, MatchPattern)>),
153}
154
155#[derive(Debug, Clone)]
159pub struct Script {
160 pub name: String,
161 pub stmts: Vec<Stmt>,
162}