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以内でランダムに生成します))
   )
 ))
 <br />
 
 $(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("<unnamed>",0,0); }
+	static this(){ dummy = new LexPosition("<nowhere>",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
 		)