1use std::io::{self, BufRead, Write};
2
3use crate::{
4 ast::Nodetrait,
5 heap::Heap,
6 lexer::Lexer,
7 object::{environment::Environment, ObjectTrait},
8 parser::Parser,
9 token::Kind,
10 treewalker::eval::evaluate,
11};
12const PROMPT: &str = "-> ";
13
14pub fn start() {
15 let mut buf = String::new();
16 let mut stdin = io::stdin().lock(); let mut env = Environment::new();
19 let mut heap = Heap::new();
20
21 let debug_lexer = false;
22 let debug_parser = false;
23 let debug_evaluator = false;
24 let show_error = true;
25
26 loop {
27 io::stdout().lock().write_all(PROMPT.as_bytes()).unwrap();
28 io::stdout().flush().unwrap();
29 match stdin.read_line(&mut buf) {
30 Ok(_) => {
31 if buf == "$env\n" {
32 dbg!(&env);
33 buf.clear();
34 continue;
35 }
36 if buf == "$heap\n" {
37 dbg!(&heap);
38 buf.clear();
39 continue;
40 }
41 if buf == "$rungc\n" {
42 heap.run_gc(&mut env);
43 buf.clear();
44 continue;
45 }
46 let lexer = Lexer::new(buf.clone());
47
48 let mut cloned_lexer = lexer.clone();
49
50 if debug_lexer {
51 loop {
52 let cur_token = cloned_lexer.next_token();
53
54 println!("Debug Output (Lexer) >> {:?}", cur_token);
55
56 if cur_token.kind == Kind::EOF {
57 break;
58 }
59 }
60 }
61
62 let mut parser = Parser::new(lexer);
63 let program = parser.parse();
64
65 if debug_parser {
66 println!("Debug Output (Parser) >> {:?}", program);
67 }
68
69 if program.is_ok() {
70 let program = program.unwrap();
71 let result =
72 evaluate(program.to_node(), &mut heap, &mut env);
73
74 if debug_evaluator {
75 println!("Debug Output (Eval) >> {:?}", result);
76 }
77
78 if result.is_ok() {
79 let eval = result.unwrap();
80 if eval.is_some() {
81 let val = eval.unwrap();
82 println!("{}", val.to_str());
83 }
84 } else if show_error {
85 println!("!!!> ERROR OCCURED <!!!");
86 println!(">> ERROR DETAIL ");
87 println!("{:?}", result.err().unwrap());
88 }
89 } else {
90 if show_error {
91 println!("!!!> ERROR OCCURED <!!!");
92 for errs in program.err().unwrap() {
93 println!(">> ERROR DETAIL ");
94 for err in errs {
95 println!("Pos>> {:?}", err.as_ref().position());
96 println!("Detail>> {} ", err.as_ref().detail());
97 }
98 }
99 }
100 }
101 buf.clear();
102 }
103 Err(err) => {
104 println!("Error occured during reading stdin");
105 println!("{:?}", err);
106 return;
107 }
108 }
109 }
110}