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

📄 eval.c

📁 开源的nasm编译器源码,研究编译器原理很有帮且
💻 C
📖 第 1 页 / 共 2 页
字号:
	return NULL;    while (i == '|')     {	i = scan(scpriv, tokval);	f = expr1(critical);	if (!f)	    return NULL;	if (!(is_simple(e) || is_just_unknown(e)) ||	    !(is_simple(f) || is_just_unknown(f))) 	{	    error(ERR_NONFATAL, "`|' operator may only be applied to"		  " scalar values");	}	if (is_just_unknown(e) || is_just_unknown(f))	    e = unknown_expr();	else	    e = scalarvect (reloc_value(e) | reloc_value(f));    }    return e;}static expr *expr1(int critical) {    expr *e, *f;    e = expr2(critical);    if (!e)	return NULL;    while (i == '^') {	i = scan(scpriv, tokval);	f = expr2(critical);	if (!f)	    return NULL;	if (!(is_simple(e) || is_just_unknown(e)) ||	    !(is_simple(f) || is_just_unknown(f))) 	{	    error(ERR_NONFATAL, "`^' operator may only be applied to"		  " scalar values");	}	if (is_just_unknown(e) || is_just_unknown(f))	    e = unknown_expr();	else	    e = scalarvect (reloc_value(e) ^ reloc_value(f));    }    return e;}static expr *expr2(int critical) {    expr *e, *f;    e = expr3(critical);    if (!e)	return NULL;    while (i == '&') {	i = scan(scpriv, tokval);	f = expr3(critical);	if (!f)	    return NULL;	if (!(is_simple(e) || is_just_unknown(e)) ||	    !(is_simple(f) || is_just_unknown(f))) 	{	    error(ERR_NONFATAL, "`&' operator may only be applied to"		  " scalar values");	}	if (is_just_unknown(e) || is_just_unknown(f))	    e = unknown_expr();	else	    e = scalarvect (reloc_value(e) & reloc_value(f));    }    return e;}static expr *expr3(int critical) {    expr *e, *f;    e = expr4(critical);    if (!e)	return NULL;    while (i == TOKEN_SHL || i == TOKEN_SHR)     {	int j = i;	i = scan(scpriv, tokval);	f = expr4(critical);	if (!f)	    return NULL;	if (!(is_simple(e) || is_just_unknown(e)) ||	    !(is_simple(f) || is_just_unknown(f))) 	{	    error(ERR_NONFATAL, "shift operator may only be applied to"		  " scalar values");	} else if (is_just_unknown(e) || is_just_unknown(f)) {	    e = unknown_expr();	} else switch (j) {	  case TOKEN_SHL:	    e = scalarvect (reloc_value(e) << reloc_value(f));	    break;	  case TOKEN_SHR:	    e = scalarvect (((unsigned long)reloc_value(e)) >>			    reloc_value(f));	    break;	}    }    return e;}static expr *expr4(int critical) {    expr *e, *f;    e = expr5(critical);    if (!e)	return NULL;    while (i == '+' || i == '-')     {	int j = i;	i = scan(scpriv, tokval);	f = expr5(critical);	if (!f)	    return NULL;	switch (j) {	  case '+':	    e = add_vectors (e, f);	    break;	  case '-':	    e = add_vectors (e, scalar_mult(f, -1L, FALSE));	    break;	}    }    return e;}static expr *expr5(int critical) {    expr *e, *f;    e = expr6(critical);    if (!e)	return NULL;    while (i == '*' || i == '/' || i == '%' ||	   i == TOKEN_SDIV || i == TOKEN_SMOD)     {	int j = i;	i = scan(scpriv, tokval);	f = expr6(critical);	if (!f)	    return NULL;	if (j != '*' && (!(is_simple(e) || is_just_unknown(e)) ||			 !(is_simple(f) || is_just_unknown(f)))) 	{	    error(ERR_NONFATAL, "division operator may only be applied to"		  " scalar values");	    return NULL;	}	if (j != '*' && !is_unknown(f) && reloc_value(f) == 0) {	    error(ERR_NONFATAL, "division by zero");	    return NULL;	}	switch (j) {	  case '*':	    if (is_simple(e))		e = scalar_mult (f, reloc_value(e), TRUE);	    else if (is_simple(f))		e = scalar_mult (e, reloc_value(f), TRUE);	    else if (is_just_unknown(e) && is_just_unknown(f))		e = unknown_expr();	    else {		error(ERR_NONFATAL, "unable to multiply two "		      "non-scalar objects");		return NULL;	    }	    break;	  case '/':	    if (is_just_unknown(e) || is_just_unknown(f))		e = unknown_expr();	    else		e = scalarvect (((unsigned long)reloc_value(e)) /				((unsigned long)reloc_value(f)));	    break;	  case '%':	    if (is_just_unknown(e) || is_just_unknown(f))		e = unknown_expr();	    else		e = scalarvect (((unsigned long)reloc_value(e)) %				((unsigned long)reloc_value(f)));	    break;	  case TOKEN_SDIV:	    if (is_just_unknown(e) || is_just_unknown(f))		e = unknown_expr();	    else		e = scalarvect (((signed long)reloc_value(e)) /				((signed long)reloc_value(f)));	    break;	  case TOKEN_SMOD:	    if (is_just_unknown(e) || is_just_unknown(f))		e = unknown_expr();	    else		e = scalarvect (((signed long)reloc_value(e)) %				((signed long)reloc_value(f)));	    break;	}    }    return e;}static expr *expr6(int critical) {    long type;    expr *e;    long label_seg, label_ofs;    if (i == '-') {	i = scan(scpriv, tokval);	e = expr6(critical);	if (!e)	    return NULL;	return scalar_mult (e, -1L, FALSE);    } else if (i == '+') {	i = scan(scpriv, tokval);	return expr6(critical);    } else if (i == '~') {	i = scan(scpriv, tokval);	e = expr6(critical);	if (!e)	    return NULL;	if (is_just_unknown(e))	    return unknown_expr();	else if (!is_simple(e)) {	    error(ERR_NONFATAL, "`~' operator may only be applied to"		  " scalar values");	    return NULL;	}	return scalarvect(~reloc_value(e));    } else if (i == TOKEN_SEG) {	i = scan(scpriv, tokval);	e = expr6(critical);	if (!e)	    return NULL;	e = segment_part(e);	if (!e)	    return NULL;	if (is_unknown(e) && critical) {	    error(ERR_NONFATAL, "unable to determine segment base");	    return NULL;	}	return e;    } else if (i == '(') {	i = scan(scpriv, tokval);	e = bexpr(critical);	if (!e)	    return NULL;	if (i != ')') {	    error(ERR_NONFATAL, "expecting `)'");	    return NULL;	}	i = scan(scpriv, tokval);	return e;    }     else if (i == TOKEN_NUM || i == TOKEN_REG || i == TOKEN_ID ||	     i == TOKEN_HERE || i == TOKEN_BASE)     {	begintemp();	switch (i) {	  case TOKEN_NUM:	    addtotemp(EXPR_SIMPLE, tokval->t_integer);	    break;	  case TOKEN_REG:	    addtotemp(tokval->t_integer, 1L);	    if (hint && hint->type == EAH_NOHINT)		hint->base = tokval->t_integer, hint->type = EAH_MAKEBASE;	    break;	  case TOKEN_ID:	  case TOKEN_HERE:	  case TOKEN_BASE:	    /*	     * If !location->known, this indicates that no	     * symbol, Here or Base references are valid because we	     * are in preprocess-only mode.	     */	    if (!location->known) {		error(ERR_NONFATAL,		      "%s not supported in preprocess-only mode",		      (i == TOKEN_ID ? "symbol references" :		       i == TOKEN_HERE ? "`$'" : "`$$'"));		addtotemp(EXPR_UNKNOWN, 1L);		break;	    }	    type = EXPR_SIMPLE;	       /* might get overridden by UNKNOWN */	    if (i == TOKEN_BASE)	    {		label_seg = in_abs_seg ? abs_seg : location->segment;		label_ofs = 0;	    } else if (i == TOKEN_HERE) {		label_seg = in_abs_seg ? abs_seg : location->segment;		label_ofs = in_abs_seg ? abs_offset : location->offset;	    } else {		if (!labelfunc(tokval->t_charptr,&label_seg,&label_ofs))		{		if (critical == 2) {		    error (ERR_NONFATAL, "symbol `%s' undefined",			   tokval->t_charptr);		    return NULL;		} else if (critical == 1) {			error (ERR_NONFATAL,				"symbol `%s' not defined before use",			   tokval->t_charptr);		    return NULL;		} else {		    if (opflags)			*opflags |= 1;		    type = EXPR_UNKNOWN;		    label_seg = NO_SEG;		    label_ofs = 1;		}	    }		if (opflags && is_extern (tokval->t_charptr))		    *opflags |= OPFLAG_EXTERN;	    }	    addtotemp(type, label_ofs);	    if (label_seg!=NO_SEG)		addtotemp(EXPR_SEGBASE + label_seg, 1L);	    break;	}	i = scan(scpriv, tokval);	return finishtemp();    } else {	error(ERR_NONFATAL, "expression syntax error");	return NULL;    }}void eval_global_info (struct ofmt *output, lfunc lookup_label, loc_t *locp) {    outfmt = output;    labelfunc = lookup_label;    location = locp;}expr *evaluate (scanner sc, void *scprivate, struct tokenval *tv,		int *fwref, int critical, efunc report_error,		struct eval_hints *hints) {    expr *e;    expr *f = NULL;    hint = hints;    if (hint)	hint->type = EAH_NOHINT;    if (critical & CRITICAL) {	critical &= ~CRITICAL;	bexpr = rexp0;    } else	bexpr = expr0;    scan = sc;    scpriv = scprivate;    tokval = tv;    error = report_error;    opflags = fwref;    if (tokval->t_type == TOKEN_INVALID)	i = scan(scpriv, tokval);    else	i = tokval->t_type;    while (ntempexprs)		       /* initialise temporary storage */	nasm_free (tempexprs[--ntempexprs]);    e = bexpr (critical);    if (!e)	return NULL;    if (i == TOKEN_WRT) {	i = scan(scpriv, tokval);      /* eat the WRT */	f = expr6 (critical);	if (!f)	    return NULL;    }    e = scalar_mult (e, 1L, FALSE);    /* strip far-absolute segment part */    if (f) {	expr *g;	if (is_just_unknown(f))	    g = unknown_expr();	else {	    long value;	    begintemp();	    if (!is_reloc(f)) {		error(ERR_NONFATAL, "invalid right-hand operand to WRT");		return NULL;	    }	    value = reloc_seg(f);	    if (value == NO_SEG)		value = reloc_value(f) | SEG_ABS;	    else if (!(value & SEG_ABS) && !(value % 2) && critical) 	    {		error(ERR_NONFATAL, "invalid right-hand operand to WRT");		return NULL;	    }	    addtotemp(EXPR_WRT, value);	    g = finishtemp();	}	e = add_vectors (e, g);    }    return e;}

⌨️ 快捷键说明

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