@@ -46,6 +46,9 @@ module Dhall.Eval (
4646 , Val (.. )
4747 , (~>)
4848 , textShow
49+ , dateShow
50+ , timeShow
51+ , timezoneShow
4952 ) where
5053
5154import Data.Bifunctor (first )
@@ -54,6 +57,7 @@ import Data.Foldable (foldr', toList)
5457import Data.List.NonEmpty (NonEmpty (.. ))
5558import Data.Sequence (Seq , ViewL (.. ), ViewR (.. ))
5659import Data.Text (Text )
60+ import Data.Time (Day , TimeOfDay (.. ), TimeZone )
5761import Data.Void (Void )
5862import Dhall.Map (Map )
5963import Dhall.Set (Set )
@@ -81,7 +85,7 @@ import qualified Data.Time as Time
8185import qualified Dhall.Map as Map
8286import qualified Dhall.Set
8387import qualified Dhall.Syntax as Syntax
84- import qualified Text.Printf
88+ import qualified Text.Printf as Printf
8589
8690data Environment a
8791 = Empty
@@ -206,10 +210,13 @@ data Val a
206210
207211 | VDate
208212 | VDateLiteral Time. Day
213+ | VDateShow ! (Val a )
209214 | VTime
210215 | VTimeLiteral Time. TimeOfDay Word
216+ | VTimeShow ! (Val a )
211217 | VTimeZone
212218 | VTimeZoneLiteral Time. TimeZone
219+ | VTimeZoneShow ! (Val a )
213220
214221 | VList ! (Val a )
215222 | VListLit ! (Maybe (Val a )) ! (Seq (Val a ))
@@ -667,14 +674,26 @@ eval !env t0 =
667674 VDate
668675 DateLiteral d ->
669676 VDateLiteral d
677+ DateShow ->
678+ VPrim $ \ case
679+ VDateLiteral d -> VTextLit (VChunks [] (dateShow d))
680+ t -> VDateShow t
670681 Time ->
671682 VTime
672683 TimeLiteral t p ->
673684 VTimeLiteral t p
685+ TimeShow ->
686+ VPrim $ \ case
687+ VTimeLiteral d p -> VTextLit (VChunks [] (timeShow d p))
688+ t -> VTimeShow t
674689 TimeZone ->
675690 VTimeZone
676691 TimeZoneLiteral z ->
677692 VTimeZoneLiteral z
693+ TimeZoneShow ->
694+ VPrim $ \ case
695+ VTimeZoneLiteral d -> VTextLit (VChunks [] (timezoneShow d))
696+ t -> VTimeZoneShow t
678697 List ->
679698 VPrim VList
680699 ListLit ma ts ->
@@ -898,9 +917,32 @@ textShow text = "\"" <> Text.concatMap f text <> "\""
898917 f ' \r ' = " \\ r"
899918 f ' \t ' = " \\ t"
900919 f ' \f ' = " \\ f"
901- f c | c <= ' \x1F ' = Text. pack (Text. Printf. printf " \\ u%04x" (Data.Char. ord c))
920+ f c | c <= ' \x1F ' = Text. pack (Printf. printf " \\ u%04x" (Data.Char. ord c))
902921 | otherwise = Text. singleton c
903922
923+ -- | Utility that powers the @Date/show@ built-in
924+ dateShow :: Day -> Text
925+ dateShow = Text. pack . Time. formatTime Time. defaultTimeLocale " %0Y-%m-%d"
926+
927+ -- | Utility that powers the @Time/show@ built-in
928+ timeShow :: TimeOfDay -> Word -> Text
929+ timeShow (TimeOfDay hh mm seconds) precision =
930+ Text. pack (Printf. printf " %02d:%02d:%02d" hh mm ss <> suffix)
931+ where
932+ magnitude :: Integer
933+ magnitude = 10 ^ precision
934+
935+ (ss, fraction) =
936+ truncate (seconds * fromInteger magnitude) `divMod` magnitude
937+
938+ suffix
939+ | precision == 0 = " "
940+ | otherwise = Printf. printf " .%0*d" precision fraction
941+
942+ -- | Utility that powers the @TimeZone/show@ built-in
943+ timezoneShow :: TimeZone -> Text
944+ timezoneShow = Text. pack . Time. formatTime Time. defaultTimeLocale " %Ez"
945+
904946conv :: forall a . Eq a => Environment a -> Val a -> Val a -> Bool
905947conv ! env t0 t0' =
906948 case (t0, t0') of
@@ -1008,14 +1050,20 @@ conv !env t0 t0' =
10081050 True
10091051 (VDateLiteral l, VDateLiteral r) ->
10101052 l == r
1053+ (VDateShow t, VDateShow t') ->
1054+ conv env t t'
10111055 (VTime , VTime ) ->
10121056 True
10131057 (VTimeLiteral tl pl, VTimeLiteral tr pr) ->
10141058 tl == tr && pl == pr
1059+ (VTimeShow t, VTimeShow t') ->
1060+ conv env t t'
10151061 (VTimeZone , VTimeZone ) ->
10161062 True
10171063 (VTimeZoneLiteral l, VTimeZoneLiteral r) ->
10181064 l == r
1065+ (VTimeZoneShow t, VTimeZoneShow t') ->
1066+ conv env t t'
10191067 (VList a, VList a') ->
10201068 conv env a a'
10211069 (VListLit _ xs, VListLit _ xs') ->
@@ -1224,14 +1272,20 @@ quote !env !t0 =
12241272 Date
12251273 VDateLiteral d ->
12261274 DateLiteral d
1275+ VDateShow t ->
1276+ DateShow `qApp` t
12271277 VTime ->
12281278 Time
12291279 VTimeLiteral t p ->
12301280 TimeLiteral t p
1281+ VTimeShow t ->
1282+ TimeShow `qApp` t
12311283 VTimeZone ->
12321284 TimeZone
12331285 VTimeZoneLiteral z ->
12341286 TimeZoneLiteral z
1287+ VTimeZoneShow t ->
1288+ TimeZoneShow `qApp` t
12351289 VList t ->
12361290 List `qApp` t
12371291 VListLit ma ts ->
@@ -1427,14 +1481,20 @@ alphaNormalize = goEnv EmptyNames
14271481 Date
14281482 DateLiteral d ->
14291483 DateLiteral d
1484+ DateShow ->
1485+ DateShow
14301486 Time ->
14311487 Time
14321488 TimeLiteral t p ->
14331489 TimeLiteral t p
1490+ TimeShow ->
1491+ TimeShow
14341492 TimeZone ->
14351493 TimeZone
14361494 TimeZoneLiteral z ->
14371495 TimeZoneLiteral z
1496+ TimeZoneShow ->
1497+ TimeZoneShow
14381498 List ->
14391499 List
14401500 ListLit ma ts ->
0 commit comments