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 $(SECTION 外部とのやりとり, $(SECBODY 602 $(SECTION 外部とのやりとり, $(SECBODY 603 $(TABLE 603 $(TABLE 604 $(TR $(TH print) $(TD (a)) $(TD a を文字列化標準出力に改行付きで表示)) 604 $(TR $(TH print) $(TD (a)) $(TD a を文字列化標準出力に改行付きで表示)) 605 $(TR $(TH argv) $(TD ) $(TD スクリプトに渡された引数文字列のconsリスト)) 605 $(TR $(TH argv) $(TD ) $(TD スクリプトに渡された引数文字列のconsリスト)) 606 $(TR $(TH gensym) $(TD ()) $(TD エセgensym。変数名として他とかぶらなそうな文字列を返します)) 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 <br /> 610 <br /> 611 611 612 $(SECTION データ型判定, $(SECBODY 612 $(SECTION データ型判定, $(SECBODY 613 $(TABLE 613 $(TABLE 614 $(TR $(TH _isint) $(TD (a)) $(TD a が整数なら 1、でなければ 0)) 614 $(TR $(TH _isint) $(TD (a)) $(TD a が整数なら 1、でなければ 0))

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

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

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

411 enrollRuntimeLibrary(e); 411 enrollRuntimeLibrary(e); 412 assert_nothrow( e.evalString(` 412 assert_nothrow( e.evalString(` 413 @macro twice(x) { x; x }; 413 @macro twice(x) { x; x }; 414 def main() { twice(1) }; 414 def main() { twice(1) }; 415 main() 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 unittest 427 unittest 420 { 428 { 421 assert_eq( evalString(`var fac = fun(x){ 429 assert_eq( evalString(`var fac = fun(x){ 422 if(x) 430 if(x) 423 { x*fac(x-1); } 431 { x*fac(x-1); } 424 else 432 else

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

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

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

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

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

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

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

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