49 Commits

Author SHA1 Message Date
crumbtoo
8fd75a67d3 seems to work 2024-03-13 18:10:29 -06:00
crumbtoo
e00e0eff3b preparing for rewrite #100 2024-03-13 16:06:20 -06:00
crumbtoo
8d8651d549 fix: vlbrace error should popLayout 2024-03-11 11:05:50 -06:00
crumbtoo
cf81b76c1a algW
i'm honestly rather disappointed in myself for not implementing a comonadic algo J.
cross my heart i'll come back to this and return stronger!
in the mean time, i really need to get this thing into a presentable state...
2024-03-11 10:36:38 -06:00
crumbtoo
35c770c63c aoooohhh 2024-03-11 09:26:53 -06:00
crumbtoo
e93548963a parse lambda 2024-03-08 16:28:40 -07:00
crumbtoo
215feb433b mgu 2024-03-07 10:20:42 -07:00
crumbtoo
f6035b8a6a refactor gather 2024-03-06 17:46:35 -07:00
crumbtoo
fe44fbfc77 begin gathering
begin gathering
2024-03-06 11:37:37 -07:00
crumbtoo
18e87c540b derive 2024-03-06 10:07:00 -07:00
crumbtoo
2d15dbb7ee lift1 fix 2024-03-05 13:08:15 -07:00
crumbtoo
156ef8d0a7 tysigd 2024-03-04 10:47:58 -07:00
crumbtoo
c85c47839a caseE 2024-03-04 10:26:04 -07:00
crumbtoo
468d6e7745 ohhhh 2024-03-03 14:52:27 -07:00
crumbtoo
1b56a7a627 pretty 2024-03-03 14:09:10 -07:00
crumbtoo
451b003e08 lintCoreProg 2024-03-01 11:18:19 -07:00
crumbtoo
c026f6f8f9 system F 2024-02-29 09:52:08 -07:00
crumbtoo
16f7f51fb8 almost done 2024-02-27 14:48:02 -07:00
crumbtoo
f8201b7d61 pretty-printing 2024-02-27 07:56:25 -07:00
crumbtoo
b67fe4eb2d terse pretty-printing 2024-02-27 06:14:02 -07:00
crumbtoo
1315ea7ea8 parse 2024-02-27 05:12:19 -07:00
crumbtoo
d60bd86842 it may not be perfection but it is progress 2024-02-26 18:18:02 -07:00
crumbtoo
c226b2da88 HasBinders Binding 2024-02-26 17:03:20 -07:00
crumbtoo
893a01a8bb HasBinders Program 2024-02-26 16:41:54 -07:00
crumbtoo
4bbf3a3afe fromString for Fix 2024-02-26 14:59:37 -07:00
crumbtoo
c8967572a6 Eq1 2024-02-26 14:58:17 -07:00
crumbtoo
30fe41ce97 Eq1 2024-02-26 14:57:22 -07:00
crumbtoo
8c2ea566dc instances for Fix 2024-02-26 14:29:57 -07:00
crumbtoo
d9682561b8 instances (finally) 2024-02-26 12:23:21 -07:00
crumbtoo
4225bf8066 Bi{foldable,functor,traversable} 2024-02-26 10:41:41 -07:00
crumbtoo
15f65a79f6 instance hell 2024-02-26 10:12:33 -07:00
crumbtoo
240db0df3d clisp->sbcl 2024-02-23 20:34:38 -07:00
crumbtoo
a582cd9fcf stopping for a bit 2024-02-22 15:56:00 -07:00
crumbtoo
a50a4590c5 parser compiles 2024-02-22 15:08:55 -07:00
crumbtoo
d3bcbf9624 things 2024-02-22 14:05:29 -07:00
crumbtoo
fd47599b06 things 2024-02-22 14:05:24 -07:00
crumbtoo
a7dd852464 fix hardcoded builddir 2024-02-22 10:51:43 -07:00
crumbtoo
a2ad7856a6 fix default prettyPrec definition 2024-02-22 08:57:35 -07:00
crumbtoo
c0baf46f29 Merge branch 'no-ttg' into dev 2024-02-22 08:15:03 -07:00
crumbtoo
09f393af89 good enough 2024-02-20 14:34:42 -07:00
crumbtoo
e63e34a3d8 ohhhhhhhh 2024-02-20 11:52:44 -07:00
crumbtoo
13e8701b8a why did i do this to myself 2024-02-20 11:26:35 -07:00
crumbtoo
66c3d878c2 i want to fucking die 2024-02-20 11:10:33 -07:00
crumbtoo
820bd7cdbc backstage 2024-02-17 01:56:29 -07:00
crumbtoo
9297d815d6 something 2024-02-16 18:23:02 -07:00
crumbtoo
910cf66468 HasLocation
HasLocation
2024-02-16 18:03:49 -07:00
crumbtoo
da81a5a98e SrcSpan 2024-02-16 16:14:38 -07:00
crumbtoo
caeec216b5 no-ttg 2024-02-16 15:11:08 -07:00
crumbtoo
e9cab1ddaf no-ttg 2024-02-15 18:27:04 -07:00
48 changed files with 920 additions and 4369 deletions

1
.ghci
View File

@@ -1,6 +1,5 @@
-- repl extensions -- repl extensions
:set -XOverloadedStrings :set -XOverloadedStrings
:set -XQuasiQuotes
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------

View File

@@ -5,7 +5,7 @@ ALEX = alex
ALEX_OPTS = -g ALEX_OPTS = -g
SRC = src SRC = src
CABAL_BUILD = $(shell ./find-build.clj) CABAL_BUILD = $(shell ./find-build.cl)
all: parsers lexers all: parsers lexers

165
README.md Normal file
View File

@@ -0,0 +1,165 @@
# rl'
`rlp` (ruelang') will be a lazily-evaluated purely-functional language heavily
imitating Haskell.
### Architecture
![rlpc architecture diagram](/rlpc.drawio.svg)
### Build Info
* rlp is built using [Cabal](https://www.haskell.org/ghcup/)
* rlp's documentation is built using [Sphinx](https://www.sphinx-doc.org/en/master/)
```sh
$ cabal build # Build the rlpc compiler
$ cabal install # Install rlpc to $PATH
$ cabal haddock # Build the API docs w/ Haddock
$ make -C doc html # Build the primary docs w/ Sphinx
# run the test suite
$ cabal test --test-show-details=direct
```
### Use
#### TLDR
```sh
# Compile and evaluate examples/rlp/QuickSort.rl
$ rlpc examples/QuickSort.rl
# Compile and evaluate t.cr, with evaluation info dumped to t.log
$ rlpc -ddump-eval -l t.log t.cr
# Compile and evaluate t.rl, dumping the desugared Core
$ rlpc -ddump-desugared t.rl
# Compile and evaluate t.rl with all compiler messages enabled
$ rlpc -dALL t.rl
```
#### 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
Listed in order of importance.
- [x] ADTs
- [x] First-class functions
- [x] Higher-kinded types
- [ ] Typeclasses
- [x] Parametric polymorphism
- [x] Hindley-Milner type inference
- [ ] Newtype coercion
- [ ] Parallelism
### Milestones
(This list is incomplete.)
Items are marked off not as they are 100% implemented, but rather once I
consider them stable enough that completion is soley a matter of getting
around to it -- no tough design decisions, theorising, etc. remain. For
example, as of writing this, the rl' frontend parser is not fully featured,
yet it is marked off on this list; finishing it would require cranking out
the remaining grammatical rules, and no work on complex tasks like layout
parsing remains.
- [ ] Backend
- [x] Core language
- [x] AST
- [x] Low-level execution model (TI)
- [x] Arithmetic
- [x] Conditionals
- [x] Structured data
- [x] Garbage collection
- [x] Low-level execution model (GM)
- [x] Arithmetic
- [x] Conditionals
- [x] Structured data
- [x] Garbage Collection
- [ ] Emitter
- [ ] Code-gen (target yet to be decided)
- [x] Core linter (Type-checker)
- [ ] Core2Core pass (optimisations and misc. preprocessing)
- [x] GM prep
- [x] Non-strict case-floating
- [ ] Let-floating
- [ ] TCO
- [ ] DCE
- [ ] Frontend
- [x] High-level language
- [x] AST
- [x] Lexer
- [x] Parser
- [x] Translation to the core language
- [ ] Constraint solver
- [ ] `do`-notation
- [x] CLI
- [ ] Documentation
- [x] State transition rules
- [ ] How does the evaluation model work?
- [ ] The Hindley-Milner type system
- [ ] CLI usage
- [ ] Tail call optimisation
- [ ] Parsing rlp
- [ ] Trees That Grow
- [ ] Tests
- [x] Generic example programs
- [ ] Parser
### ~~December Release Plan~~
- [x] Tests
- [ ] Core lexer
- [ ] Core parser
- [x] Evaluation model
- [ ] Benchmarks
- [x] Stable Core lexer
- [x] Stable Core parser
- [x] Stable evaluation model
- [x] Garbage Collection
- [ ] Stable documentation for the evaluation model
### ~~February Release Plan~~
- [x] Beta rl' to Core
- [x] UX improvements
- [x] Actual compiler errors -- no more unexceptional `error` calls
- [x] Better CLI dump flags
- [x] Annotate the AST with token positions for errors (NOTE: As of Feb. 1,
this has been done, but the locational info is not yet used in error messages)
- [x] Compiler architecture diagram
- [x] More examples
### March Release Plan
- [ ] Tests
- [ ] rl' parser
- [ ] rl' lexer
- [ ] Ditch TTG in favour of a simpler AST focusing on extendability via Fix, Free,
Cofree, etc. rather than boilerplate-heavy type families
### Indefinite Release Plan
This list is more concrete than the milestones, but likely further in the future
than the other release plans.
- [ ] Overall codebase cleaning
- [ ] Complete all TODOs
- [ ] Replace mtl with effectful
- [ ] rl' type-checker
- [ ] Stable rl' to Core
- [ ] Core polish
- [ ] Better, stable parser
- [ ] Better, stable lexer
- [ ] Less hacky handling of named data
- [ ] Less hacky pragmas
- [ ] Choose a target. LLVM, JS, C, and WASM are currently top contenders
- [ ] https://proglangdesign.net/wiki/challenges

View File

@@ -1,223 +0,0 @@
#+title: rl'
#+author: Madeleine Sydney Slaga
~rl'~ will be a lazily-evaluated, purely-functional, statically-typed language
heavily imitating Haskell.
* Architecture
[[file:rlpc.drawio.svg]]
* Build Info
- ~rlpc~ is built using [[https://www.haskell.org/ghcup/][Cabal]]
- ~rlpc~'s documentation is built using
[[https://www.sphinx-doc.org/en/master/][Sphinx]]
#+BEGIN_SRC sh
$ cabal build # Build the rlpc compiler
$ cabal install # Install rlpc to $PATH
$ cabal haddock # Build the API docs w/ Haddock
$ make -C doc html # Build the primary docs w/ Sphinx
# run the test suite
$ cabal test --test-show-details=direct
#+END_SRC
* Use
** TLDR
#+begin_src sh
# Compile and evaluate examples/rlp/QuickSort.rl
$ rlpc examples/QuickSort.rl
# Compile and evaluate t.cr, with evaluation info dumped to t.log
$ rlpc -ddump-eval -l t.log t.cr
# Compile and evaluate t.rl, dumping the desugared Core
$ rlpc -ddump-desugared t.rl
# Compile and evaluate t.rl with all compiler messages enabled
$ rlpc -dALL t.rl
#+end_src
** Options
#+begin_src sh
Usage: rlpc [-l|--log FILE] [-d DEBUG FLAG] [-f COMPILATION FLAG]
[-e|--evaluator gm|ti] [--heap-trigger INT] [-x|--language rlp|core]
FILES...
#+end_src
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
* Demos
[TODO: add hmvis video here]
* To-do List
** TODO [#A] rlp to core desugaring :feature:
** DONE [#A] HM memoisation prevents shadowing :bug:
CLOSED: [2024-04-04 Thu 12:29]
Example:
#+begin_src haskell
-- >>> runHM' $ infer1 [rlpExpr|let f = \x -> x in f (let f = 2 in f)|]
-- Left [TyErrCouldNotUnify
-- (ConT "Int#")
-- (AppT (AppT FunT (ConT "Int#")) (VarT "$a2"))]
-- >>> :t let f = \x -> x in f (let f = 2 in f)
-- let f = \x -> x in f (let f = 2 in f) :: Int
#+end_src
For the time being, I just disabled the memoisation. This is very, very bad.
*** Closing Remarks
Fixed by entirely rewriting the type inference algorithm :P. Memoisation is
no longer required; the bottom-up inference a la Algorithm M was previously
hacked together using a comonadic extend with a catamorphism, which, for each
node, would fold the entire subtree and memoise the result, which would then
be retrieved when parent nodes attempted to infer children nodes. This sucks!
It's not "bottom-up" at all! I replaced it with a gorgeous hand-rolled
recursion scheme which truly works from the bottom upwards. A bonus
specialisation is that it annotates each node with the result of a
catamorphism from that node downwards via the cofree comonad.
#+begin_src haskell
dendroscribe :: (Functor f, Base t ~ f, Recursive t)
=> (f (Cofree f a) -> a) -> t -> Cofree f a
dendroscribe c (project -> f) = c f' :< f'
where f' = dendroscribe c <$> f
dendroscribeM :: (Traversable f, Monad m, Base t ~ f, Recursive t)
=> (f (Cofree f a) -> m a) -> t -> m (Cofree f a)
dendroscribeM c (project -> f) = do
as <- dendroscribeM c `traverse` f
a <- c as
pure (a :< as)
#+end_src
** DONE README.md -> README.org :docs:
CLOSED: [2024-03-28 Thu 10:44]
** DONE [#A] ~case~ inference :feature:
CLOSED: [2024-04-05 Fri 15:26]
** DONE [#A] ADT support in Rlp/HindleyMilner.hs :feature:
CLOSED: [2024-04-05 Fri 12:28]
** DONE whole-program inference (wrap top-level in a ~letrec~) :feature:
CLOSED: [2024-04-04 Thu 12:42]
shadowing issue sucks. i'm going to have to rewrite the whole type inference
system later. and i never learn, so i'm gonna use a chronomorphism :3.
*** Closing Remarks
I don't know how a fucking chronomorphism works. None of the experts can
think of a single example of how to use it. The rewrite uses a bottom-up
recursion scheme I've dubbed ~dendroscribe~.
** TODO user-supplied annotation support in Rlp/HindleyMilner.hs :feature:
** DONE [#A] update architecture diagram :docs:
CLOSED: [2024-04-05 Fri 15:41]
** TODO pattern support; everywhere [0%] :feature:
- [-] in the type-checker
- [ ] in the desugarer
** TODO [#A] G-machine visualiser :docs:
** TODO [#C] lambda calculus visualiser :docs:
** TODO hmvis does not reload when redefining expressions :bug:
To recreate:
1. enter
#+begin_src haskell
x = 2
#+end_src
2. hit "type-check"
3. edit source to
#+begin_src haskell
x = \x -> x
#+end_src
4. hit "type-check"
** DONE in Rlp/HindleyMilner.hs, fix ~listenFreshTvNames~ :housekeeping:
CLOSED: [2024-04-04 Thu 13:17]
it /does/ work in its current state, however it captures an unreasonably
excessive amount of names, even for a heuristic.
*** Closing Remarks
Fixed with the proper Algorithm M rewrite. The original purpose of
~listenFreshTvNames~ (tracking monomorphic type variables) has been solved
much more cleanly via the (non-monadic!) ~monomorphise~ function paired with
the new ~ImplicitInstance~ constraint.
** TODO up-to-date examples [0/2] :docs:
- [ ] quicksort (core and rlp)
- [ ] factorial (core and rlp)
** TODO [#C] fix spacing in pretty-printing :bug:
note the extra space before the equals sign:
#begin_src
>>> makeItPretty $ justInferRlp "id x = x" <&> rlpProgToCore
Right
id : ∀ ($a0 : Type). $a0 -> $a0 = <lambda>;
#end_src
** TODO Core.Utils.freeVariables does not handle let-bindings :bug:
* Releases
** +December Release+
- [X] Tests
- [ ] Core lexer
- [ ] Core parser
- [X] Evaluation model
- [ ] Benchmarks
- [X] Stable Core lexer
- [X] Stable Core parser
- [X] Stable evaluation model
- [X] Garbage Collection
- [ ] Stable documentation for the evaluation model
** +February Release Plan+
- [X] Beta rl' to Core
- [X] UX improvements
- [X] Actual compiler errors -- no more unexceptional `error` calls
- [X] Better CLI dump flags
- [X] Annotate the AST with token positions for errors (NOTE: As of Feb. 1,
this has been done, but the locational info is not yet used in error messages)
- [X] Compiler architecture diagram
- [X] More examples
** Final Release Plan
SCHEDULED: <2024-04-19 Fri>
*** TODO Complete all A-priority checks in the main todo-list!!
*** TODO Tests
- [ ] rl' parser
- [ ] Type inference
*** TODO Examples
- [ ] quicksort
- [ ] factorial
- [ ] your typical FP operations -- mapping, folding, etc.
*** DONE Ditch TTG in favour of fixed-points of functors
Focus on extendability via Fix, Free, Cofree, etc. rather than
boilerplate-heavy type families
*** DONE rl' type inference
*** DONE Core type checking
** Presentation
SCHEDULED: <2024-05-10 Fri>
*** TODO Documentation
- [ ] Type inference / Algorithm M
- [ ] The G-Machine
*** TODO G-Machine visualiser
*** TODO Post-mortem write-up
e.g. what would I do differently next time, what have I learned, etc.
*** TODO Final polish check [0/3]
- [ ] CLI
- [ ] G-Machine output
- [ ] ~Compiler.JustRun~ module

View File

@@ -10,17 +10,15 @@ import Control.Lens.Combinators
import Core.Lex import Core.Lex
import Core.Parse import Core.Parse
import Core.SystemF
import GM import GM
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
driver :: RLPCIO () driver :: RLPCIO ()
driver = forFiles_ $ \f -> driver = forFiles_ $ \f ->
withSource f (lexCoreR >=> parseCoreProgR >=> lintCoreProgR >=> evalProgR) withSource f (lexCoreR >=> parseCoreProgR >=> evalProgR)
driverSource :: T.Text -> RLPCIO () driverSource :: T.Text -> RLPCIO ()
driverSource = lexCoreR >=> parseCoreProgR driverSource = lexCoreR >=> parseCoreProgR >=> evalProgR >=> printRes
>=> lintCoreProgR >=> evalProgR >=> printRes
where where
printRes = liftIO . print . view _1 printRes = liftIO . print . view _1

View File

@@ -2,7 +2,6 @@
{-# 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
@@ -24,7 +23,6 @@ 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
@@ -76,11 +74,7 @@ options = RLPCOptions
<> metavar "rlp|core" <> metavar "rlp|core"
<> help "the language to be compiled -- see README" <> help "the language to be compiled -- see README"
) )
<*> switch <*> some (argument str $ metavar "FILES...")
( long "server"
<> short 's'
)
<*> many (argument str $ metavar "FILES...")
where where
infixr 9 # infixr 9 #
f # x = f x f # x = f x
@@ -113,9 +107,7 @@ mmany v = liftA2 (<>) v (mmany v)
main :: IO () main :: IO ()
main = do main = do
opts <- execParser optParser opts <- execParser optParser
if opts ^. rlpcServer void $ evalRLPCIO opts dispatch
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 >=> undefined >=> desugarRlpProgR >=> evalProgR) withSource f (parseRlpProgR >=> desugarRlpProgR >=> evalProgR)

View File

@@ -1,115 +0,0 @@
{-# LANGUAGE LambdaCase, BlockArguments #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE OverloadedStrings #-}
module Server
( server
)
where
--------------------------------------------------------------------------------
import GHC.Generics (Generic, Generically(..))
import Data.Text.Encoding qualified as T
import Data.Text (Text)
import Data.Text qualified as T
import Data.Text.IO qualified as T
import Data.Pretty hiding (annotate)
import Data.Aeson
import Data.Function
import Control.Arrow
import Control.Applicative
import Control.Monad
import Control.Concurrent
import Network.WebSockets qualified as WS
import Control.Exception
import GHC.IO
import Control.Lens hiding ((.=))
import Control.Comonad
import Data.Functor.Foldable
import Compiler.RLPC
import Misc.CofreeF
import Rlp.AltSyntax
import Rlp.HindleyMilner
import Rlp.AltParse
--------------------------------------------------------------------------------
server :: IO ()
server = do
T.putStrLn "rlpc server started at 127.0.0.1:9002"
WS.runServer "127.0.0.1" 9002 application
application :: WS.ServerApp
application pending = do
WS.acceptRequest pending >>= talk
data Command = Annotate Text
| PartiallyAnnotate Text
deriving Show
instance FromJSON Command where
parseJSON = withObject "command object" $ \v -> do
cmd :: Text <- v .: "command"
case cmd of
"annotate" -> Annotate <$> v .: "source"
"partially-annotate" -> PartiallyAnnotate <$> v .: "source"
_ -> empty
data Response = Annotated Value
| PartiallyAnnotated Value
deriving (Generic)
deriving (ToJSON)
via Generically Response
talk :: WS.Connection -> IO ()
talk conn = (`catchAny` print) . forever $ do
msg <- WS.receiveData @Text conn
T.putStrLn $ "received: " <> msg
doCommand conn `traverse` decodeStrictText msg
doCommand :: WS.Connection -> Command -> IO ()
doCommand conn c = do
putStr "sending: "
let r = encode . respond $ c
print r
WS.sendTextData conn r
respond :: Command -> Response
respond (Annotate s)
= s & (parseRlpProgR >=> typeCheckRlpProgR)
& fmap (\p -> p ^.. funDs
<&> serialiseSc)
& runRLPCJsonDef
& Annotated
showPartialAnn = undefined
funDs :: Traversal' (Program b a) (b, [Pat b], a)
funDs = programDecls . each . _FunD
serialiseSc :: (PsName, [Pat PsName], Cofree (RlpExprF PsName) (Type PsName))
-> Value
serialiseSc (n,as,e) = object
[ "name" .= n
, "args" .= as
, "body" .= let root = extract e
in serialiseAnnotated (e <&> renamePrettily root)
]
serialiseAnnotated :: Cofree (RlpExprF PsName) (Type PsName)
-> Value
serialiseAnnotated = cata \case
t :<$ e -> object [ "e" .= e, "type" .= rout @Text t ]
runRLPCJsonWithDef :: (a -> Value) -> RLPC a -> Value
runRLPCJsonWithDef f = runRLPCJsonWith f def
runRLPCJsonDef :: (ToJSON a) => RLPC a -> Value
runRLPCJsonDef = runRLPCJsonWith toJSON def
runRLPCJsonWith :: (a -> Value) -> RLPCOptions -> RLPC a -> Value
runRLPCJsonWith f o r = object
[ "errors" .= es
, "result" .= (f <$> ma) ]
where (ma,es) = evalRLPC o r

View File

@@ -1,6 +0,0 @@
rlpc Post-Mortem
================
I begin writing this (10:11 AM, 15 Apr) shortly after I push what I believe to
be one of my final commits.

8
find-build.cl Executable file
View File

@@ -0,0 +1,8 @@
#!/usr/bin/env sbcl --script
(let* ((paths (directory "dist-newstyle/build/*/*/rlp-*/build/"))
(n (length paths)))
(cond ((< 1 n) (error ">1 build directories found. run `cabal clean`."))
((< n 1) (error "no build directories found. this shouldn't happen lol"))
(t (format t "~A" (car paths)))))

View File

@@ -1,13 +0,0 @@
#!/usr/bin/env bb
(defn die [& msgs]
(binding [*out* *err*]
(run! println msgs))
(System/exit 1))
(let [paths (map str (fs/glob "." "dist-newstyle/build/*/*/rlp-*/build"))
n (count paths)]
(cond (< 1 n) (die ">1 build directories found. run `cabal clean`.")
(< n 1) (die "no build directories found. this shouldn't happen lol")
:else (-> paths first fs/real-path str println)))

View File

@@ -16,7 +16,6 @@ tested-with: GHC==9.6.2
common warnings common warnings
-- ghc-options: -Wall -Wno-incomplete-uni-patterns -Wno-unused-top-binds -- ghc-options: -Wall -Wno-incomplete-uni-patterns -Wno-unused-top-binds
ghc-options: -fdefer-typed-holes
library library
import: warnings import: warnings
@@ -36,10 +35,10 @@ library
, Rlp.AltSyntax , Rlp.AltSyntax
, Rlp.AltParse , Rlp.AltParse
, Rlp.HindleyMilner , Rlp.HindleyMilner
, Rlp.HindleyMilner.Visual
, Rlp.HindleyMilner.Types , Rlp.HindleyMilner.Types
, Rlp.Syntax.Backstage , Rlp.Syntax.Backstage
, Rlp.Syntax.Types , Rlp.Syntax.Types
, Rlp.Syntax.Good
-- , Rlp.Parse.Decls -- , Rlp.Parse.Decls
, Rlp.Parse , Rlp.Parse
, Rlp.Parse.Associate , Rlp.Parse.Associate
@@ -56,25 +55,24 @@ library
, Rlp2Core , Rlp2Core
, Control.Monad.Utils , Control.Monad.Utils
, Misc , Misc
, Misc.MonadicRecursionSchemes
, Misc.Lift1 , Misc.Lift1
, Misc.CofreeF
, Core.SystemF , Core.SystemF
build-tool-depends: happy:happy, alex:alex build-tool-depends: happy:happy, alex:alex
-- other-extensions: -- other-extensions:
build-depends: base >=4.17 && <4.21 build-depends: base >=4.17 && <4.20
-- required for happy -- required for happy
, array >= 0.5.5 && < 0.6 , array >= 0.5.5 && < 0.6
, containers >= 0.6.7 && < 0.7 , containers >= 0.6.7 && < 0.7
, template-haskell >= 2.20.0 && < 2.23 , template-haskell >= 2.20.0 && < 2.21
, pretty >= 1.1.3 && < 1.2 , pretty >= 1.1.3 && < 1.2
, data-default >= 0.7.1 && < 0.8 , data-default >= 0.7.1 && < 0.8
, data-default-class >= 0.1.2 && < 0.2 , data-default-class >= 0.1.2 && < 0.2
, hashable >= 1.4.3 && < 1.5 , hashable >= 1.4.3 && < 1.5
, mtl >= 2.3.1 && < 2.4 , mtl >= 2.3.1 && < 2.4
, text >= 2.0.2 && < 2.3 , transformers
, text >= 2.0.2 && < 2.2
, unordered-containers >= 0.2.20 && < 0.3 , unordered-containers >= 0.2.20 && < 0.3
, recursion-schemes >= 5.2.2 && < 5.3 , recursion-schemes >= 5.2.2 && < 5.3
, data-fix >= 0.3.2 && < 0.4 , data-fix >= 0.3.2 && < 0.4
@@ -89,8 +87,6 @@ library
, these >=0.2 && <2.0 , these >=0.2 && <2.0
, free >=5.2 , free >=5.2
, bifunctors >=5.2 , bifunctors >=5.2
, aeson >=2.2.1.0 && <2.3.1.0
, lens-aeson
hs-source-dirs: src hs-source-dirs: src
default-language: GHC2021 default-language: GHC2021
@@ -111,7 +107,6 @@ 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
@@ -119,7 +114,7 @@ executable rlpc
, 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
, lens >=5.2.3 && <6.0 , lens >=5.2.3 && <6.0
, text >= 2.0.2 && < 2.3 , text >= 2.0.2 && < 2.2
hs-source-dirs: app hs-source-dirs: app
default-language: GHC2021 default-language: GHC2021

View File

@@ -1,6 +1,6 @@
<mxfile host="app.diagrams.net" modified="2024-04-05T21:39:15.427Z" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:124.0) Gecko/20100101 Firefox/124.0" etag="vzU3tfRucuQcOEqioBHC" version="23.1.2" type="device"> <mxfile host="app.diagrams.net" modified="2024-02-08T07:33:52.268Z" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:122.0) Gecko/20100101 Firefox/122.0" etag="_2ex2NLQLCDMU70EmKFT" version="23.0.2" type="device">
<diagram name="Page-1" id="ijVUcW-Be2043inOeyM6"> <diagram name="Page-1" id="ijVUcW-Be2043inOeyM6">
<mxGraphModel dx="1792" dy="2289" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0"> <mxGraphModel dx="1629" dy="2189" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root> <root>
<mxCell id="0" /> <mxCell id="0" />
<mxCell id="1" parent="0" /> <mxCell id="1" parent="0" />
@@ -22,13 +22,13 @@
<mxCell id="l7NxJpuHm0Jx_7flO9iA-57" value="&lt;div&gt;&lt;font face=&quot;Helvetica&quot;&gt;Parser&lt;/font&gt;&lt;/div&gt;" style="html=1;shape=mxgraph.er.anchor;whiteSpace=wrap;fontFamily=Courier New;" parent="l7NxJpuHm0Jx_7flO9iA-56" vertex="1"> <mxCell id="l7NxJpuHm0Jx_7flO9iA-57" value="&lt;div&gt;&lt;font face=&quot;Helvetica&quot;&gt;Parser&lt;/font&gt;&lt;/div&gt;" style="html=1;shape=mxgraph.er.anchor;whiteSpace=wrap;fontFamily=Courier New;" parent="l7NxJpuHm0Jx_7flO9iA-56" vertex="1">
<mxGeometry width="431.6" height="27.6975" as="geometry" /> <mxGeometry width="431.6" height="27.6975" as="geometry" />
</mxCell> </mxCell>
<mxCell id="l7NxJpuHm0Jx_7flO9iA-58" value="Rlp.AltParse&lt;br&gt;&lt;div&gt;(src/Rlp/AltParse.y)&lt;/div&gt;" style="rounded=1;absoluteArcSize=1;html=1;arcSize=10;whiteSpace=wrap;points=[];strokeColor=#6c8ebf;fillColor=#dae8fc;glass=0;fontFamily=Courier New;" parent="l7NxJpuHm0Jx_7flO9iA-56" vertex="1"> <mxCell id="l7NxJpuHm0Jx_7flO9iA-58" value="Rlp.Parse&lt;br&gt;&lt;div&gt;(src/Rlp/Parse.y)&lt;/div&gt;" style="rounded=1;absoluteArcSize=1;html=1;arcSize=10;whiteSpace=wrap;points=[];strokeColor=#6c8ebf;fillColor=#dae8fc;glass=0;fontFamily=Courier New;" parent="l7NxJpuHm0Jx_7flO9iA-56" vertex="1">
<mxGeometry x="26.980533333333334" y="27.6975" width="371.43053333333336" height="55.395" as="geometry" /> <mxGeometry x="26.980533333333334" y="27.6975" width="371.43053333333336" height="55.395" as="geometry" />
</mxCell> </mxCell>
<mxCell id="l7NxJpuHm0Jx_7flO9iA-59" value="&lt;div&gt;Rlp.Lex&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;(src/Rlp/Lex.x)&lt;br&gt;&lt;/div&gt;" style="rounded=1;arcSize=10;whiteSpace=wrap;html=1;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;fontFamily=Courier New;" parent="l7NxJpuHm0Jx_7flO9iA-56" vertex="1"> <mxCell id="l7NxJpuHm0Jx_7flO9iA-59" value="&lt;div&gt;Rlp.Lex&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;(src/Rlp/Lex.x)&lt;br&gt;&lt;/div&gt;" style="rounded=1;arcSize=10;whiteSpace=wrap;html=1;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;fontFamily=Courier New;" parent="l7NxJpuHm0Jx_7flO9iA-56" vertex="1">
<mxGeometry x="26.98606666666666" y="147.72" width="170.33402285714286" height="55.395" as="geometry" /> <mxGeometry x="26.98606666666666" y="147.72" width="170.33402285714286" height="55.395" as="geometry" />
</mxCell> </mxCell>
<mxCell id="l7NxJpuHm0Jx_7flO9iA-61" value="" style="endArrow=classic;html=1;rounded=0;fontFamily=Courier New;exitX=0.25;exitY=0;exitDx=0;exitDy=0;" parent="l7NxJpuHm0Jx_7flO9iA-56" source="l7NxJpuHm0Jx_7flO9iA-59" edge="1"> <mxCell id="l7NxJpuHm0Jx_7flO9iA-61" value="" style="endArrow=classic;html=1;rounded=0;fontFamily=Courier New;exitX=0.25;exitY=0;exitDx=0;exitDy=0;" parent="l7NxJpuHm0Jx_7flO9iA-56" edge="1" source="l7NxJpuHm0Jx_7flO9iA-59">
<mxGeometry relative="1" as="geometry"> <mxGeometry relative="1" as="geometry">
<mxPoint x="111.49666666666668" y="147.72" as="sourcePoint" /> <mxPoint x="111.49666666666668" y="147.72" as="sourcePoint" />
<mxPoint x="69.26631355932203" y="83.84879190161169" as="targetPoint" /> <mxPoint x="69.26631355932203" y="83.84879190161169" as="targetPoint" />
@@ -48,18 +48,18 @@
<mxPoint x="394.60571428571427" y="175.4175" as="targetPoint" /> <mxPoint x="394.60571428571427" y="175.4175" as="targetPoint" />
</mxGeometry> </mxGeometry>
</mxCell> </mxCell>
<mxCell id="l7NxJpuHm0Jx_7flO9iA-77" value="&lt;div&gt;Rlp.Program PsName RlpExpr&#39;&lt;br&gt;&lt;/div&gt;" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontFamily=Courier New;" parent="l7NxJpuHm0Jx_7flO9iA-75" vertex="1" connectable="0"> <mxCell id="l7NxJpuHm0Jx_7flO9iA-77" value="&lt;div&gt;RlpProgram&#39; RlpcPs&lt;/div&gt;" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontFamily=Courier New;" parent="l7NxJpuHm0Jx_7flO9iA-75" vertex="1" connectable="0">
<mxGeometry x="0.0677" y="5" relative="1" as="geometry"> <mxGeometry x="0.0677" y="5" relative="1" as="geometry">
<mxPoint x="39" y="6" as="offset" /> <mxPoint x="39" y="6" as="offset" />
</mxGeometry> </mxGeometry>
</mxCell> </mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-3" value="" style="endArrow=classic;html=1;rounded=0;exitX=0.368;exitY=1.014;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.811;entryY=-0.021;entryDx=0;entryDy=0;entryPerimeter=0;" parent="l7NxJpuHm0Jx_7flO9iA-56" source="l7NxJpuHm0Jx_7flO9iA-58" target="l7NxJpuHm0Jx_7flO9iA-59" edge="1"> <mxCell id="MMc0v0DIyy0xya0iXp__-3" value="" style="endArrow=classic;html=1;rounded=0;exitX=0.368;exitY=1.014;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.811;entryY=-0.021;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="l7NxJpuHm0Jx_7flO9iA-56" source="l7NxJpuHm0Jx_7flO9iA-58" target="l7NxJpuHm0Jx_7flO9iA-59">
<mxGeometry width="50" height="50" relative="1" as="geometry"> <mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="168.70805084745763" y="201.9041131288017" as="sourcePoint" /> <mxPoint x="168.70805084745763" y="201.9041131288017" as="sourcePoint" />
<mxPoint x="225.8584745762712" y="152.71439595080588" as="targetPoint" /> <mxPoint x="225.8584745762712" y="152.71439595080588" as="targetPoint" />
</mxGeometry> </mxGeometry>
</mxCell> </mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-4" value="&lt;p style=&quot;line-height: 60%;&quot;&gt;&lt;font style=&quot;font-size: 7px;&quot;&gt;(lexer &amp;amp; parser threaded w/ CPS)&lt;/font&gt;&lt;/p&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="l7NxJpuHm0Jx_7flO9iA-56" vertex="1"> <mxCell id="MMc0v0DIyy0xya0iXp__-4" value="&lt;p style=&quot;line-height: 60%;&quot;&gt;&lt;font style=&quot;font-size: 7px;&quot;&gt;(lexer &amp;amp; parser threaded w/ CPS)&lt;/font&gt;&lt;/p&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="l7NxJpuHm0Jx_7flO9iA-56">
<mxGeometry x="88.69745762711862" y="103.52467877281002" width="68.58050847457626" height="29.513830306797498" as="geometry" /> <mxGeometry x="88.69745762711862" y="103.52467877281002" width="68.58050847457626" height="29.513830306797498" as="geometry" />
</mxCell> </mxCell>
<mxCell id="l7NxJpuHm0Jx_7flO9iA-69" value="" style="rounded=1;absoluteArcSize=1;html=1;arcSize=10;fontFamily=Courier New;" parent="l7NxJpuHm0Jx_7flO9iA-2" vertex="1"> <mxCell id="l7NxJpuHm0Jx_7flO9iA-69" value="" style="rounded=1;absoluteArcSize=1;html=1;arcSize=10;fontFamily=Courier New;" parent="l7NxJpuHm0Jx_7flO9iA-2" vertex="1">
@@ -68,195 +68,185 @@
<mxCell id="l7NxJpuHm0Jx_7flO9iA-70" value="&lt;div&gt;&lt;font face=&quot;Helvetica&quot;&gt;Desugarer&lt;/font&gt;&lt;/div&gt;" style="html=1;shape=mxgraph.er.anchor;whiteSpace=wrap;fontFamily=Courier New;" parent="l7NxJpuHm0Jx_7flO9iA-69" vertex="1"> <mxCell id="l7NxJpuHm0Jx_7flO9iA-70" value="&lt;div&gt;&lt;font face=&quot;Helvetica&quot;&gt;Desugarer&lt;/font&gt;&lt;/div&gt;" style="html=1;shape=mxgraph.er.anchor;whiteSpace=wrap;fontFamily=Courier New;" parent="l7NxJpuHm0Jx_7flO9iA-69" vertex="1">
<mxGeometry width="431.6" height="46.091157894736845" as="geometry" /> <mxGeometry width="431.6" height="46.091157894736845" as="geometry" />
</mxCell> </mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-1" value="&lt;div&gt;Rlp2Core&lt;/div&gt;" style="rounded=1;arcSize=10;whiteSpace=wrap;html=1;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;fontFamily=Courier New;" parent="l7NxJpuHm0Jx_7flO9iA-69" vertex="1"> <mxCell id="MMc0v0DIyy0xya0iXp__-1" value="&lt;div&gt;Rlp2Core&lt;/div&gt;" style="rounded=1;arcSize=10;whiteSpace=wrap;html=1;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;fontFamily=Courier New;" vertex="1" parent="l7NxJpuHm0Jx_7flO9iA-69">
<mxGeometry x="22.122266666666665" y="46.088669843028626" width="387.34440000000006" height="159.17559608494923" as="geometry" /> <mxGeometry x="22.122266666666665" y="46.088669843028626" width="387.34440000000006" height="159.17559608494923" as="geometry" />
</mxCell> </mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-6" value="" style="rounded=1;absoluteArcSize=1;html=1;arcSize=10;fontFamily=Courier New;" parent="l7NxJpuHm0Jx_7flO9iA-2" vertex="1"> <mxCell id="MMc0v0DIyy0xya0iXp__-6" value="" style="rounded=1;absoluteArcSize=1;html=1;arcSize=10;fontFamily=Courier New;" vertex="1" parent="l7NxJpuHm0Jx_7flO9iA-2">
<mxGeometry x="904" y="68.42105263157895" width="244.8600518134714" height="697.8947368421053" as="geometry" /> <mxGeometry x="904" y="68.42105263157895" width="186.6" height="697.8947368421053" as="geometry" />
</mxCell> </mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-7" value="&lt;font face=&quot;Helvetica&quot;&gt;Evaluation Model&lt;br&gt;&lt;/font&gt;" style="html=1;shape=mxgraph.er.anchor;whiteSpace=wrap;fontFamily=Courier New;" parent="MMc0v0DIyy0xya0iXp__-6" vertex="1"> <mxCell id="MMc0v0DIyy0xya0iXp__-7" value="&lt;font face=&quot;Helvetica&quot;&gt;Evaluation Model&lt;br&gt;&lt;/font&gt;" style="html=1;shape=mxgraph.er.anchor;whiteSpace=wrap;fontFamily=Courier New;" vertex="1" parent="MMc0v0DIyy0xya0iXp__-6">
<mxGeometry width="186.6" height="107.07065060420568" as="geometry" /> <mxGeometry width="186.6" height="107.07065060420568" as="geometry" />
</mxCell> </mxCell>
<mxCell id="DDBEc0rYRfbomnRGFAIR-4" value="GM" style="rounded=1;arcSize=10;whiteSpace=wrap;html=1;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;fontFamily=Courier New;verticalAlign=top;" vertex="1" parent="MMc0v0DIyy0xya0iXp__-6"> <mxCell id="MMc0v0DIyy0xya0iXp__-8" value="GM" style="rounded=1;arcSize=10;whiteSpace=wrap;html=1;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;fontFamily=Courier New;" vertex="1" parent="MMc0v0DIyy0xya0iXp__-6">
<mxGeometry x="10" y="70" width="220" height="260.78" as="geometry" /> <mxGeometry x="9.568013810372213" y="356.90796215152363" width="167.46559322033886" height="82.98740890928475" as="geometry" />
</mxCell> </mxCell>
<mxCell id="DDBEc0rYRfbomnRGFAIR-5" value="&lt;font face=&quot;Courier New&quot;&gt;compile&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="MMc0v0DIyy0xya0iXp__-6"> <mxCell id="MMc0v0DIyy0xya0iXp__-9" value="TM" style="rounded=1;arcSize=10;whiteSpace=wrap;html=1;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;fontFamily=Courier New;" vertex="1" parent="MMc0v0DIyy0xya0iXp__-6">
<mxGeometry x="26" y="91.58" width="184" height="37.03" as="geometry" /> <mxGeometry x="9.562261652542377" y="263.9548629430177" width="167.46559322033886" height="82.98740890928475" as="geometry" />
</mxCell> </mxCell>
<mxCell id="DDBEc0rYRfbomnRGFAIR-6" value="&lt;font face=&quot;Courier New&quot;&gt;eval&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="MMc0v0DIyy0xya0iXp__-6"> <mxCell id="MMc0v0DIyy0xya0iXp__-10" value="TIM" style="rounded=1;arcSize=10;whiteSpace=wrap;html=1;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;fontFamily=Courier New;" vertex="1" parent="MMc0v0DIyy0xya0iXp__-6">
<mxGeometry x="26" y="211.58" width="184" height="37.03" as="geometry" /> <mxGeometry x="9.56226165254238" y="168.9311122835313" width="167.46559322033886" height="82.98740890928475" as="geometry" />
</mxCell> </mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-32" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="MMc0v0DIyy0xya0iXp__-6" source="DDBEc0rYRfbomnRGFAIR-5" target="DDBEc0rYRfbomnRGFAIR-6" edge="1"> <mxCell id="MMc0v0DIyy0xya0iXp__-11" value="STG" style="rounded=1;arcSize=10;whiteSpace=wrap;html=1;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;fontFamily=Courier New;" vertex="1" parent="MMc0v0DIyy0xya0iXp__-6">
<mxGeometry width="50" height="50" relative="1" as="geometry"> <mxGeometry x="9.56720338983051" y="73.90736162404495" width="167.46559322033886" height="82.98740890928475" as="geometry" />
<mxPoint x="-94" y="520" as="sourcePoint" />
<mxPoint x="-44" y="451.57894736842104" as="targetPoint" />
</mxGeometry>
</mxCell> </mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-33" value="&lt;font face=&quot;Courier New&quot;&gt;[Instr]&lt;/font&gt;" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="MMc0v0DIyy0xya0iXp__-32" vertex="1" connectable="0"> <mxCell id="MMc0v0DIyy0xya0iXp__-12" value="" style="rounded=1;absoluteArcSize=1;html=1;arcSize=10;fontFamily=Courier New;" vertex="1" parent="l7NxJpuHm0Jx_7flO9iA-2">
<mxGeometry x="0.0406" y="1" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="DDBEc0rYRfbomnRGFAIR-7" value="" style="curved=1;endArrow=classic;html=1;rounded=0;entryX=0.922;entryY=0.046;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="MMc0v0DIyy0xya0iXp__-6" target="DDBEc0rYRfbomnRGFAIR-6">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="210" y="231.57894736842104" as="sourcePoint" />
<mxPoint x="260" y="181.57894736842104" as="targetPoint" />
<Array as="points">
<mxPoint x="226" y="231.57894736842104" />
<mxPoint x="236" y="201.57894736842104" />
<mxPoint x="236" y="191.57894736842104" />
<mxPoint x="226" y="181.57894736842104" />
<mxPoint x="206" y="181.57894736842104" />
<mxPoint x="196" y="191.57894736842104" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="DDBEc0rYRfbomnRGFAIR-8" value="&lt;font face=&quot;Courier New&quot;&gt;GMState&lt;/font&gt;" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="MMc0v0DIyy0xya0iXp__-6">
<mxGeometry x="216" y="171.58333333333314" as="geometry">
<mxPoint x="-4" y="-1" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-12" value="" style="rounded=1;absoluteArcSize=1;html=1;arcSize=10;fontFamily=Courier New;" parent="l7NxJpuHm0Jx_7flO9iA-2" vertex="1">
<mxGeometry x="530" y="68.42" width="281.6" height="314.74" as="geometry" /> <mxGeometry x="530" y="68.42" width="281.6" height="314.74" as="geometry" />
</mxCell> </mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-13" value="&lt;div&gt;&lt;font face=&quot;Helvetica&quot;&gt;Preprocessing&lt;/font&gt;&lt;/div&gt;" style="html=1;shape=mxgraph.er.anchor;whiteSpace=wrap;fontFamily=Courier New;" parent="MMc0v0DIyy0xya0iXp__-12" vertex="1"> <mxCell id="MMc0v0DIyy0xya0iXp__-13" value="&lt;div&gt;&lt;font face=&quot;Helvetica&quot;&gt;Preprocessing&lt;/font&gt;&lt;/div&gt;" style="html=1;shape=mxgraph.er.anchor;whiteSpace=wrap;fontFamily=Courier New;" vertex="1" parent="MMc0v0DIyy0xya0iXp__-12">
<mxGeometry width="281.5999999999999" height="24.68549019607843" as="geometry" /> <mxGeometry width="281.5999999999999" height="24.68549019607843" as="geometry" />
</mxCell> </mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-15" value="Core2Core" style="rounded=1;arcSize=10;whiteSpace=wrap;html=1;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;fontFamily=Courier New;verticalAlign=top;" parent="MMc0v0DIyy0xya0iXp__-12" vertex="1"> <mxCell id="MMc0v0DIyy0xya0iXp__-15" value="Core2Core" style="rounded=1;arcSize=10;whiteSpace=wrap;html=1;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;fontFamily=Courier New;verticalAlign=top;" vertex="1" parent="MMc0v0DIyy0xya0iXp__-12">
<mxGeometry x="22.25077720207253" y="49.37098039215686" width="237.09844559585483" height="259.1976470588235" as="geometry" /> <mxGeometry x="22.25077720207253" y="49.37098039215686" width="237.09844559585483" height="259.1976470588235" as="geometry" />
</mxCell> </mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-16" value="&lt;font face=&quot;Courier New&quot;&gt;tagData&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="MMc0v0DIyy0xya0iXp__-12" vertex="1"> <mxCell id="MMc0v0DIyy0xya0iXp__-16" value="&lt;font face=&quot;Courier New&quot;&gt;tagData&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="MMc0v0DIyy0xya0iXp__-12">
<mxGeometry x="31.36994818652857" y="74.0564705882353" width="218.860103626943" height="37.02823529411765" as="geometry" /> <mxGeometry x="31.36994818652857" y="74.0564705882353" width="218.860103626943" height="37.02823529411765" as="geometry" />
</mxCell> </mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-18" value="&lt;font face=&quot;Courier New&quot;&gt;defineData&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="MMc0v0DIyy0xya0iXp__-12" vertex="1"> <mxCell id="MMc0v0DIyy0xya0iXp__-18" value="&lt;font face=&quot;Courier New&quot;&gt;defineData&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="MMc0v0DIyy0xya0iXp__-12">
<mxGeometry x="31.36994818652857" y="160.45568627450984" width="218.860103626943" height="37.02823529411765" as="geometry" /> <mxGeometry x="31.36994818652857" y="160.45568627450984" width="218.860103626943" height="37.02823529411765" as="geometry" />
</mxCell> </mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-17" value="&lt;font face=&quot;Courier New&quot;&gt;liftNonStrictCases&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="MMc0v0DIyy0xya0iXp__-12" vertex="1"> <mxCell id="MMc0v0DIyy0xya0iXp__-17" value="&lt;font face=&quot;Courier New&quot;&gt;liftNonStrictCases&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="MMc0v0DIyy0xya0iXp__-12">
<mxGeometry x="31.369948186528582" y="118.66932274509804" width="218.860103626943" height="37.02823529411765" as="geometry" /> <mxGeometry x="31.369948186528582" y="118.66932274509804" width="218.860103626943" height="37.02823529411765" as="geometry" />
</mxCell> </mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-27" value="" style="endArrow=classic;html=1;rounded=0;entryX=-0.019;entryY=0.844;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0.98;exitY=0.066;exitDx=0;exitDy=0;exitPerimeter=0;" parent="l7NxJpuHm0Jx_7flO9iA-2" source="MMc0v0DIyy0xya0iXp__-1" target="MMc0v0DIyy0xya0iXp__-12" edge="1"> <mxCell id="MMc0v0DIyy0xya0iXp__-20" value="" style="rounded=1;absoluteArcSize=1;html=1;arcSize=10;fontFamily=Courier New;" vertex="1" parent="l7NxJpuHm0Jx_7flO9iA-2">
<mxGeometry x="1240" y="68.42105263157895" width="186.6" height="697.8947368421053" as="geometry" />
</mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-21" value="&lt;font face=&quot;Helvetica&quot;&gt;Some target&lt;br&gt;&lt;/font&gt;" style="html=1;shape=mxgraph.er.anchor;whiteSpace=wrap;fontFamily=Courier New;" vertex="1" parent="MMc0v0DIyy0xya0iXp__-20">
<mxGeometry width="186.6" height="107.07065060420568" as="geometry" />
</mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-27" value="" style="endArrow=classic;html=1;rounded=0;entryX=-0.019;entryY=0.844;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0.98;exitY=0.066;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="l7NxJpuHm0Jx_7flO9iA-2" source="MMc0v0DIyy0xya0iXp__-1" target="MMc0v0DIyy0xya0iXp__-12">
<mxGeometry width="50" height="50" relative="1" as="geometry"> <mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="450" y="684.2105263157895" as="sourcePoint" /> <mxPoint x="450" y="684.2105263157895" as="sourcePoint" />
<mxPoint x="500" y="615.7894736842105" as="targetPoint" /> <mxPoint x="500" y="615.7894736842105" as="targetPoint" />
</mxGeometry> </mxGeometry>
</mxCell> </mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-28" value="&lt;font face=&quot;Courier New&quot;&gt;Core.Program Var&lt;br&gt;&lt;/font&gt;" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="MMc0v0DIyy0xya0iXp__-27" vertex="1" connectable="0"> <mxCell id="MMc0v0DIyy0xya0iXp__-28" value="&lt;font face=&quot;Courier New&quot;&gt;Program&#39;&lt;/font&gt;" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="MMc0v0DIyy0xya0iXp__-27">
<mxGeometry x="-0.1473" y="1" relative="1" as="geometry"> <mxGeometry x="-0.1473" y="1" relative="1" as="geometry">
<mxPoint x="7" y="1" as="offset" /> <mxPoint x="7" y="1" as="offset" />
</mxGeometry> </mxGeometry>
</mxCell> </mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-30" value="" style="endArrow=classic;html=1;rounded=0;entryX=-0.013;entryY=0.321;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryPerimeter=0;" parent="l7NxJpuHm0Jx_7flO9iA-2" source="MMc0v0DIyy0xya0iXp__-12" target="MMc0v0DIyy0xya0iXp__-6" edge="1"> <mxCell id="MMc0v0DIyy0xya0iXp__-30" value="" style="endArrow=classic;html=1;rounded=0;entryX=-0.013;entryY=0.321;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryPerimeter=0;" edge="1" parent="l7NxJpuHm0Jx_7flO9iA-2" source="MMc0v0DIyy0xya0iXp__-12" target="MMc0v0DIyy0xya0iXp__-6">
<mxGeometry width="50" height="50" relative="1" as="geometry"> <mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="810" y="588.421052631579" as="sourcePoint" /> <mxPoint x="810" y="588.421052631579" as="sourcePoint" />
<mxPoint x="860" y="520" as="targetPoint" /> <mxPoint x="860" y="520" as="targetPoint" />
</mxGeometry> </mxGeometry>
</mxCell> </mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-31" value="&lt;font face=&quot;Courier New&quot;&gt;Core.Program Name&lt;br&gt;&lt;/font&gt;" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="MMc0v0DIyy0xya0iXp__-30" vertex="1" connectable="0"> <mxCell id="MMc0v0DIyy0xya0iXp__-31" value="&lt;font face=&quot;Courier New&quot;&gt;Program&#39;&lt;/font&gt;" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="MMc0v0DIyy0xya0iXp__-30">
<mxGeometry x="0.0097" y="-1" relative="1" as="geometry"> <mxGeometry x="0.0097" y="-1" relative="1" as="geometry">
<mxPoint x="-1" as="offset" /> <mxPoint x="-1" as="offset" />
</mxGeometry> </mxGeometry>
</mxCell> </mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-35" value="" style="rounded=1;absoluteArcSize=1;html=1;arcSize=10;fontFamily=Courier New;" parent="l7NxJpuHm0Jx_7flO9iA-2" vertex="1"> <mxCell id="MMc0v0DIyy0xya0iXp__-32" value="" style="endArrow=classic;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="l7NxJpuHm0Jx_7flO9iA-2" source="MMc0v0DIyy0xya0iXp__-6" target="MMc0v0DIyy0xya0iXp__-20">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="810" y="588.421052631579" as="sourcePoint" />
<mxPoint x="860" y="520" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-33" value="&lt;font face=&quot;Courier New&quot;&gt;[Instr]&lt;/font&gt;" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="MMc0v0DIyy0xya0iXp__-32">
<mxGeometry x="0.0406" y="1" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-35" value="" style="rounded=1;absoluteArcSize=1;html=1;arcSize=10;fontFamily=Courier New;" vertex="1" parent="l7NxJpuHm0Jx_7flO9iA-2">
<mxGeometry x="530" y="630" width="281.6" height="131.32" as="geometry" /> <mxGeometry x="530" y="630" width="281.6" height="131.32" as="geometry" />
</mxCell> </mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-36" value="&lt;font face=&quot;Helvetica&quot;&gt;Core Parser&lt;br&gt;&lt;/font&gt;" style="html=1;shape=mxgraph.er.anchor;whiteSpace=wrap;fontFamily=Courier New;" parent="MMc0v0DIyy0xya0iXp__-35" vertex="1"> <mxCell id="MMc0v0DIyy0xya0iXp__-36" value="&lt;font face=&quot;Helvetica&quot;&gt;Core Parser&lt;br&gt;&lt;/font&gt;" style="html=1;shape=mxgraph.er.anchor;whiteSpace=wrap;fontFamily=Courier New;" vertex="1" parent="MMc0v0DIyy0xya0iXp__-35">
<mxGeometry width="281.59999999999997" height="10.299607843137254" as="geometry" /> <mxGeometry width="281.59999999999997" height="10.299607843137254" as="geometry" />
</mxCell> </mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-41" value="Core.Lex" style="rounded=1;arcSize=10;whiteSpace=wrap;html=1;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;fontFamily=Courier New;" parent="MMc0v0DIyy0xya0iXp__-35" vertex="1"> <mxCell id="MMc0v0DIyy0xya0iXp__-41" value="Core.Lex" style="rounded=1;arcSize=10;whiteSpace=wrap;html=1;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;fontFamily=Courier New;" vertex="1" parent="MMc0v0DIyy0xya0iXp__-35">
<mxGeometry x="10.140518134715029" y="16.369019607843132" width="87.1306390328152" height="106.24535947712415" as="geometry" /> <mxGeometry x="10.140518134715029" y="16.369019607843132" width="87.1306390328152" height="106.24535947712415" as="geometry" />
</mxCell> </mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-42" value="Core.Parse" style="rounded=1;arcSize=10;whiteSpace=wrap;html=1;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;fontFamily=Courier New;" parent="MMc0v0DIyy0xya0iXp__-35" vertex="1"> <mxCell id="MMc0v0DIyy0xya0iXp__-42" value="Core.Parse" style="rounded=1;arcSize=10;whiteSpace=wrap;html=1;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;fontFamily=Courier New;" vertex="1" parent="MMc0v0DIyy0xya0iXp__-35">
<mxGeometry x="182.3834196891192" y="16.369019607843146" width="87.1306390328152" height="106.24535947712415" as="geometry" /> <mxGeometry x="182.3834196891192" y="16.369019607843146" width="87.1306390328152" height="106.24535947712415" as="geometry" />
</mxCell> </mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-43" value="&lt;font face=&quot;Courier New&quot;&gt;CoreToken&lt;/font&gt;" style="endArrow=classic;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="MMc0v0DIyy0xya0iXp__-35" source="MMc0v0DIyy0xya0iXp__-41" target="MMc0v0DIyy0xya0iXp__-42" edge="1"> <mxCell id="MMc0v0DIyy0xya0iXp__-43" value="&lt;font face=&quot;Courier New&quot;&gt;CoreToken&lt;/font&gt;" style="endArrow=classic;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="MMc0v0DIyy0xya0iXp__-35" source="MMc0v0DIyy0xya0iXp__-41" target="MMc0v0DIyy0xya0iXp__-42">
<mxGeometry width="50" height="50" relative="1" as="geometry"> <mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="-72.95336787564769" y="39.35921568627452" as="sourcePoint" /> <mxPoint x="-72.95336787564769" y="39.35921568627452" as="sourcePoint" />
<mxPoint x="-12.15889464594128" y="1.0422222222222326" as="targetPoint" /> <mxPoint x="-12.15889464594128" y="1.0422222222222326" as="targetPoint" />
</mxGeometry> </mxGeometry>
</mxCell> </mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-51" value="" style="rounded=1;absoluteArcSize=1;html=1;arcSize=10;fontFamily=Courier New;" parent="l7NxJpuHm0Jx_7flO9iA-2" vertex="1"> <mxCell id="MMc0v0DIyy0xya0iXp__-51" value="" style="rounded=1;absoluteArcSize=1;html=1;arcSize=10;fontFamily=Courier New;" vertex="1" parent="l7NxJpuHm0Jx_7flO9iA-2">
<mxGeometry x="530" y="440" width="281.6" height="131.32" as="geometry" /> <mxGeometry x="530" y="440" width="281.6" height="131.32" as="geometry" />
</mxCell> </mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-52" value="&lt;font face=&quot;Helvetica&quot;&gt;Core Type-checker&lt;br&gt;&lt;/font&gt;" style="html=1;shape=mxgraph.er.anchor;whiteSpace=wrap;fontFamily=Courier New;" parent="MMc0v0DIyy0xya0iXp__-51" vertex="1"> <mxCell id="MMc0v0DIyy0xya0iXp__-52" value="&lt;font face=&quot;Helvetica&quot;&gt;Core Type-checker&lt;br&gt;&lt;/font&gt;" style="html=1;shape=mxgraph.er.anchor;whiteSpace=wrap;fontFamily=Courier New;" vertex="1" parent="MMc0v0DIyy0xya0iXp__-51">
<mxGeometry width="281.59999999999997" height="10.299607843137254" as="geometry" /> <mxGeometry width="281.59999999999997" height="10.299607843137254" as="geometry" />
</mxCell> </mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-46" value="" style="rounded=1;absoluteArcSize=1;html=1;arcSize=10;fontFamily=Courier New;" parent="l7NxJpuHm0Jx_7flO9iA-72" vertex="1"> <mxCell id="MMc0v0DIyy0xya0iXp__-46" value="(currently unimplemented)" style="rounded=1;absoluteArcSize=1;html=1;arcSize=10;fontFamily=Courier New;" vertex="1" parent="l7NxJpuHm0Jx_7flO9iA-72">
<mxGeometry x="40" y="360" width="431.6" height="90.46" as="geometry" /> <mxGeometry x="40" y="360" width="431.6" height="90.46" as="geometry" />
</mxCell> </mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-47" value="&lt;font face=&quot;Verdana&quot;&gt;Type-checker&lt;/font&gt;" style="html=1;shape=mxgraph.er.anchor;whiteSpace=wrap;fontFamily=Courier New;" parent="MMc0v0DIyy0xya0iXp__-46" vertex="1"> <mxCell id="MMc0v0DIyy0xya0iXp__-47" value="&lt;font face=&quot;Verdana&quot;&gt;Type-checker&lt;/font&gt;" style="html=1;shape=mxgraph.er.anchor;whiteSpace=wrap;fontFamily=Courier New;" vertex="1" parent="MMc0v0DIyy0xya0iXp__-46">
<mxGeometry width="431.6" height="18.092000000000002" as="geometry" /> <mxGeometry width="431.6" height="18.092000000000002" as="geometry" />
</mxCell> </mxCell>
<mxCell id="l7NxJpuHm0Jx_7flO9iA-80" value="" style="endArrow=classic;html=1;rounded=0;" parent="l7NxJpuHm0Jx_7flO9iA-72" source="DDBEc0rYRfbomnRGFAIR-1" target="MMc0v0DIyy0xya0iXp__-46" edge="1"> <mxCell id="l7NxJpuHm0Jx_7flO9iA-80" value="" style="endArrow=classic;html=1;rounded=0;" parent="l7NxJpuHm0Jx_7flO9iA-72" source="l7NxJpuHm0Jx_7flO9iA-74" target="MMc0v0DIyy0xya0iXp__-46" edge="1">
<mxGeometry relative="1" as="geometry"> <mxGeometry relative="1" as="geometry">
<mxPoint x="537.6" y="424.2105263157895" as="sourcePoint" /> <mxPoint x="537.6" y="424.2105263157895" as="sourcePoint" />
<mxPoint x="-40" y="490" as="targetPoint" /> <mxPoint x="-40" y="490" as="targetPoint" />
</mxGeometry> </mxGeometry>
</mxCell> </mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-49" value="" style="endArrow=classic;html=1;rounded=0;" parent="l7NxJpuHm0Jx_7flO9iA-72" source="MMc0v0DIyy0xya0iXp__-46" target="l7NxJpuHm0Jx_7flO9iA-69" edge="1"> <mxCell id="l7NxJpuHm0Jx_7flO9iA-81" value="&lt;font face=&quot;Courier New&quot;&gt;RlpProgram&#39; RlpcPs&lt;br&gt;&lt;/font&gt;" style="edgeLabel;resizable=0;html=1;align=center;verticalAlign=middle;" parent="l7NxJpuHm0Jx_7flO9iA-80" connectable="0" vertex="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="6" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-49" value="" style="endArrow=classic;html=1;rounded=0;" edge="1" parent="l7NxJpuHm0Jx_7flO9iA-72" source="MMc0v0DIyy0xya0iXp__-46" target="l7NxJpuHm0Jx_7flO9iA-69">
<mxGeometry relative="1" as="geometry"> <mxGeometry relative="1" as="geometry">
<mxPoint x="352" y="282" as="sourcePoint" /> <mxPoint x="352" y="282" as="sourcePoint" />
<mxPoint x="295" y="370" as="targetPoint" /> <mxPoint x="295" y="370" as="targetPoint" />
</mxGeometry> </mxGeometry>
</mxCell> </mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-50" value="&lt;font face=&quot;Courier New&quot;&gt;Rlp.Program PsName (Cofree RlpExprF&#39; Type&#39;)&lt;br&gt;&lt;/font&gt;" style="edgeLabel;resizable=0;html=1;align=center;verticalAlign=middle;" parent="MMc0v0DIyy0xya0iXp__-49" connectable="0" vertex="1"> <mxCell id="MMc0v0DIyy0xya0iXp__-50" value="&lt;font face=&quot;Courier New&quot;&gt;RlpProgram&#39; RlpcTc&lt;/font&gt;" style="edgeLabel;resizable=0;html=1;align=center;verticalAlign=middle;" connectable="0" vertex="1" parent="MMc0v0DIyy0xya0iXp__-49">
<mxGeometry relative="1" as="geometry"> <mxGeometry relative="1" as="geometry">
<mxPoint x="6" as="offset" /> <mxPoint x="6" as="offset" />
</mxGeometry> </mxGeometry>
</mxCell> </mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-57" value="Core.HindleyMilner" style="rounded=1;arcSize=10;whiteSpace=wrap;html=1;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;fontFamily=Courier New;" parent="l7NxJpuHm0Jx_7flO9iA-72" vertex="1"> <mxCell id="MMc0v0DIyy0xya0iXp__-57" value="Core.HindleyMilner" style="rounded=1;arcSize=10;whiteSpace=wrap;html=1;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;fontFamily=Courier New;" vertex="1" parent="l7NxJpuHm0Jx_7flO9iA-72">
<mxGeometry x="540" y="460" width="260" height="106.24" as="geometry" /> <mxGeometry x="540" y="460" width="260" height="106.24" as="geometry" />
</mxCell> </mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-58" value="" style="endArrow=classic;html=1;rounded=0;" parent="l7NxJpuHm0Jx_7flO9iA-72" source="MMc0v0DIyy0xya0iXp__-42" target="MMc0v0DIyy0xya0iXp__-57" edge="1"> <mxCell id="MMc0v0DIyy0xya0iXp__-58" value="" style="endArrow=classic;html=1;rounded=0;" edge="1" parent="l7NxJpuHm0Jx_7flO9iA-72" source="MMc0v0DIyy0xya0iXp__-42" target="MMc0v0DIyy0xya0iXp__-57">
<mxGeometry width="50" height="50" relative="1" as="geometry"> <mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="530" y="550" as="sourcePoint" /> <mxPoint x="530" y="550" as="sourcePoint" />
<mxPoint x="580" y="500" as="targetPoint" /> <mxPoint x="580" y="500" as="targetPoint" />
</mxGeometry> </mxGeometry>
</mxCell> </mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-59" value="Core.Program PsName" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontFamily=Courier New;" parent="MMc0v0DIyy0xya0iXp__-58" vertex="1" connectable="0"> <mxCell id="MMc0v0DIyy0xya0iXp__-59" value="Program&#39;" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontFamily=Courier New;" vertex="1" connectable="0" parent="MMc0v0DIyy0xya0iXp__-58">
<mxGeometry x="-0.0188" y="-3" relative="1" as="geometry"> <mxGeometry x="-0.0188" y="-3" relative="1" as="geometry">
<mxPoint y="-1" as="offset" /> <mxPoint y="-1" as="offset" />
</mxGeometry> </mxGeometry>
</mxCell> </mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-60" value="" style="endArrow=classic;html=1;rounded=0;" parent="l7NxJpuHm0Jx_7flO9iA-72" source="MMc0v0DIyy0xya0iXp__-57" target="MMc0v0DIyy0xya0iXp__-15" edge="1"> <mxCell id="MMc0v0DIyy0xya0iXp__-60" value="" style="endArrow=classic;html=1;rounded=0;" edge="1" parent="l7NxJpuHm0Jx_7flO9iA-72" source="MMc0v0DIyy0xya0iXp__-57" target="MMc0v0DIyy0xya0iXp__-15">
<mxGeometry width="50" height="50" relative="1" as="geometry"> <mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="741" y="656" as="sourcePoint" /> <mxPoint x="741" y="656" as="sourcePoint" />
<mxPoint x="704" y="576" as="targetPoint" /> <mxPoint x="704" y="576" as="targetPoint" />
</mxGeometry> </mxGeometry>
</mxCell> </mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-61" value="Core.Program Var" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontFamily=Courier New;" parent="MMc0v0DIyy0xya0iXp__-60" vertex="1" connectable="0"> <mxCell id="MMc0v0DIyy0xya0iXp__-61" value="Program&#39;" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontFamily=Courier New;" vertex="1" connectable="0" parent="MMc0v0DIyy0xya0iXp__-60">
<mxGeometry x="-0.0188" y="-3" relative="1" as="geometry"> <mxGeometry x="-0.0188" y="-3" relative="1" as="geometry">
<mxPoint y="-1" as="offset" /> <mxPoint y="-1" as="offset" />
</mxGeometry> </mxGeometry>
</mxCell> </mxCell>
<mxCell id="DDBEc0rYRfbomnRGFAIR-1" value="Rlp.HindleyMilner" style="rounded=1;arcSize=10;whiteSpace=wrap;html=1;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;fontFamily=Courier New;" vertex="1" parent="l7NxJpuHm0Jx_7flO9iA-72">
<mxGeometry x="49.47" y="380" width="410.53" height="60" as="geometry" />
</mxCell>
<mxCell id="DDBEc0rYRfbomnRGFAIR-2" value="" style="endArrow=classic;html=1;rounded=0;" edge="1" parent="l7NxJpuHm0Jx_7flO9iA-72" source="l7NxJpuHm0Jx_7flO9iA-74" target="DDBEc0rYRfbomnRGFAIR-1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="492" y="212" as="sourcePoint" />
<mxPoint x="435" y="300" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="DDBEc0rYRfbomnRGFAIR-3" value="&lt;font face=&quot;Courier New&quot;&gt;Rlp.Program PsName RlpExpr&#39;&lt;br&gt;&lt;/font&gt;" style="edgeLabel;resizable=0;html=1;align=center;verticalAlign=middle;" connectable="0" vertex="1" parent="DDBEc0rYRfbomnRGFAIR-2">
<mxGeometry relative="1" as="geometry">
<mxPoint x="6" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="l7NxJpuHm0Jx_7flO9iA-65" value="" style="endArrow=classic;html=1;rounded=0;fontFamily=Courier New;" parent="1" source="l7NxJpuHm0Jx_7flO9iA-64" target="l7NxJpuHm0Jx_7flO9iA-59" edge="1"> <mxCell id="l7NxJpuHm0Jx_7flO9iA-65" value="" style="endArrow=classic;html=1;rounded=0;fontFamily=Courier New;" parent="1" source="l7NxJpuHm0Jx_7flO9iA-64" target="l7NxJpuHm0Jx_7flO9iA-59" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry"> <mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="290" y="400" as="sourcePoint" /> <mxPoint x="290" y="400" as="sourcePoint" />
<mxPoint x="340" y="350" as="targetPoint" /> <mxPoint x="340" y="350" as="targetPoint" />
</mxGeometry> </mxGeometry>
</mxCell> </mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-26" value="&lt;font face=&quot;Helvetica&quot;&gt;Core source code&lt;br&gt;&lt;/font&gt;" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontFamily=Courier New;" parent="1" vertex="1"> <mxCell id="MMc0v0DIyy0xya0iXp__-26" value="&lt;font face=&quot;Helvetica&quot;&gt;Core source code&lt;br&gt;&lt;/font&gt;" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontFamily=Courier New;" vertex="1" parent="1">
<mxGeometry x="673.7099999999999" y="740" width="120" height="60" as="geometry" /> <mxGeometry x="673.7099999999999" y="740" width="120" height="60" as="geometry" />
</mxCell> </mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-34" value="" style="endArrow=classic;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;" parent="1" source="MMc0v0DIyy0xya0iXp__-26" target="MMc0v0DIyy0xya0iXp__-41" edge="1"> <mxCell id="MMc0v0DIyy0xya0iXp__-29" value="&lt;div&gt;&lt;font face=&quot;Helvetica&quot;&gt;???&lt;/font&gt;&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontFamily=Courier New;" vertex="1" parent="1">
<mxGeometry x="1420" y="730" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-34" value="" style="endArrow=classic;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;" edge="1" parent="1" source="MMc0v0DIyy0xya0iXp__-26" target="MMc0v0DIyy0xya0iXp__-41">
<mxGeometry width="50" height="50" relative="1" as="geometry"> <mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="960" y="370" as="sourcePoint" /> <mxPoint x="960" y="370" as="sourcePoint" />
<mxPoint x="690" y="570" as="targetPoint" /> <mxPoint x="690" y="570" as="targetPoint" />
</mxGeometry> </mxGeometry>
</mxCell> </mxCell>
<mxCell id="MMc0v0DIyy0xya0iXp__-62" value="" style="endArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="MMc0v0DIyy0xya0iXp__-20" target="MMc0v0DIyy0xya0iXp__-29">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1060" y="650" as="sourcePoint" />
<mxPoint x="1110" y="600" as="targetPoint" />
</mxGeometry>
</mxCell>
</root> </root>
</mxGraphModel> </mxGraphModel>
</diagram> </diagram>

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 419 KiB

After

Width:  |  Height:  |  Size: 390 KiB

View File

@@ -13,7 +13,6 @@ module Compiler.JustRun
, justParseRlp , justParseRlp
, justTypeCheckCore , justTypeCheckCore
, justHdbg , justHdbg
, justInferRlp
, makeItPretty, makeItPretty' , makeItPretty, makeItPretty'
) )
where where
@@ -36,7 +35,6 @@ import Data.Pretty
import Rlp.AltParse import Rlp.AltParse
import Rlp.AltSyntax qualified as Rlp import Rlp.AltSyntax qualified as Rlp
import Rlp.HindleyMilner
---------------------------------------------------------------------------------- ----------------------------------------------------------------------------------
justHdbg :: String -> IO GmState justHdbg :: String -> IO GmState
@@ -67,17 +65,11 @@ justTypeCheckCore s = typechk (T.pack s)
& rlpcToEither & rlpcToEither
where typechk = lexCoreR >=> parseCoreProgR >=> checkCoreProgR where typechk = lexCoreR >=> parseCoreProgR >=> checkCoreProgR
justInferRlp :: String makeItPretty :: (Pretty a) => Either e a -> Either e Doc
-> Either [MsgEnvelope RlpcError] makeItPretty = fmap pretty
(Rlp.Program Rlp.PsName Rlp.TypedRlpExpr')
justInferRlp s = infr (T.pack s) & rlpcToEither
where infr = parseRlpProgR >=> typeCheckRlpProgR
makeItPretty :: (Out a) => Either e a -> Either e (Doc ann) makeItPretty' :: (Pretty (WithTerseBinds a)) => Either e a -> Either e Doc
makeItPretty = fmap out makeItPretty' = fmap (pretty . WithTerseBinds)
makeItPretty' :: (Out (WithTerseBinds a)) => Either e a -> Either e (Doc ann)
makeItPretty' = fmap (out . WithTerseBinds)
rlpcToEither :: RLPC a -> Either [MsgEnvelope RlpcError] a rlpcToEither :: RLPC a -> Either [MsgEnvelope RlpcError] a
rlpcToEither r = case evalRLPC def r of rlpcToEither r = case evalRLPC def r of

View File

@@ -26,9 +26,8 @@ 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, liftEither, liftMaybe, hoistRlpcT , liftErrorful, liftMaybe, hoistRlpcT
-- * Misc. Rlpc Monad -related types -- * Misc. Rlpc Monad -related types
, RLPCOptions(RLPCOptions), IsRlpcError(..), RlpcError(..) , RLPCOptions(RLPCOptions), IsRlpcError(..), RlpcError(..)
, MsgEnvelope(..), Severity(..) , MsgEnvelope(..), Severity(..)
@@ -55,7 +54,6 @@ import Data.Default.Class
import Data.Foldable import Data.Foldable
import GHC.Generics (Generic) import GHC.Generics (Generic)
import Data.Maybe import Data.Maybe
import Data.Pretty
import Data.Hashable (Hashable) import Data.Hashable (Hashable)
import Data.HashSet (HashSet) import Data.HashSet (HashSet)
import Data.HashSet qualified as S import Data.HashSet qualified as S
@@ -65,6 +63,7 @@ import Data.Text qualified as T
import Data.Text.IO qualified as T import Data.Text.IO qualified as T
import System.IO import System.IO
import Text.ANSI qualified as Ansi import Text.ANSI qualified as Ansi
import Text.PrettyPrint hiding ((<>))
import Control.Lens import Control.Lens
import Data.Text.Lens (packed, unpacked, IsText) import Data.Text.Lens (packed, unpacked, IsText)
import System.Exit import System.Exit
@@ -112,13 +111,6 @@ 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 . f where
f (Left es) = (Nothing, errorMsg s . liftRlpcError <$> es)
where s = SrcSpan 0 0 0 0
f (Right a) = (Just a, [])
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 ->
@@ -131,7 +123,6 @@ 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
@@ -152,7 +143,6 @@ instance Default RLPCOptions where
, _rlpcEvaluator = EvaluatorGM , _rlpcEvaluator = EvaluatorGM
, _rlpcHeapTrigger = 200 , _rlpcHeapTrigger = 200
, _rlpcInputFiles = [] , _rlpcInputFiles = []
, _rlpcServer = False
, _rlpcLanguage = Nothing , _rlpcLanguage = Nothing
} }
@@ -213,7 +203,7 @@ renderRlpcErrs opts = (if don'tBother then id else filter byTag)
prettyRlpcMsg :: MsgEnvelope RlpcError -> String prettyRlpcMsg :: MsgEnvelope RlpcError -> String
prettyRlpcMsg m@(view msgSeverity -> SevDebug _) = prettyRlpcDebugMsg m prettyRlpcMsg m@(view msgSeverity -> SevDebug _) = prettyRlpcDebugMsg m
prettyRlpcMsg m = show $ docRlpcErr m prettyRlpcMsg m = render $ docRlpcErr m
prettyRlpcDebugMsg :: MsgEnvelope RlpcError -> String prettyRlpcDebugMsg :: MsgEnvelope RlpcError -> String
prettyRlpcDebugMsg msg = prettyRlpcDebugMsg msg =
@@ -223,10 +213,10 @@ prettyRlpcDebugMsg msg =
Text ts = msg ^. msgDiagnostic Text ts = msg ^. msgDiagnostic
SevDebug tag = msg ^. msgSeverity SevDebug tag = msg ^. msgSeverity
docRlpcErr :: MsgEnvelope RlpcError -> Doc ann docRlpcErr :: MsgEnvelope RlpcError -> Doc
docRlpcErr msg = vcat [ header docRlpcErr msg = header
, nest 2 bullets $$ nest 2 bullets
, source ] $$ source
where where
source = vcat $ zipWith (<+>) rule srclines source = vcat $ zipWith (<+>) rule srclines
where where
@@ -241,10 +231,11 @@ docRlpcErr msg = vcat [ header
<> errorColour "error" <> msgColour ":" <> errorColour "error" <> msgColour ":"
bullets = let Text ts = msg ^. msgDiagnostic bullets = let Text ts = msg ^. msgDiagnostic
in vcat $ ("" <>) . hang 2 . ttext . msgColour <$> ts in vcat $ hang "" 2 . ttext . msgColour <$> ts
msgColour = Ansi.white . Ansi.bold msgColour = Ansi.white . Ansi.bold
errorColour = Ansi.red . Ansi.bold errorColour = Ansi.red . Ansi.bold
ttext = text . T.unpack
tshow :: (Show a) => a -> Text tshow :: (Show a) => a -> Text
tshow = T.pack . show tshow = T.pack . show

View File

@@ -24,11 +24,8 @@ import Control.Monad.Errorful
import Data.Text (Text) import Data.Text (Text)
import Data.Text qualified as T import Data.Text qualified as T
import GHC.Exts (IsString(..)) import GHC.Exts (IsString(..))
import GHC.Generics import Control.Lens
import Control.Lens hiding ((.=))
import Compiler.Types import Compiler.Types
import Data.Aeson
---------------------------------------------------------------------------------- ----------------------------------------------------------------------------------
data MsgEnvelope e = MsgEnvelope data MsgEnvelope e = MsgEnvelope
@@ -38,17 +35,8 @@ data MsgEnvelope e = MsgEnvelope
} }
deriving (Functor, Show) deriving (Functor, Show)
instance (ToJSON e) => ToJSON (MsgEnvelope e) where
toJSON msg = object
[ "span" .= _msgSpan msg
, "severity" .= _msgSeverity msg
, "diagnostic" .= _msgDiagnostic msg
]
newtype RlpcError = Text [Text] newtype RlpcError = Text [Text]
deriving (Show, Generic) deriving Show
deriving (ToJSON)
via Generically [Text]
instance IsString RlpcError where instance IsString RlpcError where
fromString = Text . pure . T.pack fromString = Text . pure . T.pack
@@ -62,9 +50,7 @@ instance IsRlpcError RlpcError where
data Severity = SevWarning data Severity = SevWarning
| SevError | SevError
| SevDebug Text -- ^ Tag | SevDebug Text -- ^ Tag
deriving (Show, Generic) deriving Show
deriving (ToJSON)
via Generically Severity
makeLenses ''MsgEnvelope makeLenses ''MsgEnvelope

View File

@@ -27,32 +27,27 @@ import Language.Haskell.TH.Syntax (Lift)
import Control.Comonad import Control.Comonad
import Control.Comonad.Cofree import Control.Comonad.Cofree
import Control.Comonad.Trans.Cofree qualified as Trans.Cofree
import Control.Comonad.Trans.Cofree (CofreeF)
import Data.Functor.Apply import Data.Functor.Apply
import Data.Functor.Bind import Data.Functor.Bind
import Data.Functor.Compose import Data.Functor.Compose
import Data.Functor.Foldable import Data.Functor.Foldable
import Data.Semigroup.Foldable import Data.Semigroup.Foldable
import Data.Fix hiding (cata, ana) import Data.Fix hiding (cata, ana)
import Data.Kind import Data.Kind
import Data.Aeson import Control.Lens hiding ((<<~), (:<))
import Control.Lens hiding ((<<~), (:<), (.=))
import Data.List.NonEmpty (NonEmpty) import Data.List.NonEmpty (NonEmpty)
import Data.Function (on) import Data.Function (on)
import Misc.CofreeF
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- | Token wrapped with a span (line, column, absolute, length) -- | Token wrapped with a span (line, column, absolute, length)
data Located a = Located SrcSpan a data Located a = Located SrcSpan a
deriving (Show, Lift, Functor) deriving (Show, Lift, Functor)
instance ToJSON SrcSpan where pattern (:<$) :: a -> f b -> Trans.Cofree.CofreeF f a b
toJSON (SrcSpan l c a s) = object pattern a :<$ b = a Trans.Cofree.:< b
[ "line" .= l
, "column" .= c
, "abs" .= a
, "length" .= s]
(<~>) :: a -> b -> SrcSpan (<~>) :: a -> b -> SrcSpan
(<~>) = undefined (<~>) = undefined

View File

@@ -41,15 +41,10 @@ runErrorful m = coerce (runErrorfulT m)
class (Applicative m) => MonadErrorful e m | m -> e where class (Applicative m) => MonadErrorful e m | m -> e where
addWound :: e -> m () addWound :: e -> m ()
addFatal :: e -> m a addFatal :: e -> m a
-- | Turn any wounds into fatals
bleedOut :: m a -> m a
instance (Applicative m) => MonadErrorful e (ErrorfulT e m) where instance (Applicative m) => MonadErrorful e (ErrorfulT e m) where
addWound e = ErrorfulT $ pure (Just (), [e]) addWound e = ErrorfulT $ pure (Just (), [e])
addFatal e = ErrorfulT $ pure (Nothing, [e]) addFatal e = ErrorfulT $ pure (Nothing, [e])
bleedOut m = ErrorfulT $ runErrorfulT m <&> \case
(a, []) -> (a, [])
(_, es) -> (Nothing, es)
instance MonadTrans (ErrorfulT e) where instance MonadTrans (ErrorfulT e) where
lift m = ErrorfulT ((\x -> (Just x,[])) <$> m) lift m = ErrorfulT ((\x -> (Just x,[])) <$> m)
@@ -91,7 +86,6 @@ hoistErrorfulT nt (ErrorfulT m) = ErrorfulT (nt m)
instance (Monad m, MonadErrorful e m) => MonadErrorful e (ReaderT r m) where instance (Monad m, MonadErrorful e m) => MonadErrorful e (ReaderT r m) where
addWound = lift . addWound addWound = lift . addWound
addFatal = lift . addFatal addFatal = lift . addFatal
bleedOut = mapReaderT bleedOut
instance (Monad m, MonadState s m) => MonadState s (ErrorfulT e m) where instance (Monad m, MonadState s m) => MonadState s (ErrorfulT e m) where
state = lift . state state = lift . state
@@ -102,10 +96,6 @@ instance (Monoid w, Monad m, MonadWriter w m) => MonadWriter w (ErrorfulT e m) w
((,w) <$> ma, es) ((,w) <$> ma, es)
pass (ErrorfulT m) = undefined pass (ErrorfulT m) = undefined
instance (Monad m, MonadReader r m) => MonadReader r (ErrorfulT e m) where
ask = lift ask
local rr = hoistErrorfulT (local rr)
instance (Monoid w, Monad m, MonadAccum w m) instance (Monoid w, Monad m, MonadAccum w m)
=> MonadAccum w (ErrorfulT e m) where => MonadAccum w (ErrorfulT e m) where
accum = lift . accum accum = lift . accum

View File

@@ -16,9 +16,22 @@ module Core.HindleyMilner
) )
where where
---------------------------------------------------------------------------------- ----------------------------------------------------------------------------------
import Control.Lens hiding (Context', Context)
import Data.Maybe (fromMaybe)
import Data.Text qualified as T
import Data.Pretty (rpretty)
import Data.HashMap.Strict qualified as H
import Data.Foldable (traverse_)
import Data.Functor
import Data.Functor.Identity
import Compiler.RLPC import Compiler.RLPC
import Data.Text qualified as T import Compiler.Types
import Compiler.RlpcError
import Control.Monad (foldM, void, forM)
import Control.Monad.Errorful import Control.Monad.Errorful
import Control.Monad.State
import Control.Monad.Utils (mapAccumLM, generalise)
import Text.Printf
import Core.Syntax import Core.Syntax
---------------------------------------------------------------------------------- ----------------------------------------------------------------------------------
@@ -47,7 +60,21 @@ data TypeError
deriving (Show, Eq) deriving (Show, Eq)
instance IsRlpcError TypeError where instance IsRlpcError TypeError where
liftRlpcError = undefined liftRlpcError = \case
-- todo: use anti-parser instead of show
TyErrCouldNotUnify t u -> Text
[ T.pack $ printf "Could not match type `%s` with `%s`."
(rpretty @String t) (rpretty @String u)
, "Expected: " <> rpretty t
, "Got: " <> rpretty u
]
TyErrUntypedVariable n -> Text
[ "Untyped (likely undefined) variable `" <> n <> "`"
]
TyErrRecursiveType t x -> Text
[ T.pack $ printf "Recursive type: `%s' occurs in `%s'"
(rpretty @String t) (rpretty @String x)
]
-- | Synonym for @Errorful [TypeError]@. This means an @HMError@ action may -- | Synonym for @Errorful [TypeError]@. This means an @HMError@ action may
-- throw any number of fatal or nonfatal errors. Run with @runErrorful@. -- throw any number of fatal or nonfatal errors. Run with @runErrorful@.

View File

@@ -29,8 +29,8 @@ module Core.Syntax
, pattern Con, pattern Var, pattern App, pattern Lam, pattern Let , pattern Con, pattern Var, pattern App, pattern Lam, pattern Let
, pattern Case, pattern Type, pattern Lit , pattern Case, pattern Type, pattern Lit
-- * pretty-printing -- * Pretty-printing
, Out(out), WithTerseBinds(..) , Pretty(pretty), WithTerseBinds(..)
-- * Optics -- * Optics
, HasArrowSyntax(..) , HasArrowSyntax(..)
@@ -59,9 +59,7 @@ 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 Data.Aeson import GHC.Generics (Generic, Generic1, Generically(..))
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
@@ -112,7 +110,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, Generic) deriving (Eq, Show, Lift)
pattern (:^) :: Name -> Type -> Var pattern (:^) :: Name -> Type -> Var
pattern n :^ t = MkVar n t pattern n :^ t = MkVar n t
@@ -263,7 +261,6 @@ type ScDef' = ScDef Name
lambdaLifting :: Iso (ScDef b) (ScDef b') (b, Expr b) (b', Expr b') lambdaLifting :: Iso (ScDef b) (ScDef b') (b, Expr b) (b', Expr b')
lambdaLifting = iso sa bt where lambdaLifting = iso sa bt where
sa (ScDef n [] e) = (n, e) where
sa (ScDef n as e) = (n, e') where sa (ScDef n as e) = (n, e') where
e' = Lam as e e' = Lam as e
@@ -338,11 +335,11 @@ instance MakeTerse Var where
type AsTerse Var = Name type AsTerse Var = Name
asTerse (MkVar n _) = n asTerse (MkVar n _) = n
instance (Hashable b, Out b, Out (AsTerse b), MakeTerse b) instance (Hashable b, Pretty b, Pretty (AsTerse b), MakeTerse b)
=> Out (WithTerseBinds (Program b)) where => Pretty (WithTerseBinds (Program b)) where
out (WithTerseBinds p) pretty (WithTerseBinds p)
= vsep [ (datatags <> "\n") = (datatags <> "\n")
, defs ] $+$ defs
where where
datatags = ifoldrOf (programDataTags . ifolded) cataDataTag mempty p datatags = ifoldrOf (programDataTags . ifolded) cataDataTag mempty p
defs = vlinesOf (programJoinedDefs . to prettyGroup) p defs = vlinesOf (programJoinedDefs . to prettyGroup) p
@@ -358,17 +355,17 @@ instance (Hashable b, Out b, Out (AsTerse b), MakeTerse b)
thatSc = foldMap $ \sc -> thatSc = foldMap $ \sc ->
H.singleton (sc ^. _lhs . _1) (That sc) H.singleton (sc ^. _lhs . _1) (That sc)
prettyGroup :: These (b, Type) (ScDef b) -> Doc ann prettyGroup :: These (b, Type) (ScDef b) -> Doc
prettyGroup = bifoldr vs vs mempty prettyGroup = bifoldr vs vs mempty
. bimap (uncurry prettyTySig') . bimap (uncurry prettyTySig')
(out . WithTerseBinds) (pretty . WithTerseBinds)
where vs a b = a <> ";" <> line <> b where vs = vsepTerm ";"
cataDataTag n (t,a) acc = prettyDataTag n t a <> line <> acc cataDataTag n (t,a) acc = prettyDataTag n t a $+$ acc
instance (Hashable b, Out b) => Out (Program b) where instance (Hashable b, Pretty b) => Pretty (Program b) where
out p = vsep [ datatags <> "\n" pretty p = (datatags <> "\n")
, defs ] $+$ defs
where where
datatags = ifoldrOf (programDataTags . ifolded) cataDataTag mempty p datatags = ifoldrOf (programDataTags . ifolded) cataDataTag mempty p
defs = vlinesOf (programJoinedDefs . to prettyGroup) p defs = vlinesOf (programJoinedDefs . to prettyGroup) p
@@ -384,124 +381,139 @@ instance (Hashable b, Out b) => Out (Program b) where
thatSc = foldMap $ \sc -> thatSc = foldMap $ \sc ->
H.singleton (sc ^. _lhs . _1) (That sc) H.singleton (sc ^. _lhs . _1) (That sc)
prettyGroup :: These (b, Type) (ScDef b) -> Doc ann prettyGroup :: These (b, Type) (ScDef b) -> Doc
prettyGroup = bifoldr vs vs mempty prettyGroup = bifoldr vs vs mempty
. bimap (uncurry prettyTySig) out . bimap (uncurry prettyTySig) pretty
where vs a b = a <> ";" <> line <> b where vs = vsepTerm ";"
cataDataTag n (t,a) acc = prettyDataTag n t a <> line <> acc cataDataTag n (t,a) acc = prettyDataTag n t a $+$ acc
unionThese :: These a b -> These a b -> These a b unionThese :: These a b -> These a b -> These a b
unionThese (This a) (That b) = These a b unionThese (This a) (That b) = These a b
unionThese (That b) (This a) = These a b unionThese (That b) (This a) = These a b
unionThese (These a b) _ = These a b unionThese (These a b) _ = These a b
prettyDataTag :: (Out n, Out t, Out a) prettyDataTag :: (Pretty n, Pretty t, Pretty a)
=> n -> t -> a -> Doc ann => n -> t -> a -> Doc
prettyDataTag n t a = prettyDataTag n t a =
hsep ["{-#", "PackData", ttext n, ttext t, ttext a, "#-}"] hsep ["{-#", "PackData", ttext n, ttext t, ttext a, "#-}"]
prettyTySig :: (Out n, Out t) => n -> t -> Doc ann prettyTySig :: (Pretty n, Pretty t) => n -> t -> Doc
prettyTySig n t = hsep [ttext n, ":", out t] prettyTySig n t = hsep [ttext n, ":", pretty t]
prettyTySig' :: (MakeTerse n, Out (AsTerse n), Out t) => n -> t -> Doc ann prettyTySig' :: (MakeTerse n, Pretty (AsTerse n), Pretty t) => n -> t -> Doc
prettyTySig' n t = hsep [ttext (asTerse n), ":", out t] prettyTySig' n t = hsep [ttext (asTerse n), ":", pretty t]
-- out Type -- Pretty Type
-- TyApp | appPrec | left -- TyApp | appPrec | left
-- (:->) | appPrec-1 | right -- (:->) | appPrec-1 | right
instance Out Type where instance Pretty Type where
outPrec _ (TyVar n) = ttext n prettyPrec _ (TyVar n) = ttext n
outPrec _ TyFun = "(->)" prettyPrec _ TyFun = "(->)"
outPrec _ (TyCon n) = ttext n prettyPrec _ (TyCon n) = ttext n
outPrec p (a :-> b) = maybeParens (p>appPrec-1) $ prettyPrec p (a :-> b) = maybeParens (p>appPrec-1) $
hsep [outPrec appPrec a, "->", outPrec (appPrec-1) b] hsep [prettyPrec appPrec a, "->", prettyPrec (appPrec-1) b]
outPrec p (TyApp f x) = maybeParens (p>appPrec) $ prettyPrec p (TyApp f x) = maybeParens (p>appPrec) $
outPrec appPrec f <+> outPrec appPrec1 x prettyPrec appPrec f <+> prettyPrec appPrec1 x
outPrec p (TyForall a m) = maybeParens (p>appPrec-2) $ prettyPrec p (TyForall a m) = maybeParens (p>appPrec-2) $
"" <+> (outPrec appPrec1 a <> ".") <+> out m "" <+> (prettyPrec appPrec1 a <> ".") <+> pretty m
outPrec _ TyKindType = "Type" prettyPrec _ TyKindType = "Type"
instance (Out b, Out (AsTerse b), MakeTerse b) instance (Pretty b, Pretty (AsTerse b), MakeTerse b)
=> Out (WithTerseBinds (ScDef b)) where => Pretty (WithTerseBinds (ScDef b)) where
out (WithTerseBinds sc) = hsep [name, as, "=", hang 1 e] pretty (WithTerseBinds sc) = hsep [name, as, "=", hang empty 1 e]
where where
name = ttext $ sc ^. _lhs . _1 . to asTerse name = ttext $ sc ^. _lhs . _1 . to asTerse
as = sc & hsepOf (_lhs . _2 . each . to asTerse . to ttext) as = sc & hsepOf (_lhs . _2 . each . to asTerse . to ttext)
e = out $ sc ^. _rhs e = pretty $ sc ^. _rhs
instance (Out b) => Out (ScDef b) where instance (Pretty b) => Pretty (ScDef b) where
out sc = hsep [name, as, "=", hang 1 e] pretty sc = hsep [name, as, "=", hang empty 1 e]
where where
name = ttext $ sc ^. _lhs . _1 name = ttext $ sc ^. _lhs . _1
as = sc & hsepOf (_lhs . _2 . each . to ttext) as = sc & hsepOf (_lhs . _2 . each . to ttext)
e = out $ sc ^. _rhs e = pretty $ sc ^. _rhs
-- out Expr -- Pretty Expr
-- LamF | appPrec1 | right -- LamF | appPrec1 | right
-- AppF | appPrec | left -- AppF | appPrec | left
instance (Out b, Out a) => Out (ExprF b a) where instance (Pretty b, Pretty a) => Pretty (ExprF b a) where
outPrec = outPrec1 prettyPrec = prettyPrec1
instance (Out b) => Out1 (ExprF b) where -- prettyPrec _ (VarF n) = ttext n
liftOutPrec pr _ (VarF n) = ttext n -- prettyPrec _ (ConF t a) = "Pack{" <> (ttext t <+> ttext a) <> "}"
liftOutPrec pr _ (ConF t a) = "Pack{" <> (ttext t <+> ttext a) <> "}" -- prettyPrec p (LamF bs e) = maybeParens (p>0) $
liftOutPrec pr p (LamF bs e) = maybeParens (p>0) $ -- hsep ["λ", hsep (prettyPrec appPrec1 <$> bs), "->", pretty e]
hsep ["λ", hsep (outPrec appPrec1 <$> bs), "->", pr 0 e] -- prettyPrec p (LetF r bs e) = maybeParens (p>0)
liftOutPrec pr p (LetF r bs e) = maybeParens (p>0) -- $ hsep [pretty r, explicitLayout bs]
$ vsep [ hsep [out r, bs'] -- $+$ hsep ["in", pretty e]
, hsep ["in", pr 0 e] ] -- prettyPrec p (AppF f x) = maybeParens (p>appPrec) $
where bs' = liftExplicitLayout (liftOutPrec pr 0) bs -- prettyPrec appPrec f <+> prettyPrec appPrec1 x
liftOutPrec pr p (AppF f x) = maybeParens (p>appPrec) $ -- prettyPrec p (LitF l) = prettyPrec p l
-- prettyPrec p (CaseF e as) = maybeParens (p>0) $
-- "case" <+> pretty e <+> "of"
-- $+$ nest 2 (explicitLayout as)
-- prettyPrec p (TypeF t) = "@" <> prettyPrec appPrec1 t
instance (Pretty b) => Pretty1 (ExprF b) where
liftPrettyPrec pr _ (VarF n) = ttext n
liftPrettyPrec pr _ (ConF t a) = "Pack{" <> (ttext t <+> ttext a) <> "}"
liftPrettyPrec pr p (LamF bs e) = maybeParens (p>0) $
hsep ["λ", hsep (prettyPrec appPrec1 <$> bs), "->", pr 0 e]
liftPrettyPrec pr p (LetF r bs e) = maybeParens (p>0)
$ hsep [pretty r, bs']
$+$ hsep ["in", pr 0 e]
where bs' = liftExplicitLayout (liftPrettyPrec pr 0) bs
liftPrettyPrec pr p (AppF f x) = maybeParens (p>appPrec) $
pr appPrec f <+> pr appPrec1 x pr appPrec f <+> pr appPrec1 x
liftOutPrec pr p (LitF l) = outPrec p l liftPrettyPrec pr p (LitF l) = prettyPrec p l
liftOutPrec pr p (CaseF e as) = maybeParens (p>0) $ liftPrettyPrec pr p (CaseF e as) = maybeParens (p>0) $
vsep [ "case" <+> pr 0 e <+> "of" "case" <+> pr 0 e <+> "of"
, nest 2 as' ] $+$ nest 2 as'
where as' = liftExplicitLayout (liftOutPrec pr 0) as where as' = liftExplicitLayout (liftPrettyPrec pr 0) as
liftOutPrec pr p (TypeF t) = "@" <> outPrec appPrec1 t liftPrettyPrec pr p (TypeF t) = "@" <> prettyPrec appPrec1 t
instance Out Rec where instance Pretty Rec where
out Rec = "letrec" pretty Rec = "letrec"
out NonRec = "let" pretty NonRec = "let"
instance (Out b, Out a) => Out (AlterF b a) where instance (Pretty b, Pretty a) => Pretty (AlterF b a) where
outPrec = outPrec1 prettyPrec = prettyPrec1
instance (Out b) => Out1 (AlterF b) where instance (Pretty b) => Pretty1 (AlterF b) where
liftOutPrec pr _ (AlterF c as e) = liftPrettyPrec pr _ (AlterF c as e) =
hsep [out c, hsep (out <$> as), "->", liftOutPrec pr 0 e] hsep [pretty c, hsep (pretty <$> as), "->", liftPrettyPrec pr 0 e]
instance Out AltCon where instance Pretty AltCon where
out (AltData n) = ttext n pretty (AltData n) = ttext n
out (AltLit l) = out l pretty (AltLit l) = pretty l
out (AltTag t) = "<" <> ttext t <> ">" pretty (AltTag t) = "<" <> ttext t <> ">"
out AltDefault = "_" pretty AltDefault = "_"
instance Out Lit where instance Pretty Lit where
out (IntL n) = ttext n pretty (IntL n) = ttext n
instance (Out b, Out a) => Out (BindingF b a) where instance (Pretty b, Pretty a) => Pretty (BindingF b a) where
outPrec = outPrec1 prettyPrec = prettyPrec1
instance Out b => Out1 (BindingF b) where instance Pretty b => Pretty1 (BindingF b) where
liftOutPrec pr _ (BindingF k v) = hsep [out k, "=", liftOutPrec pr 0 v] liftPrettyPrec pr _ (BindingF k v) = hsep [pretty k, "=", liftPrettyPrec pr 0 v]
liftExplicitLayout :: (a -> Doc ann) -> [a] -> Doc ann liftExplicitLayout :: (a -> Doc) -> [a] -> Doc
liftExplicitLayout pr as = vcat inner <+> "}" where liftExplicitLayout pr as = vcat inner <+> "}" where
inner = zipWith (<+>) delims (pr <$> as) inner = zipWith (<+>) delims (pr <$> as)
delims = "{" : repeat ";" delims = "{" : repeat ";"
explicitLayout :: (Out a) => [a] -> Doc ann explicitLayout :: (Pretty a) => [a] -> Doc
explicitLayout as = vcat inner <+> "}" where explicitLayout as = vcat inner <+> "}" where
inner = zipWith (<+>) delims (out <$> as) inner = zipWith (<+>) delims (pretty <$> as)
delims = "{" : repeat ";" delims = "{" : repeat ";"
instance Out Var where instance Pretty Var where
outPrec p (MkVar n t) = maybeParens (p>0) $ prettyPrec p (MkVar n t) = maybeParens (p>0) $
hsep [out n, ":", out t] hsep [pretty n, ":", pretty t]
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
@@ -708,7 +720,7 @@ class HasArrowStops s t a b | s -> a, t -> b, s b -> t, t a -> s where
instance HasArrowStops Type Type Type Type where instance HasArrowStops Type Type Type Type where
arrowStops k (s :-> t) = (:->) <$> k s <*> arrowStops k t arrowStops k (s :-> t) = (:->) <$> k s <*> arrowStops k t
arrowStops k t = k t arrowStops k t = k t
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
@@ -768,21 +780,3 @@ 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

@@ -2,7 +2,6 @@
{-# LANGUAGE OverloadedLists #-} {-# LANGUAGE OverloadedLists #-}
module Core.SystemF module Core.SystemF
( lintCoreProgR ( lintCoreProgR
, kindOf
) )
where where
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
@@ -22,7 +21,7 @@ import Text.Printf
import Control.Comonad import Control.Comonad
import Control.Comonad.Cofree import Control.Comonad.Cofree
import Data.Fix import Data.Fix
import Data.Functor hiding (unzip) import Data.Functor
import Control.Lens hiding ((:<)) import Control.Lens hiding ((:<))
import Control.Lens.Unsound import Control.Lens.Unsound
@@ -44,7 +43,7 @@ data Gamma = Gamma
makeLenses ''Gamma makeLenses ''Gamma
lintCoreProgR :: (Monad m) => Program Var -> RLPCT m (Program Name) lintCoreProgR :: (Monad m) => Program Var -> RLPCT m (Program Name)
lintCoreProgR = liftEither . (_Left %~ pure) . lint lintCoreProgR = undefined
lintDontCheck :: Program Var -> Program Name lintDontCheck :: Program Var -> Program Name
lintDontCheck = binders %~ view (_MkVar . _1) lintDontCheck = binders %~ view (_MkVar . _1)
@@ -92,14 +91,14 @@ instance IsRlpcError SystemFError where
undefinedVariableErr n undefinedVariableErr n
SystemFErrorKindMismatch k k' -> SystemFErrorKindMismatch k k' ->
Text [ T.pack $ printf "Could not match kind `%s' with `%s'" Text [ T.pack $ printf "Could not match kind `%s' with `%s'"
(out k) (out k') (pretty k) (pretty k')
] ]
SystemFErrorCouldNotMatch t t' -> SystemFErrorCouldNotMatch t t' ->
Text [ T.pack $ printf "Could not match type `%s' with `%s'" Text [ T.pack $ printf "Could not match type `%s' with `%s'"
(out t) (out t') (pretty t) (pretty t')
] ]
justLintCoreExpr = fmap (fmap (outPrec appPrec1)) . lintE demoContext justLintCoreExpr = fmap (fmap (prettyPrec appPrec1)) . lintE demoContext
lintE :: Gamma -> Expr Var -> SysF ET lintE :: Gamma -> Expr Var -> SysF ET
lintE g = \case lintE g = \case
@@ -165,7 +164,7 @@ lintE g = \case
(ts,as') <- unzip <$> checkAlt et `traverse` as (ts,as') <- unzip <$> checkAlt et `traverse` as
case allUnify ts of case allUnify ts of
Just err -> Left err Just err -> Left err
Nothing -> pure $ head ts :< CaseF e' as' Nothing -> pure $ head ts :< CaseF e' as'
where where
checkAlt :: Type -> Alter Var -> SysF (Type, AlterF Var ET) checkAlt :: Type -> Alter Var -> SysF (Type, AlterF Var ET)
checkAlt scrutineeType (AlterF (AltData con) bs e) = do checkAlt scrutineeType (AlterF (AltData con) bs e) = do

View File

@@ -8,8 +8,8 @@ module Core.Utils
---------------------------------------------------------------------------------- ----------------------------------------------------------------------------------
import Data.Functor.Foldable.TH (makeBaseFunctor) import Data.Functor.Foldable.TH (makeBaseFunctor)
import Data.Functor.Foldable import Data.Functor.Foldable
import Data.HashSet (HashSet) import Data.Set (Set)
import Data.HashSet qualified as S import Data.Set qualified as S
import Core.Syntax import Core.Syntax
import Control.Lens import Control.Lens
import GHC.Exts (IsList(..)) import GHC.Exts (IsList(..))
@@ -28,10 +28,29 @@ isAtomic _ = False
---------------------------------------------------------------------------------- ----------------------------------------------------------------------------------
freeVariables :: Expr' -> HashSet Name freeVariables :: Expr b -> Set b
freeVariables = undefined freeVariables = undefined
-- freeVariables = cata \case
-- VarF n -> S.singleton n -- freeVariables :: Expr' -> Set Name
-- CaseF e as -> e <> (foldMap f as) -- freeVariables = cata go
-- where f (AlterF _ bs e) = fold e `S.difference` S.fromList bs -- where
-- go :: ExprF Name (Set Name) -> Set Name
-- go (VarF k) = S.singleton k
-- -- TODO: collect free vars in rhss of bs
-- go (LetF _ bs e) = (e `S.union` esFree) `S.difference` ns
-- where
-- es = bs ^.. each . _rhs :: [Expr']
-- ns = S.fromList $ bs ^.. each . _lhs
-- -- TODO: this feels a little wrong. maybe a different scheme is
-- -- appropriate
-- esFree = foldMap id $ freeVariables <$> es
-- go (CaseF e as) = e `S.union` asFree
-- where
-- -- asFree = foldMap id $ freeVariables <$> (fmap altToLam as)
-- asFree = foldMap (freeVariables . altToLam) as
-- -- we map alts to lambdas to avoid writing a 'freeVariablesAlt'
-- altToLam (Alter _ ns e) = Lam ns e
-- go (LamF bs e) = e `S.difference` (S.fromList bs)
-- go e = foldMap id e

View File

@@ -11,8 +11,8 @@ module Core2Core
---------------------------------------------------------------------------------- ----------------------------------------------------------------------------------
import Data.Functor.Foldable import Data.Functor.Foldable
import Data.Maybe (fromJust) import Data.Maybe (fromJust)
import Data.HashSet (HashSet) import Data.Set (Set)
import Data.HashSet qualified as S import Data.Set qualified as S
import Data.List import Data.List
import Data.Foldable import Data.Foldable
import Control.Monad.Writer import Control.Monad.Writer
@@ -22,8 +22,6 @@ import Data.Text qualified as T
import Data.HashMap.Strict (HashMap) import Data.HashMap.Strict (HashMap)
import Numeric (showHex) import Numeric (showHex)
import Misc.MonadicRecursionSchemes
import Data.Pretty import Data.Pretty
import Compiler.RLPC import Compiler.RLPC
import Control.Lens import Control.Lens
@@ -39,7 +37,7 @@ core2core p = undefined
gmPrepR :: (Monad m) => Program' -> RLPCT m Program' gmPrepR :: (Monad m) => Program' -> RLPCT m Program'
gmPrepR p = do gmPrepR p = do
let p' = gmPrep p let p' = gmPrep p
addDebugMsg "dump-gm-preprocessed" $ show . out $ p' addDebugMsg "dump-gm-preprocessed" $ render . pretty $ p'
pure p' pure p'
-- | G-machine-specific preprocessing. -- | G-machine-specific preprocessing.
@@ -48,14 +46,10 @@ gmPrep :: Program' -> Program'
gmPrep p = p & appFloater (floatNonStrictCases globals) gmPrep p = p & appFloater (floatNonStrictCases globals)
& tagData & tagData
& defineData & defineData
& etaReduce
where where
globals = p ^.. programScDefs . each . _lhs . _1 globals = p ^.. programScDefs . each . _lhs . _1
& S.fromList & S.fromList
programGlobals :: Program b -> HashSet b
programGlobals = undefined
-- | Define concrete supercombinators for all datatags defined via pragmas (or -- | Define concrete supercombinators for all datatags defined via pragmas (or
-- desugaring) -- desugaring)
@@ -98,7 +92,7 @@ runFloater = flip evalStateT ns >>> runWriter
-- TODO: formally define a "strict context" and reference that here -- TODO: formally define a "strict context" and reference that here
-- the returned ScDefs are guaranteed to be free of non-strict cases. -- the returned ScDefs are guaranteed to be free of non-strict cases.
floatNonStrictCases :: HashSet Name -> Expr' -> Floater Expr' floatNonStrictCases :: Set Name -> Expr' -> Floater Expr'
floatNonStrictCases g = goE floatNonStrictCases g = goE
where where
goE :: Expr' -> Floater Expr' goE :: Expr' -> Floater Expr'
@@ -110,20 +104,24 @@ floatNonStrictCases g = goE
goE e = goC e goE e = goC e
goC :: Expr' -> Floater Expr' goC :: Expr' -> Floater Expr'
goC = cataM \case -- the only truly non-trivial case: when a case expr is found in a
-- the only truly non-trivial case: when a case expr is found in a -- non-strict context, we float it into a supercombinator, give it a
-- non-strict context, we float it into a supercombinator, give it a -- name consumed from the state, record the newly created sc within the
-- name consumed from the state, record the newly created sc within the -- Writer, and finally return an expression appropriately calling the sc
-- Writer, and finally return an expression appropriately calling the sc goC p@(Case e as) = do
CaseF e as -> do n <- name
n <- name let (e',sc) = floatCase g n p
let (e',sc) = floatCase g n (Case e as) altBodies = (\(Alter _ _ b) -> b) <$> as
altBodies = (\(Alter _ _ b) -> b) <$> as tell [sc]
tell [sc] goE e
goE e traverse_ goE altBodies
traverse_ goE altBodies pure e'
pure e' goC (App f x) = App <$> goC f <*> goC x
t -> pure $ embed t goC (Let r bs e) = Let r <$> bs' <*> goE e
where bs' = travBs goC bs
goC (Lit l) = pure (Lit l)
goC (Var k) = pure (Var k)
goC (Con t as) = pure (Con t as)
name = state (fromJust . Data.List.uncons) name = state (fromJust . Data.List.uncons)
@@ -134,15 +132,10 @@ floatNonStrictCases g = goE
-- ^ ??? what the fuck? -- ^ ??? what the fuck?
-- ^ 24/02/22: what is this shit lol? -- ^ 24/02/22: what is this shit lol?
etaReduce :: Program' -> Program'
etaReduce = programScDefs . each %~ \case
ScDef n as (Lam bs e) -> ScDef n (as ++ bs) e
ScDef n as e -> ScDef n as e
-- when provided with a case expr, floatCase will float the case into a -- when provided with a case expr, floatCase will float the case into a
-- supercombinator of its free variables. the sc is returned along with an -- supercombinator of its free variables. the sc is returned along with an
-- expression that calls the sc with the necessary arguments -- expression that calls the sc with the necessary arguments
floatCase :: HashSet Name -> Name -> Expr' -> (Expr', ScDef') floatCase :: Set Name -> Name -> Expr' -> (Expr', ScDef')
floatCase g n c@(Case e as) = (e', sc) floatCase g n c@(Case e as) = (e', sc)
where where
sc = ScDef n caseFrees c sc = ScDef n caseFrees c

View File

@@ -1,27 +1,27 @@
{-# LANGUAGE PartialTypeSignatures #-}
{-# LANGUAGE QuantifiedConstraints, UndecidableInstances #-} {-# LANGUAGE QuantifiedConstraints, UndecidableInstances #-}
module Data.Pretty module Data.Pretty
( Out(..), Out1(..) ( Pretty(..), Pretty1(..)
, outPrec1 , prettyPrec1
, rout , rpretty
, ttext , ttext
, Showing(..) , Showing(..)
-- * Out-printing lens combinators -- * Pretty-printing lens combinators
, hsepOf, vsepOf, vcatOf, vlinesOf , hsepOf, vsepOf, vcatOf, vlinesOf, vsepTerm
, module Prettyprinter , vsep
, module Text.PrettyPrint
, maybeParens , maybeParens
, appPrec , appPrec
, appPrec1 , appPrec1
) )
where where
---------------------------------------------------------------------------------- ----------------------------------------------------------------------------------
import Prettyprinter import Text.PrettyPrint hiding ((<>))
import Text.PrettyPrint.HughesPJ hiding ((<>))
import Text.Printf import Text.Printf
import Data.String (IsString(..)) import Data.String (IsString(..))
import Data.Text.Lens hiding ((:<)) import Data.Text.Lens hiding ((:<))
import Data.Monoid hiding (Sum) import Data.Monoid hiding (Sum)
import Data.Bool import Control.Lens
import Control.Lens hiding ((:<))
-- instances -- instances
import Control.Comonad.Cofree import Control.Comonad.Cofree
@@ -30,84 +30,83 @@ import Data.Functor.Sum
import Data.Fix (Fix(..)) import Data.Fix (Fix(..))
---------------------------------------------------------------------------------- ----------------------------------------------------------------------------------
class Out a where class Pretty a where
out :: a -> Doc ann pretty :: a -> Doc
outPrec :: Int -> a -> Doc ann prettyPrec :: Int -> a -> Doc
{-# MINIMAL out | outPrec #-} {-# MINIMAL pretty | prettyPrec #-}
out = outPrec 0 pretty = prettyPrec 0
outPrec = const out prettyPrec = const pretty
rout :: (IsString s, Out a) => a -> s rpretty :: (IsString s, Pretty a) => a -> s
rout = fromString . show . out rpretty = fromString . render . pretty
-- instance Out (Doc ann) where instance Pretty String where
-- out = id pretty = Text.PrettyPrint.text
instance Out String where instance Pretty T.Text where
out = pretty pretty = Text.PrettyPrint.text . view unpacked
instance Out T.Text where
out = pretty
newtype Showing a = Showing a newtype Showing a = Showing a
instance (Show a) => Out (Showing a) where instance (Show a) => Pretty (Showing a) where
outPrec p (Showing a) = fromString $ showsPrec p a "" prettyPrec p (Showing a) = fromString $ showsPrec p a ""
deriving via Showing Int instance Out Int deriving via Showing Int instance Pretty Int
class (forall a. Out a => Out (f a)) => Out1 f where class (forall a. Pretty a => Pretty (f a)) => Pretty1 f where
liftOutPrec :: (Int -> a -> Doc ann) -> Int -> f a -> Doc ann liftPrettyPrec :: (Int -> a -> Doc) -> Int -> f a -> Doc
outPrec1 :: (Out1 f, Out a) => Int -> f a -> Doc ann prettyPrec1 :: (Pretty1 f, Pretty a) => Int -> f a -> Doc
outPrec1 = liftOutPrec outPrec prettyPrec1 = liftPrettyPrec prettyPrec
instance (Out1 f, Out1 g, Out a) => Out (Sum f g a) where instance (Pretty1 f, Pretty1 g, Pretty a) => Pretty (Sum f g a) where
outPrec p (InL fa) = outPrec1 p fa prettyPrec p (InL fa) = prettyPrec1 p fa
outPrec p (InR ga) = outPrec1 p ga prettyPrec p (InR ga) = prettyPrec1 p ga
instance (Out1 f, Out1 g) => Out1 (Sum f g) where instance (Pretty1 f, Pretty1 g) => Pretty1 (Sum f g) where
liftOutPrec pr p (InL fa) = liftOutPrec pr p fa liftPrettyPrec pr p (InL fa) = liftPrettyPrec pr p fa
liftOutPrec pr p (InR ga) = liftOutPrec pr p ga liftPrettyPrec pr p (InR ga) = liftPrettyPrec pr p ga
instance (Out (f (Fix f))) => Out (Fix f) where instance (Pretty (f (Fix f))) => Pretty (Fix f) where
outPrec d (Fix f) = outPrec d f prettyPrec d (Fix f) = prettyPrec d f
instance (Out (f (Cofree f a)), Out a) => Out (Cofree f a) where -- instance (Pretty1 f) => Pretty (Fix f) where
outPrec d (a :< f) = maybeParens (d>0) $ -- prettyPrec d (Fix f) = prettyPrec1 d f
hsep [outPrec 0 f, ":", outPrec 0 a]
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
ttext :: Out t => t -> Doc ann ttext :: Pretty t => t -> Doc
ttext = out ttext = pretty
hsepOf :: Getting (Endo (Doc ann)) s (Doc ann) -> s -> Doc ann hsepOf :: Getting (Endo Doc) s Doc -> s -> Doc
hsepOf l = foldrOf l (<+>) mempty hsepOf l = foldrOf l (<+>) mempty
vsepOf :: _ -> s -> Doc ann vsepOf :: Getting (Endo Doc) s Doc -> s -> Doc
vsepOf l = vsep . toListOf l vsepOf l = foldrOf l ($+$) mempty
vcatOf :: _ -> s -> Doc ann vcatOf :: Getting (Endo Doc) s Doc -> s -> Doc
vcatOf l = vcat . toListOf l vcatOf l = foldrOf l ($$) mempty
vlinesOf :: Getting (Endo (Doc ann)) s (Doc ann) -> s -> Doc ann vlinesOf :: Getting (Endo Doc) s Doc -> s -> Doc
vlinesOf l = foldrOf l (\a b -> a <> line <> b) mempty vlinesOf l = foldrOf l (\a b -> a $+$ "" $+$ b) mempty
-- hack(?) to separate chunks with a blankline -- hack(?) to separate chunks with a blankline
-------------------------------------------------------------------------------- vsepTerm :: Doc -> Doc -> Doc -> Doc
vsepTerm term a b = (a <> term) $+$ b
maybeParens :: Bool -> Doc ann -> Doc ann vsep :: [Doc] -> Doc
maybeParens = bool id parens vsep = foldr ($+$) mempty
--------------------------------------------------------------------------------
appPrec, appPrec1 :: Int appPrec, appPrec1 :: Int
appPrec = 10 appPrec = 10
appPrec1 = 11 appPrec1 = 11
instance PrintfArg (Doc ann) where instance PrintfArg Doc where
formatArg d fmt formatArg d fmt
| fmtChar (vFmt 'D' fmt) == 'D' = formatString (show d) fmt' | fmtChar (vFmt 'D' fmt) == 'D' = formatString (render d) fmt'
| otherwise = errorBadFormat $ fmtChar fmt | otherwise = errorBadFormat $ fmtChar fmt
where where
fmt' = fmt { fmtChar = 's', fmtPrecision = Nothing } fmt' = fmt { fmtChar = 's', fmtPrecision = Nothing }

View File

@@ -29,9 +29,9 @@ import Data.Tuple (swap)
import Control.Lens import Control.Lens
import Data.Text.Lens (IsText, packed, unpacked) import Data.Text.Lens (IsText, packed, unpacked)
import Text.Printf import Text.Printf
import Text.PrettyPrint hiding ((<>))
import Text.PrettyPrint.HughesPJ (maybeParens)
import Data.Foldable (traverse_) import Data.Foldable (traverse_)
import Prettyprinter
import Data.Pretty
import System.IO (Handle, hPutStrLn) import System.IO (Handle, hPutStrLn)
-- TODO: an actual output system -- TODO: an actual output system
-- TODO: an actual output system -- TODO: an actual output system
@@ -165,7 +165,7 @@ hdbgProg p hio = do
renderOut . showStats $ sts renderOut . showStats $ sts
pure final pure final
where where
renderOut r = hPutStrLn hio $ show r ++ "\n" renderOut r = hPutStrLn hio $ render r ++ "\n"
states = eval $ compile p states = eval $ compile p
final = last states final = last states
@@ -182,7 +182,7 @@ evalProgR p = do
renderOut . showStats $ sts renderOut . showStats $ sts
pure (res, sts) pure (res, sts)
where where
renderOut r = addDebugMsg "dump-eval" $ show r ++ "\n" renderOut r = addDebugMsg "dump-eval" $ render r ++ "\n"
states = eval . compile $ p states = eval . compile $ p
final = last states final = last states
@@ -823,13 +823,13 @@ showCon t n = printf "Pack{%d %d}" t n ^. packed
pprTabstop :: Int pprTabstop :: Int
pprTabstop = 4 pprTabstop = 4
qquotes :: Doc ann -> Doc ann qquotes :: Doc -> Doc
qquotes d = "`" <> d <> "'" qquotes d = "`" <> d <> "'"
showStats :: Stats -> Doc ann showStats :: Stats -> Doc
showStats sts = "==== Stats ============" <> line <> stats showStats sts = "==== Stats ============" $$ stats
where where
stats = textt @String $ printf stats = text $ printf
"Reductions : %5d\n\ "Reductions : %5d\n\
\Prim Reductions : %5d\n\ \Prim Reductions : %5d\n\
\Allocations : %5d\n\ \Allocations : %5d\n\
@@ -839,10 +839,10 @@ showStats sts = "==== Stats ============" <> line <> stats
(sts ^. stsAllocations) (sts ^. stsAllocations)
(sts ^. stsGCCycles) (sts ^. stsGCCycles)
showState :: GmState -> Doc ann showState :: GmState -> Doc
showState st = vcat showState st = vcat
[ "==== GmState " <> int stnum <> " " [ "==== GmState " <> int stnum <> " "
<> textt (replicate (28 - 13 - 1 - digitalWidth stnum) '=') <> text (replicate (28 - 13 - 1 - digitalWidth stnum) '=')
, "-- Next instructions -------" , "-- Next instructions -------"
, info $ showCodeShort c , info $ showCodeShort c
, "-- Stack -------------------" , "-- Stack -------------------"
@@ -859,23 +859,23 @@ showState st = vcat
-- indent data -- indent data
info = nest pprTabstop info = nest pprTabstop
showCodeShort :: Code -> Doc ann showCodeShort :: Code -> Doc
showCodeShort c = braces c' showCodeShort c = braces c'
where where
c' | length c > 3 = list (showInstr <$> take 3 c) <> "; ..." c' | length c > 3 = list (showInstr <$> take 3 c) <> "; ..."
| otherwise = list (showInstr <$> c) | otherwise = list (showInstr <$> c)
list = hcat . punctuate "; " list = hcat . punctuate "; "
showStackShort :: Stack -> Doc ann showStackShort :: Stack -> Doc
showStackShort s = brackets s' showStackShort s = brackets s'
where where
-- no access to heap, otherwise we'd use showNodeAt -- no access to heap, otherwise we'd use showNodeAt
s' | length s > 3 = list (showEntry <$> take 3 s) <> ", ..." s' | length s > 3 = list (showEntry <$> take 3 s) <> ", ..."
| otherwise = list (showEntry <$> s) | otherwise = list (showEntry <$> s)
list = hcat . punctuate ", " list = hcat . punctuate ", "
showEntry = textt . show showEntry = text . show
showStack :: GmState -> Doc ann showStack :: GmState -> Doc
showStack st = vcat $ uncurry showEntry <$> si showStack st = vcat $ uncurry showEntry <$> si
where where
h = st ^. gmHeap h = st ^. gmHeap
@@ -887,9 +887,10 @@ showStack st = vcat $ uncurry showEntry <$> si
w = maxWidth (addresses h) w = maxWidth (addresses h)
showIndex n = padInt w n <> ": " showIndex n = padInt w n <> ": "
showEntry :: Int -> Addr -> Doc
showEntry n a = showIndex n <> showNodeAt st a showEntry n a = showIndex n <> showNodeAt st a
showDump :: GmState -> Doc ann showDump :: GmState -> Doc
showDump st = vcat $ uncurry showEntry <$> di showDump st = vcat $ uncurry showEntry <$> di
where where
d = st ^. gmDump d = st ^. gmDump
@@ -898,13 +899,14 @@ showDump st = vcat $ uncurry showEntry <$> di
showIndex n = padInt w n <> ": " showIndex n = padInt w n <> ": "
w = maxWidth (fst <$> di) w = maxWidth (fst <$> di)
showEntry :: Int -> (Code, Stack) -> Doc
showEntry n (c,s) = showIndex n <> nest pprTabstop entry showEntry n (c,s) = showIndex n <> nest pprTabstop entry
where where
entry = vsep [ "Stack : " <> showCodeShort c entry = ("Stack : " <> showCodeShort c)
, "Code : " <> showStackShort s ] $$ ("Code : " <> showStackShort s)
padInt :: Int -> Int -> Doc ann padInt :: Int -> Int -> Doc
padInt m n = textt (replicate (m - digitalWidth n) ' ') <> int n padInt m n = text (replicate (m - digitalWidth n) ' ') <> int n
maxWidth :: [Int] -> Int maxWidth :: [Int] -> Int
maxWidth ns = digitalWidth $ maximum ns maxWidth ns = digitalWidth $ maximum ns
@@ -912,7 +914,7 @@ maxWidth ns = digitalWidth $ maximum ns
digitalWidth :: Int -> Int digitalWidth :: Int -> Int
digitalWidth = length . show digitalWidth = length . show
showHeap :: GmState -> Doc ann showHeap :: GmState -> Doc
showHeap st = vcat $ showEntry <$> addrs showHeap st = vcat $ showEntry <$> addrs
where where
showAddr n = padInt w n <> ": " showAddr n = padInt w n <> ": "
@@ -921,12 +923,13 @@ showHeap st = vcat $ showEntry <$> addrs
h = st ^. gmHeap h = st ^. gmHeap
addrs = addresses h addrs = addresses h
showEntry :: Addr -> Doc
showEntry a = showAddr a <> showNodeAt st a showEntry a = showAddr a <> showNodeAt st a
showNodeAt :: GmState -> Addr -> Doc ann showNodeAt :: GmState -> Addr -> Doc
showNodeAt = showNodeAtP 0 showNodeAt = showNodeAtP 0
showNodeAtP :: Int -> GmState -> Addr -> Doc ann showNodeAtP :: Int -> GmState -> Addr -> Doc
showNodeAtP p st a = case hLookup a h of showNodeAtP p st a = case hLookup a h of
Just (NNum n) -> int n <> "#" Just (NNum n) -> int n <> "#"
Just (NGlobal _ _) -> textt name Just (NGlobal _ _) -> textt name
@@ -950,9 +953,9 @@ showNodeAtP p st a = case hLookup a h of
h = st ^. gmHeap h = st ^. gmHeap
pprec = maybeParens (p > 0) pprec = maybeParens (p > 0)
showSc :: GmState -> (Name, Addr) -> Doc ann showSc :: GmState -> (Name, Addr) -> Doc
showSc st (k,a) = vcat [ "Supercomb " <> qquotes (textt k) <> colon showSc st (k,a) = "Supercomb " <> qquotes (textt k) <> colon
, code ] $$ code
where where
code = case hLookup a (st ^. gmHeap) of code = case hLookup a (st ^. gmHeap) of
Just (NGlobal _ c) -> showCode c Just (NGlobal _ c) -> showCode c
@@ -963,21 +966,19 @@ errTxtInvalidObject, errTxtInvalidAddress :: (IsString a) => a
errTxtInvalidObject = "<invalid object>" errTxtInvalidObject = "<invalid object>"
errTxtInvalidAddress = "<invalid address>" errTxtInvalidAddress = "<invalid address>"
showCode :: Code -> Doc ann showCode :: Code -> Doc
showCode c = "Code" <+> braces instrs showCode c = "Code" <+> braces instrs
where instrs = vcat $ showInstr <$> c where instrs = vcat $ showInstr <$> c
showInstr :: Instr -> Doc ann showInstr :: Instr -> Doc
showInstr (CaseJump alts) = vcat [ "CaseJump", nest pprTabstop alternatives ] showInstr (CaseJump alts) = "CaseJump" $$ nest pprTabstop alternatives
where where
showAlt (t,c) = "<" <> int t <> ">" <> showCodeShort c showAlt (t,c) = "<" <> int t <> ">" <> showCodeShort c
alternatives = foldr (\a acc -> showAlt a <> line <> acc) mempty alts alternatives = foldr (\a acc -> showAlt a $$ acc) mempty alts
showInstr i = textt $ show i showInstr i = text $ show i
int = pretty textt :: (IsText a) => a -> Doc
textt t = t ^. unpacked & text
textt :: (Pretty a) => a -> Doc ann
textt = pretty
---------------------------------------------------------------------------------- ----------------------------------------------------------------------------------

View File

@@ -1,13 +0,0 @@
{-# LANGUAGE PatternSynonyms #-}
module Misc.CofreeF
( pattern (:<$)
)
where
--------------------------------------------------------------------------------
import Control.Comonad.Trans.Cofree qualified as Trans.Cofree
import Control.Comonad.Trans.Cofree (CofreeF)
--------------------------------------------------------------------------------
pattern (:<$) :: a -> f b -> Trans.Cofree.CofreeF f a b
pattern a :<$ b = a Trans.Cofree.:< b

View File

@@ -1,14 +0,0 @@
module Misc.MonadicRecursionSchemes
where
--------------------------------------------------------------------------------
import Control.Monad
import Data.Functor.Foldable
--------------------------------------------------------------------------------
-- | catamorphism
cataM :: (Monad m, Traversable (Base t), Recursive t)
=> (Base t a -> m a) -- ^ algebra
-> t -> m a
cataM phi = h
where h = phi <=< mapM h . project

View File

@@ -60,7 +60,6 @@ import Core.Syntax qualified as Core
let { Located _ TokenLet } let { Located _ TokenLet }
letrec { Located _ TokenLetrec } letrec { Located _ TokenLetrec }
in { Located _ TokenIn } in { Located _ TokenIn }
forall { Located _ TokenForall }
%nonassoc '=' %nonassoc '='
%right '->' %right '->'
@@ -146,8 +145,6 @@ CaseAlt :: { Alter PsName (RlpExpr PsName) }
LetE :: { RlpExpr PsName } LetE :: { RlpExpr PsName }
: let layout1(Binding) in Expr : let layout1(Binding) in Expr
{ Finr $ LetEF Core.NonRec $2 $4 } { Finr $ LetEF Core.NonRec $2 $4 }
| letrec layout1(Binding) in Expr
{ Finr $ LetEF Core.Rec $2 $4 }
Binding :: { Binding PsName (RlpExpr PsName) } Binding :: { Binding PsName (RlpExpr PsName) }
: Pat '=' Expr { VarB $1 $3 } : Pat '=' Expr { VarB $1 $3 }
@@ -158,7 +155,6 @@ Expr1 :: { RlpExpr PsName }
. singular _TokenLitInt . singular _TokenLitInt
. to (Finl . Core.LitF . Core.IntL) } . to (Finl . Core.LitF . Core.IntL) }
| '(' Expr ')' { $2 } | '(' Expr ')' { $2 }
| ConE { $1 }
AppE :: { RlpExpr PsName } AppE :: { RlpExpr PsName }
: AppE Expr1 { Finl $ Core.AppF $1 $2 } : AppE Expr1 { Finl $ Core.AppF $1 $2 }
@@ -167,9 +163,6 @@ AppE :: { RlpExpr PsName }
VarE :: { RlpExpr PsName } VarE :: { RlpExpr PsName }
: Var { Finl $ Core.VarF $1 } : Var { Finl $ Core.VarF $1 }
ConE :: { RlpExpr PsName }
: Con { Finl $ Core.VarF $1 }
Pat1s :: { [Pat PsName] } Pat1s :: { [Pat PsName] }
: list0(Pat1) { $1 } : list0(Pat1) { $1 }
@@ -202,9 +195,8 @@ list0(p) : {- epsilon -} { [] }
| list0(p) p { $1 `snoc` $2 } | list0(p) p { $1 `snoc` $2 }
-- layout0(p : β) :: [β] -- layout0(p : β) :: [β]
layout0(p) : '{' '}' { [] } layout0(p) : '{' layout_list0(';',p) '}' { $2 }
| VL VR { [] } | VL layout_list0(VS,p) VR { $2 }
| layout1(p) { $1 }
-- layout_list0(sep : α, p : β) :: [β] -- layout_list0(sep : α, p : β) :: [β]
layout_list0(sep,p) : p { [$1] } layout_list0(sep,p) : p { [$1] }
@@ -213,7 +205,6 @@ layout_list0(sep,p) : p { [$1] }
-- layout1(p : β) :: [β] -- layout1(p : β) :: [β]
layout1(p) : '{' layout_list1(';',p) '}' { $2 } layout1(p) : '{' layout_list1(';',p) '}' { $2 }
| VL layout_list1(VS,p) VS VR { $2 }
| VL layout_list1(VS,p) VR { $2 } | VL layout_list1(VS,p) VR { $2 }
-- layout_list1(sep : α, p : β) :: [β] -- layout_list1(sep : α, p : β) :: [β]
@@ -234,9 +225,7 @@ parseRlpExprR s = liftErrorful $ errorful (ma,es)
where where
(_,es,ma) = runP' parseRlpExpr s (_,es,ma) = runP' parseRlpExpr s
parseError :: (Located RlpToken, [String]) -> P a parseError = error "explode"
parseError (Located ss t,ts) = addFatalHere (ss ^. srcSpanLen) $
RlpParErrUnexpectedToken t ts
extractName = view $ to extract . singular _TokenVarName extractName = view $ to extract . singular _TokenVarName

View File

@@ -2,15 +2,11 @@
module Rlp.AltSyntax module Rlp.AltSyntax
( (
-- * AST -- * AST
Program(..), Decl(..), ExprF(..), Pat(..), pattern ConP' Program(..), Decl(..), ExprF(..), Pat(..)
, RlpExprF, RlpExpr, Binding(..), Alter(..) , RlpExprF, RlpExpr, Binding(..), Alter(..)
, RlpExpr', RlpExprF', AnnotatedRlpExpr', Type' , DataCon(..), Type(..)
, DataCon(..), Type(..), Kind , pattern IntT
, pattern IntT, pattern TypeT
, Core.Rec(..)
, TypedRlpExpr'
, AnnotatedRlpExpr, TypedRlpExpr
, TypeF(..) , TypeF(..)
, Core.Name, PsName , Core.Name, PsName
@@ -19,37 +15,26 @@ module Rlp.AltSyntax
-- * Optics -- * Optics
, programDecls , programDecls
, _VarP, _FunB, _VarB , _VarP, _FunB, _VarB
, _TySigD, _FunD, _DataD
, _LetEF
, Core.applicants1, Core.arrowStops
-- * Functor-related tools -- * Functor-related tools
, Fix(..), Cofree(..), Sum(..), pattern Finl, pattern Finr , Fix(..), Cofree(..), Sum(..), pattern Finl, pattern Finr
-- * Misc
, serialiseCofree
, fixCofree
) )
where where
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
import Data.Functor.Sum import Data.Functor.Sum
import Control.Comonad.Cofree import Control.Comonad.Cofree
import Data.Fix hiding (cata) import Data.Fix
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 hiding ((.=), (:<)) import Control.Lens
import Data.Functor.Extend
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
@@ -57,60 +42,34 @@ import Compiler.Types
import Core.Syntax qualified as Core import Core.Syntax qualified as Core
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
type RlpExpr' = RlpExpr PsName
type RlpExprF' = RlpExprF PsName
type AnnotatedRlpExpr' = Cofree (RlpExprF PsName)
type TypedRlpExpr' = TypedRlpExpr PsName
type Type' = Type PsName
type AnnotatedRlpExpr b = Cofree (RlpExprF b)
type TypedRlpExpr b = Cofree (RlpExprF b) (Type b)
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, Functor, Foldable, Traversable) deriving Show
instance Extend (Decl b) where programDecls :: Lens' (Program b a) [Decl b a]
extended c w@(FunD n as a) = FunD n as (c w) programDecls = lens (\ (Program ds) -> ds) (const Program)
extended _ (DataD n as cs) = DataD n as cs
extended _ (TySigD n t) = TySigD n t
programDecls :: Iso (Program b a) (Program b' a') [Decl b a] [Decl b' a']
programDecls = iso sa bt where
sa (Program ds) = ds
bt = Program
data Decl b a = FunD b [Pat b] a data Decl b a = FunD b [Pat b] a
| DataD Core.Name [Core.Name] [DataCon b] | DataD b [b] [DataCon b]
| TySigD Core.Name (Type b) | TySigD b (Type b)
deriving (Show, Functor, Foldable, Traversable) deriving Show
data DataCon b = DataCon Core.Name [Type b] data DataCon b = DataCon b [Type b]
deriving (Show, Generic) deriving (Show, Generic)
data Type b = VarT Core.Name data Type b = VarT b
| ConT Core.Name | ConT b
| AppT (Type b) (Type b) | AppT (Type b) (Type b)
| FunT | FunT
| ForallT b (Type b) | ForallT b (Type b)
deriving (Show, Eq, Generic, Functor, Foldable, Traversable) deriving (Show, Eq, Generic, Functor, Foldable, Traversable)
instance Core.HasApplicants1 (Type b) (Type b) (Type b) (Type b) where
applicants1 k (AppT f x) = AppT <$> Core.applicants1 k f <*> k x
applicants1 k t = k t
instance (Hashable b) => Hashable (Type b) instance (Hashable b) => Hashable (Type b)
pattern IntT :: (IsString b, Eq b) => Type b pattern IntT :: (IsString b, Eq b) => Type b
pattern IntT = ConT "Int#" pattern IntT = ConT "Int#"
type Kind = Type
pattern TypeT :: (IsString b, Eq b) => Type b
pattern TypeT = ConT "Type"
instance Core.HasArrowSyntax (Type b) (Type b) (Type b) where instance Core.HasArrowSyntax (Type b) (Type b) (Type b) where
_arrowSyntax = prism make unmake where _arrowSyntax = prism make unmake where
make (s,t) = FunT `AppT` s `AppT` t make (s,t) = FunT `AppT` s `AppT` t
@@ -142,21 +101,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, Generic1) deriving (Eq, Show, Generic)
conList :: Prism' (Pat b) (b, [Pat b])
conList = prism' up down where
up (b,as) = foldl AppP (ConP b) as
down (ConP b) = Just (b, [])
down (AppP (ConP b) as) = Just (b, go as)
down _ = Nothing
go (AppP f x) = f : go x
go p = [p]
pattern ConP' :: b -> [Pat b] -> Pat b
pattern ConP' c as <- (preview conList -> Just (c,as))
where ConP' c as = review conList (c,as)
deriveShow1 ''Alter deriveShow1 ''Alter
deriveShow1 ''Binding deriveShow1 ''Binding
@@ -171,92 +116,70 @@ pattern Finr ga = Fix (InR ga)
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
instance (Out b, Out a) => Out (ExprF b a) where instance (Pretty b, Pretty a) => Pretty (ExprF b a) where
outPrec = outPrec1 prettyPrec = prettyPrec1
instance (Out b, Out a) => Out (Alter b a) where instance (Pretty b, Pretty a) => Pretty (Alter b a) where
outPrec = outPrec1 prettyPrec = prettyPrec1
instance (Out b) => Out1 (Alter b) where instance (Pretty b) => Pretty1 (Alter b) where
liftOutPrec pr _ (Alter p e) = liftPrettyPrec pr _ (Alter p e) =
hsep [ out p, "->", pr 0 e] hsep [ pretty p, "->", pr 0 e]
instance Out b => Out1 (ExprF b) where instance Pretty b => Pretty1 (ExprF b) where
liftOutPrec pr p (InfixEF o a b) = maybeParens (p>0) $ liftPrettyPrec pr p (InfixEF o a b) = maybeParens (p>0) $
pr 1 a <+> out o <+> pr 1 b pr 1 a <+> pretty o <+> pr 1 b
liftOutPrec pr p (CaseEF e as) = maybeParens (p>0) $ liftPrettyPrec pr p (CaseEF e as) = maybeParens (p>0) $
vsep [ hsep [ "case", pr 0 e, "of" ] hsep [ "case", pr 0 e, "of" ]
, nest 2 (vcat $ liftOutPrec pr 0 <$> as) ] $+$ nest 2 (vcat $ liftPrettyPrec pr 0 <$> as)
liftOutPrec pr p (LetEF r bs e) = maybeParens (p>0) $
vsep [ hsep [ letword r, "<bs>" ]
, nest 2 (hsep [ "in", pr 0 e ]) ]
where
letword Core.Rec = "letrec"
letword Core.NonRec = "let"
instance (Out b, Out a) => Out (Decl b a) where instance (Pretty b, Pretty a) => Pretty (Decl b a) where
outPrec = outPrec1 prettyPrec = prettyPrec1
instance (Out b) => Out1 (Decl b) where instance (Pretty b) => Pretty1 (Decl b) where
liftOutPrec pr _ (FunD f as e) = liftPrettyPrec pr _ (FunD f as e) =
hsep [ ttext f, hsep (outPrec appPrec1 <$> as) hsep [ ttext f, hsep (prettyPrec appPrec1 <$> as)
, "=", pr 0 e ] , "=", pr 0 e ]
liftOutPrec _ _ (DataD f as []) = liftPrettyPrec _ _ (DataD f as []) =
hsep [ "data", ttext f, hsep (out <$> as) ] hsep [ "data", ttext f, hsep (pretty <$> as) ]
liftOutPrec _ _ (DataD f as ds) = liftPrettyPrec _ _ (DataD f as ds) =
hsep [ "data", ttext f, hsep (out <$> as), cons ] hsep [ "data", ttext f, hsep (pretty <$> as), cons ]
where where
cons = vcat $ zipWith (<+>) delims (out <$> ds) cons = vcat $ zipWith (<+>) delims (pretty <$> ds)
delims = "=" : repeat "|" delims = "=" : repeat "|"
liftOutPrec _ _ (TySigD n t) = liftPrettyPrec _ _ (TySigD n t) =
hsep [ ttext n, ":", out t ] hsep [ ttext n, ":", pretty t ]
instance (Out b) => Out (DataCon b) where instance (Pretty b) => Pretty (DataCon b) where
out (DataCon n as) = ttext n <+> hsep (outPrec appPrec1 <$> as) pretty (DataCon n as) = ttext n <+> hsep (prettyPrec appPrec1 <$> as)
collapseForalls :: Prism' (Type b) ([b], Type b)
collapseForalls = prism' up down where
up (bs,m) = foldr ForallT m bs
down (ForallT x m) = case down m of
Just (xs,m') -> Just (x : xs, m')
Nothing -> Just ([x],m)
down _ = Nothing
-- (->) is given prec `appPrec-1` -- (->) is given prec `appPrec-1`
instance (Out b) => Out (Type b) where instance (Pretty b) => Pretty (Type b) where
outPrec _ (VarT n) = ttext n prettyPrec _ (VarT n) = ttext n
outPrec _ (ConT n) = ttext n prettyPrec _ (ConT n) = ttext n
outPrec p (s Core.:-> t) = maybeParens (p>arrPrec) $ prettyPrec p (s Core.:-> t) = maybeParens (p>appPrec-1) $
hsep [ outPrec arrPrec1 s, "->", outPrec arrPrec t ] hsep [ prettyPrec appPrec s, "->", prettyPrec (appPrec-1) t ]
where arrPrec = appPrec-1 prettyPrec p (AppT f x) = maybeParens (p>appPrec) $
arrPrec1 = appPrec prettyPrec appPrec f <+> prettyPrec appPrec1 x
outPrec p (AppT f x) = maybeParens (p>appPrec) $ prettyPrec p FunT = maybeParens (p>0) "->"
outPrec appPrec f <+> outPrec appPrec1 x
outPrec p FunT = maybeParens (p>0) "->"
outPrec p t@(ForallT _ _) = maybeParens (p>0) $
t ^. singular collapseForalls & \(bs,m) ->
let bs' = "" <> (hsep $ outPrec appPrec1 <$> bs) <> "."
in bs' <+> outPrec 0 m
instance (Out b) => Out (Pat b) where instance (Pretty b) => Pretty (Pat b) where
outPrec p (VarP b) = outPrec p b prettyPrec p (VarP b) = prettyPrec p b
outPrec p (ConP b) = outPrec p b prettyPrec p (ConP b) = prettyPrec p b
outPrec p (AppP c x) = maybeParens (p>appPrec) $ prettyPrec p (AppP c x) = maybeParens (p>appPrec) $
outPrec appPrec c <+> outPrec appPrec1 x prettyPrec appPrec c <+> prettyPrec appPrec1 x
instance (Out a, Out b) => Out (Program b a) where instance (Pretty a, Pretty b) => Pretty (Program b a) where
outPrec = outPrec1 prettyPrec = prettyPrec1
instance (Out b) => Out1 (Program b) where instance (Pretty b) => Pretty1 (Program b) where
liftOutPrec pr p (Program ds) = vsep $ liftOutPrec pr p <$> ds liftPrettyPrec pr p (Program ds) = vsep $ liftPrettyPrec pr p <$> ds
makePrisms ''ExprF
makePrisms ''Pat makePrisms ''Pat
makePrisms ''Binding makePrisms ''Binding
makePrisms ''Decl
deriving instance (Lift b, Lift a) => Lift (Program b a) deriving instance (Lift b, Lift a) => Lift (Program b a)
deriving instance (Lift b, Lift a) => Lift (Decl b a) deriving instance (Lift b, Lift a) => Lift (Decl b a)
@@ -294,33 +217,3 @@ instance (Hashable b) => Hashable1 (ExprF b)
makeBaseFunctor ''Type makeBaseFunctor ''Type
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 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 ]
--------------------------------------------------------------------------------
fixCofree :: (Functor f, Functor g)
=> Iso (Fix f) (Fix g) (Cofree f ()) (Cofree g b)
fixCofree = iso sa bt where
sa = foldFix (() :<)
bt (_ :< f) = Fix (bt <$> f)

View File

@@ -1,52 +1,39 @@
{-# LANGUAGE PartialTypeSignatures #-}
{-# LANGUAGE OverloadedLists #-}
{-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TemplateHaskell #-}
module Rlp.HindleyMilner module Rlp.HindleyMilner
( typeCheckRlpProgR ( typeCheckRlpProgR
, solve
, TypeError(..) , TypeError(..)
, renamePrettily , runHM'
, HM
) )
where where
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
import Control.Lens hiding (Context', Context, (:<), para, uncons) import Control.Lens hiding (Context', Context, (:<), para)
import Control.Lens.Unsound
import Control.Lens.Extras
import Control.Monad.Errorful import Control.Monad.Errorful
import Control.Monad.State import Control.Monad.State
import Control.Monad.Accum import Control.Monad.Accum
import Control.Monad.Reader
import Control.Monad import Control.Monad
import Control.Monad.Extra
import Control.Monad.Free
import Control.Arrow ((>>>)) import Control.Arrow ((>>>))
import Control.Monad.Writer.Strict import Control.Monad.Writer.Strict
import Data.List
import Data.Monoid
import Data.Text qualified as T import Data.Text qualified as T
import Data.Foldable (fold) import Data.Pretty
import Data.Function
import Data.Foldable
import Data.Pretty hiding (annotate)
import Data.Maybe
import Data.Hashable import Data.Hashable
import Data.HashMap.Strict (HashMap) import Data.HashMap.Strict (HashMap)
import Data.HashMap.Strict qualified as H import Data.HashMap.Strict qualified as H
import Data.HashSet (HashSet) import Data.HashSet (HashSet)
import Data.HashSet.Lens
import Data.HashSet qualified as S import Data.HashSet qualified as S
import Data.Maybe (fromMaybe) import Data.Maybe (fromMaybe)
import Data.Traversable import Data.Traversable
import GHC.Generics (Generic, Generically(..)) import GHC.Generics (Generic(..), Generically(..))
import Debug.Trace
import Data.Functor hiding (unzip) import Data.Functor
import Data.Functor.Extend import Data.Functor.Foldable
import Data.Functor.Foldable hiding (fold) import Data.Fix hiding (cata, para)
import Data.Fix hiding (cata, para, cataM, ana)
import Control.Comonad.Cofree import Control.Comonad.Cofree
import Control.Comonad import Control.Comonad
import Effectful
import Compiler.RLPC import Compiler.RLPC
import Compiler.RlpcError import Compiler.RlpcError
import Rlp.AltSyntax as Rlp import Rlp.AltSyntax as Rlp
@@ -55,319 +42,120 @@ import Core.Syntax (ExprF(..), Lit(..))
import Rlp.HindleyMilner.Types import Rlp.HindleyMilner.Types
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- | Annotate a structure with the result of a catamorphism at each level. fixCofree :: (Functor f, Functor g)
-- => Iso (Fix f) (Fix g) (Cofree f ()) (Cofree g b)
-- Pretentious etymology: 'dendr-' means 'tree' fixCofree = iso sa bt where
sa = foldFix (() :<)
bt (_ :< as) = Fix $ bt <$> as
dendroscribe :: (Functor f, Base t ~ f, Recursive t) lookupVar :: PsName -> Context -> HM (Type PsName)
=> (f (Cofree f a) -> a) -> t -> Cofree f a lookupVar n g = case g ^. contextVars . at n of
dendroscribe c (project -> f) = c f' :< f' Just t -> pure t
where f' = dendroscribe c <$> f Nothing -> addFatal $ TyErrUntypedVariable n
dendroscribeM :: (Traversable f, Monad m, Base t ~ f, Recursive t) gather :: RlpExpr PsName -> HM (Type PsName, PartialJudgement)
=> (f (Cofree f a) -> m a) -> t -> m (Cofree f a) gather e = look >>= (H.lookup e >>> maybe memoise pure)
dendroscribeM c (project -> f) = do
as <- dendroscribeM c `traverse` f
a <- c as
pure (a :< as)
--------------------------------------------------------------------------------
assume :: Name -> Type' -> Judgement
assume n t = mempty & assumptions .~ H.singleton n [t]
equal :: Type' -> Type' -> Judgement
equal a b = mempty & constraints .~ [Equality a b]
elim :: Name -> Type' -> Judgement -> Judgement
elim n t j = j & assumptions %~ H.delete n
& constraints <>~ cs
where where
cs = j & foldMapOf (assumptions . at n . each . each) \t' -> memoise = do
[Equality t t'] r <- gather' e
add (H.singleton e r)
pure r
elimGenerally :: Name -> Type' -> Judgement -> Judgement gather' :: RlpExpr PsName -> HM (Type PsName, PartialJudgement)
elimGenerally n t j = j & assumptions %~ H.delete n gather' = \case
& constraints <>~ cs Finl (LitF (IntL _)) -> pure (IntT, mempty)
where
cs = j & foldMapOf (assumptions . at n . each . each) \t' ->
[ImplicitInstance mempty t' t]
monomorphise :: Type' -> Judgement -> Judgement Finl (VarF n) -> do
monomorphise n = constraints . each . _ImplicitInstance . _1 %~ S.insert n t <- freshTv
let j = mempty & assumptions .~ H.singleton n [t]
pure (t,j)
withoutPatterns :: [Binding b a] -> [(b, a)] Finl (AppF f x) -> do
withoutPatterns bs = bs ^.. each . singular _VarB tfx <- freshTv
& each . _1 %~ view (singular _VarP) (tf,jf) <- gather f
(tx,jx) <- gather x
let jtfx = mempty & constraints .~ [Equality tf (tx :-> tfx)]
pure (tfx, jf <> jx <> jtfx)
-------------------------------------------------------------------------------- Finl (LamF [b] e) -> do
tb <- freshTv
(te,je) <- gather e
let cs = maybe [] (fmap $ Equality tb) (je ^. assumptions . at b)
as = je ^. assumptions & at b .~ Nothing
j = mempty & constraints .~ cs & assumptions .~ as
t = tb :-> te
pure (t,j)
gather :: (Unique :> es) unify :: [Constraint] -> HM Context
=> RlpExprF' (Type', Judgement) -> Eff es (Type', Judgement)
gather (InL (LitF (IntL _))) = pure (IntT, mempty)
gather (InL (VarF n)) = do unify [] = pure mempty
t <- freshTv
pure (t, assume n t)
gather (InL (AppF (tf,jf) (tx,jx))) = do unify (Equality (sx :-> sy) (tx :-> ty) : cs) =
tfx <- freshTv unify $ Equality sx tx : Equality sy ty : cs
pure (tfx, jf <> jx <> equal tf (tx :-> tfx))
gather (InL (LamF xs (te,je))) = do -- elim
bs <- for xs (\x -> (x,) <$> freshTv) unify (Equality (ConT s) (ConT t) : cs) | s == t = unify cs
let j = je & forBinds elim bs unify (Equality (VarT s) (VarT t) : cs) | s == t = unify cs
& forBinds (const monomorphise) bs
t = foldr (:->) te (bs ^.. each . _2) unify (Equality (VarT s) t : cs)
pure (t, j) | occurs s t = addFatal $ TyErrRecursiveType s t
| otherwise = unify cs' <&> contextVars . at s ?~ t
where where
elimBind (x,tx) j1 = elim x tx j1 cs' = cs & each . constraintTypes %~ subst s t
gather (InR (LetEF NonRec (withoutPatterns -> bs) (te,je))) = do -- swap
let j = foldr elimBind je bs unify (Equality s (VarT t) : cs) = unify (Equality (VarT t) s : cs)
pure (te, j)
where
elimBind (x,(tx,jx)) j1 = elimGenerally x tx (jx <> j1)
gather (InR (LetEF Rec (withoutPatterns -> bs) (te,je))) = do unify (Equality s t : _) = addFatal $ TyErrCouldNotUnify s t
let j = foldOf (each . _2 . _2) bs
j' = foldr elimRecBind j bs
pure (te, j' <> foldr elimBind je bs)
where
elimRecBind (x,(tx,_)) j = elim x tx j
elimBind (x,(tx,_)) j = elimGenerally x tx j
gather (InR (CaseEF (te,je) as)) = do annotate :: RlpExpr PsName
as' <- gatherAlter te `traverse` as -> HM (Cofree (RlpExprF PsName) (Type PsName, PartialJudgement))
t <- freshTv annotate = sequenceA . fixtend (gather . wrapFix)
let eqs = allEqual (t : (as' ^.. each . _1))
j = je <> foldOf (each . _2) as' <> eqs
pure (t,j)
gatherAlter :: (Unique :> es) solveTree :: Cofree (RlpExprF PsName) (Type PsName, PartialJudgement)
=> Type' -> HM (Type PsName)
-> Alter PsName (Type', Judgement) solveTree e = undefined
-> Eff es (Type', Judgement)
gatherAlter te (Alter (ConP' n bs) (ta,ja)) = do
-- let tc' be the type of the saturated type constructor
tc' <- freshTv
bs' <- for bs (\b -> (b ^. singular _VarP,) <$> freshTv)
let tbs = bs' ^.. each . _2
tc = foldr (:->) tc' tbs
j = equal te tc' <> assume n tc <> forBinds elim bs' ja
pure (ta,j)
allEqual :: [Type'] -> Judgement infer1 :: RlpExpr PsName -> HM (Type PsName)
allEqual = fold . ana @[_] \case infer1 e = do
[] -> Nil ((t,j) :< _) <- annotate e
[a] -> Nil g <- unify (j ^. constraints)
(a:b:xs) -> Cons (equal a b) (b:xs) pure $ ifoldrOf (contextVars . itraversed) subst t g
forBinds :: (PsName -> Type' -> Judgement -> Judgement) solve = undefined
-> [(PsName, Type')] -> Judgement -> Judgement -- solve g e = do
forBinds f bs j = foldr (uncurry f) j bs -- (t,j) <- gather e
-- g' <- unify cs
-- pure $ ifoldrOf (contextVars . itraversed) subst t g'
unify :: (Unique :> es) occurs :: PsName -> Type PsName -> Bool
=> [Constraint] -> ErrorfulT TypeError (Eff es) Subst occurs n = cata \case
unify [] = pure id VarTF m | n == m -> True
unify (c:cs) = case c of t -> or t
Equality (ConT a) (ConT b) subst :: PsName -> Type PsName -> Type PsName -> Type PsName
| a == b subst n t' = para \case
-> unify cs VarTF m | n == m -> t'
-- shadowing
ForallTF x (pre,post) | x == n -> ForallT x pre
| otherwise -> ForallT x post
t -> embed $ t <&> view _2
Equality (VarT a) (VarT b) prettyHM :: (Pretty a)
| a == b => Either [TypeError] (a, [Constraint])
-> unify cs -> Either [TypeError] (String, [String])
prettyHM = over (mapped . _1) rpretty
. over (mapped . _2 . each) rpretty
Equality (VarT a) t fixtend :: Functor f => (f (Fix f) -> b) -> Fix f -> Cofree f b
| a `occurs` t fixtend c (Fix f) = c f :< fmap (fixtend c) f
-> error "recursive type"
| otherwise
-> unify (subst a t <$> cs) <&> (. subst a t)
Equality t (VarT a) infer :: RlpExpr PsName -> HM (Cofree (RlpExprF PsName) (Type PsName))
-> unify (Equality (VarT a) t : cs) infer = undefined
Equality (s :-> t) (s' :-> t') typeCheckRlpProgR :: (Monad m)
-> unify (Equality s s' : Equality t t' : cs) => Program PsName (RlpExpr PsName)
-> RLPCT m (Program PsName
Equality (AppT s t) (AppT s' t') (Cofree (RlpExprF PsName) (Type PsName)))
-> unify (Equality s s' : Equality t t' : cs) typeCheckRlpProgR = undefined
ImplicitInstance m s t
| null $ (freeTvs t `S.difference` freeTvs m)
`S.intersection` activeTvs cs
-> unify $ ExplicitInstance s (generalise (freeTvs m) t) : cs
ExplicitInstance s t -> do
t' <- lift $ instantiate t
unify $ Equality s t' : cs
Equality a b
-> addFatal $ TyErrCouldNotUnify a b
_ -> error $ "explode (typecheckr explsiong): " <> show c
activeTvs :: [Constraint] -> HashSet Name
activeTvs = foldMap \case
Equality s t -> freeTvs s <> freeTvs t
ImplicitInstance m s t -> freeTvs s <> (freeTvs m `S.intersection` freeTvs t)
ExplicitInstance s t -> freeTvs s <> freeTvs t
instantiate :: (Unique :> es) => Scheme -> Eff es Type'
instantiate (ForallT x t) = do
x' <- freshTv
subst x x' <$> instantiate t
instantiate t = pure t
generalise :: HashSet Name -> Type' -> Scheme
generalise m t = foldr ForallT t as
where as = S.toList $ freeTvs t `S.difference` m
occurs :: (HasTypes a) => Name -> a -> Bool
occurs x t = x `elem` freeTvs t
elimGlobalBinds :: [(Name, Scheme)] -> Cofree RlpExprF' (Type', Judgement)
-> Cofree RlpExprF' (Type', Judgement)
elimGlobalBinds bs = traversed . _2 %~ forBinds f bs where
f n t@(ForallT _ _) = elimGenerally n t
f n t = elim n t
--------------------------------------------------------------------------------
annotate :: (Unique :> es)
=> RlpExpr' -> Eff es (Cofree RlpExprF' (Type', Judgement))
annotate = fmap (elimGlobalBinds [ ("Just", ForallT "a" $ VarT "a" :-> ConT "Maybe" `AppT` VarT "a")
, ("isJust", ForallT "a" $ ConT "Maybe" `AppT` VarT "a" :-> ConT "Bool")])
. dendroscribeM (gather . fmap extract)
orderConstraints :: [Constraint] -> [Constraint]
orderConstraints cs = a <> b
where (a,b) = partition (isn't _ImplicitInstance) cs
finalJudgement :: Cofree RlpExprF' (Type', Judgement) -> Judgement
finalJudgement = snd . extract
solveTree :: (Unique :> es)
=> Cofree RlpExprF' (Type', Judgement)
-> ErrorfulT TypeError (Eff es) (Cofree RlpExprF' Type')
solveTree e = do
sub <- unify (orderConstraints $ finalJudgement e ^. constraints . reversed)
pure $ sub . view _1 <$> e
solveJudgement :: (Unique :> es)
=> Judgement
-> ErrorfulT TypeError (Eff es) Subst
solveJudgement j = unify (orderConstraints $ j ^. constraints . reversed)
typeCheckRlpProgR :: Monad m
=> Program PsName RlpExpr'
-> RLPCT m (Program PsName (Cofree RlpExprF' Type'))
typeCheckRlpProgR
= liftErrorful
. hoistErrorfulT (pure . runPureEff . runUnique)
. mapErrorful (errorMsg (SrcSpan 0 0 0 0))
. inferProg
finallyGeneralise :: Cofree RlpExprF' Type' -> Cofree RlpExprF' Type'
finallyGeneralise = _extract %~ generalise mempty
inferProg :: (Unique :> es)
=> Program PsName RlpExpr'
-> ErrorfulT TypeError (Eff es)
(Program PsName (Cofree RlpExprF' Type'))
inferProg p = do
p' <- lift $ annotateProg (etaExpandProg p)
sub <- solveJudgement (foldOf (folded . _extract . _2) p')
pure $ p' & traversed . traversed %~ sub . view _1
& traversed %~ finallyGeneralise
etaExpandProg :: Program PsName RlpExpr' -> Program PsName RlpExpr'
etaExpandProg = programDecls . each %~ etaExpand where
etaExpand (FunD n [] e) = FunD n [] e
etaExpand (FunD n as e) = FunD n [] $ Finl (LamF as' e)
where as' = as ^.. each . singular _VarP
etaExpand x = x
infer :: (Unique :> es)
=> RlpExpr'
-> ErrorfulT TypeError (Eff es)
(Cofree RlpExprF' Type')
infer e = do
e' <- solveTree <=< (lift . annotate) $ e
pure $ finallyGeneralise e'
annotateDefs :: (Unique :> es)
=> Program PsName RlpExpr'
-> Eff es (Program PsName
(Cofree RlpExprF' (Type', Judgement)))
annotateDefs = traverseOf (programDefs . _2) annotate
extractDefs :: Program PsName (Cofree RlpExprF' (Type', Judgement))
-> [(Name, Type')]
extractDefs p = p ^.. programDefs & each . _2 %~ fst . extract
extractCons :: Program PsName (Cofree RlpExprF' (Type', Judgement))
-> [(Name, Type')]
extractCons = foldMapOf (programDecls . each . _DataD) \(n,as,cs) ->
let root = foldl AppT (ConT n) (VarT <$> as)
in cs & fmap \ (DataCon cn cas) -> (cn, foldr (:->) root cas)
annotateProg :: (Unique :> es)
=> Program PsName RlpExpr'
-> Eff es (Program PsName
(Cofree RlpExprF' (Type', Judgement)))
annotateProg p = do
p' <- annotateDefs p
let bs = extractCons p' ++ extractDefs p'
p'' = p' & programDefs . _2 . traversed . _2
%~ forBinds elimGenerally bs
pure p''
programDefs :: Traversal (Program b a) (Program b a') (b, a) (b, a')
programDefs k (Program ds) = Program <$> traverse go ds where
go (FunD n as e) = refun as (k (n,e))
go (DataD n as cs) = pure $ DataD n as cs
go (TySigD n ts) = pure $ TySigD n ts
refun as kne = uncurry (\a b -> FunD a as b) <$> kne
--------------------------------------------------------------------------------
renamePrettily' :: Type PsName -> Type PsName
renamePrettily' = join renamePrettily
-- | for some type, compute a substitution which will rename all free variables
-- for aesthetic purposes
renamePrettily :: Type PsName -> Type PsName -> Type PsName
renamePrettily root = (`evalState` alphabetNames) . (renameFree <=< renameBound)
where
renameBound :: Type PsName -> State [PsName] (Type PsName)
renameBound = cata \case
ForallTF x m -> do
n <- getName
ForallT n <$> (subst x (VarT n) <$> m)
t -> embed <$> sequenceA t
renameFree :: Type PsName -> State [PsName] (Type PsName)
renameFree t = do
subs <- forM (freeVariablesLTR root) $ \v -> do
n <- getName
pure $ Endo (subst v (VarT n))
pure . appEndo (fold subs) $ t
getName :: State [PsName] PsName
getName = state (fromJust . uncons)
alphabetNames :: [PsName]
alphabetNames = alphabet ++ concatMap appendAlphabet alphabetNames
where alphabet = [ T.pack [c] | c <- ['a'..'z'] ]
appendAlphabet c = [ c <> c' | c' <- alphabet ]
freeVariablesLTR :: Type PsName -> [PsName]
freeVariablesLTR = nub . cata \case
VarTF x -> [x]
ForallTF x m -> m \\ [x]
vs -> concat vs

View File

@@ -11,45 +11,57 @@ import Data.HashSet qualified as S
import GHC.Generics (Generic(..), Generically(..)) import GHC.Generics (Generic(..), Generically(..))
import Data.Kind qualified import Data.Kind qualified
import Data.Text qualified as T import Data.Text qualified as T
import Effectful.State.Static.Local import Control.Monad.Writer
import Effectful.Labeled import Control.Monad.Accum
import Effectful import Control.Monad.Trans.Accum
import Control.Monad.Errorful
import Control.Monad.State
import Text.Printf import Text.Printf
import Data.Pretty import Data.Pretty
import Data.Function import Data.Function
import Control.Lens hiding (Context', Context, para) import Control.Lens hiding (Context', Context)
import Data.Functor.Foldable hiding (fold)
import Data.Foldable
import Compiler.RlpcError import Compiler.RlpcError
import Rlp.AltSyntax import Rlp.AltSyntax
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- | A polymorphic type newtype Context = Context
{ _contextVars :: HashMap PsName (Type PsName)
}
deriving (Show, Generic)
deriving (Semigroup, Monoid)
via Generically Context
type Scheme = Type' data Constraint = Equality (Type PsName) (Type PsName)
deriving (Eq, Generic, Show)
type Subst = Type' -> Type' data PartialJudgement = PartialJudgement
{ _constraints :: [Constraint]
, _assumptions :: HashMap PsName [Type PsName]
}
deriving (Generic, Show)
deriving (Monoid)
via Generically PartialJudgement
data Constraint = Equality Type' Type' instance Semigroup PartialJudgement where
| ImplicitInstance (HashSet Type') Type' Type' a <> b = PartialJudgement
| ExplicitInstance Type' Scheme { _constraints = ((<>) `on` _constraints) a b
deriving Show , _assumptions = (H.unionWith (<>) `on` _assumptions) a b
}
instance Out Constraint where instance Hashable Constraint
out (Equality s t) =
hsep [outPrec appPrec1 s, "~", outPrec appPrec1 t]
-------------------------------------------------------------------------------- type Memo = HashMap (RlpExpr PsName) (Type PsName, PartialJudgement)
type HM = ErrorfulT TypeError (StateT Int (Accum Memo))
-- | Type error enum. -- | Type error enum.
data TypeError data TypeError
-- | Two types could not be unified -- | Two types could not be unified
= TyErrCouldNotUnify Type' Type' = TyErrCouldNotUnify (Type Name) (Type Name)
-- | @x@ could not be unified with @t@ because @x@ occurs in @t@ -- | @x@ could not be unified with @t@ because @x@ occurs in @t@
| TyErrRecursiveType Name Type' | TyErrRecursiveType Name (Type Name)
-- | Untyped, potentially undefined variable -- | Untyped, potentially undefined variable
| TyErrUntypedVariable Name | TyErrUntypedVariable Name
| TyErrMissingTypeSig Name | TyErrMissingTypeSig Name
@@ -61,115 +73,90 @@ instance IsRlpcError TypeError where
-- todo: use anti-parser instead of show -- todo: use anti-parser instead of show
TyErrCouldNotUnify t u -> Text TyErrCouldNotUnify t u -> Text
[ T.pack $ printf "Could not match type `%s` with `%s`." [ T.pack $ printf "Could not match type `%s` with `%s`."
(rout @String t) (rout @String u) (rpretty @String t) (rpretty @String u)
, "Expected: " <> rout t , "Expected: " <> rpretty t
, "Got: " <> rout u , "Got: " <> rpretty u
] ]
TyErrUntypedVariable n -> Text TyErrUntypedVariable n -> Text
[ "Untyped (likely undefined) variable `" <> n <> "`" [ "Untyped (likely undefined) variable `" <> n <> "`"
] ]
TyErrRecursiveType t x -> Text TyErrRecursiveType t x -> Text
[ T.pack $ printf "Recursive type: `%s' occurs in `%s'" [ T.pack $ printf "Recursive type: `%s' occurs in `%s'"
(rout @String t) (rout @String x) (rpretty @String t) (rpretty @String x)
] ]
-------------------------------------------------------------------------------- -- type Memo t = HashMap t (Type PsName, PartialJudgement)
type Unique = State Int -- newtype HM t a = HM { unHM :: Int -> Memo t -> (a, Int, Memo t) }
runUnique :: Eff (Unique : es) a -> Eff es a -- runHM :: (Hashable t) => HM t a -> (a, Memo t)
runUnique = evalState 0 -- runHM hm = let (a,_,m) = unHM hm 0 mempty in (a,m)
freshTv :: (Unique :> es) => Eff es (Type PsName) -- instance Functor (HM t) where
-- fmap f (HM h) = HM \n m -> h n m & _1 %~ f
-- instance Applicative (HM t) where
-- pure a = HM \n m -> (a,n,m)
-- HM hf <*> HM ha = HM \n m ->
-- let (f',n',m') = hf n m
-- (a,n'',m'') = ha n' m'
-- in (f' a, n'', m'')
-- instance Monad (HM t) where
-- HM ha >>= k = HM \n m ->
-- let (a,n',m') = ha n m
-- (a',n'',m'') = unHM (k a) n' m'
-- in (a',n'', m'')
-- instance Hashable t => MonadWriter (Memo t) (HM t) where
-- -- IMPORTAN! (<>) is left-biased for HashMap! append `w` to the RIGHt!
-- writer (a,w) = HM \n m -> (a,n,m <> w)
-- listen ma = HM \n m ->
-- let (a,n',m') = unHM ma n m
-- in ((a,m'),n',m')
-- pass maww = HM \n m ->
-- let ((a,ww),n',m') = unHM maww n m
-- in (a,n',ww m')
-- instance MonadState Int (HM t) where
-- state f = HM \n m ->
-- let (a,n') = f n
-- in (a,n',m)
freshTv :: HM (Type PsName)
freshTv = do freshTv = do
n <- get n <- get
modify @Int succ modify succ
pure (VarT $ tvNameOfInt n) pure . VarT $ "$a" <> T.pack (show n)
tvNameOfInt :: Int -> PsName runHM' :: HM a -> Either [TypeError] a
tvNameOfInt n = "$a" <> T.pack (show n) runHM' e = maybe (Left es) Right ma
where
((ma,es),m) = (`runAccum` mempty) . (`evalStateT` 0) . runErrorfulT $ e
-------------------------------------------------------------------------------- -- addConstraint :: Constraint -> HM ()
-- addConstraint = tell . pure
-- | A 'Judgement' is a sort of "co-context" used in bottom-up inference. The makePrisms ''PartialJudgement
-- typical algorithms J, W, and siblings pass some context Γ to the inference makeLenses ''PartialJudgement
-- algorithm which is used to lookup variables and such. Here in rlpc we makeLenses ''Context
-- infer a type under zero context; inference returns the assumptions made of
-- a variable which may be later eliminated and solved.
data Judgement = Judgement
{ _constraints :: [Constraint]
, _assumptions :: Assumptions
}
deriving (Show)
type Assumptions = HashMap PsName [Type PsName]
instance Semigroup Judgement where
a <> b = Judgement
{ _constraints = ((<>) `on` _constraints) a b
, _assumptions = (H.unionWith (<>) `on` _assumptions) a b
}
instance Monoid Judgement where
mempty = Judgement
{ _constraints = mempty
, _assumptions = mempty
}
--------------------------------------------------------------------------------
class HasTypes a where
types :: Traversal' a Type'
freeTvs :: a -> HashSet PsName
boundTvs :: a -> HashSet PsName
subst :: Name -> Type' -> a -> a
freeTvs = foldMapOf types $ cata \case
VarTF n -> S.singleton n
t -> fold t
boundTvs = const mempty
subst k v = types %~ cata \case
VarTF n | k == n -> v
t -> embed t
instance HasTypes Constraint where
types k (Equality s t) = Equality <$> types k s <*> types k t
types k (ImplicitInstance m s t) =
ImplicitInstance <$> types k m <*> types k s <*> types k t
types k (ExplicitInstance s t) =
ExplicitInstance <$> types k s <*> types k t
instance (Hashable a, HasTypes a) => HasTypes (HashSet a) where
types k = traverseHashSetBad (types k)
instance HasTypes Type' where
types = id
freeTvs = cata \case
VarTF n -> S.singleton n
ForallTF x t -> S.delete x t
t -> fold t
boundTvs = cata \case
ForallTF x t -> S.insert x t
t -> fold t
subst k v = para \case
VarTF n | k == n -> v
ForallTF x (pre,post)
| k == x -> ForallT x pre
t -> embed $ snd <$> t
-- illegal traversal
traverseHashSetBad :: (Hashable a, Hashable b)
=> Traversal (HashSet a) (HashSet b) a b
traverseHashSetBad k s = fmap S.fromList $ traverse k (S.toList s)
--------------------------------------------------------------------------------
makePrisms ''Judgement
makeLenses ''Judgement
makePrisms ''Constraint makePrisms ''Constraint
makePrisms ''TypeError makePrisms ''TypeError
supplement :: [(PsName, Type PsName)] -> Context -> Context
supplement bs = contextVars %~ (H.fromList bs <>)
demoContext :: Context
demoContext = Context
{ _contextVars =
[ ("+#", IntT :-> IntT :-> IntT)
]
}
constraintTypes :: Traversal' Constraint (Type PsName)
constraintTypes k (Equality s t) = Equality <$> k s <*> k t
instance Pretty Constraint where
pretty (Equality s t) =
hsep [prettyPrec appPrec1 s, "~", prettyPrec appPrec1 t]

View File

@@ -1,30 +0,0 @@
{-# LANGUAGE LexicalNegation #-}
module Rlp.HindleyMilner.Visual
(
)
where
--------------------------------------------------------------------------------
import Control.Monad
import System.IO
import Data.Text (Text)
import Data.Text qualified as T
import Data.Text.IO qualified as T
import Data.Pretty hiding (annotate)
import Data.String (IsString(..))
import Data.Foldable
import Misc.CofreeF
import Control.Exception
import Data.Functor.Foldable
import Data.Aeson
import Core.Syntax as Core
import Rlp.AltSyntax as Rlp
import Rlp.HindleyMilner
import Prelude hiding ((**))
--------------------------------------------------------------------------------
type AnnExpr = Cofree (RlpExprF PsName)

View File

@@ -59,7 +59,7 @@ $asciisym = [\!\#\$\%\&\*\+\.\/\<\=\>\?\@\\\^\|\-\~\:]
@reservedname = @reservedname =
case|data|do|import|in|let|letrec|module|of|where case|data|do|import|in|let|letrec|module|of|where
|infixr|infixl|infix|forall |infixr|infixl|infix
@reservedop = @reservedop =
"=" | \\ | "->" | "|" | ":" "=" | \\ | "->" | "|" | ":"
@@ -163,7 +163,6 @@ lexReservedName = \case
"infix" -> TokenInfix "infix" -> TokenInfix
"infixl" -> TokenInfixL "infixl" -> TokenInfixL
"infixr" -> TokenInfixR "infixr" -> TokenInfixR
"forall" -> TokenForall
s -> error (show s) s -> error (show s)
lexReservedOp :: Text -> RlpToken lexReservedOp :: Text -> RlpToken
@@ -284,7 +283,7 @@ lexStream = fmap extract <$> lexStream'
lexStream' :: P [Located RlpToken] lexStream' :: P [Located RlpToken]
lexStream' = lexToken >>= \case lexStream' = lexToken >>= \case
t@(Located _ TokenEOF) -> pure [t] t@(Located _ TokenEOF) -> pure [t]
t -> (t:) <$> lexStream' t -> (t:) <$> lexStream'
lexDebug :: (Located RlpToken -> P a) -> P a lexDebug :: (Located RlpToken -> P a) -> P a
lexDebug k = do lexDebug k = do
@@ -331,7 +330,6 @@ insertRBrace = {- traceM "inserting rbrace" >> -} insertToken TokenRBraceV
cmpLayout :: P Ordering cmpLayout :: P Ordering
cmpLayout = do cmpLayout = do
i <- indentLevel i <- indentLevel
-- traceM $ "i: " <> show i
ctx <- preuse (psLayoutStack . _head) ctx <- preuse (psLayoutStack . _head)
case ctx of case ctx of
Just (Implicit n) -> pure (i `compare` n) Just (Implicit n) -> pure (i `compare` n)
@@ -340,6 +338,8 @@ cmpLayout = do
doBol :: LexerAction (Located RlpToken) doBol :: LexerAction (Located RlpToken)
doBol inp l = do doBol inp l = do
off <- cmpLayout off <- cmpLayout
i <- indentLevel
-- traceM $ "i: " <> show i
-- important that we pop the lex state lest we find our lexer diverging -- important that we pop the lex state lest we find our lexer diverging
case off of case off of
-- the line is aligned with the previous. it therefore belongs to the -- the line is aligned with the previous. it therefore belongs to the

View File

@@ -17,7 +17,6 @@ module Rlp.Parse.Types
-- * Other parser types -- * Other parser types
, RlpToken(..), AlexInput(..), Position(..), spanFromPos, LexerAction , RlpToken(..), AlexInput(..), Position(..), spanFromPos, LexerAction
, Located(..), PsName , Located(..), PsName
, srcSpanLen
-- ** Lenses -- ** Lenses
, _TokenLitInt, _TokenVarName, _TokenConName, _TokenVarSym, _TokenConSym , _TokenLitInt, _TokenVarName, _TokenConName, _TokenVarSym, _TokenConSym
, aiPrevChar, aiSource, aiBytes, aiPos, posLine, posColumn , aiPrevChar, aiSource, aiBytes, aiPos, posLine, posColumn
@@ -109,7 +108,6 @@ data RlpToken
| TokenInfixL | TokenInfixL
| TokenInfixR | TokenInfixR
| TokenInfix | TokenInfix
| TokenForall
-- reserved ops -- reserved ops
| TokenArrow | TokenArrow
| TokenPipe | TokenPipe
@@ -279,7 +277,7 @@ initAlexInput s = AlexInput
{ _aiPrevChar = '\0' { _aiPrevChar = '\0'
, _aiSource = s , _aiSource = s
, _aiBytes = [] , _aiBytes = []
, _aiPos = (1,1,0) , _aiPos = (1,0,0)
} }
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------

56
src/Rlp/Syntax/Good.hs Normal file
View File

@@ -0,0 +1,56 @@
{-# LANGUAGE TemplateHaskell #-}
module Rlp.Syntax.Good
( Decl(..), Program(..)
, programDecls
, Mistake(..)
)
where
--------------------------------------------------------------------------------
import Data.Kind
import Control.Lens
import Rlp.Syntax.Types (NameP)
import Rlp.Syntax.Types qualified as Rlp
--------------------------------------------------------------------------------
data Program b a = Program
{ _programDecls :: [Decl b a]
}
data Decl p a = FunD (NameP p) [Rlp.Pat p] a
| TySigD [NameP p] (Rlp.Ty p)
| DataD (NameP p) [NameP p] [Rlp.ConAlt p]
| InfixD Rlp.Assoc Int (NameP p)
type Where p a = [Binding p a]
data Binding p a = PatB (Rlp.Pat p) a
deriving (Functor, Foldable, Traversable)
makeLenses ''Program
class Mistake a where
type family Ammend a :: Type
ammendMistake :: a -> Ammend a
instance Mistake (Rlp.Program p a) where
type Ammend (Rlp.Program p a) = Program p (Rlp.Expr' p a)
ammendMistake p = Program
{ _programDecls = ammendMistake <$> Rlp._programDecls p
}
instance Mistake (Rlp.Decl p a) where
type Ammend (Rlp.Decl p a) = Decl p (Rlp.Expr' p a)
ammendMistake = \case
Rlp.FunD n as e _ -> FunD n as e
Rlp.TySigD ns t -> TySigD ns t
Rlp.DataD n as cs -> DataD n as cs
Rlp.InfixD ass p n -> InfixD ass p n
instance Mistake (Rlp.Binding p a) where
type Ammend (Rlp.Binding p a) = Binding p (Rlp.ExprF p a)
ammendMistake = \case
Rlp.PatB k v -> PatB k v

View File

@@ -12,7 +12,8 @@ import Control.Monad.Writer.CPS
import Control.Monad.Utils import Control.Monad.Utils
import Control.Arrow import Control.Arrow
import Control.Applicative import Control.Applicative
import Control.Lens hiding ((:<)) import Control.Comonad
import Control.Lens
import Compiler.RLPC import Compiler.RLPC
import Data.List (mapAccumL, partition) import Data.List (mapAccumL, partition)
import Data.Text (Text) import Data.Text (Text)
@@ -21,18 +22,13 @@ import Data.HashMap.Strict qualified as H
import Data.Monoid (Endo(..)) import Data.Monoid (Endo(..))
import Data.Either (partitionEithers) import Data.Either (partitionEithers)
import Data.Foldable import Data.Foldable
import Data.Fix
import Data.Maybe (fromJust, fromMaybe) import Data.Maybe (fromJust, fromMaybe)
import Data.Functor.Bind
import Data.Function (on) import Data.Function (on)
import GHC.Stack import GHC.Stack
import Debug.Trace import Debug.Trace
import Numeric import Numeric
import Misc.MonadicRecursionSchemes
import Data.Fix hiding (cata, para, cataM)
import Data.Functor.Bind
import Data.Functor.Foldable
import Control.Comonad
import Control.Comonad.Cofree
import Effectful.State.Static.Local import Effectful.State.Static.Local
import Effectful.Labeled import Effectful.Labeled
@@ -42,7 +38,7 @@ import Text.Show.Deriving
import Core.Syntax as Core import Core.Syntax as Core
import Rlp.AltSyntax as Rlp import Rlp.AltSyntax as Rlp
import Compiler.Types import Compiler.Types
import Data.Pretty import Data.Pretty (render, pretty)
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
type Tree a = Either Name (Name, Branch a) type Tree a = Either Name (Name, Branch a)
@@ -63,146 +59,45 @@ deriveShow1 ''Branch
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- desugarRlpProgR :: forall m a. (Monad m) desugarRlpProgR :: forall m a. (Monad m)
-- => Rlp.Program PsName (TypedRlpExpr PsName) => Rlp.Program PsName a
-- -> RLPCT m (Core.Program Var) -> RLPCT m Core.Program'
-- desugarRlpProgR p = do desugarRlpProgR p = do
-- let p' = desugarRlpProg p let p' = desugarRlpProg p
-- addDebugMsg "dump-desugared" $ show (out p') addDebugMsg "dump-desugared" $ render (pretty p')
-- pure p' pure p'
desugarRlpProgR = undefined desugarRlpProg = undefined
desugarRlpProg :: Rlp.Program PsName (TypedRlpExpr PsName) -> Core.Program Var
desugarRlpProg = rlpProgToCore
desugarRlpExpr = undefined desugarRlpExpr = undefined
type NameSupply = Labeled "NameSupply" (State [Name])
runNameSupply :: Text -> Eff (NameSupply ': es) a -> Eff es a runNameSupply :: Text -> Eff (NameSupply ': es) a -> Eff es a
runNameSupply pre = runLabeled $ evalState [ pre <> "_" <> tshow name | name <- [0..] ] runNameSupply pre = undefined -- evalState [ pre <> "_" <> tshow name | name <- [0..] ]
where tshow = T.pack . show
single :: (Monoid s) => ASetter s t a b -> b -> t
single l a = mempty & l .~ a
-- the rl' program is desugared by desugaring each declaration as a separate -- the rl' program is desugared by desugaring each declaration as a separate
-- program, and taking the monoidal product of the lot :3 -- program, and taking the monoidal product of the lot :3
rlpProgToCore :: Rlp.Program PsName (TypedRlpExpr PsName) -> Core.Program Var rlpProgToCore :: Rlp.Program PsName (RlpExpr PsName) -> Program'
rlpProgToCore = foldMapOf (programDecls . each) declToCore rlpProgToCore = foldMapOf (programDecls . each) declToCore
-------------------------------------------------------------------------------- declToCore :: Rlp.Decl PsName (RlpExpr PsName) -> Program'
declToCore :: Rlp.Decl PsName TypedRlpExpr' -> Core.Program Var -- assume all arguments are VarP's for now
declToCore (FunD b as e) = mempty & programScDefs .~ [ScDef b as' e']
where
as' = as ^.. each . singular _VarP
e' = runPureEff . runNameSupply b . exprToCore $ e
declToCore (DataD n as ds) type NameSupply = State [Name]
= foldMap (uncurry $ conToCore t) ([0..] `zip` ds)
<> single programTyCons (H.singleton n k)
where
as' = TyVar <$> as
k = foldr (:->) t as'
t = foldl TyApp (TyCon n) as'
-- assume full eta-expansion for now
declToCore (FunD b [] e) = single programScDefs $
[ScDef b' [] e']
where
b' = MkVar b (typeToCore $ extract e)
e' = runPureEff . runNameSupply b . cataM exprToCore . retype $ e
conToCore :: Core.Type -> Int -> DataCon PsName -> Core.Program Var
conToCore t tag (DataCon b as)
= single programScDefs [ScDef b' [] $ Con tag arity]
where
arity = lengthOf arrowStops t - 1
b' = MkVar b t
dummyExpr :: Text -> Core.Expr b
dummyExpr a = Var ("<" <> a <> ">")
stripTypes :: Core.Program Var -> Core.Program Name
stripTypes p = Core.Program
{ _programTyCons = p ^. programTyCons
, _programDataTags = p ^. programDataTags
, _programScDefs = p ^. programScDefs
& each . binders %~ (\ (MkVar n _) -> n)
-- TEMP
, _programTypeSigs = mempty
}
--------------------------------------------------------------------------------
-- | convert rl' types to Core types, annotate binders, and strip excess type
-- info.
retype :: Cofree RlpExprF' (Rlp.Type PsName) -> RlpExpr Var
retype = (_extract %~ unquantify) >>> fmap typeToCore >>> cata \case
t :<$ InL (LamF bs e)
-> Finl (LamF bs' e)
where
bs' = zipWith MkVar bs (t ^.. arrowStops)
t :<$ InL (VarF n)
-> Finl (VarF n)
t :<$ InR (LetEF r bs e)
-> Finr (LetEF r _ _)
t :<$ InR (CaseEF e as)
-> _
unquantify :: Rlp.Type b
-> Rlp.Type b
unquantify (ForallT _ x) = unquantify x
unquantify x = x
typeToCore :: Rlp.Type PsName -> Core.Type
typeToCore = cata \case
VarTF n -> TyVar n
ConTF n -> TyCon n
FunTF -> TyFun
AppTF f x -> TyApp f x
-- TODO: we assume all quantified tyvars are of kind Type
ForallTF x m -> TyForall (MkVar x TyKindType) m
--------------------------------------------------------------------------------
exprToCore :: (NameSupply :> es) exprToCore :: (NameSupply :> es)
=> RlpExprF Var (Core.Expr Var) => RlpExpr PsName -> Eff es Core.Expr'
-> Eff es (Core.Expr Var) exprToCore = foldFixM \case
InL e -> pure $ Fix e
exprToCore (InL e) = pure . embed $ e InR e -> rlpExprToCore e
exprToCore (InR e) = exprToCore' e
exprToCore' :: (NameSupply :> es)
=> Rlp.ExprF Var (Core.Expr Var) -> Eff es (Core.Expr Var)
exprToCore' (CaseEF e as) = pure $ Case e (alterToCore <$> as)
exprToCore' _ = pure $ dummyExpr "expr"
alterToCore :: Rlp.Alter Var (Expr Var) -> Core.Alter Var
alterToCore (Rlp.Alter (ConP' (MkVar n _) bs) e)
= Core.Alter (AltData n) (noPatterns bs) e
noPatterns :: [Pat b] -> [b]
noPatterns ps = ps ^.. each . singular _VarP
--------------------------------------------------------------------------------
annotateVar :: Core.Type -> Core.ExprF PsName a -> Core.ExprF Var a
-- fix-points:
annotateVar _ (VarF n) = VarF n
annotateVar _ (ConF t a) = ConF t a
annotateVar _ (AppF f x) = AppF f x
annotateVar _ (LitF l) = LitF l
annotateVar _ (TypeF t) = TypeF t
rlpExprToCore :: (NameSupply :> es) rlpExprToCore :: (NameSupply :> es)
=> Rlp.ExprF PsName Core.Expr' -> Eff es Core.Expr' => Rlp.ExprF PsName Core.Expr' -> Eff es Core.Expr'
-- assume all binders are simple variable patterns for now -- assume all binders are simple variable patterns for now
rlpExprToCore (LetEF r bs e) = pure $ Let r bs' e rlpExprToCore (LetEF r bs e) = pure $ Let r bs' e

View File

@@ -1,8 +0,0 @@
/public/js
/node_modules
/target
/.shadow-cljs
/*.iml
/.nrepl-port
/.idea

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +0,0 @@
{
"devDependencies": {
"shadow-cljs": "^2.26.2"
},
"dependencies": {
"ace-builds": "^1.32.7",
"react": "16.13.0",
"react-ace": "^10.1.0",
"react-dom": "16.13.0"
}
}

View File

@@ -1,99 +0,0 @@
@import "solarized.css";
html, body
{ height: 100%
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
overflow: hidden;
}
.editor-container
{ position: relative
; height: 80vh
}
#editor
{ width: 100%;
; height: 100%
; position: relative
}
#type-check-button {
position: fixed;
top: 0;
left: 50%;
z-index: 2;
/* margin: 0 auto; */
transform: translateX(-50%);
}
#type-check-output
{ background: green
; width: 100%
; height: 100%
}
.main-view-container
{ columns: 2 auto;
}
.split {
height: 100%;
width: 50%;
position: fixed;
z-index: 1;
top: 0;
overflow-x: hidden;
padding-top: 20px;
}
.left {
left: 0;
}
.right {
right: 0;
}
.annotation-wrapper
{ display: inline-flex
; flex-direction: column
/* ; border-style: solid */
/* ; border-width: 0 0 0.45em 0 */
}
.typed-wrapper
{ display: inline-block
}
.annotation-wrapper .annotation
{ position: relative
; bottom: 0
; min-height: 0.60em
}
.annotation-text
{ display: none
}
.annotation.hovering > .annotation-text
{ display: inline-block
}
.code-wrapper
{ display: inline-block
}
code
{ font-family: monospace
; font-size: 1em
}
/* .typed-wrapper.hovering > .code-wrapper */
/* { border-width: 0.2em */
/* ; border-style: solid */
/* } */

View File

@@ -1,303 +0,0 @@
@import url(http://fonts.googleapis.com/css?family=PT+Sans);
@import url(http://fonts.googleapis.com/css?family=PT+Sans+Narrow:400,700);
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
nav,
section,
summary {
display: block;
}
audio,
canvas,
video {
display: inline-block;
}
audio:not([controls]) {
display: none;
height: 0;
}
[hidden] {
display: none;
}
html {
font-family: sans-serif;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
body {
margin: 0;
}
a:focus {
outline: thin dotted;
}
a:active,
a:hover {
outline: 0;
}
h1 {
font-size: 2em;
}
abbr[title] {
border-bottom: 1px dotted;
}
b,
strong {
font-weight: bold;
}
dfn {
font-style: italic;
}
mark {
background: #ff0;
color: #000;
}
code,
kbd,
pre,
samp {
font-family: monospace, serif;
font-size: 1em;
}
pre {
white-space: pre-wrap;
word-wrap: break-word;
}
q {
quotes: "\201C" "\201D" "\2018" "\2019";
}
small {
font-size: 80%;
}
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sup {
top: -0.5em;
}
sub {
bottom: -0.25em;
}
img {
border: 0;
}
svg:not(:root) {
overflow: hidden;
}
figure {
margin: 0;
}
fieldset {
border: 1px solid #c0c0c0;
margin: 0 2px;
padding: 0.35em 0.625em 0.75em;
}
legend {
border: 0;
padding: 0;
}
button,
input,
select,
textarea {
font-family: inherit;
font-size: 100%;
margin: 0;
}
button,
input {
line-height: normal;
}
button,
html input[type="button"],
input[type="reset"],
input[type="submit"] {
-webkit-appearance: button;
cursor: pointer;
}
button[disabled],
input[disabled] {
cursor: default;
}
input[type="checkbox"],
input[type="radio"] {
box-sizing: border-box;
padding: 0;
}
input[type="search"] {
-webkit-appearance: textfield;
-moz-box-sizing: content-box;
-webkit-box-sizing: content-box;
box-sizing: content-box;
}
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
button::-moz-focus-inner,
input::-moz-focus-inner {
border: 0;
padding: 0;
}
textarea {
overflow: auto;
vertical-align: top;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
html {
font-family: 'PT Sans', sans-serif;
}
pre,
code {
font-family: 'Inconsolata', sans-serif;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: 'PT Sans Narrow', sans-serif;
font-weight: 700;
}
html {
background-color: #eee8d5;
color: #657b83;
margin: 1em;
}
body {
background-color: #fdf6e3;
margin: 0 auto;
max-width: 23cm;
border: 1pt solid #93a1a1;
padding: 1em;
}
code {
background-color: #eee8d5;
padding: 2px;
}
a {
color: #b58900;
}
a:visited {
color: #cb4b16;
}
a:hover {
color: #cb4b16;
}
h1 {
color: #d33682;
}
h2,
h3,
h4,
h5,
h6 {
color: #859900;
}
pre {
background-color: #fdf6e3;
color: #657b83;
border: 1pt solid #93a1a1;
padding: 1em;
box-shadow: 5pt 5pt 8pt #eee8d5;
}
pre code {
background-color: #fdf6e3;
}
h1 {
font-size: 2.8em;
}
h2 {
font-size: 2.4em;
}
h3 {
font-size: 1.8em;
}
h4 {
font-size: 1.4em;
}
h5 {
font-size: 1.3em;
}
h6 {
font-size: 1.15em;
}
.tag {
background-color: #eee8d5;
color: #d33682;
padding: 0 0.2em;
}
.todo,
.next,
.done {
color: #fdf6e3;
background-color: #dc322f;
padding: 0 0.2em;
}
.tag {
-webkit-border-radius: 0.35em;
-moz-border-radius: 0.35em;
border-radius: 0.35em;
}
.TODO {
-webkit-border-radius: 0.2em;
-moz-border-radius: 0.2em;
border-radius: 0.2em;
background-color: #2aa198;
}
.NEXT {
-webkit-border-radius: 0.2em;
-moz-border-radius: 0.2em;
border-radius: 0.2em;
background-color: #268bd2;
}
.ACTIVE {
-webkit-border-radius: 0.2em;
-moz-border-radius: 0.2em;
border-radius: 0.2em;
background-color: #268bd2;
}
.DONE {
-webkit-border-radius: 0.2em;
-moz-border-radius: 0.2em;
border-radius: 0.2em;
background-color: #859900;
}
.WAITING {
-webkit-border-radius: 0.2em;
-moz-border-radius: 0.2em;
border-radius: 0.2em;
background-color: #cb4b16;
}
.HOLD {
-webkit-border-radius: 0.2em;
-moz-border-radius: 0.2em;
border-radius: 0.2em;
background-color: #d33682;
}
.NOTE {
-webkit-border-radius: 0.2em;
-moz-border-radius: 0.2em;
border-radius: 0.2em;
background-color: #d33682;
}
.CANCELLED {
-webkit-border-radius: 0.2em;
-moz-border-radius: 0.2em;
border-radius: 0.2em;
background-color: #859900;
}

View File

@@ -1,22 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/css/main.css">
<title>Hindley-Milner</title>
<style type="text/css" media="screen">
</style>
</head>
<body>
<div id="mount">
<div id="editor">
</div>
</div>
<script src="/js/main.js"></script>
</body>
</html>

View File

@@ -1,27 +0,0 @@
;; shadow-cljs configuration
{:source-paths
["src/"]
:dependencies
[[cider/cider-nrepl "0.24.0"]
[nilenso/wscljs "0.2.0"]
[org.clojure/core.match "1.1.0"]
[binaryage/oops "0.7.2"]
[reagent "0.10.0"]
[cljsjs/react "17.0.2-0"]
[cljsjs/react-dom "17.0.2-0"]
[cljsx "1.0.0"]]
:dev-http
{8020 "public"}
:builds
{:app
{:target :browser
:output-dir "public/js"
:asset-path "/js"
:modules
{:main ; becomes public/js/main.js
{:init-fn main/init}}}}}

View File

@@ -1,154 +0,0 @@
(ns hmvis.annotated
(:require [cljs.core.match :refer-macros [match]]
[cljsx.core :refer [jsx> react> defcomponent]]
[react :as react]
[react-dom :as react-dom]
[reagent.core :as r]
[reagent.dom :as rdom]
[clojure.pprint :refer [cl-format]]
[hmvis.ppr :as ppr]
[clojure.pprint :refer [pprint]]
[clojure.string :as str]))
(defonce tc-input (r/atom nil))
(defonce current-annotation-text (r/atom nil))
(defn unicodify [s]
(str/replace s #"->" "→"))
(defn punctuate [p & as]
(match as
[] ""
_ (reduce #(str %1 p %2) as)))
(defn hsep [& as]
(apply punctuate " " as))
(defn maybe-parens [c s]
(if c
[:<> "(" s ")"]
s))
(defn formatln [fs & rest]
(apply cl-format true (str fs "~%") rest))
(def nesting-rainbow (cycle ["red" "orange" "yellow"
"green" "blue" "purple"]))
(defn text-colour-by-background [colour]
(match colour
"yellow" "black"
_ "white"))
(defn Annotation [colour text hovering?]
[:div {:class (if @hovering?
"annotation hovering"
"annotation")
:on-mouse-enter #(reset! hovering? true)
:on-mouse-leave #(reset! hovering? false)
:style {:background colour
:color (text-colour-by-background colour)}}
[:div {:class "annotation-text"}
text]])
(defn Typed [colour t child]
(let [hovering? (r/atom false)]
(fn []
[:div {:class "annotation-wrapper"}
[:div {:class (if @hovering?
"typed-wrapper hovering"
"typed-wrapper")
}
[:div {:class "code-wrapper"} child]]
[Annotation colour (unicodify t) hovering?]])))
(declare Expr)
(defn LambdaExpr [colours binds body]
[:<>
[:code
(hsep "λ" (apply hsep binds) "-> ")]
[Expr colours 0 body]])
(defn VarExpr [var-id]
[:code var-id])
(defn AppExpr [colours f x]
[:<> [Expr colours ppr/app-prec f]
" "
[Expr colours ppr/app-prec1 x]])
(defn let-or-letrec [rec]
(match rec
"Rec" "letrec"
"NonRec" "let"))
(defn Pat [colours p {:keys [tag contents]}]
(match tag
"VarP" contents))
(defn Binding [colours {:keys [tag contents]}]
(match tag
"VarB" (let [[p v] contents]
[:<> [Pat colours 0 p] " = " [Expr colours 0 v]])))
(defn LetExpr [colours rec bs e]
[:<> (let-or-letrec rec)
" "
(apply punctuate "; " (map (partial Binding colours) bs))
" in "
(Expr colours 0 e)])
(defn LitExpr [_ l]
[:code (str l)])
(defn Alter [colours a]
(pprint a)
[:code "<alter>"])
(defn CaseExpr [colours e as]
[:<> "case " [Expr colours 0 e] " of { "
"<alters>"
" }"])
(defn Expr [[c & colours] p {e :e t :type}]
(match e
{:InL {:tag "LamF" :contents [bs body & _]}}
(maybe-parens (< ppr/app-prec1 p)
[Typed c t [LambdaExpr colours bs body]])
{:InL {:tag "VarF" :contents var-id}}
[Typed c t [VarExpr var-id]]
{:InL {:tag "AppF" :contents [f x]}}
(maybe-parens (< ppr/app-prec p)
[Typed c t [AppExpr colours f x]])
{:InR {:tag "LetEF" :contents [r bs body]}}
(maybe-parens (< ppr/app-prec1 p)
[Typed c t [LetExpr colours r bs body]])
{:InL {:tag "LitF" :contents l}}
[Typed c t [LitExpr colours l]]
{:InR {:tag "CaseEF" :contents [scrut as]}}
(maybe-parens (< ppr/app-prec1 p)
[Typed c t [CaseExpr colours scrut as]])
:else [:code "<expr>"]))
(def rainbow-cycle (cycle ["red"
"orange"
"yellow"
"green"
"blue"
"violet"]))
(defn render-decl [{name :name body :body}]
[:code {:key name :display "block"}
(str name " = ") [Expr rainbow-cycle 0 body] #_ (render-expr body)
[:br]])
(defn TypeChecker []
[:div
(map render-decl (or @tc-input []))])
; (defn init []
; (rdom/render [type-checker]
; (js/document.querySelector "#output")))

View File

@@ -1,41 +0,0 @@
(ns hmvis.ppr
(:require [cljs.core.match :refer-macros [match]]))
(def app-prec 10)
(def app-prec1 11)
(defn- maybe-parens [c s]
(if c
(str "(" s ")")
s))
(defn- hsep [& as]
(let [f (fn [a b] (str a " " b))]
(reduce f as)))
(declare expr)
(defn lambda-expr [binds body]
(hsep "λ" (apply hsep binds) "->" (expr body)))
(defn app-expr [f x]
(hsep (expr app-prec f) (expr app-prec1 x)))
(defn var-expr [var-id]
var-id)
(defn expr
([exp] (expr 0 exp))
([p {e :e}]
(match e
{:InL {:tag "LamF" :contents [bs body & _]}}
(maybe-parens (< app-prec1 p)
(lambda-expr bs body))
{:InL {:tag "VarF" :contents var-id}}
(var-expr var-id)
{:InL {:tag "AppF" :contents [f x]}}
(maybe-parens (< app-prec p)
(app-expr f x))
:else [:code "<expr>"])))

View File

@@ -1,103 +0,0 @@
(ns main
(:require [clojure.spec.alpha :as s]
["react-ace$default" :as AceEditor]
["ace-builds/src-noconflict/mode-haskell"]
["ace-builds/src-noconflict/theme-solarized_light"]
["ace-builds/src-noconflict/keybinding-vim"]
[wscljs.client :as ws]
[wscljs.format :as fmt]
[cljs.core.match :refer-macros [match]]
[hmvis.annotated :as annotated]
[reagent.core :as r]
[reagent.dom :as rdom]))
; (def *editor
; (doto (js/ace.edit "editor")
; (.setTheme "ace/theme/solarized_light")
; (.setKeyboardHandler "ace/keyboard/vim")
; (.setOption "mode" "ace/mode/haskell")))
(def *output (.querySelector js/document "#output"))
(defn display-errors [es]
(doseq [{{e :contents} :diagnostic} es]
(let [fmte (map #(str " • " % "\n") e)]
(js/console.warn (apply str "message from rlpc:\n" fmte)))))
(defn with-success [f ma]
(match ma
{:errors es :result nil} (display-errors es)
{:errors es :result a} (do (display-errors es)
(f a))))
(defn on-message [e]
(let [r (js->clj (js/JSON.parse (.-data e)) :keywordize-keys true)]
(match r
{:tag "Annotated" :contents c}
(with-success #(reset! annotated/tc-input %) c)
:else
(js/console.warn "unrecognisable response from rlp"))))
(defonce *socket (ws/create "ws://127.0.0.1:9002"
{:on-message on-message
:on-open #(println "socket opened")
:on-close #(println "socket closed")
:on-error #(println "error: " %)}))
(defn send [msg]
(ws/send *socket msg fmt/json))
(defonce *editor nil)
(defn TypeCheckButton []
[:button {:id "type-check-button"
:on-click #(send {:command "annotate"
:source (.getValue *editor)})}
"type-check"])
(defn Editor []
[:div {:class "editor-container"}
[(r/adapt-react-class AceEditor)
{:mode "haskell"
:theme "solarized_light"
:keyboardHandler "vim"
:defaultValue (str "id = \\x -> x\n"
"flip f x y = f y x\n"
"fix f = letrec x = f x in x")
:style {:width "100%"
:height "100%"}
:on-load (fn [editor]
(set! *editor editor)
(set! (.. editor -container -style -resize) "both")
(js/document.addEventListener
"mouseup"
#(.resize editor)))
:name "editor"} ]])
(defn Main []
[:<>
[:div {:class "main-view-container"}
[TypeCheckButton]
[Editor]
[annotated/TypeChecker]
#_ [:div {:id "type-check-output"}
"doge soge quoge"]]
#_ [annotated/TypeChecker]])
;; start is called by init and after code reloading finishes
(defn ^:dev/after-load start []
(rdom/render [Main]
(js/document.getElementById "mount"))
(js/console.log "start"))
(defn init []
;; init is called ONCE when the page loads
;; this is called in the index.html and must be exported
;; so it is available even in :advanced release builds
(js/console.log "init")
(start))
;; this is called before any code is reloaded
(defn ^:dev/before-load stop []
(js/console.log "stop"))