[pypy-svn] r53304 - pypy/branch/js-refactoring/pypy/lang/js
fijal at codespeak.net
fijal at codespeak.net
Fri Apr 4 02:48:28 CEST 2008
Author: fijal
Date: Fri Apr 4 02:48:26 2008
New Revision: 53304
Modified:
pypy/branch/js-refactoring/pypy/lang/js/astbuilder.py
pypy/branch/js-refactoring/pypy/lang/js/jscode.py
pypy/branch/js-refactoring/pypy/lang/js/jsobj.py
pypy/branch/js-refactoring/pypy/lang/js/operations.py
Log:
support for ForIn
Modified: pypy/branch/js-refactoring/pypy/lang/js/astbuilder.py
==============================================================================
--- pypy/branch/js-refactoring/pypy/lang/js/astbuilder.py (original)
+++ pypy/branch/js-refactoring/pypy/lang/js/astbuilder.py Fri Apr 4 02:48:26 2008
@@ -390,11 +390,13 @@
visit_regularvarfor = visit_regularfor
def visit_infor(self, node):
+ from pypy.lang.js.operations import Identifier
pos = self.get_pos(node)
left = self.dispatch(node.children[1])
right = self.dispatch(node.children[2])
body= self.dispatch(node.children[3])
- return operations.ForIn(pos, left, right, body)
+ assert isinstance(left, Identifier)
+ return operations.ForIn(pos, left.name, right, body)
def visit_invarfor(self, node):
pos = self.get_pos(node)
Modified: pypy/branch/js-refactoring/pypy/lang/js/jscode.py
==============================================================================
--- pypy/branch/js-refactoring/pypy/lang/js/jscode.py (original)
+++ pypy/branch/js-refactoring/pypy/lang/js/jscode.py Fri Apr 4 02:48:26 2008
@@ -2,7 +2,7 @@
from pypy.lang.js.jsobj import W_IntNumber, W_FloatNumber, W_String,\
W_Array, W_PrimitiveObject, ActivationObject,\
create_object, W_Object, w_Undefined, newbool,\
- w_True, w_False, W_List, w_Null
+ w_True, w_False, W_List, w_Null, W_Iterator
from pypy.lang.js.execution import JsTypeError, ReturnException, ThrowException
from pypy.rlib.unroll import unrolling_iterable
from pypy.lang.js.baseop import plus, sub, compare, AbstractEC, StrictEC,\
@@ -686,6 +686,34 @@
args = y.get_args()
stack.append(commonnew(ctx, x, args))
+# ------------ iterator support ----------------
+
+class LOAD_ITERATOR(Opcode):
+ def eval(self, ctx, stack):
+ obj = stack.pop().ToObject(ctx)
+ props = [prop.value for prop in obj.propdict.values() if not prop.de]
+ stack.append(W_Iterator(props))
+
+class JUMP_IF_ITERATOR_EMPTY(BaseJump):
+ def eval(self, ctx, stack):
+ pass
+
+ def do_jump(self, stack, pos):
+ iterator = stack[-1]
+ assert isinstance(iterator, W_Iterator)
+ if iterator.empty():
+ return self.where
+ return pos + 1
+
+class NEXT_ITERATOR(Opcode):
+ def __init__(self, name):
+ self.name = name
+
+ def eval(self, ctx, stack):
+ iterator = stack[-1]
+ assert isinstance(iterator, W_Iterator)
+ ctx.assign(self.name, iterator.next())
+
OpcodeMap = {}
for name, value in locals().items():
Modified: pypy/branch/js-refactoring/pypy/lang/js/jsobj.py
==============================================================================
--- pypy/branch/js-refactoring/pypy/lang/js/jsobj.py (original)
+++ pypy/branch/js-refactoring/pypy/lang/js/jsobj.py Fri Apr 4 02:48:26 2008
@@ -619,6 +619,17 @@
# def __str__(self):
# return "<" + str(self.base) + " -> " + str(self.property_name) + ">"
+
+class W_Iterator(W_Root):
+ def __init__(self, elements_w):
+ self.elements_w = elements_w
+
+ def next(self):
+ if self.elements_w:
+ return self.elements_w.pop()
+
+ def empty(self):
+ return len(self.elements_w) == 0
def create_object(ctx, prototypename, callfunc=None, Value=w_Undefined):
proto = ctx.get_global().Get(prototypename).Get('prototype')
Modified: pypy/branch/js-refactoring/pypy/lang/js/operations.py
==============================================================================
--- pypy/branch/js-refactoring/pypy/lang/js/operations.py (original)
+++ pypy/branch/js-refactoring/pypy/lang/js/operations.py Fri Apr 4 02:48:26 2008
@@ -865,13 +865,25 @@
class ForIn(Statement):
- def __init__(self, pos, iterator, lobject, body):
+ def __init__(self, pos, name, lobject, body):
self.pos = pos
#assert isinstance(iterator, Node)
- self.iterator = iterator
+ self.iteratorname = name
self.object = lobject
self.body = body
+ def emit(self, bytecode):
+ self.object.emit(bytecode)
+ bytecode.emit('LOAD_ITERATOR')
+ precond = bytecode.emit_startloop_label()
+ finish = bytecode.prealocate_endloop_label()
+ bytecode.emit('JUMP_IF_ITERATOR_EMPTY', finish)
+ bytecode.emit('NEXT_ITERATOR', self.iteratorname)
+ self.body.emit(bytecode)
+ bytecode.emit('JUMP', precond)
+ bytecode.emit_endloop_label(finish)
+ bytecode.emit('POP')
+
def execute(self, ctx):
obj = self.object.eval(ctx).GetValue().ToObject(ctx)
for prop in obj.propdict.values():
More information about the Pypy-commit
mailing list