|
|
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.