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

santagada at codespeak.net santagada at codespeak.net
Wed Jan 3 21:17:48 CET 2007


Author: santagada
Date: Wed Jan  3 21:17:26 2007
New Revision: 36134

Removed:
   pypy/dist/pypy/lang/js/astgen.py
Modified:
   pypy/dist/pypy/lang/js/interpreter.py
   pypy/dist/pypy/lang/js/jsobj.py
   pypy/dist/pypy/lang/js/test/test_interp.py
Log:
more tests and some code cleanup


Modified: pypy/dist/pypy/lang/js/interpreter.py
==============================================================================
--- pypy/dist/pypy/lang/js/interpreter.py	(original)
+++ pypy/dist/pypy/lang/js/interpreter.py	Wed Jan  3 21:17:26 2007
@@ -1,8 +1,30 @@
 
-from pypy.lang.js.astgen import *
 from pypy.lang.js.jsparser import parse
 from pypy.lang.js.jsobj import *
 
+class Node(object):
+    # TODO Add line info for debug
+#    def __init__(self, lineno = 1):
+#        self.lineno = lineno
+    pass
+
+class BinaryOp(Node):
+    def __init__(self, left, right):
+        self.left = left
+        self.right = right
+    
+class BinaryComparisonOp(BinaryOp):
+    """super class for binary operators"""
+    def call(self, ctx):
+        s2 = self.left.call(ctx).GetValue()
+        s4 = self.right.call(ctx).GetValue()
+        return self.decision(s2, s4)
+
+
+class BinaryLogicOp(BinaryOp):
+    """super class for binary operators"""
+    pass
+
 def writer(x):
     print x
 
@@ -27,14 +49,34 @@
         """run the interpreter"""
         return self.script.call(self.global_context)
 
+class PropertyInit(Node):
+    def __init__(self, name, value):
+        self.name = name
+        self.value = value
+    
+    def __repr__(self):
+        return "<%s : %s>"%(str(self.name), str(self.value))
+
+
+
+class Undefined(Node):
+    def __init__(self):
+        pass
+
         
+class Array(Node):
+    def __init__(self, items=()):
+        self.items = items
 
-class __extend__(Array):
     def call(self, ctx):
         d = dict(enumerate(self.items))
         return W_Array(d)
 
-class __extend__(Assign):
+class Assign(Node):
+    def __init__(self, LHSExp, AssignmentExp):
+        self.LHSExp = LHSExp
+        self.AssignmentExp = AssignmentExp
+    
     def call(self, ctx):
         print "Assign LHS = ", self.LHSExp
         v1 = self.LHSExp.call(ctx)
@@ -43,7 +85,10 @@
         v1.PutValue(v3, ctx)
         return v3
 
-class __extend__(Block):
+class Block(Node):
+    def __init__(self, nodes):
+        self.nodes = nodes
+
     def call(self, ctx):
         try:
             last = w_Undefined
@@ -53,7 +98,11 @@
         except ExecutionReturned, e:
             return e.value
 
-class __extend__(Call):
+class Call(Node):
+    def __init__(self, identifier, arglist):
+        self.identifier = identifier
+        self.arglist = arglist
+
     def call(self, ctx):
         name = self.identifier.get_literal()
         if name == 'print':
@@ -64,23 +113,33 @@
             retval = w_obj.Call(ctx=ctx, args=[i for i in self.arglist.call(ctx)])
             return retval
 
-class __extend__(Comma):
+class Comma(BinaryOp):
     def call(self, ctx):
         self.left.call(ctx)
         return self.right.call(ctx)
 
-class __extend__(Dot):
+class Dot(BinaryOp):
     def call(self, ctx):
         w_obj = self.left.call(ctx).GetValue().ToObject()
         name = self.right.get_literal()
         return Reference(name, w_obj)
 
-class __extend__(Function):
+class Function(Node):
+    def __init__(self, name, params, body):
+        self.name = name
+        self.params = params
+        self.body = body
+
     def call(self, ctx):
        w_obj = W_FunctionObject(self, ctx)
        return w_obj
 
-class __extend__(Identifier):
+class Identifier(Node):
+    def __init__(self, name, initialiser=None):
+        self.name = name
+        self.initialiser = initialiser
+    def __str__(self):
+        return "<id %s init: %s>"%(str(self.name), str(self.initialiser))
     def call(self, ctx):
         if self.initialiser is not None:
             ref = ctx.resolve_identifier(self.name)
@@ -90,7 +149,12 @@
     def get_literal(self):
         return self.name
 
-class __extend__(If):
+class If(Node):
+    def __init__(self, condition, thenPart=None, elsePart=None):
+        self.condition = condition
+        self.thenPart = thenPart
+        self.elsePart = elsePart
+
     def call(self, ctx=None):
         temp = self.condition.call(ctx)
         print "if condition = ", temp 
@@ -99,8 +163,11 @@
         else:
             return self.elsePart.call(ctx)
 
-class __extend__(Group):
-    def call(self, ctx = None):
+class Group(Node):
+    def __init__(self, expr):
+        self.expr = expr
+
+    def call(self, ctx):
         return self.expr.call(ctx)
 
 def ARC(x, y):
@@ -124,7 +191,7 @@
     else:
         pass 
 
-class __extend__(Or):
+class Or(BinaryLogicOp):
     def call(self, ctx):
         s2 = self.left.call(ctx).GetValue()
         if s2.ToBoolean():
@@ -132,7 +199,7 @@
         s4 = self.right.call(ctx).GetValue()
         return s4
 
-class __extend__(And):
+class And(BinaryLogicOp):
     def call(self, ctx):
         s2 = self.left.call(ctx).GetValue()
         if not s2.ToBoolean():
@@ -140,14 +207,7 @@
         s4 = self.right.call(ctx).GetValue()
         return s4
 
-
-class __extend__(BinaryOperator):
-    def call(self, ctx):
-        s2 = self.left.call(ctx).GetValue()
-        s4 = self.right.call(ctx).GetValue()
-        return self.decision(s2, s4)
-
-class __extend__(Ge):
+class Ge(BinaryComparisonOp):
     def decision(self, op1, op2):
         s5 = ARC(op1, op2)
         if s5 is None or s5:
@@ -155,7 +215,7 @@
         else:
             return W_Boolean(True)
 
-class __extend__(Gt):
+class Gt(BinaryComparisonOp):
     def decision(self, op1, op2):
         s5 = ARC(op2, op1)
         if s5 is None:
@@ -163,7 +223,7 @@
         else:
             return W_Boolean(s5)
 
-class __extend__(Le):
+class Le(BinaryComparisonOp):
     def decision(self, op1, op2):
         s5 = ARC(op2, op1)
         if s5 is None or s5:
@@ -171,7 +231,7 @@
         else:
             return W_Boolean(True)
 
-class __extend__(Lt):
+class Lt(BinaryComparisonOp):
     def decision(self, op1, op2):
         s5 = ARC(op1, op2)
         if s5 is None:
@@ -187,16 +247,16 @@
     r = x.ToNumber() == y.ToNumber()
     return r
 
-class __extend__(Eq):
+class Eq(BinaryComparisonOp):
     def decision(self, op1, op2):
         return W_Boolean(AEC(op1, op2))
 
-class __extend__(Ne):
+class Ne(BinaryComparisonOp):
     def decision(self, op1, op2):
         return W_Boolean(not AEC(op1, op2))
 
 
-class __extend__(In):
+class In(BinaryComparisonOp):
     def decision(self, op1, op2):
         if not isinstance(op2, W_Object):
             raise ThrowException("TypeError")
@@ -204,7 +264,11 @@
         return W_Boolean(op2.HasProperty(name))
 
 
-class __extend__(Index):
+class Index(Node):
+    def __init__(self, left, expr):
+        self.left = left
+        self.expr = expr
+
     def call(self, ctx):
         w_obj = self.left.call(ctx).GetValue()
         w_member = self.expr.call(ctx).GetValue()
@@ -212,19 +276,24 @@
         name = w_member.ToString()
         return w_obj.Get(name)
 
-class __extend__(List):
+class List(Node):
+    def __init__(self, nodes):
+        self.nodes = nodes
     def call(self, ctx):
         print "nodes = ", self.nodes
         return [node.call(ctx) for node in self.nodes]
 
-class __extend__(Minus):
+class Minus(BinaryComparisonOp):
     def decision(self, op1, op2):
         x = op1.ToNumber()
         y = op2.ToNumber()
         return W_Number(x - y)
 
-class __extend__(New):
-    def call(self, ctx=None):
+class New(Node):
+    def __init__(self, identifier):
+        self.identifier = identifier
+
+    def call(self, ctx):
         obj = W_Object()
         #it should be undefined... to be completed
         constructor = ctx.resolve_identifier(self.identifier).GetValue()
@@ -232,14 +301,20 @@
         constructor.Call(ctx, this = obj)
         return obj
 
-class __extend__(Number):
+class Number(Node):
+    def __init__(self, num):
+        self.num = num
+
     def call(self, ctx):
         return W_Number(self.num)
     
     def get_literal(self):
         return W_Number(self.num).ToString()
 
-class __extend__(ObjectInit):
+class ObjectInit(Node):
+    def __init__(self, properties):
+        self.properties = properties
+
     def call(self, ctx):
         w_obj = W_Object()
         print "properties = ", self.properties
@@ -250,7 +325,7 @@
             w_obj.Put(name, w_expr)
         return w_obj
 
-class __extend__(Plus):
+class Plus(BinaryComparisonOp):
     def decision(self, op1, op2):
         prim_left = op1.ToPrimitive('Number')
         prim_right = op2.ToPrimitive('Number')
@@ -263,7 +338,12 @@
             num_right = prim_right.ToNumber()
             return W_Number(num_left + num_right)
 
-class __extend__(Script):
+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 call(self, ctx):
         for var in self.var_decl:
             ctx.variable.Put(var.name, w_Undefined)
@@ -279,26 +359,45 @@
         except ExecutionReturned, e:
             return e.value
 
-class __extend__(Semicolon):
+class Semicolon(Node):
+    def __init__(self, expr):
+        self.expr = expr
+
     def call(self, ctx=None):
         return self.expr.call(ctx)
 
-class __extend__(String):
+class String(Node):
+    def __init__(self, strval):
+        self.strval = strval
+
     def call(self, ctx=None):
         return W_String(self.strval)
     
     def get_literal(self):
         return W_String(self.strval).ToString()
 
-class __extend__(Return):
+class Return(Node):
+    def __init__(self, expr):
+        self.expr = expr
+
     def call(self, ctx):
         raise ExecutionReturned(self.expr.call(ctx))
 
-class __extend__(Throw):
+class Throw(Node):
+    def __init__(self, exception):
+        self.exception = exception
+
     def call(self, ctx):
         raise ThrowException(self.exception.call(ctx))
 
-class __extend__(Try):
+class Try(Node):
+    # TODO: rewrite to use 'Undefined'
+    def __init__(self, tryblock, catchblock, finallyblock, catchparam):
+        self.tryblock = tryblock
+        self.catchblock = catchblock
+        self.finallyblock = finallyblock
+        self.catchparam = catchparam
+
     def call(self, ctx):
         e = None
         try:
@@ -321,19 +420,165 @@
         
         return tryresult
 
-class __extend__(Undefined):
+class Undefined(Node):
     def call(self, ctx):
         return None
 
-class __extend__(Vars):
+class Vars(Node):
+    def __init__(self, nodes):
+        self.nodes = nodes
+
     def call(self, ctx):
         print self.nodes
         for var in self.nodes:
             print var.name
             var.call(ctx)
 
-class __extend__(While):
+class While(Node):
+    def __init__(self, condition, body):
+        self.condition = condition
+        self.body = body
+
     def call(self, ctx):
         while self.condition.call(ctx).ToBoolean():
             self.body.call(ctx)
 
+def getlist(d):
+    if 'length' not in d:
+        return []
+    lgt = int(d['length'])
+    output = [from_dict(d[str(i)]) for i in range(lgt)]
+    return output
+
+def build_interpreter(d):
+    return from_dict(d)
+
+# FIXME: Continue the translation from if/elif to this dict map
+build_map = {'ARRAY_INIT':Array,
+             'ASSIGN': Assign,
+             'BLOCK': Block}
+
+def from_dict_map(d):
+    if d is None:
+        return d
+    try:
+        build_map[d['type']](d)
+    except KeyError,e:
+        raise NotImplementedError("Don't know how to handle %s" %(d['type'],))
+    
+    
+    
+def from_dict(d):
+    if d is None:
+        return d
+    tp = d['type']
+    if tp == 'ARRAY_INIT':
+        return Array(getlist(d))
+    elif tp == 'ASSIGN':
+        return Assign(from_dict(d['0']), from_dict(d['1']))
+    elif tp == 'BLOCK':
+        return Block(getlist(d))
+    elif tp == 'CALL':
+        return Call(from_dict(d['0']), from_dict(d['1']))
+    elif tp == 'COMMA':
+        return Comma(from_dict(d['0']),from_dict(d['1']))
+    elif tp == 'DOT':
+        return Dot(from_dict(d['0']), from_dict(d['1']))
+    elif tp == 'EQ':
+        return Eq(from_dict(d['0']), from_dict(d['1']))
+    elif tp == 'OR':
+        return Or(from_dict(d['0']), from_dict(d['1']))
+    elif tp == 'AND':
+        return And(from_dict(d['0']), from_dict(d['1']))
+    elif tp == 'FUNCTION':        
+        name = d.get('name', '')
+        body = from_dict(d['body'])
+        if d['params'] == '':
+            params = []
+        else:
+            params = d['params'].split(',')
+        f = Function(name, params, body)
+        return f
+    elif tp == 'GROUP':
+        return Group(from_dict(d['0']))
+    elif tp == 'GE':
+        return Ge(from_dict(d['0']), from_dict(d['1']))
+    elif tp == 'GT':
+        return Gt(from_dict(d['0']), from_dict(d['1']))
+    elif tp == 'IDENTIFIER':
+        return Identifier(d['value'], from_dict(d.get('initializer', None)))
+    elif tp == 'IF':
+        condition = from_dict(d['condition'])
+        if d['thenPart'] == 'null':
+            thenPart = Undefined()
+        else:
+            thenPart = from_dict(d['thenPart'])
+        if d['elsePart'] == 'null':
+            elsePart = Undefined()
+        else:
+            elsePart = from_dict(d['elsePart'])
+        return If(condition,thenPart,elsePart)
+    elif tp == 'IN':
+        return In(from_dict(d['0']), from_dict(d['1']))
+    elif tp == 'INDEX':
+        return Index(from_dict(d['0']), from_dict(d['1']))
+    elif tp == 'LIST':
+        return List(getlist(d))
+    elif tp == 'LE':
+        return Le(from_dict(d['0']), from_dict(d['1']))
+    elif tp == 'LT':
+        return Lt(from_dict(d['0']), from_dict(d['1']))
+    elif tp == 'MINUS':
+        return Minus(from_dict(d['0']), from_dict(d['1']))
+    elif tp == 'NE':
+        return Ne(from_dict(d['0']), from_dict(d['1']))
+    elif tp == 'NEW':
+        return New(d['0']['value'])
+    elif tp == 'NUMBER':
+        return Number(float(d['value']))
+    elif tp == 'OBJECT_INIT':
+        return ObjectInit(getlist(d))
+    elif tp == 'PLUS':
+        return Plus(from_dict(d['0']), from_dict(d['1']))
+    elif tp == 'PROPERTY_INIT':
+        return PropertyInit(from_dict(d['0']), from_dict(d['1']))
+    elif tp == 'RETURN':
+        return Return(from_dict(d['value']))
+    elif tp == 'SCRIPT':
+        if isinstance(d['funDecls'], dict):
+            func_decl = [from_dict(d['funDecls']),]
+        else:
+            func_decl = [from_dict(x) for x in d['funDecls']]
+        
+        if isinstance(d['varDecls'], dict):
+            var_decl = [from_dict(d['varDecls']),]
+        else:
+            var_decl = [from_dict(x) for x in d['varDecls']]
+        return Script(getlist(d), var_decl, func_decl)
+    elif tp == 'SEMICOLON':
+        return Semicolon(from_dict(d['expression']))
+    elif tp == 'STRING':
+        return String(d['value'])
+    elif tp == 'THIS':
+        return Identifier(d['value'])
+    elif tp == 'THROW':
+        return Throw(from_dict(d['exception']))
+    elif tp == 'TRY':
+        finallyblock = None
+        catchblock = None
+        catchparam = ''
+        if 'finallyBlock' in d:
+            finallyblock = from_dict(d['finallyBlock'])
+        if 'catchClauses' in d:
+            #multiple catch clauses is a spidermonkey extension
+            catchblock = from_dict(d['catchClauses']['block'])
+            catchparam = d['catchClauses']['varName']
+        return Try(from_dict(d['tryBlock']), catchblock, finallyblock, catchparam)
+    elif tp == 'VAR':
+        return Vars(getlist(d))
+    elif tp == 'WHILE':
+        body = from_dict(d['body'])
+        condition = from_dict(d['condition'])
+        return While(condition, body)
+    else:
+        raise NotImplementedError("Dont know how to handler %s" % tp)

Modified: pypy/dist/pypy/lang/js/jsobj.py
==============================================================================
--- pypy/dist/pypy/lang/js/jsobj.py	(original)
+++ pypy/dist/pypy/lang/js/jsobj.py	Wed Jan  3 21:17:26 2007
@@ -190,12 +190,30 @@
         print "* end of function call return = ", val
         return val
 
+class W_Array(W_Object):
+    def __init__(self, items):
+        W_Object.__init__(self)
+        self.Put('length', W_Number(0))
+    
+    def Put(self, P, V):
+        if not isinstance(P, str):
+            P = P.ToString()
+        if not self.CanPut(P): return
+        if P in self.propdict:
+            self.propdict[P].value = V
+        else:
+            try:
+                x = int(P)
+            except: # FIXME: forgot the name of the exception
+                x = -1
+            if self.Get('length') < 0: pass
+            self.propdict[P] = Property(P, V)
+    
 class W_Undefined(W_Root):
     def __str__(self):
         return "w_undefined"
     
     def ToNumber(self):
-        # XXX make NaN
         return NaN
 
     def ToBoolean(self):

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 Jan  3 21:17:26 2007
@@ -4,10 +4,9 @@
 
 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.interpreter import *
 from pypy.lang.js.jsobj import W_Number, W_Object, ExecutionContext
 
 
@@ -150,7 +149,7 @@
         """, ["test"])
 
     def test_array_initializer(self):
-        py.test.skip('not ready yet')
+        py.test.skip("not ready yet")
         self.assert_prints("""
         x = [];
         print(x);



More information about the Pypy-commit mailing list