Skip to content

Commit 7bc4005

Browse files
authored
builtin: Implement builtin_bin (#70)
1 parent fff175c commit 7bc4005

File tree

4 files changed

+70
-27
lines changed

4 files changed

+70
-27
lines changed

builtin/builtin.go

+32-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
package builtin
77

88
import (
9+
"fmt"
10+
"math/big"
911
"unicode/utf8"
1012

1113
"github.com/go-python/gpython/compile"
@@ -25,7 +27,7 @@ func init() {
2527
py.MustNewMethod("all", builtin_all, 0, all_doc),
2628
py.MustNewMethod("any", builtin_any, 0, any_doc),
2729
py.MustNewMethod("ascii", builtin_ascii, 0, ascii_doc),
28-
// py.MustNewMethod("bin", builtin_bin, 0, bin_doc),
30+
py.MustNewMethod("bin", builtin_bin, 0, bin_doc),
2931
// py.MustNewMethod("callable", builtin_callable, 0, callable_doc),
3032
py.MustNewMethod("chr", builtin_chr, 0, chr_doc),
3133
py.MustNewMethod("compile", builtin_compile, 0, compile_doc),
@@ -309,7 +311,12 @@ func builtin_any(self, seq py.Object) (py.Object, error) {
309311
return py.False, nil
310312
}
311313

312-
const ascii_doc = `
314+
const ascii_doc = `Return an ASCII-only representation of an object.
315+
316+
As repr(), return a string containing a printable representation of an
317+
object, but escape the non-ASCII characters in the string returned by
318+
repr() using \\x, \\u or \\U escapes. This generates a string similar
319+
to that returned by repr() in Python 2.
313320
`
314321

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

332+
const bin_doc = `Return the binary representation of an integer.
333+
334+
>>> bin(2796202)
335+
'0b1010101010101010101010'
336+
`
337+
338+
func builtin_bin(self, o py.Object) (py.Object, error) {
339+
bigint, ok := py.ConvertToBigInt(o)
340+
if !ok {
341+
return nil, py.ExceptionNewf(py.TypeError, "'%s' object cannot be interpreted as an integer", o.Type().Name)
342+
}
343+
344+
value := (*big.Int)(bigint)
345+
var out string
346+
if value.Sign() < 0 {
347+
value = new(big.Int).Abs(value)
348+
out = fmt.Sprintf("-0b%b", value)
349+
} else {
350+
out = fmt.Sprintf("0b%b", value)
351+
}
352+
return py.String(out), nil
353+
}
354+
325355
const round_doc = `round(number[, ndigits]) -> number
326356
327357
Round a number to a given precision in decimal digits (default 0 digits).

builtin/tests/builtin.py

+13
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,19 @@
2525
assert ascii(chr(0x10001)) == "'\\U00010001'"
2626
assert ascii('안녕 gpython') == "'\\uc548\\ub155 gpython'"
2727

28+
doc="bin"
29+
assert bin(False) == '0b0'
30+
assert bin(True) == '0b1'
31+
assert bin(0) == '0b0'
32+
assert bin(1) == '0b1'
33+
assert bin(-1) == '-0b1'
34+
assert bin(10) == '0b1010'
35+
assert bin(-10) == '-0b1010'
36+
assert bin(2**32) == '0b100000000000000000000000000000000'
37+
assert bin(2**32-1) == '0b11111111111111111111111111111111'
38+
assert bin(-(2**32)) == '-0b100000000000000000000000000000000'
39+
assert bin(-(2**32-1)) == '-0b11111111111111111111111111111111'
40+
2841
doc="chr"
2942
assert chr(65) == "A"
3043
assert chr(163) == "£"

py/bigint.go

+24-24
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ func BigIntCheck(obj Object) (*BigInt, error) {
6666
// Convert an Object to an BigInt
6767
//
6868
// Retrurns ok as to whether the conversion worked or not
69-
func convertToBigInt(other Object) (*BigInt, bool) {
69+
func ConvertToBigInt(other Object) (*BigInt, bool) {
7070
switch b := other.(type) {
7171
case Int:
7272
return (*BigInt)(big.NewInt(int64(b))), true
@@ -173,7 +173,7 @@ func (a *BigInt) M__invert__() (Object, error) {
173173
}
174174

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

190190
func (a *BigInt) M__sub__(other Object) (Object, error) {
191-
if b, ok := convertToBigInt(other); ok {
191+
if b, ok := ConvertToBigInt(other); ok {
192192
return (*BigInt)(new(big.Int).Sub((*big.Int)(a), (*big.Int)(b))).MaybeInt(), nil
193193
}
194194
return NotImplemented, nil
195195
}
196196

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

208208
func (a *BigInt) M__mul__(other Object) (Object, error) {
209-
if b, ok := convertToBigInt(other); ok {
209+
if b, ok := ConvertToBigInt(other); ok {
210210
return (*BigInt)(new(big.Int).Mul((*big.Int)(a), (*big.Int)(b))).MaybeInt(), nil
211211
}
212212
return NotImplemented, nil
@@ -306,14 +306,14 @@ func (a *BigInt) divMod(b *BigInt) (Object, Object, error) {
306306
}
307307

308308
func (a *BigInt) M__divmod__(other Object) (Object, Object, error) {
309-
if b, ok := convertToBigInt(other); ok {
309+
if b, ok := ConvertToBigInt(other); ok {
310310
return a.divMod(b)
311311
}
312312
return NotImplemented, NotImplemented, nil
313313
}
314314

315315
func (a *BigInt) M__rdivmod__(other Object) (Object, Object, error) {
316-
if b, ok := convertToBigInt(other); ok {
316+
if b, ok := ConvertToBigInt(other); ok {
317317
return b.divMod(a)
318318
}
319319
return NotImplemented, NotImplemented, nil
@@ -343,18 +343,18 @@ func (a *BigInt) M__pow__(other, modulus Object) (Object, error) {
343343
var m *BigInt
344344
if modulus != None {
345345
var ok bool
346-
if m, ok = convertToBigInt(modulus); !ok {
346+
if m, ok = ConvertToBigInt(modulus); !ok {
347347
return NotImplemented, nil
348348
}
349349
}
350-
if b, ok := convertToBigInt(other); ok {
350+
if b, ok := ConvertToBigInt(other); ok {
351351
return a.pow(b, m)
352352
}
353353
return NotImplemented, nil
354354
}
355355

356356
func (a *BigInt) M__rpow__(other Object) (Object, error) {
357-
if b, ok := convertToBigInt(other); ok {
357+
if b, ok := ConvertToBigInt(other); ok {
358358
return b.pow(a, nil)
359359
}
360360
return NotImplemented, nil
@@ -365,7 +365,7 @@ func (a *BigInt) M__ipow__(other, modulus Object) (Object, error) {
365365
}
366366

367367
func (a *BigInt) M__lshift__(other Object) (Object, error) {
368-
if b, ok := convertToBigInt(other); ok {
368+
if b, ok := ConvertToBigInt(other); ok {
369369
bb, err := b.GoInt()
370370
if err != nil {
371371
return nil, err
@@ -379,7 +379,7 @@ func (a *BigInt) M__lshift__(other Object) (Object, error) {
379379
}
380380

381381
func (a *BigInt) M__rlshift__(other Object) (Object, error) {
382-
if b, ok := convertToBigInt(other); ok {
382+
if b, ok := ConvertToBigInt(other); ok {
383383
aa, err := a.GoInt()
384384
if err != nil {
385385
return nil, err
@@ -397,7 +397,7 @@ func (a *BigInt) M__ilshift__(other Object) (Object, error) {
397397
}
398398

399399
func (a *BigInt) M__rshift__(other Object) (Object, error) {
400-
if b, ok := convertToBigInt(other); ok {
400+
if b, ok := ConvertToBigInt(other); ok {
401401
bb, err := b.GoInt()
402402
if err != nil {
403403
return nil, err
@@ -411,7 +411,7 @@ func (a *BigInt) M__rshift__(other Object) (Object, error) {
411411
}
412412

413413
func (a *BigInt) M__rrshift__(other Object) (Object, error) {
414-
if b, ok := convertToBigInt(other); ok {
414+
if b, ok := ConvertToBigInt(other); ok {
415415
aa, err := a.GoInt()
416416
if err != nil {
417417
return nil, err
@@ -429,7 +429,7 @@ func (a *BigInt) M__irshift__(other Object) (Object, error) {
429429
}
430430

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

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

461461
func (a *BigInt) M__or__(other Object) (Object, error) {
462-
if b, ok := convertToBigInt(other); ok {
462+
if b, ok := ConvertToBigInt(other); ok {
463463
return (*BigInt)(new(big.Int).Or((*big.Int)(a), (*big.Int)(b))).MaybeInt(), nil
464464
}
465465
return NotImplemented, nil
@@ -498,7 +498,7 @@ func (a *BigInt) M__complex__() (Object, error) {
498498
}
499499

500500
func (a *BigInt) M__round__(digits Object) (Object, error) {
501-
if b, ok := convertToBigInt(digits); ok {
501+
if b, ok := ConvertToBigInt(digits); ok {
502502
if (*big.Int)(b).Sign() >= 0 {
503503
return a, nil
504504
}
@@ -528,42 +528,42 @@ func (a *BigInt) M__round__(digits Object) (Object, error) {
528528
// Rich comparison
529529

530530
func (a *BigInt) M__lt__(other Object) (Object, error) {
531-
if b, ok := convertToBigInt(other); ok {
531+
if b, ok := ConvertToBigInt(other); ok {
532532
return NewBool((*big.Int)(a).Cmp((*big.Int)(b)) < 0), nil
533533
}
534534
return NotImplemented, nil
535535
}
536536

537537
func (a *BigInt) M__le__(other Object) (Object, error) {
538-
if b, ok := convertToBigInt(other); ok {
538+
if b, ok := ConvertToBigInt(other); ok {
539539
return NewBool((*big.Int)(a).Cmp((*big.Int)(b)) <= 0), nil
540540
}
541541
return NotImplemented, nil
542542
}
543543

544544
func (a *BigInt) M__eq__(other Object) (Object, error) {
545-
if b, ok := convertToBigInt(other); ok {
545+
if b, ok := ConvertToBigInt(other); ok {
546546
return NewBool((*big.Int)(a).Cmp((*big.Int)(b)) == 0), nil
547547
}
548548
return NotImplemented, nil
549549
}
550550

551551
func (a *BigInt) M__ne__(other Object) (Object, error) {
552-
if b, ok := convertToBigInt(other); ok {
552+
if b, ok := ConvertToBigInt(other); ok {
553553
return NewBool((*big.Int)(a).Cmp((*big.Int)(b)) != 0), nil
554554
}
555555
return NotImplemented, nil
556556
}
557557

558558
func (a *BigInt) M__gt__(other Object) (Object, error) {
559-
if b, ok := convertToBigInt(other); ok {
559+
if b, ok := ConvertToBigInt(other); ok {
560560
return NewBool((*big.Int)(a).Cmp((*big.Int)(b)) > 0), nil
561561
}
562562
return NotImplemented, nil
563563
}
564564

565565
func (a *BigInt) M__ge__(other Object) (Object, error) {
566-
if b, ok := convertToBigInt(other); ok {
566+
if b, ok := ConvertToBigInt(other); ok {
567567
return NewBool((*big.Int)(a).Cmp((*big.Int)(b)) >= 0), nil
568568
}
569569
return NotImplemented, nil

version.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ var (
88
version = "dev"
99
commit = "none"
1010
date = "unknown"
11-
)
11+
)

0 commit comments

Comments
 (0)