1import gleam/option.{None, Some}
 2import gleam/string
 3import nibble.{type Parser, do, return}
 4import node.{type Node}
 5
 6/// Parse a keyword string and return the specified Node on success
 7pub fn keyword(expected: String, node: Node) -> Parser(Node, String, ctx) {
 8  use _ <- do(string.to_graphemes(expected) |> match_chars(expected))
 9  return(node)
10}
11
12/// Recursively match each character in the list
13fn match_chars(chars: List(String), context: String) -> Parser(Nil, String, ctx) {
14  case chars {
15    [] -> return(Nil)
16
17    [first, ..rest] -> {
18      use _ <- do(
19        nibble.take_map(
20          "expected '" <> first <> "' in keyword '" <> context <> "'",
21          fn(tok) {
22            case tok == first {
23              True -> Some(Nil)
24              False -> None
25            }
26          },
27        ),
28      )
29      match_chars(rest, context)
30    }
31  }
32}
33
34/// Parse the "let" keyword
35pub fn let_keyword() -> Parser(Node, String, ctx) {
36  keyword("let", node.Let)
37}