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

📄 eval.c

📁 一个免费的汇编语言编译器的源代码
💻 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 + -