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

📄 symbols.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
	case O_SYM:	    p->nodetype = namenode(p);	    break;	case O_LCON:	    p->nodetype = t_int;	    break;	case O_FCON:	    p->nodetype = t_real;	    break;	case O_SCON:	    p->value.scon = strdup(p->value.scon);	    s = mkstring(p->value.scon);	    if (s == t_char) {		p->op = O_LCON;		p->value.lcon = p->value.scon[0];	    }	    p->nodetype = s;	    break;	case O_INDIR:	    p1 = p->value.arg[0];	    chkclass(p1, PTR);	    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 == FUNC) {		    p->op = O_CALL;		    p->value.arg[1] = nil;		} else if (p1->value.sym->class == CONST) {		    if (compatible(p1->value.sym->type, t_real)) {			p->op = O_FCON;			p->value.fcon = p1->value.sym->symvalue.fconval;			p->nodetype = t_real;			dispose(p1);		    } else {			p->op = O_LCON;			p->value.lcon = p1->value.sym->symvalue.iconval;			p->nodetype = p1->value.sym->type;			dispose(p1);		    }		} 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;	/*	 * Perform a cast if the call is of the form "type(expr)".	 */	case O_CALL:	    p1 = p->value.arg[0];	    p->nodetype = rtype(p1->nodetype)->type;	    break;	case O_TYPERENAME:	    p->nodetype = p->value.arg[1]->nodetype;	    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 (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;    }}/* * Create a node for a name.  The symbol for the name has already * been chosen, either implicitly with "which" or explicitly from * the dot routine. */private Symbol namenode(p)Node p;{    register Symbol r, s;    register Node np;    s = p->value.sym;    if (s->class == REF) {	np = new(Node);	np->op = p->op;	np->nodetype = s;	np->value.sym = s;	p->op = O_INDIR;	p->value.arg[0] = np;    }/* * Old way *    if (s->class == CONST or s->class == VAR or s->class == FVAR) {	r = s->type;    } else {	r = s;    } * */    return s;}/* * 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 p;    register Symbol s, t;    if (isblock(record->nodetype)) {	find(s, fieldname) where	    s->block == record->nodetype and	    s->class != FIELD and s->class != TAG	endfind(s);	if (s == nil) {	    beginerrmsg();	    fprintf(stderr, "\"%s\" is not defined in ", ident(fieldname));	    printname(stderr, record->nodetype);	    enderrmsg();	}	p = new(Node);	p->op = O_SYM;	p->value.sym = s;	p->nodetype = namenode(p);    } else {	p = record;	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, record);	    enderrmsg();	}	if (t->class == PTR and not isreg(record->nodetype)) {	    p = build(O_INDIR, record);	}	p = build(O_DOT, p, build(O_SYM, s));    }    return p;}/* * Return a tree corresponding to an array reference and do the * error checking. */public Node subscript(a, slist)Node a, slist;{    Symbol t;    t = rtype(a->nodetype);    if (t->language == nil) {	error("unknown language");    } else {	return (Node) (*language_op(t->language, L_BUILDAREF))(a, slist);    }}/* * Evaluate a subscript index. */public int evalindex(s, i)Symbol s;long i;{    Symbol t;    t = rtype(s);    if (t->language == nil) {	error("unknown language");    } else {	return ((*language_op(t->language, L_EVALAREF)) (s, i));    }}/* * 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();    }}/* * Check to make sure the given tree has a type of the given class. */private chkclass(p, class)Node p;Symclass class;{    struct Symbol tmpsym;    tmpsym.class = class;    if (rtype(p->nodetype)->class != class) {	beginerrmsg();	fprintf(stderr, "\"");	prtree(stderr, p);	fprintf(stderr, "\" is not a %s", classname(&tmpsym));	enderrmsg();    }}/* * Construct a node for the type of a string. */private Symbol mkstring(str)String str;{    register char *p, *q;    register Symbol s;    integer len;    p = str;    q = str;    while (*p != '\0') {	if (*p == '\\') {	    ++p;	}	*q = *p;	++p;	++q;    }    *q = '\0';    len = p - str;    if (len == 1) {	s = t_char;    } else {	s = newSymbol(nil, 0, ARRAY, t_char, nil);	s->language = primlang;	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 = len + 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, * this is either the active one or the most visible from the * current scope. */public Symbol which(n)Name n;{    register Symbol s, p, t, f;    find(s, n) where s->class != FIELD and s->class != TAG endfind(s);    if (s == nil) {	s = lookup(n);    }    if (s == nil) {	error("\"%s\" is not defined", ident(n));    } else if (s == program or isbuiltin(s)) {	t = s;    } else {    /*     * Old way     *	if (not isactive(program)) {	    f = program;	} else {	    f = whatblock(pc);	    if (f == nil) {		panic("no block for addr 0x%x", pc);	    }	}     *     * Now start with curfunc.     */	p = curfunc;	do {	    find(t, n) where		t->block == p and t->class != FIELD and t->class != TAG	    endfind(t);	    p = p->block;	} while (t == nil and p != nil);	if (t == nil) {	    t = s;	}    }    return t;}/* * Find the symbol which is 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 + -