1 # Create a single word alias (proc) for one or more words
2 # e.g. alias x info exists
4 proc alias
{name args
} {
6 proc $name args prefix
{
7 tailcall
{*}$prefix {*}$args
11 # Creates an anonymous procedure
12 proc lambda
{arglist args
} {
13 set name
[ref
{} function lambda.finalizer
]
14 tailcall
proc $name $arglist {*}$args
17 proc lambda.finalizer
{name val
} {
21 # Like alias, but creates and returns an anonyous procedure
25 tailcall
{*}$prefix {*}$args
29 # Returns the given argument.
30 # Useful with 'local' as follows:
37 proc function
{value
} {
42 proc lassign
{list args
} {
43 # in case the list is empty...
45 uplevel 1 [list foreach $args $list break]
46 lrange $list [llength $args] end-1
49 # Returns a list of proc filename line ...
50 # with 3 entries for each stack frame (proc),
51 # (deepest level first)
54 foreach level
[range
1 [info level
]] {
55 lassign
[info frame -$level] p f l
56 lappend trace $p $f $l
61 # Returns a human-readable version of a stack trace
62 proc stackdump
{stacktrace
} {
65 foreach {l f p
} [lreverse
$stacktrace] {
71 append result
"in procedure '$p' "
73 append result
"called "
77 append result
"at file \"$f\", line $l"
83 # Sort of replacement for $::errorInfo
84 # Usage: errorInfo error ?stacktrace?
85 proc errorInfo
{msg
{stacktrace
""}} {
86 if {$stacktrace eq
""} {
87 set stacktrace
[info stacktrace
]
89 lassign
$stacktrace p f l
91 set result
"Runtime Error: $f:$l: "
93 append result
"$msg\n"
94 append result
[stackdump
$stacktrace]
96 # Remove the trailing newline
100 # Finds the current executable by searching along the path
101 # Returns the empty string if not found.
102 proc {info nameofexecutable
} {} {
103 if {[info exists
::jim_argv0]} {
104 if {[string match
"*/*" $::jim_argv0]} {
105 return [file join [pwd] $::jim_argv0]
107 foreach path
[split [env PATH
""] $::tcl_platform(pathSeparator
)] {
108 set exec [file join [pwd] $path $::jim_argv0]
109 if {[file executable
$exec]} {
117 # Script-based implementation of 'dict with'
118 proc {dict with
} {dictVar args script
} {
121 foreach {n v
} [dict get
$dict {*}$args] {
126 catch {uplevel 1 $script} msg opts
127 if {[info exists dict
] && [dict exists
$dict {*}$args]} {
129 if {[info exists var_
$n]} {
130 dict
set dict
{*}$args $n [set var_
$n]
132 dict
unset dict
{*}$args $n
139 # Script-based implementation of 'dict merge'
140 # This won't get called in the trivial case of no args
141 proc {dict merge
} {dict args
} {
143 # Check for a valid dict