浏览代码

Action language to Rust: simple variable assignments work

Joeri Exelmans 4 年之前
父节点
当前提交
8bbe6f574b

+ 30 - 9
src/sccd/action_lang/codegen/rust.py

@@ -3,9 +3,10 @@ from sccd.action_lang.static.statement import *
 class UnsupportedFeature(Exception):
     pass
 
-class RustGenerator(Visitor):
+class ActionLangRustGenerator(Visitor):
     def __init__(self, w):
         self.w = w
+        self.scopes = []
 
     def default(self, what):
         raise UnsupportedFeature(what)
@@ -22,6 +23,7 @@ class RustGenerator(Visitor):
         self.w.wno(" = ")
         stmt.rhs.accept(self)
         self.w.wnoln(";")
+        self.w.writeln("eprintln!(\"%s\");" % termcolor.colored(stmt.render(),'blue'))
 
     def visit_IfStatement(self, stmt):
         self.w.wno("if ")
@@ -50,9 +52,9 @@ class RustGenerator(Visitor):
         self.w.wno(str(expr.i))
 
     def visit_StringLiteral(self, expr):
-        self.w.wno(expr.string)
+        self.w.wno('"'+expr.string+'"')
 
-    def visit_ArrayLiteral(self, expr):
+    def visit_Array(self, expr):
         self.w.wno("[")
         for el in expr.elements:
             el.accept(self)
@@ -63,11 +65,7 @@ class RustGenerator(Visitor):
         self.w.wno(" (")
 
         if expr.operator == "**":
-            self.w.wno(" pow(")
-            expr.lhs.accept(self)
-            self.w.wno(", ")
-            expr.rhs.accept(self)
-            self.w.wno(")")
+            raise UnsupportedFeature("exponent operator")
         else:
             expr.lhs.accept(self)
             self.w.wno(" %s " % expr.operator
@@ -88,10 +86,32 @@ class RustGenerator(Visitor):
         expr.subexpr.accept(self)
         # self.w.wno(") ")
 
+    def visit_FunctionDeclaration(self, expr):
+        self.w.wno("|")
+        for p in expr.params_decl:
+            p.accept(self)
+            self.w.wno(", ")
+        self.w.wnoln("| = {")
+        self.w.indent()
+        expr.body.accept(self)
+        self.w.dedent()
+        self.w.write("}")
+        self.scopes.append(expr.scope)
+
+    def visit_FunctionCall(self, expr):
+        self.w.wno("(")
+        expr.function.accept(self)
+        self.w.wno(")(")
+        for p in expr.params:
+            p.accept(self)
+            self.w.wno(", ")
+        self.w.wno(")")
+
     def visit_Identifier(self, lval):
-        self.w.wno(lval.name)
+        self.w.wno("sc.data."+lval.name)
 
     def visit_Scope(self, scope):
+        self.w.writeln("#[derive(Default)]")
         self.w.writeln("struct Scope_%s {" % scope.name)
         for v in scope.variables:
             self.w.write("  %s: " % v.name)
@@ -100,6 +120,7 @@ class RustGenerator(Visitor):
         self.w.writeln("}")
         self.w.writeln()
 
+
     def visit__SCCDSimpleType(self, type):
         self.w.wno(type.name
             .replace("int", "i32"))

文件差异内容过多而无法显示
+ 578 - 562
src/sccd/statechart/codegen/rust.py


+ 1 - 1
src/sccd/statechart/static/action.py

@@ -29,7 +29,7 @@ class EvalContext:
     memory: 'MemoryInterface'
 
 @dataclass
-class Action(ABC):
+class Action(ABC, Visitable):
     @abstractmethod
     def exec(self, ctx: EvalContext):
         pass

+ 1 - 1
src/sccd/statechart/static/statechart.py

@@ -3,7 +3,7 @@ from sccd.action_lang.static.scope import *
 from sccd.statechart.static.semantic_configuration import *
 
 @dataclass
-class Statechart(Freezable):
+class Statechart(Freezable, Visitable):
   __slots__ = ["semantics", "scope", "datamodel", "internal_events", "internally_raised_events", "inport_events", "event_outport", "tree"]
 
   def __init__(self, semantics: SemanticConfiguration, scope: Scope, datamodel: Optional[Block], internal_events: Bitmap, internally_raised_events: Bitmap, inport_events: Dict[str, Set[int]], event_outport: Dict[str, str], tree: StateTree):

+ 4 - 1
src/sccd/test/codegen/rust.py

@@ -20,13 +20,16 @@ def compile_test(variants: List[TestVariant], w: IndentingWriter):
     w.writeln("#![allow(unused_variables)]")
     w.writeln("#![allow(dead_code)]")
 
+
     with open(rustlib, 'r') as file:
         data = file.read()
         w.writeln(data)
 
     if len(variants) > 0:
         cd = variants[0].cd
-        compile_statechart(cd.get_default_class(), cd.globals, w)
+        gen = StatechartRustGenerator(w, cd.globals)
+        cd.get_default_class().accept(gen)
+        # compile_statechart(cd.get_default_class(), cd.globals, w)
 
 
     w.writeln("fn main() {")

+ 3 - 3
src/sccd/util/visitable.py

@@ -9,7 +9,7 @@ class Visitable:
     def accept(self, visitor: Visitor):
         typename = type(self).__qualname__.replace(".", "_")
         lookup = "visit_" + typename
-        try:
+        if hasattr(visitor, lookup):
             return getattr(visitor, lookup)(self)
-        except AttributeError:
-            return visitor.default(what)
+        else:
+            return visitor.default(typename)