src/basilisp/lang/compiler/generator.py
def _set_bang_to_py_ast(ctx: GeneratorContext, node: SetBang) -> GeneratedPyAST:
    """Return a Python AST Node for a `set!` expression."""
    assert node.op == NodeOp.SET_BANG

    val_temp_name = genname("set_bang_val")
    val_ast = gen_py_ast(ctx, node.val)

    target = node.target
    assert isinstance(
        target, (HostField, Local, VarRef)
    ), f"invalid set! target type {type(target)}"

    if isinstance(target, HostField):
        target_ast = _interop_prop_to_py_ast(ctx, target, is_assigning=True)
    elif isinstance(target, VarRef):
        target_ast = _var_sym_to_py_ast(ctx, target, is_assigning=True)
    elif isinstance(target, Local):
        target_ast = _local_sym_to_py_ast(ctx, target, is_assigning=True)
    else:  # pragma: no cover
        raise GeneratorException(
            f"invalid set! target type {type(target)}", lisp_ast=target
        )

    return GeneratedPyAST(
        node=ast.Name(id=val_temp_name, ctx=ast.Load()),
        dependencies=list(
            chain(
                val_ast.dependencies,
                [
                    ast.Assign(
                        targets=[ast.Name(id=val_temp_name, ctx=ast.Store())],
                        value=val_ast.node,
                    )
                ],
                target_ast.dependencies,
                [ast.Assign(targets=[target_ast.node], value=val_ast.node)],
            )
        ),
    )
def _set_bang_to_py_ast(ctx: GeneratorContext, node: SetBang) -> GeneratedPyAST:
    """Return a Python AST Node for a `set!` expression."""
    assert node.op == NodeOp.SET_BANG

    val_temp_name = genname("set_bang_val")
    val_ast = gen_py_ast(ctx, node.val)

    target = node.target
    assert isinstance(
        target, (HostField, Local, VarRef)
    ), f"invalid set! target type {type(target)}"

    if isinstance(target, HostField):
        target_ast = _interop_prop_to_py_ast(ctx, target, is_assigning=True)
    elif isinstance(target, VarRef):
        target_ast = _var_sym_to_py_ast(ctx, target, is_assigning=True)
    elif isinstance(target, Local):
        target_ast = _local_sym_to_py_ast(ctx, target, is_assigning=True)
    else:  # pragma: no cover
        raise GeneratorException(
            f"invalid set! target type {type(target)}", lisp_ast=target
        )

    return GeneratedPyAST(
        node=ast.Name(id=val_temp_name, ctx=ast.Load()),
        dependencies=list(
            chain(
                val_ast.dependencies,
                [
                    ast.Assign(
                        targets=[ast.Name(id=val_temp_name, ctx=ast.Store())],
                        value=val_ast.node,
                    )
                ],
                target_ast.dependencies,
                [ast.Assign(targets=[target_ast.node], value=val_ast.node)],
            )
        ),
    )
Return a Python AST Node for a `set!` expression.