src/remove/run.bend

ezx@1.11.0.0 · 54 lines · 4 definitions

1# remove/run: the interpreter for `ez remove`. It reads the directory it runs
2# in, ez.toml, `.gitignore` and the `.bend` files git lists into a World, then
3# loops: it asks the planner (remove/relock.bend) what the lock after the
4# remove still needs, answers each question with the lock's interpreter
5# (`Run.answer.all`), and adds the answers to the World, until nothing is
6# left to ask. Then it runs the plan with the lock's effect runner
7# (`Run.exec.plan`), which exits 1 with the reason when the plan refuses. It
8# decides nothing; that it reads and executes faithfully is EZ-TRUST-2.
9import Base
10import snap@1.4.0.0/main.bend as R
11import ezx@1.11.0.0/src/io/file.bend as F
12import ezx@1.11.0.0/src/lock/run.bend as Run
13import ezx@1.11.0.0/src/lock/world.bend as W
14import ezx@1.11.0.0/src/remove/plan.bend as RP
15import ezx@1.11.0.0/src/remove/relock.bend as RR
16import ezx@1.11.0.0/src/ws/relock.bend as Rel
17import ezx@1.11.0.0/src/ws/run.bend as WsRun
18
19# the World with more of the lock's answers in it
20def more(world: RR.World, rs: List<&2, W.Reply>) -> RR.World:
21  RR.World{r, here, listing, locks} = world
22  RR.World{r, here, listing, List.append(&2, W.Reply, locks, rs)}
23
24# the planner's step: its questions answered and the loop gone round again,
25# or its plan run
26def loop.step(st: RR.Next, +lib: String, world: RR.World, go: RR.World -> IO(Unit)) -> IO(Unit):
27  match st:
28    case RR.AskLock{asks}:
29      do IO<Unit>:
30        rs : List<&2, W.Reply> <- Run.answer.all(lib, asks)
31        go(more(world, rs))
32    case RR.Planned{pl}:
33      Run.exec.plan(lib, pl)
34
35# the loop, under fuel. Every round adds an answer, since the lock never asks
36# what the World answers already, so the fuel (`Run.rounds`) is only a guard.
37def loop(fuel: Nat, +lib: String, +ws: Rel.Ws, +world: RR.World) -> IO(Unit):
38  match fuel:
39    case 0n:
40      IO.die(Unit, 1, "ez: ez remove kept asking questions")
41    case 1n+f:
42      loop.step(Rel.remove.next(ws, world), lib, world, w => loop(f, lib, ws, w))
43
44# `ez remove <name>`
45def run(+name: String) -> IO(Unit):
46  do IO<Unit>:
47    lib : String <- Run.bend.lib()
48    +pwd : String <- R.exec(["pwd"])
49    led : Maybe<&2, String> <- F.read(RP.toml())
50    ig : Maybe<&2, String> <- F.read(RP.ignore.file())
51    ls : W.Listing <- Run.read.listing()
52    ws : Rel.Ws <- WsRun.relock.ws()
53    loop(Run.rounds(), lib, ws, RR.World{RP.World{name, led, F.text_of(ig)},
54      String.trim(R.text(pwd)), ls, []})