-
Notifications
You must be signed in to change notification settings - Fork 5
/
stdlib.tcl
173 lines (150 loc) · 2.53 KB
/
stdlib.tcl
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
//
// This is the "standard library".
//
// We define some functions here which are available to all users
// of our application/scripting language.
//
//
// Maths functions should be easier to use.
//
// So we can write:
//
// while { <= $a 5 } { .. }
//
// instead of
//
// while { expr $a <= 5 } { ... }
//
proc + {a b} {
expr $a + $b
}
proc - {a b} {
expr $a - $b
}
proc / {a b} {
expr $a / $b
}
proc * {a b} {
expr $a * $b
}
proc % {a b} {
expr $a % $b
}
proc ** {a b} {
expr $a ** $b
}
//
// Comparison functions
//
proc < {a b} {
expr $a < $b
}
proc <= {a b} {
expr $a <= $b
}
proc > {a b} {
expr $a > $b
}
proc >= {a b} {
expr $a >= $b
}
//
// Equality
//
proc == {a b} {
expr $a == $b
}
proc eq {a b} {
expr $a eq $b
}
proc ne {a b} {
expr $a ne $b
}
//
// Min / Max
//
proc min {a b} {
if {< $a $b } {
return $a
} else {
return $b
}
}
proc max {a b} {
if {> $a $b} {
return $a
} else {
return $b
}
}
// Assert a condition is true.
proc assert {a b c} {
if { expr $a $b $c } {
puts "OK : $a $b $c"
} else {
puts "ERR: $a $b $c"
exit 1
}
}
// Assert two strings/numbers are equal.
proc assert_equal {a b} {
// Is the first argument a number?
if { regexp {^([0-9\.]+)$$} $a } {
// Is the second argument a number?
if { regexp {^([0-9\.]+)$$} $b } {
// both numbers: numeric comparison
return [ assert $a == $b ]
}
}
// string compare
assert $a eq $b
}
//
// Utility functions
//
proc repeat {n body} {
set res ""
while {> $n 0} {
decr n
set res [$body]
}
"$res"
}
//
// Now that we have a "repeat" function defined we could use it like so:
//
// repeat 5 {
// puts "Hello I'm alive";
// }
//
// This would also work:
//
// set foo 12
// repeat 5 { incr foo }
// => foo is now 17 (i.e. 12 + 5)
//
//
// Run a body multiple times, using an named variable for the index.
//
// You could use this like so:
//
// loop cur 0 10 { puts "current iteration $cur ($min->$max)" }
// => current iteration 0 (0-10)
// => current iteration 1 (0-10)
// ..
// => current iteration 10 (0-10)
//
proc loop {var min max bdy} {
// result
set res ""
// set the variable
eval "set $var [set min]"
// Run the test
while {<= [set "$$var"] $max } {
set res [$bdy]
// This is a bit horrid
eval {incr "$var"}
}
// return the last result
"$res"
}