1: /* 2: * Definitions and declarations used throughout the run-time system. 3: */ 4: 5: #include <stdio.h> 6: #include "../h/config.h" 7: #ifdef VAX 8: /* 9: * Memory sizes. 10: */ 11: #define MAXHEAPSIZE 51200 /* size of the heap in bytes */ 12: #define MAXSTRSPACE 51200 /* size of the string space in bytes */ 13: #define STACKSIZE 2000 /* size of co-expression stack in words */ 14: #define MAXSTACKS 4 /* number of coexpression stacks */ 15: #define NUMBUF 10 /* number of i/o buffers available */ 16: #define NBUCKETS 37 /* number of hash buckets */ 17: /* 18: * Implementation specific constants. 19: */ 20: #define INTSIZE 32 /* bits per integer */ 21: #define LOGINTSIZE 5 /* log of INTSIZE */ 22: #define MINSHORT 0100000 /* smallest short integer */ 23: #define MAXSHORT 077777 /* largest short integer */ 24: #define MINLONG 020000000000L /* smallest long integer */ 25: #define MAXLONG 017777777777L /* largest long integer */ 26: #define LGHUGE 39 /* maximum base-10 exp+1 of real */ 27: #define FRAMELIMIT 2 /* maxmum negative offset in proc frame */ 28: #define WORDSIZE sizeof(int *) /* size in bytes of a pointer */ 29: #define STKBASE 0x7fffffff /* highest possible address for sp */ 30: #define GRANSIZE 1024 /* storage allocation granule size */ 31: /* 32: * Some macros for source code tailoring. 33: */ 34: #define SetBound setbound() 35: #define ClearBound clrbound() 36: #define DclSave register int saveefp,savegfp; 37: #define EntryPoint(x) (char *)x + 2 38: #define Global(x) .globl x 39: #define DummyFcn(x) .globl x; x: halt 40: #define DummyData(x) .globl x; x: .long 0 41: #define DummyRef(x) .long x 42: #define gfp r10 43: #define efp r11 44: #define ipc r9 45: /* 46: * Cset initialization macros. 47: */ 48: #define twd(w0, w1) ((w0)&0xffff | (w1)<<16) 49: #define cset_display(w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,wa,wb,wc,wd,we,wf) \ 50: {twd(w0,w1),twd(w2,w3),twd(w4,w5),twd(w6,w7), \ 51: twd(w8,w9),twd(wa,wb),twd(wc,wd),twd(we,wf)} 52: #endif VAX 53: #ifdef PORT 54: /* 55: * Memory sizes. 56: */ 57: #define MAXHEAPSIZE x /* size of the heap in bytes */ 58: #define MAXSTRSPACE x /* size of the string space in bytes */ 59: #define STACKSIZE x /* size of coexpression stack in WORDSIZE 60: words */ 61: #define MAXSTACKS x /* number of coexpression stacks */ 62: #define NUMBUF x /* number of i/o buffers available */ 63: #define NBUCKETS x /* number of hash buckets */ 64: /* 65: * Implementation specific constants. 66: */ 67: #define INTSIZE x /* bits per integer */ 68: #define LOGINTSIZE x /* log of INTSIZE */ 69: #define MINSHORT x /* smallest short integer */ 70: #define MAXSHORT x /* largest short integer */ 71: #define MINLONG x /* smallest long integer */ 72: #define MAXLONG x /* largest long integer */ 73: #define LGHUGE x /* maximum base-10 exp + 1 of float number */ 74: #define FRAMELIMIT x /* maximum negative offset in proc frame (int) */ 75: #define WORDSIZE sizeof(int *) /* size in bytes of a pointer */ 76: #define STKBASE x /* highest possible address for sp */ 77: #define GRANSIZE x /* storage allocation granule size */ 78: /* 79: * Some macros to allow customization. 80: */ 81: /*#define SetBound*/ 82: /*#define ClearBound*/ 83: /*#define DclSave*/ 84: /*#define EntryPoint(name) (char *)name + x*/ 85: /*#define Global(x)*/ 86: /*#define DummyFcn(x)*/ 87: /*#define DummyData(x)*/ 88: /*#define DummyRef(x)*/ 89: /*#define gfp x*/ 90: /*#define efp x*/ 91: /*#define ipc x*/ 92: /* 93: * Cset initialization macros. 94: */ 95: /* 96: For ints with 32 bits use these: 97: 98: #define twd(w0, w1) ((w0)&0xffff | (w1)<<16) 99: #define cset_display(w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,wa,wb,wc,wd,we,wf) \ 100: {twd(w0,w1),twd(w2,w3),twd(w4,w5),twd(w6,w7), \ 101: twd(w8,w9),twd(wa,wb),twd(wc,wd),twd(we,wf)} 102: 103: For ints with 16 bits use these: 104: 105: #define cset_display(w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,wa,wb,wc,wd,we,wf) \ 106: {w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,wa,wb,wc,wd,we,wf} 107: */ 108: #endif PORT 109: 110: #ifdef PDP11 111: #define MAXHEAPSIZE 10240 /* size of the heap in bytes */ 112: #define MAXSTRSPACE 10240 /* size of the string space in bytes */ 113: #define STACKSIZE 1000 /* size a coexpression stack in WORDSIZE 114: words */ 115: #define MAXSTACKS 2 /* number of coexpression stacks */ 116: #define NUMBUF 5 /* number of i/o buffers available */ 117: #define NBUCKETS 13 /* number of hash buckets */ 118: #define MAXLISTSIZE 4090 /* Defined if lists are limited in size 119: due to addressing limitations of a 120: particular architecture. Specified 121: value is the largest list element 122: block that can be made. */ 123: /* 124: * Implementation specific constants. 125: */ 126: #define INTSIZE 16 /* bits per integer */ 127: #define LOGINTSIZE 4 /* log of INTSIZE */ 128: #define LONGS /* longs are not same as ints */ 129: #define MINLONG 020000000000L /* smallest long integer */ 130: #define MAXLONG 017777777777L /* largest long integer */ 131: #define MINSHORT 0100000 /* smallest short integer */ 132: #define MAXSHORT 077777 /* largest short integer */ 133: #define LGHUGE 39 /* maximum base-10 exp +1 of float number */ 134: #define FRAMELIMIT 5 /* maxmum negative offset in proc frame (int) */ 135: #define WORDSIZE sizeof(int *) /* size in bytes of a pointer */ 136: #define STKBASE 0177776 /* highest possible address for sp */ 137: #define GRANSIZE 64 /* storage allocation granule size */ 138: /* 139: * Some macros to allow customization. 140: */ 141: #define SetBound 142: #define ClearBound 143: #define DclSave 144: #define EntryPoint(x) (char *)x + 4 145: #define Global(x) .globl x 146: #define DummyFcn(x) .globl x; x: 0 147: #define DummyData(x) .globl x; x: 0 148: #define DummyRef(x) .globl x; x 149: /* 150: * Cset initialization macros. 151: */ 152: #define cset_display(w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,wa,wb,wc,wd,we,wf) \ 153: {w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,wa,wb,wc,wd,we,wf} 154: #endif PDP11 155: 156: /* 157: * Constants that are not likely to vary between implementations. 158: */ 159: #define BITOFFMASK (INTSIZE-1) 160: #define CSETSIZE (256/INTSIZE) /* number of ints to hold 256 cset 161: bits. Use (256/INTSIZE)+1 if 162: 256 % INTSIZE != 0 */ 163: #define LISTBLKSIZE 8 /* number of elements in an expansion 164: * list element block */ 165: #define MAXSTRING 257 /* largest string in conversions */ 166: #define MAXREADSTRING 2049 /* largest string to read() in one piece */ 167: #define RANDA 1103515245 /* random seed multiplier */ 168: #define RANDC 453816694 /* random seed additive constant */ 169: #define RSCALE 4.65661286e-10 /* random scale factor = 1/(2^31-1)) */ 170: 171: /* 172: * Offset in word of cset bit. 173: */ 174: #define CSOFF(b) ((b) & BITOFFMASK) 175: /* 176: * Address of word of cset bit. 177: */ 178: #define CSPTR(b,c) ((c) + (((b)&0377) >> LOGINTSIZE)) 179: /* 180: * Set bit b in cset c. 181: */ 182: #define setb(b,c) (*CSPTR(b,c) |= (01 << CSOFF(b))) 183: /* 184: * Test bit b in cset c. 185: */ 186: #define tstb(b,c) ((*CSPTR(b,c) >> CSOFF(b)) & 01) 187: 188: /* 189: * Runtime data structures. 190: */ 191: 192: union numeric { /* long integers or real numbers */ 193: long integer; 194: double real; 195: }; 196: 197: struct descrip { /* descriptor */ 198: int type; /* type field */ 199: union { 200: int integr; /* integer value */ 201: char *cptr; /* pointer to character string */ 202: union block *bptr; /* pointer to a block */ 203: struct descrip *dptr; /* pointer to a descriptor */ 204: } value; 205: }; 206: 207: struct sdescrip { 208: int length; /* length of string */ 209: char *string; /* pointer to string */ 210: }; 211: 212: struct b_int { /* long integer block */ 213: int type; /* T_LONGINT */ 214: long intval; /* value */ 215: }; 216: 217: struct b_real { /* real block */ 218: int type; /* T_REAL */ 219: double realval; /* value */ 220: }; 221: 222: struct b_cset { /* cset block */ 223: int type; /* T_CSET */ 224: int bits[CSETSIZE]; /* array of bits, one per ascii character */ 225: }; 226: 227: struct b_file { /* file block */ 228: int type; /* T_FILE */ 229: FILE *fd; /* Unix file descriptor */ 230: int status; /* file status */ 231: struct descrip fname; /* file name (string qualifier) */ 232: }; 233: 234: struct b_proc { /* procedure block */ 235: int type; /* T_PROC */ 236: int size; /* size of block */ 237: char *entryp; /* entry point (code) */ 238: int nparam; /* number of parameters */ 239: int ndynam; /* number of dynamic locals */ 240: int nstatic; /* number of static locals */ 241: int fstatic; /* index (in global table) of first static */ 242: struct descrip pname; /* procedure name (string qualifier) */ 243: struct descrip lnames[1]; /* list of local names (qualifiers) */ 244: }; 245: 246: /* 247: * b_iproc blocks are used to statically initialize information about 248: * functions. They are identical to b_proc blocks except for 249: * the pname field which is a sdecrip (simple/string descriptor) instead 250: * of a descrip. This is done because unions can't be initialized. 251: */ 252: 253: struct b_iproc { /* procedure block */ 254: int ip_type; /* T_PROC */ 255: int ip_size; /* size of block */ 256: char *ip_entryp; /* entry point (code) */ 257: int ip_nparam; /* number of parameters */ 258: int ip_ndynam; /* number of dynamic locals */ 259: int ip_nstatic; /* number of static locals */ 260: int ip_fstatic; /* index (in global table) of first static */ 261: struct sdescrip ip_pname; /* procedure name (string qualifier) */ 262: struct descrip ip_lnames[1]; /* list of local names (qualifiers) */ 263: }; 264: 265: struct b_list { /* list header block */ 266: int type; /* T_LIST */ 267: int cursize; /* current list size */ 268: struct descrip listhead; /* pointer to first list element block */ 269: struct descrip listtail; /* pointer to last list element block */ 270: }; 271: 272: struct b_lelem { /* list element block */ 273: int type; /* T_LELEM */ 274: int size; /* size of block */ 275: int nelem; /* total number of elements */ 276: int first; /* index of first element */ 277: int nused; /* number of used elements */ 278: struct descrip listprev; /* pointer to previous list element block */ 279: struct descrip listnext; /* pointer to next list element block */ 280: struct descrip lslots[1]; /* array of elements */ 281: }; 282: 283: struct b_table { /* table header block */ 284: int type; /* T_TABLE */ 285: int cursize; /* current table size */ 286: struct descrip defvalue; /* default table element value */ 287: struct descrip buckets[NBUCKETS]; /* hash buckets */ 288: }; 289: 290: struct b_telem { /* table element block */ 291: int type; /* T_TELEM */ 292: int hashnum; /* for ordering chain */ 293: struct descrip blink; /* hash bucket link */ 294: struct descrip tref; /* reference field */ 295: struct descrip tval; /* value field */ 296: }; 297: 298: #ifdef SETS 299: struct b_set { /* set header block */ 300: int type; /* T_SET */ 301: int setsize; /* cardinality of the set */ 302: struct descrip sbucks[NBUCKETS]; /* hash buckets */ 303: }; 304: 305: struct b_selem { /* set element block */ 306: int type; /* T_SELEM */ 307: int hnum; /* hash number */ 308: struct descrip setmem; /* the element */ 309: struct descrip sblink; /* hash chain link */ 310: }; 311: #endif SETS 312: 313: struct b_record { /* record block */ 314: int type; /* T_RECORD */ 315: int size; /* size of block */ 316: struct b_proc *recptr; /* pointer to record constructor proc */ 317: struct descrip fields[1]; /* fields */ 318: }; 319: 320: struct b_tvsubs { /* substring trapped variable block */ 321: int type; /* T_TVSUBS */ 322: int sslen; /* length of substring */ 323: int sspos; /* position of substring */ 324: struct descrip ssvar; /* variable that substring is from */ 325: }; 326: 327: struct b_tvtbl { /* table element trapped variable block */ 328: int type; /* T_TVTBL */ 329: int hashnum; /* for ordering */ 330: struct descrip tvtable; /* pointer to table header block */ 331: struct descrip tvtref; /* reference field */ 332: struct descrip tvtval; /* used when block is converted to telem */ 333: }; 334: 335: struct b_estack { /* co-expression stack block */ 336: int type; /* T_ESTACK */ 337: struct descrip activator; /* most recent activator */ 338: int *sbase; /* stack base */ 339: int *sp; /* stack pointer */ 340: int *ap; /* address pointer, only on Vax */ 341: int *boundary; /* Icon/C boundary */ 342: int nresults; /* number of results produced */ 343: struct descrip freshblk; /* refresh block pointer */ 344: }; 345: 346: struct b_eblock { /* co-expression heap block */ 347: int type; /* T_EBLOCK */ 348: int size; /* size of block */ 349: int *ep; /* entry point */ 350: int numargs; /* number of arguments */ 351: int numlocals; /* number of locals */ 352: struct descrip elems[1]; /* arguments and locals, including arg0 */ 353: }; 354: 355: union block { /* general heap block */ 356: struct b_int longint; 357: struct b_real realblk; 358: struct b_cset cset; 359: struct b_file file; 360: struct b_proc proc; 361: struct b_list list; 362: struct b_lelem lelem; 363: struct b_table table; 364: struct b_telem telem; 365: #ifdef SETS 366: struct b_set set; 367: struct b_selem selem; 368: #endif SETS 369: struct b_record record; 370: struct b_tvsubs tvsubs; 371: struct b_tvtbl tvtbl; 372: struct b_estack estack; 373: struct b_eblock eblock; 374: }; 375: 376: /* 377: * External declarations. 378: */ 379: 380: extern char (*bufs)[BUFSIZ]; /* i/o buffers */ 381: extern FILE **bufused; /* i/o buffer use markers */ 382: 383: extern int *stacks; /* start of expression stack space */ 384: extern int *estacks; /* end of expression stack space */ 385: extern int *esfree; /* expression stack space free list header */ 386: 387: extern int ssize; /* size of string space (bytes) */ 388: extern char *strings; /* start of string space */ 389: extern char *estrings; /* end of string space */ 390: extern char *sfree; /* string space free pointer */ 391: 392: extern int hpsize; /* size of heap (words) */ 393: extern char *hpbase; /* base of heap */ 394: extern char *maxheap; /* maximum address in heap */ 395: extern char *hpfree; /* first free location in heap */ 396: 397: extern int bsizes[]; /* sizes of heap blocks */ 398: extern int firstd[]; /* offset (words) of first descrip. */ 399: extern char *blkname[]; /* print names for block types. */ 400: 401: extern int numbufs; /* number of buffers */ 402: 403: extern int stksize; /* size of coexpression stacks in words */ 404: 405: extern struct b_cset k_ascii; /* value of &ascii */ 406: extern struct b_cset k_cset; /* value of &cset */ 407: extern struct b_file k_errout; /* value of &errout */ 408: extern struct b_file k_input; /* value of &input */ 409: extern struct b_cset k_lcase; /* value of &lcase */ 410: extern int k_level; /* value of &level */ 411: extern int k_pos; /* value of &pos */ 412: extern struct descrip k_main; /* value of &main */ 413: extern struct b_file k_output; /* value of &output */ 414: extern long k_random; /* value of &random */ 415: extern struct descrip k_subject; /* value of &subject */ 416: extern int k_trace; /* value of &trace */ 417: extern struct b_cset k_ucase; /* value of &ucase */ 418: extern long starttime; /* start time in milliseconds */ 419: extern struct descrip nulldesc; /* universal &null */ 420: extern struct descrip zerodesc; /* universal 0 */ 421: extern struct descrip onedesc; /* universal 1 */ 422: extern struct descrip nullstr; /* universal null string */ 423: extern struct descrip blank; /* universal blank */ 424: extern struct descrip letr; /* universal letter 'r' */ 425: extern struct descrip maps2; /* save space for 2nd arg to map() */ 426: extern struct descrip maps3; /* save space for 3rd arg to map() */ 427: extern struct descrip current; /* current expression stack pointer */ 428: extern struct descrip input; /* universal input file */ 429: extern struct descrip errout; /* universal error file */ 430: extern struct descrip lcase; /* universal lower case string */ 431: extern struct descrip ucase; /* universal upper case string */ 432: 433: extern int line; /* current source program line number */ 434: extern char *file; /* current source program file name */ 435: 436: /* 437: * Descriptor flags. 438: */ 439: #ifdef VAX 440: #define F_NQUAL 0x80000000 /* set if NOT string qualifier */ 441: #define F_VAR 0x40000000 /* set if variable */ 442: #define F_TVAR 0x20000000 /* set if trapped variable */ 443: #define F_PTR 0x10000000 /* set if value field is pointer */ 444: #endif VAX 445: 446: #ifdef PORT 447: #define F_NQUAL x /* set if NOT string qualifier */ 448: #define F_VAR x /* set if variable */ 449: #define F_TVAR x /* set if trapped variable */ 450: #define F_PTR x /* set if value field is pointer */ 451: #endif PORT 452: 453: #ifdef PDP11 454: #define F_NQUAL 0100000 /* set if NOT string qualifier */ 455: #define F_VAR 0040000 /* set if variable */ 456: #define F_TVAR 0020000 /* set if trapped variable */ 457: #define F_PTR 0010000 /* set if value field is pointer */ 458: #endif PDP11 459: 460: #define TYPEMASK 63 /* type mask */ 461: #define OFFSETMASK (~(F_NQUAL|F_VAR|F_TVAR)) /* offset mask for variables */ 462: 463: /* 464: * Type codes (descriptors and blocks). 465: */ 466: 467: #define T_INTEGER 1 /* short integer */ 468: /* 469: * For 32 bit machines, e.g. the Vax, we make LONGINT's and INTEGER's 470: * the same. It would be better to have a generic integer type, and 471: * also have LONGINT's and SHORTINT's, but at the current time, 472: * LONGINT is used both to refer to integers not representable by 473: * a short, and as a generic integer type. 474: */ 475: #ifdef LONGS 476: #define T_LONGINT 2 /* long integer */ 477: #else LONGS 478: #define T_LONGINT 1 /* long integer */ 479: #endif LONGS 480: #define T_REAL 3 /* real number */ 481: #define T_CSET 4 /* cset */ 482: #define T_FILE 5 /* file block */ 483: #define T_PROC 6 /* procedure block */ 484: #define T_LIST 7 /* list header block */ 485: #define T_TABLE 8 /* table header */ 486: #define T_RECORD 9 /* record block */ 487: #define T_TELEM 10 /* table element block */ 488: #define T_LELEM 11 /* list element block */ 489: #define T_TVSUBS 12 /* substring trapped variable */ 490: #define JUNK_13 13 /* (no longer used) */ 491: #define T_TVTBL 14 /* table element trapped variable block */ 492: #define T_TVPOS 15 /* &pos trapped variable */ 493: #define T_TVRAND 16 /* &random trapped variable */ 494: #define T_TVTRACE 17 /* &trace trapped variable */ 495: #define T_ESTACK 18 /* expression stack block */ 496: #define T_EBLOCK 19 /* expression heap block */ 497: #ifdef SETS 498: #define T_SET 20 /* set header block */ 499: #define T_SELEM 21 /* set element block */ 500: 501: #define MAXTYPE 21 /* maximum type number */ 502: #else SETS 503: #define MAXTYPE 19 /* maximum type number w/o sets */ 504: #endif SETS 505: 506: /* 507: * Descriptor types and flags. 508: */ 509: 510: #define D_VAR (F_VAR | F_NQUAL) 511: #define D_TVAR (F_VAR | F_TVAR | F_NQUAL) 512: 513: #define D_NULL 0 514: #define D_INTEGER (T_INTEGER | F_NQUAL) 515: #define D_LONGINT (T_LONGINT | F_PTR | F_NQUAL) 516: #define D_REAL (T_REAL | F_PTR | F_NQUAL) 517: #define D_CSET (T_CSET | F_PTR | F_NQUAL) 518: #define D_FILE (T_FILE | F_PTR | F_NQUAL) 519: #define D_PROC (T_PROC | F_PTR | F_NQUAL) 520: #define D_LIST (T_LIST | F_PTR | F_NQUAL) 521: #define D_TABLE (T_TABLE | F_PTR | F_NQUAL) 522: #ifdef SETS 523: #define D_SET (T_SET | F_PTR | F_NQUAL) 524: #define D_SELEM (T_SELEM | F_PTR | F_NQUAL) 525: #endif SETS 526: #define D_RECORD (T_RECORD | F_PTR | F_NQUAL) 527: #define D_TELEM (T_TELEM | F_PTR | F_NQUAL) 528: #define D_LELEM (T_LELEM | F_PTR | F_NQUAL) 529: #define D_TVSUBS (T_TVSUBS | D_TVAR) 530: #define D_TVTBL (T_TVTBL | D_TVAR) 531: #define D_TVPOS (T_TVPOS | D_TVAR) 532: #define D_TVRAND (T_TVRAND | D_TVAR) 533: #define D_TVTRACE (T_TVTRACE | D_TVAR) 534: #define D_ESTACK (T_ESTACK | F_PTR | F_NQUAL) 535: #define D_EBLOCK (T_EBLOCK | F_PTR | F_NQUAL) 536: 537: /* 538: * File status flags in status field of file blocks. 539: */ 540: 541: #define FS_READ 01 /* read access */ 542: #define FS_WRITE 02 /* write access */ 543: #define FS_CREATE 04 /* file created on open */ 544: #define FS_APPEND 010 /* append mode */ 545: #define FS_PIPE 020 /* reading/writing on a pipe */ 546: 547: /* 548: * Macros for testing descriptors. d must be of type struct descrip. 549: */ 550: 551: #define NULLDESC(d) (((d).type|(d).value.integr)==0) /* check for &null */ 552: 553: /* 554: * String qualifiers. 555: */ 556: #define QUAL(d) (!((d).type & F_NQUAL)) /* check for qualifier */ 557: #define STRLEN(d) ((d).type) /* get length of string */ 558: #define STRLOC(d) ((d).value.cptr) /* get address of string */ 559: 560: /* 561: * Values, d must not be qualifier or variable. 562: */ 563: #define TYPE(d) ((d).type & TYPEMASK) /* get type code */ 564: #define POINTER(d) ((d).type & F_PTR) /* check for pointer */ 565: #define INTVAL(d) ((d).value.integr) /* get short integer value */ 566: #define BLKLOC(d) ((d).value.bptr) /* get pointer to block */ 567: 568: /* 569: * Variables, d must not be qualifier. 570: */ 571: #define VAR(d) ((d).type & F_VAR) /* check for variable */ 572: #define TVAR(d) ((d).type & F_TVAR) /* check for trapped var */ 573: #define OFFSET(d) ((d).type & OFFSETMASK) /* get offset field */ 574: #define VARLOC(d) ((d).value.dptr) /* get pointer to descriptor */ 575: #define TVARLOC(d) ((d).value.bptr) /* get ptr to t.v. block */ 576: 577: /* 578: * Macros to define procedure blocks. 579: */ 580: #define IDENT(x) x 581: #define CAT(x,y) IDENT(x)y 582: #define Procblock(f,nargs)\ 583: struct b_iproc CAT(B,f) = {\ 584: T_PROC,\ 585: vsizeof(struct b_proc),\ 586: EntryPoint(CAT(X,f)),\ 587: nargs,\ 588: -1,\ 589: 0, 0,\ 590: {sizeof("f")-1,"f"}}; 591: 592: #define Opblock(a,b,c) Opblock1(a,b,c,0) 593: #define Opblockx(a,b,c,d) Opblock1(a,b,c,-d) 594: #define Opblock1(f,nargs,sname,realargs)\ 595: struct b_iproc CAT(B,f) = {\ 596: T_PROC,\ 597: vsizeof(struct b_proc),\ 598: EntryPoint(f),\ 599: nargs,\ 600: -1,\ 601: realargs,\ 602: 0,\ 603: {sizeof(sname)-1,sname}}; 604: 605: /* 606: * Macros to access Icon arguments from C-language library procedures. 607: * Library procedures must have exactly one argument, named nargs. 608: */ 609: 610: /* 611: * n-th argument. 612: */ 613: #define ARG(n) (*((struct descrip *)(&nargs+1)+(nargs-n))) 614: /* 615: * Type field of n-th argument. 616: */ 617: #define ARGTYPE(n) (*(&nargs+1+2*(nargs-n))) 618: /* 619: * Value field of n-th argument. 620: */ 621: #define ARGVAL(n) (*(&nargs+2+2*(nargs-n))) 622: 623: /* 624: * Minimum of x and y. 625: */ 626: #define MIN(x,y) ((x)<(y)?(x):(y)) 627: 628: /* 629: * Maximum of x and y. 630: */ 631: #define MAX(x,y) ((x)>(y)?(x):(y)) 632: 633: /* 634: * Derefence d. 635: */ 636: #define DeRef(d) if(!QUAL(d)&&VAR(d))deref(&d); 637: 638: /* 639: * vsizeof is for use with variable-sized (i.e., indefinite) 640: * structures containing an array declared of size 1 641: * to avoid compiler warnings associated with 0-sized arrays. 642: */ 643: 644: #define vsizeof(s) (sizeof(s) - sizeof(struct descrip))