[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