📄 c.c
字号:
/*@(#)c.c 4.2 Ultrix 11/9/90*//************************************************************************ * * * Copyright (c) 1986, 1988 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//************************************************************************ * * * Modification History * * * * 005 - Fixed erroneous type mismatch. * * (Lee Miller, Jan 24, 1990) * * * * 004 - Changed c_typematch to accept 'integer' as well as * * 'int' because of lk brain damage. * * (Jon Reeves, June 9, 1988) * * * * 003 - Merged in 4.3 changes. * * (vjh, April 29, 1986) * * * * 002 - Fixed printrange() so that unsigned shorts and chars are * * displayed properly. * * (vjh, July 8, 1985) * * * * 001 - Modified c_init() to use LanguageName constant in call * * to language_define(). * * (Victoria Holt, June 22, 1985) * * * ************************************************************************//* * Copyright (c) 1983 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */#ifndef lintstatic char sccsid[] = "@(#)c.c 2.1 ULTRIX 4/24/89";#endif not lint/* * C-dependent symbol routines. */#include "defs.h"#include "symbols.h"#include "printsym.h"#include "languages.h"#include "c.h"#include "tree.h"#include "eval.h"#include "operators.h"#include "mappings.h"#include "process.h"#include "runtime.h"#include "machine.h"#include "varargs.h"#ifndef public# include "tree.h"#endif#define isdouble(range) ( \ range->symvalue.rangev.upper == 0 and range->symvalue.rangev.lower > 0 \)#define isrange(t, name) (t->class == RANGE and istypename(t->type, name))private Language langC;/* * Initialize C language information. */public c_init(){ langC = language_define("c", C); language_setop(langC, L_PRINTDECL, c_printdecl); language_setop(langC, L_PRINTVAL, c_printval); language_setop(langC, L_TYPEMATCH, c_typematch); language_setop(langC, L_BUILDAREF, c_buildaref); language_setop(langC, L_EVALAREF, c_evalaref); language_setop(langC, L_MODINIT, c_modinit); language_setop(langC, L_HASMODULES, c_hasmodules); language_setop(langC, L_PASSADDR, c_passaddr); language_setop(langC, L_PRINTF, c_printf);}/* * Test if two types are compatible. */public Boolean c_typematch(type1, type2)Symbol type1, type2;{ Boolean b; register Symbol t1, t2, tmp; t1 = type1; t2 = type2; if (t1 == t2) { b = true; } else { t1 = rtype(t1); t2 = rtype(t2); if (t1 == t_char->type or t1 == t_int->type or t1 == t_real->type) { tmp = t1; t1 = t2; t2 = tmp; } b = (Boolean) ( ( isrange(t1, "int") and (t2 == t_int->type or t2 == t_char->type) ) or ( isrange(t1, "char") and (t2 == t_char->type or t2 == t_int->type) ) or ( t1->class == RANGE and isdouble(t1) and t2 == t_real->type ) or ( t1->class == RANGE and t2->class == RANGE and t1->symvalue.rangev.lower == t2->symvalue.rangev.lower and t1->symvalue.rangev.upper == t2->symvalue.rangev.upper ) or ( t1->type == t2->type and ( (t1->class == t2->class) or (t1->class == SCAL and t2->class == CONST) or (t1->class == CONST and t2->class == SCAL) ) ) or ( t1->class == PTR and c_typematch(t1->type, t_char) and t2->class == ARRAY and c_typematch(t2->type, t_char) /*and t2->language == primlang *lrm*/ ) or ( t1->class == ARRAY and c_typematch(t1->type, t_char) and t2->class == ARRAY and c_typematch(t2->type, t_char) /*and t2->language == primlang *lrm*/ ) or ( isrange(t1, "integer") and /* jlr004 */ (t2 == t_int->type or t2 == t_char->type) ) ); } return b;}/* * Print out the declaration of a C variable. */public c_printdecl(s)Symbol s;{ printdecl(s, 0);}private printdecl(s, indent)register Symbol s;Integer indent;{ register Symbol t; Boolean semicolon, newline; semicolon = true; newline = true; if (indent > 0) { printf("%*c", indent, ' '); } if (s->class == TYPE) { printf("typedef "); } switch (s->class) { case CONST: if (s->type->class == SCAL) { printf("enumeration constant with value "); eval(s->symvalue.constval); c_printval(s); } else { printf("const %s = ", symname(s)); printval(s); } break; case TYPE: case VAR: if (s->class != TYPE and s->level < 0) { printf("register "); } if (s->type->class == ARRAY) { printtype(s->type, s->type->type, indent); t = rtype(s->type->chain); assert(t->class == RANGE); printf(" %s[%d]", symname(s), t->symvalue.rangev.upper + 1); } else { printtype(s, s->type, indent); if (s->type->class != PTR) { printf(" "); } printf("%s", symname(s)); } break; case FIELD: if (s->type->class == ARRAY) { printtype(s->type, s->type->type, indent); t = rtype(s->type->chain); assert(t->class == RANGE); printf(" %s[%d]", symname(s), t->symvalue.rangev.upper + 1); } else { printtype(s, s->type, indent); if (s->type->class != PTR) { printf(" "); } printf("%s", symname(s)); } if (isbitfield(s)) { printf(" : %d", s->symvalue.field.length); } break; case TAG: if (s->type == nil) { findtype(s); if (s->type == nil) { error("unexpected missing type information"); } } printtype(s, s->type, indent); break; case RANGE: case ARRAY: case RECORD: case VARNT: case PTR: case FFUNC: semicolon = false; printtype(s, s, indent); break; case SCAL: printf("(enumeration constant, value %d)", s->symvalue.iconval); break; case PROC: semicolon = false; printf("%s", symname(s)); c_listparams(s); newline = false; break; case FUNC: semicolon = false; if (not istypename(s->type, "void")) { printtype(s, s->type, indent); printf(" "); } printf("%s", symname(s)); c_listparams(s); newline = false; break; case MODULE: semicolon = false; printf("source file \"%s.c\"", symname(s)); break; case PROG: semicolon = false; printf("executable file \"%s\"", symname(s)); break; default: printf("[%s]", classname(s)); break; } if (semicolon) { putchar(';'); } if (newline) { putchar('\n'); }}/* * Recursive whiz-bang procedure to print the type portion * of a declaration. * * The symbol associated with the type is passed to allow * searching for type names without getting "type blah = blah". */private printtype(s, t, indent)Symbol s;Symbol t;Integer indent;{ register Symbol i; long r0, r1; register String p; checkref(s); checkref(t); switch (t->class) { case VAR: case CONST: case PROC: panic("printtype: class %s", classname(t)); break; case ARRAY: printf("array["); i = t->chain; if (i != nil) { for (;;) { printtype(i, i, indent); i = i->chain; if (i == nil) { break; } printf(", "); } } printf("] of "); printtype(t, t->type, indent); break; case RECORD: case VARNT: printf("%s ", c_classname(t)); if (s->name != nil and s->class == TAG) { p = symname(s); if (p[0] == '$' and p[1] == '$') { printf("%s ", &p[2]); } else { printf("%s ", p); } } printf("{\n", t->class == RECORD ? "struct" : "union"); for (i = t->chain; i != nil; i = i->chain) { assert(i->class == FIELD); printdecl(i, indent+4); } if (indent > 0) { printf("%*c", indent, ' '); } printf("}"); break; case RANGE: r0 = t->symvalue.rangev.lower; r1 = t->symvalue.rangev.upper; if (istypename(t->type, "char")) { if (r0 < 0x20 or r0 > 0x7e) { printf("%ld..", r0); } else { printf("'%c'..", (char) r0); } if (r1 < 0x20 or r1 > 0x7e) { printf("\\%lo", r1); } else { printf("'%c'", (char) r1); } } else if (r0 > 0 and r1 == 0) { printf("%ld byte real", r0); } else if (r0 >= 0) { printf("%lu..%lu", r0, r1); } else { printf("%ld..%ld", r0, r1); } break; case PTR:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -