@@ -86,7 +86,7 @@ pub fn tab() -> Parser(Node, String, ctx) {
return(Tab)
}
-pub fn line_comment_prefix() -> Parser(Node, String, ctx) {
+pub fn line_comment_prefix() -> Parser(Node, String, String) {
use _ <- nibble.do(consume_exact_string("--"))
return(LineCommentPrefix)
@@ -1,7 +1,7 @@
import birdie
import gleam/int
import gleam/list
-import gleam/string
+import gleam/result
import gleeunit
import nibble.{Expected}
import nibble/lexer.{Span, Token}
@@ -86,11 +86,11 @@ pub fn parse_line_ending_fails_on_lone_carriage_return_test() {
let input = "\r"
let tokens = quasi_lexer.chars() |> quasi_lexer.run(on: input)
let parser = parser.end_of_line()
- let assert Error(error) = nibble.run(tokens, parser)
+ let result = nibble.run(tokens, parser)
- snapshot_helpers.snap_parse_error(
+ snapshot_helpers.snap_parse_result_nodes(
input,
- error,
+ result |> result.map(list.wrap),
"Line ending should reject lone carriage return",
)
}
@@ -121,35 +121,15 @@ pub fn parse_multiple_line_endings_test() {
use eol3 <- nibble.do(parser.end_of_line())
nibble.return([eol1, eol2, eol3])
}
- let assert Ok(nodes) = nibble.run(tokens, parser)
+ let result = nibble.run(tokens, parser)
- snapshot_helpers.snap_parse_success(
+ snapshot_helpers.snap_parse_result_nodes(
input,
- nodes,
+ result,
"Multiple line endings should all parse as EndOfLine",
)
}
-pub fn demo_visual_error_rendering_test() {
- let input = "let x = 42\r"
- let tokens = quasi_lexer.chars() |> quasi_lexer.run(on: input)
-
- // Try to parse "let" followed by a line ending
- let parser = {
- use _ <- nibble.do(parser.let_keyword())
- use _ <- nibble.do(parser.exact_string(" x = 42", node.Let))
- parser.end_of_line()
- }
-
- let assert Error(errors) = nibble.run(tokens, parser)
-
- snapshot_helpers.snap_parse_error(
- input,
- errors,
- "Visual error demo: shows escaped chars, spans, and parser context",
- )
-}
-
// Tests for printable parser (%x20-7F)
pub fn parse_printable_space_test() {
@@ -153,16 +153,33 @@ pub fn snap_lexer_output(
birdie.snap(snap, title: title)
}
+/// Create a snapshot of a parse result (success or error)
+pub fn snap_parse_result_nodes(
+ input: String,
+ result: Result(List(Node), List(nibble.DeadEnd(tok, ctx))),
+ title: String,
+) -> Nil {
+ let snap = case result {
+ Ok(nodes) ->
+ "Input: "
+ <> escape_string(input)
+ <> "\n"
+ <> format_nodes(nodes)
+ Error(errors) ->
+ // Input is shown with each error, so no need to show it at the top level
+ format_dead_ends(input, errors)
+ }
+
+ birdie.snap(snap, title: title)
+}
+
/// Create a snapshot of a parse error showing input and errors
pub fn snap_parse_error(
input: String,
errors: List(nibble.DeadEnd(tok, ctx)),
title: String,
) -> Nil {
- // Input is shown with each error, so no need to show it at the top level
- let snap = format_dead_ends(input, errors)
-
- birdie.snap(snap, title: title)
+ snap_parse_result_nodes(input, Error(errors), title)
}
/// Create a snapshot of successful parse showing input and result
@@ -171,13 +188,7 @@ pub fn snap_parse_success(
nodes: List(Node),
title: String,
) -> Nil {
- let snap =
- "Input: "
- <> escape_string(input)
- <> "\n"
- <> format_nodes(nodes)
-
- birdie.snap(snap, title: title)
+ snap_parse_result_nodes(input, Ok(nodes), title)
}
/// Create a snapshot for a Result type (success or error)
@@ -302,11 +313,6 @@ fn visual_span_label(gutter_width: Int, col: Int, label: String) -> String {
gutter <> before <> "└─ " <> label
}
-/// Get the center column of a span for label positioning
-fn span_center_col(span: Span) -> Int {
- let Span(_, cs, _, ce) = span
- cs + { ce - cs } / 2
-}
/// Render a single span visually with context lines
pub fn visual_single_span(