~/bend-docscommunity

src/lint/world.bend source

src/lint/world.bend on the hub · documented module

# src/lint/world: everything `bolt` reads, as one value. The planner# (src/lint/plan.bend) is a pure function of a World; the interpreter# (src/lint.bend) gathers one, answering each question the planner asks by# IO, and prints the plan the planner returns. The design is# docs/rfc/bolt-lint-planner.md.## The World holds only what the lint reads: the paths named on the command# line, the working directory they are named from, and every answer the# interpreter gave. A question with no answer yet reads as a directory with no# entries or a file that cannot be read.import Baseimport ../lazy/lazy.bend as Lazy# a question the planner asks. Each is answered by one IO action: a# directory listed (src/walk/), or a file read (src/lsp/files/).type Ask is Data:  Entries{dir: String}  Text{path: String}# the answer to one question. A directory that cannot be opened lists as# empty, as src/walk/dir.c answers. A text asked of a path that is a# directory is `Directory`, not a read: it has no text.type Answer is Data:  Listed{names: List<&2, String>}  Read{text: String}  Unread{}  Directory{}# one question, answeredtype Reply is Data:  Reply{ask: Ask, answer: Answer}# everything `bolt` reads: the paths named on the command line, the working# directory (absolute) that relative paths are named from, and every answer# the interpreter gave, in the order it gave themtype World is Data:  World{paths: List<&2, String>, cwd: String, replies: List<&2, Reply>}# the paths named on the command linedef paths.of(world: World) -> List<&2, String>:  World{paths, _cwd, _replies} = world  paths# the working directory the run was started indef cwd.of(world: World) -> String:  World{_paths, cwd, _replies} = world  cwd# whether two questions are the same questiondef ask.eq(aa: Ask, bb: Ask) -> Bool:  match aa bb:    case Entries{x1} Entries{y1}:      String.eq(x1, y1)    case Text{x2} Text{y2}:      String.eq(x2, y2)    case Entries{_x3} Text{_y3}:      False{}    case Text{_x4} Entries{_y4}:      False{}# the first answer given to a questiondef answer.in(rs: List<&2, Reply>, +ask: Ask) -> Maybe<&2, Answer>:  match rs:    case Nil{}:      None{}    case Con{Reply{q, a}, rest}:      Lazy.stop(Maybe<&2, Answer>, ask.eq(q, ask), Some{a}, _u => answer.in(rest, ask))# the answer a World holds for a question, None while there is nonedef answer(world: World, +ask: Ask) -> Maybe<&2, Answer>:  World{_paths, _cwd, rs} = world  answer.in(rs, ask)# whether a World answers a questiondef answered(world: World, +ask: Ask) -> Bool:  Maybe.is_some(&2, Answer, answer(world, ask))# a listing's names; anything else lists nothingdef listing.answer(aa: Answer) -> List<&2, String>:  match aa:    case Listed{names}:      names    case Read{_text}:      []    case Unread{}:      []    case Directory{}:      []def listing.got(mm: Maybe<&2, Answer>) -> List<&2, String>:  match mm:    case None{}:      []    case Some{aa}:      listing.answer(aa)# a directory's entries, a sub-directory's name ending in "/"; none while# the directory is not listed yetdef listing(world: World, dir: String) -> List<&2, String>:  listing.got(answer(world, Entries{dir}))# a read's text; anything else is no textdef text.answer(aa: Answer) -> Maybe<&2, String>:  match aa:    case Listed{_names}:      None{}    case Read{tt}:      Some{tt}    case Unread{}:      None{}    case Directory{}:      None{}def text.got(mm: Maybe<&2, Answer>) -> Maybe<&2, String>:  match mm:    case None{}:      None{}    case Some{aa}:      text.answer(aa)# a file's text, or None when it could not be read, is a directory, or is# not read yetdef text(world: World, path: String) -> Maybe<&2, String>:  text.got(answer(world, Text{path}))