Index: polemy/_common.d ================================================================== --- polemy/_common.d +++ polemy/_common.d @@ -1,19 +1,22 @@ /** * Authors: k.inaba * License: NYSL 0.9982 http://www.kmonos.net/nysl/ * - * These modules are globaly used inside Polemy. + * The list of modules globaly used inside Polemy. */ module polemy._common; +// basic utilities public import tricks.test; public import tricks.tricks; public import std.algorithm; public import std.array; +public import std.range; public import std.bigint; +// debugging public import std.conv : text; -public import std.exception; -public import std.range; public import std.stdio : DBG = writeln; +// meta programming +public import std.exception; public import std.traits; public import std.typecons; public import std.typetuple; Index: polemy/layer.d ================================================================== --- polemy/layer.d +++ polemy/layer.d @@ -23,12 +23,28 @@ bool isMacroishLayer( Layer lay ) { return lay==MacroLayer || lay==RawMacroLayer; } + +unittest +{ + assert( !isMacroishLayer(SystemLayer) ); + assert( !isMacroishLayer(ValueLayer) ); + assert( isMacroishLayer(MacroLayer) ); + assert( isMacroishLayer(RawMacroLayer) ); +} /// True if in the specified layer @lay(...) has no effect and merely produces a syntax tree bool isNoLayerChangeLayer( Layer lay ) { return lay==RawMacroLayer; } + +unittest +{ + assert( !isNoLayerChangeLayer(SystemLayer) ); + assert( !isNoLayerChangeLayer(ValueLayer) ); + assert( !isNoLayerChangeLayer(MacroLayer) ); + assert( isNoLayerChangeLayer(RawMacroLayer) ); +} Index: polemy/lex.d ================================================================== --- polemy/lex.d +++ polemy/lex.d @@ -381,6 +381,18 @@ unittest { assert( isForwardRange!(PositionedReader!string) ); assert( is(ElementType!(PositionedReader!string) == dchar) ); + { + auto pr = PositionedReader!string("abc","",1,1); + assert_eq(pr.currentPosition().column, 1); pr.popFront; + assert_eq(pr.currentPosition().column, 2); pr.popFront; + assert_eq(pr.currentPosition().column, 3); pr.popFront; + } + { + auto pr = PositionedReader!string("\n\r\n\n","",1,1); + assert_eq(pr.currentPosition().lineno, 1); pr.popFront; + assert_eq(pr.currentPosition().lineno, 2); pr.popFront; + assert_eq(pr.currentPosition().lineno, 3); pr.popFront; + } } Index: polemy/parse.d ================================================================== --- polemy/parse.d +++ polemy/parse.d @@ -154,18 +154,18 @@ ["||"], ["&&"], ["!="], ["=="], ["<","<=",">",">="], - ["|"], - ["^"], - ["&"], - ["<<", ">>"], +// ["|"], +// ["^"], +// ["&"], +// ["<<", ">>", "<<<", ">>>"], ["+","-"], ["~"], ["*","/","%"], - ["^^","**"], +// ["^^","**"], [".",".?"] ]; AST E(size_t level) { @@ -194,11 +194,11 @@ return rec(E(level+1)); } AST Funcall() { - /// Funcall ::= BaseExpression ["(" Expression%"," ")"]* + /// Funcall ::= BaseExpression ["(" Expression%"," ")" | "{" ENTRIES "}"]* auto e = BaseExpression(); for(;;) if( tryEat("(") ) { @@ -224,10 +224,12 @@ return e; } AST parseTableSetAfterBrace(AST e) { + /// TableSet ::= "{" (ID ":" E) % "," "}" + if( tryEat("}") ) return e; auto pos = currentPosition(); for(;;) { @@ -316,11 +318,11 @@ return new Var(pos, lex.front.str); } AST parsePatternMatch(LexPosition pos) { - // case( pmExpr )cases + // case "(" pmExpr ")" CASES //==> // let pmVar = pmExpr in (... let pmTryFirst = ... in pmTryFirst()) eat("(", "after case"); AST pmExpr = E(0); eat(")", "after case"); @@ -659,6 +661,11 @@ `)); assert_nothrow(parseString(` case( 1 ) when({aaaa:_}){1} `)); + assert_nothrow(parseString(` + case( 1 ) + when({aaaa:@value(x)}){1} + when({aaaa:{bbb:_}, ccc:123}){1} + `)); } Index: polemy/runtime.d ================================================================== --- polemy/runtime.d +++ polemy/runtime.d @@ -18,10 +18,11 @@ e.addPrimitive("+", ValueLayer, (IntValue lhs, IntValue rhs){return new IntValue(lhs.data + rhs.data);} ); e.addPrimitive("-", ValueLayer, (IntValue lhs, IntValue rhs){return new IntValue(lhs.data - rhs.data);} ); e.addPrimitive("*", ValueLayer, (IntValue lhs, IntValue rhs){return new IntValue(lhs.data * rhs.data);} ); e.addPrimitive("/", ValueLayer, (IntValue lhs, IntValue rhs){return new IntValue(lhs.data / rhs.data);} ); e.addPrimitive("%", ValueLayer, (IntValue lhs, IntValue rhs){return new IntValue(lhs.data % rhs.data);} ); + e.addPrimitive("~", ValueLayer, (Value lhs, Value rhs){return new StrValue(lhs.toString ~ rhs.toString);} ); e.addPrimitive("||", ValueLayer, (IntValue lhs, IntValue rhs){return new IntValue(lhs.data!=0 || rhs.data!=0);} ); e.addPrimitive("&&", ValueLayer, (IntValue lhs, IntValue rhs){return new IntValue(lhs.data!=0 && rhs.data!=0);} ); e.addPrimitive("<", ValueLayer, (Value lhs, Value rhs){return new IntValue(lhs < rhs);} ); e.addPrimitive(">", ValueLayer, (Value lhs, Value rhs){return new IntValue(lhs > rhs);} ); e.addPrimitive("<=", ValueLayer, (Value lhs, Value rhs){return new IntValue(lhs <= rhs);} ); Index: readme.txt ================================================================== --- readme.txt +++ readme.txt @@ -381,12 +381,13 @@ .? 2-ary table-has? .= 3-ary table-set if 3-ary if-then-else - + - * / % || && 2-ary integer-operations (no short-circuit!) + + - * / % || && 2-ary integer-operations (NOTE! no short-circuit for && and ||.) < > <= >= == != 2-ary generic comparison + ~ 2-ary string concatenation (works also for non-string objects) print 1-ary print-to-stdout _isint _isstr _isfun _isundefined _istable 1-ary dynamic-type-test ADDED sample/argv.pmy Index: sample/argv.pmy ================================================================== --- sample/argv.pmy +++ sample/argv.pmy @@ -0,0 +1,1 @@ +print(argv) ADDED sample/ast.pmy Index: sample/ast.pmy ================================================================== --- sample/ast.pmy +++ sample/ast.pmy @@ -0,0 +1,27 @@ +def reverse(lst, acc) +{ + case(lst) + when( {car:a, cdr: d} ) { reverse(d, {car:a, cdr:acc}) } + when( {} ) { acc } +}; + +@macro reverseArgs(e) {@value( + var ev = @macro(e); + case(ev) + when( {is:"app", fun:f, args:a} ) + { + ev {args: reverse(a, {})} + } + when( _ ) + { + ev + } +)}; + +def main() +{ + print( reverseArgs(1 + 2) ); + print( reverseArgs(1 - 2) ); +}; + +main()