mirror of
https://github.com/anoma/juvix.git
synced 2024-12-19 04:41:36 +03:00
73364f4887
This PR is a snapshot of the current work on the JuvixAsm -> Nockma
translation. The compilation of Juvix programs to Nockma now works so we
decided to raise this PR now to avoid it getting too large.
## Juvix -> Nockma compilation
You can compile a frontend Juvix file to Nockma as follows:
example.juvix
```
module example;
import Stdlib.Prelude open;
fib : Nat → Nat → Nat → Nat
| zero x1 _ := x1
| (suc n) x1 x2 := fib n x2 (x1 + x2);
fibonacci (n : Nat) : Nat := fib n 0 1;
sumList (xs : List Nat) : Nat :=
for (acc := 0) (x in xs)
acc + x;
main : Nat := fibonacci 9 + sumList [1; 2; 3; 4];
```
```
$ juvix compile -t nockma example.juvix
```
This will generate a file `example.nockma` which can be run using the
nockma evaluator:
```
$ juvix dev nockma eval example.nockma
```
Alternatively you can compile JuvixAsm to Nockma:
```
$ juvix dev asm compile -t nockma example.jva
```
## Tests
We compile an evaluate the JuvixAsm tests in
cb3659e08e/test/Nockma/Compile/Asm/Positive.hs
We currently skip some because either:
1. They are too slow to run in the current evaluator (due to arithmetic
operations using the unjetted nock code from the anoma nock stdlib).
2. They trace data types like lists and booleans which are represented
differently by the asm interpreter and the nock interpreter
3. They operate on raw negative numbers, nock only supports raw natural
numbers
## Next steps
On top of this PR we will work on improving the evaluator so that we can
enable the slow compilation tests.
---------
Co-authored-by: Paul Cadman <git@paulcadman.dev>
Co-authored-by: Lukasz Czajka <lukasz@heliax.dev>
39 lines
1.6 KiB
Haskell
39 lines
1.6 KiB
Haskell
module Commands.Compile where
|
|
|
|
import Commands.Base
|
|
import Commands.Compile.Options
|
|
import Commands.Dev.Core.Compile.Base qualified as Compile
|
|
import Commands.Extra.Compile qualified as Compile
|
|
import Juvix.Compiler.Core qualified as Core
|
|
import Juvix.Compiler.Core.Pretty qualified as Core
|
|
import Juvix.Compiler.Core.Transformation.DisambiguateNames qualified as Core
|
|
|
|
runCommand :: (Members '[Embed IO, App, TaggedLock] r) => CompileOptions -> Sem r ()
|
|
runCommand opts@CompileOptions {..} = do
|
|
inputFile <- getMainFile _compileInputFile
|
|
Core.CoreResult {..} <- runPipeline (AppPath (preFileFromAbs inputFile) True) upToCore
|
|
let arg =
|
|
Compile.PipelineArg
|
|
{ _pipelineArgFile = inputFile,
|
|
_pipelineArgOptions = opts,
|
|
_pipelineArgModule = _coreResultModule
|
|
}
|
|
case _compileTarget of
|
|
TargetNative64 -> Compile.runCPipeline arg
|
|
TargetWasm32Wasi -> Compile.runCPipeline arg
|
|
TargetGeb -> Compile.runGebPipeline arg
|
|
TargetVampIR -> Compile.runVampIRPipeline arg
|
|
TargetCore -> writeCoreFile arg
|
|
TargetAsm -> Compile.runAsmPipeline arg
|
|
TargetNockma -> Compile.runNockmaPipeline arg
|
|
|
|
writeCoreFile :: (Members '[Embed IO, App, TaggedLock] r) => Compile.PipelineArg -> Sem r ()
|
|
writeCoreFile pa@Compile.PipelineArg {..} = do
|
|
entryPoint <- Compile.getEntry pa
|
|
coreFile <- Compile.outputFile _pipelineArgOptions _pipelineArgFile
|
|
r <- runReader entryPoint . runError @JuvixError $ Core.toStored _pipelineArgModule
|
|
case r of
|
|
Left e -> exitJuvixError e
|
|
Right md ->
|
|
embed @IO (writeFile (toFilePath coreFile) (show $ Core.ppOutDefault (Core.disambiguateNames md ^. Core.moduleInfoTable)))
|