Author: Stephan <step...@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): _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit