summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandreask <andreask>2011-03-11 19:14:13 (GMT)
committerandreask <andreask>2011-03-11 19:14:13 (GMT)
commitc7b1beaccd8ce8847fae6ff8550096b5387e275e (patch)
tree62827ffcbe8306183c2073e3a46314703c102813
parentdfbbb244c413f5f5c5cfabd42a2ee91a03265a71 (diff)
downloadtcl-activestate_nre_excised_variant_2_subtracted.zip
tcl-activestate_nre_excised_variant_2_subtracted.tar.gz
tcl-activestate_nre_excised_variant_2_subtracted.tar.bz2
The re-creation of this branch should have deleted a few NRE specific testsuites, and did not. Fixed.activestate_nre_excised_variant_2_subtracted
-rw-r--r--tests/coroutine.test576
-rw-r--r--tests/nre.test441
-rw-r--r--tests/tailcall.test665
3 files changed, 0 insertions, 1682 deletions
diff --git a/tests/coroutine.test b/tests/coroutine.test
deleted file mode 100644
index d7b30bc..0000000
--- a/tests/coroutine.test
+++ /dev/null
@@ -1,576 +0,0 @@
-# Commands covered: coroutine, yield, [info coroutine]
-#
-# This file contains a collection of tests for experimental commands that are
-# found in ::tcl::unsupported. The tests will migrate to normal test files
-# if/when the commands find their way into the core.
-#
-# Copyright (c) 2008 by Miguel Sofer.
-#
-# See the file "license.terms" for information on usage and redistribution
-# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-#
-# RCS: @(#) $Id: coroutine.test,v 1.14 2010/08/11 23:38:57 msofer Exp $
-
-if {[lsearch [namespace children] ::tcltest] == -1} {
- package require tcltest
- namespace import -force ::tcltest::*
-}
-
-testConstraint testnrelevels [llength [info commands testnrelevels]]
-testConstraint memory [llength [info commands memory]]
-
-set lambda [list {{start 0} {stop 10}} {
- # init
- set i $start
- set imax $stop
- yield
- while {$i < $imax} {
- yield [expr {$i*$stop}]
- incr i
- }
-}]
-
-test coroutine-1.1 {coroutine basic} -setup {
- coroutine foo ::apply $lambda
- set res {}
-} -body {
- for {set k 1} {$k < 4} {incr k} {
- lappend res [foo]
- }
- set res
-} -cleanup {
- rename foo {}
- unset res
-} -result {0 10 20}
-test coroutine-1.2 {coroutine basic} -setup {
- coroutine foo ::apply $lambda 2 8
- set res {}
-} -body {
- for {set k 1} {$k < 4} {incr k} {
- lappend res [foo]
- }
- set res
-} -cleanup {
- rename foo {}
- unset res
-} -result {16 24 32}
-test coroutine-1.3 {yield returns new arg} -setup {
- set body {
- # init
- set i $start
- set imax $stop
- yield
- while {$i < $imax} {
- set stop [yield [expr {$i*$stop}]]
- incr i
- }
- }
- coroutine foo ::apply [list {{start 2} {stop 10}} $body]
- set res {}
-} -body {
- for {set k 1} {$k < 4} {incr k} {
- lappend res [foo $k]
- }
- set res
-} -cleanup {
- rename foo {}
- unset res
-} -result {20 6 12}
-test coroutine-1.4 {yield in nested proc} -setup {
- proc moo {} {
- upvar 1 i i stop stop
- yield [expr {$i*$stop}]
- }
- set body {
- # init
- set i $start
- set imax $stop
- yield
- while {$i < $imax} {
- moo
- incr i
- }
- }
- coroutine foo ::apply [list {{start 0} {stop 10}} $body]
- set res {}
-} -body {
- for {set k 1} {$k < 4} {incr k} {
- lappend res [foo $k]
- }
- set res
-} -cleanup {
- rename foo {}
- rename moo {}
- unset body res
-} -result {0 10 20}
-test coroutine-1.5 {just yield} -body {
- coroutine foo yield
- list [foo] [catch foo msg] $msg
-} -cleanup {
- unset msg
-} -result {{} 1 {invalid command name "foo"}}
-test coroutine-1.6 {just yield} -body {
- coroutine foo [list yield]
- list [foo] [catch foo msg] $msg
-} -cleanup {
- unset msg
-} -result {{} 1 {invalid command name "foo"}}
-test coroutine-1.7 {yield in nested uplevel} -setup {
- set body {
- # init
- set i $start
- set imax $stop
- yield
- while {$i < $imax} {
- uplevel 0 [list yield [expr {$i*$stop}]]
- incr i
- }
- }
- coroutine foo ::apply [list {{start 0} {stop 10}} $body]
- set res {}
-} -body {
- for {set k 1} {$k < 4} {incr k} {
- lappend res [eval foo $k]
- }
- set res
-} -cleanup {
- rename foo {}
- unset body res
-} -result {0 10 20}
-test coroutine-1.8 {yield in nested uplevel} -setup {
- set body {
- # init
- set i $start
- set imax $stop
- yield
- while {$i < $imax} {
- uplevel 0 yield [expr {$i*$stop}]
- incr i
- }
- }
- coroutine foo ::apply [list {{start 0} {stop 10}} $body]
- set res {}
-} -body {
- for {set k 1} {$k < 4} {incr k} {
- lappend res [eval foo $k]
- }
- set res
-} -cleanup {
- rename foo {}
- unset body res
-} -result {0 10 20}
-test coroutine-1.9 {yield in nested eval} -setup {
- proc moo {} {
- upvar 1 i i stop stop
- yield [expr {$i*$stop}]
- }
- set body {
- # init
- set i $start
- set imax $stop
- yield
- while {$i < $imax} {
- eval moo
- incr i
- }
- }
- coroutine foo ::apply [list {{start 0} {stop 10}} $body]
- set res {}
-} -body {
- for {set k 1} {$k < 4} {incr k} {
- lappend res [foo $k]
- }
- set res
-} -cleanup {
- rename moo {}
- unset body res
-} -result {0 10 20}
-test coroutine-1.10 {yield in nested eval} -setup {
- set body {
- # init
- set i $start
- set imax $stop
- yield
- while {$i < $imax} {
- eval yield [expr {$i*$stop}]
- incr i
- }
- }
- coroutine foo ::apply [list {{start 0} {stop 10}} $body]
- set res {}
-} -body {
- for {set k 1} {$k < 4} {incr k} {
- lappend res [eval foo $k]
- }
- set res
-} -cleanup {
- unset body res
-} -result {0 10 20}
-test coroutine-1.11 {yield outside coroutine} -setup {
- proc moo {} {
- upvar 1 i i stop stop
- yield [expr {$i*$stop}]
- }
-} -body {
- variable i 5 stop 6
- moo
-} -cleanup {
- rename moo {}
- unset i stop
-} -returnCodes error -result {yield can only be called in a coroutine}
-test coroutine-1.12 {proc as coroutine} -setup {
- set body {
- # init
- set i $start
- set imax $stop
- yield
- while {$i < $imax} {
- uplevel 0 [list yield [expr {$i*$stop}]]
- incr i
- }
- }
- proc moo {{start 0} {stop 10}} $body
- coroutine foo moo 2 8
-} -body {
- list [foo] [foo]
-} -cleanup {
- unset body
- rename moo {}
- rename foo {}
-} -result {16 24}
-test coroutine-1.13 {subst as coroutine: literal} {
- list [coroutine foo eval {subst {>>[yield a],[yield b]<<}}] [foo x] [foo y]
-} {a b >>x,y<<}
-test coroutine-1.14 {subst as coroutine: in variable} {
- set pattern {>>[yield c],[yield d]<<}
- list [coroutine foo eval {subst $pattern}] [foo p] [foo q]
-} {c d >>p,q<<}
-
-test coroutine-2.1 {self deletion on return} -body {
- coroutine foo set x 3
- foo
-} -returnCodes error -result {invalid command name "foo"}
-test coroutine-2.2 {self deletion on return} -body {
- coroutine foo ::apply [list {} {yield; yield 1; return 2}]
- list [foo] [foo] [catch foo msg] $msg
-} -result {1 2 1 {invalid command name "foo"}}
-test coroutine-2.3 {self deletion on error return} -body {
- coroutine foo ::apply [list {} {yield;yield 1; error ouch!}]
- list [foo] [catch foo msg] $msg [catch foo msg] $msg
-} -result {1 1 ouch! 1 {invalid command name "foo"}}
-test coroutine-2.4 {self deletion on other return} -body {
- coroutine foo ::apply [list {} {yield;yield 1; return -code 100 ouch!}]
- list [foo] [catch foo msg] $msg [catch foo msg] $msg
-} -result {1 100 ouch! 1 {invalid command name "foo"}}
-test coroutine-2.5 {deletion of suspended coroutine} -body {
- coroutine foo ::apply [list {} {yield; yield 1; return 2}]
- list [foo] [rename foo {}] [catch foo msg] $msg
-} -result {1 {} 1 {invalid command name "foo"}}
-test coroutine-2.6 {deletion of running coroutine} -body {
- coroutine foo ::apply [list {} {yield; rename foo {}; yield 1; return 2}]
- list [foo] [catch foo msg] $msg
-} -result {1 1 {invalid command name "foo"}}
-
-test coroutine-3.1 {info level computation} -setup {
- proc a {} {while 1 {yield [info level]}}
- proc b {} foo
-} -body {
- # note that coroutines execute in uplevel #0
- set l0 [coroutine foo a]
- set l1 [foo]
- set l2 [b]
- list $l0 $l1 $l2
-} -cleanup {
- rename a {}
- rename b {}
-} -result {1 1 1}
-test coroutine-3.2 {info frame computation} -setup {
- proc a {} {while 1 {yield [info frame]}}
- proc b {} foo
-} -body {
- set l0 [coroutine foo a]
- set l1 [foo]
- set l2 [b]
- expr {$l2 - $l1}
-} -cleanup {
- rename a {}
- rename b {}
-} -result 1
-test coroutine-3.3 {info coroutine} -setup {
- proc a {} {info coroutine}
- proc b {} a
-} -body {
- b
-} -cleanup {
- rename a {}
- rename b {}
-} -result {}
-test coroutine-3.4 {info coroutine} -setup {
- proc a {} {info coroutine}
- proc b {} a
-} -body {
- coroutine foo b
-} -cleanup {
- rename a {}
- rename b {}
-} -result ::foo
-test coroutine-3.5 {info coroutine} -setup {
- proc a {} {info coroutine}
- proc b {} {rename [info coroutine] {}; a}
-} -body {
- coroutine foo b
-} -cleanup {
- rename a {}
- rename b {}
-} -result {}
-test coroutine-3.6 {info frame, bug #2910094} -setup {
- proc stack {} {
- set res [list "LEVEL:[set lev [info frame]]"]
- for {set i 1} {$i < $lev} {incr i} {
- lappend res [info frame $i]
- }
- set res
- # the precise command depends on line numbers and such, is likely not
- # to be stable: just check that the test completes!
- return
- }
- proc a {} stack
-} -body {
- coroutine aa a
-} -cleanup {
- rename stack {}
- rename a {}
-} -result {}
-
-test coroutine-4.1 {bug #2093188} -setup {
- proc foo {} {
- set v 1
- trace add variable v {write unset} bar
- yield
- set v 2
- yield
- set v 3
- }
- proc bar args {lappend ::res $args}
- coroutine a foo
-} -body {
- list [a] [a] $::res
-} -cleanup {
- rename foo {}
- rename bar {}
- unset ::res
-} -result {{} 3 {{v {} write} {v {} write} {v {} unset}}}
-test coroutine-4.2 {bug #2093188} -setup {
- proc foo {} {
- set v 1
- trace add variable v {read unset} bar
- yield
- set v 2
- set v
- yield
- set v 3
- }
- proc bar args {lappend ::res $args}
- coroutine a foo
-} -body {
- list [a] [a] $::res
-} -cleanup {
- rename foo {}
- rename bar {}
- unset ::res
-} -result {{} 3 {{v {} read} {v {} unset}}}
-
-test coroutine-4.3 {bug #2093947} -setup {
- proc foo {} {
- set v 1
- trace add variable v {write unset} bar
- yield
- set v 2
- yield
- set v 3
- }
- proc bar args {lappend ::res $args}
-} -body {
- coroutine a foo
- a
- a
- coroutine a foo
- a
- rename a {}
- set ::res
-} -cleanup {
- rename foo {}
- rename bar {}
- unset ::res
-} -result {{v {} write} {v {} write} {v {} unset} {v {} write} {v {} unset}}
-
-test coroutine-4.4 {bug #2917627: cmd resolution} -setup {
- proc a {} {return global}
- namespace eval b {proc a {} {return local}}
-} -body {
- namespace eval b {coroutine foo a}
-} -cleanup {
- rename a {}
- namespace delete b
-} -result local
-
-test coroutine-4.5 {bug #2724403} -constraints {memory} \
--setup {
- proc getbytes {} {
- set lines [split [memory info] "\n"]
- lindex $lines 3 3
- }
-} -body {
- set end [getbytes]
- for {set i 0} {$i < 5} {incr i} {
- set ns ::y$i
- namespace eval $ns {}
- proc ${ns}::start {} {yield; puts hello}
- coroutine ${ns}::run ${ns}::start
- namespace delete $ns
- set start $end
- set end [getbytes]
- }
- set leakedBytes [expr {$end - $start}]
-} -cleanup {
- rename getbytes {}
- unset i ns start end
-} -result 0
-
-test coroutine-5.1 {right numLevels on coro return} -constraints {testnrelevels} \
--setup {
- proc nestedYield {{val {}}} {
- yield $val
- }
- proc getNumLevel {} {
- # remove the level for this proc's call
- expr {[lindex [testnrelevels] 1] - 1}
- }
- proc relativeLevel base {
- # remove the level for this proc's call
- expr {[getNumLevel] - $base - 1}
- }
- proc foo {} {
- while 1 {
- nestedYield
- }
- }
- set res {}
-} -body {
- set base [getNumLevel]
- lappend res [relativeLevel $base]
- eval {coroutine a foo}
- # back to base level
- lappend res [relativeLevel $base]
- a
- lappend res [relativeLevel $base]
- eval a
- lappend res [relativeLevel $base]
- eval {eval a}
- lappend res [relativeLevel $base]
- rename a {}
- lappend res [relativeLevel $base]
- set res
-} -cleanup {
- rename foo {}
- rename nestedYield {}
- rename getNumLevel {}
- rename relativeLevel {}
- unset res
-} -result {0 0 0 0 0 0}
-test coroutine-5.2 {right numLevels within coro} -constraints {testnrelevels} \
--setup {
- proc nestedYield {{val {}}} {
- yield $val
- }
- proc getNumLevel {} {
- # remove the level for this proc's call
- expr {[lindex [testnrelevels] 1] - 1}
- }
- proc relativeLevel base {
- # remove the level for this proc's call
- expr {[getNumLevel] - $base - 1}
- }
- proc foo base {
- while 1 {
- set base [nestedYield [relativeLevel $base]]
- }
- }
- set res {}
-} -body {
- lappend res [eval {coroutine a foo [getNumLevel]}]
- lappend res [a [getNumLevel]]
- lappend res [eval {a [getNumLevel]}]
- lappend res [eval {eval {a [getNumLevel]}}]
- set base [lindex $res 0]
- foreach x $res[set res {}] {
- lappend res [expr {$x-$base}]
- }
- set res
-} -cleanup {
- rename a {}
- rename foo {}
- rename nestedYield {}
- rename getNumLevel {}
- rename relativeLevel {}
- unset res
-} -result {0 0 0 0}
-
-test coroutine-6.1 {coroutine nargs} -body {
- coroutine a ::apply $lambda
- a
-} -cleanup {
- rename a {}
-} -result 0
-test coroutine-6.2 {coroutine nargs} -body {
- coroutine a ::apply $lambda
- a a
-} -cleanup {
- rename a {}
-} -result 0
-test coroutine-6.3 {coroutine nargs} -body {
- coroutine a ::apply $lambda
- a a a
-} -cleanup {
- rename a {}
-} -returnCodes error -result {wrong # args: should be "a ?arg?"}
-test coroutine-6.4 {unsupported: multi-argument yield} -body {
- proc corobody {} {
- set a 1
- while 1 {
- set a [yield $a]
- set a [::tcl::unsupported::yieldm $a]
- lappend a [llength $a]
- }
- }
- coroutine a corobody
- coroutine b corobody
- list [a x] [a y z] [a \{p] [a \{q r] [a] [a] [rename a {}] \
- [b ok] [rename b {}]
-} -cleanup {
- rename corobody {}
-} -result {x {y z 2} \{p {\{q r 2} {} 0 {} ok {}}
-
-test coroutine-7.1 {yieldTo} -body {
- coroutine c apply {{} {
- yield
- tcl::unsupported::yieldTo return -level 0 -code 1 quux
- return quuy
- }}
- set res [list [catch c msg] $msg]
- lappend res [catch c msg] $msg
- lappend res [catch c msg] $msg
-} -cleanup {
- unset res
-} -result [list 1 quux 0 quuy 1 {invalid command name "c"}]
-
-
-# cleanup
-unset lambda
-::tcltest::cleanupTests
-
-return
-
-# Local Variables:
-# mode: tcl
-# End:
diff --git a/tests/nre.test b/tests/nre.test
deleted file mode 100644
index dcc2180..0000000
--- a/tests/nre.test
+++ /dev/null
@@ -1,441 +0,0 @@
-# Commands covered: proc, apply, [interp alias], [namespce import]
-#
-# This file contains a collection of tests for the non-recursive executor that
-# avoids recursive calls to TEBC. Only the NRE behaviour is tested here, the
-# actual command functionality is tested in the specific test file.
-#
-# Copyright (c) 2008 by Miguel Sofer.
-#
-# See the file "license.terms" for information on usage and redistribution
-# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-#
-# RCS: @(#) $Id: nre.test,v 1.12 2010/01/21 17:23:49 msofer Exp $
-
-if {[lsearch [namespace children] ::tcltest] == -1} {
- package require tcltest
- namespace import -force ::tcltest::*
-}
-
-testConstraint testnrelevels [llength [info commands testnrelevels]]
-
-#
-# The tests that risked blowing the C stack on failure have been removed: we
-# can now actually measure using testnrelevels.
-#
-
-if {[testConstraint testnrelevels]} {
- namespace eval testnre {
- namespace path ::tcl::mathop
- #
- # [testnrelevels] returns a 6-list with: C-stack depth, iPtr->numlevels,
- # cmdFrame level, callFrame level, tosPtr and callback depth
- #
- variable last [testnrelevels]
- proc depthDiff {} {
- variable last
- set depth [testnrelevels]
- set res {}
- foreach t $depth l $last {
- lappend res [expr {$t-$l}]
- }
- set last $depth
- return $res
- }
- proc setabs {} {
- variable abs [- [lindex [testnrelevels] 0]]
- }
-
- variable body0 {
- set x [depthDiff]
- if {[incr i] > 10} {
- namespace upvar [namespace qualifiers \
- [namespace origin depthDiff]] abs abs
- incr abs [lindex [testnrelevels] 0]
- return [list [lrange $x 0 3] $abs]
- }
- }
- proc makebody txt {
- variable body0
- return "$body0; $txt"
- }
- namespace export *
- }
- namespace import testnre::*
-}
-
-test nre-1.1 {self-recursive procs} -setup {
- proc a i [makebody {a $i}]
-} -body {
- setabs
- a 0
-} -cleanup {
- rename a {}
-} -constraints {
- testnrelevels
-} -result {{0 1 1 1} 0}
-
-test nre-1.2 {self-recursive lambdas} -setup {
- set a [list i [makebody {apply $::a $i}]]
-} -body {
- setabs
- apply $a 0
-} -cleanup {
- unset a
-} -constraints {
- testnrelevels
-} -result {{0 1 1 1} 0}
-
-test nre-1.3 {mutually recursive procs and lambdas} -setup {
- proc a i {
- apply $::b [incr i]
- }
- set b [list i [makebody {a $i}]]
-} -body {
- setabs
- a 0
-} -cleanup {
- rename a {}
- unset b
-} -constraints {
- testnrelevels
-} -result {{0 2 2 2} 0}
-
-#
-# Test that aliases are non-recursive
-#
-
-test nre-2.1 {alias is not recursive} -setup {
- proc a i [makebody {b $i}]
- interp alias {} b {} a
-} -body {
- setabs
- a 0
-} -cleanup {
- rename a {}
- rename b {}
-} -constraints {
- testnrelevels
-} -result {{0 2 1 1} 0}
-
-#
-# Test that imports are non-recursive
-#
-
-test nre-3.1 {imports are not recursive} -setup {
- namespace eval foo {
- setabs
- namespace export a
- }
- proc foo::a i [makebody {::a $i}]
- namespace import foo::a
-} -body {
- a 0
-} -cleanup {
- rename a {}
- namespace delete ::foo
-} -constraints {
- testnrelevels
-} -result {{0 2 1 1} 0}
-
-test nre-4.1 {ensembles are not recursive} -setup {
- proc a i [makebody {b foo $i}]
- namespace ensemble create \
- -command b \
- -map [list foo a]
-} -body {
- setabs
- a 0
-} -cleanup {
- rename a {}
- rename b {}
-} -constraints {
- testnrelevels
-} -result {{0 2 1 1} 0}
-
-test nre-5.1 {[namespace eval] is not recursive} -setup {
- namespace eval ::foo {
- setabs
- }
- proc foo::a i [makebody {namespace eval ::foo [list a $i]}]
-} -body {
- ::foo::a 0
-} -cleanup {
- namespace delete ::foo
-} -constraints {
- testnrelevels
-} -result {{0 2 2 2} 0}
-
-test nre-5.2 {[namespace eval] is not recursive} -setup {
- namespace eval ::foo {
- setabs
- }
- proc foo::a i [makebody {namespace eval ::foo "set x $i; a $i"}]
-} -body {
- foo::a 0
-} -cleanup {
- namespace delete ::foo
-} -constraints {
- testnrelevels
-} -result {{0 2 2 2} 0}
-
-test nre-6.1 {[uplevel] is not recursive} -setup {
- proc a i [makebody {uplevel 1 [list a $i]}]
-} -body {
- setabs
- a 0
-} -cleanup {
- rename a {}
-} -constraints {
- testnrelevels
-} -result {{0 2 2 0} 0}
-
-test nre-6.2 {[uplevel] is not recursive} -setup {
- setabs
- proc a i [makebody {uplevel 1 "set x $i; a $i"}]
-} -body {
- a 0
-} -cleanup {
- rename a {}
-} -constraints {
- testnrelevels
-} -result {{0 2 2 0} 0}
-
-test nre-7.1 {[catch] is not recursive} -setup {
- setabs
- proc a i [makebody {uplevel 1 "catch {a $i} msg; set msg"}]
-} -body {
- a 0
-} -cleanup {
- rename a {}
-} -constraints {
- testnrelevels
-} -result {{0 3 3 0} 0}
-
-test nre-7.2 {[if] is not recursive} -setup {
- setabs
- proc a i [makebody {uplevel 1 "if 1 {a $i}"}]
-} -body {
- a 0
-} -cleanup {
- rename a {}
-} -constraints {
- testnrelevels
-} -result {{0 2 2 0} 0}
-
-test nre-7.3 {[while] is not recursive} -setup {
- setabs
- proc a i [makebody {uplevel 1 "while 1 {set res \[a $i\]; break}; set res"}]
-} -body {
- a 0
-} -cleanup {
- rename a {}
-} -constraints {
- testnrelevels
-} -result {{0 2 2 0} 0}
-
-test nre-7.4 {[for] is not recursive} -setup {
- setabs
- proc a i [makebody {uplevel 1 "for {set j 0} {\$j < 10} {incr j} {set res \[a $i\]; break}; set res"}]
-} -body {
- a 0
-} -cleanup {
- rename a {}
-} -constraints {
- testnrelevels
-} -result {{0 2 2 0} 0}
-
-test nre-7.5 {[foreach] is not recursive} -setup {
- #
- # Enable once [foreach] is NR-enabled
- #
- setabs
- proc a i [makebody {uplevel 1 "foreach j {1 2 3 4 5 6} {set res \[a $i\]; break}; set res"}]
-} -body {
- a 0
-} -cleanup {
- rename a {}
-} -constraints {
- testnrelevels
-} -result {{0 3 3 0} 0}
-
-test nre-7.6 {[eval] is not recursive} -setup {
- proc a i [makebody {eval [list a $i]}]
-} -body {
- setabs
- a 0
-} -cleanup {
- rename a {}
-} -constraints {
- testnrelevels
-} -result {{0 2 2 1} 0}
-
-test nre-7.7 {[eval] is not recursive} -setup {
- proc a i [makebody {eval "a $i"}]
-} -body {
- setabs
- a 0
-} -cleanup {
- rename a {}
-} -constraints {
- testnrelevels
-} -result {{0 2 2 1} 0}
-
-test nre-7.8 {bug #2910748: switch out of stale BC is not nre-aware} -setup {
- proc foo args {}
- foo
- coroutine bar apply {{} {
- yield
- proc foo args {return ok}
- while 1 {
- yield [incr i]
- foo
- }
- }}
-} -body {
- # if switching to plain eval is not nre aware, this will cause a "cannot
- # yield" error
-
- list [bar] [bar] [bar]
-} -cleanup {
- rename bar {}
- rename foo {}
-} -result {1 2 3}
-
-
-test nre-8.1 {nre and {*}} -body {
- # force an expansion that grows the evaluation stack, check that nre
- # adapts the bottomPtr. This crashes on failure.
-
- proc inner {} {
- set long [lrepeat 1000000 1]
- list {*}$long
- }
- proc outer {} inner
- lrange [outer] 0 2
-} -cleanup {
- rename inner {}
- rename outer {}
-} -result {1 1 1}
-test nre-8.2 {nre and {*}, [Bug 2415422]} -body {
- # force an expansion that grows the evaluation stack, check that nre
- # adapts the bcFramePtr. This causes an NRE assertion to fail if it is not
- # done properly.
-
- proc nop {} {}
- proc crash {} {
- foreach val [list {*}[lrepeat 100000 x]] {
- nop
- }
- }
-
- crash
-} -cleanup {
- rename nop {}
- rename crash {}
-}
-
-
-#
-# Basic TclOO tests
-#
-
-test nre-oo.1 {really deep calls in oo - direct} -setup {
- oo::object create foo
- oo::objdefine foo method bar i [makebody {foo bar $i}]
-} -body {
- setabs
- foo bar 0
-} -cleanup {
- foo destroy
-} -constraints {
- testnrelevels
-} -result {{0 1 1 1} 0}
-
-test nre-oo.2 {really deep calls in oo - call via [self]} -setup {
- oo::object create foo
- oo::objdefine foo method bar i [makebody {[self] bar $i}]
-} -body {
- setabs
- foo bar 0
-} -cleanup {
- foo destroy
-} -constraints {
- testnrelevels
-} -result {{0 1 1 1} 0}
-
-test nre-oo.3 {really deep calls in oo - private calls} -setup {
- oo::object create foo
- oo::objdefine foo method bar i [makebody {my bar $i}]
-} -body {
- setabs
- foo bar 0
-} -cleanup {
- foo destroy
-} -constraints {
- testnrelevels
-} -result {{0 1 1 1} 0}
-
-test nre-oo.4 {really deep calls in oo - overriding} -setup {
- oo::class create foo {
- method bar i [makebody {my bar $i}]
- }
- oo::class create boo {
- superclass foo
- method bar i [makebody {next $i}]
- }
-} -body {
- setabs
- [boo new] bar 0
-} -cleanup {
- foo destroy
-} -constraints {
- testnrelevels
-} -result {{0 1 1 1} 0}
-
-test nre-oo.5 {really deep calls in oo - forwards} -setup {
- oo::object create foo
- set body [makebody {my boo $i}]
- oo::objdefine foo "
- method bar i {$body}
- forward boo ::foo bar
- "
-} -body {
- setabs
- foo bar 0
-} -cleanup {
- foo destroy
-} -constraints {
- testnrelevels
-} -result {{0 2 1 1} 0}
-
-
-#
-# NASTY BUG found by tcllib's interp package
-#
-
-test nre-X.1 {eval in wrong interp} {
- set i [interp create]
- set res [$i eval {
- set x {namespace children ::}
- set y [list namespace children ::]
- namespace delete {*}[{*}$y]
- set j [interp create]
- $j eval {namespace delete {*}[namespace children ::]}
- namespace eval foo {}
- set res [list [eval $x] [eval $y] [$j eval $x] [$j eval $y]]
- interp delete $j
- set res
- }]
- interp delete $i
- set res
-} {::foo ::foo {} {}}
-
-# cleanup
-::tcltest::cleanupTests
-
-if {[testConstraint testnrelevels]} {
- namespace forget testnre::*
- namespace delete testnre
-}
-
-return
diff --git a/tests/tailcall.test b/tests/tailcall.test
deleted file mode 100644
index 46e2471..0000000
--- a/tests/tailcall.test
+++ /dev/null
@@ -1,665 +0,0 @@
-# Commands covered: tailcall
-#
-# This file contains a collection of tests for experimental commands that are
-# found in ::tcl::unsupported. The tests will migrate to normal test files
-# if/when the commands find their way into the core.
-#
-# Copyright (c) 2008 by Miguel Sofer.
-#
-# See the file "license.terms" for information on usage and redistribution
-# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-#
-# RCS: @(#) $Id: tailcall.test,v 1.14 2010/08/30 14:02:10 msofer Exp $
-
-if {[lsearch [namespace children] ::tcltest] == -1} {
- package require tcltest
- namespace import -force ::tcltest::*
-}
-
-testConstraint testnrelevels [llength [info commands testnrelevels]]
-
-#
-# The tests that risked blowing the C stack on failure have been removed: we
-# can now actually measure using testnrelevels.
-#
-
-if {[testConstraint testnrelevels]} {
- namespace eval testnre {
- #
- # [testnrelevels] returns a 6-list with: C-stack depth, iPtr->numlevels,
- # cmdFrame level, callFrame level, tosPtr and callback depth
- #
- variable last [testnrelevels]
- proc depthDiff {} {
- variable last
- set depth [testnrelevels]
- set res {}
- foreach t $depth l $last {
- lappend res [expr {$t-$l}]
- }
- set last $depth
- return $res
- }
- namespace export *
- }
- namespace import testnre::*
-}
-
-proc errorcode options {
- dict get [dict merge {-errorcode NONE} $options] -errorcode
-}
-
-test tailcall-0.1 {tailcall is constant space} -constraints testnrelevels -setup {
- proc a i {
- #
- # NOTE: there may be a diff in callback depth with the first call
- # ($i==0) due to the fact that the first is from an eval. Successive
- # calls should add nothing to any stack depths.
- #
- if {$i == 1} {
- depthDiff
- }
- if {[incr i] > 10} {
- return [depthDiff]
- }
- tailcall a $i
- }
-} -body {
- a 0
-} -cleanup {
- rename a {}
-} -result {0 0 0 0 0 0}
-
-test tailcall-0.2 {tailcall is constant space} -constraints testnrelevels -setup {
- set a { i {
- if {$i == 1} {
- depthDiff
- }
- if {[incr i] > 10} {
- return [depthDiff]
- }
- upvar 1 a a
- tailcall apply $a $i
- }}
-} -body {
- apply $a 0
-} -cleanup {
- unset a
-} -result {0 0 0 0 0 0}
-
-test tailcall-0.3 {tailcall is constant space} -constraints testnrelevels -setup {
- proc a i {
- if {$i == 1} {
- depthDiff
- }
- if {[incr i] > 10} {
- return [depthDiff]
- }
- tailcall b $i
- }
- interp alias {} b {} a
-} -body {
- b 0
-} -cleanup {
- rename a {}
- rename b {}
-} -result {0 0 0 0 0 0}
-
-test tailcall-0.4 {tailcall is constant space} -constraints testnrelevels -setup {
- namespace eval ::ns {
- namespace export *
- }
- proc ::ns::a i {
- if {$i == 1} {
- depthDiff
- }
- if {[incr i] > 10} {
- return [depthDiff]
- }
- set b [uplevel 1 [list namespace which b]]
- tailcall $b $i
- }
- namespace import ::ns::a
- rename a b
-} -body {
- b 0
-} -cleanup {
- rename b {}
- namespace delete ::ns
-} -result {0 0 0 0 0 0}
-
-test tailcall-0.5 {tailcall is constant space} -constraints testnrelevels -setup {
- proc b i {
- if {$i == 1} {
- depthDiff
- }
- if {[incr i] > 10} {
- return [depthDiff]
- }
- tailcall a b $i
- }
- namespace ensemble create -command a -map {b b}
-} -body {
- a b 0
-} -cleanup {
- rename a {}
- rename b {}
-} -result {0 0 0 0 0 0}
-
-test tailcall-0.6 {tailcall is constant space} -constraints {testnrelevels knownBug} -setup {
- #
- # This test fails because ns-unknown is not NR-enabled
- #
- proc c i {
- if {$i == 1} {
- depthDiff
- }
- if {[incr i] > 10} {
- return [depthDiff]
- }
- tailcall a b $i
- }
- proc d {ens sub args} {
- return [list $ens c]
- }
- namespace ensemble create -command a -unknown d
-} -body {
- a b 0
-} -cleanup {
- rename a {}
- rename c {}
- rename d {}
-} -result {0 0 0 0 0 0}
-
-test tailcall-0.7 {tailcall is constant space} -constraints testnrelevels -setup {
- catch {rename foo {}}
- oo::class create foo {
- method b i {
- if {$i == 1} {
- depthDiff
- }
- if {[incr i] > 10} {
- return [depthDiff]
- }
- tailcall [self] b $i
- }
- }
-} -body {
- foo create a
- a b 0
-} -cleanup {
- rename a {}
- rename foo {}
-} -result {0 0 0 0 0 0}
-
-test tailcall-1 {tailcall} -body {
- namespace eval a {
- variable x *::a
- proc xset {} {
- set tmp {}
- set ns {[namespace current]}
- set level [info level]
- for {set i 0} {$i <= [info level]} {incr i} {
- uplevel #$i "set x $i$ns"
- lappend tmp "$i [info level $i]"
- }
- lrange $tmp 1 end
- }
- proc foo {} {tailcall xset; set x noreach}
- }
- namespace eval b {
- variable x *::b
- proc xset args {error b::xset}
- proc moo {} {set x 0; variable y [::a::foo]; set x}
- }
- variable x *::
- proc xset args {error ::xset}
- list [::b::moo] | $x $a::x $b::x | $::b::y
-} -cleanup {
- unset x
- rename xset {}
- namespace delete a b
-} -result {1::b | 0:: *::a *::b | {{1 ::b::moo} {2 xset}}}
-
-
-test tailcall-2 {tailcall in non-proc} -body {
- namespace eval a [list tailcall set x 1]
-} -match glob -result *tailcall* -returnCodes error
-
-test tailcall-3 {tailcall falls off tebc} -body {
- unset -nocomplain x
- proc foo {} {tailcall set x 1}
- list [catch foo msg] $msg [set x]
-} -cleanup {
- rename foo {}
- unset x
-} -result {0 1 1}
-
-test tailcall-4 {tailcall falls off tebc} -body {
- set x 2
- proc foo {} {tailcall set x 1}
- foo
- set x
-} -cleanup {
- rename foo {}
- unset x
-} -result 1
-
-test tailcall-5 {tailcall falls off tebc} -body {
- set x 2
- namespace eval bar {
- variable x 3
- proc foo {} {tailcall set x 1}
- }
- bar::foo
- list $x $bar::x
-} -cleanup {
- unset x
- namespace delete bar
-} -result {1 3}
-
-test tailcall-6 {tailcall does remove callframes} -body {
- proc foo {} {info level}
- proc moo {} {tailcall foo}
- proc boo {} {expr {[moo] - [info level]}}
- boo
-} -cleanup {
- rename foo {}
- rename moo {}
- rename boo {}
-} -result 1
-
-test tailcall-7 {tailcall does return} -setup {
- namespace eval ::foo {
- variable res {}
- proc a {} {
- variable res
- append res a
- tailcall set x 1
- append res a
- }
- proc b {} {
- variable res
- append res b
- a
- append res b
- }
- proc c {} {
- variable res
- append res c
- b
- append res c
- }
- }
-} -body {
- namespace eval ::foo c
-} -cleanup {
- namespace delete ::foo
-} -result cbabc
-
-test tailcall-8 {tailcall tailcall} -setup {
- namespace eval ::foo {
- variable res {}
- proc a {} {
- variable res
- append res a
- tailcall tailcall set x 1
- append res a
- }
- proc b {} {
- variable res
- append res b
- a
- append res b
- }
- proc c {} {
- variable res
- append res c
- b
- append res c
- }
- }
-} -body {
- namespace eval ::foo c
-} -cleanup {
- namespace delete ::foo
-} -result cbac
-
-test tailcall-9 {tailcall factorial} -setup {
- proc fact {n {b 1}} {
- if {$n == 1} {
- return $b
- }
- tailcall fact [expr {$n-1}] [expr {$n*$b}]
- }
-} -body {
- list [fact 1] [fact 5] [fact 10] [fact 15]
-} -cleanup {
- rename fact {}
-} -result {1 120 3628800 1307674368000}
-
-test tailcall-10a {tailcall and eval} -setup {
- set ::x 0
- proc a {} {
- eval [list tailcall lappend ::x 2]
- set ::x 1
- }
-} -body {
- list [a] $::x
-} -cleanup {
- unset -nocomplain ::x
-} -result {{0 2} {0 2}}
-
-test tailcall-10b {tailcall and eval} -setup {
- set ::x 0
- proc a {} {
- eval {tailcall lappend ::x 2}
- set ::x 1
- }
-} -body {
- list [a] $::x
-} -cleanup {
- unset -nocomplain ::x
-} -result {{0 2} {0 2}}
-
-test tailcall-11a {tailcall and uplevel} -setup {
- proc a {} {
- uplevel 1 [list tailcall set ::x 2]
- set ::x 1
- }
-} -body {
- list [a] $::x
-} -cleanup {
- unset -nocomplain ::x
-} -match glob -result *tailcall* -returnCodes error
-
-test tailcall-11b {tailcall and uplevel} -setup {
- proc a {} {
- uplevel 1 {tailcall set ::x 2}
- set ::x 1
- }
-} -body {
- list [a] $::x
-} -cleanup {
- unset -nocomplain ::x
-} -match glob -result *tailcall* -returnCodes error
-
-test tailcall-11c {tailcall and uplevel} -setup {
- proc a {} {
- uplevel 1 {tailcall lappend ::x 2}
- set ::x 1
- }
- proc b {} {set ::x 0; a; lappend ::x 3}
-} -body {
- list [b] $::x
-} -cleanup {
- rename a {}
- rename b {}
- unset -nocomplain ::x
-} -result {{0 3 2} {0 3 2}}
-
-test tailcall-12.1 {[Bug 2649975]} -setup {
- proc dump {{text {}}} {
- set text [uplevel 1 [list subst $text]]
- set l [expr {[info level] -1}]
- if {$text eq {}} {
- set text [info level $l]
- }
- puts "$l: $text"
- }
- # proc dump args {}
- proc bravo {} {
- upvar 1 v w
- dump {inside bravo, v -> $w}
- set v "procedure bravo"
- #uplevel 1 [list delta ::betty]
- uplevel 1 {delta ::betty}
- return $::resolution
- }
- proc delta name {
- upvar 1 v w
- dump {inside delta, v -> $w}
- set v "procedure delta"
- tailcall foxtrot
- }
- proc foxtrot {} {
- upvar 1 v w
- dump {inside foxtrot, v -> $w}
- global resolution
- set ::resolution $w
- }
- set v "global level"
-} -body {
- set result [bravo]
- if {$result ne $v} {
- puts "v should have been found at $v but was found in $result"
- }
-} -cleanup {
- unset v
- rename dump {}
- rename bravo {}
- rename delta {}
- rename foxtrot {}
-} -output {1: inside bravo, v -> global level
-1: inside delta, v -> global level
-1: inside foxtrot, v -> global level
-}
-
-test tailcall-12.2 {[Bug 2649975]} -setup {
- proc dump {{text {}}} {
- set text [uplevel 1 [list subst $text]]
- set l [expr {[info level] -1}]
- if {$text eq {}} {
- set text [info level $l]
- }
- puts "$l: $text"
- }
- # proc dump args {}
- set v "global level"
- oo::class create foo { # like connection
- method alpha {} { # like connections 'tables' method
- dump
- upvar 1 v w
- dump {inside foo's alpha, v resolves to $w}
- set v "foo's method alpha"
- dump {foo's alpha is calling [self] bravo - v should resolve at global level}
- set result [uplevel 1 [list [self] bravo]]
- dump {exiting from foo's alpha}
- return $result
- }
- method bravo {} { # like connections 'foreach' method
- dump
- upvar 1 v w
- dump {inside foo's bravo, v resolves to $w}
- set v "foo's method bravo"
- dump {foo's bravo is calling charlie to create barney}
- set barney [my charlie ::barney]
- dump {foo's bravo is calling bravo on $barney}
- dump {v should resolve at global scope there}
- set result [uplevel 1 [list $barney bravo]]
- dump {exiting from foo's bravo}
- return $result
- }
- method charlie {name} { # like tdbc prepare
- dump
- set v "foo's method charlie"
- dump {tailcalling bar's constructor}
- tailcall ::bar create $name
- }
- }
- oo::class create bar { # like statement
- method bravo {} { # like statement foreach method
- dump
- upvar 1 v w
- dump {inside bar's bravo, v is resolving to $w}
- set v "bar's method bravo"
- dump {calling delta to construct betty - v should resolve global there}
- uplevel 1 [list [self] delta ::betty]
- dump {exiting from bar's bravo}
- return [::betty whathappened]
- }
- method delta {name} { # like statement execute method
- dump
- upvar 1 v w
- dump {inside bar's delta, v is resolving to $w}
- set v "bar's method delta"
- dump {tailcalling to construct $name as instance of grill}
- dump {v should resolve at global level in grill's constructor}
- dump {grill's constructor should run at level [info level]}
- tailcall grill create $name
- }
- }
- oo::class create grill {
- variable resolution
- constructor {} {
- dump
- upvar 1 v w
- dump "in grill's constructor, v resolves to $w"
- set resolution $w
- }
- method whathappened {} {
- return $resolution
- }
- }
- foo create fred
-} -body {
- set result [fred alpha]
- if {$result ne "global level"} {
- puts "v should have been found at global level but was found in $result"
- }
-} -cleanup {
- unset result
- rename fred {}
- rename dump {}
- rename foo {}
- rename bar {}
- rename grill {}
-} -output {1: fred alpha
-1: inside foo's alpha, v resolves to global level
-1: foo's alpha is calling ::fred bravo - v should resolve at global level
-1: ::fred bravo
-1: inside foo's bravo, v resolves to global level
-1: foo's bravo is calling charlie to create barney
-2: my charlie ::barney
-2: tailcalling bar's constructor
-1: foo's bravo is calling bravo on ::barney
-1: v should resolve at global scope there
-1: ::barney bravo
-1: inside bar's bravo, v is resolving to global level
-1: calling delta to construct betty - v should resolve global there
-1: ::barney delta ::betty
-1: inside bar's delta, v is resolving to global level
-1: tailcalling to construct ::betty as instance of grill
-1: v should resolve at global level in grill's constructor
-1: grill's constructor should run at level 1
-1: grill create ::betty
-1: in grill's constructor, v resolves to global level
-1: exiting from bar's bravo
-1: exiting from foo's bravo
-1: exiting from foo's alpha
-}
-
-test tailcall-12.3a0 {[Bug 2695587]} -body {
- apply {{} {
- catch [list tailcall foo]
- }}
-} -returnCodes 1 -result {invalid command name "foo"}
-
-test tailcall-12.3a1 {[Bug 2695587]} -body {
- apply {{} {
- catch [list tailcall foo]
- tailcall
- }}
-} -result {}
-
-test tailcall-12.3a2 {[Bug 2695587]} -body {
- apply {{} {
- catch [list tailcall foo]
- tailcall moo
- }}
-} -returnCodes 1 -result {invalid command name "moo"}
-
-test tailcall-12.3a3 {[Bug 2695587]} -body {
- set x 0
- apply {{} {
- catch [list tailcall foo]
- tailcall lappend x 1
- }}
- set x
-} -cleanup {
- unset x
-} -result {0 1}
-
-test tailcall-12.3b0 {[Bug 2695587]} -body {
- apply {{} {
- set catch catch
- $catch [list tailcall foo]
- }}
-} -returnCodes 1 -result {invalid command name "foo"}
-
-test tailcall-12.3b1 {[Bug 2695587]} -body {
- apply {{} {
- set catch catch
- $catch [list tailcall foo]
- tailcall
- }}
-} -result {}
-
-test tailcall-12.3b2 {[Bug 2695587]} -body {
- apply {{} {
- set catch catch
- $catch [list tailcall foo]
- tailcall moo
- }}
-} -returnCodes 1 -result {invalid command name "moo"}
-
-test tailcall-12.3b3 {[Bug 2695587]} -body {
- set x 0
- apply {{} {
- set catch catch
- $catch [list tailcall foo]
- tailcall lappend x 1
- }}
- set x
-} -cleanup {
- unset x
-} -result {0 1}
-
-# MORE VARIANTS MISSING: bc'ed caught script vs (bc'ed, not-bc'ed)
-# catch. Actually superfluous now, as tailcall just returns TCL_RETURN so that
-# standard catch behaviour is required.
-
-test tailcall-13.1 {directly tailcalling the tailcall command is ok} {
- list [catch {
- apply {{} {
- apply {{} {
- tailcall tailcall subst ok
- subst b
- }}
- subst c
- }}
- } msg opt] $msg [errorcode $opt]
-} {0 ok NONE}
-test tailcall-13.2 {indirectly tailcalling the tailcall command is ok} {
- list [catch {
- apply {{} {
- apply {{} {
- tailcall eval tailcall subst ok
- subst b
- }}
- subst c
- }}
- } msg opt] $msg [errorcode $opt]
-} {0 ok NONE}
-
-if {[testConstraint testnrelevels]} {
- namespace forget testnre::*
- namespace delete testnre
-}
-
-# cleanup
-::tcltest::cleanupTests
-
-# Local Variables:
-# mode: tcl
-# End: