Skip to content

Commit

Permalink
builtin: Implement builtin function any, all.
Browse files Browse the repository at this point in the history
  • Loading branch information
corona10 authored and ncw committed Aug 5, 2018
1 parent c0de7de commit 8a7aec9
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 2 deletions.
61 changes: 59 additions & 2 deletions builtin/builtin.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ func init() {
py.MustNewMethod("__build_class__", builtin___build_class__, 0, build_class_doc),
py.MustNewMethod("__import__", py.InternalMethodImport, 0, import_doc),
py.MustNewMethod("abs", builtin_abs, 0, abs_doc),
// py.MustNewMethod("all", builtin_all, 0, all_doc),
// py.MustNewMethod("any", builtin_any, 0, any_doc),
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("callable", builtin_callable, 0, callable_doc),
Expand Down Expand Up @@ -225,6 +225,63 @@ func builtin_abs(self, v py.Object) (py.Object, error) {
return py.Abs(v)
}

const all_doc = `all(iterable) -> bool
Return True if bool(x) is True for all values x in the iterable.
If the iterable is empty, return True.
`

func builtin_all(self, seq py.Object) (py.Object, error) {
iter, err := py.Iter(seq)
res := false
if err != nil {
return nil, err
}
for {
item, err := py.Next(iter)
if err != nil {
if py.IsException(py.StopIteration, err) {
break
}
return nil, err
}
if py.ObjectIsTrue(item) {
res = true
} else {
res = false
break
}
}
return py.NewBool(res), nil
}

const any_doc = `any(iterable) -> bool
Return True if bool(x) is True for any x in the iterable.
If the iterable is empty, Py_RETURN_FALSE."`

func builtin_any(self, seq py.Object) (py.Object, error) {
iter, err := py.Iter(seq)
res := false
if err != nil {
return nil, err
}
for {
item, err := py.Next(iter)
if err != nil {
if py.IsException(py.StopIteration, err) {
break
}
return nil, err
}
if py.ObjectIsTrue(item) {
res = true
break
}
}
return py.NewBool(res), nil
}

const round_doc = `round(number[, ndigits]) -> number
Round a number to a given precision in decimal digits (default 0 digits).
Expand Down
12 changes: 12 additions & 0 deletions builtin/tests/builtin.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,18 @@
assert abs(10) == 10
assert abs(-10) == 10

doc="all"
assert all((0,0,0)) == False
assert all((1,1,0)) == False
assert all(["hello", "world"]) == True
assert all([]) == False

doc="any"
assert any((0,0,0)) == False
assert any((1,1,0)) == True
assert any(["hello", "world"]) == True
assert any([]) == False

doc="chr"
assert chr(65) == "A"
assert chr(163) == "£"
Expand Down
24 changes: 24 additions & 0 deletions py/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,27 @@ func ObjectRepr(o Object) Object {
// FIXME
return String(fmt.Sprintf("<%s %v>", o.Type().Name, o))
}

// Return whether the object is True or not
func ObjectIsTrue(o Object) bool {
if o == True {
return true
}
if o == False {
return false
}

if o == None {
return false
}

if I, ok := o.(I__bool__); ok {
cmp, err := I.M__bool__()
if err == nil && cmp == True {
return true
} else if err == nil && cmp == False {
return false
}
}
return false
}

0 comments on commit 8a7aec9

Please sign in to comment.