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}