Example #1
0
	bool token::is_stack_operation(stack_operation operation) const {
		if (is_stack_operation()) {
			return get_stack_operation() == operation;
		}

		return false;
	}
Example #2
0
dcpu16operand parseoperand(list *labels) {
    dcpu16operand op = {0};
    dcpu16token tok;

    op.addressing = IMMEDIATE;

    if ((tok = nexttoken()) == T_IDENTIFIER) {
        /* label */
        op.type = LABEL;
        op.label = getnewlabel(labels, cur_tok.string)->label;
    } else if (tok == T_NUMBER) {
        /* numeric */
        op.type = LITERAL;
        op.numeric = cur_tok.number;
    } else if (is_register(tok) || is_status_register(tok)
                                || is_stack_operation(tok)) {
        /* register */

        /* 
         * For all intents and purposes, stack operations, registers and
         * status registers are equivalent in usage for immediate addressing,
         * so we might as well classify them all as REGISTER
         */
        op.type = REGISTER;
        op.token = tok;
    } else if (tok == T_LBRACK) {
        /* [reference] */
        dcpu16token a = nexttoken();

        op.addressing = REFERENCE;

        if (a == T_NUMBER) {
            /* [numeric] */
            op.type = LITERAL;
            op.numeric = cur_tok.number;
        } else if (is_register(a)) {
            /* [register] */
            op.type = REGISTER;
            op.token = a;
        } else if (a == T_IDENTIFIER) {
            /* [label] */
            op.type = LABEL;
            op.label = getnewlabel(labels, cur_tok.string)->label;
        } else {
            error("Expected numeric, register or label, got %s", toktostr(a));
        }

        /* First part parsed correctly so far, now either ']' or '+'
         * follows */
        if (((tok = nexttoken()) != T_RBRACK) && (tok != T_PLUS))
            error("Expected '+' or ']', got %s", toktostr(tok));

        if (tok == T_RBRACK) {
            /* [numeric], [register], [label] checks out */
            return op;
        } else {
            dcpu16token b = nexttoken();

            op.type = REGISTER_OFFSET;

            if (is_register(a)) {
                /* [register + label], [register + numeric] */
                if (b == T_IDENTIFIER) {
                    op.register_offset.type = LABEL;
                    op.register_offset.register_index = a;
                    op.register_offset.label =
                        getnewlabel(labels, cur_tok.string)->label;

                } else if (b == T_NUMBER) {
                    op.register_offset.type = LITERAL;
                    op.register_offset.register_index = a;
                    op.register_offset.offset = cur_tok.number;

                } else {
                    error("Expected numeric or label, got %s", toktostr(b));
                }
            } else {
                /* [numeric + register], [label + register] */
                if (is_register(b)) {
                    op.register_offset.register_index = b;

                    if (a == T_NUMBER) {
                        op.register_offset.type = LITERAL;
                        op.register_offset.offset = cur_tok.number;
                    } else {
                        op.register_offset.type = LABEL;
                        op.register_offset.label =
                            getnewlabel(labels, cur_tok.string)->label;
                    }
                } else  {
                    error("Expected register, got %s", toktostr(b));
                }
            }

            if (nexttoken() != T_RBRACK)
                error("Expected ']'");
        }
    } else {
        error("Expected register, label, numeric or '[', got %s",
                toktostr(tok));
    }

    return op;
}