Index: index.dd
==================================================================
--- index.dd
+++ index.dd
@@ -602,11 +602,11 @@
$(SECTION 外部とのやりとり, $(SECBODY
$(TABLE
$(TR $(TH print) $(TD (a)) $(TD a を文字列化標準出力に改行付きで表示))
$(TR $(TH argv) $(TD ) $(TD スクリプトに渡された引数文字列のconsリスト))
$(TR $(TH gensym) $(TD ()) $(TD エセgensym。変数名として他とかぶらなそうな文字列を返します))
- $(TR $(TH rand) $(TD (n)) $(TD 0 以上 n 未満の自然数をランダムに生成します))
+ $(TR $(TH rand) $(TD (n)) $(TD 0 以上 n 未満の自然数を31bit以内でランダムに生成します))
)
))
$(SECTION データ型判定, $(SECBODY
Index: polemy/ast.d
==================================================================
--- polemy/ast.d
+++ polemy/ast.d
@@ -13,10 +13,11 @@
abstract class AST
{
LexPosition pos; ///
mixin SimpleConstructor;
+ invariant(){ assert(pos !is null);}
}
/// AST node for integer literal
class Int : AST
{
Index: polemy/eval.d
==================================================================
--- polemy/eval.d
+++ polemy/eval.d
@@ -413,10 +413,18 @@
@macro twice(x) { x; x };
def main() { twice(1) };
main()
`) );
}
+unittest
+{
+ auto e = new Evaluator;
+ enrollRuntimeLibrary(e);
+ assert_nothrow( e.evalString(`case 1`) );
+ assert_nothrow( e.evalString(`case 1 when 1: 2`) );
+}
+
/*
unittest
{
assert_eq( evalString(`var fac = fun(x){
if(x)
Index: polemy/failure.d
==================================================================
--- polemy/failure.d
+++ polemy/failure.d
@@ -21,11 +21,11 @@
mixin SimpleClass;
override string toString() const
{ return sprintf!("%s:%d:%d")(filename, lineno, column); }
static LexPosition dummy;
- static this(){ dummy = new LexPosition("",0,0); }
+ static this(){ dummy = new LexPosition("",0,0); }
}
unittest
{
auto p = new LexPosition("hello.cpp", 123, 45);
Index: polemy/parse.d
==================================================================
--- polemy/parse.d
+++ polemy/parse.d
@@ -250,11 +250,11 @@
AST BaseExpression()
{
if( lex.empty )
throw genex!UnexpectedEOF(currentPosition(), "Reached EOF when tried to parse an expression");
- auto pos = lex.front.pos;
+ auto pos = currentPosition();
if( lex.front.quoted )
{
scope(exit) lex.popFront;
return new Str(pos, lex.front.str);
}
@@ -323,16 +323,16 @@
//==>
// let pmVar = pmExpr in (... let pmTryFirst = ... in pmTryFirst())
AST pmExpr = E(0);
string pmVar = freshVarName();
string pmTryFirst = freshVarName();
- AST pmBody = parsePatternMatchCases(pmVar, pmTryFirst,
+ AST pmBody = parsePatternMatchCases(pos, pmVar, pmTryFirst,
new App(pos, new Var(pos, pmTryFirst)));
return new Let(pos, pmVar, [], pmExpr, pmBody);
}
- AST parsePatternMatchCases(string pmVar, string tryThisBranchVar, AST thenDoThis)
+ AST parsePatternMatchCases(LexPosition casePos, string pmVar, string tryThisBranchVar, AST thenDoThis)
{
// when pat: cBody
//==>
// ... let failBranchVar = ... in
// let tryThisBranchVar = fun(){ if(test){cBody}else{failBranchVar()} } in thenDoThis
@@ -345,21 +345,20 @@
eat(":", "after when pattern");
AST cBody = E(0);
AST judgement = new App(pos, new Var(pos, "if"),
ppTest(pmVar, pr), new Fun(pos,[],ppBind(pmVar, pr, cBody)),
new Var(pos, failBranchVar));
- return parsePatternMatchCases(pmVar, failBranchVar,
+ return parsePatternMatchCases(casePos, pmVar, failBranchVar,
new Let(pos, tryThisBranchVar, [],
new Fun(pos,[],judgement), thenDoThis)
);
}
else
{
- auto pos = currentPosition();
- AST doNothing = new Fun(pos,[],
- new Str(pos, sprintf!"(pattern match failure:%s)"(pos)));
- return new Let(currentPosition(), tryThisBranchVar, [], doNothing, thenDoThis);
+ AST doNothing = new Fun(casePos,[],
+ new Str(casePos, sprintf!"(pattern match failure:%s)"(casePos)));
+ return new Let(casePos, tryThisBranchVar, [], doNothing, thenDoThis);
}
}
// hageshiku tenuki
abstract class SinglePattern
@@ -557,11 +556,11 @@
return new Str(currentPosition(), "(empty function body)");
}
LexPosition currentPosition()
{
- return lex.empty ? null : lex.front.pos;
+ return lex.empty ? new LexPosition("EOF",0,0) : lex.front.pos;
}
}
unittest
{
Index: polemy/valueconv.d
==================================================================
--- polemy/valueconv.d
+++ polemy/valueconv.d
@@ -20,11 +20,11 @@
auto ln = tt.access!IntValue(ValueLayer, "lineno");
auto cl = tt.access!IntValue(ValueLayer, "column");
if(fn !is null && ln !is null && cl !is null)
return new LexPosition(fn.data,cast(int)ln.data.toInt,cast(int)cl.data.toInt);
}
- return null;
+ return LexPosition.dummy;
}
/// Experimental!! Convert Polemy value to D Value
T polemy2d(T)(Value _v, LexPosition callpos=null)
@@ -143,11 +143,20 @@
else
static if(is(T : AST))
{
assert( typeid(e) == typeid(T), text("abstracted: ", typeid(e), " vs ", typeid(T)) );
auto t = new Table;
- t.set("pos", ValueLayer, ast2table(e.pos,rec));
+ if(e.pos is null) // special treatment
+ {
+ Table post = new Table;
+ post.set("filename", ValueLayer, new StrValue("nullpo"));
+ post.set("lineno", ValueLayer, new IntValue(0));
+ post.set("column", ValueLayer, new IntValue(0));
+ t.set("pos", ValueLayer, post);
+ }
+ else
+ t.set("pos", ValueLayer, ast2table(e.pos,rec));
t.set("is" , ValueLayer, new StrValue(typeid(e).name.split(".")[$-1]));
foreach(i,m; e.tupleof)
static if(is(typeof(m) : AST))
t.set(e.tupleof[i].stringof.split(".")[$-1], ValueLayer, rec(m));
else
Index: sample/ast.pmy
==================================================================
--- sample/ast.pmy
+++ sample/ast.pmy
@@ -9,10 +9,11 @@
var ev = @macro(e);
case(ev)
when {is:"App", fun:f, args:a}:
(
ev {args: reverse(a, {})}
+# {is:"App", fun:f, args:reverse(a, {})}
)
when _ :
(
ev
)