1
1
mirror of https://github.com/anoma/juvix.git synced 2024-12-26 17:13:35 +03:00
juvix/app/Evaluator.hs
Jan Mas Rovira 2d36a65324
Make compile targets a subcommand instead of a flag (#2700)
# Changes
The main goal of this pr is to remove the `--target` flag for `juvix
compile` and use subcommands instead. The targets that are relevant to
normal users are found in `juvix compile --help`. Targets that are
relevant only to developers are found in `juvix dev compile --help`.

Below I list some of the changes in more detail.
## Compile targets for user-facing languages
- `juvix compile native`
- `juvix compile wasi`. I wasn't sure how to call this: `wasm`,
`wasm32-wasi`, etc. In the end I thought `wasi` was short and accurate,
but we can change it.
- `juvix compile vampir`
- `juvix compile anoma`
- `juvix compile cairo`
## *New* compile targets for internal languages
See `juvix dev compile --help`.

1. `dev compile core` has the same behaviour as `dev core
from-concrete`. The `dev core from-concrete` is redundant at the moment.
2. `dev compile tree` compiles to Tree and prints the InfoTable to the
output file wihout any additional checks.
3. `dev compile reg` compiles to Reg and prints the InfoTable to the
output file wihout any additional checks.
4. `dev compile asm` compiles to Asm and prints the InfoTable to the
output file wihout any additional checks.
5. 4. `dev compile casm` compiles to Asm and prints the Result to the
output file wihout any additional checks. TODO: should the Result be
printed or something else? At the moment the Result lacks a pretty
instance.
6. 
## Optional input file
1. The input file for commands that expect a .juvix file as input is now
optional. If the argument is ommited, he main file given in the
package.yaml will be used. This applies to the following commands:
   1. `juvix compile [native|wasi|geb|vampir|anoma|cairo]`
   8.  `juvix dev compile [core|reg|tree|casm|asm]`
   1. `juvix html`
   3. `juvix markdown`.
   4. `juvix dev internal [typecheck|pretty]`.
   5. `juvix dev [parse|scope]`
   7. `juvix compile [native|wasi|geb|vampir|anoma|cairo]`
   9. note that `juvix format` has not changed its behaviour.

## Refactor some C-like compiler flags
Both `juvix compile native` and `juvix compile wasi` support `--only-c`
(`-C`), `--only-preprocess` (`-E`), `--only-assemble` (`-S`). I propose
to deviate from the `gcc` style and instead use a flag with a single
argument:
- `--cstage [source|preprocess|assembly|exec(default)]`. I'm open to
suggestions. For now, I've kept the legacy flags but marked them as
deprecated in the help message.

## Remove code duplication
I've tried to reduce code duplication. This is sometimes in tension with
code readability so I've tried to find a good balance. I've tried to
make it so we don't have to jump to many different files to understand
what a single command is doing. I'm sure there is still room for
improvement.

## Other refactors
I've implemented other small refactors that I considered improved the
quality of the code.

## TODO/Future work
We should refactor commands (under `compile dev`) which still use
`module Commands.Extra.Compile` and remove it.
2024-04-09 13:29:07 +02:00

105 lines
3.3 KiB
Haskell

module Evaluator where
import App
import CommonOptions
import Juvix.Compiler.Core qualified as Core
import Juvix.Compiler.Core.Extra.Value qualified as Core
import Juvix.Compiler.Core.Info qualified as Info
import Juvix.Compiler.Core.Info.NoDisplayInfo qualified as Info
import Juvix.Compiler.Core.Normalizer
import Juvix.Compiler.Core.Pretty qualified as Core
import Juvix.Compiler.Core.Transformation.DisambiguateNames qualified as Core
data EvalOptions = EvalOptions
{ _evalInputFile :: AppPath File,
_evalNoIO :: Bool,
_evalNoDisambiguate :: Bool,
_evalPrintValues :: Bool
}
makeLenses ''EvalOptions
evalAndPrint' ::
forall r.
(Members '[EmbedIO, App] r) =>
Core.CoreOptions ->
Core.Options ->
EvalOptions ->
Core.InfoTable ->
Core.Node ->
Sem r ()
evalAndPrint' gopts copts eopts tab node = do
loc <- defaultLoc
r <- Core.doEval (Just $ project gopts ^. Core.optFieldSize) (eopts ^. evalNoIO) loc tab node
case r of
Left err -> exitJuvixError (JuvixError err)
Right node'
| Info.member Info.kNoDisplayInfo (Core.getInfo node') ->
return ()
Right node'
| eopts ^. evalPrintValues -> do
renderStdOut (Core.ppOut copts (Core.toValue tab node'))
newline
| otherwise -> do
renderStdOut (Core.ppOut copts node'')
newline
where
node'' = if project eopts ^. evalNoDisambiguate then node' else Core.disambiguateNodeNames (Core.moduleFromInfoTable tab) node'
where
defaultLoc :: Sem r Interval
defaultLoc = singletonInterval . mkInitialLoc <$> fromAppPathFile f
f :: AppPath File
f = eopts ^. evalInputFile
evalAndPrint ::
forall r evalOptions coreOptions.
( Members '[EmbedIO, App] r,
CanonicalProjection coreOptions Core.CoreOptions,
CanonicalProjection evalOptions EvalOptions,
CanonicalProjection evalOptions Core.Options
) =>
coreOptions ->
evalOptions ->
Core.InfoTable ->
Core.Node ->
Sem r ()
evalAndPrint gopts opts = evalAndPrint' (project gopts) (project opts) (project opts)
normalizeAndPrint ::
forall r evalOptions coreOptions.
( Members '[EmbedIO, App] r,
CanonicalProjection evalOptions EvalOptions,
CanonicalProjection coreOptions Core.CoreOptions,
CanonicalProjection coreOptions Core.Options
) =>
evalOptions ->
coreOptions ->
Core.InfoTable ->
Core.Node ->
Sem r ()
normalizeAndPrint eopts copts = normalizeAndPrint' eopts copts copts
normalizeAndPrint' ::
forall r evalOptions coreOptions corePretty.
( Members '[EmbedIO, App] r,
CanonicalProjection evalOptions EvalOptions,
CanonicalProjection coreOptions Core.CoreOptions,
CanonicalProjection corePretty Core.Options
) =>
evalOptions ->
coreOptions ->
corePretty ->
Core.InfoTable ->
Core.Node ->
Sem r ()
normalizeAndPrint' eopts_ copts_ popts_ tab node =
let eopts :: EvalOptions = project eopts_
copts :: Core.CoreOptions = project copts_
popts :: Core.Options = project popts_
node' = normalize (copts ^. Core.optFieldSize) (Core.moduleFromInfoTable tab) node
in unless (Info.member Info.kNoDisplayInfo (Core.getInfo node')) $ do
let node'' = if eopts ^. evalNoDisambiguate then node' else Core.disambiguateNodeNames (Core.moduleFromInfoTable tab) node'
renderStdOut (Core.ppOut popts node'')
putStrLn ""