Diff
Not logged in

Differences From Artifact [6a40040679ba714c]:

To Artifact [e50284fdcde212f7]:


> 1 # Lift to types 1 @@type = fun(x){ | 2 @@type (x) > 3 { 2 if _isint(x): "int" | 4 if _isint(x): "int" 3 else if _isstr(x): "str" | 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) ) 4 else: "any" | 11 else 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 )} < > 12 {list: "RE"} # tenuki > 13 else ... 12 }; 14 }; 13 15 14 @type "+" = binop("int", "int", "int"); | 16 # unify two types 15 @type "-" = binop("int", "int", "int"); | 17 def mergeType(a, b) 16 @type "<" = binop("int", "int", "int"); < 17 @type ">" = binop("int", "int", "int"); < 18 | 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: 19 def mergeType(a,b) { | 23 let rt = mergeType(a.list, b.list) in 20 if( _isbot(a) ): ( if( _isbot(b) ):"error" else b ) else ( a ) < > 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 > 31 # helper function > 32 def Tuni(t1, t0) > 33 { 23 @type "if" = fun(c,t,e) {@value( | 34 fun(x) {@value( 24 if(@type(c)=="int" ): mergeType(@type(t()), @type(e())) else : "error" < > 35 if @type(x)=="RE": "RE" > 36 else if @type(x)=="TE": "TE" > 37 else if @type(x)==t1: t0 > 38 else "TE" 25 )}; | 39 )} > 40 }; > 41 def Tuniany(t0) 26 | 42 { 27 def fib(x) < > 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 { > 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 29 if x<2 then 1 else fib(x-1) + fib(x-2) | 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 > 171 var xs = cons(1, cons(2, cons(3, nil))); 32 print( @type(fib(10)) ); | 172 print( @type( rev(xs) ) );