/* 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; }
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; }
/* Copying */ SCFraction* Fraction_copy(SCFraction* self) { return Fraction_new(self->numerator, self->denominator); }