File Annotation
Not logged in
576c494e53 2010-11-27        kinaba: # Lift to types
576c494e53 2010-11-27        kinaba: @@type (x)
576c494e53 2010-11-27        kinaba: {
576c494e53 2010-11-27        kinaba: 	if _isint(x): "int"
576c494e53 2010-11-27        kinaba: 	else if _isstr(x): "str"
576c494e53 2010-11-27        kinaba: 	else if _isbot(x): "RE"
576c494e53 2010-11-27        kinaba: 	else if _istbl(x):
576c494e53 2010-11-27        kinaba: 		if x.?car && x.?cdr:
576c494e53 2010-11-27        kinaba: 			let xa = x.car in let xd = x.cdr in
576c494e53 2010-11-27        kinaba: 				mergeType( {list: @type(xa)}, @type(xd) )
576c494e53 2010-11-27        kinaba: 		else
576c494e53 2010-11-27        kinaba: 			{list: "RE"} # tenuki
576c494e53 2010-11-27        kinaba: 	else ...
da7559b744 2010-11-21        kinaba: };
da7559b744 2010-11-21        kinaba: 
576c494e53 2010-11-27        kinaba: # unify two types
576c494e53 2010-11-27        kinaba: def mergeType(a, b)
576c494e53 2010-11-27        kinaba: {
576c494e53 2010-11-27        kinaba: 	if a == "RE": b
576c494e53 2010-11-27        kinaba: 	else if b == "RE": a
576c494e53 2010-11-27        kinaba: 	else if _istbl(a) && _istbl(b):
576c494e53 2010-11-27        kinaba: 		if  a.?list && b.?list:
576c494e53 2010-11-27        kinaba: 			let rt = mergeType(a.list, b.list) in
576c494e53 2010-11-27        kinaba: 				if rt=="TE" || rt=="RE" then rt else {list: rt}
576c494e53 2010-11-27        kinaba: 		else:
576c494e53 2010-11-27        kinaba: 			"TE" # type error
576c494e53 2010-11-27        kinaba: 	else if a == b: a
576c494e53 2010-11-27        kinaba: 	else "TE"  # type error
5afe8e3f26 2010-11-13        kinaba: };
5afe8e3f26 2010-11-13        kinaba: 
576c494e53 2010-11-27        kinaba: # helper function
576c494e53 2010-11-27        kinaba: def Tuni(t1, t0)
576c494e53 2010-11-27        kinaba: {
576c494e53 2010-11-27        kinaba: 	fun(x) {@value(
576c494e53 2010-11-27        kinaba: 		if @type(x)=="RE": "RE"
576c494e53 2010-11-27        kinaba: 		else if @type(x)=="TE": "TE"
576c494e53 2010-11-27        kinaba: 		else if @type(x)==t1: t0
576c494e53 2010-11-27        kinaba: 		else "TE"
576c494e53 2010-11-27        kinaba: 	)}
576c494e53 2010-11-27        kinaba: };
576c494e53 2010-11-27        kinaba: def Tuniany(t0)
576c494e53 2010-11-27        kinaba: {
576c494e53 2010-11-27        kinaba: 	fun(x) {@value(
576c494e53 2010-11-27        kinaba: 		if @type(x)=="RE": "RE"
576c494e53 2010-11-27        kinaba: 		else if @type(x)=="TE": "TE"
576c494e53 2010-11-27        kinaba: 		else t0
576c494e53 2010-11-27        kinaba: 	)}
576c494e53 2010-11-27        kinaba: };
576c494e53 2010-11-27        kinaba: def Tbin(t1, t2, t0)
576c494e53 2010-11-27        kinaba: {
576c494e53 2010-11-27        kinaba: 	fun(x,y) {@value(
576c494e53 2010-11-27        kinaba: 		if @type(x)=="RE" || @type(y)=="RE": "RE"
576c494e53 2010-11-27        kinaba: 		else if @type(x)=="TE" || @type(y)=="TE": "TE"
576c494e53 2010-11-27        kinaba: 		else if @type(x)==t1 && @type(y)==t2: t0
576c494e53 2010-11-27        kinaba: 		else "TE"
576c494e53 2010-11-27        kinaba: 	)}
576c494e53 2010-11-27        kinaba: };
576c494e53 2010-11-27        kinaba: def Tbinany(t0)
b993a8ad16 2010-11-24        kinaba: {
576c494e53 2010-11-27        kinaba: 	fun(x,y){@value(
576c494e53 2010-11-27        kinaba: 		if @type(x)=="RE" || @type(y)=="RE": "RE"
576c494e53 2010-11-27        kinaba: 		else if @type(x)=="TE" || @type(y)=="TE": "TE"
576c494e53 2010-11-27        kinaba: 		else t0
576c494e53 2010-11-27        kinaba: 	)}
576c494e53 2010-11-27        kinaba: };
576c494e53 2010-11-27        kinaba: 
576c494e53 2010-11-27        kinaba: # type annotation for built-in ops
576c494e53 2010-11-27        kinaba: @type "+" = Tbin("int", "int", "int");
576c494e53 2010-11-27        kinaba: @type "-" = Tbin("int", "int", "int");
576c494e53 2010-11-27        kinaba: @type "*" = Tbin("int", "int", "int");
576c494e53 2010-11-27        kinaba: @type "/" = Tbin("int", "int", "int");
576c494e53 2010-11-27        kinaba: @type "%" = Tbin("int", "int", "int");
576c494e53 2010-11-27        kinaba: @type "&&" = Tbin("int", "int", "int");
576c494e53 2010-11-27        kinaba: @type "||" = Tbin("int", "int", "int");
576c494e53 2010-11-27        kinaba: @type print = fun(x){x};
576c494e53 2010-11-27        kinaba: @type gensym = fun(){"str"};
576c494e53 2010-11-27        kinaba: @type argv = {list: "str"};
576c494e53 2010-11-27        kinaba: @type rand = Tuni("int","int");
576c494e53 2010-11-27        kinaba: @type "~" = Tbinany("str");
576c494e53 2010-11-27        kinaba: @type "<" = Tbinany("int");
576c494e53 2010-11-27        kinaba: @type "<=" = Tbinany("int");
576c494e53 2010-11-27        kinaba: @type ">" = Tbinany("int");
576c494e53 2010-11-27        kinaba: @type ">=" = Tbinany("int");
576c494e53 2010-11-27        kinaba: @type "==" = Tbinany("int");
576c494e53 2010-11-27        kinaba: @type "!=" = Tbinany("int");
576c494e53 2010-11-27        kinaba: @type "if" (c,t,e) {@value(
576c494e53 2010-11-27        kinaba: 	if @type(c)=="RE": "RE"
576c494e53 2010-11-27        kinaba: 	else if @type(c)!="int": "TE"
576c494e53 2010-11-27        kinaba: 	else mergeType( @type(t()), @type(e()) );
576c494e53 2010-11-27        kinaba: )};
576c494e53 2010-11-27        kinaba: @type _isint = Tuniany("int");
576c494e53 2010-11-27        kinaba: @type _isstr = Tuniany("int");
576c494e53 2010-11-27        kinaba: @type _isfun = Tuniany("int");
576c494e53 2010-11-27        kinaba: @type _istbl = Tuniany("int");
576c494e53 2010-11-27        kinaba: @type _isbot = Tuniany("int");
576c494e53 2010-11-27        kinaba: 
576c494e53 2010-11-27        kinaba: ###################################
576c494e53 2010-11-27        kinaba: 
576c494e53 2010-11-27        kinaba: # for lists
576c494e53 2010-11-27        kinaba: @type "{}"() {@value( {list: "RE"} )};
576c494e53 2010-11-27        kinaba: @type ".?"(t, s) {@value(
576c494e53 2010-11-27        kinaba: 	if @type(t)=="RE": "RE"
576c494e53 2010-11-27        kinaba: 	else if @type(t)=="TE": "TE"
576c494e53 2010-11-27        kinaba: 	else if _istbl( @type(t) ): "int"
576c494e53 2010-11-27        kinaba: 	else "TE"
576c494e53 2010-11-27        kinaba: )};
576c494e53 2010-11-27        kinaba: @type ".="(t, s@value, v) {@value(
576c494e53 2010-11-27        kinaba: 	var tt = @type(t);
576c494e53 2010-11-27        kinaba: 	if tt == "TE": "TE"
576c494e53 2010-11-27        kinaba: 	else if tt == "RE": "RE"
576c494e53 2010-11-27        kinaba: 	else if _istbl(tt) && tt.?list:
576c494e53 2010-11-27        kinaba: 		if s == "car":
576c494e53 2010-11-27        kinaba: 			mergeType(tt, {list: @type(v)})
576c494e53 2010-11-27        kinaba: 		else if s == "cdr":
576c494e53 2010-11-27        kinaba: 			mergeType(tt, @type(v))
576c494e53 2010-11-27        kinaba: 		else:
576c494e53 2010-11-27        kinaba: 			tt
576c494e53 2010-11-27        kinaba: 	else:
576c494e53 2010-11-27        kinaba: 		"TE"
576c494e53 2010-11-27        kinaba: )};
576c494e53 2010-11-27        kinaba: @type "."(t, s@value) {@value(
576c494e53 2010-11-27        kinaba: 	var tt = @type(t);
576c494e53 2010-11-27        kinaba: 	if tt == "TE": "TE"
576c494e53 2010-11-27        kinaba: 	else if tt == "RE": "RE"
576c494e53 2010-11-27        kinaba: 	else if _istbl(tt) && tt.?list:
576c494e53 2010-11-27        kinaba: 		if s == "car":
576c494e53 2010-11-27        kinaba: 			tt.list
576c494e53 2010-11-27        kinaba: 		else if s == "cdr":
576c494e53 2010-11-27        kinaba: 			tt
576c494e53 2010-11-27        kinaba: 		else:
576c494e53 2010-11-27        kinaba: 			"TE"
576c494e53 2010-11-27        kinaba: 	else:
576c494e53 2010-11-27        kinaba: 		"TE"
576c494e53 2010-11-27        kinaba: )};
576c494e53 2010-11-27        kinaba: 
576c494e53 2010-11-27        kinaba: ###################################
576c494e53 2010-11-27        kinaba: 
576c494e53 2010-11-27        kinaba: def fib(x) { if x < 2 then 1 else fib(x-1) + fib(x-2) };
576c494e53 2010-11-27        kinaba: def fibE1(x) { if "true!" then 1 else fib(x-1) + fib(x-2) };
576c494e53 2010-11-27        kinaba: def fibE2(x) { if x<2 then "ichi" else fib(x-1) + fib(x-2) };
576c494e53 2010-11-27        kinaba: def fibE3(x) { if x<2 then 1 else fib(x-1) ~ fib(x-2) };
576c494e53 2010-11-27        kinaba: def fibS(x) { if x<2 then "1" else fib(x-1) ~ fib(x-2) };
576c494e53 2010-11-27        kinaba: def fibBadButTypeIsOK(x) { if x < "2" then 1 else fib(x-1) + fib(x-2) };
576c494e53 2010-11-27        kinaba: 
576c494e53 2010-11-27        kinaba: print( @type(fib(999)) );
576c494e53 2010-11-27        kinaba: print( @type(fibE1(999)) );
576c494e53 2010-11-27        kinaba: print( @type(fibE2(999)) );
576c494e53 2010-11-27        kinaba: print( @type(fibE3(999)) );
576c494e53 2010-11-27        kinaba: print( @type(fibS(999)) );
576c494e53 2010-11-27        kinaba: print( @type(fibBadButTypeIsOK(999)) );
576c494e53 2010-11-27        kinaba: 
576c494e53 2010-11-27        kinaba: ###################################
576c494e53 2010-11-27        kinaba: 
576c494e53 2010-11-27        kinaba: def nil = {};
576c494e53 2010-11-27        kinaba: def cons(a, d) { {car: a, cdr: d} };
576c494e53 2010-11-27        kinaba: 
576c494e53 2010-11-27        kinaba: print( @type(nil) );
576c494e53 2010-11-27        kinaba: print( @type(cons(1,nil)) );
576c494e53 2010-11-27        kinaba: print( @type(cons("foo",nil)) );
576c494e53 2010-11-27        kinaba: print( @type(cons(123, cons("foo",nil))) ); # TE
576c494e53 2010-11-27        kinaba: 
576c494e53 2010-11-27        kinaba: def rev(xs) {
576c494e53 2010-11-27        kinaba: 	def revi(xs, ys) {
576c494e53 2010-11-27        kinaba: 		case xs
576c494e53 2010-11-27        kinaba: 			when {car: x, cdr: xs}: revi(xs, cons(x,ys))
576c494e53 2010-11-27        kinaba: 			when {}: ys
576c494e53 2010-11-27        kinaba: 	};
576c494e53 2010-11-27        kinaba: 	revi(xs, {})
b993a8ad16 2010-11-24        kinaba: };
b993a8ad16 2010-11-24        kinaba: 
576c494e53 2010-11-27        kinaba: var xs = cons(1, cons(2, cons(3, nil)));
576c494e53 2010-11-27        kinaba: print( @type( rev(xs) ) );