Check-in [576c494e53]
Not logged in
Overview
SHA1 Hash:576c494e53d3ab9603dbb25666e92fb88f9a45d5
Date: 2010-11-28 08:46:51
User: kinaba
Comment:fixed: literal "..." is now lifted in user-defined layers
Timelines: family | ancestors | descendants | both | trunk
Downloads: Tarball | ZIP archive
Other Links: files | file ages | manifest
Tags And Properties
Changes

Modified doc/eval.html from [5a3818f4c9865916] to [4697f3dd9da1ee2d].

128 128 <script>explorer.outline.decSymbolLevel();</script> 129 129 130 130 131 131 </td></tr> 132 132 <tr><td id="docfooter"> 133 133 Page was generated with 134 134 <img src="candydoc/img/candydoc.gif" style="vertical-align:middle; position:relative; top:-1px"> 135 - on Sat Nov 27 23:29:17 2010 135 + on Sun Nov 28 07:28:21 2010 136 136 137 137 </td></tr> 138 138 </table> 139 139 </div> 140 140 <script> 141 141 explorer.packageExplorer.addModule("index"); 142 142 explorer.packageExplorer.addModule("main");

Modified doc/index.html from [d0516fddd5213f2d] to [34739585fd5c7798].

30 30 <p> 31 31 あと、 やたらとマクロの章が長くなっていますが、 この部分は、 32 32 レイヤ機能を入れたら自動的にすごく自然にマクロが入るなーと思って、 33 33 おまけで実装してみた程度のものです。 34 34 あんまり重要ではないので、適当にスルーして下さいませ。 35 35 単に、適当に入れたら適当で微妙な部分が多く残ってしまったので注意書きが増えているだけで…。 36 36 </p> 37 +<p> 38 +言い訳ついでにもう一つ言い訳ですが、この言語は、少なくとも今のところ、 39 +実用に使うことを考えた設計にはなっていません。どちらかというと、 40 +Brainfuck や Unlambda や Whitespace の仲間と思ってお使い下さい。 41 +</p> 37 42 38 43 39 44 <script>explorer.outline.incSymbolLevel();</script> 40 45 <dl> 41 46 <script>explorer.outline.writeEnabled = true;</script> 42 47 <dt><span class="decl"> 43 48 <span class="currsymbol">Syntax</span> ................................................................................ 672 677 </p> 673 678 <pre> 674 679 @@type = fun(x) { 675 680 if( _isint(x) ) then "int" 676 681 else if( _isstr(x) ) then "str" 677 682 else if( _isbot(x) ) then "runtime error" 678 683 else "type error" 679 - } 684 + }; 680 685 </pre> 681 686 <pre> 682 687 &gt;&gt; @type( 1 ) 683 688 int 684 689 &gt;&gt; @type( 2 ) 685 690 int 686 691 &gt;&gt; @type( "foo" ) ................................................................................ 721 726 </p> 722 727 <pre> 723 728 @type "if" (c, t, e) {@value( 724 729 if( @type(c)=="int" || @type(c)=="runtime error" ) then 725 730 @type( int_int_int(t(), e()) ) 726 731 else 727 732 "type error" 728 - )} 733 + )}; 729 734 </pre> 730 735 <p> 731 736 関数が自動リフトされるので、フィボナッチ関数の型を調べることができます。 732 737 </p> 733 738 <pre> 734 739 &gt;&gt; def fib(x) { if x&lt;2 then 1 else fib(x-1)+fib(x-2) }; 735 740 &gt;&gt; @type( fib(100000000000000) ) ................................................................................ 1152 1157 <script>explorer.outline.decSymbolLevel();</script> 1153 1158 1154 1159 1155 1160 </td></tr> 1156 1161 <tr><td id="docfooter"> 1157 1162 Page was generated with 1158 1163 <img src="candydoc/img/candydoc.gif" style="vertical-align:middle; position:relative; top:-1px"> 1159 - on Sun Nov 28 00:45:59 2010 1164 + on Sun Nov 28 07:29:42 2010 1160 1165 1161 1166 </td></tr> 1162 1167 </table> 1163 1168 </div> 1164 1169 <script> 1165 1170 explorer.packageExplorer.addModule("index"); 1166 1171 explorer.packageExplorer.addModule("main");

Modified index.dd from [33d07971634f6989] to [a39b25f2bef916f0].

13 13 <p> 14 14 あと、 やたらとマクロの章が長くなっていますが、 この部分は、 15 15 レイヤ機能を入れたら自動的にすごく自然にマクロが入るなーと思って、 16 16 おまけで実装してみた程度のものです。 17 17 あんまり重要ではないので、適当にスルーして下さいませ。 18 18 単に、適当に入れたら適当で微妙な部分が多く残ってしまったので注意書きが増えているだけで…。 19 19 </p> 20 +<p> 21 +言い訳ついでにもう一つ言い訳ですが、この言語は、少なくとも今のところ、 22 +実用に使うことを考えた設計にはなっていません。どちらかというと、 23 +Brainfuck や Unlambda や Whitespace の仲間と思ってお使い下さい。 24 +</p> 20 25 21 26 $(DDOC_MEMBERS 22 27 23 28 $(SECTION Syntax, $(SECBODY 24 29 <p> 25 30 文法について。 26 31 字句解析がわりと適当なので、 ................................................................................ 519 524 </p> 520 525 <pre> 521 526 @@type = fun(x) { 522 527 if( _isint(x) ) then "int" 523 528 else if( _isstr(x) ) then "str" 524 529 else if( _isbot(x) ) then "runtime error" 525 530 else "type error" 526 - } 531 + }; 527 532 </pre> 528 533 <pre> 529 534 &gt;&gt; @type( 1 ) 530 535 int 531 536 &gt;&gt; @type( 2 ) 532 537 int 533 538 &gt;&gt; @type( "foo" ) ................................................................................ 568 573 </p> 569 574 <pre> 570 575 @type "if" (c, t, e) {@value( 571 576 if( @type(c)=="int" || @type(c)=="runtime error" ) then 572 577 @type( int_int_int(t(), e()) ) 573 578 else 574 579 "type error" 575 - )} 580 + )}; 576 581 </pre> 577 582 <p> 578 583 関数が自動リフトされるので、フィボナッチ関数の型を調べることができます。 579 584 </p> 580 585 <pre> 581 586 &gt;&gt; def fib(x) { if x<2 then 1 else fib(x-1)+fib(x-2) }; 582 587 &gt;&gt; @type( fib(100000000000000) )

Modified polemy/eval.d from [271574033e4f3a71] to [969111acf2042a22].

225 225 226 226 override Layer layerID() 227 227 { 228 228 return theID; 229 229 } 230 230 override Value eval_( Die e, Table ctx, bool ctxMod ) 231 231 { 232 - return new BottomValue; 232 + return this.lift(new BottomValue, ctx, e.pos); 233 233 } 234 234 override Value eval_( Str e, Table ctx, bool ctxMod ) 235 235 { 236 236 return this.lift(super.eval_(e,ctx,ctxMod), ctx, e.pos); 237 237 } 238 238 override Value eval_( Int e, Table ctx, bool ctxMod ) 239 239 { ................................................................................ 411 411 if( !isUserDefinedLayer(lay) ) 412 412 return nonMemoizedRun(); 413 413 414 414 // automatic memoized co-recursive execution 415 415 MemokeyType memokey = new MemokeyType(cast(void*)ast, lay, ctx); 416 416 if(auto p = memokey in memo) 417 417 { 418 - (*p)[1] ++; 419 - return (*p)[0]; 418 + if( ++(*p)[1] >= 2 ) // [TODO] is 2 really enough?? 419 + return (*p)[0]; 420 420 } 421 - else { 421 + else 422 + { 422 423 Value v; 423 424 try { v = evlay.lift(new BottomValue, ctx, pos); } catch { v = new BottomValue; } 424 425 memo[memokey] = tuple(v, 0); 425 426 } 426 427 427 428 Value r = nonMemoizedRun(); 428 - 429 - int touched = memo[memokey][1]; 430 - memo[memokey] = tuple(r, 12345678); 429 + memo[memokey] = tuple(r, 9999); 431 430 return r; 432 431 } 433 432 } 434 433 return new UserDefinedFunValue(e,ctx); 435 434 } 436 435 437 436 public:

Modified polemy/parse.d from [de23904b83613a4d] to [06d6eadbdf402360].

313 313 { 314 314 auto cond = E(0); 315 315 auto thenPos = currentPosition(); 316 316 if(!tryEat(":")) { 317 317 eat("then", "after if condition"); 318 318 tryEat(":"); 319 319 } 320 - AST th = E(0); 320 + AST th = Body(); 321 321 auto el = doNothingExpression(); 322 322 auto elsePos = currentPosition(); 323 323 if( tryEat("else") ) { 324 324 tryEat(":"); 325 - el = E(0); 325 + el = Body(); 326 326 } 327 327 return new App(pos, new Var(pos,"if"), cond, new Fun(thenPos,[],th), new Fun(elsePos,[],el)); 328 328 } 329 329 330 330 AST parsePatternMatch(LexPosition pos) 331 331 { 332 332 // case pmExpr CASES ................................................................................ 349 349 if( tryEat("when") ) 350 350 { 351 351 auto pos = currentPosition(); 352 352 string failBranchVar = freshVarName(); 353 353 354 354 auto pr = parsePattern(); 355 355 eat(":", "after when pattern"); 356 - AST cBody = E(0); 356 + AST cBody = Body(); 357 357 AST judgement = new App(pos, new Var(pos, "if"), 358 358 ppTest(pmVar, pr), new Fun(pos,[],ppBind(pmVar, pr, cBody)), 359 359 new Var(pos, failBranchVar)); 360 360 return parsePatternMatchCases(casePos, pmVar, failBranchVar, 361 361 new Let(pos, tryThisBranchVar, [], 362 362 new Fun(pos,[],judgement), thenDoThis) 363 363 );

Modified sample/type.pmy from [6a40040679ba714c] to [e50284fdcde212f7].

1 -@@type = fun(x){ 2 - if _isint(x): "int" 3 - else if _isstr(x): "str" 4 - else: "any" 5 -}; 6 - 7 -def binop(a,b,c) { 8 - fun(x,y){@value( 9 - if( _isbot( @type(x) ) || _isbot( @type(y) ) ) then @type(...) else 10 - if( @type(x)==a && @type(y)==b ) then c else "error" 11 - )} 1 +# Lift to types 2 +@@type (x) 3 +{ 4 + if _isint(x): "int" 5 + else if _isstr(x): "str" 6 + else if _isbot(x): "RE" 7 + else if _istbl(x): 8 + if x.?car && x.?cdr: 9 + let xa = x.car in let xd = x.cdr in 10 + mergeType( {list: @type(xa)}, @type(xd) ) 11 + else 12 + {list: "RE"} # tenuki 13 + else ... 12 14 }; 13 15 14 -@type "+" = binop("int", "int", "int"); 15 -@type "-" = binop("int", "int", "int"); 16 -@type "<" = binop("int", "int", "int"); 17 -@type ">" = binop("int", "int", "int"); 18 - 19 -def mergeType(a,b) { 20 - if( _isbot(a) ): ( if( _isbot(b) ):"error" else b ) else ( a ) 16 +# unify two types 17 +def mergeType(a, b) 18 +{ 19 + if a == "RE": b 20 + else if b == "RE": a 21 + else if _istbl(a) && _istbl(b): 22 + if a.?list && b.?list: 23 + let rt = mergeType(a.list, b.list) in 24 + if rt=="TE" || rt=="RE" then rt else {list: rt} 25 + else: 26 + "TE" # type error 27 + else if a == b: a 28 + else "TE" # type error 21 29 }; 22 30 23 -@type "if" = fun(c,t,e) {@value( 24 - if(@type(c)=="int" ): mergeType(@type(t()), @type(e())) else : "error" 25 -)}; 26 - 27 -def fib(x) 31 +# helper function 32 +def Tuni(t1, t0) 33 +{ 34 + fun(x) {@value( 35 + if @type(x)=="RE": "RE" 36 + else if @type(x)=="TE": "TE" 37 + else if @type(x)==t1: t0 38 + else "TE" 39 + )} 40 +}; 41 +def Tuniany(t0) 42 +{ 43 + fun(x) {@value( 44 + if @type(x)=="RE": "RE" 45 + else if @type(x)=="TE": "TE" 46 + else t0 47 + )} 48 +}; 49 +def Tbin(t1, t2, t0) 50 +{ 51 + fun(x,y) {@value( 52 + if @type(x)=="RE" || @type(y)=="RE": "RE" 53 + else if @type(x)=="TE" || @type(y)=="TE": "TE" 54 + else if @type(x)==t1 && @type(y)==t2: t0 55 + else "TE" 56 + )} 57 +}; 58 +def Tbinany(t0) 28 59 { 29 - if x<2 then 1 else fib(x-1) + fib(x-2) 60 + fun(x,y){@value( 61 + if @type(x)=="RE" || @type(y)=="RE": "RE" 62 + else if @type(x)=="TE" || @type(y)=="TE": "TE" 63 + else t0 64 + )} 65 +}; 66 + 67 +# type annotation for built-in ops 68 +@type "+" = Tbin("int", "int", "int"); 69 +@type "-" = Tbin("int", "int", "int"); 70 +@type "*" = Tbin("int", "int", "int"); 71 +@type "/" = Tbin("int", "int", "int"); 72 +@type "%" = Tbin("int", "int", "int"); 73 +@type "&&" = Tbin("int", "int", "int"); 74 +@type "||" = Tbin("int", "int", "int"); 75 +@type print = fun(x){x}; 76 +@type gensym = fun(){"str"}; 77 +@type argv = {list: "str"}; 78 +@type rand = Tuni("int","int"); 79 +@type "~" = Tbinany("str"); 80 +@type "<" = Tbinany("int"); 81 +@type "<=" = Tbinany("int"); 82 +@type ">" = Tbinany("int"); 83 +@type ">=" = Tbinany("int"); 84 +@type "==" = Tbinany("int"); 85 +@type "!=" = Tbinany("int"); 86 +@type "if" (c,t,e) {@value( 87 + if @type(c)=="RE": "RE" 88 + else if @type(c)!="int": "TE" 89 + else mergeType( @type(t()), @type(e()) ); 90 +)}; 91 +@type _isint = Tuniany("int"); 92 +@type _isstr = Tuniany("int"); 93 +@type _isfun = Tuniany("int"); 94 +@type _istbl = Tuniany("int"); 95 +@type _isbot = Tuniany("int"); 96 + 97 +################################### 98 + 99 +# for lists 100 +@type "{}"() {@value( {list: "RE"} )}; 101 +@type ".?"(t, s) {@value( 102 + if @type(t)=="RE": "RE" 103 + else if @type(t)=="TE": "TE" 104 + else if _istbl( @type(t) ): "int" 105 + else "TE" 106 +)}; 107 +@type ".="(t, s@value, v) {@value( 108 + var tt = @type(t); 109 + if tt == "TE": "TE" 110 + else if tt == "RE": "RE" 111 + else if _istbl(tt) && tt.?list: 112 + if s == "car": 113 + mergeType(tt, {list: @type(v)}) 114 + else if s == "cdr": 115 + mergeType(tt, @type(v)) 116 + else: 117 + tt 118 + else: 119 + "TE" 120 +)}; 121 +@type "."(t, s@value) {@value( 122 + var tt = @type(t); 123 + if tt == "TE": "TE" 124 + else if tt == "RE": "RE" 125 + else if _istbl(tt) && tt.?list: 126 + if s == "car": 127 + tt.list 128 + else if s == "cdr": 129 + tt 130 + else: 131 + "TE" 132 + else: 133 + "TE" 134 +)}; 135 + 136 +################################### 137 + 138 +def fib(x) { if x < 2 then 1 else fib(x-1) + fib(x-2) }; 139 +def fibE1(x) { if "true!" then 1 else fib(x-1) + fib(x-2) }; 140 +def fibE2(x) { if x<2 then "ichi" else fib(x-1) + fib(x-2) }; 141 +def fibE3(x) { if x<2 then 1 else fib(x-1) ~ fib(x-2) }; 142 +def fibS(x) { if x<2 then "1" else fib(x-1) ~ fib(x-2) }; 143 +def fibBadButTypeIsOK(x) { if x < "2" then 1 else fib(x-1) + fib(x-2) }; 144 + 145 +print( @type(fib(999)) ); 146 +print( @type(fibE1(999)) ); 147 +print( @type(fibE2(999)) ); 148 +print( @type(fibE3(999)) ); 149 +print( @type(fibS(999)) ); 150 +print( @type(fibBadButTypeIsOK(999)) ); 151 + 152 +################################### 153 + 154 +def nil = {}; 155 +def cons(a, d) { {car: a, cdr: d} }; 156 + 157 +print( @type(nil) ); 158 +print( @type(cons(1,nil)) ); 159 +print( @type(cons("foo",nil)) ); 160 +print( @type(cons(123, cons("foo",nil))) ); # TE 161 + 162 +def rev(xs) { 163 + def revi(xs, ys) { 164 + case xs 165 + when {car: x, cdr: xs}: revi(xs, cons(x,ys)) 166 + when {}: ys 167 + }; 168 + revi(xs, {}) 30 169 }; 31 170 32 -print( @type(fib(10)) ); 171 +var xs = cons(1, cons(2, cons(3, nil))); 172 +print( @type( rev(xs) ) );