Commit | Line | Data |
---|---|---|
0f4556f1 C |
1 | static char apl_h_Sccsid[] = "apl.h @(#)apl.h 1.4 7/3/83 Berkeley "; |
2 | /* | |
3 | * UNIX APL\11 | |
4 | * | |
5 | * | |
6 | * UNIX APL was originally written by Ken Thompson at Bell Labs. | |
7 | * It spent some time at Yale and finally arrived at Purdue | |
8 | * University. Since 1976 it has been modified by Jim Besemer | |
9 | * and John Bruner at the School of Electrical Engineering, Purdue, | |
10 | * under the direction of Dr. Anthony P. Reeves. It is currently | |
11 | * being developed and supported at Purdue/EE by J. Bruner and | |
12 | * A. Reeves on both PDP-11's and VAX-11/780's | |
13 | */ | |
14 | ||
15 | #include <sys/param.h> | |
16 | /* | |
17 | * New file system param.h defines MIN and MAX; we | |
18 | * have to undefine them to avoid conflicts | |
19 | */ | |
20 | #ifdef MIN | |
21 | # undef MIN | |
22 | #endif MIN | |
23 | #ifdef MAX | |
24 | # undef MAX | |
25 | #endif MAX | |
26 | ||
27 | #include <sys/stat.h> | |
28 | #include <sys/dir.h> | |
29 | #include <sys/time.h> | |
30 | #include <setjmp.h> | |
31 | ||
32 | /* | |
33 | * Configuration information | |
34 | * | |
35 | * The C preprocessor will automatically supply "vax" if APL is compiled | |
36 | * on a VAX-11/780. | |
37 | * | |
38 | * Other configuration parameters which may be specified are: | |
39 | * | |
40 | * PURDUE_EE enable special Purdue/EE code | |
41 | * VMUNIX enable code for Berkeley virtual UNIX stuff | |
42 | * VFORK use vfork() when possible (implied by VMUNIX) | |
43 | * VLIMIT use 4.1bsd vlimit() (implied by VMUNIX) | |
44 | * NDIR 4.2bsd directory format (implied by VMUNIX) | |
45 | * APL2 generate single-precision version | |
46 | */ | |
47 | ||
48 | #ifdef VMUNIX | |
49 | #define VLIMIT | |
50 | #define VFORK | |
51 | #endif | |
52 | ||
53 | #define NFDS 20 /* Number of available fd's */ | |
54 | #define MAXEOT 8 /* # of input EOT's before panic */ | |
55 | ||
56 | /* | |
57 | * Temp file names | |
58 | */ | |
59 | ||
60 | #define WSFILE ws_file /* work space file */ | |
61 | ||
62 | /* | |
63 | * Magic Numbers | |
64 | */ | |
65 | ||
66 | #define MRANK 8 | |
67 | #define CANBS 300 | |
68 | #define STKS 500 | |
69 | #define NLS 200 | |
70 | #define NAMS 40 | |
71 | #define OBJS 500 | |
72 | #define MAXLAB 30 | |
73 | ||
74 | #ifndef vax | |
75 | #ifdef APL2 | |
76 | #define MAGIC 0100555 /* PDP-11 single-precision format */ | |
77 | #else | |
78 | #define MAGIC 0100554 /* PDP-11 double-precision format */ | |
79 | #endif | |
80 | #else | |
81 | #ifdef APL2 | |
82 | #define MAGIC 0100557 /* VAX single-precision format */ | |
83 | #else | |
84 | #define MAGIC 0100556 /* VAX double-precision format */ | |
85 | #endif | |
86 | #endif | |
87 | ||
88 | #ifdef APL2 | |
89 | #define data float | |
90 | #else | |
91 | #define data double | |
92 | #endif | |
93 | ||
94 | /* | |
95 | * derived constants | |
96 | */ | |
97 | ||
98 | #define SDAT sizeof(data) | |
99 | #define SINT sizeof(int) | |
100 | ||
101 | /* | |
102 | * Interpreter Op Codes | |
103 | */ | |
104 | ||
105 | #define EOF (-1) | |
106 | #define EOL 0 | |
107 | ||
108 | #define ADD 1 | |
109 | #define PLUS 2 | |
110 | #define SUB 3 | |
111 | #define MINUS 4 | |
112 | #define MUL 5 | |
113 | #define SGN 6 | |
114 | #define DIV 7 | |
115 | #define RECIP 8 | |
116 | #define MOD 9 | |
117 | #define ABS 10 | |
118 | #define MIN 11 | |
119 | #define FLOOR 12 | |
120 | #define MAX 13 | |
121 | #define CEIL 14 | |
122 | #define PWR 15 | |
123 | #define EXP 16 | |
124 | #define LOG 17 | |
125 | #define LOGE 18 | |
126 | #define CIR 19 | |
127 | #define PI 20 | |
128 | #define COMB 21 | |
129 | #define FAC 22 | |
130 | ||
131 | #define DEAL 23 | |
132 | #define RAND 24 | |
133 | #define DRHO 25 | |
134 | #define MRHO 26 | |
135 | #define DIOT 27 | |
136 | #define MIOT 28 | |
137 | #define ROT0 29 | |
138 | #define REV0 30 | |
139 | #define DTRN 31 | |
140 | #define MTRN 32 | |
141 | #define DIBM 33 | |
142 | #define MIBM 34 | |
143 | ||
144 | #define GDU 35 | |
145 | #define GDUK 36 | |
146 | #define GDD 37 | |
147 | #define GDDK 38 | |
148 | #define EXD 39 | |
149 | #define SCAN 40 | |
150 | #define EXDK 41 | |
151 | #define SCANK 42 | |
152 | #define IPROD 43 | |
153 | #define OPROD 44 | |
154 | #define QUAD 45 | |
155 | #define QQUAD 46 | |
156 | #define BRAN0 47 | |
157 | #define BRAN 48 | |
158 | #define DDOM 49 | |
159 | #define MDOM 50 | |
160 | ||
161 | #define COM 51 | |
162 | #define RED 52 | |
163 | #define COMK 53 | |
164 | #define REDK 54 | |
165 | #define ROT 55 | |
166 | #define REV 56 | |
167 | #define ROTK 57 | |
168 | #define REVK 58 | |
169 | #define CAT 59 | |
170 | #define RAV 60 | |
171 | #define CATK 61 | |
172 | #define RAVK 62 | |
173 | ||
174 | #define PRINT 63 | |
175 | #define QUOT 64 | |
176 | #define ELID 65 | |
177 | #define CQUAD 66 | |
178 | #define COMNT 67 | |
179 | #define INDEX 68 | |
180 | #define HPRINT 69 | |
181 | ||
182 | #define LT 71 | |
183 | #define LE 72 | |
184 | #define GT 73 | |
185 | #define GE 74 | |
186 | #define EQ 75 | |
187 | #define NE 76 | |
188 | #define AND 77 | |
189 | #define OR 78 | |
190 | #define NAND 79 | |
191 | #define NOR 80 | |
192 | #define NOT 81 | |
193 | #define EPS 82 | |
194 | #define MEPS 83 | |
195 | #define REP 84 | |
196 | #define TAKE 85 | |
197 | #define DROP 86 | |
198 | #define ASGN 88 | |
199 | #define IMMED 89 | |
200 | ||
201 | ||
202 | #define NAME 90 | |
203 | #define CONST 91 | |
204 | #define FUN 92 | |
205 | #define ARG1 93 | |
206 | #define ARG2 94 | |
207 | #define AUTO 95 | |
208 | #define REST 96 | |
209 | ||
210 | #define COM0 97 | |
211 | #define RED0 98 | |
212 | #define EXD0 99 | |
213 | #define SCAN0 100 | |
214 | #define BASE 101 | |
215 | #define MENC 102 /* monadic encode */ | |
216 | #define LABEL 103 /* statement label */ | |
217 | #define PSI 104 /* PSI input character */ | |
218 | #define PSI1 105 /* PSI monadic half */ | |
219 | #define PSI2 106 /* PSI dyadic half */ | |
220 | #define ISP 107 /* ISP input code */ | |
221 | #define ISP1 108 /* ISP monadic half */ | |
222 | #define ISP2 109 /* ISP dyadic half */ | |
223 | #define QWID 110 /* quad fn1 */ | |
224 | #define QFUZZ 111 | |
225 | #define QRUN 112 | |
226 | #define QFORK 113 | |
227 | #define QWAIT 114 | |
228 | #define QEXEC 115 | |
229 | #define FDEF 116 | |
230 | #define QEXIT 117 | |
231 | #define QPIPE 118 | |
232 | #define QCHDIR 119 | |
233 | #define QOPEN 120 | |
234 | #define QCLOSE 121 | |
235 | #define QREAD 122 | |
236 | #define QWRITE 123 | |
237 | #define QCREAT 124 | |
238 | #define QSEEK 125 | |
239 | #define QUNLNK 126 | |
240 | #define QRD 127 | |
241 | #define QDUP 128 | |
242 | #define QAP 129 | |
243 | #define QKILL 130 | |
244 | #define QCRP 131 | |
245 | #define DFMT 132 | |
246 | #define MFMT 133 | |
247 | #define QNC 134 | |
248 | #define NILRET 135 | |
249 | #define XQUAD 136 | |
250 | #define SICLR 137 | |
251 | #define SICLR0 138 | |
252 | #define RVAL 139 | |
253 | #define QSIGNL 140 | |
254 | #define QFLOAT 141 /* Float character string to data */ | |
255 | #define QNL 142 /* Produce namelist */ | |
256 | ||
257 | /* | |
258 | * Immediate sub-op codes | |
259 | */ | |
260 | ||
261 | #define CLEAR 1 | |
262 | #define DIGITS 2 | |
263 | #define EDIT 3 | |
264 | #define ERASE 4 | |
265 | #define FNS 5 | |
266 | #define FUZZ 6 | |
267 | #define READ 7 | |
268 | #define ORIGIN 8 | |
269 | #define VARS 9 | |
270 | #define WIDTH 10 | |
271 | #define DEBUG 11 | |
272 | #define OFF 12 | |
273 | #define LOAD 13 | |
274 | #define SAVE 14 | |
275 | #define COPY 15 | |
276 | #define CONTIN 16 | |
277 | #define LIB 17 | |
278 | #define DROPC 18 | |
279 | #define VSAVE 19 | |
280 | #define SCRIPT 20 | |
281 | #define EDITF 21 | |
282 | #define TRACE 22 | |
283 | #define UNTRACE 23 | |
284 | #define WRITE 24 | |
285 | #define RESET 25 | |
286 | #define SICOM 26 | |
287 | #define CODE 27 | |
288 | #define DEL 28 | |
289 | #define SHELL 29 | |
290 | #define LIST 30 | |
291 | #define PRWS 31 | |
292 | ||
293 | struct chrstrct | |
294 | { | |
295 | char c[2]; /* Can't be 0 anymore (VAX) */ | |
296 | }; | |
297 | ||
298 | union uci | |
299 | { | |
300 | char cv[sizeof(int)]; /* character array */ | |
301 | unsigned i; /* unsigned integer value */ | |
302 | }; | |
303 | ||
304 | data zero; | |
305 | data one; | |
306 | data pi; | |
307 | data maxexp; /* the largest value such that exp(maxexp) is defined */ | |
308 | data datum; | |
309 | data getdat(); | |
310 | int funtrace; /* function trace enabled */ | |
311 | int labgen; /* label processing being done */ | |
312 | int apl_term; /* flag set if apl terminal mapping req'd */ | |
313 | jmp_buf gbl_env; /* Used for setexit/reset */ | |
314 | ||
315 | /* | |
316 | * Several unrelated values, which appear | |
317 | * together in the header of an apl workspace file. | |
318 | */ | |
319 | struct | |
320 | { | |
321 | double fuzz; | |
322 | int iorg; | |
323 | int digits; | |
324 | int width; | |
325 | int rl; /* Random Seed (Ph.A. S.B.B.) */ | |
326 | } thread; | |
327 | ||
328 | /* | |
329 | * Data types | |
330 | * Each new type should be accomodated for | |
331 | * in dealloc [a0.c] | |
332 | */ | |
333 | ||
334 | #define DA 1 | |
335 | #define CH 2 | |
336 | #define LV 3 | |
337 | #define QD 4 | |
338 | #define QQ 5 | |
339 | #define IN 6 | |
340 | #define EL 7 | |
341 | #define NF 8 | |
342 | #define MF 9 | |
343 | #define DF 10 | |
344 | #define QC 11 | |
345 | #define QV 12 /* quad variables */ | |
346 | #define DU 13 /* dummy -- causes fetch error except on print */ | |
347 | #define QX 14 /* latent expr. quad "Llx" */ | |
348 | #define LBL 15 /* locked label value */ | |
349 | #define NTYPES 16 /* number of defined types */ | |
350 | ||
351 | /* | |
352 | * This is a descriptor for apl data, allocated by "newdat". | |
353 | * The actual data starts at item.dim[item.rank], and thus | |
354 | * &item.dim[item.rank] should always == item.datap. | |
355 | * See the comment in "newdat" (a0.c) about "dim". | |
356 | * | |
357 | * A null item is a vector(!), and is rank==1, size==0. | |
358 | * | |
359 | * the stack is the operand stack, and sp is the pointer to the | |
360 | * top of the stack. | |
361 | */ | |
362 | ||
363 | struct item | |
364 | { | |
365 | char rank; | |
366 | char type; | |
367 | int size; | |
368 | int index; | |
369 | data *datap; | |
370 | int dim[MRANK]; | |
371 | } *stack[STKS], **sp; | |
372 | ||
373 | /* | |
374 | * variable/fn (and file name) descriptor block. | |
375 | * contains useful information about all LVals. | |
376 | * Also kludged up to handle file names (only nlist.namep | |
377 | * is then used.) | |
378 | * | |
379 | * For fns, nlist.itemp is an array of pointers to character | |
380 | * strings which are the compiled code for a line of the fn. | |
381 | * (Itemp == 0) means that the fn has not yet been compiled . | |
382 | * nlist.itemp[0] == the number of lines in the fn, and | |
383 | * nlist.itemp[1] == the function startup code, and | |
384 | * nlist.itemp[max] == the close down shop code. | |
385 | */ | |
386 | ||
387 | struct nlist | |
388 | { | |
389 | char use; | |
390 | char type; /* == LV */ | |
391 | struct item *itemp; | |
392 | char *namep; | |
393 | int label; | |
394 | } nlist[NLS]; | |
395 | ||
396 | /* | |
397 | * This is the structure used to implement the | |
398 | * APL state indicator. | |
399 | * | |
400 | * The structure is allocated dynamically in ex_fun (ai.c), | |
401 | * but not explicitly. Ex_fun declares a single, local | |
402 | * structure (allocated by C, itself), and links it to | |
403 | * previous instances of the structure. SI is used for | |
404 | * two basic things: | |
405 | * | |
406 | * 1) error traceback (Including ")SI" stuff). | |
407 | * 2) Restoration of the global variable environment | |
408 | * (or any other, pending environment). | |
409 | * | |
410 | * The global variable "gsip" is a pointer to the | |
411 | * head of a chain of these structures, one for each | |
412 | * instance of an activated function. (Gsip == 0) implies | |
413 | * an empty list, (gsip->sip == 0) implies the end of the list, | |
414 | * and (gsip->np == 0) implies a state indicator seperator. | |
415 | * (A new function was evoked with an old one pending.) | |
416 | * | |
417 | * Note that "gsip->funlc" is the same as the old global | |
418 | * variable "funlc", and | |
419 | * | |
420 | * (gsip && gsip->sip ? gsip->sip->funlc : 0) | |
421 | * | |
422 | * is the value of the old global, "ibeam36". | |
423 | */ | |
424 | ||
425 | struct si { | |
426 | int suspended; /* fn is suspended <=1, pending <= 0 */ | |
427 | struct si *sip; /* previous fn activation */ | |
428 | struct nlist *np; /* current fn vital stats. */ | |
429 | int funlc; /* current fn current line number */ | |
430 | struct item **oldsp; /* top of operand stack upon fn entry */ | |
431 | char *oldpcp; /* execution string upon fn entry */ | |
432 | jmp_buf env; /* for restoration of local | |
433 | * fn activation record */ | |
434 | } *gsip; | |
435 | ||
436 | /* | |
437 | * exop[i] is the address of the i'th action routine. | |
438 | * Because of a "symbol table overflow" problem with C, | |
439 | * the table was moved from a1.c to its own at.c | |
440 | */ | |
441 | ||
442 | int (*exop[])(); | |
443 | ||
444 | double floor(); | |
445 | double fabs(); | |
446 | double ceil(); | |
447 | double log(); | |
448 | double sin(); | |
449 | double cos(); | |
450 | double atan(); | |
451 | double atan2(); | |
452 | double sqrt(); | |
453 | double exp(); | |
454 | double gamma(); | |
455 | double ltod(); | |
456 | char *rline(); | |
457 | char *alloc(); | |
458 | char *compile(); | |
459 | struct nlist *nlook(); | |
460 | struct item *fetch(), *fetch1(), *fetch2(), *extend(); | |
461 | struct item *newdat(), *dupdat(); | |
462 | ||
463 | int integ; | |
464 | int signgam; | |
465 | int column; | |
466 | int intflg; | |
467 | int echoflg; | |
468 | int offexit; /* if != 0, require ")off" to exit */ | |
469 | int prwsflg; | |
470 | int ifile; | |
471 | int wfile; | |
472 | int debug; | |
473 | int ttystat[3]; | |
474 | long stime; | |
475 | char *pcp; /* global copy of arg to exec */ | |
476 | int rowsz; | |
477 | int mencflg; | |
478 | int aftrace; | |
479 | char *mencptr; | |
480 | int oldlb[MAXLAB]; | |
481 | int pt; | |
482 | int syze; | |
483 | int pas1; | |
484 | int ibeam36; | |
485 | int protofile; | |
486 | int lastop; /* last (current) operator exec'ed */ | |
487 | char *scr_file; /* scratch file name */ | |
488 | char *ws_file; /* apl workspace file */ | |
489 | ||
490 | ||
491 | struct | |
492 | { | |
493 | char rank; | |
494 | char type; | |
495 | int size; | |
496 | int dimk; | |
497 | int delk; | |
498 | int dim[MRANK]; | |
499 | int del[MRANK]; | |
500 | int idx[MRANK]; | |
501 | } idx; | |
502 | ||
503 | ||
504 | /* Following are definitions for buffered I/O. | |
505 | * To generate a version of APL without buffered I/O, | |
506 | * leave NBUF undefined. | |
507 | */ | |
508 | ||
509 | #define NBUF 4 /* Number of I/O buffers */ | |
510 | ||
511 | ||
512 | #ifdef NBUF | |
513 | ||
514 | #ifdef vax | |
515 | #define BLEN 512 /* Buffered I/O buffer length */ | |
516 | #else | |
517 | #define BLEN 256 /* Buffered I/O buffer length */ | |
518 | #endif | |
519 | ||
520 | struct iobuf { /* Buffered I/O buffer structure */ | |
521 | int b_len; /* Buffer length */ | |
522 | int b_next; /* Next available character */ | |
523 | int b_fd; /* Assigned file descriptor */ | |
524 | char b_buf[BLEN]; /* Actual buffer */ | |
525 | } *iobuf; | |
526 | ||
527 | ||
528 | struct fds { | |
529 | dev_t fd_dev; /* Device major/minor number */ | |
530 | ino_t fd_ind; /* File inode number */ | |
531 | int fd_pipe; /* (1=pipe, 0=not a pipe) */ | |
532 | int fd_buf; /* Number of assigned buffer */ | |
533 | char fd_lastop; /* Last operation (0=read, 1=write) */ | |
534 | char fd_uniq; /* Unique flag (1=unique, 0=not unique) */ | |
535 | char fd_dup; /* Principal fd for dups */ | |
536 | char fd_open; /* (0=closed, 1=open) */ | |
537 | } files[NFDS]; | |
538 | ||
539 | ||
540 | #define READF readf /* Buffered read routine */ | |
541 | #define WRITEF writef /* Buffered write routine */ | |
542 | #define SEEKF lseekf /* Buffered seek routine */ | |
543 | #define OPENF openf /* Buffered file open routine */ | |
544 | #define CREATF creatf /* Buffered file create routine */ | |
545 | #define DUPF dupf /* Buffered file dup routine */ | |
546 | #define CLOSEF closef /* Buffered file close routine */ | |
547 | #define FSTATF fstatf /* Buffered "fstat" call */ | |
548 | #ifndef VFORK | |
549 | #define FORKF(x) (bflush(),fork()) | |
550 | #else | |
551 | #define FORKF(x) (bflush(),(x) ? vfork() : fork()) | |
552 | #endif | |
553 | ||
554 | #endif | |
555 | ||
556 | ||
557 | #ifndef NBUF | |
558 | ||
559 | #define READF read /* Normal read routine */ | |
560 | #define WRITEF write /* Normal write routine */ | |
561 | #define SEEKF lseek /* Normal seek routine */ | |
562 | #define OPENF open /* Normal file open routine */ | |
563 | #define CREATF creat /* Normal file create routine */ | |
564 | #define DUPF dup /* Normal file dup routine */ | |
565 | #define CLOSEF close /* Normal file close routine */ | |
566 | #define FSTATF fstat /* Normal "fstat" call */ | |
567 | #define FORKF(x) fork() /* Normal "fork" call */ | |
568 | ||
569 | #endif | |
570 | ||
571 | ||
572 | long SEEKF(); /* declare SEEKF properly */ | |
573 | ||
574 | #define setexit() setjmp(gbl_env) /* "setexit" equivalent */ | |
575 | #define reset() longjmp(gbl_env) /* "reset" equivalent */ | |
576 | #define alloc(x) malloc(x) |