4198578702 2010-11-07 kinaba: /** 4198578702 2010-11-07 kinaba: * Authors: k.inaba 3464a035ec 2010-11-20 kinaba: * License: NYSL 0.9982 (http://www.kmonos.net/nysl/) 4198578702 2010-11-07 kinaba: * 4198578702 2010-11-07 kinaba: * Entry point for Polemy interpreter. 423f308350 2010-11-07 kinaba: */ 3464a035ec 2010-11-20 kinaba: module main; 423f308350 2010-11-07 kinaba: import std.stdio; 7de80acfb8 2010-11-09 kinaba: import std.algorithm; 3464a035ec 2010-11-20 kinaba: import std.array; 7de80acfb8 2010-11-09 kinaba: import polemy.value; 3464a035ec 2010-11-20 kinaba: import polemy.failure; 7de80acfb8 2010-11-09 kinaba: import polemy.parse; 7de80acfb8 2010-11-09 kinaba: import polemy.ast; 7de80acfb8 2010-11-09 kinaba: import polemy.eval; 7de80acfb8 2010-11-09 kinaba: 3464a035ec 2010-11-20 kinaba: enum VersionNoMajor = 0; 3464a035ec 2010-11-20 kinaba: enum VersionNoMinor = 1; 3464a035ec 2010-11-20 kinaba: enum VersionNoRev = 0; 3464a035ec 2010-11-20 kinaba: 3464a035ec 2010-11-20 kinaba: /// Read-Eval-Print-Loop 3464a035ec 2010-11-20 kinaba: 7de80acfb8 2010-11-09 kinaba: class REPL 7de80acfb8 2010-11-09 kinaba: { 3464a035ec 2010-11-20 kinaba: /// Load the prelude environment 3464a035ec 2010-11-20 kinaba: this() 3464a035ec 2010-11-20 kinaba: { 3464a035ec 2010-11-20 kinaba: ctx = createGlobalContext(); 3464a035ec 2010-11-20 kinaba: } 3464a035ec 2010-11-20 kinaba: 3464a035ec 2010-11-20 kinaba: /// Print the version number etc. 3464a035ec 2010-11-20 kinaba: void greet() 3464a035ec 2010-11-20 kinaba: { 3464a035ec 2010-11-20 kinaba: writefln("Welcome to Polemy %d.%d.%d", VersionNoMajor, VersionNoMinor, VersionNoRev); 3464a035ec 2010-11-20 kinaba: } 3464a035ec 2010-11-20 kinaba: 3464a035ec 2010-11-20 kinaba: /// Run one file on the global scope 3464a035ec 2010-11-20 kinaba: void runFile(string filename) 3464a035ec 2010-11-20 kinaba: { 3464a035ec 2010-11-20 kinaba: eval(parseFile(filename), ctx, false, "@v"); 3464a035ec 2010-11-20 kinaba: } 3464a035ec 2010-11-20 kinaba: 3464a035ec 2010-11-20 kinaba: /// Repeat the singleInteraction 3464a035ec 2010-11-20 kinaba: void replLoop() 3464a035ec 2010-11-20 kinaba: { 3464a035ec 2010-11-20 kinaba: while( singleInteraction() ) {} 3464a035ec 2010-11-20 kinaba: } 3464a035ec 2010-11-20 kinaba: 3464a035ec 2010-11-20 kinaba: /// Read one line from stdin, and do some reaction 3464a035ec 2010-11-20 kinaba: bool singleInteraction() 3464a035ec 2010-11-20 kinaba: { 3464a035ec 2010-11-20 kinaba: writef(">> ", lineno); 3464a035ec 2010-11-20 kinaba: string line = readln(); 3464a035ec 2010-11-20 kinaba: if( line.startsWith("exit") || line.startsWith("quit") ) 3464a035ec 2010-11-20 kinaba: return false; 3464a035ec 2010-11-20 kinaba: try { 3464a035ec 2010-11-20 kinaba: if( tryRun(line) ) 3464a035ec 2010-11-20 kinaba: writeln(lastVal); 3464a035ec 2010-11-20 kinaba: } catch(Throwable e) { 3464a035ec 2010-11-20 kinaba: writeln(e); 3464a035ec 2010-11-20 kinaba: } 3464a035ec 2010-11-20 kinaba: return true; 3464a035ec 2010-11-20 kinaba: } 3464a035ec 2010-11-20 kinaba: 3464a035ec 2010-11-20 kinaba: private: 7465fcdd7f 2010-11-09 kinaba: Table ctx; 7465fcdd7f 2010-11-09 kinaba: string buf; 7465fcdd7f 2010-11-09 kinaba: Value lastVal; 7465fcdd7f 2010-11-09 kinaba: int lineno = 1; 7465fcdd7f 2010-11-09 kinaba: int nextlineno = 1; 7de80acfb8 2010-11-09 kinaba: 7465fcdd7f 2010-11-09 kinaba: bool tryRun( string s ) 7de80acfb8 2010-11-09 kinaba: { 7465fcdd7f 2010-11-09 kinaba: scope(failure) 7465fcdd7f 2010-11-09 kinaba: { buf = ""; lineno = nextlineno; } 7465fcdd7f 2010-11-09 kinaba: 7465fcdd7f 2010-11-09 kinaba: buf ~= s; 7465fcdd7f 2010-11-09 kinaba: nextlineno ++; 7465fcdd7f 2010-11-09 kinaba: try 7465fcdd7f 2010-11-09 kinaba: { lastVal = eval(parseString(buf, "<REPL>", lineno), ctx, false, "@v"); } 7465fcdd7f 2010-11-09 kinaba: catch( UnexpectedEOF ) 7465fcdd7f 2010-11-09 kinaba: { return false; } // wait 7465fcdd7f 2010-11-09 kinaba: buf = ""; 7465fcdd7f 2010-11-09 kinaba: lineno = nextlineno; 7465fcdd7f 2010-11-09 kinaba: return true; 7465fcdd7f 2010-11-09 kinaba: } 3464a035ec 2010-11-20 kinaba: } 3464a035ec 2010-11-20 kinaba: 3464a035ec 2010-11-20 kinaba: /// Advance args[] to point the argument list fed to the script. 3464a035ec 2010-11-20 kinaba: /// Returns the name of the source file to run, or returns "" if 3464a035ec 2010-11-20 kinaba: /// no filename was given. Also, returns to libs[] the list of 3464a035ec 2010-11-20 kinaba: /// library source to load. 3464a035ec 2010-11-20 kinaba: 3464a035ec 2010-11-20 kinaba: string parseArgv(ref string[] args, out string[] libs) 3464a035ec 2010-11-20 kinaba: { 3464a035ec 2010-11-20 kinaba: args.popFront(); 7465fcdd7f 2010-11-09 kinaba: 3464a035ec 2010-11-20 kinaba: while( !args.empty && args.front=="-l" ) { 3464a035ec 2010-11-20 kinaba: args.popFront(); 3464a035ec 2010-11-20 kinaba: if( !args.empty ) { 3464a035ec 2010-11-20 kinaba: libs ~= args.front(); 3464a035ec 2010-11-20 kinaba: args.popFront(); 7465fcdd7f 2010-11-09 kinaba: } 3464a035ec 2010-11-20 kinaba: } 3464a035ec 2010-11-20 kinaba: 3464a035ec 2010-11-20 kinaba: if( args.empty ) 3464a035ec 2010-11-20 kinaba: return ""; 3464a035ec 2010-11-20 kinaba: else { 3464a035ec 2010-11-20 kinaba: scope(exit) args.popFront; 3464a035ec 2010-11-20 kinaba: return args.front; 7de80acfb8 2010-11-09 kinaba: } 7465fcdd7f 2010-11-09 kinaba: } 7465fcdd7f 2010-11-09 kinaba: 3464a035ec 2010-11-20 kinaba: /// Entry point. 3464a035ec 2010-11-20 kinaba: 7465fcdd7f 2010-11-09 kinaba: void main( string[] args ) 7465fcdd7f 2010-11-09 kinaba: { 3464a035ec 2010-11-20 kinaba: string[] libs; 3464a035ec 2010-11-20 kinaba: string src = parseArgv(args, libs); 3464a035ec 2010-11-20 kinaba: 3464a035ec 2010-11-20 kinaba: auto r = new REPL; 3464a035ec 2010-11-20 kinaba: if( src.empty ) 3464a035ec 2010-11-20 kinaba: r.greet(); 3464a035ec 2010-11-20 kinaba: foreach(lb; libs) 3464a035ec 2010-11-20 kinaba: r.runFile(lb); 3464a035ec 2010-11-20 kinaba: if( src.empty ) 3464a035ec 2010-11-20 kinaba: r.replLoop(); 7465fcdd7f 2010-11-09 kinaba: else 3464a035ec 2010-11-20 kinaba: r.runFile(src); 423f308350 2010-11-07 kinaba: }