|
1 | | -"""13_ret_far.py — CALL + RET_FAR nested return |
| 1 | +"""13_ret_far.py — Manual push + GOTO + RET_FAR pop-and-return |
2 | 2 |
|
3 | 3 | Usage: |
4 | 4 | python demos/13_ret_far.py |
5 | 5 | """ |
6 | 6 |
|
7 | 7 | import asyncio |
8 | 8 |
|
9 | | -from amrita_sense import ALIAS, ARCHIVED_NODES, CALL, NOP, Node, WorkflowInterpreter |
10 | | -from amrita_sense.instructions import RET_FAR |
| 9 | +from amrita_sense import ALIAS, NOP, Node, PointerVector, WorkflowInterpreter |
| 10 | +from amrita_sense.instructions import GOTO, RET_FAR |
11 | 11 |
|
12 | 12 |
|
13 | 13 | @Node() |
14 | | -async def deep_work() -> object: |
15 | | - """Deep task: simulate an early-exit condition""" |
16 | | - print(" Entering deep task...") |
17 | | - print(" Early exit condition met — executing RET_FAR") |
18 | | - return RET_FAR() # Pop return address and jump back to the outermost caller |
| 14 | +async def start() -> None: |
| 15 | + print("Start") |
19 | 16 |
|
20 | 17 |
|
21 | 18 | @Node() |
22 | | -async def never_reached() -> None: |
23 | | - print(" This line should never print (RET_FAR already jumped out)") |
| 19 | +async def save_ret_addr(pc: WorkflowInterpreter) -> None: |
| 20 | + """Manually push a return destination onto _ret_addr_stack.""" |
| 21 | + print(" Saving return address...") |
| 22 | + return_dest = PointerVector(pc.find_addr_alias("after")) |
| 23 | + pc._ret_addr_stack.push(return_dest) |
24 | 24 |
|
25 | 25 |
|
26 | 26 | @Node() |
27 | | -async def back_to_top() -> None: |
28 | | - print("Back to top level") |
| 27 | +async def doing_work() -> None: |
| 28 | + """The section we GOTO into.""" |
| 29 | + print(" Doing work in the jumped-to section") |
| 30 | + |
| 31 | + |
| 32 | +@Node() |
| 33 | +async def after_return() -> None: |
| 34 | + """RET_FAR pops _ret_addr_stack and jumps here.""" |
| 35 | + print("Back here (popped via RET_FAR)") |
29 | 36 |
|
30 | 37 |
|
31 | 38 | async def main() -> None: |
32 | 39 | print("=== RET_FAR example ===") |
33 | | - sub = ARCHIVED_NODES(ALIAS(deep_work, "deep")) |
| 40 | + # Pattern: manual push → GOTO → RET_FAR pop-and-return |
| 41 | + # 1) save_ret_addr pushes "after" address onto _ret_addr_stack |
| 42 | + # 2) GOTO("work") jumps to the work section |
| 43 | + # 3) RET_FAR() pops the saved address and jumps back |
34 | 44 | comp = ( |
35 | | - Node(lambda: print("Start")) # type: ignore[arg-type] |
36 | | - >> CALL("deep") |
37 | | - >> back_to_top |
| 45 | + start |
| 46 | + >> save_ret_addr |
| 47 | + >> GOTO("work") |
| 48 | + >> ALIAS(after_return, "after") |
| 49 | + >> GOTO("end") |
| 50 | + >> ALIAS(doing_work, "work") |
| 51 | + >> RET_FAR() |
| 52 | + >> ALIAS(NOP, "end") |
38 | 53 | >> NOP |
39 | | - >> sub |
40 | 54 | ) |
41 | 55 | await WorkflowInterpreter(comp.render()).run() |
42 | 56 |
|
|
0 commit comments