Index: .poseidon
==================================================================
--- .poseidon
+++ .poseidon
@@ -32,10 +32,11 @@
d2stacktrace\stacktrace.d
main.d
polemy\_common.d
polemy\ast.d
polemy\eval.d
+ polemy\failure.d
polemy\lex.d
polemy\parse.d
polemy\value.d
tricks\test.d
tricks\tricks.d
Index: doc/candydoc/modules.ddoc
==================================================================
--- doc/candydoc/modules.ddoc
+++ doc/candydoc/modules.ddoc
@@ -1,10 +1,11 @@
MODULES =
$(MODULE main)
$(MODULE tricks.tricks)
$(MODULE tricks.test)
$(MODULE polemy._common)
+ $(MODULE polemy.failure)
$(MODULE polemy.lex)
$(MODULE polemy.parse)
$(MODULE polemy.ast)
$(MODULE polemy.eval)
$(MODULE polemy.value)
Index: main.d
==================================================================
--- main.d
+++ main.d
@@ -1,33 +1,75 @@
/**
* Authors: k.inaba
- * License: NYSL 0.9982 (http://www.kmonos.net/nysl/
+ * 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.lex;
+import polemy.failure;
import polemy.parse;
import polemy.ast;
import polemy.eval;
-/// Tenuki Read-Eval-Print-Loop
+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;
- this() { ctx = createGlobalContext(); }
- this(string filename) {
- ctx = createGlobalContext();
- eval(parseFile(filename), ctx, false, "@v");
- }
bool tryRun( string s )
{
scope(failure)
{ buf = ""; lineno = nextlineno; }
@@ -40,50 +82,49 @@
{ 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();
- bool singleInteraction()
- {
- writef(">> ", lineno);
- string line = readln();
- if( line.startsWith("exit") || line.startsWith("quit") )
- return false;
- try {
- if( tryRun(line) )
- {
- // for debugging.
- //try {
- // writeln(tableToAST("@v", cast(Table)lastVal));
- //} catch(Throwable e) {
- // writeln(e);
- //}
- writeln(lastVal);
- }
- } catch(Throwable e) {
- writeln(e);
+ while( !args.empty && args.front=="-l" ) {
+ args.popFront();
+ if( !args.empty ) {
+ libs ~= args.front();
+ args.popFront();
}
- return true;
+ }
+
+ if( args.empty )
+ return "";
+ else {
+ scope(exit) args.popFront;
+ return args.front;
}
}
-/// Entry point. If args.length==1, invoke REPL.
-/// If args.length==3 && args[1]=="-l" read args[2] and invoke REPL.
-/// Otherwise interpret the argument as a filename.
+/// Entry point.
+
void main( string[] args )
{
- if( args.length <= 1 )
- {
- writeln("Welcome to Polemy 0.1.0");
- for(auto r = new REPL; r.singleInteraction();) {}
- }
- else if( args.length>=3 && args[1]=="-l" )
- {
- writeln("Welcome to Polemy 0.1.0");
- for(auto r = new REPL(args[2]); r.singleInteraction();) {}
- }
+ 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
- {
- evalFile(args[1]);
- }
+ r.runFile(src);
}
Index: polemy/_common.d
==================================================================
--- polemy/_common.d
+++ polemy/_common.d
@@ -11,6 +11,6 @@
public import std.array;
public import std.bigint;
public import std.conv : text;
public import std.exception;
public import std.range;
-public import std.stdio : writeln; // for debugging...
+public import std.stdio : DBG = writeln;
Index: polemy/ast.d
==================================================================
--- polemy/ast.d
+++ polemy/ast.d
@@ -4,11 +4,11 @@
*
* Syntax tree for Polemy programming language.
*/
module polemy.ast;
import polemy._common;
-import polemy.lex;
+import polemy.failure;
///
abstract class AST
{
immutable LexPosition pos;
Index: polemy/eval.d
==================================================================
--- polemy/eval.d
+++ polemy/eval.d
@@ -4,15 +4,15 @@
*
* Evaluator for Polemy programming language.
*/
module polemy.eval;
import polemy._common;
-import polemy.lex : LexPosition;
+import polemy.failure;
import polemy.ast;
import polemy.parse;
import polemy.value;
-import std.typecons;
+import std.typecons;
import std.stdio;
///
Table createGlobalContext()
{
ADDED polemy/failure.d
Index: polemy/failure.d
==================================================================
--- polemy/failure.d
+++ polemy/failure.d
@@ -0,0 +1,64 @@
+/**
+ * Authors: k.inaba
+ * License: NYSL 0.9982 http://www.kmonos.net/nysl/
+ *
+ * Error Information for Polemy Programming Language
+ */
+module polemy.failure;
+import polemy._common;
+
+/// Represents a position in source codes
+
+class LexPosition
+{
+ immutable string filename; /// name of the source file
+ immutable int lineno; /// 1-origin
+ immutable int column; /// 1-origin
+
+ mixin SimpleClass;
+ override string toString() const
+ {
+ return sprintf!("%s:%d:%d")(filename, lineno, column);
+ }
+
+ static immutable LexPosition dummy;
+ static this(){ dummy = new immutable(LexPosition)("",0,0); }
+}
+
+unittest
+{
+ auto p = new LexPosition("hello.cpp", 123, 45);
+
+ assert_eq( p.filename, "hello.cpp" );
+ assert_eq( p.lineno, 123 );
+ assert_eq( p.column, 45 );
+ assert_eq( text(p), "hello.cpp:123:45" );
+
+ assert( !__traits(compiles, new LexPosition) );
+ assert( !__traits(compiles, p.filename="foo") );
+ assert( !__traits(compiles, p.lineno =789) );
+ assert( !__traits(compiles, p.column =222) );
+
+ auto q = new LexPosition("hello.cpp", 123, 46);
+ assert_lt( p, q );
+ assert_ne( p, q );
+}
+
+/*mixin*/
+template ExceptionWithPosition()
+{
+ const LexPosition pos;
+ this( const LexPosition pos, string msg, string file=null, size_t line=0, Throwable next=null )
+ {
+ if(pos is null)
+ super(sprintf!("[???????] %s")(msg), file, line, next);
+ else
+ super(sprintf!("[%s] %s")(pos, msg), file, line, next);
+ this.pos = pos;
+ }
+}
+
+class UnexpectedEOF : Exception { mixin ExceptionWithPosition; } /// EOF during lexing/parsing
+class LexException : Exception { mixin ExceptionWithPosition; } /// Lexer errors
+class ParseException : Exception { mixin ExceptionWithPosition; } /// Parser errors
+class RuntimeException : Exception { mixin ExceptionWithPosition; } /// Evaluator errors
Index: polemy/lex.d
==================================================================
--- polemy/lex.d
+++ polemy/lex.d
@@ -3,77 +3,15 @@
* License: NYSL 0.9982 http://www.kmonos.net/nysl/
*
* Lexer for Polemy programming language.
*/
module polemy.lex;
-import polemy._common;
+import polemy._common;
+import polemy.failure;
import std.file : readText;
import std.ctype : isspace, isalnum;
-/*mixin*/
-template ExceptionWithPosition()
-{
- const LexPosition pos;
- this( const LexPosition pos, string msg, string file=null, size_t line=0, Throwable next=null )
- {
- if(pos is null)
- super(sprintf!"[??] %s"(msg), file, line, next);
- else
- super(sprintf!"[%s] %s"(pos, msg), file, line, next);
- this.pos = pos;
- }
-}
-
-/// Thrown when encountered an EOF in the middle of a lexical token
-
-class UnexpectedEOF : Exception
-{
- mixin ExceptionWithPosition;
-}
-
-/// Thrown when encountered a lexical error
-
-class LexException : Exception
-{
- mixin ExceptionWithPosition;
-};
-
-/// Represents a position in source codes
-
-class LexPosition
-{
- immutable string filename; /// name of the source file
- immutable int lineno; /// 1-origin
- immutable int column; /// 1-origin
-
- mixin SimpleClass;
- override string toString() const
- { return sprintf!"%s:%d:%d"(filename, lineno, column); }
-
- static immutable LexPosition dummy;
- static this(){ dummy = new immutable(LexPosition)("",0,0); }
-}
-
-unittest
-{
- auto p = new LexPosition("hello.cpp", 123, 45);
-
- assert_eq( p.filename, "hello.cpp" );
- assert_eq( p.lineno, 123 );
- assert_eq( p.column, 45 );
- assert_eq( text(p), "hello.cpp:123:45" );
-
- assert( !__traits(compiles, new LexPosition) );
- assert( !__traits(compiles, p.filename="foo") );
- assert( !__traits(compiles, p.lineno =789) );
- assert( !__traits(compiles, p.column =222) );
-
- auto q = new LexPosition("hello.cpp", 123, 46);
- assert_lt( p, q );
- assert_ne( p, q );
-}
-
/// Represents a lexer token
class Token
{
immutable LexPosition pos; /// Position where the token occurred in the source
Index: polemy/parse.d
==================================================================
--- polemy/parse.d
+++ polemy/parse.d
@@ -4,20 +4,14 @@
*
* Parser for Polemy programming language
*/
module polemy.parse;
import polemy._common;
+import polemy.failure;
import polemy.lex;
import polemy.ast;
-/// Thrown when encountered a syntax error
-
-class ParseException : Exception
-{
- mixin ExceptionWithPosition;
-}
-
/// Parse a string and return its AST
/// Throws: ParseException, LexException, UnexpectedEOF
AST parseString(S, T...)(S str, T fn_ln_cn)
{
Index: polemy/value.d
==================================================================
--- polemy/value.d
+++ polemy/value.d
@@ -4,20 +4,13 @@
*
* Runtime data structures for Polemy programming language.
*/
module polemy.value;
import polemy._common;
-import polemy.lex;
+import polemy.failure;
import polemy.ast;
-/// Raised when something went wrong in runtime
-
-class RuntimeException : Exception
-{
- mixin ExceptionWithPosition;
-}
-
/// Runtime values of Polemy
abstract class Value
{
}
Index: readme.txt
==================================================================
--- readme.txt
+++ readme.txt
@@ -48,10 +48,13 @@
executes foo.pmy
> polemy -l foo.pmy
after executing foo.pmy, starts REPL
+ > polemy -l foo.pmy -l bar.pmy buz.pmy
+ executes foo.pmy, bar.bmy, and then buz.pmy
+
<>
Comment is "# ... \n"