-
Notifications
You must be signed in to change notification settings - Fork 6
/
ToDA2.hs
145 lines (121 loc) · 6.88 KB
/
ToDA2.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
{-# LANGUAGE OverloadedStrings #-}
module ToDA2 where
import Prettyprinter as PP
import Prettyprinter.Render.Text (putDoc)
import L4.Syntax
import L4.Typing (isBooleanTp, isIntegerTp)
import Data.List (find, intersperse)
import Data.Char (toLower)
import Data.Maybe (fromMaybe, listToMaybe, catMaybes, Maybe (Nothing))
import Control.Monad (unless)
import Control.Monad.Reader
import Control.Applicative (liftA2)
createDSyaml :: (Show t, Eq t) => Program (Tp t) -> IO ()
createDSyaml p = putDoc $ showDS p
-- Perhaps instead of using Maybe, an Either would be better.
-- With Left :: Doc ann = PP.emptyDoc, and right :: WithProgram (Doc ann) = concretized
data DSBlock t = DSBlock { blkName :: String
, blkType :: Either String (Tp t)
, blkCard :: Maybe Int -- cardinality
, blkEncodings :: String
, blkAttrs :: [Maybe (DSBlock t)]
, blkUI :: [Maybe t] -- ask, tell, any, another
, blkSource :: Maybe String
}
instance (Show t) => DSYaml (DSBlock t) where
showDS DSBlock { blkName, blkType, blkCard, blkEncodings, blkAttrs, blkUI, blkSource} =
hang 2 $ "-" <+> vsep [ "name:" <+> pretty blkName
, "type:" <+> either pretty showDS blkType
, "minimum: 0 # Change cardinality accordingly" --cardinality goes here
-- , "ask/tell/any/other:" -- ui goes here
, "encodings:" , indent 2 $ "-" <+> pretty blkEncodings -- TODO : add functionality for list-encoding
, putSource blkSource <> putAttrs blkAttrs <> PP.line
]
where putAttrs ba = case ba of
[Nothing] -> PP.emptyDoc
_ -> "attributes:" <> PP.line <> indent 2 (showDSlist $ catMaybes ba) -- attributes here (one-level only)
putSource (Just x) = "source:" <+> pretty x
putSource Nothing = PP.emptyDoc
-- ClassDecl {
-- annotOfClassDecl = _
-- , nameOfClassDecl = ClsNm "Sign"
-- , defOfClassDecl = ClassDef { supersOfClassDef = [ ClsNm "Sign"
-- , ClsNm "Class"
-- , ClsNm "Object" ]
-- , fieldsOfClassDef = [ FieldDecl { annotOfFieldDecl = _
-- , nameOfFieldDecl = FldNm "beat"
-- , tpOfFieldDecl = FunT
-- ( ClassT ( ClsNm "Sign" ) ) BooleanT}]} }
--
-- ClassDecl { annotOfClassDecl = _
-- , nameOfClassDecl = ClsNm "Player"
-- , defOfClassDecl = ClassDef { supersOfClassDef = [ ClsNm "Player"
-- , ClsNm "Class"
-- , ClsNm "Object" ]
-- , fieldsOfClassDef = [ FieldDecl { annotOfFieldDecl = _
-- , nameOfFieldDecl = FldNm "throw"
-- , tpOfFieldDecl = FunT ( ClassT ( ClsNm "Sign" ) ) BooleanT } ] } }
-- ClassDecl { annotOfClassDecl = _
-- , nameOfClassDecl = ClsNm "Game"
-- , defOfClassDecl = ClassDef { supersOfClassDef = [ ClsNm "Game"
-- , ClsNm "Class"
-- , ClsNm "Object" ]
-- , fieldsOfClassDef = [ FieldDecl { annotOfFieldDecl = _
-- , nameOfFieldDecl = FldNm "participate_in"
-- , tpOfFieldDecl = FunT ( ClassT ( ClsNm "Player" ) ) BooleanT
-- }
-- , FieldDecl { annotOfFieldDecl = _
-- , nameOfFieldDecl = FldNm "win"
-- , tpOfFieldDecl = FunT ( ClassT ( ClsNm "Player" ) ) BooleanT
-- }
-- ] } } ]
classDeclToBlock :: (Eq ct, Show ct) => ClassDecl ct -> DSBlock ct
classDeclToBlock ClassDecl { nameOfClassDecl, defOfClassDecl } =
DSBlock { blkName = lowercase clnm
, blkType = Left "String" -- This needs to show "boolean" for types that are supported
, blkCard = Nothing
, blkEncodings = lowercase clnm ++ "(X)"
, blkAttrs = mapAttrs $ fieldsOfClassDef defOfClassDecl
, blkUI = undefined
, blkSource = Nothing
}
where clnm = (\(ClsNm name) -> name) nameOfClassDecl
mapAttrs x = case x of
[] -> [Nothing]
_ -> map (Just . fieldDeclToBlock) x
fieldDeclToBlock :: (Eq ct, Show ct) => FieldDecl ct -> DSBlock ct
fieldDeclToBlock (FieldDecl _ (FldNm fldnm) fieldtype) =
DSBlock { blkName = lowercase fldnm
, blkType = eitherTp "Object" fieldtype fieldtype -- This needs to show the "boolean" for types that are supported
, blkCard = Nothing
, blkEncodings = (lowercase fldnm ++) $ either id id $ eitherTp "(X,Y)" "(Y)" fieldtype
, blkAttrs = [Nothing]
, blkUI = undefined
, blkSource = showFTname fieldtype -- for supported types, there is no source block
}
eitherTp :: Eq t => String -> a -> Tp t -> Either String a
eitherTp x1 x2 tp = if isBooleanTp tp || isIntegerTp tp then Right x2 else Left x1
showFTname :: Show t => Tp t -> Maybe String
showFTname tp = case tp of
(FunT _ x (ClassT _ BooleanC)) -> showFTname x
(ClassT _ (ClsNm name)) -> Just $ lowercase name
_ -> Nothing
lowercase = map toLower
-- type WithProgram = Reader (Program Tp)
class DSYaml x where
showDS :: x -> Doc ann
showDSlist :: [x] -> Doc ann
showDSlist = vsep . map showDS
instance (Show t, Eq t) => DSYaml (Program (Tp t)) where
showDS prg = do
vsep [ "rules: "
, "query: "
, "data:" , hang 2 $ showDSlist $ map classDeclToBlock $ reverse $ drop 7 (classDeclsOfProgram prg)
, "terms: "
, "options: " <> PP.line
]
instance DSYaml (Tp t) where
showDS tp = case tp of
(ClassT _ BooleanC) -> "Boolean"
(ClassT _ IntegerC) -> "Number"
_ -> "Unsupported Type"