begin hm visualiser

This commit is contained in:
crumbtoo
2024-03-14 16:26:51 -06:00
parent 623acb3454
commit c72d93216a
11 changed files with 155 additions and 121 deletions

View File

@@ -15,10 +15,11 @@ import GM
driver :: RLPCIO () driver :: RLPCIO ()
driver = forFiles_ $ \f -> driver = forFiles_ $ \f ->
withSource f (lexCoreR >=> parseCoreProgR >=> evalProgR) withSource f (lexCoreR >=> parseCoreProgR >=> undefined >=> evalProgR)
driverSource :: T.Text -> RLPCIO () driverSource :: T.Text -> RLPCIO ()
driverSource = lexCoreR >=> parseCoreProgR >=> evalProgR >=> printRes driverSource = lexCoreR >=> parseCoreProgR
>=> undefined >=> evalProgR >=> printRes
where where
printRes = liftIO . print . view _1 printRes = liftIO . print . view _1

View File

@@ -2,6 +2,7 @@
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
module Main where module Main where
---------------------------------------------------------------------------------- ----------------------------------------------------------------------------------
import Control.Lens hiding (argument)
import Compiler.RLPC import Compiler.RLPC
import Compiler.RlpcError import Compiler.RlpcError
import Control.Exception import Control.Exception
@@ -23,6 +24,7 @@ import Control.Lens.Combinators hiding (argument)
import CoreDriver qualified import CoreDriver qualified
import RlpDriver qualified import RlpDriver qualified
import Server qualified
---------------------------------------------------------------------------------- ----------------------------------------------------------------------------------
optParser :: ParserInfo RLPCOptions optParser :: ParserInfo RLPCOptions
@@ -74,7 +76,11 @@ options = RLPCOptions
<> metavar "rlp|core" <> metavar "rlp|core"
<> help "the language to be compiled -- see README" <> help "the language to be compiled -- see README"
) )
<*> some (argument str $ metavar "FILES...") <*> switch
( long "server"
<> short 's'
)
<*> many (argument str $ metavar "FILES...")
where where
infixr 9 # infixr 9 #
f # x = f x f # x = f x
@@ -107,7 +113,9 @@ mmany v = liftA2 (<>) v (mmany v)
main :: IO () main :: IO ()
main = do main = do
opts <- execParser optParser opts <- execParser optParser
void $ evalRLPCIO opts dispatch if opts ^. rlpcServer
then Server.server
else void $ evalRLPCIO opts dispatch
dispatch :: RLPCIO () dispatch :: RLPCIO ()
dispatch = getLang >>= \case dispatch = getLang >>= \case

View File

@@ -15,5 +15,5 @@ import GM
driver :: RLPCIO () driver :: RLPCIO ()
driver = forFiles_ $ \f -> driver = forFiles_ $ \f ->
withSource f (parseRlpProgR >=> desugarRlpProgR >=> evalProgR) withSource f (parseRlpProgR >=> undefined >=> desugarRlpProgR >=> evalProgR)

68
app/Server.hs Normal file
View File

@@ -0,0 +1,68 @@
{-# LANGUAGE LambdaCase, BlockArguments #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE OverloadedStrings #-}
module Server
( server
)
where
--------------------------------------------------------------------------------
import GHC.Generics (Generic, Generically(..))
import Data.Text (Text)
import Data.Text qualified as T
import Data.Text.IO qualified as T
import Data.Pretty
import Data.Aeson
import Control.Applicative
import Control.Monad
import Control.Concurrent
import Network.WebSockets qualified as WS
import Data.Functor.Foldable
import Misc.CofreeF
import Rlp.AltSyntax
import Rlp.HindleyMilner
import Rlp.AltParse
--------------------------------------------------------------------------------
server :: IO ()
server = do
WS.runServer "127.0.0.1" 9002 application
application :: WS.ServerApp
application pending =
WS.acceptRequest pending >>= talk
newtype Command = Annotate Text
instance FromJSON Command where
parseJSON = withObject "command object" $ \v -> do
cmd :: Text <- v .: "command"
case cmd of
"annotate" -> Annotate <$> v .: "data"
_ -> empty
data Response = Annotated Value
| PartiallyAnnotated Value
deriving (Generic)
deriving (ToJSON)
via Generically Response
talk :: WS.Connection -> IO ()
talk conn = forever $ do
msg <- WS.receiveData @Text conn
T.putStrLn $ "received: " <> msg
case decodeStrictText msg of
Just c -> doCommand c
Nothing -> WS.sendTextData @Text conn "\"error while parsing json\""
doCommand :: Command -> IO ()
doCommand (Annotate s) = undefined
parse = undefined
serialisedAnnotated :: Cofree (RlpExprF PsName) (Type PsName)
-> Value
serialisedAnnotated = cata \case
t :<$ e -> object [ "e" .= e, "type" .= rout @Text t ]

View File

@@ -92,6 +92,9 @@ library
, clay , clay
, jmacro , jmacro
, js-jquery , js-jquery
, aeson
, lens-aeson
-- , servant
hs-source-dirs: src hs-source-dirs: src
default-language: GHC2021 default-language: GHC2021
@@ -112,6 +115,7 @@ executable rlpc
main-is: Main.hs main-is: Main.hs
other-modules: RlpDriver other-modules: RlpDriver
, CoreDriver , CoreDriver
, Server
build-depends: base >=4.17.0.0 && <4.20.0.0 build-depends: base >=4.17.0.0 && <4.20.0.0
, rlp , rlp

View File

@@ -26,8 +26,9 @@ module Compiler.RLPC
, DebugFlag(..), CompilerFlag(..) , DebugFlag(..), CompilerFlag(..)
-- ** Lenses -- ** Lenses
, rlpcLogFile, rlpcDFlags, rlpcEvaluator, rlpcInputFiles, rlpcLanguage , rlpcLogFile, rlpcDFlags, rlpcEvaluator, rlpcInputFiles, rlpcLanguage
, rlpcServer
-- * Misc. MTL-style functions -- * Misc. MTL-style functions
, liftErrorful, liftMaybe, hoistRlpcT , liftErrorful, liftEither, liftMaybe, hoistRlpcT
-- * Misc. Rlpc Monad -related types -- * Misc. Rlpc Monad -related types
, RLPCOptions(RLPCOptions), IsRlpcError(..), RlpcError(..) , RLPCOptions(RLPCOptions), IsRlpcError(..), RlpcError(..)
, MsgEnvelope(..), Severity(..) , MsgEnvelope(..), Severity(..)
@@ -111,6 +112,11 @@ liftErrorful e = RLPCT $ lift (fmap liftRlpcError `mapErrorful` e)
liftMaybe :: (Monad m) => Maybe a -> RLPCT m a liftMaybe :: (Monad m) => Maybe a -> RLPCT m a
liftMaybe m = RLPCT . lift . ErrorfulT . pure $ (m, []) liftMaybe m = RLPCT . lift . ErrorfulT . pure $ (m, [])
liftEither :: (Monad m, IsRlpcError e)
=> Either [e] a -> RLPCT m a
liftEither = RLPCT . lift . ErrorfulT . pure
. either (const (Nothing,[])) ((,[]) . Just)
hoistRlpcT :: (forall a. m a -> n a) hoistRlpcT :: (forall a. m a -> n a)
-> RLPCT m a -> RLPCT n a -> RLPCT m a -> RLPCT n a
hoistRlpcT f rma = RLPCT $ ReaderT $ \opt -> hoistRlpcT f rma = RLPCT $ ReaderT $ \opt ->
@@ -123,6 +129,7 @@ data RLPCOptions = RLPCOptions
, _rlpcEvaluator :: Evaluator , _rlpcEvaluator :: Evaluator
, _rlpcHeapTrigger :: Int , _rlpcHeapTrigger :: Int
, _rlpcLanguage :: Maybe Language , _rlpcLanguage :: Maybe Language
, _rlpcServer :: Bool
, _rlpcInputFiles :: [FilePath] , _rlpcInputFiles :: [FilePath]
} }
deriving Show deriving Show
@@ -143,6 +150,7 @@ instance Default RLPCOptions where
, _rlpcEvaluator = EvaluatorGM , _rlpcEvaluator = EvaluatorGM
, _rlpcHeapTrigger = 200 , _rlpcHeapTrigger = 200
, _rlpcInputFiles = [] , _rlpcInputFiles = []
, _rlpcServer = False
, _rlpcLanguage = Nothing , _rlpcLanguage = Nothing
} }

View File

@@ -59,7 +59,9 @@ import Data.Functor.Classes
import Data.Text qualified as T import Data.Text qualified as T
import Data.Char import Data.Char
import Data.These import Data.These
import GHC.Generics (Generic, Generic1, Generically(..)) import Data.Aeson
import GHC.Generics ( Generic, Generic1
, Generically(..), Generically1(..))
import Text.Show.Deriving import Text.Show.Deriving
import Data.Eq.Deriving import Data.Eq.Deriving
import Data.Kind qualified import Data.Kind qualified
@@ -110,7 +112,7 @@ type Kind = Type
-- deriving (Eq, Show, Lift) -- deriving (Eq, Show, Lift)
data Var = MkVar Name Type data Var = MkVar Name Type
deriving (Eq, Show, Lift) deriving (Eq, Show, Lift, Generic)
pattern (:^) :: Name -> Type -> Var pattern (:^) :: Name -> Type -> Var
pattern n :^ t = MkVar n t pattern n :^ t = MkVar n t
@@ -780,3 +782,21 @@ instance Hashable b => Hashable1 (AlterF b)
instance Hashable b => Hashable1 (BindingF b) instance Hashable b => Hashable1 (BindingF b)
instance Hashable b => Hashable1 (ExprF b) instance Hashable b => Hashable1 (ExprF b)
deriving via (Generically Rec)
instance ToJSON Rec
deriving via (Generically Lit)
instance ToJSON Lit
deriving via (Generically AltCon)
instance ToJSON AltCon
deriving via (Generically Type)
instance ToJSON Type
deriving via (Generically Var)
instance ToJSON Var
deriving via (Generically1 (BindingF b))
instance ToJSON b => ToJSON1 (BindingF b)
deriving via (Generically1 (AlterF b))
instance ToJSON b => ToJSON1 (AlterF b)
deriving via (Generically1 (ExprF b))
instance ToJSON b => ToJSON1 (ExprF b)

View File

@@ -18,23 +18,29 @@ module Rlp.AltSyntax
-- * Functor-related tools -- * Functor-related tools
, Fix(..), Cofree(..), Sum(..), pattern Finl, pattern Finr , Fix(..), Cofree(..), Sum(..), pattern Finl, pattern Finr
-- * Misc
, serialiseCofree
) )
where where
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
import Data.Functor.Sum import Data.Functor.Sum
import Control.Comonad.Cofree import Control.Comonad.Cofree
import Data.Fix import Data.Fix hiding (cata)
import Data.Functor.Foldable
import Data.Function (fix) import Data.Function (fix)
import GHC.Generics (Generic, Generic1) import GHC.Generics ( Generic, Generic1
, Generically(..), Generically1(..))
import Data.Hashable import Data.Hashable
import Data.Hashable.Lifted import Data.Hashable.Lifted
import GHC.Exts (IsString) import GHC.Exts (IsString)
import Control.Lens import Control.Lens hiding ((.=))
import Data.Functor.Foldable.TH import Data.Functor.Foldable.TH
import Text.Show.Deriving import Text.Show.Deriving
import Data.Eq.Deriving import Data.Eq.Deriving
import Data.Text qualified as T import Data.Text qualified as T
import Data.Aeson
import Data.Pretty import Data.Pretty
import Misc.Lift1 import Misc.Lift1
@@ -45,7 +51,7 @@ import Core.Syntax qualified as Core
type PsName = T.Text type PsName = T.Text
newtype Program b a = Program [Decl b a] newtype Program b a = Program [Decl b a]
deriving Show deriving (Show, Functor, Foldable, Traversable)
programDecls :: Lens' (Program b a) [Decl b a] programDecls :: Lens' (Program b a) [Decl b a]
programDecls = lens (\ (Program ds) -> ds) (const Program) programDecls = lens (\ (Program ds) -> ds) (const Program)
@@ -53,7 +59,7 @@ programDecls = lens (\ (Program ds) -> ds) (const Program)
data Decl b a = FunD b [Pat b] a data Decl b a = FunD b [Pat b] a
| DataD b [b] [DataCon b] | DataD b [b] [DataCon b]
| TySigD b (Type b) | TySigD b (Type b)
deriving (Show, Functor) deriving (Show, Functor, Foldable, Traversable)
data DataCon b = DataCon b [Type b] data DataCon b = DataCon b [Type b]
deriving (Show, Generic) deriving (Show, Generic)
@@ -101,7 +107,7 @@ type RlpExpr b = Fix (RlpExprF b)
data Pat b = VarP b data Pat b = VarP b
| ConP b | ConP b
| AppP (Pat b) (Pat b) | AppP (Pat b) (Pat b)
deriving (Eq, Show, Generic) deriving (Eq, Show, Generic, Generic1)
deriveShow1 ''Alter deriveShow1 ''Alter
deriveShow1 ''Binding deriveShow1 ''Binding
@@ -221,3 +227,21 @@ instance Core.HasArrowStops (Type b) (Type b) (Type b) (Type b) where
arrowStops k (s Core.:-> t) = (Core.:->) <$> k s <*> Core.arrowStops k t arrowStops k (s Core.:-> t) = (Core.:->) <$> k s <*> Core.arrowStops k t
arrowStops k t = k t arrowStops k t = k t
deriving via (Generically1 Pat)
instance ToJSON1 Pat
deriving via (Generically (Pat b))
instance ToJSON b => ToJSON (Pat b)
deriving via (Generically1 (Alter b))
instance ToJSON b => ToJSON1 (Alter b)
deriving via (Generically1 (Binding b))
instance ToJSON b => ToJSON1 (Binding b)
deriving via (Generically1 (ExprF b))
instance ToJSON b => ToJSON1 (ExprF b)
deriving via (Generically1 (RlpExprF b))
instance ToJSON b => ToJSON1 (RlpExprF b)
serialiseCofree :: (Functor f, ToJSON1 f, ToJSON a) => Cofree f a -> Value
serialiseCofree = cata \case
ann :<$ e -> object [ "ann" .= ann
, "val" .= toJSON1 e ]

View File

@@ -163,11 +163,14 @@ fixtend :: Functor f => (f (Fix f) -> b) -> Fix f -> Cofree f b
fixtend c (Fix f) = c f :< fmap (fixtend c) f fixtend c (Fix f) = c f :< fmap (fixtend c) f
infer :: RlpExpr PsName -> HM (Cofree (RlpExprF PsName) (Type PsName)) infer :: RlpExpr PsName -> HM (Cofree (RlpExprF PsName) (Type PsName))
infer = undefined infer = sequenceA . fixtend (infer1 . wrapFix)
typeCheckRlpProgR :: (Monad m) typeCheckRlpProgR :: (Monad m)
=> Program PsName (RlpExpr PsName) => Program PsName (RlpExpr PsName)
-> RLPCT m (Program PsName -> RLPCT m (Program PsName
(Cofree (RlpExprF PsName) (Type PsName))) (Cofree (RlpExprF PsName) (Type PsName)))
typeCheckRlpProgR = undefined typeCheckRlpProgR = liftHM . traverse infer
liftHM :: (Monad m) => HM a -> RLPCT m a
liftHM = liftEither . runHM'

View File

@@ -1,5 +1,4 @@
{-# LANGUAGE LexicalNegation #-} {-# LANGUAGE LexicalNegation #-}
{-# LANGUAGE QuasiQuotes #-}
module Rlp.HindleyMilner.Visual module Rlp.HindleyMilner.Visual
( (
) )
@@ -7,6 +6,7 @@ module Rlp.HindleyMilner.Visual
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
import Control.Monad import Control.Monad
import System.IO import System.IO
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 Data.Pretty hiding (annotate) import Data.Pretty hiding (annotate)
@@ -17,15 +17,7 @@ import Control.Exception
import Data.Functor.Foldable import Data.Functor.Foldable
import Text.Blaze.Html5 as H import Data.Aeson
import Text.Blaze.Html5.Attributes as A
import Text.Blaze.Html.Renderer.String
import Clay (Css, (?), px, pct, (**), (|>), (|+)
, (|~))
import Clay qualified as C
import Clay.Render qualified as C
import Language.Javascript.JMacro
import Language.Javascript.JQuery qualified as JQuery
import Core.Syntax as Core import Core.Syntax as Core
import Rlp.AltSyntax as Rlp import Rlp.AltSyntax as Rlp
@@ -36,98 +28,3 @@ import Prelude hiding ((**))
type AnnExpr = Cofree (RlpExprF PsName) type AnnExpr = Cofree (RlpExprF PsName)
tooltips :: Css
tooltips = do
".has-type" ? do
C.position C.relative
C.display C.inlineBlock
C.borderBottom (px 1) C.dotted C.black
".has-type.hovering" ? do
C.background C.green
".has-type.hovering" |> ".type-text" ? do
C.display C.block
C.opacity 1
C.position C.fixed
C.overflowWrap C.breakWord
".has-type" |> ".type-text" ? do
C.display C.none
C.overflowWrap C.breakWord
C.maxWidth (pct 50)
stylesheet :: Css
stylesheet = tooltips
numbers :: Int -> Html
numbers n = docTypeHtml do
H.head do
H.title "naturals"
H.style "doge"
body do
pre "a list of nats"
ul $ forM_ [1..n] (li . toHtml)
withTooltip :: Html -> Html -> Html
withTooltip normal hover =
H.div ! class_ "has-type"
$ normal *> (H.div ! class_ "type-text" $ hover)
-- withTooltip :: Html -> Html -> Html
-- withTooltip normal hover =
-- H.div ! class_ "has-type"
-- -- ! onload "installHoverListener(this)"
-- $ normal
annExpr :: (a -> Doc ann) -> AnnExpr a -> Html
annExpr sf = code . cata \case
t :<$ InL (LitF l) -> withTooltip (rout l) (sf' t)
t :<$ InL (VarF n) -> withTooltip (rout n) (sf' t)
t :<$ InL (AppF f x) -> withTooltip (f *> " " *> x) (sf' t)
t :<$ InL (LamF bs e) -> withTooltip ("λ" *> bs' *> " -> " *> e) (sf' t)
where
bs' = fromString . show . hsep $ outPrec appPrec1 <$> bs
where
sf' = fromString . show . sf
rootScript :: JStat
rootScript = [jmacro|
$(".has-type").on("mouseover mouseout", \e {
e.stopPropagation();
$(this).toggleClass("hovering", e.type === "mouseover");
var o = $(this).children(".type-text")[0];
var x = e.clientX;
var y = e.clientY;
o.style.top = (y + 20) + 'px';
o.style.left = (x + 20) + 'px';
});
|]
jsScript :: (IsString s, JsToDoc w, JMacro w) => w -> s
jsScript = fromString . show . renderJs
rootPage :: Html -> Html
rootPage html = docTypeHtml do
H.head do
H.title "naturals"
H.style (toHtml . C.render $ stylesheet)
H.body do
html
script ! src (fromString $ "https:" ++ JQuery.url) $ ""
script ! src "https://code.jquery.com/ui/1.13.2/jquery-ui.min.js" $ ""
script (fromString . show . renderJs $ rootScript)
renderTmp :: Html -> IO ()
renderTmp = writeFile "/tmp/t.html" . renderHtml
renderTmp' :: Html -> IO ()
renderTmp' = writeFile "/tmp/t.html" . renderHtml . rootPage
renderExpr :: RlpExpr PsName -> IO ()
renderExpr e = case runHM' . annotate $ e of
Left es -> error (show es)
Right e' -> renderTmp' . annExpr (fromString . show) $ e'
renderExpr' :: RlpExpr PsName -> IO ()
renderExpr' e = case runHM' . solve $ e of
Left es -> error (show es)
Right e' -> renderTmp' . annExpr out $ e'

1
visualisers/hmvis Submodule

Submodule visualisers/hmvis added at 8371c86933