Annotation of researchv10no/cmd/ccom/common/cgram.y, revision 1.1.1.1

1.1       root        1: /* @(#) cgram.y: 1.2 2/9/84                            */
                      2: %{
                      3: static char    SCCSID[] = "@(#) cgram.y:       2.1 83/08/02";
                      4: %}
                      5: %term NAME  2
                      6: %term STRING  3
                      7: %term ICON  4
                      8: %term FCON  5
                      9: %term PLUS   6
                     10: %term MINUS   8
                     11: %term MUL   11
                     12: %term AND   14
                     13: %term OR   17
                     14: %term ER   19
                     15: %term QUEST  21
                     16: %term COLON  22
                     17: %term ANDAND  23
                     18: %term OROR  24
                     19: 
                     20: /*     special interfaces for yacc alone */
                     21: /*     These serve as abbreviations of 2 or more ops:
                     22:        ASOP    =, = ops
                     23:        RELOP   LE,LT,GE,GT
                     24:        EQUOP   EQ,NE
                     25:        DIVOP   DIV,MOD
                     26:        SHIFTOP LS,RS
                     27:        ICOP    ICR,DECR
                     28:        UNOP    NOT,COMPL
                     29:        STROP   DOT,STREF
                     30: 
                     31:        */
                     32: %term ASOP  25
                     33: %term RELOP  26
                     34: %term EQUOP  27
                     35: %term DIVOP  28
                     36: %term SHIFTOP  29
                     37: %term INCOP  30
                     38: %term UNOP  31
                     39: %term STROP  32
                     40: 
                     41: /*     reserved words, etc */
                     42: %term TYPE  33
                     43: %term CLASS  34
                     44: %term STRUCT  35
                     45: %term RETURN  36
                     46: %term GOTO  37
                     47: %term IF  38
                     48: %term ELSE  39
                     49: %term SWITCH  40
                     50: %term BREAK  41
                     51: %term CONTINUE  42
                     52: %term WHILE  43
                     53: %term DO  44
                     54: %term FOR  45
                     55: %term DEFAULT  46
                     56: %term CASE  47
                     57: %term SIZEOF  48
                     58: %term ENUM 49
                     59: 
                     60: /*     little symbols, etc. */
                     61: /*     namely,
                     62: 
                     63:        LP      (
                     64:        RP      )
                     65: 
                     66:        LC      {
                     67:        RC      }
                     68: 
                     69:        LB      [
                     70:        RB      ]
                     71: 
                     72:        CM      ,
                     73:        SM      ;
                     74: 
                     75:        */
                     76: 
                     77: %term LP  50
                     78: %term RP  51
                     79: %term LC  52
                     80: %term RC  53
                     81: %term LB  54
                     82: %term RB  55
                     83: %term CM  56
                     84: %term SM  57
                     85: %term ASSIGN  58
                     86: %term ASM 59
                     87: 
                     88: /* at last count, there were 7 shift/reduce, 1 reduce/reduce conflicts
                     89: /* these involved:
                     90:        if/else
                     91:        recognizing functions in various contexts, including declarations
                     92:        error recovery
                     93:        */
                     94: 
                     95: %left CM
                     96: %right ASOP ASSIGN
                     97: %right QUEST COLON
                     98: %left OROR
                     99: %left ANDAND
                    100: %left OR
                    101: %left ER
                    102: %left AND
                    103: %left EQUOP
                    104: %left RELOP
                    105: %left SHIFTOP
                    106: %left PLUS MINUS
                    107: %left MUL DIVOP
                    108: %right UNOP
                    109: %right INCOP SIZEOF
                    110: %left LB LP STROP
                    111: %{
                    112: # include "mfile1.h"
                    113: %}
                    114: 
                    115:        /* define types */
                    116: %start ext_def_list
                    117: 
                    118: %type <intval> con_e ifelprefix ifprefix doprefix switchpart
                    119:                enum_head str_head name_lp
                    120: %type <nodep> e .e term attributes oattributes type enum_dcl struct_dcl
                    121:                cast_type null_decl funct_idn declarator fdeclarator
                    122:                nfdeclarator elist
                    123: 
                    124: %token <intval> CLASS NAME STRUCT RELOP CM DIVOP PLUS MINUS SHIFTOP MUL AND OR
                    125:                ER ANDAND OROR ASSIGN STROP INCOP UNOP ICON
                    126: %token <nodep> TYPE
                    127: 
                    128: %%
                    129: 
                    130: %{
                    131:        extern int wloop_level; /* specifies while loop code generation */
                    132:        extern int floop_level; /* specifies for loop code generation */
                    133:        static int fake = 0;
                    134:        static char fakename[NCHNAM+1];
                    135: %}
                    136: 
                    137: ext_def_list:     ext_def_list external_def
                    138:                |       /* EMPTY */
                    139:                        {
                    140: #ifndef LINT
                    141:                        beg_file();
                    142: #endif
                    143:                         ftnend();
                    144:                         }
                    145:                ;
                    146: external_def:     data_def
                    147:                        { curclass = SNULL;  blevel = 0; }
                    148:                |  error
                    149:                        { curclass = SNULL;  blevel = 0; }
                    150:                |  ASM SM
                    151:                        { asmout();  curclass = SNULL; blevel = 0; }
                    152:                ;
                    153: data_def:         oattributes  SM
                    154:                        {  $1->in.op = FREE; }
                    155:                |  oattributes init_dcl_list  SM
                    156:                        {  $1->in.op = FREE; }
                    157:                |  oattributes fdeclarator
                    158:                        {   defid( tymerge($1,$2),
                    159:                                        curclass==STATIC?STATIC:EXTDEF ); }
                    160:                        function_body
                    161:                        {  
                    162:                            if( blevel ) cerror( "function level error" );
                    163:                            if( reached ) retstat |= NRETVAL; 
                    164:                            $1->in.op = FREE;
                    165:                            ftnend();
                    166:                            }
                    167:                ;
                    168: 
                    169: function_body:    arg_dcl_list compoundstmt
                    170:                {       regvar = 0; }  /* clear out arguments */
                    171:                ;
                    172: 
                    173: arg_dcl_list:     arg_dcl_list attributes declarator_list SM
                    174:                        { curclass = SNULL;  $2->in.op = FREE; }
                    175:                |  arg_dcl_list attributes SM
                    176:                        /* to permit structs in decl. lists */
                    177:                        { curclass = SNULL;  $2->in.op = FREE; }
                    178:                |       /* EMPTY */  {  blevel = 1; }
                    179:                ;
                    180: 
                    181: stmt_list:        stmt_list statement
                    182:                |  /* EMPTY */
                    183:                        {  bccode();
                    184:                            locctr(PROG);
                    185:                            }
                    186:                ;
                    187: 
                    188: dcl_stat_list  :  dcl_stat_list attributes SM
                    189:                        {  $2->in.op = FREE; }
                    190:                |  dcl_stat_list attributes init_dcl_list SM
                    191:                        {  $2->in.op = FREE; }
                    192:                |  /* EMPTY */
                    193:                ;
                    194: 
                    195: oattributes:     attributes
                    196:                |  /* empty */
                    197:                        {  $$ = mkty(INT,0,INT);  curclass = SNULL; }
                    198:                ;
                    199: attributes:       class type
                    200:                        {  $$ = $2; }
                    201:                |  type class
                    202:                |  class
                    203:                        {  $$ = mkty(INT,0,INT); }
                    204:                |  type
                    205:                        { curclass = SNULL ; }
                    206:                |  type class type
                    207:                        {  $1->in.type = types( $1->in.type, $3->in.type,
                    208:                                        UNDEF );
                    209:                            $3->in.op = FREE;
                    210:                            }
                    211:                ;
                    212: 
                    213: class:           CLASS
                    214:                        {  curclass = $1; }
                    215:                ;
                    216: 
                    217: type:             TYPE
                    218:                |  TYPE TYPE
                    219:                        {  $1->in.type = types( $1->in.type, $2->in.type, UNDEF );
                    220:                            $2->in.op = FREE;
                    221:                            }
                    222:                |  TYPE TYPE TYPE
                    223:                        {  $1->in.type = types( $1->in.type, $2->in.type, $3->in.type );
                    224:                            $2->in.op = $3->in.op = FREE;
                    225:                            }
                    226:                |  struct_dcl
                    227:                |  enum_dcl
                    228:                ;
                    229: 
                    230: enum_dcl:         enum_head LC moe_list optcomma RC
                    231:                        { $$ = dclstruct($1); }
                    232:                |  ENUM NAME
                    233:                        {  $$ = rstruct($2,0);  stwart = instruct; }
                    234:                ;
                    235: 
                    236: enum_head:        ENUM
                    237:                        {  $$ = bstruct(-1,0); stwart = SEENAME; }
                    238:                |  ENUM NAME
                    239:                        {  $$ = bstruct($2,0); stwart = SEENAME; }
                    240:                ;
                    241: 
                    242: moe_list:         moe
                    243:                |  moe_list CM moe
                    244:                ;
                    245: 
                    246: moe:              NAME
                    247:                        {  moedef( $1 ); }
                    248:                |  NAME ASSIGN con_e
                    249:                        {  strucoff = $3;  moedef( $1 ); }
                    250:                ;
                    251: 
                    252: struct_dcl:       str_head LC type_dcl_list optsemi RC
                    253:                        { $$ = dclstruct($1);  }
                    254:                |  STRUCT NAME
                    255:                        {  $$ = rstruct($2,$1); }
                    256:                ;
                    257: 
                    258: str_head:         STRUCT
                    259:                        {  $$ = bstruct(-1,$1);  stwart=0; }
                    260:                |  STRUCT NAME
                    261:                        {  $$ = bstruct($2,$1);  stwart=0;  }
                    262:                ;
                    263: 
                    264: type_dcl_list:    type_declaration
                    265:                |  type_dcl_list SM type_declaration
                    266:                ;
                    267: 
                    268: type_declaration:  type declarator_list
                    269:                        { curclass = SNULL;  stwart=0; $1->in.op = FREE; }
                    270:                |  type
                    271:                        {  if( curclass != MOU ){
                    272:                                curclass = SNULL;
                    273:                                }
                    274:                            else {
                    275:                                sprintf( fakename, "$%dFAKE", fake++ );
                    276:                                defid( tymerge($1, bdty(NAME,NIL,
                    277:                                        lookup( fakename, SMOS ))), curclass );
                    278:                                werror("union member must be named");
                    279:                                }
                    280:                            stwart = 0;
                    281:                            $1->in.op = FREE;
                    282:                            }
                    283:                ;
                    284: 
                    285: 
                    286: declarator_list:   declarator
                    287:                        { defid( tymerge($<nodep>0,$1), curclass);
                    288:                                stwart = instruct; }
                    289:                |  declarator_list  CM {$<nodep>$=$<nodep>0;}  declarator
                    290:                        { defid( tymerge($<nodep>0,$4), curclass);
                    291:                                stwart = instruct; }
                    292:                ;
                    293: declarator:       nfdeclarator
                    294:                |  nfdeclarator COLON con_e
                    295:                        %prec CM
                    296:                        {  if( !(instruct&INSTRUCT) )
                    297:                                uerror( "field outside of structure" );
                    298:                            if( $3<0 || $3 >= FIELD ){
                    299:                                uerror( "illegal field size" );
                    300:                                $3 = 1;
                    301:                                }
                    302:                            defid( tymerge($<nodep>0,$1), FIELD|$3 );
                    303:                            $$ = NIL;
                    304:                            }
                    305:                |  COLON con_e
                    306:                        %prec CM
                    307:                        {   if( !(instruct&INSTRUCT) )
                    308:                                uerror( "field outside of structure" );
                    309:                            /* alignment or hole */
                    310:                            falloc( stab, $2, -1, $<nodep>0 );
                    311:                            $$ = NIL;
                    312:                            }
                    313:                |  error
                    314:                        {  $$ = NIL; }
                    315:                ;
                    316: 
                    317:                /* int (a)();   is not a function --- sorry! */
                    318: nfdeclarator:     MUL nfdeclarator             
                    319:                        {  umul:
                    320:                                $$ = bdty( UNARY MUL, $2, 0 ); }
                    321:                |  nfdeclarator  LP   RP                
                    322:                        {  uftn:
                    323:                                $$ = bdty( UNARY CALL, $1, 0 );  }
                    324:                |  nfdeclarator LB RB           
                    325:                        {  uary:
                    326:                                $$ = bdty( LB, $1, 0 );  }
                    327:                |  nfdeclarator LB con_e RB     
                    328:                        {  bary:
                    329:                                if( (int)$3 <= 0 )
                    330:                                        werror( "zero or negative subscript" );
                    331:                                $$ = bdty( LB, $1, $3 );  }
                    332:                |  NAME                 
                    333:                        {  $$ = bdty( NAME, NIL, $1 );  }
                    334:                |   LP  nfdeclarator  RP                
                    335:                        { $$=$2; }
                    336:                ;
                    337: fdeclarator:      MUL fdeclarator
                    338:                        {  goto umul; }
                    339:                |  fdeclarator  LP   RP
                    340:                        {  goto uftn; }
                    341:                |  fdeclarator LB RB
                    342:                        {  goto uary; }
                    343:                |  fdeclarator LB con_e RB
                    344:                        {  goto bary; }
                    345:                |   LP  fdeclarator  RP
                    346:                        { $$ = $2; }
                    347:                |  name_lp
                    348:                        { if (paramno)
                    349:                                uerror("arg list in declaration"); }
                    350:                        name_list  RP
                    351:                        {
                    352:                                if( blevel!=0 )
                    353:                                        uerror(
                    354:                                        "function declaration in bad context");
                    355:                                $$ = bdty( UNARY CALL, bdty(NAME,NIL,$1), 0 );
                    356:                                stwart = 0;
                    357:                                }
                    358:                |  name_lp
                    359:                        { if (paramno)
                    360:                                uerror("arg list in declaration"); }
                    361:                        RP
                    362:                        {
                    363:                                $$ = bdty( UNARY CALL, bdty(NAME,NIL,$1), 0 );
                    364:                                stwart = 0;
                    365:                                }
                    366:                ;
                    367: 
                    368: name_lp:         NAME LP
                    369:                        {
                    370:                                /* turn off typedefs for argument names */
                    371:                                stwart = SEENAME;
                    372:                                if( stab[$1].sclass == SNULL )
                    373:                                    stab[$1].stype = FTN;
                    374:                                }
                    375:                ;
                    376: 
                    377: name_list:        NAME                 
                    378:                        { ftnarg( $1 );  stwart = SEENAME; }
                    379:                |  name_list  CM  NAME 
                    380:                        { ftnarg( $3 );  stwart = SEENAME; }
                    381:                | error
                    382:                ;
                    383:                /* always preceeded by attributes: thus the $<nodep>0's */
                    384: init_dcl_list:    init_declarator
                    385:                        %prec CM
                    386:                |  init_dcl_list  CM {$<nodep>$=$<nodep>0;}  init_declarator
                    387:                ;
                    388:                /* always preceeded by attributes */
                    389: xnfdeclarator:    nfdeclarator
                    390:                        {  defid( $1 = tymerge($<nodep>0,$1), curclass);
                    391:                            beginit($1->tn.rval);
                    392:                            }
                    393:                |  error
                    394:                ;
                    395:                /* always preceeded by attributes */
                    396: init_declarator:   nfdeclarator
                    397:                        {  nidcl( tymerge($<nodep>0,$1) ); }
                    398:                |  fdeclarator
                    399:                        {  defid( tymerge($<nodep>0,$1), uclass(curclass) );
                    400:                        }
                    401:                |  xnfdeclarator ASSIGN e
                    402:                        %prec CM
                    403:                        {  doinit( $3 );
                    404:                            endinit(); }
                    405:                |  xnfdeclarator ASSIGN LC init_list optcomma RC
                    406:                        {  endinit(); }
                    407:                | error
                    408:                ;
                    409: 
                    410: init_list:        initializer
                    411:                        %prec CM
                    412:                |  init_list  CM  initializer
                    413:                ;
                    414: initializer:      e
                    415:                        %prec CM
                    416:                        {  doinit( $1 ); }
                    417:                |  ibrace init_list optcomma RC
                    418:                        {  irbrace(); }
                    419:                ;
                    420: 
                    421: optcomma       :       /* empty */
                    422:                |  CM
                    423:                ;
                    424: 
                    425: optsemi                :       /* empty */
                    426:                |  SM
                    427:                ;
                    428: 
                    429: ibrace         : LC
                    430:                        {  ilbrace(); }
                    431:                ;
                    432: 
                    433: /*     STATEMENTS      */
                    434: 
                    435: compoundstmt:     begin dcl_stat_list stmt_list RC
                    436:                        {
                    437:                            clearst(blevel);
                    438:                            if (--blevel == 1)
                    439:                            {
                    440:                                clearst(blevel);
                    441:                                blevel = 0;
                    442:                            }
                    443:                            checkst(blevel);
                    444:                            autooff = *--psavbc;
                    445:                            regvar = *--psavbc;
                    446:                        }
                    447:                ;
                    448: 
                    449: begin:           LC
                    450:                        {  if( blevel == 1 ) dclargs();
                    451:                            uplevel();
                    452:                            if( psavbc > &asavbc[BCSZ-2] )
                    453:                                        cerror( "nesting too deep" );
                    454:                            *psavbc++ = regvar;
                    455:                            *psavbc++ = autooff;
                    456:                            }
                    457:                ;
                    458: 
                    459: statement:        e SM
                    460:                        { ecomp($1); }
                    461:                |  ASM SM
                    462:                        { asmout(); }
                    463:                |  compoundstmt
                    464:                |  ifprefix statement
                    465:                        { deflab($1);
                    466:                           reached = 1;
                    467: #ifdef M32B
                    468:                           brdepth--;
                    469: #endif
                    470:                           }
                    471:                |  ifelprefix statement
                    472:                        {  if( $1 != NOLAB ){
                    473:                                deflab( $1 );
                    474:                                reached = 1;
                    475:                                }
                    476: #ifdef M32B
                    477:                            brdepth--;
                    478: #endif
                    479:                            }
                    480:                |  WHILE
                    481:                        {
                    482: #ifdef M32B
                    483:                                whdepth++;
                    484: #endif
                    485:                        }
                    486:                        LP e RP
                    487:                        {
                    488:                                savebc();
                    489:                                if (!reached)
                    490:                                        werror("loop not entered at top");
                    491:                                reached = 1;
                    492:                                brklab = getlab();
                    493:                                contlab = getlab();
                    494:                                switch (wloop_level) {
                    495:                                default:
                    496:                                        cerror("bad while loop code gen value");
                    497:                                        /*NOTREACHED*/
                    498:                                case LL_TOP:    /* test at loop top */
                    499:                                        deflab(contlab);
                    500:                                        if ($4->in.op == ICON && $4->tn.lval) {
                    501:                                                flostat = FLOOP;
                    502:                                                tfree($4);
                    503:                                        } else {
                    504:                                                $4->ln.lineno = $<lineno>1;
                    505:                                                ecomp(buildtree(CBRANCH, $4,
                    506:                                                    bcon(brklab)));
                    507:                                        }
                    508:                                        break;
                    509:                                case LL_BOT:    /* test at loop bottom */
                    510:                                        if ($4->in.op == ICON && $4->tn.lval) {
                    511:                                                flostat = FLOOP;
                    512:                                                tfree($4);
                    513:                                                deflab(contlab);
                    514:                                        } else {
                    515:                                                branch(contlab);
                    516:                                                deflab($<intval>$ = getlab());
                    517:                                        }
                    518:                                        break;
                    519:                                case LL_DUP:    /* dup. test at top & bottom */
                    520:                                        if ($4->in.op == ICON && $4->tn.lval) {
                    521:                                                flostat = FLOOP;
                    522:                                                tfree($4);
                    523:                                                deflab($<intval>$ = contlab);
                    524:                                        } else {
                    525:                                                register NODE *sav;
                    526:                                                extern NODE *treecpy();
                    527:                                                sav = treecpy($4);
                    528:                                                ecomp(buildtree(CBRANCH,$4,
                    529:                                                    bcon(brklab)));
                    530:                                                $4 = sav;
                    531:                                                deflab($<intval>$ = getlab());
                    532:                                        }
                    533:                                        break;
                    534:                                }
                    535:                        }
                    536:                        statement
                    537:                {
                    538:                        switch (wloop_level) {
                    539:                        default:
                    540:                                cerror("bad while loop code gen. value");
                    541:                                /*NOTREACHED*/
                    542:                        case LL_TOP:    /* test at loop top */
                    543:                                branch(contlab);
                    544:                                break;
                    545:                        case LL_BOT:    /* test at loop bottom */
                    546:                                if (flostat & FLOOP)
                    547:                                        branch(contlab);
                    548:                                else {
                    549:                                        reached = 1;
                    550:                                        deflab(contlab);
                    551:                                        ecomp(buildtree(CBRANCH,
                    552:                                                buildtree(NOT, $4, NIL),
                    553:                                                bcon($<intval>6)));
                    554:                                }
                    555:                                break;
                    556:                        case LL_DUP:    /* dup. test at top & bottom */
                    557:                                if (flostat & FLOOP)
                    558:                                        branch(contlab);
                    559:                                else {
                    560:                                        if (flostat & FCONT) {
                    561:                                                reached = 1;
                    562:                                                deflab(contlab);
                    563:                                        }
                    564:                                        ecomp(buildtree(CBRANCH,
                    565:                                                buildtree(NOT, $4, NIL),
                    566:                                                bcon($<intval>6)));
                    567:                                }
                    568:                                break;
                    569:                        }
                    570:                        if ((flostat & FBRK) || !(flostat & FLOOP))
                    571:                                reached = 1;
                    572:                        else
                    573:                                reached = 0;
                    574:                        deflab(brklab);
                    575:                        resetbc(0);
                    576: #ifdef M32B
                    577:                        whdepth--;
                    578: #endif
                    579:                }
                    580:                |  doprefix statement WHILE  LP  e  RP   SM
                    581:                        {   deflab( contlab );
                    582:                            if( flostat & FCONT ) reached = 1;
                    583:                            $5->ln.lineno = $<lineno>3;
                    584:                            ecomp( buildtree(CBRANCH,
                    585:                                buildtree(NOT, $5, NIL), bcon($1)));
                    586:                            deflab( brklab );
                    587:                            reached = 1;
                    588:                            resetbc(0);
                    589: #ifdef M32B
                    590:                            whdepth--;
                    591: #endif
                    592:                            }
                    593:                |  FOR LP .e SM
                    594:                        {
                    595: #ifdef M32B
                    596:                                fordepth++;
                    597: #endif
                    598:                        }
                    599:                        .e SM
                    600:                        {
                    601:                                if ($3) {
                    602:                                        $3->ln.lineno = $<lineno>1;
                    603:                                        ecomp($3);
                    604:                                } else if (!reached)
                    605:                                        werror("loop not entered at top");
                    606:                                savebc();
                    607:                                contlab = getlab();
                    608:                                brklab = getlab();
                    609:                                reached = 1;
                    610:                                switch (floop_level) {
                    611:                                default:
                    612:                                        cerror("bad for loop code gen. value");
                    613:                                        /*NOTREACHED*/
                    614:                                case LL_TOP:    /* test at loop top */
                    615:                                        deflab($<intval>$ = getlab());
                    616:                                        if (!$6)
                    617:                                                flostat |= FLOOP;
                    618:                                        else if ($6->in.op == ICON && $6->tn.lval) {
                    619:                                                flostat |= FLOOP;
                    620:                                                tfree($6);
                    621:                                                $6 = (NODE *)0;
                    622:                                        } else {
                    623:                                                if (!$3)
                    624:                                                        $6->ln.lineno = $<lineno>1;
                    625:                                                ecomp(buildtree(CBRANCH, $6,
                    626:                                                    bcon(brklab)));
                    627:                                        }
                    628:                                        break;
                    629:                                case LL_BOT:    /* test at loop bottom */
                    630:                                        if (!$6)
                    631:                                                flostat |= FLOOP;
                    632:                                        else if ($6->in.op == ICON && $6->tn.lval) {
                    633:                                                flostat |= FLOOP;
                    634:                                                tfree($6);
                    635:                                                $6 = (NODE *)0;
                    636:                                        } else
                    637:                                                branch($<intval>1 = getlab());
                    638:                                        deflab($<intval>$ = getlab());
                    639:                                        break;
                    640:                                case LL_DUP:    /* dup. test at top & bottom */
                    641:                                        if (!$6)
                    642:                                                flostat |= FLOOP;
                    643:                                        else if ($6->in.op == ICON && $6->tn.lval) {
                    644:                                                flostat |= FLOOP;
                    645:                                                tfree($6);
                    646:                                                $6 = (NODE *)0;
                    647:                                        } else {
                    648:                                                register NODE *sav;
                    649:                                                extern NODE *treecpy();
                    650:                                                sav = treecpy($6);
                    651:                                                ecomp(buildtree(CBRANCH, $6,
                    652:                                                        bcon(brklab)));
                    653:                                                $6 = sav;
                    654:                                        }
                    655:                                        deflab($<intval>$ = getlab());
                    656:                                        break;
                    657:                                }
                    658:                        }
                    659:                        .e RP statement
                    660:                {
                    661:                        if (flostat & FCONT) {
                    662:                                deflab(contlab);
                    663:                                reached = 1;
                    664:                        }
                    665:                        if ($9)
                    666:                                $9->ln.lineno = lineno, ecomp($9);
                    667:                        switch (floop_level) {
                    668:                        default:
                    669:                                cerror("bad for loop code gen. value");
                    670:                                /*NOTREACHED*/
                    671:                        case LL_TOP:    /* test at loop top */
                    672:                                branch($<intval>8);
                    673:                                break;
                    674:                        case LL_BOT:    /* test at loop bottom */
                    675:                                if ($6)
                    676:                                        deflab($<intval>1);
                    677:                                /*FALLTHROUGH*/
                    678:                        case LL_DUP:    /* dup. test at top & bottom */
                    679:                                if ($6) {
                    680:                                        ecomp(buildtree(CBRANCH,
                    681:                                                buildtree(NOT, $6, NIL),
                    682:                                                bcon($<intval>8)));
                    683:                                } else
                    684:                                        branch($<intval>8);
                    685:                                break;
                    686:                        }
                    687:                        deflab(brklab);
                    688:                        if ((flostat & FBRK) || !(flostat & FLOOP))
                    689:                                reached = 1;
                    690:                        else
                    691:                                reached = 0;
                    692:                        resetbc(0);
                    693: #ifdef M32B
                    694:                        fordepth--;
                    695: #endif
                    696:                }
                    697:                | switchpart statement
                    698:                        {   if( reached ) branch( brklab );
                    699:                            deflab( $1 );
                    700:                            swend();
                    701:                            deflab(brklab);
                    702:                            if( (flostat&FBRK) || !(flostat&FDEF) ) reached=1;
                    703:                            resetbc(FCONT);
                    704: #ifdef M32B
                    705:                            brdepth--;
                    706: #endif
                    707:                            }
                    708:                |  BREAK  SM
                    709:                        {  if( brklab == NOLAB ) uerror( "illegal break");
                    710:                            else if(reached) {
                    711:                                slineno = $<lineno>1; dbline();
                    712:                                branch( brklab );
                    713:                            }
                    714:                            flostat |= FBRK;
                    715:                            if( brkflag ) goto rch;
                    716:                            reached = 0;
                    717:                            }
                    718:                |  CONTINUE  SM
                    719:                        {   if( contlab == NOLAB ) uerror( "illegal continue");
                    720:                            else {
                    721:                                slineno = $<lineno>1; dbline();
                    722:                                branch( contlab );
                    723:                            }
                    724:                            flostat |= FCONT;
                    725:                            goto rch;
                    726:                            }
                    727:                |  RETURN  SM
                    728:                        {   retstat |= NRETVAL;
                    729:                            slineno = $<lineno>1; dbline();
                    730:                            branch( retlab );
                    731:                        rch:
                    732:                            if( !reached ) werror( "statement not reached");
                    733:                            reached = 0;
                    734:                            }
                    735:                |  RETURN e  SM
                    736:                        {   register NODE *temp;
                    737:                            TWORD indtype();
                    738:                            idname = curftn;
                    739:                            temp = buildtree( NAME, NIL, NIL );
                    740:                            temp->in.type = DECREF(temp->in.type);
                    741:                            if(temp->in.type == (FTN|VOID))
                    742:                                uerror(
                    743:                                "void function %s cannot return value",
                    744:                                        stab[idname].sname);
                    745:                            temp->tn.op = RNODE;
                    746:                            $2 = makety( $2, temp->fn.type,
                    747:                                        temp->fn.cdim, temp->fn.csiz );
                    748:                            temp->in.type = indtype( temp->in.type );
                    749:                            temp = buildtree( ASSIGN, temp, $2 );
                    750:                            temp->ln.lineno = $<lineno>1;
                    751:                            ecomp( temp );
                    752:                            retstat |= RETVAL;
                    753:                            branch( retlab );
                    754:                            reached = 0;
                    755:                            }
                    756:                |  GOTO NAME SM
                    757:                        {  register NODE *q;
                    758:                            q = block( FREE, NIL, NIL, INT|ARY, 0, INT );
                    759:                            q->tn.rval = idname = $2;
                    760:                            defid( q, ULABEL );
                    761:                            stab[idname].suse = -lineno;
                    762:                            slineno = $<lineno>1; dbline();
                    763:                            branch( stab[idname].offset );
                    764:                            goto rch;
                    765:                            }
                    766:                |   SM
                    767:                |  error  SM
                    768:                |  error RC
                    769:                |  label statement
                    770:                ;
                    771: label:            NAME COLON
                    772:                        {  register NODE *q;
                    773:                            q = block( FREE, NIL, NIL, INT|ARY, 0, LABEL );
                    774:                            q->tn.rval = $1;
                    775:                            defid( q, LABEL );
                    776:                            reached = 1;
                    777:                            }
                    778:                |  CASE e COLON
                    779:                        {  addcase($2);
                    780:                            reached = 1;
                    781:                            }
                    782:                |  DEFAULT COLON
                    783:                        {  reached = 1;
                    784:                            adddef();
                    785:                            flostat |= FDEF;
                    786:                            }
                    787:                ;
                    788: doprefix:      DO
                    789:                        {  savebc();
                    790:                            if( !reached ) werror( "loop not entered at top");
                    791:                            brklab = getlab();
                    792:                            contlab = getlab();
                    793:                            deflab( $$ = getlab() );
                    794:                            reached = 1;
                    795: #ifdef M32B
                    796:                            whdepth++;
                    797: #endif
                    798:                            }
                    799:                ;
                    800: ifprefix:      IF LP e RP
                    801:                        {   $3->ln.lineno = $<lineno>1;
                    802:                            ecomp(buildtree(CBRANCH, $3, bcon($$=getlab()))) ;
                    803:                            reached = 1;
                    804: #ifdef M32B
                    805:                            brdepth++;
                    806: #endif
                    807:                            }
                    808:                ;
                    809: ifelprefix:      ifprefix statement ELSE
                    810:                        {  if( reached ) branch( $$ = getlab() );
                    811:                            else $$ = NOLAB;
                    812:                            deflab( $1 );
                    813:                            reached = 1;
                    814:                            }
                    815:                ;
                    816: 
                    817: switchpart:       SWITCH  LP  e  RP
                    818:                        {   register NODE *temp;
                    819:                            savebc();
                    820:                            temp = block( SNODE, NIL, NIL, INT, 0, INT );
                    821:                            temp = buildtree( ASSIGN, temp, $3 );
                    822: #ifdef M32B
                    823:                            temp = setswreg( temp );
                    824: #endif
                    825:                            brklab = getlab();
                    826:                            temp->ln.lineno = $<lineno>1;
                    827:                            ecomp( temp );
                    828:                            branch( $$ = getlab() );
                    829:                            swstart();
                    830:                            reached = 0;
                    831: #ifdef M32B
                    832:                            brdepth++;
                    833: #endif
                    834:                            }
                    835:                ;
                    836: /*     EXPRESSIONS     */
                    837: con_e:            { $<intval>$=instruct; stwart=instruct=0; } e
                    838:                        %prec CM
                    839:                        {  $$ = icons( $2 ); instruct=$<intval>1; }
                    840:                ;
                    841: .e:               e
                    842:                |
                    843:                        { $$ = 0; }
                    844:                ;
                    845: elist:            e
                    846:                        %prec CM
                    847:                |  elist  CM  e
                    848:                        {  goto bop; }
                    849:                ;
                    850: 
                    851: e:                e RELOP e
                    852:                        {
                    853:                        preconf:
                    854:                            if( yychar==RELOP || yychar==EQUOP || yychar==AND
                    855:                                        || yychar==OR || yychar==ER ){
                    856:                        precplaint:
                    857:                                if( hflag ) werror(
                    858:                                "precedence confusion possible: parenthesize!"
                    859:                                        );
                    860:                                }
                    861:                        bop:
                    862:                            $$ = buildtree( $2, $1, $3 );
                    863:                            }
                    864:                |  e CM e
                    865:                        {  $2 = COMOP;
                    866:                            goto bop;
                    867:                            }
                    868:                |  e DIVOP e
                    869:                        {  goto bop; }
                    870:                |  e PLUS e
                    871:                        {  if(yychar==SHIFTOP) goto precplaint; else goto bop; }
                    872:                |  e MINUS e
                    873:                        {  if(yychar==SHIFTOP ) goto precplaint; else goto bop; }
                    874:                |  e SHIFTOP e
                    875:                        {  if(yychar==PLUS||yychar==MINUS) goto precplaint; else goto bop; }
                    876:                |  e MUL e
                    877:                        {  goto bop; }
                    878:                |  e EQUOP  e
                    879:                        {  goto preconf; }
                    880:                |  e AND e
                    881:                        {  if( yychar==RELOP||yychar==EQUOP ) goto preconf;  else goto bop; }
                    882:                |  e OR e
                    883:                        {  if(yychar==RELOP||yychar==EQUOP) goto preconf; else goto bop; }
                    884:                |  e ER e
                    885:                        {  if(yychar==RELOP||yychar==EQUOP) goto preconf; else goto bop; }
                    886:                |  e ANDAND e
                    887:                        {  goto bop; }
                    888:                |  e OROR e
                    889:                        {  goto bop; }
                    890:                |  e MUL ASSIGN e
                    891:                        {  abop:
                    892:                                $$ = buildtree( ASG $2, $1, $4 );
                    893:                                }
                    894:                |  e DIVOP ASSIGN e
                    895:                        {  goto abop; }
                    896:                |  e PLUS ASSIGN e
                    897:                        {  goto abop; }
                    898:                |  e MINUS ASSIGN e
                    899:                        {  goto abop; }
                    900:                |  e SHIFTOP ASSIGN e
                    901:                        {  goto abop; }
                    902:                |  e AND ASSIGN e
                    903:                        {  goto abop; }
                    904:                |  e OR ASSIGN e
                    905:                        {  goto abop; }
                    906:                |  e ER ASSIGN e
                    907:                        {  goto abop; }
                    908:                |  e QUEST e COLON e
                    909:                        {  $$=buildtree(QUEST, $1, buildtree( COLON, $3, $5 ) );
                    910:                            }
                    911:                |  e ASOP e
                    912:                        {  werror( "old-fashioned assignment operator" );
                    913:                                goto bop; }
                    914:                |  e ASSIGN e
                    915:                        {  goto bop; }
                    916:                |  term
                    917:                ;
                    918: 
                    919: term:             term INCOP
                    920:                        {  $$ = buildtree( $2, $1, bcon(1) ); }
                    921:                |  MUL term
                    922:                        { ubop:
                    923:                           $$ = buildtree( UNARY $1, $2, NIL );
                    924:                            }
                    925:                |  AND term
                    926:                        {
                    927: #ifdef M32B
                    928:                            myand($2);
                    929: #endif
                    930:                            if( ISFTN($2->in.type) || ISARY($2->in.type) ){
                    931:                                werror( "& before array or function: ignored" );
                    932:                                $$ = $2;
                    933:                                }
                    934:                            else goto ubop;
                    935:                            }
                    936:                |  MINUS term
                    937:                        {  goto ubop; }
                    938:                |  UNOP term
                    939:                        {
                    940:                           $$ = buildtree( $1, $2, NIL );
                    941:                            }
                    942:                |  INCOP term
                    943:                        {  $$ = buildtree( $1==INCR ? ASG PLUS : ASG MINUS,
                    944:                                                $2,
                    945:                                                bcon(1)  );
                    946:                            }
                    947:                |  SIZEOF term
                    948:                        {  $$ = doszof( $2 ); }
                    949:                |  LP cast_type RP term  %prec INCOP
                    950:                        {  $$ = buildtree( CAST, $2, $4 );
                    951:                           $$->in.left->in.op = FREE;
                    952:                           $$->in.op = FREE;
                    953:                           $$ = $$->in.right;
                    954:                            }
                    955:                |  SIZEOF LP cast_type RP  %prec SIZEOF
                    956:                        {  $$ = doszof( $3 ); }
                    957:                |  term LB e RB
                    958:                        {  $$ = buildtree( LB, $1, $3 ); }
                    959:                |  term LB e COLON e RB
                    960:                        {  $$ = xicolon( $1, $3, $5 ); }
                    961:                |  funct_idn  RP
                    962:                        {  $$=buildtree(UNARY CALL,$1,NIL);
                    963:                        }
                    964:                |  funct_idn elist  RP
                    965:                        {  $$=buildtree(CALL,$1,$2); }
                    966:                |  term STROP NAME
                    967:                        {  if( $2 == DOT ){
                    968:                                if( notlval( $1 ) )werror(
                    969:                                       "structure reference must be addressable"
                    970:                                        );
                    971:                                $1 = buildtree( UNARY AND, $1, NIL );
                    972:                                }
                    973:                            idname = $3;
                    974:                            $$ = buildtree( STREF, $1,
                    975:                                        buildtree( NAME, NIL, NIL ) );
                    976:                            }
                    977:                |  NAME
                    978:                        {  idname = $1;
                    979:                            /* recognize identifiers in initializations */
                    980:                            if( blevel==0 && stab[idname].stype == UNDEF ) {
                    981:                                register NODE *q;
                    982:                                werror( "undeclared initializer name %s",
                    983:                                        stab[idname].sname );
                    984:                                q = block( FREE, NIL, NIL, INT, 0, INT );
                    985:                                q->tn.rval = idname;
                    986:                                defid( q, EXTERN );
                    987:                                }
                    988:                            $$=buildtree(NAME,NIL,NIL);
                    989:                            stab[$1].suse = -lineno;
                    990:                        }
                    991:                |  ICON
                    992:                        {   $$=bcon(0);
                    993:                            $$->tn.lval = lastcon;
                    994:                            $$->tn.rval = NONAME;
                    995:                            if( $1 ) $$->fn.csiz = $$->in.type = ctype(LONG);
                    996:                            }
                    997:                |  FCON
                    998:                        {   $$=buildtree(FCON,NIL,NIL);
                    999:                            $$->fpn.dval = dcon;
                   1000:                            }
                   1001:                |  STRING
                   1002:                        {  $$ = getstr(); }
                   1003:                |   LP  e  RP
                   1004:                        {  $$=$2; }
                   1005:                ;
                   1006: 
                   1007: cast_type:       type null_decl
                   1008:                        {
                   1009:                        $$ = tymerge( $1, $2 );
                   1010:                        $$->in.op = NAME;
                   1011:                        $1->in.op = FREE;
                   1012:                        }
                   1013:                ;
                   1014: 
                   1015: null_decl:        /* EMPTY */
                   1016:                        { $$ = bdty( NAME, NIL, -1 ); }
                   1017:                |  LP RP
                   1018:                        { $$ = bdty( UNARY CALL, bdty(NAME,NIL,-1),0); }
                   1019:                |  LP null_decl RP LP RP
                   1020:                        {  $$ = bdty( UNARY CALL, $2, 0 ); }
                   1021:                |  MUL null_decl
                   1022:                        {  goto umul; }
                   1023:                |  null_decl LB RB
                   1024:                        {  goto uary; }
                   1025:                |  null_decl LB con_e RB
                   1026:                        {  goto bary;  }
                   1027:                |  LP null_decl RP
                   1028:                        { $$ = $2; }
                   1029:                ;
                   1030: 
                   1031: funct_idn:        NAME  LP 
                   1032:                        {  if( stab[$1].stype == UNDEF ){
                   1033:                                register NODE *q;
                   1034:                                q = block( FREE, NIL, NIL, FTN|INT, 0, INT );
                   1035:                                q->tn.rval = $1;
                   1036:                                defid( q, EXTERN );
                   1037:                                }
                   1038:                            idname = $1;
                   1039:                            $$=buildtree(NAME,NIL,NIL);
                   1040:                            stab[idname].suse = -lineno;
                   1041:                        }
                   1042:                |  term  LP 
                   1043:                ;
                   1044: %%
                   1045: 
                   1046: NODE *
                   1047: mkty( t, d, s ) unsigned t; {
                   1048:        return( block( TYPE, NIL, NIL, t, d, s ) );
                   1049:        }
                   1050: 
                   1051: NODE *
                   1052: bdty( op, p, v ) NODE *p; {
                   1053:        register NODE *q;
                   1054: 
                   1055:        q = block( op, p, NIL, INT, 0, INT );
                   1056: 
                   1057:        switch( op ){
                   1058: 
                   1059:        case UNARY MUL:
                   1060:        case UNARY CALL:
                   1061:                break;
                   1062: 
                   1063:        case LB:
                   1064:                q->in.right = bcon(v);
                   1065:                break;
                   1066: 
                   1067:        case NAME:
                   1068:                q->tn.rval = v;
                   1069:                break;
                   1070: 
                   1071:        default:
                   1072:                cerror( "bad bdty" );
                   1073:                }
                   1074: 
                   1075:        return( q );
                   1076:        }
                   1077: int dimtabsz;
                   1078: allodimtab()
                   1079: {
                   1080:        if(!dimtabsz)
                   1081:                dimtab = (int *) malloc((dimtabsz = DIMTABSZ)*sizeof(int));
                   1082:        else {
                   1083:                dimtabsz *= 3;
                   1084:                dimtab = (int *) realloc((char *)dimtab, dimtabsz*sizeof(int));
                   1085:        }
                   1086:        if(!dimtab)
                   1087:                cerror("dimension table overflow");
                   1088: }
                   1089: 
                   1090: dstash( n ){ /* put n into the dimension table */
                   1091:        if( curdim >= dimtabsz-1 ){
                   1092:                allodimtab();
                   1093:                }
                   1094:        dimtab[ curdim++ ] = n;
                   1095:        }
                   1096: 
                   1097: savebc() {
                   1098:        if( psavbc > & asavbc[BCSZ-4 ] ){
                   1099:                cerror( "whiles, fors, etc. too deeply nested");
                   1100:                }
                   1101:        *psavbc++ = brklab;
                   1102:        *psavbc++ = contlab;
                   1103:        *psavbc++ = flostat;
                   1104:        *psavbc++ = swx;
                   1105: #ifdef M32B
                   1106:        *psavbc++ = swregno;
                   1107: #endif
                   1108:        flostat = 0;
                   1109:        }
                   1110: 
                   1111: resetbc(mask){
                   1112: 
                   1113: #ifdef M32B
                   1114:        swregno = *--psavbc;
                   1115: #endif
                   1116:        swx = *--psavbc;
                   1117:        flostat = *--psavbc | (flostat&mask);
                   1118:        contlab = *--psavbc;
                   1119:        brklab = *--psavbc;
                   1120: 
                   1121:        }
                   1122: 
                   1123: addcase(p) NODE *p; { /* add case to switch */
                   1124: 
                   1125:        p = optim( p );  /* change enum to ints */
                   1126:        if( p->in.op != ICON || p->tn.rval != NONAME){
                   1127:                uerror( "non-constant case expression");
                   1128:                return;
                   1129:                }
                   1130:        if( swp == swtab ){
                   1131:                uerror( "case not in switch");
                   1132:                return;
                   1133:                }
                   1134:        if( swp >= &swtab[SWITSZ] ){
                   1135:                cerror( "switch table overflow");
                   1136:                }
                   1137:        swp->sval = p->tn.lval;
                   1138:        deflab( swp->slab = getlab() );
                   1139:        ++swp;
                   1140:        tfree(p);
                   1141:        }
                   1142: 
                   1143: adddef(){ /* add default case to switch */
                   1144:        if( swtab[swx].slab >= 0 ){
                   1145:                uerror( "duplicate default in switch");
                   1146:                return;
                   1147:                }
                   1148:        if( swp == swtab ){
                   1149:                uerror( "default not inside switch");
                   1150:                return;
                   1151:                }
                   1152:        deflab( swtab[swx].slab = getlab() );
                   1153:        }
                   1154: 
                   1155: swstart(){
                   1156:        /* begin a switch block */
                   1157:        if( swp >= &swtab[SWITSZ] ){
                   1158:                cerror( "switch table overflow");
                   1159:                }
                   1160:        swx = swp - swtab;
                   1161:        swp->slab = -1;
                   1162:        ++swp;
                   1163:        }
                   1164: 
                   1165: swend(){ /* end a switch block */
                   1166: 
                   1167:        register struct sw *swbeg, *p, *q, *r, *r1;
                   1168:        CONSZ temp;
                   1169:        int tempi;
                   1170: 
                   1171:        swbeg = &swtab[swx+1];
                   1172: 
                   1173:        /* sort */
                   1174: 
                   1175:        r1 = swbeg;
                   1176:        r = swp-1;
                   1177: 
                   1178:        while( swbeg < r ){
                   1179:                /* bubble largest to end */
                   1180:                for( q=swbeg; q<r; ++q ){
                   1181:                        if( q->sval > (q+1)->sval ){
                   1182:                                /* swap */
                   1183:                                r1 = q+1;
                   1184:                                temp = q->sval;
                   1185:                                q->sval = r1->sval;
                   1186:                                r1->sval = temp;
                   1187:                                tempi = q->slab;
                   1188:                                q->slab = r1->slab;
                   1189:                                r1->slab = tempi;
                   1190:                                }
                   1191:                        }
                   1192:                r = r1;
                   1193:                r1 = swbeg;
                   1194:                }
                   1195: 
                   1196:        /* it is now sorted */
                   1197: 
                   1198:        for( p = swbeg+1; p<swp; ++p ){
                   1199:                if( p->sval == (p-1)->sval ){
                   1200:                        uerror( "duplicate case in switch, %d", tempi=p->sval );
                   1201:                        return;
                   1202:                        }
                   1203:                }
                   1204: 
                   1205:        reached = 1;
                   1206:        genswitch( swbeg-1, (int)(swp-swbeg) );
                   1207:        swp = swbeg-1;
                   1208:        }

unix.superglobalmegacorp.com

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