예제 #1
0
uint16_t expr_evaluate(struct expr* e, uint16_t(*labelreplace)(bstring label), void(*errexit)(int code, void* data))
{
	uint16_t t;

	switch (e->type)
	{
		case EXPR_NUMBER:
			return (uint16_t)(intptr_t)e->data;
		case EXPR_LABEL:
			if (labelreplace == NULL)
			{
				errexit(EXPR_EXIT_LABEL_NOT_FOUND, (bstring)e->data);
				return 0;
			}
			else
				return labelreplace((bstring)e->data);
		case EXPR_EXPR:
			switch (e->op)
			{
				case EXPR_OP_ADD:
					return recursive_evaluate(e->a) + recursive_evaluate(e->b);
				case EXPR_OP_SUBTRACT:
					return recursive_evaluate(e->a) - recursive_evaluate(e->b);
				case EXPR_OP_MULTIPLY:
					return recursive_evaluate(e->a) * recursive_evaluate(e->b);
				case EXPR_OP_DIVIDE:
					t = recursive_evaluate(e->b);
					if (t == 0)
						errexit(EXPR_EXIT_DIVIDE_BY_ZERO, expr_representation(e->b));
					return recursive_evaluate(e->a) / t;
				case EXPR_OP_MODULUS:
					t = recursive_evaluate(e->b);
					if (t == 0)
						errexit(EXPR_EXIT_DIVIDE_BY_ZERO, expr_representation(e->b));
					return recursive_evaluate(e->a) % t;
				case EXPR_OP_EQUALS:
					return recursive_evaluate(e->a) == recursive_evaluate(e->b);
				case EXPR_OP_NOT_EQUALS:
					return recursive_evaluate(e->a) != recursive_evaluate(e->b);
				case EXPR_OP_LESS_THAN:
					return recursive_evaluate(e->a) < recursive_evaluate(e->b);
				case EXPR_OP_LESS_EQUALS:
					return recursive_evaluate(e->a) <= recursive_evaluate(e->b);
				case EXPR_OP_GREATER_THAN:
					return recursive_evaluate(e->a) > recursive_evaluate(e->b);
				case EXPR_OP_GREATER_EQUALS:
					return recursive_evaluate(e->a) >= recursive_evaluate(e->b);
				case EXPR_OP_AND:
					return recursive_evaluate(e->a) & recursive_evaluate(e->b);
				case EXPR_OP_BOR:
					return recursive_evaluate(e->a) | recursive_evaluate(e->b);
				case EXPR_OP_XOR:
					return recursive_evaluate(e->a) ^ recursive_evaluate(e->b);
				default:
					return 0;
			}
		default:
			return 0;
	}
}
예제 #2
0
struct process_parameter_results process_address(struct ast_node_address* param)
{
	struct process_parameter_results result;
	struct register_mapping* registr;
	bstring btmp = NULL;
	result.v_raw = NULL;
	
	if (param->value != NULL)
		btmp = expr_representation(param->value);

	if (param->bracketed && param->added)
	{
		// This is of the form [0x1000+I].
		registr = get_register_by_name_next(param->addcmpt);

		if (registr == NULL)
		{
			// Attempt to use a label in brackets that can't be.
			fprintf(stderr, "\n");
			ahalt(ERR_NEXTED_LABEL_UNSUPPORTED, param->addcmpt);
		}
		else if (registr->value == VALUE_NEXT_UNSUPPORTED)
		{
			// Attempt to use a register in brackets that can't be.
			fprintf(stderr, "\n");
			ahalt(ERR_NEXTED_REGISTER_UNSUPPORTED, param->addcmpt);
		}

		fprintf(stderr, "[%s+%s]", btmp->data, registr->name);
		result.v = registr->value;
		result.v_extra = param->value;
		result.v_extra_used = true;
		result.v_label = NULL;
	}
	else
	{
		// This is either the form 0x1000 or [0x1000].
		if (param->bracketed)
		{
			fprintf(stderr, "[%s]", btmp->data);
			result.v = NXT;
		}
		else
		{
			fprintf(stderr, "%s", btmp->data);
			result.v = NXT_LIT;
		}

		result.v_extra = param->value;
		result.v_extra_used = true;
		result.v_label = NULL;
	}
	
	if (btmp != NULL)
		bdestroy(btmp);
	
	return result;
}
예제 #3
0
파일: assem.c 프로젝트: jathd/DCPUToolchain
struct process_parameter_results process_address(struct ast_node_address* param)
{
    struct process_parameter_results result;
    struct register_mapping* registr;
    bstring btmp = NULL;
    result.v_raw = NULL;

    if (param->value != NULL)
        btmp = expr_representation(param->value);

    if (param->bracketed && param->added)
    {
        // This is of the form [0x1000+I].
        registr = get_register_by_name_next(param->addcmpt);

        if (registr == NULL)
        {
            // Attempt to use a label in square brackets.  Convert this
            // to an expression and then reinvoke ourselves with the
            // evaluated value.
            param->value = expr_new(expr_new_label(bautofree(bfromcstr(param->addcmpt))), EXPR_OP_ADD, param->value);
            param->addcmpt = "";
            param->added = 0;
            param->bracketed = 0;

            bdestroy(btmp);
            return process_address(param);
        }
        else if (registr->value == VALUE_NEXT_UNSUPPORTED)
        {
            // Attempt to use a register in brackets that can't be.
            printd(LEVEL_VERBOSE, "\n");
            dhalt(ERR_NEXTED_REGISTER_UNSUPPORTED, param->addcmpt);
        }

        printd(LEVEL_VERBOSE, "[%s+%s]", btmp->data, registr->name);
        result.v = registr->value;
        result.v_extra = param->value;
        result.v_extra_used = true;
        result.v_label = NULL;
    }
    else
    {
        // This is either the form 0x1000 or [0x1000].
        if (param->bracketed)
        {
            printd(LEVEL_VERBOSE, "[%s]", btmp->data);
            result.v = NXT;
        }
        else
        {
            printd(LEVEL_VERBOSE, "%s", btmp->data);
            result.v = NXT_LIT;
        }

        result.v_extra = param->value;
        result.v_extra_used = true;
        result.v_label = NULL;
    }

    if (btmp != NULL)
        bdestroy(btmp);

    return result;
}
예제 #4
0
bstring expr_representation(struct expr* e)
{
	bstring a, b, op, result;
	switch (e->type)
	{
		case EXPR_NUMBER:
			return bformat("%u", (uint16_t)(intptr_t)e->data);
		case EXPR_LABEL:
			return bstrcpy((bstring)e->data);
		case EXPR_EXPR:
			a = expr_representation(e->a);
			b = expr_representation(e->b);
			switch (e->op)
			{
				case EXPR_OP_ADD:
					op = bfromcstr("+");
					break;
				case EXPR_OP_SUBTRACT:
					op = bfromcstr("-");
					break;
				case EXPR_OP_MULTIPLY:
					op = bfromcstr("*");
					break;
				case EXPR_OP_DIVIDE:
					op = bfromcstr("/");
					break;
				case EXPR_OP_MODULUS:
					op = bfromcstr("%");
					break;
				case EXPR_OP_EQUALS:
					op = bfromcstr("==");
					break;
				case EXPR_OP_NOT_EQUALS:
					op = bfromcstr("!=");
					break;
				case EXPR_OP_LESS_THAN:
					op = bfromcstr("<");
					break;
				case EXPR_OP_LESS_EQUALS:
					op = bfromcstr("<=");
					break;
				case EXPR_OP_GREATER_THAN:
					op = bfromcstr(">");
					break;
				case EXPR_OP_GREATER_EQUALS:
					op = bfromcstr(">=");
					break;
				case EXPR_OP_AND:
					op = bfromcstr("&");
					break;
				case EXPR_OP_BOR:
					op = bfromcstr("|");
					break;
				case EXPR_OP_XOR:
					op = bfromcstr("^");
					break;
				default:
					op = bfromcstr("???");
					break;
			}
			result = bfromcstr("");
			bconchar(result, '(');
			bconcat(result, a);
			bconchar(result, ' ');
			bconcat(result, op);
			bconchar(result, ' ');
			bconcat(result, b);
			bconchar(result, ')');
			bdestroy(a);
			bdestroy(b);
			bdestroy(op);
			return result;
		default:
			return bfromcstr("???");
	}
}