[pypy-commit] lang-js default: use identifiers from scope for variable declaration to preserve order of local variable numbering

stepahn noreply at buildbot.pypy.org
Wed Jun 8 12:43:23 CEST 2011


Author: Stephan <stephan at stzal.com>
Branch: 
Changeset: r96:8fe1457c1319
Date: 2011-06-04 01:27 +0200
http://bitbucket.org/pypy/lang-js/changeset/8fe1457c1319/

Log:	use identifiers from scope for variable declaration to preserve
	order of local variable numbering

diff --git a/js/astbuilder.py b/js/astbuilder.py
--- a/js/astbuilder.py
+++ b/js/astbuilder.py
@@ -41,6 +41,11 @@
     def end_scope(self):
         self.scopes.pop()
 
+    def identifiers(self):
+        if self.current_scope() is not None:
+            return self.current_scope().local_variables
+        return []
+
     def add_local(self, identifier):
         if self.current_scope() is not None:
             return self.current_scope().add_local(identifier)
@@ -270,29 +275,12 @@
         right = self.dispatch(node.children[1])
         return operations.PropertyInit(pos,left,right)
 
-    def _search_identifier(self, name):
-        lenall = len(self.varlists)
-        for i in range(lenall):
-            num = lenall - i - 1
-            vardecl = self.varlists[num]
-            if name in vardecl:
-                return i, vardecl
-        raise ValueError("xxx")
-
     def visit_IDENTIFIERNAME(self, node):
         pos = self.get_pos(node)
         name = node.additional_info
-        try:
-            t = self._search_identifier(name)
-        except ValueError:
-            pass
-        else:
-            i, vardecl = t
-            local = self.scopes.get_local(name)
-            if local is not None:
-                return operations.LocalIdentifier(pos, name, local)
-            else:
-                return operations.VariableIdentifier(pos, i, name)
+        local = self.scopes.get_local(name)
+        if local is not None:
+            return operations.LocalIdentifier(pos, name, local)
         return operations.Identifier(pos, name)
 
     def visit_program(self, node):
@@ -319,7 +307,11 @@
             node = self.dispatch(child)
             if node is not None:
                 nodes.append(node)
-        var_decl = self.varlists.pop().keys()
+        var_decl = self.scopes.identifiers()
+        if not var_decl:
+            var_decl = self.varlists.pop().keys()
+        else:
+            self.varlists.pop()
         func_decl = self.funclists.pop()
         return operations.SourceElements(pos, var_decl, func_decl, nodes, self.sourcename)
 
diff --git a/js/operations.py b/js/operations.py
--- a/js/operations.py
+++ b/js/operations.py
@@ -794,9 +794,8 @@
         return self.identifier
 
 class VariableIdentifier(Expression):
-    def __init__(self, pos, depth, identifier):
+    def __init__(self, identifier):
         self.pos = pos
-        self.depth = depth
         self.identifier = identifier
 
     def __repr__(self):
@@ -816,7 +815,7 @@
     def emit(self, bytecode):
         for node in self.nodes:
             node.emit(bytecode)
-            if isinstance(node, VariableDeclaration) and node.expr is not None:
+            if (isinstance(node, VariableDeclaration) or isinstance(node, LocalVariableDeclaration)) and node.expr is not None:
                 bytecode.emit('POP')
 
 class Variable(Statement):
@@ -892,7 +891,7 @@
 class ForVarIn(Statement):
     def __init__(self, pos, vardecl, lobject, body):
         self.pos = pos
-        assert isinstance(vardecl, VariableDeclaration)
+        assert isinstance(vardecl, VariableDeclaration) or isinstance(vardecl, LocalVariableDeclaration)
         self.iteratorname = vardecl.identifier
         self.object = lobject
         self.body = body
diff --git a/js/test/test_parser.py b/js/test/test_parser.py
--- a/js/test/test_parser.py
+++ b/js/test/test_parser.py
@@ -378,10 +378,12 @@
                     'LOAD_MEMBER'])
 
     def test_store_local(self):
-        self.check("function f() {var x; x = 1}",
+        self.check("function f() {var x; x = 1;}",
+            ['DECLARE_FUNCTION f [] [\n  DECLARE_VAR "x"\n  LOAD_INTCONSTANT 1\n  STORE_LOCAL 0\n]'])
+        self.check("function f() {var x = 1;}",
             ['DECLARE_FUNCTION f [] [\n  DECLARE_VAR "x"\n  LOAD_INTCONSTANT 1\n  STORE_LOCAL 0\n]'])
         self.check('function f() {var x = 1; y = 2;}',
-            ['DECLARE_FUNCTION f [] [\n  DECLARE_VAR "x"\n  LOAD_INTCONSTANT 1\n  STORE_LOCAL 0\n  LOAD_INTCONSTANT 2\n  STORE "y"\n]'])
+            ['DECLARE_FUNCTION f [] [\n  DECLARE_VAR "x"\n  LOAD_INTCONSTANT 1\n  STORE_LOCAL 0\n  POP\n  LOAD_INTCONSTANT 2\n  STORE "y"\n]'])
 
 class TestToAstStatement(BaseTestToAST):
     def setup_class(cls):


More information about the pypy-commit mailing list