[pypy-svn] r52416 - in pypy/branch/jit-refactoring/pypy/lang/js: . doc test

fijal at codespeak.net fijal at codespeak.net
Wed Mar 12 15:14:38 CET 2008


Author: fijal
Date: Wed Mar 12 15:14:37 2008
New Revision: 52416

Modified:
   pypy/branch/jit-refactoring/pypy/lang/js/astbuilder.py
   pypy/branch/jit-refactoring/pypy/lang/js/doc/bytecode.txt
   pypy/branch/jit-refactoring/pypy/lang/js/jscode.py
   pypy/branch/jit-refactoring/pypy/lang/js/operations.py
   pypy/branch/jit-refactoring/pypy/lang/js/test/test_parser.py
Log:
first test in test_parser passes. everything else fails. progress.


Modified: pypy/branch/jit-refactoring/pypy/lang/js/astbuilder.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/lang/js/astbuilder.py	(original)
+++ pypy/branch/jit-refactoring/pypy/lang/js/astbuilder.py	Wed Mar 12 15:14:37 2008
@@ -1,6 +1,6 @@
 from pypy.rlib.parsing.tree import RPythonVisitor, Symbol, Nonterminal
 from pypy.lang.js import operations
-
+from pypy.rlib.parsing.parsing import ParseError
 
 class ASTBuilder(RPythonVisitor):
     BINOP_TO_CLS = {
@@ -275,11 +275,21 @@
         return left
         
     def visit_assignmentexpression(self, node):
+        from pypy.lang.js.operations import Identifier, Member, MemberDot
         pos = self.get_pos(node)
         left = self.dispatch(node.children[0])
         atype = node.children[1].additional_info
         right = self.dispatch(node.children[2])
-        return operations.Assignment(pos, left, right, atype)
+        if isinstance(left, Identifier):
+            return operations.SimpleAssignment(pos, left, right, atype)
+        elif isinstance(left, Member):
+            return operations.MemberAssignment(pos, left.left, left.right,
+                                               right, atype)
+        elif isinstance(left, MemberDot):
+            return operations.MemberDotAssignment(pos, left.left, left.right,
+                                                  right, atype)
+        else:
+            raise ParseError(left.pos, "Invalid lefthand expression")
     visit_assignmentexpressionnoin = visit_assignmentexpression
         
     def visit_emptystatement(self, node):

Modified: pypy/branch/jit-refactoring/pypy/lang/js/doc/bytecode.txt
==============================================================================
--- pypy/branch/jit-refactoring/pypy/lang/js/doc/bytecode.txt	(original)
+++ pypy/branch/jit-refactoring/pypy/lang/js/doc/bytecode.txt	Wed Mar 12 15:14:37 2008
@@ -18,11 +18,11 @@
 
 stores the last value on stack into identifierx
 
-STORE_ELEMENT <identifier>
+STORE_MEMBER
 
-identifier[last_element_on_the_stack] = previous_element_on_the_stack
-note that in javascript a.b is exactly the same as a['b'], just that
-first one can be eventually speed up
+take from stack: right side, element and where to store and store
+where[element] = right. XXX can be optimized further for direct member
+assignement
 
 LOAD_ARRAY <num>
 
@@ -45,6 +45,13 @@
 PREDECR, POSTDECR, PREINCR, POSTINCR
 decrement and increment (++, --) prefix and postfix
 
+object creation:
+
+LOAD_OBJECT <list of parameters>
+
+Takes one element per one parameter from the stack and initializes
+object this way.
+
 control flow:
 
 XXX

Modified: pypy/branch/jit-refactoring/pypy/lang/js/jscode.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/lang/js/jscode.py	(original)
+++ pypy/branch/jit-refactoring/pypy/lang/js/jscode.py	Wed Mar 12 15:14:37 2008
@@ -23,9 +23,6 @@
         return all([i == j for i, j in zip(self.opcodes, list_of_opcodes)])
 
 class Opcode(object):
-    def __init__(self, args):
-        raise NotImplementedError("Purely abstract")
-    
     def eval(self, ctx, stack):
         """ Execute in context ctx
         """
@@ -34,6 +31,9 @@
     def __eq__(self, other):
         return repr(self) == other
 
+    def __repr__(self):
+        return self.__class__.__name__
+
 class BaseBinaryComparison(Opcode):
     def eval(self, ctx):
         s2 = self.left.eval(ctx).GetValue()
@@ -116,6 +116,27 @@
     def __repr__(self):
         return 'LOAD_ARRAY %d' % (self.counter,)
 
+class STORE_MEMBER(Opcode):
+    def eval(self, ctx):
+        XXX
+
+class STORE(Opcode):
+    def __init__(self, name):
+        self.name = name
+    
+    def eval(self, ctx):
+        XXX
+
+    def __repr__(self):
+        return 'STORE "%s"' % self.name
+
+class LOAD_OBJECT(Opcode):
+    def __init__(self, listofnames):
+        self.listofnames = listofnames
+
+    def __repr__(self):
+        return 'LOAD_OBJECT %r' % (self.listofnames,)
+
 OpcodeMap = {}
 
 for name, value in locals().items():

Modified: pypy/branch/jit-refactoring/pypy/lang/js/operations.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/lang/js/operations.py	(original)
+++ pypy/branch/jit-refactoring/pypy/lang/js/operations.py	Wed Mar 12 15:14:37 2008
@@ -90,9 +90,7 @@
         self.expr = expr
     
     def emit(self, bytecode):
-        XXX # not sure what to do here, think later
         self.expr.emit(bytecode)
-        bytecode.emit('STORE', self.identifier)
 
 class Array(ListOp):
     def emit(self, bytecode):
@@ -101,15 +99,68 @@
         bytecode.emit('LOAD_ARRAY', len(self.nodes))
 
 class Assignment(Expression):
+    pass
+
+class SimpleAssignment(Assignment):
     def __init__(self, pos, left, right, operand):
-        self.pos = pos
+        assert isinstance(left, Identifier)
         self.identifier = left.name
         self.right = right
+        self.pos = pos
+        self.operand = operand
+
+    def emit(self, bytecode):
+        self.right.emit(bytecode)
+        bytecode.emit('STORE', self.identifier)
+
+class MemberAssignment(Assignment):
+    def __init__(self, pos, what, item, right, operand):
+        # XXX we can optimise here what happens if what is identifier,
+        #     but let's leave it alone for now
+        self.pos = pos
+        self.what = what
+        self.item = item
+        self.right = right
+        self.operand = operand
+
+    def emit(self, bytecode):
+        self.right.emit(bytecode)
+        self.item.emit(bytecode)
+        self.what.emit(bytecode)
+        bytecode.emit('STORE_MEMBER')
+
+class MemberDotAssignment(Assignment):
+    def __init__(self, pos, what, item, right, operand):
+        self.pos = pos
+        self.what = what
+        assert isinstance(item, Identifier)
+        self.itemname = item.name
+        self.right = right
+        self.operand = operand
+
+    def emit(self, bytecode):
+        self.right.emit(bytecode)
+        bytecode.emit('LOAD_STRINGCONSTANT', self.itemname)
+        self.what.emit(bytecode)
+        bytecode.emit('STORE_MEMBER')
+
+class StuffAssignment(Expression):
+    def __init__(self, pos, left, right, operand):
+        self.pos = pos
+        # check the sanity of lefthandside
+        if isinstance(left, Identifier):
+            self.identifier = left.name
+            self.single_assignement = True
+        elif isinstance(left, Member):
+            import pdb
+            pdb.set_trace()
+            self.lefthandside = left
+            self.single_assignement = False
+        self.right = right
         self.operand = operand
 
     def emit(self, bytecode):
         op = self.operand
-        XXX
         if op == '==':
             bytecode.emit('STORE', self.identifier)
         else:
@@ -794,6 +845,13 @@
         return ''.join(temp)
 
 class ObjectInit(ListOp):
+    def emit(self, bytecode):
+        names = []
+        for prop in self.nodes:
+            prop.emit(bytecode)
+            names.append(prop.identifier)
+        bytecode.emit('LOAD_OBJECT', names)
+    
     def eval(self, ctx):
         w_obj = create_object(ctx, 'Object')
         for prop in self.nodes:

Modified: pypy/branch/jit-refactoring/pypy/lang/js/test/test_parser.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/lang/js/test/test_parser.py	(original)
+++ pypy/branch/jit-refactoring/pypy/lang/js/test/test_parser.py	Wed Mar 12 15:14:37 2008
@@ -139,9 +139,6 @@
         assert result1 == n
         return tree
 
-    def parse_raises(self, s):
-        py.test.raises(ParseError, self.parse, s)
-
     def parse_and_eval_all(self, l):
         for i in l:
             self.parse_and_evaluate(i)
@@ -186,9 +183,6 @@
         self.parse('{}')
         self.parse('{x:1}') #per spec {x:1,} should not be supported
         self.parse('{x:1,y:2}')
-
-    def test_invalid_expression(self):
-        self.parse_raises('(1+2)=3')
     
 class TestStatements(BaseGrammarTest):
     def setup_class(cls):
@@ -326,14 +320,28 @@
             'LOAD_FLOATCONSTANT 3.3',
             'LOAD_STRINGCONSTANT "abc"',
             'LOAD_ARRAY 4'])
+        self.check('x[3] = 3', [
+            'LOAD_INTCONSTANT 3',
+            'LOAD_INTCONSTANT 3',
+            'LOAD_VARIABLE "x"',
+            'STORE_MEMBER'])
+        self.check('x.x = 3', [
+            'LOAD_INTCONSTANT 3',
+            'LOAD_STRINGCONSTANT "x"',
+            'LOAD_VARIABLE "x"',
+            'STORE_MEMBER'])
         self.check('x = 3', [
             'LOAD_INTCONSTANT 3',
             'STORE "x"'])
         self.check('{x:1}', [
             'LOAD_INTCONSTANT 1',
-            'LOAD_OBJECT ["x"]'])
+            "LOAD_OBJECT ['x']"])
+
+    def test_raising(self):
+        py.test.raises(ParseError, self.check, '1=2', [])
     
     def test_expression(self):
+        py.test.skip("Not yet")
         w_num = self.eval_expr('1 - 1 - 1')
         assert w_num.ToNumber() == -1
         w_num = self.eval_expr('-(6 * (6 * 6)) + 6 - 6')



More information about the Pypy-commit mailing list