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