Artifact e659b2cb410288fdf9df67973a47e1e3f82c1400
1 /**
2 * Authors: k.inaba
3 * License: NYSL 0.9982 (http://www.kmonos.net/nysl/)
4 *
5 * Entry point for Polemy interpreter.
6 */
7 module main;
8 import std.stdio;
9 import std.algorithm;
10 import std.array;
11 import polemy.value;
12 import polemy.failure;
13 import polemy.layer;
14 import polemy.parse;
15 import polemy.ast;
16 import polemy.eval;
17
18 enum VersionNoMajor = 0;
19 enum VersionNoMinor = 1;
20 enum VersionNoRev = 0;
21
22 /// Read-Eval-Print-Loop
23
24 class REPL
25 {
26 Evaluator ev;
27 /// Load the prelude environment
28 this()
29 {
30 ev = new Evaluator;
31 }
32
33 /// Print the version number etc.
34 void greet()
35 {
36 writefln("Welcome to Polemy %d.%d.%d", VersionNoMajor, VersionNoMinor, VersionNoRev);
37 }
38
39 /// Run one file on the global scope
40 void runFile(string filename)
41 {
42 ev.evalFile(filename);
43 }
44
45 /// Repeat the singleInteraction
46 void replLoop()
47 {
48 while( singleInteraction() ) {}
49 }
50
51 /// Read one line from stdin, and do some reaction
52 bool singleInteraction()
53 {
54 writef(">> ", lineno);
55 string line = readln();
56 if( line.startsWith("exit") || line.startsWith("quit") )
57 return false;
58 try {
59 if( tryRun(line) )
60 writeln(lastVal);
61 } catch(Throwable e) {
62 writeln(e);
63 }
64 return true;
65 }
66
67 private:
68 Table ctx;
69 string buf;
70 Value lastVal;
71 int lineno = 1;
72 int nextlineno = 1;
73
74 bool tryRun( string s )
75 {
76 scope(failure)
77 { buf = ""; lineno = nextlineno; }
78
79 buf ~= s;
80 nextlineno ++;
81 try
82 { lastVal = ev.evalString(buf, "<REPL>", lineno); }
83 catch( UnexpectedEOF )
84 { return false; } // wait
85 buf = "";
86 lineno = nextlineno;
87 return true;
88 }
89 }
90
91 /// Advance args[] to point the argument list fed to the script.
92 /// Returns the name of the source file to run, or returns "" if
93 /// no filename was given. Also, returns to libs[] the list of
94 /// library source to load.
95
96 string parseArgv(ref string[] args, out string[] libs)
97 {
98 args.popFront();
99
100 while( !args.empty && args.front=="-l" ) {
101 args.popFront();
102 if( !args.empty ) {
103 libs ~= args.front();
104 args.popFront();
105 }
106 }
107
108 if( args.empty )
109 return "";
110 else {
111 scope(exit) args.popFront;
112 return args.front;
113 }
114 }
115
116 /// Entry point.
117
118 void main( string[] args )
119 {
120 string[] libs;
121 string src = parseArgv(args, libs);
122
123 auto r = new REPL;
124 if( src.empty )
125 r.greet();
126 foreach(lb; libs)
127 r.runFile(lb);
128 if( src.empty )
129 r.replLoop();
130 else
131 r.runFile(src);
132 }