Annotation of researchv10no/cmd/PDP11/fpp/rhccomp.c, revision 1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.