1. Pypy
  2. Untitled project
  3. lang-js

Commits

stepahn  committed 8fe1457

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

  • Participants
  • Parent commits 88a7fc2
  • Branches default

Comments (0)

Files changed (3)

File js/astbuilder.py

View file
     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)
         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):
             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)
 

File js/operations.py

View file
         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):
     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):
 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

File js/test/test_parser.py

View file
                     '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):