[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