calculator.tex /size: 52 Kb    last modification: 2020-07-01 14:35
1
%D The calculator
2
%D
3
%D This document was made in 1998 as demonstration of widgets in \CONTEXT in \MKII.
4
%D It has been adapted to run in \MKIV. Not many changes were needed. The macro
5
%D definitions are layout a bit more readable and we use official scratch variables.
6
%D
7
%D The \JAVASCRIPT\ interpeter has changes and also became more strict. So, I
8
%D reformatted the code bit and added some more semicolons and vars.
9
%D
10
%D We changed to font from a Helvetica lookalike to Dejavu but kept the colors as
11
%D in the original. We also kept the \JAVASCRIPT\ and \METAPOST\ code (although
12
%D we had to add some initalizations for \METAPOST\ due to the runtime graphic
13
%D generation. I didn't check the functionality.
14
%D
15
%D Should I do it different nowaways? For sure. I might use layers of make nicer
16
%D \METAPOST\ code but it's also a demonstration of how thinsg were done in 1998.
17 18
% acrobat 3->4 : different field initialization
19
% acrobat 4->5 : typecasting fails [switch"2" vs 2]
20
% acrobat 6-> : more strict interpreter
21 22
\starttext
23 24
\dontcomplain
25 26
\setuppapersize
27
[
S
6
]
[
S
6
]
28 29
\setupwhitespace
30
[
medium
]
31 32
\setupbodyfont
33
[
dejavu
,
9
pt
]
34 35
\setuptyping
36
[
margin
=
standard
]
37 38
\setuplayout
39
[
backspace
=
1
cm
,
40
topspace
=
1
cm
,
41
header
=
0
pt
,
42
footer
=
0
pt
,
43
width
=
middle
,
44
height
=
middle
]
45 46
\setupinteraction
47
[
page
=
yes
,
48
state
=
start
,
49
author
=
Hans
Hagen
,
50
title
=
The
Calculator
,
51
color
=
keyboard
]
52 53
\setupinteractionscreen
54
[
option
=
max
]
55 56
\definecolor
[
action
]
[
r
=
1
,
g
=
.
9
,
b
=
.
5
]
57
\definecolor
[
keyboard
]
[
r
=
0
,
g
=
.
7
,
b
=
.
7
]
58
\definecolor
[
stack
]
[
r
=
.
7
,
g
=
.
6
,
b
=
.
8
]
59 60
\useURL
[
pragma
-
mail
]
[
mailto
:
pragma
@
xs
4
all
.
nl
]
[
]
[
pragma
@
xs
4
all
.
nl
]
61 62
%D We have to use \type {String(...)=""} otherwise zero is regarded
63
%D as non|-|entry (empty). This is a bit fuzzy.
64 65
\def
\MinLevel
{
5
0
}
66
\def
\MaxLevel
{
8
}
67 68
\startJSpreamble
{
variables
}
used
now
69 70
var
Growing
=
false
;
71
var
MinLevel
=
-
5
0
;
72
var
MaxLevel
=
8
;
73
var
Level
=
1
;
74
var
NoErrorFound
=
"
>
ok
"
;
75
var
NoValueError
=
"
>
invalid
"
;
76
var
WhateverError
=
"
>
error
"
;
77
var
OverflowError
=
"
>
overflow
"
;
78
var
ExhaustedError
=
"
>
exhausted
"
;
79 80
var
Stack
=
new
Array
(
)
;
81
var
Stats
=
new
Array
(
)
;
82 83
/
/
console
.
clear
(
)
;
84 85
/
/
console
.
println
(
"
preamble
loaded
:
variables
"
)
;
86 87
\stopJSpreamble
88 89
\startJSpreamble
{
housekeeping
}
used
now
90 91
function
do
_
reset
_
all
(
)
{
92
if
(
Growing
)
{
93
Level
=
1
;
94
}
else
{
95
Level
=
MaxLevel
;
96
}
97
for
(
var
i
=
MinLevel
;
i
<
=
MaxLevel
;
i
+
+
)
{
98
Stack
[
i
]
=
"
"
;
99
}
100
do
_
mark
(
NoErrorFound
)
;
101
}
102 103
function
do
_
refresh
(
i
)
{
104
var
vv
=
this
.
getField
(
"
Stack
.
"
+
String
(
i
)
)
;
105
if
(
vv
)
{
106
vv
.
value
=
Stack
[
i
]
;
107
vv
.
readonly
=
(
i
!
=
Level
)
;
108
this
.
dirty
=
false
;
109
}
110
}
111 112
function
do
_
refresh
_
all
(
)
{
113
for
(
var
i
=
1
;
i
<
=
MaxLevel
;
i
+
+
)
{
114
do
_
refresh
(
i
)
;
115
}
116
}
117 118
function
do
_
update
_
A
(
)
{
119
if
(
Stack
[
1
]
=
=
"
"
)
{
120
for
(
var
i
=
1
;
i
<
=
MaxLevel
;
i
+
+
)
{
121
vv
=
this
.
getField
(
"
Stack
.
"
+
String
(
i
)
)
;
122
if
(
vv
)
{
123
Level
=
i
;
124
if
(
valid
_
number
(
vv
.
value
)
)
{
125
Stack
[
Level
]
=
String
(
vv
.
value
)
126
}
else
{
127
vv
.
value
=
"
"
;
128
this
.
dirty
=
false
;
129
return
;
130
}
131
}
132
}
133
}
134
}
135 136
function
do
_
update
_
B
(
)
{
137
if
(
String
(
Stack
[
MaxLevel
-
1
]
)
=
=
"
"
)
{
138
for
(
var
i
=
1
;
i
<
=
MaxLevel
;
i
+
+
)
{
139
vv
=
this
.
getField
(
"
Stack
.
"
+
String
(
i
)
)
;
140
if
(
vv
)
{
141
if
(
valid
_
number
(
vv
.
value
)
)
{
142
Stack
[
Level
]
=
String
(
vv
.
value
)
;
143
}
else
{
144
vv
.
value
=
"
"
;
145
this
.
dirty
=
false
;
146
return
;
147
}
148
}
149
}
150
}
151
}
152 153
function
do
_
update
(
)
{
154
if
(
Growing
)
{
155
do
_
update
_
A
(
)
;
156
}
else
{
157
do
_
update
_
B
(
)
;
158
}
159
}
160 161
function
do
_
mark
(
s
)
{
162
var
vv
=
this
.
getField
(
"
Stack
.
"
+
String
(
Level
)
)
;
163
if
(
vv
)
{
164
vv
.
value
=
s
;
165
this
.
dirty
=
false
;
166
}
167
}
168 169
/
/
console
.
println
(
"
preamble
loaded
:
housekeeping
"
)
;
170
\stopJSpreamble
171 172
\startJSpreamble
{
handling
}
used
now
173 174
function
do
_
enter
(
)
{
175
do
_
update
(
)
;
176
var
vv
=
this
.
getField
(
"
Stack
.
"
+
String
(
Level
)
)
;
177
if
(
(
vv
.
value
!
=
Stack
[
Level
]
)
&
&
(
String
(
vv
.
value
)
.
search
(
/
>
/
)
=
=
-
1
)
)
{
178
do
_
push
(
vv
.
value
)
;
179
}
else
{
180
do
_
push
(
Stack
[
Level
]
)
;
181
}
182
}
183 184
function
do
_
push
_
A
(
Value
)
{
185
do
_
update
(
)
;
186
Stack
[
Level
]
=
String
(
Value
)
;
187
do
_
parse
(
Level
)
;
188
if
(
String
(
Stack
[
Level
]
)
!
=
"
"
)
{
189
if
(
Level
<
MaxLevel
)
{
190
+
+
Level
;
191
do
_
mark
(
ErrorString
)
;
192
}
else
{
193
for
(
var
i
=
MinLevel
;
i
<
MaxLevel
;
i
+
+
)
{
194
Stack
[
i
]
=
Stack
[
i
+
1
]
;
195
}
196
Stack
[
MaxLevel
]
=
"
"
;
197
do
_
refresh
_
all
(
)
;
198
if
(
String
(
Stack
[
MinLevel
]
)
!
=
"
"
)
{
199
ErrorString
=
ExhaustedError
;
200
}
201
do
_
mark
(
ErrorString
)
;
202
}
203
}
204
}
205 206
function
do
_
push
_
B
(
Value
)
{
207
do
_
update
(
)
;
208
Stack
[
MaxLevel
]
=
String
(
Value
)
;
209
do
_
parse
(
MaxLevel
)
;
210
if
(
String
(
Stack
[
MaxLevel
]
)
!
=
"
"
)
{
211
for
(
var
i
=
MinLevel
;
i
<
MaxLevel
;
i
+
+
)
{
212
Stack
[
i
]
=
Stack
[
i
+
1
]
;
213
}
214
Stack
[
MaxLevel
]
=
"
"
;
215
do
_
refresh
_
all
(
)
;
216
if
(
Stack
[
MinLevel
]
!
=
"
"
)
{
217
ErrorString
=
ExhaustedError
;
218
}
219
do
_
mark
(
ErrorString
)
;
220
}
221
}
222 223
function
do
_
push
(
Value
)
{
224
if
(
Growing
)
{
225
do
_
push
_
A
(
Value
)
;
226
}
else
{
227
do
_
push
_
B
(
Value
)
;
228
}
229
}
230 231
function
do
_
pop
_
A
(
)
{
232
do
_
update
(
)
;
233
if
(
String
(
Stack
[
0
]
)
!
=
"
"
)
{
234
for
(
var
i
=
MaxLevel
;
i
>
MinLevel
;
i
-
-
)
{
235
Stack
[
i
]
=
Stack
[
i
-
1
]
;
236
}
237
Stack
[
MinLevel
]
=
"
"
;
238
do
_
refresh
_
all
(
)
;
239
Level
=
MaxLevel
;
240
}
else
{
241
while
(
(
Level
>
1
)
&
&
(
String
(
Stack
[
Level
]
)
=
=
"
"
)
)
{
242
do
_
refresh
(
Level
)
;
243
-
-
Level
;
244
}
245
}
246
if
(
String
(
Stack
[
Level
]
)
=
=
"
"
)
{
247
return
(
"
"
)
;
248
}
else
{
249
Value
=
Number
(
Stack
[
Level
]
)
;
250
Stack
[
Level
]
=
"
"
;
251
do
_
refresh
(
Level
)
;
252
return
(
Value
)
;
253
}
254
}
255 256
function
do
_
pop
_
B
(
)
{
257
do
_
update
(
)
;
258
if
(
String
(
Stack
[
MaxLevel
]
)
=
=
"
"
)
{
259
for
(
var
i
=
MaxLevel
;
i
>
MinLevel
;
i
-
-
)
{
260
Stack
[
i
]
=
Stack
[
i
-
1
]
;
261
}
262
Stack
[
MinLevel
]
=
"
"
;
263
do
_
refresh
_
all
(
)
;
264
}
265
if
(
String
(
Stack
[
MaxLevel
]
)
=
=
"
"
)
{
266
return
(
"
"
)
;
267
}
else
{
268
Value
=
Number
(
Stack
[
MaxLevel
]
)
;
269
Stack
[
MaxLevel
]
=
"
"
;
270
return
(
Value
)
;
271
}
272
}
273 274
function
do
_
pop
(
)
{
275
if
(
Growing
)
{
276
return
(
do
_
pop
_
A
(
)
)
;
277
}
else
{
278
return
(
do
_
pop
_
B
(
)
)
;
279
}
280
}
281 282
function
do
_
dup
(
)
{
283
var
X
=
do
_
pop
(
)
;
284
if
(
valid
_
number
(
X
)
)
{
285
do
_
push
(
X
)
;
286
do
_
push
(
X
)
;
287
}
else
{
288
do
_
mark
(
ErrorString
)
;
289
}
290
}
291 292
function
do
_
parse
(
i
)
{
293
if
(
valid
_
number
(
Stack
[
i
]
)
)
{
294
Stack
[
i
]
=
parseFloat
(
Stack
[
i
]
)
;
295
do
_
refresh
(
i
)
;
296
}
else
{
297
Stack
[
i
]
=
"
"
;
298
do
_
refresh
(
i
)
;
299
do
_
mark
(
ErrorString
)
;
300
}
301
}
302 303
function
do
_
digit
(
d
)
{
304
Stack
[
Level
]
+
=
String
(
d
)
;
305
do
_
refresh
(
Level
)
;
306
}
307 308
function
valid
_
number
(
x
)
{
309
if
(
String
(
x
)
=
=
"
"
)
{
310
ErrorString
=
NoValueError
;
311
return
(
false
)
;
312
}
else
if
(
isNaN
(
x
)
)
{
313
ErrorString
=
NoValueError
;
314
return
(
false
)
;
315
}
else
if
(
isFinite
(
x
)
)
{
316
ErrorString
=
NoErrorFound
;
317
return
(
true
)
;
318
}
else
{
319
ErrorString
=
OverflowError
;
320
return
(
false
)
;
321
}
322
}
323 324
/
/
console
.
println
(
"
preamble
loaded
:
handling
"
)
;
325 326
\stopJSpreamble
327 328
\startJSpreamble
{
operations
}
used
now
329 330
function
do
_
calculate
(
Operator
)
{
331
do
_
enter
(
)
;
332
var
Y
=
do
_
pop
(
)
;
333
var
X
=
0
;
334
if
(
valid
_
number
(
Y
)
)
{
335
X
=
do
_
pop
(
)
;
336
if
(
valid
_
number
(
X
)
)
{
337
switch
(
Number
(
Operator
)
)
{
338
case
1
:
339
if
(
Y
)
{
340
X
/
=
Y
;
341
}
342
break
;
343
case
2
:
344
X
*
=
Y
;
345
break
;
346
case
3
:
347
X
-
=
Y
;
348
break
;
349
case
4
:
350
X
+
=
Y
;
351
break
;
352
case
5
:
353
X
=
Math
.
max
(
X
,
Y
)
;
354
break
;
355
case
6
:
356
X
=
Math
.
min
(
X
,
Y
)
;
357
break
;
358
case
7
:
359
X
=
Math
.
pow
(
X
,
Y
)
;
360
break
361
}
362
do
_
push
(
X
)
;
363
}
else
{
364
do
_
push
(
Y
)
;
365
ErrorString
=
NoValueError
;
366
}
367
}
368
do
_
mark
(
ErrorString
)
;
369
}
370 371
/
/
console
.
println
(
"
preamble
loaded
:
operations
"
)
;
372
\stopJSpreamble
373 374
\startJSpreamble
{
functions
}
used
now
375 376
function
do
_
facultate
(
Value
)
{
377
var
n
=
Math
.
min
(
Math
.
round
(
Value
)
,
5
0
0
)
;
378
if
(
n
<
=
1
)
{
379
return
(
1
)
;
380
}
else
{
381
var
m
=
1
;
382
for
(
m
=
1
,
i
=
1
;
i
<
=
n
;
i
+
+
)
{
383
m
=
m
*
i
;
384
}
385
return
(
m
)
;
386
}
387
}
388 389
function
do
_
constant
(
Operation
)
{
390
do
_
update
(
)
;
391
switch
(
Number
(
Operation
)
)
{
392
case
1
:
393
do
_
push
(
Math
.
PI
)
;
394
break
;
395
case
2
:
396
do
_
push
(
Math
.
E
)
;
397
break
;
398
case
3
:
399
do
_
push
(
Math
.
random
(
1
)
)
;
400
break
;
401
case
4
:
402
do
_
dup
(
)
;
403
break
;
404
}
405
}
406 407
function
do
_
do
_
memory
(
mv
,
Sign
)
{
408
var
X
=
do
_
pop
(
)
;
409
if
(
valid
_
number
(
X
)
)
{
410
mv
.
value
+
=
Sign
*
X
;
411
if
(
!
valid
_
number
(
mv
.
value
)
)
{
412
mv
.
value
=
"
"
;
413
}
414
this
.
dirty
=
false
;
415
}
416
do
_
mark
(
ErrorString
)
;
417
}
418 419
function
do
_
memory
(
Operation
)
{
420
var
mv
=
this
.
getField
(
"
Stats
.
mem
"
)
;
421
if
(
mv
)
{
422
switch
(
Number
(
Operation
)
)
{
423
case
1
:
424
mv
.
value
=
"
"
;
425
break
;
426
case
2
:
427
do
_
do
_
memory
(
mv
,
1
)
;
428
break
;
429
case
3
:
430
do
_
do
_
memory
(
mv
,
-
1
)
;
431
break
;
432
case
4
:
433
if
(
mv
.
value
=
=
"
"
)
{
434
ErrorString
=
NoValueError
;
435
do
_
mark
(
ErrorString
)
;
436
}
else
{
437
do
_
push
(
mv
.
value
)
;
438
}
439
break
;
440
}
441
this
.
dirty
=
false
;
442
}
443
}
444 445
function
do
_
operation
(
Operator
)
{
446
do
_
enter
(
)
;
447
var
X
=
do
_
pop
(
)
;
448
if
(
valid
_
number
(
X
)
)
{
449
switch
(
Number
(
Operator
)
)
{
450
case
1
:
451
do
_
push
(
Math
.
sin
(
X
)
)
;
452
break
;
453
case
2
:
454
do
_
push
(
Math
.
cos
(
X
)
)
;
455
break
;
456
case
3
:
457
do
_
push
(
Math
.
tan
(
X
)
)
;
458
break
;
459
case
4
:
460
do
_
push
(
Math
.
exp
(
X
)
)
;
461
break
;
462
case
5
:
463
do
_
push
(
Math
.
ceil
(
X
)
)
;
464
break
;
465
case
6
:
466
do
_
push
(
Math
.
pow
(
X
,
2
)
)
;
467
break
;
468
case
7
:
469
do
_
push
(
do
_
facultate
(
X
)
)
;
470
break
;
471
case
8
:
472
do
_
push
(
Math
.
asin
(
X
)
)
;
473
break
;
474
case
9
:
475
do
_
push
(
Math
.
acos
(
X
)
)
;
476
break
;
477
case
1
0
:
478
do
_
push
(
Math
.
atan
(
X
)
)
;
479
break
;
480
case
1
1
:
481
do
_
push
(
Math
.
log
(
X
)
)
;
482
break
;
483
case
1
2
:
484
do
_
push
(
Math
.
floor
(
X
)
)
;
485
break
;
486
case
1
3
:
487
do
_
push
(
Math
.
sqrt
(
X
)
)
;
488
break
;
489
case
1
4
:
490
do
_
push
(
Math
.
round
(
X
)
)
;
491
break
;
492
case
1
5
:
493
do
_
push
(
Math
.
pow
(
X
,
-
1
)
)
;
494
break
;
495
case
1
6
:
496
do
_
push
(
X
*
(
2
*
Math
.
PI
/
3
6
0
)
)
;
497
break
;
498
case
1
7
:
499
do
_
push
(
X
/
(
2
*
Math
.
PI
/
3
6
0
)
)
;
500
break
;
501
case
1
8
:
502
do
_
push
(
-
X
)
;
503
break
;
504
}
505
}
506
do
_
mark
(
ErrorString
)
;
507
}
508 509
/
/
console
.
println
(
"
preamble
loaded
:
functions
"
)
;
510
\stopJSpreamble
511 512
\startJSpreamble
{
statistics
}
used
now
513 514
var
s
_
min
_
max
=
1
;
515
var
s
_
sqrt
=
0
;
516 517
function
do
_
statcalcs
(
Sign
,
X
)
{
518
s
_
n
.
value
+
=
Sign
;
519
s
_
sqrt
+
=
Sign
*
X
*
X
;
520
s
_
total
.
value
+
=
Sign
*
X
;
521
s
_
mean
.
value
=
s
_
total
.
value
/
s
_
n
.
value
;
522
s
_
temp
=
Math
.
max
(
s
_
sqrt
-
2
*
s
_
total
.
value
*
s
_
mean
.
value
+
523
s
_
n
.
value
*
s
_
mean
.
value
*
s
_
mean
.
value
,
0
)
;
524
s
_
sdev
.
value
=
Math
.
sqrt
(
s
_
temp
/
s
_
n
.
value
)
;
525
if
(
!
(
valid
_
number
(
X
)
&
&
valid
_
number
(
s
_
sqrt
)
&
&
526
valid
_
number
(
s
_
sdev
.
value
)
&
&
valid
_
number
(
s
_
total
.
value
)
&
&
527
valid
_
number
(
s
_
mean
.
value
)
)
)
{
528
do
_
statistics
(
1
)
;
529
}
530
this
.
dirty
=
false
;
531
}
532 533
function
do
_
statistics
(
Operator
)
{
534
var
s
_
n
=
this
.
getField
(
"
Stats
.
n
"
)
;
535
var
s
_
min
=
this
.
getField
(
"
Stats
.
min
"
)
;
536
var
s
_
max
=
this
.
getField
(
"
Stats
.
max
"
)
;
537
var
s
_
total
=
this
.
getField
(
"
Stats
.
total
"
)
;
538
var
s
_
mean
=
this
.
getField
(
"
Stats
.
mean
"
)
;
539
var
s
_
sdev
=
this
.
getField
(
"
Stats
.
sdev
"
)
;
540
if
(
(
s
_
sqrt
=
=
0
)
&
&
(
s
_
n
.
value
!
=
"
"
)
&
&
(
s
_
n
.
value
>
0
)
)
{
541
s
_
min
_
max
=
1
;
542
s
_
sqrt
=
s
_
n
.
value
*
s
_
sdev
.
value
*
s
_
sdev
.
value
+
543
2
*
s
_
total
.
value
*
s
_
mean
.
value
-
544
s
_
n
.
value
*
s
_
mean
.
value
*
s
_
mean
.
value
;
545
}
546
switch
(
Number
(
Operator
)
)
{
547
case
1
:
548
s
_
min
_
max
=
1
;
549
s
_
n
.
value
=
"
"
;
550
s
_
min
.
value
=
"
"
;
551
s
_
max
.
value
=
"
"
;
552
s
_
total
.
value
=
"
"
;
553
s
_
mean
.
value
=
"
"
;
554
s
_
sdev
.
value
=
"
"
;
555
s
_
sqrt
=
0
;
556
break
;
557
case
2
:
558
do
_
enter
(
)
;
559
var
X
=
do
_
pop
(
)
;
560
if
(
valid
_
number
(
X
)
)
{
561
if
(
s
_
n
.
value
=
=
"
"
)
{
562
s
_
n
.
value
=
0
;
563
s
_
total
.
value
=
0
;
564
s
_
mean
.
value
=
0
;
565
if
(
s
_
min
_
max
)
{
566
s
_
min
.
value
=
X
;
567
s
_
max
.
value
=
X
;
568
}
569
}
else
{
570
if
(
(
s
_
min
_
max
)
&
&
(
X
<
s
_
min
.
value
)
)
{
571
s
_
min
.
value
=
X
;
572
}
573
if
(
(
s
_
min
_
max
)
&
&
(
X
>
s
_
max
.
value
)
)
{
574
s
_
max
.
value
=
X
;
575
}
576
}
577
do
_
statcalcs
(
1
,
X
)
;
578
}
579
break
;
580
case
3
:
581
do
_
enter
(
)
;
582
var
X
=
do
_
pop
(
)
;
583
if
(
valid
_
number
(
X
)
)
{
584
s
_
min
.
value
=
"
"
;
585
s
_
max
.
value
=
"
"
;
586
s
_
min
_
max
=
0
;
587
if
(
s
_
n
.
value
>
0
)
{
588
do
_
statcalcs
(
-
1
,
X
)
;
589
}
else
{
590
do
_
statistics
(
1
)
;
591
}
592
}
593
break
;
594
}
595
do
_
mark
(
ErrorString
)
;
596
this
.
dirty
=
false
;
597
}
598 599
function
do
_
copystat
(
Field
)
{
600
var
sv
=
this
.
getField
(
"
Stats
.
"
.
concat
(
Field
)
)
;
601
do
_
push
(
sv
.
value
)
;
602
}
603 604
/
/
console
.
println
(
"
preamble
loaded
:
statistics
"
)
;
605
\stopJSpreamble
606 607
\startJSpreamble
{
initialization
}
used
now
608
do
_
reset
_
all
(
)
;
609
do
_
update
(
)
;
610
do
_
refresh
_
all
(
)
;
611
do
_
mark
(
NoErrorFound
)
;
612 613
/
/
console
.
println
(
"
preamble
loaded
:
initialization
"
)
;
614
\stopJSpreamble
615 616
%D We could use functions instead but this demonstrates inline
617
%D code. We also could use predefined references.
618 619
\startJScode
{
period
}
620
if
(
Stack
[
Level
]
.
search
(
/
[
.
|
e
]
/
)
=
=
-
1
)
{
621
do
_
digit
(
"
.
"
)
;
622
}
623
\stopJScode
624 625
\startJScode
{
sign
}
626
L
=
Stack
[
Level
]
.
length
;
627
if
(
(
L
=
=
0
)
|
|
(
Stack
[
Level
]
.
charAt
(
L
-
1
)
=
=
"
e
"
)
)
{
628
do
_
digit
(
"
-
"
)
;
629
}
630
\stopJScode
631 632
\startJScode
{
exponent
}
633
L
=
Stack
[
Level
]
.
length
;
634
if
(
(
L
>
0
)
&
&
valid
_
number
(
Stack
[
Level
]
)
&
&
(
Stack
[
Level
]
.
search
(
/
[
e
]
/
)
=
=
-
1
)
)
{
635
do
_
digit
(
"
e
"
)
;
636
}
637
\stopJScode
638 639
\startJScode
{
reset
}
640
do
_
reset
_
all
(
)
;
641
do
_
refresh
_
all
(
)
;
642
do
_
mark
(
NoErrorFound
)
;
643
\stopJScode
644 645
\startJScode
{
clear
}
646
do
_
update
(
)
;
647
Stack
[
Level
]
=
String
(
Stack
[
Level
]
)
.
substring
(
0
,
String
(
Stack
[
Level
]
)
.
length
-
1
)
;
648
do
_
refresh
(
Level
)
;
649
\stopJScode
650 651
\startJScode
{
pop
}
652
X
=
do
_
pop
(
)
;
653
do
_
mark
(
NoErrorFound
)
;
654
\stopJScode
655 656
\startJScode
{
push
}
657
do
_
enter
(
)
;
658
\stopJScode
659 660
\startJScode
{
grow
}
661
Growing
=
!
Growing
;
662
do
_
reset
_
all
(
)
;
663
do
_
refresh
_
all
(
)
;
664
do
_
mark
(
NoErrorFound
)
;
665
\stopJScode
666 667
% graphics
668 669
\startuniqueMPgraphic
{
page
}
670
fill
OverlayBox
671
withcolor
.4
white
;
672
draw
OverlayBox
enlarged
-10
pt
673
withpen
pencircle
scaled
5
pt
674
withcolor
.8
white
;
675
\stopuniqueMPgraphic
676 677
\startuniqueMPgraphic
{
shape
}
678
path
p
;
color
c
;
679
p
:
=
OverlayBox
;
680
c
:
=
\overlaycolor
;
681
fill
p
withcolor
c
;
682
draw
p
withpen
pencircle
scaled
1.5
pt
withcolor
.8
c
;
683
\stopuniqueMPgraphic
684 685
\defineoverlay
[
page
]
[
\uniqueMPgraphic
{
page
}
]
686
\defineoverlay
[
shape
]
[
\uniqueMPgraphic
{
shape
}
]
687 688
\setupbackgrounds
689
[
page
]
690
[
background
=
page
]
691 692
\definemeasure
[
ButtonWidth
]
[
\makeupwidth
/
1
5
]
693 694
\setupbuttons
695
[
width
=
\measured
{
ButtonWidth
}
,
696
height
=
\measured
{
ButtonWidth
}
,
697
background
=
shape
,
698
backgroundcolor
=
\MPcolor
{
keyboard
}
,
699
frame
=
off
,
700
style
=
,
701
color
=
]
702 703
\setupfield
704
[
Results
]
705
[
horizontal
,
frame
]
706
[
width
=
fit
,
707
align
=
{
lohi
}
,
708
height
=
.
5
\measured
{
ButtonWidth
}
,
709
background
=
shape
,
710
backgroundcolor
=
\MPcolor
{
stack
}
,
711
frame
=
off
]
712
[
width
=
3
.
5
\measured
{
ButtonWidth
}
,
713
frame
=
off
]
714
[
width
=
3
.
5
\measured
{
ButtonWidth
}
,
715
height
=
.
4
5
\measured
{
ButtonWidth
}
,
716
option
=
readonly
,
717
frame
=
off
]
718 719
\starttexdefinition
unexpanded
Star
720
\lower
.
6
5
ex
\hbox
{
721
*
722
}
723
\stoptexdefinition
724 725
\starttexdefinition
unexpanded
InfoButton
#
1
726
\setbox
\scratchbox
\hbox
{
727
\lower
.
5
cm
\hbox
{
728
\button
[
729
width
=
\dimexpr
\overlaywidth
+
.
5
cm
\relax
,
730
height
=
\dimexpr
\overlayheight
+
.
5
cm
\relax
,
731
strut
=
no
,
732
frame
=
off
,
733
background
=
734
]
{
735
}
[
736
info
:
#
1
737
]
738
}
739
}
740
\wd
\scratchbox
\overlaywidth
741
\ht
\scratchbox
\overlayheight
742
\box
\scratchbox
743
\stoptexdefinition
744 745
\starttexdefinition
unexpanded
SomeKey
#
1
#
2
#
3
746 747
\bgroup
748 749
\doifelsenothing
{
#
2
}
{
750
\button
[
background
=
]
{
#
2
}
[
#
3
]
751
}
{
752
\defineoverlay
753
[
infobutton
]
754
[
\InfoButton
{
#
1
}
]
755
% \button
756
% [background={infobutton,shape}]
757
% {#2}
758
% [#3]
759
\framed
760
[
offset
=
overlay
,
761
frame
=
off
,
762
background
=
infobutton
,
763
backgroundcolor
=
red
]
764
{
\button
{
#
2
}
[
#
3
]
}
765
}
766 767
\egroup
768 769
\ignorespaces
770 771
\stoptexdefinition
772 773
\starttexdefinition
unexpanded
StatField
#
1
774
\hbox
\bgroup
775
\doifelsenothing
{
#
1
}
{
776
\framed
[
777
height
=
.
5
\measured
{
ButtonWidth
}
,
778
width
=
3
.
5
\measured
{
ButtonWidth
}
,
779
frame
=
off
780
]
{
781
}
782
}
{
783
\definefield
[
Stats
.
#
1
]
[
line
]
[
Results
]
784
\field
[
Stats
.
#
1
]
[
option
=
readonly
]
785
}
786
\egroup
787
\ignorespaces
788
\stoptexdefinition
789 790
\setbox
\scratchboxone
=
\hbox
to
.
4
\makeupwidth
\bgroup
791
\ss
792
\SomeKey
{
7
}
{
\ssb
7
}
{
JS
(
do
_
digit
{
7
}
)
}
\hss
793
\SomeKey
{
8
}
{
\ssb
8
}
{
JS
(
do
_
digit
{
8
}
)
}
\hss
794
\SomeKey
{
9
}
{
\ssb
9
}
{
JS
(
do
_
digit
{
9
}
)
}
\hss
795
\SomeKey
{
div
}
{
\ssb
/
}
{
JS
(
do
_
calculate
{
1
}
)
}
\hss
796
\SomeKey
{
del
}
{
del
}
{
JS
(
clear
)
}
797
\egroup
798 799
\setbox
\scratchboxtwo
=
\hbox
to
\wd
\scratchboxone
\bgroup
800
\ss
801
\SomeKey
{
4
}
{
\ssb
4
}
{
JS
(
do
_
digit
{
4
}
)
}
\hss
802
\SomeKey
{
5
}
{
\ssb
5
}
{
JS
(
do
_
digit
{
5
}
)
}
\hss
803
\SomeKey
{
6
}
{
\ssb
6
}
{
JS
(
do
_
digit
{
6
}
)
}
\hss
804
\SomeKey
{
mul
}
{
\ssb
\Star
}
{
JS
(
do
_
calculate
{
2
}
)
}
\hss
805
\SomeKey
{
E
}
{
E
}
{
JS
(
exponent
)
}
806
\egroup
807 808
\setbox
\scratchboxthree
=
\hbox
to
\wd
\scratchboxone
\bgroup
809
\ss
810
\SomeKey
{
1
}
{
\ssb
1
}
{
JS
(
do
_
digit
{
1
}
)
}
\hss
811
\SomeKey
{
2
}
{
\ssb
2
}
{
JS
(
do
_
digit
{
2
}
)
}
\hss
812
\SomeKey
{
3
}
{
\ssb
3
}
{
JS
(
do
_
digit
{
3
}
)
}
\hss
813
\SomeKey
{
sub
}
{
\ssb
-
-
}
{
JS
(
do
_
calculate
{
3
}
)
}
\hss
814
\SomeKey
{
pop
}
{
pop
}
{
JS
(
pop
)
}
815
\egroup
816 817
\setbox
\scratchboxfour
=
\hbox
to
\wd
\scratchboxone
\bgroup
818
\ss
819
\SomeKey
{
0
}
{
\ssb
0
}
{
JS
(
do
_
digit
{
0
}
)
}
\hss
820
\SomeKey
{
period
}
{
\ssb
.
}
{
JS
(
period
)
}
\hss
821
\SomeKey
{
sign
}
{
\ssb
-
}
{
JS
(
sign
)
}
\hss
822
\SomeKey
{
add
}
{
\ssb
+
}
{
JS
(
do
_
calculate
{
4
}
)
}
\hss
823
\SomeKey
{
push
}
{
push
}
{
JS
(
push
)
}
824
\egroup
825 826
\setbox
\scratchboxone
=
\vbox
to
.
8
\wd
\scratchboxone
\bgroup
827
\box
\scratchboxone
\vss
828
\box
\scratchboxtwo
\vss
829
\box
\scratchboxthree
\vss
830
\box
\scratchboxfour
831
\egroup
832 833
\setbox
\scratchboxtwo
=
\vbox
to
\ht
\scratchboxone
\bgroup
834
\dostepwiserecurse
{
\MaxLevel
}
{
1
}
{
-
1
}
{
835
\definefield
[
Stack
.
\recurselevel
]
[
line
]
[
Results
]
836
\hbox
\bgroup
837
\field
[
Stack
.
\recurselevel
]
[
option
=
readonly
]
%
838
\egroup
839
\vfill
840
}
841
\unskip
842
\egroup
843 844
\setbox
\scratchboxthree
=
\vbox
to
\ht
\scratchboxone
\bgroup
845
\StatField
{
n
}
\vfill
846
\StatField
{
min
}
\vfill
847
\StatField
{
max
}
\vfill
848
\StatField
{
total
}
\vfill
849
\StatField
{
mean
}
\vfill
850
\StatField
{
sdev
}
\vfill
851
\StatField
{
}
\vfill
852
\StatField
{
}
853
\egroup
854 855
\setbox
\scratchboxfour
=
\vbox
to
\ht
\scratchboxone
\bgroup
856
\ss
\setstrut
857
\setupbuttons
858
[
width
=
\measured
{
ButtonWidth
}
,
859
height
=
.
5
\measured
{
ButtonWidth
}
,
860
backgroundcolor
=
\MPcolor
{
action
}
]
%
861
\SomeKey
{
sn
}
{
n
}
{
JS
(
do
_
copystat
{
n
}
)
}
\vfill
862
\SomeKey
{
smin
}
{
min
}
{
JS
(
do
_
copystat
{
min
}
)
}
\vfill
863
\SomeKey
{
smax
}
{
max
}
{
JS
(
do
_
copystat
{
max
}
)
}
\vfill
864
\SomeKey
{
stotal
}
{
total
}
{
JS
(
do
_
copystat
{
total
}
)
}
\vfill
865
\SomeKey
{
smean
}
{
mean
}
{
JS
(
do
_
copystat
{
mean
}
)
}
\vfill
866
\SomeKey
{
ssdev
}
{
sdev
}
{
JS
(
do
_
copystat
{
sdev
}
)
}
\vfill
867
\SomeKey
{
}
{
}
{
}
\vfill
868
\SomeKey
{
}
{
}
{
}
869
\egroup
870 871
\setbox
\scratchboxone
=
\hbox
to
\hsize
\bgroup
872
\box
\scratchboxone
\hss
873
\box
\scratchboxtwo
\hss
874
\box
\scratchboxthree
\hss
875
\box
\scratchboxfour
876
\egroup
877 878
\setupbuttons
879
[
width
=
1
.
5
cm
,
880
height
=
1
cm
,
881
backgroundcolor
=
\MPcolor
{
action
}
]
882 883
\setbox
\scratchboxtwo
=
\hbox
to
\wd
\scratchboxone
\bgroup
884
\ss
\setstrut
885
\SomeKey
{
sin
}
{
sin
}
{
JS
(
do
_
operation
{
1
}
)
}
\hss
886
\SomeKey
{
cos
}
{
cos
}
{
JS
(
do
_
operation
{
2
}
)
}
\hss
887
\SomeKey
{
tan
}
{
tan
}
{
JS
(
do
_
operation
{
3
}
)
}
\hss
888
\SomeKey
{
max
}
{
max
}
{
JS
(
do
_
calculate
{
5
}
)
}
\hss
889
\SomeKey
{
exp
}
{
exp
}
{
JS
(
do
_
operation
{
4
}
)
}
\hss
890
\SomeKey
{
ceil
}
{
ceil
}
{
JS
(
do
_
operation
{
5
}
)
}
\hss
891
\SomeKey
{
sqr
}
{
x
\high
{
2
}
}
{
JS
(
do
_
operation
{
6
}
)
}
\hss
892
\SomeKey
{
fac
}
{
x
!
}
{
JS
(
do
_
operation
{
7
}
)
}
\hss
893
\SomeKey
{
pow
}
{
x
\high
{
y
}
}
{
JS
(
do
_
calculate
{
7
}
)
}
\hss
894
\SomeKey
{
rad
}
{
rad
}
{
JS
(
do
_
operation
{
1
6
}
)
}
895
\egroup
896 897
\setbox
\scratchboxthree
=
\hbox
to
\wd
\scratchboxone
\bgroup
898
\ss
\setstrut
899
\SomeKey
{
asin
}
{
asin
}
{
JS
(
do
_
operation
{
8
}
)
}
\hss
900
\SomeKey
{
acos
}
{
acos
}
{
JS
(
do
_
operation
{
9
}
)
}
\hss
901
\SomeKey
{
atan
}
{
atan
}
{
JS
(
do
_
operation
{
1
0
}
)
}
\hss
902
\SomeKey
{
min
}
{
min
}
{
JS
(
do
_
calculate
{
6
}
)
}
\hss
903
\SomeKey
{
ln
}
{
ln
}
{
JS
(
do
_
operation
{
1
1
}
)
}
\hss
904
\SomeKey
{
floor
}
{
floor
}
{
JS
(
do
_
operation
{
1
2
}
)
}
\hss
905
\SomeKey
{
sqrt
}
{
sqrt
}
{
JS
(
do
_
operation
{
1
3
}
)
}
\hss
906
\SomeKey
{
round
}
{
round
}
{
JS
(
do
_
operation
{
1
4
}
)
}
\hss
907
\SomeKey
{
inv
}
{
1
/
x
}
{
JS
(
do
_
operation
{
1
5
}
)
}
\hss
908
\SomeKey
{
deg
}
{
deg
}
{
JS
(
do
_
operation
{
1
7
}
)
}
909
\egroup
910 911
\setbox
\scratchboxfour
=
\hbox
to
\wd
\scratchboxone
\bgroup
912
\ss
\setstrut
913
\SomeKey
{
}
{
}
{
}
\hss
914
\SomeKey
{
}
{
}
{
}
\hss
915
\setupbuttons
916
[
backgroundcolor
=
\MPcolor
{
keyboard
}
]
%
917
\SomeKey
{
new
}
{
new
}
{
JS
(
reset
)
}
\hss
918
\SomeKey
{
}
{
}
{
}
\hss
919
\SomeKey
{
}
{
}
{
}
\hss
920
\SomeKey
{
}
{
}
{
}
\hss
921
\SomeKey
{
}
{
}
{
}
\hss
922
\SomeKey
{
newn
}
{
new
}
{
JS
(
do
_
statistics
{
1
}
)
}
\hss
923
\SomeKey
{
addn
}
{
+
n
}
{
JS
(
do
_
statistics
{
2
}
)
}
\hss
924
\SomeKey
{
subn
}
{
-
-
n
}
{
JS
(
do
_
statistics
{
3
}
)
}
925
\egroup
926 927
\setbox
\scratchboxfive
=
\hbox
to
\wd
\scratchboxone
\bgroup
928
\ss
\setstrut
929
\SomeKey
{
neg
}
{
-
-
x
}
{
JS
(
do
_
operation
{
1
8
}
)
}
\hss
930
\SomeKey
{
random
}
{
random
}
{
JS
(
do
_
constant
{
3
}
)
}
\hss
931
\SomeKey
{
pi
}
{
pi
}
{
JS
(
do
_
constant
{
1
}
)
}
\hss
932
\SomeKey
{
e
}
{
e
}
{
JS
(
do
_
constant
{
2
}
)
}
\hss
933
\SomeKey
{
dup
}
{
dup
}
{
JS
(
do
_
constant
{
4
}
)
}
\hss
934
\SomeKey
{
}
{
}
{
}
\hss
935
\SomeKey
{
}
{
}
{
}
\hss
936
\setupbuttons
937
[
backgroundcolor
=
\MPcolor
{
keyboard
}
]
%
938
\SomeKey
{
}
{
}
{
}
\hss
939
\SomeKey
{
exit
}
{
exit
}
{
CloseDocument
}
\hss
940
\SomeKey
{
help
}
{
info
}
{
info
:
help
}
941
\egroup
942 943
\setbox
\scratchboxsix
=
\hbox
to
\wd
\scratchboxone
\bgroup
944
\ss
\setstrut
945
\setupbuttons
946
[
width
=
\measured
{
ButtonWidth
}
,
947
height
=
.
5
\measured
{
ButtonWidth
}
,
948
backgroundcolor
=
\MPcolor
{
keyboard
}
]
%
949
\SomeKey
{
newmem
}
{
new
}
{
JS
(
do
_
memory
{
1
}
)
}
\hss
950
\SomeKey
{
addmem
}
{
+
m
}
{
JS
(
do
_
memory
{
2
}
)
}
\hss
951
\SomeKey
{
submem
}
{
-
-
m
}
{
JS
(
do
_
memory
{
3
}
)
}
\hss
952
\StatField
{
mem
}
\hss
953
\setupbuttons
954
[
backgroundcolor
=
\MPcolor
{
action
}
]
%
955
\SomeKey
{
copmem
}
{
mem
}
{
JS
(
do
_
memory
{
4
}
)
}
\hss
956
\SomeKey
{
}
{
}
{
}
\hss
957
\setupbuttons
958
[
backgroundcolor
=
\MPcolor
{
stack
}
]
%
959
\SomeKey
{
grow
}
{
grow
}
{
JS
(
grow
)
}
\hss
960
\StatField
{
}
961
\egroup
962 963
\startstandardmakeup
964 965
\pagereference
[
calculator
]
966 967
\vfill
968 969
\hbox
to
\hsize
\bgroup
970
\hss
971
\vbox
to
\vsize
\bgroup
972
\box
\scratchboxtwo
\vss
973
\box
\scratchboxthree
\vss
974
\box
\scratchboxone
\vss
975
\box
\scratchboxfour
\vss
976
\box
\scratchboxfive
\vss
977
\box
\scratchboxsix
978
\egroup
979
\hss
980
\egroup
981 982
\vfill
983 984
\stopstandardmakeup
985 986
\starttexdefinition
unexpanded
BackgroundButton
987
\button
[
988
background
=
screen
,
989
backgroundscreen
=
.
8
,
990
backgroundoffset
=
5
pt
,
991
height
=
\vsize
,
992
width
=
\hsize
993
]
{
994
}
[
995
calculator
996
]
997
\stoptexdefinition
998 999
\setuptexttexts
1000
[
\BackgroundButton
]
1001
[
]
1002 1003
\starttexdefinition
unexpanded
Key
#
1
#
2
1004
\goto
{
1005
\ss
#
1
1006
}
[
1007
info
:
#
2
1008
]
1009
\stoptexdefinition
1010 1011
\startstandardmakeup
[
top
=
,
bottom
=
]
1012 1013
\switchtobodyfont
[
8
pt
]
1014 1015
\start
1016 1017
\setupwhitespace
[
big
]
1018 1019
\midaligned
{
\ssd
The
Calculator
}
1020 1021
\blank
[
2
*
big
]
1022 1023
\pagereference
[
info
:
help
]
1024
This
calculator
is
stack
based
,
which
means
that
one
enters
values
and
1025
invokes
an
action
that
acts
on
the
value
(
s
)
last
entered
.
Subtracting
1
0
from
1026
2
0
using
(
\Key
{
-
-
}
{
sub
}
)
for
instance
comes
down
to
clicking
:
1027 1028
\startnarrower
\ss
1029
1
0
\quad
in
\quad
2
0
\quad
-
-
1030
\stopnarrower
1031 1032
while
calculating
a
sinus
(
\Key
{
sin
}
{
sin
}
)
results
from
entering
:
1033 1034
\startnarrower
\ss
1035
.
8
9
\quad
sin
1036
\stopnarrower
1037 1038
The
left
column
of
fields
(
numbers
)
shows
the
Stack
.
One
uses
\Key
{
push
}
1039
{
push
}
to
push
a
value
on
the
stack
and
\Key
{
pop
}
{
pop
}
to
remove
a
value
.
1040
Clicking
\Key
{
new
}
{
new
}
removes
them
all
and
the
\Key
{
del
}
{
del
}
button
1041
can
be
used
to
undo
the
last
entered
digit
.
When
a
dyadic
operation
is
1042
applied
,
the
top
value
is
used
as
~
y
.
The
\Key
{
grow
}
{
grow
}
key
toggles
1043
between
two
different
visualizations
of
the
stack
.
1044 1045
The
stack
is
considerably
larger
than
the
screen
representation
suggests
.
In
1046
the
rare
occasion
that
one
encounters
the
message
{
\ss
exhausted
}
,
the
amount
1047
of
stack
entries
already
has
totaled
far
beyond
\MinLevel
\
and
one
probably
1048
already
has
forgotten
what
the
values
first
entered
represent
.
1049 1050
The
right
column
of
fields
reports
the
statistic
calculations
.
By
clicking
on
1051
the
tag
,
one
pushes
the
value
on
the
Stack
.
The
lower
buttons
are
used
to
1052
reset
~
(
\Key
{
new
}
{
newn
}
)
,
enter
~
(
\Key
{
+
}
{
addn
}
)
and
remove
~
(
\Key
{
-
-
}
1053
{
subn
}
)
values
to
be
taken
into
account
when
calculating
those
statistics
.
1054 1055
This
document
is
produced
by
\ConTeXt
,
a
macro
package
written
in
\TeX
.
The
1056
graphics
are
METAPOST
graphics
.
The
graphics
,
the
PDF
objects
and
the
form
1057
fields
as
well
as
JavaScript
code
were
generated
and
inserted
at
run
time
.
1058
Originally
we
used
PDF
\TeX
\
and
\MKII
\
to
process
this
document
but
this
one
1059
is
done
by
\LUATEX
\
and
\MKIV
.
We
kept
the
design
and
code
original
so
that
1060
it
reflects
how
things
were
done
(
for
readability
we
updated
some
\TEX
\ 1061
definitions
)
.
1062 1063
\stop
1064 1065
\vfilll
1066 1067
\startMPrun
1068
logo
_
type
:
=
3
0
2
;
% force single logo type
1069
mpgraph
:
=
3
0
2
;
% and use this number
1070
input
mp
-
prag
;
% calculate logo of type
1071
\stopMPrun
1072 1073
\startlinecorrection
1074
\midaligned
{
\externalfigure
[
mprun
.
3
0
2
]
[
height
=
1
.
5
cm
]
}
1075
\stoplinecorrection
1076 1077
\midaligned
{
\strut
Hans
Hagen
,
PRAGMA
ADE
,
\ConTeXt
\
1
8
/
2
/
1
9
9
8
-
-
2
5
/
9
/
2
0
1
8
}
1078 1079
\blank
1080 1081
\midaligned
{
\strut
\url
[
pragma
-
mail
]
}
1082 1083
\stopstandardmakeup
1084 1085
\starttexdefinition
unexpanded
BackgroundButton
1086
\button
[
1087
background
=
screen
,
1088
backgroundscreen
=
.
8
,
1089
backgroundoffset
=
5
pt
,
1090
height
=
\vsize
,
1091
width
=
\hsize
1092
]
{
1093
}
[
1094
firstpage
1095
]
1096
\stoptexdefinition
1097 1098
\starttexdefinition
unexpanded
ShowInfo
#
1
#
2
1099
\startstandardmakeup
1100
\pagereference
[
info
:
#
1
]
1101
\vfill
1102
\hbox
to
\hsize
\bgroup
1103
\hss
1104
\useMPgraphic
{
#1
}
1105
\hss
1106
\egroup
1107
\blank
[
2
*
big
]
1108
\midaligned
{
#
2
}
1109
\vfill
1110
\stopstandardmakeup
1111
\stoptexdefinition
1112 1113
\startMPinclusions
1114 1115
path
ax
,
ay
,
p
[
]
;
1116
color
c
;
c
:
=
\MPcolor
{
action
}
;
1117
pmax
:
=
0
;
1118 1119
let
normalpow
=
pow
;
1120 1121
def
draw_function
(
text
fun
)
(
expr
xmin
,
xmax
,
xstep
)
=
1122
pmax
:
=
pmax
+1
;
1123
p
[
pmax
]
:
=
for
x
=
xmin
step
xstep
until
xmax
:
1124
(
x
,
fun
(
x
)
)
..
1125
endfor
(
xmax
,
fun
(
xmax
)
)
;
1126
enddef
;
1127 1128
def
draw_axis
=
% should sort of snap, to-do
1129
pickup
pencircle
scaled
0
;
1130
for
i
=
1
upto
pmax
:
1131
draw
p
[
i
]
;
1132
endfor
;
1133
xmin
:
=
xpart
llcorner
currentpicture
;
1134
xmax
:
=
xpart
urcorner
currentpicture
;
1135
ymin
:
=
ypart
llcorner
currentpicture
;
1136
ymax
:
=
ypart
urcorner
currentpicture
;
1137
ax
:
=
(
xmin
,
0
)
--
(
0
,
0
)
--
(
xmax
,
0
)
;
1138
ay
:
=
(
0
,
ymin
)
--
(
0
,
0
)
--
(
0
,
ymax
)
;
1139
currentpicture
:
=
nullpicture
;
1140
sx
:
=
400
/
(
xmax
-
xmin
)
;
1141
sy
:
=
250
/
(
ymax
-
ymin
)
;
1142
pickup
pencircle
xscaled
(
10
/
sx
)
yscaled
(
10
/
sy
)
;
1143
draw
ax
withcolor
.4
white
;
1144
draw
ay
withcolor
.4
white
;
1145
for
i
=
1
upto
pmax
:
1146
draw
p
[
i
]
withcolor
c
;
1147
endfor
;
1148
currentpicture
:
=
currentpicture
xscaled
sx
yscaled
sy
;
1149
pmax
:
=
0
;
1150
enddef
;
1151 1152
\stopMPinclusions
1153 1154
\startuseMPgraphic
{
sin
}
1155
draw_function
(
sind
)
(
-360
,
360
,
60
)
;
draw_axis
;
1156
\stopuseMPgraphic
1157 1158
\ShowInfo
{
sin
}
{
Calculate
the
sine
of
the
topmost
stack
entry
.
}
1159 1160
\startuseMPgraphic
{
cos
}
1161
draw_function
(
cosd
)
(
-360
,
360
,
60
)
;
draw_axis
;
1162
\stopuseMPgraphic
1163 1164
\ShowInfo
{
cos
}
{
Calculate
the
cosine
of
the
topmost
stack
entry
.
}
1165 1166
\startuseMPgraphic
{
tan
}
1167
draw_function
(
tand
)
(
-240
,
-120
,
30
)
;
1168
draw_function
(
tand
)
(
-60
,
60
,
30
)
;
1169
draw_function
(
tand
)
(
120
,
240
,
30
)
;
1170
draw_axis
;
1171
\stopuseMPgraphic
1172 1173
\ShowInfo
{
tan
}
{
Calculate
the
tangent
of
the
topmost
stack
entry
.
}
1174 1175
\startuseMPgraphic
{
asin
}
1176
draw_function
(
asin
)
(
-1
,
1
,
.2
)
;
draw_axis
;
1177
\stopuseMPgraphic
1178 1179
\ShowInfo
{
asin
}
{
Calculate
the
arcsine
of
the
topmost
stack
entry
.
}
1180 1181
\startuseMPgraphic
{
acos
}
1182
draw_function
(
acos
)
(
-1
,
1
,
.2
)
;
draw_axis
;
1183
\stopuseMPgraphic
1184 1185
\ShowInfo
{
acos
}
{
Calculate
the
arccosine
of
the
topmost
stack
entry
.
}
1186 1187
\startuseMPgraphic
{
atan
}
1188
draw_function
(
atan
)
(
-1
,
1
,
.2
)
;
draw_axis
;
1189
\stopuseMPgraphic
1190 1191
\ShowInfo
{
atan
}
{
Calculate
the
arctangent
of
the
topmost
stack
entry
.
}
1192 1193
\startuseMPgraphic
{
sqr
}
1194
draw_function
(
sqr
)
(
-3
,
3
,
1
)
;
draw_axis
;
1195
\stopuseMPgraphic
1196 1197
\ShowInfo
{
sqr
}
{
Calculate
the
square
of
the
topmost
stack
entry
.
}
1198 1199
\startuseMPgraphic
{
sqrt
}
1200
draw_function
(
sqrt
)
(
0
,
5
,
1
)
;
draw_axis
;
1201
\stopuseMPgraphic
1202 1203
\ShowInfo
{
sqrt
}
{
Calculate
the
square
root
of
the
topmost
stack
entry
.
}
1204 1205
\startuseMPgraphic
{
exp
}
1206
draw_function
(
exp
)
(
0
,
5
,
1
)
;
draw_axis
;
1207
\stopuseMPgraphic
1208 1209
\ShowInfo
{
exp
}
{
Calculate
the
exponential
function
of
the
topmost
stack
entry
.
}
1210 1211
\startuseMPgraphic
{
ln
}
1212
draw_function
(
ln
)
(
0
,
50
,
5
)
;
draw_axis
;
1213
\stopuseMPgraphic
1214 1215
\ShowInfo
{
ln
}
{
Calculate
the
natural
logaritm
of
the
topmost
stack
entry
.
}
1216 1217
\startuseMPgraphic
{
pow
}
1218
vardef
mypow
(
expr
n
)
=
3
*
*
n
enddef
;
1219
draw_function
(
mypow
)
(
-3
,
3
,
.5
)
;
draw_axis
;
1220
\stopuseMPgraphic
1221 1222
\ShowInfo
{
pow
}
{
Calculate
x
\high
{
y
}
where
y
is
the
topmost
stack
entry
.
}
1223 1224
\startuseMPgraphic
{
inv
}
1225
draw_function
(
inv
)
(
-10
,
10
,
1
)
;
draw_axis
;
1226
\stopuseMPgraphic
1227 1228
\ShowInfo
{
inv
}
{
Calculate
1
/
x
using
the
topmost
stack
entry
.
}
1229 1230
\startMPinclusions
1231 1232
def
draw_statistics
(
expr
ShowNew
,
ShowAdd
,
ShowSubtract
,
ShowN
,
ShowSum
,
ShowMin
,
ShowMax
,
ShowMean
,
ShowSdev
)
=
1233
color
c
;
c
:
=
\MPcolor
{
action
}
;
1234
Delta
:
=
20
;
1235
Total
:
=
100
;
1236
Range
:
=
24
;
1237
Sum
:
=
0
;
1238
Sqr
:
=
0
;
1239
randomseed
:
=
.5
;
1240
pickup
pencircle
scaled
.5
Delta
;
1241
for
r
:
=
0
upto
Range
:
1242
Value
[
r
]
:
=
0
;
1243
endfor
;
1244
for
i
=
1
upto
Total
:
1245
r
:
=
uniformdeviate
1
;
1246
Sum
:
=
Sum
+
r
;
1247
Sqr
:
=
Sqr
+
r
*
r
;
1248
r
:
=
round
(
r
*
Range
)
;
1249
Value
[
r
]
:
=
Value
[
r
]
+1
;
1250
endfor
;
1251
Mean
:
=
Sum
/
Total
;
1252
Sdev
:
=
sqrt
(
(
Sqr
-2
*
Sum
*
Mean
+
Total
*
Mean
*
Mean
)
/
Total
)
;
1253
Mean
:
=
Mean
*
Range
;
1254
Sdev
:
=
Sdev
*
Range
;
1255
SdevMin
:
=
Mean
-
Sdev
;
1256
SdevMax
:
=
Mean
+
Sdev
;
1257
for
r
:
=
0
upto
Range
:
1258
draw
(
r
*
Delta
,
0
)
--
(
r
*
Delta
,
Value
[
r
]
*
Delta
)
1259
withcolor
1260
if
(
ShowSdev
and
(
r
>
SdevMin
)
and
(
r
<
SdevMax
)
)
or
ShowSum
or
1261
(
ShowMin
and
(
r
=
0
)
)
or
(
ShowMax
and
(
r
=
Range
)
)
or
1262
(
ShowMean
and
(
r
=
round
(
Mean
)
)
or
ShowSubtract
)
:
1263
c
1264
else
:
1265
.4
white
1266
fi
;
1267
if
ShowN
:
1268
draw
(
r
*
Delta
,
0
)
withcolor
c
1269
fi
;
1270
endfor
;
1271
if
ShowAdd
or
ShowNew
:
1272
pushboundingbox
currentpicture
;
1273
currentpicture
:
=
nullpicture
;
1274
for
r
:
=
0
upto
Range
:
1275
draw
(
r
*
Delta
,
0
)
withcolor
.4
white
;
1276
endfor
;
1277
if
ShowAdd
:
1278
draw
(
5
*
Delta
,
0
)
withcolor
c
;
1279
fi
;
1280
popboundingbox
currentpicture
;
1281
elseif
ShowSubtract
:
1282
draw
(
5
*
Delta
,
0
)
withcolor
.4
white
;
1283
fi
;
1284
enddef
;
1285 1286
\stopMPinclusions
1287 1288
\startuseMPgraphic
{
addn
}
1289
draw_statistics
(
false
,
true
,
false
,
false
,
false
,
false
,
false
,
false
,
false
)
;
1290
\stopuseMPgraphic
1291 1292
\ShowInfo
{
addn
}
{
Add
an
observation
to
the
statistics
.
}
1293 1294
\startuseMPgraphic
{
subn
}
1295
draw_statistics
(
false
,
false
,
true
,
false
,
false
,
false
,
false
,
false
,
false
)
;
1296
\stopuseMPgraphic
1297 1298
\ShowInfo
{
subn
}
{
Remove
an
observation
from
the
statistics
.
}
1299 1300
\startuseMPgraphic
{
newn
}
1301
draw_statistics
(
true
,
false
,
false
,
false
,
false
,
false
,
false
,
false
,
false
)
;
1302
\stopuseMPgraphic
1303 1304
\ShowInfo
{
newn
}
{
Reset
the
statistics
.
}
1305 1306
\startuseMPgraphic
{
sn
}
1307
draw_statistics
(
false
,
false
,
false
,
true
,
false
,
false
,
false
,
false
,
false
)
;
1308
\stopuseMPgraphic
1309 1310
\ShowInfo
{
sn
}
{
Push
the
number
of
observations
to
the
stack
.
}
1311 1312
\startuseMPgraphic
{
stotal
}
1313
draw_statistics
(
false
,
false
,
false
,
false
,
true
,
false
,
false
,
false
,
false
)
;
1314
\stopuseMPgraphic
1315 1316
\ShowInfo
{
stotal
}
{
Push
the
sum
of
encountered
values
to
the
stack
.
}
1317 1318
\startuseMPgraphic
{
smin
}
1319
draw_statistics
(
false
,
false
,
false
,
false
,
false
,
true
,
false
,
false
,
false
)
;
1320
\stopuseMPgraphic
1321 1322
\ShowInfo
{
smin
}
{
Push
the
lowest
encountered
value
to
the
stack
.
}
1323 1324
\startuseMPgraphic
{
smax
}
1325
draw_statistics
(
false
,
false
,
false
,
false
,
false
,
false
,
true
,
false
,
false
)
;
1326
\stopuseMPgraphic
1327 1328
\ShowInfo
{
smax
}
{
Push
the
highest
encountered
value
to
the
stack
.
}
1329 1330
\startuseMPgraphic
{
smean
}
1331
draw_statistics
(
false
,
false
,
false
,
false
,
false
,
false
,
false
,
true
,
false
)
;
1332
\stopuseMPgraphic
1333 1334
\ShowInfo
{
smean
}
{
Push
the
mean
value
to
the
stack
.
}
1335 1336
\startuseMPgraphic
{
ssdev
}
1337
draw_statistics
(
false
,
false
,
false
,
false
,
false
,
false
,
false
,
false
,
true
)
;
1338
\stopuseMPgraphic
1339 1340
\ShowInfo
{
ssdev
}
{
Push
the
standard
deviation
to
the
stack
.
}
1341 1342
\startMPinclusions
1343 1344
def
draw_ranges
(
expr
ShowNegate
,
ShowCeiling
,
ShowFloor
,
ShowRound
,
ShowMin
,
ShowMax
,
ShowE
)
=
1345 1346
color
c
;
c
:
=
\MPcolor
{
action
}
;
1347 1348
Tics
:
=
5
;
1349
Gap
:
=
5
Tics
;
1350
Height
:
=
.5
Gap
;
1351
Place
:
=
3
;
1352 1353
pickup
pencircle
scaled
10
;
1354 1355
for
i
=
-
Tics
upto
Tics
:
1356
draw
(
i
*
Gap
,
-
Height
)
--
(
i
*
Gap
,
Height
)
withcolor
.4
white
;
1357
endfor
;
1358 1359
draw
(
-
Tics
*
Gap
,
0
)
--
(
Tics
*
Gap
,
0
)
withcolor
.4
white
;
1360
draw
(
0
,
-2
Height
)
--
(
0
,
2
Height
)
withcolor
.4
white
;
1361 1362
z
1
=
(
Place
*
Gap
,
0
)
;
1363
z
2
=
(
(
Place
+1
)
*
Gap
,
0
)
;
1364 1365
if
ShowNegate
:
1366
draw
(
x
1
,
-
Height
)
--
(
x
1
,
Height
)
withcolor
c
;
1367
draw
(
-
x
1
,
-0
)
--
(
-
x
1
,
0
)
withcolor
c
;
1368
elseif
ShowCeiling
:
1369
draw
(
x
2
,
-
Height
)
--
(
x
2
,
Height
)
withcolor
c
;
1370
linecap
:
=
butt
;
1371
draw
z
1
-
-
z
2
withcolor
c
;
1372
elseif
ShowFloor
:
1373
draw
(
x
1
,
-
Height
)
--
(
x
1
,
Height
)
withcolor
c
;
1374
linecap
:
=
butt
;
1375
draw
z
1
-
-
z
2
withcolor
c
;
1376
elseif
ShowRound
:
1377
draw
(
x
2
,
-
Height
)
--
(
x
2
,
Height
)
withcolor
c
;
1378
linecap
:
=
butt
;
1379
draw
.5
[
z
1
,
z
2
]
-
-
z
2
withcolor
c
;
1380
elseif
ShowMin
:
1381
draw
(
x
1
,
-
Height
)
--
(
x
1
,
Height
)
withcolor
c
;
1382
draw
(
x
2
,
0
)
--
(
x
2
,
0
)
withcolor
c
;
1383
elseif
ShowMax
:
1384
draw
(
x
2
,
-
Height
)
--
(
x
2
,
Height
)
withcolor
c
;
1385
draw
(
x
1
,
0
)
--
(
x
1
,
0
)
withcolor
c
;
1386
elseif
ShowE
:
1387
e
:
=
Gap
*
mexp
256
;
1388
draw
(
e
,
-3
Height
)
--
(
e
,
3
Height
)
withcolor
c
;
1389
fi
;
1390 1391
enddef
;
1392 1393
\stopMPinclusions
1394 1395
\startuseMPgraphic
{
neg
}
1396
draw_ranges
(
true
,
false
,
false
,
false
,
false
,
false
,
false
)
;
1397
\stopuseMPgraphic
1398 1399
\ShowInfo
{
neg
}
{
Negate
the
topmost
stack
entry
.
}
1400 1401
\startuseMPgraphic
{
ceil
}
1402
draw_ranges
(
false
,
true
,
false
,
false
,
false
,
false
,
false
)
;
1403
\stopuseMPgraphic
1404 1405
\ShowInfo
{
ceil
}
{
Set
the
topmost
stack
entry
to
the
next
integer
.
}
1406 1407
\startuseMPgraphic
{
floor
}
1408
draw_ranges
(
false
,
false
,
true
,
false
,
false
,
false
,
false
)
;
1409
\stopuseMPgraphic
1410 1411
\ShowInfo
{
floor
}
{
Set
the
topmost
stack
entry
to
the
previous
integer
.
}
1412 1413
\startuseMPgraphic
{
round
}
1414
draw_ranges
(
false
,
false
,
false
,
true
,
false
,
false
,
false
)
;
1415
\stopuseMPgraphic
1416 1417
\ShowInfo
{
round
}
{
Set
the
topmost
stack
entry
to
the
nearest
integer
.
}
1418 1419
\startuseMPgraphic
{
min
}
1420
draw_ranges
(
false
,
false
,
false
,
false
,
true
,
false
,
false
)
;
1421
\stopuseMPgraphic
1422 1423
\ShowInfo
{
min
}
{
Take
the
minumum
of
the
two
topmost
stack
entries
.
}
1424 1425
\startuseMPgraphic
{
max
}
1426
draw_ranges
(
false
,
false
,
false
,
false
,
false
,
true
,
false
)
;
1427
\stopuseMPgraphic
1428 1429
\ShowInfo
{
max
}
{
Take
the
maximum
of
the
two
topmost
stack
entries
.
}
1430 1431
\startuseMPgraphic
{
e
}
1432
draw_ranges
(
false
,
false
,
false
,
false
,
false
,
false
,
true
)
;
1433
\stopuseMPgraphic
1434 1435
\ShowInfo
{
e
}
{
Push
2
.
7
1
8
2
8
1
8
2
8
4
5
9
0
5
onto
the
stack
.
}
1436 1437
\startuseMPgraphic
{
pi
}
1438
pickup
pencircle
scaled
10
;
1439
draw
fullcircle
scaled
150
withcolor
.4
white
;
1440
linecap
:
=
butt
;
1441
ahlength
:
=
25
;
1442
drawarrow
halfcircle
scaled
150
withcolor
\MPcolor
{
action
}
;
1443
\stopuseMPgraphic
1444 1445
\ShowInfo
{
pi
}
{
Push
3
.
1
4
1
5
9
2
6
5
3
5
8
9
7
9
onto
the
stack
.
}
1446 1447
\startMPinclusions
1448 1449
def
draw_degrees
(
expr
DrawInner
,
DrawOuter
)
=
1450
pickup
pencircle
scaled
.02
;
1451
path
p
;
p
:
=
fullcircle
;
1452
path
q
;
q
:
=
subpath
(
0
,
1
)
of
fullcircle
;
1453
path
r
;
r
:
=
(
0
,
0
)
-
-
q
--
(
0
,
0
)
-
-
cycle
;
1454
filldraw
p
withcolor
.4
white
;
1455
filldraw
r
withcolor
\MPcolor
{
action
}
;
1456
ahlength
:
=
.04
;
1457
if
DrawInner
:
1458
drawarrow
q
scaled
.30
withcolor
.4
white
;
1459
elseif
DrawOuter
:
1460
drawarrow
q
scaled
.90
withcolor
.4
white
;
1461
fi
;
1462
currentpicture
:
=
currentpicture
scaled
200
;
1463
enddef
;
1464 1465
\stopMPinclusions
1466 1467
\startuseMPgraphic
{
deg
}
1468
draw_degrees
(
true
,
false
)
1469
\stopuseMPgraphic
1470 1471
\ShowInfo
{
deg
}
{
Convert
radians
into
degrees
.
}
1472 1473
\startuseMPgraphic
{
rad
}
1474
draw_degrees
(
false
,
true
)
1475
\stopuseMPgraphic
1476 1477
\ShowInfo
{
rad
}
{
Convert
degrees
into
radians
.
}
1478 1479
\startuseMPgraphic
{
random
}
1480 1481
pickup
pencircle
scaled
5
;
1482
color
c
;
c
:
=
\MPcolor
{
action
}
;
1483
draw
unitsquare
scaled
100
withcolor
.4
white
;
1484
for
i
=
1
upto
250
:
1485
draw
(
uniformdeviate
90
,
uniformdeviate
90
)
1486
shifted
(
5
,
5
)
withcolor
(
.4
+
uniformdeviate
.6
)
*
c
;
1487
endfor
;
1488
currentpicture
:
=
currentpicture
scaled
2
;
1489 1490
\stopuseMPgraphic
1491 1492
\ShowInfo
{
random
}
{
Generate
a
random
number
in
the
range
0
-
-
1
.
}
1493 1494
\startMPinclusions
1495 1496
def
do_draw_number
(
expr
n
,
drift
,
s
,
c
)
=
1497
numeric
Height
,
Delta
,
Drift
,
x_max
,
y_max
,
x_pos
,
y_pos
;
1498
Height
:
=
11
;
1499
Delta
:
=
5
;
1500
Drift
:
=
if
drift
:
1.5
else
:
0
fi
;
1501
x_max
:
=
8
;
1502
def
d
=
(
uniformdeviate
Drift
)
enddef
;
1503
if
n
=
0
:
1504
draw
(
(
-
d
-4.5
Delta
,
d
)
--
(
+
d
-0.5
Delta
,
Height
-
d
)
)
1505
withpen
pencircle
scaled
2
1506
withcolor
c
;
1507
else
:
1508
for
i
:
=
1
upto
n
:
1509
x_pos
:
=
(
(
i
-1
)
mod
(
5
*
x_max
)
)
*
Delta
;
1510
y_pos
:
=
(
(
i
-1
)
div
(
5
*
x_max
)
)
*
(
Height
+
Delta
)
;
1511
draw
1512
if
(
i
mod
5
)
=
0
:
1513
(
(
-
d
-4.5
Delta
,
d
)
--
(
+
d
-0.5
Delta
,
Height
-
d
)
)
1514
else
:
1515
(
(
-
d
,
+
d
)
--
(
+
d
,
Height
-
d
)
)
1516
fi
1517
shifted
(
x_pos
,
-
y_pos
)
1518
withpen
pencircle
scaled
2
1519
withcolor
c
;
1520
endfor
;
1521
fi
;
1522
currentpicture
:
=
currentpicture
scaled
s
;
1523
enddef
;
1524 1525
def
draw_number
(
expr
n
,
s
)
=
1526
do_draw_number
(
n
,
false
,
s
,
\MPcolor
{
keyboard
}
)
;
1527
push_boundingbox
currentpicture
;
1528
currentpicture
:
=
nullpicture
;
1529
do_draw_number
(
n
,
true
,
s
,
\MPcolor
{
keyboard
}
)
;
1530
pop_boundingbox
currentpicture
;
1531
enddef
;
1532 1533
\stopMPinclusions
1534 1535
\dostepwiserecurse
{
0
}
{
9
}
{
1
}
{
1536
\startuseMPgraphic
{
\recurselevel
}
1537
draw_number
(
\recurselevel
,
10
)
1538
\stopuseMPgraphic
1539
\expanded
{
1540
\ShowInfo
1541
{
\recurselevel
}
1542
{
Add
a
digit
\recurselevel
\
to
the
current
stack
entry
.
}
%
1543
}
1544
}
1545 1546
\startuseMPgraphic
{
fac
}
1547 1548
def
facultate
(
expr
n
)
=
1549
if
n
=
1
:
1
else
:
n
*
facultate
(
n
-1
)
fi
1550
enddef
;
1551
picture
pic
[
]
;
1552
for
m
:
=
1
upto
5
:
1553
do_draw_number
(
facultate
(
m
)
,
true
,
1
,
\MPcolor
{
action
}
)
;
1554
pic
[
m
]
:
=
currentpicture
;
1555
currentpicture
:
=
nullpicture
;
1556
endfor
;
1557
xmax
:
=
xpart
urcorner
pic
[
5
]
-
xpart
llcorner
pic
[
5
]
;
1558
for
m
=
1
upto
5
:
1559
xmin
:
=
xpart
urcorner
pic
[
m
]
-
xpart
llcorner
pic
[
m
]
;
1560
addto
currentpicture
also
pic
[
m
]
shifted
(
.5
(
xmax
-
xmin
)
,
-
m
*
25
)
;
1561
endfor
;
1562
currentpicture
:
=
currentpicture
scaled
2
;
1563 1564
\stopuseMPgraphic
1565 1566
\ShowInfo
{
fac
}
{
Calculate
the
recursive
multiplication
of
n
,
n
-
-
1
,
n
-
-
2
,
etc
.
}
1567 1568
\startMPinclusions
1569 1570
def
draw_template
(
expr
ShowSign
,
ShowPeriod
,
ShowExponent
,
ShowDel
)
=
1571
pickup
pencircle
scaled
10
;
1572
color
ca
;
ca
:
=
if
(
ShowDel
)
:
.4
white
else
:
\MPcolor
{
stack
}
fi
;
1573
color
cb
;
cb
:
=
\MPcolor
{
keyboard
}
;
1574
Delta
:
=
20
;
1575
Width
:
=
10
;
1576
Position
:
=
6
;
1577
Max
:
=
15
;
1578
path
p
;
p
:
=
(
0
,
0
)
--
(
Width
,
0
)
;
1579
draw
(
-2
Width
,
0
)
--
(
0
,
0
)
withcolor
if
ShowSign
:
cb
else
:
ca
fi
;
1580
for
i
=
1
upto
Position
-1
:
1581
draw
p
shifted
(
i
*
Delta
,
0
)
withcolor
ca
;
1582
endfor
;
1583
draw
(
Position
*
Delta
+.5
Width
,
0
)
1584
withcolor
if
ShowPeriod
:
cb
else
:
ca
fi
;
1585
for
i
=
Position
+1
upto
Max
:
1586
if
i
=
Max
-3
:
1587
draw
(
(
Width
,
0
)
--
(
0
,
0
)
--
(
0
,
2
Width
)
--
(
Width
,
2
Width
)
)
1588
shifted
(
i
*
Delta
,
-2.5
)
1589
withpen
pencircle
scaled
5
1590
withcolor
if
ShowExponent
:
cb
else
:
ca
fi
;
1591
draw
(
(
0
,
Width
)
--
(
Width
,
Width
)
)
1592
shifted
(
i
*
Delta
,
-2.5
)
1593
withpen
pencircle
scaled
5
1594
withcolor
if
ShowExponent
:
cb
else
:
ca
fi
;
1595
else
:
1596
draw
p
shifted
(
i
*
Delta
,
0
)
withcolor
ca
;
1597
fi
;
1598
endfor
;
1599
enddef
;
1600 1601
\stopMPinclusions
1602 1603
\startuseMPgraphic
{
sign
}
1604
draw_template
(
true
,
false
,
false
,
false
)
;
1605
\stopuseMPgraphic
1606 1607
\ShowInfo
{
sign
}
{
Add
a
sign
to
the
current
stack
entry
.
}
1608 1609
\startuseMPgraphic
{
period
}
1610
draw_template
(
false
,
true
,
false
,
false
)
;
1611
\stopuseMPgraphic
1612 1613
\ShowInfo
{
period
}
{
Add
a
period
to
the
current
stack
entry
.
}
1614 1615
\startuseMPgraphic
{
E
}
1616
draw_template
(
false
,
false
,
true
,
false
)
;
1617
\stopuseMPgraphic
1618 1619
\ShowInfo
{
E
}
{
Start
setting
the
exponent
part
of
the
current
stack
entry
.
}
1620 1621
\startuseMPgraphic
{
del
}
1622
draw_template
(
false
,
false
,
false
,
true
)
;
1623
\stopuseMPgraphic
1624 1625
\ShowInfo
{
del
}
{
Delete
the
last
entered
digit
of
the
current
stack
entry
.
}
1626 1627
\startMPinclusions
1628 1629
u
:
=
50
;
1630
logo_type
:
=
0
;
1631
input
mp
-
prag
;
1632
set_phead
(
u
)
;
1633 1634
def
draw_memory
(
expr
DrawErase
,
DrawAdd
,
DrawSubtract
,
DrawCopy
)
=
1635
pickup
pencircle
scaled
.1
u
;
1636
color
ca
;
ca
:
=
\MPcolor
{
stack
}
;
1637
color
cb
;
cb
:
=
\MPcolor
{
keyboard
}
;
1638
draw
phead
withcolor
.4
white
;
1639
if
DrawErase
:
1640
stripe_path_n
1641
(
withcolor
.4
white
)
1642
(
fill
)
pbrain
scaled
.8
shifted
(
.5
u
,
.5
u
)
withcolor
.8
cb
;
1643
else
:
1644
fill
pbrain
scaled
.8
shifted
(
.5
u
,
.5
u
)
1645
if
DrawCopy
:
withcolor
.8
ca
else
:
withcolor
.8
cb
fi
;
1646
fi
;
1647
draw
pbrain
scaled
.8
shifted
(
.5
u
,
.5
u
)
withcolor
cb
;
1648
push_boundingbox
currentpicture
;
1649
ahlength
:
=
.2
u
;
1650
path
drain
;
drain
:
=
(
4.5
u
,
2
u
)
{
dir
120
}
..
(
2.25
u
,
2.75
u
)
;
1651
if
DrawAdd
:
1652
drawarrow
drain
withcolor
ca
;
1653
elseif
DrawSubtract
or
DrawCopy
:
1654
drawarrow
reverse
drain
withcolor
ca
;
1655
fi
;
1656
pop_boundingbox
currentpicture
;
1657
enddef
;
1658 1659
\stopMPinclusions
1660 1661
\startuseMPgraphic
{
newmem
}
1662
draw_memory
(
true
,
false
,
false
,
false
)
;
1663
\stopuseMPgraphic
1664 1665
\ShowInfo
{
newmem
}
{
Erase
the
memory
buffer
.
}
1666 1667
\startuseMPgraphic
{
addmem
}
1668
draw_memory
(
false
,
true
,
false
,
false
)
;
1669
\stopuseMPgraphic
1670 1671
\ShowInfo
{
addmem
}
{
Add
to
the
memory
buffer
.
}
1672 1673
\startuseMPgraphic
{
submem
}
1674
draw_memory
(
false
,
false
,
true
,
false
)
;
1675
\stopuseMPgraphic
1676 1677
\ShowInfo
{
submem
}
{
Substract
from
the
memory
buffer
.
}
1678 1679
\startuseMPgraphic
{
copmem
}
1680
draw_memory
(
false
,
false
,
false
,
true
)
;
1681
\stopuseMPgraphic
1682 1683
\ShowInfo
{
copmem
}
{
Copy
the
memory
buffer
to
the
stack
.
}
1684 1685
\startMPinclusions
1686 1687
def
erase_stack
=
1688
stripe_path_n
1689
(
withcolor
.4
white
)
1690
(
fill
)
p
withcolor
.8
cb
;
1691
enddef
;
1692 1693
def
draw_stack
(
expr
ShowNew
,
ShowPush
,
ShowPop
,
ShowDup
)
=
1694
path
p
;
1695
color
ca
;
ca
:
=
\MPcolor
{
stack
}
;
1696
color
cb
;
cb
:
=
\MPcolor
{
keyboard
}
;
1697
for
i
=
8
downto
1
:
1698
j
:
=
i
-1
;
1699
pickup
pencircle
scaled
1.5
;
1700
p
:
=
unitsquare
1701
shifted
(
-.5
,
-.5
)
1702
xscaled
100
yscaled
40
1703
shifted
(
20
*
j
,
j
*
15
)
1704
scaled
(
1
-
j
*
.04
)
;
1705
if
i
<
3
:
1706
fill
p
withcolor
.4
white
;
1707
elseif
ShowPush
:
1708
fill
p
withcolor
if
i
=
3
:
.8
cb
else
:
.8
ca
fi
;
1709
elseif
ShowPop
:
1710
if
i
=
3
:
erase_stack
else
:
fill
p
withcolor
.8
ca
fi
;
1711
elseif
ShowNew
:
1712
erase_stack
;
1713
elseif
ShowDup
:
1714
fill
p
withcolor
if
i
>
4
:
.8
ca
else
:
.8
cb
fi
;
1715
else
:
1716
fill
p
withcolor
.4
white
;
1717
fi
;
1718
draw
p
withcolor
ca
;
1719
endfor
;
1720
currentpicture
:
=
currentpicture
scaled
1.5
;
1721
enddef
;
1722 1723
\stopMPinclusions
1724 1725
\startuseMPgraphic
{
push
}
1726
draw_stack
(
false
,
true
,
false
,
false
)
1727
\stopuseMPgraphic
1728 1729
\ShowInfo
{
push
}
{
Push
a
new
entry
to
the
stack
.
}
1730 1731
\startuseMPgraphic
{
pop
}
1732
draw_stack
(
false
,
false
,
true
,
false
)
1733
\stopuseMPgraphic
1734 1735
\ShowInfo
{
pop
}
{
Remove
the
topmost
entry
from
the
stack
.
}
1736 1737
\startuseMPgraphic
{
new
}
1738
draw_stack
(
true
,
false
,
false
,
false
)
1739
\stopuseMPgraphic
1740 1741
\ShowInfo
{
new
}
{
Erase
the
whole
stack
.
}
1742 1743
\startuseMPgraphic
{
dup
}
1744
draw_stack
(
false
,
false
,
false
,
true
)
1745
\stopuseMPgraphic
1746 1747
\ShowInfo
{
dup
}
{
Duplicate
the
topmost
stack
entry
.
}
1748 1749
\startMPinclusions
1750 1751
def
draw_funcalc
(
expr
p
,
q
,
r
,
action
)
=
1752 1753
color
b
;
b
:
=
\MPcolor
{
keyboard
}
;
1754
color
c
;
c
:
=
\MPcolor
{
stack
}
;
1755 1756
draw
(
(
-2.25
max
(
p
,
q
,
r
)
)
-1
,
0
)
--
(
-1
,
0
)
withcolor
.4
white
;
1757 1758
pickup
pencircle
scaled
2
;
1759
for
i
=
1
upto
p
:
draw
(
-
i
*
2.25
,
3.75
)
withcolor
c
;
endfor
;
1760
for
i
=
1
upto
q
:
draw
(
-
i
*
2.25
,
1.50
)
withcolor
c
;
endfor
;
1761
for
i
=
1
upto
r
:
draw
(
-
i
*
2.25
,
-1.50
)
withcolor
c
;
endfor
;
1762
pickup
pencircle
scaled
.5
;
1763 1764
push_boundingbox
currentpicture
;
1765 1766
pair
w
;
w
:
=
(
1.125
,
0
)
;
1767
path
ww
;
ww
:
=
-
w
--
w
;
1768 1769
if
action
=
1
:
1770
draw
ww
shifted
w
withcolor
b
;
1771
draw
ww
rotated
90
shifted
w
withcolor
b
;
1772
elseif
action
=
2
:
1773
draw
ww
shifted
w
withcolor
b
;
1774
elseif
action
=
3
:
1775
draw
ww
rotated
45
shifted
w
withcolor
b
;
1776
draw
ww
rotated
135
shifted
w
withcolor
b
;
1777
elseif
action
=
4
:
1778
draw
ww
rotated
45
shifted
w
withcolor
b
;
1779
fi
;
1780 1781
pop_boundingbox
currentpicture
;
1782 1783
currentpicture
:
=
currentpicture
scaled
15
;
1784 1785
enddef
;
1786 1787
\stopMPinclusions
1788 1789
\startuseMPgraphic
{
add
}
1790
draw_funcalc
(
6
,
6
,
7
,
1
)
1791
\stopuseMPgraphic
1792 1793
\ShowInfo
{
add
}
{
Add
the
two
topmost
stack
entries
.
}
1794 1795
\startuseMPgraphic
{
sub
}
1796
draw_funcalc
(
5
,
4
,
5
,
2
)
1797
\stopuseMPgraphic
1798 1799
\ShowInfo
{
sub
}
{
Subtract
the
topmost
stack
entry
from
the
one
below
.
}
1800 1801
\startuseMPgraphic
{
mul
}
1802
draw_funcalc
(
3
,
4
,
7
,
3
)
1803
\stopuseMPgraphic
1804 1805
\ShowInfo
{
mul
}
{
Multiply
the
two
topmost
stack
entries
.
}
1806 1807
\startuseMPgraphic
{
div
}
1808
draw_funcalc
(
5
,
2
,
4
,
4
)
1809
\stopuseMPgraphic
1810 1811
\ShowInfo
{
div
}
{
Divide
the
pre
-
last
stack
entry
by
the
topmost
one
.
}
1812 1813
\startuseMPgraphic
{
grow
}
1814 1815
pickup
pencircle
scaled
5
;
1816
ahlength
:
=
10
;
1817 1818
path
p
;
p
:
=
(
0
,
0
)
--
(
60
,
0
)
;
1819
path
q
;
q
:
=
(
30
,
2
*
15
)
--
(
30
,
7
*
15
)
;
1820
path
r
;
r
:
=
(
30
,
0
)
--
(
30
,
7
*
15
)
;
1821 1822
for
i
=
0
upto
7
:
1823
draw
p
shifted
(
0
,
i
*
15
)
withcolor
1824
if
i
<
3
:
\MPcolor
{
stack
}
else
:
.4
white
fi
;
1825
endfor
;
1826 1827
addto
currentpicture
also
currentpicture
1828
rotatedaround
(
center
currentpicture
,
180
)
1829
shifted
(
90
,
0
)
;
1830 1831
drawarrow
q
withcolor
\MPcolor
{
keyboard
}
;
1832
drawarrow
reverse
r
shifted
(
90
,
0
)
withcolor
\MPcolor
{
keyboard
}
;
1833 1834
currentpicture
:
=
currentpicture
scaled
2
;
1835 1836
\stopuseMPgraphic
1837 1838
\ShowInfo
{
grow
}
{
Toggle
grow
mode
,
another
way
of
stacking
.
}
1839 1840
\startuseMPgraphic
{
exit
}
1841 1842
path
p
;
p
:
=
(
100
,
30
)
--
(
100
,
0
)
--
(
0
,
0
)
--
(
0
,
100
)
--
(
100
,
100
)
--
(
100
,
70
)
;
1843
pickup
pencircle
scaled
10
;
1844
linecap
:
=
butt
;
1845
ahlength
:
=
60
;
1846
ahangle
:
=
75
;
1847
filldraw
1848
p
-
-
cycle
1849
withcolor
\MPcolor
{
action
}
;
1850
draw
1851
p
1852
withcolor
\MPcolor
{
stack
}
;
1853
push_boundingbox
currentpicture
;
1854
pickup
pencircle
scaled
30
;
1855
draw
1856
center
currentpicture
--
1857
(
xpart
lrcorner
currentpicture
+.75
ahlength
,
ypart
center
currentpicture
)
1858
withcolor
\MPcolor
{
keyboard
}
;
1859
pickup
pencircle
scaled
5
;
1860
drawarrow
1861
center
currentpicture
--
1862
(
xpart
lrcorner
currentpicture
,
ypart
center
currentpicture
)
1863
withcolor
\MPcolor
{
keyboard
}
;
1864
pop_boundingbox
currentpicture
;
1865
currentpicture
:
=
currentpicture
scaled
1.75
;
1866 1867
\stopuseMPgraphic
1868 1869
\ShowInfo
{
exit
}
{
Close
this
document
.
}
1870 1871
\stoptext
1872