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
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
|
include "vex.h"
# VEX_STACK -- Procedures which manipulate the vex stack
#
# The expression evaluator, vex_eval, uses a stack to hold intermediate
# results, constants, and variable names in the expression. There are
# actually two stacks, a type stack wich contains the data types of the
# elements on the stack, and a value stack, which contains pointers to
# the stack elements. Constants and variable names are stored in two
# buffers which are part of the stack structure and pointers to their
# locations are placed on the stack. Intermediate results are stored in
# malloc'ed arrays and their pointers are also placed on the stack. The
# stack structure contains three indices, bottom, an index one greater
# than the last constant or variable name, top, an index that is one
# greater than the current top of stack, and high, an index that is one
# greater than the last valid pointer on the stack. Valid pointers exist
# beyond the top of stack because the arrays which store intermediate
# results are not mfree'd when the stack is popped, instead, they are
# kept in case they may be needed for a future intermediate result. The
# only user callable procedure in this file is stk_alloc, which should
# be called by getvar, the user's function which fills an array when
# passed the name of a variable.
#
# B.Simon 24-Apr-91 Original
# B.Simon 15-Oct-98 Store strings in pseudocode, not on stack
# STK_ALLOC -- Allocate an array of the specified length and type
pointer procedure stk_alloc (stack, len, type)
pointer stack # i: Stack structure
int len # i: Length of array to allocate
int type # i: Data type of array (spp type)
#--
int index, stype, top
pointer var, svar
string badstack "stk_alloc: illegal type on stack"
string badsize "Requested array size does not match previous requests"
errchk stk_find
begin
# Check to see if array length is being defined for the first time
if (STK_LENVAL(stack) == 0 && len != 0) {
# Store length in stack structure
STK_LENVAL(stack) = len
# Free all stack arrays not currently being used
index = STK_TOP(stack)
while (index < STK_HIGH(stack)) {
svar = STK_VALUE(stack,index)
stype = STK_TYPE(stack,index)
call mfree (svar, stype)
index = index + 1
}
STK_HIGH(stack) = STK_TOP(stack)
# Reallocate the null buffer
if (STK_NULLARY(stack) != NULL) {
call stk_freenull (stack)
call stk_initnull (stack, true)
}
# Convert length one arrays to their full length
index = 0
while (index < STK_TOP(stack)) {
svar = STK_VALUE(stack,index)
stype = STK_TYPE(stack,index)
call malloc (var, len, stype)
STK_VALUE(stack,index) = var
switch (stype) {
case TY_INT,TY_LONG:
call amovki (Memi[svar], Memi[var], len)
call mfree (svar, TY_INT)
case TY_REAL:
call amovkr (Memr[svar], Memr[var], len)
call mfree (svar, TY_REAL)
case TY_DOUBLE:
call amovkd (Memd[svar], Memd[var], len)
call mfree (svar, TY_DOUBLE)
default:
call error (1, badstack)
}
index = index + 1
}
}
# Check requested size
if (len != 0 && len != STK_LENVAL(stack))
call error (1, badsize)
# Look for an existing array of the same type
call stk_find (stack, type, index)
# Increment top of stack pointer
top = STK_TOP(stack)
STK_TOP(stack) = top + 1
# Swap array with one currently at top of stack
if (top != index) {
stype = STK_TYPE(stack,top)
STK_TYPE(stack,top) = STK_TYPE(stack,index)
STK_TYPE(stack,index) = stype
svar = STK_VALUE(stack,top)
STK_VALUE(stack,top) = STK_VALUE(stack,index)
STK_VALUE(stack,index) = svar
}
var = STK_VALUE(stack,top)
return (var)
end
# STK_CLEAR -- Clear all stack elements above the bottom
procedure stk_clear (stack)
pointer stack # u: Stack pointer
#--
int index
begin
# Free all value arrays above the bottom of stack
index = 0
while (index < STK_HIGH(stack)) {
call mfree (STK_VALUE(stack,index), STK_TYPE(stack,index))
index = index + 1
}
# Free null array
call stk_freenull (stack)
# Reset scalars
STK_TOP(stack) = 0
STK_HIGH(stack) = 0
STK_LENVAL(stack) = 0
end
# STK_COERCE -- Coerce an array in the stack to the specified type
procedure stk_coerce (stack, pos, type, var)
pointer stack # i: Stack descriptor
int pos # i: Position of array in stack
int type # i: New type for array
pointer var # o: New pointer to array
#--
int index, last, stype, len, i
pointer svar
string underflow "stk_coerce: underflow in expression evaluator"
errchk stk_find
begin
# Convert relative to absolute position
if (pos == TOP) {
index = STK_TOP(stack) - 1
if (index < 0)
call error (1, underflow)
} else {
index = pos
}
# If type of array matches requested type, return pointer to array
# Otherwise, get new array and copy old array to it
if (type == STK_TYPE(stack,index)) {
var = STK_VALUE(stack,index)
} else {
# Find array of correct type
last = index
call stk_find (stack, type, index)
# Copy array, converting to new type
len = max (1, STK_LENVAL(stack))
var = STK_VALUE(stack,index)
stype = STK_TYPE(stack,last)
svar = STK_VALUE(stack,last)
switch (type) {
case TY_INT,TY_LONG:
switch (stype) {
case TY_INT,TY_LONG:
; # can't happen
case TY_REAL:
do i = 0, len-1 {
if (IS_INDEFR(Memr[svar+i])) {
Memi[var+i] = INDEFI
} else {
Memi[var+i] = Memr[svar+i]
}
}
case TY_DOUBLE:
do i = 0, len-1 {
if (IS_INDEFD(Memd[svar+i])) {
Memi[var+i] = INDEFI
} else {
Memi[var+i] = Memd[svar+i]
}
}
}
case TY_REAL:
switch (stype) {
case TY_INT,TY_LONG:
do i = 0, len-1 {
if (IS_INDEFI(Memi[svar+i])) {
Memr[var+i] = INDEFR
} else {
Memr[var+i] = Memi[svar+i]
}
}
case TY_REAL:
; # can't happen
case TY_DOUBLE:
do i = 0, len-1 {
if (IS_INDEFD(Memd[svar+i])) {
Memr[var+i] = INDEFR
} else {
Memr[var+i] = Memd[svar+i]
}
}
}
case TY_DOUBLE:
switch (stype) {
case TY_INT,TY_LONG:
do i = 0, len-1 {
if (IS_INDEFI(Memi[svar+i])) {
Memd[var+i] = INDEFD
} else {
Memd[var+i] = Memi[svar+i]
}
}
case TY_REAL:
do i = 0, len-1 {
if (IS_INDEFR(Memr[svar+i])) {
Memd[var+i] = INDEFD
} else {
Memd[var+i] = Memr[svar+i]
}
}
case TY_DOUBLE:
; # can't happen
}
}
# Swap position of new and old arrays on stack
STK_TYPE(stack,last) = STK_TYPE(stack,index)
STK_TYPE(stack,index) = stype
STK_VALUE(stack,last) = STK_VALUE(stack,index)
STK_VALUE(stack,index) = svar
}
end
# STK_FETCH -- Fetch the specified number of arrays from the stack
procedure stk_fetch (stack, nvar, var, len, type)
pointer stack # i: Stack descriptor
int nvar # i: Number of pointers requested
pointer var[ARB] # o: Array pointers
int len # o: Length of arrays
int type # o: Type of arrays
#--
int one, two, index, ivar
string underflow "stk_fetch: underflow in expression evaluator"
errchk stk_coerce
begin
# If length is not yet defined, STK_LENVAL equals zero
len = STK_LENVAL(stack)
# Find the highest type in the pointers to be returned
one = STK_TOP(stack) - 1
two = STK_TOP(stack) - 2
type = STK_TYPE(stack,one)
if (nvar > 1) {
switch (STK_TYPE(stack,two)) {
case TY_INT, TY_LONG:
;
case TY_REAL:
if (type == TY_INT)
type = TY_REAL
case TY_DOUBLE:
type = TY_DOUBLE
}
}
# Retrieve pointers to arrays from stack. var[nvar] is top of stack
# Convert arrays to output type when the type differs
index = STK_TOP(stack) - nvar
do ivar = 1, nvar {
if (index < 0)
call error (1, underflow)
if (type == STK_TYPE(stack,index) || index < two) {
var[ivar] = STK_VALUE(stack,index)
} else {
call stk_coerce (stack, index, type, var[ivar])
}
index = index + 1
}
end
# STK_FIND -- Find a free array of the proper type on the stack
procedure stk_find (stack, type, index)
pointer stack # i: Stack descriptor
int type # i: Required type
int index # o: Position on the stack
#--
int len
pointer var
string overflow "Expression too complex to be evaluated"
begin
# Try to find an array of the proper type already on the stack
index = STK_TOP(stack)
while (index < STK_HIGH(stack)) {
if (type == STK_TYPE(stack,index))
break
index = index + 1
}
# If not found, allocate a new array
if (index == MAX_STACK) {
call error (1, overflow)
} else if (index == STK_HIGH(stack)) {
len = max (1, STK_LENVAL(stack))
call malloc (var, len, type)
STK_TYPE(stack,index) = type
STK_VALUE(stack,index) = var
STK_HIGH(stack) = STK_HIGH(stack) + 1
}
end
# STK_FREE -- Free memory used by the stack
procedure stk_free (stack)
pointer stack # u: Stack pointer
#--
begin
# Free all values above the stack bottom
call stk_clear (stack)
# Free substructures in stack
if (STK_NULLARY(stack) != NULL)
call mfree (STK_NULLARY(stack), TY_BOOL)
call mfree (STK_VALARY(stack), TY_INT)
call mfree (STK_TYPARY(stack), TY_INT)
# Free the stack structure
call mfree (stack, TY_INT)
end
# STK_FREENULL -- Free the null array in the stack
procedure stk_freenull (stack)
pointer stack # u: Stack structure
#--
begin
if (STK_NULLARY(stack) != NULL)
call mfree (STK_NULLARY(stack), TY_BOOL)
STK_NULLARY(stack) = NULL
end
# STK_GET -- Get a single array from the stack
procedure stk_get (stack, pos, var, len, type)
pointer stack # i: Stack descriptor
int pos # i: Position on the stack
pointer var # o: Pointer to array
int len # o: Length of array
int type # o: Type of the array
#--
int index
string underflow "stk_get: underflow in expression evaluator"
begin
# Convert relative to absolute position
if (pos == TOP) {
index = STK_TOP(stack) - 1
if (index < 0)
call error (1, underflow)
} else {
index = pos
}
var = STK_VALUE(stack,index)
len = STK_LENVAL(stack)
type = STK_TYPE(stack,index)
end
# STK_GETNULL -- Get the null array from the stack
procedure stk_getnull (stack, nullvec)
pointer stack # i: Stack structure
pointer nullvec # o: Null array
#--
begin
nullvec = STK_NULLARY(stack)
end
# STK_INIT -- Initialize the stack
procedure stk_init (stack)
pointer stack # o: Stack pointer
#--
begin
# Allocate stack and initialize members to zero
call calloc (stack, SZ_STKSTRUCT, TY_INT)
# Allocate substructures in stack
call malloc (STK_VALARY(stack), MAX_STACK, TY_INT)
call malloc (STK_TYPARY(stack), MAX_STACK, TY_INT)
end
# STK_INITNULL -- Initialize the null array on the stack
procedure stk_initnull (stack, value)
pointer stack # u: Stack structure
bool value # i: Value used in initialization
#--
int len, i
pointer nullvec
begin
# Only initialize if array doesn't exist
if (STK_NULLARY(stack) == NULL) {
len = STK_LENVAL(stack)
# Allocate array
call malloc (nullvec, len, TY_BOOL)
STK_NULLARY(stack) = nullvec
# Initialize to value
do i = 0, len-1
Memb[nullvec+i] = value
}
end
# STK_ORNULL -- Update null array by doing a logical or
procedure stk_ornull (stack, newvec, newlen)
pointer stack # u: Stack structure
bool newvec[ARB] # i: Array of new values
int newlen # i: Length of new array
#--
int len, i
pointer nullvec
string badlength "stk_ornull: length of array does not match null array"
begin
len = STK_LENVAL(stack)
if (len != newlen)
call error (1, badlength)
call stk_initnull (stack, false)
nullvec = STK_NULLARY(stack)
do i = 1, len {
Memb[nullvec] = Memb[nullvec] || newvec[i]
nullvec = nullvec + 1
}
end
# STK_POP -- Remove the specified number of arrays from the stack
procedure stk_pop (stack, npop)
pointer stack # u: Stack structure
int npop # i: Number of arrays to pop
#--
int top, index, type
pointer var
string underflow "stk_pop: underflow in expression evaluator"
begin
top = STK_TOP(stack) - 1
index = top - npop
if (index < 0) {
call error (1, underflow)
} else {
STK_TOP(stack) = index + 1
}
var = STK_VALUE(stack,index)
STK_VALUE(stack,index) = STK_VALUE(stack,top)
STK_VALUE(stack,top) = var
type = STK_TYPE(stack,index)
STK_TYPE(stack,index) = STK_TYPE(stack,top)
STK_TYPE(stack,top) = type
end
# STK_POS -- Compute absolute position on stack
int procedure stk_pos (stack, pos)
pointer stack # i: Stack structure
int pos # i: Position relative to top of stack
#--
begin
return (STK_TOP(stack) - pos)
end
# STK_SETNULL -- Set a single value in the null array to true
procedure stk_setnull (stack, index)
pointer stack # u: Stack structure
int index # i: Index into null array
#--
begin
STK_NULL(stack,index) = true
end
|