Created
September 18, 2016 05:38
-
-
Save jaredly/ef307824f87fbac949ed7eee1cf01d4f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * from PackTypes.Result | |
let module P = PackTypes.Parsing | |
let rec getChild = (children, mapper) => switch children { | |
case []: None | |
case [child ...rest]: switch mapper(child) { | |
case None: getChild(rest, mapper) | |
case x: x | |
} | |
} | |
let rec getChildren = (children, mapper) => switch children { | |
case []: [] | |
case [child ...rest]: switch mapper(child) { | |
case None: getChildren(rest, mapper) | |
case Some(x): [x, getChildren(rest, mapper)] | |
} | |
} | |
let getContentsByLabel = (children, needle) => getChild( | |
children, | |
(label, child) => if (needle <> label) { None } else { switch child { | |
case Leaf(_, contents, _): Some(contents) | |
case Node(_): failwith("expected a leaf") | |
} } | |
) | |
let getContentsByType = (children, needle) => getChild( | |
children, | |
child => switch child { | |
case (_, Leaf((name, _), contents, _)) with (name = needle): Some(contents) | |
case (_, Node((name, _), _, _)) with (name = needle): failwith("expected a leaf") | |
case _: None | |
} | |
) | |
let rec getPresence = (children, mapper) => switch children { | |
case []: false | |
case [child ...rest]: switch mapper(child) { | |
case false: getPresence(rest, mapper) | |
case x: x | |
} | |
} | |
let getPresenceByLabel = (children, needle) => getPresence( | |
children, | |
child => switch child { | |
case (name, _) with (name = needle): true | |
case _: false | |
} | |
) | |
let getPresenceByType = (children, needle) => getPresence( | |
children, | |
child => switch child { | |
case (_, Leaf((name, _), _, _)) | (_, Node((name, _), _, _)) with (name = needle): true | |
case _: false | |
} | |
) | |
let getNodeByType = (children, needle) => getChild( | |
children, | |
(label, child) => if (label <> "") { None } else { switch child { | |
case Node((name, sub), children, loc) with (name = needle): Some(sub, children, loc) | |
case _: None | |
} } | |
) | |
let getNodesByType = (children, needle, nodeMapper) => getChildren( | |
children, | |
(label, child) => switch child { | |
case Node((name, sub), children, loc) with (name = needle): Some(nodeMapper((sub, children, loc))) | |
case _: None | |
} | |
) | |
let getNodesByLabel = (children, needle, nodeMapper) => getChildren( | |
children, | |
(label, child) => if (label = needle) { switch child { | |
case Node((name, sub), children, loc): Some(nodeMapper((sub, children, loc))) | |
case _: None | |
} } else { None } | |
) | |
let getNodeByLabel = (children, needle) => getChild( | |
children, | |
(label, child) => if (label = needle) { switch child { | |
case Node(rule, children, loc): Some(rule, children, loc) | |
case Leaf(_): failwith(("Expected node for label " ^ needle)) | |
} } else { None } | |
) | |
let getLeafByType = (children, needle) => getChild( | |
children, | |
(label, child) => switch child { | |
case Leaf((name, sub), contents, loc) with (name = needle): Some((name, sub), contents, loc) | |
case _: None | |
} | |
) | |
let unescapeString = x => { | |
let contents = String.sub(x, 1, (String.length(x) - 2)) | |
if (String.length(contents) = 1) { contents } else { Scanf.unescaped(contents) } | |
} | |
let unescapeChar = x => if (String.length(x) = 1) { String.get(x, 0) } else { String.get(unescapeString(x), 0) } | |
exception ConversionFailure ( string ) | |
let unwrap = opt => switch opt { | |
case Some(x): x | |
case None: raise(ConversionFailure("Unwrapping none")) | |
} | |
let assertEq = (one, two) => if (one <> two) { raise(ConversionFailure("Assertion error")) } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment