require "python-semantics-literals.k"
require "python-semantics-try.k"
module PYTHON-SEMANTICS-ITERATORS
imports PYTHON-SEMANTICS-LITERALS
imports PYTHON-SEMANTICS-TRY
rule invokeBuiltin(obj("get_iter",_), ListItem(obj(B:ObjId,_)), .) => mutable("__index__" |-> 0 "__value__" |-> ref(B), ref("iterator")) ...
rule invokeBuiltin(obj("iter_iter",_), ListItem(O:Object), .) => O ...
rule invokeBuiltin(obj("iter_next",_), ListItem(obj(B,_)), .) => try: (getmember(B2, "__getitem__", true, false, true) (I:Int)) except ref("IndexError"): (setx(ref("None")) ~> raise ref("StopIteration")) else: pass ...
syntax ObjRef ::= "checkIter" "(" Exp ")" [strict]
rule invokeBuiltin(obj("iter",_), ListItem(O), .) => checkIter(getmember(O, "__iter__", true, false, false) (.Arguments) -> test(getmember(O, "__getitem__", true, false, false) =/=Obj .Obj, mutable("__index__" |-> 0 "__value__" |-> ref(id(O)), ref("iterator")), .Obj) -> (raiseInternal("TypeError", "object is not iterable"))) ...
rule checkIter(O:Object) => test(getmember(O, "__next__", true, false, false) ==Obj .Obj, raiseInternal("TypeError", "iter() returned non-iterator"), O) ...
//TODO: sentinels
rule invokeBuiltin(obj("next",_), ListItem(O:Object), .) => getmember(O, "__next__", true, false, false)(.Arguments) -> raiseInternal("TypeError", "object is not an iterator")
rule invokeBuiltin(obj("next",_), ListItem(O:Object) ListItem(Default:Object), .) => try: ref("next")(O) except ref("StopIteration"): Default
endmodule