Artifact b98f6cda3b1606b700eb0230aebf5bfec2bf4862
/**
* Authors: k.inaba
* License: NYSL 0.9982 (http://www.kmonos.net/nysl/)
*
* Read-Eval-Print-Loop
*/
module polemy.repl;
import polemy.failure;
import polemy.layer;
import polemy.eval;
import polemy.runtime;
import polemy.value;
import polemy.valueconv;
import std.stdio;
import std.string;
import std.cstream;
enum VersionNoMajor = 0; /// Version Number
enum VersionNoMinor = 1; /// Version Number
enum VersionNoRev = 0; /// Version Number
/// Read-Eval-Print-Loop
class REPL
{
/// Load the prelude environment
this(string[] args)
{
ev = new Evaluator;
ev.globalContext.set("argv", ValueLayer, d2polemy(args));
enrollRuntimeLibrary(ev);
}
/// Print the version number etc.
void greet()
{
writefln("Welcome to Polemy %d.%d.%d", VersionNoMajor, VersionNoMinor, VersionNoRev);
}
/// Run one file on the global scope
void runFile(string filename)
{
ev.evalFile(filename);
}
/// Repeat the singleInteraction
void replLoop()
{
while( singleInteraction() ) {}
}
/// Read one line from stdin, and do some reaction
bool singleInteraction()
{
writef(">> ", lineno);
string line = readln();
if( line.startsWith("exit") || line.startsWith("quit") || din.eof() )
return false;
try {
if( tryRun(line) )
writeln(lastVal);
} catch(Throwable e) {
writeln(e);
}
return true;
}
private:
Evaluator ev;
Table ctx;
string buf;
Value lastVal;
int lineno = 1;
int nextlineno = 1;
bool tryRun( string s )
{
scope(failure)
{ buf = ""; lineno = nextlineno; }
buf ~= s;
nextlineno ++;
try
{ lastVal = ev.evalString(buf, "<REPL>", lineno); }
catch( UnexpectedEOF )
{ return false; } // wait
buf = "";
lineno = nextlineno;
return true;
}
}