1 module orelang.Interpreter;
2 import orelang.Transpiler,
3        orelang.Engine,
4        orelang.Value;
5 import std..string,
6        std.stdio,
7        std.conv;
8 
9 // TODO: Need to implement exit operator
10 
11 class Interpreter {
12   private {
13     Engine     engine;
14     Transpiler transpiler;
15     long       bracketState;
16   }
17 
18   this() {
19     this.engine       = new Engine();
20     this.bracketState = 0;
21   }
22 
23   this(Engine engine) {
24     this.engine       = engine;
25     this.bracketState = 0;
26   }
27 
28   Engine peekEngine() {
29     return this.engine;
30   }
31 
32   void defineARGS(string[] args) {
33     Value[] vargs;
34 
35     foreach (arg; args) {
36       vargs ~= new Value(arg);
37     }
38 
39     this.engine.defineVariable("ARGS", new Value(vargs));
40   }
41 
42   bool checkBracket(string code) {
43     for (size_t i; i < code.length; ++i) {
44       char ch = code[i];
45 
46       if (ch == '(') { this.bracketState++; }
47       if (ch == ')') { this.bracketState--; }
48     }
49 
50     if (this.bracketState == 0) {
51       return true;
52     } else {
53       return false;
54     }
55   }
56 
57   void interpreter() {
58     string buf;
59     write("=> ");
60 
61     void e(char val) {
62       if (checkBracket(val.to!string) && (buf.length != 0)) {
63 //        writeln("buf -> ", buf);
64         auto transpiled = Transpiler.transpile(buf);
65 //        writeln("transpiled -> ", transpiled);
66         writeln(engine.eval(transpiled));
67         buf = [];
68       }
69     }
70 
71     while (true) {
72       string input = readln.chomp;
73 
74       if (input == "exit" || input == "(exit)") {
75         break;
76       }
77 
78       foreach (char val; input) {
79         if ('\n' == val) {
80           e(val);
81         } else {
82           buf ~= val;
83           e(val);
84         }
85       }
86 
87       for (size_t i; i < bracketState + 1; ++i) {
88         write("=");
89       }
90       write("> ");
91     }
92   }
93 
94   Value executer(string code) {
95     string buf;
96     Value ret;
97 
98     void e(char val) {
99       if (checkBracket(val.to!string) && (buf.length != 0)) {
100         auto transpiled = Transpiler.transpile(buf);
101         ret = engine.eval(transpiled);
102         buf = [];
103       }
104     }
105 
106     foreach(input; code.split("\n")) {
107       if (input == "exit" || input == "(exit)") {
108         break;
109       }
110 
111       foreach (char val; input) {
112         if ('\n' == val) {
113           e(val);
114         } else {
115           buf ~= val;
116           e(val);
117         }
118       }
119     }
120 
121     return ret;
122   }
123 }