    module Data.String.Interpolate.Parse where

    import           Data.String.Interpolate.Internal.Util

    data Node a = Literal String | Expression String | Abstraction a

    parseNodes :: String -> [Node ()]
    parseNodes :: String -> [Node ()]
    parseNodes = String -> String -> [Node ()]
    go String
    ""
      where
        go :: String -> String -> [Node ()]
        go :: String -> String -> [Node ()]
    go String
    acc String
    input = case String
    input of
          String
    ""  -> [Node ()] -> [Node ()]
    lit []
          Char
    '\\':Char
    x:String
    xs -> String -> String -> [Node ()]
    go (Char
    xChar -> String -> String
    forall a. a -> [a] -> [a]
    :Char
    '\\'Char -> String -> String
    forall a. a -> [a] -> [a]
    :String
    acc) String
    xs
          Char
    '#':Char
    '{':String
    xs | (String
    e, Char
    '}':String
    ys) <- (Char -> Bool) -> String -> (String, String)
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    span (Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Char
    '}') String
    xs -> [Node ()] -> [Node ()]
    lit ([Node ()] -> [Node ()]) -> [Node ()] -> [Node ()]
    forall a b. (a -> b) -> a -> b
    $ String -> Node ()
    expression String
    e Node () -> [Node ()] -> [Node ()]
    forall a. a -> [a] -> [a]
    : String -> String -> [Node ()]
    go String
    "" String
    ys
          Char
    x:String
    xs -> String -> String -> [Node ()]
    go (Char
    xChar -> String -> String
    forall a. a -> [a] -> [a]
    :String
    acc) String
    xs
          where
            expression :: String -> Node ()
    expression String
    e
              | String -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null String
    e = () -> Node ()
    forall a. a -> Node a
    Abstraction ()
              | Bool
    otherwise = String -> Node ()
    forall a. String -> Node a
    Expression String
    e

            lit :: [Node ()] -> [Node ()]
            lit :: [Node ()] -> [Node ()]
    lit [Node ()]
    nodes
              | String -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null String
    acc = [Node ()]
    nodes
              | Bool
    otherwise = (String -> Node ()
    forall a. String -> Node a
    Literal (String -> Node ()) -> (String -> String) -> String -> Node ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String
    unescape (String -> Node ()) -> String -> Node ()
    forall a b. (a -> b) -> a -> b
    $ String -> String
    forall a. [a] -> [a]
    reverse String
    acc) Node () -> [Node ()] -> [Node ()]
    forall a. a -> [a] -> [a]
    : [Node ()]
    nodes