about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorelioat <elioat@tilde.institute>2025-01-19 10:52:07 -0500
committerelioat <elioat@tilde.institute>2025-01-19 10:52:07 -0500
commit5fef9e4cb3fb6ea79245533eefc39a05884e7bc6 (patch)
tree74ad72ce0fe19ceb95502a8112c1a4d0ed692066
parent2ae79a0cf9d0f7439fac454d65e2cb8f962b7ca9 (diff)
downloadtour-5fef9e4cb3fb6ea79245533eefc39a05884e7bc6.tar.gz
*
-rwxr-xr-xawk/vm/compiler.py124
-rw-r--r--awk/vm/test.coffee7
2 files changed, 131 insertions, 0 deletions
diff --git a/awk/vm/compiler.py b/awk/vm/compiler.py
new file mode 100755
index 0000000..4cd7b83
--- /dev/null
+++ b/awk/vm/compiler.py
@@ -0,0 +1,124 @@
+#!/usr/bin/env python3
+
+"""
+A simple compiler that translates CoffeeScript-like syntax to VM instructions.
+Example input:
+    
+    # Simple arithmetic
+    x = 5
+    y = 3
+    z = x + y
+    
+    # Using memory
+    array = []
+    array[0] = 42
+    array[1] = array[0] * 2
+    
+Will compile to VM instructions like:
+    
+    5 A!              # store 5 in A register
+    3 B!              # store 3 in B register
+    A @B +            # add them
+"""
+
+import sys
+import re
+
+class Compiler:
+    def __init__(self):
+        self.variables = {}  # Maps variable names to memory locations
+        self.next_memory = 0  # Next available memory location
+        
+    def allocate_variable(self, name):
+        """Allocate memory location for a variable"""
+        if name not in self.variables:
+            self.variables[name] = self.next_memory
+            self.next_memory += 1
+        return self.variables[name]
+    
+    def compile_assignment(self, line):
+        """Compile assignment statements like 'x = 5' or 'x = y + z'"""
+        match = re.match(r'(\w+)\s*=\s*(.+)', line)
+        if not match:
+            return None
+            
+        var_name = match.group(1)
+        expression = match.group(2)
+        
+        # Allocate memory for the variable
+        mem_loc = self.allocate_variable(var_name)
+        
+        # Compile the right-hand expression
+        vm_code = self.compile_expression(expression)
+        
+        # Store result in variable's memory location
+        vm_code.append(f"{mem_loc} !")
+        
+        return vm_code
+    
+    def compile_expression(self, expr):
+        """Compile expressions like '5', 'x + y', etc."""
+        vm_code = []
+        
+        # Handle simple number
+        if expr.isdigit():
+            vm_code.append(expr)
+            return vm_code
+            
+        # Handle variable reference
+        if expr in self.variables:
+            vm_code.append(str(self.variables[expr]))
+            vm_code.append("@")
+            return vm_code
+            
+        # Handle binary operations
+        ops = {
+            '+': '+',
+            '*': '2*',  # Note: This is a simplification
+            '-': 'NOT +',  # This is a hack, proper subtraction would need more
+        }
+        
+        for op in ops:
+            if op in expr:
+                left, right = expr.split(op)
+                vm_code.extend(self.compile_expression(left.strip()))
+                vm_code.extend(self.compile_expression(right.strip()))
+                vm_code.append(ops[op])
+                return vm_code
+        
+        return vm_code
+
+    def compile(self, source):
+        """Compile source code to VM instructions"""
+        output = []
+        
+        for line in source.split('\n'):
+            # Skip empty lines and comments
+            line = line.strip()
+            if not line or line.startswith('#'):
+                continue
+                
+            # Handle assignment
+            if '=' in line:
+                vm_code = self.compile_assignment(line)
+                if vm_code:
+                    output.extend(vm_code)
+                    continue
+            
+            # Other statement types can be added here
+            
+        return ' '.join(output)
+
+def main():
+    if len(sys.argv) > 1:
+        with open(sys.argv[1]) as f:
+            source = f.read()
+    else:
+        source = sys.stdin.read()
+    
+    compiler = Compiler()
+    vm_code = compiler.compile(source)
+    print(vm_code)
+
+if __name__ == '__main__':
+    main() 
\ No newline at end of file
diff --git a/awk/vm/test.coffee b/awk/vm/test.coffee
new file mode 100644
index 0000000..aecda14
--- /dev/null
+++ b/awk/vm/test.coffee
@@ -0,0 +1,7 @@
+# Calculate sum
+x = 5
+y = 3
+z = x + y
+
+# Double it
+result = z * 2