import gleam/option.{None, Some} import gleam/string import nibble.{type Parser, do, return} import node.{type Node} /// Parse a keyword string and return the specified Node on success pub fn keyword(expected: String, node: Node) -> Parser(Node, String, ctx) { use _ <- do(string.to_graphemes(expected) |> match_chars(expected)) return(node) } /// Recursively match each character in the list fn match_chars(chars: List(String), context: String) -> Parser(Nil, String, ctx) { case chars { [] -> return(Nil) [first, ..rest] -> { use _ <- do( nibble.take_map( "expected '" <> first <> "' in keyword '" <> context <> "'", fn(tok) { case tok == first { True -> Some(Nil) False -> None } }, ), ) match_chars(rest, context) } } } /// Parse the "let" keyword pub fn let_keyword() -> Parser(Node, String, ctx) { keyword("let", node.Let) }