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   void defineARGS(string[] args) {
29     Value[] vargs;
30 
31     foreach (arg; args) {
32       vargs ~= new Value(arg);
33     }
34 
35     this.engine.defineVariable("ARGS", new Value(vargs));
36   }
37 
38   bool checkBracket(string code) {
39     for (size_t i; i < code.length; ++i) {
40       char ch = code[i];
41 
42       if (ch == '(') { this.bracketState++; }
43       if (ch == ')') { this.bracketState--; }
44     }
45 
46     if (this.bracketState == 0) {
47       return true;
48     } else {
49       return false;
50     }
51   }
52 
53   void interpreter() {
54     string buf;
55     write("=> ");
56 
57     void e(char val) {
58       if (checkBracket(val.to!string) && (buf.length != 0)) {
59 //        writeln("buf -> ", buf);
60         auto transpiled = Transpiler.transpile(buf);
61 //        writeln("transpiled -> ", transpiled);
62         writeln(engine.eval(transpiled));
63         buf = [];
64       }
65     }
66 
67     while (true) {
68       string input = readln.chomp;
69 
70       if (input == "exit" || input == "(exit)") {
71         break;
72       }
73 
74       foreach (char val; input) {
75         if ('\n' == val) {
76           e(val);
77         } else {
78           buf ~= val;
79           e(val);
80         }
81       }
82 
83       for (size_t i; i < bracketState + 1; ++i) {
84         write("=");
85       }
86       write("> ");
87     }
88   }
89 
90   void executer(string code) {
91     string buf;
92 
93     void e(char val) {
94       if (checkBracket(val.to!string) && (buf.length != 0)) {
95         auto transpiled = Transpiler.transpile(buf);
96         engine.eval(transpiled);
97         buf = [];
98       }
99     }
100 
101     foreach(input; code.split("\n")) {
102       if (input == "exit" || input == "(exit)") {
103         break;
104       }
105 
106       foreach (char val; input) {
107         if ('\n' == val) {
108           e(val);
109         } else {
110           buf ~= val;
111           e(val);
112         }
113       }
114     }
115   }
116 }