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, bool showMsg = true) { 95 string buf; 96 Value ret; 97 98 try { 99 void e(char val) { 100 if (checkBracket(val.to!string) && (buf.length != 0)) { 101 auto transpiled = Transpiler.transpile(buf); 102 ret = engine.eval(transpiled); 103 buf = []; 104 } 105 } 106 107 foreach(input; code.split("\n")) { 108 if (input == "exit" || input == "(exit)") { 109 break; 110 } 111 112 foreach (char val; input) { 113 if ('\n' == val) { 114 e(val); 115 } else { 116 buf ~= val; 117 e(val); 118 } 119 } 120 } 121 122 return ret; 123 } catch (Exception e) { 124 if (showMsg) { 125 writeln("[Exception] - ", e.msg); 126 } 127 return new Value(new CCException(e.msg)); 128 } 129 } 130 }