Skip to content

Instantly share code, notes, and snippets.

@lepoetemaudit
Created September 1, 2017 17:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lepoetemaudit/cbb43ed214f58a612118469599ec00f4 to your computer and use it in GitHub Desktop.
Save lepoetemaudit/cbb43ed214f58a612118469599ec00f4 to your computer and use it in GitHub Desktop.
Quick Alpaca parser/combinator tests
module main
type result 'a 'b = Error 'a | Ok 'b
type parser 'a = fn binary -> result string ('a, binary)
let (<|) f x = f x
let (|>) x f = f x
let assertEquals a b =
match (a == b) with
true -> :ok
| false -> throw (:not_equal, a, b)
-- Infix string concat
val (^^) : fn string string -> string
let (^^) fst snd =
<<fst: type=utf8, snd: type=utf8>> |> bin_to_string
val bin_to_string : fn binary -> string
let bin_to_string str =
match str with
<<res: type=utf8>> -> res
val char : fn binary binary -> result string (binary, binary)
let char charToMatch str =
match str with
<<chr: type=binary size=8, rest: type=binary>> ->
match charToMatch == chr with
| true -> Ok (chr, rest)
| false -> Error ("Unexpected char: " ^^ (bin_to_string chr))
let andThen p1 p2 input =
let res1 = p1 input in
match res1 with
| Error err -> Error err
| Ok (val1, rest1) ->
let res2 = p2 rest1 in
match res2 with
| Error err -> Error err
| Ok (val2, rest2) ->
Ok ((val1, val2), rest2)
let (.>>.) p1 p2 input =
andThen p1 p2 input
test "we can match chars" =
assertEquals (char <<"x">> <<"xperiment">>) (Ok (<<"x">>, <<"periment">>))
test "we can chain with andThen" =
let p1 = char <<"y">> in
let p2 = char <<"z">> in
let parser = p1 .>>. p2 in
let input = <<"yzblah">> in
assertEquals (parser input) (Ok ((<<"y">>, <<"z">>), <<"blah">>))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment