[BACK]Return to simple.y CVS log [TXT][DIR] Up to [local] / OpenXM / src / k097

Annotation of OpenXM/src/k097/simple.y, Revision 1.1

1.1     ! maekawa     1:
        !             2: /* simple.y 1996, 1/1 --- 1/6 */
        !             3: /* simple.y.ccc,  1996, 4/1 --- */
        !             4: %{
        !             5: #include <stdio.h>
        !             6: #include "d.h"
        !             7: %}
        !             8:
        !             9:
        !            10: %token ID QUOTE SINGLEQUOTE NUMBER
        !            11:
        !            12: /* You have to change  isReserved() [d.c], too */
        !            13: %token CLASS SUPER OPERATOR FINAL EXTENDS INCETANCEVARIABLE
        !            14: %token THIS NEW SIZEOFTHISCLASS STARTOFTHISCLASS
        !            15: %token MODULE PRINT LOCAL DEF SM1 LOAD TEST SPECIAL
        !            16: %token AUTO BREAK CASE CHAR CONST CONTINUE DEFAULT DO DOUBLE ELSE ENUM
        !            17: %token EXTERN FLOAT FOR GOTO IF INT LONG REGISTER
        !            18: %token RETURN SHORT SIGNED SIZEOF STATIC STRUCT SWITCH TYPEDEF UNION
        !            19: %token UNSIGNED VOLATILE VOID WHILE  PSFOR PROMPT
        !            20:
        !            21: %right '=' PUT MULTPUT NEGATEPUT RESIDUEPUT
        !            22:
        !            23: %left OR
        !            24: %left AND
        !            25: %left '|'
        !            26: %left '&'
        !            27: %left EQUAL NOTEQUAL
        !            28: %left '<' '>' LESSEQUAL GREATEREQUAL
        !            29: %left LEFTSHIFT RIGHTSHIFT
        !            30: %left '+' '-'
        !            31: %left '*' '/' '%'
        !            32:
        !            33: %left UNARYMINUS '!' INCREMENT DECREMENT '~'
        !            34: %right '^'
        !            35:
        !            36: %left '.'
        !            37: %left MEMBER
        !            38: %%
        !            39:
        !            40: /* Mathematica-like parser */
        !            41: program
        !            42:   : globalstatements
        !            43:   ;
        !            44:
        !            45: globalstatements
        !            46:   :
        !            47:     sentence globalstatements
        !            48:   | sentence
        !            49:   ;
        !            50:
        !            51: sentence   /*  { ... } {...} :  ; does not need. */
        !            52:   :
        !            53:     for
        !            54:   | PSfor
        !            55:   | while
        !            56:   | if
        !            57:   | functionDefinition   {sendKan(0); }
        !            58:   | exp ';'              {sendKan(0); }
        !            59:   | exp ':'              {pkkan(" [ ] {showln} sendmsg2 \n"); sendKan(0); }
        !            60:   | ';'                  {sendKan(0); }
        !            61:   | class_definition     {sendKan(0); }
        !            62:   | error ';'
        !            63:   | PROMPT ';'           {sendKan(10); }
        !            64:   ;
        !            65:
        !            66: statements
        !            67:   :
        !            68:     localsentence statements
        !            69:   | localsentence
        !            70:   ;
        !            71:
        !            72: localsentence
        !            73:   :
        !            74:     for
        !            75:   | PSfor
        !            76:   | while
        !            77:   | if
        !            78:   | exp ';'
        !            79:   | return ';'
        !            80:   | break ';'
        !            81:   | ';'
        !            82:   ;
        !            83:
        !            84: argList
        !            85:   : exp ',' argList
        !            86:   | exp   /* It does not cause reduce-reduce conflict
        !            87:             between "program"! */
        !            88:   ;
        !            89:
        !            90: return :
        !            91:     RETURN exp   { pkkan(" /FunctionValue set  {/ExitPoint goto} exec %%return\n");}
        !            92:   | RETURN  {pkkan("  {/ExitPoint goto} exec %%return void\n");}
        !            93:   ;
        !            94:
        !            95: break : BREAK  { pkkan(" exit "); }
        !            96:
        !            97: list_prefix
        !            98:   :
        !            99:     '['  { pkkan("[ "); }
        !           100:   ;
        !           101: list
        !           102:   : list_prefix  ']'           { pkkan("  ] "); }
        !           103:   | list_prefix argList ']'    { pkkan("  ] "); }
        !           104:   ;
        !           105:
        !           106: curryBrace
        !           107:   :  '{'  '}'
        !           108:   |  '{' statements '}'
        !           109:   ;
        !           110:
        !           111: if_prefix
        !           112:   : IF '(' exp ')' { pkkan(" %% if-condition\n  { %%ifbody\n"); }
        !           113:   ;
        !           114: if_body
        !           115:   : localsentence    { pkkan("  }%%end if if body\n  { %%if- else part\n"); }
        !           116:   | curryBrace     { pkkan("  }%%end if if body\n  { %%if- else part\n"); }
        !           117:   ;
        !           118: if
        !           119:   : if_prefix if_body                   { pkkan("  } ifelse\n"); }
        !           120: /* The line cause 1 shift/reduce conflict. Look up a book. */
        !           121:   | if_prefix if_body ELSE localsentence     { pkkan("  } ifelse\n"); }
        !           122:   | if_prefix if_body ELSE curryBrace   { pkkan("  } ifelse\n"); }
        !           123:   ;
        !           124:
        !           125:
        !           126: for_prefix0
        !           127:   : FOR '(' exp ';'  { pkkan("%%for init.\n%%for\n{ "); }
        !           128:   | FOR '('     ';'  { pkkan("%%nothing for init.\n%%for\n{ "); }
        !           129:   ;
        !           130: for_exit
        !           131:   : exp ';'    { pkkan(" {  } {exit} ifelse\n[ {%%increment\n"); }
        !           132:   |     ';'    { pkkan("%%no exit rule.\n[ {%%increment\n"); }
        !           133:   ;
        !           134: for_inc
        !           135:   : exp        { pkkan("} %%end of increment{A}\n"); }
        !           136:   ;
        !           137: /* [{ A } { B } roll 2 1] {exec} map ---> B A */
        !           138: for_prefix
        !           139:   : for_prefix0  for_exit  for_inc ')'
        !           140:                {  pkkan("{%%start of B part{B}\n"); }
        !           141:   | for_prefix0  for_exit      ')'
        !           142:                {  pkkan("  } %% dummy A\n{%%start of B part{B}\n"); }
        !           143:   ;
        !           144: for
        !           145:   : for_prefix curryBrace
        !           146:                { pkkan("} %% end of B part. {B}\n");
        !           147:                  pkkan(" 2 1 roll] {exec} map pop\n} loop %%end of for\n"); }
        !           148:
        !           149: PSfor_prefix
        !           150:   : PSFOR '(' ID '=' exp ';'
        !           151:      { pkkan("%%PSfor initvalue.\n (integer) data_conversion \n");
        !           152:        ips($3);
        !           153:      }
        !           154:     ID '<' exp ';' ID INCREMENT  ')'
        !           155:      { ips($7); ips($10);
        !           156:        /* They must be equal id, but it is not checked. */
        !           157:        pkkan(" (1).. sub  (integer) data_conversion  1  2 -1 roll \n");
        !           158:        pkkan("{ %% for body\n (universalNumber) data_conversion ");
        !           159:        pkkan("/"); printObjectSymbol($3); pkkan("  set \n");
        !           160:      }
        !           161:   ;
        !           162: PSfor
        !           163:   : PSfor_prefix curryBrace
        !           164:      { pkkan("  } for \n"); }
        !           165:   ;
        !           166:
        !           167: while_prefix0
        !           168:   : WHILE '('  { pkkan("\n%%while\n{ "); }
        !           169:   ;
        !           170:
        !           171: while_prefix
        !           172:   : while_prefix0 exp ')'   { pkkan(" { } {exit} ifelse\n "); }
        !           173:   | while_prefix0     ')'   { pkkan("%%no exit condition.\n "); }
        !           174:   ;
        !           175:
        !           176: while
        !           177:   :  while_prefix curryBrace {   pkkan("} loop\n"); }
        !           178:   ;
        !           179:
        !           180:
        !           181: print
        !           182:   : PRINT '(' exp ')' { pkkan(" print\n");}
        !           183:   ;
        !           184:
        !           185: sm1 :
        !           186:     SM1 '(' sm1ArgList ')'
        !           187:   ;
        !           188:
        !           189: load :
        !           190:     LOAD '(' QUOTE ')'   {   loadFile($3);  }
        !           191:   | LOAD '(' ID ')'      {   loadFile($3);  }
        !           192:   | LOAD ID              {   loadFile($2);  }
        !           193:   | LOAD QUOTE           {   loadFile($2);  }
        !           194:   | LOAD '[' QUOTE ']'   {   loadFileWithCpp($3); }
        !           195:
        !           196: sm1ArgList :
        !           197:   | sm1ArgList ',' QUOTE  { pkkan(" "); printObjectSymbol($3); pkkan(" "); }
        !           198:   | QUOTE                 { pkkan(" "); printObjectSymbol($1); pkkan(" "); }
        !           199:   | sm1ArgList ',' ID     { pkkan(" "); printObjectSymbol($3); pkkan(" "); }
        !           200:   | ID                    { pkkan(" "); printObjectSymbol($1); pkkan(" "); }
        !           201:   ;
        !           202:
        !           203: primitive
        !           204:   : ID
        !           205:    { int tmp0;
        !           206:      if ((tmp0 = K00getIncetanceVariable(objectSymbolToString($1))) != -1) {
        !           207:        pkkan(" this "); pkkanInteger(tmp0); pkkan(" get ");
        !           208:      } else {
        !           209:        printObjectSymbol($1); pkkan(" ");
        !           210:      }
        !           211:    }
        !           212:   | QUOTE     { pkkan("("); printObjectSymbol($1); pkkan(") "); }
        !           213:   | SINGLEQUOTE
        !           214:   | NUMBER    { pkkan("("); printObjectSymbol($1); pkkan(").. ");}
        !           215:   | THIS      { pkkan(" this "); }
        !           216:   | '(' exp ')'
        !           217:   | functionCall
        !           218:   | list
        !           219:   | print
        !           220:   | sm1
        !           221:   | load
        !           222:   | test
        !           223:   | special
        !           224:   | set
        !           225:   | arrayValue
        !           226:   ;
        !           227:
        !           228: functionCall_prefix
        !           229:   :
        !           230:     ID '('  { pkkan("this [ %% function args \n"); $$ = $1 }
        !           231:   ;
        !           232:
        !           233: /* function call. cf. Schreiner 19p */
        !           234: /* If you want to have a strong binding s.t.
        !           235:    ID[1,2], then you need to define a new non-terminal
        !           236:    such as primitive. ????*/
        !           237: functionCall
        !           238:   :
        !           239:     functionCall_prefix  argList  ')'
        !           240:        {pkkan("] {");printObjectSymbol($1);pkkan("} sendmsg2 \n");}
        !           241:   | functionCall_prefix           ')'
        !           242:        {pkkan("] {");printObjectSymbol($1);pkkan("} sendmsg2 \n");}
        !           243:
        !           244:   ;
        !           245: idList
        !           246:   : idList ',' ID   { pkkan("/");printObjectSymbol($3); pkkan(" "); ips($3);}
        !           247:   | ID              { pkkan("/");printObjectSymbol($1); pkkan(" "); ips($1);}
        !           248:   ;
        !           249:
        !           250: functionHead
        !           251:   : DEF ID
        !           252:         { pkkan("/"); printObjectSymbol($2); pkkan(" {\n"); ips($2);
        !           253:           pkdebug("In function : ", objectSymbolToString($2),
        !           254:                  " of class ",K00getCurrentContextName());
        !           255:          pkkan(" /Arglist set /Argthis set /FunctionValue [ ] def\n [/this ");
        !           256:          $$ = $2;}
        !           257:   ;
        !           258:
        !           259: voidfunctionHead
        !           260:   : DEF VOID ID
        !           261:         { pkkan("/"); printObjectSymbol($3); pkkan(" {\n"); ips($3);
        !           262:           pkdebug("In function : ", objectSymbolToString($3),
        !           263:                  " of class ",K00getCurrentContextName());
        !           264:          pkkan(" /Arglist set /Argthis set /FunctionValue [ ] def\n [/this ");
        !           265:          $$ = $2;}
        !           266:   ;
        !           267:
        !           268: functionArg
        !           269:   : '(' idList ')'  '{'
        !           270:      {pkkan(" ] /ArgNames set ArgNames pushVariables [ %%function body\n");
        !           271:       pkkan(" [Argthis] Arglist join ArgNames mapset\n");}
        !           272:   | '('        ')'  '{'
        !           273:      {pkkan(" ] /ArgNames set ArgNames pushVariables [ %%function body\n");
        !           274:       pkkan(" [Argthis]  ArgNames mapset\n"); }
        !           275:   ;
        !           276:
        !           277: functionBody
        !           278:   :
        !           279:     declaration extern_declaration statements '}'
        !           280:           { pkkan("/ExitPoint ]pop popVariables %%pop the local variables\n"); }
        !           281:   |  extern_declaration statements '}'
        !           282:   ;
        !           283:
        !           284:
        !           285: functionDefinition
        !           286:   : functionHead functionArg functionBody
        !           287:         {pkkan("/ExitPoint ]pop popVariables %%pop argValues\n");
        !           288:         pkdebug2();
        !           289:          pkkan("FunctionValue } def\n%%end of function\n\n"); }
        !           290:   | operatorfunctionHead functionArg functionBody
        !           291:         {pkkan("/ExitPoint ]pop popVariables %%pop argValues\n");
        !           292:         pkdebug2();
        !           293:          pkkan("FunctionValue } def\n%%end of function\n\n"); }
        !           294:   | voidfunctionHead functionArg functionBody
        !           295:         {pkkan("/ExitPoint ]pop popVariables %%pop argValues\n");
        !           296:         pkdebug2();
        !           297:          pkkan("} def\n%%end of function\n\n"); }
        !           298:   ;
        !           299:
        !           300: declaration_prefix
        !           301:   : LOCAL { pkkan("[ %%start of local variables\n"); }
        !           302:   ;
        !           303:
        !           304: declaration
        !           305:   : declaration_prefix  idList ';'
        !           306:        { pkkan("] pushVariables [ %%local variables\n"); }
        !           307:   ;
        !           308:
        !           309: extern_idList
        !           310:   : extern_idList ',' ID
        !           311:            {     ;}
        !           312:   | ID     {     ;}
        !           313:   ;
        !           314:
        !           315: extern_declaration_prefix
        !           316:   : EXTERN {   ; }
        !           317:   ;
        !           318:
        !           319: extern_declaration
        !           320:   : extern_declaration_prefix  extern_idList ';'
        !           321:        {  ; }
        !           322:   |
        !           323:   ;
        !           324:
        !           325: arrayValue :
        !           326:    array    { pkkan(" Get\n"); }
        !           327:   ;
        !           328: array :
        !           329:    array_prefix arrayIndex ']' {pkkan(" ] "); }
        !           330:   ;
        !           331: arrayIndex :
        !           332:     exp ',' arrayIndex
        !           333:   | exp
        !           334:   ;
        !           335: array_prefix :
        !           336:     ID '['
        !           337:      { int tmp0;
        !           338:        if ((tmp0 = K00getIncetanceVariable(objectSymbolToString($1))) != -1) {
        !           339:          pkkan(" this "); pkkanInteger(tmp0); pkkan(" get [");
        !           340:        } else {
        !           341:          printObjectSymbol($1); pkkan(" [");
        !           342:        }
        !           343:      }
        !           344:   ;
        !           345:
        !           346:
        !           347: id_set
        !           348:   : ID             { $$ = $1;}
        !           349:   ;
        !           350: set
        !           351:   : id_set '=' exp
        !           352:     { int tmp0;
        !           353:       if ((tmp0 = K00getIncetanceVariable(objectSymbolToString($1))) != -1) {
        !           354:        pkkan(" this "); pkkanInteger(tmp0);
        !           355:        pkkan(" 3 -1 roll   put\n");
        !           356:       }else {
        !           357:        pkkan("/"); printObjectSymbol($1); pkkan(" "); ips($1); pkkan(" set\n");
        !           358:       }
        !           359:     }
        !           360:   | array '=' exp  { pkkan(" Put\n"); }
        !           361:   | THIS '=' exp   { pkkan(" /this set \n"); }
        !           362:   ;
        !           363:
        !           364: exp
        !           365:   : primitive
        !           366:   | new
        !           367:   | '!' exp      { pkkan(" not\n"); }
        !           368:   | '~' exp
        !           369:   | '-' exp      { pkkan(" (0)..  2 1 roll {sub} sendmsg \n"); }
        !           370:   | exp '+' exp  { pkkan(" {add} sendmsg2 \n"); }
        !           371:   | exp '-' exp  { pkkan(" {sub} sendmsg2 \n"); }
        !           372:   | exp '*' exp  { pkkan(" {mul} sendmsg2 \n"); }
        !           373:   | exp '/' exp  { pkkan(" {div} sendmsg2 \n"); }
        !           374:   | exp '%' exp
        !           375:   | exp '^' exp  { pkkan(" power\n"); }
        !           376:   | exp '&' exp
        !           377:   | exp '|' exp
        !           378:   | exp EQUAL exp { pkkan(" eq\n"); }
        !           379:   | exp '<' exp { pkkan(" lt\n"); }
        !           380:   | exp '>' exp { pkkan(" gt\n"); }
        !           381:   | exp LESSEQUAL exp { pkkan(" lessThanOrEqual\n"); }
        !           382:   | exp LEFTSHIFT exp
        !           383:   | exp GREATEREQUAL exp { pkkan(" greaterThanOrEqual\n"); }
        !           384:   | exp RIGHTSHIFT exp
        !           385:   | exp AND exp { pkkan(" and\n"); }
        !           386:   | exp OR exp  { pkkan(" or\n"); }
        !           387:   | exp NOTEQUAL exp  { pkkan(" eq not\n"); }
        !           388:   | exp PUT exp
        !           389:   | id_set INCREMENT { pkkan("/");
        !           390:                       printObjectSymbol($1); ips($1);
        !           391:                       pkkan(" "); printObjectSymbol($1);
        !           392:                       pkkan(" (1).. {add} sendmsg2 "); pkkan("def\n"); }
        !           393:   | id_set DECREMENT { pkkan("/");
        !           394:                       printObjectSymbol($1); ips($1);
        !           395:                       pkkan(" "); printObjectSymbol($1);
        !           396:                       pkkan(" (1).. {sub} sendmsg2 "); pkkan("def\n"); }
        !           397:   | exp MEMBER exp
        !           398:   | exp '.' member_functionCall {  pkkan(" sendmsg2 \n"); }
        !           399:   | exp '.' ID   { /* Not implemented yet. */ }
        !           400:   | super '.' member_functionCall {  pkkan(" supmsg2 \n"); }
        !           401:   | NUMBER '.' NUMBER {  pkkan("("); printObjectSymbol($1);
        !           402:                         pkkan(")..  (double) dc ");
        !           403:                         pkkan("("); printObjectSymbol($3); pkkan(")..  ");
        !           404:                          pkkan("("); printTens($3); pkkan(").. ");
        !           405:                         pkkan(" div (double) dc  add\n"); }
        !           406:   | exp RESIDUEPUT exp
        !           407:   | exp NEGATEPUT exp
        !           408:   | exp MULTPUT exp
        !           409:   | SIZEOFTHISCLASS
        !           410:     {
        !           411:       int tmp0;
        !           412:       tmp0 = K00getIncetanceVariable("K00sizeof");
        !           413:       pkkan(" ("); pkkanInteger(tmp0); pkkan(").. ");
        !           414:     }
        !           415:
        !           416:   | STARTOFTHISCLASS
        !           417:     {
        !           418:       int tmp0;
        !           419:       tmp0 = K00getIncetanceVariable("K00start");
        !           420:       pkkan(" ("); pkkanInteger(tmp0); pkkan(").. ");
        !           421:     }
        !           422:   ;
        !           423:
        !           424: test : TEST '(' exp ')'
        !           425:           { /* It is not used now. */
        !           426:            sendKan(1);
        !           427:            Sm1obj = KSpop();
        !           428:            if (Sm1obj.tag != Sdollar) {
        !           429:              fprintf(stderr," Argument of test must be a string.\n");
        !           430:            }
        !           431:            testNewFunction((struct Object *)&Sm1obj);
        !           432:          }
        !           433:      ;
        !           434:
        !           435: special : SPECIAL '(' list ')'
        !           436:       {
        !           437:           fprintf(stderr," special is used to extend the function. \n");
        !           438:       }
        !           439:       ;
        !           440:
        !           441:
        !           442: member_functionCall
        !           443:   :
        !           444:     member_functionCall_prefix  argList  ')'
        !           445:        {pkkan("] {");printObjectSymbol($1);pkkan("}  ");}
        !           446:   | member_functionCall_prefix           ')'
        !           447:        {pkkan("] {");printObjectSymbol($1);pkkan("}  ");}
        !           448:
        !           449:   ;
        !           450: member_functionCall_prefix
        !           451:   :
        !           452:     ID '('  { pkkan(" [ %% function args \n"); $$ = $1 }
        !           453:   ;
        !           454:
        !           455:
        !           456: class_definition
        !           457:   :
        !           458:     class_definition_prefix incetance_variables globalstatements '}'
        !           459:       { pkkan(" PrimitiveContextp setcontext ");
        !           460:        /* debug */ K00foo1();
        !           461:         K00toPrimitiveClass();
        !           462:       }
        !           463:   |
        !           464:     class_definition_prefix  globalstatements '}'
        !           465:       { pkkan(" PrimitiveContextp setcontext ");
        !           466:        K00putIncetanceVariable(IEXIT," ");
        !           467:        /* debug */ K00foo1();
        !           468:        K00toPrimitiveClass();
        !           469:       }
        !           470:   ;
        !           471:
        !           472: class_definition_prefix
        !           473:   :
        !           474:     CLASS ID EXTENDS ID '{'
        !           475:       { ips($2);
        !           476:        pkkan("[ $") ; printObjectSymbol($2); pkkan("$ ");
        !           477:        printObjectSymbol($4); pkkan(" 0 get  newcontext ] /");
        !           478:        printObjectSymbol($2);  pkkan(" set \n");
        !           479:        printObjectSymbol($2); pkkan(" 0 get setcontext \n");
        !           480:
        !           481:        if (K00declareClass(objectSymbolToString($2),
        !           482:                            objectSymbolToString($4)) == -1) {
        !           483:          /* error */
        !           484:          KCerror("Super class has not been defined or Invalid class name.");
        !           485:        }else{
        !           486:          K00putIncetanceVariable(IRESET," ");
        !           487:        }
        !           488:       }
        !           489:
        !           490: incetance_variables
        !           491:   : LOCAL incetance_variables_list ';'
        !           492:       {
        !           493:        K00putIncetanceVariable(IEXIT," ");
        !           494:       }
        !           495:   ;
        !           496: incetance_variables_list
        !           497:   : incetance_variables_list ',' ID
        !           498:     {
        !           499:       K00putIncetanceVariable(IPUT,objectSymbolToString($3));
        !           500:     }
        !           501:   | ID
        !           502:     {
        !           503:       K00putIncetanceVariable(IPUT,objectSymbolToString($1));
        !           504:     }
        !           505:
        !           506: operatorfunctionHead
        !           507:   : DEF OPERATOR ID
        !           508:         { pkkan("/"); printObjectSymbol($3); pkkan(" {\n"); ips($3);
        !           509:           pkdebug("In function : ", objectSymbolToString($3),", of class  ",
        !           510:                  K00getCurrentContextName());
        !           511:          pkkan(" /Arglist set /Arglist [Arglist] def ");
        !           512:           pkkan(" /Argthis set /FunctionValue [ ] def\n [/this ");
        !           513:          $$ = $3;}
        !           514:   ;
        !           515:
        !           516: super
        !           517:   : SUPER   { pkkan(" this "); }
        !           518:   ;
        !           519:
        !           520: new
        !           521:   : NEW '(' exp ')'
        !           522:        { int tmp;
        !           523:         tmp = K00getIncetanceVariable("K00sizeof")
        !           524:           +K00getIncetanceVariable("K00start");
        !           525:         pkkanInteger(tmp);
        !           526:         pkkan(" ");
        !           527:         pkkan(K00getCurrentContextName());
        !           528:         pkkan(" cclass \n");
        !           529:        }
        !           530:   | NEW '(' ')'
        !           531:        { int tmp;
        !           532:          pkkan(" PrimitiveObject ");
        !           533:         tmp = K00getIncetanceVariable("K00sizeof")
        !           534:           +K00getIncetanceVariable("K00start");
        !           535:         pkkanInteger(tmp);
        !           536:         pkkan(" ");
        !           537:         pkkan(K00getCurrentContextName());
        !           538:         pkkan(" cclass \n");
        !           539:        }
        !           540:   ;
        !           541:
        !           542:
        !           543:
        !           544:
        !           545:
        !           546:

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>