Skip to content

Commit

Permalink
feat(std.parser): Include the byte offset in the error message
Browse files Browse the repository at this point in the history
  • Loading branch information
Marwes committed Dec 21, 2017
1 parent 8fd443b commit fc7c676
Showing 1 changed file with 9 additions and 8 deletions.
17 changes: 9 additions & 8 deletions std/parser.glu
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ let { Functor, Applicative, Alternative, Monad } = prelude
let { id, flip } = import! std.function
let { Bool } = import! std.bool
let char = import! std.char
let int = import! std.int
let { (==) } = char.eq
let { Result } = import! std.result
let string = import! std.string
Expand All @@ -12,7 +13,7 @@ let { Option } = import! std.option

type OffsetString = { start : Int, end : Int, buffer : String }
type Position = Int
type Error = String
type Error = { position : Position, message : String }
type ParseResult a = Result Error { value : a, buffer : OffsetString }
type Parser a =
OffsetString -> ParseResult a
Expand Down Expand Up @@ -54,7 +55,7 @@ let alternative : Alternative Parser = {
match parser l stream with
| Ok a -> Ok a
| Err _ -> parser r stream),
empty = parser (\stream -> Err "empty"),
empty = parser (\stream -> Err { position = stream.start, message = "empty" }),
}

let { (<|>) } = prelude.make_Alternative alternative
Expand Down Expand Up @@ -88,11 +89,11 @@ let uncons stream : OffsetString -> Option { char : Char, rest : OffsetString }
let update_position c position : Char -> Position -> Position =
position + char.len_utf8 c

let (<?>) p msg : Parser a -> String -> Parser a =
let (<?>) p message : Parser a -> String -> Parser a =
parser (\stream ->
match p stream with
| Ok x -> Ok x
| Err _ -> Err msg)
| Err _ -> Err { position = stream.start, message })


let any : Parser Char =
Expand All @@ -101,10 +102,10 @@ let any : Parser Char =
| Some record ->
let { char, rest } = record
Ok { value = char, buffer = rest }
| None -> Err "End of stream")
| None -> Err { position = stream.start, message = "End of stream" })

let fail message : String -> Parser a =
parser (\stream -> Err message)
parser (\stream -> Err { position = stream.start, message })

let satisfy_map predicate : (Char -> Option a) -> Parser a =
let f c =
Expand Down Expand Up @@ -137,7 +138,7 @@ let take1 predicate : (Char -> Bool) -> Parser String =
if predicate record.char
then take_ record.rest
else if stream.start == stream2.start
then Err "Unexpected token"
then Err { position = stream.start, message = "Unexpected token" }
else Ok {
value = string.slice stream.buffer stream.start stream2.start,
buffer = stream2,
Expand Down Expand Up @@ -208,7 +209,7 @@ let sep_by parser sep : Parser a -> Parser b -> Parser (List a) =
let parse p input : Parser a -> String -> Result String a =
match p { start = 0, end = string.len input, buffer = input } with
| Ok ok -> Ok ok.value
| Err err -> Err err
| Err err -> Err (int.show.show err.position <> ":" <> err.message)

{
Position, Error, ParseResult, Parser,
Expand Down

0 comments on commit fc7c676

Please sign in to comment.