-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathAtomTable.hs
56 lines (43 loc) · 1.49 KB
/
AtomTable.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
{-# LANGUAGE OverloadedStrings #-}
module AtomTable
( AtomTable
, empty
, fromList
, add
, merge
, listNames
, lookupByName
, lookupByCode
) where
import qualified Data.ByteString as B
import Data.Int
import Data.List as List
import ETerm (AtomNo (..))
data AtomTable = AT !Int32 [(B.ByteString, AtomNo)] deriving Show
empty :: AtomTable
empty = AT 0 []
fromList :: [B.ByteString] -> AtomTable
fromList lst = merge empty (AT (fromIntegral (length lst)) (zip lst (map AtomNo [0..])))
add :: AtomTable -> B.ByteString -> AtomTable
add at@(AT no xs) name =
case lookupByNameM at name of
Just _ -> at
Nothing -> AT (no+1) ((name, AtomNo no):xs)
merge :: AtomTable -> AtomTable -> AtomTable
merge at1 at2 = foldl' add at1 (listNames at2)
listNames :: AtomTable -> [B.ByteString]
listNames (AT _ xs) = map fst xs
lookupByNameM :: AtomTable -> B.ByteString -> Maybe AtomNo
lookupByNameM (AT _ xs) name = List.lookup name xs
lookupByName :: AtomTable -> B.ByteString -> AtomNo
lookupByName at name =
case lookupByNameM at name of
Just no -> no
Nothing -> error $ "AT.lookupByName: atom not found: " ++ show name
lookupByCodeM :: AtomTable -> AtomNo -> Maybe B.ByteString
lookupByCodeM (AT _ xs) code = List.lookup code (map (\(x,y) -> (y,x)) xs)
lookupByCode :: AtomTable -> AtomNo -> B.ByteString
lookupByCode at no =
case lookupByCodeM at no of
Just bs -> bs
Nothing -> error $ "AT.lookupByCode: atom not found: " ++ show no