From cf8694db24640b18e5d2f9ebd7bdcdc54a1b69db Mon Sep 17 00:00:00 2001 From: Jan Mas Rovira Date: Thu, 18 Jan 2024 17:59:22 +0100 Subject: [PATCH 1/6] add location to nockma atoms --- src/Juvix/Compiler/Nockma/Language.hs | 42 +++++++++++++++---- src/Juvix/Compiler/Nockma/Pretty/Base.hs | 2 +- .../Nockma/Translation/FromSource/Base.hs | 26 ++++++++---- src/Juvix/Data/Loc.hs | 6 +-- src/Juvix/Parser/Lexer.hs | 2 +- 5 files changed, 58 insertions(+), 20 deletions(-) diff --git a/src/Juvix/Compiler/Nockma/Language.hs b/src/Juvix/Compiler/Nockma/Language.hs index 227d9281be..551c36df71 100644 --- a/src/Juvix/Compiler/Nockma/Language.hs +++ b/src/Juvix/Compiler/Nockma/Language.hs @@ -59,9 +59,15 @@ data Cell a = Cell' } deriving stock (Show, Eq, Lift) +data AtomInfo = AtomInfo + { _atomInfoHint :: Maybe AtomHint, + _atomInfoLoc :: Maybe Interval + } + deriving stock (Show, Eq, Lift) + data Atom a = Atom { _atom :: a, - _atomInfo :: Irrelevant (Maybe AtomHint) + _atomInfo :: Irrelevant AtomInfo } deriving stock (Show, Eq, Lift) @@ -192,6 +198,13 @@ makeLenses ''Program makeLenses ''Assignment makeLenses ''WithStack makeLenses ''EncodedPath +makeLenses ''AtomInfo + +atomHint :: Lens' (Atom a) (Maybe AtomHint) +atomHint = atomInfo . unIrrelevant . atomInfoHint + +atomLoc :: Lens' (Atom a) (Maybe Interval) +atomLoc = atomInfo . unIrrelevant . atomInfoLoc naturalNockOps :: HashMap Natural NockOp naturalNockOps = HashMap.fromList [(serializeOp op, op) | op <- allElements] @@ -294,15 +307,21 @@ nockBoolLiteral b instance NockNatural Natural where type ErrNockNatural Natural = NockNaturalNaturalError nockNatural a = return (a ^. atom) - nockTrue = Atom 0 (Irrelevant (Just AtomHintBool)) - nockFalse = Atom 1 (Irrelevant (Just AtomHintBool)) - nockNil = Atom 0 (Irrelevant (Just AtomHintNil)) + nockTrue = Atom 0 (Irrelevant (atomHintInfo AtomHintBool)) + nockFalse = Atom 1 (Irrelevant (atomHintInfo AtomHintBool)) + nockNil = Atom 0 (Irrelevant (atomHintInfo AtomHintNil)) nockSucc = over atom succ errInvalidOp atm = NaturalInvalidOp atm errInvalidPath atm = NaturalInvalidPath atm serializeNockOp = serializeOp serializePath = (^. encodedPath) . encodePath +atomHintInfo :: AtomHint -> AtomInfo +atomHintInfo h = + emptyAtomInfo + { _atomInfoHint = Just h + } + class IsNock nock where toNock :: nock -> Term Natural @@ -316,10 +335,10 @@ instance IsNock (Cell Natural) where toNock = TermCell instance IsNock Natural where - toNock n = TermAtom (Atom n (Irrelevant Nothing)) + toNock = TAtom instance IsNock NockOp where - toNock op = toNock (Atom (serializeOp op) (Irrelevant (Just AtomHintOp))) + toNock op = toNock (Atom (serializeOp op) (Irrelevant (atomHintInfo AtomHintOp))) instance IsNock Bool where toNock = \case @@ -327,7 +346,7 @@ instance IsNock Bool where True -> toNock (nockTrue @Natural) instance IsNock Path where - toNock pos = TermAtom (Atom (encodePath pos ^. encodedPath) (Irrelevant (Just AtomHintPath))) + toNock pos = TermAtom (Atom (encodePath pos ^. encodedPath) (Irrelevant (atomHintInfo AtomHintPath))) instance IsNock EncodedPath where toNock = toNock . decodePath' @@ -386,4 +405,11 @@ pattern TCell l r <- TermCell (Cell' l r _) pattern TAtom :: a -> Term a pattern TAtom a <- TermAtom (Atom a _) where - TAtom a = TermAtom (Atom a (Irrelevant Nothing)) + TAtom a = TermAtom (Atom a (Irrelevant emptyAtomInfo)) + +emptyAtomInfo :: AtomInfo +emptyAtomInfo = + AtomInfo + { _atomInfoHint = Nothing, + _atomInfoLoc = Nothing + } diff --git a/src/Juvix/Compiler/Nockma/Pretty/Base.hs b/src/Juvix/Compiler/Nockma/Pretty/Base.hs index 4bb2a819a8..8c75b1ae52 100644 --- a/src/Juvix/Compiler/Nockma/Pretty/Base.hs +++ b/src/Juvix/Compiler/Nockma/Pretty/Base.hs @@ -28,7 +28,7 @@ instance (PrettyCode a, NockNatural a) => PrettyCode (Atom a) where . failFromError @(ErrNockNatural a) $ do whenM (asks (^. optIgnoreHints)) fail - h' <- failMaybe (h ^. unIrrelevant) + h' <- failMaybe (atm ^. atomHint) case h' of AtomHintOp -> nockOp atm >>= ppCode AtomHintPath -> nockPath atm >>= ppCode diff --git a/src/Juvix/Compiler/Nockma/Translation/FromSource/Base.hs b/src/Juvix/Compiler/Nockma/Translation/FromSource/Base.hs index fffa95f203..3eb8c38fa6 100644 --- a/src/Juvix/Compiler/Nockma/Translation/FromSource/Base.hs +++ b/src/Juvix/Compiler/Nockma/Translation/FromSource/Base.hs @@ -6,6 +6,7 @@ import Data.Text qualified as Text import Juvix.Compiler.Nockma.Language import Juvix.Extra.Strings qualified as Str import Juvix.Parser.Error +import Juvix.Parser.Lexer (withLoc) import Juvix.Prelude hiding (Atom, many, some) import Juvix.Prelude.Parsing hiding (runParser) import Text.Megaparsec qualified as P @@ -74,18 +75,29 @@ dottedNatural = lexeme $ do atomOp :: Parser (Atom Natural) atomOp = do - op' <- choice [symbol opName $> op | (opName, op) <- HashMap.toList atomOps] - return (Atom (serializeNockOp op') (Irrelevant (Just AtomHintOp))) + WithLoc loc op' <- withLoc (choice [symbol opName $> op | (opName, op) <- HashMap.toList atomOps]) + let info = + AtomInfo + { _atomInfoHint = Just AtomHintOp, + _atomInfoLoc = Just loc + } + return (Atom (serializeNockOp op') (Irrelevant info)) atomDirection :: Parser (Atom Natural) atomDirection = do - dirs <- - symbol "S" $> [] - <|> NonEmpty.toList <$> some (choice [symbol "L" $> L, symbol "R" $> R]) - return (Atom (serializePath dirs) (Irrelevant (Just AtomHintPath))) + WithLoc loc dirs <- + withLoc $ + symbol "S" $> [] + <|> NonEmpty.toList <$> some (choice [symbol "L" $> L, symbol "R" $> R]) + let info = + AtomInfo + { _atomInfoHint = Just AtomHintOp, + _atomInfoLoc = Just loc + } + return (Atom (serializePath dirs) (Irrelevant info)) atomNat :: Parser (Atom Natural) -atomNat = (\n -> Atom n (Irrelevant Nothing)) <$> dottedNatural +atomNat = (\n -> Atom n (Irrelevant emptyAtomInfo)) <$> dottedNatural atomBool :: Parser (Atom Natural) atomBool = diff --git a/src/Juvix/Data/Loc.hs b/src/Juvix/Data/Loc.hs index d6673dcc73..2bf63d6f42 100644 --- a/src/Juvix/Data/Loc.hs +++ b/src/Juvix/Data/Loc.hs @@ -7,7 +7,7 @@ import Prettyprinter import Text.Megaparsec qualified as M newtype Pos = Pos {_unPos :: Word64} - deriving stock (Show, Eq, Ord, Data, Generic) + deriving stock (Show, Eq, Ord, Data, Generic, Lift) deriving newtype (Hashable, Num, Enum, Real, Integral) instance Serialize Pos @@ -26,7 +26,7 @@ data FileLoc = FileLoc -- | Offset wrt the start of the input. Used for syntax highlighting. _locOffset :: !Pos } - deriving stock (Show, Eq, Generic, Data) + deriving stock (Show, Eq, Generic, Data, Lift) instance Hashable FileLoc @@ -72,7 +72,7 @@ data Interval = Interval _intervalStart :: FileLoc, _intervalEnd :: FileLoc } - deriving stock (Show, Ord, Eq, Generic, Data) + deriving stock (Show, Ord, Eq, Generic, Data, Lift) instance Hashable Interval diff --git a/src/Juvix/Parser/Lexer.hs b/src/Juvix/Parser/Lexer.hs index 045eb6fe01..b1a3bb870d 100644 --- a/src/Juvix/Parser/Lexer.hs +++ b/src/Juvix/Parser/Lexer.hs @@ -215,7 +215,7 @@ interval ma = do end <- curLoc return (res, mkInterval start end) -withLoc :: ParsecS r a -> ParsecS r (WithLoc a) +withLoc :: (MonadParsec e Text m) => m a -> m (WithLoc a) withLoc ma = do (a, i) <- interval ma return (WithLoc i a) From 35ede7f288e70b820f481a647024d03d5a8b4d9e Mon Sep 17 00:00:00 2001 From: Jan Mas Rovira Date: Thu, 18 Jan 2024 19:15:19 +0100 Subject: [PATCH 2/6] add location to nockma cells --- src/Juvix/Compiler/Nockma/Evaluator.hs | 2 +- src/Juvix/Compiler/Nockma/Language.hs | 29 +++++++++++++-- src/Juvix/Compiler/Nockma/Pretty/Base.hs | 4 +-- .../Compiler/Nockma/Translation/FromAsm.hs | 2 +- .../Nockma/Translation/FromSource/Base.hs | 36 ++++++++++++++----- src/Juvix/Parser/Lexer.hs | 2 +- 6 files changed, 59 insertions(+), 16 deletions(-) diff --git a/src/Juvix/Compiler/Nockma/Evaluator.hs b/src/Juvix/Compiler/Nockma/Evaluator.hs index 7ada4da0ce..b18e64f597 100644 --- a/src/Juvix/Compiler/Nockma/Evaluator.hs +++ b/src/Juvix/Compiler/Nockma/Evaluator.hs @@ -63,7 +63,7 @@ parseCell :: Cell a -> Sem r (ParsedCell a) parseCell c = case c ^. cellLeft of - TermAtom a -> operatorOrStdlibCall a (c ^. cellRight) (c ^. cellInfo . unIrrelevant) + TermAtom a -> operatorOrStdlibCall a (c ^. cellRight) (c ^. cellCall) TermCell l -> return (ParsedAutoConsCell (AutoConsCell l (c ^. cellRight))) where operatorOrStdlibCall :: Atom a -> Term a -> Maybe (StdlibCall a) -> Sem r (ParsedCell a) diff --git a/src/Juvix/Compiler/Nockma/Language.hs b/src/Juvix/Compiler/Nockma/Language.hs index 551c36df71..ac23aa9756 100644 --- a/src/Juvix/Compiler/Nockma/Language.hs +++ b/src/Juvix/Compiler/Nockma/Language.hs @@ -52,10 +52,16 @@ data StdlibCall a = StdlibCall deriving stock instance (Lift a) => Lift (StdlibCall a) +data CellInfo a = CellInfo + { _cellInfoLoc :: Maybe Interval, + _cellInfoCall :: Maybe (StdlibCall a) + } + deriving stock (Lift) + data Cell a = Cell' { _cellLeft :: Term a, _cellRight :: Term a, - _cellInfo :: Irrelevant (Maybe (StdlibCall a)) + _cellInfo :: Irrelevant (CellInfo a) } deriving stock (Show, Eq, Lift) @@ -199,10 +205,20 @@ makeLenses ''Assignment makeLenses ''WithStack makeLenses ''EncodedPath makeLenses ''AtomInfo +makeLenses ''CellInfo atomHint :: Lens' (Atom a) (Maybe AtomHint) atomHint = atomInfo . unIrrelevant . atomInfoHint +termLoc :: Lens' (Term a) (Maybe Interval) +termLoc = undefined + +cellLoc :: Lens' (Cell a) (Maybe Interval) +cellLoc = cellInfo . unIrrelevant . cellInfoLoc + +cellCall :: Lens' (Cell a) (Maybe (StdlibCall a)) +cellCall = cellInfo . unIrrelevant . cellInfoCall + atomLoc :: Lens' (Atom a) (Maybe Interval) atomLoc = atomInfo . unIrrelevant . atomInfoLoc @@ -393,20 +409,27 @@ stdlibNumArgs = \case pattern Cell :: Term a -> Term a -> Cell a pattern Cell {_cellLeft', _cellRight'} <- Cell' _cellLeft' _cellRight' _ where - Cell a b = Cell' a b (Irrelevant Nothing) + Cell a b = Cell' a b (Irrelevant emptyCellInfo) {-# COMPLETE TCell, TAtom #-} pattern TCell :: Term a -> Term a -> Term a pattern TCell l r <- TermCell (Cell' l r _) where - TCell a b = TermCell (Cell' a b (Irrelevant Nothing)) + TCell a b = TermCell (Cell a b) pattern TAtom :: a -> Term a pattern TAtom a <- TermAtom (Atom a _) where TAtom a = TermAtom (Atom a (Irrelevant emptyAtomInfo)) +emptyCellInfo :: CellInfo a +emptyCellInfo = + CellInfo + { _cellInfoCall = Nothing, + _cellInfoLoc = Nothing + } + emptyAtomInfo :: AtomInfo emptyAtomInfo = AtomInfo diff --git a/src/Juvix/Compiler/Nockma/Pretty/Base.hs b/src/Juvix/Compiler/Nockma/Pretty/Base.hs index 8c75b1ae52..72866098b5 100644 --- a/src/Juvix/Compiler/Nockma/Pretty/Base.hs +++ b/src/Juvix/Compiler/Nockma/Pretty/Base.hs @@ -24,7 +24,7 @@ runPrettyCode :: (PrettyCode c) => Options -> c -> Doc Ann runPrettyCode opts = run . runReader opts . ppCode instance (PrettyCode a, NockNatural a) => PrettyCode (Atom a) where - ppCode atm@(Atom k h) = runFailDefaultM (annotate (AnnKind KNameFunction) <$> ppCode k) + ppCode atm = runFailDefaultM (annotate (AnnKind KNameFunction) <$> ppCode (atm ^. atom)) . failFromError @(ErrNockNatural a) $ do whenM (asks (^. optIgnoreHints)) fail @@ -70,7 +70,7 @@ instance (PrettyCode a, NockNatural a) => PrettyCode (Cell a) where m <- asks (^. optPrettyMode) stdlibCall <- runFail $ do failWhenM (asks (^. optIgnoreHints)) - failMaybe (c ^. cellInfo . unIrrelevant) >>= ppCode + failMaybe (c ^. cellCall) >>= ppCode components <- case m of AllDelimiters -> do l' <- ppCode (c ^. cellLeft) diff --git a/src/Juvix/Compiler/Nockma/Translation/FromAsm.hs b/src/Juvix/Compiler/Nockma/Translation/FromAsm.hs index f9e0ce76b2..f8530b4be3 100644 --- a/src/Juvix/Compiler/Nockma/Translation/FromAsm.hs +++ b/src/Juvix/Compiler/Nockma/Translation/FromAsm.hs @@ -771,7 +771,7 @@ callStdlibOn' s f = do _stdlibCallFunction = f } - callCell = (OpPush #. (decodeFn # callFn)) {_cellInfo = Irrelevant (Just meta)} + callCell = set cellCall (Just meta) (OpPush #. (decodeFn # callFn)) output (toNock callCell) output (replaceTopStackN fNumArgs s) diff --git a/src/Juvix/Compiler/Nockma/Translation/FromSource/Base.hs b/src/Juvix/Compiler/Nockma/Translation/FromSource/Base.hs index 3eb8c38fa6..277a0610c3 100644 --- a/src/Juvix/Compiler/Nockma/Translation/FromSource/Base.hs +++ b/src/Juvix/Compiler/Nockma/Translation/FromSource/Base.hs @@ -6,7 +6,7 @@ import Data.Text qualified as Text import Juvix.Compiler.Nockma.Language import Juvix.Extra.Strings qualified as Str import Juvix.Parser.Error -import Juvix.Parser.Lexer (withLoc) +import Juvix.Parser.Lexer (onlyInterval, withLoc) import Juvix.Prelude hiding (Atom, many, some) import Juvix.Prelude.Parsing hiding (runParser) import Text.Megaparsec qualified as P @@ -15,10 +15,10 @@ import Text.Megaparsec.Char.Lexer qualified as L type Parser = Parsec Void Text parseText :: Text -> Either MegaparsecError (Term Natural) -parseText = runParser "" +parseText = runParser noFile parseReplText :: Text -> Either MegaparsecError (ReplTerm Natural) -parseReplText = runParserFor replTerm "" +parseReplText = runParserFor replTerm noFile parseTermFile :: (MonadIO m) => FilePath -> m (Either MegaparsecError (Term Natural)) parseTermFile fp = do @@ -31,7 +31,10 @@ parseProgramFile fp = do return (runParserProgram fp txt) parseReplStatement :: Text -> Either MegaparsecError (ReplStatement Natural) -parseReplStatement = runParserFor replStatement "" +parseReplStatement = runParserFor replStatement noFile + +noFile :: FilePath +noFile = "/" runParserProgram :: FilePath -> Text -> Either MegaparsecError (Program Natural) runParserProgram = runParserFor program @@ -97,7 +100,14 @@ atomDirection = do return (Atom (serializePath dirs) (Irrelevant info)) atomNat :: Parser (Atom Natural) -atomNat = (\n -> Atom n (Irrelevant emptyAtomInfo)) <$> dottedNatural +atomNat = do + WithLoc loc n <- withLoc dottedNatural + let info = + AtomInfo + { _atomInfoHint = Nothing, + _atomInfoLoc = Just loc + } + return (Atom n (Irrelevant info)) atomBool :: Parser (Atom Natural) atomBool = @@ -106,6 +116,11 @@ atomBool = symbol "false" $> nockFalse ] +atomWithLoc :: Parser a -> Atom Natural -> Parser (Atom Natural) +atomWithLoc p n = do + loc <- onlyInterval p + return (set atomLoc (Just loc) n) + atomNil :: Parser (Atom Natural) atomNil = symbol "nil" $> nockNil @@ -122,13 +137,18 @@ iden = lexeme (takeWhile1P (Just "") isAlphaNum) cell :: Parser (Cell Natural) cell = do - lsbracket + lloc <- onlyInterval lsbracket c <- optional stdlibCall firstTerm <- term restTerms <- some term - rsbracket + rloc <- onlyInterval rsbracket let r = buildCell firstTerm restTerms - return (set cellInfo (Irrelevant c) r) + info = + CellInfo + { _cellInfoCall = c, + _cellInfoLoc = Just (lloc <> rloc) + } + return (set cellInfo (Irrelevant info) r) where stdlibCall :: Parser (StdlibCall Natural) stdlibCall = do diff --git a/src/Juvix/Parser/Lexer.hs b/src/Juvix/Parser/Lexer.hs index b1a3bb870d..80f288457c 100644 --- a/src/Juvix/Parser/Lexer.hs +++ b/src/Juvix/Parser/Lexer.hs @@ -205,7 +205,7 @@ curLoc = do offset <- getOffset return (mkLoc offset sp) -onlyInterval :: ParsecS r a -> ParsecS r Interval +onlyInterval :: (MonadParsec e Text m) => m a -> m Interval onlyInterval = fmap snd . interval interval :: (MonadParsec e Text m) => m a -> m (a, Interval) From 6bdd7f9e54e2c1122dcaae91cf0910e4f5354735 Mon Sep 17 00:00:00 2001 From: Jan Mas Rovira Date: Fri, 19 Jan 2024 09:52:51 +0100 Subject: [PATCH 3/6] add crumbs --- app/Commands/Dev/Nockma/Repl.hs | 16 +- src/Juvix/Compiler/Nockma/Evaluator.hs | 334 ++++++++++-------- src/Juvix/Compiler/Nockma/Evaluator/Crumbs.hs | 48 +++ src/Juvix/Compiler/Nockma/Evaluator/Error.hs | 15 +- .../Compiler/Nockma/Translation/FromAsm.hs | 10 +- test/Nockma/Compile/Positive.hs | 7 +- test/Nockma/Eval/Positive.hs | 2 +- 7 files changed, 272 insertions(+), 160 deletions(-) create mode 100644 src/Juvix/Compiler/Nockma/Evaluator/Crumbs.hs diff --git a/app/Commands/Dev/Nockma/Repl.hs b/app/Commands/Dev/Nockma/Repl.hs index eb02af9646..07ea3ba1e1 100644 --- a/app/Commands/Dev/Nockma/Repl.hs +++ b/app/Commands/Dev/Nockma/Repl.hs @@ -10,13 +10,13 @@ import Data.String.Interpolate (__i) import Juvix.Compiler.Nockma.Evaluator (NockEvalError, evalRepl, fromReplTerm, programAssignments) import Juvix.Compiler.Nockma.Evaluator.Options import Juvix.Compiler.Nockma.Language -import Juvix.Compiler.Nockma.Pretty (ppPrint) import Juvix.Compiler.Nockma.Pretty qualified as Nockma import Juvix.Compiler.Nockma.Translation.FromSource (parseProgramFile, parseReplStatement, parseReplText, parseText) import Juvix.Parser.Error import System.Console.Haskeline import System.Console.Repline qualified as Repline import Prelude (read) +import Juvix.Compiler.Nockma.Pretty type ReplS = State.StateT ReplState IO @@ -110,14 +110,20 @@ direction' s = Repline.dontCrash $ do liftIO (putStrLn (ppPrint p)) readTerm :: String -> Repl (Term Natural) -readTerm s = return (fromMegaParsecError (parseText (strip (pack s)))) +readTerm = return . fromMegaParsecError . parseText . strip . pack readReplTerm :: String -> Repl (Term Natural) readReplTerm s = do mprog <- getProgram - let t = run $ runError @NockEvalError (fromReplTerm (programAssignments mprog) (fromMegaParsecError (parseReplText (strip (pack s))))) + let t = + run + . runError @NockEvalError + . fromReplTerm (programAssignments mprog) + . fromMegaParsecError + . parseReplText + $ strip (pack s) case t of - Left e -> error (show e) + Left e -> error (ppTrace e) Right tv -> return tv readStatement :: String -> Repl (ReplStatement Natural) @@ -142,7 +148,7 @@ evalStatement = \case case et of Left e -> error (show e) Right ev -> case ev of - Left e -> error (show e) + Left e -> error (ppTrace e) Right res -> liftIO (putStrLn (ppPrint res)) replCommand :: String -> Repl () diff --git a/src/Juvix/Compiler/Nockma/Evaluator.hs b/src/Juvix/Compiler/Nockma/Evaluator.hs index b18e64f597..edbcfb505f 100644 --- a/src/Juvix/Compiler/Nockma/Evaluator.hs +++ b/src/Juvix/Compiler/Nockma/Evaluator.hs @@ -44,13 +44,14 @@ subTermT = go L -> (\l' -> TermCell (set cellLeft l' c)) <$> go ds g (c ^. cellLeft) R -> (\r' -> TermCell (set cellRight r' c)) <$> go ds g (c ^. cellRight) -subTerm :: (Member (Error NockEvalError) r) => Term a -> Path -> Sem r (Term a) +subTerm :: (Members '[Reader EvalCtx, Error NockEvalError] r) => Term a -> Path -> Sem r (Term a) subTerm term pos = do + ctx <- ask case term ^? subTermT pos of - Nothing -> throw (InvalidPath "subterm") + Nothing -> throw (InvalidPath ctx) Just t -> return t -setSubTerm :: (Member (Error NockEvalError) r) => Term a -> Path -> Term a -> Sem r (Term a) +setSubTerm :: (Members '[Error NockEvalError] r) => Term a -> Path -> Term a -> Sem r (Term a) setSubTerm term pos repTerm = let (old, new) = setAndRemember (subTermT' pos) repTerm term in if @@ -122,152 +123,189 @@ evalRepl handleTrace mprog defaultStack expr = do namedTerms = programAssignments mprog eval :: - forall r a. - (PrettyCode a, Integral a, Members '[Reader EvalOptions, Output (Term a), Error NockEvalError, Error (ErrNockNatural a)] r, NockNatural a) => + forall s a. + (PrettyCode a, Integral a, Members '[Reader EvalOptions, Output (Term a), Error NockEvalError, Error (ErrNockNatural a)] s, NockNatural a) => Term a -> Term a -> - Sem r (Term a) -eval stack = \case - TermAtom a -> throw (ExpectedCell ("eval " <> ppTrace a)) - TermCell c -> - parseCell c >>= \case - ParsedAutoConsCell a -> goAutoConsCell a - ParsedOperatorCell o -> goOperatorCell o - ParsedStdlibCallCell o -> do - ignore <- asks (^. evalIgnoreStdlibCalls) - if - | ignore -> goOperatorCell (o ^. stdlibCallRaw) - | otherwise -> goStdlibCall (o ^. stdlibCallCell) + Sem s (Term a) +eval inistack initerm = + topEvalCtx $ + recEval inistack initerm where - goStdlibCall :: StdlibCall a -> Sem r (Term a) - goStdlibCall StdlibCall {..} = do - args' <- eval stack _stdlibCallArgs - let binArith :: (a -> a -> a) -> Sem r (Term a) - binArith f = case args' of - TCell (TAtom l) (TAtom r) -> return (TCell (TAtom (f l r)) stack) - _ -> error "expected a cell with two atoms" - - unaArith :: (a -> a) -> Sem r (Term a) - unaArith f = case args' of - TAtom n -> return (TCell (TAtom (f n)) stack) - _ -> error "expected an atom" - - binCmp :: (a -> a -> Bool) -> Sem r (Term a) - binCmp f = case args' of - TCell (TAtom l) (TAtom r) -> return (TCell (TermAtom (nockBool (f l r))) stack) - _ -> error "expected a cell with two atoms" - - case _stdlibCallFunction of - StdlibDec -> unaArith pred - StdlibAdd -> binArith (+) - StdlibMul -> binArith (*) - StdlibSub -> binArith (-) - StdlibDiv -> binArith div - StdlibMod -> binArith mod - StdlibLt -> binCmp (<) - StdlibLe -> binCmp (<=) - - goAutoConsCell :: AutoConsCell a -> Sem r (Term a) - goAutoConsCell c = do - l' <- eval stack (TermCell (c ^. autoConsCellLeft)) - r' <- eval stack (c ^. autoConsCellRight) - return (TermCell (Cell l' r')) - - goOperatorCell :: OperatorCell a -> Sem r (Term a) - goOperatorCell c = case c ^. operatorCellOp of - OpAddress -> goOpAddress - OpQuote -> goOpQuote - OpApply -> goOpApply - OpIsCell -> goOpIsCell - OpInc -> goOpInc - OpEq -> goOpEq - OpIf -> goOpIf - OpSequence -> goOpSequence - OpPush -> goOpPush - OpCall -> goOpCall - OpReplace -> goOpReplace - OpHint -> goOpHint - OpTrace -> goOpTrace - where - goOpAddress :: Sem r (Term a) - goOpAddress = asPath (c ^. operatorCellTerm) >>= subTerm stack - - goOpQuote :: Sem r (Term a) - goOpQuote = return (c ^. operatorCellTerm) - - goOpIsCell :: Sem r (Term a) - goOpIsCell = return . TermAtom $ case c ^. operatorCellTerm of - TermCell {} -> nockTrue - TermAtom {} -> nockFalse - - goOpTrace :: Sem r (Term a) - goOpTrace = do - Cell' tr a _ <- asCell "OpTrace" (c ^. operatorCellTerm) - tr' <- eval stack tr - output tr' - eval stack a - - goOpHint :: Sem r (Term a) - goOpHint = do - -- Ignore the hint and evaluate - h <- asCell "OpHint" (c ^. operatorCellTerm) - eval stack (h ^. cellRight) - - goOpPush :: Sem r (Term a) - goOpPush = do - cellTerm <- asCell "OpPush" (c ^. operatorCellTerm) - l <- eval stack (cellTerm ^. cellLeft) - let s = TermCell (Cell l stack) - eval s (cellTerm ^. cellRight) - - goOpReplace :: Sem r (Term a) - goOpReplace = do - Cell' rot1 t2 _ <- asCell "OpReplace 1" (c ^. operatorCellTerm) - Cell' ro t1 _ <- asCell "OpReplace 2" rot1 - r <- asPath ro - t1' <- eval stack t1 - t2' <- eval stack t2 - setSubTerm t2' r t1' - - goOpApply :: Sem r (Term a) - goOpApply = do - cellTerm <- asCell "OpApply" (c ^. operatorCellTerm) - t1' <- eval stack (cellTerm ^. cellLeft) - t2' <- eval stack (cellTerm ^. cellRight) - eval t1' t2' - - goOpIf :: Sem r (Term a) - goOpIf = do - cellTerm <- asCell "OpIf 1" (c ^. operatorCellTerm) - let t0 = cellTerm ^. cellLeft - Cell' t1 t2 _ <- asCell "OpIf 2" (cellTerm ^. cellRight) - cond <- eval stack t0 >>= asBool - if - | cond -> eval stack t1 - | otherwise -> eval stack t2 - - goOpInc :: Sem r (Term a) - goOpInc = TermAtom . nockSucc <$> (eval stack (c ^. operatorCellTerm) >>= asAtom) - - goOpEq :: Sem r (Term a) - goOpEq = do - cellTerm <- asCell "OpEq" (c ^. operatorCellTerm) - l <- eval stack (cellTerm ^. cellLeft) - r <- eval stack (cellTerm ^. cellRight) - return . TermAtom $ + recEval :: + forall r. + (r ~ Reader EvalCtx ': s) => + Term a -> + Term a -> + Sem r (Term a) + recEval stack term = case term of + TermAtom a -> throw (ExpectedCell ("eval " <> ppTrace a)) + TermCell c -> + parseCell c >>= \case + ParsedAutoConsCell a -> goAutoConsCell a + ParsedOperatorCell o -> goOperatorCell o + ParsedStdlibCallCell o -> do + ignore <- asks (^. evalIgnoreStdlibCalls) if - | l == r -> nockTrue - | otherwise -> nockFalse - - goOpCall :: Sem r (Term a) - goOpCall = do - cellTerm <- asCell "OpCall" (c ^. operatorCellTerm) - r <- asPath (cellTerm ^. cellLeft) - t' <- eval stack (cellTerm ^. cellRight) - subTerm t' r >>= eval t' - - goOpSequence :: Sem r (Term a) - goOpSequence = do - cellTerm <- asCell "OpSequence" (c ^. operatorCellTerm) - t1' <- eval stack (cellTerm ^. cellLeft) - eval t1' (cellTerm ^. cellRight) + | ignore -> goOperatorCell (o ^. stdlibCallRaw) + | otherwise -> goStdlibCall (o ^. stdlibCallCell) + where + loc :: Maybe Interval + loc = term ^. termLoc + + goStdlibCall :: StdlibCall a -> Sem r (Term a) + goStdlibCall StdlibCall {..} = do + let w = EvalCrumbStdlibCallArgs (CrumbStdlibCallArgs _stdlibCallFunction) + args' <- withCrumb w (recEval stack _stdlibCallArgs) + let binArith :: (a -> a -> a) -> Sem r (Term a) + binArith f = case args' of + TCell (TAtom l) (TAtom r) -> return (TCell (TAtom (f l r)) stack) + _ -> error "expected a cell with two atoms" + + unaArith :: (a -> a) -> Sem r (Term a) + unaArith f = case args' of + TAtom n -> return (TCell (TAtom (f n)) stack) + _ -> error "expected an atom" + + binCmp :: (a -> a -> Bool) -> Sem r (Term a) + binCmp f = case args' of + TCell (TAtom l) (TAtom r) -> return (TCell (TermAtom (nockBool (f l r))) stack) + _ -> error "expected a cell with two atoms" + + case _stdlibCallFunction of + StdlibDec -> unaArith pred + StdlibAdd -> binArith (+) + StdlibMul -> binArith (*) + StdlibSub -> binArith (-) + StdlibDiv -> binArith div + StdlibMod -> binArith mod + StdlibLt -> binCmp (<) + StdlibLe -> binCmp (<=) + + goAutoConsCell :: AutoConsCell a -> Sem r (Term a) + goAutoConsCell c = do + let w a = + EvalCrumbAutoCons + CrumbAutoCons + { _crumbAutoConsArgName = a, + _crumbAutoConsLoc = loc + } + l' <- withCrumb (w FirstArg) (recEval stack (TermCell (c ^. autoConsCellLeft))) + r' <- withCrumb (w SecondArg) (recEval stack (c ^. autoConsCellRight)) + return (TermCell (Cell l' r')) + + goOperatorCell :: OperatorCell a -> Sem r (Term a) + goOperatorCell c = case c ^. operatorCellOp of + OpAddress -> goOpAddress + OpQuote -> return goOpQuote + OpApply -> goOpApply + OpIsCell -> return goOpIsCell + OpInc -> goOpInc + OpEq -> goOpEq + OpIf -> goOpIf + OpSequence -> goOpSequence + OpPush -> goOpPush + OpCall -> goOpCall + OpReplace -> goOpReplace + OpHint -> goOpHint + OpTrace -> goOpTrace + where + crumb argName = + EvalCrumbOperator $ + CrumbOperator + { _crumbOperatorOp = c ^. operatorCellOp, + _crumbOperatorArgName = argName, + _crumbOperatorLoc = loc + } + + evalArg :: ArgName -> Term a -> Term a -> Sem r (Term a) + evalArg argName stack' arg = do + withCrumb (crumb argName) (recEval stack' arg) + + goOpAddress :: Sem r (Term a) + goOpAddress = withCrumb (crumb Itself) (asPath (c ^. operatorCellTerm) >>= subTerm stack) + + goOpQuote :: Term a + goOpQuote = c ^. operatorCellTerm + + goOpIsCell :: Term a + goOpIsCell = TermAtom $ case c ^. operatorCellTerm of + TermCell {} -> nockTrue + TermAtom {} -> nockFalse + + goOpTrace :: Sem r (Term a) + goOpTrace = do + Cell' tr a _ <- withCrumb (crumb Itself) (asCell "OpTrace" (c ^. operatorCellTerm)) + tr' <- evalArg FirstArg stack tr + output tr' + evalArg SecondArg stack a + + goOpHint :: Sem r (Term a) + goOpHint = do + -- Ignore the hint and evaluate + h <- withCrumb (crumb Itself) (asCell "OpHint" (c ^. operatorCellTerm)) + evalArg FirstArg stack (h ^. cellRight) + + goOpPush :: Sem r (Term a) + goOpPush = do + cellTerm <- withCrumb (crumb Itself) (asCell "OpPush" (c ^. operatorCellTerm)) + l <- evalArg FirstArg stack (cellTerm ^. cellLeft) + let s = TermCell (Cell l stack) + evalArg SecondArg s (cellTerm ^. cellRight) + + goOpReplace :: Sem r (Term a) + goOpReplace = do + Cell' rot1 t2 _ <- withCrumb (crumb Itself) (asCell "OpReplace 1" (c ^. operatorCellTerm)) + Cell' ro t1 _ <- withCrumb (crumb Itself) (asCell "OpReplace 2" rot1) + r <- withCrumb (crumb Itself) (asPath ro) + t1' <- evalArg FirstArg stack t1 + t2' <- evalArg SecondArg stack t2 + setSubTerm t2' r t1' + + goOpApply :: Sem r (Term a) + goOpApply = do + cellTerm <- withCrumb (crumb Itself) (asCell "OpApply" (c ^. operatorCellTerm)) + t1' <- evalArg FirstArg stack (cellTerm ^. cellLeft) + t2' <- evalArg SecondArg stack (cellTerm ^. cellRight) + evalArg SecondArg t1' t2' + + goOpIf :: Sem r (Term a) + goOpIf = do + cellTerm <- withCrumb (crumb Itself) (asCell "OpIf 1" (c ^. operatorCellTerm)) + let t0 = cellTerm ^. cellLeft + Cell' t1 t2 _ <- withCrumb (crumb Itself) (asCell "OpIf 2" (cellTerm ^. cellRight)) + cond <- evalArg FirstArg stack t0 >>= asBool + if + | cond -> evalArg TrueBranch stack t1 + | otherwise -> evalArg FalseBranch stack t2 + + goOpInc :: Sem r (Term a) + goOpInc = + withCrumb + (crumb Itself) + ( TermAtom . nockSucc + <$> (evalArg FirstArg stack (c ^. operatorCellTerm) >>= asAtom) + ) + + goOpEq :: Sem r (Term a) + goOpEq = do + cellTerm <- withCrumb (crumb Itself) (asCell "OpEq" (c ^. operatorCellTerm)) + l <- evalArg FirstArg stack (cellTerm ^. cellLeft) + r <- evalArg SecondArg stack (cellTerm ^. cellRight) + return . TermAtom $ + if + | l == r -> nockTrue + | otherwise -> nockFalse + + goOpCall :: Sem r (Term a) + goOpCall = do + cellTerm <- withCrumb (crumb Itself) (asCell "OpCall" (c ^. operatorCellTerm)) + r <- withCrumb (crumb Itself) (asPath (cellTerm ^. cellLeft)) + t' <- evalArg FirstArg stack (cellTerm ^. cellRight) + subTerm t' r >>= evalArg SecondArg t' + + goOpSequence :: Sem r (Term a) + goOpSequence = do + cellTerm <- withCrumb (crumb Itself) (asCell "OpSequence" (c ^. operatorCellTerm)) + t1' <- evalArg FirstArg stack (cellTerm ^. cellLeft) + evalArg SecondArg t1' (cellTerm ^. cellRight) diff --git a/src/Juvix/Compiler/Nockma/Evaluator/Crumbs.hs b/src/Juvix/Compiler/Nockma/Evaluator/Crumbs.hs new file mode 100644 index 0000000000..62cff83127 --- /dev/null +++ b/src/Juvix/Compiler/Nockma/Evaluator/Crumbs.hs @@ -0,0 +1,48 @@ +module Juvix.Compiler.Nockma.Evaluator.Crumbs where + +import Juvix.Compiler.Nockma.Language +import Juvix.Compiler.Nockma.Pretty.Base +import Juvix.Prelude hiding (Atom) + +data EvalCrumb + = EvalCrumbStdlibCallArgs CrumbStdlibCallArgs + | EvalCrumbOperator CrumbOperator + | EvalCrumbAutoCons CrumbAutoCons + +newtype EvalCtx = EvalCtx + { _evalStack :: [EvalCrumb] + } + +topEvalCtx :: Sem (Reader EvalCtx ': r) a -> Sem r a +topEvalCtx = runReader (EvalCtx []) + +newtype CrumbStdlibCallArgs = CrumbStdlibCallArgs + { _crumbStdlibCallArgsFunction :: StdlibFunction + } + +data ArgName + = Itself + | FirstArg + | SecondArg + | ThirdArg + | TrueBranch + | FalseBranch + +data CrumbAutoCons = CrumbAutoCons + { _crumbAutoConsArgName :: ArgName, + _crumbAutoConsLoc :: Maybe Interval + } + +data CrumbOperator = CrumbOperator + { _crumbOperatorOp :: NockOp, + _crumbOperatorArgName :: ArgName, + _crumbOperatorLoc :: Maybe Interval + } + +makeLenses ''EvalCtx + +withCrumb :: (Members '[Reader EvalCtx] r) => EvalCrumb -> Sem r a -> Sem r a +withCrumb c = local (over evalStack (c :)) + +instance PrettyCode EvalCtx where + ppCode (EvalCtx l) = undefined diff --git a/src/Juvix/Compiler/Nockma/Evaluator/Error.hs b/src/Juvix/Compiler/Nockma/Evaluator/Error.hs index 2d04e39fda..6481436262 100644 --- a/src/Juvix/Compiler/Nockma/Evaluator/Error.hs +++ b/src/Juvix/Compiler/Nockma/Evaluator/Error.hs @@ -1,15 +1,20 @@ -module Juvix.Compiler.Nockma.Evaluator.Error where +module Juvix.Compiler.Nockma.Evaluator.Error + ( module Juvix.Compiler.Nockma.Evaluator.Error, + module Juvix.Compiler.Nockma.Evaluator.Crumbs, + ) +where +import Juvix.Compiler.Nockma.Evaluator.Crumbs +import Juvix.Compiler.Nockma.Pretty.Base import Juvix.Prelude hiding (Atom) import Juvix.Prelude.Pretty data NockEvalError - = InvalidPath Text + = InvalidPath EvalCtx | ExpectedAtom | ExpectedCell Text | NoStack | AssignmentNotFound Text - deriving stock (Show) newtype GenericNockEvalError = GenericNockEvalError { _genericNockEvalErrorMessage :: AnsiText @@ -17,3 +22,7 @@ newtype GenericNockEvalError = GenericNockEvalError class ToGenericNockEvalError a where toGenericNockEvalError :: a -> GenericNockEvalError + +instance PrettyCode NockEvalError where + ppCode = \case + InvalidPath ctx -> ppCode ctx diff --git a/src/Juvix/Compiler/Nockma/Translation/FromAsm.hs b/src/Juvix/Compiler/Nockma/Translation/FromAsm.hs index f8530b4be3..c99a9adedf 100644 --- a/src/Juvix/Compiler/Nockma/Translation/FromAsm.hs +++ b/src/Juvix/Compiler/Nockma/Translation/FromAsm.hs @@ -1019,9 +1019,15 @@ evalCompiledNock' stack mainTerm = do case evalT of Left e -> error (show e) Right ev -> case ev of - Left e -> error (show e) + Left e -> error (ppTrace e) Right res -> return res -- | Used in testing and app getStack :: StackId -> Term Natural -> Term Natural -getStack st m = fromRight' (run (runError @NockEvalError (subTerm m (stackPath st)))) +getStack st m = + fromRight' + . run + . runError @NockEvalError + . topEvalCtx + . subTerm m + $ stackPath st diff --git a/test/Nockma/Compile/Positive.hs b/test/Nockma/Compile/Positive.hs index e1c18e45f1..24b338c7b0 100644 --- a/test/Nockma/Compile/Positive.hs +++ b/test/Nockma/Compile/Positive.hs @@ -162,7 +162,12 @@ eqTraces expected = do subStackPred :: StackId -> Path -> (Term Natural -> Check ()) -> Check () subStackPred st subp p = do s <- getStack st <$> ask - case run (runError @NockEvalError (subTerm s subp)) of + let res = + run + . runError @NockEvalError + . topEvalCtx + $ subTerm s subp + case res of Left {} -> assertFailure "Subterm path is not valid" Right n -> p n diff --git a/test/Nockma/Eval/Positive.hs b/test/Nockma/Eval/Positive.hs index 39f58243e0..6b1de581ed 100644 --- a/test/Nockma/Eval/Positive.hs +++ b/test/Nockma/Eval/Positive.hs @@ -34,7 +34,7 @@ allTests = testGroup "Nockma eval unit positive" (map mk tests) case evalResult of Left natErr -> assertFailure ("Evaluation error: " <> show natErr) Right r -> case r of - Left evalErr -> assertFailure ("Evaluation error: " <> show evalErr) + Left evalErr -> assertFailure ("Evaluation error: " <> unpack (ppTrace evalErr)) Right res -> runM (runReader res _testCheck) eqNock :: Term Natural -> Check () From 1949e9adf3c305af18e8ebbec78f7f659e67decc Mon Sep 17 00:00:00 2001 From: Jan Mas Rovira Date: Fri, 19 Jan 2024 15:08:05 +0100 Subject: [PATCH 4/6] add tracing to nockma evaluator and pretty errors --- app/Commands/Dev/Nockma/Repl.hs | 6 +- src/Juvix/Compiler/Nockma/Evaluator.hs | 136 +++++++++--------- src/Juvix/Compiler/Nockma/Evaluator/Crumbs.hs | 83 +++++++++-- src/Juvix/Compiler/Nockma/Evaluator/Error.hs | 99 +++++++++++-- src/Juvix/Compiler/Nockma/Language.hs | 4 +- src/Juvix/Compiler/Nockma/Pretty/Base.hs | 3 + .../Compiler/Nockma/Translation/FromAsm.hs | 5 +- test/Nockma/Compile/Positive.hs | 2 +- test/Nockma/Eval/Positive.hs | 2 +- 9 files changed, 245 insertions(+), 95 deletions(-) diff --git a/app/Commands/Dev/Nockma/Repl.hs b/app/Commands/Dev/Nockma/Repl.hs index 07ea3ba1e1..f48928f163 100644 --- a/app/Commands/Dev/Nockma/Repl.hs +++ b/app/Commands/Dev/Nockma/Repl.hs @@ -10,13 +10,13 @@ import Data.String.Interpolate (__i) import Juvix.Compiler.Nockma.Evaluator (NockEvalError, evalRepl, fromReplTerm, programAssignments) import Juvix.Compiler.Nockma.Evaluator.Options import Juvix.Compiler.Nockma.Language +import Juvix.Compiler.Nockma.Pretty import Juvix.Compiler.Nockma.Pretty qualified as Nockma import Juvix.Compiler.Nockma.Translation.FromSource (parseProgramFile, parseReplStatement, parseReplText, parseText) import Juvix.Parser.Error import System.Console.Haskeline import System.Console.Repline qualified as Repline import Prelude (read) -import Juvix.Compiler.Nockma.Pretty type ReplS = State.StateT ReplState IO @@ -117,7 +117,7 @@ readReplTerm s = do mprog <- getProgram let t = run - . runError @NockEvalError + . runError @(NockEvalError Natural) . fromReplTerm (programAssignments mprog) . fromMegaParsecError . parseReplText @@ -143,7 +143,7 @@ evalStatement = \case . runM . runReader defaultEvalOptions . runError @(ErrNockNatural Natural) - . runError @NockEvalError + . runError @(NockEvalError Natural) $ evalRepl (putStrLn . Nockma.ppTrace) prog s t case et of Left e -> error (show e) diff --git a/src/Juvix/Compiler/Nockma/Evaluator.hs b/src/Juvix/Compiler/Nockma/Evaluator.hs index edbcfb505f..ab42737545 100644 --- a/src/Juvix/Compiler/Nockma/Evaluator.hs +++ b/src/Juvix/Compiler/Nockma/Evaluator.hs @@ -8,25 +8,27 @@ where import Juvix.Compiler.Nockma.Evaluator.Error import Juvix.Compiler.Nockma.Evaluator.Options import Juvix.Compiler.Nockma.Language -import Juvix.Compiler.Nockma.Pretty import Juvix.Prelude hiding (Atom, Path) -asAtom :: (Member (Error NockEvalError) r) => Term a -> Sem r (Atom a) +asAtom :: (Members '[Reader EvalCtx, Error (NockEvalError a)] r) => Term a -> Sem r (Atom a) asAtom = \case TermAtom a -> return a - TermCell {} -> throw ExpectedAtom + TermCell c -> throwExpectedAtom c -asCell :: (Member (Error NockEvalError) r) => Text -> Term a -> Sem r (Cell a) -asCell msg = \case - TermAtom {} -> throw (ExpectedCell msg) +asCell :: (Members '[Reader EvalCtx, Error (NockEvalError a)] r) => Term a -> Sem r (Cell a) +asCell = \case + TermAtom a -> throwExpectedCell a TermCell c -> return c -asBool :: (Member (Error NockEvalError) r, NockNatural a) => Term a -> Sem r Bool +asBool :: (Members '[Reader EvalCtx, Error (NockEvalError a)] r, NockNatural a) => Term a -> Sem r Bool asBool t = do a <- asAtom t return (a == nockTrue) -asPath :: (Members '[Error NockEvalError, Error (ErrNockNatural a)] r, NockNatural a) => Term a -> Sem r Path +asPath :: + (Members '[Reader EvalCtx, Error (NockEvalError a), Error (ErrNockNatural a)] r, NockNatural a) => + Term a -> + Sem r Path asPath = asAtom >=> nockPath subTermT' :: Path -> Traversal (Term a) (Term a) (First (Term a)) (Term a) @@ -44,23 +46,22 @@ subTermT = go L -> (\l' -> TermCell (set cellLeft l' c)) <$> go ds g (c ^. cellLeft) R -> (\r' -> TermCell (set cellRight r' c)) <$> go ds g (c ^. cellRight) -subTerm :: (Members '[Reader EvalCtx, Error NockEvalError] r) => Term a -> Path -> Sem r (Term a) -subTerm term pos = do - ctx <- ask +subTerm :: (Members '[Reader EvalCtx, Error (NockEvalError a)] r) => Term a -> Path -> Sem r (Term a) +subTerm term pos = case term ^? subTermT pos of - Nothing -> throw (InvalidPath ctx) + Nothing -> throwInvalidPath term pos Just t -> return t -setSubTerm :: (Members '[Error NockEvalError] r) => Term a -> Path -> Term a -> Sem r (Term a) +setSubTerm :: forall a r. (Members '[Error (NockEvalError a)] r) => Term a -> Path -> Term a -> Sem r (Term a) setSubTerm term pos repTerm = let (old, new) = setAndRemember (subTermT' pos) repTerm term in if - | isNothing (getFirst old) -> throw @NockEvalError (error "") + | isNothing (getFirst old) -> throw @(NockEvalError a) (error "") | otherwise -> return new parseCell :: forall r a. - (Members '[Error NockEvalError, Error (ErrNockNatural a)] r, NockNatural a) => + (Members '[Error (NockEvalError a), Error (ErrNockNatural a)] r, NockNatural a) => Cell a -> Sem r (ParsedCell a) parseCell c = case c ^. cellLeft of @@ -86,9 +87,9 @@ parseCell c = case c ^. cellLeft of _operatorCellTerm = t } -fromReplTerm :: (Members '[Error NockEvalError] r) => HashMap Text (Term a) -> ReplTerm a -> Sem r (Term a) +fromReplTerm :: forall a r. (Members '[Error (NockEvalError a)] r) => HashMap Text (Term a) -> ReplTerm a -> Sem r (Term a) fromReplTerm namedTerms = \case - ReplName n -> maybe (throw (AssignmentNotFound n)) return (namedTerms ^. at n) + ReplName n -> maybe (throw @(NockEvalError a) (ErrAssignmentNotFound n)) return (namedTerms ^. at n) ReplTerm t -> return t programAssignments :: Maybe (Program a) -> HashMap Text (Term a) @@ -101,7 +102,7 @@ programAssignments mprog = -- | The stack provided in the replExpression has priority evalRepl :: forall r a. - (PrettyCode a, Integral a, Members '[Reader EvalOptions, Error NockEvalError, Error (ErrNockNatural a)] r, NockNatural a) => + (Integral a, Members '[Reader EvalOptions, Error (NockEvalError a), Error (ErrNockNatural a)] r, NockNatural a) => (Term a -> Sem r ()) -> Maybe (Program a) -> Maybe (Term a) -> @@ -117,14 +118,14 @@ evalRepl handleTrace mprog defaultStack expr = do fromReplTerm namedTerms t >>= runOutputSem @(Term a) handleTrace . eval stack where errNoStack :: Sem r x - errNoStack = throw NoStack + errNoStack = throw @(NockEvalError a) (ErrNoStack NoStack) namedTerms :: HashMap Text (Term a) namedTerms = programAssignments mprog eval :: forall s a. - (PrettyCode a, Integral a, Members '[Reader EvalOptions, Output (Term a), Error NockEvalError, Error (ErrNockNatural a)] s, NockNatural a) => + (Integral a, Members '[Reader EvalOptions, Output (Term a), Error (NockEvalError a), Error (ErrNockNatural a)] s, NockNatural a) => Term a -> Term a -> Sem s (Term a) @@ -139,7 +140,7 @@ eval inistack initerm = Term a -> Sem r (Term a) recEval stack term = case term of - TermAtom a -> throw (ExpectedCell ("eval " <> ppTrace a)) + TermAtom a -> throwExpectedCell a TermCell c -> parseCell c >>= \case ParsedAutoConsCell a -> goAutoConsCell a @@ -187,11 +188,11 @@ eval inistack initerm = let w a = EvalCrumbAutoCons CrumbAutoCons - { _crumbAutoConsArgName = a, + { _crumbAutoConsTag = a, _crumbAutoConsLoc = loc } - l' <- withCrumb (w FirstArg) (recEval stack (TermCell (c ^. autoConsCellLeft))) - r' <- withCrumb (w SecondArg) (recEval stack (c ^. autoConsCellRight)) + l' <- withCrumb (w crumbEvalFirst) (recEval stack (TermCell (c ^. autoConsCellLeft))) + r' <- withCrumb (w crumbEvalSecond) (recEval stack (c ^. autoConsCellRight)) return (TermCell (Cell l' r')) goOperatorCell :: OperatorCell a -> Sem r (Term a) @@ -210,20 +211,22 @@ eval inistack initerm = OpHint -> goOpHint OpTrace -> goOpTrace where - crumb argName = + crumb crumbTag = EvalCrumbOperator $ CrumbOperator { _crumbOperatorOp = c ^. operatorCellOp, - _crumbOperatorArgName = argName, + _crumbOperatorTag = crumbTag, _crumbOperatorLoc = loc } - evalArg :: ArgName -> Term a -> Term a -> Sem r (Term a) - evalArg argName stack' arg = do - withCrumb (crumb argName) (recEval stack' arg) + evalArg :: CrumbTag -> Term a -> Term a -> Sem r (Term a) + evalArg crumbTag stack' arg = do + withCrumb (crumb crumbTag) (recEval stack' arg) goOpAddress :: Sem r (Term a) - goOpAddress = withCrumb (crumb Itself) (asPath (c ^. operatorCellTerm) >>= subTerm stack) + goOpAddress = do + cr <- withCrumb (crumb crumbDecodeFirst) (asPath (c ^. operatorCellTerm)) + withCrumb (crumb crumbEval) (subTerm stack cr) goOpQuote :: Term a goOpQuote = c ^. operatorCellTerm @@ -235,63 +238,62 @@ eval inistack initerm = goOpTrace :: Sem r (Term a) goOpTrace = do - Cell' tr a _ <- withCrumb (crumb Itself) (asCell "OpTrace" (c ^. operatorCellTerm)) - tr' <- evalArg FirstArg stack tr + Cell' tr a _ <- withCrumb (crumb crumbDecodeFirst) (asCell (c ^. operatorCellTerm)) + tr' <- evalArg crumbEvalFirst stack tr output tr' - evalArg SecondArg stack a + evalArg crumbEvalSecond stack a goOpHint :: Sem r (Term a) goOpHint = do -- Ignore the hint and evaluate - h <- withCrumb (crumb Itself) (asCell "OpHint" (c ^. operatorCellTerm)) - evalArg FirstArg stack (h ^. cellRight) + h <- withCrumb (crumb crumbDecodeFirst) (asCell (c ^. operatorCellTerm)) + evalArg crumbEvalFirst stack (h ^. cellRight) goOpPush :: Sem r (Term a) goOpPush = do - cellTerm <- withCrumb (crumb Itself) (asCell "OpPush" (c ^. operatorCellTerm)) - l <- evalArg FirstArg stack (cellTerm ^. cellLeft) + cellTerm <- withCrumb (crumb crumbDecodeFirst) (asCell (c ^. operatorCellTerm)) + l <- evalArg crumbEvalFirst stack (cellTerm ^. cellLeft) let s = TermCell (Cell l stack) - evalArg SecondArg s (cellTerm ^. cellRight) + evalArg crumbEvalSecond s (cellTerm ^. cellRight) goOpReplace :: Sem r (Term a) goOpReplace = do - Cell' rot1 t2 _ <- withCrumb (crumb Itself) (asCell "OpReplace 1" (c ^. operatorCellTerm)) - Cell' ro t1 _ <- withCrumb (crumb Itself) (asCell "OpReplace 2" rot1) - r <- withCrumb (crumb Itself) (asPath ro) - t1' <- evalArg FirstArg stack t1 - t2' <- evalArg SecondArg stack t2 + Cell' rot1 t2 _ <- withCrumb (crumb crumbDecodeFirst) (asCell (c ^. operatorCellTerm)) + Cell' ro t1 _ <- withCrumb (crumb crumbDecodeSecond) (asCell rot1) + r <- withCrumb (crumb crumbDecodeThird) (asPath ro) + t1' <- evalArg crumbEvalFirst stack t1 + t2' <- evalArg crumbEvalSecond stack t2 setSubTerm t2' r t1' goOpApply :: Sem r (Term a) goOpApply = do - cellTerm <- withCrumb (crumb Itself) (asCell "OpApply" (c ^. operatorCellTerm)) - t1' <- evalArg FirstArg stack (cellTerm ^. cellLeft) - t2' <- evalArg SecondArg stack (cellTerm ^. cellRight) - evalArg SecondArg t1' t2' + cellTerm <- withCrumb (crumb crumbDecodeFirst) (asCell (c ^. operatorCellTerm)) + t1' <- evalArg crumbEvalFirst stack (cellTerm ^. cellLeft) + t2' <- evalArg crumbEvalSecond stack (cellTerm ^. cellRight) + evalArg crumbEvalSecond t1' t2' goOpIf :: Sem r (Term a) goOpIf = do - cellTerm <- withCrumb (crumb Itself) (asCell "OpIf 1" (c ^. operatorCellTerm)) + cellTerm <- withCrumb (crumb crumbDecodeFirst) (asCell (c ^. operatorCellTerm)) let t0 = cellTerm ^. cellLeft - Cell' t1 t2 _ <- withCrumb (crumb Itself) (asCell "OpIf 2" (cellTerm ^. cellRight)) - cond <- evalArg FirstArg stack t0 >>= asBool + Cell' t1 t2 _ <- withCrumb (crumb crumbDecodeSecond) (asCell (cellTerm ^. cellRight)) + cond <- evalArg crumbEvalFirst stack t0 >>= asBool if - | cond -> evalArg TrueBranch stack t1 - | otherwise -> evalArg FalseBranch stack t2 + | cond -> evalArg crumbTrueBranch stack t1 + | otherwise -> evalArg crumbFalseBranch stack t2 goOpInc :: Sem r (Term a) goOpInc = - withCrumb - (crumb Itself) - ( TermAtom . nockSucc - <$> (evalArg FirstArg stack (c ^. operatorCellTerm) >>= asAtom) - ) + TermAtom . nockSucc + <$> ( evalArg crumbEvalFirst stack (c ^. operatorCellTerm) + >>= withCrumb (crumb crumbDecodeFirst) . asAtom + ) goOpEq :: Sem r (Term a) goOpEq = do - cellTerm <- withCrumb (crumb Itself) (asCell "OpEq" (c ^. operatorCellTerm)) - l <- evalArg FirstArg stack (cellTerm ^. cellLeft) - r <- evalArg SecondArg stack (cellTerm ^. cellRight) + cellTerm <- withCrumb (crumb crumbDecodeFirst) (asCell (c ^. operatorCellTerm)) + l <- evalArg crumbEvalFirst stack (cellTerm ^. cellLeft) + r <- evalArg crumbEvalSecond stack (cellTerm ^. cellRight) return . TermAtom $ if | l == r -> nockTrue @@ -299,13 +301,13 @@ eval inistack initerm = goOpCall :: Sem r (Term a) goOpCall = do - cellTerm <- withCrumb (crumb Itself) (asCell "OpCall" (c ^. operatorCellTerm)) - r <- withCrumb (crumb Itself) (asPath (cellTerm ^. cellLeft)) - t' <- evalArg FirstArg stack (cellTerm ^. cellRight) - subTerm t' r >>= evalArg SecondArg t' + cellTerm <- withCrumb (crumb crumbDecodeFirst) (asCell (c ^. operatorCellTerm)) + r <- withCrumb (crumb crumbDecodeSecond) (asPath (cellTerm ^. cellLeft)) + t' <- evalArg crumbEvalFirst stack (cellTerm ^. cellRight) + subTerm t' r >>= evalArg crumbEvalSecond t' goOpSequence :: Sem r (Term a) goOpSequence = do - cellTerm <- withCrumb (crumb Itself) (asCell "OpSequence" (c ^. operatorCellTerm)) - t1' <- evalArg FirstArg stack (cellTerm ^. cellLeft) - evalArg SecondArg t1' (cellTerm ^. cellRight) + cellTerm <- withCrumb (crumb crumbDecodeFirst) (asCell (c ^. operatorCellTerm)) + t1' <- evalArg crumbEvalFirst stack (cellTerm ^. cellLeft) + evalArg crumbEvalSecond t1' (cellTerm ^. cellRight) diff --git a/src/Juvix/Compiler/Nockma/Evaluator/Crumbs.hs b/src/Juvix/Compiler/Nockma/Evaluator/Crumbs.hs index 62cff83127..115b6698c2 100644 --- a/src/Juvix/Compiler/Nockma/Evaluator/Crumbs.hs +++ b/src/Juvix/Compiler/Nockma/Evaluator/Crumbs.hs @@ -20,22 +20,40 @@ newtype CrumbStdlibCallArgs = CrumbStdlibCallArgs { _crumbStdlibCallArgsFunction :: StdlibFunction } -data ArgName - = Itself - | FirstArg - | SecondArg - | ThirdArg - | TrueBranch - | FalseBranch +newtype CrumbTag = CrumbTag {_crumbTag :: Text} + +crumbEval :: CrumbTag +crumbEval = CrumbTag "Evaluating itself" + +crumbDecodeThird :: CrumbTag +crumbDecodeThird = CrumbTag "Decoding third argument" + +crumbDecodeSecond :: CrumbTag +crumbDecodeSecond = CrumbTag "Decoding second argument" + +crumbDecodeFirst :: CrumbTag +crumbDecodeFirst = CrumbTag "Decoding first argument" + +crumbEvalFirst :: CrumbTag +crumbEvalFirst = CrumbTag "Evaluating first argument" + +crumbTrueBranch :: CrumbTag +crumbTrueBranch = CrumbTag "Evaluating true branch" + +crumbFalseBranch :: CrumbTag +crumbFalseBranch = CrumbTag "Evaluating false branch" + +crumbEvalSecond :: CrumbTag +crumbEvalSecond = CrumbTag "Evaluating second argument" data CrumbAutoCons = CrumbAutoCons - { _crumbAutoConsArgName :: ArgName, + { _crumbAutoConsTag :: CrumbTag, _crumbAutoConsLoc :: Maybe Interval } data CrumbOperator = CrumbOperator { _crumbOperatorOp :: NockOp, - _crumbOperatorArgName :: ArgName, + _crumbOperatorTag :: CrumbTag, _crumbOperatorLoc :: Maybe Interval } @@ -44,5 +62,50 @@ makeLenses ''EvalCtx withCrumb :: (Members '[Reader EvalCtx] r) => EvalCrumb -> Sem r a -> Sem r a withCrumb c = local (over evalStack (c :)) +instance PrettyCode CrumbTag where + ppCode (CrumbTag a) = + return + . annotate AnnImportant + $ pretty a + +instance PrettyCode CrumbStdlibCallArgs where + ppCode CrumbStdlibCallArgs {..} = do + op <- annotate AnnImportant <$> ppCode _crumbStdlibCallArgsFunction + return ("Evaluating address to arguments to stdlib call for" <+> op) + +ppCtx :: (Member (Reader Options) r) => EvalCtx -> Sem r (Doc Ann) +ppCtx c = do + ctx <- ppCode c + let title = annotate AnnImportant "Evaluation trace:" + return (title <> line <> ctx <> line) + +ppLoc :: (Member (Reader Options) r) => Maybe Interval -> Sem r (Doc Ann) +ppLoc = \case + Nothing -> return mempty + Just x -> do + x' <- ppCode x + return (x' <> ":") + +instance PrettyCode CrumbOperator where + ppCode CrumbOperator {..} = do + tag <- ppCode _crumbOperatorTag + loc <- ppLoc _crumbOperatorLoc + op <- ppCode _crumbOperatorOp + return (loc <+> tag <+> "for" <+> op) + +instance PrettyCode CrumbAutoCons where + ppCode CrumbAutoCons {..} = do + let au = annotate AnnImportant "AutoCons" + loc <- ppLoc _crumbAutoConsLoc + tag <- ppCode _crumbAutoConsTag + return (loc <+> tag <+> "for" <+> au) + +instance PrettyCode EvalCrumb where + ppCode = \case + EvalCrumbAutoCons a -> ppCode a + EvalCrumbStdlibCallArgs a -> ppCode a + EvalCrumbOperator a -> ppCode a + instance PrettyCode EvalCtx where - ppCode (EvalCtx l) = undefined + ppCode (EvalCtx l) = + vsep <$> mapM (fmap nest' . ppCode) (reverse l) diff --git a/src/Juvix/Compiler/Nockma/Evaluator/Error.hs b/src/Juvix/Compiler/Nockma/Evaluator/Error.hs index 6481436262..ef840aad3b 100644 --- a/src/Juvix/Compiler/Nockma/Evaluator/Error.hs +++ b/src/Juvix/Compiler/Nockma/Evaluator/Error.hs @@ -5,16 +5,18 @@ module Juvix.Compiler.Nockma.Evaluator.Error where import Juvix.Compiler.Nockma.Evaluator.Crumbs +import Juvix.Compiler.Nockma.Language import Juvix.Compiler.Nockma.Pretty.Base -import Juvix.Prelude hiding (Atom) -import Juvix.Prelude.Pretty +import Juvix.Prelude hiding (Atom, Path) -data NockEvalError - = InvalidPath EvalCtx - | ExpectedAtom - | ExpectedCell Text - | NoStack - | AssignmentNotFound Text +data NockEvalError a + = ErrInvalidPath (InvalidPath a) + | ErrExpectedAtom (ExpectedAtom a) + | ErrExpectedCell (ExpectedCell a) + | -- TODO perhaps this should be a repl error type + ErrNoStack NoStack + | -- TODO perhaps this should be a repl error type + ErrAssignmentNotFound Text newtype GenericNockEvalError = GenericNockEvalError { _genericNockEvalErrorMessage :: AnsiText @@ -23,6 +25,83 @@ newtype GenericNockEvalError = GenericNockEvalError class ToGenericNockEvalError a where toGenericNockEvalError :: a -> GenericNockEvalError -instance PrettyCode NockEvalError where +data ExpectedCell a = ExpectedCell + { _expectedCellCtx :: EvalCtx, + _expectedCellAtom :: Atom a + } + +data ExpectedAtom a = ExpectedAtom + { _expectedAtomCtx :: EvalCtx, + _expectedAtomCell :: Cell a + } + +data InvalidPath a = InvalidPath + { _invalidPathCtx :: EvalCtx, + _invalidPathTerm :: Term a, + _invalidPathPath :: Path + } + +data NoStack = NoStack + +throwInvalidPath :: (Members '[Error (NockEvalError a), Reader EvalCtx] r) => Term a -> Path -> Sem r x +throwInvalidPath tm p = do + ctx <- ask + throw $ + ErrInvalidPath + InvalidPath + { _invalidPathCtx = ctx, + _invalidPathTerm = tm, + _invalidPathPath = p + } + +throwExpectedCell :: (Members '[Error (NockEvalError a), Reader EvalCtx] r) => Atom a -> Sem r x +throwExpectedCell a = do + ctx <- ask + throw $ + ErrExpectedCell + ExpectedCell + { _expectedCellCtx = ctx, + _expectedCellAtom = a + } + +throwExpectedAtom :: (Members '[Error (NockEvalError a), Reader EvalCtx] r) => Cell a -> Sem r x +throwExpectedAtom a = do + ctx <- ask + throw $ + ErrExpectedAtom + ExpectedAtom + { _expectedAtomCtx = ctx, + _expectedAtomCell = a + } + +instance PrettyCode NoStack where + ppCode _ = return "Missing stack" + +instance (PrettyCode a, NockNatural a) => PrettyCode (InvalidPath a) where + ppCode InvalidPath {..} = do + ctx <- ppCtx _invalidPathCtx + path <- ppCode _invalidPathPath + tm <- ppCode _invalidPathTerm + return (ctx <> "The path" <+> path <+> "is invalid for the following term:" <> line <> tm) + +instance (PrettyCode a, NockNatural a) => PrettyCode (ExpectedAtom a) where + ppCode ExpectedAtom {..} = do + cell <- ppCode _expectedAtomCell + ctx <- ppCtx _expectedAtomCtx + let atm = annotate AnnImportant "atom" + return (ctx <> "Expected an" <+> atm <+> "but got:" <> line <> cell) + +instance (PrettyCode a, NockNatural a) => PrettyCode (ExpectedCell a) where + ppCode ExpectedCell {..} = do + atm <- ppCode _expectedCellAtom + ctx <- ppCtx _expectedCellCtx + let cell = annotate AnnImportant "cell" + return (ctx <> "Expected an" <+> atm <+> "but got:" <> line <> cell) + +instance (PrettyCode a, NockNatural a) => PrettyCode (NockEvalError a) where ppCode = \case - InvalidPath ctx -> ppCode ctx + ErrInvalidPath e -> ppCode e + ErrExpectedAtom e -> ppCode e + ErrExpectedCell e -> ppCode e + ErrNoStack e -> ppCode e + ErrAssignmentNotFound e -> return (pretty e) diff --git a/src/Juvix/Compiler/Nockma/Language.hs b/src/Juvix/Compiler/Nockma/Language.hs index ac23aa9756..62f3725c52 100644 --- a/src/Juvix/Compiler/Nockma/Language.hs +++ b/src/Juvix/Compiler/Nockma/Language.hs @@ -211,7 +211,9 @@ atomHint :: Lens' (Atom a) (Maybe AtomHint) atomHint = atomInfo . unIrrelevant . atomInfoHint termLoc :: Lens' (Term a) (Maybe Interval) -termLoc = undefined +termLoc f = \case + TermAtom a -> TermAtom <$> atomLoc f a + TermCell a -> TermCell <$> cellLoc f a cellLoc :: Lens' (Cell a) (Maybe Interval) cellLoc = cellInfo . unIrrelevant . cellInfoLoc diff --git a/src/Juvix/Compiler/Nockma/Pretty/Base.hs b/src/Juvix/Compiler/Nockma/Pretty/Base.hs index 72866098b5..e11bb7ac6f 100644 --- a/src/Juvix/Compiler/Nockma/Pretty/Base.hs +++ b/src/Juvix/Compiler/Nockma/Pretty/Base.hs @@ -38,6 +38,9 @@ instance (PrettyCode a, NockNatural a) => PrettyCode (Atom a) where | otherwise -> fail AtomHintNil -> return (annotate (AnnKind KNameConstructor) "nil") +instance PrettyCode Interval where + ppCode = return . pretty + instance PrettyCode Natural where ppCode = return . pretty diff --git a/src/Juvix/Compiler/Nockma/Translation/FromAsm.hs b/src/Juvix/Compiler/Nockma/Translation/FromAsm.hs index c99a9adedf..5238b71cac 100644 --- a/src/Juvix/Compiler/Nockma/Translation/FromAsm.hs +++ b/src/Juvix/Compiler/Nockma/Translation/FromAsm.hs @@ -764,6 +764,7 @@ callStdlibOn' s f = do preargs = stdlibStackTake s fNumArgs arguments = OpSequence # (OpAddress # [R]) # preargs extractResult = (OpAddress # [L]) # (OpAddress # [R, R]) + -- callFn = OpPush # (OpCall # [L] # (OpReplace # ([R, L] # arguments) # (OpAddress # [L]))) # extractResult callFn = OpPush # (OpCall # [L] # (OpReplace # ([R, L] # arguments) # (OpAddress # [L]))) # extractResult meta = StdlibCall @@ -1014,7 +1015,7 @@ evalCompiledNock' :: (Members '[Reader EvalOptions, Output (Term Natural)] r) => evalCompiledNock' stack mainTerm = do evalT <- runError @(ErrNockNatural Natural) - . runError @NockEvalError + . runError @(NockEvalError Natural) $ eval stack mainTerm case evalT of Left e -> error (show e) @@ -1027,7 +1028,7 @@ getStack :: StackId -> Term Natural -> Term Natural getStack st m = fromRight' . run - . runError @NockEvalError + . runError @(NockEvalError Natural) . topEvalCtx . subTerm m $ stackPath st diff --git a/test/Nockma/Compile/Positive.hs b/test/Nockma/Compile/Positive.hs index 24b338c7b0..57cf54ed03 100644 --- a/test/Nockma/Compile/Positive.hs +++ b/test/Nockma/Compile/Positive.hs @@ -164,7 +164,7 @@ subStackPred st subp p = do s <- getStack st <$> ask let res = run - . runError @NockEvalError + . runError @(NockEvalError Natural) . topEvalCtx $ subTerm s subp case res of diff --git a/test/Nockma/Eval/Positive.hs b/test/Nockma/Eval/Positive.hs index 6b1de581ed..25001a9bab 100644 --- a/test/Nockma/Eval/Positive.hs +++ b/test/Nockma/Eval/Positive.hs @@ -29,7 +29,7 @@ allTests = testGroup "Nockma eval unit positive" (map mk tests) . runReader defaultEvalOptions . ignoreOutput @(Term Natural) . runError @(ErrNockNatural Natural) - . runError @NockEvalError + . runError @(NockEvalError Natural) $ eval _testProgramSubject _testProgramFormula case evalResult of Left natErr -> assertFailure ("Evaluation error: " <> show natErr) From af2fb51c517260b1768d52339911fce4124b58ae Mon Sep 17 00:00:00 2001 From: Jan Mas Rovira Date: Fri, 19 Jan 2024 15:20:29 +0100 Subject: [PATCH 5/6] itemize trace --- src/Juvix/Compiler/Nockma/Evaluator/Crumbs.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Juvix/Compiler/Nockma/Evaluator/Crumbs.hs b/src/Juvix/Compiler/Nockma/Evaluator/Crumbs.hs index 115b6698c2..be608d2703 100644 --- a/src/Juvix/Compiler/Nockma/Evaluator/Crumbs.hs +++ b/src/Juvix/Compiler/Nockma/Evaluator/Crumbs.hs @@ -108,4 +108,4 @@ instance PrettyCode EvalCrumb where instance PrettyCode EvalCtx where ppCode (EvalCtx l) = - vsep <$> mapM (fmap nest' . ppCode) (reverse l) + itemize <$> mapM (fmap nest' . ppCode) (reverse l) From 8265ede7be1305aee0b83151d19eabb8e83bff72 Mon Sep 17 00:00:00 2001 From: Jan Mas Rovira Date: Mon, 22 Jan 2024 16:34:20 +0100 Subject: [PATCH 6/6] rm comment --- src/Juvix/Compiler/Nockma/Translation/FromAsm.hs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Juvix/Compiler/Nockma/Translation/FromAsm.hs b/src/Juvix/Compiler/Nockma/Translation/FromAsm.hs index 5238b71cac..30a6911d06 100644 --- a/src/Juvix/Compiler/Nockma/Translation/FromAsm.hs +++ b/src/Juvix/Compiler/Nockma/Translation/FromAsm.hs @@ -764,7 +764,6 @@ callStdlibOn' s f = do preargs = stdlibStackTake s fNumArgs arguments = OpSequence # (OpAddress # [R]) # preargs extractResult = (OpAddress # [L]) # (OpAddress # [R, R]) - -- callFn = OpPush # (OpCall # [L] # (OpReplace # ([R, L] # arguments) # (OpAddress # [L]))) # extractResult callFn = OpPush # (OpCall # [L] # (OpReplace # ([R, L] # arguments) # (OpAddress # [L]))) # extractResult meta = StdlibCall