Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Geb Backend Evaluator with some extra subcommands #1808

Merged
merged 60 commits into from Feb 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
1173431
w.i.p geb-evaluator
jonaprieto Feb 3, 2023
01b2bc5
Fix mostly all merging conflicts. It needs the geb-eval update with n…
jonaprieto Feb 3, 2023
976787a
Add missing cases to eval
jonaprieto Feb 3, 2023
c9945db
Use indent' instead
jonaprieto Feb 3, 2023
a64d756
w.i.p
jonaprieto Feb 6, 2023
2863e23
save progress, now using effects
jonaprieto Feb 7, 2023
1801ba6
Fix CLI and more polysemy stuff
jonaprieto Feb 7, 2023
2ea9b40
Make pre-commit happy
jonaprieto Feb 7, 2023
919e802
Add some revisions
jonaprieto Feb 8, 2023
adbad1d
Enough to use all Geb: import Juvix.Compiler.Backend.Geb qualified as…
jonaprieto Feb 8, 2023
848b3c3
Enough to use all Geb: import Juvix.Compiler.Backend.Geb qualified as…
jonaprieto Feb 8, 2023
e2b0d75
Remove T flag
jonaprieto Feb 8, 2023
cd3d920
w.i.p adding geb lisp parser and tests
jonaprieto Feb 9, 2023
e8de2e5
Add smoke tests
jonaprieto Feb 9, 2023
c986531
Add template for testing geb eval
jonaprieto Feb 9, 2023
f1a68ab
Fix: dev geb read (lisp files)
jonaprieto Feb 9, 2023
fdab3d0
Add dev geb infer command
jonaprieto Feb 9, 2023
b3871a3
save progress, working on the tests
jonaprieto Feb 10, 2023
ba7958b
Add better formatter for geb morphisms
jonaprieto Feb 10, 2023
077d01d
Add some revisions and examples
jonaprieto Feb 10, 2023
0326f96
Debugging and organizing Evaluator folder
jonaprieto Feb 10, 2023
cd8b1d3
Add TODOs for test
jonaprieto Feb 10, 2023
11821ec
Use BackendGeb for tests
jonaprieto Feb 10, 2023
2e087cc
Ready for testing
jonaprieto Feb 14, 2023
caec29f
fix some smoke tests and evalError
jonaprieto Feb 15, 2023
250c5d3
adding check utility
jonaprieto Feb 15, 2023
714ae32
Fix check and base for tests
jonaprieto Feb 15, 2023
8451592
Make pre-commit happy
jonaprieto Feb 15, 2023
5150226
Makefile work
jonaprieto Feb 15, 2023
1b3d2f4
Use latest commit on Juvix-Stdlib main branch
jonaprieto Feb 15, 2023
397f64d
Make ormolu happy
jonaprieto Feb 15, 2023
f2e6465
relax smoke test for root cmd
jonaprieto Feb 15, 2023
fd197fc
Refactor geb repl
jonaprieto Feb 15, 2023
0b0ed50
Respect color scheme for errors
jonaprieto Feb 15, 2023
4422c03
Add error types for check/infer functions
jonaprieto Feb 15, 2023
b6bbc5c
Make pre-commit happy
jonaprieto Feb 15, 2023
9423ad9
Fix JuvixGeb tests
jonaprieto Feb 15, 2023
6175a40
Add first round of revisions
jonaprieto Feb 15, 2023
4ae59e0
Run CoreToGeb for testing
jonaprieto Feb 16, 2023
223bf9f
Add case-on test
jonaprieto Feb 16, 2023
4be0509
Remove unused import
jonaprieto Feb 16, 2023
60883ea
Added another test
jonaprieto Feb 16, 2023
7e04b32
Investigating an issue with Env for Geb
jonaprieto Feb 16, 2023
1de823c
remove unnecessary type
jonaprieto Feb 17, 2023
eba3245
Add some testing.
jonaprieto Feb 17, 2023
75173d3
Debugging test002.lisp
jonaprieto Feb 18, 2023
d5f9a52
Add retry progress
jonaprieto Feb 20, 2023
489ae11
add feb21 progress
jonaprieto Feb 21, 2023
831f9a7
Add geb eval tests
jonaprieto Feb 21, 2023
694b3aa
Seems ready for review
jonaprieto Feb 21, 2023
e138ae4
remove unnecessary file
jonaprieto Feb 21, 2023
96d45e7
remove autogenerated files
lukaszcz Feb 21, 2023
28cd2fe
remove autogenerated file
lukaszcz Feb 21, 2023
95867d0
Restructure test files
jonaprieto Feb 21, 2023
a4eee12
Remove strategies for eval.
jonaprieto Feb 21, 2023
9717311
Simplify pretty printer for Geb values
jonaprieto Feb 21, 2023
d12cafa
Fix smoke tests
jonaprieto Feb 21, 2023
2b06875
remove redudant import
jonaprieto Feb 21, 2023
f93529b
Remove comment
jonaprieto Feb 22, 2023
4cace44
Remove redundant imports
jonaprieto Feb 22, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 4 additions & 4 deletions Makefile
Expand Up @@ -22,6 +22,9 @@ EXAMPLE_WEBAPP_OUTPUT=_docs/examples/webapp
WEBAPP_EXAMPLES=TicTacToe/Web/TicTacToe.juvix
DEMO_EXAMPLE=examples/demo/Demo.juvix

MAKEAUXFLAGS?=-s
MAKE=make ${MAKEAUXFLAGS}

ORGTOMDPRG ?=pandoc
ORGOPTS=--from org --to markdown_strict -s -o $@

Expand All @@ -46,7 +49,7 @@ clean: clean-runtime

.PHONY: clean-runtime
clean-runtime: clean-juvix-build
@cd runtime && make clean
@cd runtime && ${MAKE} clean

.PHONY: clean-juvix-build
clean-juvix-build:
Expand Down Expand Up @@ -130,9 +133,6 @@ haddock :
# -- Codebase Health
# ------------------------------------------------------------------------------

MAKEAUXFLAGS?=-s
MAKE=make ${MAKEAUXFLAGS}

ORMOLU?=stack exec -- ormolu
ORMOLUFILES = $(shell git ls-files '*.hs' '*.hs-boot' | grep -v '^contrib/')
ORMOLUFLAGS?=--no-cabal
Expand Down
2 changes: 2 additions & 0 deletions app/Commands/Dev.hs
Expand Up @@ -8,6 +8,7 @@ import Commands.Base
import Commands.Dev.Asm qualified as Asm
import Commands.Dev.Core qualified as Core
import Commands.Dev.DisplayRoot qualified as DisplayRoot
import Commands.Dev.Geb qualified as Geb
import Commands.Dev.Highlight qualified as Highlight
import Commands.Dev.Internal qualified as Internal
import Commands.Dev.MiniC qualified as MiniC
Expand All @@ -26,6 +27,7 @@ runCommand = \case
MiniC opts -> MiniC.runCommand opts
Termination opts -> Termination.runCommand opts
Core opts -> Core.runCommand opts
Geb opts -> Geb.runCommand opts
Asm opts -> Asm.runCommand opts
Runtime opts -> Runtime.runCommand opts
DisplayRoot opts -> DisplayRoot.runCommand opts
10 changes: 9 additions & 1 deletion app/Commands/Dev/Core/Read.hs
Expand Up @@ -8,7 +8,15 @@ import Juvix.Compiler.Core.Scoper qualified as Scoper
import Juvix.Compiler.Core.Transformation qualified as Core
import Juvix.Compiler.Core.Translation.FromSource qualified as Core

runCommand :: forall r a. (Members '[Embed IO, App] r, CanonicalProjection a Eval.EvalOptions, CanonicalProjection a Core.Options, CanonicalProjection a CoreReadOptions) => a -> Sem r ()
runCommand ::
forall r a.
( Members '[Embed IO, App] r,
CanonicalProjection a Eval.EvalOptions,
CanonicalProjection a Core.Options,
CanonicalProjection a CoreReadOptions
) =>
a ->
Sem r ()
runCommand opts = do
inputFile :: Path Abs File <- someBaseToAbs' sinputFile
s' <- embed . readFile . toFilePath $ inputFile
Expand Down
21 changes: 21 additions & 0 deletions app/Commands/Dev/Geb.hs
@@ -0,0 +1,21 @@
module Commands.Dev.Geb
( module Commands.Dev.Geb,
module Commands.Dev.Geb.Options,
)
where

import Commands.Base
import Commands.Dev.Geb.Eval as Eval
import Commands.Dev.Geb.Infer as Check
import Commands.Dev.Geb.Infer as Infer
import Commands.Dev.Geb.Options
import Commands.Dev.Geb.Read as Read
import Commands.Dev.Geb.Repl as Repl

runCommand :: forall r. (Members '[Embed IO, App] r) => GebCommand -> Sem r ()
runCommand = \case
GebCommandRepl opts -> Repl.runCommand opts
GebCommandEval opts -> Eval.runCommand opts
GebCommandRead opts -> Read.runCommand opts
GebCommandInfer opts -> Infer.runCommand opts
GebCommandCheck opts -> Check.runCommand opts
23 changes: 23 additions & 0 deletions app/Commands/Dev/Geb/Check.hs
@@ -0,0 +1,23 @@
module Commands.Dev.Geb.Check where

import Commands.Base
import Commands.Dev.Geb.Infer.Options
import Juvix.Compiler.Backend.Geb qualified as Geb
import Juvix.Compiler.Backend.Geb.Analysis.TypeChecking.Error

runCommand ::
forall r.
(Member App r, Member (Embed IO) r) =>
GebInferOptions ->
Sem r ()
runCommand opts = do
let b :: SomeBase File
b = opts ^. gebInferOptionsInputFile . pathPath
f :: Path Abs File <- someBaseToAbs' b
content :: Text <- embed (readFile (toFilePath f))
case Geb.runParser' f content of
Right tyMorph@(Geb.TypedMorphism {}) -> do
case run . runError @CheckingError $ (Geb.check' tyMorph) of
Left err -> exitJuvixError (JuvixError err)
Right _ -> renderStdOut ("Well done! It typechecks" :: Text)
Left err -> exitJuvixError (JuvixError err)
54 changes: 54 additions & 0 deletions app/Commands/Dev/Geb/Eval.hs
@@ -0,0 +1,54 @@
module Commands.Dev.Geb.Eval where

import Commands.Base
import Commands.Dev.Geb.Eval.Options
import Juvix.Compiler.Backend.Geb.Evaluator qualified as Geb
import Juvix.Compiler.Backend.Geb.Language qualified as Geb
import Juvix.Compiler.Backend.Geb.Pretty qualified as Geb
import Juvix.Compiler.Backend.Geb.Translation.FromSource qualified as Geb

runCommand ::
forall r a.
( Members '[App, Embed IO] r,
CanonicalProjection a Geb.EvaluatorOptions,
CanonicalProjection a GebEvalOptions
) =>
a ->
Sem r ()
runCommand opts = do
let b :: SomeBase File
b = project opts ^. gebEvalOptionsInputFile . pathPath
f :: Path Abs File <- someBaseToAbs' b
content :: Text <- embed (readFile (toFilePath f))
case Geb.runParser f content of
Left err -> exitJuvixError (JuvixError err)
Right gebTerm -> do
evalAndPrint opts gebTerm
embed (putStrLn "")

evalAndPrint ::
forall r a.
( Members '[App, Embed IO] r,
CanonicalProjection a Geb.EvaluatorOptions
) =>
a ->
Geb.Expression ->
Sem r ()
evalAndPrint opts = \case
Geb.ExpressionMorphism morphism -> do
let opts' :: Geb.EvaluatorOptions = project opts
let env :: Geb.Env =
Geb.Env
{ _envEvaluatorOptions = opts',
_envContext = mempty
}
if
| opts' ^. Geb.evaluatorOptionsOutputMorphism ->
case Geb.evalAndOutputMorphism' env morphism of
Left err -> exitJuvixError err
Right m -> renderStdOut (Geb.ppOut opts' m)
lukaszcz marked this conversation as resolved.
Show resolved Hide resolved
| otherwise ->
case Geb.eval' env morphism of
Left err -> exitJuvixError err
Right m -> renderStdOut (Geb.ppOut opts' m)
Geb.ExpressionObject _ -> error Geb.objNoEvalMsg
37 changes: 37 additions & 0 deletions app/Commands/Dev/Geb/Eval/Options.hs
@@ -0,0 +1,37 @@
module Commands.Dev.Geb.Eval.Options where

import CommonOptions
import Juvix.Compiler.Backend.Geb.Evaluator qualified as Geb
import Juvix.Compiler.Backend.Geb.Pretty qualified as Geb

data GebEvalOptions = GebEvalOptions
{ _gebEvalOptionsInputFile :: AppPath File,
_gebEvalOptionsOutputMorphism :: Bool
}
deriving stock (Data)

makeLenses ''GebEvalOptions

instance CanonicalProjection GebEvalOptions Geb.EvaluatorOptions where
project x =
Geb.EvaluatorOptions
{ _evaluatorOptionsOutputMorphism = (x ^. gebEvalOptionsOutputMorphism)
}

instance CanonicalProjection GebEvalOptions Geb.Options where
project _ = Geb.defaultOptions

parseGebEvalOptions :: Parser GebEvalOptions
parseGebEvalOptions = do
_gebEvalOptionsInputFile <- parseInputJuvixGebFile
_gebEvalOptionsOutputMorphism <- optOutputMorphism
pure GebEvalOptions {..}

optOutputMorphism :: Parser Bool
optOutputMorphism =
switch
( long "output-morphism"
<> short 'm'
<> showDefault
<> help "Output a Geb morphism back from a Geb value"
)
24 changes: 24 additions & 0 deletions app/Commands/Dev/Geb/Infer.hs
@@ -0,0 +1,24 @@
module Commands.Dev.Geb.Infer where

import Commands.Base
import Commands.Dev.Geb.Infer.Options
import Juvix.Compiler.Backend.Geb qualified as Geb

runCommand ::
forall r.
(Member App r, Member (Embed IO) r) =>
GebInferOptions ->
Sem r ()
runCommand opts = do
let b :: SomeBase File
b = opts ^. gebInferOptionsInputFile . pathPath
f :: Path Abs File <- someBaseToAbs' b
content :: Text <- embed (readFile (toFilePath f))
case Geb.runParser f content of
Right (Geb.ExpressionMorphism gebTerm) ->
case Geb.inferObject' gebTerm of
Left err -> exitJuvixError (JuvixError err)
Right obj -> renderStdOut (Geb.ppOut opts obj)
Right (Geb.ExpressionObject _) ->
exitJuvixError (error @JuvixError "No inference for objects")
Left err -> exitJuvixError (JuvixError err)
19 changes: 19 additions & 0 deletions app/Commands/Dev/Geb/Infer/Options.hs
@@ -0,0 +1,19 @@
module Commands.Dev.Geb.Infer.Options where

import CommonOptions
import Juvix.Compiler.Backend.Geb.Pretty qualified as Geb

newtype GebInferOptions = GebInferOptions
{ _gebInferOptionsInputFile :: AppPath File
}
deriving stock (Data)

makeLenses ''GebInferOptions

instance CanonicalProjection GebInferOptions Geb.Options where
project _ = Geb.defaultOptions

parseGebInferOptions :: Parser GebInferOptions
parseGebInferOptions = do
_gebInferOptionsInputFile <- parseInputJuvixGebFile
pure GebInferOptions {..}
76 changes: 76 additions & 0 deletions app/Commands/Dev/Geb/Options.hs
@@ -0,0 +1,76 @@
module Commands.Dev.Geb.Options
( module Commands.Dev.Geb.Options,
module Commands.Dev.Geb.Eval.Options,
module Commands.Dev.Geb.Repl.Options,
)
where

import Commands.Dev.Geb.Eval.Options
import Commands.Dev.Geb.Infer.Options
import Commands.Dev.Geb.Read.Options
import Commands.Dev.Geb.Repl.Options
import CommonOptions

data GebCommand
= GebCommandRepl GebReplOptions
| GebCommandEval GebEvalOptions
| GebCommandRead GebReadOptions
| GebCommandInfer GebInferOptions
| GebCommandCheck GebInferOptions
deriving stock (Data)

parseGebCommand :: Parser GebCommand
parseGebCommand =
hsubparser $
mconcat
[ commandRepl,
commandEval,
commandRead,
commandInfer,
commandCheck
]
where
commandRepl :: Mod CommandFields GebCommand
commandRepl = command "repl" replInfo

commandEval :: Mod CommandFields GebCommand
commandEval = command "eval" evalInfo

commandRead :: Mod CommandFields GebCommand
commandRead = command "read" readInfo

commandInfer :: Mod CommandFields GebCommand
commandInfer = command "infer" inferInfo

commandCheck :: Mod CommandFields GebCommand
commandCheck = command "check" checkInfo

replInfo :: ParserInfo GebCommand
replInfo =
info
(GebCommandRepl <$> parseGebReplOptions)
(progDesc "Start an interactive session of the JuvixGeb evaluator")

evalInfo :: ParserInfo GebCommand
evalInfo =
info
(GebCommandEval <$> parseGebEvalOptions)
(progDesc "Evaluate a JuvixGeb file and pretty print the result")

readInfo :: ParserInfo GebCommand
readInfo =
info
(GebCommandRead <$> parseGebReadOptions)
(progDesc "Read a JuvixGeb file and pretty print it")

inferInfo :: ParserInfo GebCommand
inferInfo =
info
(GebCommandInfer <$> parseGebInferOptions)
(progDesc "Infer the Geb object for a Geb morphism found in the given file. ")

checkInfo :: ParserInfo GebCommand
checkInfo =
info
(GebCommandInfer <$> parseGebInferOptions)
(progDesc "Check the given Geb object matches the given Geb morphism")
22 changes: 22 additions & 0 deletions app/Commands/Dev/Geb/Read.hs
@@ -0,0 +1,22 @@
module Commands.Dev.Geb.Read where

import Commands.Base
import Commands.Dev.Geb.Read.Options
import Juvix.Compiler.Backend.Geb.Pretty qualified as Geb
import Juvix.Compiler.Backend.Geb.Translation.FromSource qualified as Geb

runCommand ::
forall r.
(Member App r, Member (Embed IO) r) =>
GebReadOptions ->
Sem r ()
runCommand opts = do
let b :: SomeBase File
b = opts ^. gebReadOptionsInputFile . pathPath
f :: Path Abs File <- someBaseToAbs' b
content :: Text <- embed (readFile (toFilePath f))
case Geb.runParser f content of
Left err -> exitJuvixError (JuvixError err)
Right gebTerm -> do
renderStdOut (Geb.ppOut opts gebTerm)
embed (putStrLn "")
19 changes: 19 additions & 0 deletions app/Commands/Dev/Geb/Read/Options.hs
@@ -0,0 +1,19 @@
module Commands.Dev.Geb.Read.Options where

import CommonOptions
import Juvix.Compiler.Backend.Geb.Pretty qualified as Geb

newtype GebReadOptions = GebReadOptions
{ _gebReadOptionsInputFile :: AppPath File
}
deriving stock (Data)

makeLenses ''GebReadOptions

instance CanonicalProjection GebReadOptions Geb.Options where
project _ = Geb.defaultOptions

parseGebReadOptions :: Parser GebReadOptions
parseGebReadOptions = do
_gebReadOptionsInputFile <- parseInputJuvixGebFile
pure GebReadOptions {..}