-
Notifications
You must be signed in to change notification settings - Fork 57
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
JuvixTree parser and pretty printer (#2583)
This PR implements: * JuvixTree parser. * JuvixTree pretty printer. * `juvix dev tree read file.jvt` command which reads and pretty prints a JuvixTree file. * The `tree` target in the `compile` command. * Removal of `StackRef` in JuvixAsm. This makes JuvixAsm more consistent with JuvixTree and simplifies the data structures. `StackRef` is not needed for compilation from Core. Tests for the parser will appear in a separate PR, when I implement an automatic translation of JuvixAsm to JuvixTree files. --------- Co-authored-by: Paul Cadman <[email protected]> Co-authored-by: Jan Mas Rovira <[email protected]>
- Loading branch information
1 parent
510490a
commit e5ea085
Showing
59 changed files
with
2,056 additions
and
968 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
module Commands.Dev.Tree where | ||
|
||
import Commands.Base | ||
import Commands.Dev.Tree.Options | ||
import Commands.Dev.Tree.Read as Read | ||
|
||
runCommand :: forall r. (Members '[Embed IO, App, TaggedLock] r) => TreeCommand -> Sem r () | ||
runCommand = \case | ||
Read opts -> Read.runCommand opts |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
module Commands.Dev.Tree.Options where | ||
|
||
import Commands.Dev.Tree.Read.Options | ||
import CommonOptions | ||
|
||
newtype TreeCommand | ||
= Read TreeReadOptions | ||
deriving stock (Data) | ||
|
||
parseTreeCommand :: Parser TreeCommand | ||
parseTreeCommand = | ||
hsubparser $ | ||
mconcat | ||
[ commandRead | ||
] | ||
where | ||
commandRead :: Mod CommandFields TreeCommand | ||
commandRead = command "read" readInfo | ||
|
||
readInfo :: ParserInfo TreeCommand | ||
readInfo = | ||
info | ||
(Read <$> parseTreeReadOptions) | ||
(progDesc "Parse a JuvixTree file and pretty print it") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
module Commands.Dev.Tree.Read where | ||
|
||
import Commands.Base | ||
import Commands.Dev.Tree.Read.Options | ||
import Juvix.Compiler.Tree.Pretty qualified as Tree | ||
import Juvix.Compiler.Tree.Translation.FromSource qualified as Tree | ||
|
||
runCommand :: forall r. (Members '[Embed IO, App] r) => TreeReadOptions -> Sem r () | ||
runCommand opts = do | ||
afile :: Path Abs File <- fromAppPathFile file | ||
s <- readFile (toFilePath afile) | ||
case Tree.runParser (toFilePath afile) s of | ||
Left err -> exitJuvixError (JuvixError err) | ||
Right tab -> renderStdOut (Tree.ppOutDefault tab tab) | ||
where | ||
file :: AppPath File | ||
file = opts ^. treeReadInputFile |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
module Commands.Dev.Tree.Read.Options where | ||
|
||
import CommonOptions | ||
|
||
newtype TreeReadOptions = TreeReadOptions | ||
{ _treeReadInputFile :: AppPath File | ||
} | ||
deriving stock (Data) | ||
|
||
makeLenses ''TreeReadOptions | ||
|
||
parseTreeReadOptions :: Parser TreeReadOptions | ||
parseTreeReadOptions = do | ||
_treeReadInputFile <- parseInputFile FileExtJuvixTree | ||
pure TreeReadOptions {..} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,80 +1,40 @@ | ||
module Juvix.Compiler.Asm.Data.InfoTableBuilder where | ||
module Juvix.Compiler.Asm.Data.InfoTableBuilder | ||
( module Juvix.Compiler.Asm.Data.InfoTableBuilder, | ||
module Juvix.Compiler.Tree.Data.InfoTableBuilder.Base, | ||
) | ||
where | ||
|
||
import Data.HashMap.Strict qualified as HashMap | ||
import Juvix.Compiler.Asm.Data.InfoTable | ||
import Juvix.Compiler.Asm.Language | ||
import Juvix.Compiler.Tree.Data.InfoTableBuilder.Base | ||
|
||
data IdentKind | ||
= IdentFun Symbol | ||
| IdentFwd Symbol | ||
| IdentInd Symbol | ||
| IdentConstr Tag | ||
type InfoTableBuilder = InfoTableBuilder' Code (Maybe FunctionInfoExtra) | ||
|
||
data InfoTableBuilder m a where | ||
FreshSymbol :: InfoTableBuilder m Symbol | ||
FreshTag :: InfoTableBuilder m Tag | ||
RegisterFunction :: FunctionInfo -> InfoTableBuilder m () | ||
RegisterConstr :: ConstructorInfo -> InfoTableBuilder m () | ||
RegisterInductive :: InductiveInfo -> InfoTableBuilder m () | ||
RegisterForward :: Text -> Symbol -> InfoTableBuilder m () | ||
RegisterMain :: Symbol -> InfoTableBuilder m () | ||
GetIdent :: Text -> InfoTableBuilder m (Maybe IdentKind) | ||
GetFunctionInfo :: Symbol -> InfoTableBuilder m FunctionInfo | ||
type BuilderState = BuilderState' Code (Maybe FunctionInfoExtra) | ||
|
||
makeSem ''InfoTableBuilder | ||
freshSymbol :: (Member InfoTableBuilder r) => Sem r Symbol | ||
freshSymbol = freshSymbol' @Code @(Maybe FunctionInfoExtra) | ||
|
||
data BuilderState = BuilderState | ||
{ _stateNextSymbolId :: Word, | ||
_stateNextUserTag :: Word, | ||
_stateInfoTable :: InfoTable, | ||
_stateIdents :: HashMap Text IdentKind | ||
} | ||
freshTag :: (Member InfoTableBuilder r) => Sem r Tag | ||
freshTag = freshTag' @Code @(Maybe FunctionInfoExtra) | ||
|
||
makeLenses ''BuilderState | ||
registerFunction :: (Member InfoTableBuilder r) => FunctionInfo -> Sem r () | ||
registerFunction = registerFunction' @Code @(Maybe FunctionInfoExtra) | ||
|
||
emptyBuilderState :: BuilderState | ||
emptyBuilderState = | ||
BuilderState | ||
{ _stateNextSymbolId = 0, | ||
_stateNextUserTag = 0, | ||
_stateInfoTable = emptyInfoTable, | ||
_stateIdents = mempty | ||
} | ||
registerConstr :: (Member InfoTableBuilder r) => ConstructorInfo -> Sem r () | ||
registerConstr = registerConstr' @Code @(Maybe FunctionInfoExtra) | ||
|
||
runInfoTableBuilder :: Sem (InfoTableBuilder ': r) a -> Sem r (InfoTable, a) | ||
runInfoTableBuilder = fmap (first (^. stateInfoTable)) . runInfoTableBuilder' emptyBuilderState | ||
registerInductive :: (Member InfoTableBuilder r) => InductiveInfo -> Sem r () | ||
registerInductive = registerInductive' @Code @(Maybe FunctionInfoExtra) | ||
|
||
runInfoTableBuilder' :: BuilderState -> Sem (InfoTableBuilder ': r) a -> Sem r (BuilderState, a) | ||
runInfoTableBuilder' bs = | ||
runState bs | ||
. reinterpret interp | ||
where | ||
interp :: InfoTableBuilder m a -> Sem (State BuilderState ': r) a | ||
interp = \case | ||
FreshSymbol -> do | ||
s <- get | ||
modify' (over stateNextSymbolId (+ 1)) | ||
return (Symbol defaultModuleId (s ^. stateNextSymbolId)) | ||
FreshTag -> do | ||
modify' (over stateNextUserTag (+ 1)) | ||
s <- get | ||
return (UserTag (TagUser defaultModuleId (s ^. stateNextUserTag - 1))) | ||
RegisterFunction fi -> do | ||
modify' (over (stateInfoTable . infoFunctions) (HashMap.insert (fi ^. functionSymbol) fi)) | ||
modify' (over stateIdents (HashMap.insert (fi ^. functionName) (IdentFun (fi ^. functionSymbol)))) | ||
RegisterConstr ci -> do | ||
modify' (over (stateInfoTable . infoConstrs) (HashMap.insert (ci ^. constructorTag) ci)) | ||
modify' (over stateIdents (HashMap.insert (ci ^. constructorName) (IdentConstr (ci ^. constructorTag)))) | ||
RegisterInductive ii -> do | ||
modify' (over (stateInfoTable . infoInductives) (HashMap.insert (ii ^. inductiveSymbol) ii)) | ||
modify' (over stateIdents (HashMap.insert (ii ^. inductiveName) (IdentInd (ii ^. inductiveSymbol)))) | ||
RegisterForward txt sym -> | ||
modify' (over stateIdents (HashMap.insert txt (IdentFwd sym))) | ||
RegisterMain sym -> | ||
modify' (over stateInfoTable (set infoMainFunction (Just sym))) | ||
GetIdent txt -> do | ||
s <- get | ||
return $ HashMap.lookup txt (s ^. stateIdents) | ||
GetFunctionInfo sym -> do | ||
s <- get | ||
return (lookupFunInfo (s ^. stateInfoTable) sym) | ||
registerForward :: (Member InfoTableBuilder r) => Text -> Symbol -> Sem r () | ||
registerForward = registerForward' @Code @(Maybe FunctionInfoExtra) | ||
|
||
registerMain :: (Member InfoTableBuilder r) => Symbol -> Sem r () | ||
registerMain = registerMain' @Code @(Maybe FunctionInfoExtra) | ||
|
||
getIdent :: (Member InfoTableBuilder r) => Text -> Sem r (Maybe IdentKind) | ||
getIdent = getIdent' @Code @(Maybe FunctionInfoExtra) | ||
|
||
getFunctionInfo :: (Member InfoTableBuilder r) => Symbol -> Sem r FunctionInfo | ||
getFunctionInfo = getFunctionInfo' @Code @(Maybe FunctionInfoExtra) |
Oops, something went wrong.