aboutsummaryrefslogtreecommitdiff
path: root/tests/tailcall.test
diff options
context:
space:
mode:
authorSteve Bennett <steveb@workware.net.au>2010-03-03 16:02:25 +1000
committerSteve Bennett <steveb@workware.net.au>2010-10-15 11:02:49 +1000
commit8a21e1c0ea44a829f84e526a8302e6effbc4a9b1 (patch)
tree84f7fe867f2a3adce1a936a5f1e7cdcb724f4cfd /tests/tailcall.test
parentb83beb2febcbe0abcf338e3f915b43889ce93eca (diff)
downloadjimtcl-8a21e1c0ea44a829f84e526a8302e6effbc4a9b1.zip
jimtcl-8a21e1c0ea44a829f84e526a8302e6effbc4a9b1.tar.gz
jimtcl-8a21e1c0ea44a829f84e526a8302e6effbc4a9b1.tar.bz2
Improvements to tailcall
Add tests and documentation Make tailcall work within 'try' Fix tailcall interaction with uplevel Use tailcall for dispatch in tree.tcl Also some related improvements in tree.tcl Signed-off-by: Steve Bennett <steveb@workware.net.au>
Diffstat (limited to 'tests/tailcall.test')
-rw-r--r--tests/tailcall.test50
1 files changed, 50 insertions, 0 deletions
diff --git a/tests/tailcall.test b/tests/tailcall.test
new file mode 100644
index 0000000..eb097e5
--- /dev/null
+++ b/tests/tailcall.test
@@ -0,0 +1,50 @@
+source testing.tcl
+
+test tailcall-1.1 {Basic tailcall} {
+ # Demo -- a tail-recursive factorial function
+ proc fac {x {val 1}} {
+ if {$x <= 2} {
+ expr {$x * $val}
+ } else {
+ tailcall fac [expr {$x -1}] [expr {$x * $val}]
+ }
+ }
+ fac 10
+} {3628800}
+
+test tailcall-1.2 {Tailcall in try} {
+ set x 0
+ proc a {} { upvar x x; incr x }
+ proc b {} { upvar x x; incr x 4; try { tailcall a } finally { incr x 8 }}
+ b
+ set x
+} {13}
+
+test tailcall-1.3 {Tailcall does return} {
+ set x 0
+ proc a {} { upvar x x; incr x }
+ proc b {} { upvar x x; incr x 4; tailcall a; incr x 8}
+ b
+ set x
+} {5}
+
+test tailcall-1.4 {uplevel tailcall} {
+ proc a {} { set ::y [info level] }
+ proc b {} { set ::x [info level]; uplevel 1 tailcall a}
+ b
+ list $x $y
+} {1 1}
+
+test tailcall-1.5 {interaction of uplevel and tailcall} {
+ proc a {cmd} {
+ tailcall $cmd
+ }
+ proc b {} {
+ lappend result [uplevel 1 a c]
+ lappend result [uplevel 1 a c]
+ }
+ proc c {} {
+ return c
+ }
+ a b
+} {c c}