Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nockma backend: translate trace to %puts hints #3053

Merged
merged 6 commits into from
Oct 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 9 additions & 11 deletions src/Juvix/Compiler/Nockma/Evaluator.hs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import Juvix.Compiler.Nockma.Evaluator.Error
import Juvix.Compiler.Nockma.Evaluator.Options
import Juvix.Compiler.Nockma.Evaluator.Storage
import Juvix.Compiler.Nockma.Language
import Juvix.Compiler.Nockma.Pretty
import Juvix.Prelude hiding (Atom, Path)
import Juvix.Prelude.Pretty

newtype OpCounts = OpCounts
{ _opCountsMap :: HashMap NockOp Int
Expand Down Expand Up @@ -358,7 +358,6 @@ evalProfile inistack initerm =
OpReplace -> goOpReplace
OpHint -> goOpHint
OpScry -> goOpScry
OpTrace -> goOpTrace
where
crumb crumbTag =
EvalCrumbOperator $
Expand Down Expand Up @@ -388,20 +387,19 @@ evalProfile inistack initerm =
TermCell {} -> nockTrue
TermAtom {} -> nockFalse

goOpTrace :: Sem r (Term a)
goOpTrace = do
Cell' tr a _ <- withCrumb (crumb crumbDecodeFirst) (asCell (c ^. operatorCellTerm))
tr' <- evalArg crumbEvalFirst stack tr
output tr'
evalArg crumbEvalSecond stack a

goOpHint :: Sem r (Term a)
goOpHint = do
Cell' l r _ <- withCrumb (crumb crumbDecodeFirst) (asCell (c ^. operatorCellTerm))
case l of
TAtom {} -> evalArg crumbEvalFirst stack r
TCell _t1 t2 -> do
void (evalArg crumbEvalFirst stack t2)
TCell t1 t2 -> do
t2' <- evalArg crumbEvalFirst stack t2
putsHint <- fromNatural (nockHintValue NockHintPuts)
case t1 of
TAtom a
| a == putsHint ->
output t2'
_ -> return ()
evalArg crumbEvalSecond stack r

goOpPush :: Sem r (Term a)
Expand Down
22 changes: 19 additions & 3 deletions src/Juvix/Compiler/Nockma/Language.hs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,6 @@ data NockOp
| OpReplace
| OpHint
| OpScry
| OpTrace
deriving stock (Bounded, Enum, Eq, Generic)

instance Hashable NockOp
Expand All @@ -164,7 +163,9 @@ instance Pretty NockOp where
OpReplace -> "replace"
OpHint -> "hint"
OpScry -> "scry"
OpTrace -> "trace"

data NockHint = NockHintPuts
deriving stock (Show, Eq, Enum, Bounded)

textToStdlibFunctionMap :: HashMap Text StdlibFunction
textToStdlibFunctionMap =
Expand Down Expand Up @@ -267,7 +268,6 @@ serializeOp = \case
OpReplace -> 10
OpHint -> 11
OpScry -> 12
OpTrace -> 100

class (NockmaEq a) => NockNatural a where
type ErrNockNatural a :: Type
Expand Down Expand Up @@ -325,6 +325,22 @@ nockBoolLiteral b
| b = nockTrueLiteral
| otherwise = nockFalseLiteral

nockHintName :: NockHint -> Text
nockHintName = \case
NockHintPuts -> "puts"

nockHintValue :: NockHint -> Natural
nockHintValue = \case
NockHintPuts -> 0x73747570

nockHintAtom :: NockHint -> Term Natural
nockHintAtom hint =
TermAtom
Atom
{ _atomInfo = emptyAtomInfo,
_atom = nockHintValue hint
}

instance NockNatural Natural where
type ErrNockNatural Natural = NockNaturalNaturalError
nockNatural a = return (a ^. atom)
Expand Down
8 changes: 8 additions & 0 deletions src/Juvix/Compiler/Nockma/Translation/FromSource/Base.hs
Original file line number Diff line number Diff line change
Expand Up @@ -151,10 +151,18 @@ atomStringLiteral = do
}
return (Atom (textToNatural s) info)

atomNockHint :: Maybe Tag -> Parser (Atom Natural)
atomNockHint mtag = do
symbol Str.percent
let hints :: [NockHint] = enumerate
val <- choice (map (\hnt -> symbol (nockHintName hnt) >> return (nockHintValue hnt)) hints)
return (Atom val emptyAtomInfo {_atomInfoTag = mtag})

patom :: Parser (Atom Natural)
patom = do
mtag <- optional pTag
atomOp mtag
<|> atomNockHint mtag
<|> atomNat mtag
<|> atomPath mtag
<|> atomBool
Expand Down
23 changes: 7 additions & 16 deletions src/Juvix/Compiler/Nockma/Translation/FromTree.hs
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,11 @@ data BuiltinFunctionId

instance Hashable BuiltinFunctionId

newtype CompilerOptions = CompilerOptions
{_compilerOptionsEnableTrace :: Bool}
data CompilerOptions = CompilerOptions

fromEntryPoint :: EntryPoint -> CompilerOptions
fromEntryPoint EntryPoint {..} =
fromEntryPoint EntryPoint {} =
CompilerOptions
{ _compilerOptionsEnableTrace = _entryPointDebug
}

data FunctionInfo = FunctionInfo
{ _functionInfoPath :: Path,
Expand All @@ -115,8 +112,7 @@ newtype FunctionCtx = FunctionCtx

data CompilerCtx = CompilerCtx
{ _compilerFunctionInfos :: HashMap FunctionId FunctionInfo,
_compilerConstructorInfos :: ConstructorInfos,
_compilerOptions :: CompilerOptions
_compilerConstructorInfos :: ConstructorInfos
}

data ConstructorInfo = ConstructorInfo
Expand Down Expand Up @@ -652,12 +648,8 @@ compile = \case

goTrace :: Term Natural -> Sem r (Term Natural)
goTrace arg = do
enabled <- asks (^. compilerOptions . compilerOptionsEnableTrace)
return $
if
-- TODO: remove duplication of `arg` here
| enabled -> OpTrace # arg # arg
| otherwise -> arg
-- TODO: remove duplication of `arg` here
return $ OpHint # (nockHintAtom NockHintPuts # arg) # arg

goBinop :: Tree.NodeBinop -> Sem r (Term Natural)
goBinop Tree.NodeBinop {..} = do
Expand Down Expand Up @@ -922,7 +914,7 @@ remakeList :: (Foldable l) => l (Term Natural) -> Term Natural
remakeList ts = foldTerms (toList ts `prependList` pure (OpQuote # nockNilTagged "remakeList"))

runCompilerWith :: CompilerOptions -> ConstructorInfos -> [CompilerFunction] -> CompilerFunction -> AnomaResult
runCompilerWith opts constrs moduleFuns mainFun = makeAnomaFun
runCompilerWith _opts constrs moduleFuns mainFun = makeAnomaFun
where
libFuns :: [CompilerFunction]
libFuns = moduleFuns ++ (builtinFunction <$> allElements)
Expand All @@ -934,8 +926,7 @@ runCompilerWith opts constrs moduleFuns mainFun = makeAnomaFun
compilerCtx =
CompilerCtx
{ _compilerFunctionInfos = functionInfos,
_compilerConstructorInfos = constrs,
_compilerOptions = opts
_compilerConstructorInfos = constrs
}

mainClosure :: Term Natural
Expand Down
3 changes: 3 additions & 0 deletions src/Juvix/Extra/Strings.hs
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,9 @@ tagTag = "tag@"
stdlibTag :: (IsString s) => s
stdlibTag = "stdlib@"

percent :: (IsString s) => s
percent = "%"

instrSub :: (IsString s) => s
instrSub = "sub"

Expand Down
10 changes: 5 additions & 5 deletions test/Anoma/Compilation/Positive.hs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ mkAnomaCallTest' enableDebug _testProgramStorage _testName relRoot mainFile args
<$> testDefaultEntryPointIO testRootDir (testRootDir <//> mainFile)
(^. pipelineResult) . snd <$> testRunIO entryPoint upToAnoma

mkAnomaCallTestNoTrace :: Text -> Prelude.Path Rel Dir -> Prelude.Path Rel File -> [Term Natural] -> Check () -> TestTree
mkAnomaCallTestNoTrace = mkAnomaCallTest' False emptyStorage
mkAnomaCallTestNoDebug :: Text -> Prelude.Path Rel Dir -> Prelude.Path Rel File -> [Term Natural] -> Check () -> TestTree
mkAnomaCallTestNoDebug = mkAnomaCallTest' False emptyStorage

mkAnomaCallTest :: Text -> Prelude.Path Rel Dir -> Prelude.Path Rel File -> [Term Natural] -> Check () -> TestTree
mkAnomaCallTest = mkAnomaCallTest' True emptyStorage
Expand Down Expand Up @@ -78,12 +78,12 @@ allTests =
$(mkRelFile "test003.juvix")
[]
(checkNatOutput [1, 4, 2, 4, 0]),
mkAnomaCallTestNoTrace
"Test003: Integer arithmetic - no trace"
mkAnomaCallTestNoDebug
"Test003: Integer arithmetic - no debug"
$(mkRelDir ".")
$(mkRelFile "test003.juvix")
[]
(checkNatOutput [0]),
(checkNatOutput [1, 4, 2, 4, 0]),
mkAnomaCallTest
"Test005: Higher-order functions"
$(mkRelDir ".")
Expand Down
4 changes: 2 additions & 2 deletions test/Nockma/Eval/Positive.hs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ anomaTest n mainFun args _testCheck _evalInterceptStdlibCalls =
| _evalInterceptStdlibCalls = n <> " - intercept stdlib"
| otherwise = n

opts = CompilerOptions {_compilerOptionsEnableTrace = False}
opts = CompilerOptions

res :: AnomaResult = runCompilerWith opts mempty [] f
_testProgramSubject = res ^. anomaClosure
Expand Down Expand Up @@ -302,7 +302,7 @@ unitTests =
test "push" [nock| [0 1] |] [nock| [push [[suc [@ L]] [@ S]]] |] (eqNock [nock| [1 0 1] |]),
test "call" [nock| [quote 1] |] [nock| [call [S [@ S]]] |] (eqNock [nock| 1 |]),
test "replace" [nock| [0 1] |] [nock| [replace [[L [quote 1]] [@ S]]] |] (eqNock [nock| [1 1] |]),
test "hint" [nock| [0 1] |] [nock| [hint [nil [trace [quote 2] [quote 3]]] [quote 1]] |] (eqTraces [[nock| 2 |]] >> eqNock [nock| 1 |]),
test "hint" [nock| [0 1] |] [nock| [hint [1937012080 [quote 2]] [quote 1]] |] (eqTraces [[nock| 2 |]] >> eqNock [nock| 1 |]),
testWithStorage [([nock| 111 |], [nock| 222 |])] "scry" [nock| nil |] [nock| [scry [quote nil] [quote 111]] |] (eqNock [nock| 222 |]),
withAssertErrKeyNotInStorage $ testWithStorage [([nock| 333 |], [nock| 222 |]), ([nock| 3 |], [nock| 222 |])] "scry" [nock| nil |] [nock| [scry [quote nil] [quote 111]] |] (eqNock [nock| 222 |])
]
Loading