Index: .poseidon ================================================================== --- .poseidon +++ .poseidon @@ -9,11 +9,11 @@ 0 main.d - -g -unittest + -cov -D -Dddoc -g -unittest @@ -28,10 +28,12 @@ d2stacktrace\dbghelp.d d2stacktrace\stacktrace.d + doc\candydoc\candy.ddoc + doc\candydoc\modules.ddoc main.d polemy\_common.d polemy\ast.d polemy\eval.d polemy\failure.d @@ -46,14 +48,13 @@ build.bat build.sh - builddoc.bat readme.txt DELETED builddoc.bat Index: builddoc.bat ================================================================== --- builddoc.bat +++ builddoc.bat @@ -1,6 +0,0 @@ -@setlocal ENABLEDELAYEDEXPANSION -@set ARGS= -@for %%I in (main.d polemy\*.d tricks\*.d) do @set ARGS=!ARGS! %%I -@if not exist bin mkdir bin -@echo dmd -o- -Dddoc doc\candydoc\candy.ddoc doc\candydoc\modules.ddoc %ARGS% -@dmd -o- -Dddoc doc\candydoc\candy.ddoc doc\candydoc\modules.ddoc %ARGS% Index: polemy/ast.d ================================================================== --- polemy/ast.d +++ polemy/ast.d @@ -9,11 +9,11 @@ import polemy.failure; /// abstract class AST { - immutable LexPosition pos; + LexPosition pos; mixin SimpleConstructor; mixin SimplePatternMatch; } /// Index: polemy/failure.d ================================================================== --- polemy/failure.d +++ polemy/failure.d @@ -7,11 +7,11 @@ module polemy.failure; import polemy._common; /// Represents a position in source codes -class LexPosition +class LexPosition_t { immutable string filename; /// name of the source file immutable int lineno; /// 1-origin immutable int column; /// 1-origin @@ -19,14 +19,18 @@ override string toString() const { return sprintf!("%s:%d:%d")(filename, lineno, column); } - static immutable LexPosition dummy; - static this(){ dummy = new immutable(LexPosition)("",0,0); } + static LexPosition dummy; + static this(){ dummy = new LexPosition("",0,0); } } +/// Represents a position in source codes + +alias immutable(LexPosition_t) LexPosition; + unittest { auto p = new LexPosition("hello.cpp", 123, 45); assert_eq( p.filename, "hello.cpp" ); @@ -45,15 +49,15 @@ } /*mixin*/ template ExceptionWithPosition() { - const LexPosition pos; - this( const LexPosition pos, string msg, string file=null, size_t line=0, Throwable next=null ) + LexPosition pos; + this( 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); + super(sprintf!("[??] %s")(msg), file, line, next); else super(sprintf!("[%s] %s")(pos, msg), file, line, next); this.pos = pos; } } Index: polemy/lex.d ================================================================== --- polemy/lex.d +++ polemy/lex.d @@ -21,11 +21,11 @@ mixin SimpleClass; } unittest { - auto p = new immutable(LexPosition)("hello.cpp", 123, 45); + auto p = new LexPosition("hello.cpp", 123, 45); auto t = new Token(p, "class", false); auto u = new Token(p, "class", true); assert_eq( t.pos, p ); assert_eq( t.str, "class" ); @@ -371,16 +371,16 @@ { return this; } /// Get the current position - immutable(LexPosition) currentPosition() const + LexPosition currentPosition() const { - return new immutable(LexPosition)(filename, lineno, column); + return new LexPosition(filename, lineno, column); } } unittest { assert( isForwardRange!(PositionedReader!string) ); assert( is(ElementType!(PositionedReader!string) == dchar) ); } Index: polemy/parse.d ================================================================== --- polemy/parse.d +++ polemy/parse.d @@ -10,19 +10,17 @@ import polemy.lex; import polemy.ast; import polemy.layer; /// Parse a string and return its AST -/// Throws: ParseException, LexException, UnexpectedEOF AST parseString(S, T...)(S str, T fn_ln_cn) { return parserFromString(str, fn_ln_cn).parse(); } /// Parse the content of a file and return its AST -/// Throws: ParseException, LexException, UnexpectedEOF AST parseFile(S, T...)(S filename, T ln_cn) { return parserFromFile(filename, ln_cn).parse(); } @@ -73,30 +71,30 @@ /// | ["@" Layer|"let"|"var"|"def"] Var "(" Param%"," ")" "{" Body "}" ([";"|"in"] Body?)? /// | ["@" "@" Layer "=" Expression ([";"|"in"] Body?)? /// | ["@" "@" Layer "(" Param%"," ")" "{" Body "}" ([";"|"in"] Body?)? auto pos = currentPosition(); - string layer = ""; - bool layerRiseDecl = false; + Layer layer = ""; + bool layerLiftDecl = false; if( tryEat("@") ) { layer = "@" ~ eatId("after @", AllowQuoted); if( layer == "@@" ) { layer = "@" ~ eatId("after @@", AllowQuoted); - layerRiseDecl = true; + layerLiftDecl = true; } else { if( tryEat("(") ) return null; // @lay(...) expression, not a declaration } } // [TODO] Refactor - if( layerRiseDecl ) + if( layerLiftDecl ) { string kwd = "@" ~ layer; string var = layer; auto e = tryEat("(") @@ -103,11 +101,13 @@ ? parseLambdaAfterOpenParen(pos) // let var ( ... : (eat("=", "after "~kwd), E(0)); // let var = ... if( moreDeclarationExists() ) return new LetExpression(pos, var, SystemLayer, e, Body()); else - return new LetExpression(pos, var, SystemLayer, e, new VarExpression(pos, var)); + return new LetExpression(pos, var, SystemLayer, e, + new LayeredExpression(pos, SystemLayer, new VarExpression(pos, var)) + ); } else { string kwd = layer; if( layer.empty && !tryEat(kwd="let") && !tryEat(kwd="var") && !tryEat(kwd="def") ) @@ -391,11 +391,11 @@ return lex.front.str; } AST doNothingExpression() { - return new IntLiteral(currentPosition(), BigInt(178)); + return new StrLiteral(currentPosition(), "(empty function body)"); } immutable(LexPosition) currentPosition() { return lex.empty ? null : lex.front.pos; @@ -418,21 +418,21 @@ assert_eq(parseString(`var x=1;2;`), let("x","",intl(1),intl(2))); assert_eq(parseString(`def x=1`), let("x","",intl(1),var("x"))); assert_eq(parseString(`@val x=1;`), let("x","@val",intl(1),var("x"))); assert_eq(parseString(`@typ x="#int";`), let("x","@typ",strl("#int"),var("x"))); assert_eq(parseString(`f(1,2)`), call(var("f"),intl(1),intl(2))); - assert_eq(parseString(`if(1){2}`), call(var("if"),intl(1),fun([],intl(2)),fun([],intl(178)))); + assert_eq(parseString(`if(1){2}`), call(var("if"),intl(1),fun([],intl(2)),fun([],strl("(empty function body)")))); assert_eq(parseString(`if(1){2}else{3}`), call(var("if"),intl(1),fun([],intl(2)),fun([],intl(3)))); assert_eq(parseString(`if(1){}else{3}()()`), - call(call(call(var("if"),intl(1),fun([],intl(178)),fun([],intl(3)))))); + call(call(call(var("if"),intl(1),fun([],strl("(empty function body)")),fun([],intl(3)))))); assert_eq(parseString(`1+2*3`), call(var("+"),intl(1),call(var("*"),intl(2),intl(3)))); assert_eq(parseString(`(1+2)*3`), call(var("*"),call(var("+"),intl(1),intl(2)),intl(3))); assert_eq(parseString(`1*(2+3)`), call(var("*"),intl(1),call(var("+"),intl(2),intl(3)))); assert_eq(parseString(`1*2+3`), call(var("+"),call(var("*"),intl(1),intl(2)),intl(3))); assert_eq(parseString(`@x(1)`), lay("@x", intl(1))); assert_eq(parseString(`fun(x @v @t, y, z @t){}`), - funp([param("x",["@v","@t"]), param("y",[]), param("z",["@t"])], intl(178))); + funp([param("x",["@v","@t"]), param("y",[]), param("z",["@t"])], strl("(empty function body)"))); assert_eq(parseString(` let x = 100; #comment let y = 200; #comment!!!!! x+y @@ -474,14 +474,14 @@ fun(["x"], call(var("+"), var("x"), intl(1))), var("foo")) ); assert_eq(parseString(`@@type ( x ) { x }`), - let("@type", SystemLayer, fun(["x"], var("x")), var("@type")) ); + let("@type", SystemLayer, fun(["x"], var("x")), lay(SystemLayer, var("@type"))) ); assert_eq(parseString(`{}`), call(var("{}"))); assert_eq(parseString(`{foo:1,"bar":2}`), call(var(".="), call(var(".="), call(var("{}")), strl("foo"), intl(1)), strl("bar"), intl(2))); assert_eq(parseString(`{}.foo`), call(var("."),call(var("{}")),strl("foo"))); assert_eq(parseString(`{}.?foo`), call(var(".?"),call(var("{}")),strl("foo"))); assert_eq(parseString(`x{y:1}`), call(var(".="),var("x"),strl("y"),intl(1))); }