Exemple #1
0
static AST ifstmt() {
    Token *t = &tok;
    AST a=0;
    AST a1=0,a2=0,a3=0;

    if (t->sym == tIF) {
	gettoken();
	if (t->sym == '(') {
	    gettoken();
	    a1 = bexpr();

	    if (t->sym == ')') gettoken();
	    else parse_error("expected )");

	    a2 = stmt();
	    if (t->sym == tELSE) {   /* else is optional */
		gettoken();
		a3 = stmt();
	    }
	} else {
	    parse_error("expected (");
	}
	a = make_AST_if(a1,a2,a3);
    } else {
	parse_error("expected if");
	skiptoken(';');
    }
    return a;
}
Exemple #2
0
expr *evaluate(scanner sc, void *scprivate, struct tokenval *tv,
               int *fwref, int critical, 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;
    opflags = fwref;

    if (tokval->t_type == TOKEN_INVALID)
        i = scan(scpriv, tokval);
    else
        i = tokval->t_type;

    while (ntempexprs)          /* initialize 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 {
            int64_t value;
            begintemp();
            if (!is_reloc(f)) {
                nasm_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) {
                nasm_error(ERR_NONFATAL, "invalid right-hand operand to WRT");
                return NULL;
            }
            addtotemp(EXPR_WRT, value);
            g = finishtemp();
        }
        e = add_vectors(e, g);
    }
    return e;
}
Exemple #3
0
static expr *expr6(int critical)
{
    int32_t type;
    expr *e;
    int32_t label_seg;
    int64_t label_ofs;
    int64_t tmpval;
    bool rn_warn;
    char *scope;

    switch (i) {
    case '-':
        i = scan(scpriv, tokval);
        e = expr6(critical);
        if (!e)
            return NULL;
        return scalar_mult(e, -1L, false);

    case '+':
        i = scan(scpriv, tokval);
        return expr6(critical);

    case '~':
        i = scan(scpriv, tokval);
        e = expr6(critical);
        if (!e)
            return NULL;
        if (is_just_unknown(e))
            return unknown_expr();
        else if (!is_simple(e)) {
            nasm_error(ERR_NONFATAL, "`~' operator may only be applied to"
                  " scalar values");
            return NULL;
        }
        return scalarvect(~reloc_value(e));

    case '!':
        i = scan(scpriv, tokval);
        e = expr6(critical);
        if (!e)
            return NULL;
        if (is_just_unknown(e))
            return unknown_expr();
        else if (!is_simple(e)) {
            nasm_error(ERR_NONFATAL, "`!' operator may only be applied to"
                  " scalar values");
            return NULL;
        }
        return scalarvect(!reloc_value(e));

    case TOKEN_IFUNC:
    {
        enum ifunc func = tokval->t_integer;
        i = scan(scpriv, tokval);
        e = expr6(critical);
        if (!e)
            return NULL;
        if (is_just_unknown(e))
            return unknown_expr();
        else if (!is_simple(e)) {
            nasm_error(ERR_NONFATAL, "function may only be applied to"
                  " scalar values");
            return NULL;
        }
        return scalarvect(eval_ifunc(reloc_value(e), func));
    }

    case 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) {
            nasm_error(ERR_NONFATAL, "unable to determine segment base");
            return NULL;
        }
        return e;

    case TOKEN_FLOATIZE:
        return eval_floatize(tokval->t_integer);

    case TOKEN_STRFUNC:
        return eval_strfunc(tokval->t_integer);

    case '(':
        i = scan(scpriv, tokval);
        e = bexpr(critical);
        if (!e)
            return NULL;
        if (i != ')') {
            nasm_error(ERR_NONFATAL, "expecting `)'");
            return NULL;
        }
        i = scan(scpriv, tokval);
        return e;

    case TOKEN_NUM:
    case TOKEN_STR:
    case TOKEN_REG:
    case TOKEN_ID:
    case TOKEN_INSN:            /* Opcodes that occur here are really labels */
    case TOKEN_HERE:
    case TOKEN_BASE:
    case TOKEN_DECORATOR:
        begintemp();
        switch (i) {
        case TOKEN_NUM:
            addtotemp(EXPR_SIMPLE, tokval->t_integer);
            break;
        case TOKEN_STR:
            tmpval = readstrnum(tokval->t_charptr, tokval->t_inttwo, &rn_warn);
            if (rn_warn)
                nasm_error(ERR_WARNING|ERR_PASS1, "character constant too long");
            addtotemp(EXPR_SIMPLE, tmpval);
            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_INSN:
        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) {
                nasm_error(ERR_NONFATAL,
                      "%s not supported in preprocess-only mode",
                      (i == TOKEN_HERE ? "`$'" :
                       i == TOKEN_BASE ? "`$$'" :
                       "symbol references"));
                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 (!lookup_label(tokval->t_charptr, &label_seg, &label_ofs)) {
                    scope = local_scope(tokval->t_charptr);
                    if (critical == 2) {
                        nasm_error(ERR_NONFATAL, "symbol `%s%s' undefined",
                              scope,tokval->t_charptr);
                        return NULL;
                    } else if (critical == 1) {
                        nasm_error(ERR_NONFATAL,
                              "symbol `%s%s' not defined before use",
                              scope,tokval->t_charptr);
                        return NULL;
                    } else {
                        if (opflags)
                            *opflags |= OPFLAG_FORWARD;
                        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;
        case TOKEN_DECORATOR:
            addtotemp(EXPR_RDSAE, tokval->t_integer);
            break;
        }
        i = scan(scpriv, tokval);
        return finishtemp();

    default:
        nasm_error(ERR_NONFATAL, "expression syntax error");
        return NULL;
    }
}