1 # Creates an anonymous procedure
2 proc lambda
{arglist args
} {
3 tailcall
proc [ref
{} function lambda.finalizer
] $arglist {*}$args
6 proc lambda.finalizer
{name val
} {
10 # Like alias, but creates and returns an anonyous procedure
12 alias
[ref
{} function lambda.finalizer
] {*}$args
15 # Returns the given argument.
16 # Useful with 'local' as follows:
23 proc function
{value
} {
27 # Returns a list of proc filename line ...
28 # with 3 entries for each stack frame (proc),
29 # (deepest level first)
32 foreach level
[range
1 [info level
]] {
33 lassign
[info frame -$level] p f l
34 lappend trace $p $f $l
39 # Returns a human-readable version of a stack trace
40 proc stackdump
{stacktrace
} {
43 foreach {l f p
} [lreverse
$stacktrace] {
49 append result
"in procedure '$p' "
51 append result
"called "
55 append result
"at file \"$f\", line $l"
61 # Sort of replacement for $::errorInfo
62 # Usage: errorInfo error ?stacktrace?
63 proc errorInfo
{msg
{stacktrace
""}} {
64 if {$stacktrace eq
""} {
65 set stacktrace
[info stacktrace
]
67 lassign
$stacktrace p f l
69 set result
"Runtime Error: $f:$l: "
71 append result
"$msg\n"
72 append result
[stackdump
$stacktrace]
74 # Remove the trailing newline
78 # Finds the current executable by searching along the path
79 # Returns the empty string if not found.
80 proc {info nameofexecutable
} {} {
81 if {[info exists
::jim_argv0]} {
82 if {[string match
"*/*" $::jim_argv0]} {
83 return [file join [pwd] $::jim_argv0]
85 foreach path
[split [env PATH
""] $::tcl_platform(pathSeparator
)] {
86 set exec [file join [pwd] [string map
{\\ /} $path] $::jim_argv0]
87 if {[file executable
$exec]} {
95 # Script-based implementation of 'dict with'
96 proc {dict with
} {dictVar args script
} {
99 foreach {n v
} [dict get
$dict {*}$args] {
104 catch {uplevel 1 $script} msg opts
105 if {[info exists dict
] && [dict exists
$dict {*}$args]} {
107 if {[info exists var_
$n]} {
108 dict
set dict
{*}$args $n [set var_
$n]
110 dict
unset dict
{*}$args $n
117 # Script-based implementation of 'dict merge'
118 # This won't get called in the trivial case of no args
119 proc {dict merge
} {dict args
} {
121 # Check for a valid dict