@@ -22,7 +22,6 @@ import Fay.Compiler.PrimOp
2222import qualified Fay.Exts.NoAnnotation as N
2323import Fay.Types
2424
25- import Control.Monad.State
2625import Data.Aeson.Encode
2726import qualified Data.ByteString.Lazy.UTF8 as UTF8
2827import Language.Haskell.Exts.Annotated hiding (alt , name , op , sym )
@@ -33,11 +32,11 @@ import SourceMap.Types
3332
3433-- | Print the JS to a flat string.
3534printJSString :: Printable a => a -> String
36- printJSString x = concat . reverse . psOutput $ execState (runPrinter ( printJS x)) defaultPrintState
35+ printJSString x = concat . reverse . pwOutput $ execPrinter ( printJS x) defaultPrintReader
3736
3837-- | Print the JS to a pretty string.
3938printJSPretty :: Printable a => a -> String
40- printJSPretty x = concat . reverse . psOutput $ execState (runPrinter ( printJS x)) defaultPrintState { psPretty = True }
39+ printJSPretty x = concat . reverse . pwOutput $ execPrinter ( printJS x) defaultPrintReader { prPretty = True }
4140
4241-- | Print literals. These need some special encoding for
4342-- JS-format literals. Could use the Text.JSON library.
@@ -88,7 +87,7 @@ instance Printable N.Name where
8887
8988-- | Print a list of statements.
9089instance Printable [JsStmt ] where
91- printJS = mapM_ printJS
90+ printJS = mconcat . map printJS
9291
9392-- | Print a single statement.
9493instance Printable JsStmt where
@@ -102,9 +101,9 @@ instance Printable JsStmt where
102101 name +> " = " +> expr +> " ;" +> newline
103102 printJS (JsSetProp name prop expr) =
104103 name +> " ." +> prop +> " = " +> expr +> " ;" +> newline
105- printJS (JsSetQName msrcloc name expr) = do
106- maybe ( return () ) mapping msrcloc
107- name +> " = " +> expr +> " ;" +> newline
104+ printJS (JsSetQName msrcloc name expr) =
105+ maybe mempty mapping msrcloc
106+ <> ( name +> " = " +> expr +> " ;" +> newline)
108107 printJS (JsSetConstructor name expr) =
109108 printCons name +> " = " +> expr +> " ;" +> newline +>
110109 -- The unqualifiedness here is bad.
@@ -117,9 +116,11 @@ instance Printable JsStmt where
117116 " if (" +> exp +> " ) {" +> newline +>
118117 indented (printJS thens) +>
119118 " }" +>
120- (unless (null elses) $ " else {" +>
121- indented (printJS elses) +>
122- " }" ) +> newline
119+ (if (null elses)
120+ then mempty
121+ else " else {" +>
122+ indented (printJS elses) +>
123+ " }" ) +> newline
123124 printJS (JsEarlyReturn exp ) =
124125 " return " +> exp +> " ;" +> newline
125126 printJS (JsThrow exp ) =
@@ -137,7 +138,7 @@ instance Printable ModulePath where
137138
138139-- | Print an expression.
139140instance Printable JsExp where
140- printJS (JsSeq es) = " (" +> intercalateM " ," (map printJS es) +> " )"
141+ printJS (JsSeq es) = " (" +> mintercalate " ," (map printJS es) +> " )"
141142 printJS (JsRawExp e) = write e
142143 printJS (JsName name) = printJS name
143144 printJS (JsThrowExp exp ) =
@@ -151,7 +152,7 @@ instance Printable JsExp where
151152 printJS (JsParen exp ) =
152153 " (" +> exp +> " )"
153154 printJS (JsList exps) =
154- " [" +> intercalateM " ," (map printJS exps) +> printJS " ]"
155+ " [" +> mintercalate " ," (map printJS exps) +> " ]"
155156 printJS (JsNew name args) =
156157 " new " +> JsApp (JsName name) args
157158 printJS (JsIndex i exp ) =
@@ -176,28 +177,26 @@ instance Printable JsExp where
176177 printJS (JsInstanceOf exp classname) =
177178 exp +> " instanceof " +> classname
178179 printJS (JsObj assoc) =
179- " {" +> intercalateM " ," (map cons assoc) +> " }"
180+ " {" +> mintercalate " ," (map cons assoc) +> " }"
180181 where cons (key,value) = " \" " +> key +> " \" : " +> value
181182 printJS (JsLitObj assoc) =
182- " {" +> intercalateM " ," (map cons assoc) +> " }"
183- where
184- cons :: (N. Name , JsExp ) -> Printer ()
185- cons (key,value) = " \" " +> key +> " \" : " +> value
183+ " {" +> mintercalate " ," (map cons assoc) +> " }"
184+ where cons (key,value) = " \" " +> key +> " \" : " +> value
186185 printJS (JsFun nm params stmts ret) =
187186 " function"
188- +> maybe ( return () ) ((" " +> ) . printJS . ident) nm
187+ +> maybe mempty ((" " +> ) . printJS . ident) nm
189188 +> " ("
190- +> intercalateM " ," (map printJS params)
189+ +> mintercalate " ," (map printJS params)
191190 +> " ){" +> newline
192191 +> indented (stmts +>
193192 case ret of
194193 Just ret' -> " return " +> ret' +> " ;" +> newline
195- Nothing -> return () )
194+ Nothing -> mempty )
196195 +> " }"
197196 printJS (JsApp op args) =
198197 (if isFunc op then JsParen op else op)
199198 +> " ("
200- +> (intercalateM " ," (map printJS args) )
199+ +> mintercalate " ," (map printJS args)
201200 +> " )"
202201 where isFunc JsFun {.. } = True ; isFunc _ = False
203202 printJS (JsNegApp args) =
@@ -230,27 +229,27 @@ instance Printable JsName where
230229 JsModuleName (ModuleName _ m) -> write m
231230
232231-- | Print a constructor name given a QName.
233- printCons :: N. QName -> Printer ()
232+ printCons :: N. QName -> Printer
234233printCons (UnQual _ n) = printConsName n
235234printCons (Qual _ (ModuleName _ m) n) = printJS m +> " ." +> printConsName n
236235printCons (Special {}) = error " qname2String Special"
237236
238237-- | Print an unqualified name.
239- printConsUnQual :: N. QName -> Printer ()
238+ printConsUnQual :: N. QName -> Printer
240239printConsUnQual (UnQual _ x) = printJS x
241240printConsUnQual (Qual _ _ n) = printJS n
242241printConsUnQual (Special {}) = error " printConsUnqual Special"
243242
244243-- | Print a constructor name given a Name. Helper for printCons.
245- printConsName :: N. Name -> Printer ()
246- printConsName n = write " _" >> printJS n
244+ printConsName :: N. Name -> Printer
245+ printConsName = ( write " _" <> ) . printJS
247246
248247-- | Just write out strings.
249248instance Printable String where
250249 printJS = write
251250
252251-- | A printer is a printable.
253- instance Printable ( Printer () ) where
252+ instance Printable Printer where
254253 printJS = id
255254
256255--------------------------------------------------------------------------------
@@ -299,63 +298,55 @@ normalizeName = concatMap encodeChar
299298
300299
301300-- | Print the given printer indented.
302- indented :: Printer a -> Printer ()
303- indented p = do
304- PrintState {.. } <- get
305- if psPretty
306- then do modify $ \ s -> s { psIndentLevel = psIndentLevel + 1 }
307- void p
308- modify $ \ s -> s { psIndentLevel = psIndentLevel }
309- else void p
301+ indented :: Printer -> Printer
302+ indented p = askP $ \ PrintReader {.. } ->
303+ if prPretty
304+ then addToIndentLevel 1 <> p <> addToIndentLevel (- 1 )
305+ else p
306+ where addToIndentLevel d = modifyP (\ s@ PrintState {.. } -> s { psIndentLevel = psIndentLevel + d } )
310307
311308-- | Output a newline.
312- newline :: Printer ()
313- newline = do
314- PrintState {.. } <- get
315- when psPretty $ do
316- write " \n "
317- modify $ \ s -> s { psNewline = True }
309+ newline :: Printer
310+ newline = askP $ \ PrintReader {.. } ->
311+ whenP prPretty $ write " \n " <> (modifyP $ \ s -> s { psNewline = True })
312+
318313
319314-- | Write out a string, updating the current position information.
320- write :: String -> Printer ()
321- write x = do
322- PrintState {.. } <- get
323- let out = if psNewline then replicate (2 * psIndentLevel) ' ' ++ x else x
324- modify $ \ s -> s { psOutput = out : psOutput
325- , psLine = psLine + additionalLines
326- , psColumn = if additionalLines > 0
327- then length (concat (take 1 (reverse srclines)))
328- else psColumn + length x
329- , psNewline = False
330- }
331- return (error " Nothing to return for writer string." )
332-
333- where srclines = lines x
315+ write :: String -> Printer
316+ write x = p <> q
317+ where p = getP $ \ PrintState {.. } ->
318+ let out = if psNewline
319+ then replicate (2 * psIndentLevel) ' ' ++ x
320+ else x
321+ in tellP mempty { pwOutput = [out] }
322+ q = modifyP $ \ s@ PrintState {.. } ->
323+ s { psLine = psLine + additionalLines
324+ , psColumn = if additionalLines > 0
325+ then length (concat (take 1 (reverse srclines)))
326+ else psColumn + length x
327+ , psNewline = False
328+ }
329+ srclines = lines x
334330 additionalLines = length (filter (== ' \n ' ) x)
335331
332+
336333-- | Generate a mapping from the Haskell location to the current point in the output.
337- mapping :: SrcSpan -> Printer ()
338- mapping SrcSpan {.. } = do
339- modify $ \ s -> s { psMappings = m s : psMappings s }
340- return ()
341-
342- where m ps = Mapping { mapGenerated = Pos (fromIntegral (psLine ps))
343- (fromIntegral (psColumn ps))
344- , mapOriginal = Just (Pos (fromIntegral srcSpanStartLine)
345- (fromIntegral srcSpanStartColumn - 1 ))
346- , mapSourceFile = Just srcSpanFilename
347- , mapName = Nothing
348- }
349-
350- -- | Intercalate monadic action.
351- intercalateM :: String -> [Printer a ] -> Printer ()
352- intercalateM _ [] = return ()
353- intercalateM _ [x] = void x
354- intercalateM str (x: xs) = do
355- void x
356- write str
357- intercalateM str xs
334+ mapping :: SrcSpan -> Printer
335+ mapping SrcSpan {.. } =
336+ getP $ \ PrintState {.. } ->
337+ let m = Mapping { mapGenerated = Pos (fromIntegral (psLine))
338+ (fromIntegral (psColumn))
339+ , mapOriginal = Just (Pos (fromIntegral srcSpanStartLine)
340+ (fromIntegral srcSpanStartColumn - 1 ))
341+ , mapSourceFile = Just srcSpanFilename
342+ , mapName = Nothing
343+ }
344+ in tellP $ mempty { pwMappings = [m] }
345+
346+ -- | Intercalate monoids.
347+ mintercalate :: String -> [Printer ] -> Printer
348+ mintercalate str xs = mconcat $ intersperse (write str) xs
358349
359350-- | Concatenate two printables.
360- (+>) :: (Printable a , Printable b ) => a -> b -> Printer ()
361- pa +> pb = printJS pa > > printJS pb
351+ (+>) :: (Printable a , Printable b ) => a -> b -> Printer
352+ pa +> pb = printJS pa < > printJS pb
0 commit comments