diff --git a/src/Juvix/Compiler/Nockma/Evaluator.hs b/src/Juvix/Compiler/Nockma/Evaluator.hs index c8a731577c..3c77d86ea4 100644 --- a/src/Juvix/Compiler/Nockma/Evaluator.hs +++ b/src/Juvix/Compiler/Nockma/Evaluator.hs @@ -146,10 +146,10 @@ eval inistack initerm = ParsedAutoConsCell a -> goAutoConsCell a ParsedOperatorCell o -> goOperatorCell o ParsedStdlibCallCell o -> do - ignore <- asks (^. evalIgnoreStdlibCalls) + intercept' <- asks (^. evalInterceptStdlibCalls) if - | ignore -> goOperatorCell (o ^. stdlibCallRaw) - | otherwise -> goStdlibCall (o ^. stdlibCallCell) + | intercept' -> goStdlibCall (o ^. stdlibCallCell) + | otherwise -> goOperatorCell (o ^. stdlibCallRaw) where loc :: Maybe Interval loc = term ^. termLoc @@ -182,6 +182,7 @@ eval inistack initerm = StdlibMod -> binArith mod StdlibLt -> binCmp (<) StdlibLe -> binCmp (<=) + StdlibPow2 -> unaArith (2 ^) goAutoConsCell :: AutoConsCell a -> Sem r (Term a) goAutoConsCell c = do diff --git a/src/Juvix/Compiler/Nockma/Evaluator/Options.hs b/src/Juvix/Compiler/Nockma/Evaluator/Options.hs index 34451675cf..39bae81fc6 100644 --- a/src/Juvix/Compiler/Nockma/Evaluator/Options.hs +++ b/src/Juvix/Compiler/Nockma/Evaluator/Options.hs @@ -3,10 +3,13 @@ module Juvix.Compiler.Nockma.Evaluator.Options where import Juvix.Prelude.Base newtype EvalOptions = EvalOptions - { _evalIgnoreStdlibCalls :: Bool + { _evalInterceptStdlibCalls :: Bool } defaultEvalOptions :: EvalOptions -defaultEvalOptions = EvalOptions False +defaultEvalOptions = + EvalOptions + { _evalInterceptStdlibCalls = True + } makeLenses ''EvalOptions diff --git a/src/Juvix/Compiler/Nockma/Language.hs b/src/Juvix/Compiler/Nockma/Language.hs index de2fac7c71..14a581db9d 100644 --- a/src/Juvix/Compiler/Nockma/Language.hs +++ b/src/Juvix/Compiler/Nockma/Language.hs @@ -1,7 +1,7 @@ module Juvix.Compiler.Nockma.Language ( module Juvix.Compiler.Nockma.Language, module Juvix.Compiler.Core.Language.Base, - module Juvix.Compiler.Nockma.StdlibFunction, + module Juvix.Compiler.Nockma.StdlibFunction.Base, module Juvix.Compiler.Nockma.Language.Path, ) where @@ -10,7 +10,7 @@ import Data.HashMap.Strict qualified as HashMap import GHC.Base (Type) import Juvix.Compiler.Core.Language.Base (Symbol) import Juvix.Compiler.Nockma.Language.Path -import Juvix.Compiler.Nockma.StdlibFunction +import Juvix.Compiler.Nockma.StdlibFunction.Base import Juvix.Prelude hiding (Atom, Path) import Juvix.Prelude.Pretty @@ -332,17 +332,6 @@ infixl 1 >># (>>#) :: (IsNock x, IsNock y) => x -> y -> Term Natural a >># b = TermCell (a >>#. b) -stdlibNumArgs :: StdlibFunction -> Natural -stdlibNumArgs = \case - StdlibDec -> 1 - StdlibAdd -> 2 - StdlibSub -> 2 - StdlibMul -> 2 - StdlibMod -> 2 - StdlibDiv -> 2 - StdlibLe -> 2 - StdlibLt -> 2 - {-# COMPLETE Cell #-} pattern Cell :: Term a -> Term a -> Cell a diff --git a/src/Juvix/Compiler/Nockma/Stdlib.hs b/src/Juvix/Compiler/Nockma/Stdlib.hs index 6957265dc6..a48f0087cd 100644 --- a/src/Juvix/Compiler/Nockma/Stdlib.hs +++ b/src/Juvix/Compiler/Nockma/Stdlib.hs @@ -6,294 +6,323 @@ import Juvix.Prelude stdlib :: Term Natural stdlib = [nock| -[ [ [ 7 - [ 8 - [1 1 1] - [ 1 - 8 - [1 0] - 8 + [ [ [8 [1 0] [1 6 [5 [1 0] 0 6] [1 1] 8 [9 4 0 63] 9 2 10 [6 [7 [0 3] 1 2] 7 [0 3] 9 2 10 [6 8 [9 342 0 63] 9 2 10 [6 0 14] 0 2] 0 1] 0 2] 0 1] + [ 8 + [1 0] + [ 1 + [8 [1 0 0] [1 8 [9 20 0 255] 9 2 10 [6 [7 [0 3] 8 [9 90 0 7] 9 2 10 [6 [7 [0 3] 8 [9 190 0 7] 9 2 10 [6 0 28] 0 2] 0 29] 0 2] 0 28] 0 2] 0 1] + [8 [1 0] [1 8 [9 367 0 7] 9 2 10 [6 [7 [0 3] 1 1] 0 14] 0 2] 0 1] + [ [ 8 + [1 0 0] [ 1 - 6 - [5 [1 0] 0 60] - [0 6] - 9 - 2 - 10 - [60 8 [9 342 0 31] 9 2 10 [6 0 124] 0 2] - 10 - [6 8 [9 20 0 31] 9 2 10 [6 [0 125] 0 14] 0 2] - 0 - 1 + 8 + [1 0] + 7 + [10 [29 8 [9 10 0 15] 9 2 10 [6 0 61] 0 2] 0 1] + 8 + [0 29] + 8 + [ 1 + 6 + [5 [0 14] 0 124] + [8 [9 767 0 63] 9 2 10 [6 [7 [0 3] 1 1] 0 14] 0 2] + 9 + 2 + 10 + [14 4 0 14] + 10 + [6 8 [9 20 0 2.047] 9 2 10 [6 [0 253] 7 [0 3] 8 [9 90 0 63] 9 2 10 [6 [7 [0 3] 1 1] 0 14] 0 2] 0 2] + 0 + 1 + ] + 9 + 2 + 0 + 1 ] - 9 - 2 0 1 + ] + [8 [1 0 0] [1 8 [9 4 0 255] 9 2 10 [6 [0 29] 7 [0 3] 8 [9 4 0 31] 9 2 10 [6 7 [0 3] 8 [9 4 0 255] 9 2 10 [6 [7 [0 3] 9 182 0 7] 0 28] 0 2] 0 2] 0 2] 0 1] + [8 [9 4 0 7] 9 2 10 [6 0 14] 0 2] + [8 [1 0] [1 8 [9 47 0 255] 9 2 10 [6 [7 [0 3] 8 [9 342 0 255] 9 2 10 [6 7 [0 3] 9 382 0 7] 0 2] 7 [0 3] 8 [9 10 0 7] 9 2 10 [6 0 14] 0 2] 0 2] 0 1] + 8 + [1 0 0] + [1 8 [9 46 0 255] 9 2 10 [6 [0 29] 7 [0 3] 8 [9 4 0 31] 9 2 10 [6 7 [0 3] 8 [9 4 0 255] 9 2 10 [6 [7 [0 3] 9 182 0 7] 0 28] 0 2] 0 2] 0 2] + 0 + 1 ] + [8 [1 0 0] [1 8 [9 10 0 7] 9 2 10 [6 7 [0 3] 8 [9 20 0 255] 9 2 10 [6 [0 28] 0 29] 0 2] 0 2] 0 1] + [8 [1 [0 0] 0] [1 8 [9 367 0 7] 9 2 10 [6 [0 57] 7 [0 3] 8 [9 767 0 7] 9 2 10 [6 [0 56] 0 29] 0 2] 0 2] 0 1] + [8 [1 0] [1 8 [1 0] 8 [1 6 [5 [1 0] 0 30] [0 6] 9 2 10 [30 8 [9 767 0 31] 9 2 10 [6 [7 [0 3] 1 1] 0 62] 0 2] 10 [6 4 0 6] 0 1] 9 2 0 1] 0 1] + [8 [9 4 0 7] 9 2 10 [6 7 [0 3] 8 [9 4 0 7] 9 2 10 [6 0 14] 0 2] 0 2] + [8 [1 0] [1 8 [9 46 0 7] 9 2 10 [6 [7 [0 3] 8 [9 366 0 7] 9 2 10 [6 0 14] 0 2] 7 [0 3] 1 1] 0 2] 0 1] + 8 + [1 0 0] + [1 8 [9 170 0 255] 9 2 10 [6 [0 29] 7 [0 3] 8 [9 4 0 31] 9 2 10 [6 7 [0 3] 8 [9 4 0 255] 9 2 10 [6 [7 [0 3] 9 182 0 7] 0 28] 0 2] 0 2] 0 2] 0 1 - ] - 11 - [1.953.718.630 1 7.107.949 [0 7] 0] + ] + 0 + 1 + ] + 8 + [1 0] + [1 8 [8 [9 10 0 7] 9 190 10 [6 7 [0 3] 1 0] 0 2] 9 2 10 [6 0 14] 0 2] + 0 + 1 + ] + [ [ 7 + [8 [1 0 0] [1 6 [5 [1 0] 0 13] [1 1] 8 [9 4 0 31] 9 2 10 [6 [0 28] 7 [0 3] 9 2 10 [13 8 [9 342 0 31] 9 2 10 [6 0 29] 0 2] 0 1] 0 2] 0 1] + 11 + [1.953.718.630 1 7.827.312 [0 7] 0] + 0 + 1 + ] + 8 + [1 0] + [ 1 + [8 [1 1 1] [1 8 [9 42 0 7] 9 2 10 [6 7 [0 3] 8 [9 4 0 127] 9 2 10 [6 [0 28] 0 29] 0 2] 0 2] 0 1] + [ [8 [1 0 0] [1 8 [9 42 0 7] 9 2 10 [6 7 [0 3] 8 [9 20 0 127] 9 2 10 [6 [0 28] 0 29] 0 2] 0 2] 0 1] + [8 [1 0] [1 8 [9 46 0 127] 9 2 10 [6 [0 14] 0 62] 0 2] 0 1] + [8 [1 1 1] [1 8 [9 4 0 7] 9 2 10 [6 [0 28] 7 [0 3] 8 [9 174 0 7] 9 2 10 [6 0 29] 0 2] 0 2] 0 1] + [8 [1 0] [1 0 0] 0 1] + 8 + [1 0] + [1 8 [9 47 0 127] 9 2 10 [6 [0 62] 7 [0 3] 8 [9 42 0 7] 9 2 10 [6 0 14] 0 2] 0 2] 0 1 + ] + [8 [1 0 0] [1 5 [8 [9 42 0 7] 9 2 10 [6 0 28] 0 2] 8 [9 42 0 7] 9 2 10 [6 0 29] 0 2] 0 1] + [8 [1 0 0] [1 8 [9 42 0 7] 9 2 10 [6 7 [0 3] 8 [9 4 0 31] 9 2 10 [6 [0 28] 0 29] 0 2] 0 2] 0 1] + 8 + [1 0 0] + [ 1 + 8 + [9 42 0 7] + 9 + 2 + 10 + [6 7 [0 3] 8 [9 47 0 127] 9 2 10 [6 [7 [0 3] 8 [9 20 0 127] 9 2 10 [6 [0 62] 0 28] 0 2] 7 [0 3] 8 [9 42 0 7] 9 2 10 [6 0 29] 0 2] 0 2] + 0 + 2 + ] + 0 + 1 ] - [ [ 7 - [ 8 - [1 0 0] - [ 1 - 6 - [5 [1 0] 0 12] - [0 13] - 9 - 2 - 10 - [6 [8 [9 342 0 7] 9 2 10 [6 0 28] 0 2] 4 0 13] - 0 - 1 - ] - 0 - 1 - ] - 11 - [1.953.718.630 1 6.579.297 [0 7] 0] + 0 + 1 + ] + [ [8 [1 [[0 15] [0 0] [0 0] 0] 0] [1 8 [0 101] [1 8 [0 60] 9 2 10 [6 [0 125] 0 14] 0 2] 0 1] 0 1] + [ [8 [8 [1 0] [1 8 [0 6] 8 [5 [0 14] 0 2] 0 6] 0 1] [1 8 [1 0] [1 8 [7 [0 7] [1 7 [0 14] 9 2 0 1] 0 1] 8 [5 [0 14] 0 2] 0 6] 0 1] 0 1] + [ 8 + [8 [1 0] [1 8 [0 6] 8 [5 [0 14] 0 2] 0 6] 0 1] + [1 8 [1 0] [1 8 [6 [3 0 6] [[6 [5 [1 0] 0 12] [1 0] 0 0] 8 [0 30] 9 2 10 [6 0 29] 0 2] 6 [5 [1 0] 0 6] [1 0] 0 0] 8 [5 [0 14] 0 2] 0 6] 0 1] 0 1 + ] + [ 8 + [8 [1 0] [1 8 [0 6] 8 [5 [0 14] 0 2] 0 6] 0 1] + [ 1 + 8 + [[0 26] 7 [8 [9 47 0 7] 9 2 10 [6 0 14] 0 2] 0 6] + [1 8 [[8 [0 30] 9 2 10 [6 0 28] 0 2] 8 [7 [0 7] 8 [9 47 0 7] 9 2 10 [6 0 14] 0 2] 9 2 10 [6 0 29] 0 2] 8 [5 [0 14] 0 2] 0 6] + 0 + 1 ] - [ [ 7 - [ 8 - [1 0 0] - [ 1 - 6 - [5 [0 12] 0 13] - [1 0] - 6 - [8 [9 343 0 7] 9 2 10 [6 [0 28] 0 29] 0 2] - [1 0] - 1 - 1 - ] - 0 - 1 - ] - 11 - [1.953.718.630 1 6.648.940 [0 7] 0] + 0 + 1 + ] + [8 [1 0] [1 8 [7 [1 0 0] 8 [0 2] [1 0 15] 0 1] 8 [5 [0 14] 0 2] 0 6] 0 1] + [ 8 + [[8 [1 0] [1 8 [0 6] 8 [5 [0 14] 0 2] 0 6] 0 1] 8 [1 0] [1 8 [0 6] 8 [5 [0 14] 0 2] 0 6] 0 1] + [ 1 + 8 + [[1 0] 0 54] + [ 1 + 8 + [6 [5 [1 1] 0 12] [[6 [5 [0 12] 1 1] [1 1] 0 0] 8 [0 60] 9 2 10 [6 0 29] 0 2] [6 [5 [0 12] 1 0] [1 0] 0 0] 8 [0 61] 9 2 10 [6 0 29] 0 2] + 8 + [5 [0 14] 0 2] 0 - 1 + 6 + ] + 0 + 1 ] - [ 7 - [ 8 - [1 1 1] - [ 1 - 6 - [5 [1 0] 0 13] - [0 0] - 8 - [1 0] + 0 + 1 + ] + [ 8 + [8 [1 0] [1 8 [0 6] 8 [5 [0 14] 0 2] 0 6] 0 1] + [ 1 + 8 + [1 0] + [ 1 + 8 + [ 6 + [3 0 6] + [ [8 [0 30] 9 2 10 [6 0 28] 0 2] + [8 [7 [0 7] 8 [9 702 0 7] 9 2 10 [6 0 14] 0 2] 9 2 10 [6 0 58] 0 2] 8 - [ 1 - 6 - [8 [9 343 0 31] 9 2 10 [6 [0 124] 0 125] 0 2] - [0 6] + [7 [0 7] 8 [9 702 0 7] 9 2 10 [6 0 14] 0 2] 9 2 10 - [60 8 [9 47 0 31] 9 2 10 [6 [0 124] 0 125] 0 2] - 10 - [6 4 0 6] + [6 0 59] 0 - 1 - ] - 9 2 - 0 - 1 - ] - 0 - 1 + ] + 6 + [5 [1 0] 0 6] + [1 0] + 0 + 0 ] - 11 - [1.953.718.630 1 7.760.228 [0 7] 0] + 8 + [5 [0 14] 0 2] 0 - 1 + 6 + ] + 0 + 1 ] + 0 + 1 + ] + [8 [1 0] [1 6 [5 [1 0] 0 6] [1 0] 4 9 2 10 [6 0 13] 0 1] 0 1] + 8 + [8 [1 0] [1 8 [0 6] 8 [5 [0 14] 0 2] 0 6] 0 1] + [1 8 [8 [1 0] [1 8 [0 6] 8 [5 [0 14] 0 2] 0 6] 0 1] 8 [5 [0 14] 0 2] 0 6] + 0 + 1 + ] + [8 [1 0 [0 15] 0 0 0] [1 8 [1 6 [5 [1 0] 0 28] [1 0] [8 [0 29] 9 2 10 [6 0 120] 0 2] 9 2 10 [28 0 57] 0 1] 9 2 0 1] 0 1] + [8 [1 0 [0 13] [0 0] 0] [1 8 [1 6 [5 [1 0] 0 28] [0 237] 8 [0 29] 9 2 10 [6 [0 120] 7 [0 3] 9 2 10 [28 0 57] 0 1] 0 2] 9 2 0 1] 0 1] + 8 + [8 [1 0] [1 8 [0 6] 8 [5 [0 14] 0 2] 0 6] 0 1] + [ 1 + 8 + [1 0] + [ 1 + 8 + [6 [3 0 6] [[8 [0 30] 9 2 10 [6 0 28] 0 2] 8 [7 [0 7] 8 [9 47 0 7] 9 2 10 [6 0 14] 0 2] 9 2 10 [6 0 29] 0 2] 6 [5 [1 0] 0 6] [1 0] 0 0] + 8 + [5 [0 14] 0 2] + 0 + 6 + ] + 0 + 1 + ] + 0 + 1 + ] + [ [ 7 + [ 8 + [1 1 1] + [1 8 [1 0] 8 [1 6 [5 [1 0] 0 60] [0 6] 9 2 10 [60 8 [9 342 0 31] 9 2 10 [6 0 124] 0 2] 10 [6 8 [9 20 0 31] 9 2 10 [6 [0 125] 0 14] 0 2] 0 1] 9 2 0 1] + 0 + 1 + ] + 11 + [1.953.718.630 1 7.107.949 [0 7] 0] + 0 + 1 + ] + [ [7 [8 [1 0 0] [1 6 [5 [1 0] 0 12] [0 13] 9 2 10 [6 [8 [9 342 0 7] 9 2 10 [6 0 28] 0 2] 4 0 13] 0 1] 0 1] 11 [1.953.718.630 1 6.579.297 [0 7] 0] 0 1] + [ [7 [8 [1 0 0] [1 6 [5 [0 12] 0 13] [1 0] 6 [8 [9 343 0 7] 9 2 10 [6 [0 28] 0 29] 0 2] [1 0] 1 1] 0 1] 11 [1.953.718.630 1 6.648.940 [0 7] 0] 0 1] [ 7 - [ 8 - [1 0] + [ 8 + [1 1 1] [ 1 - 6 - [5 [1 0] 0 6] - [0 0] - 8 - [1 0] - 8 - [1 6 [5 [0 30] 4 0 6] [0 6] 9 2 10 [6 4 0 6] 0 1] - 9 - 2 - 0 - 1 - ] - 0 - 1 + 6 + [5 [1 0] 0 13] + [0 0] + 8 + [1 0] + 8 + [1 6 [8 [9 343 0 31] 9 2 10 [6 [0 124] 0 125] 0 2] [0 6] 9 2 10 [60 8 [9 47 0 31] 9 2 10 [6 [0 124] 0 125] 0 2] 10 [6 4 0 6] 0 1] + 9 + 2 + 0 + 1 ] - 11 - [1.953.718.630 1 6.514.020 [0 7] 0] 0 1 + ] + 11 + [1.953.718.630 1 7.760.228 [0 7] 0] + 0 + 1 ] + [7 [8 [1 0] [1 6 [5 [1 0] 0 6] [0 0] 8 [1 0] 8 [1 6 [5 [0 30] 4 0 6] [0 6] 9 2 10 [6 4 0 6] 0 1] 9 2 0 1] 0 1] 11 [1.953.718.630 1 6.514.020 [0 7] 0] 0 1] 7 [ 8 - [1 0 0] - [ 1 + [1 0 0] + [ 1 6 [6 [5 [0 12] 0 13] [1 1] 1 0] [ 6 - [ 8 + [ 8 [ 1 - 6 - [5 [1 0] 0 28] - [1 0] - 6 - [ 6 - [6 [5 [1 0] 0 29] [1 1] 1 0] - [ 6 - [ 9 - 2 - 10 - [ 14 - [8 [9 342 0 15] 9 2 10 [6 0 60] 0 2] - 8 - [9 342 0 15] - 9 - 2 - 10 - [6 0 61] - 0 - 2 - ] - 0 - 1 - ] - [1 0] - 1 - 1 - ] - 1 - 1 - ] - [1 0] - 1 - 1 + 6 + [5 [1 0] 0 28] + [1 0] + 6 + [6 [6 [5 [1 0] 0 29] [1 1] 1 0] [6 [9 2 10 [14 [8 [9 342 0 15] 9 2 10 [6 0 60] 0 2] 8 [9 342 0 15] 9 2 10 [6 0 61] 0 2] 0 1] [1 0] 1 1] 1 1] + [1 0] + 1 + 1 ] 9 2 0 1 - ] - [1 0] - 1 - 1 + ] + [1 0] + 1 + 1 ] 1 1 - ] - 0 - 1 + ] + 0 + 1 ] 11 [1.953.718.630 1 6.845.548 [0 7] 0] 0 1 - ] - 7 - [8 [1 0 0] [1 6 [8 [9 84 0 7] 9 2 10 [6 [0 28] 0 29] 0 2] [1 1] 1 0] 0 1] - 11 - [1.953.718.630 1 6.845.543 [0 7] 0] - 0 - 1 - ] - [ 7 - [ 8 - [1 0 0] - [1 6 [8 [9 343 0 7] 9 2 10 [6 [0 28] 0 29] 0 2] [1 1] 1 0] - 0 - 1 - ] - 11 - [1.953.718.630 1 6.648.935 [0 7] 0] - 0 - 1 + ] + 7 + [8 [1 0 0] [1 6 [8 [9 84 0 7] 9 2 10 [6 [0 28] 0 29] 0 2] [1 1] 1 0] 0 1] + 11 + [1.953.718.630 1 6.845.543 [0 7] 0] + 0 + 1 ] + [7 [8 [1 0 0] [1 6 [8 [9 343 0 7] 9 2 10 [6 [0 28] 0 29] 0 2] [1 1] 1 0] 0 1] 11 [1.953.718.630 1 6.648.935 [0 7] 0] 0 1] [ 7 - [ 8 + [ 8 [1 1 1] - [ 1 - 6 - [5 [1 0] 0 13] - [0 0] - 8 - [9 47 0 7] - 9 - 2 - 10 - [ 6 - [0 28] - 7 - [0 3] - 8 - [9 4 0 7] - 9 - 2 - 10 - [6 [0 29] 7 [0 3] 8 [9 170 0 7] 9 2 10 [6 [0 28] 0 29] 0 2] - 0 - 2 - ] - 0 - 2 - ] - 0 - 1 - ] - 11 - [1.953.718.630 1 6.582.125 [0 7] 0] + [1 6 [5 [1 0] 0 13] [0 0] 8 [9 47 0 7] 9 2 10 [6 [0 28] 7 [0 3] 8 [9 4 0 7] 9 2 10 [6 [0 29] 7 [0 3] 8 [9 170 0 7] 9 2 10 [6 [0 28] 0 29] 0 2] 0 2] 0 2] 0 1 + ] + 11 + [1.953.718.630 1 6.582.125 [0 7] 0] + 0 + 1 ] 7 - [ 8 - [1 0 0] - [ 1 - 6 - [5 [1 0] 0 13] - [0 12] - 9 - 2 - 10 - [ 6 - [8 [9 342 0 7] 9 2 10 [6 0 28] 0 2] - 8 - [9 342 0 7] - 9 - 2 - 10 - [6 0 29] - 0 - 2 - ] - 0 - 1 - ] - 0 - 1 - ] + [8 [1 0 0] [1 6 [5 [1 0] 0 13] [0 12] 9 2 10 [6 [8 [9 342 0 7] 9 2 10 [6 0 28] 0 2] 8 [9 342 0 7] 9 2 10 [6 0 29] 0 2] 0 1] 0 1] 11 [1.953.718.630 1 6.452.595 [0 7] 0] 0 1 - ] - [0 3] - 909 -] + ] + [0 3] + 909 + ] |] diff --git a/src/Juvix/Compiler/Nockma/StdlibFunction.hs b/src/Juvix/Compiler/Nockma/StdlibFunction.hs index 8d87d955f7..930a0d57d4 100644 --- a/src/Juvix/Compiler/Nockma/StdlibFunction.hs +++ b/src/Juvix/Compiler/Nockma/StdlibFunction.hs @@ -1,40 +1,22 @@ module Juvix.Compiler.Nockma.StdlibFunction where -import Juvix.Compiler.Nockma.Language.Path -import Juvix.Prelude hiding (Atom, Path) -import Juvix.Prelude.Pretty +import Juvix.Compiler.Nockma.Translation.FromSource.QQ +import Juvix.Prelude hiding (Path) -instance Pretty StdlibFunction where - pretty = \case - StdlibDec -> "dec" - StdlibAdd -> "add" - StdlibSub -> "sub" - StdlibMul -> "mul" - StdlibDiv -> "div" - StdlibMod -> "mod" - StdlibLt -> "<" - StdlibLe -> "<=" - -data StdlibFunction - = StdlibDec - | StdlibAdd - | StdlibSub - | StdlibMul - | StdlibDiv - | StdlibMod - | StdlibLt - | StdlibLe - deriving stock (Show, Lift, Eq, Bounded, Enum) - --- | The stdlib paths are obtained using scripts/nockma-stdlib-parser.sh -stdlibPath :: StdlibFunction -> Path -stdlibPath = - decodePath' . EncodedPath . \case - StdlibDec -> 342 - StdlibAdd -> 20 - StdlibSub -> 47 - StdlibMul -> 4 - StdlibDiv -> 170 - StdlibMod -> 46 - StdlibLe -> 84 - StdlibLt -> 343 +-- | The stdlib paths are obtained from the Urbit dojo +-- * Load the stdlib file into the Urbit dojo +-- * Run: `=> anoma !=(s)` where s is a stdlib symbol +-- eg: +-- => anoma !=(add) +-- [9 20 0 15] +stdlibPath :: StdlibFunction -> Term Natural +stdlibPath = \case + StdlibDec -> [nock| [9 342 0 15] |] + StdlibAdd -> [nock| [9 20 0 15] |] + StdlibSub -> [nock| [9 47 0 15] |] + StdlibMul -> [nock| [9 4 0 15] |] + StdlibDiv -> [nock| [9 170 0 15] |] + StdlibMod -> [nock| [9 46 0 15] |] + StdlibLe -> [nock| [9 84 0 15] |] + StdlibLt -> [nock| [9 343 0 15] |] + StdlibPow2 -> [nock| [9 4 0 1] |] diff --git a/src/Juvix/Compiler/Nockma/StdlibFunction/Base.hs b/src/Juvix/Compiler/Nockma/StdlibFunction/Base.hs new file mode 100644 index 0000000000..e07905059f --- /dev/null +++ b/src/Juvix/Compiler/Nockma/StdlibFunction/Base.hs @@ -0,0 +1,28 @@ +module Juvix.Compiler.Nockma.StdlibFunction.Base where + +import Juvix.Prelude hiding (Atom, Path) +import Juvix.Prelude.Pretty + +instance Pretty StdlibFunction where + pretty = \case + StdlibDec -> "dec" + StdlibAdd -> "add" + StdlibSub -> "sub" + StdlibMul -> "mul" + StdlibDiv -> "div" + StdlibMod -> "mod" + StdlibLt -> "<" + StdlibLe -> "<=" + StdlibPow2 -> "pow2" + +data StdlibFunction + = StdlibDec + | StdlibAdd + | StdlibSub + | StdlibMul + | StdlibDiv + | StdlibMod + | StdlibLt + | StdlibLe + | StdlibPow2 + deriving stock (Show, Lift, Eq, Bounded, Enum) diff --git a/src/Juvix/Compiler/Nockma/Translation/FromTree.hs b/src/Juvix/Compiler/Nockma/Translation/FromTree.hs index 51cdce2af0..df5cbe699b 100644 --- a/src/Juvix/Compiler/Nockma/Translation/FromTree.hs +++ b/src/Juvix/Compiler/Nockma/Translation/FromTree.hs @@ -3,6 +3,7 @@ module Juvix.Compiler.Nockma.Translation.FromTree where import Juvix.Compiler.Nockma.Language.Path import Juvix.Compiler.Nockma.Pretty import Juvix.Compiler.Nockma.Stdlib +import Juvix.Compiler.Nockma.StdlibFunction import Juvix.Compiler.Pipeline.EntryPoint import Juvix.Compiler.Tree.Data.InfoTable qualified as Tree import Juvix.Compiler.Tree.Language qualified as Tree @@ -40,9 +41,8 @@ data FunctionId instance Hashable FunctionId data BuiltinFunctionId - = BuiltinPow2Go - | BuiltinPow2 - | BuiltinAppendRights + = -- | Not intended to be used, it exists only so the Enum and Bounded instances can be derived. + BuiltinPlaceholder deriving stock (Eq, Enum, Bounded, Generic) instance Hashable BuiltinFunctionId @@ -389,17 +389,12 @@ compile = \case let argsNum = getClosureField ClosureArgsNum f' oldArgs = getClosureField ClosureArgs f' fcode = getClosureField ClosureCode f' - posOfArgsNil <- appendRights emptyPath argsNum - let allArgs = replaceSubterm' oldArgs posOfArgsNil (remakeList newargs) + posOfArgsNil = appendRights emptyPath argsNum + allArgs = replaceSubterm' oldArgs posOfArgsNil (remakeList newargs) return (OpApply # replaceArgsWithTerm allArgs # fcode) -appendRights :: - (Members '[Reader CompilerCtx] r) => - Path -> - Term Natural -> - Sem r (Term Natural) -appendRights path n = - callFun (BuiltinFunction BuiltinAppendRights) [n, toNock path] +appendRights :: Path -> Term Natural -> Term Natural +appendRights path n = dec (mul (pow2 n) (OpInc # OpQuote # path)) pushTemp :: Term Natural -> Term Natural pushTemp toBePushed = @@ -437,22 +432,35 @@ extendClosure Tree.NodeExtendClosure {..} = do let argsNum = getClosureField ClosureArgsNum closure oldArgs = getClosureField ClosureArgs closure fcode = getClosureField ClosureCode closure - posOfArgsNil <- appendRights emptyPath argsNum - let allArgs = replaceSubterm' oldArgs posOfArgsNil (remakeList args) - let newArgsNum = add argsNum (nockIntegralLiteral (length _nodeExtendClosureArgs)) + posOfArgsNil = appendRights emptyPath argsNum + allArgs = replaceSubterm' oldArgs posOfArgsNil (remakeList args) + newArgsNum = add argsNum (nockIntegralLiteral (length _nodeExtendClosureArgs)) return . makeClosure $ \case ClosureCode -> fcode ClosureTotalArgsNum -> getClosureField ClosureTotalArgsNum closure ClosureArgsNum -> newArgsNum ClosureArgs -> allArgs +-- Calling convention for Anoma stdlib +-- +-- [push +-- [seq [@ locStdlib] getF] :: Obtain the function f within the stdlib. +-- :: locStdlib is the location of the stdlib in the subject +-- :: getF is a term that fetches f relative to the stdlib +-- [call L :: eval formula @ L of the following +-- [replace [RL :: edit at axis RL +-- [seq [@ R] :: evaluate the a formula in the original context without f on it +-- a]] :: the formula giving a goes here +-- @ L] :: this whole replace is editing what's at axis L, i.e. what was +-- ] +-- ] callStdlib :: StdlibFunction -> [Term Natural] -> Term Natural callStdlib fun args = let fPath = stdlibPath fun - getFunCode = OpCall # fPath # (OpAddress # stackPath StandardLibrary) + getFunCode = OpAddress # stackPath StandardLibrary >># fPath adjustArgs = case nonEmpty args of - Just args' -> OpReplace # ([R, L] # foldTerms args') - Nothing -> OpAddress # emptyPath + Just args' -> OpReplace # ([R, L] # ((OpAddress # [R]) >># foldTerms args')) # (OpAddress # [L]) + Nothing -> OpAddress # [L] callFn = OpCall # [L] # adjustArgs callCell = set cellCall (Just meta) (OpPush #. (getFunCode # callFn)) meta = @@ -588,36 +596,11 @@ runCompilerWith opts constrs libFuns mainFun = builtinFunction :: BuiltinFunctionId -> CompilerFunction builtinFunction = \case - BuiltinAppendRights -> - CompilerFunction - { _compilerFunctionName = BuiltinFunction BuiltinAppendRights, - _compilerFunctionArity = 2, -- args: n path - _compilerFunction = do - let n = OpAddress # pathToArg 0 - pos = OpAddress # pathToArg 1 - twoToTheN <- pow2 n - return (dec (mul twoToTheN (OpInc # pos))) - } - BuiltinPow2 -> - CompilerFunction - { _compilerFunctionName = BuiltinFunction BuiltinPow2, - _compilerFunctionArity = 1, - _compilerFunction = do - let n = OpAddress # pathToArg 0 - callFun (BuiltinFunction BuiltinPow2Go) [n, nockNatLiteral 1] - } - BuiltinPow2Go -> + BuiltinPlaceholder -> CompilerFunction - { _compilerFunctionName = BuiltinFunction BuiltinPow2Go, - _compilerFunctionArity = 2, -- args: n acc - _compilerFunction = do - let n = OpAddress # pathToArg 0 - acc = OpAddress # pathToArg 1 - cond = OpEq # n # nockNatLiteral 0 - baseCase = acc - recCase <- - callFun (BuiltinFunction BuiltinPow2Go) [dec n, mul (nockNatLiteral 2) acc] - return (branch cond baseCase recCase) + { _compilerFunctionName = BuiltinFunction BuiltinPlaceholder, + _compilerFunctionArity = 0, + _compilerFunction = return crash } callFun :: @@ -773,8 +756,8 @@ crash = (OpAddress # OpAddress # OpAddress) mul :: Term Natural -> Term Natural -> Term Natural mul a b = callStdlib StdlibMul [a, b] -pow2 :: (Members '[Reader CompilerCtx] r) => Term Natural -> Sem r (Term Natural) -pow2 = callFun (BuiltinFunction BuiltinPow2) . pure +pow2 :: Term Natural -> Term Natural +pow2 = callStdlib StdlibPow2 . pure add :: Term Natural -> Term Natural -> Term Natural add a b = callStdlib StdlibAdd [a, b] diff --git a/test/Nockma/Eval/Positive.hs b/test/Nockma/Eval/Positive.hs index e25191b9e4..016ced615f 100644 --- a/test/Nockma/Eval/Positive.hs +++ b/test/Nockma/Eval/Positive.hs @@ -1,15 +1,18 @@ module Nockma.Eval.Positive where import Base hiding (Path) +import Juvix.Compiler.Core.Language.Base (defaultSymbol) import Juvix.Compiler.Nockma.Evaluator import Juvix.Compiler.Nockma.Language import Juvix.Compiler.Nockma.Pretty import Juvix.Compiler.Nockma.Translation.FromSource.QQ +import Juvix.Compiler.Nockma.Translation.FromTree type Check = Sem '[Reader [Term Natural], Reader (Term Natural), Embed IO] data Test = Test - { _testName :: Text, + { _testEvalOptions :: EvalOptions, + _testName :: Text, _testProgramSubject :: Term Natural, _testProgramFormula :: Term Natural, _testCheck :: Check () @@ -24,11 +27,12 @@ allTests = testGroup "Nockma eval unit positive" (map mk tests) mk Test {..} = testCase (unpack _testName) $ do let (traces, evalResult) = run - . runReader defaultEvalOptions + . runReader _testEvalOptions . runOutputList @(Term Natural) . runError @(ErrNockNatural Natural) . runError @(NockEvalError Natural) $ eval _testProgramSubject _testProgramFormula + case evalResult of Left natErr -> assertFailure ("Evaluation error: " <> show natErr) Right r -> case r of @@ -63,22 +67,60 @@ eqTraces expected = do <> ppTrace ts assertFailure (unpack msg) +compilerTest :: Text -> Term Natural -> Check () -> Bool -> Test +compilerTest n mainFun _testCheck _evalInterceptStdlibCalls = + let f = + CompilerFunction + { _compilerFunctionName = UserFunction (defaultSymbol 0), + _compilerFunctionArity = 0, + _compilerFunction = return mainFun + } + _testName :: Text + | _evalInterceptStdlibCalls = n <> " - intercept stdlib" + | otherwise = n + opts = CompilerOptions {_compilerOptionsEnableTrace = False} + Cell _testProgramSubject _testProgramFormula = runCompilerWith opts mempty [] f + _testEvalOptions = EvalOptions {..} + in Test {..} + +test :: Text -> Term Natural -> Term Natural -> Check () -> Test +test = Test defaultEvalOptions + +compilerTests :: [Test] +compilerTests = + concatMap + (\mkT -> [mkT True, mkT False]) + [ compilerTest "stdlib add" (add (nockNatLiteral 1) (nockNatLiteral 2)) (eqNock [nock| 3 |]), + compilerTest "stdlib dec" (dec (nockNatLiteral 1)) (eqNock [nock| 0 |]), + compilerTest "stdlib mul" (mul (nockNatLiteral 2) (nockNatLiteral 3)) (eqNock [nock| 6 |]), + compilerTest "stdlib sub" (sub (nockNatLiteral 2) (nockNatLiteral 1)) (eqNock [nock| 1 |]), + compilerTest "stdlib div" (callStdlib StdlibDiv [nockNatLiteral 10, nockNatLiteral 3]) (eqNock [nock| 3 |]), + compilerTest "stdlib mod" (callStdlib StdlibMod [nockNatLiteral 3, nockNatLiteral 2]) (eqNock [nock| 1 |]), + compilerTest "stdlib le" (callStdlib StdlibLe [nockNatLiteral 3, nockNatLiteral 3]) (eqNock [nock| true |]), + compilerTest "stdlib lt" (callStdlib StdlibLt [nockNatLiteral 3, nockNatLiteral 3]) (eqNock [nock| false |]), + compilerTest "stdlib pow2" (pow2 (nockNatLiteral 3)) (eqNock [nock| 8 |]), + compilerTest "stdlib nested" (dec (dec (nockNatLiteral 20))) (eqNock [nock| 18 |]), + compilerTest "append rights - empty" (appendRights emptyPath (nockNatLiteral 3)) (eqNock (toNock [R, R, R])), + compilerTest "append rights" (appendRights [L, L] (nockNatLiteral 3)) (eqNock (toNock [L, L, R, R, R])) + ] + tests :: [Test] tests = - [ Test "address" [nock| [0 1] |] [nock| [[@ R] [@ L]] |] (eqNock [nock| [1 0] |]), - Test "address nested" [nock| [0 1 2 3 4 5] |] [nock| [@ RRRRR] |] (eqNock [nock| 5 |]), - Test "quote" [nock| [0 1] |] [nock| [quote [1 0]] |] (eqNock [nock| [1 0] |]), - Test "apply" [nock| [0 1] |] [nock| [apply [@ S] [quote [@ R]]] |] (eqNock [nock| 1 |]), - Test "isCell atom" [nock| [0 1] |] [nock| [isCell [@ L]] |] (eqNock [nock| false |]), - Test "isCell cell" [nock| [0 1] |] [nock| [isCell [@ S]] |] (eqNock [nock| true |]), - Test "suc" [nock| [0 1] |] [nock| [suc [quote 1]] |] (eqNock [nock| 2 |]), - Test "eq" [nock| [0 1] |] [nock| [= [1 0] [1 0]] |] (eqNock [nock| true |]), - Test "eq" [nock| [0 1] |] [nock| [= [1 0] [0 1]] |] (eqNock [nock| false |]), - Test "if" [nock| [0 1] |] [nock| [if [quote true] [@ L] [@ R]] |] (eqNock [nock| 0 |]), - Test "if" [nock| [0 1] |] [nock| [if [quote false] [@ L] [@ R]] |] (eqNock [nock| 1 |]), - Test "seq" [nock| [0 1] |] [nock| [seq [[suc [@ L]] [@ R]] [suc [@ L]]] |] (eqNock [nock| 2 |]), - 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 "address" [nock| [0 1] |] [nock| [[@ R] [@ L]] |] (eqNock [nock| [1 0] |]), + test "address nested" [nock| [0 1 2 3 4 5] |] [nock| [@ RRRRR] |] (eqNock [nock| 5 |]), + test "quote" [nock| [0 1] |] [nock| [quote [1 0]] |] (eqNock [nock| [1 0] |]), + test "apply" [nock| [0 1] |] [nock| [apply [@ S] [quote [@ R]]] |] (eqNock [nock| 1 |]), + test "isCell atom" [nock| [0 1] |] [nock| [isCell [@ L]] |] (eqNock [nock| false |]), + test "isCell cell" [nock| [0 1] |] [nock| [isCell [@ S]] |] (eqNock [nock| true |]), + test "suc" [nock| [0 1] |] [nock| [suc [quote 1]] |] (eqNock [nock| 2 |]), + test "eq" [nock| [0 1] |] [nock| [= [1 0] [1 0]] |] (eqNock [nock| true |]), + test "eq" [nock| [0 1] |] [nock| [= [1 0] [0 1]] |] (eqNock [nock| false |]), + test "if" [nock| [0 1] |] [nock| [if [quote true] [@ L] [@ R]] |] (eqNock [nock| 0 |]), + test "if" [nock| [0 1] |] [nock| [if [quote false] [@ L] [@ R]] |] (eqNock [nock| 1 |]), + test "seq" [nock| [0 1] |] [nock| [seq [[suc [@ L]] [@ R]] [suc [@ L]]] |] (eqNock [nock| 2 |]), + 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 |]) ] + ++ compilerTests