brainfuck_plus_core/
parser.rs1use std::process::exit;
2
3use crate::prelude::*;
4
5fn trim_tokens(i: &mut usize, tokens: &Vec<Token>, token_type: TokenType) -> Operation {
6 let mut count = 0;
7
8 let len: usize = tokens.len();
9
10 let mut values: Vec<String> = Vec::new();
11
12 let row = tokens[*i].row;
13 let col = tokens[*i].col;
14 let filename: String = tokens[*i].filename.clone();
15
16 while tokens[*i].token_type == token_type {
17 count += 1;
18 *i += 1;
19 values.push(tokens[*i].value.clone());
20 if *i >= len {
21 break;
22 }
23 }
24
25 Operation {
26 token_type,
27 count,
28 values,
29 tape: None,
30 row,
31 col,
32 filename,
33 }
34}
35
36#[must_use]
37pub fn parse_file(tokens: Vec<Token>, tapes: &[Tape]) -> Vec<Operation> {
38 let mut operations: Vec<Operation> = Vec::new();
39
40 let mut i: usize = 0;
41 let len: usize = tokens.len();
42
43 while i < len {
44 let token = tokens[i].clone();
45
46 match token.token_type {
47 TokenType::Add => operations.push(trim_tokens(&mut i, &tokens, token.token_type)),
48
49 TokenType::Sub => operations.push(trim_tokens(&mut i, &tokens, token.token_type)),
50
51 TokenType::PointerLeft => {
52 operations.push(trim_tokens(&mut i, &tokens, token.token_type))
53 }
54 TokenType::BitwiseLeft => {
55 operations.push(trim_tokens(&mut i, &tokens, token.token_type))
56 }
57 TokenType::BitwiseRight => {
58 operations.push(trim_tokens(&mut i, &tokens, token.token_type))
59 }
60
61 TokenType::PointerRight => {
62 operations.push(trim_tokens(&mut i, &tokens, token.token_type))
63 }
64
65 TokenType::Push => operations.push(trim_tokens(&mut i, &tokens, token.token_type)),
66
67 TokenType::Pop => operations.push(trim_tokens(&mut i, &tokens, token.token_type)),
68
69 TokenType::CurrentTape => {
70 i += 1;
71 let tape_name = tokens[i].clone();
72 if tape_name.token_type != TokenType::TapeName {
73 println!(
74 "{}:{}:{} CurrentTape: Expected tape name after operation got {}",
75 token.filename,
76 token.row,
77 token.col + 1,
78 tape_name.value
79 );
80 exit(1);
81 }
82
83 let tape = {
84 let mut tape: Option<Tape> = None;
85 for tapem in tapes {
86 if tapem.name == tape_name.value {
87 tape = Some(tapem.clone());
88 break;
89 }
90 }
91
92 tape
93 };
94
95 if tape.is_none() {
96 println!(
97 "{}:{}:{} Tape {} not defined",
98 token.filename,
99 token.col,
100 token.row + 1,
101 tape_name.value
102 );
103 exit(1);
104 }
105
106 operations.push(Operation {
107 token_type: token.token_type,
108 count: 1,
109 values: vec![token.value],
110 tape,
111 row: token.row,
112 col: token.col,
113 filename: token.filename,
114 });
115 i += 1;
116 }
117
118 _ => {
119 operations.push(Operation {
120 token_type: token.token_type,
121 count: 1,
122 values: vec![token.value],
123 tape: None,
124 row: token.row,
125 col: token.col,
126 filename: token.filename,
127 });
128 i += 1;
129 }
130 }
131 }
132
133 operations
134}