Added the tests that I'm using for porting.

This commit is contained in:
Abdulaziz Ghuloum 2008-01-04 05:55:06 -05:00
parent 069ff811e2
commit e35ed42f6c
27 changed files with 2137 additions and 0 deletions

View File

@ -0,0 +1,11 @@
(add-tests-with-string-output "integers"
[0 => "0\n"]
[1 => "1\n"]
[-1 => "-1\n"]
[10 => "10\n"]
[-10 => "-10\n"]
[2736 => "2736\n"]
[-2736 => "-2736\n"]
[536870911 => "536870911\n"]
[-536870912 => "-536870912\n"]
)

View File

@ -0,0 +1,133 @@
(add-tests-with-string-output "immediate constants"
[#f => "#f\n"]
[#t => "#t\n"]
[() => "()\n"]
; [#\nul => "#\\nul\n"]
; [#\001 => "#\\soh\n"]
; [#\002 => "#\\stx\n"]
; [#\003 => "#\\etx\n"]
; [#\004 => "#\\eot\n"]
; [#\005 => "#\\enq\n"]
; [#\006 => "#\\ack\n"]
; [#\bel => "#\\bel\n"]
; [#\backspace => "#\\bs\n"]
[#\tab => "#\\tab\n"]
; [#\newline => "#\\newline\n"]
; [#\vt => "#\\vt\n"]
; [#\page => "#\\ff\n"]
; [#\return => "#\\return\n"]
; [#\016 => "#\\so\n"]
; [#\017 => "#\\si\n"]
; [#\020 => "#\\dle\n"]
; [#\021 => "#\\dc1\n"]
; [#\022 => "#\\dc2\n"]
; [#\023 => "#\\dc3\n"]
; [#\024 => "#\\dc4\n"]
; [#\025 => "#\\nak\n"]
; [#\026 => "#\\syn\n"]
; [#\027 => "#\\etb\n"]
; [#\030 => "#\\can\n"]
; [#\031 => "#\\em\n"]
; [#\032 => "#\\sub\n"]
; [#\033 => "#\\esc\n"]
; [#\034 => "#\\fs\n"]
; [#\035 => "#\\gs\n"]
; [#\036 => "#\\rs\n"]
; [#\037 => "#\\us\n"]
[#\space => "#\\space\n"]
[#\! => "#\\!\n"]
[#\" => "#\\\"\n"]
[#\# => "#\\#\n"]
[#\$ => "#\\$\n"]
[#\% => "#\\%\n"]
[#\& => "#\\&\n"]
[#\' => "#\\'\n"]
[#\( => "#\\(\n"]
[#\) => "#\\)\n"]
[#\* => "#\\*\n"]
[#\+ => "#\\+\n"]
[#\, => "#\\,\n"]
[#\- => "#\\-\n"]
[#\. => "#\\.\n"]
[#\/ => "#\\/\n"]
[#\0 => "#\\0\n"]
[#\1 => "#\\1\n"]
[#\2 => "#\\2\n"]
[#\3 => "#\\3\n"]
[#\4 => "#\\4\n"]
[#\5 => "#\\5\n"]
[#\6 => "#\\6\n"]
[#\7 => "#\\7\n"]
[#\8 => "#\\8\n"]
[#\9 => "#\\9\n"]
[#\: => "#\\:\n"]
[#\; => "#\\;\n"]
[#\< => "#\\<\n"]
[#\= => "#\\=\n"]
[#\> => "#\\>\n"]
[#\? => "#\\?\n"]
[#\@ => "#\\@\n"]
[#\A => "#\\A\n"]
[#\B => "#\\B\n"]
[#\C => "#\\C\n"]
[#\D => "#\\D\n"]
[#\E => "#\\E\n"]
[#\F => "#\\F\n"]
[#\G => "#\\G\n"]
[#\H => "#\\H\n"]
[#\I => "#\\I\n"]
[#\J => "#\\J\n"]
[#\K => "#\\K\n"]
[#\L => "#\\L\n"]
[#\M => "#\\M\n"]
[#\N => "#\\N\n"]
[#\O => "#\\O\n"]
[#\P => "#\\P\n"]
[#\Q => "#\\Q\n"]
[#\R => "#\\R\n"]
[#\S => "#\\S\n"]
[#\T => "#\\T\n"]
[#\U => "#\\U\n"]
[#\V => "#\\V\n"]
[#\W => "#\\W\n"]
[#\X => "#\\X\n"]
[#\Y => "#\\Y\n"]
[#\Z => "#\\Z\n"]
[#\[ => "#\\[\n"]
[#\\ => "#\\\\\n"]
[#\] => "#\\]\n"]
[#\^ => "#\\^\n"]
[#\_ => "#\\_\n"]
[#\` => "#\\`\n"]
[#\a => "#\\a\n"]
[#\b => "#\\b\n"]
[#\c => "#\\c\n"]
[#\d => "#\\d\n"]
[#\e => "#\\e\n"]
[#\f => "#\\f\n"]
[#\g => "#\\g\n"]
[#\h => "#\\h\n"]
[#\i => "#\\i\n"]
[#\j => "#\\j\n"]
[#\k => "#\\k\n"]
[#\l => "#\\l\n"]
[#\m => "#\\m\n"]
[#\n => "#\\n\n"]
[#\o => "#\\o\n"]
[#\p => "#\\p\n"]
[#\q => "#\\q\n"]
[#\r => "#\\r\n"]
[#\s => "#\\s\n"]
[#\t => "#\\t\n"]
[#\u => "#\\u\n"]
[#\v => "#\\v\n"]
[#\w => "#\\w\n"]
[#\x => "#\\x\n"]
[#\y => "#\\y\n"]
[#\z => "#\\z\n"]
[#\{ => "#\\{\n"]
[#\| => "#\\|\n"]
[#\} => "#\\}\n"]
[#\~ => "#\\~\n"]
; [#\rubout => "#\\del\n"]
)

View File

@ -0,0 +1,117 @@
(add-tests-with-string-output "fxadd1"
[($fxadd1 0) => "1\n"]
[($fxadd1 -1) => "0\n"]
[($fxadd1 1) => "2\n"]
[($fxadd1 -100) => "-99\n"]
[($fxadd1 1000) => "1001\n"]
[($fxadd1 536870910) => "536870911\n"]
[($fxadd1 -536870912) => "-536870911\n"]
[($fxadd1 ($fxadd1 0)) => "2\n"]
[($fxadd1 ($fxadd1 ($fxadd1 ($fxadd1 ($fxadd1 ($fxadd1 12)))))) => "18\n"]
)
(add-tests-with-string-output "fixnum->char and char->fixnum"
[($fixnum->char 65) => "#\\A\n"]
[($fixnum->char 97) => "#\\a\n"]
[($fixnum->char 122) => "#\\z\n"]
[($fixnum->char 90) => "#\\Z\n"]
[($fixnum->char 48) => "#\\0\n"]
[($fixnum->char 57) => "#\\9\n"]
[($char->fixnum #\A) => "65\n"]
[($char->fixnum #\a) => "97\n"]
[($char->fixnum #\z) => "122\n"]
[($char->fixnum #\Z) => "90\n"]
[($char->fixnum #\0) => "48\n"]
[($char->fixnum #\9) => "57\n"]
[($char->fixnum ($fixnum->char 12)) => "12\n"]
[($fixnum->char ($char->fixnum #\x)) => "#\\x\n"]
)
(add-tests-with-string-output "fixnum?"
[(fixnum? 0) => "#t\n"]
[(fixnum? 1) => "#t\n"]
[(fixnum? -1) => "#t\n"]
[(fixnum? 37287) => "#t\n"]
[(fixnum? -23873) => "#t\n"]
[(fixnum? 536870911) => "#t\n"]
[(fixnum? -536870912) => "#t\n"]
[(fixnum? #t) => "#f\n"]
[(fixnum? #f) => "#f\n"]
[(fixnum? ()) => "#f\n"]
[(fixnum? #\Q) => "#f\n"]
[(fixnum? (fixnum? 12)) => "#f\n"]
[(fixnum? (fixnum? #f)) => "#f\n"]
[(fixnum? (fixnum? #\A)) => "#f\n"]
[(fixnum? ($char->fixnum #\r)) => "#t\n"]
[(fixnum? ($fixnum->char 12)) => "#f\n"]
)
(add-tests-with-string-output "fxzero?"
[($fxzero? 0) => "#t\n"]
[($fxzero? 1) => "#f\n"]
[($fxzero? -1) => "#f\n"]
)
(add-tests-with-string-output "null?"
[(null? ()) => "#t\n"]
[(null? #f) => "#f\n"]
[(null? #t) => "#f\n"]
[(null? (null? ())) => "#f\n"]
[(null? #\a) => "#f\n"]
[(null? 0) => "#f\n"]
[(null? -10) => "#f\n"]
[(null? 10) => "#f\n"]
)
(add-tests-with-string-output "boolean?"
[(boolean? #t) => "#t\n"]
[(boolean? #f) => "#t\n"]
[(boolean? 0) => "#f\n"]
[(boolean? 1) => "#f\n"]
[(boolean? -1) => "#f\n"]
[(boolean? ()) => "#f\n"]
[(boolean? #\a) => "#f\n"]
[(boolean? (boolean? 0)) => "#t\n"]
[(boolean? (fixnum? (boolean? 0))) => "#t\n"]
)
(add-tests-with-string-output "char?"
[(char? #\a) => "#t\n"]
[(char? #\Z) => "#t\n"]
[(char? #\newline) => "#t\n"]
[(char? #t) => "#f\n"]
[(char? #f) => "#f\n"]
[(char? ()) => "#f\n"]
[(char? (char? #t)) => "#f\n"]
[(char? 0) => "#f\n"]
[(char? 23870) => "#f\n"]
[(char? -23789) => "#f\n"]
)
(add-tests-with-string-output "not"
[(not #t) => "#f\n"]
[(not #f) => "#t\n"]
[(not 15) => "#f\n"]
[(not ()) => "#f\n"]
[(not #\A) => "#f\n"]
[(not (not #t)) => "#t\n"]
[(not (not #f)) => "#f\n"]
[(not (not 15)) => "#t\n"]
[(not (fixnum? 15)) => "#f\n"]
[(not (fixnum? #f)) => "#t\n"]
)
(add-tests-with-string-output "fxlognot"
[($fxlognot 0) => "-1\n"]
[($fxlognot -1) => "0\n"]
[($fxlognot 1) => "-2\n"]
[($fxlognot -2) => "1\n"]
[($fxlognot 536870911) => "-536870912\n"]
[($fxlognot -536870912) => "536870911\n"]
[($fxlognot ($fxlognot 237463)) => "237463\n"]
)

View File

@ -0,0 +1,18 @@
(add-tests-with-string-output "if"
[(if #t 12 13) => "12\n"]
[(if #f 12 13) => "13\n"]
[(if 0 12 13) => "12\n"]
[(if () 43 ()) => "43\n"]
[(if #t (if 12 13 4) 17) => "13\n"]
[(if #f 12 (if #f 13 4)) => "4\n"]
[(if #\X (if 1 2 3) (if 4 5 6)) => "2\n"]
[(if (not (boolean? #t)) 15 (boolean? #f)) => "#t\n"]
[(if (if (char? #\a) (boolean? #\b) (fixnum? #\c)) 119 -23) => "-23\n"]
[(if (if (if (not 1) (not 2) (not 3)) 4 5) 6 7) => "6\n"]
[(if (not (if (if (not 1) (not 2) (not 3)) 4 5)) 6 7) => "7\n"]
[(not (if (not (if (if (not 1) (not 2) (not 3)) 4 5)) 6 7)) => "#f\n"]
[(if (char? 12) 13 14) => "14\n"]
[(if (char? #\a) 13 14) => "13\n"]
[($fxadd1 (if ($fxsub1 1) ($fxsub1 13) 14)) => "13\n"]
)

View File

@ -0,0 +1,172 @@
(add-tests-with-string-output "fx+"
[(fx+ 1 2) => "3\n"]
[(fx+ 1 -2) => "-1\n"]
[(fx+ -1 2) => "1\n"]
[(fx+ -1 -2) => "-3\n"]
[(fx+ 536870911 -1) => "536870910\n"]
[(fx+ 536870910 1) => "536870911\n"]
[(fx+ -536870912 1) => "-536870911\n"]
[(fx+ -536870911 -1) => "-536870912\n"]
[(fx+ 536870911 -536870912) => "-1\n"]
[(fx+ 1 (fx+ 2 3)) => "6\n"]
[(fx+ 1 (fx+ 2 -3)) => "0\n"]
[(fx+ 1 (fx+ -2 3)) => "2\n"]
[(fx+ 1 (fx+ -2 -3)) => "-4\n"]
[(fx+ -1 (fx+ 2 3)) => "4\n"]
[(fx+ -1 (fx+ 2 -3)) => "-2\n"]
[(fx+ -1 (fx+ -2 3)) => "0\n"]
[(fx+ -1 (fx+ -2 -3)) => "-6\n"]
[(fx+ (fx+ 1 2) 3) => "6\n"]
[(fx+ (fx+ 1 2) -3) => "0\n"]
[(fx+ (fx+ 1 -2) 3) => "2\n"]
[(fx+ (fx+ 1 -2) -3) => "-4\n"]
[(fx+ (fx+ -1 2) 3) => "4\n"]
[(fx+ (fx+ -1 2) -3) => "-2\n"]
[(fx+ (fx+ -1 -2) 3) => "0\n"]
[(fx+ (fx+ -1 -2) -3) => "-6\n"]
[(fx+ (fx+ (fx+ (fx+ (fx+ (fx+ (fx+ (fx+ 1 2) 3) 4) 5) 6) 7) 8) 9) => "45\n"]
[(fx+ 1 (fx+ 2 (fx+ 3 (fx+ 4 (fx+ 5 (fx+ 6 (fx+ 7 (fx+ 8 9)))))))) => "45\n"]
)
(add-tests-with-string-output "fx-"
[(fx- 1 2) => "-1\n"]
[(fx- 1 -2) => "3\n"]
[(fx- -1 2) => "-3\n"]
[(fx- -1 -2) => "1\n"]
[(fx- 536870910 -1) => "536870911\n"]
[(fx- 536870911 1) => "536870910\n"]
[(fx- -536870911 1) => "-536870912\n"]
[(fx- -536870912 -1) => "-536870911\n"]
[(fx- 1 536870911) => "-536870910\n"]
[(fx- -1 536870911) => "-536870912\n"]
[(fx- 1 -536870910) => "536870911\n"]
[(fx- -1 -536870912) => "536870911\n"]
[(fx- 536870911 536870911) => "0\n"]
;[(fx- 536870911 -536870912) => "-1\n"]
[(fx- -536870911 -536870912) => "1\n"]
[(fx- 1 (fx- 2 3)) => "2\n"]
[(fx- 1 (fx- 2 -3)) => "-4\n"]
[(fx- 1 (fx- -2 3)) => "6\n"]
[(fx- 1 (fx- -2 -3)) => "0\n"]
[(fx- -1 (fx- 2 3)) => "0\n"]
[(fx- -1 (fx- 2 -3)) => "-6\n"]
[(fx- -1 (fx- -2 3)) => "4\n"]
[(fx- -1 (fx- -2 -3)) => "-2\n"]
[(fx- 0 (fx- -2 -3)) => "-1\n"]
[(fx- (fx- 1 2) 3) => "-4\n"]
[(fx- (fx- 1 2) -3) => "2\n"]
[(fx- (fx- 1 -2) 3) => "0\n"]
[(fx- (fx- 1 -2) -3) => "6\n"]
[(fx- (fx- -1 2) 3) => "-6\n"]
[(fx- (fx- -1 2) -3) => "0\n"]
[(fx- (fx- -1 -2) 3) => "-2\n"]
[(fx- (fx- -1 -2) -3) => "4\n"]
[(fx- (fx- (fx- (fx- (fx- (fx- (fx- (fx- 1 2) 3) 4) 5) 6) 7) 8) 9) => "-43\n"]
[(fx- 1 (fx- 2 (fx- 3 (fx- 4 (fx- 5 (fx- 6 (fx- 7 (fx- 8 9)))))))) => "5\n"]
)
(add-tests-with-string-output "fx*"
[(fx* 2 3) => "6\n"]
[(fx* 2 -3) => "-6\n"]
[(fx* -2 3) => "-6\n"]
[(fx* -2 -3) => "6\n"]
[(fx* 536870911 1) => "536870911\n"]
[(fx* 536870911 -1) => "-536870911\n"]
[(fx* -536870912 1) => "-536870912\n"]
[(fx* -536870911 -1) => "536870911\n"]
[(fx* 2 (fx* 3 4)) => "24\n"]
[(fx* (fx* 2 3) 4) => "24\n"]
[(fx* (fx* (fx* (fx* (fx* 2 3) 4) 5) 6) 7) => "5040\n"]
[(fx* 2 (fx* 3 (fx* 4 (fx* 5 (fx* 6 7))))) => "5040\n"]
)
(add-tests-with-string-output "fxlogand and fxlogor"
[(fxlogor 3 16) => "19\n"]
[(fxlogor 3 5) => "7\n"]
[(fxlogor 3 7) => "7\n"]
[(fxlognot (fxlogor (fxlognot 7) 1)) => "6\n"]
[(fxlognot (fxlogor 1 (fxlognot 7))) => "6\n"]
[(fxlogand 3 7) => "3\n"]
[(fxlogand 3 5) => "1\n"]
[(fxlogand 2346 (fxlognot 2346)) => "0\n"]
[(fxlogand (fxlognot 2346) 2346) => "0\n"]
[(fxlogand 2376 2376) => "2376\n"]
)
(add-tests-with-string-output "fx="
[(fx= 12 13) => "#f\n"]
[(fx= 12 12) => "#t\n"]
[(fx= 16 (fx+ 13 3)) => "#t\n"]
[(fx= 16 (fx+ 13 13)) => "#f\n"]
[(fx= (fx+ 13 3) 16) => "#t\n"]
[(fx= (fx+ 13 13) 16) => "#f\n"]
)
(add-tests-with-string-output "fx<"
[(fx< 12 13) => "#t\n"]
[(fx< 12 12) => "#f\n"]
[(fx< 13 12) => "#f\n"]
[(fx< 16 (fx+ 13 1)) => "#f\n"]
[(fx< 16 (fx+ 13 3)) => "#f\n"]
[(fx< 16 (fx+ 13 13)) => "#t\n"]
[(fx< (fx+ 13 1) 16) => "#t\n"]
[(fx< (fx+ 13 3) 16) => "#f\n"]
[(fx< (fx+ 13 13) 16) => "#f\n"]
)
(add-tests-with-string-output "fx<="
[(fx<= 12 13) => "#t\n"]
[(fx<= 12 12) => "#t\n"]
[(fx<= 13 12) => "#f\n"]
[(fx<= 16 (fx+ 13 1)) => "#f\n"]
[(fx<= 16 (fx+ 13 3)) => "#t\n"]
[(fx<= 16 (fx+ 13 13)) => "#t\n"]
[(fx<= (fx+ 13 1) 16) => "#t\n"]
[(fx<= (fx+ 13 3) 16) => "#t\n"]
[(fx<= (fx+ 13 13) 16) => "#f\n"]
)
(add-tests-with-string-output "fx>"
[(fx> 12 13) => "#f\n"]
[(fx> 12 12) => "#f\n"]
[(fx> 13 12) => "#t\n"]
[(fx> 16 (fx+ 13 1)) => "#t\n"]
[(fx> 16 (fx+ 13 3)) => "#f\n"]
[(fx> 16 (fx+ 13 13)) => "#f\n"]
[(fx> (fx+ 13 1) 16) => "#f\n"]
[(fx> (fx+ 13 3) 16) => "#f\n"]
[(fx> (fx+ 13 13) 16) => "#t\n"]
)
(add-tests-with-string-output "fx>="
[(fx>= 12 13) => "#f\n"]
[(fx>= 12 12) => "#t\n"]
[(fx>= 13 12) => "#t\n"]
[(fx>= 16 (fx+ 13 1)) => "#t\n"]
[(fx>= 16 (fx+ 13 3)) => "#t\n"]
[(fx>= 16 (fx+ 13 13)) => "#f\n"]
[(fx>= (fx+ 13 1) 16) => "#f\n"]
[(fx>= (fx+ 13 3) 16) => "#t\n"]
[(fx>= (fx+ 13 13) 16) => "#t\n"]
)
(add-tests-with-string-output "if"
[(if (fx= 12 13) 12 13) => "13\n"]
[(if (fx= 12 12) 13 14) => "13\n"]
[(if (fx< 12 13) 12 13) => "12\n"]
[(if (fx< 12 12) 13 14) => "14\n"]
[(if (fx< 13 12) 13 14) => "14\n"]
[(if (fx<= 12 13) 12 13) => "12\n"]
[(if (fx<= 12 12) 12 13) => "12\n"]
[(if (fx<= 13 12) 13 14) => "14\n"]
[(if (fx> 12 13) 12 13) => "13\n"]
[(if (fx> 12 12) 12 13) => "13\n"]
[(if (fx> 13 12) 13 14) => "13\n"]
[(if (fx>= 12 13) 12 13) => "13\n"]
[(if (fx>= 12 12) 12 13) => "12\n"]
[(if (fx>= 13 12) 13 14) => "13\n"]
)

View File

@ -0,0 +1,37 @@
(add-tests-with-string-output "let"
[(let ([x 5]) x) => "5\n"]
[(let ([x (fx+ 1 2)]) x) => "3\n"]
[(let ([x (fx+ 1 2)])
(let ([y (fx+ 3 4)])
(fx+ x y)))
=> "10\n"]
[(let ([x (fx+ 1 2)])
(let ([y (fx+ 3 4)])
(fx- y x)))
=> "4\n"]
[(let ([x (fx+ 1 2)]
[y (fx+ 3 4)])
(fx- y x))
=> "4\n"]
[(let ([x (let ([y (fx+ 1 2)]) (fx* y y))])
(fx+ x x))
=> "18\n"]
[(let ([x (fx+ 1 2)])
(let ([x (fx+ 3 4)])
x))
=> "7\n"]
[(let ([x (fx+ 1 2)])
(let ([x (fx+ x 4)])
x))
=> "7\n"]
[(let ([t (let ([t (let ([t (let ([t (fx+ 1 2)]) t)]) t)]) t)]) t)
=> "3\n"]
[(let ([x 12])
(let ([x (fx+ x x)])
(let ([x (fx+ x x)])
(let ([x (fx+ x x)])
(fx+ x x)))))
=> "192\n"]
)

View File

@ -0,0 +1,80 @@
(add-tests-with-string-output "binary primitives"
[(fxlognot -7) => "6\n"]
[(fxlognot (fxlogor (fxlognot 7) 1)) => "6\n"]
[(fxlognot (fxlogor (fxlognot 7) (fxlognot 2))) => "2\n"]
[(fxlogand (fxlognot (fxlognot 12)) (fxlognot (fxlognot 12))) => "12\n"]
[(fx+ (fx+ 1 2) (fx+ 3 4)) => "10\n"]
[(fx+ (fx+ 1 2) (fx+ 3 -4)) => "2\n"]
[(fx+ (fx+ 1 2) (fx+ -3 4)) => "4\n"]
[(fx+ (fx+ 1 2) (fx+ -3 -4)) => "-4\n"]
[(fx+ (fx+ 1 -2) (fx+ 3 4)) => "6\n"]
[(fx+ (fx+ 1 -2) (fx+ 3 -4)) => "-2\n"]
[(fx+ (fx+ 1 -2) (fx+ -3 4)) => "0\n"]
[(fx+ (fx+ 1 -2) (fx+ -3 -4)) => "-8\n"]
[(fx+ (fx+ -1 2) (fx+ 3 4)) => "8\n"]
[(fx+ (fx+ -1 2) (fx+ 3 -4)) => "0\n"]
[(fx+ (fx+ -1 2) (fx+ -3 4)) => "2\n"]
[(fx+ (fx+ -1 2) (fx+ -3 -4)) => "-6\n"]
[(fx+ (fx+ -1 -2) (fx+ 3 4)) => "4\n"]
[(fx+ (fx+ -1 -2) (fx+ 3 -4)) => "-4\n"]
[(fx+ (fx+ -1 -2) (fx+ -3 4)) => "-2\n"]
[(fx+ (fx+ -1 -2) (fx+ -3 -4)) => "-10\n"]
[(fx+ (fx+ (fx+ (fx+ (fx+ (fx+ (fx+ (fx+ 1 2) 3) 4) 5) 6) 7) 8) 9) => "45\n"]
[(fx+ 1 (fx+ 2 (fx+ 3 (fx+ 4 (fx+ 5 (fx+ 6 (fx+ 7 (fx+ 8 9)))))))) => "45\n"]
[(fx+ (fx+ (fx+ (fx+ 1 2) (fx+ 3 4)) (fx+ (fx+ 5 6) (fx+ 7 8)))
(fx+ (fx+ (fx+ 9 10) (fx+ 11 12)) (fx+ (fx+ 13 14) (fx+ 15 16))))
=> "136\n"]
[(fx- (fx- 1 2) (fx- 3 4)) => "0\n"]
[(fx- (fx- 1 2) (fx- 3 -4)) => "-8\n"]
[(fx- (fx- 1 2) (fx- -3 4)) => "6\n"]
[(fx- (fx- 1 2) (fx- -3 -4)) => "-2\n"]
[(fx- (fx- 1 -2) (fx- 3 4)) => "4\n"]
[(fx- (fx- 1 -2) (fx- 3 -4)) => "-4\n"]
[(fx- (fx- 1 -2) (fx- -3 4)) => "10\n"]
[(fx- (fx- 1 -2) (fx- -3 -4)) => "2\n"]
[(fx- (fx- -1 2) (fx- 3 4)) => "-2\n"]
[(fx- (fx- -1 2) (fx- 3 -4)) => "-10\n"]
[(fx- (fx- -1 2) (fx- -3 4)) => "4\n"]
[(fx- (fx- -1 2) (fx- -3 -4)) => "-4\n"]
[(fx- (fx- -1 -2) (fx- 3 4)) => "2\n"]
[(fx- (fx- -1 -2) (fx- 3 -4)) => "-6\n"]
[(fx- (fx- -1 -2) (fx- -3 4)) => "8\n"]
[(fx- (fx- -1 -2) (fx- -3 -4)) => "0\n"]
[(fx- (fx- (fx- (fx- (fx- (fx- (fx- (fx- 1 2) 3) 4) 5) 6) 7) 8) 9) => "-43\n"]
[(fx- 1 (fx- 2 (fx- 3 (fx- 4 (fx- 5 (fx- 6 (fx- 7 (fx- 8 9)))))))) => "5\n"]
[(fx- (fx- (fx- (fx- 1 2) (fx- 3 4)) (fx- (fx- 5 6) (fx- 7 8)))
(fx- (fx- (fx- 9 10) (fx- 11 12)) (fx- (fx- 13 14) (fx- 15 16))))
=> "0\n"]
[(fx* (fx* (fx* (fx* 2 3) (fx* 4 5)) (fx* (fx* 6 7) (fx* 8 9)))
(fx* (fx* (fx* 2 3) (fx* 2 3)) (fx* (fx* 2 3) (fx* 2 3))))
=> "470292480\n"]
[(fxlognot (fxlogor (fxlognot 7) 1)) => "6\n"]
[(fxlognot (fxlogor (fxlognot 7) (fxlognot 2))) => "2\n"]
[(fxlogand (fxlognot (fxlognot 12)) (fxlognot (fxlognot 12))) => "12\n"]
[(fx= (fx+ 13 3) (fx+ 10 6)) => "#t\n"]
[(fx= (fx+ 13 0) (fx+ 10 6)) => "#f\n"]
[(fx= (fx+ 12 1) (fx+ -12 -1)) => "#f\n"]
[(fx< (fx+ 10 6) (fx+ 13 1)) => "#f\n"]
[(fx< (fx+ 10 6) (fx+ 13 3)) => "#f\n"]
[(fx< (fx+ 10 6) (fx+ 13 31)) => "#t\n"]
[(fx< (fx+ 12 1) (fx+ -12 -1)) => "#f\n"]
[(fx< (fx+ -12 -1) (fx+ 12 1)) => "#t\n"]
[(fx<= (fx+ 10 6) (fx+ 13 1)) => "#f\n"]
[(fx<= (fx+ 10 6) (fx+ 13 3)) => "#t\n"]
[(fx<= (fx+ 10 6) (fx+ 13 31)) => "#t\n"]
[(fx<= (fx+ 12 1) (fx+ -12 -1)) => "#f\n"]
[(fx<= (fx+ -12 -1) (fx+ 12 1)) => "#t\n"]
[(fx> (fx+ 10 6) (fx+ 13 1)) => "#t\n"]
[(fx> (fx+ 10 6) (fx+ 13 3)) => "#f\n"]
[(fx> (fx+ 10 6) (fx+ 13 31)) => "#f\n"]
[(fx> (fx+ 12 1) (fx+ -12 -1)) => "#t\n"]
[(fx> (fx+ -12 -1) (fx+ 12 1)) => "#f\n"]
[(fx>= (fx+ 10 6) (fx+ 13 1)) => "#t\n"]
[(fx>= (fx+ 10 6) (fx+ 13 3)) => "#t\n"]
[(fx>= (fx+ 10 6) (fx+ 13 31)) => "#f\n"]
[(fx>= (fx+ 12 1) (fx+ -12 -1)) => "#t\n"]
[(fx>= (fx+ -12 -1) (fx+ 12 1)) => "#f\n"]
)

View File

@ -0,0 +1,92 @@
(add-tests-with-string-output "cons"
[(fxadd1 0) => "1\n"]
[(pair? (cons 1 2)) => "#t\n"]
[(pair? 12) => "#f\n"]
[(pair? #t) => "#f\n"]
[(pair? #f) => "#f\n"]
[(pair? ()) => "#f\n"]
[(fixnum? (cons 12 43)) => "#f\n"]
[(boolean? (cons 12 43)) => "#f\n"]
[(null? (cons 12 43)) => "#f\n"]
[(not (cons 12 43)) => "#f\n"]
[(if (cons 12 43) 32 43) => "32\n"]
[(car (cons 1 23)) => "1\n"]
[(cdr (cons 43 123)) => "123\n"]
[(car (car (cons (cons 12 3) (cons #t #f)))) => "12\n"]
[(cdr (car (cons (cons 12 3) (cons #t #f)))) => "3\n"]
[(car (cdr (cons (cons 12 3) (cons #t #f)))) => "#t\n"]
[(cdr (cdr (cons (cons 12 3) (cons #t #f)))) => "#f\n"]
[(let ([x (let ([y (fx+ 1 2)]) (fx* y y))])
(cons x (fx+ x x)))
=> "(9 . 18)\n"]
[(let ([t0 (cons 1 2)] [t1 (cons 3 4)])
(let ([a0 (car t0)] [a1 (car t1)] [d0 (cdr t0)] [d1 (cdr t1)])
(let ([t0 (cons a0 d1)] [t1 (cons a1 d0)])
(cons t0 t1))))
=> "((1 . 4) 3 . 2)\n"]
[(let ([t (cons 1 2)])
(let ([t t])
(let ([t t])
(let ([t t])
t))))
=> "(1 . 2)\n"]
[(let ([t (let ([t (let ([t (let ([t (cons 1 2)]) t)]) t)]) t)]) t)
=> "(1 . 2)\n"]
[(let ([x ()])
(let ([x (cons x x)])
(let ([x (cons x x)])
(let ([x (cons x x)])
(cons x x)))))
=> "((((()) ()) (()) ()) ((()) ()) (()) ())\n"]
[(cons (let ([x #t]) (let ([y (cons x x)]) (cons x y)))
(cons (let ([x #f]) (let ([y (cons x x)]) (cons y x)))
()))
=> "((#t #t . #t) ((#f . #f) . #f))\n"]
)
#!eof
(add-tests-with-string-output "procedures"
[(letrec () 12) => "12\n"]
[(letrec () (let ([x 5]) (fx+ x x))) => "10\n"]
[(letrec ([f (lambda () 5)]) 7) => "7\n"]
[(letrec ([f (lambda () 5)]) (let ([x 12]) x)) => "12\n"]
[(letrec ([f (lambda () 5)]) (f)) => "5\n"]
[(letrec ([f (lambda () 5)]) (let ([x (f)]) x)) => "5\n"]
[(letrec ([f (lambda () 5)]) (fx+ (f) 6)) => "11\n"]
[(letrec ([f (lambda () 5)]) (fx- 20 (f))) => "15\n"]
[(letrec ([f (lambda () 5)]) (fx+ (f) (f))) => "10\n"]
[(letrec ([f (lambda () (fx+ 5 7))]
[g (lambda () 13)])
(fx+ (f) (g))) => "25\n"]
[(letrec ([f (lambda (x) (fx+ x 12))]) (f 13)) => "25\n"]
[(letrec ([f (lambda (x) (fx+ x 12))]) (f (f 10))) => "34\n"]
[(letrec ([f (lambda (x) (fx+ x 12))]) (f (f (f 0)))) => "36\n"]
[(letrec ([f (lambda (x y) (fx+ x y))]
[g (lambda (x) (fx+ x 12))])
(f 16 (f (g 0) (fx+ 1 (g 0))))) => "41\n"]
[(letrec ([f (lambda (x) (g x x))]
[g (lambda (x y) (fx+ x y))])
(f 12)) => "24\n"]
[(letrec ([f (lambda (x)
(if (fxzero? x)
1
(fx* x (f (fxsub1 x)))))])
(f 5)) => "120\n"]
[(letrec ([e (lambda (x) (if (fxzero? x) #t (o (fxsub1 x))))]
[o (lambda (x) (if (fxzero? x) #f (e (fxsub1 x))))])
(e 25)) => "#f\n"]
)
(add-tests-with-string-output "deeply nested procedures"
[(letrec ([sum (lambda (n ac)
(if (fxzero? n)
ac
(app sum (fxsub1 n) (fx+ n ac))))])
(app sum 10000 0)) => "50005000\n"]
[(letrec ([e (lambda (x) (if (fxzero? x) #t (app o (fxsub1 x))))]
[o (lambda (x) (if (fxzero? x) #f (app e (fxsub1 x))))])
(app e 5000000)) => "#t\n"]
)

View File

@ -0,0 +1,229 @@
(add-tests-with-string-output "begin/implicit-begin"
[(begin 12) => "12\n"]
[(begin 13 122) => "122\n"]
[(begin 123 2343 #t) => "#t\n"]
[(let ([t (begin 12 (cons 1 2))]) (begin t t)) => "(1 . 2)\n"]
[(let ([t (begin 13 (cons 1 2))])
(cons 1 t)
t) => "(1 . 2)\n"]
[(let ([t (cons 1 2)])
(if (pair? t)
(begin t)
12)) => "(1 . 2)\n"]
)
(add-tests-with-string-output "set-car! set-cdr!"
[(let ([x (cons 1 2)])
(begin (set-cdr! x ())
x)) => "(1)\n"]
[(let ([x (cons 1 2)])
(set-cdr! x ())
x) => "(1)\n"]
[(let ([x (cons 12 13)] [y (cons 14 15)])
(set-cdr! x y)
x) => "(12 14 . 15)\n"]
[(let ([x (cons 12 13)] [y (cons 14 15)])
(set-cdr! y x)
y) => "(14 12 . 13)\n"]
[(let ([x (cons 12 13)] [y (cons 14 15)])
(set-cdr! y x)
x) => "(12 . 13)\n"]
[(let ([x (cons 12 13)] [y (cons 14 15)])
(set-cdr! x y)
y) => "(14 . 15)\n"]
[(let ([x (let ([x (cons 1 2)]) (set-car! x #t) (set-cdr! x #f) x)])
(cons x x)
x) => "(#t . #f)\n"]
[(let ([x (cons 1 2)])
(set-cdr! x x)
(set-car! (cdr x) x)
(cons (eq? x (car x)) (eq? x (cdr x)))) => "(#t . #t)\n"]
[(let ([x #f])
(if (pair? x)
(set-car! x 12)
#f)
x) => "#f\n"]
;;; [(let ([x #f])
;;; (if (pair? #f)
;;; (set-car! #f 12)
;;; #f)
;;; x) => "#f\n"]
)
(add-tests-with-string-output "vectors"
[(vector? (make-vector 0)) => "#t\n"]
[(vector-length (make-vector 12)) => "12\n"]
[(vector? (cons 1 2)) => "#f\n"]
[(vector? 1287) => "#f\n"]
[(vector? ()) => "#f\n"]
[(vector? #t) => "#f\n"]
[(vector? #f) => "#f\n"]
[(pair? (make-vector 12)) => "#f\n"]
[(null? (make-vector 12)) => "#f\n"]
[(boolean? (make-vector 12)) => "#f\n"]
[(make-vector 0) => "#()\n"]
[(let ([v (make-vector 2)])
(vector-set! v 0 #t)
(vector-set! v 1 #f)
v) => "#(#t #f)\n"]
[(let ([v (make-vector 2)])
(vector-set! v 0 v)
(vector-set! v 1 v)
(eq? (vector-ref v 0) (vector-ref v 1))) => "#t\n"]
[(let ([v (make-vector 1)] [y (cons 1 2)])
(vector-set! v 0 y)
(cons y (eq? y (vector-ref v 0)))) => "((1 . 2) . #t)\n"]
[(let ([v0 (make-vector 2)])
(let ([v1 (make-vector 2)])
(vector-set! v0 0 100)
(vector-set! v0 1 200)
(vector-set! v1 0 300)
(vector-set! v1 1 400)
(cons v0 v1))) => "(#(100 200) . #(300 400))\n"]
[(let ([v0 (make-vector 3)])
(let ([v1 (make-vector 3)])
(vector-set! v0 0 100)
(vector-set! v0 1 200)
(vector-set! v0 2 150)
(vector-set! v1 0 300)
(vector-set! v1 1 400)
(vector-set! v1 2 350)
(cons v0 v1))) => "(#(100 200 150) . #(300 400 350))\n"]
[(let ([n 2])
(let ([v0 (make-vector n)])
(let ([v1 (make-vector n)])
(vector-set! v0 0 100)
(vector-set! v0 1 200)
(vector-set! v1 0 300)
(vector-set! v1 1 400)
(cons v0 v1)))) => "(#(100 200) . #(300 400))\n"]
[(let ([n 3])
(let ([v0 (make-vector n)])
(let ([v1 (make-vector (vector-length v0))])
(vector-set! v0 (fx- (vector-length v0) 3) 100)
(vector-set! v0 (fx- (vector-length v1) 2) 200)
(vector-set! v0 (fx- (vector-length v0) 1) 150)
(vector-set! v1 (fx- (vector-length v1) 3) 300)
(vector-set! v1 (fx- (vector-length v0) 2) 400)
(vector-set! v1 (fx- (vector-length v1) 1) 350)
(cons v0 v1)))) => "(#(100 200 150) . #(300 400 350))\n"]
[(let ([n 1])
(vector-set! (make-vector n) (fxsub1 n) (fx* n n))
n) => "1\n"]
[(let ([n 1])
(let ([v (make-vector 1)])
(vector-set! v (fxsub1 n) n)
(vector-ref v (fxsub1 n)))) => "1\n"]
[(let ([v0 (make-vector 1)])
(vector-set! v0 0 1)
(let ([v1 (make-vector 1)])
(vector-set! v1 0 13)
(vector-set! (if (vector? v0) v0 v1)
(fxsub1 (vector-length (if (vector? v0) v0 v1)))
(fxadd1 (vector-ref
(if (vector? v0) v0 v1)
(fxsub1 (vector-length (if (vector? v0) v0 v1))))))
(cons v0 v1))) => "(#(2) . #(13))\n"]
)
(add-tests-with-string-output "strings"
[(string? (make-string 0)) => "#t\n"]
[(make-string 0) => "\"\"\n"]
[(let ([s (make-string 1)])
(string-set! s 0 #\a)
(string-ref s 0)) => "#\\a\n"]
[(let ([s (make-string 2)])
(string-set! s 0 #\a)
(string-set! s 1 #\b)
(cons (string-ref s 0) (string-ref s 1))) => "(#\\a . #\\b)\n"]
[(let ([i 0])
(let ([s (make-string 1)])
(string-set! s i #\a)
(string-ref s i))) => "#\\a\n"]
[(let ([i 0] [j 1])
(let ([s (make-string 2)])
(string-set! s i #\a)
(string-set! s j #\b)
(cons (string-ref s i) (string-ref s j)))) => "(#\\a . #\\b)\n"]
[(let ([i 0] [c #\a])
(let ([s (make-string 1)])
(string-set! s i c)
(string-ref s i))) => "#\\a\n"]
[(string-length (make-string 12)) => "12\n"]
[(string? (make-vector 12)) => "#f\n"]
[(string? (cons 1 2)) => "#f\n"]
[(string? 1287) => "#f\n"]
[(string? ()) => "#f\n"]
[(string? #t) => "#f\n"]
[(string? #f) => "#f\n"]
[(pair? (make-string 12)) => "#f\n"]
[(null? (make-string 12)) => "#f\n"]
[(boolean? (make-string 12)) => "#f\n"]
[(vector? (make-string 12)) => "#f\n"]
[(make-string 0) => "\"\"\n"]
[(let ([v (make-string 2)])
(string-set! v 0 #\t)
(string-set! v 1 #\f)
v) => "\"tf\"\n"]
[(let ([v (make-string 2)])
(string-set! v 0 #\x)
(string-set! v 1 #\x)
(char= (string-ref v 0) (string-ref v 1))) => "#t\n"]
[(let ([v0 (make-string 3)])
(let ([v1 (make-string 3)])
(string-set! v0 0 #\a)
(string-set! v0 1 #\b)
(string-set! v0 2 #\c)
(string-set! v1 0 #\d)
(string-set! v1 1 #\e)
(string-set! v1 2 #\f)
(cons v0 v1))) => "(\"abc\" . \"def\")\n"]
[(let ([n 2])
(let ([v0 (make-string n)])
(let ([v1 (make-string n)])
(string-set! v0 0 #\a)
(string-set! v0 1 #\b)
(string-set! v1 0 #\c)
(string-set! v1 1 #\d)
(cons v0 v1)))) => "(\"ab\" . \"cd\")\n"]
[(let ([n 3])
(let ([v0 (make-string n)])
(let ([v1 (make-string (string-length v0))])
(string-set! v0 (fx- (string-length v0) 3) #\a)
(string-set! v0 (fx- (string-length v1) 2) #\b)
(string-set! v0 (fx- (string-length v0) 1) #\c)
(string-set! v1 (fx- (string-length v1) 3) #\Z)
(string-set! v1 (fx- (string-length v0) 2) #\Y)
(string-set! v1 (fx- (string-length v1) 1) #\X)
(cons v0 v1)))) => "(\"abc\" . \"ZYX\")\n"]
[(let ([n 1])
(string-set! (make-string n) (fxsub1 n) (fixnum->char 34))
n) => "1\n"]
[(let ([n 1])
(let ([v (make-string 1)])
(string-set! v (fxsub1 n) (fixnum->char n))
(char->fixnum (string-ref v (fxsub1 n))))) => "1\n"]
[(let ([v0 (make-string 1)])
(string-set! v0 0 #\a)
(let ([v1 (make-string 1)])
(string-set! v1 0 #\A)
(string-set! (if (string? v0) v0 v1)
(fxsub1 (string-length (if (string? v0) v0 v1)))
(fixnum->char
(fxadd1
(char->fixnum
(string-ref
(if (string? v0) v0 v1)
(fxsub1 (string-length (if (string? v0) v0 v1))))))))
(cons v0 v1))) => "(\"b\" . \"A\")\n"]
[(let ([s (make-string 1)])
(string-set! s 0 #\")
s) => "\"\\\"\"\n"]
[(let ([s (make-string 1)])
(string-set! s 0 #\\)
s) => "\"\\\\\"\n"]
)

View File

@ -0,0 +1,144 @@
;;; one possible implementation strategy for procedures is via closure
;;; conversion.
;;; Lambda does many things at the same time:
;;; 1) It creates a procedure object (ie. one that passes procedure?)
;;; 2) It contains both code (what to do when applied) and data (what
;;; variables it references.
;;; 3) The procedure object, in addition to passing procedure?, can be
;;; applied to arguments.
;;; First step: separate code from data:
;;; convert every program containing lambda to a program containing
;;; codes and closures:
;;; (let ([f (lambda () 12)]) (procedure? f))
;;; =>
;;; (codes ([f-code (code () () 12)])
;;; (let ([f (closure f-code)])
;;; (procedure? f)))
;;;
;;; The codes binds code names to code points. Every code
;;; is of the form (code (formals ...) (free-vars ...) body)
;;;
;;; sexpr
;;; => recordize
;;; recognize lambda forms and applications
;;; =>
;;; (let ([y 12])
;;; (let ([f (lambda (x) (fx+ y x))])
;;; (fx+ (f 10) (f 0))))
;;; => convert closures
;;; (let ([y 12])
;;; (let ([f (closure (code (x) (y) (fx+ x y)) y)])
;;; (fx+ (call f 10) (call f 0))
;;; => lift codes
;;; (codes ([code0 (code (x) (y) (fx+ x y))])
;;; (let ([y 12])
;;; (let ([f (closure code0 y)])
;;; (fx+ (call f 10) (call f 0)))))
;;; => code generation
;;; 1) codes form generates unique-labels for every code and
;;; binds the names of the code to these labels.
;;; 2) Every code object has a list of formals and a list of free vars.
;;; The formals are at stack locations -4(%esp), -8(%esp), -12(%esp), ...
;;; The free vars are at -2(%edi), 2(%edi), 6(%edi), 10(%edi) ...
;;; These are inserted in the environment and then the body of the code
;;; is generated.
;;; 3) A (closure code-name free-vars ...) is generated the same way a
;;; (vector val* ...) is generated: First, the code-label and the free
;;; variables are placed at 0(%ebp), 4(%ebp), 8(%ebp), etc..
;;; A closure pointer is placed in %eax, and %ebp is incremented to the
;;; next boundary.
;;; 4) A (call f arg* ...) does the following:
;;; a) evaluates the args and places them at contiguous stack locations
;;; si-8(%esp), si-12(%esp), ... (leaving room for two values).
;;; b) The value of the current closure pointer, %edi, is saved on the
;;; stack at si(%esp).
;;; c) The closure pointer of the callee is loaded in %edi.
;;; d) The value of %esp is adjusted by si
;;; e) An indirect call to -6(%edi) is issued.
;;; f) After return, the value of %esp is adjusted back by -si
;;; g) The value of the closure pointer is restored.
;;; The returned value is still in %eax.
(add-tests-with-string-output "procedure?"
[(procedure? (lambda (x) x)) => "#t\n"]
[(let ([f (lambda (x) x)]) (procedure? f)) => "#t\n"]
[(procedure? (make-vector 0)) => "#f\n"]
[(procedure? (make-string 0)) => "#f\n"]
[(procedure? (cons 1 2)) => "#f\n"]
[(procedure? #\S) => "#f\n"]
[(procedure? ()) => "#f\n"]
[(procedure? #t) => "#f\n"]
[(procedure? #f) => "#f\n"]
[(string? (lambda (x) x)) => "#f\n"]
[(vector? (lambda (x) x)) => "#f\n"]
[(boolean? (lambda (x) x)) => "#f\n"]
[(null? (lambda (x) x)) => "#f\n"]
[(not (lambda (x) x)) => "#f\n"]
)
(add-tests-with-string-output "applying thunks"
[(let ([f (lambda () 12)]) (f)) => "12\n"]
[(let ([f (lambda () (fx+ 12 13))]) (f)) => "25\n"]
[(let ([f (lambda () 13)]) (fx+ (f) (f))) => "26\n"]
[(let ([f (lambda ()
(let ([g (lambda () (fx+ 2 3))])
(fx* (g) (g))))])
(fx+ (f) (f))) => "50\n"]
[(let ([f (lambda ()
(let ([f (lambda () (fx+ 2 3))])
(fx* (f) (f))))])
(fx+ (f) (f))) => "50\n"]
[(let ([f (if (boolean? (lambda () 12))
(lambda () 13)
(lambda () 14))])
(f)) => "14\n"]
)
(add-tests-with-string-output "parameter passing"
[(let ([f (lambda (x) x)]) (f 12)) => "12\n"]
[(let ([f (lambda (x y) (fx+ x y))]) (f 12 13)) => "25\n"]
[(let ([f (lambda (x)
(let ([g (lambda (x y) (fx+ x y))])
(g x 100)))])
(f 1000)) => "1100\n"]
[(let ([f (lambda (g) (g 2 13))])
(f (lambda (n m) (fx* n m)))) => "26\n"]
[(let ([f (lambda (g) (fx+ (g 10) (g 100)))])
(f (lambda (x) (fx* x x)))) => "10100\n"]
[(let ([f (lambda (f n m)
(if (fxzero? n)
m
(f f (fxsub1 n) (fx* n m))))])
(f f 5 1)) => "120\n"]
[(let ([f (lambda (f n)
(if (fxzero? n)
1
(fx* n (f f (fxsub1 n)))))])
(f f 5)) => "120\n"]
)
(add-tests-with-string-output "closures"
[(let ([n 12])
(let ([f (lambda () n)])
(f))) => "12\n"]
[(let ([n 12])
(let ([f (lambda (m) (fx+ n m))])
(f 100))) => "112\n"]
[(let ([f (lambda (f n m)
(if (fxzero? n)
m
(f (fxsub1 n) (fx* n m))))])
(let ([g (lambda (g n m) (f (lambda (n m) (g g n m)) n m))])
(g g 5 1))) => "120\n"]
[(let ([f (lambda (f n)
(if (fxzero? n)
1
(fx* n (f (fxsub1 n)))))])
(let ([g (lambda (g n) (f (lambda (n) (g g n)) n))])
(g g 5))) => "120\n"]
)

View File

@ -0,0 +1,68 @@
(add-tests-with-string-output "set!"
[(let ([x 12])
(set! x 13)
x) => "13\n"]
[(let ([x 12])
(set! x (fxadd1 x))
x) => "13\n"]
[(let ([x 12])
(let ([x #f]) (set! x 14))
x) => "12\n"]
[(let ([x 12])
(let ([y (let ([x #f]) (set! x 14))])
x)) => "12\n"]
[(let ([f #f])
(let ([g (lambda () f)])
(set! f 10)
(g))) => "10\n"]
[(let ([f (lambda (x)
(set! x (fxadd1 x))
x)])
(f 12)) => "13\n"]
[(let ([x 10])
(let ([f (lambda (x)
(set! x (fxadd1 x))
x)])
(cons x (f x)))) => "(10 . 11)\n"]
[(let ([t #f])
(let ([locative
(cons
(lambda () t)
(lambda (n) (set! t n)))])
((cdr locative) 17)
((car locative)))) => "17\n"]
[(let ([locative
(let ([t #f])
(cons
(lambda () t)
(lambda (n) (set! t n))))])
((cdr locative) 17)
((car locative))) => "17\n"]
[(let ([make-counter
(lambda ()
(let ([counter -1])
(lambda ()
(set! counter (fxadd1 counter))
counter)))])
(let ([c0 (make-counter)]
[c1 (make-counter)])
(c0)
(cons (c0) (c1)))) => "(1 . 0)\n"]
[(let ([fact #f])
(set! fact (lambda (n)
(if (fxzero? n)
1
(fx* n (fact (fxsub1 n))))))
(fact 5)) => "120\n"]
[(let ([fact #f])
((begin
(set! fact (lambda (n)
(if (fxzero? n)
1
(fx* n (fact (fxsub1 n))))))
fact)
5)) => "120\n"]
)

View File

@ -0,0 +1,19 @@
(add-tests-with-string-output "complex constants"
['42 => "42\n"]
['(1 . 2) => "(1 . 2)\n"]
['(1 2 3) => "(1 2 3)\n"]
[(let ([x '(1 2 3)]) x) => "(1 2 3)\n"]
[(let ([f (lambda () '(1 2 3))])
(f)) => "(1 2 3)\n"]
[(let ([f (lambda () '(1 2 3))])
(eq? (f) (f))) => "#t\n"]
[(let ([f (lambda ()
(lambda ()
'(1 2 3)))])
((f))) => "(1 2 3)\n"]
[(let ([x '#(1 2 3)])
(cons x (vector-ref x 0))) => "(#(1 2 3) . 1)\n"]
["Hello World" => "\"Hello World\"\n"]
['("Hello" "World") => "(\"Hello\" \"World\")\n"]
)

View File

@ -0,0 +1,174 @@
(add-tests-with-string-output "letrec"
[(letrec () 12) => "12\n"]
[(letrec ([f 12]) f) => "12\n"]
[(letrec ([f 12] [g 13]) (fx+ f g)) => "25\n"]
[(letrec ([fact
(lambda (n)
(if (fxzero? n)
1
(fx* n (fact (fxsub1 n)))))])
(fact 5)) => "120\n"]
[(letrec ([f 12] [g (lambda () f)])
(g)) => "12\n"]
[(letrec ([f 12] [g (lambda (n) (set! f n))])
(g 130)
f) => "130\n"]
[(letrec ([f (lambda (g) (set! f g) (f))])
(f (lambda () 12))) => "12\n"]
[(letrec ([f (cons (lambda () f)
(lambda (x) (set! f x)))])
(let ([g (car f)])
((cdr f) 100)
(g))) => "100\n"]
[(letrec ([f (letrec ([g (lambda (x) (fx* x 2))])
(lambda (n) (g (fx* n 2))))])
(f 12)) => "48\n"]
[(letrec ([f (lambda (f n)
(if (fxzero? n)
1
(fx* n (f f (fxsub1 n)))))])
(f f 5)) => "120\n"]
[(let ([f (lambda (f)
(lambda (n)
(if (fxzero? n)
1
(fx* n (f (fxsub1 n))))))])
(letrec ([fix
(lambda (f)
(f (lambda (n) ((fix f) n))))])
((fix f) 5))) => "120\n"]
)
(add-tests-with-string-output "letrec*"
[(letrec* () 12) => "12\n"]
[(letrec* ([f 12]) f) => "12\n"]
[(letrec* ([f 12] [g 13]) (fx+ f g)) => "25\n"]
[(letrec* ([fact
(lambda (n)
(if (fxzero? n)
1
(fx* n (fact (fxsub1 n)))))])
(fact 5)) => "120\n"]
[(letrec* ([f 12] [g (lambda () f)])
(g)) => "12\n"]
[(letrec* ([f 12] [g (lambda (n) (set! f n))])
(g 130)
f) => "130\n"]
[(letrec* ([f (lambda (g) (set! f g) (f))])
(f (lambda () 12))) => "12\n"]
[(letrec* ([f (cons (lambda () f)
(lambda (x) (set! f x)))])
(let ([g (car f)])
((cdr f) 100)
(g))) => "100\n"]
[(letrec* ([f (letrec* ([g (lambda (x) (fx* x 2))])
(lambda (n) (g (fx* n 2))))])
(f 12)) => "48\n"]
[(letrec* ([f (lambda (f n)
(if (fxzero? n)
1
(fx* n (f f (fxsub1 n)))))])
(f f 5)) => "120\n"]
[(let ([f (lambda (f)
(lambda (n)
(if (fxzero? n)
1
(fx* n (f (fxsub1 n))))))])
(letrec* ([fix
(lambda (f)
(f (lambda (n) ((fix f) n))))])
((fix f) 5))) => "120\n"]
[(letrec* ([a 12] [b (fx+ a 5)] [c (fx+ b a)])
c) => "29\n"]
)
(add-tests-with-string-output "and/or"
[(and) => "#t\n"]
[(and 5) => "5\n"]
[(and #f) => "#f\n"]
[(and 5 6) => "6\n"]
[(and #f ((lambda (x) (x x)) (lambda (x) (x x)))) => "#f\n"]
[(or) => "#f\n"]
[(or #t) => "#t\n"]
[(or 5) => "5\n"]
[(or 1 2 3) => "1\n"]
[(or (cons 1 2) ((lambda (x) (x x)) (lambda (x) (x x)))) => "(1 . 2)\n"]
[(let ([if 12]) (or if 17)) => "12\n"]
[(let ([if 12]) (and if 17)) => "17\n"]
[(let ([let 8]) (or let 18)) => "8\n"]
[(let ([let 8]) (and let 18)) => "18\n"]
[(let ([t 1])
(and (begin (set! t (fxadd1 t)) t) t)) => "2\n"]
[(let ([t 1])
(or (begin (set! t (fxadd1 t)) t) t)) => "2\n"]
)
(add-tests-with-string-output "when/unless"
[(let ([x (cons 1 2)])
(when (pair? x)
(set-car! x (fx+ (car x) (cdr x))))
x) => "(3 . 2)\n"]
[(let ([x (cons 1 2)])
(when (pair? x)
(set-car! x (fx+ (car x) (cdr x)))
(set-car! x (fx+ (car x) (cdr x))))
x) => "(5 . 2)\n"]
[(let ([x (cons 1 2)])
(unless (fixnum? x)
(set-car! x (fx+ (car x) (cdr x))))
x) => "(3 . 2)\n"]
[(let ([x (cons 1 2)])
(unless (fixnum? x)
(set-car! x (fx+ (car x) (cdr x)))
(set-car! x (fx+ (car x) (cdr x))))
x) => "(5 . 2)\n"]
[(let ([let 12])
(when let let let let let)) => "12\n"]
[(let ([let #f])
(unless let let let let let)) => "#f\n"]
)
(add-tests-with-string-output "cond"
[(cond [1 2] [else 3]) => "2\n"]
[(cond [1] [else 13]) => "1\n"]
[(cond [#f #t] [#t #f]) => "#f\n"]
[(cond [else 17]) => "17\n"]
[(cond [#f] [#f 12] [12 13]) => "13\n"]
[(cond [(cons 1 2) => (lambda (x) (cdr x))]) => "2\n"]
[(let ([else #t])
(cond
[else 1287])) => "1287\n"]
[(let ([else 17])
(cond
[else])) => "17\n"]
[(let ([else 17])
(cond
[else => (lambda (x) x)])) => "17\n"]
[(let ([else #f])
(cond
[else ((lambda (x) (x x)) (lambda (x) (x x)))])
else) => "#f\n"]
[(let ([=> 12])
(cond
[12 => 14]
[else 17])) => "14\n"]
[(let ([=> 12])
(cond
[=>])) => "12\n"]
[(let ([=> 12])
(cond
[=> =>])) => "12\n"]
[(let ([=> 12])
(cond
[=> => =>])) => "12\n"]
[(let ([let 12])
(cond
[let => (lambda (x) (fx+ let x))]
[else 14])) => "24\n"]
)

77