rc #13
33
README.md
33
README.md
@@ -22,21 +22,38 @@ $ cabal test --test-show-details=direct
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Use
|
### Use
|
||||||
|
|
||||||
|
#### TLDR
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
# Compile and evaluate examples/factorial.hs, with evaluation info dumped to stderr
|
# Compile and evaluate examples/factorial.cr, with evaluation info dumped to stderr
|
||||||
$ rlpc -ddump-eval examples/factorial.hs
|
$ rlpc -ddump-eval examples/factorial.cr
|
||||||
# Compile and evaluate t.hs, with evaluation info dumped to t.log
|
# Compile and evaluate t.cr, with evaluation info dumped to t.log
|
||||||
$ rlpc -ddump-eval -l t.log t.hs
|
$ rlpc -ddump-eval -l t.log t.cr
|
||||||
# Print the raw structure describing the compiler options
|
# Compile and evaluate t.rl, dumping the desugared Core
|
||||||
# (option parsing still must succeed in order to print)
|
$ rlpc -ddump-desugared t.rl
|
||||||
$ rlpc -ddump-opts t.hs
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Options
|
||||||
|
|
||||||
|
```sh
|
||||||
|
Usage: rlpc [-l|--log FILE] [-d DEBUG FLAG] [-f COMPILATION FLAG]
|
||||||
|
[-e|--evaluator gm|ti] [--heap-trigger INT] [-x|--language rlp|core]
|
||||||
|
FILES...
|
||||||
|
```
|
||||||
|
|
||||||
|
Available debug flags include:
|
||||||
|
* `-ddump-desugared`: dump Core generated from rl'
|
||||||
|
* `-ddump-parsed-core`: dump raw Core AST
|
||||||
|
* `-ddump-parsed`: dump raw rl' AST
|
||||||
|
* `-ddump-eval`: dump evaluation logs
|
||||||
|
* `-dALL`: disable debug message filtering. enables **all** debug messages
|
||||||
|
|
||||||
### Potential Features
|
### Potential Features
|
||||||
Listed in order of importance.
|
Listed in order of importance.
|
||||||
- [x] ADTs
|
- [x] ADTs
|
||||||
- [x] First-class functions
|
- [x] First-class functions
|
||||||
- [ ] Higher-kinded types
|
- [x] Higher-kinded types
|
||||||
- [ ] Typeclasses
|
- [ ] Typeclasses
|
||||||
- [x] Parametric polymorphism
|
- [x] Parametric polymorphism
|
||||||
- [x] Hindley-Milner type inference
|
- [x] Hindley-Milner type inference
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ module CoreDriver
|
|||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
import Compiler.RLPC
|
import Compiler.RLPC
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
|
import Data.Text qualified as T
|
||||||
|
import Lens.Micro.Platform
|
||||||
|
|
||||||
import Core.Lex
|
import Core.Lex
|
||||||
import Core.Parse
|
import Core.Parse
|
||||||
@@ -15,3 +17,8 @@ driver :: RLPCIO ()
|
|||||||
driver = forFiles_ $ \f ->
|
driver = forFiles_ $ \f ->
|
||||||
withSource f (lexCoreR >=> parseCoreProgR >=> evalProgR)
|
withSource f (lexCoreR >=> parseCoreProgR >=> evalProgR)
|
||||||
|
|
||||||
|
driverSource :: T.Text -> RLPCIO ()
|
||||||
|
driverSource = lexCoreR >=> parseCoreProgR >=> evalProgR >=> printRes
|
||||||
|
where
|
||||||
|
printRes = liftIO . print . view _1
|
||||||
|
|
||||||
|
|||||||
41
app/Main.hs
41
app/Main.hs
@@ -1,7 +1,9 @@
|
|||||||
{-# LANGUAGE BlockArguments, LambdaCase #-}
|
{-# LANGUAGE BlockArguments, LambdaCase #-}
|
||||||
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
module Main where
|
module Main where
|
||||||
----------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------
|
||||||
import Compiler.RLPC
|
import Compiler.RLPC
|
||||||
|
import Compiler.RlpcError
|
||||||
import Control.Exception
|
import Control.Exception
|
||||||
import Options.Applicative hiding (ParseError)
|
import Options.Applicative hiding (ParseError)
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
@@ -11,12 +13,13 @@ import Data.Text (Text)
|
|||||||
import Data.Text qualified as T
|
import Data.Text qualified as T
|
||||||
import Data.Text.IO qualified as TIO
|
import Data.Text.IO qualified as TIO
|
||||||
import Data.List
|
import Data.List
|
||||||
|
import Data.Maybe (listToMaybe)
|
||||||
import System.IO
|
import System.IO
|
||||||
import System.Exit (exitSuccess)
|
import System.Exit (exitSuccess)
|
||||||
import Core
|
import Core
|
||||||
import TI
|
import TI
|
||||||
import GM
|
import GM
|
||||||
import Lens.Micro.Mtl
|
import Lens.Micro.Platform
|
||||||
|
|
||||||
import CoreDriver qualified
|
import CoreDriver qualified
|
||||||
import RlpDriver qualified
|
import RlpDriver qualified
|
||||||
@@ -65,7 +68,7 @@ options = RLPCOptions
|
|||||||
\triggering the garbage collector"
|
\triggering the garbage collector"
|
||||||
<> value 50
|
<> value 50
|
||||||
)
|
)
|
||||||
<*> option languageReader
|
<*> optional # option languageReader
|
||||||
( long "language"
|
( long "language"
|
||||||
<> short 'x'
|
<> short 'x'
|
||||||
<> metavar "rlp|core"
|
<> metavar "rlp|core"
|
||||||
@@ -80,6 +83,8 @@ languageReader :: ReadM Language
|
|||||||
languageReader = maybeReader $ \case
|
languageReader = maybeReader $ \case
|
||||||
"rlp" -> Just LanguageRlp
|
"rlp" -> Just LanguageRlp
|
||||||
"core" -> Just LanguageCore
|
"core" -> Just LanguageCore
|
||||||
|
"rl" -> Just LanguageRlp
|
||||||
|
"cr" -> Just LanguageCore
|
||||||
_ -> Nothing
|
_ -> Nothing
|
||||||
|
|
||||||
debugFlagReader :: ReadM DebugFlag
|
debugFlagReader :: ReadM DebugFlag
|
||||||
@@ -102,10 +107,34 @@ mmany v = liftA2 (<>) v (mmany v)
|
|||||||
main :: IO ()
|
main :: IO ()
|
||||||
main = do
|
main = do
|
||||||
opts <- execParser optParser
|
opts <- execParser optParser
|
||||||
void $ evalRLPCIO opts driver
|
void $ evalRLPCIO opts dispatch
|
||||||
|
|
||||||
|
dispatch :: RLPCIO ()
|
||||||
|
dispatch = getLang >>= \case
|
||||||
|
Just LanguageCore -> CoreDriver.driver
|
||||||
|
Just LanguageRlp -> RlpDriver.driver
|
||||||
|
Nothing -> addFatal err
|
||||||
|
where
|
||||||
|
-- TODO: why didn't i make the srcspan optional LOL
|
||||||
|
err = errorMsg (SrcSpan 0 0 0 0) $ Text
|
||||||
|
[ "Could not determine source language from filetype."
|
||||||
|
, "Possible Solutions:\n\
|
||||||
|
\ Suffix the file with `.cr' for Core, or `.rl' for rl'\n\
|
||||||
|
\ Specify a language with `rlpc -x core' or `rlpc -x rlp'"
|
||||||
|
]
|
||||||
|
where
|
||||||
|
getLang = liftA2 (<|>)
|
||||||
|
(view rlpcLanguage)
|
||||||
|
-- TODO: we only check the first file lol
|
||||||
|
((listToMaybe >=> inferLanguage) <$> view rlpcInputFiles)
|
||||||
|
|
||||||
|
|
||||||
driver :: RLPCIO ()
|
driver :: RLPCIO ()
|
||||||
driver = view rlpcLanguage >>= \case
|
driver = undefined
|
||||||
LanguageCore -> CoreDriver.driver
|
|
||||||
LanguageRlp -> RlpDriver.driver
|
inferLanguage :: FilePath -> Maybe Language
|
||||||
|
inferLanguage fp
|
||||||
|
| ".rl" `isSuffixOf` fp = Just LanguageRlp
|
||||||
|
| ".cr" `isSuffixOf` fp = Just LanguageCore
|
||||||
|
| otherwise = Nothing
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,19 @@
|
|||||||
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
module RlpDriver
|
module RlpDriver
|
||||||
( driver
|
( driver
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
import Compiler.RLPC
|
import Compiler.RLPC
|
||||||
|
import Control.Monad
|
||||||
|
|
||||||
|
import Rlp.Lex
|
||||||
|
import Rlp.Parse
|
||||||
|
import Rlp2Core
|
||||||
|
import GM
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
driver :: RLPCIO ()
|
driver :: RLPCIO ()
|
||||||
driver = undefined
|
driver = forFiles_ $ \f ->
|
||||||
|
withSource f (parseRlpProgR >=> desugarRlpProgR >=> evalProgR)
|
||||||
|
|
||||||
|
|||||||
@@ -88,6 +88,9 @@ library
|
|||||||
LambdaCase
|
LambdaCase
|
||||||
ViewPatterns
|
ViewPatterns
|
||||||
DataKinds
|
DataKinds
|
||||||
|
DerivingVia
|
||||||
|
StandaloneDeriving
|
||||||
|
DerivingStrategies
|
||||||
|
|
||||||
executable rlpc
|
executable rlpc
|
||||||
import: warnings
|
import: warnings
|
||||||
@@ -98,8 +101,7 @@ executable rlpc
|
|||||||
build-depends: base >=4.17.0.0 && <4.20.0.0
|
build-depends: base >=4.17.0.0 && <4.20.0.0
|
||||||
, rlp
|
, rlp
|
||||||
, optparse-applicative >= 0.18.1 && < 0.19
|
, optparse-applicative >= 0.18.1 && < 0.19
|
||||||
, microlens >= 0.4.13 && < 0.5
|
, microlens-platform
|
||||||
, microlens-mtl >= 0.2.0 && < 0.3
|
|
||||||
, mtl >= 2.3.1 && < 2.4
|
, mtl >= 2.3.1 && < 2.4
|
||||||
, unordered-containers >= 0.2.20 && < 0.3
|
, unordered-containers >= 0.2.20 && < 0.3
|
||||||
, text >= 2.0.2 && < 2.1
|
, text >= 2.0.2 && < 2.1
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ errors and the family of RLPC monads.
|
|||||||
{-# LANGUAGE TemplateHaskell #-}
|
{-# LANGUAGE TemplateHaskell #-}
|
||||||
-- only used for mtl instances
|
-- only used for mtl instances
|
||||||
{-# LANGUAGE UndecidableInstances #-}
|
{-# LANGUAGE UndecidableInstances #-}
|
||||||
{-# LANGUAGE DeriveGeneric, DerivingStrategies, DerivingVia #-}
|
|
||||||
{-# LANGUAGE BlockArguments, ViewPatterns #-}
|
{-# LANGUAGE BlockArguments, ViewPatterns #-}
|
||||||
module Compiler.RLPC
|
module Compiler.RLPC
|
||||||
(
|
(
|
||||||
@@ -18,6 +17,7 @@ module Compiler.RLPC
|
|||||||
RLPCT(RLPCT),
|
RLPCT(RLPCT),
|
||||||
-- ** Special cases
|
-- ** Special cases
|
||||||
RLPC, RLPCIO
|
RLPC, RLPCIO
|
||||||
|
, liftIO
|
||||||
-- ** Running
|
-- ** Running
|
||||||
, runRLPCT
|
, runRLPCT
|
||||||
, evalRLPCT, evalRLPCIO, evalRLPC
|
, evalRLPCT, evalRLPCIO, evalRLPC
|
||||||
@@ -61,6 +61,7 @@ import Data.Coerce
|
|||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
import Data.Text qualified as T
|
import Data.Text qualified as T
|
||||||
import Data.Text.IO qualified as T
|
import Data.Text.IO qualified as T
|
||||||
|
import System.IO
|
||||||
import Text.ANSI qualified as Ansi
|
import Text.ANSI qualified as Ansi
|
||||||
import Text.PrettyPrint hiding ((<>))
|
import Text.PrettyPrint hiding ((<>))
|
||||||
import Lens.Micro.Platform
|
import Lens.Micro.Platform
|
||||||
@@ -84,7 +85,11 @@ type RLPC = RLPCT Identity
|
|||||||
|
|
||||||
type RLPCIO = RLPCT IO
|
type RLPCIO = RLPCT IO
|
||||||
|
|
||||||
|
instance MonadTrans RLPCT where
|
||||||
|
lift = RLPCT . lift . lift
|
||||||
|
|
||||||
instance (MonadIO m) => MonadIO (RLPCT m) where
|
instance (MonadIO m) => MonadIO (RLPCT m) where
|
||||||
|
liftIO = lift . liftIO
|
||||||
|
|
||||||
evalRLPC :: RLPCOptions
|
evalRLPC :: RLPCOptions
|
||||||
-> RLPC a
|
-> RLPC a
|
||||||
@@ -114,7 +119,7 @@ data RLPCOptions = RLPCOptions
|
|||||||
, _rlpcFFlags :: HashSet CompilerFlag
|
, _rlpcFFlags :: HashSet CompilerFlag
|
||||||
, _rlpcEvaluator :: Evaluator
|
, _rlpcEvaluator :: Evaluator
|
||||||
, _rlpcHeapTrigger :: Int
|
, _rlpcHeapTrigger :: Int
|
||||||
, _rlpcLanguage :: Language
|
, _rlpcLanguage :: Maybe Language
|
||||||
, _rlpcInputFiles :: [FilePath]
|
, _rlpcInputFiles :: [FilePath]
|
||||||
}
|
}
|
||||||
deriving Show
|
deriving Show
|
||||||
@@ -135,7 +140,7 @@ instance Default RLPCOptions where
|
|||||||
, _rlpcEvaluator = EvaluatorGM
|
, _rlpcEvaluator = EvaluatorGM
|
||||||
, _rlpcHeapTrigger = 200
|
, _rlpcHeapTrigger = 200
|
||||||
, _rlpcInputFiles = []
|
, _rlpcInputFiles = []
|
||||||
, _rlpcLanguage = LanguageRlp
|
, _rlpcLanguage = Nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
-- debug flags are passed with -dFLAG
|
-- debug flags are passed with -dFLAG
|
||||||
@@ -175,10 +180,18 @@ evalRLPCIO opt r = do
|
|||||||
Nothing -> die "Failed, no code compiled."
|
Nothing -> die "Failed, no code compiled."
|
||||||
|
|
||||||
putRlpcErrs :: RLPCOptions -> [MsgEnvelope RlpcError] -> IO ()
|
putRlpcErrs :: RLPCOptions -> [MsgEnvelope RlpcError] -> IO ()
|
||||||
putRlpcErrs opts = filter byTag
|
putRlpcErrs opt es = case opt ^. rlpcLogFile of
|
||||||
>>> traverse_ (putStrLn . ('\n':) . prettyRlpcMsg)
|
Just lf -> withFile lf WriteMode putter
|
||||||
|
Nothing -> putter stderr
|
||||||
|
where
|
||||||
|
putter h = hPutStrLn h `traverse_` renderRlpcErrs opt es
|
||||||
|
|
||||||
|
renderRlpcErrs :: RLPCOptions -> [MsgEnvelope RlpcError] -> [String]
|
||||||
|
renderRlpcErrs opts = (if don'tBother then id else filter byTag)
|
||||||
|
>>> fmap prettyRlpcMsg
|
||||||
where
|
where
|
||||||
dflags = opts ^. rlpcDFlags
|
dflags = opts ^. rlpcDFlags
|
||||||
|
don'tBother = "ALL" `S.member` (opts ^. rlpcDFlags)
|
||||||
|
|
||||||
byTag :: MsgEnvelope RlpcError -> Bool
|
byTag :: MsgEnvelope RlpcError -> Bool
|
||||||
byTag (view msgSeverity -> SevDebug t) =
|
byTag (view msgSeverity -> SevDebug t) =
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ data MsgEnvelope e = MsgEnvelope
|
|||||||
deriving (Functor, Show)
|
deriving (Functor, Show)
|
||||||
|
|
||||||
newtype RlpcError = Text [Text]
|
newtype RlpcError = Text [Text]
|
||||||
deriving Show
|
deriving Show
|
||||||
|
|
||||||
instance IsString RlpcError where
|
instance IsString RlpcError where
|
||||||
fromString = Text . pure . T.pack
|
fromString = Text . pure . T.pack
|
||||||
@@ -47,7 +47,7 @@ instance IsRlpcError RlpcError where
|
|||||||
|
|
||||||
data Severity = SevWarning
|
data Severity = SevWarning
|
||||||
| SevError
|
| SevError
|
||||||
| SevDebug Text
|
| SevDebug Text -- ^ Tag
|
||||||
deriving Show
|
deriving Show
|
||||||
|
|
||||||
makeLenses ''MsgEnvelope
|
makeLenses ''MsgEnvelope
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ instance (MonadIO m) => MonadIO (ErrorfulT e m) where
|
|||||||
liftIO = lift . liftIO
|
liftIO = lift . liftIO
|
||||||
|
|
||||||
instance (Functor m) => Functor (ErrorfulT e m) where
|
instance (Functor m) => Functor (ErrorfulT e m) where
|
||||||
fmap f (ErrorfulT m) = ErrorfulT (m & mapped . _1 . _Just %~ f)
|
fmap f (ErrorfulT m) = ErrorfulT (m <&> _1 . _Just %~ f)
|
||||||
|
|
||||||
instance (Applicative m) => Applicative (ErrorfulT e m) where
|
instance (Applicative m) => Applicative (ErrorfulT e m) where
|
||||||
pure a = ErrorfulT . pure $ (Just a, [])
|
pure a = ErrorfulT . pure $ (Just a, [])
|
||||||
@@ -63,12 +63,12 @@ instance (Monad m) => Monad (ErrorfulT e m) where
|
|||||||
ErrorfulT m >>= k = ErrorfulT $ do
|
ErrorfulT m >>= k = ErrorfulT $ do
|
||||||
(a,es) <- m
|
(a,es) <- m
|
||||||
case a of
|
case a of
|
||||||
Just x -> runErrorfulT (k x)
|
Just x -> runErrorfulT (k x) <&> _2 %~ (es<>)
|
||||||
Nothing -> pure (Nothing, es)
|
Nothing -> pure (Nothing, es)
|
||||||
|
|
||||||
mapErrorful :: (Functor m) => (e -> e') -> ErrorfulT e m a -> ErrorfulT e' m a
|
mapErrorful :: (Functor m) => (e -> e') -> ErrorfulT e m a -> ErrorfulT e' m a
|
||||||
mapErrorful f (ErrorfulT m) = ErrorfulT $
|
mapErrorful f (ErrorfulT m) = ErrorfulT $
|
||||||
m & mapped . _2 . mapped %~ f
|
m <&> _2 . mapped %~ f
|
||||||
|
|
||||||
-- when microlens-pro drops we can write this as
|
-- when microlens-pro drops we can write this as
|
||||||
-- mapErrorful f = coerced . mapped . _2 . mapped %~ f
|
-- mapErrorful f = coerced . mapped . _2 . mapped %~ f
|
||||||
|
|||||||
@@ -234,7 +234,7 @@ parseCoreProgR = ddumpast <=< (hoistRlpcT generalise . parseCoreProg)
|
|||||||
|
|
||||||
ddumpast :: Program' -> RLPCT m Program'
|
ddumpast :: Program' -> RLPCT m Program'
|
||||||
ddumpast p = do
|
ddumpast p = do
|
||||||
addDebugMsg "dump-ast" . show $ p
|
addDebugMsg "dump-parsed-core" . show $ p
|
||||||
pure p
|
pure p
|
||||||
|
|
||||||
happyBind :: RLPC a -> (a -> RLPC b) -> RLPC b
|
happyBind :: RLPC a -> (a -> RLPC b) -> RLPC b
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ module Core.Syntax
|
|||||||
, Binding'
|
, Binding'
|
||||||
, HasRHS(_rhs)
|
, HasRHS(_rhs)
|
||||||
, HasLHS(_lhs)
|
, HasLHS(_lhs)
|
||||||
|
, Pretty(pretty)
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
----------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------
|
||||||
@@ -56,7 +57,7 @@ import Data.HashMap.Strict qualified as H
|
|||||||
import Data.Hashable
|
import Data.Hashable
|
||||||
import Data.Text qualified as T
|
import Data.Text qualified as T
|
||||||
import Data.Char
|
import Data.Char
|
||||||
import GHC.Generics
|
import GHC.Generics (Generic, Generically(..))
|
||||||
-- Lift instances for the Core quasiquoters
|
-- Lift instances for the Core quasiquoters
|
||||||
import Language.Haskell.TH.Syntax (Lift)
|
import Language.Haskell.TH.Syntax (Lift)
|
||||||
-- import Lens.Micro.TH (makeLenses)
|
-- import Lens.Micro.TH (makeLenses)
|
||||||
@@ -215,3 +216,61 @@ instance HasLHS (Binding b) (Binding b) b b where
|
|||||||
(\ (k := _) -> k)
|
(\ (k := _) -> k)
|
||||||
(\ (_ := e) k' -> k' := e)
|
(\ (_ := e) k' -> k' := e)
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- TODO: print type sigs with corresponding scdefs
|
||||||
|
-- TODO: emit pragmas for datatags
|
||||||
|
instance (Pretty b) => Pretty (Program b) where
|
||||||
|
pretty = vsepOf (programScDefs . each . to pretty)
|
||||||
|
|
||||||
|
instance (Pretty b) => Pretty (ScDef b) where
|
||||||
|
pretty sc = hsep [name, as, "=", hang empty 1 e]
|
||||||
|
where
|
||||||
|
name = ttext $ sc ^. _lhs . _1
|
||||||
|
as = sc & hsepOf (_lhs . _2 . each . to ttext)
|
||||||
|
e = pretty $ sc ^. _rhs
|
||||||
|
|
||||||
|
instance (Pretty b) => Pretty (Expr b) where
|
||||||
|
prettyPrec _ (Var n) = ttext n
|
||||||
|
prettyPrec _ (Con t a) = "Pack{" <> (ttext t <+> ttext a) <> "}"
|
||||||
|
prettyPrec _ (Lam bs e) = hsep ["λ", hsep (prettyPrec 1 <$> bs), "->", pretty e]
|
||||||
|
prettyPrec _ (Let r bs e) = hsep [word, explicitLayout bs]
|
||||||
|
$$ hsep ["in", pretty e]
|
||||||
|
where word = if r == Rec then "letrec" else "let"
|
||||||
|
prettyPrec p (App f x) = maybeParens (p>0) $
|
||||||
|
prettyPrec 0 f <+> prettyPrec 1 x
|
||||||
|
prettyPrec _ (Lit l) = pretty l
|
||||||
|
prettyPrec p (Case e as) = maybeParens (p>0) $
|
||||||
|
"case" <+> pretty e <+> "of"
|
||||||
|
$$ nest 2 (explicitLayout as)
|
||||||
|
|
||||||
|
{-
|
||||||
|
|
||||||
|
x = pretty $ desugarRlpProg [rlpProg|
|
||||||
|
main = 3
|
||||||
|
data B = T | F
|
||||||
|
|]
|
||||||
|
|
||||||
|
-}
|
||||||
|
|
||||||
|
instance (Pretty b) => Pretty (Alter b) where
|
||||||
|
pretty (Alter c as e) =
|
||||||
|
hsep [pretty c, hsep (pretty <$> as), "->", pretty e]
|
||||||
|
|
||||||
|
instance Pretty AltCon where
|
||||||
|
pretty (AltData n) = ttext n
|
||||||
|
pretty (AltLit l) = pretty l
|
||||||
|
pretty (AltTag t) = ttext t
|
||||||
|
pretty AltDefault = "_"
|
||||||
|
|
||||||
|
instance Pretty Lit where
|
||||||
|
pretty (IntL n) = ttext n
|
||||||
|
|
||||||
|
instance (Pretty b) => Pretty (Binding b) where
|
||||||
|
pretty (k := v) = hsep [pretty k, "=", pretty v]
|
||||||
|
|
||||||
|
explicitLayout :: (Pretty a) => [a] -> Doc
|
||||||
|
explicitLayout as = vcat inner <+> "}" where
|
||||||
|
inner = zipWith (<+>) delims (pretty <$> as)
|
||||||
|
delims = "{" : repeat ";"
|
||||||
|
|
||||||
|
|||||||
@@ -21,16 +21,27 @@ import Control.Arrow ((>>>))
|
|||||||
import Data.Text qualified as T
|
import Data.Text qualified as T
|
||||||
import Data.HashMap.Strict (HashMap)
|
import Data.HashMap.Strict (HashMap)
|
||||||
import Numeric (showHex)
|
import Numeric (showHex)
|
||||||
|
|
||||||
|
import Data.Pretty
|
||||||
|
import Compiler.RLPC
|
||||||
-- import Lens.Micro.Platform
|
-- import Lens.Micro.Platform
|
||||||
import Control.Lens
|
import Control.Lens
|
||||||
import Core.Syntax
|
import Core.Syntax
|
||||||
import Core.Utils
|
import Core.Utils
|
||||||
----------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- | General optimisations
|
||||||
|
|
||||||
core2core :: Program' -> Program'
|
core2core :: Program' -> Program'
|
||||||
core2core p = undefined
|
core2core p = undefined
|
||||||
|
|
||||||
-- | G-machine preprocessing.
|
gmPrepR :: (Monad m) => Program' -> RLPCT m Program'
|
||||||
|
gmPrepR p = do
|
||||||
|
let p' = gmPrep p
|
||||||
|
addDebugMsg "dump-gm-preprocessed" $ render . pretty $ p'
|
||||||
|
pure p'
|
||||||
|
|
||||||
|
-- | G-machine-specific preprocessing.
|
||||||
|
|
||||||
gmPrep :: Program' -> Program'
|
gmPrep :: Program' -> Program'
|
||||||
gmPrep p = p & appFloater (floatNonStrictCases globals)
|
gmPrep p = p & appFloater (floatNonStrictCases globals)
|
||||||
@@ -46,7 +57,6 @@ gmPrep p = p & appFloater (floatNonStrictCases globals)
|
|||||||
defineData :: Program' -> Program'
|
defineData :: Program' -> Program'
|
||||||
defineData p = p & programScDefs <>~ defs
|
defineData p = p & programScDefs <>~ defs
|
||||||
where
|
where
|
||||||
-- defs = ifoldMap' _ (p ^. programDataTags)
|
|
||||||
defs = p ^. programDataTags
|
defs = p ^. programDataTags
|
||||||
. to (ifoldMap (\k (t,a) -> [ScDef k [] (Con t a)]))
|
. to (ifoldMap (\k (t,a) -> [ScDef k [] (Con t a)]))
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,51 @@
|
|||||||
{-# LANGUAGE OverloadedStrings #-}
|
|
||||||
module Data.Pretty
|
module Data.Pretty
|
||||||
( Pretty(..)
|
( Pretty(..)
|
||||||
|
, ttext
|
||||||
|
-- * Pretty-printing lens combinators
|
||||||
|
, hsepOf, vsepOf
|
||||||
|
, module Text.PrettyPrint
|
||||||
|
, maybeParens
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
----------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------
|
||||||
import Data.String (IsString(..))
|
import Text.PrettyPrint hiding ((<>))
|
||||||
|
import Text.PrettyPrint.HughesPJ hiding ((<>))
|
||||||
|
import Data.String (IsString(..))
|
||||||
|
import Data.Text.Lens
|
||||||
|
import Data.Monoid
|
||||||
|
import Data.Text qualified as T
|
||||||
|
import Control.Lens
|
||||||
----------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------
|
||||||
|
|
||||||
class Pretty a where
|
class Pretty a where
|
||||||
-- pretty :: a -> ISeq
|
pretty :: a -> Doc
|
||||||
-- prettyPrec :: a -> Int -> ISeq
|
prettyPrec :: Int -> a -> Doc
|
||||||
|
|
||||||
-- {-# MINIMAL pretty | prettyPrec #-}
|
{-# MINIMAL pretty | prettyPrec #-}
|
||||||
-- pretty a = prettyPrec a 0
|
pretty = prettyPrec 0
|
||||||
-- prettyPrec a _ = iBracket (pretty a)
|
prettyPrec a _ = pretty a
|
||||||
|
|
||||||
|
instance Pretty String where
|
||||||
|
pretty = Text.PrettyPrint.text
|
||||||
|
|
||||||
|
instance Pretty T.Text where
|
||||||
|
pretty = Text.PrettyPrint.text . view unpacked
|
||||||
|
|
||||||
|
newtype Showing a = Showing a
|
||||||
|
|
||||||
|
instance (Show a) => Pretty (Showing a) where
|
||||||
|
prettyPrec p (Showing a) = fromString $ showsPrec p a ""
|
||||||
|
|
||||||
|
deriving via Showing Int instance Pretty Int
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ttext :: Pretty t => t -> Doc
|
||||||
|
ttext = pretty
|
||||||
|
|
||||||
|
hsepOf :: Getting (Endo Doc) s Doc -> s -> Doc
|
||||||
|
hsepOf l = foldrOf l (<+>) mempty
|
||||||
|
|
||||||
|
vsepOf :: Getting (Endo Doc) s Doc -> s -> Doc
|
||||||
|
vsepOf l = foldrOf l ($+$) mempty
|
||||||
|
|
||||||
|
|||||||
@@ -228,6 +228,7 @@ Expr1 :: { RlpExpr' RlpcPs }
|
|||||||
: '(' Expr ')' { $1 .> $2 <. $3 }
|
: '(' Expr ')' { $1 .> $2 <. $3 }
|
||||||
| Lit { fmap LitE $1 }
|
| Lit { fmap LitE $1 }
|
||||||
| Var { fmap VarE $1 }
|
| Var { fmap VarE $1 }
|
||||||
|
| Con { fmap VarE $1 }
|
||||||
|
|
||||||
InfixOp :: { Located PsName }
|
InfixOp :: { Located PsName }
|
||||||
: consym { mkPsName $1 }
|
: consym { mkPsName $1 }
|
||||||
@@ -251,8 +252,11 @@ parseRlpExprR s = liftErrorful $ pToErrorful parseRlpExpr st
|
|||||||
st = programInitState s
|
st = programInitState s
|
||||||
|
|
||||||
parseRlpProgR :: (Monad m) => Text -> RLPCT m (RlpProgram RlpcPs)
|
parseRlpProgR :: (Monad m) => Text -> RLPCT m (RlpProgram RlpcPs)
|
||||||
parseRlpProgR s = liftErrorful $ pToErrorful parseRlpProg st
|
parseRlpProgR s = do
|
||||||
where
|
a <- liftErrorful $ pToErrorful parseRlpProg st
|
||||||
|
addDebugMsg @_ @String "dump-parsed" $ show a
|
||||||
|
pure a
|
||||||
|
where
|
||||||
st = programInitState s
|
st = programInitState s
|
||||||
|
|
||||||
mkPsName :: Located RlpToken -> Located PsName
|
mkPsName :: Located RlpToken -> Located PsName
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
{-# LANGUAGE TemplateHaskell #-}
|
{-# LANGUAGE TemplateHaskell #-}
|
||||||
{-# LANGUAGE DeriveTraversable #-}
|
{-# LANGUAGE DeriveTraversable #-}
|
||||||
module Rlp2Core
|
module Rlp2Core
|
||||||
( desugarRlpProg
|
( desugarRlpProgR
|
||||||
|
, desugarRlpProg
|
||||||
, desugarRlpExpr
|
, desugarRlpExpr
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
@@ -15,6 +16,7 @@ import Control.Comonad
|
|||||||
-- import Lens.Micro
|
-- import Lens.Micro
|
||||||
-- import Lens.Micro.Internal
|
-- import Lens.Micro.Internal
|
||||||
import Control.Lens
|
import Control.Lens
|
||||||
|
import Compiler.RLPC
|
||||||
import Data.List (mapAccumL)
|
import Data.List (mapAccumL)
|
||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
import Data.Text qualified as T
|
import Data.Text qualified as T
|
||||||
@@ -26,6 +28,7 @@ import Data.Maybe (fromJust, fromMaybe)
|
|||||||
import Data.Functor.Bind
|
import Data.Functor.Bind
|
||||||
import Data.Function (on)
|
import Data.Function (on)
|
||||||
import Debug.Trace
|
import Debug.Trace
|
||||||
|
|
||||||
import Effectful.State.Static.Local
|
import Effectful.State.Static.Local
|
||||||
import Effectful.Labeled
|
import Effectful.Labeled
|
||||||
import Effectful
|
import Effectful
|
||||||
@@ -33,6 +36,7 @@ import Text.Show.Deriving
|
|||||||
|
|
||||||
import Core.Syntax as Core
|
import Core.Syntax as Core
|
||||||
import Compiler.Types
|
import Compiler.Types
|
||||||
|
import Data.Pretty (render, pretty)
|
||||||
import Rlp.Syntax as Rlp
|
import Rlp.Syntax as Rlp
|
||||||
import Rlp.Parse.Types (RlpcPs, PsName)
|
import Rlp.Parse.Types (RlpcPs, PsName)
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
@@ -55,6 +59,12 @@ deriveShow1 ''Branch
|
|||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
desugarRlpProgR :: forall m. (Monad m) => RlpProgram RlpcPs -> RLPCT m Program'
|
||||||
|
desugarRlpProgR p = do
|
||||||
|
let p' = desugarRlpProg p
|
||||||
|
addDebugMsg "dump-desugared" $ render (pretty p')
|
||||||
|
pure p'
|
||||||
|
|
||||||
desugarRlpProg :: RlpProgram RlpcPs -> Program'
|
desugarRlpProg :: RlpProgram RlpcPs -> Program'
|
||||||
desugarRlpProg = rlpProgToCore
|
desugarRlpProg = rlpProgToCore
|
||||||
|
|
||||||
@@ -107,10 +117,19 @@ exprToCore (VarE n) = pure $ Var (dsNameToName n)
|
|||||||
|
|
||||||
exprToCore (AppE a b) = (liftA2 App `on` exprToCore . unXRec) a b
|
exprToCore (AppE a b) = (liftA2 App `on` exprToCore . unXRec) a b
|
||||||
|
|
||||||
|
exprToCore (OAppE f a b) = (liftA2 mkApp `on` exprToCore . unXRec) a b
|
||||||
|
where
|
||||||
|
mkApp s t = (Var f `App` s) `App` t
|
||||||
|
|
||||||
exprToCore (CaseE (unXRec -> e) as) = do
|
exprToCore (CaseE (unXRec -> e) as) = do
|
||||||
e' <- exprToCore e
|
e' <- exprToCore e
|
||||||
Case e' <$> caseAltToCore `traverse` as
|
Case e' <$> caseAltToCore `traverse` as
|
||||||
|
|
||||||
|
exprToCore (LitE l) = litToCore l
|
||||||
|
|
||||||
|
litToCore :: (NameSupply :> es) => Rlp.Lit RlpcPs -> Eff es Expr'
|
||||||
|
litToCore (Rlp.IntL n) = pure . Lit $ Core.IntL n
|
||||||
|
|
||||||
-- TODO: where-binds
|
-- TODO: where-binds
|
||||||
caseAltToCore :: (NameSupply :> es)
|
caseAltToCore :: (NameSupply :> es)
|
||||||
=> (Alt RlpcPs, Where RlpcPs) -> Eff es Alter'
|
=> (Alt RlpcPs, Where RlpcPs) -> Eff es Alter'
|
||||||
@@ -127,6 +146,7 @@ conToRose (ConP cn as) = Fix . Branch cn <$> patToForrest `traverse` as
|
|||||||
Right <$> liftA2 (,) uniqueName br
|
Right <$> liftA2 (,) uniqueName br
|
||||||
where
|
where
|
||||||
br = unwrapFix <$> conToRose (unXRec p)
|
br = unwrapFix <$> conToRose (unXRec p)
|
||||||
|
conToRose _ = error "conToRose: not a ConP!"
|
||||||
|
|
||||||
branchToCore :: Expr' -> Branch Alter' -> Alter'
|
branchToCore :: Expr' -> Branch Alter' -> Alter'
|
||||||
branchToCore e (Branch cn as) = Alter (AltData cn) myBinds e'
|
branchToCore e (Branch cn as) = Alter (AltData cn) myBinds e'
|
||||||
|
|||||||
Reference in New Issue
Block a user