From bb1e6a4a657418eb46d2d1362a92dfefb75bddc1 Mon Sep 17 00:00:00 2001 From: Laurent Date: Wed, 23 Feb 2022 20:56:08 -0500 Subject: [PATCH 1/2] Represent every values as text --- core/src/Language/Avaleryar/Syntax.hs | 36 +++++++++++++++++++++------ 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/core/src/Language/Avaleryar/Syntax.hs b/core/src/Language/Avaleryar/Syntax.hs index 674e0f5..8304bf5 100644 --- a/core/src/Language/Avaleryar/Syntax.hs +++ b/core/src/Language/Avaleryar/Syntax.hs @@ -6,11 +6,13 @@ {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE PatternSynonyms #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeSynonymInstances #-} +{-# LANGUAGE ViewPatterns #-} {-| @@ -59,13 +61,36 @@ import GHC.Generics (Generic) import Text.Megaparsec (SourcePos(..), pos1, unPos) import Text.PrettyPrint.Leijen.Text (Doc, Pretty(..), brackets, colon, dot, empty, group, hsep, line, nest, parens, punctuate, space, vsep) +import Text.Read (readMaybe) -data Value - = I Int - | T Text - | B Bool +newtype Value = T Text deriving (Eq, Ord, Read, Show, Generic) +{-# COMPLETE I, B, T #-} +pattern I :: Int -> Value +pattern I i <- T (readMaybe . T.unpack -> Just i) where + I i = T . T.pack $ show i + +pattern B :: Bool -> Value +pattern B b <- T (textToBool -> Just b) where + B b = T (if b then "#t" else "#f") + +textToBool :: Text -> Maybe Bool +textToBool "#t" = Just True +textToBool "#f" = Just False +textToBool _ = Nothing + +-- COMPLETE Pragma is necessary because the exhausiveness checker doesn't work at all with pattern synonyms. +-- See https://gitlab.haskell.org/ghc/ghc/-/wikis/pattern-synonyms/complete-sigs +-- pattern IpAddr :: ToFromWords word => word -> word -> word -> word -> IpAddr word +-- pattern IpAddr w1 w2 w3 w4 <- IpAddrInternal (toWords -> (w1, w2, w3, w4)) where +-- IpAddr w1 w2 w3 w4 = IpAddrInternal $ fromWords w1 w2 w3 w4 +-- pattern Smarter{ nonneg } <- Pos nonneg where +-- Smarter x = if x >= 0 then (Pos x) else (Neg x) +-- pattern Smarter{ nonneg } <- Pos nonneg where +-- Smarter x | x >= 0 = (Pos x) +-- | otherwise = (Neg x) + instance NFData Value instance Hashable Value @@ -73,8 +98,6 @@ instance IsString Value where fromString = T . fromString instance Pretty Value where - pretty (I n) = pretty n - pretty (B b) = if b then "#t" else "#f" pretty (T t) = if T.any isSpace t then pretty (show t) -- want the quotes/escaping else pretty t -- display as a symbol @@ -267,7 +290,6 @@ instance Valuable Value where instance Valuable Text where toValue = T fromValue (T a) = Just a - fromValue _ = Nothing instance Valuable Int where toValue = I From b2cea93bf303c19fd44939503187db88525a5547 Mon Sep 17 00:00:00 2001 From: Laurent Date: Wed, 23 Feb 2022 21:02:51 -0500 Subject: [PATCH 2/2] Comments --- core/src/Language/Avaleryar/Syntax.hs | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/core/src/Language/Avaleryar/Syntax.hs b/core/src/Language/Avaleryar/Syntax.hs index 8304bf5..1c8dc5a 100644 --- a/core/src/Language/Avaleryar/Syntax.hs +++ b/core/src/Language/Avaleryar/Syntax.hs @@ -64,8 +64,10 @@ import Text.PrettyPrint.Leijen.Text import Text.Read (readMaybe) newtype Value = T Text - deriving (Eq, Ord, Read, Show, Generic) + deriving (Eq, Ord, Read, Show, Generic) +-- COMPLETE Pragma is necessary because the exhausiveness checker doesn't work at all with pattern synonyms. +-- See https://gitlab.haskell.org/ghc/ghc/-/wikis/pattern-synonyms/complete-sigs {-# COMPLETE I, B, T #-} pattern I :: Int -> Value pattern I i <- T (readMaybe . T.unpack -> Just i) where @@ -80,17 +82,6 @@ textToBool "#t" = Just True textToBool "#f" = Just False textToBool _ = Nothing --- COMPLETE Pragma is necessary because the exhausiveness checker doesn't work at all with pattern synonyms. --- See https://gitlab.haskell.org/ghc/ghc/-/wikis/pattern-synonyms/complete-sigs --- pattern IpAddr :: ToFromWords word => word -> word -> word -> word -> IpAddr word --- pattern IpAddr w1 w2 w3 w4 <- IpAddrInternal (toWords -> (w1, w2, w3, w4)) where --- IpAddr w1 w2 w3 w4 = IpAddrInternal $ fromWords w1 w2 w3 w4 --- pattern Smarter{ nonneg } <- Pos nonneg where --- Smarter x = if x >= 0 then (Pos x) else (Neg x) --- pattern Smarter{ nonneg } <- Pos nonneg where --- Smarter x | x >= 0 = (Pos x) --- | otherwise = (Neg x) - instance NFData Value instance Hashable Value