1use super::token::{self, Literal, Operator, Token, Word};
2use super::{ast::*, Column, Error, LineNumber, MaxValue};
3use crate::error;
4use std::collections::HashMap;
5
6type Result<T> = std::result::Result<T, Error>;
7
8const FN_RESERVED: &str = "FN RESERVED FOR FUNCTIONS";
9const ARRAY_NOT_ALLOWED: &str = "ARRAY NOT ALLOWED";
10const EXPECTED_VARIABLE: &str = "EXPECTED VARIABLE";
11
12pub fn parse(line_number: LineNumber, tokens: &[Token]) -> Result<Vec<Statement>> {
13 match BasicParser::parse(tokens) {
14 Err(e) => Err(e.in_line_number(line_number)),
15 Ok(r) => Ok(r),
16 }
17}
18
19struct BasicParser<'a> {
20 token_stream: std::slice::Iter<'a, Token>,
21 peeked: Option<&'a Token>,
22 rem: bool,
23 col: Column,
24}
25
26impl<'a> BasicParser<'a> {
27 fn parse(tokens: &'a [Token]) -> Result<Vec<Statement>> {
28 let mut parse = BasicParser {
29 token_stream: tokens.iter(),
30 peeked: None,
31 rem: false,
32 col: 0..0,
33 };
34 match parse.peek() {
35 Some(Token::Literal(Literal::Integer(_)))
36 | Some(Token::Literal(Literal::Single(_)))
37 | Some(Token::Literal(Literal::Double(_))) => {
38 return Err(error!(UndefinedLine, ..&parse.col; "INVALID LINE NUMBER"));
39 }
40 _ => {}
41 }
42 parse.expect_statements()
43 }
44
45 fn next(&mut self) -> Option<&'a Token> {
46 if self.peeked.is_some() {
47 return self.peeked.take();
48 }
49 loop {
50 self.col.start = self.col.end;
51 let token = self.token_stream.next()?;
52 if matches!(token, Token::Word(Word::Rem1) | Token::Word(Word::Rem2)) {
53 self.rem = true;
54 }
55 if self.rem {
56 continue;
57 }
58 self.col.end += token.to_string().chars().count();
59 match token {
60 Token::Whitespace(_) => continue,
61 _ => return Some(token),
62 }
63 }
64 }
65
66 fn peek(&mut self) -> Option<&&'a Token> {
67 if self.peeked.is_none() {
68 self.peeked = self.next();
69 }
70 self.peeked.as_ref()
71 }
72
73 fn expect_statements(&mut self) -> Result<Vec<Statement>> {
74 let mut statements: Vec<Statement> = vec![];
75 let mut expect_colon = false;
76 loop {
77 match self.peek() {
78 None | Some(Token::Word(Word::Else)) => return Ok(statements),
79 Some(Token::Colon) => {
80 expect_colon = false;
81 self.next();
82 continue;
83 }
84 Some(_) => {
85 if expect_colon {
86 return Err(error!(SyntaxError, ..&self.col; "UNEXPECTED TOKEN"));
87 }
88 statements.push(Statement::expect(self)?);
89 expect_colon = true;
90 }
91 }
92 }
93 }
94
95 fn expect_expression(&mut self) -> Result<Expression> {
96 self.expect_fn_expression(&HashMap::default())
97 }
98
99 fn expect_expression_list(&mut self) -> Result<Vec<Expression>> {
100 self.expect_fn_expression_list(&HashMap::default())
101 }
102
103 fn expect_fn_expression(
104 &mut self,
105 var_map: &HashMap<token::Ident, Variable>,
106 ) -> Result<Expression> {
107 Expression::expect(self, var_map)
108 }
109
110 fn expect_fn_expression_list(
111 &mut self,
112 var_map: &HashMap<token::Ident, Variable>,
113 ) -> Result<Vec<Expression>> {
114 let mut expressions: Vec<Expression> = vec![];
115 loop {
116 expressions.push(self.expect_fn_expression(var_map)?);
117 if self.maybe(Token::Comma) {
118 continue;
119 }
120 return Ok(expressions);
121 }
122 }
123
124 fn expect_print_list(&mut self) -> Result<Vec<Expression>> {
125 let mut expressions: Vec<Expression> = vec![];
126 let mut linefeed = true;
127 loop {
128 match self.peek() {
129 None | Some(Token::Colon) | Some(Token::Word(Word::Else)) => {
130 let mut column = self.col.clone();
131 column.start = column.end;
132 if linefeed {
133 expressions.push(Expression::String(column, "\n".into()));
134 }
135 return Ok(expressions);
136 }
137 Some(Token::Semicolon) => {
138 linefeed = false;
139 self.next();
140 }
141 Some(Token::Comma) => {
142 linefeed = false;
143 self.next();
144 expressions.push(Expression::Variable(Variable::Array(
145 self.col.clone(),
146 Ident::String("TAB".into()),
147 vec![Expression::Integer(self.col.clone(), -14)],
148 )));
149 }
150 _ => {
151 linefeed = true;
152 expressions.push(self.expect_expression()?);
153 }
154 };
155 }
156 }
157
158 fn expect_ident(&mut self) -> Result<(Column, token::Ident)> {
159 let ident = if let Some(Token::Ident(ident)) = self.next() {
160 ident.clone()
161 } else {
162 return Err(error!(SyntaxError, ..&self.col; EXPECTED_VARIABLE));
163 };
164 let col = self.col.clone();
165 if ident.is_user_function() {
166 return Err(error!(SyntaxError, ..&col; FN_RESERVED));
167 }
168 if let Some(Token::LParen) = self.peek() {
169 return Err(error!(SyntaxError, ..&(col); ARRAY_NOT_ALLOWED));
170 }
171 Ok((col, ident))
172 }
173
174 fn expect_ident_list(&mut self) -> Result<Vec<(Column, token::Ident)>> {
175 let mut idents: Vec<(Column, token::Ident)> = vec![];
176 let mut expecting = false;
177 loop {
178 match self.peek() {
179 None | Some(Token::Colon) | Some(Token::Word(Word::Else)) if !expecting => break,
180 _ => idents.push(self.expect_ident()?),
181 };
182 if self.maybe(Token::Comma) {
183 expecting = true;
184 } else {
185 break;
186 }
187 }
188 Ok(idents)
189 }
190
191 fn expect_var(&mut self) -> Result<Variable> {
192 let ident = if let Some(Token::Ident(ident)) = self.next() {
193 ident.clone()
194 } else {
195 return Err(error!(SyntaxError, ..&self.col; EXPECTED_VARIABLE));
196 };
197 let col = self.col.clone();
198 if ident.is_user_function() {
199 return Err(error!(SyntaxError, ..&col; FN_RESERVED));
200 }
201 match self.peek() {
202 Some(Token::LParen) => {
203 self.expect(Token::LParen)?;
204 let vec_expr = self.expect_expression_list()?;
205 self.expect(Token::RParen)?;
206 Ok(Variable::Array(
207 col.start..self.col.end,
208 ident.into(),
209 vec_expr,
210 ))
211 }
212 _ => Ok(Variable::Unary(col, ident.into())),
213 }
214 }
215
216 fn expect_var_list(&mut self) -> Result<Vec<Variable>> {
217 let mut vec_var: Vec<Variable> = vec![];
218 loop {
219 vec_var.push(self.expect_var()?);
220 if self.maybe(Token::Comma) {
221 continue;
222 }
223 break;
224 }
225 Ok(vec_var)
226 }
227
228 fn maybe_line_number(&mut self) -> Result<LineNumber> {
229 if let Some(str) = match self.peek() {
230 Some(Token::Literal(Literal::Integer(s))) => Some(s),
231 Some(Token::Literal(Literal::Single(s))) => Some(s),
232 Some(Token::Literal(Literal::Double(s))) => Some(s),
233 _ => None,
234 } {
235 self.next();
236 if let Ok(num) = str.parse::<u16>() {
237 if num <= LineNumber::max_value() {
238 return Ok(Some(num));
239 }
240 }
241 return Err(error!(UndefinedLine, ..&self.col; "INVALID LINE NUMBER"));
242 }
243 Ok(None)
244 }
245
246 fn expect_line_number(&mut self) -> Result<Expression> {
247 match self.maybe_line_number()? {
248 Some(num) => Ok(Expression::Single(self.col.clone(), num as f32)),
249 None => Err(error!(SyntaxError, ..&self.col; "EXPECTED LINE NUMBER")),
250 }
251 }
252
253 fn expect_line_number_list(&mut self) -> Result<Vec<Expression>> {
254 let mut vars: Vec<Expression> = vec![];
255 let mut expecting = false;
256 loop {
257 match self.peek() {
258 None | Some(Token::Colon) | Some(Token::Word(Word::Else)) if !expecting => break,
259 _ => vars.push(self.expect_line_number()?),
260 };
261 if self.maybe(Token::Comma) {
262 expecting = true;
263 } else {
264 break;
265 }
266 }
267 Ok(vars)
268 }
269
270 fn expect_line_number_range(&mut self) -> Result<(Expression, Expression)> {
271 let from;
272 let from_num;
273 let to;
274 let mut to_num;
275 let col = self.col.clone();
276 if let Some(num) = self.maybe_line_number()? {
277 from_num = num as f32;
278 to_num = from_num;
279 from = Expression::Single(self.col.clone(), from_num);
280 } else {
281 from_num = 0.0;
282 to_num = LineNumber::max_value() as f32;
283 from = Expression::Single(self.col.start..self.col.start, from_num);
284 };
285 if self.maybe(Token::Operator(Operator::Minus)) {
286 if let Some(ln) = self.maybe_line_number()? {
287 to_num = ln as f32;
288 to = Expression::Single(self.col.clone(), to_num);
289 } else {
290 to_num = LineNumber::max_value() as f32;
291 to = Expression::Single(self.col.start..self.col.start, to_num);
292 }
293 } else {
294 to = Expression::Single(self.col.start..self.col.start, to_num);
295 }
296 if from_num > to_num {
297 return Err(error!(UndefinedLine, ..&(col.start..self.col.end); "INVALID RANGE"));
298 }
299 Ok((from, to))
300 }
301
302 fn expect_var_range(&mut self) -> Result<(Variable, Variable)> {
303 let (from_col, from_ident) = self.expect_ident()?;
304 let (to_col, to_ident) = if self.maybe(Token::Operator(Operator::Minus)) {
305 self.expect_ident()?
306 } else {
307 (from_col.clone(), from_ident.clone())
308 };
309 let from_char = match &from_ident {
310 token::Ident::Plain(s) if s.len() == 1 => s,
311 _ => return Err(error!(SyntaxError, ..&from_col)),
312 };
313 let to_char = match &to_ident {
314 token::Ident::Plain(s) if s.len() == 1 => s,
315 _ => return Err(error!(SyntaxError, ..&to_col)),
316 };
317 if from_char > to_char {
318 return Err(error!(SyntaxError, ..&(from_col.start..to_col.end)));
319 }
320 let from = Variable::Unary(from_col, from_ident.into());
321 let to = Variable::Unary(to_col, to_ident.into());
322 Ok((from, to))
323 }
324
325 fn maybe(&mut self, token: Token) -> bool {
326 if let Some(t) = self.peek() {
327 if **t == token {
328 self.next();
329 return true;
330 }
331 }
332 false
333 }
334
335 fn expect(&mut self, token: Token) -> Result<()> {
336 if let Some(t) = self.next() {
337 if *t == token {
338 return Ok(());
339 }
340 }
341 Err(error!(SyntaxError, ..&self.col;
342 match token {
343 Token::Unknown(_) | Token::Whitespace(_) => {"EXPECTED THE IMPOSSIBLE"}
344 Token::Literal(_) => {"EXPECTED LITERAL"}
345 Token::Word(Word::Then) => {"EXPECTED THEN"}
346 Token::Word(Word::To) => {"EXPECTED TO"}
347 Token::Word(_) => {"EXPECTED STATEMENT WORD"}
348 Token::Operator(Operator::Equal) => {"EXPECTED EQUALS SIGN"}
349 Token::Operator(_) => {"EXPECTED OPERATOR"}
350 Token::Ident(_) => {"EXPECTED IDENTIFIER"}
351 Token::LParen => {"EXPECTED LEFT PARENTHESIS"}
352 Token::RParen => {"EXPECTED RIGHT PARENTHESIS"}
353 Token::Comma => {"EXPECTED COMMA"}
354 Token::Colon => {"EXPECTED COLON"}
355 Token::Semicolon => {"EXPECTED SEMICOLON"}
356 }
357 ))
358 }
359}
360
361impl Expression {
362 fn expect(
363 parse: &mut BasicParser,
364 var_map: &HashMap<token::Ident, Variable>,
365 ) -> Result<Expression> {
366 fn descend(
367 parse: &mut BasicParser,
368 var_map: &HashMap<token::Ident, Variable>,
369 precedence: usize,
370 ) -> Result<Expression> {
371 let mut lhs = match parse.next() {
372 Some(Token::LParen) => {
373 let expr = descend(parse, var_map, 0)?;
374 parse.expect(Token::RParen)?;
375 expr
376 }
377 Some(Token::Ident(tok_ident)) => {
378 let ident = tok_ident.clone();
379 let col = parse.col.clone();
380 match parse.peek() {
381 Some(&&Token::LParen) => {
382 parse.expect(Token::LParen)?;
383 let mut vec_expr = vec![];
384 if !parse.maybe(Token::RParen) {
385 vec_expr = parse.expect_fn_expression_list(var_map)?;
386 parse.expect(Token::RParen)?;
387 }
388 let col = col.start..parse.col.end;
389 Expression::Variable(Variable::Array(col, ident.into(), vec_expr))
390 }
391 _ => {
392 if ident.is_user_function() {
393 return Err(error!(SyntaxError, ..&col; FN_RESERVED));
394 }
395 match var_map.get(&ident) {
396 Some(var) => Expression::Variable(var.clone()),
397 None => Expression::Variable(Variable::Unary(col, ident.into())),
398 }
399 }
400 }
401 }
402 Some(Token::Operator(Operator::Plus)) => {
403 let op_prec = Expression::unary_op_precedence(&Operator::Plus)?;
404 descend(parse, var_map, op_prec)?
405 }
406 Some(Token::Operator(Operator::Minus)) => {
407 let col = parse.col.clone();
408 let op_prec = Expression::unary_op_precedence(&Operator::Minus)?;
409 let expr = descend(parse, var_map, op_prec)?;
410 Expression::Negation(col, Box::new(expr))
411 }
412 Some(Token::Operator(Operator::Not)) => {
413 let col = parse.col.clone();
414 let op_prec = Expression::unary_op_precedence(&Operator::Not)?;
415 let expr = descend(parse, var_map, op_prec)?;
416 Expression::Not(col, Box::new(expr))
417 }
418 Some(Token::Literal(lit)) => Expression::literal(parse.col.clone(), lit)?,
419 _ => return Err(error!(SyntaxError, ..&parse.col; "EXPECTED EXPRESSION")),
420 };
421 let mut rhs;
422 while let Some(Token::Operator(op)) = parse.peek() {
423 let op_prec = Expression::binary_op_precedence(op)?;
424 if op_prec <= precedence {
425 break;
426 }
427 parse.next();
428 let column = parse.col.clone();
429 rhs = descend(parse, var_map, op_prec)?;
430 lhs = Expression::binary_op(column, op, lhs, rhs)?;
431 }
432 Ok(lhs)
433 };
434 descend(parse, var_map, 0)
435 }
436
437 fn binary_op(
438 col: Column,
439 op: &Operator,
440 lhs: Expression,
441 rhs: Expression,
442 ) -> Result<Expression> {
443 use Operator::*;
444 Ok(match op {
445 Caret => Expression::Power(col, Box::new(lhs), Box::new(rhs)),
446 Multiply => Expression::Multiply(col, Box::new(lhs), Box::new(rhs)),
447 Divide => Expression::Divide(col, Box::new(lhs), Box::new(rhs)),
448 DivideInt => Expression::DivideInt(col, Box::new(lhs), Box::new(rhs)),
449 Modulo => Expression::Modulo(col, Box::new(lhs), Box::new(rhs)),
450 Plus => Expression::Add(col, Box::new(lhs), Box::new(rhs)),
451 Minus => Expression::Subtract(col, Box::new(lhs), Box::new(rhs)),
452 Equal => Expression::Equal(col, Box::new(lhs), Box::new(rhs)),
453 NotEqual => Expression::NotEqual(col, Box::new(lhs), Box::new(rhs)),
454 Less => Expression::Less(col, Box::new(lhs), Box::new(rhs)),
455 LessEqual => Expression::LessEqual(col, Box::new(lhs), Box::new(rhs)),
456 Greater => Expression::Greater(col, Box::new(lhs), Box::new(rhs)),
457 GreaterEqual => Expression::GreaterEqual(col, Box::new(lhs), Box::new(rhs)),
458 Not => return Err(error!(InternalError)),
459 And => Expression::And(col, Box::new(lhs), Box::new(rhs)),
460 Or => Expression::Or(col, Box::new(lhs), Box::new(rhs)),
461 Xor => Expression::Xor(col, Box::new(lhs), Box::new(rhs)),
462 Imp => Expression::Imp(col, Box::new(lhs), Box::new(rhs)),
463 Eqv => Expression::Eqv(col, Box::new(lhs), Box::new(rhs)),
464 })
465 }
466
467 fn unary_op_precedence(op: &Operator) -> Result<usize> {
468 use Operator::*;
469 Ok(match op {
470 Plus | Minus => 12,
471 Not => 6,
472 _ => 0,
473 })
474 }
475
476 fn binary_op_precedence(op: &Operator) -> Result<usize> {
477 use Operator::*;
478 Ok(match op {
479 Caret => 13,
480 Multiply | Divide => 11,
482 DivideInt => 10,
483 Modulo => 9,
484 Plus | Minus => 8,
485 Equal | NotEqual | Less | LessEqual | Greater | GreaterEqual => 7,
486 And => 5,
488 Or => 4,
489 Xor => 3,
490 Imp => 2,
491 Eqv => 1,
492 _ => 0,
493 })
494 }
495
496 fn literal(col: Column, lit: &Literal) -> Result<Expression> {
497 fn parse<T: std::str::FromStr>(col: Column, s: &str) -> Result<T> {
498 let mut s = String::from(s).replace("D", "E");
499 match s.chars().last() {
500 Some('!') | Some('#') | Some('%') => {
501 s.pop();
502 }
503 _ => {}
504 };
505 match s.parse() {
506 Ok(num) => Ok(num),
507 Err(_) => Err(error!(TypeMismatch, ..&col)),
508 }
509 }
510 fn parse_radix(col: Column, src: &str, radix: u32) -> Result<Expression> {
511 match i16::from_str_radix(src, radix) {
512 Ok(num) => Ok(Expression::Integer(col, num)),
513 Err(_) => Err(error!(Overflow, ..&col)),
514 }
515 }
516 match lit {
517 Literal::Hex(s) => parse_radix(col, s, 16),
518 Literal::Octal(s) => parse_radix(col, s, 8),
519 Literal::Single(s) => Ok(Expression::Single(col.clone(), parse(col, s)?)),
520 Literal::Double(s) => Ok(Expression::Double(col.clone(), parse(col, s)?)),
521 Literal::Integer(s) => Ok(Expression::Integer(col.clone(), parse(col, s)?)),
522 Literal::String(s) => {
523 if s.chars().count() > 255 {
524 Err(error!(StringTooLong, ..&col; "MAXIMUM LITERAL LENGTH IS 255"))
525 } else {
526 Ok(Expression::String(col, s.clone().into()))
527 }
528 }
529 }
530 }
531}
532
533impl Statement {
534 #[allow(clippy::cognitive_complexity)]
535 fn expect(parse: &mut BasicParser) -> Result<Statement> {
536 match parse.peek() {
537 Some(Token::Ident(_)) => return Ok(Self::r#let(parse, true)?),
538 Some(Token::Word(word)) => {
539 parse.next();
540 use Word::*;
541 match word {
542 Clear => return Ok(Self::r#clear(parse)?),
543 Cls => return Ok(Self::r#cls(parse)?),
544 Cont => return Ok(Self::r#cont(parse)?),
545 Data => return Ok(Self::r#data(parse)?),
546 Def => return Ok(Self::r#def(parse)?),
547 Defdbl => return Ok(Self::r#defdbl(parse)?),
548 Defint => return Ok(Self::r#defint(parse)?),
549 Defsng => return Ok(Self::r#defsng(parse)?),
550 Defstr => return Ok(Self::r#defstr(parse)?),
551 Delete => return Ok(Self::r#delete(parse)?),
552 Dim => return Ok(Self::r#dim(parse)?),
553 End => return Ok(Self::r#end(parse)?),
554 Erase => return Ok(Self::r#erase(parse)?),
555 For => return Ok(Self::r#for(parse)?),
556 Gosub => return Ok(Self::r#gosub(parse)?),
557 Goto => return Ok(Self::r#goto(parse)?),
558 If => return Ok(Self::r#if(parse)?),
559 Input => return Ok(Self::r#input(parse)?),
560 Let => return Ok(Self::r#let(parse, false)?),
561 List => return Ok(Self::r#list(parse)?),
562 Load => return Ok(Self::r#load(parse)?),
563 New => return Ok(Self::r#new(parse)?),
564 Next => return Ok(Self::r#next(parse)?),
565 On => return Ok(Self::r#on(parse)?),
566 Print => return Ok(Self::r#print(parse)?),
567 Read => return Ok(Self::r#read(parse)?),
568 Renum => return Ok(Self::r#renum(parse)?),
569 Restore => return Ok(Self::r#restore(parse)?),
570 Return => return Ok(Self::r#return(parse)?),
571 Run => return Ok(Self::r#run(parse)?),
572 Save => return Ok(Self::r#save(parse)?),
573 Stop => return Ok(Self::r#stop(parse)?),
574 Swap => return Ok(Self::r#swap(parse)?),
575 Troff => return Ok(Self::r#troff(parse)?),
576 Tron => return Ok(Self::r#tron(parse)?),
577 Wend => return Ok(Self::r#wend(parse)?),
578 While => return Ok(Self::r#while(parse)?),
579 Else | Rem1 | Rem2 | Step | Then | To => {}
580 }
581 }
582 _ => {}
583 }
584 Err(error!(SyntaxError, ..&parse.col; "EXPECTED STATEMENT"))
585 }
586
587 fn r#clear(parse: &mut BasicParser) -> Result<Statement> {
588 let result = Ok(Statement::Clear(parse.col.clone()));
589 while match parse.peek() {
590 None | Some(Token::Colon) | Some(Token::Word(Word::Else)) => false,
591 _ => true,
592 } {
593 parse.next();
594 }
595 result
596 }
597
598 fn r#cls(parse: &mut BasicParser) -> Result<Statement> {
599 Ok(Statement::Cls(parse.col.clone()))
600 }
601
602 fn r#cont(parse: &mut BasicParser) -> Result<Statement> {
603 Ok(Statement::Cont(parse.col.clone()))
604 }
605
606 fn r#data(parse: &mut BasicParser) -> Result<Statement> {
607 let vec_expr = parse.expect_expression_list()?;
608 Ok(Statement::Data(parse.col.clone(), vec_expr))
609 }
610
611 fn r#def(parse: &mut BasicParser) -> Result<Statement> {
612 let column = parse.col.clone();
613 let fn_ident = if let Some(Token::Ident(ident)) = parse.next() {
614 ident.clone()
615 } else {
616 return Err(error!(SyntaxError, ..&parse.col; EXPECTED_VARIABLE));
617 };
618 if !fn_ident.is_user_function() {
619 return Err(error!(SyntaxError, ..&parse.col; "MUST START WITH FN"));
620 }
621 let fn_ident_col = parse.col.clone();
622 parse.expect(Token::LParen)?;
623 let mut ident_list = parse.expect_ident_list()?;
624 parse.expect(Token::RParen)?;
625 parse.expect(Token::Operator(Operator::Equal))?;
626 let mut var_map: HashMap<token::Ident, Variable> = HashMap::default();
627 let var_ident: Vec<Variable> = ident_list
628 .drain(..)
629 .map(|(tok_col, tok_ident)| {
630 let ast_ident = Ident::from((&fn_ident, &tok_ident));
631 var_map.insert(
632 tok_ident,
633 Variable::Unary(tok_col.clone(), ast_ident.clone()),
634 );
635 Variable::Unary(tok_col, ast_ident)
636 })
637 .collect();
638 let expr = parse.expect_fn_expression(&var_map)?;
639 let var = Variable::Unary(fn_ident_col, fn_ident.into());
640 Ok(Statement::Def(column, var, var_ident, expr))
641 }
642
643 fn r#defdbl(parse: &mut BasicParser) -> Result<Statement> {
644 let (from, to) = parse.expect_var_range()?;
645 Ok(Statement::Defdbl(parse.col.clone(), from, to))
646 }
647
648 fn r#defint(parse: &mut BasicParser) -> Result<Statement> {
649 let (from, to) = parse.expect_var_range()?;
650 Ok(Statement::Defint(parse.col.clone(), from, to))
651 }
652
653 fn r#defsng(parse: &mut BasicParser) -> Result<Statement> {
654 let (from, to) = parse.expect_var_range()?;
655 Ok(Statement::Defsng(parse.col.clone(), from, to))
656 }
657
658 fn r#defstr(parse: &mut BasicParser) -> Result<Statement> {
659 let (from, to) = parse.expect_var_range()?;
660 Ok(Statement::Defstr(parse.col.clone(), from, to))
661 }
662
663 fn r#delete(parse: &mut BasicParser) -> Result<Statement> {
664 let column = parse.col.clone();
665 let (from, to) = parse.expect_line_number_range()?;
666 Ok(Statement::Delete(column, from, to))
667 }
668
669 fn r#dim(parse: &mut BasicParser) -> Result<Statement> {
670 let column = parse.col.clone();
671 let var_list = parse.expect_var_list()?;
672 Ok(Statement::Dim(column, var_list))
673 }
674
675 fn r#end(parse: &mut BasicParser) -> Result<Statement> {
676 Ok(Statement::End(parse.col.clone()))
677 }
678
679 fn r#erase(parse: &mut BasicParser) -> Result<Statement> {
680 let column = parse.col.clone();
681 let mut idents = parse.expect_ident_list()?;
682 if idents.is_empty() {
683 return Err(error!(SyntaxError, ..&(column.start..column.start); "EXPECTED VARIABLE"));
684 }
685 let vec_var = idents
686 .drain(..)
687 .map(|(col, i)| Variable::Unary(col, i.into()))
688 .collect::<Vec<Variable>>();
689 Ok(Statement::Erase(column, vec_var))
690 }
691
692 fn r#for(parse: &mut BasicParser) -> Result<Statement> {
693 let column = parse.col.clone();
694 let (ident_col, ident) = parse.expect_ident()?;
695 let var = Variable::Unary(ident_col, ident.into());
696 parse.expect(Token::Operator(Operator::Equal))?;
697 let expr_from = parse.expect_expression()?;
698 parse.expect(Token::Word(Word::To))?;
699 let expr_to = parse.expect_expression()?;
700 let expr_step = if parse.maybe(Token::Word(Word::Step)) {
701 parse.expect_expression()?
702 } else {
703 Expression::Integer(parse.col.end..parse.col.end, 1)
704 };
705 Ok(Statement::For(column, var, expr_from, expr_to, expr_step))
706 }
707
708 fn r#gosub(parse: &mut BasicParser) -> Result<Statement> {
709 Ok(Statement::Gosub(
710 parse.col.clone(),
711 parse.expect_line_number()?,
712 ))
713 }
714
715 fn r#goto(parse: &mut BasicParser) -> Result<Statement> {
716 Ok(Statement::Goto(
717 parse.col.clone(),
718 parse.expect_line_number()?,
719 ))
720 }
721
722 fn r#if(parse: &mut BasicParser) -> Result<Statement> {
723 let column = parse.col.clone();
724 let predicate = parse.expect_expression()?;
725 let then_stmt = if parse.maybe(Token::Word(Word::Goto)) {
726 vec![Statement::Goto(
727 parse.col.clone(),
728 parse.expect_line_number()?,
729 )]
730 } else {
731 parse.expect(Token::Word(Word::Then))?;
732 match parse.maybe_line_number()? {
733 Some(n) => vec![Statement::Goto(
734 column.clone(),
735 Expression::Single(parse.col.clone(), n as f32),
736 )],
737 None => parse.expect_statements()?,
738 }
739 };
740 let else_stmt = if parse.maybe(Token::Word(Word::Else)) {
741 match parse.maybe_line_number()? {
742 Some(n) => vec![Statement::Goto(
743 column.clone(),
744 Expression::Single(parse.col.clone(), n as f32),
745 )],
746 None => parse.expect_statements()?,
747 }
748 } else {
749 vec![]
750 };
751 Ok(Statement::If(column, predicate, then_stmt, else_stmt))
752 }
753
754 fn r#input(parse: &mut BasicParser) -> Result<Statement> {
755 let column = parse.col.clone();
756 let mut prompt_col = column.end..column.end;
757 let caps = if let Some(Token::Comma) = parse.peek() {
758 parse.next();
759 Expression::Integer(parse.col.clone(), 0)
760 } else {
761 Expression::Integer(parse.col.start..parse.col.start, -1)
762 };
763 let prompt = match parse.peek() {
764 Some(Token::Literal(Literal::String(s))) => {
765 parse.next();
766 prompt_col = parse.col.clone();
767 match parse.peek() {
768 None | Some(Token::Colon) | Some(Token::Word(Word::Else)) => {}
769 Some(Token::Semicolon) => {
770 parse.next();
771 }
772 _ => {
773 return Err(error!(SyntaxError, ..&parse.col.clone(); "UNEXPECTED TOKEN"));
774 }
775 }
776 s.clone()
777 }
778 _ => String::new(),
779 };
780 let var_list = parse.expect_var_list()?;
781 Ok(Statement::Input(
782 column,
783 caps,
784 Expression::String(prompt_col, prompt.into()),
785 var_list,
786 ))
787 }
788
789 fn r#let(parse: &mut BasicParser, is_shortcut: bool) -> Result<Statement> {
790 let column = parse.col.clone();
791 if let Some(Token::Ident(token::Ident::String(s))) = parse.peek() {
792 if s == "MID$" {
793 parse.next();
794 parse.expect(Token::LParen)?;
795 let var = parse.expect_var()?;
796 parse.expect(Token::Comma)?;
797 let pos = parse.expect_expression()?;
798 let len = if parse.maybe(Token::Comma) {
799 parse.expect_expression()?
800 } else {
801 Expression::Integer(parse.col.start..parse.col.start, i16::max_value())
802 };
803 parse.expect(Token::RParen)?;
804 parse.expect(Token::Operator(Operator::Equal))?;
805 let expr = parse.expect_expression()?;
806 return Ok(Statement::Mid(column, var, pos, len, expr));
807 }
808 }
809 let var = parse.expect_var()?;
810 match parse.next() {
811 Some(Token::Operator(Operator::Equal)) => {
812 Ok(Statement::Let(column, var, parse.expect_expression()?))
813 }
814 _ => {
815 if is_shortcut {
816 Err(error!(SyntaxError, ..&column; "UNKNOWN STATEMENT"))
817 } else {
818 Err(error!(SyntaxError, ..&parse.col; "EXPECTED EQUALS SIGN"))
819 }
820 }
821 }
822 }
823
824 fn r#list(parse: &mut BasicParser) -> Result<Statement> {
825 let column = parse.col.clone();
826 let (from, to) = parse.expect_line_number_range()?;
827 Ok(Statement::List(column, from, to))
828 }
829
830 fn r#load(parse: &mut BasicParser) -> Result<Statement> {
831 Ok(Statement::Load(
832 parse.col.clone(),
833 parse.expect_expression()?,
834 ))
835 }
836
837 fn r#new(parse: &mut BasicParser) -> Result<Statement> {
838 Ok(Statement::New(parse.col.clone()))
839 }
840
841 fn r#next(parse: &mut BasicParser) -> Result<Statement> {
842 let column = parse.col.clone();
843 let mut idents = parse.expect_ident_list()?;
844 if idents.is_empty() {
845 return Ok(Statement::Next(
846 column,
847 vec![Variable::Unary(0..0, Ident::Plain("".into()))],
848 ));
849 }
850 let vec_var = idents
851 .drain(..)
852 .map(|(col, i)| Variable::Unary(col, i.into()))
853 .collect::<Vec<Variable>>();
854
855 Ok(Statement::Next(column, vec_var))
856 }
857
858 fn r#on(parse: &mut BasicParser) -> Result<Statement> {
859 let column = parse.col.clone();
860 let expr = parse.expect_expression()?;
861 match parse.next() {
862 Some(Token::Word(Word::Goto)) => Ok(Statement::OnGoto(
863 column,
864 expr,
865 parse.expect_line_number_list()?,
866 )),
867 Some(Token::Word(Word::Gosub)) => Ok(Statement::OnGosub(
868 column,
869 expr,
870 parse.expect_line_number_list()?,
871 )),
872 _ => Err(error!(SyntaxError, ..&parse.col; "EXPECTED GOTO OR GOSUB")),
873 }
874 }
875
876 fn r#print(parse: &mut BasicParser) -> Result<Statement> {
877 let column = parse.col.clone();
878 let vec_expr = parse.expect_print_list()?;
879 Ok(Statement::Print(column, vec_expr))
880 }
881
882 fn r#read(parse: &mut BasicParser) -> Result<Statement> {
883 Ok(Statement::Read(parse.col.clone(), parse.expect_var_list()?))
884 }
885
886 fn r#renum(parse: &mut BasicParser) -> Result<Statement> {
887 fn parse_start(parse: &mut BasicParser, default: f32) -> Result<Expression> {
888 if parse.maybe(Token::Comma) {
889 Ok(Expression::Single(parse.col.clone(), default))
890 } else {
891 match parse.peek() {
892 None | Some(Token::Colon) | Some(Token::Word(Word::Else)) => Ok(
893 Expression::Single(parse.col.start..parse.col.start, default),
894 ),
895 _ => {
896 let ln = parse.expect_line_number()?;
897 parse.maybe(Token::Comma);
898 Ok(ln)
899 }
900 }
901 }
902 }
903 let column = parse.col.clone();
904 let new_start = parse_start(parse, 10.0)?;
905 let old_start = parse_start(parse, 0.0)?;
906 let step = match parse.peek() {
907 None | Some(Token::Colon) | Some(Token::Word(Word::Else)) => {
908 Expression::Single(parse.col.start..parse.col.start, 10.0)
909 }
910 _ => parse.expect_line_number()?,
911 };
912 Ok(Statement::Renum(column, new_start, old_start, step))
913 }
914
915 fn r#restore(parse: &mut BasicParser) -> Result<Statement> {
916 let num = if let Some(num) = parse.maybe_line_number()? {
917 num as f32
918 } else {
919 -1.0
920 };
921 Ok(Statement::Restore(
922 parse.col.clone(),
923 Expression::Single(parse.col.clone(), num as f32),
924 ))
925 }
926
927 fn r#return(parse: &mut BasicParser) -> Result<Statement> {
928 Ok(Statement::Return(parse.col.clone()))
929 }
930
931 fn r#run(parse: &mut BasicParser) -> Result<Statement> {
932 let column = parse.col.clone();
933 if let Some(Token::Literal(Literal::String(s))) = parse.peek() {
934 parse.next();
935 Ok(Statement::Run(
936 column,
937 Expression::String(parse.col.clone(), s.clone().into()),
938 ))
939 } else if let Some(num) = parse.maybe_line_number()? {
940 Ok(Statement::Run(
941 column,
942 Expression::Single(parse.col.clone(), num as f32),
943 ))
944 } else {
945 let empty = parse.col.clone();
946 let empty = empty.start..empty.start;
947 Ok(Statement::Run(column, Expression::Single(empty, -1.0)))
948 }
949 }
950
951 fn r#save(parse: &mut BasicParser) -> Result<Statement> {
952 Ok(Statement::Save(
953 parse.col.clone(),
954 parse.expect_expression()?,
955 ))
956 }
957
958 fn r#stop(parse: &mut BasicParser) -> Result<Statement> {
959 Ok(Statement::Stop(parse.col.clone()))
960 }
961
962 fn r#swap(parse: &mut BasicParser) -> Result<Statement> {
963 let col = parse.col.clone();
964 let mut var_list = parse.expect_var_list()?;
965 if var_list.len() != 2 {
966 return Err(
967 error!(SyntaxError, ..&(col.start..parse.col.end); "EXPECTED TWO VARIABLES" ),
968 );
969 }
970 Ok(Statement::Swap(
971 col,
972 var_list.pop().unwrap(),
973 var_list.pop().unwrap(),
974 ))
975 }
976
977 fn r#troff(parse: &mut BasicParser) -> Result<Statement> {
978 Ok(Statement::Troff(parse.col.clone()))
979 }
980
981 fn r#tron(parse: &mut BasicParser) -> Result<Statement> {
982 Ok(Statement::Tron(parse.col.clone()))
983 }
984
985 fn r#wend(parse: &mut BasicParser) -> Result<Statement> {
986 Ok(Statement::Wend(parse.col.clone()))
987 }
988
989 fn r#while(parse: &mut BasicParser) -> Result<Statement> {
990 Ok(Statement::While(
991 parse.col.clone(),
992 parse.expect_expression()?,
993 ))
994 }
995}
996
997impl From<token::Ident> for Ident {
998 fn from(ident: token::Ident) -> Self {
999 use token::Ident::*;
1000 match ident {
1001 Plain(s) => Ident::Plain(s.into()),
1002 String(s) => Ident::String(s.into()),
1003 Single(s) => Ident::Single(s.into()),
1004 Double(s) => Ident::Double(s.into()),
1005 Integer(s) => Ident::Integer(s.into()),
1006 }
1007 }
1008}
1009
1010impl From<(&token::Ident, &token::Ident)> for Ident {
1011 fn from(f: (&token::Ident, &token::Ident)) -> Self {
1012 let mut string = match f.0 {
1013 token::Ident::Plain(s) => s,
1014 token::Ident::String(s) => s,
1015 token::Ident::Single(s) => s,
1016 token::Ident::Double(s) => s,
1017 token::Ident::Integer(s) => s,
1018 }
1019 .to_string();
1020 string.push('.');
1021 match f.1 {
1022 token::Ident::Plain(s) => Ident::Plain({
1023 string.push_str(&s);
1024 string.into()
1025 }),
1026 token::Ident::String(s) => Ident::String({
1027 string.push_str(&s);
1028 string.into()
1029 }),
1030 token::Ident::Single(s) => Ident::Single({
1031 string.push_str(&s);
1032 string.into()
1033 }),
1034 token::Ident::Double(s) => Ident::Double({
1035 string.push_str(&s);
1036 string.into()
1037 }),
1038 token::Ident::Integer(s) => Ident::Integer({
1039 string.push_str(&s);
1040 string.into()
1041 }),
1042 }
1043 }
1044}
1045
1046impl token::Ident {
1047 fn is_user_function(&self) -> bool {
1048 use token::Ident::*;
1049 match self {
1050 Plain(s) => s,
1051 String(s) => s,
1052 Single(s) => s,
1053 Double(s) => s,
1054 Integer(s) => s,
1055 }
1056 .starts_with("FN")
1057 }
1058}