src/lint.bend
bolt@1.26.0.0 · 115 lines · 11 definitions
1
2
3
4
5
6
7
8
9
10
11
12
13import Base
14import bolt@1.26.0.0/src/lint/world.bend as W
15import bolt@1.26.0.0/src/lint/plan.bend as Plan
16import bolt@1.26.0.0/src/lsp/files/disk.bend as Disk
17import bolt@1.26.0.0/src/walk/disk.bend as WalkDisk
18import bolt@1.26.0.0/src/status.bend as Status
19import bolt@1.26.0.0/src/lazy/lazy.bend as Lazy
20
21
22def read.answer(mm: Maybe<&2, String>) -> W.Answer:
23 match mm:
24 case None{}:
25 W.Unread{}
26 case Some{text}:
27 W.Read{text}
28
29
30def text.answer(dir: Bool, path: String) -> IO(W.Answer):
31 match dir:
32 case True{}:
33 IO.pure(W.Answer, W.Directory{})
34 case False{}:
35 do IO<W.Answer>:
36 mm : Maybe<&2, String> <- Disk.read(path)
37 return read.answer(mm)
38
39
40def answer(ask: W.Ask) -> IO(W.Answer):
41 match ask:
42 case W.Entries{dir}:
43 do IO<W.Answer>:
44 es : List<&2, String> <- WalkDisk.entries(dir)
45 return W.Listed{es}
46 case W.Contents{+path}:
47 do IO<W.Answer>:
48 dir : Bool <- WalkDisk.is_dir(path)
49 text.answer(dir, path)
50
51
52def answer.all(asks: List<&2, W.Ask>) -> IO(List<&2, W.Reply>):
53 match asks:
54 case Nil{}:
55 IO.pure(List<&2, W.Reply>, [])
56 case Con{+ask, rest}:
57 do IO<List<&2, W.Reply>>:
58 a : W.Answer <- answer(ask)
59 more : List<&2, W.Reply> <- answer.all(rest)
60 return W.Reply{ask, a} <> more
61
62
63def more(world: W.World, rs: List<&2, W.Reply>) -> W.World:
64 W.World{paths, cwd, replies} = world
65 W.World{paths, cwd, List.append(&2, W.Reply, replies, rs)}
66
67
68def print_all(lines: List<&2, String>) -> IO(Unit):
69 match lines:
70 case Nil{}:
71 IO.pure(Unit, Unit{})
72 case Con{l, t}:
73 do IO<Unit>:
74 IO.print(l)
75 print_all(t)
76
77
78def exec(pl: Plan.Plan) -> IO(Unit):
79 Plan.Plan{lines, exit} = pl
80 do IO<Unit>:
81 print_all(lines)
82 Status.stop(U32.is_gt(exit, 0))
83
84
85
86def loop.step(asks: List<&2, W.Ask>, +world: W.World, go: W.World -> IO(Unit)) -> IO(Unit):
87 match asks:
88 case Nil{}:
89 exec(Plan.plan(world))
90 case Con{a, rest}:
91 do IO<Unit>:
92 rs : List<&2, W.Reply> <- answer.all(a <> rest)
93 go(more(world, rs))
94
95
96
97
98def loop(fuel: Nat, +world: W.World) -> IO(Unit):
99 match fuel:
100 case 0n:
101 IO.die(Unit, 1, "bolt: the lint kept asking")
102 case 1n+f:
103 loop.step(Plan.wants(world), world, ww => loop(f, ww))
104
105
106
107def run.from(paths: List<&2, String>, +cwd: String) -> IO(Unit):
108 Lazy.stop(IO(Unit), String.is_empty(cwd), IO.die(Unit, 1, "bolt: cannot name the working directory"),
109 _u => loop(Nat.add(Plan.limit(), 2n), W.World{paths, cwd, []}))
110
111
112def run(paths: List<&2, String>) -> IO(Unit):
113 do IO<Unit>:
114 cwd : String <- WalkDisk.cwd()
115 run.from(paths, cwd)