1use std::fmt;
2
3#[derive(Debug, PartialEq, Clone)]
4pub struct Variable {
5 identifier: u8,
6}
7
8impl Variable {
9 pub fn new(identifier: u8) -> Self {
10 debug_assert!(identifier.is_ascii_uppercase());
11 Self { identifier }
12 }
13
14 pub fn identifier(&self) -> u8 {
15 self.identifier
16 }
17}
18
19impl fmt::Display for Variable {
20 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
21 write!(f, "{}", self.identifier as char)
22 }
23}
24
25#[derive(Debug, PartialEq, Clone)]
26pub struct NumberLiteral {
27 value: i16,
28}
29
30impl NumberLiteral {
31 pub fn new(value: i16) -> Self {
32 Self { value }
33 }
34
35 pub fn value(&self) -> i16 {
36 self.value
37 }
38}
39
40impl fmt::Display for NumberLiteral {
41 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
42 write!(f, "{}", self.value)
43 }
44}
45
46#[derive(Debug, PartialEq, Clone)]
47pub struct StringLiteral {
48 value: Vec<u8>,
49}
50
51impl StringLiteral {
52 pub fn new(value: Vec<u8>) -> Self {
53 Self { value }
54 }
55
56 pub fn value(&self) -> &Vec<u8> {
57 &self.value
58 }
59}
60
61impl fmt::Display for StringLiteral {
62 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
63 write!(f, "{}", String::from_utf8_lossy(&self.value))
64 }
65}
66
67#[derive(Debug, PartialEq, Clone)]
68pub enum Factor {
69 Variable(Variable),
70 NumberLiteral(NumberLiteral),
71 Expression(Box<Expression>),
72}
73
74impl fmt::Display for Factor {
75 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
76 match self {
77 Factor::Variable(variable) => write!(f, "{}", variable),
78 Factor::NumberLiteral(number_literal) => write!(f, "{}", number_literal),
79 Factor::Expression(expression) => write!(f, "({})", expression),
80 }
81 }
82}
83
84#[derive(Debug, PartialEq, Clone)]
85pub struct Term {
86 factor: Factor,
87 operations: Vec<(MultiplicativeOperator, Factor)>,
88}
89
90impl Term {
91 pub fn new(factor: Factor, next: Vec<(MultiplicativeOperator, Factor)>) -> Self {
92 Self {
93 factor,
94 operations: next,
95 }
96 }
97
98 pub fn factor(&self) -> &Factor {
99 &self.factor
100 }
101
102 pub fn operations(&self) -> &[(MultiplicativeOperator, Factor)] {
103 &self.operations
104 }
105}
106
107impl fmt::Display for Term {
108 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
109 write!(f, "{}", self.factor)?;
110
111 for operation in &self.operations {
112 write!(f, " {} {}", operation.0, operation.1)?;
113 }
114
115 Ok(())
116 }
117}
118
119#[derive(Debug, PartialEq, Clone)]
120pub enum MultiplicativeOperator {
121 Multiplication,
122 Division,
123}
124
125impl fmt::Display for MultiplicativeOperator {
126 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
127 match self {
128 MultiplicativeOperator::Multiplication => write!(f, "*"),
129 MultiplicativeOperator::Division => write!(f, "/"),
130 }
131 }
132}
133
134#[derive(Debug, PartialEq, Clone)]
135pub struct Expression {
136 unary_operator: Option<AdditiveOperator>,
137 term: Term,
138 others: Vec<(AdditiveOperator, Term)>,
139}
140
141impl Expression {
142 pub fn new(
143 unary_operator: Option<AdditiveOperator>,
144 term: Term,
145 others: Vec<(AdditiveOperator, Term)>,
146 ) -> Self {
147 Self {
148 unary_operator,
149 term,
150 others,
151 }
152 }
153
154 pub fn unary_operator(&self) -> &Option<AdditiveOperator> {
155 &self.unary_operator
156 }
157
158 pub fn term(&self) -> &Term {
159 &self.term
160 }
161
162 pub fn others(&self) -> &[(AdditiveOperator, Term)] {
163 &self.others
164 }
165}
166
167impl fmt::Display for Expression {
168 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
169 if let Some(operator) = &self.unary_operator {
170 write!(f, "{}", operator)?;
171 }
172
173 write!(f, "{}", self.term)?;
174
175 for (operator, term) in &self.others {
176 write!(f, " {} {}", operator, term)?;
177 }
178
179 Ok(())
180 }
181}
182
183#[derive(Debug, PartialEq, Clone)]
184pub enum AdditiveOperator {
185 Addition,
186 Subtraction,
187}
188
189impl fmt::Display for AdditiveOperator {
190 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
191 match self {
192 AdditiveOperator::Addition => write!(f, "+"),
193 AdditiveOperator::Subtraction => write!(f, "-"),
194 }
195 }
196}
197
198#[derive(Debug, PartialEq, Clone)]
199pub enum ExpressionListElement {
200 StringLiteral(StringLiteral),
201 Expression(Expression),
202}
203
204impl fmt::Display for ExpressionListElement {
205 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
206 match self {
207 ExpressionListElement::StringLiteral(string_literal) => write!(f, "{}", string_literal),
208 ExpressionListElement::Expression(expression) => write!(f, "{}", expression),
209 }
210 }
211}
212
213#[derive(Debug, PartialEq, Clone)]
214pub enum Statement {
215 Print {
216 expression_list: Vec<ExpressionListElement>,
217 },
218 If {
219 left: Expression,
220 operator: RelationalOperator,
221 right: Expression,
222 then: Box<Statement>,
223 },
224 Goto {
225 expression: Expression,
226 },
227 Input {
228 variable_list: Vec<Variable>,
229 },
230 Let {
231 variable: Variable,
232 expression: Expression,
233 },
234 GoSub {
235 expression: Expression,
236 },
237 Return,
238 Clear,
239 List,
240 Run,
241 End,
242}
243
244impl fmt::Display for Statement {
245 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
246 match self {
247 Statement::Print { expression_list } => {
248 write!(f, "PRINT ")?;
249
250 for (i, element) in expression_list.iter().enumerate() {
251 if i > 0 {
252 write!(f, ", ")?;
253 }
254
255 write!(f, "{}", element)?;
256 }
257
258 Ok(())
259 }
260 Statement::If {
261 left,
262 operator,
263 right,
264 then,
265 } => write!(f, "IF {} {} {} THEN {}", left, operator, right, then),
266 Statement::Goto { expression } => write!(f, "GOTO {}", expression),
267 Statement::Input { variable_list } => {
268 write!(f, "INPUT ")?;
269
270 for (i, variable) in variable_list.iter().enumerate() {
271 if i > 0 {
272 write!(f, ", ")?;
273 }
274
275 write!(f, "{}", variable)?;
276 }
277
278 Ok(())
279 }
280 Statement::Let {
281 variable,
282 expression,
283 } => write!(f, "LET {} = {}", variable, expression),
284 Statement::GoSub { expression } => write!(f, "GOSUB {}", expression),
285 Statement::Return => write!(f, "RETURN"),
286 Statement::Clear => write!(f, "CLEAR"),
287 Statement::List => write!(f, "LIST"),
288 Statement::Run => write!(f, "RUN"),
289 Statement::End => write!(f, "END"),
290 }
291 }
292}
293
294#[derive(Debug, PartialEq, Clone)]
295pub enum RelationalOperator {
296 Equal,
297 NotEqual,
298 LessThan,
299 LessThanOrEqual,
300 GreaterThan,
301 GreaterThanOrEqual,
302}
303
304impl fmt::Display for RelationalOperator {
305 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
306 match self {
307 RelationalOperator::Equal => write!(f, "="),
308 RelationalOperator::NotEqual => write!(f, "<>"),
309 RelationalOperator::LessThan => write!(f, "<"),
310 RelationalOperator::LessThanOrEqual => write!(f, "<="),
311 RelationalOperator::GreaterThan => write!(f, ">"),
312 RelationalOperator::GreaterThanOrEqual => write!(f, ">="),
313 }
314 }
315}
316
317#[derive(Debug, PartialEq, Clone)]
318pub struct Line {
319 number: Option<u8>,
320 statement: Statement,
321}
322
323impl Line {
324 pub fn new(number: Option<u8>, statement: Statement) -> Self {
325 Self { number, statement }
326 }
327
328 pub fn number(&self) -> Option<u8> {
329 self.number
330 }
331
332 pub fn statement(&self) -> &Statement {
333 &self.statement
334 }
335}
336
337impl fmt::Display for Line {
338 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
339 if let Some(number) = self.number {
340 write!(f, "{} ", number)?;
341 }
342
343 write!(f, "{}", self.statement)
344 }
345}