diff --git a/juvix-stdlib b/juvix-stdlib index 8d3941afda..ee5a96ac9e 160000 --- a/juvix-stdlib +++ b/juvix-stdlib @@ -1 +1 @@ -Subproject commit 8d3941afdae706fe1c9960e7b68be799df515c32 +Subproject commit ee5a96ac9eb3c41f12e6bfa51dfa0a8ec24dc478 diff --git a/src/Juvix/Compiler/Backend/C/Extra/Serialization.hs b/src/Juvix/Compiler/Backend/C/Extra/Serialization.hs index 90433921fb..c8e59da29a 100644 --- a/src/Juvix/Compiler/Backend/C/Extra/Serialization.hs +++ b/src/Juvix/Compiler/Backend/C/Extra/Serialization.hs @@ -2,7 +2,7 @@ module Juvix.Compiler.Backend.C.Extra.Serialization where import Codec.Binary.UTF8.String qualified as UTF8 import Juvix.Compiler.Backend.C.Language -import Juvix.Prelude hiding (Binary, Unary) +import Juvix.Prelude import Language.C qualified as C import Language.C.Data.Ident qualified as C import Language.C.Pretty qualified as P diff --git a/src/Juvix/Compiler/Backend/C/Translation/FromReg.hs b/src/Juvix/Compiler/Backend/C/Translation/FromReg.hs index db82e79f47..770cf09e83 100644 --- a/src/Juvix/Compiler/Backend/C/Translation/FromReg.hs +++ b/src/Juvix/Compiler/Backend/C/Translation/FromReg.hs @@ -73,10 +73,10 @@ fromReg lims tab = getAssoc :: OperatorArity -> Text getAssoc = \case - Fixity.Unary _ -> "assoc_none" - Fixity.Binary AssocNone -> "assoc_none" - Fixity.Binary AssocLeft -> "assoc_left" - Fixity.Binary AssocRight -> "assoc_right" + Fixity.OpUnary _ -> "assoc_none" + Fixity.OpBinary AssocNone -> "assoc_none" + Fixity.OpBinary AssocLeft -> "assoc_left" + Fixity.OpBinary AssocRight -> "assoc_right" functionInfo :: CCode functionInfo = diff --git a/src/Juvix/Compiler/Backend/Html/Translation/FromTyped.hs b/src/Juvix/Compiler/Backend/Html/Translation/FromTyped.hs index 80d17beff7..23a3ceef97 100644 --- a/src/Juvix/Compiler/Backend/Html/Translation/FromTyped.hs +++ b/src/Juvix/Compiler/Backend/Html/Translation/FromTyped.hs @@ -7,7 +7,6 @@ where import Data.ByteString.Builder qualified as Builder import Data.HashMap.Strict qualified as HashMap -import Data.Text qualified as Text import Data.Time.Clock import Data.Versions (prettySemVer) import Juvix.Compiler.Backend.Html.Data @@ -23,7 +22,6 @@ import Juvix.Compiler.Internal.Translation.FromInternal.Analysis.ArityChecking.D import Juvix.Compiler.Internal.Translation.FromInternal.Analysis.TypeChecking qualified as InternalTyped import Juvix.Compiler.Internal.Translation.FromInternal.Analysis.TypeChecking.Data.Context import Juvix.Compiler.Pipeline.EntryPoint -import Juvix.Data.FixityInfo as FixityInfo import Juvix.Extra.Assets import Juvix.Extra.Strings qualified as Str import Juvix.Prelude @@ -441,9 +439,10 @@ goStatement = \case goFixity :: forall r. (Members '[Reader HtmlOptions, Reader NormalizedTable] r) => FixitySyntaxDef 'Scoped -> Sem r Html goFixity def = do - sig' <- ppHelper (ppFixityDefHeader def) + sig' <- ppHelper (ppFixityDefHeaderNew def) header' <- defHeader (def ^. fixitySymbol) sig' (def ^. fixityDoc) - let tbl' = table . tbody $ ari <> prec + prec' <- mkPrec + let tbl' = table . tbody $ ari <> prec' return $ header' <> ( Html.div @@ -452,27 +451,31 @@ goFixity def = do <> tbl' ) where - info :: FixityInfo - info = def ^. fixityInfo . withLocParam . withSourceValue + info :: ParsedFixityInfo 'Scoped + info = def ^. fixityInfo row :: Html -> Html row x = tr $ td ! Attr.class_ "src" $ x - prec :: Html - prec = case info ^. fixityPrecSame of - Just txt -> row $ toHtml ("Same precedence as " <> txt) + mkPrec :: Sem r Html + mkPrec = case info ^. fixityPrecSame of + Just txt -> do + s <- ppCodeHtml defaultOptions txt + return (row $ toHtml ("Same precedence as " <> s)) Nothing -> goPrec "Higher" (info ^. fixityPrecAbove) <> goPrec "Lower" (info ^. fixityPrecBelow) where - goPrec :: Html -> [Text] -> Html - goPrec above ls = case nonEmpty ls of + goPrec :: Html -> Maybe [S.Symbol] -> Sem r Html + goPrec above ls = case ls >>= nonEmpty of Nothing -> mempty - Just l -> row $ above <> " precedence than: " <> toHtml (Text.intercalate ", " (toList l)) + Just l -> do + l' <- foldr (\x acc -> x <> ", " <> acc) mempty <$> mapM (ppCodeHtml defaultOptions) l + return (row $ above <> " precedence than: " <> l') ari :: Html ari = - let arit = toHtml @String $ show (info ^. FixityInfo.fixityArity) + let arit = toHtml @String $ show (info ^. fixityParsedArity) assoc = toHtml @String $ case fromMaybe AssocNone (info ^. fixityAssoc) of AssocNone -> "" AssocRight -> ", right-associative" diff --git a/src/Juvix/Compiler/Concrete/Data/ScopedName.hs b/src/Juvix/Compiler/Concrete/Data/ScopedName.hs index 7ab873fad6..9e69aa62a5 100644 --- a/src/Juvix/Compiler/Concrete/Data/ScopedName.hs +++ b/src/Juvix/Compiler/Concrete/Data/ScopedName.hs @@ -10,7 +10,7 @@ import Juvix.Compiler.Concrete.Data.IsConcrete import Juvix.Compiler.Concrete.Data.Name qualified as C import Juvix.Compiler.Concrete.Data.VisibilityAnn import Juvix.Data.Fixity qualified as C -import Juvix.Data.IteratorAttribs (IteratorAttribs) +import Juvix.Data.IteratorInfo import Juvix.Data.NameId import Juvix.Data.NameKind import Juvix.Prelude @@ -71,7 +71,7 @@ data Name' n = Name' _nameKind :: NameKind, _nameDefinedIn :: AbsModulePath, _nameFixity :: Maybe C.Fixity, - _nameIterator :: Maybe IteratorAttribs, + _nameIterator :: Maybe IteratorInfo, _nameWhyInScope :: WhyInScope, _nameVisibilityAnn :: VisibilityAnn, -- | The textual representation of the name at the binding site diff --git a/src/Juvix/Compiler/Concrete/Keywords.hs b/src/Juvix/Compiler/Concrete/Keywords.hs index f57a9cc4df..98966b90d3 100644 --- a/src/Juvix/Compiler/Concrete/Keywords.hs +++ b/src/Juvix/Compiler/Concrete/Keywords.hs @@ -21,11 +21,15 @@ import Juvix.Data.Keyword.All delimSemicolon, -- keywords + kwAbove, kwAlias, kwAs, kwAssign, + kwAssoc, kwAt, kwAxiom, + kwBelow, + kwBinary, kwBracketL, kwBracketR, kwBuiltin, @@ -39,23 +43,30 @@ import Juvix.Data.Keyword.All kwImport, kwIn, kwInductive, + kwInit, kwInstance, kwIterator, kwLambda, + kwLeft, kwLet, kwMapsTo, kwModule, + kwNone, kwOf, kwOpen, kwOperator, kwPipe, kwPositive, kwPublic, + kwRange, + kwRight, kwRightArrow, + kwSame, kwSyntax, kwTerminating, kwTrait, kwType, + kwUnary, kwUsing, kwWhere, kwWildcard, @@ -63,10 +74,10 @@ import Juvix.Data.Keyword.All import Juvix.Prelude allKeywordStrings :: HashSet Text -allKeywordStrings = keywordsStrings allKeywords +allKeywordStrings = keywordsStrings reservedKeywords -allKeywords :: [Keyword] -allKeywords = +reservedKeywords :: [Keyword] +reservedKeywords = [ delimSemicolon, kwAssign, kwAt, @@ -93,15 +104,3 @@ allKeywords = kwWhere, kwWildcard ] - --- | Keywords that do not need to be reserved. Currently only for documentation --- purposes -nonKeywords :: [Keyword] -nonKeywords = - [ kwAs, - kwEq, - kwFixity, - kwOperator, - kwAlias, - kwIterator - ] diff --git a/src/Juvix/Compiler/Concrete/Language.hs b/src/Juvix/Compiler/Concrete/Language.hs index 7b386f7f14..ccd6d47f2b 100644 --- a/src/Juvix/Compiler/Concrete/Language.hs +++ b/src/Juvix/Compiler/Concrete/Language.hs @@ -2,6 +2,8 @@ module Juvix.Compiler.Concrete.Language ( module Juvix.Compiler.Concrete.Language, + module Juvix.Data.FixityInfo, + module Juvix.Data.IteratorInfo, module Juvix.Compiler.Concrete.Data.Name, module Juvix.Compiler.Concrete.Data.Stage, module Juvix.Compiler.Concrete.Data.NameRef, @@ -31,8 +33,8 @@ import Juvix.Compiler.Concrete.Data.VisibilityAnn import Juvix.Data import Juvix.Data.Ape.Base as Ape import Juvix.Data.Fixity -import Juvix.Data.FixityInfo (FixityInfo) -import Juvix.Data.IteratorAttribs +import Juvix.Data.FixityInfo (Arity (..), FixityInfo) +import Juvix.Data.IteratorInfo import Juvix.Data.Keyword import Juvix.Data.NameKind import Juvix.Parser.Lexer (isDelimiterStr) @@ -142,10 +144,6 @@ type family ModuleEndType t = res | res -> t where -- choices on the user. type ParsedPragmas = WithLoc (WithSource Pragmas) -type ParsedIteratorAttribs = WithLoc (WithSource IteratorAttribs) - -type ParsedFixityInfo = WithLoc (WithSource FixityInfo) - data Argument (s :: Stage) = ArgumentSymbol (SymbolType s) | ArgumentWildcard Wildcard @@ -269,6 +267,13 @@ deriving stock instance (Ord (AliasDef 'Parsed)) deriving stock instance (Ord (AliasDef 'Scoped)) +data ParsedIteratorInfo = ParsedIteratorInfo + { _parsedIteratorInfoInitNum :: Maybe (WithLoc Int), + _parsedIteratorInfoRangeNum :: Maybe (WithLoc Int), + _parsedIteratorInfoBraces :: Irrelevant (KeywordRef, KeywordRef) + } + deriving stock (Show, Eq, Ord, Generic) + data SyntaxDef (s :: Stage) = SyntaxFixity (FixitySyntaxDef s) | SyntaxOperator OperatorSyntaxDef @@ -287,11 +292,49 @@ deriving stock instance (Ord (SyntaxDef 'Parsed)) deriving stock instance (Ord (SyntaxDef 'Scoped)) +data ParsedFixityFields (s :: Stage) = ParsedFixityFields + { _fixityFieldsAssoc :: Maybe BinaryAssoc, + _fixityFieldsPrecSame :: Maybe (SymbolType s), + _fixityFieldsPrecBelow :: Maybe [SymbolType s], + _fixityFieldsPrecAbove :: Maybe [SymbolType s], + _fixityFieldsBraces :: Irrelevant (KeywordRef, KeywordRef) + } + +deriving stock instance (Show (ParsedFixityFields 'Parsed)) + +deriving stock instance (Show (ParsedFixityFields 'Scoped)) + +deriving stock instance (Eq (ParsedFixityFields 'Parsed)) + +deriving stock instance (Eq (ParsedFixityFields 'Scoped)) + +deriving stock instance (Ord (ParsedFixityFields 'Parsed)) + +deriving stock instance (Ord (ParsedFixityFields 'Scoped)) + +data ParsedFixityInfo (s :: Stage) = ParsedFixityInfo + { _fixityParsedArity :: WithLoc Arity, + _fixityFields :: Maybe (ParsedFixityFields s) + } + +deriving stock instance (Show (ParsedFixityInfo 'Parsed)) + +deriving stock instance (Show (ParsedFixityInfo 'Scoped)) + +deriving stock instance (Eq (ParsedFixityInfo 'Parsed)) + +deriving stock instance (Eq (ParsedFixityInfo 'Scoped)) + +deriving stock instance (Ord (ParsedFixityInfo 'Parsed)) + +deriving stock instance (Ord (ParsedFixityInfo 'Scoped)) + data FixitySyntaxDef (s :: Stage) = FixitySyntaxDef { _fixitySymbol :: SymbolType s, _fixityDoc :: Maybe (Judoc s), - _fixityInfo :: ParsedFixityInfo, + _fixityInfo :: ParsedFixityInfo s, _fixityKw :: KeywordRef, + _fixityAssignKw :: KeywordRef, _fixitySyntaxKw :: KeywordRef } @@ -314,9 +357,6 @@ data FixityDef = FixityDef } deriving stock (Show, Eq, Ord) -instance HasLoc (FixitySyntaxDef s) where - getLoc FixitySyntaxDef {..} = getLoc _fixitySyntaxKw <> getLoc _fixityInfo - data OperatorSyntaxDef = OperatorSyntaxDef { _opSymbol :: Symbol, _opFixity :: Symbol, @@ -330,7 +370,7 @@ instance HasLoc OperatorSyntaxDef where data IteratorSyntaxDef = IteratorSyntaxDef { _iterSymbol :: Symbol, - _iterAttribs :: Maybe ParsedIteratorAttribs, + _iterInfo :: Maybe ParsedIteratorInfo, _iterSyntaxKw :: KeywordRef, _iterIteratorKw :: KeywordRef } @@ -1705,7 +1745,6 @@ makeLenses ''Application makeLenses ''Let makeLenses ''FunctionParameters makeLenses ''Import -makeLenses ''FixitySyntaxDef makeLenses ''OperatorSyntaxDef makeLenses ''IteratorSyntaxDef makeLenses ''ConstructorDef @@ -1737,10 +1776,39 @@ makeLenses ''ArgumentBlock makeLenses ''NamedArgument makeLenses ''NamedApplication makeLenses ''AliasDef +makeLenses ''FixitySyntaxDef +makeLenses ''ParsedFixityInfo +makeLenses ''ParsedFixityFields + +fixityFieldHelper :: SimpleGetter (ParsedFixityFields s) (Maybe a) -> SimpleGetter (ParsedFixityInfo s) (Maybe a) +fixityFieldHelper l = to (^? fixityFields . _Just . l . _Just) + +fixityAssoc :: SimpleGetter (ParsedFixityInfo s) (Maybe (BinaryAssoc)) +fixityAssoc = fixityFieldHelper fixityFieldsAssoc + +fixityPrecSame :: SimpleGetter (ParsedFixityInfo s) (Maybe (SymbolType s)) +fixityPrecSame = fixityFieldHelper fixityFieldsPrecSame + +fixityPrecAbove :: SimpleGetter (ParsedFixityInfo s) (Maybe [SymbolType s]) +fixityPrecAbove = fixityFieldHelper fixityFieldsPrecAbove + +fixityPrecBelow :: SimpleGetter (ParsedFixityInfo s) (Maybe [SymbolType s]) +fixityPrecBelow = fixityFieldHelper fixityFieldsPrecBelow instance (SingI s) => HasLoc (AliasDef s) where getLoc AliasDef {..} = getLoc _aliasDefSyntaxKw <> getLocIdentifierType _aliasDefAsName +instance HasLoc (ParsedFixityFields s) where + getLoc d = getLoc l <> getLoc r + where + (l, r) = d ^. fixityFieldsBraces . unIrrelevant + +instance HasLoc (ParsedFixityInfo s) where + getLoc def = getLoc (def ^. fixityParsedArity) <>? (getLoc <$> def ^. fixityFields) + +instance HasLoc (FixitySyntaxDef s) where + getLoc def = getLoc (def ^. fixitySyntaxKw) <> getLoc (def ^. fixityInfo) + instance (SingI s) => HasLoc (SyntaxDef s) where getLoc = \case SyntaxFixity t -> getLoc t @@ -2427,6 +2495,13 @@ scopedIdenName f n = case n ^. scopedIdenAlias of a' <- f a pure (set scopedIdenAlias (Just a') n) +fromParsedIteratorInfo :: ParsedIteratorInfo -> IteratorInfo +fromParsedIteratorInfo ParsedIteratorInfo {..} = + IteratorInfo + { _iteratorInfoInitNum = (^. withLocParam) <$> _parsedIteratorInfoInitNum, + _iteratorInfoRangeNum = (^. withLocParam) <$> _parsedIteratorInfoRangeNum + } + instance HasFixity PostfixApplication where getFixity (PostfixApplication _ op) = fromMaybe impossible (op ^. scopedIdenName . S.nameFixity) diff --git a/src/Juvix/Compiler/Concrete/Print/Base.hs b/src/Juvix/Compiler/Concrete/Print/Base.hs index 397efdf4ef..6be7ca0454 100644 --- a/src/Juvix/Compiler/Concrete/Print/Base.hs +++ b/src/Juvix/Compiler/Concrete/Print/Base.hs @@ -22,7 +22,6 @@ import Juvix.Data.Ape.Print import Juvix.Data.CodeAnn (Ann, CodeAnn (..), ppStringLit) import Juvix.Data.CodeAnn qualified as C import Juvix.Data.Effect.ExactPrint -import Juvix.Data.IteratorAttribs import Juvix.Data.Keyword.All qualified as Kw import Juvix.Data.NameKind import Juvix.Extra.Strings qualified as Str @@ -654,16 +653,54 @@ instance PrettyPrint Precedence where PrecApp -> noLoc (pretty ("ω" :: Text)) PrecUpdate -> noLoc (pretty ("ω₁" :: Text)) -ppFixityDefHeader :: (SingI s) => PrettyPrinting (FixitySyntaxDef s) -ppFixityDefHeader FixitySyntaxDef {..} = do +ppFixityDefHeaderNew :: (SingI s) => PrettyPrinting (FixitySyntaxDef s) +ppFixityDefHeaderNew FixitySyntaxDef {..} = do let sym' = annotated (AnnKind KNameFixity) (ppSymbolType _fixitySymbol) ppCode _fixitySyntaxKw <+> ppCode _fixityKw <+> sym' +instance PrettyPrint Arity where + ppCode = \case + Unary -> noLoc Str.unary + Binary -> noLoc Str.binary + +instance PrettyPrint BinaryAssoc where + ppCode a = noLoc $ case a of + AssocNone -> Str.none + AssocLeft -> Str.left + AssocRight -> Str.right + +ppSymbolList :: (SingI s) => PrettyPrinting [SymbolType s] +ppSymbolList items = do + ppCode Kw.kwBracketL + hsepSemicolon (map ppSymbolType items) + ppCode Kw.kwBracketR + +instance (SingI s) => PrettyPrint (ParsedFixityInfo s) where + ppCode ParsedFixityInfo {..} = do + let rhs = do + ParsedFixityFields {..} <- _fixityFields + let assocItem = do + a <- _fixityFieldsAssoc + return (ppCode Kw.kwAssoc <+> ppCode Kw.kwAssign <+> ppCode a) + sameItem = do + a <- _fixityFieldsPrecSame + return (ppCode Kw.kwSame <+> ppCode Kw.kwAssign <+> ppSymbolType a) + aboveItem = do + a <- _fixityFieldsPrecAbove + return (ppCode Kw.kwAbove <+> ppCode Kw.kwAssign <+> ppSymbolList a) + belowItem = do + a <- _fixityFieldsPrecBelow + return (ppCode Kw.kwBelow <+> ppCode Kw.kwAssign <+> ppSymbolList a) + items = hsepSemicolon (catMaybes [assocItem, sameItem, aboveItem, belowItem]) + (l, r) = _fixityFieldsBraces ^. unIrrelevant + return (ppCode l <> items <> ppCode r) + ppCode _fixityParsedArity <+?> rhs + instance (SingI s) => PrettyPrint (FixitySyntaxDef s) where ppCode f@FixitySyntaxDef {..} = do - let header' = ppFixityDefHeader f - txt = pretty (_fixityInfo ^. withLocParam . withSourceText) - header' <+> braces (noLoc txt) + let header' = ppFixityDefHeaderNew f + body' = ppCode _fixityInfo + header' <+> ppCode _fixityAssignKw <+> body' instance PrettyPrint OperatorSyntaxDef where ppCode OperatorSyntaxDef {..} = do @@ -683,13 +720,28 @@ instance PrettyPrint InfixApplication where instance PrettyPrint PostfixApplication where ppCode = apeHelper +instance PrettyPrint ParsedIteratorInfo where + ppCode :: forall r. (Members '[ExactPrint, Reader Options] r) => ParsedIteratorInfo -> Sem r () + ppCode ParsedIteratorInfo {..} = do + let (l, r) = _parsedIteratorInfoBraces ^. unIrrelevant + ppInt :: WithLoc Int -> Sem r () + ppInt = morphemeWithLoc . fmap (annotate AnnLiteralInteger . pretty) + iniItem = do + a <- _parsedIteratorInfoInitNum + return (ppCode Kw.kwInit <+> ppCode Kw.kwAssign <+> ppInt a) + rangeItem = do + a <- _parsedIteratorInfoRangeNum + return (ppCode Kw.kwRange <+> ppCode Kw.kwAssign <+> ppInt a) + items = hsepSemicolon (catMaybes [iniItem, rangeItem]) + ppCode l <> items <> ppCode r + instance PrettyPrint IteratorSyntaxDef where ppCode IteratorSyntaxDef {..} = do let iterSymbol' = ppUnkindedSymbol _iterSymbol ppCode _iterSyntaxKw <+> ppCode _iterIteratorKw <+> iterSymbol' - <+?> fmap ppCode _iterAttribs + <+?> fmap ppCode _iterInfo instance PrettyPrint RecordUpdateApp where ppCode = apeHelper @@ -728,9 +780,6 @@ instance PrettyPrint (WithSource Pragmas) where let txt = pretty (Str.pragmasStart <> pragma ^. withSourceText <> Str.pragmasEnd) in annotated AnnComment (noLoc txt) <> line -instance PrettyPrint (WithSource IteratorAttribs) where - ppCode = braces . noLoc . pretty . (^. withSourceText) - ppJudocStart :: (Members '[ExactPrint, Reader Options] r) => Sem r (Maybe ()) ppJudocStart = do inBlock <- asks (^. optInJudocBlock) diff --git a/src/Juvix/Compiler/Concrete/Translation/FromParsed/Analysis/Scoping.hs b/src/Juvix/Compiler/Concrete/Translation/FromParsed/Analysis/Scoping.hs index 4f4529bdce..5ecc97a65a 100644 --- a/src/Juvix/Compiler/Concrete/Translation/FromParsed/Analysis/Scoping.hs +++ b/src/Juvix/Compiler/Concrete/Translation/FromParsed/Analysis/Scoping.hs @@ -27,7 +27,6 @@ import Juvix.Compiler.Concrete.Translation.FromSource.Data.Context (ParserResult import Juvix.Compiler.Concrete.Translation.FromSource.Data.Context qualified as Parsed import Juvix.Compiler.Pipeline.EntryPoint import Juvix.Data.FixityInfo qualified as FI -import Juvix.Data.IteratorAttribs import Juvix.Data.NameKind import Juvix.Prelude hiding (scoped) @@ -173,17 +172,14 @@ freshSymbol _nameKind _nameConcrete = do return mf | otherwise = return Nothing - iter :: Sem r (Maybe IteratorAttribs) + iter :: Sem r (Maybe IteratorInfo) iter | S.canBeIterator _nameKind = do - mma <- gets (^? scoperSyntaxIterators . scoperIterators . at _nameConcrete . _Just . symbolIteratorDef . iterAttribs) - case mma of - Just ma -> do - let attrs = maybe emptyIteratorAttribs (^. withLocParam . withSourceValue) ma - modify (set (scoperSyntaxIterators . scoperIterators . at _nameConcrete . _Just . symbolIteratorUsed) True) - return $ Just attrs - Nothing -> - return Nothing + mma :: Maybe (Maybe ParsedIteratorInfo) <- gets (^? scoperSyntaxIterators . scoperIterators . at _nameConcrete . _Just . symbolIteratorDef . iterInfo) + runFail $ do + ma <- failMaybe mma + modify (set (scoperSyntaxIterators . scoperIterators . at _nameConcrete . _Just . symbolIteratorUsed) True) + return (maybe emptyIteratorInfo fromParsedIteratorInfo ma) | otherwise = return Nothing reserveSymbolSignatureOf :: @@ -623,6 +619,33 @@ readScopeModule import_ = do addImport :: ScopeParameters -> ScopeParameters addImport = over scopeTopParents (cons import_) +checkFixityInfo :: + forall r. + (Members '[Error ScoperError, Reader ScopeParameters, State Scope, State ScoperState, State ScoperSyntax, NameIdGen, InfoTableBuilder] r) => + ParsedFixityInfo 'Parsed -> + Sem r (ParsedFixityInfo 'Scoped) +checkFixityInfo ParsedFixityInfo {..} = do + fields' <- mapM checkFields _fixityFields + return + ParsedFixityInfo + { _fixityFields = fields', + .. + } + where + checkFields :: ParsedFixityFields 'Parsed -> Sem r (ParsedFixityFields 'Scoped) + checkFields ParsedFixityFields {..} = do + same' <- mapM checkFixitySymbol _fixityFieldsPrecSame + below' <- mapM (mapM checkFixitySymbol) _fixityFieldsPrecBelow + above' <- mapM (mapM checkFixitySymbol) _fixityFieldsPrecAbove + return + ParsedFixityFields + { _fixityFieldsPrecSame = same', + _fixityFieldsPrecAbove = above', + _fixityFieldsPrecBelow = below', + _fixityFieldsAssoc, + _fixityFieldsBraces + } + checkFixitySyntaxDef :: forall r. (Members '[Error ScoperError, Reader ScopeParameters, State Scope, State ScoperState, State ScoperSyntax, NameIdGen, InfoTableBuilder] r) => @@ -631,12 +654,16 @@ checkFixitySyntaxDef :: checkFixitySyntaxDef FixitySyntaxDef {..} = topBindings $ do sym <- bindFixitySymbol _fixitySymbol doc <- mapM checkJudoc _fixityDoc + info' <- checkFixityInfo _fixityInfo registerHighlightDoc (sym ^. S.nameId) doc return FixitySyntaxDef { _fixitySymbol = sym, _fixityDoc = doc, - .. + _fixityInfo = info', + _fixityAssignKw, + _fixitySyntaxKw, + _fixityKw } resolveFixitySyntaxDef :: @@ -646,22 +673,21 @@ resolveFixitySyntaxDef :: Sem r () resolveFixitySyntaxDef fdef@FixitySyntaxDef {..} = topBindings $ do sym <- reserveSymbolOf SKNameFixity Nothing _fixitySymbol - let loc = getLoc _fixityInfo - fi = _fixityInfo ^. withLocParam . withSourceValue - same <- checkMaybeFixity loc $ fi ^. FI.fixityPrecSame - below <- mapM (checkFixitySymbol . WithLoc loc) $ fi ^. FI.fixityPrecBelow - above <- mapM (checkFixitySymbol . WithLoc loc) $ fi ^. FI.fixityPrecAbove + let fi :: ParsedFixityInfo 'Parsed = _fixityInfo + same <- mapM checkFixitySymbol (fi ^. fixityPrecSame) + below <- mapM (mapM checkFixitySymbol) (fi ^. fixityPrecBelow) + above <- mapM (mapM checkFixitySymbol) (fi ^. fixityPrecAbove) tab <- getInfoTable fid <- maybe freshNameId (return . getFixityId tab) same - let below' = map (getFixityId tab) below - above' = map (getFixityId tab) above - forM_ above' (`registerPrecedence` fid) - forM_ below' (registerPrecedence fid) + let below' = map (getFixityId tab) <$> below + above' = map (getFixityId tab) <$> above + forM_ above' $ mapM_ (`registerPrecedence` fid) + forM_ below' $ mapM_ (registerPrecedence fid) let samePrec = getPrec tab <$> same belowPrec :: Integer - belowPrec = fromIntegral $ maximum (minInt + 1 : map (getPrec tab) above) + belowPrec = fromIntegral $ maximum (minInt + 1 : maybe [] (map (getPrec tab)) above) abovePrec :: Integer - abovePrec = fromIntegral $ minimum (maxInt - 1 : map (getPrec tab) below) + abovePrec = fromIntegral $ minimum (maxInt - 1 : maybe [] (map (getPrec tab)) below) when (belowPrec >= abovePrec + 1) $ throw (ErrPrecedenceInconsistency (PrecedenceInconsistencyError fdef)) when (isJust same && not (null below && null above)) $ @@ -673,13 +699,13 @@ resolveFixitySyntaxDef fdef@FixitySyntaxDef {..} = topBindings $ do { _fixityId = Just fid, _fixityPrecedence = PrecNat prec, _fixityArity = - case fi ^. FI.fixityArity of - FI.Unary -> Unary AssocPostfix - FI.Binary -> case fi ^. FI.fixityAssoc of - Nothing -> Binary AssocNone - Just FI.AssocLeft -> Binary AssocLeft - Just FI.AssocRight -> Binary AssocRight - Just FI.AssocNone -> Binary AssocNone + case fi ^. fixityParsedArity . withLocParam of + FI.Unary -> OpUnary AssocPostfix + FI.Binary -> case fi ^. fixityAssoc of + Nothing -> OpBinary AssocNone + Just FI.AssocLeft -> OpBinary AssocLeft + Just FI.AssocRight -> OpBinary AssocRight + Just FI.AssocNone -> OpBinary AssocNone } registerFixity @$> FixityDef @@ -689,16 +715,6 @@ resolveFixitySyntaxDef fdef@FixitySyntaxDef {..} = topBindings $ do } return () where - checkMaybeFixity :: - forall r'. - (Members '[Error ScoperError, State Scope, State ScoperState] r') => - Interval -> - Maybe Text -> - Sem r' (Maybe S.Symbol) - checkMaybeFixity loc = \case - Just same -> Just <$> checkFixitySymbol (WithLoc loc same) - Nothing -> return Nothing - getFixityDef :: InfoTable -> S.Symbol -> FixityDef getFixityDef tab = fromJust . flip HashMap.lookup (tab ^. infoFixities) . (^. S.nameId) @@ -739,6 +755,7 @@ resolveIteratorSyntaxDef :: Sem r () resolveIteratorSyntaxDef s@IteratorSyntaxDef {..} = do checkNotDefined + checkAtLeastOneRange let sf = SymbolIterator { _symbolIteratorUsed = False, @@ -746,6 +763,12 @@ resolveIteratorSyntaxDef s@IteratorSyntaxDef {..} = do } modify (set (scoperSyntaxIterators . scoperIterators . at _iterSymbol) (Just sf)) where + checkAtLeastOneRange :: Sem r () + checkAtLeastOneRange = unless (maybe True (> 0) num) (throw (ErrInvalidRangeNumber (InvalidRangeNumber s))) + where + num :: Maybe Int + num = s ^? iterInfo . _Just . to fromParsedIteratorInfo . iteratorInfoRangeNum . _Just + checkNotDefined :: Sem r () checkNotDefined = whenJustM @@ -974,7 +997,7 @@ checkTopModule m@Module {..} = do _nameVisibilityAnn = VisPublic _nameWhyInScope = S.BecauseDefined _nameVerbatim = N.topModulePathToDottedPath _modulePath - _nameIterator :: Maybe IteratorAttribs + _nameIterator :: Maybe IteratorInfo _nameIterator = Nothing moduleName = S.Name' {..} registerName moduleName @@ -1890,7 +1913,7 @@ checkUnqualifiedName s = do n = NameUnqualified s checkFixitySymbol :: - (Members '[Error ScoperError, State Scope, State ScoperState] r) => + (Members '[Error ScoperError, State Scope, State ScoperState, InfoTableBuilder] r) => Symbol -> Sem r S.Symbol checkFixitySymbol s = do @@ -1899,7 +1922,10 @@ checkFixitySymbol s = do entries <- thd3 <$> lookupQualifiedSymbol ([], s) case resolveShadowing entries of [] -> throw (ErrSymNotInScope (NotInScope s scope)) - [x] -> return $ entryToSymbol x s + [x] -> do + let res = entryToSymbol x s + registerName res + return res es -> throw (ErrAmbiguousSym (AmbiguousSym n (map (PreSymbolFinal . SymbolEntry . (^. fixityEntry)) es))) where n = NameUnqualified s @@ -2149,8 +2175,8 @@ checkIterator :: checkIterator iter = do _iteratorName <- checkScopedIden (iter ^. iteratorName) case _iteratorName ^. scopedIdenName . S.nameIterator of - Just IteratorAttribs {..} -> do - case _iteratorAttribsInitNum of + Just IteratorInfo {..} -> do + case _iteratorInfoInitNum of Just n | n /= length (iter ^. iteratorInitializers) -> throw @@ -2158,7 +2184,7 @@ checkIterator iter = do IteratorInitializer {_iteratorInitializerIterator = iter} ) _ -> return () - case _iteratorAttribsRangeNum of + case _iteratorInfoRangeNum of Just n | n /= length (iter ^. iteratorRanges) -> throw @@ -2408,12 +2434,12 @@ makeExpressionTable (ExpressionAtoms atoms _) = [recordUpdate] : [appOpExplicit] mkOperator iden | Just Fixity {..} <- _nameFixity = Just $ case _fixityArity of - Unary u -> (_fixityPrecedence, P.Postfix (unaryApp <$> parseSymbolId _nameId)) + OpUnary u -> (_fixityPrecedence, P.Postfix (unaryApp <$> parseSymbolId _nameId)) where unaryApp :: ScopedIden -> Expression -> Expression unaryApp funName arg = case u of AssocPostfix -> ExpressionPostfixApplication (PostfixApplication arg funName) - Binary b -> (_fixityPrecedence, infixLRN (binaryApp <$> parseSymbolId _nameId)) + OpBinary b -> (_fixityPrecedence, infixLRN (binaryApp <$> parseSymbolId _nameId)) where binaryApp :: ScopedIden -> Expression -> Expression -> Expression binaryApp _infixAppOperator _infixAppLeft _infixAppRight = @@ -2690,12 +2716,12 @@ makePatternTable (PatternAtoms latoms _) = [appOp] : operators Fixity {..} <- failMaybe (constr ^. scopedIdenName . S.nameFixity) let _nameId = constr ^. scopedIdenName . S.nameId return $ case _fixityArity of - Unary u -> (_fixityPrecedence, P.Postfix (unaryApp <$> parseSymbolId _nameId)) + OpUnary u -> (_fixityPrecedence, P.Postfix (unaryApp <$> parseSymbolId _nameId)) where unaryApp :: ScopedIden -> PatternArg -> PatternArg unaryApp constrName = case u of AssocPostfix -> explicitP . PatternPostfixApplication . (`PatternPostfixApp` constrName) - Binary b -> (_fixityPrecedence, infixLRN (binaryInfixApp <$> parseSymbolId _nameId)) + OpBinary b -> (_fixityPrecedence, infixLRN (binaryInfixApp <$> parseSymbolId _nameId)) where binaryInfixApp :: ScopedIden -> PatternArg -> PatternArg -> PatternArg binaryInfixApp name argLeft = explicitP . PatternInfixApplication . PatternInfixApp argLeft name @@ -2755,7 +2781,8 @@ parsePatternTerm = do where parseNoInfixConstructor :: ParsePat PatternArg parseNoInfixConstructor = - explicitP . PatternConstructor + explicitP + . PatternConstructor <$> P.token constructorNoFixity mempty where constructorNoFixity :: PatternAtom 'Scoped -> Maybe ScopedIden diff --git a/src/Juvix/Compiler/Concrete/Translation/FromParsed/Analysis/Scoping/Error.hs b/src/Juvix/Compiler/Concrete/Translation/FromParsed/Analysis/Scoping/Error.hs index d69e4d6275..c76c8ca364 100644 --- a/src/Juvix/Compiler/Concrete/Translation/FromParsed/Analysis/Scoping/Error.hs +++ b/src/Juvix/Compiler/Concrete/Translation/FromParsed/Analysis/Scoping/Error.hs @@ -47,6 +47,7 @@ data ScoperError | ErrPrecedenceInconsistency PrecedenceInconsistencyError | ErrIncomparablePrecedences IncomaprablePrecedences | ErrAliasCycle AliasCycle + | ErrInvalidRangeNumber InvalidRangeNumber instance ToGenericError ScoperError where genericError = \case @@ -85,3 +86,4 @@ instance ToGenericError ScoperError where ErrPrecedenceInconsistency e -> genericError e ErrIncomparablePrecedences e -> genericError e ErrAliasCycle e -> genericError e + ErrInvalidRangeNumber e -> genericError e diff --git a/src/Juvix/Compiler/Concrete/Translation/FromParsed/Analysis/Scoping/Error/Types.hs b/src/Juvix/Compiler/Concrete/Translation/FromParsed/Analysis/Scoping/Error/Types.hs index b6577ae345..f26d897fd2 100644 --- a/src/Juvix/Compiler/Concrete/Translation/FromParsed/Analysis/Scoping/Error/Types.hs +++ b/src/Juvix/Compiler/Concrete/Translation/FromParsed/Analysis/Scoping/Error/Types.hs @@ -651,6 +651,23 @@ instance ToGenericError IteratorInitializer where i :: Interval i = getLoc _iteratorInitializerIterator +newtype InvalidRangeNumber = InvalidRangeNumber + { _invalidRangeNumber :: IteratorSyntaxDef + } + deriving stock (Show) + +instance ToGenericError InvalidRangeNumber where + genericError InvalidRangeNumber {..} = do + return + GenericError + { _genericErrorLoc = i, + _genericErrorMessage = mkAnsiText ("Iterators must be defined with at least one range" :: Doc Ann), + _genericErrorIntervals = [i] + } + where + i :: Interval + i = getLoc _invalidRangeNumber + newtype IteratorRange = IteratorRange { _iteratorRangeIterator :: Iterator 'Parsed } diff --git a/src/Juvix/Compiler/Concrete/Translation/FromSource.hs b/src/Juvix/Compiler/Concrete/Translation/FromSource.hs index f99a742e57..bdca5b6ae1 100644 --- a/src/Juvix/Compiler/Concrete/Translation/FromSource.hs +++ b/src/Juvix/Compiler/Concrete/Translation/FromSource.hs @@ -6,6 +6,7 @@ module Juvix.Compiler.Concrete.Translation.FromSource ) where +import Control.Applicative.Permutations import Data.ByteString.UTF8 qualified as BS import Data.List.NonEmpty.Extra qualified as NonEmpty import Data.Singletons @@ -514,19 +515,67 @@ aliasDef synKw = do _aliasDefAsName <- name return AliasDef {..} --------------------------------------------------------------------------------- --- Operator syntax declaration --------------------------------------------------------------------------------- - -precedence :: (Members '[InfoTableBuilder, PragmasStash, JudocStash, NameIdGen] r) => ParsecS r Precedence -precedence = PrecNat <$> (fst <$> decimal) +parsedFixityFields :: + forall r. + (Members '[InfoTableBuilder, PragmasStash, JudocStash, NameIdGen] r) => + ParsecS r (ParsedFixityFields 'Parsed) +parsedFixityFields = do + l <- kw delimBraceL + (_fixityFieldsAssoc, _fixityFieldsPrecBelow, _fixityFieldsPrecAbove, _fixityFieldsPrecSame) <- intercalateEffect semicolon $ do + as <- toPermutationWithDefault Nothing (Just <$> assoc) + bel <- toPermutationWithDefault Nothing (Just <$> belowAbove kwBelow) + abov <- toPermutationWithDefault Nothing (Just <$> belowAbove kwAbove) + sam <- toPermutationWithDefault Nothing (Just <$> same) + pure (as, bel, abov, sam) + r <- kw delimBraceR + let _fixityFieldsBraces = Irrelevant (l, r) + return ParsedFixityFields {..} + where + same :: ParsecS r Symbol + same = do + kw kwSame + kw kwAssign + symbol + + belowAbove :: Keyword -> ParsecS r [Symbol] + belowAbove aboveOrBelow = do + kw aboveOrBelow + kw kwAssign + kw kwBracketL + r <- P.sepEndBy symbol semicolon + kw kwBracketR + return r + + assoc :: ParsecS r BinaryAssoc + assoc = do + void (kw kwAssoc >> kw kwAssign) + kw kwLeft + $> AssocLeft + <|> kw kwRight + $> AssocRight + <|> kw kwNone + $> AssocNone + +parsedFixityInfo :: forall r. (Members '[InfoTableBuilder, PragmasStash, JudocStash, NameIdGen] r) => ParsecS r (ParsedFixityInfo 'Parsed) +parsedFixityInfo = do + _fixityParsedArity <- withLoc ari + _fixityFields <- optional parsedFixityFields + return ParsedFixityInfo {..} + where + ari :: ParsecS r Arity + ari = + kw kwUnary + $> Unary + <|> kw kwBinary + $> Binary fixitySyntaxDef :: forall r. (Members '[InfoTableBuilder, PragmasStash, JudocStash, NameIdGen] r) => KeywordRef -> ParsecS r (FixitySyntaxDef 'Parsed) fixitySyntaxDef _fixitySyntaxKw = P.label "" $ do + _fixityDoc <- getJudoc _fixityKw <- kw kwFixity _fixitySymbol <- symbol - _fixityInfo <- withLoc (parseYaml "{" "}") - _fixityDoc <- getJudoc + _fixityAssignKw <- kw kwAssign + _fixityInfo <- parsedFixityInfo return FixitySyntaxDef {..} operatorSyntaxDef :: forall r. (Members '[InfoTableBuilder, PragmasStash, JudocStash, NameIdGen] r) => KeywordRef -> ParsecS r OperatorSyntaxDef @@ -536,15 +585,35 @@ operatorSyntaxDef _opSyntaxKw = do _opFixity <- symbol return OperatorSyntaxDef {..} --------------------------------------------------------------------------------- --- Iterator syntax declaration --------------------------------------------------------------------------------- +parsedIteratorInfo :: + forall r. + (Members '[InfoTableBuilder, PragmasStash, JudocStash, NameIdGen] r) => + ParsecS r ParsedIteratorInfo +parsedIteratorInfo = do + l <- kw delimBraceL + (_parsedIteratorInfoInitNum, _parsedIteratorInfoRangeNum) <- intercalateEffect semicolon $ do + ini <- toPermutationWithDefault Nothing (Just <$> pinit) + ran <- toPermutationWithDefault Nothing (Just <$> prangeNum) + pure (ini, ran) + r <- kw delimBraceR + let _parsedIteratorInfoBraces = Irrelevant (l, r) + return ParsedIteratorInfo {..} + where + pinit :: ParsecS r (WithLoc Int) + pinit = do + void (kw kwInit >> kw kwAssign) + fmap fromIntegral <$> integer + + prangeNum :: ParsecS r (WithLoc Int) + prangeNum = do + void (kw kwRange >> kw kwAssign) + fmap fromIntegral <$> integer iteratorSyntaxDef :: forall r. (Members '[InfoTableBuilder, PragmasStash, JudocStash, NameIdGen] r) => KeywordRef -> ParsecS r IteratorSyntaxDef iteratorSyntaxDef _iterSyntaxKw = do _iterIteratorKw <- kw kwIterator _iterSymbol <- symbol - _iterAttribs <- optional (withLoc (parseYaml "{" "}")) + _iterInfo <- optional parsedIteratorInfo return IteratorSyntaxDef {..} -------------------------------------------------------------------------------- @@ -827,9 +896,7 @@ parseList = do -------------------------------------------------------------------------------- literalInteger :: (Members '[InfoTableBuilder, PragmasStash, JudocStash, NameIdGen] r) => ParsecS r LiteralLoc -literalInteger = do - (x, loc) <- integer - return (WithLoc loc (LitInteger x)) +literalInteger = fmap LitInteger <$> integer literalString :: (Members '[InfoTableBuilder, PragmasStash, JudocStash, NameIdGen] r) => ParsecS r LiteralLoc literalString = do diff --git a/src/Juvix/Compiler/Concrete/Translation/FromSource/Lexer.hs b/src/Juvix/Compiler/Concrete/Translation/FromSource/Lexer.hs index fbac112807..be3f0995c1 100644 --- a/src/Juvix/Compiler/Concrete/Translation/FromSource/Lexer.hs +++ b/src/Juvix/Compiler/Concrete/Translation/FromSource/Lexer.hs @@ -50,8 +50,10 @@ identifier = fmap fst identifierL identifierL :: (Members '[InfoTableBuilder] r) => ParsecS r (Text, Interval) identifierL = lexeme bareIdentifier -integer :: (Members '[InfoTableBuilder] r) => ParsecS r (Integer, Interval) -integer = integer' decimal +integer :: (Members '[InfoTableBuilder] r) => ParsecS r (WithLoc Integer) +integer = do + (num, i) <- integer' decimal + return (WithLoc i num) bracedString :: forall e m. (MonadParsec e Text m) => m Text bracedString = diff --git a/src/Juvix/Compiler/Core/Language/Nodes.hs b/src/Juvix/Compiler/Core/Language/Nodes.hs index 850391d847..e79c1f8b36 100644 --- a/src/Juvix/Compiler/Core/Language/Nodes.hs +++ b/src/Juvix/Compiler/Core/Language/Nodes.hs @@ -310,7 +310,7 @@ lambdaFixity :: Fixity lambdaFixity = Fixity { _fixityPrecedence = PrecNat 0, - _fixityArity = Unary AssocPostfix, + _fixityArity = OpUnary AssocPostfix, _fixityId = Nothing } diff --git a/src/Juvix/Data/Effect/ExactPrint.hs b/src/Juvix/Data/Effect/ExactPrint.hs index e9b44dff7d..285410be93 100644 --- a/src/Juvix/Data/Effect/ExactPrint.hs +++ b/src/Juvix/Data/Effect/ExactPrint.hs @@ -8,6 +8,7 @@ import Juvix.Data.CodeAnn qualified as C import Juvix.Data.Effect.ExactPrint.Base import Juvix.Data.IsImplicit import Juvix.Data.Keyword.All +import Juvix.Data.WithLoc import Juvix.Prelude.Base hiding ((<+>)) import Juvix.Prelude.Pretty qualified as P @@ -173,6 +174,9 @@ delimIf ImplicitInstance _ = doubleBraces delimIf Explicit True = parens delimIf Explicit False = id +morphemeWithLoc :: forall r. (Members '[ExactPrint] r) => WithLoc (Doc C.CodeAnn) -> Sem r () +morphemeWithLoc (WithLoc loc doc) = morpheme loc doc + morpheme :: forall r. (Members '[ExactPrint] r) => Interval -> Doc C.CodeAnn -> Sem r () morpheme loc doc = do void (printCommentsUntil loc) diff --git a/src/Juvix/Data/Fixity.hs b/src/Juvix/Data/Fixity.hs index 8533183872..ec990654e2 100644 --- a/src/Juvix/Data/Fixity.hs +++ b/src/Juvix/Data/Fixity.hs @@ -22,8 +22,8 @@ data BinaryAssoc deriving stock (Show, Eq, Ord, Data) data OperatorArity - = Unary UnaryAssoc - | Binary BinaryAssoc + = OpUnary UnaryAssoc + | OpBinary BinaryAssoc deriving stock (Show, Eq, Ord, Data) data Fixity = Fixity @@ -48,23 +48,23 @@ class HasFixity a where isLeftAssoc :: Fixity -> Bool isLeftAssoc opInf = case opInf ^. fixityArity of - Binary AssocLeft -> True + OpBinary AssocLeft -> True _ -> False isRightAssoc :: Fixity -> Bool isRightAssoc opInf = case opInf ^. fixityArity of - Binary AssocRight -> True + OpBinary AssocRight -> True _ -> False isPostfixAssoc :: Fixity -> Bool isPostfixAssoc opInf = case opInf ^. fixityArity of - Unary AssocPostfix -> True + OpUnary AssocPostfix -> True _ -> False isBinary :: Fixity -> Bool isBinary f = case f ^. fixityArity of - Binary {} -> True - Unary {} -> False + OpBinary {} -> True + OpUnary {} -> False isUnary :: Fixity -> Bool isUnary = not . isBinary @@ -73,7 +73,7 @@ appFixity :: Fixity appFixity = Fixity { _fixityPrecedence = PrecApp, - _fixityArity = (Binary AssocLeft), + _fixityArity = (OpBinary AssocLeft), _fixityId = Nothing } @@ -81,7 +81,7 @@ funFixity :: Fixity funFixity = Fixity { _fixityPrecedence = PrecArrow, - _fixityArity = (Binary AssocRight), + _fixityArity = (OpBinary AssocRight), _fixityId = Nothing } @@ -89,7 +89,7 @@ updateFixity :: Fixity updateFixity = Fixity { _fixityPrecedence = PrecUpdate, - _fixityArity = (Unary AssocPostfix), + _fixityArity = (OpUnary AssocPostfix), _fixityId = Nothing } diff --git a/src/Juvix/Data/IteratorAttribs.hs b/src/Juvix/Data/IteratorAttribs.hs deleted file mode 100644 index 714872d464..0000000000 --- a/src/Juvix/Data/IteratorAttribs.hs +++ /dev/null @@ -1,30 +0,0 @@ -module Juvix.Data.IteratorAttribs where - -import Juvix.Data.Yaml -import Juvix.Prelude.Base - -data IteratorAttribs = IteratorAttribs - { _iteratorAttribsInitNum :: Maybe Int, - _iteratorAttribsRangeNum :: Maybe Int - } - deriving stock (Show, Eq, Ord, Generic) - -instance FromJSON IteratorAttribs where - parseJSON = toAesonParser id parseAttribs - where - parseAttribs :: Parse YamlError IteratorAttribs - parseAttribs = do - checkYamlKeys ["init", "range"] - _iteratorAttribsInitNum <- keyMay "init" asIntegral - _iteratorAttribsRangeNum <- keyMay "range" asIntegral - unless - (maybe True (> 0) _iteratorAttribsRangeNum) - (throwCustomError "the iterator must have at least one range") - return IteratorAttribs {..} - -emptyIteratorAttribs :: IteratorAttribs -emptyIteratorAttribs = - IteratorAttribs - { _iteratorAttribsInitNum = Nothing, - _iteratorAttribsRangeNum = Nothing - } diff --git a/src/Juvix/Data/IteratorInfo.hs b/src/Juvix/Data/IteratorInfo.hs new file mode 100644 index 0000000000..6074cb3c28 --- /dev/null +++ b/src/Juvix/Data/IteratorInfo.hs @@ -0,0 +1,18 @@ +module Juvix.Data.IteratorInfo where + +import Juvix.Prelude.Base + +data IteratorInfo = IteratorInfo + { _iteratorInfoInitNum :: Maybe Int, + _iteratorInfoRangeNum :: Maybe Int + } + deriving stock (Show, Eq, Ord, Generic) + +makeLenses ''IteratorInfo + +emptyIteratorInfo :: IteratorInfo +emptyIteratorInfo = + IteratorInfo + { _iteratorInfoInitNum = Nothing, + _iteratorInfoRangeNum = Nothing + } diff --git a/src/Juvix/Data/Keyword/All.hs b/src/Juvix/Data/Keyword/All.hs index 5c34ae8e48..2f7e51e0da 100644 --- a/src/Juvix/Data/Keyword/All.hs +++ b/src/Juvix/Data/Keyword/All.hs @@ -88,6 +88,39 @@ kwRightArrow = unicodeKw Str.toAscii Str.toUnicode kwSyntax :: Keyword kwSyntax = asciiKw Str.syntax +kwInit :: Keyword +kwInit = asciiKw Str.init + +kwRange :: Keyword +kwRange = asciiKw Str.range + +kwAssoc :: Keyword +kwAssoc = asciiKw Str.assoc + +kwNone :: Keyword +kwNone = asciiKw Str.none + +kwRight :: Keyword +kwRight = asciiKw Str.right + +kwLeft :: Keyword +kwLeft = asciiKw Str.left + +kwUnary :: Keyword +kwUnary = asciiKw Str.unary + +kwBinary :: Keyword +kwBinary = asciiKw Str.binary + +kwSame :: Keyword +kwSame = asciiKw Str.same + +kwBelow :: Keyword +kwBelow = asciiKw Str.below + +kwAbove :: Keyword +kwAbove = asciiKw Str.above + kwAlias :: Keyword kwAlias = asciiKw Str.alias diff --git a/src/Juvix/Extra/Strings.hs b/src/Juvix/Extra/Strings.hs index 58d7194a52..c238d81ecb 100644 --- a/src/Juvix/Extra/Strings.hs +++ b/src/Juvix/Extra/Strings.hs @@ -110,6 +110,15 @@ open = "open" syntax :: (IsString s) => s syntax = "syntax" +below :: (IsString s) => s +below = "below" + +above :: (IsString s) => s +above = "above" + +assoc :: (IsString s) => s +assoc = "assoc" + fixity :: (IsString s) => s fixity = "fixity" @@ -739,3 +748,27 @@ nil = "nil" cons :: (IsString s) => s cons = "cons" + +unary :: (IsString s) => s +unary = "unary" + +binary :: (IsString s) => s +binary = "binary" + +left :: (IsString s) => s +left = "left" + +right :: (IsString s) => s +right = "right" + +same :: (IsString s) => s +same = "same" + +none :: (IsString s) => s +none = "none" + +init :: (IsString s) => s +init = "init" + +range :: (IsString s) => s +range = "range" diff --git a/test/Scope/Negative.hs b/test/Scope/Negative.hs index c748837418..5aa5c2a098 100644 --- a/test/Scope/Negative.hs +++ b/test/Scope/Negative.hs @@ -330,6 +330,13 @@ scoperErrorTests = $ \case ErrAliasCycle {} -> Nothing _ -> wrongError, + NegTest + "Invalid range number in iterator definition" + $(mkRelDir ".") + $(mkRelFile "InvalidRangeNumber.juvix") + $ \case + ErrInvalidRangeNumber {} -> Nothing + _ -> wrongError, NegTest "Dangling double brace" $(mkRelDir "Internal") diff --git a/tests/Compilation/positive/test045.juvix b/tests/Compilation/positive/test045.juvix index d99c2428e6..756a6bc058 100644 --- a/tests/Compilation/positive/test045.juvix +++ b/tests/Compilation/positive/test045.juvix @@ -8,7 +8,7 @@ type Nat := | zero : Nat | suc : Nat → Nat; -syntax fixity additive {arity: binary, assoc: left}; +syntax fixity additive := binary {assoc := left}; syntax operator + additive; diff --git a/tests/Compilation/positive/test052.juvix b/tests/Compilation/positive/test052.juvix index 1e4ef13904..0a1e4d749e 100644 --- a/tests/Compilation/positive/test052.juvix +++ b/tests/Compilation/positive/test052.juvix @@ -156,7 +156,7 @@ evalNat : Expr -> Either Error Nat Λ : Expr -> Expr | body := lam (mkLambda body); -syntax fixity app {arity: binary, assoc: left, above: [composition]}; +syntax fixity app := binary {assoc := left; above := [composition]}; syntax operator # app; --- Syntactical helper for creating an ;app;. diff --git a/tests/Compilation/positive/test054.juvix b/tests/Compilation/positive/test054.juvix index 03ed5ee5ab..aae917428a 100644 --- a/tests/Compilation/positive/test054.juvix +++ b/tests/Compilation/positive/test054.juvix @@ -7,7 +7,7 @@ syntax iterator myfor; myfor : {A B : Type} → (A → B → A) → A → List B → A := foldl {_} {_}; -syntax iterator mymap {init: 0}; +syntax iterator mymap {init := 0}; mymap : {A B : Type} → (A → B) → List A → List B | f nil := nil | f (x :: xs) := f x :: mymap f xs; @@ -20,7 +20,7 @@ sum' : List Nat → Nat lst : List Nat := 1 :: 2 :: 3 :: 4 :: 5 :: nil; -syntax iterator myfor2 {init: 1, range: 2}; +syntax iterator myfor2 {init := 1; range := 2}; myfor2 : {A B C : Type} → (A → B → C → A) @@ -33,7 +33,7 @@ myfor2 myfor (acc'' := acc') (y in ys) f acc'' x y; -syntax iterator myzip2 {init: 2, range: 2}; +syntax iterator myzip2 {init := 2; range := 2}; myzip2 : {A A' B C : Type} → (A → A' → B → C → A × A') diff --git a/tests/Compilation/positive/test060.juvix b/tests/Compilation/positive/test060.juvix index 85f6d245bd..df3c1ad580 100644 --- a/tests/Compilation/positive/test060.juvix +++ b/tests/Compilation/positive/test060.juvix @@ -4,17 +4,17 @@ module test060; import Stdlib.Prelude open hiding {fst}; type Triple (A B C : Type) := - | mkTriple { - fst : A; - snd : B; - thd : C - }; + mkTriple { + fst : A; + snd : B; + thd : C + }; type Pair (A B : Type) := - | mkPair { - fst : A; - snd : B - }; + mkPair { + fst : A; + snd : B + }; mf : Pair (Pair Bool (List Nat)) (List Nat) → Bool | mkPair@{fst := mkPair@{fst; snd := nil}; diff --git a/tests/negative/230/Foo/Data/Bool.juvix b/tests/negative/230/Foo/Data/Bool.juvix index 89f8937f86..022ca0441d 100644 --- a/tests/negative/230/Foo/Data/Bool.juvix +++ b/tests/negative/230/Foo/Data/Bool.juvix @@ -2,7 +2,7 @@ module Foo.Data.Bool; import Stdlib.Data.Bool; -syntax fixity logical {arity: binary, assoc: right}; +syntax fixity logical := binary {assoc := right}; type Bool := | true : Bool diff --git a/tests/negative/DuplicateOperator.juvix b/tests/negative/DuplicateOperator.juvix index de8838ccc6..378c056432 100644 --- a/tests/negative/DuplicateOperator.juvix +++ b/tests/negative/DuplicateOperator.juvix @@ -1,6 +1,6 @@ module DuplicateOperator; - syntax fixity add {arity: binary}; + syntax fixity add := binary; syntax operator + add; diff --git a/tests/negative/IncomparablePrecedences.juvix b/tests/negative/IncomparablePrecedences.juvix index 57b0e8c5b2..ee2d34f364 100644 --- a/tests/negative/IncomparablePrecedences.juvix +++ b/tests/negative/IncomparablePrecedences.juvix @@ -2,8 +2,8 @@ module IncomparablePrecedences; type Bool := true | false; -syntax fixity log1 {arity: binary, assoc: left}; -syntax fixity log2 {arity: binary, assoc: right}; +syntax fixity log1 := binary {assoc := left}; +syntax fixity log2 := binary {assoc := right}; syntax operator && log1; syntax operator || log2; diff --git a/tests/negative/InfixError.juvix b/tests/negative/InfixError.juvix index 5fa09d5bf4..78234815cb 100644 --- a/tests/negative/InfixError.juvix +++ b/tests/negative/InfixError.juvix @@ -1,6 +1,6 @@ module InfixError; - syntax fixity add {arity: binary, assoc: none}; + syntax fixity add := binary {assoc := none}; syntax operator + add; axiom + : Type → Type → Type; diff --git a/tests/negative/InfixErrorP.juvix b/tests/negative/InfixErrorP.juvix index 93a8a4ead7..740b5d8e57 100644 --- a/tests/negative/InfixErrorP.juvix +++ b/tests/negative/InfixErrorP.juvix @@ -1,6 +1,6 @@ module InfixErrorP; - syntax fixity pair {arity: binary}; + syntax fixity pair := binary; syntax operator , pair; diff --git a/tests/negative/InvalidRangeNumber.juvix b/tests/negative/InvalidRangeNumber.juvix new file mode 100644 index 0000000000..f6bf90b0e6 --- /dev/null +++ b/tests/negative/InvalidRangeNumber.juvix @@ -0,0 +1,5 @@ +module InvalidRangeNumber; + +syntax iterator wrong {range := 0}; + +wrong : Type := Type; diff --git a/tests/negative/Iterators1.juvix b/tests/negative/Iterators1.juvix index 51cd1794d9..9ddc7b8d70 100644 --- a/tests/negative/Iterators1.juvix +++ b/tests/negative/Iterators1.juvix @@ -1,6 +1,6 @@ module Iterators1; -syntax iterator map {init: 0}; +syntax iterator map {init := 0}; map : {A B : Type} → (A → B) → A → B | f x := f x; diff --git a/tests/negative/Iterators2.juvix b/tests/negative/Iterators2.juvix index 2fae6c3c48..efbcbc0744 100644 --- a/tests/negative/Iterators2.juvix +++ b/tests/negative/Iterators2.juvix @@ -1,6 +1,6 @@ module Iterators2; -syntax iterator bind {range: 1}; +syntax iterator bind {range := 1}; bind : {A B : Type} → (A → B) → A → B | f x := f x; diff --git a/tests/negative/Iterators4.juvix b/tests/negative/Iterators4.juvix index 174049b7c8..95d8404252 100644 --- a/tests/negative/Iterators4.juvix +++ b/tests/negative/Iterators4.juvix @@ -1,7 +1,7 @@ module Iterators4; syntax iterator map; -syntax iterator map {init: 0}; +syntax iterator map {init := 0}; map {A B} (f : A → B) (x : A) : B := f x; builtin bool diff --git a/tests/negative/Termination/Data/Bool.juvix b/tests/negative/Termination/Data/Bool.juvix index 88f75fa156..42385daa7e 100644 --- a/tests/negative/Termination/Data/Bool.juvix +++ b/tests/negative/Termination/Data/Bool.juvix @@ -1,6 +1,6 @@ module Data.Bool; -syntax fixity logical {arity: binary, assoc: right}; +syntax fixity logical := binary {assoc := right}; type Bool := | true : Bool diff --git a/tests/negative/Termination/Data/Nat.juvix b/tests/negative/Termination/Data/Nat.juvix index 44164f1762..90721c2667 100644 --- a/tests/negative/Termination/Data/Nat.juvix +++ b/tests/negative/Termination/Data/Nat.juvix @@ -1,7 +1,7 @@ module Data.Nat; -syntax fixity add {arity: binary}; -syntax fixity mul {arity: binary, above: [add]}; +syntax fixity add := binary; +syntax fixity mul := binary {above := [add]}; type ℕ := | zero : ℕ diff --git a/tests/negative/UnusedOperatorDef.juvix b/tests/negative/UnusedOperatorDef.juvix index b46cd741f7..f928d1faf0 100644 --- a/tests/negative/UnusedOperatorDef.juvix +++ b/tests/negative/UnusedOperatorDef.juvix @@ -1,4 +1,4 @@ module UnusedOperatorDef; - syntax fixity add {arity: binary}; + syntax fixity add := binary; syntax operator + add; end ; diff --git a/tests/positive/Ape.juvix b/tests/positive/Ape.juvix index 8b9d95c5aa..9b268ca716 100644 --- a/tests/positive/Ape.juvix +++ b/tests/positive/Ape.juvix @@ -3,11 +3,11 @@ module Ape; builtin string axiom String : Type; -syntax fixity seq {arity: binary, assoc: left}; -syntax fixity sub {arity: binary, assoc: right, above: [seq]}; -syntax fixity ladd {arity: binary, assoc: left, above: [sub]}; -syntax fixity radd {arity: binary, assoc: right, same: ladd}; -syntax fixity mul {arity: binary, assoc: left, above: [ladd]}; +syntax fixity seq := binary {assoc := left}; +syntax fixity sub := binary {assoc := right; above := [seq]}; +syntax fixity ladd := binary {assoc := left; above := [sub]}; +syntax fixity radd := binary {assoc := right; same := ladd}; +syntax fixity mul := binary {assoc := left; above := [ladd]}; syntax operator * mul; axiom * : String → String → String; diff --git a/tests/positive/Format.juvix b/tests/positive/Format.juvix index 6c3e0f9e2a..fa38ac0ac5 100644 --- a/tests/positive/Format.juvix +++ b/tests/positive/Format.juvix @@ -87,11 +87,11 @@ t3 : String := -- escaping in String literals e1 : String := "\"\n"; -syntax fixity l1 {arity: binary, assoc: left, below: [pair]}; -syntax fixity r3 {arity: binary, assoc: right, above: [pair]}; -syntax fixity l6 {arity: binary, assoc: left, above: [r3]}; -syntax fixity r6 {arity: binary, assoc: right, same: l6}; -syntax fixity l7 {arity: binary, assoc: left, above: [l6]}; +syntax fixity l1 := binary {assoc := left; below := [pair]}; +syntax fixity r3 := binary {assoc := right; above := [pair]}; +syntax fixity l6 := binary {assoc := left; above := [r3]}; +syntax fixity r6 := binary {assoc := right; same := l6}; +syntax fixity l7 := binary {assoc := left; above := [l6]}; syntax operator +l7 l7; axiom +l7 : String → String → String; diff --git a/tests/positive/Imports/A.juvix b/tests/positive/Imports/A.juvix index 304ea31ff1..1b14f6fabb 100644 --- a/tests/positive/Imports/A.juvix +++ b/tests/positive/Imports/A.juvix @@ -1,14 +1,14 @@ module A; -syntax fixity i3 {arity: binary}; +syntax fixity i3 := binary; module M; module N; syntax operator t i3; - type T := t : T; + type T := t : T -> T -> T; end; - syntax fixity add {arity: binary, assoc: right, below: [i3]}; + syntax fixity add := binary {assoc := right; above := [i3]}; syntax operator + add; axiom + : Type → Type → Type; @@ -16,5 +16,5 @@ end; import M; -f : M.N.T - | (_ M.N.t _) := Type M.+ Type M.+ M.MType; +f : M.N.T -> M.N.T + | (a M.N.t b) := a M.N.t b; diff --git a/tests/positive/Internal/Simple.juvix b/tests/positive/Internal/Simple.juvix index d20a95ca14..f4f1105224 100644 --- a/tests/positive/Internal/Simple.juvix +++ b/tests/positive/Internal/Simple.juvix @@ -13,9 +13,9 @@ type Nat := | zero : Nat | suc : Nat → Nat; -syntax fixity cmp {arity: binary}; -syntax fixity add {arity: binary, assoc: left, above: [cmp]}; -syntax fixity cons {arity: binary, assoc: right, above: [add]}; +syntax fixity cmp := binary; +syntax fixity add := binary {assoc := left; above := [cmp]}; +syntax fixity cons := binary {assoc := right; above := [add]}; syntax operator == cmp; diff --git a/tests/positive/Iterators.juvix b/tests/positive/Iterators.juvix index 8d1034866d..d0ec842d9d 100644 --- a/tests/positive/Iterators.juvix +++ b/tests/positive/Iterators.juvix @@ -1,11 +1,11 @@ module Iterators; -syntax iterator for {init: 1, range: 1}; +syntax iterator for {init := 1; range := 1}; for {A B : Type} (f : A → B → A) (x : A) (y : B) : A := f x y; -syntax iterator itconst {init: 2, range: 2}; +syntax iterator itconst {init := 2; range := 2}; itconst : {A B C : Type} → (A → A → B → C → A) → A → A → B → C → A diff --git a/tests/positive/MutualType.juvix b/tests/positive/MutualType.juvix index 8175ce2c14..f8dca82f85 100644 --- a/tests/positive/MutualType.juvix +++ b/tests/positive/MutualType.juvix @@ -1,6 +1,6 @@ module MutualType; -syntax fixity cons {arity: binary, assoc: right}; +syntax fixity cons := binary {assoc := right}; syntax operator :: cons; --- Inductive list. diff --git a/tests/positive/Operators.juvix b/tests/positive/Operators.juvix index 536420fda2..947dfd2557 100644 --- a/tests/positive/Operators.juvix +++ b/tests/positive/Operators.juvix @@ -1,6 +1,6 @@ module Operators; -syntax fixity add {arity: binary, assoc: left}; +syntax fixity add := binary {assoc := left}; syntax operator + add; axiom + : Type → Type → Type; diff --git a/tests/positive/Reachability/Data/Nat.juvix b/tests/positive/Reachability/Data/Nat.juvix index f191f2efed..e7a5154b9f 100644 --- a/tests/positive/Reachability/Data/Nat.juvix +++ b/tests/positive/Reachability/Data/Nat.juvix @@ -1,7 +1,7 @@ module Data.Nat; -syntax fixity add {arity: binary, assoc: left}; -syntax fixity mul {arity: binary, assoc: left, above: [add]}; +syntax fixity add := binary {assoc := left}; +syntax fixity mul := binary {assoc := left; above := [add]}; type ℕ := | zero : ℕ diff --git a/tests/positive/Reachability/Data/Product.juvix b/tests/positive/Reachability/Data/Product.juvix index f69487394d..b0c2d1e990 100644 --- a/tests/positive/Reachability/Data/Product.juvix +++ b/tests/positive/Reachability/Data/Product.juvix @@ -1,6 +1,6 @@ module Data.Product; -syntax fixity prod {arity: binary}; +syntax fixity prod := binary; syntax operator × prod; type × (a : Type) (b : Type) := diff --git a/tests/positive/StdlibList/Data/Nat.juvix b/tests/positive/StdlibList/Data/Nat.juvix index f191f2efed..3b689573ea 100644 --- a/tests/positive/StdlibList/Data/Nat.juvix +++ b/tests/positive/StdlibList/Data/Nat.juvix @@ -1,7 +1,7 @@ module Data.Nat; -syntax fixity add {arity: binary, assoc: left}; -syntax fixity mul {arity: binary, assoc: left, above: [add]}; +syntax fixity add := binary {assoc := left}; +syntax fixity mul := binary {assoc := left; above := [add]}; type ℕ := | zero : ℕ diff --git a/tests/positive/StdlibList/Data/Product.juvix b/tests/positive/StdlibList/Data/Product.juvix index a647d3794a..d0f5f9d4de 100644 --- a/tests/positive/StdlibList/Data/Product.juvix +++ b/tests/positive/StdlibList/Data/Product.juvix @@ -1,6 +1,6 @@ module Data.Product; -syntax fixity prod {arity: binary}; +syntax fixity prod := binary; syntax operator × prod; type × (a : Type) (b : Type) := , : a → b → a × b; diff --git a/tests/positive/Syntax.juvix b/tests/positive/Syntax.juvix index 6c9ed1780a..83b5719238 100644 --- a/tests/positive/Syntax.juvix +++ b/tests/positive/Syntax.juvix @@ -26,7 +26,7 @@ odd : Nat -> Bool | zero := false | (suc n) := even n; -syntax fixity cmp {arity: binary}; +syntax fixity cmp := binary {}; syntax operator ==1 cmp; diff --git a/tests/positive/Termination/Data/Bool.juvix b/tests/positive/Termination/Data/Bool.juvix index 566974b7d4..9cf79c59aa 100644 --- a/tests/positive/Termination/Data/Bool.juvix +++ b/tests/positive/Termination/Data/Bool.juvix @@ -1,6 +1,6 @@ module Data.Bool; -syntax fixity logical {arity: binary, assoc: right}; +syntax fixity logical := binary {assoc := right}; type Bool := | true : Bool diff --git a/tests/positive/Termination/Data/Nat.juvix b/tests/positive/Termination/Data/Nat.juvix index 1ea39c77d2..7952e2dc04 100644 --- a/tests/positive/Termination/Data/Nat.juvix +++ b/tests/positive/Termination/Data/Nat.juvix @@ -1,7 +1,7 @@ module Data.Nat; -syntax fixity add {arity: binary, assoc: left}; -syntax fixity mul {arity: binary, assoc: left, above: [add]}; +syntax fixity add := binary {assoc := left}; +syntax fixity mul := binary {assoc := left; above := [add]}; type ℕ := | zero : ℕ diff --git a/tests/positive/Termination/Fib.juvix b/tests/positive/Termination/Fib.juvix index 651eb6332c..bfb96a9223 100644 --- a/tests/positive/Termination/Fib.juvix +++ b/tests/positive/Termination/Fib.juvix @@ -1,6 +1,6 @@ module Fib; -syntax fixity add {arity: binary, assoc: left}; +syntax fixity add := binary {assoc := left}; type Nat := | zero : Nat diff --git a/tests/positive/TypeAlias.juvix b/tests/positive/TypeAlias.juvix index 18f1f96635..0de096ca7b 100644 --- a/tests/positive/TypeAlias.juvix +++ b/tests/positive/TypeAlias.juvix @@ -13,7 +13,7 @@ x : alias := t; id : Type → Type | x := x; -syntax fixity composition {arity: binary, assoc: right}; +syntax fixity composition := binary {assoc := right}; syntax operator ⊙ composition; diff --git a/tests/positive/issue1466/M.juvix b/tests/positive/issue1466/M.juvix index 71db0ac751..2da491721d 100644 --- a/tests/positive/issue1466/M.juvix +++ b/tests/positive/issue1466/M.juvix @@ -8,7 +8,7 @@ nat : Type := ℕ; nat2 : Type := nat; -syntax fixity add {arity: binary}; +syntax fixity add := binary; syntax operator + add;