basic/lang/
ast.rs

1use super::Column;
2use std::rc::Rc;
3
4#[derive(Debug, PartialEq)]
5pub enum Statement {
6    Clear(Column),
7    Cls(Column),
8    Cont(Column),
9    Data(Column, Vec<Expression>),
10    Def(Column, Variable, Vec<Variable>, Expression),
11    Defdbl(Column, Variable, Variable),
12    Defint(Column, Variable, Variable),
13    Defsng(Column, Variable, Variable),
14    Defstr(Column, Variable, Variable),
15    Delete(Column, Expression, Expression),
16    Dim(Column, Vec<Variable>),
17    End(Column),
18    Erase(Column, Vec<Variable>),
19    For(Column, Variable, Expression, Expression, Expression),
20    Gosub(Column, Expression),
21    Goto(Column, Expression),
22    If(Column, Expression, Vec<Statement>, Vec<Statement>),
23    Input(Column, Expression, Expression, Vec<Variable>),
24    Let(Column, Variable, Expression),
25    List(Column, Expression, Expression),
26    Load(Column, Expression),
27    Mid(Column, Variable, Expression, Expression, Expression),
28    New(Column),
29    Next(Column, Vec<Variable>),
30    OnGoto(Column, Expression, Vec<Expression>),
31    OnGosub(Column, Expression, Vec<Expression>),
32    Print(Column, Vec<Expression>),
33    Read(Column, Vec<Variable>),
34    Renum(Column, Expression, Expression, Expression),
35    Restore(Column, Expression),
36    Return(Column),
37    Run(Column, Expression),
38    Save(Column, Expression),
39    Stop(Column),
40    Swap(Column, Variable, Variable),
41    Troff(Column),
42    Tron(Column),
43    Wend(Column),
44    While(Column, Expression),
45}
46
47#[derive(Debug, PartialEq, Clone)]
48pub enum Variable {
49    Unary(Column, Ident),
50    Array(Column, Ident, Vec<Expression>),
51}
52
53#[derive(Debug, PartialEq, Clone)]
54pub enum Expression {
55    Variable(Variable),
56    Single(Column, f32),
57    Double(Column, f64),
58    Integer(Column, i16),
59    String(Column, Rc<str>),
60    Negation(Column, Box<Expression>),
61    Power(Column, Box<Expression>, Box<Expression>),
62    Multiply(Column, Box<Expression>, Box<Expression>),
63    Divide(Column, Box<Expression>, Box<Expression>),
64    DivideInt(Column, Box<Expression>, Box<Expression>),
65    Modulo(Column, Box<Expression>, Box<Expression>),
66    Add(Column, Box<Expression>, Box<Expression>),
67    Subtract(Column, Box<Expression>, Box<Expression>),
68    Equal(Column, Box<Expression>, Box<Expression>),
69    NotEqual(Column, Box<Expression>, Box<Expression>),
70    Less(Column, Box<Expression>, Box<Expression>),
71    LessEqual(Column, Box<Expression>, Box<Expression>),
72    Greater(Column, Box<Expression>, Box<Expression>),
73    GreaterEqual(Column, Box<Expression>, Box<Expression>),
74    Not(Column, Box<Expression>),
75    And(Column, Box<Expression>, Box<Expression>),
76    Or(Column, Box<Expression>, Box<Expression>),
77    Xor(Column, Box<Expression>, Box<Expression>),
78    Imp(Column, Box<Expression>, Box<Expression>),
79    Eqv(Column, Box<Expression>, Box<Expression>),
80}
81
82#[derive(Debug, PartialEq, Clone)]
83pub enum Ident {
84    Plain(Rc<str>),
85    String(Rc<str>),
86    Single(Rc<str>),
87    Double(Rc<str>),
88    Integer(Rc<str>),
89}
90
91pub trait Visitor {
92    fn visit_statement(&mut self, _: &Statement) {}
93    fn visit_variable(&mut self, _: &Variable) {}
94    fn visit_expression(&mut self, _: &Expression) {}
95}
96
97pub trait AcceptVisitor {
98    fn accept<V: Visitor>(&self, visitor: &mut V);
99}
100
101impl AcceptVisitor for Variable {
102    fn accept<V: Visitor>(&self, visitor: &mut V) {
103        use Variable::*;
104        match self {
105            Unary(..) => {}
106            Array(_, _, vec_expr) => {
107                for expr in vec_expr {
108                    expr.accept(visitor);
109                }
110            }
111        }
112        visitor.visit_variable(self)
113    }
114}
115
116impl AcceptVisitor for Statement {
117    fn accept<V: Visitor>(&self, visitor: &mut V) {
118        use Statement::*;
119        match self {
120            Clear(_) | Cls(_) | Cont(_) | End(_) | New(_) | Stop(_) | Troff(_) | Tron(_)
121            | Return(_) | Wend(_) => {}
122            Data(_, vec_expr) | Print(_, vec_expr) => {
123                for v in vec_expr {
124                    v.accept(visitor);
125                }
126            }
127            Def(_, var, vec_var, expr) => {
128                var.accept(visitor);
129                for v in vec_var {
130                    v.accept(visitor);
131                }
132                expr.accept(visitor);
133            }
134            Defdbl(_, var1, var2)
135            | Defint(_, var1, var2)
136            | Defsng(_, var1, var2)
137            | Defstr(_, var1, var2)
138            | Swap(_, var1, var2) => {
139                var1.accept(visitor);
140                var2.accept(visitor);
141            }
142            Mid(_, var, expr1, expr2, expr3) | For(_, var, expr1, expr2, expr3) => {
143                var.accept(visitor);
144                expr1.accept(visitor);
145                expr2.accept(visitor);
146                expr3.accept(visitor);
147            }
148            Gosub(_, expr)
149            | Goto(_, expr)
150            | Load(_, expr)
151            | Restore(_, expr)
152            | Run(_, expr)
153            | Save(_, expr)
154            | While(_, expr) => {
155                expr.accept(visitor);
156            }
157            If(_, predicate, then_stmt, else_stmt) => {
158                predicate.accept(visitor);
159                for stmt in then_stmt {
160                    stmt.accept(visitor);
161                }
162                for stmt in else_stmt {
163                    stmt.accept(visitor);
164                }
165            }
166            Let(_, var, expr) => {
167                var.accept(visitor);
168                expr.accept(visitor);
169            }
170            Delete(_, expr1, expr2) | List(_, expr1, expr2) => {
171                expr1.accept(visitor);
172                expr2.accept(visitor);
173            }
174            Input(_, expr1, expr2, vec_var) => {
175                expr1.accept(visitor);
176                expr2.accept(visitor);
177                for var in vec_var {
178                    var.accept(visitor);
179                }
180            }
181            OnGoto(_, expr, vec_expr) | OnGosub(_, expr, vec_expr) => {
182                expr.accept(visitor);
183                for expr in vec_expr {
184                    expr.accept(visitor);
185                }
186            }
187            Renum(_, expr1, expr2, expr3) => {
188                expr1.accept(visitor);
189                expr2.accept(visitor);
190                expr3.accept(visitor);
191            }
192            Dim(_, vec_var) | Erase(_, vec_var) | Next(_, vec_var) | Read(_, vec_var) => {
193                for var in vec_var {
194                    var.accept(visitor);
195                }
196            }
197        }
198        visitor.visit_statement(self)
199    }
200}
201
202impl AcceptVisitor for Expression {
203    fn accept<V: Visitor>(&self, visitor: &mut V) {
204        use Expression::*;
205        match self {
206            Single(..) | Double(..) | Integer(..) | String(..) => {}
207            Variable(var) => var.accept(visitor),
208            Negation(_, expr) | Not(_, expr) => expr.accept(visitor),
209            Power(_, expr1, expr2)
210            | Multiply(_, expr1, expr2)
211            | Divide(_, expr1, expr2)
212            | DivideInt(_, expr1, expr2)
213            | Modulo(_, expr1, expr2)
214            | Add(_, expr1, expr2)
215            | Subtract(_, expr1, expr2)
216            | Equal(_, expr1, expr2)
217            | NotEqual(_, expr1, expr2)
218            | Less(_, expr1, expr2)
219            | LessEqual(_, expr1, expr2)
220            | Greater(_, expr1, expr2)
221            | GreaterEqual(_, expr1, expr2)
222            | And(_, expr1, expr2)
223            | Or(_, expr1, expr2)
224            | Xor(_, expr1, expr2)
225            | Imp(_, expr1, expr2)
226            | Eqv(_, expr1, expr2) => {
227                expr1.accept(visitor);
228                expr2.accept(visitor);
229            }
230        }
231        visitor.visit_expression(self)
232    }
233}