Artifact abae545f4409680b811fbd5ac043cf811b1fad4a
1 /**
2 * Authors: k.inaba
3 * License: NYSL 0.9982 (http://www.kmonos.net/nysl/
4 *
5 * Entry point for Polemy interpreter.
6 */
7
8 import std.stdio;
9 import std.algorithm;
10 import polemy.value;
11 import polemy.lex;
12 import polemy.parse;
13 import polemy.ast;
14 import polemy.eval;
15
16 /// Tenuki Read-Eval-Print-Loop
17 class REPL
18 {
19 Table ctx;
20 string buf;
21 Value lastVal;
22 int lineno = 1;
23 int nextlineno = 1;
24 this() { ctx = createGlobalContext(); }
25
26 bool tryRun( string s )
27 {
28 scope(failure)
29 { buf = ""; lineno = nextlineno; }
30
31 buf ~= s;
32 nextlineno ++;
33 try
34 { lastVal = eval(parseString(buf, "<REPL>", lineno), ctx, false, "@v"); }
35 catch( UnexpectedEOF )
36 { return false; } // wait
37 buf = "";
38 lineno = nextlineno;
39 return true;
40 }
41
42 bool singleInteraction()
43 {
44 writef(">> ", lineno);
45 string line = readln();
46 if( line.startsWith("exit") || line.startsWith("quit") )
47 return false;
48 try {
49 if( tryRun(line) )
50 writeln(lastVal);
51 } catch(Throwable e) {
52 writeln(e);
53 }
54 return true;
55 }
56 }
57
58 version(unittest) {
59 bool success = false;
60 static ~this(){ if(!success){writeln("(press enter to exit)"); readln();} }
61 }
62
63 /// Entry point. If args.length==1, invoke REPL.
64 /// Otherwise interpret the argument as a filename.
65 void main( string[] args )
66 {
67 version(unittest) success=true;
68
69 if( args.length <= 1 )
70 {
71 writeln("Welcome to Polemy 0.1.0");
72 for(auto r = new REPL; r.singleInteraction();) {}
73 }
74 else
75 {
76 evalFile(args[1]);
77 }
78 }