Artifact b6f89f38f0a1626d03407b97a2d9b2df3867472c
/**
* Authors: k.inaba
* License: NYSL 0.9982 (http://www.kmonos.net/nysl/
*
* Entry point for Polemy interpreter.
*/
import std.stdio;
import std.algorithm;
import polemy.value;
import polemy.lex;
import polemy.parse;
import polemy.ast;
import polemy.eval;
/// Tenuki Read-Eval-Print-Loop
class REPL
{
Table ctx;
string buf;
Value lastVal;
int lineno = 1;
int nextlineno = 1;
this() { ctx = createGlobalContext(); }
this(string filename) {
ctx = createGlobalContext();
eval(parseFile(filename), ctx, false, "@v");
}
bool tryRun( string s )
{
scope(failure)
{ buf = ""; lineno = nextlineno; }
buf ~= s;
nextlineno ++;
try
{ lastVal = eval(parseString(buf, "<REPL>", lineno), ctx, false, "@v"); }
catch( UnexpectedEOF )
{ return false; } // wait
buf = "";
lineno = nextlineno;
return true;
}
bool singleInteraction()
{
writef(">> ", lineno);
string line = readln();
if( line.startsWith("exit") || line.startsWith("quit") )
return false;
try {
if( tryRun(line) )
writeln(lastVal);
} catch(Throwable e) {
writeln(e);
}
return true;
}
}
/// Entry point. If args.length==1, invoke REPL.
/// If args.length==3 && args[1]=="-l" read args[2] and invoke REPL.
/// Otherwise interpret the argument as a filename.
void main( string[] args )
{
if( args.length <= 1 )
{
writeln("Welcome to Polemy 0.1.0");
for(auto r = new REPL; r.singleInteraction();) {}
}
else if( args.length>=3 && args[1]=="-l" )
{
writeln("Welcome to Polemy 0.1.0");
for(auto r = new REPL(args[2]); r.singleInteraction();) {}
}
else
{
evalFile(args[1]);
}
}