1#[derive(Debug, Clone, PartialEq)]
5pub struct Function {
6 pub params: Vec<String>,
7 pub is_vararg: bool,
8 pub body: Block,
9}
10
11pub type Block = Vec<Stat>;
13
14#[derive(Debug, Clone, PartialEq)]
16pub enum Stat {
17 LocalAssign {
19 names: Vec<String>,
20 exprs: Vec<Expr>,
21 },
22 Assign {
24 targets: Vec<Expr>,
25 values: Vec<Expr>,
26 },
27 Call(CallExpr),
29 DoBlock(Block),
31 While {
33 cond: Expr,
34 body: Block,
35 },
36 Repeat {
38 body: Block,
39 cond: Expr,
40 },
41 If {
43 cond: Expr,
44 then_block: Block,
45 elseif_clauses: Vec<(Expr, Block)>,
46 else_block: Option<Block>,
47 },
48 NumericFor {
50 name: String,
51 start: Expr,
52 limit: Expr,
53 step: Option<Expr>,
54 body: Block,
55 },
56 GenericFor {
58 names: Vec<String>,
59 iterators: Vec<Expr>,
60 body: Block,
61 },
62 Return(Vec<Expr>),
64 Break,
66 Comment(String),
68}
69
70#[derive(Debug, Clone, PartialEq)]
72pub enum Expr {
73 Nil,
75 Bool(bool),
77 Number(NumLit),
79 StringLit(Vec<u8>),
81 VarArg,
83 Name(String),
85 Index(Box<Expr>, Box<Expr>),
87 Field(Box<Expr>, String),
89 MethodCall(Box<CallExpr>),
91 FuncCall(Box<CallExpr>),
93 BinOp(BinOp, Box<Expr>, Box<Expr>),
95 UnOp(UnOp, Box<Expr>),
97 FunctionDef(Box<Function>),
99 Table(Vec<TableField>),
101 Register(u32),
103 Upvalue(u32),
105 Global(String),
107}
108
109#[derive(Debug, Clone, PartialEq)]
111pub enum NumLit {
112 Int(i64),
113 Float(f64),
114}
115
116#[derive(Debug, Clone, PartialEq)]
118pub struct CallExpr {
119 pub func: Expr,
120 pub args: Vec<Expr>,
121}
122
123#[derive(Debug, Clone, PartialEq)]
125pub enum TableField {
126 IndexField(Expr, Expr),
128 NameField(String, Expr),
130 Value(Expr),
132}
133
134#[derive(Debug, Clone, Copy, PartialEq, Eq)]
136pub enum BinOp {
137 Add,
138 Sub,
139 Mul,
140 Div,
141 Mod,
142 Pow,
143 Concat,
144 Eq,
145 Ne,
146 Lt,
147 Le,
148 Gt,
149 Ge,
150 And,
151 Or,
152}
153
154#[derive(Debug, Clone, Copy, PartialEq, Eq)]
156pub enum UnOp {
157 Neg,
158 Not,
159 Len,
160}
161
162impl BinOp {
164 pub fn precedence(self) -> u8 {
165 match self {
166 BinOp::Or => 1,
167 BinOp::And => 2,
168 BinOp::Eq | BinOp::Ne | BinOp::Lt | BinOp::Le | BinOp::Gt | BinOp::Ge => 3,
169 BinOp::Concat => 4,
170 BinOp::Add | BinOp::Sub => 5,
171 BinOp::Mul | BinOp::Div | BinOp::Mod => 6,
172 BinOp::Pow => 7,
173 }
174 }
175
176 pub fn is_right_assoc(self) -> bool {
178 matches!(self, BinOp::Pow | BinOp::Concat)
179 }
180
181 pub fn symbol(self) -> &'static str {
182 match self {
183 BinOp::Add => "+",
184 BinOp::Sub => "-",
185 BinOp::Mul => "*",
186 BinOp::Div => "/",
187 BinOp::Mod => "%",
188 BinOp::Pow => "^",
189 BinOp::Concat => "..",
190 BinOp::Eq => "==",
191 BinOp::Ne => "~=",
192 BinOp::Lt => "<",
193 BinOp::Le => "<=",
194 BinOp::Gt => ">",
195 BinOp::Ge => ">=",
196 BinOp::And => "and",
197 BinOp::Or => "or",
198 }
199 }
200}
201
202impl UnOp {
203 pub fn precedence(self) -> u8 {
204 8 }
206
207 pub fn symbol(self) -> &'static str {
208 match self {
209 UnOp::Neg => "-",
210 UnOp::Not => "not ",
211 UnOp::Len => "#",
212 }
213 }
214}