Artifact 3594122dc7a67c3c24c2950d360a517b461f1540
/**
* Authors: k.inaba
* License: NYSL 0.9982 (http://www.kmonos.net/nysl/)
*
* Entry point for Polemy interpreter.
*/
module main;
import std.stdio;
import std.algorithm;
import std.array;
import polemy.value;
import polemy.failure;
import polemy.parse;
import polemy.ast;
import polemy.eval;
enum VersionNoMajor = 0;
enum VersionNoMinor = 1;
enum VersionNoRev = 0;
/// Read-Eval-Print-Loop
class REPL
{
/// Load the prelude environment
this()
{
ctx = createGlobalContext();
}
/// 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)
{
eval(parseFile(filename), ctx, false, "@v");
}
/// 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") )
return false;
try {
if( tryRun(line) )
writeln(lastVal);
} catch(Throwable e) {
writeln(e);
}
return true;
}
private:
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 = eval(parseString(buf, "<REPL>", lineno), ctx, false, "@v"); }
catch( UnexpectedEOF )
{ return false; } // wait
buf = "";
lineno = nextlineno;
return true;
}
}
/// Advance args[] to point the argument list fed to the script.
/// Returns the name of the source file to run, or returns "" if
/// no filename was given. Also, returns to libs[] the list of
/// library source to load.
string parseArgv(ref string[] args, out string[] libs)
{
args.popFront();
while( !args.empty && args.front=="-l" ) {
args.popFront();
if( !args.empty ) {
libs ~= args.front();
args.popFront();
}
}
if( args.empty )
return "";
else {
scope(exit) args.popFront;
return args.front;
}
}
/// Entry point.
void main( string[] args )
{
string[] libs;
string src = parseArgv(args, libs);
auto r = new REPL;
if( src.empty )
r.greet();
foreach(lb; libs)
r.runFile(lb);
if( src.empty )
r.replLoop();
else
r.runFile(src);
}