[pypy-svn] r52416 - in pypy/branch/jit-refactoring/pypy/lang/js: . doc test
fijal at codespeak.net
fijal at codespeak.net
Wed Mar 12 15:14:38 CET 2008
Author: fijal
Date: Wed Mar 12 15:14:37 2008
New Revision: 52416
Modified:
pypy/branch/jit-refactoring/pypy/lang/js/astbuilder.py
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:
first test in test_parser passes. everything else fails. progress.
Modified: pypy/branch/jit-refactoring/pypy/lang/js/astbuilder.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/lang/js/astbuilder.py (original)
+++ pypy/branch/jit-refactoring/pypy/lang/js/astbuilder.py Wed Mar 12 15:14:37 2008
@@ -1,6 +1,6 @@
from pypy.rlib.parsing.tree import RPythonVisitor, Symbol, Nonterminal
from pypy.lang.js import operations
-
+from pypy.rlib.parsing.parsing import ParseError
class ASTBuilder(RPythonVisitor):
BINOP_TO_CLS = {
@@ -275,11 +275,21 @@
return left
def visit_assignmentexpression(self, node):
+ from pypy.lang.js.operations import Identifier, Member, MemberDot
pos = self.get_pos(node)
left = self.dispatch(node.children[0])
atype = node.children[1].additional_info
right = self.dispatch(node.children[2])
- return operations.Assignment(pos, left, right, atype)
+ if isinstance(left, Identifier):
+ return operations.SimpleAssignment(pos, left, right, atype)
+ elif isinstance(left, Member):
+ return operations.MemberAssignment(pos, left.left, left.right,
+ right, atype)
+ elif isinstance(left, MemberDot):
+ return operations.MemberDotAssignment(pos, left.left, left.right,
+ right, atype)
+ else:
+ raise ParseError(left.pos, "Invalid lefthand expression")
visit_assignmentexpressionnoin = visit_assignmentexpression
def visit_emptystatement(self, node):
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 Wed Mar 12 15:14:37 2008
@@ -18,11 +18,11 @@
stores the last value on stack into identifierx
-STORE_ELEMENT <identifier>
+STORE_MEMBER
-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
+take from stack: right side, element and where to store and store
+where[element] = right. XXX can be optimized further for direct member
+assignement
LOAD_ARRAY <num>
@@ -45,6 +45,13 @@
PREDECR, POSTDECR, PREINCR, POSTINCR
decrement and increment (++, --) prefix and postfix
+object creation:
+
+LOAD_OBJECT <list of parameters>
+
+Takes one element per one parameter from the stack and initializes
+object this way.
+
control flow:
XXX
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 Wed Mar 12 15:14:37 2008
@@ -23,9 +23,6 @@
return all([i == j for i, j in zip(self.opcodes, list_of_opcodes)])
class Opcode(object):
- def __init__(self, args):
- raise NotImplementedError("Purely abstract")
-
def eval(self, ctx, stack):
""" Execute in context ctx
"""
@@ -34,6 +31,9 @@
def __eq__(self, other):
return repr(self) == other
+ def __repr__(self):
+ return self.__class__.__name__
+
class BaseBinaryComparison(Opcode):
def eval(self, ctx):
s2 = self.left.eval(ctx).GetValue()
@@ -116,6 +116,27 @@
def __repr__(self):
return 'LOAD_ARRAY %d' % (self.counter,)
+class STORE_MEMBER(Opcode):
+ def eval(self, ctx):
+ XXX
+
+class STORE(Opcode):
+ def __init__(self, name):
+ self.name = name
+
+ def eval(self, ctx):
+ XXX
+
+ def __repr__(self):
+ return 'STORE "%s"' % self.name
+
+class LOAD_OBJECT(Opcode):
+ def __init__(self, listofnames):
+ self.listofnames = listofnames
+
+ def __repr__(self):
+ return 'LOAD_OBJECT %r' % (self.listofnames,)
+
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 Wed Mar 12 15:14:37 2008
@@ -90,9 +90,7 @@
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)
class Array(ListOp):
def emit(self, bytecode):
@@ -101,15 +99,68 @@
bytecode.emit('LOAD_ARRAY', len(self.nodes))
class Assignment(Expression):
+ pass
+
+class SimpleAssignment(Assignment):
def __init__(self, pos, left, right, operand):
- self.pos = pos
+ assert isinstance(left, Identifier)
self.identifier = left.name
self.right = right
+ self.pos = pos
+ self.operand = operand
+
+ def emit(self, bytecode):
+ self.right.emit(bytecode)
+ bytecode.emit('STORE', self.identifier)
+
+class MemberAssignment(Assignment):
+ def __init__(self, pos, what, item, right, operand):
+ # XXX we can optimise here what happens if what is identifier,
+ # but let's leave it alone for now
+ self.pos = pos
+ self.what = what
+ self.item = item
+ self.right = right
+ self.operand = operand
+
+ def emit(self, bytecode):
+ self.right.emit(bytecode)
+ self.item.emit(bytecode)
+ self.what.emit(bytecode)
+ bytecode.emit('STORE_MEMBER')
+
+class MemberDotAssignment(Assignment):
+ def __init__(self, pos, what, item, right, operand):
+ self.pos = pos
+ self.what = what
+ assert isinstance(item, Identifier)
+ self.itemname = item.name
+ self.right = right
+ self.operand = operand
+
+ def emit(self, bytecode):
+ self.right.emit(bytecode)
+ bytecode.emit('LOAD_STRINGCONSTANT', self.itemname)
+ self.what.emit(bytecode)
+ bytecode.emit('STORE_MEMBER')
+
+class StuffAssignment(Expression):
+ def __init__(self, pos, left, right, operand):
+ self.pos = pos
+ # check the sanity of lefthandside
+ if isinstance(left, Identifier):
+ self.identifier = left.name
+ self.single_assignement = True
+ elif isinstance(left, Member):
+ import pdb
+ pdb.set_trace()
+ self.lefthandside = left
+ self.single_assignement = False
+ self.right = right
self.operand = operand
def emit(self, bytecode):
op = self.operand
- XXX
if op == '==':
bytecode.emit('STORE', self.identifier)
else:
@@ -794,6 +845,13 @@
return ''.join(temp)
class ObjectInit(ListOp):
+ def emit(self, bytecode):
+ names = []
+ for prop in self.nodes:
+ prop.emit(bytecode)
+ names.append(prop.identifier)
+ bytecode.emit('LOAD_OBJECT', names)
+
def eval(self, ctx):
w_obj = create_object(ctx, 'Object')
for prop in self.nodes:
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 Wed Mar 12 15:14:37 2008
@@ -139,9 +139,6 @@
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:
self.parse_and_evaluate(i)
@@ -186,9 +183,6 @@
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):
@@ -326,14 +320,28 @@
'LOAD_FLOATCONSTANT 3.3',
'LOAD_STRINGCONSTANT "abc"',
'LOAD_ARRAY 4'])
+ self.check('x[3] = 3', [
+ 'LOAD_INTCONSTANT 3',
+ 'LOAD_INTCONSTANT 3',
+ 'LOAD_VARIABLE "x"',
+ 'STORE_MEMBER'])
+ self.check('x.x = 3', [
+ 'LOAD_INTCONSTANT 3',
+ 'LOAD_STRINGCONSTANT "x"',
+ 'LOAD_VARIABLE "x"',
+ 'STORE_MEMBER'])
self.check('x = 3', [
'LOAD_INTCONSTANT 3',
'STORE "x"'])
self.check('{x:1}', [
'LOAD_INTCONSTANT 1',
- 'LOAD_OBJECT ["x"]'])
+ "LOAD_OBJECT ['x']"])
+
+ def test_raising(self):
+ py.test.raises(ParseError, self.check, '1=2', [])
def test_expression(self):
+ py.test.skip("Not yet")
w_num = self.eval_expr('1 - 1 - 1')
assert w_num.ToNumber() == -1
w_num = self.eval_expr('-(6 * (6 * 6)) + 6 - 6')
More information about the Pypy-commit
mailing list