def __call__(self, expr: E.Apply, env: E.Env) -> V.Base: assert len(expr.arguments) == 2 lhs = expr.arguments[0] rhs = expr.arguments[1] if isinstance(lhs.type, T.Array): arr = lhs.eval(env) assert isinstance(arr, V.Array) assert isinstance(arr.type, T.Array) assert isinstance(arr.value, list) idx = rhs.eval(env).expect(T.Int()).value if idx < 0 or idx >= len(arr.value): raise Error.OutOfBounds(rhs) return arr.value[idx] # pyre-fixme if isinstance(lhs.type, T.Map): mp = lhs.eval(env) assert isinstance(mp, V.Map) assert isinstance(mp.type, T.Map) assert mp.type.item_type is not None assert isinstance(mp.value, list) ans = None key = rhs.eval(env).expect(mp.type.item_type[0]) for k, v in mp.value: if key == k: ans = v.expect(mp.type.item_type[1]) if ans is None: raise Error.OutOfBounds(rhs) # TODO: KeyNotFound return ans # pyre-fixme assert False # pyre-fixme
def _call_eager(self, expr: E.Apply, arguments: List[V.Base]) -> V.Base: assert len(expr.arguments) == 2 and len(arguments) == 2 lhs = arguments[0] rhs = arguments[1] if isinstance(lhs, V.Array): assert isinstance(rhs, V.Int) if rhs.value < 0 or rhs.value >= len(lhs.value): raise Error.OutOfBounds(expr.arguments[1]) return lhs.value[rhs.value] if isinstance(lhs, V.Map): mty = expr.arguments[0].type assert isinstance(mty, T.Map) key = rhs.coerce(mty.item_type[0]) ans = None for k, v in lhs.value: if rhs == k: ans = v if ans is None: raise Error.OutOfBounds(expr.arguments[1]) # TODO: KeyNotFound return ans assert False
def infer_type(self, expr: E.Apply) -> T.Base: assert len(expr.arguments) == 2 lhs = expr.arguments[0] rhs = expr.arguments[1] if isinstance(lhs.type, T.Array): if isinstance(lhs, E.Array) and not lhs.items: # the user wrote: [][idx] raise Error.OutOfBounds(expr) try: rhs.typecheck(T.Int()) except Error.StaticTypeMismatch: raise Error.StaticTypeMismatch(rhs, T.Int(), rhs.type, "Array index") from None return lhs.type.item_type if isinstance(lhs.type, T.Map): if lhs.type.item_type is None: raise Error.OutOfBounds(expr) try: rhs.typecheck(lhs.type.item_type[0]) except Error.StaticTypeMismatch: raise Error.StaticTypeMismatch( rhs, lhs.type.item_type[0], rhs.type, "Map key" ) from None return lhs.type.item_type[1] raise Error.NotAnArray(lhs)