Skip to content

Commit 4ee96e7

Browse files
r41k0uclaude
andcommitted
Core: Support augmented assignment by desugaring to x = x op v
AugAssign previously raised 'not supported' outright. Desugaring to an ordinary assignment with a BinOp reproduces its Python semantics for Name and Attribute targets and reuses the whole existing assignment path -- locals, struct fields, and the new globals all work, so 'counter += 1' (the canonical global idiom in the kernel selftest corpus) compiles to load/add/store on @counter. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L1PX8EuP9C3o3veWGA84RF
1 parent 930594d commit 4ee96e7

1 file changed

Lines changed: 28 additions & 1 deletion

File tree

pythonbpf/functions/functions_pass.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,33 @@ def handle_assign(func, compilation_context, builder, stmt, local_sym_tab):
189189
logger.error(f"Unsupported assignment target: {ast.dump(target)}")
190190

191191

192+
def handle_aug_assign(func, compilation_context, builder, stmt, local_sym_tab):
193+
"""Handle `x += v` by desugaring to `x = x op v` and reusing handle_assign.
194+
195+
That is the statement's Python semantics for the targets we support, and it
196+
means globals come along for free: `counter += 1` under `global counter`
197+
becomes load/add/store on @counter.
198+
"""
199+
if isinstance(stmt.target, ast.Name):
200+
load_target = ast.Name(id=stmt.target.id, ctx=ast.Load())
201+
elif isinstance(stmt.target, ast.Attribute):
202+
load_target = ast.Attribute(
203+
value=stmt.target.value, attr=stmt.target.attr, ctx=ast.Load()
204+
)
205+
else:
206+
raise SyntaxError(
207+
f"Unsupported augmented-assignment target: {ast.dump(stmt.target)}"
208+
)
209+
210+
desugared = ast.Assign(
211+
targets=[stmt.target],
212+
value=ast.BinOp(left=load_target, op=stmt.op, right=stmt.value),
213+
)
214+
ast.copy_location(desugared, stmt)
215+
ast.fix_missing_locations(desugared)
216+
handle_assign(func, compilation_context, builder, desugared, local_sym_tab)
217+
218+
192219
def handle_cond(func, compilation_context, builder, cond, local_sym_tab):
193220
val = eval_expr(func, compilation_context, builder, cond, local_sym_tab)[0]
194221
return convert_to_bool(builder, val)
@@ -283,7 +310,7 @@ def process_stmt(
283310
elif isinstance(stmt, ast.Assign):
284311
handle_assign(func, compilation_context, builder, stmt, local_sym_tab)
285312
elif isinstance(stmt, ast.AugAssign):
286-
raise SyntaxError("Augmented assignment not supported")
313+
handle_aug_assign(func, compilation_context, builder, stmt, local_sym_tab)
287314
elif isinstance(stmt, ast.Global):
288315
# Declarations were collected by process_func_body; nothing to emit.
289316
pass

0 commit comments

Comments
 (0)