Skip to content

Commit

Permalink
Add Float# abs, ceil, floor
Browse files Browse the repository at this point in the history
  • Loading branch information
SD10 committed Mar 17, 2018
1 parent 89a4c50 commit 8e425c1
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 1 deletion.
72 changes: 71 additions & 1 deletion vm/float.go
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,76 @@ func builtinFloatInstanceMethods() []*BuiltinMethodObject {
}
},
},
{
// Returns the Float as a positive value.
//
// ```Ruby
// -3.14.abs # => 3.14
// 3.14.abs # => 3.14
// ```
// @return [Float]
Name: "abs",
Fn: func(receiver Object, sourceLine int) builtinMethodBody {
return func(t *thread, args []Object, blockFrame *normalCallFrame) Object {
if len(args) != 0 {
return t.vm.initErrorObject(errors.ArgumentError, sourceLine, "Expect 0 argument. got=%v", strconv.Itoa(len(args)))
}
r := receiver.(*FloatObject)
result := math.Abs(r.value)
return t.vm.initFloatObject(result)
}
},
},
{
// Returns the smallest Integer greater than or equal to self.
//
// ```Ruby
// 1.2.ceil # => 2
// 2.ceil # => 2
// -1.2.ceil # => -1
// -2.ceil # => -2
// ```
// @return [Integer]
Name: "ceil",
Fn: func(receiver Object, sourceLine int) builtinMethodBody {
return func(t *thread, args []Object, blockFrame *normalCallFrame) Object {
// TODO: Make ceil accept arguments
if len(args) != 0 {
return t.vm.initErrorObject(errors.ArgumentError, sourceLine, "Expect 0 argument. got=%v", strconv.Itoa(len(args)))
}
r := receiver.(*FloatObject)
result := math.Ceil(r.value)
newInt := t.vm.initIntegerObject(int(result))
newInt.flag = i
return newInt
}
},
},
{
// Returns the largest Integer less than or equal to self.
//
// ```Ruby
// 1.2.floor # => 1
// 2.0.floor # => 2
// -1.2.floor # => -2
// -2.0.floor # => -2
// ```
// @return [Integer]
Name: "floor",
Fn: func(receiver Object, sourceLine int) builtinMethodBody {
return func(t *thread, args []Object, blockFrame *normalCallFrame) Object {
// TODO: Make floor accept arguments
if len(args) != 0 {
return t.vm.initErrorObject(errors.ArgumentError, sourceLine, "Expect 0 argument. got=%v", strconv.Itoa(len(args)))
}
r := receiver.(*FloatObject)
result := math.Floor(r.value)
newInt := t.vm.initIntegerObject(int(result))
newInt.flag = i
return newInt
}
},
},
}
}

Expand Down Expand Up @@ -453,4 +523,4 @@ func (f *FloatObject) toJSON(t *thread) string {
// equal checks if the Float values between receiver and argument are equal
func (f *FloatObject) equal(e *FloatObject) bool {
return f.value == e.value
}
}
58 changes: 58 additions & 0 deletions vm/float_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,3 +266,61 @@ func TestFloatZeroDivisionFail(t *testing.T) {
v.checkSP(t, i, 1)
}
}

func TestFloatAbs(t *testing.T) {
tests := []struct {
input string
expected interface{}
}{
{"34.56.abs", 34.56},
{"-34.56.abs", 34.56},
}

for i, tt := range tests {
v := initTestVM()
evaluated := v.testEval(t, tt.input, getFilename())
verifyExpected(t, i, evaluated, tt.expected)
v.checkCFP(t, i, 0)
v.checkSP(t, i, 1)
}
}

func TestFloatCeil(t *testing.T) {
tests := []struct {
input string
expected interface{}
}{
{"1.2.ceil", 2},
{"2.0.ceil", 2},
{"-1.2.ceil", -1},
{"-2.0.ceil", -2},
}

for i, tt := range tests {
v := initTestVM()
evaluated := v.testEval(t, tt.input, getFilename())
verifyExpected(t, i, evaluated, tt.expected)
v.checkCFP(t, i, 0)
v.checkSP(t, i, 1)
}
}

func TestFloatFloor(t *testing.T) {
tests := []struct {
input string
expected interface{}
}{
{"1.2.floor", 1},
{"2.0.floor", 2},
{"-1.2.floor", -2},
{"-2.0.floor", -2},
}

for i, tt := range tests {
v := initTestVM()
evaluated := v.testEval(t, tt.input, getFilename())
verifyExpected(t, i, evaluated, tt.expected)
v.checkCFP(t, i, 0)
v.checkSP(t, i, 1)
}
}

0 comments on commit 8e425c1

Please sign in to comment.