Skip to content

builtin: Implement builtin_bin #70

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 32 additions & 2 deletions builtin/builtin.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
package builtin

import (
"fmt"
"math/big"
"unicode/utf8"

"github.com/go-python/gpython/compile"
Expand All @@ -25,7 +27,7 @@ func init() {
py.MustNewMethod("all", builtin_all, 0, all_doc),
py.MustNewMethod("any", builtin_any, 0, any_doc),
py.MustNewMethod("ascii", builtin_ascii, 0, ascii_doc),
// py.MustNewMethod("bin", builtin_bin, 0, bin_doc),
py.MustNewMethod("bin", builtin_bin, 0, bin_doc),
// py.MustNewMethod("callable", builtin_callable, 0, callable_doc),
py.MustNewMethod("chr", builtin_chr, 0, chr_doc),
py.MustNewMethod("compile", builtin_compile, 0, compile_doc),
Expand Down Expand Up @@ -309,7 +311,12 @@ func builtin_any(self, seq py.Object) (py.Object, error) {
return py.False, nil
}

const ascii_doc = `
const ascii_doc = `Return an ASCII-only representation of an object.

As repr(), return a string containing a printable representation of an
object, but escape the non-ASCII characters in the string returned by
repr() using \\x, \\u or \\U escapes. This generates a string similar
to that returned by repr() in Python 2.
`

func builtin_ascii(self, o py.Object) (py.Object, error) {
Expand All @@ -322,6 +329,29 @@ func builtin_ascii(self, o py.Object) (py.Object, error) {
return py.String(out), err
}

const bin_doc = `Return the binary representation of an integer.

>>> bin(2796202)
'0b1010101010101010101010'
`

func builtin_bin(self, o py.Object) (py.Object, error) {
bigint, ok := py.ConvertToBigInt(o)
if !ok {
return nil, py.ExceptionNewf(py.TypeError, "'%s' object cannot be interpreted as an integer", o.Type().Name)
}

value := (*big.Int)(bigint)
var out string
if value.Sign() < 0 {
value = new(big.Int).Abs(value)
out = fmt.Sprintf("-0b%b", value)
} else {
out = fmt.Sprintf("0b%b", value)
}
return py.String(out), nil
}

const round_doc = `round(number[, ndigits]) -> number

Round a number to a given precision in decimal digits (default 0 digits).
Expand Down
13 changes: 13 additions & 0 deletions builtin/tests/builtin.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,19 @@
assert ascii(chr(0x10001)) == "'\\U00010001'"
assert ascii('안녕 gpython') == "'\\uc548\\ub155 gpython'"

doc="bin"
assert bin(False) == '0b0'
assert bin(True) == '0b1'
assert bin(0) == '0b0'
assert bin(1) == '0b1'
assert bin(-1) == '-0b1'
assert bin(10) == '0b1010'
assert bin(-10) == '-0b1010'
assert bin(2**32) == '0b100000000000000000000000000000000'
assert bin(2**32-1) == '0b11111111111111111111111111111111'
assert bin(-(2**32)) == '-0b100000000000000000000000000000000'
assert bin(-(2**32-1)) == '-0b11111111111111111111111111111111'

doc="chr"
assert chr(65) == "A"
assert chr(163) == "£"
Expand Down
48 changes: 24 additions & 24 deletions py/bigint.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func BigIntCheck(obj Object) (*BigInt, error) {
// Convert an Object to an BigInt
//
// Retrurns ok as to whether the conversion worked or not
func convertToBigInt(other Object) (*BigInt, bool) {
func ConvertToBigInt(other Object) (*BigInt, bool) {
switch b := other.(type) {
case Int:
return (*BigInt)(big.NewInt(int64(b))), true
Expand Down Expand Up @@ -173,7 +173,7 @@ func (a *BigInt) M__invert__() (Object, error) {
}

func (a *BigInt) M__add__(other Object) (Object, error) {
if b, ok := convertToBigInt(other); ok {
if b, ok := ConvertToBigInt(other); ok {
return (*BigInt)(new(big.Int).Add((*big.Int)(a), (*big.Int)(b))).MaybeInt(), nil
}
return NotImplemented, nil
Expand All @@ -188,14 +188,14 @@ func (a *BigInt) M__iadd__(other Object) (Object, error) {
}

func (a *BigInt) M__sub__(other Object) (Object, error) {
if b, ok := convertToBigInt(other); ok {
if b, ok := ConvertToBigInt(other); ok {
return (*BigInt)(new(big.Int).Sub((*big.Int)(a), (*big.Int)(b))).MaybeInt(), nil
}
return NotImplemented, nil
}

func (a *BigInt) M__rsub__(other Object) (Object, error) {
if b, ok := convertToBigInt(other); ok {
if b, ok := ConvertToBigInt(other); ok {
return (*BigInt)(new(big.Int).Sub((*big.Int)(b), (*big.Int)(a))).MaybeInt(), nil
}
return NotImplemented, nil
Expand All @@ -206,7 +206,7 @@ func (a *BigInt) M__isub__(other Object) (Object, error) {
}

func (a *BigInt) M__mul__(other Object) (Object, error) {
if b, ok := convertToBigInt(other); ok {
if b, ok := ConvertToBigInt(other); ok {
return (*BigInt)(new(big.Int).Mul((*big.Int)(a), (*big.Int)(b))).MaybeInt(), nil
}
return NotImplemented, nil
Expand Down Expand Up @@ -306,14 +306,14 @@ func (a *BigInt) divMod(b *BigInt) (Object, Object, error) {
}

func (a *BigInt) M__divmod__(other Object) (Object, Object, error) {
if b, ok := convertToBigInt(other); ok {
if b, ok := ConvertToBigInt(other); ok {
return a.divMod(b)
}
return NotImplemented, NotImplemented, nil
}

func (a *BigInt) M__rdivmod__(other Object) (Object, Object, error) {
if b, ok := convertToBigInt(other); ok {
if b, ok := ConvertToBigInt(other); ok {
return b.divMod(a)
}
return NotImplemented, NotImplemented, nil
Expand Down Expand Up @@ -343,18 +343,18 @@ func (a *BigInt) M__pow__(other, modulus Object) (Object, error) {
var m *BigInt
if modulus != None {
var ok bool
if m, ok = convertToBigInt(modulus); !ok {
if m, ok = ConvertToBigInt(modulus); !ok {
return NotImplemented, nil
}
}
if b, ok := convertToBigInt(other); ok {
if b, ok := ConvertToBigInt(other); ok {
return a.pow(b, m)
}
return NotImplemented, nil
}

func (a *BigInt) M__rpow__(other Object) (Object, error) {
if b, ok := convertToBigInt(other); ok {
if b, ok := ConvertToBigInt(other); ok {
return b.pow(a, nil)
}
return NotImplemented, nil
Expand All @@ -365,7 +365,7 @@ func (a *BigInt) M__ipow__(other, modulus Object) (Object, error) {
}

func (a *BigInt) M__lshift__(other Object) (Object, error) {
if b, ok := convertToBigInt(other); ok {
if b, ok := ConvertToBigInt(other); ok {
bb, err := b.GoInt()
if err != nil {
return nil, err
Expand All @@ -379,7 +379,7 @@ func (a *BigInt) M__lshift__(other Object) (Object, error) {
}

func (a *BigInt) M__rlshift__(other Object) (Object, error) {
if b, ok := convertToBigInt(other); ok {
if b, ok := ConvertToBigInt(other); ok {
aa, err := a.GoInt()
if err != nil {
return nil, err
Expand All @@ -397,7 +397,7 @@ func (a *BigInt) M__ilshift__(other Object) (Object, error) {
}

func (a *BigInt) M__rshift__(other Object) (Object, error) {
if b, ok := convertToBigInt(other); ok {
if b, ok := ConvertToBigInt(other); ok {
bb, err := b.GoInt()
if err != nil {
return nil, err
Expand All @@ -411,7 +411,7 @@ func (a *BigInt) M__rshift__(other Object) (Object, error) {
}

func (a *BigInt) M__rrshift__(other Object) (Object, error) {
if b, ok := convertToBigInt(other); ok {
if b, ok := ConvertToBigInt(other); ok {
aa, err := a.GoInt()
if err != nil {
return nil, err
Expand All @@ -429,7 +429,7 @@ func (a *BigInt) M__irshift__(other Object) (Object, error) {
}

func (a *BigInt) M__and__(other Object) (Object, error) {
if b, ok := convertToBigInt(other); ok {
if b, ok := ConvertToBigInt(other); ok {
return (*BigInt)(new(big.Int).And((*big.Int)(a), (*big.Int)(b))).MaybeInt(), nil
}
return NotImplemented, nil
Expand All @@ -444,7 +444,7 @@ func (a *BigInt) M__iand__(other Object) (Object, error) {
}

func (a *BigInt) M__xor__(other Object) (Object, error) {
if b, ok := convertToBigInt(other); ok {
if b, ok := ConvertToBigInt(other); ok {
return (*BigInt)(new(big.Int).Xor((*big.Int)(a), (*big.Int)(b))).MaybeInt(), nil
}
return NotImplemented, nil
Expand All @@ -459,7 +459,7 @@ func (a *BigInt) M__ixor__(other Object) (Object, error) {
}

func (a *BigInt) M__or__(other Object) (Object, error) {
if b, ok := convertToBigInt(other); ok {
if b, ok := ConvertToBigInt(other); ok {
return (*BigInt)(new(big.Int).Or((*big.Int)(a), (*big.Int)(b))).MaybeInt(), nil
}
return NotImplemented, nil
Expand Down Expand Up @@ -498,7 +498,7 @@ func (a *BigInt) M__complex__() (Object, error) {
}

func (a *BigInt) M__round__(digits Object) (Object, error) {
if b, ok := convertToBigInt(digits); ok {
if b, ok := ConvertToBigInt(digits); ok {
if (*big.Int)(b).Sign() >= 0 {
return a, nil
}
Expand Down Expand Up @@ -528,42 +528,42 @@ func (a *BigInt) M__round__(digits Object) (Object, error) {
// Rich comparison

func (a *BigInt) M__lt__(other Object) (Object, error) {
if b, ok := convertToBigInt(other); ok {
if b, ok := ConvertToBigInt(other); ok {
return NewBool((*big.Int)(a).Cmp((*big.Int)(b)) < 0), nil
}
return NotImplemented, nil
}

func (a *BigInt) M__le__(other Object) (Object, error) {
if b, ok := convertToBigInt(other); ok {
if b, ok := ConvertToBigInt(other); ok {
return NewBool((*big.Int)(a).Cmp((*big.Int)(b)) <= 0), nil
}
return NotImplemented, nil
}

func (a *BigInt) M__eq__(other Object) (Object, error) {
if b, ok := convertToBigInt(other); ok {
if b, ok := ConvertToBigInt(other); ok {
return NewBool((*big.Int)(a).Cmp((*big.Int)(b)) == 0), nil
}
return NotImplemented, nil
}

func (a *BigInt) M__ne__(other Object) (Object, error) {
if b, ok := convertToBigInt(other); ok {
if b, ok := ConvertToBigInt(other); ok {
return NewBool((*big.Int)(a).Cmp((*big.Int)(b)) != 0), nil
}
return NotImplemented, nil
}

func (a *BigInt) M__gt__(other Object) (Object, error) {
if b, ok := convertToBigInt(other); ok {
if b, ok := ConvertToBigInt(other); ok {
return NewBool((*big.Int)(a).Cmp((*big.Int)(b)) > 0), nil
}
return NotImplemented, nil
}

func (a *BigInt) M__ge__(other Object) (Object, error) {
if b, ok := convertToBigInt(other); ok {
if b, ok := ConvertToBigInt(other); ok {
return NewBool((*big.Int)(a).Cmp((*big.Int)(b)) >= 0), nil
}
return NotImplemented, nil
Expand Down
2 changes: 1 addition & 1 deletion version.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ var (
version = "dev"
commit = "none"
date = "unknown"
)
)