Example #1
0
/* Arithmetic */
SCValue* Fraction_add(SCFraction* self, SCValue* other) {
    SCValue* ret;
    switch (other->type) {
        case kValueFraction:
        {
            SCNumber numerator = self->numerator * other->fraction->denominator + self->denominator * other->fraction->numerator;
            SCNumber denominator = self->denominator * other->fraction->denominator;
            ret = ValFrac(Fraction_new(numerator, denominator));
            break;
        }
        case kValueInteger:
        {
            SCNumber numerator = self->numerator + other->integer * self->denominator;
            SCNumber denominator = self->denominator;
            ret = ValFrac(Fraction_new(numerator, denominator));
            break;
        }
        case kValueReal:
        {
            ret = ValReal(Fraction_asReal(self) + other->real);
            break;
        }
        default:
            return ValErr(nonArithType(other->type));
            break;
    }
    return ret;
}
Example #2
0
static Value* eval_abs(const Context* ctx, const ArgList* arglist, bool internal) {
	if(arglist->count != 1) {
		return ValErr(builtinArgs("abs", 1, arglist->count));
	}
	
	Value* val = Value_coerce(arglist->args[0], ctx);
	if(val->type == VAL_ERR) {
		return val;
	}
	
	Value* ret;
	switch(val->type) {
		case VAL_INT:
			ret = ValInt(ABS(val->ival));
			break;
		
		case VAL_REAL:
			ret = ValReal(ABS(val->rval));
			break;
		
		case VAL_FRAC:
			ret = ValFrac(Fraction_new(ABS(val->frac->n), val->frac->d));
			break;
			
		case VAL_VEC:
			ret = Vector_magnitude(val->vec, ctx);
			break;
		
		default:
			badValType(val->type);
	}
	
	Value_free(val);
	return ret;
}
Example #3
0
SCValue* Fraction_eval(SCFraction* self) {
    SCFraction* frac = Fraction_copy(self);
    Fraction_simplify(frac);
    SCValue* ret;
    if (frac->denominator == 1) {
        ret = ValInt(frac->numerator);
        Fraction_free(frac);
    } else {
        ret = ValFrac(frac);
    }
    return ret;
}
Example #4
0
Value* Value_copy(const Value* val) {
	Value* ret;
	
	switch(val->type) {
		case VAL_INT:
			ret = ValInt(val->ival);
			break;
		
		case VAL_REAL:
			ret = ValReal(val->rval);
			break;
		
		case VAL_FRAC:
			ret = ValFrac(Fraction_copy(val->frac));
			break;
		
		case VAL_EXPR:
			ret = ValExpr(BinOp_copy(val->expr));
			break;
		
		case VAL_CALL:
			ret = ValCall(FuncCall_copy(val->call));
			break;
		
		case VAL_UNARY:
			ret = ValUnary(UnOp_copy(val->term));
			break;
		
		case VAL_VAR:
			ret = ValVar(val->name);
			break;
		
		case VAL_VEC:
			ret = ValVec(Vector_copy(val->vec));
			break;
		
		case VAL_NEG:
			/* Shouldn't be reached, but so easy to code */
			ret = ValNeg();
			break;
		
		case VAL_ERR:
			ret = ValErr(Error_copy(val->err));
			break;
		
		default:
			typeError("Unknown value type: %d.", val->type);
			ret = NULL;
			break;
	}
	
	return ret;
}