Skip to content

Commit

Permalink
Implement tuple len.
Browse files Browse the repository at this point in the history
This is extremely simple as it doesn't even need C layer changes
(because we can actually compute its return value at the IR
generation phase).
  • Loading branch information
jhance committed Jul 27, 2017
1 parent d10737d commit 270ca1a
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 4 deletions.
9 changes: 8 additions & 1 deletion mypyc/genops.py
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,14 @@ def visit_call_expr(self, expr: CallExpr) -> int:
if fn == 'len' and len(expr.args) == 1 and expr.arg_kinds == [ARG_POS]:
target = self.alloc_target(RTType('int'))
arg = self.accept(expr.args[0])
self.add(PrimitiveOp(target, PrimitiveOp.LIST_LEN, arg))

expr_rttype = type_to_rttype(self.types[expr.args[0]])
if expr_rttype.name == 'list':
self.add(PrimitiveOp(target, PrimitiveOp.LIST_LEN, arg))
elif isinstance(expr_rttype, TupleRTType):
self.add(LoadInt(target, len(expr_rttype.types)))
else:
assert False, "unsupported use of len"
else:
target = self.alloc_target(RTType('int'))
args = [self.accept(arg) for arg in expr.args]
Expand Down
7 changes: 4 additions & 3 deletions test-data/fixtures/ir.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# These builtins stubs are used implicitly in AST to IR generation
# test cases.

from typing import TypeVar, Generic, List, Iterator, Iterable
from typing import TypeVar, Generic, List, Iterator, Iterable, Sized

T = TypeVar('T')

Expand Down Expand Up @@ -33,14 +33,15 @@ class bool: pass
class tuple: pass
class function: pass

class list(Generic[T], Iterable[T]):
class list(Generic[T], Iterable[T], Sized):
def __getitem__(self, i: int) -> T: pass
def __setitem__(self, i: int, o: T) -> None: pass
def __mul__(self, i: int) -> List[T]: pass
def __rmul__(self, i: int) -> List[T]: pass
def __iter__(self) -> Iterator[T]: pass
def __len__(self) -> int: pass
def append(self, x: T) -> None: pass

def len(o: list) -> int: pass
def len(o: Sized) -> int: pass
def print(*object) -> None: pass
def range(x: int) -> Iterator[int]: pass
12 changes: 12 additions & 0 deletions test-data/genops-basic.test
Original file line number Diff line number Diff line change
Expand Up @@ -450,3 +450,15 @@ L0:
t = (r0, r1)
r2 = t[1]
return r2

[case testTupleLen]
from typing import Tuple
def f(x: Tuple[bool, bool, int]) -> int:
return len(x)
[out]
def f(x):
x :: tuple
r0 :: int
L0:
r0 = 3
return r0

0 comments on commit 270ca1a

Please sign in to comment.