📄 eval.c
字号:
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 + -