elna/lib/Language/Elna/SymbolTable.hs

79 lines
2.2 KiB
Haskell
Raw Normal View History

2024-07-26 12:22:07 +02:00
module Language.Elna.SymbolTable
( Info(..)
, ParameterInfo(..)
2024-07-29 07:26:47 +02:00
, SymbolTable
2024-08-05 22:56:35 +02:00
, builtInSymbolTable
, empty
2024-07-29 07:26:47 +02:00
, enter
2024-08-04 12:23:19 +02:00
, fromList
2024-07-29 07:26:47 +02:00
, lookup
2024-08-05 22:56:35 +02:00
, member
2024-07-26 12:22:07 +02:00
) where
import Data.HashMap.Strict (HashMap)
2024-07-29 07:26:47 +02:00
import qualified Data.HashMap.Strict as HashMap
2024-08-05 22:56:35 +02:00
import Data.List (sort)
import Data.List.NonEmpty (NonEmpty)
import qualified Data.List.NonEmpty as NonEmpty
2024-07-26 12:22:07 +02:00
import Data.Vector (Vector)
2024-07-29 07:26:47 +02:00
import Language.Elna.Location (Identifier(..))
import Language.Elna.Types (Type(..), intType, booleanType)
import Prelude hiding (lookup)
2024-07-26 12:22:07 +02:00
2024-07-29 07:26:47 +02:00
newtype SymbolTable = SymbolTable (HashMap Identifier Info)
deriving (Eq, Show)
instance Semigroup SymbolTable
where
(SymbolTable lhs) <> (SymbolTable rhs) = SymbolTable $ rhs <> lhs
2024-07-26 12:22:07 +02:00
2024-07-29 07:26:47 +02:00
instance Monoid SymbolTable
2024-07-26 12:22:07 +02:00
where
2024-08-05 22:56:35 +02:00
mempty = empty
2024-07-26 12:22:07 +02:00
2024-08-04 12:23:19 +02:00
builtInSymbolTable :: SymbolTable
builtInSymbolTable = SymbolTable $ HashMap.fromList
2024-07-29 07:26:47 +02:00
[ ("boolean", TypeInfo booleanType)
, ("int", TypeInfo intType)
]
2024-07-26 12:22:07 +02:00
empty :: SymbolTable
empty = SymbolTable HashMap.empty
2024-08-05 22:56:35 +02:00
enter :: Identifier -> Info -> SymbolTable -> Maybe SymbolTable
enter identifier info table@(SymbolTable hashTable)
| member identifier table = Nothing
| otherwise = Just
$ SymbolTable
$ HashMap.insert identifier info hashTable
2024-07-26 12:22:07 +02:00
2024-07-29 07:26:47 +02:00
lookup :: Identifier -> SymbolTable -> Maybe Info
lookup identifier (SymbolTable table) = HashMap.lookup identifier table
2024-07-26 12:22:07 +02:00
2024-08-05 22:56:35 +02:00
member :: Identifier -> SymbolTable -> Bool
member identifier (SymbolTable table) = HashMap.member identifier table
fromList :: [(Identifier, Info)] -> Either (NonEmpty Identifier) SymbolTable
fromList elements
| Just identifierDuplicates' <- identifierDuplicates =
Left identifierDuplicates'
| otherwise = Right $ SymbolTable $ HashMap.fromList elements
where
identifierDuplicates = NonEmpty.nonEmpty
$ fmap NonEmpty.head
$ filter ((> 1) . NonEmpty.length)
$ NonEmpty.group . sort
$ fst <$> elements
2024-08-04 12:23:19 +02:00
2024-07-26 12:22:07 +02:00
data ParameterInfo = ParameterInfo
{ name :: Identifier
, type' :: Type
, isReferenceParameter :: Bool
} deriving (Eq, Show)
data Info
= TypeInfo Type
| VariableInfo Type Bool
| ProcedureInfo SymbolTable (Vector ParameterInfo)
deriving (Eq, Show)