Skip to content

Commit ad0e877

Browse files
committed
Add ceil(), floor() and round() function
Fixes #476
1 parent 281d598 commit ad0e877

File tree

4 files changed

+110
-0
lines changed

4 files changed

+110
-0
lines changed

Diff for: builtin/builtin.go

+42
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,48 @@ var Builtins = []*ast.Function{
126126
return anyType, fmt.Errorf("invalid argument for abs (type %s)", args[0])
127127
},
128128
},
129+
{
130+
Name: "ceil",
131+
Fast: Ceil,
132+
Validate: func(args []reflect.Type) (reflect.Type, error) {
133+
if len(args) != 1 {
134+
return anyType, fmt.Errorf("invalid number of arguments (expected 1, got %d)", len(args))
135+
}
136+
switch kind(args[0]) {
137+
case reflect.Float32, reflect.Float64, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Interface:
138+
return floatType, nil
139+
}
140+
return anyType, fmt.Errorf("invalid argument for ceil (type %s)", args[0])
141+
},
142+
},
143+
{
144+
Name: "floor",
145+
Fast: Floor,
146+
Validate: func(args []reflect.Type) (reflect.Type, error) {
147+
if len(args) != 1 {
148+
return anyType, fmt.Errorf("invalid number of arguments (expected 1, got %d)", len(args))
149+
}
150+
switch kind(args[0]) {
151+
case reflect.Float32, reflect.Float64, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Interface:
152+
return floatType, nil
153+
}
154+
return anyType, fmt.Errorf("invalid argument for floor (type %s)", args[0])
155+
},
156+
},
157+
{
158+
Name: "round",
159+
Fast: Round,
160+
Validate: func(args []reflect.Type) (reflect.Type, error) {
161+
if len(args) != 1 {
162+
return anyType, fmt.Errorf("invalid number of arguments (expected 1, got %d)", len(args))
163+
}
164+
switch kind(args[0]) {
165+
case reflect.Float32, reflect.Float64, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Interface:
166+
return floatType, nil
167+
}
168+
return anyType, fmt.Errorf("invalid argument for floor (type %s)", args[0])
169+
},
170+
},
129171
{
130172
Name: "int",
131173
Fast: Int,

Diff for: builtin/builtin_test.go

+7
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ func TestBuiltin(t *testing.T) {
3636
{`abs(-5)`, 5},
3737
{`abs(.5)`, .5},
3838
{`abs(-.5)`, .5},
39+
{`ceil(5.5)`, 6.0},
40+
{`ceil(5)`, 5.0},
41+
{`floor(5.5)`, 5.0},
42+
{`floor(5)`, 5.0},
43+
{`round(5.5)`, 6.0},
44+
{`round(5)`, 5.0},
45+
{`round(5.49)`, 5.0},
3946
{`int(5.5)`, 5},
4047
{`int(5)`, 5},
4148
{`int("5")`, 5},

Diff for: builtin/func.go

+37
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package builtin
22

33
import (
44
"fmt"
5+
"math"
56
"reflect"
67
"strconv"
78

@@ -138,6 +139,42 @@ func Abs(x any) any {
138139
panic(fmt.Sprintf("invalid argument for abs (type %T)", x))
139140
}
140141

142+
func Ceil(x any) any {
143+
switch x := x.(type) {
144+
case float32:
145+
return math.Ceil(float64(x))
146+
case float64:
147+
return math.Ceil(x)
148+
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
149+
return Float(x)
150+
}
151+
panic(fmt.Sprintf("invalid argument for ceil (type %T)", x))
152+
}
153+
154+
func Floor(x any) any {
155+
switch x := x.(type) {
156+
case float32:
157+
return math.Floor(float64(x))
158+
case float64:
159+
return math.Floor(x)
160+
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
161+
return Float(x)
162+
}
163+
panic(fmt.Sprintf("invalid argument for floor (type %T)", x))
164+
}
165+
166+
func Round(x any) any {
167+
switch x := x.(type) {
168+
case float32:
169+
return math.Round(float64(x))
170+
case float64:
171+
return math.Round(x)
172+
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
173+
return Float(x)
174+
}
175+
panic(fmt.Sprintf("invalid argument for round (type %T)", x))
176+
}
177+
141178
func Int(x any) any {
142179
switch x := x.(type) {
143180
case float32:

Diff for: docs/Language-Definition.md

+24
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,30 @@ min(5, 7) == 5
380380

381381
Returns the absolute value of a number.
382382

383+
### ceil(n)
384+
385+
Returns the least integer value greater than or equal to x.
386+
387+
```expr
388+
ceil(1.5) == 2.0
389+
```
390+
391+
### floor(n)
392+
393+
Returns the greatest integer value less than or equal to x.
394+
395+
```expr
396+
floor(1.5) == 1.0
397+
```
398+
399+
### round(n)
400+
401+
Returns the nearest integer, rounding half away from zero.
402+
403+
```expr
404+
round(1.5) == 2.0
405+
```
406+
383407
## Array Functions
384408

385409
### all(array, predicate)

0 commit comments

Comments
 (0)