Implement binary operations (BinOp) support

**Parser changes (parser.py):**
- Added ast.BinOp handling in _transform_expr()
- Emits: {type: "binop", left: ..., op: "Add|Sub|Mult|Div|Mod", right: ...}

**Codegen changes (llvm_codegen_signals.py):**
- Added BinOp handling in _emit_expr()
- Maps Python ops to LLVM instructions:
  - Add → add i32
  - Sub → sub i32
  - Mult → mul i32
  - Div → sdiv i32 (signed division)
  - Mod → srem i32 (signed remainder)

**Result:**
Before: count = count + 1 → store i32 0 (WRONG!)
After:  count = count + 1 → load, add i32 1, store ✓

**Still TODO:**
The counter buttons now UPDATE the signal correctly, but the display
doesn't update because f-string text nodes aren't reactive yet.
We need reactive text nodes (similar to reactive attributes).

All 55 tests passing ✓

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Aaron SinclairandClaude committed 2025-11-15 12:18:16 -08:00
1 parent 60bbad9c68
commit e1219ea0c1
7 files changed
+78 -47

No files matched your search

Binary file not shown.
+19
View File
@@ -1093,6 +1093,25 @@ class SignalLLVMIRGenerator:
result_var = self._new_var()
self.lines.append(f" %{result_var} = select i1 %{cond_var}, i32 {true_val}, i32 {false_val}")
return f"%{result_var}"
elif expr["type"] == "binop":
# Handle binary operations (e.g., count + 1, x - 5)
left_val = self._emit_expr(expr["left"])
right_val = self._emit_expr(expr["right"])
op = expr["op"]
# Map Python operators to LLVM instructions
op_map = {
"Add": "add",
"Sub": "sub",
"Mult": "mul",
"Div": "sdiv", # signed division
"Mod": "srem", # signed remainder
}
llvm_op = op_map.get(op, "add")
result_var = self._new_var()
self.lines.append(f" %{result_var} = {llvm_op} i32 {left_val}, {right_val}")
return f"%{result_var}"
else:
# Unknown expression type
return "0"
+8
View File
@@ -356,6 +356,14 @@ def _transform_expr(expr: ast.expr | None) -> dict[str, Any]:
"body": _transform_expr(expr.body),
"orelse": _transform_expr(expr.orelse),
}
elif isinstance(expr, ast.BinOp):
# Handle binary operations (e.g., count + 1, x - 5, a * b)
return {
"type": "binop",
"left": _transform_expr(expr.left),
"op": type(expr.op).__name__, # Add, Sub, Mult, Div, Mod, etc.
"right": _transform_expr(expr.right),
}
else:
return {"type": "unknown", "ast_type": type(expr).__name__}