1use crate::lexer;
3use crate::lexer::TT;
4
5#[derive(Clone, Debug, PartialEq)]
6pub enum Misc {
7 Stop,
8 IfStop,
9 Unknown,
10}
11#[derive(Clone, Debug, PartialEq)]
12pub enum Var {
13 Sstring(String),
14 Var(String),
15}
16
17#[derive(Clone, Debug, PartialEq)]
18pub enum Math {
19 Eq(i64),
20 Pass,
21 Plus(i64),
22 Minus(i64),
23 Div(i64),
24 Times(i64),
25
26
27}
28
29
30#[derive(Clone, Debug, PartialEq)]
31pub enum Command {
32 Prints(Var),
33 If(Var, String, Var),
34
35 Fn(String, [i64; 2], Vec<String>),
36 Loop(String, [i64; 2], Vec<String>, Vec<String>, i64),
37 Run(String, [i64; 2], Vec<String>, Vec<String>),
38
39 Misc(Misc),
40 Get(String),
41
42 Var([String; 2]),
43 Change(String, Var, Math),
44 Delete(String),
45 Cus(String,Vec<Var>),
46}
47#[derive(Clone)]
48pub struct Parse {
49 pub parsed_data: Vec<Command>,
50}
51impl Parse {
52 pub fn new() -> Parse {
53 Parse {
54 parsed_data: Vec::new(),
55 }
56 }
57 pub fn push(&mut self, ty: Command) {
58 self.parsed_data.push(ty);
59 }
60 pub fn find_fn(&mut self, name: &str) -> Command {
61 for x in 0..self.parsed_data.len() {
62 match self.parsed_data[x].clone() {
63 Command::Fn(a, _b, _c) => {
64 if a == name {
65 return self.parsed_data[x].clone();
66 }
67 }
68 _ => {}
69 }
70 }
71 panic!("no function")
72 }
73}
74pub fn parser(code: lexer::Coder) -> Parse {
76 let mut parsed = Parse::new();
77 #[allow(unused_variables)]
78 let curlin = 0;
79 let mut modif = 0;
80 fn unif_pan(a: TT){
82 panic!("MP command not found {:#?}", a)
83 }
84
85 for line in 0..code.lex.clone().len() {
86 let line = line + modif;
87 if line >= code.lex.clone().len() {
88 break;
89 }
90 match code.lex[line].clone() {
91 TT::Char(a) =>{
92 if a.as_str() == "/"{
94 let next_rb = code.next(TT::LBracket, line);
95 modif += next_rb -1 - line;
96 }else{
97 unif_pan(TT::Char(a));
98 }
99 }
100 TT::LBracket => {
101 let code = code.clone();
103 let next_rb = code.next(TT::RBracket, line);
105 let x = sub_parser([line + 1, next_rb], code.clone());
107 parsed.push(x);
109 modif += next_rb - line;
111 }
112 TT::WhiteSpace=>{
113
114 }
115 a => unif_pan(a),
116 }
117 }
119 return parsed;
120}
121pub fn sub_parser(pos: [usize; 2], code: lexer::Coder) -> Command {
123 let curlin = pos[0];
124 #[allow(unused_assignments)]
126 let mut command_return: Command = Command::Misc(Misc::Unknown);
127 match code.lex[pos[0]].clone() {
128 TT::LParen => {
129 let code = code.clone();
131 let mut com: Vec<String> = Vec::new();
134 let mut args: Vec<String> = Vec::new();
135 for codes in curlin + 1..code.next(TT::RParen, pos[0]) {
138 match code.lex[codes].clone() {
140 TT::Letter(a) => {
141 com.push(a);
142 }
143
144 TT::WhiteSpace => {
145 com.push(" ".to_string());
146 }
147 TT::Num (a) =>{
148 com.push(a);
149
150 }
151 _ => panic!("sub parsing error "),
152 }
153 }
154
155 let com = com.join("");
156
157 match com.as_str() {
159 "print" => {
160 let mut is_str = false;
163 let mut ne_q = code.next(TT::RParen, pos[0]) + 1;
164 let mut ne_q2 = code.next(TT::RBracket, pos[0]);
165 for x in code.next(TT::RParen, pos[0]) + 1..code.next(TT::RBracket, pos[0]) {
166 if code.lex[x] == TT::Quotation {
167 is_str = true;
168 }
169 }
170 if is_str {
171 ne_q = code.next(TT::Quotation, pos[0]) + 1;
172 ne_q2 = code.next(TT::Quotation, ne_q);
173 }
174
175 for codes in ne_q..ne_q2 {
176 match code.lex[codes].clone() {
180 TT::Letter(a) => {
181 args.push(a);
182 }
183 TT::Num(a) => {
184 args.push(a);
185 }
186 TT::WhiteSpace => {
187 args.push(" ".to_string());
188 }
189 TT::Char(a) => {
190 args.push(a);
191 }
192 a => panic!("sub parsing error 2: {:#?}", a),
193 }
194 }
195 let args = args.join("");
196 if is_str {
197 command_return = Command::Prints(Var::Sstring(args));
198 } else {
199 command_return = Command::Prints(Var::Var(args));
200 }
201 }
202 "var" => {
203 let ne_q = code.next(TT::RParen, pos[0]) + 1;
206 let ne_q2 = code.next(TT::RBracket, pos[0]);
207 let mut val: Vec<String> = Vec::new();
208 let mut push_to_val: bool = false;
209
210 for codes in ne_q..ne_q2 {
211 match code.lex[codes].clone() {
215 TT::Letter(a) => {
216 if push_to_val {
217 val.push(a);
218 } else {
219 args.push(a);
220 }
221 }
222 TT::Num(a) => {
223 if push_to_val {
224 val.push(a);
225 } else {
226 args.push(a);
227 }
228 }
229 TT::WhiteSpace => {
230 if push_to_val {
231 val.push(" ".to_string());
232 } else {
233 }
234 }
236 TT::Char(a) => {
237 args.push(a);
238 }
239 TT::Quotation => {
240 push_to_val = true;
241 }
242 a => panic!("sub parsing error 2: {:#?}", a),
243 }
244 }
245
246 let args = args.join("");
247 let val = val.join("");
248
249 command_return = Command::Var([args, val]);
252 }
253 "if" => {
254 let ne_q = code.next(TT::RParen, pos[0]) + 1;
256 let ne_q2 = code.next(TT::WhiteSpace, ne_q);
257 let x1 = collect_str([ne_q, ne_q2], code.clone());
258 let x1 = parse_str_var(x1);
259 let ne_q = ne_q2 + 1;
261 let ne_q2 = code.next(TT::WhiteSpace, ne_q);
262 let _xe = collect_str([ne_q, ne_q2], code.clone());
263 let ne_q = ne_q2 + 1;
266 let ne_q2 = code.next(TT::RBracket, ne_q);
267 let x2 = collect_str([ne_q, ne_q2], code.clone());
268 let x2 = parse_str_var(x2);
269 command_return = Command::If(x1, _xe, x2);
272 }
273 "if stop" => {
274 command_return = Command::Misc(Misc::IfStop);
276 }
277 "edit" | "cha" => match var_par([pos[0], pos[1]], code) {
278 Command::Change(a, b, c) => {
281 command_return = Command::Change(a, b, c);
282 }
283 _ => {
284 panic!("this should never happen");
285 }
286 },
287 "drop" | "dump" => {
288 let var = collect_str([code.next(TT::RParen, pos[0]) + 1, pos[1]], code);
289 match parse_str_var(var.clone()) {
290 Var::Sstring(_) => {
291 panic!("To dump a variable it needs to be a variable not a string");
292 }
293 _ => {}
294 }
295 command_return = Command::Delete(var);
296 }
297 "com" =>{
298
299 }
300 a => {
301 let cus = collect_str([code.next(TT::RParen, pos[0]) + 1, pos[1]], code);
305 let cus: Vec<String> = cus.split(",<").collect::<Vec<&str>>().into_iter().map(|x|x.to_string()).collect();
306
307
308 let mut custom_arg: Vec<Var> = Vec::new();
324 for x in cus{
325 custom_arg.push(parse_str_var(x));
326 }
327
328 command_return = Command::Cus(a.to_string(),custom_arg)
329
330 }
331 }
332 }
333 a => panic!("SP command not found {:#?} line {}", a, curlin),
334 }
335 return command_return;
340}
341
342fn parse_str_var(str: String) -> Var {
343 let mut str = str;
345 let mut am_of = 0;
346 let mut _am_of_le = 0;
347
348 for x in str.chars() {
349 match x {
350 '"' => am_of += 1,
351 _ => _am_of_le += 1,
352 }
353 }
354 if am_of == 2 {
355 str.retain(|x| x != '"');
356
357 Var::Sstring(str)
358 } else {
359 Var::Var(str)
360 }
361}
362fn collect_str(pos: [usize; 2], code: lexer::Coder) -> String {
363 let mut args: Vec<String> = Vec::new();
364 for codes in pos[0]..pos[1] {
366 match code.lex[codes].clone() {
370 TT::Letter(a) => {
371 args.push(a);
372 }
373 TT::Num(a) => {
374 args.push(a);
375 }
376 TT::WhiteSpace => {
377 args.push(" ".to_string());
378 }
379 TT::Char(a) => {
380 args.push(a);
381 }
382 TT::Quotation => {
383 args.push(r#"""#.to_string());
384 }
385 a => panic!("sub_ parsing error 1: {:#?}", a),
386 }
387 }
388 args.join("")
389}
390
391fn var_par(pos: [usize; 2], code: lexer::Coder) -> Command {
392 let ne_q = code.next(TT::RParen, pos[0]) + 1;
394 let ne_q2 = code.next(TT::RBracket, pos[0]);
395 let mut val: Vec<String> = Vec::new();
396 let mut args: Vec<String> = Vec::new();
397
398 let mut push_to_val: bool = false;
399 let mut math: bool = true;
400 let mut math_tp:&str = "_";
401
402 for codes in ne_q..ne_q2 {
403 match code.lex[codes].clone() {
407 TT::Letter(a) => {
408 if push_to_val {
409 val.push(a);
410 } else {
411 args.push(a);
412 }
413 }
414 TT::Num(a) => {
415 if push_to_val {
416 val.push(a);
417 } else {
418 args.push(a);
419 }
420 }
421 TT::WhiteSpace => {
422 if push_to_val {
423 val.push(" ".to_string());
424 } else {
425 push_to_val = true;
426 }
427 }
429 TT::Char(a) => {
430 if push_to_val | math{
431 match a.as_str() {
432 "-" =>{
433 math_tp = "-";
434 math = false;
435 }
436 "+" =>{
437 math_tp = "+";
438 math = false;
439 }
440 "/" =>{
441 math_tp = "/";
442 math = false;
443 }
444 "*"|";" =>{
445 math_tp = "*";
446 math = false;
447 }
448 _=> args.push(a)
449 }
450 }else{
451 args.push(a);
452 }
453 }
454 TT::Quotation => {
455 if push_to_val{
456 math = false;
457 val.push(r#"""#.to_string());
458 } else {
459 }
460 }
461 a => panic!("sub parsing error 2: {:#?}", a),
462 }
463 }
464 let args = args.join("");
466 let vals = val.join("");
467 let val = parse_str_var(vals.clone());
468
469 let mut mth = Math::Pass;
470 match math_tp{
471 "-" =>{
472 mth = Math::Minus(vals.parse::<i64>().unwrap())
473 }
474 "/" =>{
475 mth = Math::Div(vals.parse::<i64>().unwrap())
476 }
477 "+" =>{
478
479 mth = Math::Plus(vals.parse::<i64>().unwrap())
480 }
481 "*" =>{
482 mth = Math::Times(vals.parse::<i64>().unwrap())
483 }
484 _=>{
485
486 }
487 }
488
489 return Command::Change(args, val, mth);
494}