add <-iea operator
[soc.git] / src / soc / decoder / pseudo / parser.py
index 6abe1913a204d3bf7b6683e28fda08ae94fc4840..bd05b4e9e8c2f11d7014e5c1fa36f044b5f8a8df 100644 (file)
@@ -23,7 +23,7 @@ import ast
 # Helper function
 
 
-def Assign(left, right):
+def Assign(left, right, iea_mode):
     names = []
     print("Assign", left, right)
     if isinstance(left, ast.Name):
@@ -107,6 +107,7 @@ def make_eq_compare(arg):
 
 
 binary_ops = {
+    "^": ast.BitXor(),
     "&": ast.BitAnd(),
     "|": ast.BitOr(),
     "+": ast.Add(),
@@ -209,6 +210,7 @@ class PowerParser:
     precedence = (
         ("left", "EQ", "GT", "LT", "LE", "GE", "LTU", "GTU"),
         ("left", "BITOR"),
+        ("left", "BITXOR"),
         ("left", "BITAND"),
         ("left", "PLUS", "MINUS"),
         ("left", "MULT", "DIV", "MOD"),
@@ -318,7 +320,8 @@ class PowerParser:
     # augassign: ('+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' |
     #             '<<=' | '>>=' | '**=' | '//=')
     def p_expr_stmt(self, p):
-        """expr_stmt : testlist ASSIGN testlist
+        """expr_stmt : testlist ASSIGNEA testlist
+                     | testlist ASSIGN testlist
                      | testlist """
         print("expr_stmt", p)
         if len(p) == 2:
@@ -326,6 +329,7 @@ class PowerParser:
             #p[0] = ast.Discard(p[1])
             p[0] = p[1]
         else:
+            iea_mode = p[2] == '<-iea'
             name = None
             if isinstance(p[1], ast.Name):
                 name = p[1].id
@@ -354,7 +358,7 @@ class PowerParser:
             print("expr assign", name, p[1])
             if name and name in self.gprs:
                 self.write_regs.add(name)  # add to list of regs to write
-            p[0] = Assign(p[1], p[3])
+            p[0] = Assign(p[1], p[3], iea_mode)
 
     def p_flow_stmt(self, p):
         "flow_stmt : return_stmt"
@@ -379,9 +383,9 @@ class PowerParser:
         p[0] = ast.Break()
 
     def p_for_stmt(self, p):
-        """for_stmt : FOR test EQ test TO test COLON suite
+        """for_stmt : FOR atom EQ test TO test COLON suite
+                    | DO atom EQ test TO test COLON suite
         """
-        p[0] = ast.While(p[2], p[4], [])
         # auto-add-one (sigh) due to python range
         start = p[4]
         end = ast.BinOp(p[6], ast.Add(), ast.Constant(1))
@@ -439,6 +443,7 @@ class PowerParser:
                       | comparison LT comparison
                       | comparison GT comparison
                       | comparison BITOR comparison
+                      | comparison BITXOR comparison
                       | comparison BITAND comparison
                       | PLUS comparison
                       | comparison MINUS
@@ -643,20 +648,21 @@ class PowerParser:
 
 
 class GardenSnakeParser(PowerParser):
-    def __init__(self, lexer=None):
+    def __init__(self, lexer=None, debug=False):
         PowerParser.__init__(self)
+        self.debug = debug
         if lexer is None:
             lexer = IndentLexer(debug=0)
         self.lexer = lexer
         self.tokens = lexer.tokens
         self.parser = yacc.yacc(module=self, start="file_input_end",
-                                debug=False, write_tables=False)
+                                debug=debug, write_tables=False)
 
         self.sd = create_pdecode()
 
     def parse(self, code):
         # self.lexer.input(code)
-        result = self.parser.parse(code, lexer=self.lexer, debug=False)
+        result = self.parser.parse(code, lexer=self.lexer, debug=self.debug)
         return ast.Module(result)
 
 
@@ -665,8 +671,8 @@ class GardenSnakeParser(PowerParser):
 #from compiler import misc, syntax, pycodegen
 
 class GardenSnakeCompiler(object):
-    def __init__(self):
-        self.parser = GardenSnakeParser()
+    def __init__(self, debug=False):
+        self.parser = GardenSnakeParser(debug=debug)
 
     def compile(self, code, mode="exec", filename="<string>"):
         tree = self.parser.parse(code)