1: /*
   2:  * Copyright (c) 1983 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  */
   6: 
   7: #ifndef lint
   8: static char sccsid[] = "@(#)c.c	5.1 (Berkeley) 5/31/85";
   9: #endif not lint
  10: 
  11: static char rcsid[] = "$Header: c.c,v 1.5 84/12/26 10:38:23 linton Exp $";
  12: 
  13: /*
  14:  * C-dependent symbol routines.
  15:  */
  16: 
  17: #include "defs.h"
  18: #include "symbols.h"
  19: #include "printsym.h"
  20: #include "languages.h"
  21: #include "c.h"
  22: #include "tree.h"
  23: #include "eval.h"
  24: #include "operators.h"
  25: #include "mappings.h"
  26: #include "process.h"
  27: #include "runtime.h"
  28: #include "machine.h"
  29: 
  30: #ifndef public
  31: # include "tree.h"
  32: #endif
  33: 
  34: #define isdouble(range) ( \
  35:     range->symvalue.rangev.upper == 0 and range->symvalue.rangev.lower > 0 \
  36: )
  37: 
  38: #define isrange(t, name) (t->class == RANGE and istypename(t->type, name))
  39: 
  40: private Language langC;
  41: 
  42: /*
  43:  * Initialize C language information.
  44:  */
  45: 
  46: public c_init()
  47: {
  48:     langC = language_define("c", ".c");
  49:     language_setop(langC, L_PRINTDECL, c_printdecl);
  50:     language_setop(langC, L_PRINTVAL, c_printval);
  51:     language_setop(langC, L_TYPEMATCH, c_typematch);
  52:     language_setop(langC, L_BUILDAREF, c_buildaref);
  53:     language_setop(langC, L_EVALAREF, c_evalaref);
  54:     language_setop(langC, L_MODINIT, c_modinit);
  55:     language_setop(langC, L_HASMODULES, c_hasmodules);
  56:     language_setop(langC, L_PASSADDR, c_passaddr);
  57: }
  58: 
  59: /*
  60:  * Test if two types are compatible.
  61:  */
  62: 
  63: public Boolean c_typematch(type1, type2)
  64: Symbol type1, type2;
  65: {
  66:     Boolean b;
  67:     register Symbol t1, t2, tmp;
  68: 
  69:     t1 = type1;
  70:     t2 = type2;
  71:     if (t1 == t2) {
  72:     b = true;
  73:     } else {
  74:     t1 = rtype(t1);
  75:     t2 = rtype(t2);
  76:     if (t1 == t_char->type or t1 == t_int->type or t1 == t_real->type) {
  77:         tmp = t1;
  78:         t1 = t2;
  79:         t2 = tmp;
  80:     }
  81:     b = (Boolean) (
  82:         (
  83:         isrange(t1, "int") and
  84:         (t2 == t_int->type or t2 == t_char->type)
  85:         ) or (
  86:         isrange(t1, "char") and
  87:         (t2 == t_char->type or t2 == t_int->type)
  88:         ) or (
  89:         t1->class == RANGE and isdouble(t1) and t2 == t_real->type
  90:         ) or (
  91:         t1->class == RANGE and t2->class == RANGE and
  92:         t1->symvalue.rangev.lower == t2->symvalue.rangev.lower and
  93:         t1->symvalue.rangev.upper == t2->symvalue.rangev.upper
  94:         ) or (
  95:         t1->type == t2->type and (
  96:             (t1->class == t2->class) or
  97:             (t1->class == SCAL and t2->class == CONST) or
  98:             (t1->class == CONST and t2->class == SCAL)
  99:         )
 100:         ) or (
 101:         t1->class == PTR and c_typematch(t1->type, t_char) and
 102:         t2->class == ARRAY and c_typematch(t2->type, t_char) and
 103:         t2->language == primlang
 104:         )
 105:     );
 106:     }
 107:     return b;
 108: }
 109: 
 110: /*
 111:  * Print out the declaration of a C variable.
 112:  */
 113: 
 114: public c_printdecl(s)
 115: Symbol s;
 116: {
 117:     printdecl(s, 0);
 118: }
 119: 
 120: private printdecl(s, indent)
 121: register Symbol s;
 122: Integer indent;
 123: {
 124:     register Symbol t;
 125:     Boolean semicolon, newline;
 126: 
 127:     semicolon = true;
 128:     newline = true;
 129:     if (indent > 0) {
 130:     printf("%*c", indent, ' ');
 131:     }
 132:     if (s->class == TYPE) {
 133:     printf("typedef ");
 134:     }
 135:     switch (s->class) {
 136:     case CONST:
 137:         if (s->type->class == SCAL) {
 138:         printf("enumeration constant with value ");
 139:         eval(s->symvalue.constval);
 140:         c_printval(s);
 141:         } else {
 142:         printf("const %s = ", symname(s));
 143:         printval(s);
 144:         }
 145:         break;
 146: 
 147:     case TYPE:
 148:     case VAR:
 149:         if (s->class != TYPE and s->level < 0) {
 150:         printf("register ");
 151:         }
 152:         if (s->type->class == ARRAY) {
 153:         printtype(s->type, s->type->type, indent);
 154:         t = rtype(s->type->chain);
 155:         assert(t->class == RANGE);
 156:         printf(" %s[%d]", symname(s), t->symvalue.rangev.upper + 1);
 157:         } else {
 158:         printtype(s, s->type, indent);
 159:         if (s->type->class != PTR) {
 160:             printf(" ");
 161:         }
 162:         printf("%s", symname(s));
 163:         }
 164:         break;
 165: 
 166:     case FIELD:
 167:         if (s->type->class == ARRAY) {
 168:         printtype(s->type, s->type->type, indent);
 169:         t = rtype(s->type->chain);
 170:         assert(t->class == RANGE);
 171:         printf(" %s[%d]", symname(s), t->symvalue.rangev.upper + 1);
 172:         } else {
 173:         printtype(s, s->type, indent);
 174:         if (s->type->class != PTR) {
 175:             printf(" ");
 176:         }
 177:         printf("%s", symname(s));
 178:         }
 179:         if (isbitfield(s)) {
 180:         printf(" : %d", s->symvalue.field.length);
 181:         }
 182:         break;
 183: 
 184:     case TAG:
 185:         if (s->type == nil) {
 186:         findtype(s);
 187:         if (s->type == nil) {
 188:             error("unexpected missing type information");
 189:         }
 190:         }
 191:         printtype(s, s->type, indent);
 192:         break;
 193: 
 194:     case RANGE:
 195:     case ARRAY:
 196:     case RECORD:
 197:     case VARNT:
 198:     case PTR:
 199:     case FFUNC:
 200:         semicolon = false;
 201:         printtype(s, s, indent);
 202:         break;
 203: 
 204:     case SCAL:
 205:         printf("(enumeration constant, value %d)", s->symvalue.iconval);
 206:         break;
 207: 
 208:     case PROC:
 209:         semicolon = false;
 210:         printf("%s", symname(s));
 211:         c_listparams(s);
 212:         newline = false;
 213:         break;
 214: 
 215:     case FUNC:
 216:         semicolon = false;
 217:         if (not istypename(s->type, "void")) {
 218:         printtype(s, s->type, indent);
 219:         printf(" ");
 220:         }
 221:         printf("%s", symname(s));
 222:         c_listparams(s);
 223:         newline = false;
 224:         break;
 225: 
 226:     case MODULE:
 227:         semicolon = false;
 228:         printf("source file \"%s.c\"", symname(s));
 229:         break;
 230: 
 231:     case PROG:
 232:         semicolon = false;
 233:         printf("executable file \"%s\"", symname(s));
 234:         break;
 235: 
 236:     default:
 237:         printf("[%s]", classname(s));
 238:         break;
 239:     }
 240:     if (semicolon) {
 241:     putchar(';');
 242:     }
 243:     if (newline) {
 244:     putchar('\n');
 245:     }
 246: }
 247: 
 248: /*
 249:  * Recursive whiz-bang procedure to print the type portion
 250:  * of a declaration.
 251:  *
 252:  * The symbol associated with the type is passed to allow
 253:  * searching for type names without getting "type blah = blah".
 254:  */
 255: 
 256: private printtype(s, t, indent)
 257: Symbol s;
 258: Symbol t;
 259: Integer indent;
 260: {
 261:     register Symbol i;
 262:     long r0, r1;
 263:     register String p;
 264: 
 265:     checkref(s);
 266:     checkref(t);
 267:     switch (t->class) {
 268:     case VAR:
 269:     case CONST:
 270:     case PROC:
 271:         panic("printtype: class %s", classname(t));
 272:         break;
 273: 
 274:     case ARRAY:
 275:         printf("array[");
 276:         i = t->chain;
 277:         if (i != nil) {
 278:         for (;;) {
 279:             printtype(i, i, indent);
 280:             i = i->chain;
 281:             if (i == nil) {
 282:             break;
 283:             }
 284:             printf(", ");
 285:         }
 286:         }
 287:         printf("] of ");
 288:         printtype(t, t->type, indent);
 289:         break;
 290: 
 291:     case RECORD:
 292:     case VARNT:
 293:         printf("%s ", c_classname(t));
 294:         if (s->name != nil and s->class == TAG) {
 295:         p = symname(s);
 296:         if (p[0] == '$' and p[1] == '$') {
 297:             printf("%s ", &p[2]);
 298:         } else {
 299:             printf("%s ", p);
 300:         }
 301:         }
 302:         printf("{\n", t->class == RECORD ? "struct" : "union");
 303:         for (i = t->chain; i != nil; i = i->chain) {
 304:         assert(i->class == FIELD);
 305:         printdecl(i, indent+4);
 306:         }
 307:         if (indent > 0) {
 308:         printf("%*c", indent, ' ');
 309:         }
 310:         printf("}");
 311:         break;
 312: 
 313:     case RANGE:
 314:         r0 = t->symvalue.rangev.lower;
 315:         r1 = t->symvalue.rangev.upper;
 316:         if (istypename(t->type, "char")) {
 317:         if (r0 < 0x20 or r0 > 0x7e) {
 318:             printf("%ld..", r0);
 319:         } else {
 320:             printf("'%c'..", (char) r0);
 321:         }
 322:         if (r1 < 0x20 or r1 > 0x7e) {
 323:             printf("\\%lo", r1);
 324:         } else {
 325:             printf("'%c'", (char) r1);
 326:         }
 327:         } else if (r0 > 0 and r1 == 0) {
 328:         printf("%ld byte real", r0);
 329:         } else if (r0 >= 0) {
 330:         printf("%lu..%lu", r0, r1);
 331:         } else {
 332:         printf("%ld..%ld", r0, r1);
 333:         }
 334:         break;
 335: 
 336:     case PTR:
 337:         printtype(t, t->type, indent);
 338:         if (t->type->class != PTR) {
 339:         printf(" ");
 340:         }
 341:         printf("*");
 342:         break;
 343: 
 344:     case FUNC:
 345:     case FFUNC:
 346:         printtype(t, t->type, indent);
 347:         printf("()");
 348:         break;
 349: 
 350:     case TYPE:
 351:         if (t->name != nil) {
 352:         printname(stdout, t);
 353:         } else {
 354:         printtype(t, t->type, indent);
 355:         }
 356:         break;
 357: 
 358:     case TYPEREF:
 359:         printf("@%s", symname(t));
 360:         break;
 361: 
 362:     case SCAL:
 363:         printf("enum ");
 364:         if (s->name != nil and s->class == TAG) {
 365:         printf("%s ", symname(s));
 366:         }
 367:         printf("{ ");
 368:         i = t->chain;
 369:         if (i != nil) {
 370:         for (;;) {
 371:             printf("%s", symname(i));
 372:             i = i->chain;
 373:         if (i == nil) break;
 374:             printf(", ");
 375:         }
 376:         }
 377:         printf(" }");
 378:         break;
 379: 
 380:     case TAG:
 381:         if (t->type == nil) {
 382:         printf("unresolved tag %s", symname(t));
 383:         } else {
 384:         i = rtype(t->type);
 385:         printf("%s %s", c_classname(i), symname(t));
 386:         }
 387:         break;
 388: 
 389:     default:
 390:         printf("(class %d)", t->class);
 391:         break;
 392:     }
 393: }
 394: 
 395: /*
 396:  * List the parameters of a procedure or function.
 397:  * No attempt is made to combine like types.
 398:  */
 399: 
 400: public c_listparams(s)
 401: Symbol s;
 402: {
 403:     register Symbol t;
 404: 
 405:     putchar('(');
 406:     for (t = s->chain; t != nil; t = t->chain) {
 407:     printf("%s", symname(t));
 408:     if (t->chain != nil) {
 409:         printf(", ");
 410:     }
 411:     }
 412:     putchar(')');
 413:     if (s->chain != nil) {
 414:     printf("\n");
 415:     for (t = s->chain; t != nil; t = t->chain) {
 416:         if (t->class != VAR) {
 417:         panic("unexpected class %d for parameter", t->class);
 418:         }
 419:         printdecl(t, 0);
 420:     }
 421:     } else {
 422:     putchar('\n');
 423:     }
 424: }
 425: 
 426: /*
 427:  * Print out the value on the top of the expression stack
 428:  * in the format for the type of the given symbol.
 429:  */
 430: 
 431: public c_printval(s)
 432: Symbol s;
 433: {
 434:     register Symbol t;
 435:     register Address a;
 436:     integer i, len;
 437: 
 438:     switch (s->class) {
 439:     case CONST:
 440:     case TYPE:
 441:     case VAR:
 442:     case REF:
 443:     case FVAR:
 444:     case TAG:
 445:         c_printval(s->type);
 446:         break;
 447: 
 448:     case FIELD:
 449:         if (isbitfield(s)) {
 450:         i = 0;
 451:         popn(size(s), &i);
 452:         i >>= (s->symvalue.field.offset mod BITSPERBYTE);
 453:         i &= ((1 << s->symvalue.field.length) - 1);
 454:         t = rtype(s->type);
 455:         if (t->class == SCAL) {
 456:             printEnum(i, t);
 457:         } else {
 458:             printRangeVal(i, t);
 459:         }
 460:         } else {
 461:         c_printval(s->type);
 462:         }
 463:         break;
 464: 
 465:     case ARRAY:
 466:         t = rtype(s->type);
 467:         if ((t->class == RANGE and istypename(t->type, "char")) or
 468:         t == t_char->type
 469:         ) {
 470:         len = size(s);
 471:         sp -= len;
 472:         if (s->language == primlang) {
 473:             printf("%.*s", len, sp);
 474:         } else {
 475:             printf("\"%.*s\"", len, sp);
 476:         }
 477:         } else {
 478:         printarray(s);
 479:         }
 480:         break;
 481: 
 482:     case RECORD:
 483:         c_printstruct(s);
 484:         break;
 485: 
 486:     case RANGE:
 487:         if (s == t_boolean->type or istypename(s->type, "boolean")) {
 488:         printRangeVal(popsmall(s), s);
 489:         } else if (s == t_char->type or istypename(s->type, "char")) {
 490:         printRangeVal(pop(char), s);
 491:         } else if (s == t_real->type or isdouble(s)) {
 492:         switch (s->symvalue.rangev.lower) {
 493:             case sizeof(float):
 494:             prtreal(pop(float));
 495:             break;
 496: 
 497:             case sizeof(double):
 498:             prtreal(pop(double));
 499:             break;
 500: 
 501:             default:
 502:             panic("bad real size %d", t->symvalue.rangev.lower);
 503:             break;
 504:         }
 505:         } else {
 506:         printRangeVal(popsmall(s), s);
 507:         }
 508:         break;
 509: 
 510:     case PTR:
 511:         t = rtype(s->type);
 512:         a = pop(Address);
 513:         if (a == 0) {
 514:         printf("(nil)");
 515:         } else if (t->class == RANGE and istypename(t->type, "char")) {
 516:         printString(a, (boolean) (s->language != primlang));
 517:         } else {
 518:         printf("0x%x", a);
 519:         }
 520:         break;
 521: 
 522:     case SCAL:
 523:         i = pop(Integer);
 524:         printEnum(i, s);
 525:         break;
 526: 
 527:     /*
 528: 	 * Unresolved structure pointers?
 529: 	 */
 530:     case BADUSE:
 531:         a = pop(Address);
 532:         printf("@%x", a);
 533:         break;
 534: 
 535:     default:
 536:         if (ord(s->class) > ord(TYPEREF)) {
 537:         panic("printval: bad class %d", ord(s->class));
 538:         }
 539:         sp -= size(s);
 540:         printf("[%s]", c_classname(s));
 541:         break;
 542:     }
 543: }
 544: 
 545: /*
 546:  * Print out a C structure.
 547:  */
 548: 
 549: private c_printstruct (s)
 550: Symbol s;
 551: {
 552:     Symbol f;
 553:     Stack *savesp;
 554:     integer n, off, len;
 555: 
 556:     sp -= size(s);
 557:     savesp = sp;
 558:     printf("(");
 559:     f = s->chain;
 560:     for (;;) {
 561:     off = f->symvalue.field.offset;
 562:     len = f->symvalue.field.length;
 563:     n = (off + len + BITSPERBYTE - 1) div BITSPERBYTE;
 564:     sp += n;
 565:     printf("%s = ", symname(f));
 566:     c_printval(f);
 567:     sp = savesp;
 568:     f = f->chain;
 569:     if (f == nil) break;
 570:     printf(", ");
 571:     }
 572:     printf(")");
 573: }
 574: 
 575: /*
 576:  * Return the C name for the particular class of a symbol.
 577:  */
 578: 
 579: public String c_classname(s)
 580: Symbol s;
 581: {
 582:     String str;
 583: 
 584:     switch (s->class) {
 585:     case RECORD:
 586:         str = "struct";
 587:         break;
 588: 
 589:     case VARNT:
 590:         str = "union";
 591:         break;
 592: 
 593:     case SCAL:
 594:         str = "enum";
 595:         break;
 596: 
 597:     default:
 598:         str = classname(s);
 599:     }
 600:     return str;
 601: }
 602: 
 603: public Node c_buildaref(a, slist)
 604: Node a, slist;
 605: {
 606:     register Symbol t;
 607:     register Node p;
 608:     Symbol etype, atype, eltype;
 609:     Node r, esub;
 610: 
 611:     t = rtype(a->nodetype);
 612:     eltype = t->type;
 613:     if (t->class == PTR) {
 614:     p = slist->value.arg[0];
 615:     if (not compatible(p->nodetype, t_int)) {
 616:         beginerrmsg();
 617:         fprintf(stderr, "subscript must be integer-compatible");
 618:         enderrmsg();
 619:     }
 620:     r = build(O_MUL, p, build(O_LCON, (long) size(eltype)));
 621:     r = build(O_ADD, build(O_RVAL, a), r);
 622:     r->nodetype = eltype;
 623:     } else if (t->class != ARRAY) {
 624:     beginerrmsg();
 625:     fprintf(stderr, "\"");
 626:     prtree(stderr, a);
 627:     fprintf(stderr, "\" is not an array");
 628:     enderrmsg();
 629:     } else {
 630:     r = a;
 631:     p = slist;
 632:     t = t->chain;
 633:     for (; p != nil and t != nil; p = p->value.arg[1], t = t->chain) {
 634:         esub = p->value.arg[0];
 635:         etype = rtype(esub->nodetype);
 636:         atype = rtype(t);
 637:         if (not compatible(atype, etype)) {
 638:         beginerrmsg();
 639:         fprintf(stderr, "subscript \"");
 640:         prtree(stderr, esub);
 641:         fprintf(stderr, "\" is the wrong type");
 642:         enderrmsg();
 643:         }
 644:         r = build(O_INDEX, r, esub);
 645:         r->nodetype = eltype;
 646:     }
 647:     if (p != nil or t != nil) {
 648:         beginerrmsg();
 649:         if (p != nil) {
 650:         fprintf(stderr, "too many subscripts for \"");
 651:         } else {
 652:         fprintf(stderr, "not enough subscripts for \"");
 653:         }
 654:         prtree(stderr, a);
 655:         fprintf(stderr, "\"");
 656:         enderrmsg();
 657:     }
 658:     }
 659:     return r;
 660: }
 661: 
 662: /*
 663:  * Evaluate a subscript index.
 664:  */
 665: 
 666: public c_evalaref(s, base, i)
 667: Symbol s;
 668: Address base;
 669: long i;
 670: {
 671:     Symbol t;
 672:     long lb, ub;
 673: 
 674:     t = rtype(s);
 675:     s = t->chain;
 676:     lb = s->symvalue.rangev.lower;
 677:     ub = s->symvalue.rangev.upper;
 678:     if (i < lb or i > ub) {
 679:     error("subscript out of range");
 680:     }
 681:     push(long, base + (i - lb) * size(t->type));
 682: }
 683: 
 684: /*
 685:  * Initialize typetable information.
 686:  */
 687: 
 688: public c_modinit (typetable)
 689: Symbol typetable[];
 690: {
 691:     /* nothing right now */
 692: }
 693: 
 694: public boolean c_hasmodules ()
 695: {
 696:     return false;
 697: }
 698: 
 699: public boolean c_passaddr (param, exprtype)
 700: Symbol param, exprtype;
 701: {
 702:     boolean b;
 703:     Symbol t;
 704: 
 705:     t = rtype(exprtype);
 706:     b = (boolean) (t->class == ARRAY);
 707:     return b;
 708: }

Defined functions

c_buildaref defined in line 603; used 1 times
  • in line 52
c_classname defined in line 579; used 3 times
c_evalaref defined in line 666; used 1 times
  • in line 53
c_hasmodules defined in line 694; used 1 times
  • in line 55
c_init defined in line 46; used 1 times
c_listparams defined in line 400; used 2 times
c_modinit defined in line 688; used 1 times
  • in line 54
c_passaddr defined in line 699; used 1 times
  • in line 56
c_printdecl defined in line 114; used 1 times
  • in line 49
c_printstruct defined in line 549; used 1 times
c_printval defined in line 431; used 5 times
c_typematch defined in line 63; used 3 times
printtype defined in line 256; used 12 times

Defined variables

rcsid defined in line 11; never used
sccsid defined in line 8; never used

Defined macros

isdouble defined in line 34; used 2 times
isrange defined in line 38; used 2 times
Last modified: 1985-05-31
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1943
Valid CSS Valid XHTML 1.0 Strict