Artifact Content
Not logged in

Artifact 3594122dc7a67c3c24c2950d360a517b461f1540


     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.parse;
    14  import polemy.ast;
    15  import polemy.eval;
    16  
    17  enum VersionNoMajor = 0;
    18  enum VersionNoMinor = 1;
    19  enum VersionNoRev   = 0;
    20  
    21  /// Read-Eval-Print-Loop
    22  
    23  class REPL
    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:
    66  	Table ctx;
    67  	string buf;
    68  	Value  lastVal;
    69  	int lineno = 1;
    70  	int nextlineno = 1;
    71  
    72  	bool tryRun( string s )
    73  	{
    74  		scope(failure)
    75  			{ buf = ""; lineno = nextlineno; }
    76  
    77  		buf ~= s;
    78  		nextlineno ++;
    79  		try 
    80  			{ lastVal = eval(parseString(buf, "<REPL>", lineno), ctx, false, "@v"); }
    81  		catch( UnexpectedEOF )
    82  			{ return false; } // wait
    83  		buf = "";
    84  		lineno = nextlineno;
    85  		return true;
    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();
    97  
    98  	while( !args.empty && args.front=="-l" ) {
    99  		args.popFront();
   100  		if( !args.empty ) {
   101  			libs ~= args.front();
   102  			args.popFront();
   103  		}
   104  	}
   105  
   106  	if( args.empty )
   107  		return "";
   108  	else {
   109  		scope(exit) args.popFront;
   110  		return args.front;
   111  	}
   112  }
   113  
   114  /// Entry point.
   115  
   116  void main( string[] args )
   117  {
   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();
   128  	else
   129  		r.runFile(src);
   130  }