Artifact Content
Not logged in

Artifact e659b2cb410288fdf9df67973a47e1e3f82c1400


     1  /**
     2   * Authors: k.inaba
     3   * License: NYSL 0.9982 (http://www.kmonos.net/nysl/)
     4   *
     5   * Entry point for Polemy interpreter.
     6   */
     7  module main;
     8  import std.stdio;
     9  import std.algorithm;
    10  import std.array;
    11  import polemy.value;
    12  import polemy.failure;
    13  import polemy.layer;
    14  import polemy.parse;
    15  import polemy.ast;
    16  import polemy.eval;
    17  
    18  enum VersionNoMajor = 0;
    19  enum VersionNoMinor = 1;
    20  enum VersionNoRev   = 0;
    21  
    22  /// Read-Eval-Print-Loop
    23  
    24  class REPL
    25  {
    26  Evaluator ev;
    27  	/// Load the prelude environment
    28  	this()
    29  	{
    30  		ev = new Evaluator;
    31  	}
    32  
    33  	/// Print the version number etc.
    34  	void greet()
    35  	{
    36  		writefln("Welcome to Polemy %d.%d.%d", VersionNoMajor, VersionNoMinor, VersionNoRev);
    37  	}
    38  
    39  	/// Run one file on the global scope
    40  	void runFile(string filename)
    41  	{
    42  		ev.evalFile(filename);
    43  	}
    44  
    45  	/// Repeat the singleInteraction
    46  	void replLoop()
    47  	{
    48  		while( singleInteraction() ) {}
    49  	}
    50  
    51  	/// Read one line from stdin, and do some reaction
    52  	bool singleInteraction()
    53  	{
    54  		writef(">> ", lineno);
    55  		string line = readln();
    56  		if( line.startsWith("exit") || line.startsWith("quit") )
    57  			return false;
    58  		try {
    59  			if( tryRun(line) )
    60  				writeln(lastVal);
    61  		} catch(Throwable e) {
    62  			writeln(e);
    63  		}
    64  		return true;
    65  	}
    66  
    67  private:
    68  	Table ctx;
    69  	string buf;
    70  	Value  lastVal;
    71  	int lineno = 1;
    72  	int nextlineno = 1;
    73  
    74  	bool tryRun( string s )
    75  	{
    76  		scope(failure)
    77  			{ buf = ""; lineno = nextlineno; }
    78  
    79  		buf ~= s;
    80  		nextlineno ++;
    81  		try 
    82  			{ lastVal = ev.evalString(buf, "<REPL>", lineno); }
    83  		catch( UnexpectedEOF )
    84  			{ return false; } // wait
    85  		buf = "";
    86  		lineno = nextlineno;
    87  		return true;
    88  	}
    89  }
    90  
    91  /// Advance args[] to point the argument list fed to the script.
    92  /// Returns the name of the source file to run, or returns "" if
    93  /// no filename was given. Also, returns to libs[] the list of
    94  /// library source to load.
    95  
    96  string parseArgv(ref string[] args, out string[] libs)
    97  {
    98  	args.popFront();
    99  
   100  	while( !args.empty && args.front=="-l" ) {
   101  		args.popFront();
   102  		if( !args.empty ) {
   103  			libs ~= args.front();
   104  			args.popFront();
   105  		}
   106  	}
   107  
   108  	if( args.empty )
   109  		return "";
   110  	else {
   111  		scope(exit) args.popFront;
   112  		return args.front;
   113  	}
   114  }
   115  
   116  /// Entry point.
   117  
   118  void main( string[] args )
   119  {
   120  	string[] libs;
   121  	string   src = parseArgv(args, libs);
   122  
   123  	auto r = new REPL;
   124  	if( src.empty )
   125  		r.greet();
   126  	foreach(lb; libs)
   127  		r.runFile(lb);
   128  	if( src.empty )
   129  		r.replLoop();
   130  	else
   131  		r.runFile(src);
   132  }