Check-in [f9c31f3cd8]
Not logged in
Overview
SHA1 Hash:f9c31f3cd81099be17caeda53609a40b4661b3d1
Date: 2010-11-24 22:22:04
User: kinaba
Comment:Fixed the null dereference bug when directly wrote "case 1 when 2: 3" in REPL. It was due to null LexPosition in the AST. Now AST.pos !is null is an invariant of AST.
Timelines: family | ancestors | descendants | both | trunk
Downloads: Tarball | ZIP archive
Other Links: files | file ages | manifest
Tags And Properties
Changes

Modified index.dd from [5308ff05201ec907] to [d00c8d535d50e1e2].

600 600 )) 601 601 602 602 $(SECTION 外部とのやりとり, $(SECBODY 603 603 $(TABLE 604 604 $(TR $(TH print) $(TD (a)) $(TD a を文字列化標準出力に改行付きで表示)) 605 605 $(TR $(TH argv) $(TD ) $(TD スクリプトに渡された引数文字列のconsリスト)) 606 606 $(TR $(TH gensym) $(TD ()) $(TD エセgensym。変数名として他とかぶらなそうな文字列を返します)) 607 - $(TR $(TH rand) $(TD (n)) $(TD 0 以上 n 未満の自然数をランダムに生成します)) 607 + $(TR $(TH rand) $(TD (n)) $(TD 0 以上 n 未満の自然数を31bit以内でランダムに生成します)) 608 608 ) 609 609 )) 610 610 <br /> 611 611 612 612 $(SECTION データ型判定, $(SECBODY 613 613 $(TABLE 614 614 $(TR $(TH _isint) $(TD (a)) $(TD a が整数なら 1、でなければ 0))

Modified polemy/ast.d from [55043f61f436485a] to [98d6a7a3304f7043].

11 11 12 12 /// 13 13 abstract class AST 14 14 { 15 15 LexPosition pos; /// 16 16 17 17 mixin SimpleConstructor; 18 + invariant(){ assert(pos !is null);} 18 19 } 19 20 20 21 /// AST node for integer literal 21 22 class Int : AST 22 23 { 23 24 BigInt data; /// 24 25

Modified polemy/eval.d from [bd6a863bd24c7016] to [197c2cfb75326106].

411 411 enrollRuntimeLibrary(e); 412 412 assert_nothrow( e.evalString(` 413 413 @macro twice(x) { x; x }; 414 414 def main() { twice(1) }; 415 415 main() 416 416 `) ); 417 417 } 418 +unittest 419 +{ 420 + auto e = new Evaluator; 421 + enrollRuntimeLibrary(e); 422 + assert_nothrow( e.evalString(`case 1`) ); 423 + assert_nothrow( e.evalString(`case 1 when 1: 2`) ); 424 +} 425 + 418 426 /* 419 427 unittest 420 428 { 421 429 assert_eq( evalString(`var fac = fun(x){ 422 430 if(x) 423 431 { x*fac(x-1); } 424 432 else

Modified polemy/failure.d from [9cdb01160429b059] to [2827b7df74d1df19].

19 19 immutable int lineno; /// 1-origin 20 20 immutable int column; /// 1-origin 21 21 22 22 mixin SimpleClass; 23 23 override string toString() const 24 24 { return sprintf!("%s:%d:%d")(filename, lineno, column); } 25 25 static LexPosition dummy; 26 - static this(){ dummy = new LexPosition("<unnamed>",0,0); } 26 + static this(){ dummy = new LexPosition("<nowhere>",0,0); } 27 27 } 28 28 29 29 unittest 30 30 { 31 31 auto p = new LexPosition("hello.cpp", 123, 45); 32 32 33 33 assert_eq( p.filename, "hello.cpp" );

Modified polemy/parse.d from [f6a85fc83dd90cb0] to [38516f68b159d6bd].

248 248 } 249 249 250 250 AST BaseExpression() 251 251 { 252 252 if( lex.empty ) 253 253 throw genex!UnexpectedEOF(currentPosition(), "Reached EOF when tried to parse an expression"); 254 254 255 - auto pos = lex.front.pos; 255 + auto pos = currentPosition(); 256 256 if( lex.front.quoted ) 257 257 { 258 258 scope(exit) lex.popFront; 259 259 return new Str(pos, lex.front.str); 260 260 } 261 261 if( isNumber(lex.front.str) ) 262 262 { ................................................................................ 321 321 { 322 322 // case pmExpr CASES 323 323 //==> 324 324 // let pmVar = pmExpr in (... let pmTryFirst = ... in pmTryFirst()) 325 325 AST pmExpr = E(0); 326 326 string pmVar = freshVarName(); 327 327 string pmTryFirst = freshVarName(); 328 - AST pmBody = parsePatternMatchCases(pmVar, pmTryFirst, 328 + AST pmBody = parsePatternMatchCases(pos, pmVar, pmTryFirst, 329 329 new App(pos, new Var(pos, pmTryFirst))); 330 330 return new Let(pos, pmVar, [], pmExpr, pmBody); 331 331 } 332 332 333 - AST parsePatternMatchCases(string pmVar, string tryThisBranchVar, AST thenDoThis) 333 + AST parsePatternMatchCases(LexPosition casePos, string pmVar, string tryThisBranchVar, AST thenDoThis) 334 334 { 335 335 // when pat: cBody 336 336 //==> 337 337 // ... let failBranchVar = ... in 338 338 // let tryThisBranchVar = fun(){ if(test){cBody}else{failBranchVar()} } in thenDoThis 339 339 if( tryEat("when") ) 340 340 { ................................................................................ 343 343 344 344 auto pr = parsePattern(); 345 345 eat(":", "after when pattern"); 346 346 AST cBody = E(0); 347 347 AST judgement = new App(pos, new Var(pos, "if"), 348 348 ppTest(pmVar, pr), new Fun(pos,[],ppBind(pmVar, pr, cBody)), 349 349 new Var(pos, failBranchVar)); 350 - return parsePatternMatchCases(pmVar, failBranchVar, 350 + return parsePatternMatchCases(casePos, pmVar, failBranchVar, 351 351 new Let(pos, tryThisBranchVar, [], 352 352 new Fun(pos,[],judgement), thenDoThis) 353 353 ); 354 354 } 355 355 else 356 356 { 357 - auto pos = currentPosition(); 358 - AST doNothing = new Fun(pos,[], 359 - new Str(pos, sprintf!"(pattern match failure:%s)"(pos))); 360 - return new Let(currentPosition(), tryThisBranchVar, [], doNothing, thenDoThis); 357 + AST doNothing = new Fun(casePos,[], 358 + new Str(casePos, sprintf!"(pattern match failure:%s)"(casePos))); 359 + return new Let(casePos, tryThisBranchVar, [], doNothing, thenDoThis); 361 360 } 362 361 } 363 362 364 363 // hageshiku tenuki 365 364 abstract class SinglePattern 366 365 { 367 366 string[] path; ................................................................................ 555 554 AST doNothingExpression() 556 555 { 557 556 return new Str(currentPosition(), "(empty function body)"); 558 557 } 559 558 560 559 LexPosition currentPosition() 561 560 { 562 - return lex.empty ? null : lex.front.pos; 561 + return lex.empty ? new LexPosition("EOF",0,0) : lex.front.pos; 563 562 } 564 563 } 565 564 566 565 unittest 567 566 { 568 567 mixin EasyAST; 569 568

Modified polemy/valueconv.d from [bca45e855c0f4664] to [cd634c9bb4b6ba14].

18 18 { 19 19 auto fn = tt.access!StrValue(ValueLayer, "filename"); 20 20 auto ln = tt.access!IntValue(ValueLayer, "lineno"); 21 21 auto cl = tt.access!IntValue(ValueLayer, "column"); 22 22 if(fn !is null && ln !is null && cl !is null) 23 23 return new LexPosition(fn.data,cast(int)ln.data.toInt,cast(int)cl.data.toInt); 24 24 } 25 - return null; 25 + return LexPosition.dummy; 26 26 } 27 27 28 28 /// Experimental!! Convert Polemy value to D Value 29 29 30 30 T polemy2d(T)(Value _v, LexPosition callpos=null) 31 31 { 32 32 static if(is(T==BigInt)) ................................................................................ 141 141 return lst; 142 142 } 143 143 else 144 144 static if(is(T : AST)) 145 145 { 146 146 assert( typeid(e) == typeid(T), text("abstracted: ", typeid(e), " vs ", typeid(T)) ); 147 147 auto t = new Table; 148 - t.set("pos", ValueLayer, ast2table(e.pos,rec)); 148 + if(e.pos is null) // special treatment 149 + { 150 + Table post = new Table; 151 + post.set("filename", ValueLayer, new StrValue("nullpo")); 152 + post.set("lineno", ValueLayer, new IntValue(0)); 153 + post.set("column", ValueLayer, new IntValue(0)); 154 + t.set("pos", ValueLayer, post); 155 + } 156 + else 157 + t.set("pos", ValueLayer, ast2table(e.pos,rec)); 149 158 t.set("is" , ValueLayer, new StrValue(typeid(e).name.split(".")[$-1])); 150 159 foreach(i,m; e.tupleof) 151 160 static if(is(typeof(m) : AST)) 152 161 t.set(e.tupleof[i].stringof.split(".")[$-1], ValueLayer, rec(m)); 153 162 else 154 163 t.set(e.tupleof[i].stringof.split(".")[$-1], ValueLayer, ast2table(m,rec)); 155 164 return t;

Modified sample/ast.pmy from [a9061a338889d74c] to [7e23af883e94d990].

7 7 8 8 @macro reverseArgs(e) {@value( 9 9 var ev = @macro(e); 10 10 case(ev) 11 11 when {is:"App", fun:f, args:a}: 12 12 ( 13 13 ev {args: reverse(a, {})} 14 +# {is:"App", fun:f, args:reverse(a, {})} 14 15 ) 15 16 when _ : 16 17 ( 17 18 ev 18 19 ) 19 20 )}; 20 21