oppc/pseudocode: support switches
authorDmitry Selyutin <ghostmansd@gmail.com>
Sun, 14 Jan 2024 14:15:19 +0000 (17:15 +0300)
committerDmitry Selyutin <ghostmansd@gmail.com>
Tue, 16 Jan 2024 19:10:07 +0000 (22:10 +0300)
src/openpower/oppc/pc_code.py

index 62063a1fb0452691363938113da14c5fd30b3938..de0150f44d2628c99c9a205aa9bc2fd00b78404f 100644 (file)
@@ -304,6 +304,15 @@ class CodeVisitor(pc_util.Visitor):
             for (level, stmt) in self[transient]:
                 self[node].emit(stmt=stmt, level=level)
 
+    @pc_util.Hook(pc_ast.Overflow)
+    def Overflow(self, node):
+        yield node
+        (value, bits) = ("OPPC_OVERFLOW", "(uint8_t)OPPC_OVERFLOW")
+        transient = self.transient(node=node, value=value, bits=bits)
+        with self.pseudocode(node=node):
+            for (level, stmt) in self[transient]:
+                self[node].emit(stmt=stmt, level=level)
+
     @pc_util.Hook(pc_ast.SubscriptExpr)
     def SubscriptExpr(self, node):
         yield node
@@ -404,6 +413,51 @@ class CodeVisitor(pc_util.Visitor):
                 self[node].emit(stmt=stmt, level=level)
         self[node].emit(stmt="}")
 
+    @pc_util.Hook(pc_ast.SwitchExpr)
+    def SwitchExpr(self, node):
+        yield node
+        subject = self.ccall(name="oppc_int64", node=node, code=[
+            self[node.subject],
+        ])
+        self[node].emit(stmt="switch (")
+        with self[node]:
+            for (level, stmt) in self[subject]:
+                self[node].emit(stmt=stmt, level=level)
+        self[node].emit(") {")
+        with self[node]:
+            for (level, stmt) in self[node.cases]:
+                self[node].emit(stmt=stmt, level=level)
+
+    @pc_util.Hook(pc_ast.Cases)
+    def Cases(self, node):
+        yield node
+        for subnode in node:
+            for (level, stmt) in self[subnode]:
+                self[node].emit(stmt=stmt, level=level)
+
+    @pc_util.Hook(pc_ast.Case)
+    def Case(self, node):
+        yield node
+        for (level, stmt) in self[node.labels]:
+            self[node].emit(stmt=stmt, level=level)
+        for (level, stmt) in self[node.body]:
+            self[node].emit(stmt=stmt, level=level)
+
+    @pc_util.Hook(pc_ast.Labels)
+    def Labels(self, node):
+        yield node
+        if ((len(node) == 1) and isinstance(node[-1], pc_ast.DefaultLabel)):
+            stmt = "default:"
+        else:
+            labels = ", ".join(map(lambda label: str(self[label]), node))
+            stmt = f"case ({labels}):"
+        self[node].emit(stmt=stmt)
+
+    @pc_util.Hook(pc_ast.Label)
+    def Label(self, node):
+        yield node
+        self[node].emit(stmt=str(node))
+
     @pc_util.Hook(pc_ast.Call.Name)
     def CallName(self, node):
         yield node
@@ -427,9 +481,10 @@ class CodeVisitor(pc_util.Visitor):
     @pc_util.Hook(pc_ast.Symbol)
     def Symbol(self, node):
         yield node
-        self.__decls[str(node)].append(node)
         with self.pseudocode(node=node):
-            self[node].emit(stmt=f"&{str(node)}")
+            if str(node) not in ("fallthrough",):
+                self.__decls[str(node)].append(node)
+                self[node].emit(stmt=f"&{str(node)}")
 
     @pc_util.Hook(pc_ast.Node)
     def Node(self, node):