1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#include <jim.h>
int Jim_stdlibInit(Jim_Interp *interp)
{
if (Jim_PackageProvide(interp, "stdlib", "1.0", JIM_ERRMSG)) return JIM_ERR;
return Jim_EvalSource(interp, "stdlib.tcl", 1, "\n"
"\n"
"if {![exists -command ref]} {\n"
"\n"
" proc ref {args} {{count 0}} {\n"
" format %08x [incr count]\n"
" }\n"
"}\n"
"\n"
"\n"
"proc lambda {arglist args} {\n"
" tailcall proc [ref {} function lambda.finalizer] $arglist {*}$args\n"
"}\n"
"\n"
"proc lambda.finalizer {name val} {\n"
" rename $name {}\n"
"}\n"
"\n"
"\n"
"proc curry {args} {\n"
" alias [ref {} function lambda.finalizer] {*}$args\n"
"}\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"proc function {value} {\n"
" return $value\n"
"}\n"
"\n"
"\n"
"\n"
"\n"
"proc stacktrace {{skip 0}} {\n"
" set trace {}\n"
" incr skip\n"
" foreach level [range $skip [info level]] {\n"
" lappend trace {*}[info frame -$level]\n"
" }\n"
" return $trace\n"
"}\n"
"\n"
"\n"
"proc stackdump {stacktrace} {\n"
" set lines {}\n"
" foreach {l f p} [lreverse $stacktrace] {\n"
" set line {}\n"
" if {$p ne \"\"} {\n"
" append line \"in procedure '$p' \"\n"
" if {$f ne \"\"} {\n"
" append line \"called \"\n"
" }\n"
" }\n"
" if {$f ne \"\"} {\n"
" append line \"at file \\\"$f\\\", line $l\"\n"
" }\n"
" if {$line ne \"\"} {\n"
" lappend lines $line\n"
" }\n"
" }\n"
" join $lines \\n\n"
"}\n"
"\n"
"\n"
"\n"
"proc defer {script} {\n"
" upvar jim::defer v\n"
" lappend v $script\n"
"}\n"
"\n"
"\n"
"\n"
"proc errorInfo {msg {stacktrace \"\"}} {\n"
" if {$stacktrace eq \"\"} {\n"
"\n"
" set stacktrace [info stacktrace]\n"
"\n"
" lappend stacktrace {*}[stacktrace 1]\n"
" }\n"
" lassign $stacktrace p f l\n"
" if {$f ne \"\"} {\n"
" set result \"$f:$l: Error: \"\n"
" }\n"
" append result \"$msg\\n\"\n"
" append result [stackdump $stacktrace]\n"
"\n"
"\n"
" string trim $result\n"
"}\n"
"\n"
"\n"
"\n"
"proc {info nameofexecutable} {} {\n"
" if {[exists ::jim::exe]} {\n"
" return $::jim::exe\n"
" }\n"
"}\n"
"\n"
"\n"
"proc {dict update} {&varName args script} {\n"
" set keys {}\n"
" foreach {n v} $args {\n"
" upvar $v var_$v\n"
" if {[dict exists $varName $n]} {\n"
" set var_$v [dict get $varName $n]\n"
" }\n"
" }\n"
" catch {uplevel 1 $script} msg opts\n"
" if {[info exists varName]} {\n"
" foreach {n v} $args {\n"
" if {[info exists var_$v]} {\n"
" dict set varName $n [set var_$v]\n"
" } else {\n"
" dict unset varName $n\n"
" }\n"
" }\n"
" }\n"
" return {*}$opts $msg\n"
"}\n"
"\n"
"proc {dict replace} {dictionary {args {key value}}} {\n"
" if {[llength ${key value}] % 2} {\n"
" tailcall {dict replace}\n"
" }\n"
" tailcall dict merge $dictionary ${key value}\n"
"}\n"
"\n"
"\n"
"proc {dict lappend} {varName key {args value}} {\n"
" upvar $varName dict\n"
" if {[exists dict] && [dict exists $dict $key]} {\n"
" set list [dict get $dict $key]\n"
" }\n"
" lappend list {*}$value\n"
" dict set dict $key $list\n"
"}\n"
"\n"
"\n"
"proc {dict append} {varName key {args value}} {\n"
" upvar $varName dict\n"
" if {[exists dict] && [dict exists $dict $key]} {\n"
" set str [dict get $dict $key]\n"
" }\n"
" append str {*}$value\n"
" dict set dict $key $str\n"
"}\n"
"\n"
"\n"
"proc {dict incr} {varName key {increment 1}} {\n"
" upvar $varName dict\n"
" if {[exists dict] && [dict exists $dict $key]} {\n"
" set value [dict get $dict $key]\n"
" }\n"
" incr value $increment\n"
" dict set dict $key $value\n"
"}\n"
"\n"
"\n"
"proc {dict remove} {dictionary {args key}} {\n"
" foreach k $key {\n"
" dict unset dictionary $k\n"
" }\n"
" return $dictionary\n"
"}\n"
"\n"
"\n"
"proc {dict for} {vars dictionary script} {\n"
" if {[llength $vars] != 2} {\n"
" return -code error \"must have exactly two variable names\"\n"
" }\n"
" dict size $dictionary\n"
" tailcall foreach $vars $dictionary $script\n"
"}\n");
}{ ... }