Diff
Not logged in

Differences From Artifact [d5ef45952651bda8]:

To Artifact [3594122dc7a67c3c]:


1 1 /** 2 2 * Authors: k.inaba 3 - * License: NYSL 0.9982 (http://www.kmonos.net/nysl/ 3 + * License: NYSL 0.9982 (http://www.kmonos.net/nysl/) 4 4 * 5 5 * Entry point for Polemy interpreter. 6 6 */ 7 - 7 +module main; 8 8 import std.stdio; 9 9 import std.algorithm; 10 +import std.array; 10 11 import polemy.value; 11 -import polemy.lex; 12 +import polemy.failure; 12 13 import polemy.parse; 13 14 import polemy.ast; 14 15 import polemy.eval; 15 16 16 -/// Tenuki Read-Eval-Print-Loop 17 +enum VersionNoMajor = 0; 18 +enum VersionNoMinor = 1; 19 +enum VersionNoRev = 0; 20 + 21 +/// Read-Eval-Print-Loop 22 + 17 23 class REPL 18 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: 19 66 Table ctx; 20 67 string buf; 21 68 Value lastVal; 22 69 int lineno = 1; 23 70 int nextlineno = 1; 24 - this() { ctx = createGlobalContext(); } 25 - this(string filename) { 26 - ctx = createGlobalContext(); 27 - eval(parseFile(filename), ctx, false, "@v"); 28 - } 29 71 30 72 bool tryRun( string s ) 31 73 { 32 74 scope(failure) 33 75 { buf = ""; lineno = nextlineno; } 34 76 35 77 buf ~= s; ................................................................................ 38 80 { lastVal = eval(parseString(buf, "<REPL>", lineno), ctx, false, "@v"); } 39 81 catch( UnexpectedEOF ) 40 82 { return false; } // wait 41 83 buf = ""; 42 84 lineno = nextlineno; 43 85 return true; 44 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(); 45 97 46 - bool singleInteraction() 47 - { 48 - writef(">> ", lineno); 49 - string line = readln(); 50 - if( line.startsWith("exit") || line.startsWith("quit") ) 51 - return false; 52 - try { 53 - if( tryRun(line) ) 54 - { 55 - // for debugging. 56 - //try { 57 - // writeln(tableToAST("@v", cast(Table)lastVal)); 58 - //} catch(Throwable e) { 59 - // writeln(e); 60 - //} 61 - writeln(lastVal); 62 - } 63 - } catch(Throwable e) { 64 - writeln(e); 98 + while( !args.empty && args.front=="-l" ) { 99 + args.popFront(); 100 + if( !args.empty ) { 101 + libs ~= args.front(); 102 + args.popFront(); 65 103 } 66 - return true; 104 + } 105 + 106 + if( args.empty ) 107 + return ""; 108 + else { 109 + scope(exit) args.popFront; 110 + return args.front; 67 111 } 68 112 } 69 113 70 -/// Entry point. If args.length==1, invoke REPL. 71 -/// If args.length==3 && args[1]=="-l" read args[2] and invoke REPL. 72 -/// Otherwise interpret the argument as a filename. 114 +/// Entry point. 115 + 73 116 void main( string[] args ) 74 117 { 75 - if( args.length <= 1 ) 76 - { 77 - writeln("Welcome to Polemy 0.1.0"); 78 - for(auto r = new REPL; r.singleInteraction();) {} 79 - } 80 - else if( args.length>=3 && args[1]=="-l" ) 81 - { 82 - writeln("Welcome to Polemy 0.1.0"); 83 - for(auto r = new REPL(args[2]); r.singleInteraction();) {} 84 - } 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(); 85 128 else 86 - { 87 - evalFile(args[1]); 88 - } 129 + r.runFile(src); 89 130 }