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

cfbolz at codespeak.net cfbolz at codespeak.net
Sun May 6 11:09:00 CEST 2007


Author: cfbolz
Date: Sun May  6 11:08:59 2007
New Revision: 42729

Modified:
   pypy/dist/pypy/lang/js/newparser.py
   pypy/dist/pypy/lang/js/operations.py
   pypy/dist/pypy/lang/js/test/test_new_parser.py
Log:
first sketch at a transformer to get the evaluation trees the js interpreter
works with out of the parse trees the new parser produces.


Modified: pypy/dist/pypy/lang/js/newparser.py
==============================================================================
--- pypy/dist/pypy/lang/js/newparser.py	(original)
+++ pypy/dist/pypy/lang/js/newparser.py	Sun May  6 11:08:59 2007
@@ -1,29 +1,84 @@
 from pypy.rlib.parsing.ebnfparse import parse_ebnf, make_parse_function
 from pypy.rlib.parsing.parsing import ParseError, Rule
+from pypy.rlib.parsing.tree import RPythonVisitor, Symbol
+from pypy.lang.js.jsobj import W_Number
+from pypy.lang.js import operations
 import sys
 
-try:
-    t = open("jsgrammar.txt").read()
-    regexs, rules, ToAST = parse_ebnf(t)
-except ParseError,e:
-    print e.nice_error_message(filename="jsgrammar.txt",source=t)
-    sys.exit(1)
-
-def setstartrule(rules, start):
-    "takes the rule start and put it on the beginning of the rules"
-    oldpos = 0
-    newrules = [Rule("hacked_first_symbol", [[start, "EOF"]])] + rules
-    return newrules
-
-if len(sys.argv) == 1:
-    parse = make_parse_function(regexs, rules, eof=True)
-else:
-    parse = make_parse_function(regexs, setstartrule(rules,sys.argv[1]), eof=True)
-
-print rules[2].nonterminal
-source = raw_input()
-while source != "":
-    t = parse(source).children[0].visit(ToAST())[0]
-    print t
-    t.view()
-    source = raw_input()
+##try:
+##    t = open("jsgrammar.txt").read()
+##    regexs, rules, ToAST = parse_ebnf(t)
+##except ParseError,e:
+##    print e.nice_error_message(filename="jsgrammar.txt",source=t)
+##    sys.exit(1)
+##
+##def setstartrule(rules, start):
+##    "takes the rule start and put it on the beginning of the rules"
+##    oldpos = 0
+##    newrules = [Rule("hacked_first_symbol", [[start, "EOF"]])] + rules
+##    return newrules
+##
+##if len(sys.argv) == 1:
+##    parse = make_parse_function(regexs, rules, eof=True)
+##else:
+##    parse = make_parse_function(regexs, setstartrule(rules,sys.argv[1]), eof=True)
+##
+##print rules[2].nonterminal
+##source = raw_input()
+##while source != "":
+##    t = parse(source).children[0].visit(ToAST())[0]
+##    print t
+##    t.view()
+##    source = raw_input()
+
+class EvalTreeBuilder(RPythonVisitor):
+    BINOP_TO_CLS = {
+        '+': operations.Plus,
+        '-': operations.Minus,
+        '*': operations.Mult,
+        '/': operations.Div,
+        '%': operations.Mod,
+    }
+    UNOP_TO_CLS = {
+        '+': operations.UPlus,
+        '-': operations.UMinus,
+    }
+    def get_instance(self, symbol, cls):
+        assert isinstance(symbol, Symbol)
+        source_pos = symbol.token.source_pos
+        # XXX some of the source positions are not perfect
+        return cls(None, "no clue what self.type is used for",
+                   symbol.additional_info, 
+                   source_pos.lineno,
+                   source_pos.columnno,
+                   source_pos.columnno + len(symbol.additional_info))
+
+    def visit_DECIMALLITERAL(self, node):
+        result = self.get_instance(node, operations.Number)
+        result.num = float(node.additional_info)
+        return result
+
+    def binaryop(self, node):
+        left = self.dispatch(node.children[0])
+        for i in range((len(node.children) - 1) // 2):
+            op = node.children[i * 2 + 1]
+            result = self.get_instance(
+                    op, self.BINOP_TO_CLS[op.additional_info])
+            right = self.dispatch(node.children[i * 2 + 2])
+            result.left = left
+            result.right = right
+            left = result
+        return left
+
+    visit_additiveexpression = binaryop
+    visit_multiplicativeexpression = binaryop
+
+    def visit_unaryexpression(self, node):
+        op = node.children[0]
+        result = self.get_instance(
+                op, self.UNOP_TO_CLS[op.additional_info])
+        child = self.dispatch(node.children[1])
+        result.expr = child
+        result.postfix = False
+        return result
+

Modified: pypy/dist/pypy/lang/js/operations.py
==============================================================================
--- pypy/dist/pypy/lang/js/operations.py	(original)
+++ pypy/dist/pypy/lang/js/operations.py	Sun May  6 11:08:59 2007
@@ -4,6 +4,7 @@
 Implements the javascript operations nodes for the interpretation tree
 """
 
+#XXX * imports are bad
 from pypy.lang.js.jsobj import *
 from pypy.lang.js.jsparser import JsSyntaxError
 from pypy.rlib.parsing.ebnfparse import Symbol, Nonterminal

Modified: pypy/dist/pypy/lang/js/test/test_new_parser.py
==============================================================================
--- pypy/dist/pypy/lang/js/test/test_new_parser.py	(original)
+++ pypy/dist/pypy/lang/js/test/test_new_parser.py	Sun May  6 11:08:59 2007
@@ -4,6 +4,7 @@
 from pypy.rlib.parsing.ebnfparse import parse_ebnf, make_parse_function
 from pypy.rlib.parsing.parsing import ParseError, Rule
 from pypy.rlib.parsing.tree import RPythonVisitor
+from pypy.lang.js.newparser import EvalTreeBuilder
 from pypy import conftest
 import sys
 
@@ -277,3 +278,23 @@
         self.parse('function z (a,b,c,d,e) {;}')
     
         
+class TestToEvalTree(BaseGrammarTest):
+    def setup_class(cls):
+        cls.parse = parse_func('expression')
+
+    def to_etree(self, s):
+        return EvalTreeBuilder().dispatch(self.parse(s))
+
+    def test_primary(self):
+        etree = self.to_etree('(6)')
+        w_num = etree.eval(None)
+        assert w_num.ToNumber() == 6
+        etree = self.to_etree('((((6))))')
+        w_num = etree.eval(None)
+        assert w_num.ToNumber() == 6
+        etree = self.to_etree('1 - 1 - 1')
+        w_num = etree.eval(None)
+        assert w_num.ToNumber() == -1
+        etree = self.to_etree('-(6 * (6 * 6)) + 6 - 6')
+        w_num = etree.eval(None)
+        assert w_num.ToNumber() == -216


More information about the pypy-svn mailing list