2019-06-10 05:36:18 +03:00
|
|
|
-- Copyright 2019 Google LLC
|
|
|
|
--
|
|
|
|
-- Use of this source code is governed by a BSD-style
|
|
|
|
-- license that can be found in the LICENSE file or at
|
|
|
|
-- https://developers.google.com/open-source/licenses/bsd
|
|
|
|
|
|
|
|
-- | Simple example using this package
|
|
|
|
{-# LANGUAGE OverloadedStrings #-}
|
|
|
|
{-# LANGUAGE NoMonomorphismRestriction #-}
|
|
|
|
module Main (main) where
|
|
|
|
|
|
|
|
import GHC.Paths (libdir)
|
|
|
|
import GHC (runGhc)
|
2021-08-12 15:23:54 +03:00
|
|
|
import GHC.Utils.Outputable (Outputable)
|
2019-06-10 05:36:18 +03:00
|
|
|
|
|
|
|
import GHC.SourceGen
|
|
|
|
|
|
|
|
main :: IO ()
|
|
|
|
main = mapM_ run [test1, test2, test3, test4, test5]
|
|
|
|
where
|
|
|
|
run act = putStrLn "========" >> act
|
|
|
|
|
|
|
|
pprint :: Outputable a => a -> IO ()
|
|
|
|
pprint x = runGhc (Just libdir) $ putPpr x
|
|
|
|
|
|
|
|
test1 :: IO ()
|
|
|
|
test1 = pprint $ tuple
|
|
|
|
[ var "Foo.abc"
|
|
|
|
, overLabel "def"
|
|
|
|
, char 'g'
|
|
|
|
, let' [ typeSig "result" $ var "A" @@ var "B"
|
|
|
|
, funBind "result"
|
2019-08-31 20:38:36 +03:00
|
|
|
$ match [bvar "x", wildP]
|
2019-06-10 05:36:18 +03:00
|
|
|
$ var "foo" @@ char 'c'
|
|
|
|
]
|
|
|
|
(var "result")
|
|
|
|
]
|
|
|
|
|
|
|
|
test2 :: IO ()
|
|
|
|
test2 = pprint $ module' (Just "Foo") (Just [var "efg"]) []
|
|
|
|
[ typeSigs ["efg", "h"] $ tuple [var "A", var "B"]
|
|
|
|
, funBind "efg"
|
2019-08-18 08:21:24 +03:00
|
|
|
$ matchGRHSs []
|
2019-07-14 16:40:18 +03:00
|
|
|
$ rhs (char 'a')
|
2019-06-10 05:36:18 +03:00
|
|
|
`where'` [ typeSig "q" $ var "Q"
|
2019-08-18 08:21:24 +03:00
|
|
|
, funBind "q" $ matchGRHSs []
|
2019-07-14 16:56:18 +03:00
|
|
|
$ guardedRhs [var "True" `guard` char 'q']
|
2019-06-10 05:36:18 +03:00
|
|
|
]
|
|
|
|
, funBind "f"
|
2019-08-31 20:38:36 +03:00
|
|
|
$ matchGRHSs [bvar "x", bvar "y"]
|
2019-07-14 16:40:18 +03:00
|
|
|
$ rhs
|
2019-06-10 05:36:18 +03:00
|
|
|
(case' (var "y")
|
2019-08-18 08:21:24 +03:00
|
|
|
[match [wildP] $ var "x"])
|
|
|
|
`where'` [funBind "q" $ match [] $ char 't']
|
2019-06-10 05:36:18 +03:00
|
|
|
]
|
|
|
|
|
|
|
|
test3 :: IO ()
|
|
|
|
test3 = pprint $ module' Nothing Nothing []
|
2019-08-31 20:38:36 +03:00
|
|
|
[ funBind "lambdas" $ match [] $ lambda [bvar "y"]
|
|
|
|
$ lambdaCase [match [bvar "z"] (char 'a')]
|
2019-06-10 05:36:18 +03:00
|
|
|
, funBinds "ifs"
|
2019-08-31 20:38:36 +03:00
|
|
|
[ match [bvar "x"] $ if' (var "b") (var "t") (var "f")
|
|
|
|
, match [bvar "y"] $ multiIf [guard (var "False") $ char 'f'
|
2019-07-14 16:40:18 +03:00
|
|
|
, guard (var "True") $ char 't'
|
|
|
|
]
|
2019-08-31 20:38:36 +03:00
|
|
|
, match [bvar "z"] $ multiIf
|
2019-07-14 16:40:18 +03:00
|
|
|
[ guard (var "f" @@ var "x") $ string "f"
|
|
|
|
, guard (var "g" @@ var "x") $ string "g"
|
|
|
|
, guard (var "otherwise") $ string "h"
|
2019-06-10 05:36:18 +03:00
|
|
|
]
|
|
|
|
]
|
|
|
|
, funBind "do'"
|
2019-08-31 20:38:36 +03:00
|
|
|
$ match [] (do' [ bvar "x" <-- var "act"
|
2019-06-10 05:36:18 +03:00
|
|
|
, stmt $ var "return" @@ var "x"
|
|
|
|
])
|
|
|
|
, typeSig "types"
|
2019-08-31 20:38:36 +03:00
|
|
|
$ forall' [bvar "x", bvar "y"]
|
2019-06-10 05:36:18 +03:00
|
|
|
$ [var "Show" @@ var "x"] ==> var "y"
|
|
|
|
, typeSig "types'"
|
|
|
|
$ [var "Show" @@ var "x"] ==>
|
2019-08-31 20:38:36 +03:00
|
|
|
(forall' [bvar "x", bvar "y"]
|
2019-06-10 05:36:18 +03:00
|
|
|
$ var "y")
|
|
|
|
, funBind "swap"
|
2019-08-31 20:38:36 +03:00
|
|
|
$ match [tuple [bvar "x", bvar "y"]]
|
2019-06-10 05:36:18 +03:00
|
|
|
$ tuple [var "y", var "x"]
|
2019-08-18 08:21:24 +03:00
|
|
|
, funBind "char" $ match [char 'a'] (char 'b')
|
|
|
|
, funBind "string" $ match [string "abc"] (string "def")
|
2019-06-10 05:36:18 +03:00
|
|
|
, funBind "as"
|
2019-08-31 20:38:36 +03:00
|
|
|
$ match [asP "x" (tuple [bvar "y", bvar "z"])]
|
2019-06-10 05:36:18 +03:00
|
|
|
(var "x")
|
|
|
|
, funBind "con"
|
2019-08-31 20:38:36 +03:00
|
|
|
$ match [conP "A" [bvar "b", conP "C" [bvar "d"]]]
|
2019-06-10 05:36:18 +03:00
|
|
|
$ tuple [var "b", var "d"]
|
|
|
|
, funBind "ops"
|
2019-08-31 20:38:36 +03:00
|
|
|
$ match [bvar "x", bvar "y"]
|
2019-06-10 05:36:18 +03:00
|
|
|
$ op (var "x") "+" (var "y")
|
|
|
|
, funBinds "ops'"
|
2019-08-18 08:21:24 +03:00
|
|
|
[ match [] (op (int 1) "*"
|
2019-06-10 05:36:18 +03:00
|
|
|
(op (int 2) "+" (int 3)))
|
2019-08-18 08:21:24 +03:00
|
|
|
, match [] (op (var "A" @@ var "x") "*"
|
2019-06-10 05:36:18 +03:00
|
|
|
(op (var "B" @@ var "y") "+"
|
|
|
|
(var "C" @@ var "z")))
|
2019-08-18 08:21:24 +03:00
|
|
|
, match [] (op (var "A" @@ var "x") "mult"
|
2019-06-10 05:36:18 +03:00
|
|
|
(op (var "B" @@ var "y") "+"
|
|
|
|
(var "C" @@ var "z")))
|
|
|
|
]
|
|
|
|
, funBinds "cons'"
|
2019-08-18 08:21:24 +03:00
|
|
|
[ match [] (var "X" @@ int 1 @@
|
2019-06-10 05:36:18 +03:00
|
|
|
(var "Y" @@ int 2 @@ int 3)
|
|
|
|
@@ var "Z")
|
2019-08-18 08:21:24 +03:00
|
|
|
, match [] (var "f" @@ par (var "g" @@ var "x"))
|
2019-06-10 05:36:18 +03:00
|
|
|
]
|
|
|
|
, typeSig "f" $ var "X" @@ var "a" @@
|
|
|
|
(var "Y" @@ var "b" @@ var "c")
|
|
|
|
@@ var "Z"
|
|
|
|
, typeSig "g" $ op (var "A" @@ var "x") "*"
|
|
|
|
(op (var "B" @@ var "y") "+"
|
|
|
|
(var "C" @@ var "z"))
|
2020-02-03 19:23:30 +03:00
|
|
|
, class' [var "A" @@ var "a"] "B" [bvar "b", bvar "b'"]
|
2019-06-10 05:36:18 +03:00
|
|
|
[ typeSig "f" $ var "b" --> var "b'"
|
2019-08-18 08:21:24 +03:00
|
|
|
, funBind "f" $ match [] $ var "id"
|
2019-06-10 05:36:18 +03:00
|
|
|
]
|
2020-02-03 19:23:30 +03:00
|
|
|
, class' [] "F" [bvar "a", bvar "b", bvar "c"]
|
2019-06-10 05:36:18 +03:00
|
|
|
[ funDep ["a", "b"] ["c"]
|
|
|
|
, funDep ["a"] ["b", "c"]
|
|
|
|
]
|
2020-02-03 19:23:30 +03:00
|
|
|
, class' [] "Ident" [bvar "a", bvar "b"]
|
2019-06-10 05:36:18 +03:00
|
|
|
[ funDep ["a"] ["b"]
|
|
|
|
, funDep ["b"] ["a"]
|
|
|
|
, typeSig "ident" $ var "a" --> var "b"
|
|
|
|
]
|
2020-02-03 19:23:30 +03:00
|
|
|
, type' "A" [bvar "b", bvar "c"] $ var "D"
|
|
|
|
, data' "A" [bvar "b", bvar "c"]
|
2019-06-10 05:36:18 +03:00
|
|
|
[ prefixCon "A" [field (var "b"), field (var "c")]
|
|
|
|
, prefixCon "D" []
|
|
|
|
]
|
2019-07-29 04:04:59 +03:00
|
|
|
[deriving' [var "X", var "Y"]]
|
2020-02-03 19:23:30 +03:00
|
|
|
, newtype' "A" [bvar "b", bvar "c"] (prefixCon "A" [field (var "b")])
|
2019-07-29 04:04:59 +03:00
|
|
|
[deriving' [var "X", var "Y"]]
|
2019-06-10 05:36:18 +03:00
|
|
|
, instance' (var "A" @@ var "b" @@ var "c")
|
|
|
|
[ typeSig "f" $ var "b" --> var "c"
|
2019-08-18 08:21:24 +03:00
|
|
|
, funBind "f" $ match [] $ var "undefined"
|
2019-06-10 05:36:18 +03:00
|
|
|
]
|
|
|
|
, let a = var "a"
|
|
|
|
in class'
|
|
|
|
[var "Real" @@ a, var "Enum" @@ a]
|
|
|
|
"Integral"
|
2020-02-03 19:23:30 +03:00
|
|
|
[bvar "a"]
|
2019-06-10 05:36:18 +03:00
|
|
|
[ typeSig "divMod" $ a --> a --> tuple [a, a]
|
|
|
|
, typeSig "div" $ a --> a --> a
|
|
|
|
, funBind "div"
|
2019-08-31 20:38:36 +03:00
|
|
|
$ match [bvar "x", bvar "y"]
|
2019-06-10 05:36:18 +03:00
|
|
|
$ var "fst" @@ (var "divMod" @@ var "x" @@ var "y")
|
|
|
|
]
|
|
|
|
, instance' (var "Show" @@ var "Bool")
|
|
|
|
[ typeSig "show" $ var "Bool" --> var "String"
|
|
|
|
, funBinds "show"
|
2019-08-31 20:38:36 +03:00
|
|
|
[ match [conP "True" []] $ string "True"
|
|
|
|
, match [conP "False" []] $ string "False"
|
2019-06-10 05:36:18 +03:00
|
|
|
]
|
|
|
|
]
|
2020-02-03 19:23:30 +03:00
|
|
|
, data' "X" [bvar "b"]
|
2019-06-10 05:36:18 +03:00
|
|
|
[ prefixCon "X"
|
|
|
|
[ field $ var "A" @@ var "b"
|
|
|
|
, strict $ field $ var "A" @@ var "b"
|
|
|
|
, lazy $ field $ var "A" @@ var "b"
|
|
|
|
]
|
|
|
|
, prefixCon ":+"
|
|
|
|
[ field $ var "A" @@ var "b"
|
|
|
|
, strict $ field $ var "A" @@ var "b"
|
|
|
|
, lazy $ field $ var "A" @@ var "b"
|
|
|
|
]
|
|
|
|
, infixCon
|
|
|
|
(strict $ field $ var "A" @@ var "b")
|
|
|
|
"Y"
|
|
|
|
(lazy $ field $ var "A" @@ var "b")
|
|
|
|
, infixCon
|
|
|
|
(strict $ field $ var "A" @@ var "b")
|
|
|
|
":*"
|
|
|
|
(lazy $ field $ var "A" @@ var "b")
|
|
|
|
, infixCon
|
|
|
|
(field $ var "A" @@ var "b")
|
|
|
|
":*"
|
|
|
|
(field $ var "A" @@ var "b")
|
|
|
|
, recordCon "Z"
|
|
|
|
[ ("x", field $ var "Int")
|
|
|
|
, ("y", field $ var "A" @@ var "b")
|
|
|
|
, ("y", strict $ field $ var "A" @@ var "b")
|
|
|
|
, ("y", lazy $ field $ var "A" @@ var "b")
|
|
|
|
]
|
|
|
|
]
|
2019-07-29 04:04:59 +03:00
|
|
|
[]
|
2019-06-10 05:36:18 +03:00
|
|
|
, funBind "strictness"
|
2019-08-18 08:21:24 +03:00
|
|
|
$ match
|
2019-08-31 20:38:36 +03:00
|
|
|
[strictP (conP "A" [bvar "b"]),
|
|
|
|
lazyP (conP "A" [bvar "b"])
|
2019-06-10 05:36:18 +03:00
|
|
|
] (char 'x')
|
|
|
|
, typeSig "unit" $ unit --> unit
|
2019-08-18 08:21:24 +03:00
|
|
|
, funBind "unit" $ match [unit] unit
|
2019-06-10 05:36:18 +03:00
|
|
|
]
|
|
|
|
|
|
|
|
test4 :: IO ()
|
|
|
|
test4 = pprint constModule
|
|
|
|
|
|
|
|
test5 :: IO ()
|
|
|
|
test5 = pprint $ module' (Just "M") (Just exports) imports []
|
|
|
|
where
|
2019-07-29 06:29:26 +03:00
|
|
|
exports = [ var "a"
|
|
|
|
, var "A"
|
|
|
|
, thingAll "B"
|
|
|
|
, thingWith "C" ["d", "E"]
|
|
|
|
]
|
2019-06-10 05:36:18 +03:00
|
|
|
imports = [ qualified' $ import' "A"
|
|
|
|
, import' "B" `as'` "C"
|
|
|
|
, import' "D" `exposing` [var "d"]
|
|
|
|
, import' "E" `hiding` [var "e"]
|
|
|
|
]
|
|
|
|
|
|
|
|
constModule :: HsModule'
|
|
|
|
constModule = module' (Just "Const") (Just [var "const"]) []
|
|
|
|
[ typeSig "const" $ a --> b --> a
|
2019-08-18 08:21:24 +03:00
|
|
|
, funBind "const" $ match [wildP, x] x
|
2019-06-10 05:36:18 +03:00
|
|
|
]
|
|
|
|
where
|
2019-08-31 20:38:36 +03:00
|
|
|
a = bvar "a"
|
|
|
|
b = bvar "b"
|
|
|
|
x = bvar "x"
|