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 ""
  where
    go :: String -> String -> [Node ()]
    go :: String -> String -> [Node ()]
go acc :: String
acc input :: String
input = case String
input of
      ""  -> [Node ()] -> [Node ()]
lit []
      '\\':x :: Char
x:xs :: String
xs -> String -> String -> [Node ()]
go (Char
xChar -> String -> String
forall a. a -> [a] -> [a]
:'\\'Char -> String -> String
forall a. a -> [a] -> [a]
:String
acc) String
xs
      '#':'{':xs :: String
xs | (e :: String
e, '}':ys :: 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
/= '}') 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
ys
      x :: Char
x:xs :: String
xs -> String -> String -> [Node ()]
go (Char
xChar -> String -> String
forall a. a -> [a] -> [a]
:String
acc) String
xs
      where
        expression :: String -> Node ()
expression e :: String
e
          | String -> 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 nodes :: [Node ()]
nodes
          | String -> 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