about summary refs log tree commit diff stats
path: root/awk/vm/compiler.py
diff options
context:
space:
mode:
Diffstat (limited to 'awk/vm/compiler.py')
-rwxr-xr-xawk/vm/compiler.py82
1 files changed, 65 insertions, 17 deletions
diff --git a/awk/vm/compiler.py b/awk/vm/compiler.py
index 4cd7b83..a406779 100755
--- a/awk/vm/compiler.py
+++ b/awk/vm/compiler.py
@@ -38,21 +38,38 @@ class Compiler:
     
     def compile_assignment(self, line):
         """Compile assignment statements like 'x = 5' or 'x = y + z'"""
+        # Remove any comments from the line
+        line = line.split('#')[0].strip()
+        
         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
+        print(f"# Compiling assignment: {var_name} = {expression}", file=sys.stderr)
+        
+        # First get the memory location
         mem_loc = self.allocate_variable(var_name)
         
-        # Compile the right-hand expression
-        vm_code = self.compile_expression(expression)
+        # Then compile the expression
+        expr_code = self.compile_expression(expression)
+        if not expr_code:
+            print(f"# Error: Failed to compile expression: {expression}", file=sys.stderr)
+            return None
         
-        # Store result in variable's memory location
-        vm_code.append(f"{mem_loc} !")
+        # Generate code that:
+        # 1. Evaluates the expression
+        # 2. Duplicates the result (for storing and leaving on stack)
+        # 3. Stores at memory location
+        vm_code = []
+        vm_code.extend(expr_code)     # Evaluate expression
+        vm_code.append("DUP")         # Make a copy
+        vm_code.append(str(mem_loc))  # Push memory location
+        vm_code.append("@")           # Read current value (for debugging)
+        vm_code.append("DROP")        # Drop the old value
+        vm_code.append("!")           # Store new value
         
         return vm_code
     
@@ -60,6 +77,9 @@ class Compiler:
         """Compile expressions like '5', 'x + y', etc."""
         vm_code = []
         
+        # Remove any comments from the expression
+        expr = expr.split('#')[0].strip()
+        
         # Handle simple number
         if expr.isdigit():
             vm_code.append(expr)
@@ -74,39 +94,67 @@ class Compiler:
         # Handle binary operations
         ops = {
             '+': '+',
-            '*': '2*',  # Note: This is a simplification
-            '-': 'NOT +',  # This is a hack, proper subtraction would need more
+            '*': '*',
+            '-': 'NOT +',
         }
         
+        # Try each operator
         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
+                parts = expr.split(op, 1)
+                if len(parts) == 2:
+                    left = parts[0].strip()
+                    right = parts[1].strip()
+                    
+                    print(f"# Debug: left={left}, right={right}", file=sys.stderr)
+                    
+                    # Generate code for left operand
+                    left_code = self.compile_expression(left)
+                    if not left_code:
+                        continue
+                    vm_code.extend(left_code)
+                    
+                    # Generate code for right operand
+                    right_code = self.compile_expression(right)
+                    if not right_code:
+                        continue
+                    vm_code.extend(right_code)
+                    
+                    # Add the operation
+                    vm_code.append(ops[op])
+                    return vm_code
         
         return vm_code
 
     def compile(self, source):
         """Compile source code to VM instructions"""
         output = []
+        debug_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 line == "SHOW":
+                output.append("SHOW")
+                continue
+                
             if '=' in line:
                 vm_code = self.compile_assignment(line)
                 if vm_code:
                     output.extend(vm_code)
+                    debug_output.append(f"{' '.join(vm_code)}  # {line}")
+                    if not line.startswith('result ='):  # If not final result
+                        output.append("DROP")  # Drop the duplicate we left on stack
                     continue
+        
+        print("# Generated VM code:", file=sys.stderr)
+        for line in debug_output:
+            print(f"# {line}", file=sys.stderr)
             
-            # Other statement types can be added here
-            
+        # Add final SHOW to see the result
+        output.append("SHOW")
         return ' '.join(output)
 
 def main():