-- | Utilities for constructing Hydra code trees

module Hydra.Tools.Serialization where

import Hydra.Ast

import qualified Data.List as L
import qualified Data.Maybe as Y


angleBraces :: Brackets
angleBraces :: Brackets
angleBraces = Symbol -> Symbol -> Brackets
Brackets (String -> Symbol
sym String
"<") (String -> Symbol
sym String
">")

angleBracesList ::  BlockStyle -> [Expr] -> Expr
angleBracesList :: BlockStyle -> [Expr] -> Expr
angleBracesList BlockStyle
style [Expr]
els = case [Expr]
els of
  [] -> String -> Expr
cst String
"<>"
  [Expr]
_ -> Brackets -> BlockStyle -> Expr -> Expr
brackets Brackets
angleBraces BlockStyle
style (Expr -> Expr) -> Expr -> Expr
forall a b. (a -> b) -> a -> b
$ BlockStyle -> [Expr] -> Expr
commaSep BlockStyle
style [Expr]
els

bracketList :: BlockStyle -> [Expr] -> Expr
bracketList :: BlockStyle -> [Expr] -> Expr
bracketList BlockStyle
style [Expr]
els = case [Expr]
els of
  [] -> String -> Expr
cst String
"[]"
  [Expr]
_ -> Brackets -> BlockStyle -> Expr -> Expr
brackets Brackets
squareBrackets BlockStyle
style (Expr -> Expr) -> Expr -> Expr
forall a b. (a -> b) -> a -> b
$ BlockStyle -> [Expr] -> Expr
commaSep BlockStyle
style [Expr]
els

brackets :: Brackets -> BlockStyle -> Expr -> Expr
brackets :: Brackets -> BlockStyle -> Expr -> Expr
brackets Brackets
br BlockStyle
style Expr
e = BracketExpr -> Expr
ExprBrackets (BracketExpr -> Expr) -> BracketExpr -> Expr
forall a b. (a -> b) -> a -> b
$ Brackets -> Expr -> BlockStyle -> BracketExpr
BracketExpr Brackets
br Expr
e BlockStyle
style

commaSep :: BlockStyle -> [Expr] -> Expr
commaSep :: BlockStyle -> [Expr] -> Expr
commaSep = String -> BlockStyle -> [Expr] -> Expr
symbolSep String
","

curlyBlock :: BlockStyle -> Expr -> Expr
curlyBlock :: BlockStyle -> Expr -> Expr
curlyBlock BlockStyle
style Expr
e = Maybe String -> BlockStyle -> [Expr] -> Expr
curlyBracesList Maybe String
forall a. Maybe a
Nothing BlockStyle
style [Expr
e]

curlyBraces :: Brackets
curlyBraces :: Brackets
curlyBraces = Symbol -> Symbol -> Brackets
Brackets (String -> Symbol
sym String
"{") (String -> Symbol
sym String
"}")

curlyBracesList :: Maybe String -> BlockStyle -> [Expr] -> Expr
curlyBracesList :: Maybe String -> BlockStyle -> [Expr] -> Expr
curlyBracesList Maybe String
msymb BlockStyle
style [Expr]
els = case [Expr]
els of
  [] -> String -> Expr
cst String
"{}"
  [Expr]
_ -> Brackets -> BlockStyle -> Expr -> Expr
brackets Brackets
curlyBraces BlockStyle
style (Expr -> Expr) -> Expr -> Expr
forall a b. (a -> b) -> a -> b
$ String -> BlockStyle -> [Expr] -> Expr
symbolSep (String -> Maybe String -> String
forall a. a -> Maybe a -> a
Y.fromMaybe String
"," Maybe String
msymb) BlockStyle
style [Expr]
els

cst :: String -> Expr
cst :: String -> Expr
cst = Symbol -> Expr
ExprConst (Symbol -> Expr) -> (String -> Symbol) -> String -> Expr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Symbol
Symbol

customIndent :: String -> String -> String
customIndent :: String -> String -> String
customIndent String
idt String
s = String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
L.intercalate String
"\n" ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ (String
idt String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> [String] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> [String]
lines String
s

customIndentBlock :: String -> [Expr] -> Expr
customIndentBlock :: String -> [Expr] -> Expr
customIndentBlock String
idt [Expr]
els = case [Expr]
els of
  [Expr
x] -> Expr
x
--  (head:rest) -> ifx idtOp head $ indentSep idt rest
  (Expr
head:[Expr]
rest) -> Op -> Expr -> Expr -> Expr
ifx Op
idtOp Expr
head (Expr -> Expr) -> Expr -> Expr
forall a b. (a -> b) -> a -> b
$ [Expr] -> Expr
newlineSep [Expr]
rest
    where
      idtOp :: Op
idtOp = Symbol -> Padding -> Precedence -> Associativity -> Op
Op (String -> Symbol
sym String
"") (Ws -> Ws -> Padding
Padding Ws
WsSpace (Ws -> Padding) -> Ws -> Padding
forall a b. (a -> b) -> a -> b
$ String -> Ws
WsBreakAndIndent String
idt) (Int -> Precedence
Precedence Int
0) Associativity
AssociativityNone

dotSep :: [Expr] -> Expr
dotSep :: [Expr] -> Expr
dotSep = Op -> [Expr] -> Expr
sep (Op -> [Expr] -> Expr) -> Op -> [Expr] -> Expr
forall a b. (a -> b) -> a -> b
$ Symbol -> Padding -> Precedence -> Associativity -> Op
Op (String -> Symbol
sym String
".") (Ws -> Ws -> Padding
Padding Ws
WsNone Ws
WsNone) (Int -> Precedence
Precedence Int
0) Associativity
AssociativityNone

doubleNewlineSep :: [Expr] -> Expr
doubleNewlineSep :: [Expr] -> Expr
doubleNewlineSep = Op -> [Expr] -> Expr
sep (Op -> [Expr] -> Expr) -> Op -> [Expr] -> Expr
forall a b. (a -> b) -> a -> b
$ Symbol -> Padding -> Precedence -> Associativity -> Op
Op (String -> Symbol
sym String
"") (Ws -> Ws -> Padding
Padding Ws
WsBreak Ws
WsBreak) (Int -> Precedence
Precedence Int
0) Associativity
AssociativityNone

doubleSpace :: String
doubleSpace :: String
doubleSpace = String
"  "

fullBlockStyle :: BlockStyle
fullBlockStyle :: BlockStyle
fullBlockStyle = Maybe String -> Bool -> Bool -> BlockStyle
BlockStyle (String -> Maybe String
forall a. a -> Maybe a
Just String
doubleSpace) Bool
True Bool
True

halfBlockStyle :: BlockStyle
halfBlockStyle :: BlockStyle
halfBlockStyle = Maybe String -> Bool -> Bool -> BlockStyle
BlockStyle (String -> Maybe String
forall a. a -> Maybe a
Just String
doubleSpace) Bool
True Bool
False

ifx :: Op -> Expr -> Expr -> Expr
ifx :: Op -> Expr -> Expr -> Expr
ifx Op
op Expr
lhs Expr
rhs = OpExpr -> Expr
ExprOp (OpExpr -> Expr) -> OpExpr -> Expr
forall a b. (a -> b) -> a -> b
$ Op -> Expr -> Expr -> OpExpr
OpExpr Op
op Expr
lhs Expr
rhs

indent :: String -> String
indent :: String -> String
indent = String -> String -> String
customIndent String
doubleSpace

indentBlock :: [Expr] -> Expr
indentBlock :: [Expr] -> Expr
indentBlock = String -> [Expr] -> Expr
customIndentBlock String
doubleSpace

indentLines :: [Expr] -> Expr
indentLines :: [Expr] -> Expr
indentLines [Expr]
els = Op -> Expr -> Expr -> Expr
ifx Op
topOp (String -> Expr
cst String
"") ([Expr] -> Expr
newlineSep [Expr]
els)
  where
    topOp :: Op
topOp = Symbol -> Padding -> Precedence -> Associativity -> Op
Op (String -> Symbol
sym String
"") (Ws -> Ws -> Padding
Padding Ws
WsNone (String -> Ws
WsBreakAndIndent String
doubleSpace)) (Int -> Precedence
Precedence Int
0) Associativity
AssociativityNone

indentSubsequentLines :: String -> Expr -> Expr
indentSubsequentLines :: String -> Expr -> Expr
indentSubsequentLines String
idt Expr
e = IndentedExpression -> Expr
ExprIndent (IndentedExpression -> Expr) -> IndentedExpression -> Expr
forall a b. (a -> b) -> a -> b
$ IndentStyle -> Expr -> IndentedExpression
IndentedExpression (String -> IndentStyle
IndentStyleSubsequentLines String
idt) Expr
e

infixWs :: String -> Expr -> Expr -> Expr
infixWs :: String -> Expr -> Expr -> Expr
infixWs String
op Expr
l Expr
r = [Expr] -> Expr
spaceSep [Expr
l, String -> Expr
cst String
op, Expr
r]

infixWsList :: String -> [Expr] -> Expr
infixWsList :: String -> [Expr] -> Expr
infixWsList String
op [Expr]
opers = [Expr] -> Expr
spaceSep ([Expr] -> Expr) -> [Expr] -> Expr
forall a b. (a -> b) -> a -> b
$ ([Expr] -> Expr -> [Expr]) -> [Expr] -> [Expr] -> [Expr]
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
L.foldl (\[Expr]
e Expr
r -> if [Expr] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
L.null [Expr]
e then [Expr
r] else Expr
rExpr -> [Expr] -> [Expr]
forall a. a -> [a] -> [a]
:Expr
opExprExpr -> [Expr] -> [Expr]
forall a. a -> [a] -> [a]
:[Expr]
e) [] ([Expr] -> [Expr]) -> [Expr] -> [Expr]
forall a b. (a -> b) -> a -> b
$ [Expr] -> [Expr]
forall a. [a] -> [a]
L.reverse [Expr]
opers
  where
    opExpr :: Expr
opExpr = String -> Expr
cst String
op

inlineStyle :: BlockStyle
inlineStyle :: BlockStyle
inlineStyle = Maybe String -> Bool -> Bool -> BlockStyle
BlockStyle Maybe String
forall a. Maybe a
Nothing Bool
False Bool
False

newlineSep :: [Expr] -> Expr
newlineSep :: [Expr] -> Expr
newlineSep = Op -> [Expr] -> Expr
sep (Op -> [Expr] -> Expr) -> Op -> [Expr] -> Expr
forall a b. (a -> b) -> a -> b
$ Symbol -> Padding -> Precedence -> Associativity -> Op
Op (String -> Symbol
sym String
"") (Ws -> Ws -> Padding
Padding Ws
WsNone Ws
WsBreak) (Int -> Precedence
Precedence Int
0) Associativity
AssociativityNone

noPadding :: Padding
noPadding :: Padding
noPadding = Ws -> Ws -> Padding
Padding Ws
WsNone Ws
WsNone

noSep :: [Expr] -> Expr
noSep :: [Expr] -> Expr
noSep = Op -> [Expr] -> Expr
sep (Op -> [Expr] -> Expr) -> Op -> [Expr] -> Expr
forall a b. (a -> b) -> a -> b
$ Symbol -> Padding -> Precedence -> Associativity -> Op
Op (String -> Symbol
sym String
"") (Ws -> Ws -> Padding
Padding Ws
WsNone Ws
WsNone) (Int -> Precedence
Precedence Int
0) Associativity
AssociativityNone

num :: Int -> Expr
num :: Int -> Expr
num = String -> Expr
cst (String -> Expr) -> (Int -> String) -> Int -> Expr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> String
forall a. Show a => a -> String
show

op :: String -> Int -> Associativity -> Op
op :: String -> Int -> Associativity -> Op
op String
s Int
p = Symbol -> Padding -> Precedence -> Associativity -> Op
Op (String -> Symbol
Symbol String
s) (Ws -> Ws -> Padding
Padding Ws
WsSpace Ws
WsSpace) (Int -> Precedence
Precedence Int
p)

orOp :: Bool -> Op
orOp :: Bool -> Op
orOp Bool
newlines = Symbol -> Padding -> Precedence -> Associativity -> Op
Op (String -> Symbol
sym String
"|") (Ws -> Ws -> Padding
Padding Ws
WsSpace (if Bool
newlines then Ws
WsBreak else Ws
WsSpace)) (Int -> Precedence
Precedence Int
0) Associativity
AssociativityNone -- No source

orSep :: BlockStyle -> [Expr] -> Expr
orSep :: BlockStyle -> [Expr] -> Expr
orSep BlockStyle
style [Expr]
l = case [Expr]
l of
  [] -> String -> Expr
cst String
""
  [Expr
x] -> Expr
x
  (Expr
h:[Expr]
r) -> Op -> Expr -> Expr -> Expr
ifx (Bool -> Op
orOp Bool
newlines) Expr
h (Expr -> Expr) -> Expr -> Expr
forall a b. (a -> b) -> a -> b
$ BlockStyle -> [Expr] -> Expr
orSep BlockStyle
style [Expr]
r
  where
    newlines :: Bool
newlines = BlockStyle -> Bool
blockStyleNewlineBeforeContent BlockStyle
style

parenList :: Bool -> [Expr] -> Expr
parenList :: Bool -> [Expr] -> Expr
parenList Bool
newlines [Expr]
els = case [Expr]
els of
    [] -> String -> Expr
cst String
"()"
    [Expr]
_ -> Brackets -> BlockStyle -> Expr -> Expr
brackets Brackets
parentheses BlockStyle
style (Expr -> Expr) -> Expr -> Expr
forall a b. (a -> b) -> a -> b
$ BlockStyle -> [Expr] -> Expr
commaSep BlockStyle
style [Expr]
els
  where
    style :: BlockStyle
style = if Bool
newlines Bool -> Bool -> Bool
&& [Expr] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
L.length [Expr]
els Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1 then BlockStyle
halfBlockStyle else BlockStyle
inlineStyle

parens :: Expr -> Expr
parens :: Expr -> Expr
parens = Brackets -> BlockStyle -> Expr -> Expr
brackets Brackets
parentheses BlockStyle
inlineStyle

parentheses :: Brackets
parentheses :: Brackets
parentheses = Symbol -> Symbol -> Brackets
Brackets (String -> Symbol
sym String
"(") (String -> Symbol
sym String
")")

parenthesize :: Expr -> Expr
parenthesize :: Expr -> Expr
parenthesize Expr
exp = case Expr
exp of
  ExprBrackets (BracketExpr Brackets
br Expr
e BlockStyle
newlines) -> BracketExpr -> Expr
ExprBrackets (Brackets -> Expr -> BlockStyle -> BracketExpr
BracketExpr Brackets
br (Expr -> Expr
parenthesize Expr
e) BlockStyle
newlines)
  ExprConst Symbol
_ -> Expr
exp
  ExprIndent (IndentedExpression IndentStyle
style Expr
e) -> IndentedExpression -> Expr
ExprIndent (IndentStyle -> Expr -> IndentedExpression
IndentedExpression IndentStyle
style (Expr -> Expr
parenthesize Expr
e))
  ExprOp (OpExpr op :: Op
op@(Op Symbol
_ Padding
_ Precedence
prec Associativity
assoc) Expr
lhs Expr
rhs) -> OpExpr -> Expr
ExprOp (Op -> Expr -> Expr -> OpExpr
OpExpr Op
op Expr
lhs2 Expr
rhs2)
    where
      lhs' :: Expr
lhs' = Expr -> Expr
parenthesize Expr
lhs
      rhs' :: Expr
rhs' = Expr -> Expr
parenthesize Expr
rhs
      lhs2 :: Expr
lhs2 = case Expr
lhs' of
        ExprOp (OpExpr (Op Symbol
_ Padding
_ Precedence
lprec Associativity
lassoc) Expr
_ Expr
_) -> case Precedence
prec Precedence -> Precedence -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` Precedence
lprec of
          Ordering
LT -> Expr
lhs'
          Ordering
GT -> Expr -> Expr
parens Expr
lhs'
          Ordering
EQ -> if Associativity -> Bool
assocLeft Associativity
assoc Bool -> Bool -> Bool
&& Associativity -> Bool
assocLeft Associativity
lassoc
            then Expr
lhs'
            else Expr -> Expr
parens Expr
lhs'
        Expr
_ -> Expr
lhs'
      rhs2 :: Expr
rhs2 = case Expr
rhs' of
        ExprOp (OpExpr (Op Symbol
_ Padding
_ Precedence
rprec Associativity
rassoc) Expr
_ Expr
_) -> case Precedence
prec Precedence -> Precedence -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` Precedence
rprec of
          Ordering
LT -> Expr
rhs'
          Ordering
GT -> Expr -> Expr
parens Expr
rhs'
          Ordering
EQ -> if Associativity -> Bool
assocRight Associativity
assoc Bool -> Bool -> Bool
&& Associativity -> Bool
assocRight Associativity
rassoc
            then Expr
rhs'
            else Expr -> Expr
parens Expr
rhs'
        Expr
_ -> Expr
rhs'
      assocLeft :: Associativity -> Bool
assocLeft Associativity
a = Associativity
a Associativity -> Associativity -> Bool
forall a. Eq a => a -> a -> Bool
== Associativity
AssociativityLeft Bool -> Bool -> Bool
|| Associativity
a Associativity -> Associativity -> Bool
forall a. Eq a => a -> a -> Bool
== Associativity
AssociativityNone Bool -> Bool -> Bool
|| Associativity
a Associativity -> Associativity -> Bool
forall a. Eq a => a -> a -> Bool
== Associativity
AssociativityBoth
      assocRight :: Associativity -> Bool
assocRight Associativity
a = Associativity
a Associativity -> Associativity -> Bool
forall a. Eq a => a -> a -> Bool
== Associativity
AssociativityRight Bool -> Bool -> Bool
|| Associativity
a Associativity -> Associativity -> Bool
forall a. Eq a => a -> a -> Bool
== Associativity
AssociativityNone Bool -> Bool -> Bool
|| Associativity
a Associativity -> Associativity -> Bool
forall a. Eq a => a -> a -> Bool
== Associativity
AssociativityBoth

prefix :: String -> Expr -> Expr
prefix :: String -> Expr -> Expr
prefix String
p = Op -> Expr -> Expr -> Expr
ifx Op
preOp (String -> Expr
cst String
"")
  where
    preOp :: Op
preOp = Symbol -> Padding -> Precedence -> Associativity -> Op
Op (String -> Symbol
sym String
p) (Ws -> Ws -> Padding
Padding Ws
WsNone Ws
WsNone) (Int -> Precedence
Precedence Int
0) Associativity
AssociativityNone

printExpr :: Expr -> String
printExpr :: Expr -> String
printExpr Expr
e = case Expr
e of
  ExprConst (Symbol String
s) -> String
s
  ExprIndent (IndentedExpression IndentStyle
style Expr
expr) -> String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
L.intercalate String
"\n" ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ case IndentStyle
style of
      IndentStyleAllLines String
idt -> (String
idt String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> [String] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [String]
lns
      IndentStyleSubsequentLines String
idt -> case [String]
lns of
        [String
x] -> [String
x]
        (String
head:[String]
rest) -> String
headString -> [String] -> [String]
forall a. a -> [a] -> [a]
:((String
idt String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> [String] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [String]
rest)
    where
      lns :: [String]
lns = String -> [String]
lines (String -> [String]) -> String -> [String]
forall a b. (a -> b) -> a -> b
$ Expr -> String
printExpr Expr
expr
  ExprOp (OpExpr (Op (Symbol String
sym) (Padding Ws
padl Ws
padr) Precedence
_ Associativity
_) Expr
l Expr
r) -> String
lhs String -> String -> String
forall a. [a] -> [a] -> [a]
++ Ws -> String
pad Ws
padl String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
sym String -> String -> String
forall a. [a] -> [a] -> [a]
++ Ws -> String
pad Ws
padr String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
rhs
    where
      lhs :: String
lhs = Ws -> String -> String
idt Ws
padl (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ Expr -> String
printExpr Expr
l
      rhs :: String
rhs = Ws -> String -> String
idt Ws
padr (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ Expr -> String
printExpr Expr
r
      idt :: Ws -> String -> String
idt Ws
ws String
s = case Ws
ws of
        WsBreakAndIndent String
idt -> String -> String -> String
customIndent String
idt String
s
        Ws
_ -> String
s
      pad :: Ws -> String
pad Ws
ws = case Ws
ws of
        Ws
WsNone -> String
""
        Ws
WsSpace -> String
" "
        Ws
WsBreak -> String
"\n"
        WsBreakAndIndent String
_ -> String
"\n"
        Ws
WsDoubleBreak -> String
"\n\n"
  ExprBrackets (BracketExpr (Brackets (Symbol String
l) (Symbol String
r)) Expr
e BlockStyle
style) ->
      String
l String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
pre String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
ibody String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
suf String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
r
    where
      body :: String
body = Expr -> String
printExpr Expr
e
      ibody :: String
ibody = case Maybe String
doIndent of
         Maybe String
Nothing -> String
body
         Just String
idt -> String -> String -> String
customIndent String
idt String
body
      pre :: String
pre = if Bool
nlBefore then String
"\n" else String
""
      suf :: String
suf = if Bool
nlAfter then String
"\n" else String
""
      BlockStyle Maybe String
doIndent Bool
nlBefore Bool
nlAfter = BlockStyle
style

sep :: Op -> [Expr] -> Expr
sep :: Op -> [Expr] -> Expr
sep Op
op [Expr]
els =  case [Expr]
els of
  [] -> String -> Expr
cst String
""
  [Expr
x] -> Expr
x
  (Expr
h:[Expr]
r) -> Op -> Expr -> Expr -> Expr
ifx Op
op Expr
h (Expr -> Expr) -> Expr -> Expr
forall a b. (a -> b) -> a -> b
$ Op -> [Expr] -> Expr
sep Op
op [Expr]
r

spaceSep :: [Expr] -> Expr
spaceSep :: [Expr] -> Expr
spaceSep = Op -> [Expr] -> Expr
sep (Op -> [Expr] -> Expr) -> Op -> [Expr] -> Expr
forall a b. (a -> b) -> a -> b
$ Symbol -> Padding -> Precedence -> Associativity -> Op
Op (String -> Symbol
sym String
"") (Ws -> Ws -> Padding
Padding Ws
WsSpace Ws
WsNone) (Int -> Precedence
Precedence Int
0) Associativity
AssociativityNone

squareBrackets :: Brackets
squareBrackets :: Brackets
squareBrackets = Symbol -> Symbol -> Brackets
Brackets (String -> Symbol
sym String
"[") (String -> Symbol
sym String
"]")

sym :: String -> Symbol
sym :: String -> Symbol
sym = String -> Symbol
Symbol

symbolSep :: String -> BlockStyle -> [Expr] -> Expr
symbolSep :: String -> BlockStyle -> [Expr] -> Expr
symbolSep String
symb BlockStyle
style [Expr]
l = case [Expr]
l of
    [] -> String -> Expr
cst String
""
    [Expr
x] -> Expr
x
    (Expr
h:[Expr]
r) -> Op -> Expr -> Expr -> Expr
ifx Op
commaOp Expr
h (Expr -> Expr) -> Expr -> Expr
forall a b. (a -> b) -> a -> b
$ String -> BlockStyle -> [Expr] -> Expr
symbolSep String
symb BlockStyle
style [Expr]
r
  where
    break :: Ws
break = case [Bool] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
L.length ([Bool] -> Int) -> [Bool] -> Int
forall a b. (a -> b) -> a -> b
$ (Bool -> Bool) -> [Bool] -> [Bool]
forall a. (a -> Bool) -> [a] -> [a]
L.filter Bool -> Bool
forall a. a -> a
id [BlockStyle -> Bool
blockStyleNewlineBeforeContent BlockStyle
style, BlockStyle -> Bool
blockStyleNewlineAfterContent BlockStyle
style] of
      Int
0 -> Ws
WsSpace
      Int
1 -> Ws
WsBreak
      Int
2 -> Ws
WsDoubleBreak
    commaOp :: Op
commaOp = Symbol -> Padding -> Precedence -> Associativity -> Op
Op (String -> Symbol
sym String
symb) (Ws -> Ws -> Padding
Padding Ws
WsNone Ws
break) (Int -> Precedence
Precedence Int
0) Associativity
AssociativityNone -- No source