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

santagada at codespeak.net santagada at codespeak.net
Wed Dec 20 02:28:08 CET 2006


Author: santagada
Date: Wed Dec 20 02:27:52 2006
New Revision: 35910

Removed:
   pypy/dist/pypy/lang/js/context.py
Modified:
   pypy/dist/pypy/lang/js/astgen.py
   pypy/dist/pypy/lang/js/interpreter.py
   pypy/dist/pypy/lang/js/jsobj.py
   pypy/dist/pypy/lang/js/reference.py
   pypy/dist/pypy/lang/js/test/test_interp.py
Log:
24 of 32 test passing, and a lot less hacks


Modified: pypy/dist/pypy/lang/js/astgen.py
==============================================================================
--- pypy/dist/pypy/lang/js/astgen.py	(original)
+++ pypy/dist/pypy/lang/js/astgen.py	Wed Dec 20 02:27:52 2006
@@ -1,8 +1,6 @@
 
 from pypy.annotation.pairtype import extendabletype
-from pypy.lang.js.context import ExecutionContext
-from pypy.lang.js.jsobj import W_Object, w_Undefined
-from pypy.lang.js.scope import scope_manager
+from pypy.lang.js.jsobj import W_Object, w_Undefined, ExecutionContext
 
 class Node(object):
     __metaclass__ = extendabletype
@@ -47,11 +45,10 @@
         self.right = right
 
 class Function(Node):
-    def __init__(self, name, params, body, scope):
+    def __init__(self, name, params, body):
         self.name = name
         self.params = params
         self.body = body
-        self.scope = scope
 
 class Group(Node):
     def __init__(self, expr):
@@ -107,8 +104,6 @@
 class Script(Node):
     def __init__(self, nodes, var_decl, func_decl):
         self.nodes = nodes
-        [scope_manager.add_variable(id.name, w_Undefined) for id in var_decl]
-        [scope_manager.add_variable(id.name, id) for id in func_decl]
         self.var_decl = var_decl
         self.func_decl = func_decl
 
@@ -190,14 +185,12 @@
         return Dot(from_dict(d['0']), from_dict(d['1']))
     elif tp == 'FUNCTION':        
         name = d.get('name', '')
-        scope = scope_manager.enter_scope()
         body = from_dict(d['body'])
         if d['params'] == '':
             params = []
         else:
             params = d['params'].split(',')
-        f = Function(name, params, body, scope)
-        scope_manager.leave_scope()
+        f = Function(name, params, body)
         return f
     elif tp == 'GROUP':
         return Group(from_dict(d['0']))

Modified: pypy/dist/pypy/lang/js/interpreter.py
==============================================================================
--- pypy/dist/pypy/lang/js/interpreter.py	(original)
+++ pypy/dist/pypy/lang/js/interpreter.py	Wed Dec 20 02:27:52 2006
@@ -1,9 +1,7 @@
 
 from pypy.lang.js.astgen import *
 from pypy.lang.js.jsparser import parse
-from pypy.lang.js.context import *
-from pypy.lang.js.jsobj import W_Number, W_String, W_Object 
-from pypy.lang.js.jsobj import w_Undefined, W_Arguments, W_Boolean, NaN
+from pypy.lang.js.jsobj import *
 
 def writer(x):
     print x
@@ -41,7 +39,7 @@
         
 
 class __extend__(Array):
-    def call(self, context):
+    def call(self, ctx):
         d = dict(enumerate(self.items))
         return W_Array(d)
 
@@ -53,85 +51,80 @@
         return v3
 
 class __extend__(Block):
-    def call(self, context):
+    def call(self, ctx):
         try:
             last = w_Undefined
             for node in self.nodes:
-                last = node.call(context)
+                last = node.call(ctx)
             return last
         except ExecutionReturned, e:
             return e.value
 
 class __extend__(Call):
-    def call(self, context):
+    def call(self, ctx):
         name = self.identifier.get_literal()
         if name == 'print':
-            writer(",".join([i.GetValue().ToString() for i in self.arglist.call(context)]))
-        else:
-            backup_scope = scope_manager.current_scope
-            
-            w_obj = context.access(name)
-            scope_manager.current_scope = w_obj.function.scope
-            
-            retval = w_obj.Call(context=context, args=[i for i in self.arglist.call(context)])
-            scope_manager.current_scope = backup_scope
+            writer(",".join([i.GetValue().ToString() for i in self.arglist.call(ctx)]))
+        else:    
+            w_obj = ctx.resolve_identifier(name).GetValue()
+            retval = w_obj.Call(ctx=ctx, args=[i for i in self.arglist.call(ctx)])
             return retval
 
 class __extend__(Comma):
-    def call(self, context):
-        self.left.call(context)
-        return self.right.call(context)
+    def call(self, ctx):
+        self.left.call(ctx)
+        return self.right.call(ctx)
 
 class __extend__(Dot):
-    def call(self, context=None):
-        w_obj = self.left.call(context).GetValue().ToObject()
+    def call(self, ctx=None):
+        w_obj = self.left.call(ctx).GetValue().ToObject()
         name = self.right.get_literal()
         return w_obj.Get(name)
         
-    def put(self, context, val):
+    def put(self, ctx, val):
         print self.left.name, self.right.name, val
         if isinstance(self.left,Identifier):
-            obj = context.access(self.left.name)
+            obj = ctx.access(self.left.name)
             print obj.Class
             obj.dict_w[self.right.name] = val
         elif isinstance(self.left,Dot):
-            obj = self.left.put(context, val)
+            obj = self.left.put(ctx, val)
 
         return obj
 
-        #w_obj = self.left.put(context).GetValue().ToObject()
+        #w_obj = self.left.put(ctx).GetValue().ToObject()
         #name = self.right.get_literal()
         #w_obj.dict_w[self.name] = val
         
 
 class __extend__(Function):
-    def call(self, context):
-       w_obj = W_Object({}, function=self)
+    def call(self, ctx):
+       w_obj = W_FunctionObject(self, ctx)
        return w_obj
 
 class __extend__(Identifier):
     def call(self, ctx):
-        # if self.initialiser is not None:
-        #     context.assign(self.name, self.initialiser.call(context))
-        value = ctx.resolve_identifier(self.name)
-        return value
+        if self.initialiser is not None:
+            ref = ctx.resolve_identifier(self.name)
+            ref.PutValue(self.initialiser.call(ctx), ctx)
+        return ctx.resolve_identifier(self.name)
 
-    def put(self, context, val, obj=None):            
-        context.assign(self.name, val)
+    def put(self, ctx, val, obj=None):            
+        ctx.assign(self.name, val)
     
     def get_literal(self):
         return self.name
 
 class __extend__(If):
-    def call(self, context=None):
-        if self.condition.call(context).ToBoolean():
-            return self.thenPart.call(context)
+    def call(self, ctx=None):
+        if self.condition.call(ctx).ToBoolean():
+            return self.thenPart.call(ctx)
         else:
-            return self.elsePart.call(context)
+            return self.elsePart.call(ctx)
 
 class __extend__(Group):
-    def call(self, context = None):
-        return self.expr.call(context)
+    def call(self, ctx = None):
+        return self.expr.call(ctx)
 
 def ARC(x, y):
     """
@@ -154,9 +147,9 @@
         pass 
 
 class __extend__(Gt):
-    def call(self, context = None):
-        s2 = self.left.call(context).GetValue()
-        s4 = self.right.call(context).GetValue()
+    def call(self, ctx = None):
+        s2 = self.left.call(ctx).GetValue()
+        s4 = self.right.call(ctx).GetValue()
         s5 = ARC(s4, s2)
         if s5 is None:
             return W_Boolean(False)
@@ -164,9 +157,9 @@
             return W_Boolean(s5)
 
 class __extend__(Lt):
-    def call(self, context = None):
-        s2 = self.left.call(context).GetValue()
-        s4 = self.right.call(context).GetValue()
+    def call(self, ctx = None):
+        s2 = self.left.call(ctx).GetValue()
+        s4 = self.right.call(ctx).GetValue()
         s5 = ARC(s2, s4)
         if s5 is None:
             return W_Boolean(False)
@@ -174,34 +167,30 @@
             return W_Boolean(s5)
 
 class __extend__(Index):
-    def call(self, context=None):
-        w_obj = self.left.call(context).GetValue()
-        w_member = self.expr.call(context).GetValue()
+    def call(self, ctx=None):
+        w_obj = self.left.call(ctx).GetValue()
+        w_member = self.expr.call(ctx).GetValue()
         w_obj = w_obj.ToObject()
         name = w_member.ToString()
         return w_obj.Get(name)
 
 class __extend__(List):
-    def call(self, context=None):
-        return [node.call(context) for node in self.nodes]
+    def call(self, ctx):
+        return [node.call(ctx) for node in self.nodes]
 
 class __extend__(New):
-    def call(self, context=None):
-        try:
-            constructor = context.access(self.identifier)
-        except NameError:
-            constructor = scope_manager.get_variable(self.identifier)
-        obj = W_Object({})
-        obj.Class = 'Object'
+    def call(self, ctx=None):
+        obj = W_Object()
         #it should be undefined... to be completed
-        obj.dict_w['prototype'] = constructor.dict_w['prototype']
-        constructor.Call(context, this = obj)
+        constructor = ctx.resolve_identifier(self.identifier).GetValue()
+        obj.Put('prototype', constructor.Get('prototype'))
+        constructor.Call(ctx, this = obj)
         
         return obj
 
 
 class __extend__(Number):
-    def call(self, context):
+    def call(self, ctx):
         return W_Number(self.num)
     
     def get_literal(self):
@@ -209,18 +198,19 @@
         return str(W_Number(self.num))
 
 class __extend__(ObjectInit):
-    def call(self, context=None):
-        w_obj = W_Object({})
+    def call(self, ctx):
+        w_obj = W_Object()
         for property in self.properties:
             name = property.name.get_literal()
-            w_expr = property.value.call(context).GetValue()
+            w_expr = property.value.call(ctx).GetValue()
             w_obj.Put(name, w_expr)
         return w_obj
 
 class __extend__(Plus):
-    def call(self, context=None):
-        left = self.left.call(context).GetValue()
-        right = self.right.call(context).GetValue()
+    def call(self, ctx):
+        print "left", self.left.call(ctx)
+        left = self.left.call(ctx).GetValue()
+        right = self.right.call(ctx).GetValue()
         prim_left = left.ToPrimitive('Number')
         prim_right = right.ToPrimitive('Number')
         # INSANE
@@ -236,25 +226,9 @@
 
 class __extend__(Script):
     def call(self, ctx):
-        # ncontext = ExecutionContext(context)
-        # for i, item in enumerate(params):
-        #     try:
-        #         temp = args[i]
-        #     except IndexError:
-        #         temp = w_Undefined
-        #     ncontext.assign(item, temp)
-        # 
-        # for var in self.var_decl:
-        #     if first:
-        #         ncontext.globals[var.name] = w_Undefined
-        #     else:
-        #         ncontext.locals[var.name] = w_Undefined
-        
-        # w_Arguments = W_Arguments(dict([(str(x),y) for x,y in enumerate(args)]))
-        # ncontext.assign('arguments', w_Arguments)
-        # 
-        # ncontext.assign('this', this)
-        
+        for var in self.var_decl:
+            ctx.variable.Put(var.name, w_Undefined)
+                
         try:
             last = w_Undefined
             for node in self.nodes:
@@ -264,38 +238,38 @@
             return e.value
 
 class __extend__(Semicolon):
-    def call(self, context=None):
-        return self.expr.call(context)
+    def call(self, ctx=None):
+        return self.expr.call(ctx)
 
 class __extend__(String):
-    def call(self, context=None):
+    def call(self, ctx=None):
         return W_String(self.strval)
     
     def get_literal(self):
         return self.strval
 
 class __extend__(Return):
-    def call(self, context=None):
-        raise ExecutionReturned(self.expr.call(context))
+    def call(self, ctx):
+        raise ExecutionReturned(self.expr.call(ctx))
 
 class __extend__(Throw):
-    def call(self, context=None):
-        raise ThrowException(self.exception.call(context))
+    def call(self, ctx):
+        raise ThrowException(self.exception.call(ctx))
 
 class __extend__(Try):
-    def call(self, context=None):
+    def call(self, ctx):
         e = None
         try:
-            tryresult = self.tryblock.call(context)
+            tryresult = self.tryblock.call(ctx)
         except ThrowException, excpt:
             e = excpt
-            ncontext = ExecutionContext(context)
-            ncontext.assign(self.catchparam, e.exception)
+            nctx = ExecutionContext(ctx)
+            nctx.assign(self.catchparam, e.exception)
             if self.catchblock is not None:
-                tryresult = self.catchblock.call(ncontext)
+                tryresult = self.catchblock.call(nctx)
         
         if self.finallyblock is not None:
-            tryresult = self.finallyblock.call(context)
+            tryresult = self.finallyblock.call(ctx)
         
         #if there is no catchblock reraise the exception
         if (e is not None) and (self.catchblock is None):
@@ -309,7 +283,9 @@
 
 class __extend__(Vars):
     def call(self, ctx):
+        print self.nodes
         for var in self.nodes:
+            print var.name
             var.call(ctx)
 
 class __extend__(While):

Modified: pypy/dist/pypy/lang/js/jsobj.py
==============================================================================
--- pypy/dist/pypy/lang/js/jsobj.py	(original)
+++ pypy/dist/pypy/lang/js/jsobj.py	Wed Dec 20 02:27:52 2006
@@ -1,3 +1,6 @@
+# encoding: utf-8
+
+from pypy.lang.js.reference import Reference
 
 class SeePage(NotImplementedError):
     pass
@@ -30,7 +33,7 @@
         return self
 
     def ToString(self):
-        return str(self)
+        return ''
     
     def ToObject(self):
         return self
@@ -39,40 +42,31 @@
         return NaN
     
     def __repr__(self):
-        return "<%s(%s)>" % (self.__class__.__name__, str(self))
+        return "<%s(%s)>" % (self.__class__.__name__, self.ToString())
 
 class W_Primitive(W_Root):
     """unifying parent for primitives"""
     def ToPrimitive(self, PreferredType):
         return self
 
-    
-
 class W_Object(W_Root):
-    def __init__(self, function=None):
+    def __init__(self):
         self.propdict = {}
         self.propdict['toString'] = Property('toString', 
-                                             W_Builtin(self.__str__)) # FIXME: Not working
+                                             W_Builtin(self.__str__))
         self.propdict['prototype'] = Property('prototype', w_Undefined,
                                               DontDelete=True)
         self.Prototype = None
         self.Class = "Object"
-        self.function = function
         self.scope = []
     
-    def Call(self, context, args=[], this = None): # FIXME: Context-ng
-        if self.function is not none:
-            return self.function.body.call(context=context, args=args,
-                                           params=self.function.params,
-                                           this=this)
-        else:
-            print "returning common object"
-            return W_Object()
+    def Call(self, ctx, args=[], this = None):
+        return W_Object()
     
     def Get(self, P):
         if P in self.propdict: return self.propdict[P].value
-        if self.prototype is None: return w_Undefined
-        return self.prototype.Get(P) # go down the prototype chain
+        if self.Prototype is None: return w_Undefined
+        return self.Prototype.Get(P) # go down the prototype chain
     
     def CanPut(self, P):
         if P in self.propdict:
@@ -121,18 +115,49 @@
     
     ToPrimitive = DefaultValue
 
-    def __str__(self):
+    def ToString(self):
         return "[object %s]"%(self.Class,)
     
 class W_Arguments(W_Object):
-    pass
+    def __init__(self, callee, args):
+        W_Object.__init__(self)
+        self.Put('callee', callee)
+        self.Put('length', len(args))
+        for i, arg in enumerate(args):
+            self.Put(str(i), arg)
 
 class ActivationObject(W_Object):
     """The object used on function calls to hold arguments and this"""
     def __init__(self):
-        W_Object.__init__()
-        self.propdict.pop(P)
-
+        W_Object.__init__(self)
+        self.propdict.pop("toString")
+        self.propdict.pop("prototype")
+
+class W_FunctionObject(W_Object):
+    def __init__(self, function, ctx):
+        # TODO: See page 80
+        W_Object.__init__(self)
+        self.function = function
+        self.Class = "Function"
+        self.Prototype = None # TODO: See page 95 section 15.3.3.1
+        self.scope = ctx.scope[:]
+    
+    def Call(self, ctx, args=[], this=None):
+        print args
+        act = ActivationObject()
+        for i, arg in enumerate(args):
+            try:
+                value = args[i]
+            except IndexError:
+                value = w_Undefined
+            act.Put(self.function.params[i], value)
+        act.Put('this', this)
+        print act.propdict
+        w_Arguments = W_Arguments(self, args)
+        act.Put('arguments', w_Arguments)
+        newctx = function_context(self.scope, act, this)
+        val = self.function.body.call(ctx=newctx)
+        return val
 
 class W_Undefined(W_Root):
     def __str__(self):
@@ -173,12 +198,16 @@
     def __str__(self):
         return self.strval
 
+    def ToString(self):
+        return self.strval
+    
     def ToBoolean(self):
         return bool(self.strval)
 
 
 class W_Number(W_Primitive):
     def __init__(self, floatval):
+        print "novo numero"
         self.floatval = floatval
 
     def ToString(self):
@@ -223,4 +252,66 @@
 w_Undefined = W_Undefined()
 w_Null = W_Null()
 
+class ExecutionContext(object):
+    def __init__(self):
+        self.scope = []
+        self.this = None
+        self.variable = None
+        self.property = Property('',w_Undefined) #Attribute flags for new vars
+    
+    def assign(self, name, value):
+        """
+        assign to property name, creating it if it doesn't exist
+        """
+        pass
+        #ref = self.resolve_identifier(name)
+        #if ref.
+    
+    def get_global(self):
+        return self.scope[-1]
+            
+    def push_object(self, obj):
+        """push object into scope stack"""
+        self.scope.insert(0, obj)
+        self.variable = obj
+    
+    def pop_object(self):
+        """docstring for pop_object"""
+        return self.scope.pop(0)
+        
+    def resolve_identifier(self, identifier):
+        for obj in self.scope:
+            if obj.HasProperty(identifier):
+                return Reference(identifier, obj)
+        
+        return Reference(identifier)
+    
+
+def global_context(w_global):
+    ctx = ExecutionContext()
+    ctx.push_object(w_global)
+    ctx.this = w_global
+    ctx.property = Property('', w_Undefined, DontDelete=True)
+    return ctx
+
+def function_context(scope, activation, this=None):
+    ctx = ExecutionContext()
+    ctx.scope = scope
+    ctx.push_object(activation)
+    if this is None:
+        ctx.this = ctx.get_global()
+    else:
+        ctx.this = this
+    
+    ctx.property = Property('', w_Undefined, DontDelete=True)
+    return ctx
+    
+def eval_context(calling_context):
+    ctx = ExecutionContext()
+    ctx.scope = calling_context.scope[:]
+    ctx.this = calling_context.this
+    ctx.variable = calling_context.variable
+    ctx.property = Property('', w_Undefined)
+    return ctx
+
         
\ No newline at end of file

Modified: pypy/dist/pypy/lang/js/reference.py
==============================================================================
--- pypy/dist/pypy/lang/js/reference.py	(original)
+++ pypy/dist/pypy/lang/js/reference.py	Wed Dec 20 02:27:52 2006
@@ -15,4 +15,7 @@
         base = self.baseobject
         if self.baseobject is None:
             base = ctx.scope[-1]
-        base.Put(self.propertyname, w)
\ No newline at end of file
+        base.Put(self.propertyname, w)
+        
+    def __str__(self):
+        return str(self.baseobject) + " : " + str(self.propertyname)
\ No newline at end of file

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	Wed Dec 20 02:27:52 2006
@@ -1,14 +1,14 @@
+
+import sys
+from StringIO import StringIO
+
 import py.test
 
 from pypy.lang.js.astgen import *
 from pypy.lang.js import interpreter
 from pypy.lang.js.jsparser import parse
 from pypy.lang.js.interpreter import ThrowException
-from pypy.lang.js.jsobj import W_Number, W_Object
-from pypy.lang.js.context import ExecutionContext
-
-import sys
-from StringIO import StringIO
+from pypy.lang.js.jsobj import W_Number, W_Object, ExecutionContext
 
 
 def js_is_on_path():
@@ -21,7 +21,7 @@
 
 class TestInterp(object):
     def test_simple(self):
-        assert Plus(Number(3), Number(4)).call().floatval == 7
+        assert Plus(Number(3), Number(4)).call(ExecutionContext()).floatval == 7
         #    s = Script([Semicolon(Plus(Number(3), Number(4)))], [], [])
         #    s.call()
         l = []
@@ -79,8 +79,10 @@
     def test_function_returns(self):
         self.assert_prints('x=function(){return 1;}; print(x()+x());', ["2"])
     
-    def test_var_declartion(self):
+    def test_var_declaration(self):
+        self.assert_prints('var x = 3; print(x);', ["3"])
         self.assert_prints('var x = 3; print(x+x);', ["6"])
+
     
     def test_var_scoping(self):
         self.assert_prints("""



More information about the Pypy-commit mailing list