Skip to content

Commit

Permalink
JuvixReg parser and pretty printer (#2617)
Browse files Browse the repository at this point in the history
* Closes #2578 
* Implements JuvixReg parser and pretty printer.
* Adds the `juvix dev reg read file.jvr` command.
* Adds the `reg` target to the `compile` commands.
* Adds tests for the JuvixReg parser.
  • Loading branch information
lukaszcz authored Feb 9, 2024
1 parent 5dfafe0 commit ed15e57
Show file tree
Hide file tree
Showing 128 changed files with 5,433 additions and 387 deletions.
1 change: 1 addition & 0 deletions app/Commands/Compile.hs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ runCommand opts@CompileOptions {..} = do
TargetCore -> writeCoreFile arg
TargetTree -> Compile.runTreePipeline arg
TargetAsm -> Compile.runAsmPipeline arg
TargetReg -> Compile.runRegPipeline arg
TargetNockma -> Compile.runNockmaPipeline arg

writeCoreFile :: (Members '[Embed IO, App, TaggedLock] r) => Compile.PipelineArg -> Sem r ()
Expand Down
2 changes: 2 additions & 0 deletions app/Commands/Dev.hs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import Commands.Dev.MigrateJuvixYaml qualified as MigrateJuvixYaml
import Commands.Dev.Nockma qualified as Nockma
import Commands.Dev.Options
import Commands.Dev.Parse qualified as Parse
import Commands.Dev.Reg qualified as Reg
import Commands.Dev.Runtime qualified as Runtime
import Commands.Dev.Scope qualified as Scope
import Commands.Dev.Termination qualified as Termination
Expand All @@ -32,6 +33,7 @@ runCommand = \case
Core opts -> Core.runCommand opts
Geb opts -> Geb.runCommand opts
Asm opts -> Asm.runCommand opts
Reg opts -> Reg.runCommand opts
Tree opts -> Tree.runCommand opts
Casm opts -> Casm.runCommand opts
Runtime opts -> Runtime.runCommand opts
Expand Down
40 changes: 27 additions & 13 deletions app/Commands/Dev/Asm/Compile.hs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import Commands.Extra.Compile qualified as Compile
import Juvix.Compiler.Asm.Translation.FromSource qualified as Asm
import Juvix.Compiler.Backend qualified as Backend
import Juvix.Compiler.Backend.C qualified as C
import Juvix.Compiler.Reg.Pretty qualified as Reg

runCommand :: forall r. (Members '[Embed IO, App, TaggedLock] r) => AsmCompileOptions -> Sem r ()
runCommand opts = do
Expand All @@ -22,19 +23,31 @@ runCommand opts = do
{ _entryPointTarget = tgt,
_entryPointDebug = opts ^. compileDebug
}
case run $ runReader entryPoint $ runError $ asmToMiniC tab of
Left err -> exitJuvixError err
Right C.MiniCResult {..} -> do
buildDir <- askBuildDir
ensureDir buildDir
cFile <- inputCFile file
embed @IO $ writeFileEnsureLn cFile _resultCCode
outfile <- Compile.outputFile opts file
Compile.runCommand
opts
{ _compileInputFile = Just (AppPath (preFileFromAbs cFile) False),
_compileOutputFile = Just (AppPath (preFileFromAbs outfile) False)
}
case opts ^. compileTarget of
TargetReg -> do
regFile <- Compile.outputFile opts file
r <-
runReader entryPoint
. runError @JuvixError
. asmToReg
$ tab
tab' <- getRight r
let code = Reg.ppPrint tab' tab'
embed @IO $ writeFileEnsureLn regFile code
_ ->
case run $ runReader entryPoint $ runError $ asmToMiniC tab of
Left err -> exitJuvixError err
Right C.MiniCResult {..} -> do
buildDir <- askBuildDir
ensureDir buildDir
cFile <- inputCFile file
embed @IO $ writeFileEnsureLn cFile _resultCCode
outfile <- Compile.outputFile opts file
Compile.runCommand
opts
{ _compileInputFile = Just (AppPath (preFileFromAbs cFile) False),
_compileOutputFile = Just (AppPath (preFileFromAbs outfile) False)
}
where
getFile :: Sem r (Path Abs File)
getFile = getMainFile (opts ^. compileInputFile)
Expand All @@ -43,6 +56,7 @@ runCommand opts = do
getTarget = \case
TargetWasm32Wasi -> return Backend.TargetCWasm32Wasi
TargetNative64 -> return Backend.TargetCNative64
TargetReg -> return Backend.TargetReg
TargetNockma -> err "Nockma"
TargetTree -> err "JuvixTree"
TargetGeb -> err "GEB"
Expand Down
2 changes: 1 addition & 1 deletion app/Commands/Dev/Asm/Compile/Options.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ asmSupportedTargets =
NonEmpty.fromList
[ TargetWasm32Wasi,
TargetNative64,
TargetNockma
TargetReg
]

parseAsmCompileOptions :: Parser AsmCompileOptions
Expand Down
1 change: 1 addition & 0 deletions app/Commands/Dev/Core/Compile.hs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ runCommand opts = do
TargetVampIR -> runVampIRPipeline arg
TargetCore -> return ()
TargetAsm -> runAsmPipeline arg
TargetReg -> runRegPipeline arg
TargetTree -> runTreePipeline arg
TargetNockma -> runNockmaPipeline arg
where
Expand Down
15 changes: 15 additions & 0 deletions app/Commands/Dev/Core/Compile/Base.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Juvix.Compiler.Backend.Geb qualified as Geb
import Juvix.Compiler.Backend.VampIR.Translation qualified as VampIR
import Juvix.Compiler.Core.Data.Module qualified as Core
import Juvix.Compiler.Nockma.Pretty qualified as Nockma
import Juvix.Compiler.Reg.Pretty qualified as Reg
import Juvix.Compiler.Tree.Pretty qualified as Tree
import System.FilePath (takeBaseName)

Expand Down Expand Up @@ -39,6 +40,7 @@ getEntry PipelineArg {..} = do
TargetVampIR -> Backend.TargetVampIR
TargetCore -> Backend.TargetCore
TargetAsm -> Backend.TargetAsm
TargetReg -> Backend.TargetReg
TargetTree -> Backend.TargetTree
TargetNockma -> Backend.TargetNockma

Expand Down Expand Up @@ -113,6 +115,19 @@ runAsmPipeline pa@PipelineArg {..} = do
let code = Asm.ppPrint tab' tab'
embed @IO $ writeFileEnsureLn asmFile code

runRegPipeline :: (Members '[Embed IO, App, TaggedLock] r) => PipelineArg -> Sem r ()
runRegPipeline pa@PipelineArg {..} = do
entryPoint <- getEntry pa
regFile <- Compile.outputFile _pipelineArgOptions _pipelineArgFile
r <-
runReader entryPoint
. runError @JuvixError
. coreToReg
$ _pipelineArgModule
tab' <- getRight r
let code = Reg.ppPrint tab' tab'
embed @IO $ writeFileEnsureLn regFile code

runTreePipeline :: (Members '[Embed IO, App, TaggedLock] r) => PipelineArg -> Sem r ()
runTreePipeline pa@PipelineArg {..} = do
entryPoint <- getEntry pa
Expand Down
3 changes: 2 additions & 1 deletion app/Commands/Dev/Core/Compile/Options.hs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ coreSupportedTargets =
TargetNative64,
TargetGeb,
TargetVampIR,
TargetTree,
TargetAsm,
TargetTree
TargetReg
]

parseCoreCompileOptions :: Parser CoreCompileOptions
Expand Down
10 changes: 10 additions & 0 deletions app/Commands/Dev/Options.hs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import Commands.Dev.Internal.Options
import Commands.Dev.MigrateJuvixYaml.Options
import Commands.Dev.Nockma.Options
import Commands.Dev.Parse.Options
import Commands.Dev.Reg.Options
import Commands.Dev.Repl.Options
import Commands.Dev.Runtime.Options
import Commands.Dev.Scope.Options
Expand All @@ -37,6 +38,7 @@ data DevCommand
| Core CoreCommand
| Geb GebCommand
| Asm AsmCommand
| Reg RegCommand
| Tree TreeCommand
| Casm CasmCommand
| Runtime RuntimeCommand
Expand All @@ -57,6 +59,7 @@ parseDevCommand =
commandCore,
commandGeb,
commandAsm,
commandReg,
commandTree,
commandCasm,
commandRuntime,
Expand Down Expand Up @@ -105,6 +108,13 @@ commandAsm =
(Asm <$> parseAsmCommand)
(progDesc "Subcommands related to JuvixAsm")

commandReg :: Mod CommandFields DevCommand
commandReg =
command "reg" $
info
(Reg <$> parseRegCommand)
(progDesc "Subcommands related to JuvixReg")

commandTree :: Mod CommandFields DevCommand
commandTree =
command "tree" $
Expand Down
9 changes: 9 additions & 0 deletions app/Commands/Dev/Reg.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module Commands.Dev.Reg where

import Commands.Base
import Commands.Dev.Reg.Options
import Commands.Dev.Reg.Read as Read

runCommand :: forall r. (Members '[Embed IO, App, TaggedLock] r) => RegCommand -> Sem r ()
runCommand = \case
Read opts -> Read.runCommand opts
24 changes: 24 additions & 0 deletions app/Commands/Dev/Reg/Options.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
module Commands.Dev.Reg.Options where

import Commands.Dev.Reg.Read.Options
import CommonOptions

newtype RegCommand
= Read RegReadOptions
deriving stock (Data)

parseRegCommand :: Parser RegCommand
parseRegCommand =
hsubparser $
mconcat
[ commandRead
]
where
commandRead :: Mod CommandFields RegCommand
commandRead = command "read" readInfo

readInfo :: ParserInfo RegCommand
readInfo =
info
(Read <$> parseRegReadOptions)
(progDesc "Parse a JuvixReg file and pretty print it")
19 changes: 19 additions & 0 deletions app/Commands/Dev/Reg/Read.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module Commands.Dev.Reg.Read where

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

runCommand :: forall r. (Members '[Embed IO, App] r) => RegReadOptions -> Sem r ()
runCommand opts = do
afile :: Path Abs File <- fromAppPathFile file
s <- readFile (toFilePath afile)
case Reg.runParser (toFilePath afile) s of
Left err ->
exitJuvixError (JuvixError err)
Right tab ->
renderStdOut (Reg.ppOutDefault tab tab)
where
file :: AppPath File
file = opts ^. regReadInputFile
15 changes: 15 additions & 0 deletions app/Commands/Dev/Reg/Read/Options.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module Commands.Dev.Reg.Read.Options where

import CommonOptions

newtype RegReadOptions = RegReadOptions
{ _regReadInputFile :: AppPath File
}
deriving stock (Data)

makeLenses ''RegReadOptions

parseRegReadOptions :: Parser RegReadOptions
parseRegReadOptions = do
_regReadInputFile <- parseInputFile FileExtJuvixAsm
pure RegReadOptions {..}
1 change: 1 addition & 0 deletions app/Commands/Dev/Tree/Compile.hs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ runCommand opts = do
TargetVampIR -> return ()
TargetCore -> return ()
TargetAsm -> runAsmPipeline arg
TargetReg -> runRegPipeline arg
TargetTree -> return ()
TargetNockma -> runNockmaPipeline arg
where
Expand Down
15 changes: 15 additions & 0 deletions app/Commands/Dev/Tree/Compile/Base.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Juvix.Compiler.Asm.Pretty qualified as Asm
import Juvix.Compiler.Backend qualified as Backend
import Juvix.Compiler.Backend.C qualified as C
import Juvix.Compiler.Nockma.Pretty qualified as Nockma
import Juvix.Compiler.Reg.Pretty qualified as Reg
import Juvix.Compiler.Tree.Data.InfoTable qualified as Tree

data PipelineArg = PipelineArg
Expand Down Expand Up @@ -35,6 +36,7 @@ getEntry PipelineArg {..} = do
TargetVampIR -> Backend.TargetVampIR
TargetCore -> Backend.TargetCore
TargetAsm -> Backend.TargetAsm
TargetReg -> Backend.TargetReg
TargetTree -> Backend.TargetTree
TargetNockma -> Backend.TargetNockma

Expand Down Expand Up @@ -84,6 +86,19 @@ runAsmPipeline pa@PipelineArg {..} = do
let code = Asm.ppPrint tab' tab'
embed @IO $ writeFileEnsureLn asmFile code

runRegPipeline :: (Members '[Embed IO, App, TaggedLock] r) => PipelineArg -> Sem r ()
runRegPipeline pa@PipelineArg {..} = do
entryPoint <- getEntry pa
regFile <- Compile.outputFile _pipelineArgOptions _pipelineArgFile
r <-
runReader entryPoint
. runError @JuvixError
. treeToReg
$ _pipelineArgTable
tab' <- getRight r
let code = Reg.ppPrint tab' tab'
embed @IO $ writeFileEnsureLn regFile code

runNockmaPipeline :: (Members '[Embed IO, App, TaggedLock] r) => PipelineArg -> Sem r ()
runNockmaPipeline pa@PipelineArg {..} = do
entryPoint <- getEntry pa
Expand Down
1 change: 1 addition & 0 deletions app/Commands/Dev/Tree/Compile/Options.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ treeSupportedTargets =
[ TargetWasm32Wasi,
TargetNative64,
TargetAsm,
TargetReg,
TargetNockma
]

Expand Down
4 changes: 4 additions & 0 deletions app/Commands/Extra/Compile.hs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ runCompile inputFile o = do
TargetVampIR -> return (Right ())
TargetCore -> return (Right ())
TargetAsm -> return (Right ())
TargetReg -> return (Right ())
TargetTree -> return (Right ())
TargetNockma -> return (Right ())

Expand All @@ -50,6 +51,7 @@ prepareRuntime buildDir o = do
TargetVampIR -> return ()
TargetCore -> return ()
TargetAsm -> return ()
TargetReg -> return ()
TargetTree -> return ()
TargetNockma -> return ()
where
Expand Down Expand Up @@ -109,6 +111,8 @@ outputFile opts inputFile =
replaceExtension' juvixCoreFileExt baseOutputFile
TargetAsm ->
replaceExtension' juvixAsmFileExt baseOutputFile
TargetReg ->
replaceExtension' juvixRegFileExt baseOutputFile
TargetTree ->
replaceExtension' juvixTreeFileExt baseOutputFile
TargetNockma ->
Expand Down
2 changes: 2 additions & 0 deletions app/Commands/Extra/Compile/Options.hs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ data CompileTarget
| TargetVampIR
| TargetCore
| TargetAsm
| TargetReg
| TargetTree
| TargetNockma
deriving stock (Eq, Data, Bounded, Enum)
Expand All @@ -23,6 +24,7 @@ instance Show CompileTarget where
TargetVampIR -> "vampir"
TargetCore -> "core"
TargetAsm -> "asm"
TargetReg -> "reg"
TargetTree -> "tree"
TargetNockma -> "nockma"

Expand Down
Loading

0 comments on commit ed15e57

Please sign in to comment.