[pypy-svn] r33981 - in pypy/dist/pypy/lang/js: . js test

fijal at codespeak.net fijal at codespeak.net
Tue Oct 31 19:26:41 CET 2006


Author: fijal
Date: Tue Oct 31 19:26:39 2006
New Revision: 33981

Modified:
   pypy/dist/pypy/lang/js/astgen.py
   pypy/dist/pypy/lang/js/interpreter.py
   pypy/dist/pypy/lang/js/js/jsparse.js
   pypy/dist/pypy/lang/js/jsobj.py
   pypy/dist/pypy/lang/js/parser.py
   pypy/dist/pypy/lang/js/test/test_interp.py
Log:
(santagada, fijal) - First version of nested scopes.


Modified: pypy/dist/pypy/lang/js/astgen.py
==============================================================================
--- pypy/dist/pypy/lang/js/astgen.py	(original)
+++ pypy/dist/pypy/lang/js/astgen.py	Tue Oct 31 19:26:39 2006
@@ -1,7 +1,8 @@
 
 from pypy.annotation.pairtype import extendabletype
 from pypy.lang.js.context import ExecutionContext
-from pypy.lang.js.jsobj import W_Object
+from pypy.lang.js.jsobj import W_Object, w_Undefined
+from pypy.lang.js.scope import scope_manager
 
 class Node(object):
     __metaclass__ = extendabletype
@@ -31,16 +32,18 @@
         self.right = right
 
 class Function(Node):
-    def __init__(self, params, body):
+    def __init__(self, params, body, scope):
         self.params = params
         self.body = body
+        self.scope = scope
         w_obj = W_Object({}, body=self)
         #self.scope = Scope(copy(scope.dict))
     
 class Identifier(Node):
-    def __init__(self, name):
+    def __init__(self, name, initialiser):
         self.name = name
-        
+        self.initialiser = initialiser
+
 class Index(Node):
     def __init__(self, left, expr):
         self.left = left
@@ -72,20 +75,12 @@
     def __init__(self, expr):
         self.expr = expr
 
-class Scope(Node):
-    def __init__(self, dict):
-        self.dict = self.dicts
-    
 class Script(Node):
     def __init__(self, nodes, var_decl, func_decl):
         self.nodes = nodes
         self.var_decl = var_decl
         self.func_decl = func_decl
 
-#    def from_dict(d):
-#        return Script(self.getlist(d), d['varDecl'], d['funcDecl'])
-#    from_dict = staticmethod(from_dict)
-
 class Semicolon(Node):
     def __init__(self, expr):
         self.expr = expr
@@ -94,6 +89,11 @@
     def __init__(self, strval):
         self.strval = strval
 
+class Vars(Node):
+    def __init__(self, nodes):
+        self.nodes = nodes
+        [scope_manager.add_variable(id.name, w_Undefined) for id in nodes]
+
 def getlist(d):
     if 'length' not in d:
         return []
@@ -102,6 +102,8 @@
     return output
 
 def from_dict(d):
+    if d is None:
+        return d
     tp = d['type']
     if tp == 'SCRIPT':
         # XXX: Cannot parse it right now
@@ -111,7 +113,7 @@
     elif tp == 'NUMBER':
         return Number(float(d['value']))
     elif tp == 'IDENTIFIER':
-        return Identifier(d['value'])
+        return Identifier(d['value'], from_dict(d.get('initializer', None)))
     elif tp == 'LIST':
         return List(getlist(d))
     elif tp == 'CALL':
@@ -130,9 +132,15 @@
         return Dot(from_dict(d['0']), from_dict(d['1']))
     elif tp == 'INDEX':
         return Index(from_dict(d['0']), from_dict(d['1']))
-    elif tp == 'FUNCTION':        
-        return Function(d['params'], from_dict(d['body']))
+    elif tp == 'FUNCTION':
+        scope = scope_manager.enter_scope()
+        body = from_dict(d['body'])
+        f = Function(d['params'], body, scope)
+        scope_manager.leave_scope()
+        return f
     elif tp == 'RETURN':
         return Return(from_dict(d['value']))
+    elif tp == 'VAR':
+        return Vars(getlist(d))
     else:
         raise NotImplementedError("Dont know how to handler %s" % tp)

Modified: pypy/dist/pypy/lang/js/interpreter.py
==============================================================================
--- pypy/dist/pypy/lang/js/interpreter.py	(original)
+++ pypy/dist/pypy/lang/js/interpreter.py	Tue Oct 31 19:26:39 2006
@@ -2,6 +2,7 @@
 from pypy.lang.js.astgen import *
 from pypy.lang.js.context import ExecutionContext
 from pypy.lang.js.jsobj import W_Number, W_String, W_Object, w_Undefined
+from pypy.lang.js.scope import scope_manager
 
 def writer(x):
     print x
@@ -13,7 +14,7 @@
 class __extend__(Assign):
     def call(self, context):
         val = self.expr.call(context)
-        context.assign(self.identifier.name, val)
+        scope_manager.set_variable(self.identifier.name, val)
         return val
 
 class __extend__(Number):
@@ -32,8 +33,12 @@
 
 class __extend__(Function):
     def call(self, context=None):
-        return self.body.call()
-    
+        backup_scope = scope_manager.current_scope
+        scope_manager.current_scope = self.scope
+        retval = self.body.call()
+        scope_manager.current_scope = backup_scope
+        return retval
+
 class __extend__(Plus):
     def call(self, context=None):
         left = self.left.call(context).GetValue()
@@ -58,7 +63,9 @@
 
 class __extend__(Identifier):
     def call(self, context=None):
-        return context.access(self.name)
+        if self.initialiser is not None:
+            scope_manager.set_variable(self.name, self.initialiser.call(context))
+        return scope_manager.get_variable(self.name)
     
     def get_literal(self):
         return self.name
@@ -79,7 +86,7 @@
         if name == 'print':
             writer(",".join([i.ToString() for i in self.arglist.call(context)]))
         else:
-            w_obj = context.access(name)
+            w_obj = scope_manager.get_variable(name)
             return w_obj.Call()
 
 class __extend__(List):
@@ -122,3 +129,8 @@
 class __extend__(Return):
     def call(self, context=None):
         raise ExecutionReturned(self.expr.call(context))
+
+class __extend__(Vars):
+    def call(self, context=None):
+        for var in self.nodes:
+            var.call(context)

Modified: pypy/dist/pypy/lang/js/js/jsparse.js
==============================================================================
--- pypy/dist/pypy/lang/js/js/jsparse.js	(original)
+++ pypy/dist/pypy/lang/js/js/jsparse.js	Tue Oct 31 19:26:39 2006
@@ -283,11 +283,15 @@
     var n = ++Node.indentLevel;
     var s = "{\n" + INDENTATION.repeat(n) + "'type': '" + tokenstr(this.type) + "'";
     for (i = 0; i < a.length; i++) {
-        val = a[i].value + ""
-        if (val.search("\n") != -1) {
-            s += ",\n" + INDENTATION.repeat(n) + "'" + a[i].id + "': " + val + " ";
+        val = a[i].value + "";
+        if (val.search("},{") != -1) {
+            s += ",\n" + INDENTATION.repeat(n) + "'" + a[i].id + "': [" + val + "]";
         } else {
-            s += ",\n" + INDENTATION.repeat(n) + "'" + a[i].id + "': '" + val + "'";
+            if (val.search("\n") != -1) {
+                s += ",\n" + INDENTATION.repeat(n) + "'" + a[i].id + "': " + val + " ";
+            } else {
+                s += ",\n" + INDENTATION.repeat(n) + "'" + a[i].id + "': '" + val + "'";
+            }
         }
     }
     n = --Node.indentLevel;

Modified: pypy/dist/pypy/lang/js/jsobj.py
==============================================================================
--- pypy/dist/pypy/lang/js/jsobj.py	(original)
+++ pypy/dist/pypy/lang/js/jsobj.py	Tue Oct 31 19:26:39 2006
@@ -6,11 +6,11 @@
     def GetValue(self):
         return self
 
-    def ToPrimitive(self):
+    def ToPrimitive(self, hint=""):
         return self
 
-    def ToNumber(self):
-        raise SeePage(37)
+    #def ToNumber(self):
+    #    return int(self.ToPrimitive(hint="number"))
 
     def ToString(self):
         return str(self)
@@ -24,6 +24,10 @@
 class W_Undefined(W_Root):
     def __str__(self):
         return ""
+    
+    def ToNumber(self):
+        # XXX make NaN
+        return 0
 
 class W_Null(W_Root):
     def __str__(self):
@@ -37,7 +41,12 @@
         if self.boolval:
             return "true"
         return "false"
-
+    
+    def ToNumber(self):
+        if self.boolval:
+            return 1
+        return 0
+    
 class W_String(W_Root):
     def __init__(self, strval):
         # XXX: Should be unicode object
@@ -89,7 +98,7 @@
         return W_String(str(self))
     
     def DefaultValue(self, hint):
-        assert hint == "string"
+        #if hint == "string":
         tostring_meth = self.Get("toString")
         if isinstance(tostring_meth, W_Object):
             return tostring_meth.Call(this=self)
@@ -98,6 +107,21 @@
             retval = valueof_meth.Call(this=self)
             # XXX: check primitiveness of retval
             return retval
+##    else:
+##            if isinstance(valueof_meth, W_Object):
+##                retval = valueof_meth.Call(this=self)
+##                # XXX: check primitiveness of retval
+##                return retval
+##            tostring_meth = self.Get("toString")
+##            if isinstance(tostring_meth, W_Object):
+##                return tostring_meth.Call(this=self)
+        return w_Undefined
+    
+    def ToPrimitive(self, hint=""):
+        return self.DefaultValue(hint)
+    
+    def ToNumber(self):
+        return self.ToPrimitive("number").ToNumber(hint="number")
     
     def ToString(self):
         return str(self.DefaultValue(hint="string"))
@@ -108,8 +132,8 @@
         
         return w_Undefined
 
-    def ToPrimitive(self):
-        raise SeePage(37)
+    #def ToPrimitive(self, hint=""):
+    #    return DefaultValue(hint)
 
     #def ToString(self):
     #    raise SeePage(42)

Modified: pypy/dist/pypy/lang/js/parser.py
==============================================================================
--- pypy/dist/pypy/lang/js/parser.py	(original)
+++ pypy/dist/pypy/lang/js/parser.py	Tue Oct 31 19:26:39 2006
@@ -50,4 +50,3 @@
         open("/tmp/out", "w").write("\n".join(output))
         raise
     return d['code']
-

Modified: pypy/dist/pypy/lang/js/test/test_interp.py
==============================================================================
--- pypy/dist/pypy/lang/js/test/test_interp.py	(original)
+++ pypy/dist/pypy/lang/js/test/test_interp.py	Tue Oct 31 19:26:39 2006
@@ -16,7 +16,7 @@
         #    s.call()
         l = []
         interpreter.writer = l.append
-        Script([Semicolon(Call(Identifier('print'), List([Number(1), Number(2)])))],[],[]).call()
+        Script([Semicolon(Call(Identifier('print', None), List([Number(1), Number(2)])))],[],[]).call()
         assert l == ['1,2']
 
     def assert_prints(self, code, assval):
@@ -59,3 +59,6 @@
     
     def test_function_returns(self):
         self.assert_prints(parse_d('x=function(){return 1;}; print(x()+x());'), ["2"])
+    
+    def test_var_declartion(self):
+        self.assert_prints(parse_d('var x = 3; print(x+x);'), ["6"])



More information about the Pypy-commit mailing list