Skip to content
This repository has been archived by the owner on Mar 23, 2023. It is now read-only.

Commit

Permalink
Add __builtin__.round (#240)
Browse files Browse the repository at this point in the history
  • Loading branch information
aisk authored and trotterdylan committed Feb 12, 2017
1 parent e20709c commit fe2a86a
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 6 deletions.
29 changes: 29 additions & 0 deletions runtime/builtin_types.go
Expand Up @@ -16,6 +16,7 @@ package grumpy

import (
"fmt"
"math"
"math/big"
"os"
"unicode"
Expand Down Expand Up @@ -570,6 +571,33 @@ func builtinRepr(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
return s.ToObject(), nil
}

func builtinRound(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
argc := len(args)
expectedTypes := []*Type{ObjectType, ObjectType}
if argc == 1 {
expectedTypes = expectedTypes[:1]
}
if raised := checkFunctionArgs(f, "round", args, expectedTypes...); raised != nil {
return nil, raised
}
ndigits := 0
if argc > 1 {
var raised *BaseException
if ndigits, raised = IndexInt(f, args[1]); raised != nil {
return nil, raised
}
}
// TODO: implement this.
if ndigits != 0 {
return nil, f.RaiseType(NotImplementedErrorType, "round with ndigits is not implemented in grumpy")
}
number, isFloat := floatCoerce(args[0])
if !isFloat {
return nil, f.RaiseType(TypeErrorType, "a float is required")
}
return NewFloat(math.Floor(number + 0.5)).ToObject(), nil
}

func builtinSetAttr(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
if raised := checkFunctionArgs(f, "setattr", args, ObjectType, StrType, ObjectType); raised != nil {
return nil, raised
Expand Down Expand Up @@ -667,6 +695,7 @@ func init() {
"print": newBuiltinFunction("print", builtinPrint).ToObject(),
"range": newBuiltinFunction("range", builtinRange).ToObject(),
"repr": newBuiltinFunction("repr", builtinRepr).ToObject(),
"round": newBuiltinFunction("round", builtinRound).ToObject(),
"setattr": newBuiltinFunction("setattr", builtinSetAttr).ToObject(),
"sorted": newBuiltinFunction("sorted", builtinSorted).ToObject(),
"True": True.ToObject(),
Expand Down
23 changes: 17 additions & 6 deletions runtime/builtin_types_test.go
Expand Up @@ -75,11 +75,6 @@ func TestBuiltinFuncs(t *testing.T) {
return NewStr("0octal").ToObject(), nil
}).ToObject(),
}))
indexType := newTestClass("Index", []*Type{ObjectType}, newStringDict(map[string]*Object{
"__index__": newBuiltinFunction("__index__", func(f *Frame, _ Args, _ KWArgs) (*Object, *BaseException) {
return NewInt(123).ToObject(), nil
}).ToObject(),
}))
badNonZeroType := newTestClass("BadNonZeroType", []*Type{ObjectType}, newStringDict(map[string]*Object{
"__nonzero__": newBuiltinFunction("__nonzero__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
return nil, f.RaiseType(RuntimeErrorType, "foo")
Expand Down Expand Up @@ -140,7 +135,7 @@ func TestBuiltinFuncs(t *testing.T) {
{f: "bin", args: wrapArgs("foo"), wantExc: mustCreateException(TypeErrorType, "str object cannot be interpreted as an index")},
{f: "bin", args: wrapArgs(0.1), wantExc: mustCreateException(TypeErrorType, "float object cannot be interpreted as an index")},
{f: "bin", args: wrapArgs(1, 2, 3), wantExc: mustCreateException(TypeErrorType, "'bin' requires 1 arguments")},
{f: "bin", args: wrapArgs(newObject(indexType)), want: NewStr("0b1111011").ToObject()},
{f: "bin", args: wrapArgs(newTestIndexObject(123)), want: NewStr("0b1111011").ToObject()},
{f: "callable", args: wrapArgs(fooBuiltinFunc), want: True.ToObject()},
{f: "callable", args: wrapArgs(fooFunc), want: True.ToObject()},
{f: "callable", args: wrapArgs(0), want: False.ToObject()},
Expand Down Expand Up @@ -275,6 +270,13 @@ func TestBuiltinFuncs(t *testing.T) {
{f: "repr", args: wrapArgs(NewUnicode("abc")), want: NewStr("u'abc'").ToObject()},
{f: "repr", args: wrapArgs(newTestTuple("foo", "bar")), want: NewStr("('foo', 'bar')").ToObject()},
{f: "repr", args: wrapArgs("a", "b", "c"), wantExc: mustCreateException(TypeErrorType, "'repr' requires 1 arguments")},
{f: "round", args: wrapArgs(1234.567), want: NewFloat(1235).ToObject()},
{f: "round", args: wrapArgs(1234.111), want: NewFloat(1234).ToObject()},
{f: "round", args: wrapArgs(-1234.567), want: NewFloat(-1235).ToObject()},
{f: "round", args: wrapArgs(-1234.111), want: NewFloat(-1234).ToObject()},
{f: "round", args: wrapArgs(1234.567, newTestIndexObject(0)), want: NewFloat(1235).ToObject()},
{f: "round", args: wrapArgs("foo"), wantExc: mustCreateException(TypeErrorType, "a float is required")},
{f: "round", args: wrapArgs(1234.5, 1), wantExc: mustCreateException(NotImplementedErrorType, "round with ndigits is not implemented in grumpy")},
{f: "sorted", args: wrapArgs(NewList()), want: NewList().ToObject()},
{f: "sorted", args: wrapArgs(newTestList("foo", "bar")), want: newTestList("bar", "foo").ToObject()},
{f: "sorted", args: wrapArgs(newTestList(true, false)), want: newTestList(false, true).ToObject()},
Expand Down Expand Up @@ -422,3 +424,12 @@ func TestBuiltinSetAttr(t *testing.T) {
}
}
}

func newTestIndexObject(index int) *Object {
indexType := newTestClass("Index", []*Type{ObjectType}, newStringDict(map[string]*Object{
"__index__": newBuiltinFunction("__index__", func(f *Frame, _ Args, _ KWArgs) (*Object, *BaseException) {
return NewInt(index).ToObject(), nil
}).ToObject(),
}))
return newObject(indexType)
}

0 comments on commit fe2a86a

Please sign in to comment.