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

📄 sym.c

📁 计算机系统结构的讲义,浓缩了一本一千多页的书.真的是好东西.
💻 C
📖 第 1 页 / 共 2 页
字号:
 *	analysis or executing an embedded command.  In that case a *	standard Tcl error is returned, using machPtr->interp->result to hold *	an error message.  In the event of a successful return, the token *	and (possibly) number fields in infoPtr are updated to refer to *	the next symbol in the expression string, and the expr field is *	advanced. * * Side effects: *	None. * *---------------------------------------------------------------------- */static intLex(infoPtr)    register ExprInfo *infoPtr;		/* Describes the state of the parse. */{    register char *p, c;    /*     * The next token is either:     * (a)	A number (convert it from ASCII to binary).     * (b)	A symbol name (lookup the symbol).     * (c)	Space (skip it).     * (d)	An operator (see what kind it is).     */    p = infoPtr->expr;    infoPtr->tokenChars = p;    c = *p;    while (isspace(c)) {	p++;  c = *p;    }    infoPtr->expr = p;    if (!isascii(c)) {	infoPtr->token = END;	return TCL_OK;    }    if (c == '#') {	if (((*(p+1) == '-') && (!isdigit(*(p+2)))) ||            (!isdigit(*(p+1)) && (*(p+1) != '-'))) {	    return TCL_ERROR;	}	infoPtr->token = NUMBER;	infoPtr->number = strtol(p+1, &infoPtr->expr, 0);	return TCL_OK;    }    if (isdigit(c)) {	infoPtr->token = NUMBER;	infoPtr->number = strtol(p, &infoPtr->expr, 0);	return TCL_OK;    }    if (isalpha(c) || (c == '_')) {	char savedChar;	int result;	for (p++; isalnum(*p) || (*p == '_') || (*p == '$'); p++) {	    /* Null loop body;  just skip to end of symbol. */	}	savedChar = *p;	*p = 0;	result = Sym_GetSym(infoPtr->machPtr, infoPtr->fileName,		infoPtr->expr, 0, (unsigned int *) &infoPtr->number);	if (result == SYM_NOT_FOUND) {	    if (infoPtr->ignoreUndef) {		infoPtr->number = 0;	    } else {		sprintf(infoPtr->machPtr->interp->result,			"undefined symbol \"%.50s\"", infoPtr->expr);		*p = savedChar;		return TCL_ERROR;	    }	} else if (result == SYM_AMBIGUOUS) {	    sprintf(infoPtr->machPtr->interp->result,		    "symbol \"%.50s\" multiply defined", infoPtr->expr);	    *p = savedChar;	    return TCL_ERROR;	} else if (result == SYM_REG_NOT_OK) {	    sprintf(infoPtr->machPtr->interp->result,		    "can't use register name in expression");	    *p = savedChar;	    return TCL_ERROR;	}	infoPtr->token = NUMBER;	*p = savedChar;	infoPtr->expr = p;	return TCL_OK;    }    infoPtr->expr = p+1;    switch (c) {	case '(':	    infoPtr->token = OPEN_PAREN;	    return TCL_OK;	case ')':	    infoPtr->token = CLOSE_PAREN;	    return TCL_OK;	case '*':	    infoPtr->token = MULT;	    return TCL_OK;	case '/':	    infoPtr->token = DIVIDE;	    return TCL_OK;	case '%':	    infoPtr->token = MOD;	    return TCL_OK;	case '+':	    infoPtr->token = PLUS;	    return TCL_OK;	case '-':	    infoPtr->token = MINUS;	    return TCL_OK;	case '<':	    if (p[1] == '<') {		infoPtr->expr = p+2;		infoPtr->token = LEFT_SHIFT;	    } else {		infoPtr->token = END;	    }	    return TCL_OK;	case '>':	    if (p[1] == '>') {		infoPtr->expr = p+2;		infoPtr->token = RIGHT_SHIFT;	    } else {		infoPtr->token = END;	    }	    return TCL_OK;	case '&':	    infoPtr->token = BIT_AND;	    return TCL_OK;	case '^':	    infoPtr->token = BIT_XOR;	    return TCL_OK;	case '|':	    infoPtr->token = BIT_OR;	    return TCL_OK;	case '~':	    infoPtr->token = BIT_NOT;	    return TCL_OK;	case 0:	default:	    infoPtr->token = END;	    infoPtr->expr = p;	    return TCL_OK;    }}/* *---------------------------------------------------------------------- * * GetValue -- * *	Parse a "value" from the remainder of the expression in infoPtr. * * Results: *	Normally TCL_OK is returned.  The value of the parsed number is *	returned in infoPtr->number.  If an error occurred, then *	interp->result contains an error message and TCL_ERROR is returned. * * Side effects: *	Information gets parsed from the remaining expression, and the *	expr and token and tokenChars fields in infoPtr get updated. *	Information is parsed until either the end of the expression is *	reached (null character or close paren), an error occurs, or a *	binary operator is encountered with precedence <= prec.  In any *	of these cases, infoPtr->token will be left pointing to the token *	AFTER the expression. * *---------------------------------------------------------------------- */static intGetValue(infoPtr, prec)    register ExprInfo *infoPtr;		/* Describes the state of the parse					 * just before the value (i.e. Lex					 * will be called to get first token					 * of value). */    int prec;				/* Treat any un-parenthesized operator					 * with precedence <= this as the end					 * of the expression. */{    int result, operator, operand;    int gotOp;				/* Non-zero means already lexed the					 * operator (while picking up value					 * for unary operator).  Don't lex					 * again. */    char *savedPtr;    /*     * There are two phases to this procedure.  First, pick off an initial     * value.  Then, parse (binary operator, value) pairs until done.     */    gotOp = 0;    result = Lex(infoPtr);    if (result != TCL_OK) {	return result;    }    if (infoPtr->token == OPEN_PAREN) {	/*	 * Parenthesized sub-expression.	 */	result = GetValue(infoPtr, -1);	if (result != TCL_OK) {	    return result;	}	if (infoPtr->token != CLOSE_PAREN) {	    Tcl_Return(infoPtr->machPtr->interp, (char *) NULL, TCL_STATIC);	    sprintf(infoPtr->machPtr->interp->result,		    "unmatched parenthesis in expression");	    return TCL_ERROR;	}    } else {	if (infoPtr->token == MINUS) {	    infoPtr->token = UNARY_MINUS;	}	if (infoPtr->token >= UNARY_MINUS) {	    /*	     * Process unary operators.	     */	    operator = infoPtr->token;	    savedPtr = infoPtr->expr;	    result = GetValue(infoPtr, exprPrecTable[infoPtr->token]);	    if (result != TCL_OK) {		return result;	    }	    if (infoPtr->tokenChars == savedPtr) {		sprintf(infoPtr->machPtr->interp->result,			"missing value after operator in expression");		return TCL_ERROR;	    }	    switch (operator) {		case UNARY_MINUS:		    infoPtr->number = -infoPtr->number;		    break;		case BIT_NOT:		    infoPtr->number = ~infoPtr->number;		    break;	    }	    gotOp = 1;	} else if (infoPtr->token != NUMBER) {	    return TCL_OK;	}    }    /*     * Got the first operand.  Now fetch (operator, operand) pairs.     */    if (!gotOp) {	result = Lex(infoPtr);	if (result != TCL_OK) {	    return result;	}    }    while (1) {	operand = infoPtr->number;	operator = infoPtr->token;	if ((operator < MULT) || (operator >= UNARY_MINUS)) {	    return TCL_OK;	}	if (exprPrecTable[operator] <= prec) {	    return TCL_OK;	}	savedPtr = infoPtr->expr;	result = GetValue(infoPtr, exprPrecTable[operator]);	if (infoPtr->tokenChars == savedPtr) {	    sprintf(infoPtr->machPtr->interp->result,		    "missing value after operator in expression");	    return TCL_ERROR;	}	if (result != TCL_OK) {	    return result;	}	switch (operator) {	    case MULT:		infoPtr->number = operand * infoPtr->number;		break;	    case DIVIDE:		if (infoPtr->number == 0) {		    Tcl_Return(infoPtr->machPtr->interp,			    "divide by zero in expression", TCL_STATIC);		    return TCL_ERROR;	        }		infoPtr->number = operand / infoPtr->number;		break;	    case MOD:		if (infoPtr->number == 0) {		    Tcl_Return(infoPtr->machPtr->interp,			    "divide by zero in expression", TCL_STATIC);		    return TCL_ERROR;	        }		infoPtr->number = operand % infoPtr->number;		break;	    case PLUS:		infoPtr->number = operand + infoPtr->number;		break;	    case MINUS:		infoPtr->number = operand - infoPtr->number;		break;	    case LEFT_SHIFT:		infoPtr->number = operand << infoPtr->number;		break;	    case RIGHT_SHIFT:		infoPtr->number = operand >> infoPtr->number;		break;	    case BIT_AND:		infoPtr->number = operand & infoPtr->number;		break;	    case BIT_XOR:		infoPtr->number = operand ^ infoPtr->number;		break;	    case BIT_OR:		infoPtr->number = operand | infoPtr->number;		break;	}    }}/* *---------------------------------------------------------------------- * * Sym_EvalExpr -- * *	Given an expression including symbol names and constants, compute *	the value of the expression. * * Results: *	The result is a standard Tcl return value.  MachPtr's interp may *	get a result added to it also.  *valuePtr is modified to hold *	the value of the expression, and *endPtr is modified to point to *	the character that terminated the expression (i.e. the first *	character not in the expression).  If an error occurs, *endPtr *	is set to exprString. * * Side effects: *	None. * *---------------------------------------------------------------------- */intSym_EvalExpr(machPtr, fileName, exprString, ignoreUndef, valuePtr, endPtr)    DLX *machPtr;		/* Machine to manipulate. */    char *fileName;		/* Name of file to use for symbol lookup.				 * See declaration of Sym_GetSym arg for more				 * information. */    char *exprString;		/* Expression string to evaluate. */    int ignoreUndef;		/* Non-zero means treat undefined symbols				 * as having address 0. */    int *valuePtr;		/* Store the expression value here. */    char **endPtr;		/* Store address of terminating character				 * here. */{    ExprInfo info;    int result;    info.machPtr = machPtr;    info.fileName = fileName;    info.ignoreUndef = ignoreUndef;    info.expr = exprString;    result = GetValue(&info, -1);    if (result != TCL_OK) {	*valuePtr = 0;	*endPtr = exprString;	return result;    }    *valuePtr = info.number;    /*     * If the expression contained no information at all, then     * it's an error.     */    if (info.tokenChars == exprString) {	sprintf(machPtr->interp->result, "missing expression");	return TCL_ERROR;    }    /*     * Skip over blank space at the end of the expression.     */    while (isspace(*(info.tokenChars))) {	info.tokenChars++;    }    *endPtr = info.tokenChars;    return TCL_OK;}/* *---------------------------------------------------------------------- * * Sym_GetString -- * *	Given an address, return a string describing the address. * * Results: *	The return value is a textual description of address.  If *	possible, the address is identified symbolically (or with *	an offset).  In the worst case, it may simply be identified *	with a hex address. * * Side effects: *	None. * *---------------------------------------------------------------------- */char *Sym_GetString(machPtr, address)    DLX *machPtr;		/* Machine to manipulate. */    unsigned int address;	/* Address for which an identifying string				 * is returned. */{    Tcl_HashSearch search;    Tcl_HashEntry *hPtr;    register Sym *symPtr;    int distance, closestDistance;    char *closestName;    static char string[100];    closestDistance = 10000;    closestName = NULL;    for (hPtr = Tcl_FirstHashEntry(&machPtr->symbols, &search);	    hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {	for (symPtr = (Sym *) Tcl_GetHashValue(hPtr); symPtr != NULL;		symPtr = symPtr->nextPtr) {	    distance = address - symPtr->address;	    if ((distance < 0) || (distance >= closestDistance)) {		continue;	    }	    if (distance == 0) {		return hPtr->key.string;	    }	    closestDistance = distance;	    closestName = hPtr->key.string;	}    }    if (closestName == NULL) {	sprintf(string, "0x%x", address);    } else {	sprintf(string, "%.50s+0x%x", closestName, closestDistance);    }    return string;}

⌨️ 快捷键说明

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