rslua_march1917/
ast.rs

1use crate::tokens::TokenType;
2use crate::types::Source;
3use crate::types::{FloatType, IntType};
4#[derive(Copy, Clone, PartialEq, Debug)]
5pub enum UnOp {
6    Minus,
7    BNot,
8    Not,
9    Len,
10    None,
11}
12
13impl UnOp {
14    pub fn from_token(token: TokenType) -> UnOp {
15        match token {
16            TokenType::Minus => UnOp::Minus,
17            TokenType::BXor => UnOp::BNot,
18            TokenType::Not => UnOp::Not,
19            TokenType::Len => UnOp::Len,
20            _ => UnOp::None,
21        }
22    }
23    pub fn priority(self) -> u8 {
24        match self {
25            _ => 12,
26        }
27    }
28}
29
30#[derive(Copy, Clone, PartialEq, Debug)]
31pub enum BinOp {
32    Add,
33    Minus,
34    Mul,
35    Mod,
36    Pow,
37    Div,
38    IDiv,
39    BAnd,
40    BOr,
41    BXor,
42    Shl,
43    Shr,
44    Concat,
45    Ne,
46    Eq,
47    Lt,
48    Le,
49    Gt,
50    Ge,
51    And,
52    Or,
53    None,
54}
55
56pub struct BinOpPriority {
57    pub left: u8,
58    pub right: u8,
59}
60
61impl BinOp {
62    pub fn from_token(token: TokenType) -> BinOp {
63        match token {
64            TokenType::Add => BinOp::Add,
65            TokenType::Minus => BinOp::Minus,
66            TokenType::Mul => BinOp::Mul,
67            TokenType::Mod => BinOp::Mod,
68            TokenType::Pow => BinOp::Pow,
69            TokenType::Div => BinOp::Div,
70            TokenType::IDiv => BinOp::IDiv,
71            TokenType::BAnd => BinOp::BAnd,
72            TokenType::BOr => BinOp::BOr,
73            TokenType::BXor => BinOp::BXor,
74            TokenType::Shl => BinOp::Shl,
75            TokenType::Shr => BinOp::Shr,
76            TokenType::Concat => BinOp::Concat,
77            TokenType::Ne => BinOp::Ne,
78            TokenType::Eq => BinOp::Eq,
79            TokenType::Lt => BinOp::Lt,
80            TokenType::Le => BinOp::Le,
81            TokenType::Gt => BinOp::Gt,
82            TokenType::Ge => BinOp::Ge,
83            TokenType::And => BinOp::And,
84            TokenType::Or => BinOp::Or,
85            _ => BinOp::None,
86        }
87    }
88
89    pub fn priority(self) -> BinOpPriority {
90        match self {
91            BinOp::Or => BinOpPriority { left: 1, right: 1 },
92            BinOp::And => BinOpPriority { left: 2, right: 2 },
93            BinOp::Eq | BinOp::Ne | BinOp::Lt | BinOp::Gt | BinOp::Le | BinOp::Ge => {
94                BinOpPriority { left: 3, right: 3 }
95            }
96            BinOp::BOr => BinOpPriority { left: 4, right: 4 },
97            BinOp::BXor => BinOpPriority { left: 5, right: 5 },
98            BinOp::BAnd => BinOpPriority { left: 6, right: 6 },
99            BinOp::Shl | BinOp::Shr => BinOpPriority { left: 7, right: 7 },
100            BinOp::Concat => BinOpPriority { left: 9, right: 8 },
101            BinOp::Add | BinOp::Minus => BinOpPriority {
102                left: 10,
103                right: 10,
104            },
105            BinOp::Mul | BinOp::Mod | BinOp::Div | BinOp::IDiv => BinOpPriority {
106                left: 11,
107                right: 11,
108            },
109            BinOp::Pow => BinOpPriority {
110                left: 14,
111                right: 13,
112            },
113            _ => unreachable!(),
114        }
115    }
116
117    pub fn is_comp(&self) -> bool {
118        match self {
119            BinOp::Le | BinOp::Ge | BinOp::Ne | BinOp::Eq | BinOp::Lt | BinOp::Gt => true,
120            _ => false,
121        }
122    }
123}
124
125#[derive(PartialEq, Debug, Clone)]
126pub enum Expr {
127    Nil,
128    True,
129    False,
130    VarArg,
131    Float(FloatType),
132    Int(IntType),
133    String(String),
134    Name(String),
135    ParenExpr(Box<Expr>),
136    FuncBody(FuncBody),
137    Table(Table),
138    BinExpr(BinExpr),
139    UnExpr(UnExpr),
140    SuffixedExpr(SuffixedExpr),
141}
142
143impl Expr {
144    pub fn has_multi_ret(&self) -> bool {
145        match self {
146            Expr::SuffixedExpr(s) => s.has_multi_ret(),
147            Expr::VarArg => true,
148            _ => false,
149        }
150    }
151}
152
153#[derive(PartialEq, Debug,Clone)]
154pub enum Assignable {
155    Name(String),
156    SuffixedExpr(SuffixedExpr),
157}
158
159impl Expr {
160    pub fn to_assignable(self) -> Assignable {
161        match self {
162            Expr::Name(s) => Assignable::Name(s),
163            Expr::SuffixedExpr(s) => Assignable::SuffixedExpr(s),
164            _ => unreachable!(),
165        }
166    }
167}
168
169#[derive(PartialEq, Debug,Clone)]
170pub struct SuffixedExpr {
171    pub primary: Box<Expr>,
172    pub suffixes: Vec<Suffix>,
173}
174
175impl SuffixedExpr {
176    pub fn has_multi_ret(&self) -> bool {
177        todo!()
178    }
179}
180
181#[derive(PartialEq, Debug,Clone)]
182pub enum Suffix {
183    Attr(String),
184    Index(Expr),
185    Method(String),
186    FuncArgs(FuncArgs),
187}
188
189#[derive(PartialEq, Debug,Clone)]
190pub enum FuncArgs {
191    Exprs(Vec<Expr>),
192    Table(Table),
193    String(String),
194}
195
196#[derive(PartialEq, Debug,Clone)]
197pub struct Table {
198    pub fields: Vec<Field>,
199}
200
201#[derive(PartialEq, Debug,Clone)]
202pub enum Field {
203    ListField(Expr),
204    RecField(RecField),
205}
206
207#[derive(PartialEq, Debug,Clone)]
208pub struct RecField {
209    pub key: FieldKey,
210    pub value: Expr,
211}
212
213#[derive(PartialEq, Debug,Clone)]
214pub enum FieldKey {
215    Name(String),
216    Expr(Expr),
217}
218
219#[derive(PartialEq, Debug,Clone)]
220pub struct UnExpr {
221    pub op: UnOp,
222    pub expr: Box<Expr>,
223}
224
225#[derive(PartialEq, Debug,Clone)]
226pub struct BinExpr {
227    pub op: BinOp,
228    pub left: Box<Expr>,
229    pub right: Box<Expr>,
230}
231
232#[derive(PartialEq, Debug, Clone)]
233pub struct IfStat {
234    pub cond_blocks: Vec<CondBlock>,
235    pub else_block: Option<Block>,
236}
237
238#[derive(PartialEq, Debug, Clone)]
239pub struct CondBlock {
240    pub cond: Expr,
241    pub block: Block,
242}
243
244#[derive(PartialEq, Debug, Clone)]
245pub struct WhileStat {
246    pub cond: Expr,
247    pub block: Block,
248}
249
250#[derive(PartialEq, Debug,Clone)]
251pub struct DoBlock {
252    pub block: Block,
253}
254
255#[derive(PartialEq, Debug,Clone)]
256pub enum ForStat {
257    ForNum(ForNum),
258    ForList(ForList),
259}
260
261#[derive(PartialEq, Debug,Clone)]
262pub struct ForNum {
263    pub var: String,
264    pub init: Expr,
265    pub limit: Expr,
266    pub step: Option<Expr>,
267    pub body: Block,
268}
269
270#[derive(PartialEq, Debug,Clone)]
271pub struct ForList {
272    pub vars: Vec<String>,
273    pub exprs: Vec<Expr>,
274    pub body: Block,
275}
276
277#[derive(PartialEq, Debug,Clone)]
278pub struct RepeatStat {
279    pub cond: Expr,
280    pub block: Block,
281}
282
283#[derive(PartialEq, Debug,Clone)]
284pub enum FuncType {
285    Global,
286    Local,
287}
288
289#[derive(PartialEq, Debug,Clone)]
290pub struct FuncStat {
291    pub func_type: FuncType,
292    pub func_name: FuncName,
293    pub body: FuncBody,
294}
295
296#[derive(PartialEq, Debug,Clone)]
297pub struct FuncName {
298    pub fields: Vec<String>,
299    pub method: Option<String>,
300}
301
302#[derive(PartialEq, Debug, Clone)]
303pub struct FuncBody {
304    pub params: Vec<Param>,
305    pub block: Block,
306}
307
308#[derive(PartialEq, Debug, Clone)]
309pub enum Param {
310    VarArg,
311    Name(String),
312}
313
314#[derive(PartialEq, Debug, Clone)]
315pub struct LocalStat {
316    pub names: Vec<String>,
317    pub exprs: Vec<Expr>,
318}
319
320#[derive(PartialEq, Debug, Clone)]
321pub struct LabelStat {
322    pub label: String,
323}
324
325#[derive(PartialEq, Debug, Clone)]
326pub struct RetStat {
327    pub exprs: Vec<Expr>,
328}
329
330#[derive(PartialEq, Debug,Clone)]
331pub struct BreakStat {}
332
333#[derive(PartialEq, Debug,Clone)]
334pub struct GotoStat {
335    pub label: String,
336}
337
338#[derive(PartialEq, Debug,Clone)]
339pub struct AssignStat {
340    pub left: Vec<Assignable>,
341    pub right: Vec<Expr>,
342}
343
344#[derive(PartialEq, Debug,Clone)]
345pub struct CallStat {
346    pub call: Assignable,
347}
348
349#[derive(PartialEq, Debug,Clone)]
350pub struct CommentStat {
351    pub is_single_line: bool,
352    pub comment: String,
353}
354
355#[derive(PartialEq, Debug, Clone)]
356pub enum Stat {
357    IfStat(IfStat),
358    WhileStat(WhileStat),
359    DoBlock(DoBlock),
360    ForStat(ForStat),
361    RepeatStat(RepeatStat),
362    FuncStat(FuncStat),
363    LocalStat(LocalStat),
364    LabelStat(LabelStat),
365    RetStat(RetStat),
366    BreakStat(BreakStat),
367    GotoStat(GotoStat),
368    AssignStat(AssignStat),
369    CallStat(CallStat),
370    CommentStat(CommentStat),
371}
372
373impl Stat {
374    pub fn to_stat_info(self) -> StatInfo {
375        StatInfo {
376            stat: self,
377            source: Source::new(),
378        }
379    }
380}
381
382#[derive(Debug, Clone)]
383pub struct StatInfo {
384    pub stat: Stat,
385    pub source: Source,
386}
387
388impl StatInfo {
389    pub fn from_stat(stat: Stat) -> Self {
390        StatInfo {
391            stat,
392            source: Source::new(),
393        }
394    }
395}
396
397impl PartialEq for StatInfo {
398    fn eq(&self, other: &Self) -> bool {
399        self.stat == other.stat
400    }
401}
402
403#[derive(PartialEq, Debug, Clone)]
404pub struct Block {
405    pub stats: Vec<StatInfo>,
406}