1
1
mirror of https://github.com/anoma/juvix.git synced 2025-01-05 14:34:03 +03:00

setup InfoTable for parser

This commit is contained in:
Jan Mas Rovira 2022-04-04 15:53:16 +02:00
parent 743b5b153a
commit 22b5de42f3
16 changed files with 434 additions and 265 deletions

View File

@ -16,6 +16,7 @@ import qualified MiniJuvix.Syntax.Concrete.Language as M
import qualified MiniJuvix.Syntax.Concrete.Parser as M
import qualified MiniJuvix.Syntax.Concrete.Scoped.Pretty.Ansi as M
import qualified MiniJuvix.Syntax.Concrete.Scoped.InfoTable as Scoped
import qualified MiniJuvix.Syntax.Concrete.Parser.InfoTable as Parser
import qualified MiniJuvix.Syntax.Concrete.Scoped.Highlight as Scoped
import MiniJuvix.Syntax.Concrete.Scoped.Pretty.Base (defaultOptions)
import qualified MiniJuvix.Syntax.Concrete.Scoped.Pretty.Base as M
@ -35,6 +36,7 @@ import MiniJuvix.Utils.Version (runDisplayVersion)
import Options.Applicative
import Options.Applicative.Help.Pretty
import Text.Show.Pretty hiding (Html)
import MiniJuvix.Syntax.Concrete.Parser.InfoTable (infoParsedItems)
--------------------------------------------------------------------------------
@ -265,6 +267,10 @@ mkScopePrettyOptions ScopeOptions {..} =
parseModuleIO :: FilePath -> IO (M.Module 'M.Parsed 'M.ModuleTop)
parseModuleIO = fromRightIO id . M.runModuleParserIO
parseModuleIO' :: FilePath -> IO (Parser.InfoTable, M.Module 'M.Parsed 'M.ModuleTop)
parseModuleIO' = fromRightIO id . M.runModuleParserIO'
minijuvixYamlFile :: FilePath
minijuvixYamlFile = "minijuvix.yaml"
@ -275,8 +281,9 @@ findRoot = do
Left err -> do
putStrLn "Something went wrong when figuring out the root of the project."
putStrLn (pack (IO.displayException err))
putStrLn "I will try to use the current directory."
getCurrentDirectory
cur <- getCurrentDirectory
putStrLn ("I will try to use the current directory: " <> pack cur)
return cur
Right root -> return root
where
possiblePaths :: FilePath -> [FilePath]
@ -300,7 +307,7 @@ runCommand c = do
Scope opts@ScopeOptions {..} -> do
forM_ _scopeInputFiles $ \scopeInputFile -> do
m <- parseModuleIO scopeInputFile
(_ , s) <- fromRightIO' printErrorAnsi $ M.scopeCheck1IO root m
s <- head . M._resultModules <$> fromRightIO' printErrorAnsi (M.scopeCheck1IO root m)
printer (mkScopePrettyOptions opts) s
where
printer :: M.Options -> M.Module 'M.Scoped 'M.ModuleTop -> IO ()
@ -308,15 +315,19 @@ runCommand c = do
| not _scopeNoColors = M.printPrettyCode
| otherwise = T.printPrettyCode
Highlight HighlightOptions {..} -> do
m <- parseModuleIO _highlightInputFile
(i , _) <- fromRightIO' printErrorAnsi $ M.scopeCheck1IO root m
putStrLn (Scoped.go (i ^. Scoped.infoNames))
(tbl, m) <- parseModuleIO' _highlightInputFile
res <- fromRightIO' printErrorAnsi $ M.scopeCheck1IO root m
let
names = res ^. M.resultScoperTable . Scoped.infoNames
parsedItems = res ^. M.resultParserTable . Parser.infoParsedItems
<> tbl ^. infoParsedItems
putStrLn (Scoped.go parsedItems names)
Parse ParseOptions {..} -> do
m <- parseModuleIO _parseInputFile
if _parseNoPrettyShow then print m else pPrint m
Html HtmlOptions {..} -> do
m <- parseModuleIO _htmlInputFile
(_ , s) <- fromRightIO' printErrorAnsi $ M.scopeCheck1IO root m
s <- head . M._resultModules <$> fromRightIO' printErrorAnsi (M.scopeCheck1IO root m)
genHtml defaultOptions _htmlRecursive _htmlTheme s
MicroJuvix (Pretty MicroJuvixOptions {..}) -> do
micro <- miniToMicro root _mjuvixInputFile
@ -328,8 +339,8 @@ runCommand c = do
Left es -> sequence_ (intersperse (putStrLn "") (printErrorAnsi <$> toList es)) >> exitFailure
MiniHaskell MiniHaskellOptions {..} -> do
m <- parseModuleIO _mhaskellInputFile
(_, s) <- fromRightIO' printErrorAnsi $ M.scopeCheck1IO root m
(_, a) <- fromRightIO' putStrLn (return $ A.translateModule s)
s <- head . M._resultModules <$> fromRightIO' printErrorAnsi (M.scopeCheck1IO root m)
(_, a) <- fromRightIO' putStrLn (return (A.translateModule s))
let micro = Micro.translateModule a
case Micro.checkModule micro of
Right checkedMicro -> do
@ -338,7 +349,7 @@ runCommand c = do
Left es -> mapM_ printErrorAnsi es >> exitFailure
Termination (Calls opts@CallsOptions {..}) -> do
m <- parseModuleIO _callsInputFile
(_ , s) <- fromRightIO' printErrorAnsi $ M.scopeCheck1IO root m
s <- head . M._resultModules <$> fromRightIO' printErrorAnsi (M.scopeCheck1IO root m)
(_, a) <- fromRightIO' putStrLn (return $ A.translateModule s)
let callMap0 = T.buildCallMap a
callMap = case _callsFunctionNameFilter of
@ -349,8 +360,8 @@ runCommand c = do
putStrLn ""
Termination (CallGraph CallGraphOptions {..}) -> do
m <- parseModuleIO _graphInputFile
(_ , s) <- fromRightIO' printErrorAnsi $ M.scopeCheck1IO root m
(_, a) <- fromRightIO' putStrLn (return $ A.translateModule s)
s <- head . M._resultModules <$> fromRightIO' printErrorAnsi (M.scopeCheck1IO root m)
(_, a) <- fromRightIO' putStrLn (return (A.translateModule s))
let callMap = T.buildCallMap a
opts' = A.defaultOptions
completeGraph = T.completeCallGraph callMap
@ -370,7 +381,7 @@ runCommand c = do
miniToMicro :: FilePath -> FilePath -> IO Micro.Module
miniToMicro root p = do
m <- parseModuleIO p
(_, s) <- fromRightIO' printErrorAnsi $ M.scopeCheck1IO root m
s <- head . M._resultModules <$> fromRightIO' printErrorAnsi (M.scopeCheck1IO root m)
(_, a) <- fromRightIO' putStrLn (return $ A.translateModule s)
return (Micro.translateModule a)

View File

@ -48,5 +48,21 @@
"The face used for axioms."
:group 'minijuvix-highlight-faces)
(defface minijuvix-highlight-string-face
'((((background light))
(:foreground "#f07171"))
(((background dark))
(:foreground "#bf616a")))
"The face used for string literals."
:group 'minijuvix-highlight-faces)
(defface minijuvix-highlight-number-face
'((((background light))
(:foreground "#000000"))
(((background dark))
(:foreground "#d8dee9")))
"The face used for numbers."
:group 'minijuvix-highlight-faces)
(provide 'minijuvix-highlight)

View File

@ -27,6 +27,7 @@ dependencies:
- directory == 1.3.*
- edit-distance == 0.2.*
- extra == 1.7.*
- transformers == 0.5.*
- filepath == 1.4.*
- gitrev == 1.3.*
- hashable == 1.4.*

View File

@ -65,12 +65,21 @@ let_ = "let"
public :: IsString s => s
public = "public"
number :: IsString s => s
number = "number"
string :: IsString s => s
string = "string"
any :: IsString s => s
any = "Any"
type_ :: IsString s => s
type_ = "Type"
keyword :: IsString s => s
keyword = "keyword"
using :: IsString s => s
using = "using"

View File

@ -42,7 +42,6 @@ module MiniJuvix.Prelude.Base
module Polysemy.Output,
module Polysemy.Reader,
module Polysemy.State,
module Polysemy.View,
module Prettyprinter,
module System.Directory,
module System.Exit,
@ -115,7 +114,6 @@ import Polysemy.Fixpoint
import Polysemy.Output
import Polysemy.Reader
import Polysemy.State
import Polysemy.View
import Prettyprinter (Doc, (<+>))
import System.Directory
import System.Exit

View File

@ -4,6 +4,7 @@ module MiniJuvix.Syntax.Concrete.Base
module Text.Megaparsec.Char,
module Control.Monad.Combinators.Expr,
module Control.Monad.Combinators.NonEmpty,
module Control.Monad.Trans.Class
)
where
@ -13,3 +14,4 @@ import Data.List.NonEmpty (NonEmpty)
import MiniJuvix.Prelude hiding (some)
import Text.Megaparsec hiding (sepBy1, sepEndBy1, some)
import Text.Megaparsec.Char
import Control.Monad.Trans.Class (lift)

View File

@ -1,19 +1,17 @@
module MiniJuvix.Syntax.Concrete.Lexer where
--------------------------------------------------------------------------------
import qualified Data.Text as Text
import GHC.Unicode
import qualified MiniJuvix.Internal.Strings as Str
import MiniJuvix.Prelude
import MiniJuvix.Syntax.Concrete.Base hiding (Pos, space)
import MiniJuvix.Syntax.Concrete.Parser.InfoTableBuilder
import qualified MiniJuvix.Syntax.Concrete.Base as P
import MiniJuvix.Syntax.Concrete.Loc
import qualified Text.Megaparsec.Char.Lexer as L
--------------------------------------------------------------------------------
type OperatorSym = Text
type ParsecS r = ParsecT Void Text (Sem r)
space :: forall m e. MonadParsec e Text m => m ()
space = L.space space1 lineComment block
@ -30,10 +28,10 @@ symbol = void . L.symbol space
decimal :: (MonadParsec e Text m, Num n) => m n
decimal = lexeme L.decimal
identifier :: MonadParsec e Text m => m Text
identifier :: Member InfoTableBuilder r => ParsecS r Text
identifier = fmap fst identifierL
identifierL :: MonadParsec e Text m => m (Text, Interval)
identifierL :: Member InfoTableBuilder r => ParsecS r (Text, Interval)
identifierL = lexeme bareIdentifier
fromPos :: P.Pos -> Pos
@ -78,9 +76,6 @@ curLoc = do
offset <- stateOffset <$> getParserState
return (mkLoc offset sp)
withLoc :: MonadParsec e Text m => (Loc -> m a) -> m a
withLoc ma = curLoc >>= ma
interval :: MonadParsec e Text m => m a -> m (a, Interval)
interval ma = do
start <- curLoc
@ -88,10 +83,16 @@ interval ma = do
end <- curLoc
return (res, mkInterval start end)
keyword :: Member InfoTableBuilder r => Text -> ParsecS r ()
keyword kw = do
l <- snd <$> interval (symbol kw)
lift (registerKeyword l)
-- | Same as @identifier@ but does not consume space after it.
-- TODO: revise.
bareIdentifier :: MonadParsec e Text m => m (Text, Interval)
bareIdentifier :: Member InfoTableBuilder r => ParsecS r (Text, Interval)
bareIdentifier = interval $ do
-- TODO how to ignore these keywords for the InfoTableBuilder?
notFollowedBy (choice allKeywords)
h <- P.satisfy validFirstChar
t <- P.takeWhileP Nothing validChar
@ -117,13 +118,13 @@ bareIdentifier = interval $ do
dot :: forall e m. MonadParsec e Text m => m Char
dot = P.char '.'
dottedIdentifier :: forall e m. MonadParsec e Text m => m (NonEmpty (Text, Interval))
dottedIdentifier :: Member InfoTableBuilder r => ParsecS r (NonEmpty (Text, Interval))
dottedIdentifier = lexeme $ P.sepBy1 bareIdentifier dot
braces :: MonadParsec e Text m => m a -> m a
braces = between (symbol "{") (symbol "}")
allKeywords :: MonadParsec e Text m => [m ()]
allKeywords :: Member InfoTableBuilder r => [ParsecS r ()]
allKeywords =
[ kwAssignment,
kwAxiom,
@ -131,7 +132,6 @@ allKeywords =
kwColonOmega,
kwColonOne,
kwColonZero,
kwCompile,
kwEnd,
kwEval,
kwForeign,
@ -168,105 +168,102 @@ rparen = symbol ")"
parens :: MonadParsec e Text m => m a -> m a
parens = between lparen rparen
kwAssignment :: MonadParsec e Text m => m ()
kwAssignment = symbol Str.assignUnicode <|> symbol Str.assignAscii
kwAssignment :: Member InfoTableBuilder r => ParsecS r ()
kwAssignment = keyword Str.assignUnicode <|> keyword Str.assignAscii
kwAxiom :: MonadParsec e Text m => m ()
kwAxiom = symbol Str.axiom
kwAxiom :: Member InfoTableBuilder r => ParsecS r ()
kwAxiom = keyword Str.axiom
-- | Note that the trailing space is needed to distinguish it from ':='.
kwColon :: MonadParsec e Text m => m ()
kwColon = symbol Str.colonSpace
kwColon :: Member InfoTableBuilder r => ParsecS r ()
kwColon = keyword Str.colonSpace
kwColonOmega :: MonadParsec e Text m => m ()
kwColonOmega = symbol Str.colonOmegaUnicode <|> symbol Str.colonOmegaAscii
kwColonOmega :: Member InfoTableBuilder r => ParsecS r ()
kwColonOmega = keyword Str.colonOmegaUnicode <|> keyword Str.colonOmegaAscii
kwColonOne :: MonadParsec e Text m => m ()
kwColonOne = symbol Str.colonOne
kwColonOne :: Member InfoTableBuilder r => ParsecS r ()
kwColonOne = keyword Str.colonOne
kwColonZero :: MonadParsec e Text m => m ()
kwColonZero = symbol Str.colonZero
kwColonZero :: Member InfoTableBuilder r => ParsecS r ()
kwColonZero = keyword Str.colonZero
kwEnd :: MonadParsec e Text m => m ()
kwEnd = symbol Str.end
kwEnd :: Member InfoTableBuilder r => ParsecS r ()
kwEnd = keyword Str.end
kwEval :: MonadParsec e Text m => m ()
kwEval = symbol Str.eval
kwEval :: Member InfoTableBuilder r => ParsecS r ()
kwEval = keyword Str.eval
kwHiding :: MonadParsec e Text m => m ()
kwHiding = symbol Str.hiding
kwHiding :: Member InfoTableBuilder r => ParsecS r ()
kwHiding = keyword Str.hiding
kwImport :: MonadParsec e Text m => m ()
kwImport = symbol Str.import_
kwImport :: Member InfoTableBuilder r => ParsecS r ()
kwImport = keyword Str.import_
kwForeign :: MonadParsec e Text m => m ()
kwForeign = symbol Str.foreign_
kwForeign :: Member InfoTableBuilder r => ParsecS r ()
kwForeign = keyword Str.foreign_
kwCompile :: MonadParsec e Text m => m ()
kwCompile = symbol Str.compile
kwIn :: Member InfoTableBuilder r => ParsecS r ()
kwIn = keyword Str.in_
kwIn :: MonadParsec e Text m => m ()
kwIn = symbol Str.in_
kwInductive :: Member InfoTableBuilder r => ParsecS r ()
kwInductive = keyword Str.inductive
kwInductive :: MonadParsec e Text m => m ()
kwInductive = symbol Str.inductive
kwInfix :: Member InfoTableBuilder r => ParsecS r ()
kwInfix = keyword Str.infix_
kwInfix :: MonadParsec e Text m => m ()
kwInfix = symbol Str.infix_
kwInfixl :: Member InfoTableBuilder r => ParsecS r ()
kwInfixl = keyword Str.infixl_
kwInfixl :: MonadParsec e Text m => m ()
kwInfixl = symbol Str.infixl_
kwInfixr :: Member InfoTableBuilder r => ParsecS r ()
kwInfixr = keyword Str.infixr_
kwInfixr :: MonadParsec e Text m => m ()
kwInfixr = symbol Str.infixr_
kwLambda :: Member InfoTableBuilder r => ParsecS r ()
kwLambda = keyword Str.lambdaUnicode <|> keyword Str.lambdaAscii
kwLambda :: MonadParsec e Text m => m ()
kwLambda = symbol Str.lambdaUnicode <|> symbol Str.lambdaAscii
kwLet :: Member InfoTableBuilder r => ParsecS r ()
kwLet = keyword Str.let_
kwLet :: MonadParsec e Text m => m ()
kwLet = symbol Str.let_
kwMapsTo :: Member InfoTableBuilder r => ParsecS r ()
kwMapsTo = keyword Str.mapstoUnicode <|> keyword Str.mapstoAscii
kwMapsTo :: MonadParsec e Text m => m ()
kwMapsTo = symbol Str.mapstoUnicode <|> symbol Str.mapstoAscii
kwMatch :: Member InfoTableBuilder r => ParsecS r ()
kwMatch = keyword Str.match
kwMatch :: MonadParsec e Text m => m ()
kwMatch = symbol Str.match
kwModule :: Member InfoTableBuilder r => ParsecS r ()
kwModule = keyword Str.module_
kwModule :: MonadParsec e Text m => m ()
kwModule = symbol Str.module_
kwOpen :: Member InfoTableBuilder r => ParsecS r ()
kwOpen = keyword Str.open
kwOpen :: MonadParsec e Text m => m ()
kwOpen = symbol Str.open
kwPostfix :: Member InfoTableBuilder r => ParsecS r ()
kwPostfix = keyword Str.postfix
kwPostfix :: MonadParsec e Text m => m ()
kwPostfix = symbol Str.postfix
kwPrint :: Member InfoTableBuilder r => ParsecS r ()
kwPrint = keyword Str.print
kwPrint :: MonadParsec e Text m => m ()
kwPrint = symbol Str.print
kwPublic :: Member InfoTableBuilder r => ParsecS r ()
kwPublic = keyword Str.public
kwPublic :: MonadParsec e Text m => m ()
kwPublic = symbol Str.public
kwRightArrow :: Member InfoTableBuilder r => ParsecS r ()
kwRightArrow = keyword Str.toUnicode <|> keyword Str.toAscii
kwRightArrow :: MonadParsec e Text m => m ()
kwRightArrow = symbol Str.toUnicode <|> symbol Str.toAscii
kwSemicolon :: Member InfoTableBuilder r => ParsecS r ()
kwSemicolon = keyword Str.semicolon
kwSemicolon :: MonadParsec e Text m => m ()
kwSemicolon = symbol Str.semicolon
kwType :: Member InfoTableBuilder r => ParsecS r ()
kwType = keyword Str.type_
kwType :: MonadParsec e Text m => m ()
kwType = symbol Str.type_
kwUsing :: Member InfoTableBuilder r => ParsecS r ()
kwUsing = keyword Str.using
kwUsing :: MonadParsec e Text m => m ()
kwUsing = symbol Str.using
kwWhere :: Member InfoTableBuilder r => ParsecS r ()
kwWhere = keyword Str.where_
kwWhere :: MonadParsec e Text m => m ()
kwWhere = symbol Str.where_
kwWildcard :: Member InfoTableBuilder r => ParsecS r ()
kwWildcard = keyword Str.underscore
kwWildcard :: MonadParsec e Text m => m ()
kwWildcard = symbol Str.underscore
ghc :: Member InfoTableBuilder r => ParsecS r ()
ghc = keyword Str.ghc
ghc :: MonadParsec e Text m => m ()
ghc = symbol Str.ghc
agda :: MonadParsec e Text m => m ()
agda = symbol Str.agda
agda :: Member InfoTableBuilder r => ParsecS r ()
agda = keyword Str.agda

View File

@ -1,7 +1,5 @@
module MiniJuvix.Syntax.Concrete.Parser where
--------------------------------------------------------------------------------
import qualified Data.List.NonEmpty.Extra as NonEmpty
import Data.Singletons
import qualified Data.Text as Text
@ -10,46 +8,48 @@ import MiniJuvix.Prelude
import MiniJuvix.Syntax.Concrete.Base (MonadParsec)
import qualified MiniJuvix.Syntax.Concrete.Base as P
import MiniJuvix.Syntax.Concrete.Language
import MiniJuvix.Syntax.Concrete.Parser.InfoTableBuilder
import MiniJuvix.Syntax.Concrete.Lexer hiding (symbol)
--------------------------------------------------------------------------------
-- Running the parser
--------------------------------------------------------------------------------
debugModuleParser :: FilePath -> IO ()
debugModuleParser fileName = do
r <- runModuleParserIO fileName
case r of
Left err -> error err
Right m -> print m
runModuleParserIO :: FilePath -> IO (Either Text (Module 'Parsed 'ModuleTop))
runModuleParserIO fileName = do
runModuleParserIO fileName =
fmap (fmap snd) (runModuleParserIO' fileName)
runModuleParserIO' :: FilePath -> IO (Either Text (InfoTable, Module 'Parsed 'ModuleTop))
runModuleParserIO' fileName = do
input <- Text.readFile fileName
return (runModuleParser fileName input)
return (runModuleParser' fileName input)
runModuleParser :: FilePath -> Text -> Either Text (Module 'Parsed 'ModuleTop)
runModuleParser fileName input = fmap snd (runModuleParser' fileName input)
-- | The 'FilePath' is only used for reporting errors. It is safe to pass
-- an empty string.
runModuleParser :: FilePath -> Text -> Either Text (Module 'Parsed 'ModuleTop)
runModuleParser fileName input =
case P.runParser topModuleDef fileName input of
Left err -> Left $ Text.pack (P.errorBundlePretty err)
Right r -> return r
runModuleParser' :: FilePath -> Text -> Either Text (InfoTable, Module 'Parsed 'ModuleTop)
runModuleParser' fileName input =
case run $ runInfoTableBuilder $ P.runParserT topModuleDef fileName input of
(_, Left err) -> Left (Text.pack (P.errorBundlePretty err))
(tbl, Right r) -> return (tbl, r)
topModuleDef :: MonadParsec Void Text m => m (Module 'Parsed 'ModuleTop)
topModuleDef :: Member InfoTableBuilder r => ParsecS r (Module 'Parsed 'ModuleTop)
topModuleDef = space >> moduleDef <* (optional kwSemicolon >> P.eof)
--------------------------------------------------------------------------------
-- Symbols and names
--------------------------------------------------------------------------------
symbol :: MonadParsec e Text m => m Symbol
symbol :: Member InfoTableBuilder r => ParsecS r Symbol
symbol = uncurry Symbol <$> identifierL
dottedSymbol :: forall e m. MonadParsec e Text m => m (NonEmpty Symbol)
dottedSymbol :: Member InfoTableBuilder r => ParsecS r (NonEmpty Symbol)
dottedSymbol = fmap (uncurry Symbol) <$> dottedIdentifier
name :: forall e m. MonadParsec e Text m => m Name
name :: Member InfoTableBuilder r => ParsecS r Name
name = do
parts <- dottedSymbol
return $ case nonEmptyUnsnoc parts of
@ -59,17 +59,17 @@ name = do
mkTopModulePath :: NonEmpty Symbol -> TopModulePath
mkTopModulePath l = TopModulePath (NonEmpty.init l) (NonEmpty.last l)
symbolList :: MonadParsec e Text m => m (NonEmpty Symbol)
symbolList :: Member InfoTableBuilder r => ParsecS r (NonEmpty Symbol)
symbolList = braces (P.sepBy1 symbol kwSemicolon)
topModulePath :: MonadParsec e Text m => m TopModulePath
topModulePath :: Member InfoTableBuilder r => ParsecS r TopModulePath
topModulePath = mkTopModulePath <$> dottedSymbol
--------------------------------------------------------------------------------
-- Top level statement
--------------------------------------------------------------------------------
statement :: forall e m. MonadParsec e Text m => m (Statement 'Parsed)
statement :: Member InfoTableBuilder r => ParsecS r (Statement 'Parsed)
statement =
(StatementOperator <$> operatorSyntaxDef)
<|> (StatementOpenModule <$> openModule)
@ -88,11 +88,11 @@ statement =
-- Foreign
--------------------------------------------------------------------------------
backend :: forall e m. MonadParsec e Text m => m Backend
backend :: Member InfoTableBuilder r => ParsecS r Backend
backend = ghc $> BackendGhc
<|> agda $> BackendAgda
foreignBlock :: forall e m. MonadParsec e Text m => m ForeignBlock
foreignBlock :: Member InfoTableBuilder r => ParsecS r ForeignBlock
foreignBlock = do
kwForeign
_foreignBackend <- backend
@ -106,7 +106,7 @@ foreignBlock = do
precedence :: MonadParsec e Text m => m Precedence
precedence = PrecNat <$> decimal
operatorSyntaxDef :: forall e m. MonadParsec e Text m => m OperatorSyntaxDef
operatorSyntaxDef :: forall r. Member InfoTableBuilder r => ParsecS r OperatorSyntaxDef
operatorSyntaxDef = do
fixityArity <- arity
fixityPrecedence <- precedence
@ -114,7 +114,7 @@ operatorSyntaxDef = do
let opFixity = Fixity {..}
return OperatorSyntaxDef {..}
where
arity :: m OperatorArity
arity :: ParsecS r OperatorArity
arity =
do
Binary AssocRight <$ kwInfixr
@ -126,7 +126,7 @@ operatorSyntaxDef = do
-- Import statement
--------------------------------------------------------------------------------
import_ :: MonadParsec e Text m => m (Import 'Parsed)
import_ :: Member InfoTableBuilder r => ParsecS r (Import 'Parsed)
import_ = do
kwImport
importModule <- topModulePath
@ -136,7 +136,7 @@ import_ = do
-- Expression
--------------------------------------------------------------------------------
expressionAtom :: MonadParsec e Text m => m (ExpressionAtom 'Parsed)
expressionAtom :: Member InfoTableBuilder r => ParsecS r (ExpressionAtom 'Parsed)
expressionAtom =
do
AtomLiteral <$> P.try literal
@ -149,7 +149,7 @@ expressionAtom =
<|> (AtomFunArrow <$ kwRightArrow)
<|> parens (AtomParens <$> expressionAtoms)
expressionAtoms :: MonadParsec e Text m => m (ExpressionAtoms 'Parsed)
expressionAtoms :: Member InfoTableBuilder r => ParsecS r (ExpressionAtoms 'Parsed)
expressionAtoms = ExpressionAtoms <$> P.some expressionAtom
--------------------------------------------------------------------------------
@ -166,21 +166,24 @@ literalString = do
(x, loc) <- interval string
return (LiteralLoc (LitString x) loc)
literal :: MonadParsec e Text m => m LiteralLoc
literal = literalInteger <|> literalString
literal :: Member InfoTableBuilder r => ParsecS r LiteralLoc
literal = do
l <- literalInteger
<|> literalString
P.lift (registerLiteral l)
--------------------------------------------------------------------------------
-- Match expression
--------------------------------------------------------------------------------
matchAlt :: MonadParsec e Text m => m (MatchAlt 'Parsed)
matchAlt :: Member InfoTableBuilder r => ParsecS r (MatchAlt 'Parsed)
matchAlt = do
matchAltPattern <- patternAtom
kwMapsTo
matchAltBody <- expressionAtoms
return MatchAlt {..}
match :: MonadParsec e Text m => m (Match 'Parsed)
match :: Member InfoTableBuilder r => ParsecS r (Match 'Parsed)
match = do
kwMatch
matchExpression <- expressionAtoms
@ -191,11 +194,11 @@ match = do
-- Let expression
--------------------------------------------------------------------------------
letClause :: MonadParsec e Text m => m (LetClause 'Parsed)
letClause :: Member InfoTableBuilder r => ParsecS r (LetClause 'Parsed)
letClause = do
either LetTypeSig LetFunClause <$> auxTypeSigFunClause
letBlock :: MonadParsec e Text m => m (LetBlock 'Parsed)
letBlock :: Member InfoTableBuilder r => ParsecS r (LetBlock 'Parsed)
letBlock = do
kwLet
letClauses <- braces (P.sepEndBy letClause kwSemicolon)
@ -207,7 +210,7 @@ letBlock = do
-- Universe expression
--------------------------------------------------------------------------------
universe :: MonadParsec e Text m => m Universe
universe :: Member InfoTableBuilder r => ParsecS r Universe
universe = do
kwType
Universe <$> optional decimal
@ -216,11 +219,7 @@ universe = do
-- Type signature declaration
-------------------------------------------------------------------------------
typeSignature ::
forall e m.
MonadParsec e Text m =>
Symbol ->
m (TypeSignature 'Parsed)
typeSignature :: Member InfoTableBuilder r => Symbol -> ParsecS r (TypeSignature 'Parsed)
typeSignature _sigName = do
kwColon
_sigType <- expressionAtoms
@ -231,10 +230,8 @@ typeSignature _sigName = do
-------------------------------------------------------------------------------
-- | Used to minimize the amount of required @P.try@s.
auxTypeSigFunClause ::
forall e m.
MonadParsec e Text m =>
m (Either (TypeSignature 'Parsed) (FunctionClause 'Parsed))
auxTypeSigFunClause :: Member InfoTableBuilder r =>
ParsecS r (Either (TypeSignature 'Parsed) (FunctionClause 'Parsed))
auxTypeSigFunClause = do
s <- symbol
(Left <$> typeSignature s)
@ -244,7 +241,7 @@ auxTypeSigFunClause = do
-- Axioms
-------------------------------------------------------------------------------
axiomDef :: forall e m. MonadParsec e Text m => m (AxiomDef 'Parsed)
axiomDef :: Member InfoTableBuilder r => ParsecS r (AxiomDef 'Parsed)
axiomDef = do
kwAxiom
_axiomName <- symbol
@ -264,10 +261,7 @@ axiomDef = do
-- Function expression
--------------------------------------------------------------------------------
functionParam ::
forall e m.
MonadParsec e Text m =>
m (FunctionParameter 'Parsed)
functionParam :: forall r. Member InfoTableBuilder r => ParsecS r (FunctionParameter 'Parsed)
functionParam = do
(paramName, paramUsage) <- P.try $ do
lparen
@ -278,18 +272,18 @@ functionParam = do
rparen
return $ FunctionParameter {..}
where
pName :: m (Maybe Symbol)
pName :: ParsecS r (Maybe Symbol)
pName =
(Just <$> symbol)
<|> (Nothing <$ kwWildcard)
pUsage :: m (Maybe Usage)
pUsage :: ParsecS r (Maybe Usage)
pUsage =
(Just UsageNone <$ kwColonZero)
<|> (Just UsageOnce <$ kwColonOne)
<|> (Just UsageOmega <$ kwColonOmega)
<|> (Nothing <$ kwColon)
function :: MonadParsec e Text m => m (Function 'Parsed)
function :: Member InfoTableBuilder r => ParsecS r (Function 'Parsed)
function = do
funParameter <- functionParam
kwRightArrow
@ -300,31 +294,31 @@ function = do
-- Where block clauses
--------------------------------------------------------------------------------
whereBlock :: MonadParsec e Text m => m (WhereBlock 'Parsed)
whereBlock :: Member InfoTableBuilder r => ParsecS r (WhereBlock 'Parsed)
whereBlock = do
kwWhere
WhereBlock <$> braces (P.sepEndBy1 whereClause kwSemicolon)
whereClause :: forall e m. MonadParsec e Text m => m (WhereClause 'Parsed)
whereClause :: forall r. Member InfoTableBuilder r => ParsecS r (WhereClause 'Parsed)
whereClause =
(WhereOpenModule <$> openModule)
<|> sigOrFun
where
sigOrFun :: m (WhereClause 'Parsed)
sigOrFun :: ParsecS r (WhereClause 'Parsed)
sigOrFun = either WhereTypeSig WhereFunClause <$> auxTypeSigFunClause
--------------------------------------------------------------------------------
-- Lambda expression
--------------------------------------------------------------------------------
lambdaClause :: MonadParsec e Text m => m (LambdaClause 'Parsed)
lambdaClause :: Member InfoTableBuilder r => ParsecS r (LambdaClause 'Parsed)
lambdaClause = do
lambdaParameters <- P.some patternAtom
kwMapsTo
lambdaBody <- expressionAtoms
return LambdaClause {..}
lambda :: MonadParsec e Text m => m (Lambda 'Parsed)
lambda :: Member InfoTableBuilder r => ParsecS r (Lambda 'Parsed)
lambda = do
kwLambda
lambdaClauses <- braces (P.sepEndBy lambdaClause kwSemicolon)
@ -334,7 +328,7 @@ lambda = do
-- Data type construction declaration
-------------------------------------------------------------------------------
inductiveDef :: MonadParsec e Text m => m (InductiveDef 'Parsed)
inductiveDef :: Member InfoTableBuilder r => ParsecS r (InductiveDef 'Parsed)
inductiveDef = do
kwInductive
_inductiveName <- symbol
@ -343,14 +337,14 @@ inductiveDef = do
_inductiveConstructors <- braces $ P.sepEndBy constructorDef kwSemicolon
return InductiveDef {..}
inductiveParam :: MonadParsec e Text m => m (InductiveParameter 'Parsed)
inductiveParam :: Member InfoTableBuilder r => ParsecS r (InductiveParameter 'Parsed)
inductiveParam = parens $ do
_inductiveParameterName <- symbol
kwColon
_inductiveParameterType <- expressionAtoms
return InductiveParameter {..}
constructorDef :: MonadParsec e Text m => m (InductiveConstructorDef 'Parsed)
constructorDef :: Member InfoTableBuilder r => ParsecS r (InductiveConstructorDef 'Parsed)
constructorDef = do
_constructorName <- symbol
kwColon
@ -361,27 +355,20 @@ constructorDef = do
-- Pattern section
--------------------------------------------------------------------------------
patternAtom :: forall e m. MonadParsec e Text m => m (PatternAtom 'Parsed)
patternAtom :: Member InfoTableBuilder r => ParsecS r (PatternAtom 'Parsed)
patternAtom =
PatternAtomIden <$> name
<|> PatternAtomWildcard <$ kwWildcard
<|> (PatternAtomParens <$> parens patternAtoms)
patternAtoms ::
forall e m.
MonadParsec e Text m =>
m (PatternAtoms 'Parsed)
patternAtoms :: Member InfoTableBuilder r => ParsecS r (PatternAtoms 'Parsed)
patternAtoms = PatternAtoms <$> P.some patternAtom
--------------------------------------------------------------------------------
-- Function binding declaration
--------------------------------------------------------------------------------
functionClause ::
forall e m.
MonadParsec e Text m =>
Symbol ->
m (FunctionClause 'Parsed)
functionClause :: Member InfoTableBuilder r => Symbol -> ParsecS r (FunctionClause 'Parsed)
functionClause _clauseOwnerFunction = do
_clausePatterns <- P.many patternAtom
kwAssignment
@ -393,15 +380,12 @@ functionClause _clauseOwnerFunction = do
-- Module declaration
--------------------------------------------------------------------------------
pmodulePath ::
forall t e m.
(SingI t, MonadParsec e Text m) =>
m (ModulePathType 'Parsed t)
pmodulePath :: forall t r. (SingI t, Member InfoTableBuilder r) => ParsecS r (ModulePathType 'Parsed t)
pmodulePath = case sing :: SModuleIsTop t of
SModuleTop -> topModulePath
SModuleLocal -> symbol
moduleDef :: (SingI t, MonadParsec e Text m) => m (Module 'Parsed t)
moduleDef :: (SingI t, Member InfoTableBuilder r) => ParsecS r (Module 'Parsed t)
moduleDef = do
kwModule
_modulePath <- pmodulePath
@ -412,7 +396,7 @@ moduleDef = do
return Module {..}
-- | An ExpressionAtom which is a valid expression on its own.
atomicExpression :: forall e m. MonadParsec e Text m => m (ExpressionType 'Parsed)
atomicExpression :: Member InfoTableBuilder r => ParsecS r (ExpressionType 'Parsed)
atomicExpression = do
atom <- expressionAtom
case atom of
@ -420,7 +404,7 @@ atomicExpression = do
_ -> return ()
return $ ExpressionAtoms (NonEmpty.singleton atom)
openModule :: forall e m. MonadParsec e Text m => m (OpenModule 'Parsed)
openModule :: forall r. Member InfoTableBuilder r => ParsecS r (OpenModule 'Parsed)
openModule = do
kwOpen
_openModuleName <- name
@ -429,7 +413,7 @@ openModule = do
_openPublic <- maybe NoPublic (const Public) <$> optional kwPublic
return OpenModule {..}
where
usingOrHiding :: m UsingHiding
usingOrHiding :: ParsecS r UsingHiding
usingOrHiding =
(kwUsing >> (Using <$> symbolList))
<|> (kwHiding >> (Hiding <$> symbolList))
@ -438,12 +422,12 @@ openModule = do
-- Debugging statements
--------------------------------------------------------------------------------
eval :: MonadParsec e Text m => m (Eval 'Parsed)
eval :: Member InfoTableBuilder r => ParsecS r (Eval 'Parsed)
eval = do
kwEval
Eval <$> expressionAtoms
printS :: MonadParsec e Text m => m (Print 'Parsed)
printS :: Member InfoTableBuilder r => ParsecS r (Print 'Parsed)
printS = do
kwPrint
Print <$> expressionAtoms

View File

@ -0,0 +1,11 @@
module MiniJuvix.Syntax.Concrete.Parser.InfoTable where
import MiniJuvix.Prelude
import MiniJuvix.Syntax.Concrete.Parser.ParsedItem
newtype InfoTable = InfoTable {
_infoParsedItems :: [ParsedItem]
}
deriving newtype (Semigroup, Monoid)
makeLenses ''InfoTable

View File

@ -0,0 +1,75 @@
module MiniJuvix.Syntax.Concrete.Parser.InfoTableBuilder (
InfoTableBuilder,
registerLiteral,
registerKeyword,
ignoring,
mergeTable,
runInfoTableBuilder,
module MiniJuvix.Syntax.Concrete.Parser.InfoTable,
) where
import MiniJuvix.Prelude
import MiniJuvix.Syntax.Concrete.Parser.ParsedItem
import MiniJuvix.Syntax.Concrete.Parser.InfoTable
import MiniJuvix.Syntax.Concrete.Literal
import MiniJuvix.Syntax.Concrete.Loc
import MiniJuvix.Syntax.Concrete.Language (LiteralLoc(..))
data InfoTableBuilder m a where
RegisterItem :: ParsedItem -> InfoTableBuilder m ()
Ignoring :: m a -> InfoTableBuilder m a
MergeTable :: InfoTable -> InfoTableBuilder m ()
makeSem ''InfoTableBuilder
registerKeyword :: Member (InfoTableBuilder) r => Interval -> Sem r ()
registerKeyword i = registerItem ParsedItem {
_parsedLoc = i,
_parsedTag = ParsedTagKeyword
}
registerLiteral :: Member (InfoTableBuilder) r => LiteralLoc -> Sem r LiteralLoc
registerLiteral l =
l <$ registerItem ParsedItem {
_parsedLoc = loc,
_parsedTag = tag
}
where
tag = case _literalLocLiteral l of
LitString {} -> ParsedTagLiteralString
LitInteger {} -> ParsedTagLiteralInt
loc = getLoc l
data BuilderState = BuilderState {
_stateIgnoring :: Bool,
_stateItems :: [ParsedItem]
}
deriving stock (Show)
makeLenses ''BuilderState
iniState :: BuilderState
iniState = BuilderState {
_stateIgnoring = False,
_stateItems = []
}
build :: BuilderState -> InfoTable
build st = InfoTable (st ^. stateItems)
runInfoTableBuilder :: Sem (InfoTableBuilder ': r) a -> Sem r (InfoTable, a)
runInfoTableBuilder = fmap (first build) . runState iniState . reinterpretH
(\case
RegisterItem i -> do
unlessM (gets (^. stateIgnoring))
(modify' (over stateItems (i :)))
pureT ()
Ignoring m -> do
s0 <- gets (^. stateIgnoring)
modify (set stateIgnoring True)
r <- runTSimple m
modify (over stateIgnoring (const s0))
return r
MergeTable tbl -> do
modify' (over stateItems ((tbl ^. infoParsedItems) <>))
pureT ()
)

View File

@ -0,0 +1,21 @@
module MiniJuvix.Syntax.Concrete.Parser.ParsedItem where
import MiniJuvix.Prelude
import MiniJuvix.Syntax.Concrete.Loc
data ParsedItem = ParsedItem {
_parsedLoc :: Interval,
_parsedTag :: ParsedItemTag
}
deriving stock (Show)
instance HasLoc ParsedItem where
getLoc = _parsedLoc
data ParsedItemTag =
ParsedTagKeyword
| ParsedTagLiteralInt
| ParsedTagLiteralString
deriving stock (Show)
makeLenses ''ParsedItem

View File

@ -2,6 +2,7 @@ module MiniJuvix.Syntax.Concrete.Scoped.Highlight where
import MiniJuvix.Syntax.Concrete.Scoped.Name
import MiniJuvix.Syntax.Concrete.Loc
import MiniJuvix.Syntax.Concrete.Parser.ParsedItem
import qualified MiniJuvix.Internal.Strings as Str
import MiniJuvix.Prelude
import Prettyprinter
@ -13,6 +14,9 @@ data Face =
| FaceFunction
| FaceModule
| FaceAxiom
| FaceKeyword
| FaceString
| FaceNumber
data Property =
PropertyFace Face
@ -31,8 +35,11 @@ data SExp =
makeLenses ''Instruction
go :: [Name] -> Text
go = renderSExp . progn . mapMaybe goName
go :: [ParsedItem] -> [Name] -> Text
go items names =
renderSExp (progn (map goParsedItem items
<> mapMaybe goName names
))
progn :: [SExp] -> SExp
progn l = List (Symbol "progn" : l)
@ -57,14 +64,27 @@ instr i f =
pos l = Int (succ (l ^. locOffset . unPos))
start = pos (i ^. intStart)
end = pos (i ^. intEnd)
face = Quote (List [Symbol "face", faceSymbol ])
faceSymbol = Symbol ("minijuvix-highlight-" <> faceSymbolStr <> "-face")
face = Quote (List [Symbol "face", faceSymbol faceSymbolStr])
faceSymbolStr = case f of
FaceAxiom -> Str.axiom
FaceInductive -> Str.inductive
FaceConstructor -> Str.constructor
FaceModule -> Str.module_
FaceKeyword -> Str.keyword
FaceFunction -> Str.function
FaceNumber -> Str.number
FaceString -> Str.string
faceSymbol :: Text -> SExp
faceSymbol faceSymbolStr = Symbol ("minijuvix-highlight-" <> faceSymbolStr <> "-face")
goParsedItem :: ParsedItem -> SExp
goParsedItem i = instr (getLoc i) face
where
face = case i ^. parsedTag of
ParsedTagKeyword -> FaceKeyword
ParsedTagLiteralInt -> FaceNumber
ParsedTagLiteralString -> FaceString
goName :: Name -> Maybe SExp
goName n = do

View File

@ -5,7 +5,7 @@ module MiniJuvix.Syntax.Concrete.Scoped.Pretty.Base
where
import qualified Data.List.NonEmpty.Extra as NonEmpty
import MiniJuvix.Internal.Strings as Str
import qualified MiniJuvix.Internal.Strings as Str
import MiniJuvix.Prelude
import MiniJuvix.Syntax.Concrete.Language
import MiniJuvix.Syntax.Concrete.Scoped.Name (AbsModulePath)

View File

@ -1,7 +1,10 @@
-- | Limitations:
-- 1. A symbol introduced by a type signature can only be used once per Module.
--
module MiniJuvix.Syntax.Concrete.Scoped.Scoper where
module MiniJuvix.Syntax.Concrete.Scoped.Scoper (
module MiniJuvix.Syntax.Concrete.Scoped.Scoper,
module MiniJuvix.Syntax.Concrete.Scoped.Scoper.ScoperResult,
) where
import qualified Control.Monad.Combinators.Expr as P
import Data.Functor.Identity
@ -13,55 +16,63 @@ import Lens.Micro.Platform
import MiniJuvix.Prelude
import qualified MiniJuvix.Syntax.Concrete.Base as P
import MiniJuvix.Syntax.Concrete.Language
import MiniJuvix.Syntax.Concrete.Parser (runModuleParser)
import MiniJuvix.Syntax.Concrete.Parser (runModuleParser')
import MiniJuvix.Syntax.Concrete.Scoped.Error
import qualified MiniJuvix.Syntax.Concrete.Scoped.Name as S
import qualified MiniJuvix.Syntax.Concrete.Name as N
import MiniJuvix.Syntax.Concrete.Scoped.Scope
import qualified MiniJuvix.Syntax.Concrete.Parser.InfoTableBuilder as Parser
import MiniJuvix.Syntax.Concrete.Scoped.Scoper.Files
import MiniJuvix.Syntax.Concrete.Scoped.Scoper.InfoTableBuilder
import MiniJuvix.Syntax.Concrete.Scoped.Scoper.ScoperResult
--------------------------------------------------------------------------------
scopeCheck1IO :: FilePath -> Module 'Parsed 'ModuleTop -> IO (Either ScopeError (InfoTable, Module 'Scoped 'ModuleTop))
scopeCheck1IO :: FilePath -> Module 'Parsed 'ModuleTop -> IO (Either ScopeError ScoperResult)
scopeCheck1IO root = runFinal . embedToFinal @IO . runFilesIO . fixpointToFinal @IO . scopeCheck1 root
scopeCheck1Pure :: HashMap FilePath Text -> FilePath -> Module 'Parsed 'ModuleTop -> Either ScopeError (InfoTable, Module 'Scoped 'ModuleTop)
scopeCheck1Pure :: HashMap FilePath Text -> FilePath -> Module 'Parsed 'ModuleTop -> Either ScopeError ScoperResult
scopeCheck1Pure fs root = runIdentity . runFinal . runFilesPure fs . fixpointToFinal @Identity . scopeCheck1 root
scopeCheck1 ::
Members [Files, Fixpoint] r =>
FilePath ->
Module 'Parsed 'ModuleTop ->
Sem r (Either ScopeError (InfoTable, Module 'Scoped 'ModuleTop))
scopeCheck1 root m = fmap (second head) <$> scopeCheck root (pure m)
Sem r (Either ScopeError ScoperResult)
scopeCheck1 root m = scopeCheck root (pure m)
scopeCheck ::
Members [Files, Fixpoint] r =>
FilePath ->
NonEmpty (Module 'Parsed 'ModuleTop) ->
Sem r (Either ScopeError (InfoTable, NonEmpty (Module 'Scoped 'ModuleTop)))
Sem r (Either ScopeError ScoperResult)
scopeCheck root modules =
runError $
fmap mkResult $
Parser.runInfoTableBuilder $
runInfoTableBuilder $
runReader scopeParameters $
evalState iniScoperState $
mapM checkTopModule_ modules
where
iniScoperState :: ScoperState
iniScoperState =
ScoperState
{ _scoperModulesCache = ModulesCache mempty,
_scoperFreeNames = S.allNameIds,
_scoperModules = mempty
}
scopeParameters :: ScopeParameters
scopeParameters =
ScopeParameters
{ _scopeRootPath = root,
_scopeFileExtension = ".mjuvix",
_scopeTopParents = mempty
}
mkResult :: (Parser.InfoTable, (InfoTable, NonEmpty (Module 'Scoped 'ModuleTop))) -> ScoperResult
mkResult (pt, (st, ms)) = ScoperResult {
_resultParserTable = pt,
_resultScoperTable = st,
_resultModules = ms
}
iniScoperState :: ScoperState
iniScoperState =
ScoperState
{ _scoperModulesCache = ModulesCache mempty,
_scoperFreeNames = S.allNameIds,
_scoperModules = mempty
}
scopeParameters :: ScopeParameters
scopeParameters =
ScopeParameters
{ _scopeRootPath = root,
_scopeFileExtension = ".mjuvix",
_scopeTopParents = mempty
}
freshNameId ::
Members '[State ScoperState] r =>
@ -198,7 +209,7 @@ bindLocalModuleSymbol _moduleExportInfo _moduleRefModule =
checkImport ::
forall r.
Members '[Error ScopeError, State Scope, Reader ScopeParameters, Files, State ScoperState, Fixpoint, InfoTableBuilder] r =>
Members '[Error ScopeError, State Scope, Reader ScopeParameters, Files, State ScoperState, Fixpoint, InfoTableBuilder, Parser.InfoTableBuilder] r =>
Import 'Parsed ->
Sem r (Import 'Scoped)
checkImport import_@(Import path) = do
@ -362,15 +373,15 @@ exportScope Scope {..} = do
)
readParseModule ::
Members '[Error ScopeError, Reader ScopeParameters, Files] r =>
Members '[Error ScopeError, Reader ScopeParameters, Files, Parser.InfoTableBuilder] r =>
TopModulePath ->
Sem r (Module 'Parsed 'ModuleTop)
readParseModule mp = do
path <- modulePathToFilePath mp
txt <- readFile' path
case runModuleParser path txt of
case runModuleParser' path txt of
Left err -> throw (ErrParser (MegaParsecError err))
Right r -> return r
Right (t, r) -> Parser.mergeTable t $> r
modulePathToFilePath ::
Members '[Reader ScopeParameters] r =>
@ -463,14 +474,14 @@ checkInductiveDef InductiveDef {..} = do
checkTopModule_ ::
forall r.
Members '[Error ScopeError, Reader ScopeParameters, Files, State ScoperState, Fixpoint , InfoTableBuilder] r =>
Members '[Error ScopeError, Reader ScopeParameters, Files, State ScoperState, Fixpoint , InfoTableBuilder, Parser.InfoTableBuilder] r =>
Module 'Parsed 'ModuleTop ->
Sem r (Module 'Scoped 'ModuleTop)
checkTopModule_ = fmap (^. moduleRefModule) . checkTopModule
checkTopModule ::
forall r.
Members '[Error ScopeError, Reader ScopeParameters, Files, State ScoperState, Fixpoint , InfoTableBuilder ] r =>
Members '[Error ScopeError, Reader ScopeParameters, Files, State ScoperState, Fixpoint , InfoTableBuilder, Parser.InfoTableBuilder] r =>
Module 'Parsed 'ModuleTop ->
Sem r (ModuleRef'' 'S.NotConcrete 'ModuleTop)
checkTopModule m@(Module path params body) = do
@ -479,54 +490,54 @@ checkTopModule m@(Module path params body) = do
modify (over (scoperModulesCache . cachedModules) (HashMap.insert path r))
return r
where
checkPath :: Members '[Files, Reader ScopeParameters, Error ScopeError] s => Sem s ()
checkPath = do
expectedPath <- modulePathToFilePath path
let actualPath = getLoc path ^. intFile
unlessM (fromMaybe True <$> equalPaths' expectedPath actualPath) $
throw
( ErrWrongTopModuleName
WrongTopModuleName
{ _wrongTopModuleNameActualName = path,
_wrongTopModuleNameExpectedPath = expectedPath,
_wrongTopModuleNameActualPath = actualPath
}
)
freshTopModulePath ::
forall s.
Members '[State ScoperState] s =>
Sem s S.TopModulePath
freshTopModulePath = do
_nameId <- freshNameId
let _nameDefinedIn = S.topModulePathToAbsPath path
_nameConcrete = path
_nameDefined = getLoc (_modulePathName path)
_nameKind = S.KNameTopModule
_nameFixity = Nothing
-- This visibility annotation is not relevant
_nameVisibilityAnn = VisPublic
_nameWhyInScope = S.BecauseDefined
_nameVerbatim = N.topModulePathToDottedPath path
moduleName = S.Name' {..}
-- registerName moduleName
return moduleName
iniScope :: Scope
iniScope = emptyScope (getTopModulePath m)
checkedModule :: Sem r (ModuleRef'' 'S.NotConcrete 'ModuleTop)
checkedModule = do
evalState iniScope $ do
path' <- freshTopModulePath
localScope $
withParams params $ \params' -> do
(_moduleExportInfo, body') <- checkModuleBody body
let _moduleRefModule =
Module
{ _modulePath = path',
_moduleParameters = params',
_moduleBody = body'
}
_moduleRefName = set S.nameConcrete () path'
return ModuleRef'' {..}
checkPath :: Members '[Files, Reader ScopeParameters, Error ScopeError] s => Sem s ()
checkPath = do
expectedPath <- modulePathToFilePath path
let actualPath = getLoc path ^. intFile
unlessM (fromMaybe True <$> equalPaths' expectedPath actualPath) $
throw
( ErrWrongTopModuleName
WrongTopModuleName
{ _wrongTopModuleNameActualName = path,
_wrongTopModuleNameExpectedPath = expectedPath,
_wrongTopModuleNameActualPath = actualPath
}
)
freshTopModulePath ::
forall s.
Members '[State ScoperState] s =>
Sem s S.TopModulePath
freshTopModulePath = do
_nameId <- freshNameId
let _nameDefinedIn = S.topModulePathToAbsPath path
_nameConcrete = path
_nameDefined = getLoc (_modulePathName path)
_nameKind = S.KNameTopModule
_nameFixity = Nothing
-- This visibility annotation is not relevant
_nameVisibilityAnn = VisPublic
_nameWhyInScope = S.BecauseDefined
_nameVerbatim = N.topModulePathToDottedPath path
moduleName = S.Name' {..}
-- registerName moduleName
return moduleName
iniScope :: Scope
iniScope = emptyScope (getTopModulePath m)
checkedModule :: Sem r (ModuleRef'' 'S.NotConcrete 'ModuleTop)
checkedModule = do
evalState iniScope $ do
path' <- freshTopModulePath
localScope $
withParams params $ \params' -> do
(_moduleExportInfo, body') <- checkModuleBody body
let _moduleRefModule =
Module
{ _modulePath = path',
_moduleParameters = params',
_moduleBody = body'
}
_moduleRefName = set S.nameConcrete () path'
return ModuleRef'' {..}
withScope :: Members '[State Scope] r => Sem r a -> Sem r a
withScope ma = do
@ -537,7 +548,7 @@ withScope ma = do
checkModuleBody ::
forall r.
Members '[Error ScopeError, State Scope, Reader ScopeParameters, State ScoperState, Files, Reader LocalVars, Fixpoint , InfoTableBuilder ] r =>
Members '[Error ScopeError, State Scope, Reader ScopeParameters, State ScoperState, Files, Reader LocalVars, Fixpoint , InfoTableBuilder, Parser.InfoTableBuilder] r =>
[Statement 'Parsed] ->
Sem r (ExportInfo, [Statement 'Scoped])
checkModuleBody body = do
@ -549,7 +560,7 @@ checkModuleBody body = do
checkLocalModule ::
forall r.
Members '[Error ScopeError, State Scope, Reader ScopeParameters, State ScoperState, Files, Reader LocalVars, Fixpoint , InfoTableBuilder ] r =>
Members '[Error ScopeError, State Scope, Reader ScopeParameters, State ScoperState, Files, Reader LocalVars, Fixpoint , InfoTableBuilder, Parser.InfoTableBuilder] r =>
Module 'Parsed 'ModuleLocal ->
Sem r (Module 'Scoped 'ModuleLocal)
checkLocalModule Module {..} = do
@ -1058,7 +1069,7 @@ checkParsePatternAtom ::
checkParsePatternAtom = checkPatternAtom >=> parsePatternAtom
checkStatement ::
Members '[Error ScopeError, Reader ScopeParameters, Files, State Scope, State ScoperState, Reader LocalVars, Fixpoint , InfoTableBuilder] r =>
Members '[Error ScopeError, Reader ScopeParameters, Files, State Scope, State ScoperState, Reader LocalVars, Fixpoint , InfoTableBuilder, Parser.InfoTableBuilder] r =>
Statement 'Parsed ->
Sem r (Statement 'Scoped)
checkStatement s = case s of

View File

@ -0,0 +1,14 @@
module MiniJuvix.Syntax.Concrete.Scoped.Scoper.ScoperResult where
import MiniJuvix.Prelude
import MiniJuvix.Syntax.Concrete.Language
import qualified MiniJuvix.Syntax.Concrete.Scoped.InfoTable as Scoped
import qualified MiniJuvix.Syntax.Concrete.Parser.InfoTable as Parser
data ScoperResult = ScoperResult {
_resultParserTable :: Parser.InfoTable,
_resultScoperTable :: Scoped.InfoTable,
_resultModules :: NonEmpty (Module 'Scoped 'ModuleTop)
}
makeLenses ''ScoperResult

View File

@ -147,4 +147,3 @@ vp token keys-changed verifiers :=
auxVP (foldl (check-keys verifiers) (MakePair 0 false) keys-changed);
end;