3 Copyright : (c) Miguel Vilaça and Daniel Mendes 2007
5 Maintainer : jmvilaca@di.uminho.pt and danielgomesmendes@gmail.com
6 Stability : experimental
10 Small Functional Language: Graphical stuff for integration in INblobs.
19 import qualified PersistentDocument as PD
24 import Text.XML.HaXml.XmlContent (XmlContent)
27 import Graphics.UI.WXCore
29 import Functional.Language
30 import Functional.Parser
31 import Functional.Compiler
35 import qualified Control.Exception as E
38 -- | List of strategies for which compilation is available.
39 listCallBy :: [CallBy]
40 listCallBy = [ Name, Value ]
42 -- | GUI for compilation of BNL to INs.
43 compileUI :: (InfoKind n g, InfoKind e g, XmlContent g) => State g n e -> g -> n -> e -> IO ()
44 compileUI state g n e =
45 closeDocAndThen state $
47 theFrame <- getNetworkFrame state
49 res <- parseDialog theFrame
53 |not . null $ freeVars term ->
54 errorDialog theFrame "Free variables"
55 $ "Only closed terms are allowed and this one have the following free vars:\n" ++ commasAnd (freeVars term)
56 Just (term, callBy) ->
58 let iterSymbs = listIteratorSymbols term
59 names <- if null iterSymbs
61 else meaningfulNamesDialog iterSymbs theFrame
65 flip E.catch (\exception ->
67 logMessage "END COMPILATION BADLY"
69 errorDialog theFrame "Compilation failed..." (show exception)
73 let fname = "examples/New-Token-Passing/CallBy"
75 "ForClosedTerms+BNL-Iterators.INblobs"
76 openNetworkFile fname state (Just theFrame)
77 pDoc <- getDocument state
78 doc <- PD.getDocument pDoc
80 logMessage "COMPILING..."
81 doc2 <- compile g n e callBy term names doc
82 logMessage "END COMPILATION SUCCESSFULLY"
84 let fname2 = "examples/New-Token-Passing/GENERATED-CallBy"
86 "ForClosedTerms+BNL-Iterators.INblobs"
87 PD.resetDocument (Just fname2) doc2 pDoc
91 buildVisiblePalette state
95 -- | Deal with collecting a term from the user.
96 -- Graphical treatment of parsing errors is done here.
97 parseDialog :: Frame () -> IO (Maybe (FuncLang,CallBy))
98 parseDialog theFrame =
100 dial <- dialog theFrame [text := "Functional term to IN system", position := pt 200 20]
102 termbox <- textCtrlRich p [text := ""]
105 , on command := infoDialog dial "Help" helpString
108 okB <- button p [ text := "Ok" ]
109 canB <- button p [ text := "Cancel" ]
111 -- one button per functional language constructor
112 listBs <- mapM (\(name,term) -> button p
114 , on command := addTxtInPlace2TextCtrl termbox $ show term
119 when (null listCallBy) (error "No strategies available.")
120 callByUI <- radioBox p Vertical (map show listCallBy)
121 [ text := "Which evaluation strategy?"
125 errorsUI <- textCtrl p [ visible := False ]
127 set dial [ layout := container p $
129 column 5 [ label "Input your term:"
130 , row 2 [ hfill $ widget termbox
131 , column 10 (map widget listBs)
134 , minsize (sz 30 30) . fill $ widget errorsUI
137 , floatRight $ row 5 [widget okB, widget canB]
141 showModal dial $ \stop ->
143 set canB [on command := stop Nothing]
144 set okB [on command :=
146 set errorsUI [ visible := False, text := ""]
147 txt <- get termbox text
148 i <- get callByUI selection
151 Left term -> stop $ Just (term, listCallBy !! i)
154 set errorsUI [ visible := True
155 , text := "Parse error:\n" ++ errMsg
157 errorDialog theFrame "Parsing Error" "Parsing error.\nSee report."
160 where helpString = "Use the buttons on the right side to create a term or write it if already familiar with the syntax."
162 -- | Allow the user to supply more meaningful names for symbols that correspond to iterators with internalized arguments.
164 -- * given names don't contain blank or control characters
165 -- * given names are disjoint
166 meaningfulNamesDialog :: [FuncLang] -> Frame () -> IO (Maybe [(FuncLang, String)])
167 meaningfulNamesDialog terms theFrame =
169 dial <- dialog theFrame [text := "Meaningful names"
170 , position := pt 200 20
175 listG <- listCtrl p [ columns := [ ("Symbol name", AlignRight, -1)
176 , ("Term", AlignLeft, 200)
178 , items := [[name, showAgent term] | (term, name) <- giveNames terms]
179 , style :~ (wxLC_EDIT_LABELS .+. wxLC_VRULES .+.)
182 okB <- button p [ text := "Ok" ]
183 canB <- button p [ text := "Cancel" ]
185 errorsUI <- textCtrl p [ visible := False ]
187 set dial [ layout := container p $
189 column 5 [ label "Edit the \"Symbol name\" column to give more meaningful names."
190 , fill $ widget listG
191 , fill $ widget errorsUI
193 , floatRight $ row 5 [widget okB, widget canB]
197 showModal dial $ \stop ->
198 do set okB [ on command :=
200 newNames <- get listG items
201 let mapp = zip terms (map head newNames)
202 -- Check that given names are good names.
203 badNames = filter (badName . snd) mapp
204 -- Check that given names are disjoint.
205 equalNames = filter ((> 1) . length)
206 $ groupBy (\(_,a) (_,b) -> a == b) mapp
207 case (null badNames, null equalNames) of
208 (True, True) -> stop $ Just mapp
209 (False, _) -> -- some bad names
210 set errorsUI [ visible := True
211 , text := "The symbol's name(s) for the following term(s) contain invalid (control or blank) characters:\n"
212 ++ (indent 1 . unlines) (map (showAgent . fst) badNames)
214 (True, False) -> -- repeated names
215 set errorsUI [ visible := True
216 , text := "The following terms have the same name(s):\n "
217 ++ beautify equalNames
220 set canB [on command := stop Nothing]
222 beautify :: [[(FuncLang,String)]] -> String
223 beautify = unlines . map (\l -> snd (head l) ++ "\n"
224 ++ indent 1 (unlines $ map (showAgent.fst) l))
225 badName = any (\c -> isSpace c || isControl c)