[pypy-svn] r52400 - in pypy/branch/jit-refactoring/pypy/lang/js: . doc test

fijal at codespeak.net fijal at codespeak.net
Tue Mar 11 22:21:12 CET 2008


Author: fijal
Date: Tue Mar 11 22:21:11 2008
New Revision: 52400

Modified:
   pypy/branch/jit-refactoring/pypy/lang/js/doc/bytecode.txt
   pypy/branch/jit-refactoring/pypy/lang/js/jscode.py
   pypy/branch/jit-refactoring/pypy/lang/js/operations.py
   pypy/branch/jit-refactoring/pypy/lang/js/test/test_parser.py
Log:
general non-progress. showcase the problem with js parser.


Modified: pypy/branch/jit-refactoring/pypy/lang/js/doc/bytecode.txt
==============================================================================
--- pypy/branch/jit-refactoring/pypy/lang/js/doc/bytecode.txt	(original)
+++ pypy/branch/jit-refactoring/pypy/lang/js/doc/bytecode.txt	Tue Mar 11 22:21:11 2008
@@ -18,6 +18,16 @@
 
 stores the last value on stack into identifierx
 
+STORE_ELEMENT <identifier>
+
+identifier[last_element_on_the_stack] = previous_element_on_the_stack
+note that in javascript a.b is exactly the same as a['b'], just that
+first one can be eventually speed up
+
+LOAD_ARRAY <num>
+
+create array out of num elements on the stack
+
 Arithmetic binary operations:
 (all pops two values and pushes on stack the result)
 

Modified: pypy/branch/jit-refactoring/pypy/lang/js/jscode.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/lang/js/jscode.py	(original)
+++ pypy/branch/jit-refactoring/pypy/lang/js/jscode.py	Tue Mar 11 22:21:11 2008
@@ -1,5 +1,5 @@
 
-from pypy.lang.js.jsobj import W_IntNumber
+from pypy.lang.js.jsobj import W_IntNumber, W_FloatNumber, W_String
 
 class JsCode(object):
     """ That object stands for code of a single javascript function
@@ -7,11 +7,12 @@
     def __init__(self):
         self.opcodes = []
 
-    def emit(self, operation, args):
+    def emit(self, operation, *args):
         try:
-            self.opcodes.append(OpcodeMap[operation](args))
+            self.opcodes.append(OpcodeMap[operation](*args))
         except KeyError:
             raise ValueError("Unknown opcode %s" % (operation,))
+    emit._annspecialcase_ = 'specialize:arg(1)'
 
     def __repr__(self):
         return "\n".join([repr(i) for i in self.opcodes])
@@ -59,9 +60,8 @@
         return w_Undefined
 
 class LOAD_INTCONSTANT(Opcode):
-    def __init__(self, args):
-        assert len(args) == 1
-        self.w_intvalue = W_IntNumber(int(args[0]))
+    def __init__(self, value):
+        self.w_intvalue = W_IntNumber(int(value))
 
     def eval(self, ctx):
         return self.w_intvalue
@@ -69,10 +69,32 @@
     def __repr__(self):
         return 'LOAD_INTCONSTANT %s' % (self.w_intvalue.intval,)
 
+class LOAD_FLOATCONSTANT(Opcode):
+    def __init__(self, value):
+        self.w_floatvalue = W_FloatNumber(float(value))
+
+    def eval(self, ctx):
+        return self.w_floatvalue
+
+    def __repr__(self):
+        return 'LOAD_FLOATCONSTANT %s' % (self.w_floatvalue.floatval,)
+
+class LOAD_STRINGCONSTANT(Opcode):
+    def __init__(self, value):
+        self.w_stringvalue = W_String(value)
+
+    def eval(self, ctx):
+        return self.w_stringvalue
+
+    def get_literal(self):
+        return W_String(self.strval).ToString()
+
+    def __repr__(self):
+        return 'LOAD_STRINGCONSTANT "%s"' % (self.w_stringvalue.strval,)
+
 class LOAD_VARIABLE(Opcode):
-    def __init__(self, args):
-        assert len(args) == 1
-        self.identifier = args[0]
+    def __init__(self, identifier):
+        self.identifier = identifier
 
     def eval(self, ctx):
         return ctx.resolve_identifier(self.identifier)
@@ -80,6 +102,20 @@
     def __repr__(self):
         return 'LOAD_VARIABLE "%s"' % (self.identifier,)
 
+class LOAD_ARRAY(Opcode):
+    def __init__(self, counter):
+        self.counter = counter
+
+    def eval(self, ctx):
+        proto = ctx.get_global().Get('Array').Get('prototype')
+        array = W_Array(ctx, Prototype=proto, Class = proto.Class)
+        for i in range(len(self.nodes)):
+            array.Put(str(i), self.nodes[i].eval(ctx).GetValue())
+        return array
+
+    def __repr__(self):
+        return 'LOAD_ARRAY %d' % (self.counter,)
+
 OpcodeMap = {}
 
 for name, value in locals().items():

Modified: pypy/branch/jit-refactoring/pypy/lang/js/operations.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/lang/js/operations.py	(original)
+++ pypy/branch/jit-refactoring/pypy/lang/js/operations.py	Tue Mar 11 22:21:11 2008
@@ -84,29 +84,36 @@
         bytecode.emit('LOAD_UNDEFINED')
 
 class PropertyInit(Expression):
-    def __init__(self, identifier, expr):
-        self.identifier = identifier
-        assert isinstance(identifier, str)
+    def __init__(self, pos, identifier, expr):
+        self.pos = pos
+        self.identifier = identifier.name
         self.expr = expr
     
     def emit(self, bytecode):
+        XXX # not sure what to do here, think later
         self.expr.emit(bytecode)
-        bytecode.emit('STORE', [self.identifier])
+        bytecode.emit('STORE', self.identifier)
 
 class Array(ListOp):
-    def eval(self, ctx):
-        proto = ctx.get_global().Get('Array').Get('prototype')
-        array = W_Array(ctx, Prototype=proto, Class = proto.Class)
-        for i in range(len(self.nodes)):
-            array.Put(str(i), self.nodes[i].eval(ctx).GetValue())
-        return array
+    def emit(self, bytecode):
+        for element in self.nodes:
+            element.emit(bytecode)
+        bytecode.emit('LOAD_ARRAY', len(self.nodes))
 
 class Assignment(Expression):
-    def __init__(self, pos, left, right, atype):
+    def __init__(self, pos, left, right, operand):
         self.pos = pos
-        self.left = left
+        self.identifier = left.name
         self.right = right
-        self.type = atype
+        self.operand = operand
+
+    def emit(self, bytecode):
+        op = self.operand
+        XXX
+        if op == '==':
+            bytecode.emit('STORE', self.identifier)
+        else:
+            XXX
 
     def eval(self, ctx):
         v1 = self.left.eval(ctx)
@@ -278,7 +285,7 @@
         self.name = name
 
     def emit(self, bytecode):
-        bytecode.emit('LOAD_VARIABLE', [self.name])
+        bytecode.emit('LOAD_VARIABLE', self.name)
         
 #    def get_literal(self):
 #        return self.name
@@ -741,28 +748,27 @@
         self.num = num
 
     def emit(self, bytecode):
-        bytecode.emit('LOAD_INTCONSTANT', [self.num])
+        bytecode.emit('LOAD_INTCONSTANT', self.num)
 
 class FloatNumber(BaseNumber):
     def __init__(self, pos, num):
         self.pos = pos
         self.num = num
 
-    def eval(self, ctx):
-        return W_FloatNumber(float(self.num))
+    def emit(self, bytecode):
+        bytecode.emit('LOAD_FLOATCONSTANT', self.num)
 
 class String(Expression):
     def __init__(self, pos, strval):
         self.pos = pos
         self.strval = self.string_unquote(strval)
-    
-    def eval(self, ctx):
-        return W_String(self.strval)
-    
-    def get_literal(self):
-        return W_String(self.strval).ToString()
+
+    def emit(self, bytecode):
+        bytecode.emit('LOAD_STRINGCONSTANT', self.strval)
     
     def string_unquote(self, string):
+        # XXX I don't think this works, it's very unlikely IMHO
+        #     test it
         temp = []
         stop = len(string)-1
         # XXX proper error
@@ -786,7 +792,6 @@
                 temp.append(c)
             last = c
         return ''.join(temp)
-    
 
 class ObjectInit(ListOp):
     def eval(self, ctx):

Modified: pypy/branch/jit-refactoring/pypy/lang/js/test/test_parser.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/lang/js/test/test_parser.py	(original)
+++ pypy/branch/jit-refactoring/pypy/lang/js/test/test_parser.py	Tue Mar 11 22:21:11 2008
@@ -138,7 +138,9 @@
         result1 = self.evaluator.dispatch(tree)
         assert result1 == n
         return tree
-        
+
+    def parse_raises(self, s):
+        py.test.raises(ParseError, self.parse, s)
 
     def parse_and_eval_all(self, l):
         for i in l:
@@ -184,6 +186,9 @@
         self.parse('{}')
         self.parse('{x:1}') #per spec {x:1,} should not be supported
         self.parse('{x:1,y:2}')
+
+    def test_invalid_expression(self):
+        self.parse_raises('(1+2)=3')
     
 class TestStatements(BaseGrammarTest):
     def setup_class(cls):
@@ -293,6 +298,10 @@
 #         w_Object = W_Object(Prototype=W_Object())
 #         w_Global.Put('Object', w_Object)
 #         return ast.eval(global_context(w_Global))
+
+    def check(self, source, expected):
+        bytecode = self.compile(source)
+        assert bytecode == expected
     
     def test_get_pos(self):
         from pypy.lang.js import operations
@@ -306,21 +315,23 @@
         assert not isinstance(t, Symbol)
         pos = astb.get_pos(t)
         assert pos.start == 0
-        
+
     def test_primaryexpression(self):
-        bytecode = self.compile('(6)')
-        assert bytecode == ['LOAD_INTCONSTANT 6']
-        bytecode = self.compile('((((6))))')
-        assert bytecode == ['LOAD_INTCONSTANT 6']
-        bytecode = self.compile('x')
-        assert bytecode == ['LOAD_VARIABLE "x"']
-        # w_array = self.eval_expr('[1,2,3]')
-        # assert w_array.ToString(self.ctx) == '1,2,3'
-        w_identifier = self.eval_expr('x')
-        py.test.raises(ThrowException, w_identifier.GetValue)
-        w_object = self.eval_expr('{x:1}')
-        assert w_object.ToString(self.ctx) == '[object Object]'
-        assert w_object.Get('x').ToNumber() == 1
+        self.check('(6)', ['LOAD_INTCONSTANT 6'])
+        self.check('((((6))))', ['LOAD_INTCONSTANT 6'])
+        self.check('x', ['LOAD_VARIABLE "x"'])
+        self.check('[1,2,3.3,"abc"]', [
+            'LOAD_INTCONSTANT 1',
+            'LOAD_INTCONSTANT 2',
+            'LOAD_FLOATCONSTANT 3.3',
+            'LOAD_STRINGCONSTANT "abc"',
+            'LOAD_ARRAY 4'])
+        self.check('x = 3', [
+            'LOAD_INTCONSTANT 3',
+            'STORE "x"'])
+        self.check('{x:1}', [
+            'LOAD_INTCONSTANT 1',
+            'LOAD_OBJECT ["x"]'])
     
     def test_expression(self):
         w_num = self.eval_expr('1 - 1 - 1')



More information about the Pypy-commit mailing list