{-# LANGUAGE TemplateHaskell, StandaloneKindSignatures, UndecidableInstances #-}

module Language.Fortran.Repr.Type.Scalar.String where

import Language.Fortran.Repr.Compat.Natural

import GHC.Generics ( Generic )
import Data.Data ( Data )

--import Data.Singletons.TH
-- required for deriving instances (seems like bug)
--import Prelude.Singletons
--import Data.Ord.Singletons

-- $(singletons [d|
-- | The length of a CHARACTER value.
--
-- IanH provides a great reference on StackOverflow:
-- https://stackoverflow.com/a/25051522/2246637
data CharLen
  = CharLen Natural
  -- ^ @CHARACTER(LEN=x)@ (where @x@ is a constant integer expression). Value
  --   has the given static length.

  | CharLenAssumed
  -- ^ @CHARACTER(LEN=*)@. F90. Value has assumed length. For a dummy argument,
  --   the length is assumed from the actual argument. For a PARAMETER named
  --   constant, the length is assumed from the length of the initializing
  --   expression.

  | CharLenDeferred
  -- ^ @CHARACTER(LEN=:)@. F2003. Value has deferred length. Must have the
  --   ALLOCATABLE or POINTER attribute.

    deriving stock (CharLen -> CharLen -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CharLen -> CharLen -> Bool
$c/= :: CharLen -> CharLen -> Bool
== :: CharLen -> CharLen -> Bool
$c== :: CharLen -> CharLen -> Bool
Eq, Eq CharLen
CharLen -> CharLen -> Bool
CharLen -> CharLen -> Ordering
CharLen -> CharLen -> CharLen
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: CharLen -> CharLen -> CharLen
$cmin :: CharLen -> CharLen -> CharLen
max :: CharLen -> CharLen -> CharLen
$cmax :: CharLen -> CharLen -> CharLen
>= :: CharLen -> CharLen -> Bool
$c>= :: CharLen -> CharLen -> Bool
> :: CharLen -> CharLen -> Bool
$c> :: CharLen -> CharLen -> Bool
<= :: CharLen -> CharLen -> Bool
$c<= :: CharLen -> CharLen -> Bool
< :: CharLen -> CharLen -> Bool
$c< :: CharLen -> CharLen -> Bool
compare :: CharLen -> CharLen -> Ordering
$ccompare :: CharLen -> CharLen -> Ordering
Ord, Int -> CharLen -> ShowS
[CharLen] -> ShowS
CharLen -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CharLen] -> ShowS
$cshowList :: [CharLen] -> ShowS
show :: CharLen -> String
$cshow :: CharLen -> String
showsPrec :: Int -> CharLen -> ShowS
$cshowsPrec :: Int -> CharLen -> ShowS
Show)
--    |])

deriving stock instance Generic CharLen
deriving stock instance Data    CharLen

prettyCharLen :: Natural -> String
prettyCharLen :: Natural -> String
prettyCharLen Natural
l = String
"LEN="forall a. Semigroup a => a -> a -> a
<>forall a. Show a => a -> String
show Natural
l