jl-0.1.0: src/JL/Printer.hs
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE FlexibleContexts #-}
-- |
module JL.Printer where
import qualified Data.HashMap.Strict as HM
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Vector as V
import JL.Types
-- | Pretty printing for type.
prettyType :: Type -> Text
prettyType = render
where
render = go
where
go t =
case t of
JSONType -> "JSON"
VariableType (TypeVariable n) -> nameStream !! n
FunctionType a b ->
(case a of
FunctionType {} -> "(" <> go a <> ")"
_ -> go a) <>
" → " <>
go b
nameStream = go 'a' (0 :: Integer)
where
go c n =
(T.pack
(c :
if n == 0
then ""
else show n)) :
(go
(toEnum (fromEnum 'a' + (mod (fromEnum c - fromEnum 'a' + 1) 26)))
(if c == 'z'
then n + 1
else n))
-- | Pretty printing for expression.
prettyExp :: Expression -> Text
prettyExp = go
where
go t =
case t of
VariableExpression (Variable name) -> name
LambdaExpression (Variable n) e ->
"(\\" <> n <> " -> " <> go e <> ")"
ApplicationExpression f x -> "(" <> go f <> " (" <> go x <> "))"
InfixExpression l o r ->
prettyExp l <> " " <> prettyVariable o <> " " <> prettyExp r
IfExpression a b c ->
"if " <> prettyExp a <> " then " <> prettyExp b <> " else " <>
prettyExp c
RecordExpression hm ->
"{" <>
T.intercalate
", "
(map (\(k, v) -> k <> ": " <> prettyExp v) (HM.toList hm)) <>
"}"
SubscriptExpression o ks ->
(case o of
WildcardSubscripted -> "_"
ExpressionSubscripted e -> go e) <>
mconcat (map prettySubcript ks)
ArrayExpression as ->
"[" <> T.intercalate ", " (map prettyExp (V.toList as)) <> "]"
ConstantExpression c -> prettyConstant c
-- | Pretty printing for core.
prettyCore :: Core -> Text
prettyCore = go
where
go t =
case t of
VariableCore (Variable name) -> name
LambdaCore (Variable n) e -> "(\\" <> n <> " -> " <> go e <> ")"
ApplicationCore f x -> "(" <> go f <> " (" <> go x <> "))"
IfCore a b c ->
"if " <> prettyCore a <> " then " <> prettyCore b <> " else " <>
prettyCore c
RecordCore hm ->
"{" <>
T.intercalate
", "
(map (\(k, v) -> k <> ": " <> prettyCore v) (HM.toList hm)) <>
"}"
EvalCore _ -> "<internal>"
ArrayCore as ->
"[" <> T.intercalate ", " (map prettyCore (V.toList as)) <> "]"
ConstantCore c -> prettyConstant c
prettyConstant :: Constant -> Text
prettyConstant =
\case
NumberConstant s -> T.pack (show s)
StringConstant t -> T.pack (show t)
BoolConstant b ->
if b
then "true"
else "false"
NullConstant -> "null"
prettySubcript :: Subscript -> Text
prettySubcript =
\case
ExpressionSubscript e -> "[" <> prettyExp e <> "]"
PropertySubscript p -> "." <> p
prettyVariable :: Variable -> Text
prettyVariable (Variable t) = t