Author: Stephan <[email protected]>
Branch:
Changeset: r109:0657a7b641ac
Date: 2011-07-17 21:09 +0200
http://bitbucket.org/pypy/lang-js/changeset/0657a7b641ac/
Log: started a ExecutionContext replacement
diff --git a/js/jsexecution_context.py b/js/jsexecution_context.py
new file mode 100644
--- /dev/null
+++ b/js/jsexecution_context.py
@@ -0,0 +1,60 @@
+from js.jsobj import RO, Property
+
+class ExecutionContext(object):
+ def __init__(self, parent=None):
+ self.values = {}
+ self.parent = parent
+
+ def resolve_identifier(self, ctx, identifier):
+ try:
+ p = self._identifier_get(identifier)
+ assert isinstance(p, Property)
+ return p.value
+ except KeyError:
+ from js.jsobj import W_String
+ from js.execution import ThrowException
+ raise ThrowException(W_String("ReferenceError: %s is not defined"
% identifier))
+
+ def assign(self, name, value):
+ assert name is not None
+ try:
+ p = self._identifier_get(identifier)
+ assert isinstance(p, Property)
+ if p.flags & RO:
+ return
+ p.value = value
+ except KeyError:
+ p = Property(identifier, value)
+ self._identifier_set(identifier, p)
+
+ def _identifier_set_local(self, identifier, value):
+ self.values[identifier] = value
+
+ def _identifier_get_local(self, identifier):
+ return self.values[identifier]
+
+ def _identifier_is_local(self, identifier):
+ return identifier in self.values
+
+ def _identifier_set(self, identifier, value):
+ try:
+ self._identifier_set_if_local(identifier, value)
+ except KeyError:
+ self._identifier_set_local(identifier, value)
+
+ def _identifier_set_if_local(self, identifier, value):
+ if self._identifier_is_local(identifier):
+ self._identifier_set_local(identifier, value)
+ return
+ elif self.parent:
+ self.parent._identifier_set_if_local(identifier, value)
+ return
+ raise KeyError
+
+ def _identifier_get(self, identifier):
+ try:
+ return self._identifier_get_local(identifier)
+ except KeyError:
+ if self.parent:
+ return self.parent._identifier_get(identifier)
+ raise KeyError
diff --git a/js/test/test_execution_context.py
b/js/test/test_execution_context.py
new file mode 100644
--- /dev/null
+++ b/js/test/test_execution_context.py
@@ -0,0 +1,124 @@
+import py
+
+from js.jsexecution_context import ExecutionContext
+from js.execution import ThrowException
+from js.jsobj import Property
+
+class TestExecutionContext(object):
+ def test_identifier_set_local(self):
+ context = ExecutionContext()
+ context._identifier_set_local('foo', 1)
+ assert context.values['foo'] == 1
+
+ def test_identifier_get_local(self):
+ context = ExecutionContext()
+ context.values['foo'] = 1
+ assert context._identifier_get_local('foo') == 1
+
+ def test_identifier_is_local(sefl):
+ context = ExecutionContext()
+ context.values['foo'] = 1
+ assert context._identifier_is_local('foo') is True
+ assert context._identifier_is_local('bar') is False
+
+
+ def test_identifier_get(self):
+ context = ExecutionContext()
+ context._identifier_set_local('foo', 1)
+ context._identifier_set_local('bar', 2)
+ assert context._identifier_get('foo') == 1
+ assert context._identifier_get('bar') == 2
+
+ def test_identifier_get_from_parent(self):
+ parent = ExecutionContext()
+ parent._identifier_set_local('foo', 1)
+ context = ExecutionContext(parent)
+ context._identifier_set_local('bar', 2)
+ assert context._identifier_get('foo') == 1
+ assert context._identifier_get('bar') == 2
+
+ def test_identifier_get_from_parents(self):
+ grandparent = ExecutionContext()
+ parent = ExecutionContext(grandparent)
+ context = ExecutionContext(parent)
+
+ grandparent._identifier_set_local('foo', 0)
+ parent._identifier_set_local('foo', 1)
+ parent._identifier_set_local('bar', 2)
+
+ assert context._identifier_get('foo') == 1
+ assert context._identifier_get('bar') == 2
+
+ def test_identifier_get_local_precedence(self):
+ parent = ExecutionContext()
+ context = ExecutionContext(parent)
+ parent._identifier_set_local('foo', 1)
+ context._identifier_set_local('foo', 2)
+ assert context._identifier_get('foo') == 2
+ assert parent._identifier_get('foo') == 1
+
+ def test_identifier_get_undefined_identifier(self):
+ parent = ExecutionContext()
+ context = ExecutionContext(parent)
+ py.test.raises(KeyError, context._identifier_get, 'foo')
+ py.test.raises(KeyError, parent._identifier_get, 'foo')
+
+ def test_identifier_set_if_local(self):
+ context = ExecutionContext()
+ context._identifier_set_local('foo', 0)
+ context._identifier_set_if_local('foo', 1)
+ assert context._identifier_get_local('foo') == 1
+
+ def test_identifier_set_if_local_not_local(self):
+ context = ExecutionContext()
+ py.test.raises(KeyError, context._identifier_set_if_local, 'foo', 1)
+
+ def test_identifier_set_if_local_on_parent(self):
+ parent = ExecutionContext()
+ context = ExecutionContext(parent)
+ parent._identifier_set_local('foo', None)
+
+ context._identifier_set_if_local('foo', 1)
+ assert parent._identifier_get_local('foo') == 1
+
+ def test_identifier_set_if_local_not_in_parent(self):
+ parent = ExecutionContext()
+ context = ExecutionContext(parent)
+ py.test.raises(KeyError, context._identifier_set_if_local, 'foo', 1)
+
+ def test_identifier_set_if_local_on_parents(self):
+ grandparent = ExecutionContext()
+ parent = ExecutionContext(grandparent)
+ context = ExecutionContext(parent)
+
+ grandparent._identifier_set_local('foo', 0)
+ parent._identifier_set_local('foo', 1)
+
+ context._identifier_set_if_local('foo', 99)
+
+ assert context._identifier_get('foo') == 99
+ assert parent._identifier_get('foo') == 99
+
+ py.test.raises(KeyError, context._identifier_get_local,'foo')
+ assert parent._identifier_get_local('foo') == 99
+ assert grandparent._identifier_get_local('foo') == 0
+
+ def test_resolve_identifier(self):
+ parent = ExecutionContext()
+ context = ExecutionContext(parent)
+ parent._identifier_set_local('foo', Property('foo', 0))
+ context._identifier_set_local('bar', Property('foo', 1))
+
+ ctx = None
+ assert context.resolve_identifier(ctx, 'foo') == 0
+ assert context.resolve_identifier(ctx, 'bar') == 1
+ py.test.raises(ThrowException, context.resolve_identifier, ctx, 'baz')
+
+ def test_assign(self):
+ parent = ExecutionContext()
+ context = ExecutionContext(parent)
+ p_foo = Property('foo', 0)
+ p_bar = Property('foo', 1)
+ parent._identifier_set_local('foo', p_foo)
+ context._identifier_set_local('bar', p_bar)
+
diff --git a/js/test/test_interp.py b/js/test/test_interp.py
--- a/js/test/test_interp.py
+++ b/js/test/test_interp.py
@@ -1,4 +1,3 @@
-
import py
from js import interpreter
from js.operations import IntNumber, FloatNumber, Position, Plus
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit