txlyre 1 năm trước cách đây
mục cha
commit
fa0fdbde5c
1 tập tin đã thay đổi với 52 bổ sung4 xóa
  1. 52 4
      langs/wm/wmc.py

+ 52 - 4
langs/wm/wmc.py

@@ -34,6 +34,8 @@ asm: "asm" "(" STRING+ ")"
 ?op: block
    | label
    | goto ";"
+   | break ";"
+   | continue ";"
    | vardec ";"
    | arrdec ";"
    | varinit ";"
@@ -50,14 +52,16 @@ asm: "asm" "(" STRING+ ")"
    | return ";"
 label: NAME ":"
 goto: "goto" NAME
+break: "break"
+continue: "continue"
 if: "if" "(" expr ")" op ("else" op)?
 while: "while" "(" expr ")" op
 for: "for" "(" vardec ";" expr ";" (inc|dec|vardec|funcall) ")" op
 return: "return" expr
-inc: NAME "++"
-dec: NAME "--"
-rinc: "++" NAME
-rdec: "--" NAME 
+inc: NAME ("[" expr "]")? "++"
+dec: NAME ("[" expr "]")? "--"
+rinc: "++" NAME ("[" expr "]")?
+rdec: "--" NAME ("[" expr "]")?
 
 funcall: NAME "(" args ")"
 args:
@@ -245,6 +249,8 @@ class WMC:
 
     self.parser = lark.Lark(GRAMMAR)
 
+    self.loops = []
+
   def record_usage(self, name):
     if name in self.used_symbols:
       self.used_symbols[name].add(self.where)
@@ -707,6 +713,9 @@ class WMC:
         )
       )   
     elif node.data == "inc":
+      if len(node.children) == 2:
+        raise Exception(f"Not implemented: {node}")
+
       name = self.scope[node.children[0].value]
 
       self.record_usage(name)
@@ -720,6 +729,9 @@ class WMC:
         name
       )     
     elif node.data == "dec":
+      if len(node.children) == 2:
+        raise Exception(f"Not implemented: {node}")
+
       name = self.scope[node.children[0].value]
 
       self.record_usage(name)
@@ -732,6 +744,9 @@ class WMC:
         name
       )     
     elif node.data == "rinc":
+      if len(node.children) == 2:
+        raise Exception(f"Not implemented: {node}")
+
       name = self.scope[node.children[0].value]
 
       self.record_usage(name)
@@ -745,6 +760,9 @@ class WMC:
         name
       )  
     elif node.data == "rdec":
+      if len(node.children) == 2:
+        raise Exception(f"Not implemented: {node}")
+
       name = self.scope[node.children[0].value]
 
       self.record_usage(name)
@@ -921,6 +939,22 @@ class WMC:
         "jmp {}",
         self.scope.get_label(node.children[0].value)
       )
+    elif node.data == "break":
+      if len(self.loops) < 1:
+        raise Exception("'break` outside of a loop.")
+
+      buffer.emit(
+        "jmp {}",
+        self.loops[-1][1]
+      )
+    elif node.data == "continue":
+      if len(self.loops) < 1:
+        raise Exception("'continue` outside of a loop.")
+
+      buffer.emit(
+        "jmp {}",
+        self.loops[-1][0]
+      ) 
     elif node.data == "varinit":
       name = node.children[0].value
 
@@ -945,6 +979,9 @@ class WMC:
         self.compile_arrdec(node)
       )
     elif node.data in ("inc", "rinc"):
+      if len(node.children) == 2:
+        raise Exception(f"Not implemented: {node}")
+
       name = self.scope[node.children[0].value]
 
       self.record_usage(name)
@@ -954,6 +991,9 @@ class WMC:
         name
       )
     elif node.data == ("dec", "rdec"):
+      if len(node.children) == 2:
+        raise Exception(f"Not implemented: {node}")
+
       name = self.scope[node.children[0].value]
 
       self.record_usage(name)
@@ -1024,6 +1064,8 @@ class WMC:
       loop_label = self.make_label()
       exit_label = self.make_label()
 
+      self.loops.append((loop_label, exit_label))
+
       buffer.emit(
         "{}:",
         loop_label
@@ -1046,6 +1088,8 @@ class WMC:
         )
       )
 
+      self.loops.pop()
+
       buffer.emit(
         "jmp {}",
         loop_label
@@ -1058,6 +1102,8 @@ class WMC:
       loop_label = self.make_label()
       exit_label = self.make_label()
 
+      self.loops.append((loop_label, exit_label))
+
       self.scope.new()
 
       buffer.emit(
@@ -1096,6 +1142,8 @@ class WMC:
 
       self.scope.leave()
 
+      self.loops.pop()
+
       buffer.emit(
         "jmp {}",
         loop_label