Detect common patterns involving PEEK(-16336) and convert to tones (roughly)
authorNick Downing <nick@ndcode.org>
Tue, 24 May 2022 10:57:09 +0000 (20:57 +1000)
committerNick Downing <nick@ndcode.org>
Tue, 24 May 2022 11:22:58 +0000 (21:22 +1000)
applesoft_basic.t

index 5f5d822..4488900 100644 (file)
   random.seed(time.time())
   last_random = random.random()
   inter_statement_delay = 0.
+
+  FOR_NEXT_DELAY_HZ = 1080. # empty for/next loops per sec
+  FOR_NEXT_CLICK_HZ = 540. # clicks within a for/next loop
+  STATEMENT_CLICK_HZ = 1620. # clicks within a single statement
 %}
 
 %%
@@ -222,7 +226,8 @@ class Context:
     j = 1,
     k = 0,
     l = 1,
-    m = 0
+    m = 0,
+    clicks = 0
   ):
     self.program = program if program is not None else Program()
     self.variables = variables if variables is not None else {}
@@ -237,6 +242,9 @@ class Context:
     self.l = l
     self.m = m
 
+    # count peek(-16336) within a statement, convert to a tone
+    self.clicks = clicks
+
   def run(self):
     try:
       self.execute()
@@ -262,6 +270,12 @@ class Context:
         statement = line.children[self.j]
         self.j += 1
         statement.execute(self)
+        if self.clicks:
+          apple_io.tone(
+            STATEMENT_CLICK_HZ,
+            self.clicks * 2 / STATEMENT_CLICK_HZ
+          )
+          self.clicks = 0
         if inter_statement_delay != 0:
           time.sleep(inter_statement_delay)
       else:
@@ -355,23 +369,40 @@ def execute(self, context):
   if step != 0.:
     i = context.i
     j = context.j
+    clicks = 0
     while i < len(context.program.children):
       line = context.program.children[i]
       if j < len(line.children):
         statement = line.children[j]
         j += 1
         if (
+          isinstance(statement, StatementLet) and
+            isinstance(statement.children[1], RValuePeek) and
+            isinstance(statement.children[1].children[0], RValueSign) and
+            statement.children[1].children[0].sign == -1 and
+            isinstance(statement.children[1].children[0].children[0], RValueIntLiteral) and
+            statement.children[1].children[0].children[0].children[0].int_value == 16336
+        ):
+          clicks += 1
+        elif (
           isinstance(statement, StatementNext) and (
             len(statement.children) < 1 or
               statement.children[0].str_value == name
           )
         ):
           counts = math.floor((end - variable.value) / step) + 1
-          time.sleep(counts / 1080.)
+          if clicks:
+            apple_io.tone(
+              FOR_NEXT_CLICK_HZ,
+              clicks * counts * 2 / FOR_NEXT_CLICK_HZ
+            )
+          else:
+            time.sleep(counts / FOR_NEXT_DELAY_HZ)
           context.i = i
           context.j = j
           return
-        break
+        else:
+          break
       else:
         i += 1
         j = 1
@@ -760,7 +791,7 @@ def get(self, context):
     raise Exception(
       f'?ILLEGAL QUANTITY ERROR IN {context.line_number():d}'
     )
-  return ' ' * value 
+  return ' ' * value
 @method(RValueNot)
 def get(self, context):
   value = self.children[0].get_float(context)