|
|
1.1 root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.