|
|
1.1 root 1: /*
2: * mjm: alloc(sz) -> own subroutine which calls malloc();
3: * HEADLEN: 4 -> (2*(sizeof(int))
4: */
5: #define Q register struct obj
6: #define COMMAOPP 1
7: #define PUTOPP 2
8: #define AEOROPP 2
9: #define AIOROPP 2
10: #define AANDOPP 2
11: #define ASHROPP 2
12: #define ASHLOPP 2
13: #define AMODOPP 2
14: #define ADIVOPP 2
15: #define AMULOPP 2
16: #define ASUBOPP 2
17: #define APLUSOPP 2
18: #define QSTOPP 5
19: #define QSTOPP2 3
20: #define OROPP 7
21: #define ANDOPP 8
22: #define BITIORP 9
23: #define BITEORP 10
24: #define BITANDP 11
25: #define EQOPP 12
26: #define NEOPP 12
27: #define GTOPP 13
28: #define GEOPP 13
29: #define LTOPP 13
30: #define LEOPP 13
31: #define SHLOPP 14
32: #define SHROPP 14
33: #define ADDOPP 15
34: #define SUBOPP 15
35: #define MULOPP 16
36: #define DIVOPP 16
37: #define MODOPP 16
38: #define CASTP 17
39: #define UNMINUSP 17
40: #define UNPLUSP 17
41: #define UNSTARP 17
42: #define UNADDRP 17
43: #define UNNOTP 17
44: #define UNCOMP 17
45: #define UNINC1P 17
46: #define UNINC2P 17
47: #define UNDEC1P 17
48: #define UNDEC2P 17
49: #define SIZEOFP 17
50: #define DOTOPP 18
51: #define FCALLOPP 18
52: #define SUBSCRP 18
53: #define PTROPP 18
54:
55: #define F 0 /*floating point type*/
56: #define N 1 /*norgen in4 or int*/
57: #define L 2 /*unix long*/
58: #define I 3 /*unix int*/
59: #define U 4 /*unix unsigned*/
60:
61: #define MAXTYPE 5 /* "pointer to ..." adds MAXTYPE to type */
62:
63: #define DFFUNCT 040000 /* declarator cannot be stored into */
64: #define FFSTRUCT 020000 /* structure prototype should follow */
65: #define DFLASTID 010000 /* item is identifier */
66: #define DFMOD 010000 /* bits below this are part of symbol defn */
67: #define DFTYPEDF 04000 /* this is a typedef typename */
68: #define DFFUNCT2 02000 /* this is a typedef typename which can't be */
69: /* stored into */
70: #define DFSTRUCT 01000 /* this is a structure tag or name */
71:
72: #define NAMELEN 30
73: #define NUMBLEN 30
74: #define STRLEN 30
75: #define CHCONST 10
76:
77: #define COMMAOP 1
78: #define AEOROP 2
79: #define AIOROP 3
80: #define AANDOP 4
81: #define ASHROP 5
82: #define ASHLOP 6
83: #define AMODOP 7
84: #define ADIVOP 8
85: #define AMULOP 9
86: #define ASUBOP 10
87: #define APLUSOP 11
88: #define QSTOP 12
89: #define OROP 14
90: #define ANDOP 15
91: #define BITIOR 16
92: #define BITEOR 17
93: #define BITAND 18
94: #define EQOP 19
95: #define NEOP 20
96: #define GTOP 21
97: #define GEOP 22
98: #define LTOP 23
99: #define LEOP 24
100: #define SHLOP 25
101: #define SHROP 26
102: #define ADDOP 27
103: #define SUBOP 28
104: #define MULOP 29
105: #define DIVOP 30
106: #define MODOP 31
107: #define UNMINUS 32
108: #define UNPLUS 33
109: #define UNSTAR 34
110: #define UNADDR 35
111: #define UNNOT 36
112: #define UNCOM 37
113: #define UNINC1 38
114: #define UNINC2 39
115: #define UNDEC1 40
116: #define UNDEC2 41
117: #define DOTOP 42
118: #define PTROP 43
119: #define LP 44
120: #define RP 45
121: #define LB 46
122: #define RB 47
123: #define LBC 48
124: #define RBC 49
125: #define SQ 50
126: #define DQ 51
127: #define SHARP 52
128: #define SC 53
129: #define BACK 54
130: #define CONST 55
131: #define IDENT 56
132: #define SIZEOF 57
133: #define PUTOP 58
134: #define SUBSCROP 59
135: #define FCALLOP 60
136:
137: #define HEADLEN (2*sizeof(int)) /* Q struct 'type' and 'size' fields */ /*mjm*/
138:
139: #define CHAR 1
140: #define SHORT 2
141: #define INT 4
142: #define LONG 010
143: #define UNSIGNED 020
144: #define FLOAT 040
145: #define DOUBLE 0100
146: #define STRUCT 0200
147: #define UNION 0400
148: #define FLOATN 01000
149: #define INTN 02000
150: #define TYPEDF 04000
151:
152: #define OUT (-1) /* out of storage in alloc() */
153:
154: /* int outcore {OUT}; mjm removed */
155:
156: /* if unixfmt is 1, floats are unix-format; else norgen-format */
157: int unixfmt = {0};
158:
159: /* if unsign is 1, declare _ftou() and _ntou() unsigned */
160: int unsign = {1};
161:
162: /* the value to be returned by gettype() when symbol is undefined
163: should be "function returning int" */
164: int undefin = MAXTYPE+I;
165:
166: /* the current function return type */
167: static int frettype,lasttype;
168:
169: /* the following flags flag that the sign bit should be set in symbol
170: definitions and inquiries: an unforseen necessity to keep
171: structure names and variable names separate in the symbol
172: table. instruct affects definitions, and dotid affects
173: inquires */
174: static int dotid; /* set by expr() after dot (. ->) for ident() */
175: static int instruct; /* set by structure statement for alt symbol table */
176:
177: /* this is the {} nesting level for symbol defns, etc. */
178: int level;
179:
180: /* a chain of prototype arguments to be defined as type "int" if not
181: declared explicitly */
182: struct argstruct {
183: struct argstruct *acnext;
184: char *acstring;
185: } *argchain;
186:
187: static struct obj {
188: int type; /* the type of an object */
189: int size; /* the size of the following string */
190: char text[2]; /* the object stored here. variable size */
191: };
192:
193: /* primative operations on Q items */
194:
195: /* functions called here :
196: prfx(string,o) return object with prefixed string
197: psfx(o,string) return object with string postfixed
198: unop(s1,s2,o) unary minus rules
199: unop2(s1,s2,o) unary ! rules
200: unop3(s1,s2,o) unary ~ rules
201: unop4(s1,s2,s3,o) postfix ++ rules
202: unop5(s1,s2,s3,o) prefix ++ rules
203: binop(ol,or,s1,s2) + rules
204: binop2(ol,or,s) >> rules
205: binop3(ol,or,s1,s2) > rules
206: binop4(ol,or,s) == rules
207: binop5(ol,or,s) & rules
208: binop6(ol,or,s) : rules
209: binop7(ol,or,s) ? rules
210: binop8(ol,or,s) = rules
211: binop9(ol,or,s) , rules
212: binop10(ol,or,s) || rules
213: copy(o) form a copy of o
214: cvt(o,type) do conversion from o-type to type
215: seq(s1,s2) return string equality
216: qcat(ol,or) cat two objects together
217: bcat(s1,ol,s2,or,s3) form obj from cat of s's and o's
218: */
219:
220: ptrop(ol,or)
221: Q *ol,*or;
222: {
223: /* used to be dotop(prfx("(",psfx(unstar(ol),")")),or), but "C" won't
224: take (*0).smember, and will take 0->smember. */
225:
226: if((ol->type=ol->type-MAXTYPE)<0)warn("illegal indirection");
227: if((ol->type&DFSTRUCT)==0)warn("non-structure used as structure name");
228: ol->type=or->type;
229: return(qcat(psfx(ol,"->\377"),or));
230: }
231: dotop(ol,or)
232: Q *ol,*or;
233: {
234: if((ol->type&DFSTRUCT)==0) warn("non-structure used as structure name");
235: ol->type=or->type;
236: return(qcat(psfx(ol,"\377."),or));
237: }
238: unstar(op)
239: Q *op;
240: {
241: if((op->type=op->type-MAXTYPE)<0)warn("illegal indirection");
242: return(prfx("\377 *",op));
243: }
244: unaddr(op)
245: Q *op;
246: {
247: op->type += MAXTYPE;
248: return(prfx("\377 &",op));
249: }
250: unminus(op)
251: Q *op;
252: {
253: /* catch fltg point constants preceeded by minus signs and spaces by
254: checking for op->text octal constant and fltg point type.
255: */
256:
257: if(op->type==F&&op->text[0]=='0'&&op->size==13) {
258: if(unixfmt) op->text[1] ^= 2; /* flip sign */
259: else op->text[6] ^= 1;
260: return(op);
261: }
262: return(unop("\377 -","\377_funmin(",op));
263: }
264: unplus(op)
265: Q *op;
266: {
267: return(unop("\377 +","\377_funplus(",op));
268: }
269: unnot(op)
270: Q *op;
271: {
272: return(unop2("\377 !","\377!(",op));
273: }
274: uncom(op)
275: Q *op;
276: {
277: return(unop3("\377 ~","\377~(",op));
278: }
279: uninc1(op)
280: Q *op;
281: {
282: return(unop5("\377 ++","\377_finc1(&","\377_ninc1(&",op));
283: }
284: uninc2(op)
285: Q *op;
286: {
287: return(unop4("++\377 ","\377_finc2(&","\377_ninc2(&",op));
288: }
289: undec1(op)
290: Q *op;
291: {
292: return(unop5("\377 --","\377_fdec1(&","\377_ndec1(&",op));
293: }
294: undec2(op)
295: Q *op;
296: {
297: return(unop4("--\377 ","\377_fdec2(&","\377_ndec2(&",op));
298: }
299: mulop(ol,or)
300: Q *ol,*or;
301: {
302: return(binop(ol,or,"*\377","\377_fmul("));
303: }
304: divop(ol,or)
305: Q *ol,*or;
306: {
307: return(binop(ol,or,"/\377","\377_fdiv("));
308: }
309: modop(ol,or)
310: Q *ol,*or;
311: {
312: return(binop(ol,or,"%\377","\377_fmod("));
313: }
314: addop(ol,or)
315: Q *ol,*or;
316: {
317: if(ol->type>=MAXTYPE||or->type>=MAXTYPE) {
318: if(ol->type<MAXTYPE) {
319: ol=cvt(ol,I);
320: ol->type=or->type;
321: }
322: else or=cvt(or,I);
323: }
324: return(binop(ol,or,"+\377","\377_fadd("));
325: }
326: subop(ol,or)
327: Q *ol,*or;
328: {
329: if(ol->type>=MAXTYPE||or->type>=MAXTYPE) {
330: if(ol->type>=MAXTYPE&&or->type>=MAXTYPE) {
331: ol->type=or->type=I;
332: }
333: else {
334: if(ol->type<MAXTYPE) {
335: ol=cvt(ol,I);
336: ol->type=or->type;
337: }
338: else or=cvt(or,I);
339: }
340: }
341: return(binop(ol,or,"-\377","\377_fsub("));
342: }
343: shlop(ol,or)
344: Q *ol,*or;
345: {
346: return(binop2(ol,or,"<<\377"));
347: }
348: shrop(ol,or)
349: Q *ol,*or;
350: {
351: return(binop2(ol,or,">>\377"));
352: }
353: gtop(ol,or)
354: Q *ol,*or;
355: {
356: return(binop3(ol,or,">\377","\377_fgt("));
357: }
358: geop(ol,or)
359: Q *ol,*or;
360: {
361: return(binop3(ol,or,">=\377","\377_fge("));
362: }
363: ltop(ol,or)
364: Q *ol,*or;
365: {
366: return(binop3(ol,or,"<\377","\377_flt("));
367: }
368: leop(ol,or)
369: Q *ol,*or;
370: {
371: return(binop3(ol,or,"<=\377","\377_fle("));
372: }
373: eqop(ol,or)
374: Q *ol,*or;
375: {
376: return(binop4(ol,or,"==\377"));
377: }
378: neop(ol,or)
379: Q *ol,*or;
380: {
381: return(binop4(ol,or,"!=\377"));
382: }
383: bitand(ol,or)
384: Q *ol,*or;
385: {
386: return(binop5(ol,or,"&\377"));
387: }
388: biteor(ol,or)
389: Q *ol,*or;
390: {
391: return(binop5(ol,or,"^\377"));
392: }
393: bitior(ol,or)
394: Q *ol,*or;
395: {
396: return(binop5(ol,or,"|\377"));
397: }
398: andop(ol,or)
399: Q *ol,*or;
400: {
401: return(binop10(ol,or,"&&\377"));
402: }
403: orop(ol,or)
404: Q *ol,*or;
405: {
406: return(binop10(ol,or,"||\377"));
407: }
408: altop(ol,or)
409: Q *ol,*or;
410: {
411: return(binop6(ol,or,":\377"));
412: }
413: questop(ol,or)
414: Q *ol,*or;
415: {
416: return(binop7(ol,or,"?\377"));
417: }
418: putop(ol,or)
419: Q *ol,*or;
420: {
421: return(binop8(ol,or,"= \377"));
422: }
423: assignop(ol,or,op)
424: Q *ol,*or;
425: char *op;
426: {
427: char *s;
428: if(ol->type!=F&&ol->type!=N) {
429: return(binop8(ol,or,op));
430: }
431: or=cvt(or,ol->type);
432: if(ol->type==N) or->type=ol->type=L; /* N returns L */
433: s=ol->type==F?"\377_f":"\377_n";
434:
435: /* if arguments to functions are evaluated left-to-right, each of these
436: must be flipped to xxxx(& ol , or ) */
437:
438: if(seq(op,"+= ")) return(prfx(s,bcat("eqpl(\377",or,",\377&",ol,")\377")));
439: if(seq(op,"-= ")) return(prfx(s,bcat("eqmi(\377",or,",\377&",ol,")\377")));
440: if(seq(op,"*= ")) return(prfx(s,bcat("eqmu(\377",or,",\377&",ol,")\377")));
441: if(seq(op,"/= ")) return(prfx(s,bcat("eqdv(\377",or,",\377&",ol,")\377")));
442: if(seq(op,"&= ")) return(prfx(s,bcat("eqan(\377",or,",\377&",ol,")\377")));
443: if(seq(op,"^= ")) return(prfx(s,bcat("eqer(\377",or,",\377&",ol,")\377")));
444: if(seq(op,"%= ")) return(prfx(s,bcat("eqmo(\377",or,",\377&",ol,")\377")));
445: if(seq(op,"|= ")) return(prfx(s,bcat("eqor(\377",or,",\377&",ol,")\377")));
446: if(seq(op,">>= ")) return(prfx(s,bcat("eqsr(\377",or,",\377&",ol,")\377")));
447: if(seq(op,"<<= ")) return(prfx(s,bcat("eqsl(\377",or,",\377&",ol,")\377")));
448: abt("illegal assign operator");
449: }
450: commaop(ol,or)
451: Q *ol,*or;
452: {
453: return(binop9(ol,or,",\377"));
454: }
455:
456: /* primatives called above */
457:
458: seq(s1,s2) /* are strings equal? */
459: char *s1,*s2;
460: {
461: while(*s1)if(*s1++!= *s2++)return(0);
462: return(*s2==0);
463: }
464:
465: cvt(op,ty) /*convert the type of an object*/
466: Q *op;
467: int ty;
468: {
469: if(op->type==ty) return(op);
470: if(ty==F) {
471: if(op->type==L) {
472: op->type=F;
473: return(prfx("\377_ffrl(",psfx(op,")")));
474: }
475: if(op->type==N) {
476: op->type=F;
477: return(prfx("\377_ffrn(",psfx(op,")")));
478: }
479: if(op->type==U) {
480: op->type=F;
481: return(prfx("\377_ffru(",psfx(op,")")));
482: }
483: op->type=F;
484: return(prfx("\377_ffri(",psfx(op,")")));
485: }
486: if(ty==L) {
487: if(op->type==F) {
488: op->type=L;
489: return(prfx("\377_ftol(",psfx(op,")")));
490: }
491: if(op->type==N) {
492: op->type=L;
493: return(prfx("\377_ntol(",psfx(op,")")));
494: }
495: op->type=L;
496: return(op);
497: }
498: if(ty==N) {
499: if(op->type==F) {
500: op->type=N;
501: return(prfx("\377_fton(",psfx(op,")")));
502: }
503: if(op->type==L) {
504: op->type=N;
505: return(prfx("\377_lton(",psfx(op,")")));
506: }
507: if(op->type==U) {
508: op->type=N;
509: return(prfx("\377_uton(",psfx(op,")")));
510: }
511: op->type=N;
512: return(prfx("\377_iton(",psfx(op,")")));
513: }
514: if(ty==U) {
515: if(op->type==F) {
516: op->type=ty;
517: return(prfx("\377_ftou(",psfx(op,")")));
518: }
519: if(op->type==N) {
520: op->type=ty;
521: return(prfx("\377_ntou(",psfx(op,")")));
522: }
523: op->type=ty;
524: return(op);
525: }
526: else {
527: if(op->type==F) {
528: op->type=ty;
529: return(prfx("\377_ftoi(",psfx(op,")")));
530: }
531: if(op->type==N) {
532: op->type=ty;
533: return(prfx("\377_ntoi(",psfx(op,")")));
534: }
535: op->type=ty;
536: return(op);
537: }
538: }
539:
540: copy(op) /* make a copy of op */
541: Q *op;
542: {
543: Q *ans;
544: int i,k;
545: ans=getq(k=op->size);
546: ans->type=op->type;
547: ans->size=k;
548: for(i=0; i<k; i++) ans->text[i]=op->text[i];
549: return(ans);
550: }
551:
552: prfx(s,op) /*prefix a string onto op*/
553: char *s;
554: Q *op;
555: {
556: int i,j,k;
557: Q *ans;
558: for(i=0; s[i]; i++);
559: ans=getq((k=op->size)+i);
560: for(i=0; *s; i++)ans->text[i]= *s++;
561: for(j=0; j<k; j++)ans->text[i++]=op->text[j];
562: ans->size=i;
563: ans->type=op->type;
564: free(op);
565: return(ans);
566: }
567:
568: psfx(op,s) /*postfix a string after op */
569: char *s;
570: Q *op;
571: {
572: int i,j,k;
573: Q *ans;
574: for(i=0; s[i]; i++);
575: ans=getq((k=op->size)+i);
576: for(i=0; i<k; i++)ans->text[i]=op->text[i];
577: while(*s)ans->text[i++]= *s++;
578: ans->size=i;
579: ans->type=op->type;
580: free(op);
581: return(ans);
582: }
583:
584: getq(sz) /* get a new Q with size=sz */
585: int sz;
586: {
587: Q *ans;
588: if((ans=alloc(sz+HEADLEN))==OUT) {
589: abt("out of storage in 'getq()'");
590: }
591: return(ans);
592: }
593: getqs(s) /* get a new Q with a string in it */
594: char *s;
595: {
596: int i;
597: Q *ans;
598: for(i=0; s[i]; i++);
599: ans=getq(i);
600: ans->type= -1;
601: ans->size=i;
602: while(--i>=0)ans->text[i]=s[i];
603: return(ans);
604: }
605:
606:
607: unop(s1,s2,op) /* unary minus rules */
608: char *s1,*s2;
609: Q *op;
610: {
611: if(op->type==F) {
612: return(prfx(s2,psfx(op,")")));
613: }
614: if(op->type==N) {
615: return(prfx(s1,cvt(op,L)));
616: }
617: else {
618: return(prfx(s1,op));
619: }
620: }
621:
622: unop2(s1,s2,op) /* unary ! rules */
623: char *s1,*s2;
624: Q *op;
625: {
626: if(op->type==F) {
627: op->type=I;
628: return(prfx(s2,psfx(op,")")));
629: }
630: else {
631: op->type=I;
632: return(prfx(s1,op));
633: }
634: }
635: unop3(s1,s2,op) /* unary ~ rules */
636: char *s1,*s2;
637: Q *op;
638: {
639: if(op->type==F) {
640: return(prfx(s2,psfx(op,")")));
641: }
642: else {
643: return(prfx(s1,op));
644: }
645: }
646:
647: unop4(s1,s2,s3,op) /* postfix ++ rules */
648: char *s1,*s2,*s3;
649: Q *op;
650: {
651: if(op->type==F) {
652: return(prfx(s2,psfx(op,")")));
653: }
654: if(op->type==N) {
655: op->type=L;
656: return(prfx(s3,psfx(op,")")));
657: }
658: else {
659: return(psfx(op,s1));
660: }
661: }
662: unop5(s1,s2,s3,op) /* prefix ++ rules */
663: char *s1,*s2,*s3;
664: Q *op;
665: {
666: if(op->type==F) {
667: return(prfx(s2,psfx(op,")")));
668: }
669: if(op->type==N) {
670: op->type=L;
671: return(prfx(s3,psfx(op,")")));
672: }
673: else {
674: return(prfx(s1,op));
675: }
676: }
677:
678: binop(ol,or,s1,s2) /* + rules */
679: char *s1,*s2;
680: Q *ol,*or;
681: {
682: if(ol->type==F||or->type==F) {
683: ol=cvt(ol,F); or=cvt(or,F);
684:
685: /* if arguments are evaluated left-to-right, flip this to read
686: bcat(s2,ol,",",or,")") */
687:
688: return(bcat(s2,or,",\377",ol,")"));
689: }
690: if(ol->type==N) ol=cvt(ol,L);
691: if(or->type==N) or=cvt(or,L);
692: if(ol->type==L||or->type==L) {
693: ol=cvt(ol,L); or=cvt(or,L);
694: return(qcat(psfx(ol,s1),or));
695: }
696: if(ol->type==U||or->type==U) {
697: ol=cvt(ol,U); or=cvt(or,U);
698: }
699: return(qcat(psfx(ol,s1),or));
700: }
701:
702: binop2(ol,or,s) /* >> rules */
703: char *s;
704: Q *ol,*or;
705: {
706: if(or->type!=I) or=cvt(or,I);
707: if(ol->type==N) ol=cvt(ol,L);
708: return(qcat(psfx(ol,s),or));
709: }
710:
711: binop3(ol,or,s1,s2) /* > rules */
712: char *s1,*s2;
713: Q *ol,*or;
714: {
715: if(ol->type==F||or->type==F) {
716: ol=cvt(ol,F); or=cvt(or,F);
717: ol->type=I;
718:
719: /* if arguments are evaluated left-to-right, flip this to read
720: bcat(s2,ol,",",or,")") */
721:
722: return(bcat(s2,or,",",ol,")"));
723: }
724: if(ol->type==N) ol=cvt(ol,L);
725: if(or->type==N) or=cvt(or,L);
726: ol->type=I;
727: return(qcat(psfx(ol,s1),or));
728: }
729:
730: binop4(ol,or,s) /* == rules */
731: char *s;
732: Q *ol,*or;
733: {
734: if(ol->type==F||or->type==F) {
735: ol=cvt(ol,F); or=cvt(or,F);
736: }
737: else if(ol->type==N||or->type==N) {
738: ol=cvt(ol,N); or=cvt(or,N);
739: }
740: else if(ol->type==L||or->type==L) {
741: ol=cvt(ol,L); or=cvt(or,L);
742: }
743: ol->type=I;
744: return(qcat(psfx(ol,s),or));
745: }
746: binop5(ol,or,s) /* bitwise & */
747: char *s;
748: Q *ol,*or;
749: {
750: if(ol->type==N) ol=cvt(ol,L);
751: if(or->type==N) or=cvt(or,L);
752: if(ol->type!=F&&ol->type!=L) {
753: if(or->type==F||or->type==L) ol->type=or->type;
754: }
755: return(qcat(psfx(ol,s),or));
756: }
757:
758: binop6(ol,or,s) /* : rules, as in ... ? ... : ... */
759: char *s;
760: Q *ol,*or;
761: {
762: if(ol->type==F||or->type==F) {
763: ol=cvt(ol,F); or=cvt(or,F);
764: }
765: if((ol->type==N||or->type==N)&&ol->type!=or->type) {
766: ol=cvt(ol,L);
767: or=cvt(or,L);
768: }
769: if(or->type==L) ol->type=L;
770: if(or->type==U) ol->type=U;
771: return(qcat(psfx(ol,s),or));
772: }
773:
774: binop7(ol,or,s) /* ? rules */
775: char *s;
776: Q *ol,*or;
777: {
778: ol->type=or->type;
779: return(qcat(psfx(ol,s),or));
780: }
781:
782: binop8(ol,or,s) /* = rules */
783: char *s;
784: Q *ol,*or;
785: {
786: int oltype;
787: oltype=ol->type;
788: return(qcat(psfx(ol,s),cvt(or,oltype)));
789: }
790:
791: binop9(ol,or,s) /* comma rules */
792: char *s;
793: Q *ol,*or;
794: {
795: ol->type=or->type;
796: return(qcat(psfx(ol,s),or));
797: }
798:
799: binop10(ol,or,s) /* logical or rules */
800: char *s;
801: Q *ol,*or;
802: {
803: ol->type=I;
804: return(qcat(psfx(ol,s),or));
805: }
806:
807: qcat(ol,or) /* cat two q's */
808: Q *ol,*or;
809: {
810: Q *ans;
811: int i,j,k;
812: ans=getq(k=(j=ol->size)+or->size);
813: ans->type=ol->type;
814: ans->size=k;
815: for(i=0; i<j; i++) ans->text[i]=ol->text[i];
816: for(i=0; j<k; i++) ans->text[j++]=or->text[i];
817: free(ol);
818: free(or);
819: return(ans);
820: }
821:
822: bcat(s1,ol,s2,or,s3) /* cat s's and o's */
823: char *s1,*s2,*s3;
824: Q *ol,*or;
825: {
826: return(qcat(prfx(s1,psfx(ol,s2)),psfx(or,s3)));
827: }
828:
829: /* parse an expression and return a Q pointer to it */
830:
831: expr(pr) /* precedence that stuff must be below */
832: int pr;
833: {
834: int keynum;
835: int dummy;
836: Q *token,*op;
837: keynum=whatprf(); /* get operation index */
838: if(keynum==LP) {
839: rmv(LP);
840: if(op=declspec()) {
841: dummy=0;
842: op=decltor(op,&dummy);
843: if(dummy)free(dummy);
844: op->type %= DFMOD;
845: skipbl();
846: strip(")");
847: token=expr(CASTP);
848: if(op->type==F||op->type==N||token->type==F||token->type==N) {
849: token=cvt(token,op->type);
850: free(op);
851: }
852: else {
853: token=cvt(token,op->type);
854: token=bcat("(",op,")",token,"");
855: }
856: }
857: else {
858: token=expr(0);
859: skipbl();
860: strip(")");
861: token=(prfx("(",psfx(token,")")));
862: }
863: }
864: else if(keynum==UNMINUS) {
865: rmv(UNMINUS);
866: token=(unminus(expr(UNMINUSP-1)));
867: }
868: else if(keynum==UNPLUS) {
869: rmv(UNPLUS);
870: token=(unplus(expr(UNPLUSP-1)));
871: }
872: else if(keynum==UNSTAR) {
873: rmv(UNSTAR);
874: token=(unstar(expr(UNSTARP-1)));
875: }
876: else if(keynum==UNADDR) {
877: rmv(UNADDR);
878: token=(unaddr(expr(UNADDRP-1)));
879: }
880: else if(keynum==UNNOT) {
881: rmv(UNNOT);
882: token=(unnot(expr(UNNOTP-1)));
883: }
884: else if(keynum==UNCOM) {
885: rmv(UNCOM);
886: token=(uncom(expr(UNCOMP-1)));
887: }
888: else if(keynum==UNINC1) {
889: rmv(UNINC1);
890: token=(uninc1(expr(UNINC1P-1)));
891: }
892: else if(keynum==UNDEC1) {
893: rmv(UNDEC1);
894: token=(undec1(expr(UNDEC1P-1)));
895: }
896: else if(keynum==SIZEOF) {
897: strip("sizeof");
898: if(look(skipbl())=='(') {
899: gc();
900: if((token=declspec())==0)token=expr(0);
901: else {
902: dummy=0;
903: token=decltor(token,&dummy);
904: if(dummy)free(dummy);
905: }
906: token=prfx("sizeof(\377",psfx(token,")"));
907: if(gc(skipbl())!=')')abt("expect ')' after sizeof(..");
908: }
909: else {
910: token=prfx("sizeof \377",expr(SIZEOFP-1));
911: }
912: token->type=I;
913: }
914:
915: /* get a constant or variable name */
916:
917: else if(keynum==CONST) {
918: token=constant();
919: }
920: else if(keynum==IDENT) {
921: token=ident();
922: }
923: else abt("expect expression, constant, or identifier");
924:
925: /* do postfix op and binary ops until no more at precedence pr */
926:
927: while(1) {
928: keynum=whatpsf(); /* get unary postfix operator */
929:
930: if(keynum==UNINC2&&pr<UNINC2P) {
931: rmv(UNINC2);
932: token=uninc2(token);
933: }
934: else if(keynum==UNDEC2&&pr<UNDEC2P) {
935: rmv(UNDEC2);
936: token=undec2(token);
937: }
938:
939: /* now try a binary operation */
940:
941: keynum=whatbin();
942:
943: if(keynum==SUBSCROP&&pr<SUBSCRP) {
944: token=subscr(token);
945: }
946: else if(keynum==FCALLOP&&pr<FCALLOPP) {
947: token=fcall(token);
948: }
949: else if(keynum==ADDOP&&pr<ADDOPP) {
950: rmv(ADDOP);
951: token=addop(token,expr(ADDOPP));
952: }
953: else if(keynum==SUBOP&&pr<SUBOPP) {
954: rmv(SUBOP);
955: token=subop(token,expr(SUBOPP));
956: }
957: else if(keynum==MULOP&&pr<MULOPP) {
958: rmv(MULOP);
959: token=mulop(token,expr(MULOPP));
960: }
961: else if(keynum==DIVOP&&pr<DIVOPP) {
962: rmv(DIVOP);
963: token=divop(token,expr(DIVOPP));
964: }
965: else if(keynum==GTOP&&pr<GTOPP) {
966: rmv(GTOP);
967: token=gtop(token,expr(GTOPP));
968: }
969: else if(keynum==GEOP&&pr<GEOPP) {
970: rmv(GEOP);
971: token=geop(token,expr(GEOPP));
972: }
973: else if(keynum==LEOP&&pr<LEOPP) {
974: rmv(LEOP);
975: token=leop(token,expr(LEOPP));
976: }
977: else if(keynum==LTOP&&pr<LTOPP) {
978: rmv(LTOP);
979: token=ltop(token,expr(LTOPP));
980: }
981: else if(keynum==EQOP&&pr<EQOPP) {
982: rmv(EQOP);
983: token=eqop(token,expr(EQOPP));
984: }
985: else if(keynum==NEOP&&pr<NEOPP) {
986: rmv(NEOP);
987: token=neop(token,expr(NEOPP));
988: }
989: else if(keynum==PUTOP&&pr<PUTOPP) {
990: rmv(PUTOP);
991: token=putop(token,expr(PUTOPP-1));
992: }
993: else if(keynum==OROP&&pr<OROPP) {
994: rmv(OROP);
995: token=orop(token,expr(OROPP));
996: }
997: else if(keynum==ANDOP&&pr<ANDOPP) {
998: rmv(ANDOP);
999: token=andop(token,expr(ANDOPP));
1000: }
1001: else if(keynum==MODOP&&pr<MODOPP) {
1002: rmv(MODOP);
1003: token=modop(token,expr(MODOPP));
1004: }
1005: else if(keynum==DOTOP&&pr<DOTOPP) {
1006: rmv(DOTOP);
1007: dotid=1; /* set id flag for alternate symbol table */
1008: token=dotop(token,expr(DOTOPP));
1009: }
1010: else if(keynum==PTROP&&pr<PTROPP) {
1011: rmv(PTROP);
1012: dotid=1; /* set id flag for alt s t */
1013: token=ptrop(token,expr(PTROPP));
1014: }
1015: else if(keynum==SHLOP&&pr<SHLOPP) {
1016: rmv(SHLOP);
1017: token=shlop(token,expr(SHLOPP));
1018: }
1019: else if(keynum==SHROP&&pr<SHROPP) {
1020: rmv(SHROP);
1021: token=shrop(token,expr(SHROPP));
1022: }
1023: else if(keynum==BITAND&&pr<BITANDP) {
1024: rmv(BITAND);
1025: token=bitand(token,expr(BITANDP));
1026: }
1027: else if(keynum==BITIOR&&pr<BITIORP) {
1028: rmv(BITIOR);
1029: token=bitior(token,expr(BITIORP));
1030: }
1031: else if(keynum==BITEOR&&pr<BITEORP) {
1032: rmv(BITEOR);
1033: token=biteor(token,expr(BITEORP));
1034: }
1035: else if(keynum==QSTOP&&pr<QSTOPP) {
1036: rmv(QSTOP);
1037: op=expr(QSTOPP2); /* need r to l grouping */
1038: if(gc(skipbl())!=':') abt("want ':' after '?'");
1039: token=questop(token,altop(op,expr(QSTOPP2)));
1040: }
1041: else if(keynum==APLUSOP&&pr<APLUSOPP) {
1042: rmv(APLUSOP);
1043: token=assignop(token,expr(APLUSOPP),"+= ");
1044: }
1045: else if(keynum==ASUBOP&&pr<ASUBOPP) {
1046: rmv(ASUBOP);
1047: token=assignop(token,expr(ASUBOPP),"-= ");
1048: }
1049: else if(keynum==AMULOP&&pr<AMULOPP) {
1050: rmv(AMULOP);
1051: token=assignop(token,expr(AMULOPP),"*= ");
1052: }
1053: else if(keynum==ADIVOP&&pr<ADIVOPP) {
1054: rmv(ADIVOP);
1055: token=assignop(token,expr(ADIVOPP),"/= ");
1056: }
1057: else if(keynum==AMODOP&&pr<AMODOPP) {
1058: rmv(AMODOP);
1059: token=assignop(token,expr(AMODOPP),"%= ");
1060: }
1061: else if(keynum==ASHLOP&&pr<ASHLOPP) {
1062: rmv(ASHLOP);
1063: token=assignop(token,expr(ASHLOPP),"<<= ");
1064: }
1065: else if(keynum==ASHROP&&pr<ASHROPP) {
1066: rmv(ASHROP);
1067: token=assignop(token,expr(ASHROPP),">>= ");
1068: }
1069: else if(keynum==AANDOP&&pr<AANDOPP) {
1070: rmv(AANDOP);
1071: token=assignop(token,expr(AANDOPP),"&= ");
1072: }
1073: else if(keynum==AIOROP&&pr<AIOROPP) {
1074: rmv(AIOROP);
1075: token=assignop(token,expr(AIOROPP),"|= ");
1076: }
1077: else if(keynum==AEOROP&&pr<AEOROPP) {
1078: rmv(AEOROP);
1079: token=assignop(token,expr(AEOROPP),"^= ");
1080: }
1081: else if(keynum==COMMAOP&&pr<COMMAOPP) {
1082: rmv(COMMAOP);
1083: token=commaop(token,expr(COMMAOPP));
1084: }
1085: else return(token);
1086: }
1087: }
1088:
1089: fcall(op) /* return a function call */
1090: Q *op;
1091: {
1092: strip("(");
1093: op=psfx(op,"(\377");
1094: if((op->type=op->type-MAXTYPE)<0)warn("illegal function call");
1095: skipbl();
1096: while(!strip(")")) {
1097: op=qcat(op,expr(COMMAOPP));
1098: if(strip(","))op=psfx(op,",\377");
1099: }
1100: return(psfx(op,")"));
1101: }
1102:
1103: alphanum() /* return a name string */
1104: {
1105: char *s;
1106: int i,c;
1107: if((s=alloc(NAMELEN+1))==OUT)abt("out of space in 'alphanum'");
1108: i=0;
1109: do {
1110: c=gc();
1111: if((c>='a'&&c<='z')||
1112: (c>='0'&&c<='9')||
1113: (c>='A'&&c<='Z')||
1114: c=='_') {
1115: s[i++]=c;
1116: }
1117: else {
1118: ug(c);
1119: break;
1120: }
1121: } while(i<NAMELEN);
1122: s[i]=0;
1123: if(*s==0) {
1124: free(s);
1125: return(0);
1126: }
1127: return(s);
1128: }
1129:
1130: ugs(s) /* unget a string */
1131: char *s;
1132: {
1133: int i;
1134: for(i=0; s[i]; i++);
1135: while(i>0)ug(s[--i]);
1136: free(s);
1137: }
1138:
1139: digits() /* strip a digit string */
1140: {
1141: char *s;
1142: int i,c;
1143: if((s=alloc(NUMBLEN+1))==OUT)abt("out of space in 'digits'");
1144: i=0;
1145: do {
1146: c=gc();
1147: if(c<='9'&&c>='0') {
1148: s[i++]=c;
1149: }
1150: else {
1151: ug(c);
1152: break;
1153: }
1154: } while(i<NUMBLEN);
1155: s[i]=0;
1156: if(*s==0) {
1157: free(s);
1158: return(0);
1159: }
1160: return(s);
1161: }
1162:
1163: anyof(s) /* return a string of s's */
1164: char *s;
1165: {
1166: int c,i,j;
1167: char *ans;
1168: if((ans=alloc(STRLEN+1))==OUT)abt("out of room in 'anyof'");
1169: i=0;
1170: do {
1171: c=gc();
1172: for(j=0; s[j]; j++) if(c==s[j])break;
1173: if(s[j]==0) {
1174: ug(c);
1175: break;
1176: }
1177: ans[i++]=c;
1178: } while(i<STRLEN);
1179: ans[i]=0;
1180: if(*ans==0) {
1181: free(ans);
1182: return(0);
1183: }
1184: return(ans);
1185: }
1186:
1187: ident() /* return a q-object identifier */
1188: {
1189: char *s;
1190: Q *op;
1191: int i;
1192: skipbl();
1193: if((s=alphanum())==0)abt("expect identifier");
1194: for(i=0; s[i]; i++);
1195: op=getq(i);
1196: op->size=i;
1197: for(i=0; s[i]; i++)op->text[i]=s[i];
1198: if(dotid) {
1199: *s |= 0200;
1200: dotid=0;
1201: }
1202: op->type=gettype(s);
1203: free(s);
1204: return(op);
1205: }
1206:
1207: subscr(op) /* return added subscripting */
1208: Q *op;
1209: {
1210: Q *or;
1211: skipbl();
1212: while(look()=='[') {
1213: gc();
1214: or=expr(0);
1215: if(op->type<MAXTYPE&&or->type>=MAXTYPE) {
1216: op=cvt(op,I);
1217: op->type=or->type;
1218: }
1219: else or=cvt(or,I);
1220: op=bcat("",op,"[\377",or,"]");
1221: if((op->type=op->type-MAXTYPE)<0)warn("too many subscripts");
1222: skipbl();
1223: if(gc()!=']')abt("expect close subscript");
1224: skipbl();
1225: }
1226: return(op);
1227: }
1228:
1229: look() /* get and put back a character */
1230: {
1231: int c;
1232: ug(c=gc());
1233: return(c);
1234: }
1235:
1236: constant() /* return a Q constant */
1237: {
1238: Q *op;
1239: skipbl();
1240: if(look()=='0') {
1241: gc();
1242: if(look()=='x'||look()=='X') {
1243: gc();
1244: op=hex();
1245: }
1246: else if(look()=='.') op=decimal();
1247: else op=octal();
1248: }
1249: else if(look()=='\'') op=charc();
1250: else if(look()=='"') op=stringc();
1251: else op=decimal();
1252: return(op);
1253: }
1254:
1255: octal() /* return octal constant */
1256: {
1257: Q *op;
1258: char *s;
1259: long num;
1260: int i;
1261: if((s=digits())==0) {
1262: op=getq(1);
1263: op->type=I;
1264: op->size=1;
1265: op->text[0]='0';
1266: if(look()=='l'||look()=='L') {
1267: gc();
1268: op=psfx(op,"L");
1269: op->type=L;
1270: }
1271: return(op);
1272: }
1273: for(num=i=0; s[i]; i++)num=num*8+s[i]-'0';
1274: op=getq(i);
1275: op->size=i;
1276: if(num>32767)op->type=L; else op->type=I;
1277: for(i=0; i<op->size; i++) op->text[i]=s[i];
1278: free(s);
1279: if(look()=='l'||look()=='L') {
1280: gc();
1281: op->type=L;
1282: op=psfx(op,"L");
1283: }
1284: return(prfx("0",op));
1285: }
1286:
1287: hex() /* return hex constant */
1288: {
1289: Q *op;
1290: char *s;
1291: long num;
1292: int i;
1293: while((s=anyof("0123456789ABCDEFabcdef"))==0) ug('0');
1294: for(num=i=0; s[i]; i++) {
1295: if(s[i]>='a'&&s[i]<='f')num=num*16+s[i]-'a'+10;
1296: else if(s[i]>='A'&&s[i]<='F')num=num*16+s[i]-'A'+10;
1297: else num=num*16+s[i]-'0';
1298: }
1299: op=getq(i);
1300: op->size=i;
1301: if(num>32767)op->type=L; else op->type=I;
1302: for(i=0; i<op->size; i++) op->text[i]=s[i];
1303: free(s);
1304: if(look()=='l'||look()=='L') {
1305: gc();
1306: op->type=L;
1307: op=psfx(op,"L");
1308: }
1309: return(prfx("0X",op));
1310: }
1311:
1312: decimal() /* return decimal number */
1313: {
1314: Q *op;
1315: char *s;
1316: long num;
1317: int i;
1318: if((s=digits())==0) {
1319: return(floatc());
1320: }
1321: if(look()=='.'||look()=='e'||look()=='E') {
1322: ugs(s);
1323: return(floatc());
1324: }
1325: for(num=i=0; s[i]; i++)num=num*10+s[i]-'0';
1326: op=getq(i);
1327: op->size=i;
1328: if(num>32767)op->type=L; else op->type=I;
1329: for(i=0; i<op->size; i++) op->text[i]=s[i];
1330: free(s);
1331: if(look()=='l'||look()=='L') {
1332: gc();
1333: op->type=L;
1334: op=psfx(op,"L");
1335: }
1336: return(op);
1337: }
1338:
1339: floatc() /* return a float constant */
1340: {
1341: Q *op;
1342: /**********this code redone avoiding floating point below.....
1343: int i,c;
1344: double fnum,xp;
1345: long lnum;
1346: i=0;
1347: fnum=0.0;
1348: xp=1.0;
1349: while((c=gc())<='9'&&c>='0')fnum=fnum*10.0+c-'0';
1350: if(c=='.') {
1351: while((c=gc())<='9'&&c>='0')fnum=fnum+(c-'0')/(xp=xp*10.0);
1352: }
1353: if(c=='e'||c=='E') {
1354: if((c=gc())=='-') {
1355: while((c=gc())<='9'&&c>='0')i=i*10+c-'0';
1356: while(--i>=0)fnum=fnum/10.0;
1357: }
1358: else {
1359: ug(c);
1360: while((c=gc())<='9'&&c>='0')i=i*10+c-'0';
1361: while(--i>=0)fnum=fnum*10.0;
1362: }
1363: }
1364: ********this code replaced by below */
1365: #define FWH 256
1366: #define FW (FWH*2)
1367: #define DEC (c=gc())<='9'&&c>='0'
1368: char q[FW+1];
1369: int i,j,k,c;
1370: long fnum;
1371: long lnum;
1372: i=0; /* tens exponent */
1373: k=0; /* twos exponent */
1374: for(j=0; j<FW; j++)q[j]=0; /* set bit array to zero */
1375: while(DEC)multenadd(q,c-'0'); /* mul by 10 and add character */
1376: if(c=='.') {
1377: while(DEC) {
1378: multenadd(q,c-'0');
1379: i--; /* decr tens exponent */
1380: }
1381: }
1382: if(c=='e'||c=='E') {
1383: if((c=gc())=='-') {
1384: for(j=0; DEC; j=j*10+c-'0');
1385: i -= j;
1386: }
1387: else {
1388: ug(c);
1389: for(j=0; DEC; j=j*10+c-'0');
1390: i += j;
1391: }
1392: }
1393: if(i>0)while(i--)multenadd(q,0);
1394: else if(i<0)while(i++)divten(q,&k);
1395: for(j=FW-1; j>23; --j)if(q[j])break; /* find leading bit */
1396: i=j+k+(0201-FWH); /* exponent for fltg point number */
1397: if(i>0377)i=0377;
1398: if(i<0)i=0;
1399: fnum=i;
1400: fnum <<= 31-8;
1401: if(i) {
1402: for(k=31-9; --j&&k>=0; --k) {
1403: if(q[j])fnum |= 1l<<k;
1404: }
1405: }
1406: /* **** end of replacement code, number now in fnum **** */
1407: ug(c);
1408: dblflt(&lnum,&fnum); /* copy two hi words */
1409: op=getq(13); /*0 00000000000 L*/
1410: op->size=13;
1411: op->type=F;
1412: i=13;
1413: op->text[--i]='L';
1414: while(i) {
1415: c=lnum;
1416: op->text[--i]=(c&7)+'0';
1417: lnum=lnum>>3;
1418: lnum=lnum&03777777777l;
1419: }
1420: return(op);
1421: }
1422:
1423: /* mul by 10 and div by 10 for replacement code above */
1424: multenadd(q,ad)
1425: int ad;
1426: char *q;
1427: {
1428: int j;
1429: for(j=0; j<FW; j++)q[j] *= 10;
1430: q[FWH] += ad;
1431: for(j=0; j<FW; j++)
1432: while(q[j]>1) {
1433: q[j] -= 2;
1434: q[j+1]++;
1435: }
1436: }
1437: divten(q,xc)
1438: int *xc;
1439: char *q;
1440: {
1441: int i,j;
1442: for(j=FW; j>=4; --j) {
1443: i=q[j-1]*8+q[j-2]*4+q[j-3]*2+q[j-4];
1444: if(i>=5) {
1445: q[j-1]=1;
1446: i -= 5;
1447: q[j-2]=i>=4;
1448: q[j-3]=i%4>=2;
1449: q[j-4]=i%2;
1450: }
1451: }
1452: *xc -= 4;
1453: }
1454: /**** end of mul and div routines ****/
1455: dblflt(lnump,fnump) /* reorder float words into a long */
1456: int *lnump; /* called with long */
1457: int *fnump; /* called with double */
1458: {
1459: if(unixfmt) {
1460: lnump[0]=fnump[0];
1461: lnump[1]=fnump[1];
1462: }
1463: else {
1464: lnump[1]=fnump[0];
1465: lnump[0]=fnump[1];
1466: }
1467: }
1468:
1469: charc() /* return a character constant */
1470: {
1471: Q *op;
1472: int i;
1473: int e;
1474: op=getq(CHCONST);
1475: for(e=1,i=0; i<CHCONST; i++) {
1476: if((op->text[i]=gc2())==0)abt("missing end \"'\"");
1477: if(e)e=0;
1478: else if(op->text[i]=='\\')e=1;
1479: else if(op->text[i]=='\'')break;
1480: }
1481: if(i==CHCONST)abt("character const too long");
1482: op->type=I;
1483: op->size=i+1;;
1484: return(op);
1485: }
1486:
1487: stringc() /* return a string constant */
1488: {
1489: Q *op;
1490: static char s[2]; /* ensure trailing null */
1491: int e;
1492: op=getq(1);
1493: op->text[0]=gc();
1494: op->type=I+MAXTYPE;
1495: op->size=1;
1496: e=0;
1497: while(1) {
1498: if((*s=gc2())==0)abt("missing end '\"'");
1499: op=psfx(op,s);
1500: if(e)e=0;
1501: else if(*s=='\\')e=1;
1502: else if(*s=='"')break;
1503: }
1504: return(op);
1505: }
1506:
1507: skipbl() /* skip 'blanks' */
1508: {
1509: int c;
1510: while((c=gc())==' '||c=='\n'||c=='\t');
1511: ug(c);
1512: }
1513:
1514: whatprf() /* return keyword of unary-prefix operation/thing */
1515: {
1516: int r;
1517: char *s;
1518: skipbl();
1519: r=0;
1520: if(s=anyof("*&-!~+(.")) {
1521: if(*s=='*') r=UNSTAR;
1522: else if(*s=='&') r=UNADDR;
1523: else if(*s=='-') {
1524: if(s[1]=='-') r=UNDEC1;
1525: else r=UNMINUS;
1526: }
1527: else if(*s=='.') r=CONST;
1528: else if(*s=='!') r=UNNOT;
1529: else if(*s=='~') r=UNCOM;
1530: else if(*s=='+') {
1531: if(s[1]=='+') r=UNINC1;
1532: else r=UNPLUS;
1533: }
1534: else if(*s=='(') r=LP;
1535: ugs(s);
1536: if(r)return(r);
1537: }
1538: if(look()=='"'||look()=='\'')return(CONST);
1539: if(s=alphanum()) {
1540: if(*s>='0'&&*s<='9') {
1541: ugs(s);
1542: return(CONST);
1543: }
1544: if(seq(s,"sizeof")) {
1545: ugs(s);
1546: return(SIZEOF);
1547: }
1548: ugs(s);
1549: return(IDENT);
1550: }
1551: abt("expect unary operator or identifier or constant");
1552: }
1553:
1554: whatpsf() /* return postfix unary operator */
1555: {
1556: char *s;
1557: int r;
1558: skipbl();
1559: r=0;
1560: if(s=anyof("+-")) {
1561: if(*s=='+'&&s[1]=='+') r=UNINC2;
1562: else if(*s=='-'&&s[1]=='-') r=UNDEC2;
1563: ugs(s);
1564: }
1565: return(r);
1566: }
1567:
1568: whatbin() /* return binary operator */
1569: {
1570: char *s;
1571: int r;
1572: skipbl();
1573: r=0;
1574: if(s=anyof("*/%+-<>=!&^|?,.([")) {
1575: if(*s=='(') r=FCALLOP;
1576: else if(*s=='[') r=SUBSCROP;
1577: else if(*s=='-') {
1578: if(s[1]=='>') r=PTROP;
1579: else if(s[1]=='=') r=ASUBOP;
1580: else r=SUBOP;
1581: }
1582: else if(*s=='/') {
1583: if(s[1]=='=') r=ADIVOP;
1584: else r=DIVOP;
1585: }
1586: else if(*s=='*') {
1587: if(s[1]=='=') r=AMULOP;
1588: else r=MULOP;
1589: }
1590: else if(*s=='.') r=DOTOP;
1591: else if(*s=='%') {
1592: if(s[1]=='=') r=AMODOP;
1593: else r=MODOP;
1594: }
1595: else if(*s=='+') {
1596: if(s[1]=='=') r=APLUSOP;
1597: else r=ADDOP;
1598: }
1599: else if(*s=='<') {
1600: if(s[1]=='<') {
1601: if(s[2]=='=') r=ASHLOP;
1602: else r=SHLOP;
1603: }
1604: else if(s[1]=='=') r=LEOP;
1605: else r=LTOP;
1606: }
1607: else if(*s=='>') {
1608: if(s[1]=='>') {
1609: if(s[2]=='=') r=ASHROP;
1610: else r=SHROP;
1611: }
1612: else if(s[1]=='=') r=GEOP;
1613: else r=GTOP;
1614: }
1615: else if(*s=='=') {
1616: if(s[1]=='=') r=EQOP;
1617: else if(s[1]=='>'&&s[2]=='>')
1618: r=ASHROP;
1619: else if(s[1]=='<'&&s[2]=='<')
1620: r=ASHLOP;
1621: else if(s[1]=='+') r=APLUSOP;
1622: else if(s[1]=='-') r=ASUBOP;
1623: else if(s[1]=='*') r=AMULOP;
1624: else if(s[1]=='/') r=ADIVOP;
1625: else if(s[1]=='%') r=AMODOP;
1626: else if(s[1]=='&') r=AANDOP;
1627: else if(s[1]=='^') r=AEOROP;
1628: else if(s[1]=='|') r=AIOROP;
1629: else r=PUTOP;
1630: }
1631: else if(*s=='!'&&s[1]=='=') r=NEOP;
1632: else if(*s=='&') {
1633: if(s[1]=='&') r=ANDOP;
1634: else if(s[1]=='=') r=AANDOP;
1635: else r=BITAND;
1636: }
1637: else if(*s=='^') {
1638: if(s[1]=='=') r=AEOROP;
1639: else r=BITEOR;
1640: }
1641: else if(*s=='|') {
1642: if(s[1]=='|') r=OROP;
1643: else if(s[1]=='=') r=AIOROP;
1644: else r=BITIOR;
1645: }
1646: else if(*s=='?') r=QSTOP;
1647: else if(*s==',') r=COMMAOP;
1648: ugs(s);
1649: }
1650: return(r);
1651: }
1652:
1653: rmv(r) /* delete the r-type found above */
1654: int r;
1655: {
1656: if(r==UNSTAR||r==UNADDR||r==UNMINUS||
1657: r==UNNOT||r==UNCOM||r==UNPLUS||r==LP) {
1658: gc();
1659: }
1660: else if(r==UNDEC1||r==UNDEC2||r==UNINC1||r==UNINC2) {
1661: gc();
1662: gc();
1663: }
1664: else if(r==SUBOP||r==DIVOP||r==MODOP||r==ADDOP||r==LTOP||
1665: r==GTOP||r==PUTOP||r==BITAND||r==BITEOR||
1666: r==BITIOR||r==QSTOP||
1667: r==MULOP||r==COMMAOP||r==DOTOP) {
1668: gc();
1669: }
1670: else if(r==PTROP||r==ASUBOP||r==ADIVOP||r==AMODOP||
1671: r==APLUSOP||r==SHLOP||r==LEOP||r==SHROP||
1672: r==GEOP||r==EQOP||r==AANDOP||r==AEOROP||
1673: r==AIOROP||r==NEOP||r==ANDOP||r==OROP||
1674: r==AMULOP) {
1675: gc();
1676: gc();
1677: }
1678: else if(r==ASHLOP||r==ASHROP) {
1679: gc();
1680: gc();
1681: gc();
1682: }
1683: }
1684:
1685: strip(s) /* remove a string */
1686: char *s;
1687: {
1688: while(*s++==look())gc();
1689: return(!*--s);
1690: }
1691: declspec()
1692: {
1693: Q *q;
1694: int c;
1695: char *s;
1696: if(s=alphanum(skipbl())) {
1697: q=getq(0);
1698: q->size=0;
1699: q->type=0;
1700: q=sclass(q,s);
1701: if(q->size) {
1702: free(s);
1703: s=alphanum(skipbl());
1704: }
1705: if(s&&((c=gettype(s))&DFTYPEDF)) {
1706: if(c&DFFUNCT2)c=(c^DFFUNCT2)|DFFUNCT;
1707: q->type |= c^DFTYPEDF;
1708: q=psfx(psfx(q,s)," ");
1709: skipbl();
1710: free(s);
1711: return(q);
1712: }
1713: while(s) {
1714: if(seq(s,"char")) (q=psfx(q,"char "))->type |= CHAR;
1715: else if(seq(s,"short")) (q=psfx(q,"short "))->type |= SHORT;
1716: else if(seq(s,"int")) (q=psfx(q,"int "))->type |= INT;
1717: else if(seq(s,"long")) (q=psfx(q,"long "))->type |= LONG;
1718: else if(seq(s,"unsigned"))(q=psfx(q,"unsigned "))->type |=
1719: UNSIGNED;
1720: else if(seq(s,"float")) (q=psfx(q,"long "))->type |= FLOAT;
1721: else if(seq(s,"double")) (q=psfx(q,"long "))->type |= DOUBLE;
1722: else if(seq(s,"struct")) (q=psfx(q,"struct "))->type |= STRUCT;
1723: else if(seq(s,"union")) (q=psfx(q,"union "))->type |= UNION;
1724: else if(seq(s,"floatn")) (q=psfx(q,"long "))->type |= FLOATN;
1725: else if(seq(s,"intn")) (q=psfx(q,"long "))->type |= INTN;
1726:
1727: /* can sc specifier appear anywhere but first? it appears that "C"
1728: accepts it elsewhere, unlike the specification. skip it if found
1729: here. */
1730:
1731: else {
1732: if(seq(s,"auto"))q=psfx(q,"auto ");
1733: else if(seq(s,"static"))q=psfx(q,"static ");
1734: else if(seq(s,"extern"))q=psfx(q,"extern ");
1735: else if(seq(s,"register"))q=psfx(q,"register ");
1736: else if(seq(s,"typedef"))q=psfx(q,"typedef "); /*cmon*/
1737: else break;
1738: warn("misplaced sc specifier");
1739: }
1740: free(s);
1741: s=alphanum(skipbl());
1742: }
1743: if(s) ugs(s);
1744: if(q->size) {
1745: c=q->type;
1746: if(c&(CHAR|SHORT))q->type=I;
1747: else if(c&(FLOAT|FLOATN|DOUBLE))q->type=F;
1748: else if(c&(LONG))q->type=L;
1749: else if(c&(INTN))q->type=N;
1750: else if(c&(UNION|STRUCT))q->type=DFSTRUCT|FFSTRUCT;
1751: else if(c&(UNSIGNED))q->type=U;
1752: else q->type=I;
1753: if(c&TYPEDF)q->type |= DFTYPEDF;
1754: return(q);
1755: }
1756: free(q);
1757: }
1758: return(0);
1759: }
1760:
1761: sclass(q,s)
1762: Q *q;
1763: char *s;
1764: {
1765: if(seq(s,"auto"))return(psfx(q,"auto "));
1766: if(seq(s,"static"))return(psfx(q,"static "));
1767: if(seq(s,"extern"))return(psfx(q,"extern "));
1768: if(seq(s,"register"))return(psfx(q,"register "));
1769: if(seq(s,"typedef")) {
1770: q->type |= TYPEDF;
1771: return(psfx(q,"typedef "));
1772: }
1773: return(q);
1774: }
1775:
1776: /* parse a decraration list */
1777: declist(op)
1778: Q *op;
1779: {
1780: Q *q;
1781: char *s;
1782: while(look(skipbl())!=';') {
1783: s=0;
1784: q=getq(0);
1785: q->size=0;
1786: q->type=op->type;
1787: q=decltor(q,&s);
1788: if((q->type&DFTYPEDF)&&(q->type&DFFUNCT))q->type |= DFFUNCT2;
1789: if(s) {
1790: if(instruct)*s |= 0200;
1791: definesy(s,lasttype=q->type%DFMOD);
1792: free(s);
1793: }
1794: else if(q->size==0)abt("can't parse declarator list");
1795: if(look(skipbl())!=';'&&look()!=','&&(q->type&DFFUNCT)==0) {
1796: if(look()=='=') {
1797: gc();
1798: q=psfx(q," =\377");
1799: }
1800: q=initdcl(q);
1801: }
1802: if(look(skipbl())==',') {
1803: gc();
1804: op=qcat(op,psfx(q,",\377"));
1805: }
1806: else {
1807: op=qcat(op,q);
1808: break;
1809: }
1810: }
1811: return(op);
1812: }
1813:
1814: /* parse a declarator eg. **s[3][2] */
1815: /* This is messy. If sp is zero, the first alphanumeric encountered
1816: is stripped out and put into it (the symbol being declared). When
1817: this is done, DFLASTID is set. If a "(" is parsed with DFLASTID set,
1818: the identifier is a function, and DFFUNCT is set. This is used by
1819: caller to determine that an initialization is not allowed. If a
1820: "*" is encountered, DFLASTID is cleared. Thus,
1821:
1822: (*f)() {0
1823:
1824: cannot be the start of a function definition, but is a declaration
1825: of f as pointer to a function, which pointer is initialized to 0, and
1826:
1827: *f() {0
1828:
1829: is the start of a new function (there is no variable to initialize).
1830:
1831: The flag "skiptext" informs decltor that it is inside at least one
1832: "(", and must eat all text until balancing ")"'s are encountered
1833: (otherwise it stops at commas, for example). If, while skiptext is
1834: set, with DFFUNCT also set (and level==0, though it shouldn't matter),
1835: some more alphanumeric symbols are found, they are prototype arguments.
1836: Stash them in "argchain" for later definition (at higher level) as
1837: "int" in case there is no declaration for them.
1838: */
1839: decltor(q,sp) /* parse a declarator, return symbol in *sp,type in q */
1840: Q *q;
1841: char **sp;
1842: {
1843: char *s;
1844: struct argchain *temp;
1845: static int skiptext;
1846: while(1) {
1847: if(look(skipbl())=='(') {
1848: skiptext++;
1849: gc();
1850: if(q->type&DFLASTID) {
1851: q->type += MAXTYPE;
1852: if(q->type&DFLASTID) q->type |= DFFUNCT;
1853: q->type &= ~DFLASTID;
1854: }
1855: else if(look(skipbl())==')')q->type += MAXTYPE;
1856: q=decltor(psfx(q,"("),sp);
1857: while(look(skipbl())==',') {
1858: gc();
1859: q=decltor(psfx(q,",\377"),sp);
1860: }
1861: if(gc()!=')')abt("expect ')' in declarator");
1862: skiptext--;
1863: q=psfx(q,")\377");
1864: }
1865: else if(look()=='*') {
1866: gc();
1867: q=decltor(psfx(q," *"),sp);
1868: q->type &= ~DFLASTID;
1869: q->type += MAXTYPE;
1870: }
1871: else if(look()=='[') {
1872: gc();
1873: q->type += MAXTYPE;
1874: if(look(skipbl())!=']')q=bcat("",q,"[",expr(0),"]");
1875: else q=psfx(q,"[]");
1876: if(gc(skipbl())!=']')abt("expect ']' in subscript");
1877: }
1878: else if((*sp==0||skiptext)&&(s=alphanum())) {
1879: q=psfx(psfx(q,"\377 "),s);
1880: if(*sp==0) {
1881: *sp=s;
1882: q->type |= DFLASTID;
1883: }
1884: /* A late adddition: if we are inside the argument list
1885: of a function prototype, form a list of the arguments
1886: chained off of "arglist" to define as integer type in
1887: case not declared by explicit declaration. Check of level
1888: should firewall the change's effects pretty well */
1889:
1890: else if(level==0&&skiptext&&(q->type&DFFUNCT)) {
1891: temp=argchain;
1892: (argchain=getq(0))->acnext=temp;
1893: argchain->acstring=s;
1894: }
1895:
1896: else free(s);
1897: }
1898: else if(look()==':') {
1899: gc();
1900: q=qcat(psfx(q,":"),expr(COMMAOPP));
1901: }
1902: else break;
1903: }
1904: return(q);
1905: }
1906:
1907: /* do initialization */
1908: initdcl(op)
1909: Q *op;
1910: {
1911: if(look(skipbl())=='{') {
1912: gc();
1913: op=psfx(op," \377{");
1914: while(look(skipbl())!=';'&&look()!='}') {
1915: op=initdcl(op);
1916: if(look(skipbl())==',') {
1917: gc();
1918: op=psfx(op,",\377");
1919: }
1920: }
1921: op=psfx(op,"}\377");
1922: if(gc(skipbl())!='}')abt("expect '}' in init");
1923: }
1924: else op=qcat(op,prfx(" \377",expr(COMMAOPP)));
1925: return(op);
1926: }
1927:
1928: /* parse and output a statement */
1929: statement()
1930: {
1931: Q *op;
1932: int c;
1933: char *s;
1934: if(look(skipbl())=='{') {
1935: gc();
1936: definelv(++level);
1937: op=getqs("\n{\n"); outq(op); free(op);
1938: while(op=declarat()) {
1939: outq(op);
1940: free(op);
1941: }
1942: while(statement());
1943: if(gc(skipbl())!='}')abt("expect '}' for end of block");
1944: op=getqs("\n}\n"); outq(op); free(op);
1945: definelv(--level);
1946: return(1);
1947: }
1948: else if(look()==';') {
1949: gc();
1950: op=getqs(";\n"); outq(op); free(op);
1951: return(1);
1952: }
1953: else if(look()=='}')return(0);
1954: else if(s=alphanum()) {
1955: if(seq(s,"if")) { /* do if() [else] */
1956: free(s);
1957: if(gc(skipbl())!='(')abt("expect '(' after 'if'");
1958: op=getqs("if(\377");
1959: if(look(skipbl())!=')') op=qcat(op,expr(0));
1960: op=psfx(op,")\377");
1961: if(gc(skipbl())!=')') abt("expect ')' after 'if(...'");
1962: outq(op);
1963: free(op);
1964: statement();
1965: if(s=alphanum(skipbl())) {
1966: if(seq(s,"else")) {
1967: free(s);
1968: op=getqs("else \377");
1969: outq(op);
1970: free(op);
1971: statement();
1972: }
1973: else ugs(s);
1974: }
1975: return(1);
1976: }
1977: else if(seq(s,"while")) {
1978: free(s);
1979: if(gc(skipbl())!='(')abt("expect '(' after 'while'");
1980: op=getqs("while(\377");
1981: if(look(skipbl())!=')')op=qcat(op,expr(0));
1982: op=psfx(op,")\377");
1983: if(gc(skipbl())!=')') abt("expect ')' after 'while(...'");
1984: outq(op);
1985: free(op);
1986: statement();
1987: return(1);
1988: }
1989: else if(seq(s,"do")) {
1990: free(s);
1991: op=getqs("do \377");
1992: outq(op);
1993: free(op);
1994: statement();
1995: if((s=alphanum(skipbl()))&&seq(s,"while")) {
1996: free(s);
1997: if(gc(skipbl())!='(')
1998: abt("expect '(' after 'do ... while'");
1999: else op=getqs("\377while(\377");
2000: if(look(skipbl())!=')') {
2001: op=qcat(op,expr(0));
2002: }
2003: if(gc(skipbl())!=')')
2004: abt("expect ')' after 'do ... while('");
2005: if(gc(skipbl())!=';')
2006: abt("expect ';' after 'do while()'");
2007: op=psfx(op,");\n");
2008: outq(op);
2009: free(op);
2010: return(1);
2011: }
2012: else abt("expect 'while' after 'do'");
2013: }
2014: else if(seq(s,"for")) {
2015: free(s);
2016: if(gc(skipbl())!='(') abt("expect '(' after 'for'");
2017: op=getqs("for(\377");
2018: if(look(skipbl())!=';') op=qcat(op,expr(0));
2019: if(gc(skipbl())!=';') abt("expect ';' after 'for( ...'");
2020: op=psfx(op,";\377");
2021: if(look(skipbl())!=';') op=qcat(op,expr(0));
2022: if(gc(skipbl())!=';') abt("expect ';' after 'for(...;...'");
2023: op=psfx(op,";\377");
2024: if(look(skipbl())!=')') op=qcat(op,expr(0));
2025: if(gc(skipbl())!=')') abt("expect ')' after 'for(..;..;..'");
2026: op=psfx(op,") \377");
2027: outq(op);
2028: free(op);
2029: statement();
2030: return(1);
2031: }
2032: else if(seq(s,"switch")) {
2033: free(s);
2034: if(gc(skipbl())!='(') abt("expect '(' after 'switch'");
2035: op=prfx("switch(\377",expr(0));
2036: if(gc(skipbl())!=')')abt("expect ')' after 'switch(...'");
2037: op=psfx(op,")\n");
2038: outq(op);
2039: free(op);
2040: return(statement());
2041: }
2042: else if(seq(s,"case")) {
2043: free(s);
2044: op=prfx("\377case ",expr(0));
2045: if(gc(skipbl())!=':') abt("expect ':' after 'case'");
2046: op=psfx(op,":\377");
2047: outq(op);
2048: free(op);
2049: return(statement());
2050: }
2051: else if(seq(s,"default")) {
2052: free(s);
2053: if(gc(skipbl())!=':') abt("expect ':' after 'default'");
2054: op=getqs("default:\377");
2055: outq(op);
2056: free(op);
2057: return(statement());
2058: }
2059: else if(seq(s,"break")) {
2060: free(s);
2061: if(gc(skipbl())!=';') abt("expect ';' after 'break'");
2062: op=getqs("break;\n");
2063: outq(op);
2064: free(op);
2065: return(1);
2066: }
2067: else if(seq(s,"continue")) {
2068: free(s);
2069: if(gc(skipbl())!=';') abt("expect ';' after 'continue'");
2070: op=getqs("continue;\n");
2071: outq(op);
2072: free(op);
2073: return(1);
2074: }
2075: else if(seq(s,"return")) {
2076: free(s);
2077: op=getqs("return ");
2078: if(look(skipbl())!=';')op=qcat(op,cvt(expr(0),frettype));
2079: if(gc(skipbl())!=';') abt("expect ';' after 'return ... '");
2080: op=psfx(op,";\n");
2081: outq(op);
2082: free(op);
2083: return(1);
2084: }
2085: else if(seq(s,"goto")) {
2086: free(s);
2087: if((s=alphanum(skipbl()))==0) abt("goto where?");
2088: op=psfx(getqs("goto "),s); /*god*/
2089: if(gc(skipbl())!=';') abt("expect ';' after 'goto ...'");
2090: op=psfx(op,";\n");
2091: outq(op);
2092: free(op);
2093: return(1);
2094: }
2095: else if((c=look())==':'||look(skipbl())==':') {
2096: op=psfx(getqs(s),":\377");
2097: gc();
2098: free(s);
2099: outq(op);
2100: free(op);
2101: statement();
2102: return(1);
2103: }
2104: else {
2105: if(c!=look()) ug(c);
2106: ugs(s);
2107: }
2108: }
2109: /* must be an expression statement! */
2110: {
2111: op=psfx(expr(0),";\n");
2112: outq(op);
2113: free(op);
2114: if(gc(skipbl())!=';')abt("expect ';' after expression");
2115: return(1);
2116: }
2117: }
2118:
2119: /* do a declaration statement */
2120: declarat()
2121: {
2122: Q *op;
2123: if(op=declspec()) {
2124: if((op->type&FFSTRUCT)) op=declstru(op);
2125: else op=declist(op);
2126: if(gc(skipbl())!=';')abt("expect ';' after declaration");
2127: return(psfx(op,";\n"));
2128: }
2129: else return(0);
2130: }
2131:
2132: /* do a struct or union statement */
2133: declstru(op)
2134: Q *op;
2135: {
2136: char *s;
2137: Q *q;
2138: s=alphanum(skipbl());
2139: if(look(skipbl())=='{') {
2140: gc();
2141: if(s) {
2142: op=psfx(op," ");
2143: op=psfx(op,s);
2144: free(s);
2145: }
2146: op=psfx(op," {\n");
2147: instruct++; /* alternate symbol table for defns */
2148: while(look(skipbl())!='}') {
2149: if(q=declarat()) {
2150: op=qcat(op,prfx(" ",q));
2151: }
2152: else if(look()==';') gc();
2153: else abt("bad statement inside struct");
2154: }
2155: instruct--; /* out of struct */
2156: op=psfx(op,"} \377");
2157: gc();
2158: }
2159: else if(s) {
2160: op=psfx(op," ");
2161: op=psfx(op,s);
2162: op=psfx(op," ");
2163: free(s);
2164: }
2165: op=declist(op);
2166: return(op);
2167: }
2168:
2169: file() /* do a program file */
2170: {
2171: Q *op;
2172: int c;
2173: op=getqs("extern long _funmin(),_funplus(),_finc1(),_finc2(),\n");
2174: outq(op); free(op);
2175: op=getqs("_fdec1(),_fdec2(),_ninc1(),_ninc2(),_ndec1(),_ndec2(),\n");
2176: outq(op); free(op);
2177: op=getqs("_fmul(),_fdiv(),_fmod(),_fadd(),_fsub(),\n");
2178: outq(op); free(op);
2179: op=getqs("_ffrl(),_ffrn(),_ftol(),_ntol(),_fton(),\n");
2180: outq(op); free(op);
2181: op=getqs("_lton(),_iton(),_ffri(),_uton(),_ffru();\n");
2182: outq(op); free(op);
2183: op=getqs("extern int _ftoi(),_ntoi(),_fgt(),_fge(),_fle(),_flt();\n");
2184: outq(op); free(op);
2185: if(unsign==1) {
2186: op=getqs("extern unsigned _ftou(),_ntou();\n");
2187: outq(op); free(op);
2188: }
2189: op=getqs("extern long _feqpl(),_neqpl(),_feqmi(),_neqmi(),\n");
2190: outq(op); free(op);
2191: op=getqs("_feqmu(),_neqmu(),_feqdv(),_neqdv(),_feqan(),_neqan(),\n");
2192: outq(op); free(op);
2193: op=getqs("_feqer(),_neqer(),_feqmo(),_neqmo(),_feqor(),_neqor(),\n");
2194: outq(op); free(op);
2195: op=getqs("_feqsr(),_neqsr(),_feqsl(),_neqsl();\n");
2196: outq(op); free(op);
2197: while(look(skipbl())) {
2198: while(1){
2199: if(look(skipbl())==0) return;
2200: if((op=declspec())==0) {
2201: op=getq(0);
2202: op->type=I;
2203: op->size=0;
2204: }
2205: if(op->type&FFSTRUCT) op=declstru(op);
2206: else op=declist(op);
2207: if((c=gc(skipbl()))!=';')break;
2208: op=psfx(op,";\n");
2209: outq(op);
2210: free(op);
2211: }
2212: frettype=(lasttype-MAXTYPE)%DFMOD;
2213: if(frettype<0)warn("illegal function type");
2214: op=psfx(op,"\n");
2215: outq(op);
2216: free(op);
2217: ug(c);
2218: definelv(++level);
2219: while(op=declarat()) {
2220: outq(op);
2221: free(op);
2222: }
2223: /* now define all the prototype args as "int". symbol table takes first
2224: definition, so declaration preceeding will override. */
2225: while(argchain) {
2226: definesy(argchain->acstring,I);
2227: free(argchain->acstring);
2228: argchain=argchain->acnext;
2229: }
2230: if(look(skipbl())=='{') statement();
2231: else abt("expect '{' after function prototype");
2232: definelv(--level);
2233: }
2234: }
2235:
2236: /*
2237: * mjm: own alloc() which calls malloc()
2238: */
2239: static alloc(sz)
2240: int sz;
2241: { /* mjm: made malloc arg always even */
2242: if((sz=malloc((sz+1)&~01)) != 0)
2243: return(sz);
2244: else return(OUT);
2245: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.