[pypy-svn] r53222 - in pypy/branch/js-refactoring/pypy/lang/js: . test
fijal at codespeak.net
fijal at codespeak.net
Tue Apr 1 01:26:22 CEST 2008
Author: fijal
Date: Tue Apr 1 01:26:21 2008
New Revision: 53222
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/operations.py
pypy/branch/js-refactoring/pypy/lang/js/test/test_parser.py
Log:
some general progress in area of assignments.
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 Tue Apr 1 01:26:21 2008
@@ -40,16 +40,10 @@
#'!': operations.Not,
'+': operations.UPlus,
'-': operations.UMinus,
- '++': operations.PreIncrement,
- '--': operations.PreDecrement,
#'typeof': operations.Typeof,
#'void': operations.Void,
#'delete': operations.Delete,
}
- POSTFIX_TO_CLS = {
- '++': operations.PostIncrement,
- '--': operations.PostDecrement,
- }
LISTOP_TO_CLS = {
'[': operations.Array,
'{': operations.ObjectInit,
@@ -161,14 +155,35 @@
op = node.children[0]
pos = self.get_pos(op)
child = self.dispatch(node.children[1])
+ if op.additional_info in ['++', '--']:
+ return self._dispatch_assignment(pos, child, op.additional_info,
+ 'pre')
return self.UNOP_TO_CLS[op.additional_info](pos, child)
+ def _dispatch_assignment(self, pos, left, atype, prepost):
+ from pypy.lang.js.operations import Identifier, Member, MemberDot,\
+ VariableIdentifier
+
+ if isinstance(left, Identifier):
+ return operations.SimpleAssignment(pos, left, None, atype, prepost)
+ elif isinstance(left, VariableIdentifier):
+ return operations.VariableAssignment(pos, left, None, atype,
+ prepost)
+ elif isinstance(left, Member):
+ return operations.MemberAssignment(pos, left.left, left.expr,
+ None, atype, prepost)
+ elif isinstance(left, MemberDot):
+ return operations.MemberDotAssignment(pos, left.left, left.name,
+ None, atype, prepost)
+ else:
+ return operations.SimpleIncrement(pos, left, atype)
+
def visit_postfixexpression(self, node):
op = node.children[1]
pos = self.get_pos(op)
child = self.dispatch(node.children[0])
- return self.POSTFIX_TO_CLS[op.additional_info](pos, child)
-
+ # all postfix expressions are assignments
+ return self._dispatch_assignment(pos, child, op.additional_info, 'post')
def listop(self, node):
op = node.children[0]
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 Tue Apr 1 01:26:21 2008
@@ -241,21 +241,46 @@
def __repr__(self):
return 'LOAD_FUNCTION' # XXX
-class STORE_MEMBER(Opcode):
+class BaseStoreMember(Opcode):
pass
#def eval(self, ctx, ):
# XXX
-class STORE(Opcode):
+class STORE_MEMBER(Opcode):
+ pass
+
+class STORE_MEMBER_POSTINCR(Opcode):
+ pass
+
+class STORE_MEMBER_PREINCR(Opcode):
+ pass
+
+class STORE_MEMBER_SUB(Opcode):
+ pass
+
+class BaseStore(Opcode):
def __init__(self, name):
self.name = name
def eval(self, ctx, stack):
value = stack[-1]
+ value = self.process(ctx, self.name, value)
ctx.assign(self.name, value)
def __repr__(self):
- return 'STORE "%s"' % self.name
+ return '%s "%s"' % (self.__class__.__name__, self.name)
+
+class STORE(BaseStore):
+ def process(self, ctx, name, value):
+ return value
+
+class STORE_ADD(BaseStore):
+ def process(self, ctx, name, value):
+ xxx
+
+class STORE_POSTINCR(BaseStore):
+ def process(self, ctx, name, value):
+ xxx
class STORE_VAR(Opcode):
def __init__(self, depth, name):
@@ -338,17 +363,11 @@
class UMINUS(BaseUnaryOperation):
pass
-#class PREINCR(BaseUnaryOperation):
-# pass
-
-#class POSTINCR(BaseUnaryOperation):
-# pass
-
-#class PREDECR(BaseUnaryOperation):
-# pass
+class INCR(BaseUnaryOperation):
+ pass
-#class POSTDECR(BaseUnaryOperation):
-# pass
+class DECR(BaseUnaryOperation):
+ pass
class GT(BaseBinaryComparison):
def decision(self, ctx, op1, op2):
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 Tue Apr 1 01:26:21 2008
@@ -121,18 +121,48 @@
bytecode.emit('LOAD_ARRAY', len(self.nodes))
class Assignment(Expression):
- pass
+ def _get_name(self):
+ addoper = OPERANDS[self.operand]
+ if addoper:
+ addoper = '_' + self.prefix.upper() + addoper
+ return addoper
+
+OPERANDS = {
+ '=' : '',
+ '+=' : 'ADD',
+ '-=' : 'SUB',
+ '*=' : 'MUL',
+ '/=' : 'DIV',
+ '++' : 'INCR',
+ '--' : 'DECR',
+ }
+
+class SimpleIncrement(Expression):
+ def __init__(self, pos, left, atype):
+ self.pos = pos
+ self.left = left
+ self.atype = atype
+
+ def emit(self, bytecode):
+ self.left.emit(bytecode)
+ if self.atype == '++':
+ bytecode.emit('INCR')
+ elif self.atype == '--':
+ bytecode.emit('DECR')
class SimpleAssignment(Assignment):
- def __init__(self, pos, left, right, operand):
+ def __init__(self, pos, left, right, operand, prefix=''):
self.identifier = left.get_literal()
self.right = right
self.pos = pos
self.operand = operand
+ self.prefix = prefix
def emit(self, bytecode):
- self.right.emit(bytecode)
- bytecode.emit('STORE', self.identifier)
+ if self.right is not None:
+ self.right.emit(bytecode)
+ bytecode_name = 'STORE' + self._get_name()
+ bytecode.emit(bytecode_name, self.identifier)
class VariableAssignment(Assignment):
def __init__(self, pos, left, right, operand):
@@ -147,7 +177,7 @@
bytecode.emit('STORE_VAR', self.depth, self.identifier)
class MemberAssignment(Assignment):
- def __init__(self, pos, what, item, right, operand):
+ def __init__(self, pos, what, item, right, operand, prefix=''):
# XXX we can optimise here what happens if what is identifier,
# but let's leave it alone for now
self.pos = pos
@@ -155,26 +185,30 @@
self.item = item
self.right = right
self.operand = operand
+ self.prefix = prefix
def emit(self, bytecode):
- self.right.emit(bytecode)
+ if self.right is not None:
+ self.right.emit(bytecode)
self.item.emit(bytecode)
self.what.emit(bytecode)
- bytecode.emit('STORE_MEMBER')
+ bytecode.emit('STORE_MEMBER' + self._get_name())
class MemberDotAssignment(Assignment):
- def __init__(self, pos, what, name, right, operand):
+ def __init__(self, pos, what, name, right, operand, prefix=''):
self.pos = pos
self.what = what
self.itemname = name
self.right = right
self.operand = operand
+ self.prefix = prefix
def emit(self, bytecode):
- self.right.emit(bytecode)
+ if self.right is not None:
+ self.right.emit(bytecode)
bytecode.emit('LOAD_STRINGCONSTANT', self.itemname)
self.what.emit(bytecode)
- bytecode.emit('STORE_MEMBER')
+ bytecode.emit('STORE_MEMBER' + self._get_name())
class StuffAssignment(Expression):
def __init__(self, pos, left, right, operand):
@@ -507,11 +541,6 @@
# r4 = r1.GetPropertyName()
# return W_Boolean(r3.Delete(r4))
-PreIncrement = create_unary_op('PREINCR')
-PostIncrement = create_unary_op('POSTINCR')
-PreDecrement = create_unary_op('PREDECRE')
-PostDecrement = create_unary_op('POSTDECR')
-
#class Index(BinaryOp):
# def eval(self, ctx):
# w_obj = self.left.eval(ctx).GetValue().ToObject(ctx)
Modified: pypy/branch/js-refactoring/pypy/lang/js/test/test_parser.py
==============================================================================
--- pypy/branch/js-refactoring/pypy/lang/js/test/test_parser.py (original)
+++ pypy/branch/js-refactoring/pypy/lang/js/test/test_parser.py Tue Apr 1 01:26:21 2008
@@ -360,10 +360,10 @@
'SUB'])
self.check('++5', [
'LOAD_INTCONSTANT 5',
- 'PREINCR'])
+ 'INCR'])
self.check('5--', [
'LOAD_INTCONSTANT 5',
- 'POSTDECR'])
+ 'DECR'])
self.check('"hello " + \'world\'',
['LOAD_STRINGCONSTANT "hello "',
'LOAD_STRINGCONSTANT "world"',
@@ -478,6 +478,25 @@
'STORE_MEMBER',
'POP'])
+ def test_different_assignments(self):
+ self.check('x += y', [
+ 'LOAD_VARIABLE "y"',
+ 'STORE_ADD "x"',
+ 'POP'])
+ self.check('x++', ['STORE_POSTINCR "x"',
+ 'POP'])
+ self.check('++x[2]', [
+ 'LOAD_INTCONSTANT 2',
+ 'LOAD_VARIABLE "x"',
+ 'STORE_MEMBER_PREINCR',
+ 'POP'])
+ self.check('x.y -= 2',
+ ['LOAD_INTCONSTANT 2',
+ 'LOAD_STRINGCONSTANT "y"',
+ 'LOAD_VARIABLE "x"',
+ 'STORE_MEMBER_SUB',
+ 'POP'])
+
from pypy.lang.js.jsparser import parse
def test_simplesemicolon():
More information about the pypy-svn
mailing list