2021-01-30 23:37:53 +00:00
|
|
|
module haskell
|
2021-02-01 01:46:31 +00:00
|
|
|
imports libstrategolib signatures/- util
|
2021-01-30 23:37:53 +00:00
|
|
|
rules
|
2021-02-01 01:46:31 +00:00
|
|
|
/* Approach: Generate code from the bottom up.
|
|
|
|
At every node, we create a pair of the implementation and
|
|
|
|
necessary preamble of IO actions.
|
|
|
|
We concatenate preambles as we go up.
|
|
|
|
Finally, at the toplevel we emit the preamble before returning the
|
|
|
|
final value.
|
|
|
|
*/
|
|
|
|
|
|
|
|
hs: TopLevel((c,p)) -> $[import System.IO
|
2021-01-30 23:37:53 +00:00
|
|
|
data IOStream = StdIO
|
|
|
|
|
2021-02-06 05:11:41 +00:00
|
|
|
gets :: Show b => a -> b -> IO a
|
|
|
|
gets s d = do
|
2021-01-30 23:37:53 +00:00
|
|
|
putStr(show d)
|
2021-02-06 05:11:41 +00:00
|
|
|
return s
|
2021-01-30 23:37:53 +00:00
|
|
|
|
|
|
|
main = do
|
2021-02-01 01:46:31 +00:00
|
|
|
[p]return [c]]
|
2021-01-30 23:37:53 +00:00
|
|
|
|
2021-02-10 20:47:34 +00:00
|
|
|
hs: Stream() -> ("StdIO", "")
|
|
|
|
hs: Int(x) -> (x, "")
|
2021-02-11 18:02:43 +00:00
|
|
|
hs: LitString(x)
|
|
|
|
-> ($["[<string-as-chars(escape-chars(HaskellEscape))>x]"], "")
|
2021-02-06 05:11:41 +00:00
|
|
|
hs: Sum( (c, p), (d, q)) -> ($[([c] + [d])], <conc-strings>(p,q))
|
|
|
|
|
2021-02-10 20:47:34 +00:00
|
|
|
hs: Gets((c, p), (d, q)) -> <hsget>(c,d,<conc-strings>(p,q),<newname>"fosgt")
|
2021-02-06 05:11:41 +00:00
|
|
|
hsget: (s, x, p, v) -> (v, <concat-strings>[p, $[[v] <- [s] `gets` [x]],
|
|
|
|
"\n"])
|
|
|
|
|
|
|
|
hs: To( (c, p), (d, q)) -> <hsto>(c,d,<conc-strings>(p,q),<newname>"fosto")
|
|
|
|
hsto: (x, s, p, v) -> (v, <concat-strings>[p, $[let [v] = [x]], "\n",
|
2021-02-10 20:47:34 +00:00
|
|
|
$[[s] `gets` [v]], "\n"])
|
2021-02-01 01:46:31 +00:00
|
|
|
|
2021-02-10 20:47:34 +00:00
|
|
|
hs: Terminate((c,p)) -> ($[[c];;], p)
|
|
|
|
hs: Sequence(l) -> (<last; Fst>l, <map(Snd); concat-strings>l)
|
2021-01-30 23:37:53 +00:00
|
|
|
|
2021-02-11 18:02:43 +00:00
|
|
|
/* Characters we need to escape in Haskell string constants */
|
|
|
|
Hascape: ['\t' | cs ] -> ['\', 't' | cs ]
|
|
|
|
/* I think I can just use ASCII constants for characters... */
|
|
|
|
Hascape: [ 0 | cs ] -> ['\', '0' | cs ]
|
|
|
|
Hascape: [ 7 | cs ] -> ['\', 'a' | cs ] // Alert
|
|
|
|
Hascape: [ 8 | cs ] -> ['\', 'b' | cs ] // Backspace
|
|
|
|
Hascape: [ 11 | cs ] -> ['\', 'v' | cs ] // Vertical tab
|
|
|
|
Hascape: [ 12 | cs ] -> ['\', 'f' | cs ] // Form feed
|
|
|
|
|
2021-01-30 23:37:53 +00:00
|
|
|
strategies
|
2021-02-11 18:02:43 +00:00
|
|
|
HaskellEscape = Escape <+ Hascape
|
2021-02-01 08:29:00 +00:00
|
|
|
|
2021-02-06 05:11:41 +00:00
|
|
|
haskell = bottomup(try(hs))
|
2021-01-30 23:37:53 +00:00
|
|
|
|
|
|
|
// Interface haskell code generation with editor services and file system
|
|
|
|
to-haskell: (selected, _, _, path, project-path) -> (filename, result)
|
|
|
|
with filename := <guarantee-extension(|"hs")> path
|
|
|
|
; result := <haskell> selected
|