⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 symbols.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
			        			b = (boolean) (*language_op(t1->language, 														L_TYPEMATCH))(t1, t2);    		            	}							else {								b = false;							}    		            }			}    return b;}/* * Check for a type of the given name. */public Boolean istypename(type, name)Symbol type;String name;{    register Symbol t;    Boolean b;    t = type;    if (t == nil) {	b = false;    } else {	b = (Boolean) (	    t->class == TYPE and streq(ident(t->name), name)	);    }    return b;}/* * Determine if a (value) parameter should actually be passed by address. */public boolean passaddr (p, exprtype)Symbol p, exprtype;{    boolean b;    Language def;    if (p == nil) {	def = findlanguage(C);	b = (boolean) (*language_op(def, L_PASSADDR))(p, exprtype);    } else if (p->language == nil or p->language == primlang) {	b = false;    } else if (isopenarray(p->type)) {	b = true;    } else {	b = (boolean) (*language_op(p->language, L_PASSADDR))(p, exprtype);    }    return b;}/* * Test if the name of a symbol is uniquely defined or not. */public Boolean isambiguous(s)register Symbol s;{    register Symbol t;    find(t, s->name) where t != s endfind(t);    return (Boolean) (t != nil);}typedef char *Arglist;#define nextarg(type)  ((type *) (ap += sizeof(type)))[-1]private Symbol mkstring();/* * Determine the type of a parse tree. * * Also make some symbol-dependent changes to the tree such as * removing indirection for constant or register symbols. */public assigntypes (p)register Node p;{    register Node p1;    register Symbol s;    switch (p->op) {	case O_SYM:	    p->nodetype = p->value.sym;	    break;	case O_LCON:	    p->nodetype = t_int;	    break;	case O_CCON:	    p->nodetype = t_char;	    break;	case O_FCON:	    p->nodetype = t_real;	    break;	case O_SCON:	    p->nodetype = mkstring(p->value.scon);	    break;	case O_INDIR:	    p1 = p->value.arg[0];	    s = rtype(p1->nodetype);	    if (s->class != PTR) {		beginerrmsg();		fprintf(stderr, "\"");		prtree(stderr, p1);		fprintf(stderr, "\" is not a pointer");		enderrmsg();	    }	    p->nodetype = rtype(p1->nodetype)->type;	    break;	case O_DOT:	    p->nodetype = p->value.arg[1]->value.sym;	    break;	case O_RVAL:	    p1 = p->value.arg[0];	    p->nodetype = p1->nodetype;	    if (p1->op == O_SYM) {		if (p1->nodetype->class == PROC or p->nodetype->class == FUNC) {		    p->op = p1->op;		    p->value.sym = p1->value.sym;		    p->nodetype = p1->nodetype;		    dispose(p1);		} else if (p1->value.sym->class == CONST) {		    p->op = p1->op;		    p->value = p1->value;		    p->nodetype = p1->nodetype;		    dispose(p1);		} else if (isvreg(p1->value.sym)) {		    /* Start vector support */		    p->op = O_VREG;		    p->value.sym = p1->value.sym;		    dispose(p1);		    /* End vector support */		} else if (isreg(p1->value.sym)) {		    p->op = O_SYM;		    p->value.sym = p1->value.sym;		    dispose(p1);		}	    } else if (p1->op == O_INDIR and p1->value.arg[0]->op == O_SYM) {		s = p1->value.arg[0]->value.sym;		if (isreg(s)) {		    p1->op = O_SYM;		    dispose(p1->value.arg[0]);		    p1->value.sym = s;		    p1->nodetype = s;		}	    }	    break;	case O_COMMA:	    p->nodetype = p->value.arg[0]->nodetype;	    break;	case O_CALLPROC:	case O_CALL:	    p1 = p->value.arg[0];	    p->nodetype = rtype(p1->nodetype)->type;	    break;	case O_TYPERENAME:	    s = p->value.arg[1]->nodetype;	    /* Start vector Support */	    p1 = p->value.arg[0];	    if (p1->op == O_VREG) {	        /* Apply cast to an element of a vector register */	        if (size(s) == sizeof(Vquad)) {		    	s = newSymbol(p1->nodetype->name, 0, ARRAY, s, nil);		    	s->chain = rtype(p1->nodetype)->chain;			} else {		    	beginerrmsg();		    	fprintf(stderr, "\"");		    	prtree(stderr, p->value.arg[1]);		    	fprintf(stderr, "\" is improper type");		    	enderrmsg();			}	    }	    /* End vector Support */	    p->nodetype = s;	    break;	case O_ITOF:	    p->nodetype = t_real;	    break;	case O_NEG:	    s = p->value.arg[0]->nodetype;	    if (not compatible(s, t_int)) {		if (not compatible(s, t_real)) {		    beginerrmsg();		    fprintf(stderr, "\"");		    prtree(stderr, p->value.arg[0]);		    fprintf(stderr, "\" is improper type");		    enderrmsg();		} else {		    p->op = O_NEGF;		}	    }	    p->nodetype = s;	    break;	case O_ADD:	case O_SUB:	case O_MUL:	    binaryop(p, nil);	    break;	case O_LT:	case O_LE:	case O_GT:	case O_GE:	case O_EQ:	case O_NE:	    binaryop(p, t_boolean);	    break;	case O_DIVF:	    convert(&(p->value.arg[0]), t_real, O_ITOF);	    convert(&(p->value.arg[1]), t_real, O_ITOF);	    p->nodetype = t_real;	    break;	case O_DIV:	case O_MOD:	    convert(&(p->value.arg[0]), t_int, O_NOP);	    convert(&(p->value.arg[1]), t_int, O_NOP);	    p->nodetype = t_int;	    break;	case O_AND:	case O_OR:	    chkboolean(p->value.arg[0]);	    chkboolean(p->value.arg[1]);	    p->nodetype = t_boolean;	    break;	case O_QLINE:	    p->nodetype = t_int;	    break;	default:	    p->nodetype = nil;	    break;    }}/* * Process a binary arithmetic or relational operator. * Convert from integer to real if necessary. */private binaryop (p, t)Node p;Symbol t;{    Node p1, p2;    Boolean t1real, t2real;    Symbol t1, t2;    p1 = p->value.arg[0];    p2 = p->value.arg[1];    t1 = rtype(p1->nodetype);    t2 = rtype(p2->nodetype);    t1real = compatible(t1, t_real);    t2real = compatible(t2, t_real);    if (t1real or t2real) {	p->op = (Operator) (ord(p->op) + 1);	if (not t1real) {	    p->value.arg[0] = build(O_ITOF, p1);	} else if (not t2real) {	    p->value.arg[1] = build(O_ITOF, p2);	}	p->nodetype = t_real;    } else {        if (t != nil and p1->op == O_SCON) {	    beginerrmsg();	    fprintf(stderr, "operation not defined on a string constant (");	    prtree(stderr, p1);	    fprintf(stderr, ")");	    enderrmsg();        } else if (t != nil and p2->op == O_SCON) {	    beginerrmsg();	    fprintf(stderr, "operation not defined on a string constant (");	    prtree(stderr, p2);	    fprintf(stderr, ")");	    enderrmsg();	} else if (size(p1->nodetype) > sizeof(integer)) {	    beginerrmsg();	    fprintf(stderr, "operation not defined on \"");	    prtree(stderr, p1);	    fprintf(stderr, "\"");	    enderrmsg();	} else if (size(p2->nodetype) > sizeof(integer)) {	    beginerrmsg();	    fprintf(stderr, "operation not defined on \"");	    prtree(stderr, p2);	    fprintf(stderr, "\"");	    enderrmsg();	}	p->nodetype = t_int;    }    if (t != nil) {	p->nodetype = t;    }}/* * Convert a tree to a type via a conversion operator; * if this isn't possible generate an error. * * Note the tree is call by address, hence the #define below. */private convert(tp, typeto, op)Node *tp;Symbol typeto;Operator op;{    Node tree;    Symbol s, t;    tree = *tp;    s = rtype(tree->nodetype);    t = rtype(typeto);    if (compatible(t, t_real) and compatible(s, t_int)) {	tree = build(op, tree);    } else if (not compatible(s, t)) {	beginerrmsg();	fprintf(stderr, "expected integer or real, found \"");	prtree(stderr, tree);	fprintf(stderr, "\"");	enderrmsg();    } else if (op != O_NOP and s != t) {	tree = build(op, tree);    }    *tp = tree;}/* * Construct a node for the dot operator. * * If the left operand is not a record, but rather a procedure * or function, then we interpret the "." as referencing an * "invisible" variable; i.e. a variable within a dynamically * active block but not within the static scope of the current procedure. */public Node dot(record, fieldname)Node record;Name fieldname;{    register Node rec, p;    register Symbol s, t;    rec = record;    if (isblock(rec->nodetype)) {	find(s, fieldname) where	    s->block == rec->nodetype and	    s->class != FIELD	endfind(s);	if (s == nil) {	    beginerrmsg();	    fprintf(stderr, "\"%s\" is not defined in ", ident(fieldname));	    printname(stderr, rec->nodetype);	    enderrmsg();	}	p = new(Node);	p->op = O_SYM;	p->value.sym = s;	p->nodetype = s;    } else {	p = rec;	t = rtype(p->nodetype);	if (t->class == PTR) {	    s = findfield(fieldname, t->type);	} else {	    s = findfield(fieldname, t);	}	if (s == nil) {	    beginerrmsg();	    fprintf(stderr, "\"%s\" is not a field in ", ident(fieldname));	    prtree(stderr, rec);	    enderrmsg();	}	if (t->class != PTR or isreg(rec->nodetype)) {	    p = unrval(p);	}	p->nodetype = t_addr;	p = build(O_DOT, p, build(O_SYM, s));    }    return build(O_RVAL, p);}/* * Return a tree corresponding to an array reference and do the * error checking. */public Node subscript(a, slist)Node a, slist;{    Symbol t;    Node p;    t = rtype(a->nodetype);    if (t->language == nil or t->language == primlang) {	p = (Node) (*language_op(findlanguage(ASSEMBLER), L_BUILDAREF))(a, slist);    } else {	p = (Node) (*language_op(t->language, L_BUILDAREF))(a, slist);    }    return build(O_RVAL, p);}/* * Evaluate a subscript index. */public int evalindex(s, base, i)Symbol s;Address base;long i;{    Symbol t;    int r;    t = rtype(s);    if (t->language == nil or t->language == primlang) {	r = ((*language_op(findlanguage(ASSEMBLER), L_EVALAREF)) (s, base, i));    } else {	r = ((*language_op(t->language, L_EVALAREF)) (s, base, i));    }    return r;}/* * Check to see if a tree is boolean-valued, if not it's an error. */public chkboolean(p)register Node p;{    if (p->nodetype != t_boolean) {	beginerrmsg();	fprintf(stderr, "found ");	prtree(stderr, p);	fprintf(stderr, ", expected boolean expression");	enderrmsg();    }}/* * Construct a node for the type of a string. */private Symbol mkstring(str)String str;{    register Symbol s;    s = newSymbol(nil, 0, ARRAY, t_char, nil);    s->chain = newSymbol(nil, 0, RANGE, t_int, nil);    s->chain->language = s->language;    s->chain->symvalue.rangev.lower = 1;    s->chain->symvalue.rangev.upper = strlen(str) + 1;    return s;}/* * Free up the space allocated for a string type. */public unmkstring(s)Symbol s;{    dispose(s->chain);}/* * Figure out the "current" variable or function being referred to * by the name n. */private boolean stwhich(), dynwhich();public Symbol which (n)Name n;{    Symbol s;/* RBN 3-28-90 * RBN 3-28-90 * RBN 3-28-90 * RBN 3-28-90 * RBN 3-28-90 */    Char oldid[81];    register Char *oid, *p;    s = lookup(n);    if (s == nil) {        p = n->identifier;      /* store original identifier in oldid */        oid = oldid;        while (*oid++ = *p++);        p = oldid;            /* convert identifier to all lower-case */        while (*p != '\0') {            if (*p >= 'A' and *p <= 'Z') {                *p = *p + 'a' - 'A';            }            ++p;        }        s = lookup(identname(oldid, true));           /* search again */        if (s == nil) {            p = oldid;        /* convert identifier to all UPPER-case */            while (*p != '\0') {                if (*p >= 'a' and *p <= 'z') {                    *p = *p - 'a' + 'A';                }                ++p;            }            s = lookup(identname(oldid, true));          /* once more */            if (s == nil) {                error("\"%s\" is not defined", n->identifier);            }        }    }/* RBN 3-28-90 * RBN 3-28-90 * RBN 3-28-90 * RBN 3-28-90 * RBN 3-28-90 */    if(isvreg(s))        return s;    if (not stwhich(&s) and isambiguous(s) and not dynwhich(&s)) {        printf("[using ");        printname(stdout, s);        printf("]\n");    }    if (no_dstmap(s)) {        error("symbolic information not available for symbol \"%s\"",        symname(s));    }    return s;}/* * Static search. */private boolean stwhich (var_s)Symbol *var_s;{    Name n;		/* name of desired symbol */    Symbol s;		/* iteration variable for symbols with name n */    Symbol f;		/* iteration variable for blocks containing s */    integer count;	/* number of levels from s->block to curfunc */    Symbol t;		/* current best answer for stwhich(n) */    integer mincount;	/* relative level for current best answer (t) */    boolean b;		/* return value, true if symbol found */    s = *var_s;    n = s->name;    t = s;    mincount = 10000; /* force first match to set mincount */    do {	if (s->name == n and s->class != FIELD and s->class != TAG) {	    f = curfunc;	    count = 0;	    while (f != nil and f != s->block) {		++count;		f = f->block;	    }	    if (f != nil and count < mincount) {		t = s;		mincount = count;		b = true;	    }	}	s = s->next_sym;    } while (s != nil);    if (mincount != 10000) {	*var_s = t;	b = true;    } else {	b = false;    }    return b;}/* * Dynamic search. */private boolean dynwhich (var_s)Symbol *var_s;{    Name n;		/* name of desired symbol */    Symbol s;		/* iteration variable for possible symbols */    Symbol f;		/* iteration variable for active functions */    Frame frp;		/* frame associated with stack walk */    boolean b;		/* return value */    f = curfunc;    frp = curfuncframe();    n = (*var_s)->name;    b = false;    if (frp != nil) {	frp = nextfunc(frp, &f);	while (frp != nil) {	    s = *var_s;	    while (s != nil and		(		    s->name != n or s->block != f or		    s->class == FIELD or s->class == TAG		)	    ) {		s = s->next_sym;	    }	    if (s != nil) {		*var_s = s;		b = true;		break;	    }	    if (f == program) {		break;	    }	    frp = nextfunc(frp, &f);	}    }    return b;}/* * Find the symbol that has the same name and scope as the * given symbol but is of the given field.  Return nil if there is none. */public Symbol findfield (fieldname, record)Name fieldname;Symbol record;{    register Symbol t;    t = rtype(record)->chain;    while (t != nil and t->name != fieldname) {	t = t->chain;    }    return t;}public Boolean getbound(s,off,type,valp)Symbol s;int off;Rangetype type;int *valp;{    Frame frp;    Address addr;    Symbol cur;    if (not isactive(s->block)) {	return(false);    }    cur = s->block;    while (cur != nil and cur->class == MODULE) {  /* WHY*/    		cur = cur->block;    }    if(cur == nil) {		cur = whatblock(pc);    }    frp = findframe(cur);    if (frp == nil) {	return(false);    }    if(type == R_TEMP) addr = locals_base(frp) + off;    else if (type == R_ARG) addr = args_base(frp) + off;    else return(false);    dread(valp,addr,sizeof(long));    return(true);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -