summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--generic/tclCompCmds.c55
-rw-r--r--generic/tclDictObj.c3
-rw-r--r--tests/dict.test54
-rw-r--r--tests/lmap.test471
4 files changed, 290 insertions, 293 deletions
diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c
index 13f479d..61f7988 100644
--- a/generic/tclCompCmds.c
+++ b/generic/tclCompCmds.c
@@ -854,6 +854,19 @@ CompileDictEachCmd(
}
/*
+ * Create temporary variable to capture return values from loop body when
+ * we're collecting results.
+ */
+
+ if (collect == TCL_EACH_COLLECT) {
+ collectVar = TclFindCompiledLocal(NULL, /*nameChars*/ 0, /*create*/ 1,
+ envPtr);
+ if (collectVar < 0) {
+ return TCL_ERROR;
+ }
+ }
+
+ /*
* Check we've got a pair of variables and that they are local variables.
* Then extract their indices in the LVT.
*/
@@ -903,23 +916,21 @@ CompileDictEachCmd(
}
/*
- * Create temporary variable to capture return values from loop body.
+ * Preparation complete; issue instructions. Note that this code issues
+ * fixed-sized jumps. That simplifies things a lot!
+ *
+ * First up, initialize the accumulator dictionary if needed.
*/
if (collect == TCL_EACH_COLLECT) {
- collectVar = TclFindCompiledLocal(NULL, /*nameChars*/ 0, /*create*/ 1,
- envPtr);
- if (collectVar < 0) {
- return TCL_ERROR;
- }
+ PushLiteral(envPtr, "", 0);
+ Emit14Inst( INST_STORE_SCALAR, collectVar, envPtr);
+ TclEmitOpcode( INST_POP, envPtr);
}
/*
- * Preparation complete; issue instructions. Note that this code issues
- * fixed-sized jumps. That simplifies things a lot!
- *
- * First up, get the dictionary and start the iteration. No catching of
- * errors at this point.
+ * Get the dictionary and start the iteration. No catching of errors at
+ * this point.
*/
CompileWord(envPtr, dictTokenPtr, interp, 3);
@@ -928,16 +939,6 @@ CompileDictEachCmd(
TclEmitInstInt4( INST_JUMP_TRUE4, 0, envPtr);
/*
- * Initialize the accumulator dictionary, if needed.
- */
-
- if (collect == TCL_EACH_COLLECT) {
- PushLiteral(envPtr, "", 0);
- Emit14Inst( INST_STORE_SCALAR, collectVar, envPtr);
- TclEmitOpcode( INST_POP, envPtr);
- }
-
- /*
* Now we catch errors from here on so that we can finalize the search
* started by Tcl_DictObjFirst above.
*/
@@ -973,7 +974,7 @@ CompileDictEachCmd(
Emit14Inst( INST_LOAD_SCALAR, keyVarIndex, envPtr);
TclEmitInstInt4(INST_OVER, 1, envPtr);
TclEmitInstInt4(INST_DICT_SET, 1, envPtr);
- TclEmitInt4( collectVar, envPtr);
+ TclEmitInt4( collectVar, envPtr);
TclEmitOpcode( INST_POP, envPtr);
}
TclEmitOpcode( INST_POP, envPtr);
@@ -1024,6 +1025,10 @@ CompileDictEachCmd(
TclEmitInstInt1( INST_UNSET_SCALAR, 0, envPtr);
TclEmitInt4( infoIndex, envPtr);
TclEmitOpcode( INST_END_CATCH, envPtr);
+ if (collect == TCL_EACH_COLLECT) {
+ TclEmitInstInt1(INST_UNSET_SCALAR, 0, envPtr);
+ TclEmitInt4( collectVar, envPtr);
+ }
TclEmitOpcode( INST_RETURN_STK, envPtr);
/*
@@ -1039,7 +1044,7 @@ CompileDictEachCmd(
TclEmitOpcode( INST_POP, envPtr);
TclEmitOpcode( INST_POP, envPtr);
TclEmitInstInt1( INST_UNSET_SCALAR, 0, envPtr);
- TclEmitInt4( infoIndex, envPtr);
+ TclEmitInt4( infoIndex, envPtr);
/*
* Final stage of the command (normal case) is that we push an empty
@@ -1052,6 +1057,8 @@ CompileDictEachCmd(
envPtr->codeStart + endTargetOffset);
if (collect == TCL_EACH_COLLECT) {
Emit14Inst( INST_LOAD_SCALAR, collectVar, envPtr);
+ TclEmitInstInt1(INST_UNSET_SCALAR, 0, envPtr);
+ TclEmitInt4( collectVar, envPtr);
} else {
PushLiteral(envPtr, "", 0);
}
@@ -2279,6 +2286,8 @@ CompileEachloopCmd(
envPtr->currStackDepth = savedStackDepth;
if (collect == TCL_EACH_COLLECT) {
Emit14Inst( INST_LOAD_SCALAR, collectVar, envPtr);
+ TclEmitInstInt1(INST_UNSET_SCALAR, 0, envPtr);
+ TclEmitInt4( collectVar, envPtr);
} else {
PushLiteral(envPtr, "", 0);
}
diff --git a/generic/tclDictObj.c b/generic/tclDictObj.c
index dac4cbe..b64b776 100644
--- a/generic/tclDictObj.c
+++ b/generic/tclDictObj.c
@@ -2619,6 +2619,7 @@ DictMapNRCmd(
* internally so that updates, shimmering, etc are not a problem.
*/
+ Tcl_IncrRefCount(storagePtr->accumulatorObj);
Tcl_IncrRefCount(storagePtr->keyVarObj);
Tcl_IncrRefCount(storagePtr->valueVarObj);
Tcl_IncrRefCount(storagePtr->scriptObj);
@@ -2707,7 +2708,7 @@ DictMapLoopCallback(
Tcl_DictObjNext(&storagePtr->search, &keyObj, &valueObj, &done);
if (done) {
- Tcl_ResetResult(interp);
+ Tcl_SetObjResult(interp, storagePtr->accumulatorObj);
goto done;
}
diff --git a/tests/dict.test b/tests/dict.test
index 398493a..aa22c00 100644
--- a/tests/dict.test
+++ b/tests/dict.test
@@ -1543,15 +1543,17 @@ test dict-24.6 {dict map command: syntax} -returnCodes error -body {
test dict-24.7 {dict map command: syntax} -returnCodes error -body {
dict map "\{x" x x
} -result {unmatched open brace in list}
-test dict-24.8 {dict map command} -body {
+test dict-24.8 {dict map command} -setup {
+ set values {}
+ set keys {}
+} -body {
# This test confirms that [dict keys], [dict values] and [dict map]
# all traverse a dictionary in the same order.
set dictv {a A b B c C}
- set values {}
- set keys [dict map {k v} $dictv {
+ dict map {k v} $dictv {
+ lappend keys $k
lappend values $v
- set k
- }]
+ }
set result [expr {
$keys eq [dict keys $dictv] && $values eq [dict values $dictv]
}]
@@ -1614,19 +1616,33 @@ test dict-24.13 {dict map command: script results} {
error "return didn't go far enough"
}}
} ok,a,b
-test dict-24.14 {dict map command: handle representation loss} -body {
- set dictVar {a b c d e f g h}
+test dict-24.14 {dict map command: handle representation loss} -setup {
+ set keys {}
set values {}
- set keys [dict map {k v} $dictVar {
+} -body {
+ set dictVar {a b c d e f g h}
+ list [dict size [dict map {k v} $dictVar {
if {[llength $dictVar]} {
+ lappend keys $k
lappend values $v
return -level 0 $k
}
- }]
- list [lsort $keys] [lsort $values]
+ }]] [lsort $keys] [lsort $values]
} -cleanup {
unset dictVar keys values k v
-} -result {{a c e g} {b d f h}}
+} -result {4 {a c e g} {b d f h}}
+test dict-24.14a {dict map command: handle representation loss} -body {
+ apply {{} {
+ set dictVar {a b c d e f g h}
+ list [dict size [dict map {k v} $dictVar {
+ if {[llength $dictVar]} {
+ lappend keys $k
+ lappend values $v
+ return -level 0 $k
+ }
+ }]] [lsort $keys] [lsort $values]
+ }}
+} -result {4 {a c e g} {b d f h}}
test dict-24.15 {dict map command: keys are unique and iterated over once only} -setup {
unset -nocomplain accum
array set accum {}
@@ -1672,7 +1688,7 @@ test dict-24.17a {dict map command in compilation context} {
dict set d $k 0 ;# Any modification will do
}
}}
-} {{a 0}}
+} {a {a 0}}
test dict-24.18 {dict map command in compilation context} {
# Bug 1382528 (dict for)
apply {{} {
@@ -1739,33 +1755,33 @@ test dict-24.22 {dict map results (non-compiled)} {
dict map {k v} [dict map {k v} {a 1 b 2 c 3 d 4} { list $v $k }] {
return -level 0 "$k,$v"
}
-} {{1 a,2 b} {3 c,4 d}}
+} {a {a,1 a} b {b,2 b} c {c,3 c} d {d,4 d}}
test dict-24.23 {dict map results (compiled)} {
apply {{} {
dict map {k v} [dict map {k v} {a 1 b 2 c 3 d 4} { list $v $k }] {
return -level 0 "$k,$v"
}
}}
-} {{1 a,2 b} {3 c,4 d}}
+} {a {a,1 a} b {b,2 b} c {c,3 c} d {d,4 d}}
test dict-24.23a {dict map results (compiled)} {
apply {{list} {
dict map {k v} [dict map {k v} $list { list $v $k }] {
return -level 0 "$k,$v"
}
}} {a 1 b 2 c 3 d 4}
-} {{1 a,2 b} {3 c,4 d}}
+} {a {a,1 a} b {b,2 b} c {c,3 c} d {d,4 d}}
test dict-24.24 {dict map with huge dict (non-compiled)} {
- tcl::mathop::+ {*}[dict map {k v} [lsearch -all [lrepeat 1000000 x] x] {
+ tcl::mathop::+ {*}[dict map {k v} [lsearch -all [lrepeat 100000 x] x] {
expr { $k * $v }
}]
-} 166666416666500000
+} 166666666600000
test dict-24.25 {dict map with huge dict (compiled)} {
apply {{n} {
tcl::mathop::+ {*}[dict map {k v} [lsearch -all [lrepeat $n y] y] {
expr { $k * $v }
}]
- }} 1000000
-} 166666416666500000
+ }} 100000
+} 166666666600000
# cleanup
diff --git a/tests/lmap.test b/tests/lmap.test
index dc5053f..7baa77b 100644
--- a/tests/lmap.test
+++ b/tests/lmap.test
@@ -13,20 +13,16 @@
#
# RCS: @(#) $Id: $
-if {[lsearch [namespace children] ::tcltest] == -1} {
- package require tcltest
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2
namespace import -force ::tcltest::*
}
-catch {unset a}
-catch {unset i}
-catch {unset x}
-
-# ----- Non-compiled operation -------------------------------------------------
-
+unset -nocomplain a i x
+
+# ----- Non-compiled operation -----------------------------------------------
# Basic "lmap" operation (non-compiled)
-
test lmap-1.1 {basic lmap tests} {
set a {}
lmap i {a b c d} {
@@ -40,62 +36,53 @@ test lmap-1.2 {basic lmap tests} {
} {a b {{c d} e} {123 {{x}}}}
test lmap-1.2a {basic lmap tests} {
lmap i {a b {{c d} e} {123 {{x}}}} {
- return -level 0 $i
+ return -level 0 $i
}
} {a b {{c d} e} {123 {{x}}}}
-test lmap-1.3 {basic lmap tests} {catch {lmap} msg} 1
-test lmap-1.4 {basic lmap tests} {
- catch {lmap} msg
- set msg
-} {wrong # args: should be "lmap varList list ?varList list ...? command"}
-test lmap-1.5 {basic lmap tests} {catch {lmap i} msg} 1
-test lmap-1.6 {basic lmap tests} {
- catch {lmap i} msg
- set msg
-} {wrong # args: should be "lmap varList list ?varList list ...? command"}
-test lmap-1.7 {basic lmap tests} {catch {lmap i j} msg} 1
-test lmap-1.8 {basic lmap tests} {
- catch {lmap i j} msg
- set msg
-} {wrong # args: should be "lmap varList list ?varList list ...? command"}
-test lmap-1.9 {basic lmap tests} {catch {lmap i j k l} msg} 1
-test lmap-1.10 {basic lmap tests} {
- catch {lmap i j k l} msg
- set msg
-} {wrong # args: should be "lmap varList list ?varList list ...? command"}
+test lmap-1.4 {basic lmap tests} -returnCodes error -body {
+ lmap
+} -result {wrong # args: should be "lmap varList list ?varList list ...? command"}
+test lmap-1.6 {basic lmap tests} -returnCodes error -body {
+ lmap i
+} -result {wrong # args: should be "lmap varList list ?varList list ...? command"}
+test lmap-1.8 {basic lmap tests} -returnCodes error -body {
+ lmap i j
+} -result {wrong # args: should be "lmap varList list ?varList list ...? command"}
+test lmap-1.10 {basic lmap tests} -returnCodes error -body {
+ lmap i j k l
+} -result {wrong # args: should be "lmap varList list ?varList list ...? command"}
test lmap-1.11 {basic lmap tests} {
lmap i {} {
- set i
+ set i
}
} {}
test lmap-1.12 {basic lmap tests} {
lmap i {} {
- return -level 0 x
+ return -level 0 x
}
} {}
-test lmap-1.13 {lmap errors} {
- list [catch {lmap {{a}{b}} {1 2 3} {}} msg] $msg
-} {1 {list element in braces followed by "{b}" instead of space}}
-test lmap-1.14 {lmap errors} {
- list [catch {lmap a {{1 2}3} {}} msg] $msg
-} {1 {list element in braces followed by "3" instead of space}}
-catch {unset a}
-test lmap-1.15 {lmap errors} {
- catch {unset a}
+test lmap-1.13 {lmap errors} -returnCodes error -body {
+ lmap {{a}{b}} {1 2 3} {}
+} -result {list element in braces followed by "{b}" instead of space}
+test lmap-1.14 {lmap errors} -returnCodes error -body {
+ lmap a {{1 2}3} {}
+} -result {list element in braces followed by "3" instead of space}
+unset -nocomplain a
+test lmap-1.15 {lmap errors} -setup {
+ unset -nocomplain a
+} -body {
set a(0) 44
list [catch {lmap a {1 2 3} {}} msg o] $msg $::errorInfo
-} {1 {can't set "a": variable is array} {can't set "a": variable is array
- (setting foreach loop variable "a")
+} -result {1 {can't set "a": variable is array} {can't set "a": variable is array
+ (setting lmap loop variable "a")
invoked from within
"lmap a {1 2 3} {}"}}
-test lmap-1.16 {lmap errors} {
- list [catch {lmap {} {} {}} msg] $msg
-} {1 {foreach varlist is empty}}
-catch {unset a}
-
+test lmap-1.16 {lmap errors} -returnCodes error -body {
+ lmap {} {} {}
+} -result {lmap varlist is empty}
+unset -nocomplain a
# Parallel "lmap" operation (non-compiled)
-
test lmap-2.1 {parallel lmap tests} {
lmap {a b} {1 2 3 4} {
list $b $a
@@ -137,23 +124,22 @@ test lmap-2.8 {parallel lmap tests} {
}
} {{.1.1.1.1 2} .2.2.2. .3..3. ...4.}
test lmap-2.9 {lmap only sets vars if repeating loop} {
- namespace eval ::lmap_test {
- set rgb {65535 0 0}
- lmap {r g b} [set rgb] {}
- set ::x "r=$r, g=$g, b=$b"
- }
- namespace delete ::lmap_test
- set x
+ namespace eval ::lmap_test {
+ set rgb {65535 0 0}
+ lmap {r g b} [set rgb] {}
+ set ::x "r=$r, g=$g, b=$b"
+ }
+ namespace delete ::lmap_test
+ set x
} {r=65535, g=0, b=0}
-test lmap-2.10 {lmap only supports local scalar variables} {
- catch { unset a }
- lmap {a(3)} {1 2 3 4} {set {a(3)}}
-} {1 2 3 4}
-catch { unset a }
-
+test lmap-2.10 {lmap only supports local scalar variables} -setup {
+ unset -nocomplain a
+} -body {
+ lmap {a(3)} {1 2 3 4} {set {a(3)}}
+} -result {1 2 3 4}
+unset -nocomplain a
# "lmap" with "continue" and "break" (non-compiled)
-
test lmap-3.1 {continue tests} {
lmap i {a b c d} {
if {[string compare $i "b"] == 0} continue
@@ -171,149 +157,139 @@ test lmap-3.2 {continue tests} {
test lmap-3.3 {break tests} {
set x 0
list [lmap i {a b c d} {
- incr x
+ incr x
if {[string compare $i "c"] == 0} break
set i
}] $x
} {{a b} 3}
# Check for bug similar to #406709
test lmap-3.4 {break tests} {
- set a 1
- lmap b b {list [concat a; break]; incr a}
- incr a
+ set a 1
+ lmap b b {list [concat a; break]; incr a}
+ incr a
} {2}
-
-# ----- Compiled operation ------------------------------------------------------
+# ----- Compiled operation ---------------------------------------------------
# Basic "lmap" operation (compiled)
-
test lmap-4.1 {basic lmap tests} {
- apply {{} {
- set a {}
- lmap i {a b c d} {
- set a [concat $a $i]
- }
- }}
+ apply {{} {
+ set a {}
+ lmap i {a b c d} {
+ set a [concat $a $i]
+ }
+ }}
} {a {a b} {a b c} {a b c d}}
test lmap-4.2 {basic lmap tests} {
- apply {{} {
- lmap i {a b {{c d} e} {123 {{x}}}} {
- set i
- }
- }}
+ apply {{} {
+ lmap i {a b {{c d} e} {123 {{x}}}} {
+ set i
+ }
+ }}
} {a b {{c d} e} {123 {{x}}}}
test lmap-4.2a {basic lmap tests} {
- apply {{} {
- lmap i {a b {{c d} e} {123 {{x}}}} {
- return -level 0 $i
- }
- }}
+ apply {{} {
+ lmap i {a b {{c d} e} {123 {{x}}}} {
+ return -level 0 $i
+ }
+ }}
} {a b {{c d} e} {123 {{x}}}}
-test lmap-4.3 {basic lmap tests} {catch { apply {{} { lmap }} } msg} 1
-test lmap-4.4 {basic lmap tests} {
- catch { apply {{} { lmap }} } msg
- set msg
-} {wrong # args: should be "lmap varList list ?varList list ...? command"}
-test lmap-4.5 {basic lmap tests} {catch { apply {{} { lmap i }} } msg} 1
-test lmap-4.6 {basic lmap tests} {
- catch { apply {{} { lmap i }} } msg
- set msg
-} {wrong # args: should be "lmap varList list ?varList list ...? command"}
-test lmap-4.7 {basic lmap tests} {catch { apply {{} { lmap i j }} } msg} 1
-test lmap-4.8 {basic lmap tests} {
- catch { apply {{} { lmap i j }} } msg
- set msg
-} {wrong # args: should be "lmap varList list ?varList list ...? command"}
-test lmap-4.9 {basic lmap tests} {catch { apply {{} { lmap i j k l }} } msg} 1
-test lmap-4.10 {basic lmap tests} {
- catch { apply {{} { lmap i j k l }} } msg
- set msg
-} {wrong # args: should be "lmap varList list ?varList list ...? command"}
+test lmap-4.4 {basic lmap tests} -returnCodes error -body {
+ apply {{} { lmap }}
+} -result {wrong # args: should be "lmap varList list ?varList list ...? command"}
+test lmap-4.6 {basic lmap tests} -returnCodes error -body {
+ apply {{} { lmap i }}
+} -result {wrong # args: should be "lmap varList list ?varList list ...? command"}
+test lmap-4.8 {basic lmap tests} -returnCodes error -body {
+ apply {{} { lmap i j }}
+} -result {wrong # args: should be "lmap varList list ?varList list ...? command"}
+test lmap-4.10 {basic lmap tests} -returnCodes error -body {
+ apply {{} { lmap i j k l }}
+} -result {wrong # args: should be "lmap varList list ?varList list ...? command"}
test lmap-4.11 {basic lmap tests} {
- apply {{} { lmap i {} { set i } }}
+ apply {{} { lmap i {} { set i } }}
} {}
test lmap-4.12 {basic lmap tests} {
- apply {{} { lmap i {} { return -level 0 x } }}
+ apply {{} { lmap i {} { return -level 0 x } }}
} {}
-test lmap-4.13 {lmap errors} {
- list [catch { apply {{} { lmap {{a}{b}} {1 2 3} {} }} } msg] $msg
-} {1 {list element in braces followed by "{b}" instead of space}}
-test lmap-4.14 {lmap errors} {
- list [catch { apply {{} { lmap a {{1 2}3} {} }} } msg] $msg
-} {1 {list element in braces followed by "3" instead of space}}
-catch {unset a}
+test lmap-4.13 {lmap errors} -returnCodes error -body {
+ apply {{} { lmap {{a}{b}} {1 2 3} {} }}
+} -result {list element in braces followed by "{b}" instead of space}
+test lmap-4.14 {lmap errors} -returnCodes error -body {
+ apply {{} { lmap a {{1 2}3} {} }}
+} -result {list element in braces followed by "3" instead of space}
+unset -nocomplain a
test lmap-4.15 {lmap errors} {
apply {{} {
- set a(0) 44
- list [catch {lmap a {1 2 3} {}} msg o] $msg $::errorInfo
+ set a(0) 44
+ list [catch {lmap a {1 2 3} {}} msg o] $msg $::errorInfo
}}
} {1 {can't set "a": variable is array} {can't set "a": variable is array
while executing
"lmap a {1 2 3} {}"}}
-test lmap-4.16 {lmap errors} {
- list [catch { apply {{} { lmap {} {} {} }} } msg] $msg
-} {1 {foreach varlist is empty}}
-catch {unset a}
-
+test lmap-4.16 {lmap errors} -returnCodes error -body {
+ apply {{} {
+ lmap {} {} {}
+ }}
+} -result {lmap varlist is empty}
+unset -nocomplain a
# Parallel "lmap" operation (compiled)
-
test lmap-5.1 {parallel lmap tests} {
- apply {{} {
- lmap {a b} {1 2 3 4} {
- list $b $a
- }
- }}
+ apply {{} {
+ lmap {a b} {1 2 3 4} {
+ list $b $a
+ }
+ }}
} {{2 1} {4 3}}
test lmap-5.2 {parallel lmap tests} {
- apply {{} {
- lmap {a b} {1 2 3 4 5} {
- list $b $a
- }
- }}
+ apply {{} {
+ lmap {a b} {1 2 3 4 5} {
+ list $b $a
+ }
+ }}
} {{2 1} {4 3} {{} 5}}
test lmap-5.3 {parallel lmap tests} {
- apply {{} {
- lmap a {1 2 3} b {4 5 6} {
- list $b $a
- }
- }}
+ apply {{} {
+ lmap a {1 2 3} b {4 5 6} {
+ list $b $a
+ }
+ }}
} {{4 1} {5 2} {6 3}}
test lmap-5.4 {parallel lmap tests} {
- apply {{} {
- lmap a {1 2 3} b {4 5 6 7 8} {
- list $b $a
- }
- }}
+ apply {{} {
+ lmap a {1 2 3} b {4 5 6 7 8} {
+ list $b $a
+ }
+ }}
} {{4 1} {5 2} {6 3} {7 {}} {8 {}}}
test lmap-5.5 {parallel lmap tests} {
- apply {{} {
- lmap {a b} {a b A B aa bb} c {c C cc CC} {
- list $a $b $c
- }
- }}
+ apply {{} {
+ lmap {a b} {a b A B aa bb} c {c C cc CC} {
+ list $a $b $c
+ }
+ }}
} {{a b c} {A B C} {aa bb cc} {{} {} CC}}
test lmap-5.6 {parallel lmap tests} {
- apply {{} {
- lmap a {1 2 3} b {1 2 3} c {1 2 3} d {1 2 3} e {1 2 3} {
- list $a$b$c$d$e
- }
- }}
+ apply {{} {
+ lmap a {1 2 3} b {1 2 3} c {1 2 3} d {1 2 3} e {1 2 3} {
+ list $a$b$c$d$e
+ }
+ }}
} {11111 22222 33333}
test lmap-5.7 {parallel lmap tests} {
- apply {{} {
- lmap a {} b {1 2 3} c {1 2} d {1 2 3 4} e {{1 2}} {
- set x $a$b$c$d$e
- }
- }}
+ apply {{} {
+ lmap a {} b {1 2 3} c {1 2} d {1 2 3 4} e {{1 2}} {
+ set x $a$b$c$d$e
+ }
+ }}
} {{1111 2} 222 33 4}
test lmap-5.8 {parallel lmap tests} {
- apply {{} {
- lmap a {} b {1 2 3} c {1 2} d {1 2 3 4} e {{1 2}} {
- join [list $a $b $c $d $e] .
- }
- }}
+ apply {{} {
+ lmap a {} b {1 2 3} c {1 2} d {1 2 3 4} e {{1 2}} {
+ join [list $a $b $c $d $e] .
+ }
+ }}
} {{.1.1.1.1 2} .2.2.2. .3..3. ...4.}
test lmap-5.9 {lmap only sets vars if repeating loop} {
apply {{} {
@@ -328,34 +304,32 @@ test lmap-5.10 {lmap only supports local scalar variables} {
}}
} {1 2 3 4}
-
# "lmap" with "continue" and "break" (compiled)
-
test lmap-6.1 {continue tests} {
- apply {{} {
- lmap i {a b c d} {
- if {[string compare $i "b"] == 0} continue
- set i
- }
- }}
+ apply {{} {
+ lmap i {a b c d} {
+ if {[string compare $i "b"] == 0} continue
+ set i
+ }
+ }}
} {a c d}
test lmap-6.2 {continue tests} {
- apply {{} {
- list [lmap i {a b c d} {
- incr x
- if {[string compare $i "b"] != 0} continue
- set i
- }] $x
- }}
+ apply {{} {
+ list [lmap i {a b c d} {
+ incr x
+ if {[string compare $i "b"] != 0} continue
+ set i
+ }] $x
+ }}
} {b 4}
test lmap-6.3 {break tests} {
- apply {{} {
- list [lmap i {a b c d} {
- incr x
- if {[string compare $i "c"] == 0} break
- set i
- }] $x
- }}
+ apply {{} {
+ list [lmap i {a b c d} {
+ incr x
+ if {[string compare $i "c"] == 0} break
+ set i
+ }] $x
+ }}
} {{a b} 3}
# Check for bug similar to #406709
test lmap-6.4 {break tests} {
@@ -366,13 +340,10 @@ test lmap-6.4 {break tests} {
}}
} {2}
-
-
-# ----- Special cases and bugs -------------------------------------------------
-
-
-test lmap-7.1 {compiled lmap backward jump works correctly} {
- catch {unset x}
+# ----- Special cases and bugs -----------------------------------------------
+test lmap-7.1 {compiled lmap backward jump works correctly} -setup {
+ unset -nocomplain x
+} -body {
array set x {0 zero 1 one 2 two 3 three}
lsort [apply {{arrayName} {
upvar 1 $arrayName a
@@ -380,16 +351,15 @@ test lmap-7.1 {compiled lmap backward jump works correctly} {
list $member [set a($member)]
}
}} x]
-} [lsort {{0 zero} {1 one} {2 two} {3 three}}]
-
-test lmap-7.2 {noncompiled lmap and shared variable or value list objects that are converted to another type} {
- catch {unset x}
+} -result [lsort {{0 zero} {1 one} {2 two} {3 three}}]
+test lmap-7.2 {noncompiled lmap and shared variable or value list objects that are converted to another type} -setup {
+ unset -nocomplain x
+} -body {
lmap {12.0} {a b c} {
set x 12.0
set x [expr $x + 1]
}
-} {13.0 13.0 13.0}
-
+} -result {13.0 13.0 13.0}
# Test for incorrect "double evaluation" semantics
test lmap-7.3 {delayed substitution of body} {
apply {{} {
@@ -397,10 +367,9 @@ test lmap-7.3 {delayed substitution of body} {
lmap a [list 1 2 3] "
set x $a
"
- set x
+ return $x
}}
} {0}
-
# Related to "foreach" test for [Bug 1189274]; crash on failure
test lmap-7.4 {empty list handling} {
proc crash {} {
@@ -411,17 +380,18 @@ test lmap-7.4 {empty list handling} {
}
crash
} {{aa = x bb = } {aa = y bb = } {aa = z bb = }}
-
-# Related to [Bug 1671138]; infinite loop with empty var list in bytecompiled version
-test lmap-7.5 {compiled empty var list} {
+# Related to [Bug 1671138]; infinite loop with empty var list in bytecompiled
+# version.
+test lmap-7.5 {compiled empty var list} -returnCodes error -body {
proc foo {} {
lmap {} x {
error "reached body"
}
}
- list [catch { foo } msg] $msg
-} {1 {foreach varlist is empty}}
-
+ foo
+} -cleanup {
+ catch {rename foo ""}
+} -result {lmap varlist is empty}
test lmap-7.6 {lmap: related to "foreach" [Bug 1671087]} -setup {
proc demo {} {
set vals {1 2 3 4}
@@ -433,61 +403,62 @@ test lmap-7.6 {lmap: related to "foreach" [Bug 1671087]} -setup {
} -cleanup {
rename demo {}
} -result {2 4}
-
# Huge lists must not overflow the bytecode interpreter (development bug)
test lmap-7.7 {huge list non-compiled} {
- set x [lmap a [lrepeat 1000000 x] { set b y$a }]
- list $b [llength $x] [string length $x]
+ set x [lmap a [lrepeat 1000000 x] { set b y$a }]
+ list $b [llength $x] [string length $x]
} {yx 1000000 2999999}
-
test lmap-7.8 {huge list compiled} {
- set x [apply {{times} { lmap a [lrepeat $times x] { set b y$a }}} 1000000]
- list $b [llength $x] [string length $x]
+ set x [apply {{times} { lmap a [lrepeat $times x] { set b y$a }}} 1000000]
+ list $b [llength $x] [string length $x]
} {yx 1000000 2999999}
-
test lmap-7.9 {error then dereference loop var (dev bug)} {
- catch { lmap a 0 b {1 2 3} { error x } }
- set a
+ catch { lmap a 0 b {1 2 3} { error x } }
+ set a
} 0
test lmap-7.9a {error then dereference loop var (dev bug)} {
- catch { lmap a 0 b {1 2 3} { incr a $b; error x } }
- set a
+ catch { lmap a 0 b {1 2 3} { incr a $b; error x } }
+ set a
} 1
-# ----- Coroutines -------------------------------------------------------------
-
-test lmap-8.1 {lmap non-compiled with coroutines} {
- coroutine coro apply {{} {
- set values [yield [info coroutine]]
- eval lmap i [list $values] {{ yield $i }}
- }} ;# returns 'coro'
- coro {a b c d e f} ;# -> a
- coro 1 ;# -> b
- coro 2 ;# -> c
- coro 3 ;# -> d
- coro 4 ;# -> e
- coro 5 ;# -> f
- list [coro 6] [info commands coro]
-} {{1 2 3 4 5 6} {}}
-
-test lmap-8.2 {lmap compiled with coroutines} {
- coroutine coro apply {{} {
- set values [yield [info coroutine]]
- lmap i $values { yield $i }
- }} ;# returns 'coro'
- coro {a b c d e f} ;# -> a
- coro 1 ;# -> b
- coro 2 ;# -> c
- coro 3 ;# -> d
- coro 4 ;# -> e
- coro 5 ;# -> f
- list [coro 6] [info commands coro]
-} {{1 2 3 4 5 6} {}}
-
-
+# ----- Coroutines -----------------------------------------------------------
+test lmap-8.1 {lmap non-compiled with coroutines} -body {
+ coroutine coro apply {{} {
+ set values [yield [info coroutine]]
+ eval lmap i [list $values] {{ yield $i }}
+ }} ;# returns 'coro'
+ coro {a b c d e f} ;# -> a
+ coro 1 ;# -> b
+ coro 2 ;# -> c
+ coro 3 ;# -> d
+ coro 4 ;# -> e
+ coro 5 ;# -> f
+ list [coro 6] [info commands coro]
+} -cleanup {
+ catch {rename coro ""}
+} -result {{1 2 3 4 5 6} {}}
+test lmap-8.2 {lmap compiled with coroutines} -body {
+ coroutine coro apply {{} {
+ set values [yield [info coroutine]]
+ lmap i $values { yield $i }
+ }} ;# returns 'coro'
+ coro {a b c d e f} ;# -> a
+ coro 1 ;# -> b
+ coro 2 ;# -> c
+ coro 3 ;# -> d
+ coro 4 ;# -> e
+ coro 5 ;# -> f
+ list [coro 6] [info commands coro]
+} -cleanup {
+ catch {rename coro ""}
+} -result {{1 2 3 4 5 6} {}}
+
# cleanup
-catch {unset a}
-catch {unset x}
+unset -nocomplain a x
catch {rename foo {}}
::tcltest::cleanupTests
return
+
+# Local Variables:
+# mode: tcl
+# End: