-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathItem.hs
150 lines (112 loc) · 4.31 KB
/
Item.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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
{-# LANGUAGE MultiParamTypeClasses, TypeSynonymInstances, FlexibleInstances #-}
{- |
Module : $Header$
Description : positions, simple and mixfix identifiers
Copyright : (c) Christian Maeder and Ewaryst Schulz and Uni Bremen 2009
License : GPLv2 or higher, see LICENSE.txt
Maintainer : Ewaryst.Schulz@dfki.de
Stability : experimental
Portability : non-portable (MPTC)
This module provides the item datatype for an abstract logic independent
representation of basic specs.
-}
module Common.Item where
import Common.Id
import Common.AS_Annotation
import Common.Doc
import Data.Maybe
import Control.Monad
-- element name, attributes and optional text
data ItemType = IT
{ getName :: String
, attrList :: [(String, String)]
, getText :: Maybe Doc }
-- flat items (isFlat=True) are intended for output as xml-attributes
-- but this is not yet used
data Item = Item { itemType :: ItemType
, isFlat :: Bool
, range :: Range
, items :: [Annoted Item]
}
hasValue :: ItemType -> Bool
hasValue (IT _ attrs md) = isJust md || not (null attrs)
instance GetRange Item where
getRange = range
{-
In the following we use these abbreviations:
I = Item
AI = Annoted Item
IT = ItemType or ItemTypeable
-}
-- often we have the situation where we want to obtain an ItemType
-- from a certain Type:
class ItemTypeable a where
toIT :: a -> ItemType
instance ItemTypeable ItemType where
toIT = id
-- intelligent ItemType generation
instance ItemTypeable String where
toIT s = IT s [] Nothing
instance ItemTypeable (String, Doc) where
toIT (s, s') = IT s [] $ Just s'
instance ItemTypeable (String, String, String) where
toIT (s, s', s'') = IT s [(s', s'')] Nothing
class Monad m => ItemConvertible a m where
toitem :: a -> m Item
-- -------------------------- Sublist creation ----------------------------
listFromAL :: ItemConvertible a m => [Annoted a] -> m [Annoted Item]
listFromAL = mapM annToAItem
listFromLWithA :: ItemConvertible a m =>
(Item -> Annoted Item) -> [a] -> m [Annoted Item]
listFromLWithA f = mapM (toAItemWithA f)
listFromL :: ItemConvertible a m => [a] -> m [Annoted Item]
listFromL = mapM toAItem
annToAItem :: ItemConvertible a m => Annoted a -> m (Annoted Item)
annToAItem v = liftM (`replaceAnnoted` v) (toitem $ item v)
toAItemWithA :: ItemConvertible a m =>
(Item -> Annoted Item) -> a -> m (Annoted Item)
toAItemWithA f = liftM f . toitem
toAItem :: ItemConvertible a m => a -> m (Annoted Item)
toAItem = toAItemWithA emptyAnno
-- -------------------------- ItemType lifting ----------------------------
-- often we have the situation where we want to obtain a whole Item
-- or even an Annoted Item from an ItemType:
liftIT2I :: ItemTypeable a => a -> Item
liftIT2I t = mkItem t nullRange []
liftIT2AI :: ItemTypeable a => a -> Annoted Item
liftIT2AI = emptyAnno . liftIT2I
-- -------------------------- Combinators ----------------------------
fromC :: ItemConvertible a m => a -> m (Annoted Item)
fromC = fromAC . emptyAnno
fromAC :: ItemConvertible a m => Annoted a -> m (Annoted Item)
fromAC = annToAItem
fromL :: (ItemConvertible a m, ItemTypeable b) => b -> [a] -> m (Annoted Item)
fromL it l = do
l' <- listFromL l
let i = liftIT2I it
return $ emptyAnno i { items = l' }
fromAL :: (ItemConvertible a m, ItemTypeable b) => b -> [Annoted a] ->
m (Annoted Item)
fromAL it l = do
l' <- listFromAL l
let i = liftIT2I it
return $ emptyAnno i { items = l' }
-- -------------------------- standard items ----------------------------
rootItem :: Item
rootItem = liftIT2I "Basicspec"
mkItem :: ItemTypeable a => a -> Range -> [Annoted Item] -> Item
mkItem it = Item (toIT it) False
mkFlatItem :: ItemTypeable a => a -> Range -> Item
mkFlatItem it rg = Item (toIT it) True rg []
mkItemM :: (ItemTypeable a, Monad m) => a -> Range -> m [Annoted Item] ->
m Item
mkItemM it = liftM . mkItem it
mkItemMM :: (ItemTypeable a, Monad m) => a -> Range -> [m (Annoted Item)] ->
m Item
mkItemMM it rg = mkItemM it rg . sequence
mkFlatItemM :: (ItemTypeable a, Monad m) => a -> Range -> m Item
mkFlatItemM it rg = return $ mkFlatItem it rg
flattenItem :: Item -> Item
flattenItem x = x { isFlat = True }
addRange :: Range -> Item -> Item
addRange rg x = x { range = rg }