mirror of
https://github.com/unisonweb/unison.git
synced 2024-09-22 15:58:34 +03:00
Merge remote-tracking branch 'origin/trunk' into topic/hash-module-v1b
# Conflicts: # parser-typechecker/src/Unison/Codebase.hs # unison-core/src/Unison/Type.hs
This commit is contained in:
commit
c2f8fbe803
@ -21,6 +21,7 @@ On startup, Unison prints a url for the codebase UI. If you did step 3 above, th
|
||||
* `stack exec tests` runs the tests
|
||||
* `stack exec transcripts` runs all the integration tests, found in `unison-src/transcripts`. You can add more tests to this directory.
|
||||
* `stack exec tests -- prefix-of-test` and `stack exec transcripts -- prefix-of-test` only run tests with a matching prefix.
|
||||
* `stack exec unison -- transcript unison-src/transcripts-round-trip/main.md` runs the pretty-printing round trip tests
|
||||
|
||||
### What if you want a profiled build?
|
||||
|
||||
|
BIN
parser-typechecker/.DS_Store
vendored
Normal file
BIN
parser-typechecker/.DS_Store
vendored
Normal file
Binary file not shown.
@ -144,6 +144,7 @@ executables:
|
||||
- unison-parser-typechecker
|
||||
- unison-codebase-sync
|
||||
- uri-encode
|
||||
- unliftio
|
||||
when:
|
||||
- condition: '!os(windows)'
|
||||
dependencies: unix
|
||||
|
@ -256,7 +256,8 @@ typeOf a f r = maybe a f (Map.lookup r termRefTypes)
|
||||
|
||||
builtinsSrc :: Var v => [BuiltinDSL v]
|
||||
builtinsSrc =
|
||||
[ B "Int.+" $ int --> int --> int
|
||||
[ B "Any.unsafeExtract" $ forall1 "a" (\a -> anyt --> a)
|
||||
, B "Int.+" $ int --> int --> int
|
||||
, B "Int.-" $ int --> int --> int
|
||||
, B "Int.*" $ int --> int --> int
|
||||
, B "Int./" $ int --> int --> int
|
||||
@ -634,13 +635,16 @@ codeBuiltins =
|
||||
, ("Code.serialize", code --> bytes)
|
||||
, ("Code.deserialize", bytes --> eithert text code)
|
||||
, ("Code.cache_", list (tuple [termLink,code]) --> io (list termLink))
|
||||
, ("Code.validate", list (tuple [termLink,code]) --> io (optionalt failure))
|
||||
, ("Code.lookup", termLink --> io (optionalt code))
|
||||
, ("Code.display", text --> code --> text)
|
||||
, ("Value.dependencies", value --> list termLink)
|
||||
, ("Value.serialize", value --> bytes)
|
||||
, ("Value.deserialize", bytes --> eithert text value)
|
||||
, ("Value.value", forall1 "a" $ \a -> a --> value)
|
||||
, ("Value.load"
|
||||
, forall1 "a" $ \a -> value --> io (eithert (list termLink) a))
|
||||
, ("Link.Term.toText", termLink --> text)
|
||||
]
|
||||
|
||||
stmBuiltins :: forall v. Var v => [(Text, Type v)]
|
||||
|
@ -8,6 +8,7 @@ module Unison.Codebase
|
||||
GetRootBranchError (..),
|
||||
getBranchForHash,
|
||||
getCodebaseDir,
|
||||
isBlank,
|
||||
SyncToDir,
|
||||
addDefsToCodebase,
|
||||
installUcmDependencies,
|
||||
@ -27,6 +28,7 @@ module Unison.Codebase
|
||||
)
|
||||
where
|
||||
|
||||
import Control.Error (rightMay)
|
||||
import Control.Error.Util (hush)
|
||||
import Control.Monad.Except (ExceptT (ExceptT), runExceptT)
|
||||
import Data.List as List
|
||||
@ -208,6 +210,11 @@ isType c r = case r of
|
||||
Reference.Builtin{} -> pure $ Builtin.isBuiltinType r
|
||||
Reference.DerivedId r -> isJust <$> getTypeDeclaration c r
|
||||
|
||||
isBlank :: Applicative m => Codebase m v a -> m Bool
|
||||
isBlank codebase = do
|
||||
root <- fromMaybe Branch.empty . rightMay <$> getRootBranch codebase
|
||||
pure (root == Branch.empty)
|
||||
|
||||
-- * Git stuff
|
||||
|
||||
-- | Sync elements as needed from a remote codebase into the local one.
|
||||
|
@ -12,12 +12,12 @@ import qualified Unison.Codebase.Path as Path
|
||||
import Data.Void (Void)
|
||||
|
||||
-- |"release/M1j.2" -> "releases._M1j"
|
||||
-- "devel/*" -> "trunk"
|
||||
-- "latest-*" -> "trunk"
|
||||
defaultBaseLib :: Parsec Void Text ReadRemoteNamespace
|
||||
defaultBaseLib = fmap makeNS $ devel <|> release
|
||||
defaultBaseLib = fmap makeNS $ latest <|> release
|
||||
where
|
||||
devel, release, version :: Parsec Void Text Text
|
||||
devel = "devel/" *> many anyChar *> eof $> "trunk"
|
||||
latest, release, version :: Parsec Void Text Text
|
||||
latest = "latest-" *> many anyChar *> eof $> "trunk"
|
||||
release = fmap ("releases._" <>) $ "release/" *> version <* eof
|
||||
version = fmap Text.pack $
|
||||
try (someTill anyChar "." <* many anyChar) <|> many anyChar
|
||||
|
@ -5,14 +5,14 @@ module Unison.Codebase.Init
|
||||
( Init (..),
|
||||
DebugName,
|
||||
InitError (..),
|
||||
CodebaseDir (..),
|
||||
CodebaseInitOptions (..),
|
||||
InitResult (..),
|
||||
SpecifiedCodebase (..),
|
||||
Pretty,
|
||||
createCodebase,
|
||||
initCodebaseAndExit,
|
||||
openOrCreateCodebase,
|
||||
openNewUcmCodebaseOrExit,
|
||||
homeOrSpecifiedDir
|
||||
)
|
||||
where
|
||||
|
||||
@ -25,21 +25,23 @@ import Unison.Prelude
|
||||
import qualified Unison.PrettyTerminal as PT
|
||||
import Unison.Symbol (Symbol)
|
||||
import qualified Unison.Util.Pretty as P
|
||||
import UnliftIO.Directory (canonicalizePath, getHomeDirectory)
|
||||
import UnliftIO.Directory (canonicalizePath)
|
||||
import Unison.Codebase.Init.CreateCodebaseError
|
||||
|
||||
-- CodebaseDir is used to help pass around a Home directory that isn't the
|
||||
-- CodebaseInitOptions is used to help pass around a Home directory that isn't the
|
||||
-- actual home directory of the user. Useful in tests.
|
||||
data CodebaseDir = Home CodebasePath | Specified CodebasePath
|
||||
data CodebaseInitOptions
|
||||
= Home CodebasePath
|
||||
| Specified SpecifiedCodebase
|
||||
|
||||
homeOrSpecifiedDir :: Maybe CodebasePath -> IO CodebaseDir
|
||||
homeOrSpecifiedDir specifiedDir = do
|
||||
homeDir <- getHomeDirectory
|
||||
pure $ maybe (Home homeDir) Specified specifiedDir
|
||||
data SpecifiedCodebase
|
||||
= CreateWhenMissing CodebasePath
|
||||
| DontCreateWhenMissing CodebasePath
|
||||
|
||||
codebaseDirToCodebasePath :: CodebaseDir -> CodebasePath
|
||||
codebaseDirToCodebasePath (Home dir) = dir
|
||||
codebaseDirToCodebasePath (Specified dir) = dir
|
||||
initOptionsToDir :: CodebaseInitOptions -> CodebasePath
|
||||
initOptionsToDir (Home dir ) = dir
|
||||
initOptionsToDir (Specified (CreateWhenMissing dir)) = dir
|
||||
initOptionsToDir (Specified (DontCreateWhenMissing dir)) = dir
|
||||
|
||||
type DebugName = String
|
||||
|
||||
@ -65,28 +67,42 @@ data InitResult m v a
|
||||
| CreatedCodebase CodebasePath (FinalizerAndCodebase m v a)
|
||||
| Error CodebasePath InitError
|
||||
|
||||
openOrCreateCodebase :: MonadIO m => Init m v a -> DebugName -> CodebaseDir -> m (InitResult m v a)
|
||||
openOrCreateCodebase cbInit debugName codebaseDir = do
|
||||
let resolvedPath = (codebaseDirToCodebasePath codebaseDir)
|
||||
createCodebaseWithResult :: MonadIO m => Init m v a -> DebugName -> CodebasePath -> m (InitResult m v a)
|
||||
createCodebaseWithResult cbInit debugName dir =
|
||||
createCodebase cbInit debugName dir >>= \case
|
||||
Left errorMessage -> do
|
||||
pure (Error dir (CouldntCreateCodebase errorMessage))
|
||||
Right cb -> do
|
||||
pure (CreatedCodebase dir cb)
|
||||
|
||||
whenNoV1Codebase :: MonadIO m => CodebasePath -> m (InitResult m v a) -> m (InitResult m v a )
|
||||
whenNoV1Codebase dir initResult =
|
||||
ifM (FCC.codebaseExists dir)
|
||||
(pure (Error dir FoundV1Codebase))
|
||||
initResult
|
||||
|
||||
openOrCreateCodebase :: MonadIO m => Init m v a -> DebugName -> CodebaseInitOptions -> m (InitResult m v a)
|
||||
openOrCreateCodebase cbInit debugName initOptions = do
|
||||
let resolvedPath = initOptionsToDir initOptions
|
||||
openCodebase cbInit debugName resolvedPath >>= \case
|
||||
Right cb -> pure (OpenedCodebase resolvedPath cb)
|
||||
Left _ ->
|
||||
case codebaseDir of
|
||||
case initOptions of
|
||||
Home homeDir -> do
|
||||
ifM (FCC.codebaseExists homeDir)
|
||||
(do pure (Error homeDir FoundV1Codebase))
|
||||
(do
|
||||
-- Create V2 codebase if neither a V1 or V2 exists
|
||||
createCodebase cbInit debugName homeDir >>= \case
|
||||
Left errorMessage -> do
|
||||
pure (Error homeDir (CouldntCreateCodebase errorMessage))
|
||||
Right cb -> do
|
||||
pure (CreatedCodebase homeDir cb)
|
||||
createCodebaseWithResult cbInit debugName homeDir
|
||||
)
|
||||
Specified specifiedDir -> do
|
||||
ifM (FCC.codebaseExists specifiedDir)
|
||||
(pure (Error specifiedDir FoundV1Codebase))
|
||||
(pure (Error specifiedDir NoCodebaseFoundAtSpecifiedDir))
|
||||
|
||||
Specified specified ->
|
||||
whenNoV1Codebase resolvedPath $ do
|
||||
case specified of
|
||||
DontCreateWhenMissing dir ->
|
||||
pure (Error dir NoCodebaseFoundAtSpecifiedDir)
|
||||
CreateWhenMissing dir ->
|
||||
createCodebaseWithResult cbInit debugName dir
|
||||
|
||||
createCodebase :: MonadIO m => Init m v a -> DebugName -> CodebasePath -> m (Either Pretty (m (), Codebase m v a))
|
||||
createCodebase cbInit debugName path = do
|
||||
@ -123,6 +139,6 @@ openNewUcmCodebaseOrExit cbInit debugName path = do
|
||||
pure x
|
||||
|
||||
-- | try to init a codebase where none exists and then exit regardless (i.e. `ucm -codebase dir init`)
|
||||
initCodebaseAndExit :: MonadIO m => Init m Symbol Ann -> DebugName -> Maybe CodebasePath -> m ()
|
||||
initCodebaseAndExit :: MonadIO m => Init m Symbol Ann -> DebugName -> Maybe CodebasePath -> m () -- RLM : or could change here
|
||||
initCodebaseAndExit i debugName mdir =
|
||||
void $ openNewUcmCodebaseOrExit i debugName =<< Codebase.getCodebaseDir mdir
|
||||
|
@ -29,7 +29,8 @@ import Unison.Parser.Ann (Ann)
|
||||
import Unison.Prelude
|
||||
import Unison.PrettyTerminal
|
||||
import Unison.Symbol (Symbol)
|
||||
import Unison.CommandLine.Main (asciiartUnison, expandNumber)
|
||||
import Unison.CommandLine.Main (expandNumber)
|
||||
import Unison.CommandLine.Welcome (asciiartUnison)
|
||||
import qualified Data.Char as Char
|
||||
import qualified Data.Map as Map
|
||||
import qualified Data.Text as Text
|
||||
|
@ -312,7 +312,7 @@ displayDoc pped terms typeOf evaluated types = go
|
||||
Referent.Con r _ _ -> prettyType r
|
||||
prettyType r = let ppe = PPE.declarationPPE pped r in types r >>= \case
|
||||
Nothing -> pure $ "😶 Missing type source for: " <> typeName ppe r
|
||||
Just ty -> pure . P.syntaxToColor $ P.group $ DP.prettyDecl ppe r (PPE.typeName ppe r) ty
|
||||
Just ty -> pure . P.syntaxToColor $ P.group $ DP.prettyDecl pped r (PPE.typeName ppe r) ty
|
||||
|
||||
termName :: PPE.PrettyPrintEnv -> Referent -> Pretty
|
||||
termName ppe r = P.syntaxToColor $
|
||||
|
@ -11,7 +11,6 @@ import Control.Exception (finally, catch, AsyncException(UserInterrupt), asyncEx
|
||||
import Control.Monad.State (runStateT)
|
||||
import Data.Configurator.Types (Config)
|
||||
import Data.IORef
|
||||
import Data.Tuple.Extra (uncurry3)
|
||||
import Prelude hiding (readFile, writeFile)
|
||||
import System.IO.Error (isDoesNotExistError)
|
||||
import Unison.Codebase.Branch (Branch)
|
||||
@ -21,13 +20,12 @@ import qualified Unison.Server.CodebaseServer as Server
|
||||
import qualified Unison.Codebase.Editor.HandleInput as HandleInput
|
||||
import qualified Unison.Codebase.Editor.HandleCommand as HandleCommand
|
||||
import Unison.Codebase.Editor.Command (LoadSourceResult(..))
|
||||
import Unison.Codebase.Editor.RemoteRepo (ReadRemoteNamespace, printNamespace)
|
||||
import Unison.Codebase (Codebase)
|
||||
import Unison.CommandLine
|
||||
import Unison.PrettyTerminal
|
||||
import Unison.CommandLine.InputPattern (ArgumentType (suggestions), InputPattern (aliases, patternName))
|
||||
import Unison.CommandLine.InputPatterns (validInputs)
|
||||
import Unison.CommandLine.OutputMessages (notifyUser, notifyNumbered, shortenDirectory)
|
||||
import Unison.CommandLine.OutputMessages (notifyUser, notifyNumbered)
|
||||
import Unison.Parser.Ann (Ann)
|
||||
import Unison.Symbol (Symbol)
|
||||
import qualified Control.Concurrent.Async as Async
|
||||
@ -42,6 +40,7 @@ import qualified Unison.Codebase as Codebase
|
||||
import qualified Unison.CommandLine.InputPattern as IP
|
||||
import qualified Unison.Util.Pretty as P
|
||||
import qualified Unison.Util.TQueue as Q
|
||||
import qualified Unison.CommandLine.Welcome as Welcome
|
||||
import Text.Regex.TDFA
|
||||
import Control.Lens (view)
|
||||
import Control.Error (rightMay)
|
||||
@ -104,77 +103,26 @@ getUserInput patterns codebase branch currentPath numberedArgs = Line.runInputT
|
||||
pure $ suggestions argType word codebase branch currentPath
|
||||
_ -> pure []
|
||||
|
||||
asciiartUnison :: P.Pretty P.ColorText
|
||||
asciiartUnison =
|
||||
P.red " _____"
|
||||
<> P.hiYellow " _ "
|
||||
<> P.newline
|
||||
<> P.red "| | |"
|
||||
<> P.hiRed "___"
|
||||
<> P.hiYellow "|_|"
|
||||
<> P.hiGreen "___ "
|
||||
<> P.cyan "___ "
|
||||
<> P.purple "___ "
|
||||
<> P.newline
|
||||
<> P.red "| | | "
|
||||
<> P.hiYellow "| |"
|
||||
<> P.hiGreen "_ -"
|
||||
<> P.cyan "| . |"
|
||||
<> P.purple " |"
|
||||
<> P.newline
|
||||
<> P.red "|_____|"
|
||||
<> P.hiRed "_|_"
|
||||
<> P.hiYellow "|_|"
|
||||
<> P.hiGreen "___"
|
||||
<> P.cyan "|___|"
|
||||
<> P.purple "_|_|"
|
||||
|
||||
welcomeMessage :: FilePath -> String -> P.Pretty P.ColorText
|
||||
welcomeMessage dir version =
|
||||
asciiartUnison
|
||||
<> P.newline
|
||||
<> P.newline
|
||||
<> P.linesSpaced
|
||||
[ P.wrap "Welcome to Unison!"
|
||||
, P.wrap ("You are running version: " <> P.string version)
|
||||
, P.wrap
|
||||
( "I'm currently watching for changes to .u files under "
|
||||
<> (P.group . P.blue $ fromString dir)
|
||||
)
|
||||
, P.wrap ("Type " <> P.hiBlue "help" <> " to get help. 😎")
|
||||
]
|
||||
|
||||
hintFreshCodebase :: ReadRemoteNamespace -> P.Pretty P.ColorText
|
||||
hintFreshCodebase ns =
|
||||
P.wrap $ "Enter "
|
||||
<> (P.hiBlue . P.group)
|
||||
("pull " <> P.text (uncurry3 printNamespace ns) <> " .base")
|
||||
<> "to set up the default base library. 🏗"
|
||||
|
||||
main
|
||||
:: FilePath
|
||||
-> Maybe ReadRemoteNamespace
|
||||
-> Welcome.Welcome
|
||||
-> Path.Absolute
|
||||
-> (Config, IO ())
|
||||
-> [Either Event Input]
|
||||
-> Runtime.Runtime Symbol
|
||||
-> Codebase IO Symbol Ann
|
||||
-> String
|
||||
-> Maybe Server.BaseUrl
|
||||
-> IO ()
|
||||
main dir defaultBaseLib initialPath (config, cancelConfig) initialInputs runtime codebase version serverBaseUrl = do
|
||||
dir' <- shortenDirectory dir
|
||||
main dir welcome initialPath (config, cancelConfig) initialInputs runtime codebase serverBaseUrl = do
|
||||
root <- fromMaybe Branch.empty . rightMay <$> Codebase.getRootBranch codebase
|
||||
putPrettyLn $ case defaultBaseLib of
|
||||
Just ns | Branch.isOne root ->
|
||||
welcomeMessage dir' version <> P.newline <> P.newline <> hintFreshCodebase ns
|
||||
_ -> welcomeMessage dir' version
|
||||
(welcomeCmds, welcomeMsg) <- Welcome.welcome codebase welcome
|
||||
putPrettyLn welcomeMsg
|
||||
eventQueue <- Q.newIO
|
||||
do
|
||||
-- we watch for root branch tip changes, but want to ignore ones we expect.
|
||||
rootRef <- newIORef root
|
||||
pathRef <- newIORef initialPath
|
||||
initialInputsRef <- newIORef initialInputs
|
||||
initialInputsRef <- newIORef (welcomeCmds ++ initialInputs)
|
||||
numberedArgsRef <- newIORef []
|
||||
pageOutput <- newIORef True
|
||||
cancelFileSystemWatch <- watchFileSystem eventQueue dir
|
||||
|
@ -1150,7 +1150,7 @@ displayDefinitions' ppe0 types terms = P.syntaxToColor $ P.sep "\n\n" (prettyTyp
|
||||
BuiltinObject _ -> builtin n
|
||||
UserObject decl -> case decl of
|
||||
Left d -> DeclPrinter.prettyEffectDecl (ppeBody r) r n d
|
||||
Right d -> DeclPrinter.prettyDataDecl (ppeBody r) r n d
|
||||
Right d -> DeclPrinter.prettyDataDecl (PPE.declarationPPEDecl ppe0 r) r n d
|
||||
builtin n = P.wrap $ "--" <> prettyHashQualified n <> " is built-in."
|
||||
missing n r = P.wrap (
|
||||
"-- The name " <> prettyHashQualified n <> " is assigned to the "
|
||||
|
111
parser-typechecker/src/Unison/CommandLine/Welcome.hs
Normal file
111
parser-typechecker/src/Unison/CommandLine/Welcome.hs
Normal file
@ -0,0 +1,111 @@
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
module Unison.CommandLine.Welcome where
|
||||
|
||||
import Unison.Prelude
|
||||
import Unison.Codebase (Codebase)
|
||||
import qualified Unison.Codebase as Codebase
|
||||
import Prelude hiding (readFile, writeFile)
|
||||
import qualified Unison.Util.Pretty as P
|
||||
import System.Random (randomRIO)
|
||||
import qualified Unison.Codebase.Path as Path
|
||||
import qualified Unison.Codebase.SyncMode as SyncMode
|
||||
import Unison.Codebase.Editor.Input (Input (..), Event)
|
||||
import Data.Sequence (singleton)
|
||||
import Unison.NameSegment (NameSegment(NameSegment))
|
||||
import Unison.Codebase.Editor.RemoteRepo (ReadRemoteNamespace)
|
||||
|
||||
-- Should Welcome include whether or not the codebase was created just now?
|
||||
|
||||
data DownloadBase = DownloadBase ReadRemoteNamespace | DontDownloadBase
|
||||
|
||||
data Welcome = Welcome
|
||||
{ downloadBase :: DownloadBase
|
||||
, watchDir :: FilePath
|
||||
, unisonVersion :: String
|
||||
}
|
||||
|
||||
welcome :: Codebase IO v a -> Welcome -> IO ([Either Event Input], P.Pretty P.ColorText)
|
||||
welcome codebase welcome' = do
|
||||
let Welcome{downloadBase=downloadBase, watchDir=dir, unisonVersion=version} = welcome'
|
||||
welcomeMsg <- welcomeMessage dir version
|
||||
isBlankCodebase <- Codebase.isBlank codebase
|
||||
pure $ case downloadBase of
|
||||
DownloadBase ns@(_, _, path) | isBlankCodebase ->
|
||||
let
|
||||
cmd =
|
||||
Right (pullBase ns)
|
||||
|
||||
baseVersion =
|
||||
P.string (show path)
|
||||
|
||||
downloadMsg =
|
||||
P.lines [ P.newline <> P.newline
|
||||
, P.wrap ("🕐 Downloading"
|
||||
<> P.blue baseVersion
|
||||
<> "of the"
|
||||
<> P.bold "base library"
|
||||
<> "into"
|
||||
<> P.group (P.blue ".base" <> ", this may take a minute..."))
|
||||
]
|
||||
in
|
||||
([cmd], welcomeMsg <> downloadMsg)
|
||||
_ ->
|
||||
([], welcomeMsg)
|
||||
|
||||
welcomeMessage :: FilePath -> String -> IO (P.Pretty P.ColorText)
|
||||
welcomeMessage dir version = do
|
||||
earth <- (["🌎", "🌍", "🌏"] !!) <$> randomRIO (0, 2)
|
||||
|
||||
pure $
|
||||
asciiartUnison
|
||||
<> P.newline
|
||||
<> P.newline
|
||||
<> P.linesSpaced
|
||||
[ P.wrap "👋 Welcome to Unison!",
|
||||
P.wrap ("You are running version: " <> P.bold (P.string version)) <> P.newline,
|
||||
P.wrap "Get started:",
|
||||
P.indentN
|
||||
2
|
||||
( P.column2
|
||||
[ ("📖", "Type " <> P.hiBlue "help" <> " to list all commands, or " <> P.hiBlue "help <cmd>" <> " to view help for one command"),
|
||||
("🎨", "Type " <> P.hiBlue "ui" <> " to open the Codebase UI in your default browser"),
|
||||
("📚", "Read the official docs at " <> P.blue "https://unisonweb.org/docs"),
|
||||
(earth, "Visit Unison Share at " <> P.blue "https://share.unison-lang.org" <> " to discover libraries"),
|
||||
("👀", "I'm watching for changes to " <> P.bold ".u" <> " files under " <> (P.group . P.blue $ P.string dir))
|
||||
]
|
||||
)
|
||||
]
|
||||
|
||||
pullBase :: ReadRemoteNamespace -> Input
|
||||
pullBase ns = do
|
||||
let
|
||||
seg = NameSegment "base"
|
||||
rootPath = Path.Path { Path.toSeq = singleton seg }
|
||||
abs = Path.Absolute {Path.unabsolute = rootPath}
|
||||
PullRemoteBranchI (Just ns) (Path.Path' {Path.unPath' = Left abs}) SyncMode.Complete
|
||||
|
||||
asciiartUnison :: P.Pretty P.ColorText
|
||||
asciiartUnison =
|
||||
P.red " _____"
|
||||
<> P.hiYellow " _ "
|
||||
<> P.newline
|
||||
<> P.red "| | |"
|
||||
<> P.hiRed "___"
|
||||
<> P.hiYellow "|_|"
|
||||
<> P.hiGreen "___ "
|
||||
<> P.cyan "___ "
|
||||
<> P.purple "___ "
|
||||
<> P.newline
|
||||
<> P.red "| | | "
|
||||
<> P.hiYellow "| |"
|
||||
<> P.hiGreen "_ -"
|
||||
<> P.cyan "| . |"
|
||||
<> P.purple " |"
|
||||
<> P.newline
|
||||
<> P.red "|_____|"
|
||||
<> P.hiRed "_|_"
|
||||
<> P.hiYellow "|_|"
|
||||
<> P.hiGreen "___"
|
||||
<> P.cyan "|___|"
|
||||
<> P.purple "_|_|"
|
||||
|
@ -20,6 +20,7 @@ import qualified Unison.Name as Name
|
||||
import Unison.Name ( Name )
|
||||
import Unison.NamePrinter ( styleHashQualified'' )
|
||||
import Unison.PrettyPrintEnv ( PrettyPrintEnv )
|
||||
import Unison.PrettyPrintEnvDecl ( PrettyPrintEnvDecl(..) )
|
||||
import qualified Unison.PrettyPrintEnv as PPE
|
||||
import qualified Unison.Referent as Referent
|
||||
import Unison.Reference ( Reference(DerivedId) )
|
||||
@ -35,13 +36,13 @@ type SyntaxText = S.SyntaxText' Reference
|
||||
|
||||
prettyDecl
|
||||
:: Var v
|
||||
=> PrettyPrintEnv
|
||||
=> PrettyPrintEnvDecl
|
||||
-> Reference
|
||||
-> HashQualified Name
|
||||
-> DD.Decl v a
|
||||
-> Pretty SyntaxText
|
||||
prettyDecl ppe r hq d = case d of
|
||||
Left e -> prettyEffectDecl ppe r hq e
|
||||
prettyDecl ppe@(PrettyPrintEnvDecl unsuffixifiedPPE _) r hq d = case d of
|
||||
Left e -> prettyEffectDecl unsuffixifiedPPE r hq e
|
||||
Right dd -> prettyDataDecl ppe r hq dd
|
||||
|
||||
prettyEffectDecl
|
||||
@ -88,12 +89,12 @@ prettyPattern env ctorType ref namespace cid = styleHashQualified''
|
||||
|
||||
prettyDataDecl
|
||||
:: Var v
|
||||
=> PrettyPrintEnv
|
||||
=> PrettyPrintEnvDecl
|
||||
-> Reference
|
||||
-> HashQualified Name
|
||||
-> DataDeclaration v a
|
||||
-> Pretty SyntaxText
|
||||
prettyDataDecl env r name dd =
|
||||
prettyDataDecl (PrettyPrintEnvDecl unsuffixifiedPPE suffixifiedPPE) r name dd =
|
||||
(header <>) . P.sep (fmt S.DelimiterChar (" | " `P.orElse` "\n | ")) $ constructor <$> zip
|
||||
[0 ..]
|
||||
(DD.constructors' dd)
|
||||
@ -101,16 +102,16 @@ prettyDataDecl env r name dd =
|
||||
constructor (n, (_, _, (Type.ForallsNamed' _ t))) = constructor' n t
|
||||
constructor (n, (_, _, t) ) = constructor' n t
|
||||
constructor' n t = case Type.unArrows t of
|
||||
Nothing -> prettyPattern env CT.Data r name n
|
||||
Just ts -> case fieldNames env r name dd of
|
||||
Nothing -> P.group . P.hang' (prettyPattern env CT.Data r name n) " "
|
||||
$ P.spaced (TypePrinter.prettyRaw env Map.empty 10 <$> init ts)
|
||||
Nothing -> prettyPattern suffixifiedPPE CT.Data r name n
|
||||
Just ts -> case fieldNames unsuffixifiedPPE r name dd of
|
||||
Nothing -> P.group . P.hang' (prettyPattern suffixifiedPPE CT.Data r name n) " "
|
||||
$ P.spaced (TypePrinter.prettyRaw suffixifiedPPE Map.empty 10 <$> init ts)
|
||||
Just fs -> P.group $ (fmt S.DelimiterChar "{ ")
|
||||
<> P.sep ((fmt S.DelimiterChar ",") <> " " `P.orElse` "\n ")
|
||||
(field <$> zip fs (init ts))
|
||||
<> (fmt S.DelimiterChar " }")
|
||||
field (fname, typ) = P.group $ styleHashQualified'' (fmt (S.Reference r)) fname <>
|
||||
(fmt S.TypeAscriptionColon " :") `P.hang` TypePrinter.prettyRaw env Map.empty (-1) typ
|
||||
(fmt S.TypeAscriptionColon " :") `P.hang` TypePrinter.prettyRaw suffixifiedPPE Map.empty (-1) typ
|
||||
header = prettyDataHeader name dd <> (fmt S.DelimiterChar (" = " `P.orElse` "\n = "))
|
||||
|
||||
-- Comes up with field names for a data declaration which has the form of a
|
||||
@ -145,7 +146,6 @@ fieldNames env r name dd = case DD.constructors dd of
|
||||
[ (r, f) | (r, n) <- names
|
||||
, typename <- pure (HQ.toString name)
|
||||
, typename `isPrefixOf` n
|
||||
-- drop the typename and the following '.'
|
||||
, rest <- pure $ drop (length typename + 1) n
|
||||
, (f, rest) <- pure $ span (/= '.') rest
|
||||
, rest `elem` ["",".set",".modify"] ]
|
||||
|
@ -230,7 +230,7 @@ modifier = do
|
||||
unique = do
|
||||
tok <- openBlockWith "unique"
|
||||
uid <- do
|
||||
o <- optional (reserved "[" *> wordyIdString <* reserved "]")
|
||||
o <- optional (openBlockWith "[" *> wordyIdString <* closeBlock)
|
||||
case o of
|
||||
Nothing -> uniqueName 32
|
||||
Just uid -> pure (fromString . L.payload $ uid)
|
||||
|
@ -90,6 +90,7 @@ data Err
|
||||
| InvalidEscapeCharacter Char
|
||||
| LayoutError
|
||||
| CloseWithoutMatchingOpen String String -- open, close
|
||||
| UnexpectedDelimiter String
|
||||
| Opaque String -- Catch-all failure type, generally these will be
|
||||
-- automatically generated errors coming from megaparsec
|
||||
-- Try to avoid this for common errors a user is likely to see.
|
||||
@ -214,7 +215,8 @@ token'' tok p = do
|
||||
|
||||
topHasClosePair :: Layout -> Bool
|
||||
topHasClosePair [] = False
|
||||
topHasClosePair ((name,_):_) = name `elem` ["{", "(", "handle", "match", "if", "then"]
|
||||
topHasClosePair ((name,_):_) =
|
||||
name `elem` ["{", "(", "[", "handle", "match", "if", "then"]
|
||||
|
||||
lexer0' :: String -> String -> [Token Lexeme]
|
||||
lexer0' scope rem =
|
||||
@ -340,22 +342,24 @@ lexemes' eof = P.optional space >> do
|
||||
isPrefixOf "}}" word ||
|
||||
all (== '#') word
|
||||
|
||||
wordy ok = wrap "syntax.docWord" . tok . fmap Textual . P.try $ do
|
||||
let end = P.lookAhead $ void docClose
|
||||
<|> void docOpen
|
||||
<|> void (CP.satisfy isSpace)
|
||||
<|> void (CP.satisfy (not . ok))
|
||||
word <- P.someTill (CP.satisfy (\ch -> not (isSpace ch) && ok ch)) end
|
||||
guard (not $ reserved word)
|
||||
wordy closing = wrap "syntax.docWord" . tok . fmap Textual . P.try $ do
|
||||
let end =
|
||||
P.lookAhead
|
||||
$ void docClose
|
||||
<|> void docOpen
|
||||
<|> void (CP.satisfy isSpace)
|
||||
<|> void closing
|
||||
word <- P.manyTill (CP.satisfy (\ch -> not (isSpace ch))) end
|
||||
guard (not $ reserved word || null word)
|
||||
pure word
|
||||
|
||||
leafy ok = groupy ok gs
|
||||
where
|
||||
gs = link <|> externalLink <|> exampleInline <|> expr
|
||||
<|> boldOrItalicOrStrikethrough ok <|> verbatim
|
||||
<|> atDoc <|> wordy ok
|
||||
leafy closing = groupy closing gs
|
||||
where
|
||||
gs = link <|> externalLink <|> exampleInline <|> expr
|
||||
<|> boldOrItalicOrStrikethrough closing <|> verbatim
|
||||
<|> atDoc <|> wordy closing
|
||||
|
||||
leaf = leafy (const True)
|
||||
leaf = leafy mzero
|
||||
|
||||
atDoc = src <|> evalInline <|> signature <|> signatureInline
|
||||
where
|
||||
@ -401,9 +405,9 @@ lexemes' eof = P.optional space >> do
|
||||
signatureLink = wrap "syntax.docEmbedSignatureLink" $
|
||||
tok (symbolyId <|> wordyId) <* CP.space
|
||||
|
||||
groupy ok p = do
|
||||
groupy closing p = do
|
||||
(start,p,stop) <- positioned p
|
||||
after <- P.optional . P.try $ leafy ok
|
||||
after <- P.optional . P.try $ leafy closing
|
||||
pure $ case after of
|
||||
Nothing -> p
|
||||
Just after ->
|
||||
@ -484,28 +488,30 @@ lexemes' eof = P.optional space >> do
|
||||
verbatim <- tok $ Textual . trim <$> P.someTill CP.anyChar ([] <$ lit fence)
|
||||
pure (name <> verbatim)
|
||||
|
||||
boldOrItalicOrStrikethrough ok = do
|
||||
let start = some (CP.satisfy (== '*')) <|> some (CP.satisfy (== '_')) <|> some (CP.satisfy (== '~'))
|
||||
name s = if take 1 s == "~" then "syntax.docStrikethrough"
|
||||
else if length s > 1 then "syntax.docBold"
|
||||
else "syntax.docItalic"
|
||||
(end,ch) <- P.try $ do
|
||||
end@(ch:_) <- start
|
||||
boldOrItalicOrStrikethrough closing = do
|
||||
let start =
|
||||
some (CP.satisfy (== '*')) <|> some (CP.satisfy (== '_')) <|> some
|
||||
(CP.satisfy (== '~'))
|
||||
name s = if take 1 s == "~"
|
||||
then "syntax.docStrikethrough"
|
||||
else if take 1 s == "*" then "syntax.docBold" else "syntax.docItalic"
|
||||
end <- P.try $ do
|
||||
end <- start
|
||||
P.lookAhead (CP.satisfy (not . isSpace))
|
||||
pure (end,ch)
|
||||
wrap (name end) . wrap "syntax.docParagraph" $
|
||||
join <$> P.someTill (leafy (\c -> ok c && c /= ch) <* nonNewlineSpaces)
|
||||
(lit end)
|
||||
pure end
|
||||
wrap (name end) . wrap "syntax.docParagraph" $ join <$> P.someTill
|
||||
(leafy (closing <|> (void $ lit end)) <* nonNewlineSpaces)
|
||||
(lit end)
|
||||
|
||||
externalLink =
|
||||
P.label "hyperlink (example: [link name](https://destination.com))" $
|
||||
wrap "syntax.docNamedLink" $ do
|
||||
_ <- lit "["
|
||||
p <- leafies (/= ']')
|
||||
p <- leafies (void $ char ']')
|
||||
_ <- lit "]"
|
||||
_ <- lit "("
|
||||
target <- wrap "syntax.docGroup" . wrap "syntax.docJoin" $
|
||||
link <|> fmap join (P.some (expr <|> wordy (/= ')')))
|
||||
link <|> fmap join (P.some (expr <|> wordy (char ')')))
|
||||
_ <- lit ")"
|
||||
pure (p <> target)
|
||||
|
||||
@ -771,13 +777,29 @@ lexemes' eof = P.optional space >> do
|
||||
|
||||
reserved :: P [Token Lexeme]
|
||||
reserved =
|
||||
token' (\ts _ _ -> ts) $
|
||||
braces <|> parens <|> delim <|> delayOrForce <|> keywords <|> layoutKeywords
|
||||
where
|
||||
keywords = symbolyKw ":" <|> symbolyKw "@" <|> symbolyKw "||" <|> symbolyKw "|" <|> symbolyKw "&&"
|
||||
<|> wordyKw "true" <|> wordyKw "false"
|
||||
<|> wordyKw "use" <|> wordyKw "forall" <|> wordyKw "∀"
|
||||
<|> wordyKw "termLink" <|> wordyKw "typeLink"
|
||||
token' (\ts _ _ -> ts)
|
||||
$ braces
|
||||
<|> parens
|
||||
<|> brackets
|
||||
<|> commaSeparator
|
||||
<|> delim
|
||||
<|> delayOrForce
|
||||
<|> keywords
|
||||
<|> layoutKeywords
|
||||
where
|
||||
keywords =
|
||||
symbolyKw ":"
|
||||
<|> symbolyKw "@"
|
||||
<|> symbolyKw "||"
|
||||
<|> symbolyKw "|"
|
||||
<|> symbolyKw "&&"
|
||||
<|> wordyKw "true"
|
||||
<|> wordyKw "false"
|
||||
<|> wordyKw "use"
|
||||
<|> wordyKw "forall"
|
||||
<|> wordyKw "∀"
|
||||
<|> wordyKw "termLink"
|
||||
<|> wordyKw "typeLink"
|
||||
|
||||
wordyKw s = separated wordySep (kw s)
|
||||
symbolyKw s = separated (not . symbolyIdChar) (kw s)
|
||||
@ -809,12 +831,12 @@ lexemes' eof = P.optional space >> do
|
||||
let opens = [Token (Open "with") pos1 pos2]
|
||||
pure $ replicate n (Token Close pos1 pos2) ++ opens
|
||||
|
||||
-- In `structural/unique type` and `structural/unique ability`,
|
||||
-- In `structural/unique type` and `structural/unique ability`,
|
||||
-- only the `structural` or `unique` opens a layout block,
|
||||
-- and `ability` and `type` are just keywords.
|
||||
openTypeKw1 t = do
|
||||
b <- S.gets (topBlockName . layout)
|
||||
case b of
|
||||
case b of
|
||||
Just mod | Set.member mod typeModifiers -> wordyKw t
|
||||
_ -> openKw1 wordySep t
|
||||
|
||||
@ -840,7 +862,7 @@ lexemes' eof = P.optional space >> do
|
||||
env <- S.get
|
||||
-- -> introduces a layout block if we're inside a `match with` or `cases`
|
||||
case topBlockName (layout env) of
|
||||
Just match | match == "match-with" || match == "cases" -> do
|
||||
Just match | match `elem` matchWithBlocks -> do
|
||||
S.put (env { opening = Just "->" })
|
||||
pure [Token (Open "->") start end]
|
||||
_ -> pure [Token (Reserved "->") start end]
|
||||
@ -854,7 +876,20 @@ lexemes' eof = P.optional space >> do
|
||||
inLayout <- S.gets inLayout
|
||||
when (not inLayout) $ void $ P.lookAhead (CP.satisfy (/= '}'))
|
||||
pure l
|
||||
matchWithBlocks = ["match-with", "cases"]
|
||||
parens = open "(" <|> close ["("] (lit ")")
|
||||
brackets = open "[" <|> close ["["] (lit "]")
|
||||
-- `allowCommaToClose` determines if a comma should close inner blocks.
|
||||
-- Currently there is a set of blocks where `,` is not treated specially
|
||||
-- and it just emits a Reserved ",". There are currently only three:
|
||||
-- `cases`, `match-with`, and `{`
|
||||
allowCommaToClose match = not $ match `elem` ("{" : matchWithBlocks)
|
||||
commaSeparator = do
|
||||
env <- S.get
|
||||
case topBlockName (layout env) of
|
||||
Just match | allowCommaToClose match ->
|
||||
blockDelimiter ["[", "("] (lit ",")
|
||||
_ -> fail "this comma is a pattern separator"
|
||||
|
||||
delim = P.try $ do
|
||||
ch <- CP.satisfy (\ch -> ch /= ';' && Set.member ch delimiters)
|
||||
@ -882,6 +917,18 @@ lexemes' eof = P.optional space >> do
|
||||
|
||||
close = close' Nothing
|
||||
|
||||
blockDelimiter :: [String] -> P String -> P [Token Lexeme]
|
||||
blockDelimiter open closeP = do
|
||||
(pos1, close, pos2) <- positioned $ closeP
|
||||
env <- S.get
|
||||
case findClose open (layout env) of
|
||||
Nothing -> err pos1 (UnexpectedDelimiter (quote close))
|
||||
where quote s = "'" <> s <> "'"
|
||||
Just (_, n) -> do
|
||||
S.put (env { layout = drop (n-1) (layout env) })
|
||||
let delims = [Token (Reserved close) pos1 pos2]
|
||||
pure $ replicate (n-1) (Token Close pos1 pos2) ++ delims
|
||||
|
||||
close' :: Maybe String -> [String] -> P String -> P [Token Lexeme]
|
||||
close' reopenBlockname open closeP = do
|
||||
(pos1, close, pos2) <- positioned $ closeP
|
||||
@ -1086,7 +1133,7 @@ symbolyIdChars = Set.fromList "!$%^&*-=+<>.~\\/|:"
|
||||
keywords :: Set String
|
||||
keywords = Set.fromList [
|
||||
"if", "then", "else", "forall", "∀",
|
||||
"handle", "with",
|
||||
"handle", "with",
|
||||
"where", "use",
|
||||
"true", "false",
|
||||
"alias", "typeLink", "termLink",
|
||||
|
@ -406,24 +406,22 @@ string = queryToken getString
|
||||
getString _ = Nothing
|
||||
|
||||
tupleOrParenthesized :: Ord v => P v a -> (Ann -> a) -> (a -> a -> a) -> P v a
|
||||
tupleOrParenthesized p unit pair = do
|
||||
open <- openBlockWith "("
|
||||
es <- sepBy (reserved "," *> optional semi) p
|
||||
close <- optional semi *> closeBlock
|
||||
pure $ go es open close
|
||||
where
|
||||
go [t] _ _ = t
|
||||
go as s e = foldr pair (unit (ann s <> ann e)) as
|
||||
tupleOrParenthesized p unit pair = seq' "(" go p
|
||||
where
|
||||
go _ [t] = t
|
||||
go a xs = foldr pair (unit a) xs
|
||||
|
||||
seq :: Ord v => (Ann -> [a] -> a) -> P v a -> P v a
|
||||
seq f p = f' <$> leading <*> elements <*> trailing
|
||||
where
|
||||
f' open elems close = f (ann open <> ann close) elems
|
||||
redundant = P.skipMany (P.eitherP (reserved ",") semi)
|
||||
leading = reserved "[" <* redundant
|
||||
trailing = redundant *> reserved "]"
|
||||
sep = P.try $ optional semi *> reserved "," <* redundant
|
||||
elements = sepEndBy sep p
|
||||
seq = seq' "["
|
||||
|
||||
seq' :: Ord v => String -> (Ann -> [a] -> a) -> P v a -> P v a
|
||||
seq' openStr f p = do
|
||||
open <- openBlockWith openStr <* redundant
|
||||
es <- sepEndBy (P.try $ optional semi *> reserved "," <* redundant) p
|
||||
close <- redundant *> closeBlock
|
||||
pure $ go open es close
|
||||
where go open elems close = f (ann open <> ann close) elems
|
||||
redundant = P.skipMany (P.eitherP (reserved ",") semi)
|
||||
|
||||
chainr1 :: Ord v => P v a -> P v (a -> a -> a) -> P v a
|
||||
chainr1 p op = go1 where
|
||||
|
@ -1,6 +1,6 @@
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
|
||||
module Unison.PrettyPrintEnv.Util (declarationPPE) where
|
||||
module Unison.PrettyPrintEnv.Util (declarationPPE, declarationPPEDecl) where
|
||||
|
||||
import qualified Data.Set as Set
|
||||
import Unison.PrettyPrintEnv (PrettyPrintEnv (..))
|
||||
@ -29,3 +29,8 @@ declarationPPE ppe rd = PrettyPrintEnv tm ty
|
||||
if Set.member r comp
|
||||
then types (unsuffixifiedPPE ppe) r
|
||||
else types (suffixifiedPPE ppe) r
|
||||
|
||||
-- The suffixed names uses the fully-qualified name for `r`
|
||||
declarationPPEDecl :: PrettyPrintEnvDecl -> Reference -> PrettyPrintEnvDecl
|
||||
declarationPPEDecl ppe r =
|
||||
ppe { suffixifiedPPE = declarationPPE ppe r }
|
@ -2,7 +2,7 @@
|
||||
|
||||
module Unison.PrettyPrintEnvDecl (PrettyPrintEnvDecl(..)) where
|
||||
|
||||
import Unison.PrettyPrintEnv (PrettyPrintEnv)
|
||||
import Unison.PrettyPrintEnv (PrettyPrintEnv(..))
|
||||
|
||||
-- A pair of PrettyPrintEnvs:
|
||||
-- - suffixifiedPPE uses the shortest unique suffix
|
||||
@ -16,3 +16,4 @@ data PrettyPrintEnvDecl = PrettyPrintEnvDecl {
|
||||
unsuffixifiedPPE :: PrettyPrintEnv,
|
||||
suffixifiedPPE :: PrettyPrintEnv
|
||||
} deriving Show
|
||||
|
||||
|
@ -1031,6 +1031,10 @@ prettyParseError s = \case
|
||||
where
|
||||
excerpt = showSource s ((\t -> (rangeForToken t, ErrorSite)) <$> ts)
|
||||
go = \case
|
||||
L.UnexpectedDelimiter s ->
|
||||
"I found a " <> style ErrorSite (fromString s) <>
|
||||
" here, but I didn't see a list or tuple that it might be a separator for.\n\n" <>
|
||||
excerpt
|
||||
L.CloseWithoutMatchingOpen open close ->
|
||||
"I found a closing " <> style ErrorSite (fromString close) <>
|
||||
" here without a matching " <> style ErrorSite (fromString open) <> ".\n\n" <>
|
||||
|
@ -101,7 +101,7 @@ import Unison.Typechecker.Components (minimize')
|
||||
import Unison.Pattern (SeqOp(..))
|
||||
import qualified Unison.Pattern as P
|
||||
import Unison.Reference (Reference(..))
|
||||
import Unison.Referent (Referent, pattern Ref, pattern Con)
|
||||
import Unison.Referent (Referent)
|
||||
|
||||
-- For internal errors
|
||||
data CompileExn = CE CallStack (Pretty.Pretty Pretty.ColorText)
|
||||
@ -751,7 +751,8 @@ data POp
|
||||
| EQLU | CMPU | EROR
|
||||
-- Code
|
||||
| MISS | CACH | LKUP | LOAD -- isMissing,cache_,lookup,load
|
||||
| VALU -- value
|
||||
| CVLD -- validate
|
||||
| VALU | TLTT -- value, Term.Link.toText
|
||||
-- Debug
|
||||
| PRNT | INFO
|
||||
-- STM
|
||||
@ -1205,12 +1206,8 @@ contLinks f (Mark ps de k)
|
||||
contLinks _ KE = mempty
|
||||
|
||||
litLinks :: Monoid a => (Bool -> Reference -> a) -> BLit -> a
|
||||
litLinks _ (Text _) = mempty
|
||||
litLinks _ (Bytes _) = mempty
|
||||
litLinks f (List s) = foldMap (valueLinks f) s
|
||||
litLinks f (TmLink (Ref r)) = f False r
|
||||
litLinks f (TmLink (Con r _ _)) = f True r
|
||||
litLinks f (TyLink r) = f True r
|
||||
litLinks _ _ = mempty
|
||||
|
||||
groupTermLinks :: SuperGroup v -> [Reference]
|
||||
groupTermLinks = Set.toList . groupLinks f
|
||||
|
@ -528,7 +528,7 @@ getCase ctx frsh0 = do
|
||||
let l = length ccs
|
||||
frsh = frsh0 + fromIntegral l
|
||||
us = getFresh <$> take l [frsh0..]
|
||||
(,) ccs <$> getNormal (us++ctx) frsh
|
||||
(,) ccs . TAbss us <$> getNormal (us++ctx) frsh
|
||||
|
||||
putCTag :: MonadPut m => CTag -> m ()
|
||||
putCTag c = serialize (VarInt $ fromEnum c)
|
||||
|
@ -738,6 +738,24 @@ code'lookup
|
||||
, (1, ([BX], TAbs r $ TCon Ty.optionalRef 1 [r]))
|
||||
]
|
||||
|
||||
code'validate :: Var v => SuperNormal v
|
||||
code'validate
|
||||
= unop0 5 $ \[item, t, ref, msg, extra, fail]
|
||||
-> TLetD t UN (TPrm CVLD [item])
|
||||
. TMatch t . MatchSum
|
||||
$ mapFromList
|
||||
[ (1, ([BX, BX, BX],)
|
||||
. TAbss [ref, msg, extra]
|
||||
. TLetD fail BX (TCon Ty.failureRef 0 [ref, msg, extra])
|
||||
$ TCon Ty.optionalRef 1 [fail])
|
||||
, (0, ([],)
|
||||
$ TCon Ty.optionalRef 0 [])
|
||||
]
|
||||
|
||||
term'link'to'text :: Var v => SuperNormal v
|
||||
term'link'to'text
|
||||
= unop0 0 $ \[link] -> TPrm TLTT [link]
|
||||
|
||||
value'load :: Var v => SuperNormal v
|
||||
value'load
|
||||
= unop0 2 $ \[vlu,t,r]
|
||||
@ -771,6 +789,17 @@ standard'handle instr
|
||||
where
|
||||
(h0,h) = fresh2
|
||||
|
||||
any'construct :: Var v => SuperNormal v
|
||||
any'construct
|
||||
= unop0 0 $ \[v]
|
||||
-> TCon Ty.anyRef 0 [v]
|
||||
|
||||
any'extract :: Var v => SuperNormal v
|
||||
any'extract
|
||||
= unop0 1
|
||||
$ \[v,v1] -> TMatch v
|
||||
$ MatchData Ty.anyRef (mapSingleton 0 $ ([BX], TAbs v1 (TVar v1))) Nothing
|
||||
|
||||
seek'handle :: ForeignOp
|
||||
seek'handle instr
|
||||
= ([BX,BX,BX],)
|
||||
@ -1451,9 +1480,12 @@ builtinLookup
|
||||
, ("Code.isMissing", code'missing)
|
||||
, ("Code.cache_", code'cache)
|
||||
, ("Code.lookup", code'lookup)
|
||||
, ("Code.validate", code'validate)
|
||||
, ("Value.load", value'load)
|
||||
, ("Value.value", value'create)
|
||||
|
||||
, ("Any.Any", any'construct)
|
||||
, ("Any.unsafeExtract", any'extract)
|
||||
, ("Link.Term.toText", term'link'to'text)
|
||||
, ("STM.atomically", stm'atomic)
|
||||
] ++ foreignWrappers
|
||||
|
||||
@ -1789,6 +1821,8 @@ declareForeigns = do
|
||||
-> pure . Bytes.fromArray $ serializeGroup sg
|
||||
declareForeign "Code.deserialize" boxToEBoxBox
|
||||
. mkForeign $ pure . deserializeGroup @Symbol . Bytes.toArray
|
||||
declareForeign "Code.display" boxBoxDirect . mkForeign
|
||||
$ \(nm,sg) -> pure $ prettyGroup @Symbol (Text.unpack nm) sg ""
|
||||
declareForeign "Value.dependencies" boxDirect
|
||||
. mkForeign $
|
||||
pure . fmap (Wrap Ty.termLinkRef . Ref) . valueTermLinks
|
||||
@ -1796,10 +1830,6 @@ declareForeigns = do
|
||||
. mkForeign $ pure . Bytes.fromArray . serializeValue
|
||||
declareForeign "Value.deserialize" boxToEBoxBox
|
||||
. mkForeign $ pure . deserializeValue . Bytes.toArray
|
||||
|
||||
declareForeign "Any.Any" boxDirect . mkForeign $ \(a :: Closure) ->
|
||||
pure $ Closure.DataB1 Ty.anyRef 0 a
|
||||
|
||||
-- Hashing functions
|
||||
let declareHashAlgorithm :: forall v alg . Var v => Hash.HashAlgorithm alg => Text -> alg -> FDecl v ()
|
||||
declareHashAlgorithm txt alg = do
|
||||
|
@ -330,7 +330,8 @@ data BPrim1
|
||||
| FLTB -- flatten
|
||||
-- code
|
||||
| MISS | CACH | LKUP | LOAD -- isMissing,cache_,lookup,load
|
||||
| VALU -- value
|
||||
| CVLD -- validate
|
||||
| VALU | TLTT -- value, Term.Link.toText
|
||||
deriving (Show, Eq, Ord)
|
||||
|
||||
data BPrim2
|
||||
@ -741,7 +742,7 @@ emitSection rns grpn rec ctx (TMatch v bs)
|
||||
| Just (i,BX) <- ctxResolve ctx v
|
||||
, MatchData r cs df <- bs
|
||||
= Ins (Unpack (Just r) i)
|
||||
<$> emitDataMatching rns grpn rec ctx cs df
|
||||
<$> emitDataMatching r rns grpn rec ctx cs df
|
||||
| Just (i,BX) <- ctxResolve ctx v
|
||||
, MatchRequest hs0 df <- bs
|
||||
, hs <- mapFromList $ first (dnum rns) <$> M.toList hs0
|
||||
@ -1057,6 +1058,8 @@ emitPOp ANF.CMPU = emitBP2 CMPU
|
||||
emitPOp ANF.MISS = emitBP1 MISS
|
||||
emitPOp ANF.CACH = emitBP1 CACH
|
||||
emitPOp ANF.LKUP = emitBP1 LKUP
|
||||
emitPOp ANF.TLTT = emitBP1 TLTT
|
||||
emitPOp ANF.CVLD = emitBP1 CVLD
|
||||
emitPOp ANF.LOAD = emitBP1 LOAD
|
||||
emitPOp ANF.VALU = emitBP1 VALU
|
||||
|
||||
@ -1121,21 +1124,22 @@ emitBP2 p a
|
||||
|
||||
emitDataMatching
|
||||
:: Var v
|
||||
=> RefNums
|
||||
=> Reference
|
||||
-> RefNums
|
||||
-> Word64
|
||||
-> RCtx v
|
||||
-> Ctx v
|
||||
-> EnumMap CTag ([Mem], ANormal v)
|
||||
-> Maybe (ANormal v)
|
||||
-> Emit Section
|
||||
emitDataMatching rns grpn rec ctx cs df
|
||||
emitDataMatching r rns grpn rec ctx cs df
|
||||
= MatchW 0 <$> edf <*> traverse (emitCase rns grpn rec ctx) (coerce cs)
|
||||
where
|
||||
-- Note: this is not really accurate. A default data case needs
|
||||
-- stack space corresponding to the actual data that shows up there.
|
||||
-- However, we currently don't use default cases for data.
|
||||
edf | Just co <- df = emitSection rns grpn rec ctx co
|
||||
| otherwise = countCtx ctx $ Die "missing data case"
|
||||
| otherwise = countCtx ctx $ Die ("missing data case for hash " <> show r)
|
||||
|
||||
-- Emits code corresponding to an unboxed sum match.
|
||||
-- The match is against a tag on the stack, and cases introduce
|
||||
|
@ -15,7 +15,7 @@ import GHC.Conc as STM (unsafeIOToSTM)
|
||||
import Data.Maybe (fromMaybe)
|
||||
|
||||
import Data.Bits
|
||||
import Data.Foldable (toList)
|
||||
import Data.Foldable (toList, traverse_)
|
||||
import Data.Traversable
|
||||
import Data.Word (Word64)
|
||||
|
||||
@ -33,13 +33,14 @@ import qualified Data.Primitive.PrimArray as PA
|
||||
|
||||
import Text.Read (readMaybe)
|
||||
|
||||
import Unison.Builtin.Decls (exceptionRef)
|
||||
import Unison.Reference (Reference(Builtin))
|
||||
import Unison.Builtin.Decls (exceptionRef, ioFailureRef)
|
||||
import Unison.Reference (Reference(Builtin), toShortHash)
|
||||
import Unison.Referent (pattern Ref)
|
||||
import qualified Unison.ShortHash as SH
|
||||
import Unison.Symbol (Symbol)
|
||||
|
||||
import Unison.Runtime.ANF
|
||||
as ANF (Mem(..), SuperGroup, valueLinks, groupLinks)
|
||||
as ANF (Mem(..), CompileExn(..), SuperGroup, valueLinks, groupLinks)
|
||||
import qualified Unison.Runtime.ANF as ANF
|
||||
import Unison.Runtime.Builtin
|
||||
import Unison.Runtime.Exception
|
||||
@ -51,6 +52,7 @@ import Unison.Runtime.MCode
|
||||
import qualified Unison.Type as Rf
|
||||
|
||||
import qualified Unison.Util.Bytes as By
|
||||
import Unison.Util.Pretty (toPlainUnbroken)
|
||||
import Unison.Util.EnumContainers as EC
|
||||
|
||||
type Tag = Word64
|
||||
@ -216,8 +218,25 @@ exec !env !denv !ustk !bstk !k (BPrim1 CACH i) = do
|
||||
unknown <- cacheAdd news env
|
||||
bstk <- bump bstk
|
||||
pokeS bstk
|
||||
(Sq.fromList $ Foreign . Wrap Rf.typeLinkRef . Ref <$> unknown)
|
||||
(Sq.fromList $ Foreign . Wrap Rf.termLinkRef . Ref <$> unknown)
|
||||
pure (denv, ustk, bstk, k)
|
||||
exec !env !denv !ustk !bstk !k (BPrim1 CVLD i) = do
|
||||
arg <- peekOffS bstk i
|
||||
news <- decodeCacheArgument arg
|
||||
codeValidate news env >>= \case
|
||||
Nothing -> do
|
||||
ustk <- bump ustk
|
||||
poke ustk 0
|
||||
pure (denv, ustk, bstk, k)
|
||||
Just (Failure ref msg clo) -> do
|
||||
ustk <- bump ustk
|
||||
bstk <- bumpn bstk 3
|
||||
poke ustk 1
|
||||
poke bstk (Foreign $ Wrap Rf.typeLinkRef ref)
|
||||
pokeOffBi bstk 1 msg
|
||||
pokeOff bstk 2 clo
|
||||
pure (denv, ustk, bstk, k)
|
||||
|
||||
exec !env !denv !ustk !bstk !k (BPrim1 LKUP i) = do
|
||||
clink <- peekOff bstk i
|
||||
let Ref link = unwrapForeign $ marshalToForeign clink
|
||||
@ -230,6 +249,13 @@ exec !env !denv !ustk !bstk !k (BPrim1 LKUP i) = do
|
||||
bstk <- bump bstk
|
||||
bstk <$ pokeBi bstk sg
|
||||
pure (denv, ustk, bstk, k)
|
||||
exec !_ !denv !ustk !bstk !k (BPrim1 TLTT i) = do
|
||||
clink <- peekOff bstk i
|
||||
let Ref link = unwrapForeign $ marshalToForeign clink
|
||||
let sh = SH.toText $ toShortHash link
|
||||
bstk <- bump bstk
|
||||
pokeBi bstk sh
|
||||
pure (denv, ustk, bstk, k)
|
||||
exec !env !denv !ustk !bstk !k (BPrim1 LOAD i) = do
|
||||
v <- peekOffBi bstk i
|
||||
ustk <- bump ustk
|
||||
@ -1179,6 +1205,8 @@ bprim1 !ustk !bstk FLTB i = do
|
||||
bprim1 !ustk !bstk MISS _ = pure (ustk, bstk)
|
||||
bprim1 !ustk !bstk CACH _ = pure (ustk, bstk)
|
||||
bprim1 !ustk !bstk LKUP _ = pure (ustk, bstk)
|
||||
bprim1 !ustk !bstk CVLD _ = pure (ustk, bstk)
|
||||
bprim1 !ustk !bstk TLTT _ = pure (ustk, bstk)
|
||||
bprim1 !ustk !bstk LOAD _ = pure (ustk, bstk)
|
||||
bprim1 !ustk !bstk VALU _ = pure (ustk, bstk)
|
||||
{-# inline bprim1 #-}
|
||||
@ -1449,7 +1477,9 @@ decodeCacheArgument
|
||||
:: Sq.Seq Closure -> IO [(Reference, SuperGroup Symbol)]
|
||||
decodeCacheArgument s = for (toList s) $ \case
|
||||
DataB2 _ _ (Foreign x) (DataB2 _ _ (Foreign y) _)
|
||||
-> pure (unwrapForeign x, unwrapForeign y)
|
||||
-> case unwrapForeign x of
|
||||
Ref r -> pure (r, unwrapForeign y)
|
||||
_ -> die "decodeCacheArgument: Con reference"
|
||||
_ -> die "decodeCacheArgument: unrecognized value"
|
||||
|
||||
addRefs
|
||||
@ -1470,6 +1500,30 @@ addRefs vfrsh vfrom vto rs = do
|
||||
modifyTVar vto (nto <>)
|
||||
pure from
|
||||
|
||||
codeValidate
|
||||
:: [(Reference, SuperGroup Symbol)]
|
||||
-> CCache
|
||||
-> IO (Maybe (Failure Closure))
|
||||
codeValidate tml cc = do
|
||||
rty0 <- readTVarIO (refTy cc)
|
||||
fty <- readTVarIO (freshTy cc)
|
||||
let f b r | b, M.notMember r rty0 = S.singleton r
|
||||
| otherwise = mempty
|
||||
ntys0 = (foldMap.foldMap) (groupLinks f) tml
|
||||
ntys = M.fromList $ zip (S.toList ntys0) [fty..]
|
||||
rty = ntys <> rty0
|
||||
ftm <- readTVarIO (freshTm cc)
|
||||
rtm0 <- readTVarIO (refTm cc)
|
||||
let (rs, gs) = unzip tml
|
||||
rtm = rtm0 `M.withoutKeys` S.fromList rs
|
||||
rns = RN (refLookup "ty" rty) (refLookup "tm" rtm)
|
||||
combinate (n, g) = evaluate $ emitCombs rns n g
|
||||
(Nothing <$ traverse_ combinate (zip [ftm..] gs))
|
||||
`catch` \(CE cs perr) -> let
|
||||
msg = Tx.pack $ toPlainUnbroken perr
|
||||
extra = Foreign . Wrap Rf.textRef . Tx.pack $ show cs in
|
||||
pure . Just $ Failure ioFailureRef msg extra
|
||||
|
||||
cacheAdd0
|
||||
:: S.Set Reference
|
||||
-> [(Reference, SuperGroup Symbol)]
|
||||
@ -1480,6 +1534,7 @@ cacheAdd0 ntys0 tml cc = atomically $ do
|
||||
let new = M.difference toAdd have
|
||||
sz = fromIntegral $ M.size new
|
||||
(rs,gs) = unzip $ M.toList new
|
||||
int <- writeTVar (intermed cc) (have <> new)
|
||||
rty <- addRefs (freshTy cc) (refTy cc) (tagRefs cc) ntys0
|
||||
ntm <- stateTVar (freshTm cc) $ \i -> (i, i+sz)
|
||||
rtm <- updateMap (M.fromList $ zip rs [ntm..]) (refTm cc)
|
||||
@ -1488,7 +1543,7 @@ cacheAdd0 ntys0 tml cc = atomically $ do
|
||||
combinate n g = (n, emitCombs rns n g)
|
||||
nrs <- updateMap (mapFromList $ zip [ntm..] rs) (combRefs cc)
|
||||
ncs <- updateMap (mapFromList $ zipWith combinate [ntm..] gs) (combs cc)
|
||||
pure $ rtm `seq` nrs `seq` ncs `seq` ()
|
||||
pure $ int `seq` rtm `seq` nrs `seq` ncs `seq` ()
|
||||
where
|
||||
toAdd = M.fromList tml
|
||||
|
||||
@ -1552,7 +1607,7 @@ reflectValue rty = goV
|
||||
= pure (ANF.TmLink l)
|
||||
| Just l <- maybeUnwrapForeign Rf.typeLinkRef f
|
||||
= pure (ANF.TyLink l)
|
||||
| otherwise = die $ err "foreign value"
|
||||
| otherwise = die $ err $ "foreign value: " <> (show f)
|
||||
|
||||
|
||||
reifyValue :: CCache -> ANF.Value -> IO (Either [Reference] Closure)
|
||||
|
@ -324,7 +324,7 @@ typeListEntry codebase r n = do
|
||||
pure $ case decl of
|
||||
Just (Left _) -> Ability
|
||||
_ -> Data
|
||||
_ -> pure Data
|
||||
_ -> pure (if Set.member r Type.builtinAbilities then Ability else Data)
|
||||
pure $ TypeEntry r n tag
|
||||
|
||||
typeDeclHeader
|
||||
@ -891,9 +891,6 @@ typesToSyntax suff width ppe0 types =
|
||||
(first (PPE.typeName ppeDecl) . dupe)
|
||||
types
|
||||
where
|
||||
ppeBody r = if suffixified suff
|
||||
then PPE.suffixifiedPPE ppe0
|
||||
else PPE.declarationPPE ppe0 r
|
||||
ppeDecl = if suffixified suff
|
||||
then PPE.suffixifiedPPE ppe0
|
||||
else PPE.unsuffixifiedPPE ppe0
|
||||
@ -901,7 +898,7 @@ typesToSyntax suff width ppe0 types =
|
||||
BuiltinObject _ -> BuiltinObject (formatTypeName' ppeDecl r)
|
||||
MissingObject sh -> MissingObject sh
|
||||
UserObject d -> UserObject . Pretty.render width $
|
||||
DeclPrinter.prettyDecl (ppeBody r) r n d
|
||||
DeclPrinter.prettyDecl (PPE.declarationPPEDecl ppe0 r) r n d
|
||||
|
||||
loadSearchResults
|
||||
:: (Var v, Applicative m)
|
||||
|
@ -244,7 +244,7 @@ renderDoc pped terms typeOf eval types tm = eval tm >>= \case
|
||||
Just decl ->
|
||||
pure $ DO.UserObject (Src folded full)
|
||||
where
|
||||
full = formatPretty (DeclPrinter.prettyDecl ppe r (PPE.typeName ppe r) decl)
|
||||
full = formatPretty (DeclPrinter.prettyDecl pped r (PPE.typeName ppe r) decl)
|
||||
folded = formatPretty (DeclPrinter.prettyDeclHeader (PPE.typeName ppe r) decl)
|
||||
|
||||
go :: (Set.Set Reference, [Ref (UnisonHash, DisplayObject SyntaxText Src)])
|
||||
|
@ -406,21 +406,24 @@ pretty0
|
||||
-- produce any backticks. We build the result out from the right,
|
||||
-- starting at `f2`.
|
||||
binaryApps
|
||||
:: Var v => [(Term3 v PrintAnnotation, Term3 v PrintAnnotation)]
|
||||
-> Pretty SyntaxText
|
||||
-> Pretty SyntaxText
|
||||
:: Var v
|
||||
=> [(Term3 v PrintAnnotation, Term3 v PrintAnnotation)]
|
||||
-> Pretty SyntaxText
|
||||
-> Pretty SyntaxText
|
||||
binaryApps xs last = unbroken `PP.orElse` broken
|
||||
-- todo: use `PP.column2` in the case where we need to break
|
||||
where
|
||||
unbroken = PP.spaced (ps ++ [last])
|
||||
broken = PP.column2 (psCols $ [""] ++ ps ++ [last])
|
||||
broken = PP.hang (head ps) . PP.column2 . psCols $ (tail ps ++ [last])
|
||||
psCols ps = case take 2 ps of
|
||||
[x,y] -> (x,y) : psCols (drop 2 ps)
|
||||
[] -> []
|
||||
_ -> error "??"
|
||||
ps = join $ [r a f | (a, f) <- reverse xs ]
|
||||
r a f = [pretty0 n (ac 3 Normal im doc) a,
|
||||
pretty0 n (AmbientContext 10 Normal Infix im doc False) f]
|
||||
[x, y] -> (x, y) : psCols (drop 2 ps)
|
||||
[x] -> [(x, "")]
|
||||
[] -> []
|
||||
_ -> undefined
|
||||
ps = join $ [ r a f | (a, f) <- reverse xs ]
|
||||
r a f =
|
||||
[ pretty0 n (ac 3 Normal im doc) a
|
||||
, pretty0 n (AmbientContext 10 Normal Infix im doc False) f
|
||||
]
|
||||
|
||||
prettyPattern
|
||||
:: forall v loc . Var v
|
||||
@ -493,9 +496,9 @@ prettyPattern n c@(AmbientContext { imports = im }) p vs patt = case patt of
|
||||
(pr, rvs) = prettyPattern n c (p + 1) lvs r
|
||||
f i s = (paren (p >= i) (pl <> " " <> (fmt (S.Op op) s) <> " " <> pr), rvs)
|
||||
in case op of
|
||||
Pattern.Cons -> f 9 "+:"
|
||||
Pattern.Snoc -> f 9 ":+"
|
||||
Pattern.Concat -> f 9 "++"
|
||||
Pattern.Cons -> f 0 "+:"
|
||||
Pattern.Snoc -> f 0 ":+"
|
||||
Pattern.Concat -> f 0 "++"
|
||||
where
|
||||
l :: IsString s => String -> s
|
||||
l = fromString
|
||||
@ -1308,6 +1311,16 @@ prettyDoc2 ppe ac tm = case tm of
|
||||
S.DocDelimiter
|
||||
"}}"
|
||||
bail tm = brace (pretty0 ppe ac tm)
|
||||
-- Finds the longest run of a character and return a run one longer than that
|
||||
oneMore c inner = replicate num c
|
||||
where
|
||||
num =
|
||||
case
|
||||
filter (\s -> take 2 s == "__")
|
||||
$ group (PP.toPlainUnbroken $ PP.syntaxToColor inner)
|
||||
of
|
||||
[] -> 2
|
||||
x -> 1 + (maximum $ map length x)
|
||||
go :: Width -> Term3 v PrintAnnotation -> Pretty SyntaxText
|
||||
go hdr = \case
|
||||
(toDocTransclude ppe -> Just d) ->
|
||||
@ -1333,15 +1346,23 @@ prettyDoc2 ppe ac tm = case tm of
|
||||
(toDocWord ppe -> Just t) ->
|
||||
PP.text t
|
||||
(toDocCode ppe -> Just d) ->
|
||||
PP.group ("''" <> rec d <> "''")
|
||||
let inner = rec d
|
||||
quotes = oneMore '\'' inner
|
||||
in PP.group $ PP.string quotes <> inner <> PP.string quotes
|
||||
(toDocJoin ppe -> Just ds) ->
|
||||
foldMap rec ds
|
||||
(toDocItalic ppe -> Just d) ->
|
||||
PP.group $ "*" <> rec d <> "*"
|
||||
let inner = rec d
|
||||
underscores = oneMore '_' inner
|
||||
in PP.group $ PP.string underscores <> inner <> PP.string underscores
|
||||
(toDocBold ppe -> Just d) ->
|
||||
PP.group $ "__" <> rec d <> "__"
|
||||
let inner = rec d
|
||||
stars = oneMore '*' inner
|
||||
in PP.group $ PP.string stars <> inner <> PP.string stars
|
||||
(toDocStrikethrough ppe -> Just d) ->
|
||||
PP.group $ "~~" <> rec d <> "~~"
|
||||
let inner = rec d
|
||||
quotes = oneMore '~' inner
|
||||
in PP.group $ PP.string quotes <> inner <> PP.string quotes
|
||||
(toDocGroup ppe -> Just d) ->
|
||||
PP.group $ rec d
|
||||
(toDocColumn ppe -> Just ds) ->
|
||||
|
@ -84,9 +84,9 @@ effectList = do
|
||||
|
||||
sequenceTyp :: Var v => TypeP v
|
||||
sequenceTyp = do
|
||||
open <- reserved "["
|
||||
open <- openBlockWith "["
|
||||
t <- valueType
|
||||
close <- reserved "]"
|
||||
close <- closeBlock
|
||||
let a = ann open <> ann close
|
||||
pure $ Type.app a (Type.list a) t
|
||||
|
||||
|
@ -104,11 +104,13 @@ prettyRaw n im p tp = go n im p tp
|
||||
in (fmt S.TypeOperator "∀ " <> vformatted <> fmt S.TypeOperator ".")
|
||||
`PP.hang` go n im (-1) body
|
||||
t@(Arrow' _ _) -> case t of
|
||||
EffectfulArrows' (Ref' DD.UnitRef) rest -> arrows True True rest
|
||||
EffectfulArrows' (Ref' DD.UnitRef) rest ->
|
||||
PP.parenthesizeIf (p >= 10) $ arrows True True rest
|
||||
EffectfulArrows' fst rest ->
|
||||
case fst of
|
||||
Var' v | Var.name v == "()"
|
||||
-> fmt S.DelayForceChar "'" <> arrows False True rest
|
||||
Var' v | Var.name v == "()" ->
|
||||
PP.parenthesizeIf (p >= 10) $
|
||||
fmt S.DelayForceChar "'" <> arrows False True rest
|
||||
_ -> PP.parenthesizeIf (p >= 0) $
|
||||
go n im 0 fst <> arrows False False rest
|
||||
_ -> "error"
|
||||
|
@ -7,6 +7,10 @@ module Unison.Test.CodebaseInit where
|
||||
import EasyTest
|
||||
import qualified Unison.Codebase.Init as CI
|
||||
import Unison.Codebase.Init
|
||||
( CodebaseInitOptions(..)
|
||||
, Init(..)
|
||||
, SpecifiedCodebase(..)
|
||||
)
|
||||
import qualified System.IO.Temp as Temp
|
||||
|
||||
-- keep it off for CI, since the random temp dirs it generates show up in the
|
||||
@ -28,7 +32,7 @@ test = scope "Codebase.Init" $ tests
|
||||
, scope "a v2 codebase should be created when one does not exist" do
|
||||
tmp <- io (Temp.getCanonicalTemporaryDirectory >>= flip Temp.createTempDirectory "ucm-test")
|
||||
cbInit <- io initMockWithoutCodebase
|
||||
res <- io (CI.openOrCreateCodebase cbInit "ucm-test" (Home tmp) )
|
||||
res <- io (CI.openOrCreateCodebase cbInit "ucm-test" (Home tmp))
|
||||
case res of
|
||||
CI.CreatedCodebase _ _ -> expect True
|
||||
_ -> expect False
|
||||
@ -37,18 +41,35 @@ test = scope "Codebase.Init" $ tests
|
||||
[ scope "a v2 codebase should be opened" do
|
||||
tmp <- io (Temp.getCanonicalTemporaryDirectory >>= flip Temp.createTempDirectory "ucm-test")
|
||||
cbInit <- io initMockWithCodebase
|
||||
res <- io (CI.openOrCreateCodebase cbInit "ucm-test" (Specified tmp))
|
||||
res <- io (CI.openOrCreateCodebase cbInit "ucm-test" (Specified (DontCreateWhenMissing tmp)))
|
||||
case res of
|
||||
CI.OpenedCodebase _ _ -> expect True
|
||||
_ -> expect False
|
||||
, scope "a v2 codebase should be *not* created when one does not exist at the Specified dir" do
|
||||
tmp <- io (Temp.getCanonicalTemporaryDirectory >>= flip Temp.createTempDirectory "ucm-test")
|
||||
cbInit <- io initMockWithoutCodebase
|
||||
res <- io (CI.openOrCreateCodebase cbInit "ucm-test" (Specified tmp) )
|
||||
res <- io (CI.openOrCreateCodebase cbInit "ucm-test" (Specified (DontCreateWhenMissing tmp)))
|
||||
case res of
|
||||
CI.Error _ CI.NoCodebaseFoundAtSpecifiedDir -> expect True
|
||||
_ -> expect False
|
||||
]
|
||||
, scope "*with* a --codebase-create flag" $ tests
|
||||
[ scope "a v2 codebase should be created when one does not exist at the Specified dir" do
|
||||
tmp <- io (Temp.getCanonicalTemporaryDirectory >>= flip Temp.createTempDirectory "ucm-test")
|
||||
cbInit <- io initMockWithoutCodebase
|
||||
res <- io (CI.openOrCreateCodebase cbInit "ucm-test" (Specified (CreateWhenMissing tmp)))
|
||||
case res of
|
||||
CI.CreatedCodebase _ _ -> expect True
|
||||
_ -> expect False
|
||||
,
|
||||
scope "a v2 codebase should be opened when one exists" do
|
||||
tmp <- io (Temp.getCanonicalTemporaryDirectory >>= flip Temp.createTempDirectory "ucm-test")
|
||||
cbInit <- io initMockWithCodebase
|
||||
res <- io (CI.openOrCreateCodebase cbInit "ucm-test" (Specified (CreateWhenMissing tmp)))
|
||||
case res of
|
||||
CI.OpenedCodebase _ _ -> expect True
|
||||
_ -> expect False
|
||||
]
|
||||
]
|
||||
|
||||
-- Test helpers
|
||||
@ -58,9 +79,9 @@ initMockWithCodebase = do
|
||||
let codebase = error "did we /actually/ need a Codebase?"
|
||||
pure $ Init {
|
||||
-- DebugName -> CodebasePath -> m (Either Pretty (m (), Codebase m v a)),
|
||||
openCodebase = (\_ _ -> pure ( Right (pure (), codebase))),
|
||||
openCodebase = \_ _ -> pure ( Right (pure (), codebase)),
|
||||
-- DebugName -> CodebasePath -> m (Either CreateCodebaseError (m (), Codebase m v a)),
|
||||
createCodebase' = (\_ _ -> pure (Right (pure (), codebase))),
|
||||
createCodebase' = \_ _ -> pure (Right (pure (), codebase)),
|
||||
-- CodebasePath -> CodebasePath
|
||||
codebasePath = id
|
||||
}
|
||||
@ -70,9 +91,9 @@ initMockWithoutCodebase = do
|
||||
let codebase = error "did we /actually/ need a Codebase?"
|
||||
pure $ Init {
|
||||
-- DebugName -> CodebasePath -> m (Either Pretty (m (), Codebase m v a)),
|
||||
openCodebase = (\_ _ -> pure (Left "no codebase found")),
|
||||
openCodebase = \_ _ -> pure (Left "no codebase found"),
|
||||
-- DebugName -> CodebasePath -> m (Either CreateCodebaseError (m (), Codebase m v a)),
|
||||
createCodebase' = (\_ _ -> pure (Right (pure (), codebase))),
|
||||
createCodebase' = \_ _ -> pure (Right (pure (), codebase)),
|
||||
-- CodebasePath -> CodebasePath
|
||||
codebasePath = id
|
||||
}
|
@ -64,10 +64,10 @@ test =
|
||||
, t "woot;(woot)" [simpleWordyId "woot", Semi False, Open "(", simpleWordyId "woot", Close]
|
||||
, t
|
||||
"[+1,+1]"
|
||||
[Reserved "[", Numeric "+1", Reserved ",", Numeric "+1", Reserved "]"]
|
||||
[Open "[", Numeric "+1", Reserved ",", Numeric "+1", Close ]
|
||||
, t
|
||||
"[ +1 , +1 ]"
|
||||
[Reserved "[", Numeric "+1", Reserved ",", Numeric "+1", Reserved "]"]
|
||||
[Open "[", Numeric "+1", Reserved ",", Numeric "+1", Close ]
|
||||
, t "-- a comment 1.0" []
|
||||
, t "\"woot\" -- a comment 1.0" [Textual "woot"]
|
||||
, t "0:Int" [Numeric "0", Reserved ":", simpleWordyId "Int"]
|
||||
|
@ -134,8 +134,7 @@ test = scope "typeprinter" . tests $
|
||||
, tc "'{e} a"
|
||||
, tc "'{e} (a -> b)"
|
||||
, tc "'{e} (a ->{f} b)"
|
||||
, pending $ tc "Pair a '{e} b" -- parser hits unexpected '
|
||||
, tc_diff_rtt False "Pair a ('{e} b)" "Pair a '{e} b" 80 -- no RTT due to the above
|
||||
, tc "Pair a ('{e} b)"
|
||||
, tc "'(a -> 'a)"
|
||||
, tc "'()"
|
||||
, tc "'('a)"
|
||||
|
@ -13,7 +13,7 @@ test :: Test ()
|
||||
test = scope "versionparser" . tests . fmap makeTest $
|
||||
[ ("release/M1j", "releases._M1j")
|
||||
, ("release/M1j.2", "releases._M1j")
|
||||
, ("devel/M1k", "trunk")
|
||||
, ("latest-abc", "trunk")
|
||||
]
|
||||
|
||||
makeTest :: (Text, Text) -> Test ()
|
||||
|
@ -89,6 +89,7 @@ library
|
||||
Unison.CommandLine.InputPatterns
|
||||
Unison.CommandLine.Main
|
||||
Unison.CommandLine.OutputMessages
|
||||
Unison.CommandLine.Welcome
|
||||
Unison.DeclPrinter
|
||||
Unison.FileParser
|
||||
Unison.FileParsers
|
||||
@ -495,6 +496,7 @@ executable unison
|
||||
, unison-codebase-sync
|
||||
, unison-core1
|
||||
, unison-parser-typechecker
|
||||
, unliftio
|
||||
, uri-encode
|
||||
if flag(optimized)
|
||||
ghc-options: -funbox-strict-fields -O2
|
||||
|
@ -69,11 +69,21 @@ data ShouldForkCodebase
|
||||
| DontFork
|
||||
deriving (Show, Eq)
|
||||
|
||||
data ShouldDownloadBase
|
||||
= ShouldDownloadBase
|
||||
| ShouldNotDownloadBase
|
||||
deriving (Show, Eq)
|
||||
|
||||
data ShouldSaveCodebase
|
||||
= SaveCodebase
|
||||
| DontSaveCodebase
|
||||
deriving (Show, Eq)
|
||||
|
||||
data CodebasePathOption
|
||||
= CreateCodebaseWhenMissing FilePath
|
||||
| DontCreateCodebaseWhenMissing FilePath
|
||||
deriving (Show, Eq)
|
||||
|
||||
data IsHeadless = Headless | WithCLI
|
||||
deriving (Show, Eq)
|
||||
|
||||
@ -82,8 +92,9 @@ data IsHeadless = Headless | WithCLI
|
||||
-- Note that this is not one-to-one with command-parsers since some are simple variants.
|
||||
-- E.g. run, run.file, run.pipe
|
||||
data Command
|
||||
= Launch IsHeadless CodebaseServerOpts
|
||||
= Launch IsHeadless CodebaseServerOpts ShouldDownloadBase
|
||||
| PrintVersion
|
||||
-- @deprecated in trunk after M2g. Remove the Init command completely after M2h has been released
|
||||
| Init
|
||||
| Run RunSource
|
||||
| Transcript ShouldForkCodebase ShouldSaveCodebase (NonEmpty FilePath )
|
||||
@ -91,7 +102,7 @@ data Command
|
||||
|
||||
-- | Options shared by sufficiently many subcommands.
|
||||
data GlobalOptions = GlobalOptions
|
||||
{ codebasePath :: Maybe FilePath
|
||||
{ codebasePathOption :: Maybe CodebasePathOption
|
||||
} deriving (Show, Eq)
|
||||
|
||||
-- | The root-level 'ParserInfo'.
|
||||
@ -138,7 +149,8 @@ versionCommand = command "version" (info versionParser (fullDesc <> progDesc "Pr
|
||||
initCommand :: Mod CommandFields Command
|
||||
initCommand = command "init" (info initParser (progDesc initHelp))
|
||||
where
|
||||
initHelp = "Initialise a unison codebase"
|
||||
initHelp =
|
||||
"This command is has been removed. Use --codebase-create instead to create a codebase in the specified directory when starting the UCM."
|
||||
|
||||
runSymbolCommand :: Mod CommandFields Command
|
||||
runSymbolCommand =
|
||||
@ -190,18 +202,28 @@ commandParser envOpts =
|
||||
, transcriptForkCommand
|
||||
, launchHeadlessCommand envOpts
|
||||
]
|
||||
|
||||
|
||||
globalOptionsParser :: Parser GlobalOptions
|
||||
globalOptionsParser = do -- ApplicativeDo
|
||||
codebasePath <- codebasePathParser
|
||||
pure GlobalOptions{..}
|
||||
codebasePathOption <- codebasePathParser <|> codebaseCreateParser
|
||||
|
||||
codebasePathParser :: Parser (Maybe FilePath)
|
||||
codebasePathParser =
|
||||
optional . strOption $
|
||||
pure GlobalOptions{codebasePathOption = codebasePathOption}
|
||||
|
||||
codebasePathParser :: Parser (Maybe CodebasePathOption)
|
||||
codebasePathParser = do
|
||||
optString <- optional . strOption $
|
||||
long "codebase"
|
||||
<> metavar "path/to/codebase"
|
||||
<> help "The path to the codebase, defaults to the home directory"
|
||||
<> metavar "codebase/path"
|
||||
<> help "The path to an existing codebase"
|
||||
pure (fmap DontCreateCodebaseWhenMissing optString)
|
||||
|
||||
codebaseCreateParser :: Parser (Maybe CodebasePathOption)
|
||||
codebaseCreateParser = do
|
||||
path <- optional . strOption $
|
||||
long "codebase-create"
|
||||
<> metavar "codebase/path"
|
||||
<> help "The path to a new or existing codebase (one will be created if there isn't one)"
|
||||
pure (fmap CreateCodebaseWhenMissing path)
|
||||
|
||||
launchHeadlessCommand :: CodebaseServerOpts -> Mod CommandFields Command
|
||||
launchHeadlessCommand envOpts =
|
||||
@ -246,10 +268,11 @@ codebaseServerOptsParser envOpts = do -- ApplicativeDo
|
||||
launchParser :: CodebaseServerOpts -> IsHeadless -> Parser Command
|
||||
launchParser envOpts isHeadless = do -- ApplicativeDo
|
||||
codebaseServerOpts <- codebaseServerOptsParser envOpts
|
||||
pure (Launch isHeadless codebaseServerOpts)
|
||||
downloadBase <- downloadBaseFlag
|
||||
pure (Launch isHeadless codebaseServerOpts downloadBase)
|
||||
|
||||
initParser :: Parser Command
|
||||
initParser = pure Init
|
||||
initParser = pure Init
|
||||
|
||||
versionParser :: Parser Command
|
||||
versionParser = pure PrintVersion
|
||||
@ -273,6 +296,11 @@ saveCodebaseFlag = flag DontSaveCodebase SaveCodebase (long "save-codebase" <> h
|
||||
where
|
||||
saveHelp = "if set the resulting codebase will be saved to a new directory, otherwise it will be deleted"
|
||||
|
||||
downloadBaseFlag :: Parser ShouldDownloadBase
|
||||
downloadBaseFlag = flag ShouldDownloadBase ShouldNotDownloadBase (long "no-base" <> help downloadBaseHelp)
|
||||
where
|
||||
downloadBaseHelp = "if set, a new codebase will be created without downloading the base library, otherwise the new codebase will download base"
|
||||
|
||||
fileArgument :: String -> Parser FilePath
|
||||
fileArgument varName =
|
||||
strArgument ( metavar varName
|
||||
|
@ -22,7 +22,7 @@ import qualified System.IO.Temp as Temp
|
||||
import qualified System.Path as Path
|
||||
import Text.Megaparsec (runParser)
|
||||
import qualified Unison.Codebase as Codebase
|
||||
import Unison.Codebase.Init (InitResult(..), InitError(..))
|
||||
import Unison.Codebase.Init (InitResult(..), InitError(..), CodebaseInitOptions(..), SpecifiedCodebase(..))
|
||||
import qualified Unison.Codebase.Init as CodebaseInit
|
||||
import qualified Unison.Codebase.Editor.Input as Input
|
||||
import Unison.Codebase.Editor.RemoteRepo (ReadRemoteNamespace)
|
||||
@ -32,6 +32,7 @@ import qualified Unison.Codebase.Path as Path
|
||||
import qualified Unison.Codebase.SqliteCodebase as SC
|
||||
import qualified Unison.Codebase.TranscriptParser as TR
|
||||
import Unison.CommandLine (plural', watchConfig)
|
||||
import qualified Unison.CommandLine.Welcome as Welcome
|
||||
import qualified Unison.CommandLine.Main as CommandLine
|
||||
import Unison.Parser.Ann (Ann)
|
||||
import Unison.Prelude
|
||||
@ -42,14 +43,17 @@ import qualified Unison.Server.CodebaseServer as Server
|
||||
import Unison.Symbol (Symbol)
|
||||
import qualified Unison.Util.Pretty as P
|
||||
import qualified Version
|
||||
import UnliftIO.Directory ( getHomeDirectory )
|
||||
import Compat ( installSignalHandlers )
|
||||
import ArgParse
|
||||
( UsageRenderer,
|
||||
GlobalOptions(GlobalOptions, codebasePath),
|
||||
GlobalOptions(GlobalOptions, codebasePathOption),
|
||||
Command(Launch, PrintVersion, Init, Run, Transcript),
|
||||
IsHeadless(WithCLI, Headless),
|
||||
ShouldSaveCodebase(..),
|
||||
ShouldForkCodebase(..),
|
||||
ShouldDownloadBase (..),
|
||||
CodebasePathOption(..),
|
||||
RunSource(RunFromPipe, RunFromSymbol, RunFromFile),
|
||||
parseCLIArgs )
|
||||
import Data.List.NonEmpty (NonEmpty)
|
||||
@ -62,8 +66,9 @@ main = do
|
||||
|
||||
void installSignalHandlers
|
||||
(renderUsageInfo, globalOptions, command) <- parseCLIArgs progName Version.gitDescribe
|
||||
let GlobalOptions{codebasePath=mcodepath} = globalOptions
|
||||
let cbInit = SC.init
|
||||
let GlobalOptions{codebasePathOption=mCodePathOption} = globalOptions
|
||||
let mcodepath = fmap codebasePathOptionToPath mCodePathOption
|
||||
|
||||
currentDir <- getCurrentDirectory
|
||||
configFilePath <- getConfigFilePath mcodepath
|
||||
config <-
|
||||
@ -72,10 +77,21 @@ main = do
|
||||
case command of
|
||||
PrintVersion ->
|
||||
putStrLn $ progName ++ " version: " ++ Version.gitDescribe
|
||||
Init ->
|
||||
CodebaseInit.initCodebaseAndExit cbInit "main.init" mcodepath
|
||||
Init -> do
|
||||
PT.putPrettyLn $
|
||||
P.callout
|
||||
"⚠️"
|
||||
(P.lines ["The Init command has been removed"
|
||||
, P.newline
|
||||
, P.wrap "Use --codebase-create to create a codebase at a specified location and open it:"
|
||||
, P.indentN 2 (P.hiBlue "$ ucm --codebase-create myNewCodebase")
|
||||
, "Running UCM without the --codebase-create flag: "
|
||||
, P.indentN 2 (P.hiBlue "$ ucm")
|
||||
, P.wrap ("will " <> P.bold "always" <> " create a codebase in your home directory if one does not already exist.")
|
||||
])
|
||||
|
||||
Run (RunFromSymbol mainName) -> do
|
||||
(closeCodebase, theCodebase) <- getCodebaseOrExit mcodepath
|
||||
(closeCodebase, theCodebase) <- getCodebaseOrExit mCodePathOption
|
||||
runtime <- RTI.startRuntime
|
||||
execute theCodebase runtime mainName
|
||||
closeCodebase
|
||||
@ -86,36 +102,41 @@ main = do
|
||||
case e of
|
||||
Left _ -> PT.putPrettyLn $ P.callout "⚠️" "I couldn't find that file or it is for some reason unreadable."
|
||||
Right contents -> do
|
||||
(closeCodebase, theCodebase) <- getCodebaseOrExit mcodepath
|
||||
(closeCodebase, theCodebase) <- getCodebaseOrExit mCodePathOption
|
||||
rt <- RTI.startRuntime
|
||||
let fileEvent = Input.UnisonFileChanged (Text.pack file) contents
|
||||
launch currentDir config rt theCodebase [Left fileEvent, Right $ Input.ExecuteI mainName, Right Input.QuitI] Nothing
|
||||
launch currentDir config rt theCodebase [Left fileEvent, Right $ Input.ExecuteI mainName, Right Input.QuitI] Nothing ShouldNotDownloadBase
|
||||
closeCodebase
|
||||
Run (RunFromPipe mainName) -> do
|
||||
e <- safeReadUtf8StdIn
|
||||
case e of
|
||||
Left _ -> PT.putPrettyLn $ P.callout "⚠️" "I had trouble reading this input."
|
||||
Right contents -> do
|
||||
(closeCodebase, theCodebase) <- getCodebaseOrExit mcodepath
|
||||
(closeCodebase, theCodebase) <- getCodebaseOrExit mCodePathOption
|
||||
rt <- RTI.startRuntime
|
||||
let fileEvent = Input.UnisonFileChanged (Text.pack "<standard input>") contents
|
||||
launch
|
||||
currentDir config rt theCodebase
|
||||
[Left fileEvent, Right $ Input.ExecuteI mainName, Right Input.QuitI]
|
||||
Nothing
|
||||
ShouldNotDownloadBase
|
||||
closeCodebase
|
||||
Transcript shouldFork shouldSaveCodebase transcriptFiles ->
|
||||
runTranscripts renderUsageInfo shouldFork shouldSaveCodebase mcodepath transcriptFiles
|
||||
Launch isHeadless codebaseServerOpts -> do
|
||||
(closeCodebase, theCodebase) <- getCodebaseOrExit mcodepath
|
||||
runTranscripts renderUsageInfo shouldFork shouldSaveCodebase mCodePathOption transcriptFiles
|
||||
Launch isHeadless codebaseServerOpts downloadBase -> do
|
||||
(closeCodebase, theCodebase) <- getCodebaseOrExit mCodePathOption
|
||||
runtime <- RTI.startRuntime
|
||||
Server.startServer codebaseServerOpts runtime theCodebase $ \baseUrl -> do
|
||||
PT.putPrettyLn $ P.lines
|
||||
["The Unison Codebase UI is running at", P.string $ Server.urlFor Server.UI baseUrl]
|
||||
case isHeadless of
|
||||
Headless -> do
|
||||
PT.putPrettyLn $ P.lines
|
||||
["I've started the codebase API server at" , P.string $ Server.urlFor Server.Api baseUrl]
|
||||
PT.putPrettyLn $
|
||||
P.lines
|
||||
[ "I've started the Codebase API server at",
|
||||
P.string $ Server.urlFor Server.Api baseUrl,
|
||||
"and the Codebase UI at",
|
||||
P.string $ Server.urlFor Server.UI baseUrl
|
||||
]
|
||||
|
||||
PT.putPrettyLn $ P.string "Running the codebase manager headless with "
|
||||
<> P.shown GHC.Conc.numCapabilities
|
||||
<> " "
|
||||
@ -124,19 +145,20 @@ main = do
|
||||
mvar <- newEmptyMVar
|
||||
takeMVar mvar
|
||||
WithCLI -> do
|
||||
PT.putPrettyLn $ P.string "Now starting the Unison Codebase Manager..."
|
||||
launch currentDir config runtime theCodebase [] (Just baseUrl)
|
||||
PT.putPrettyLn $ P.string "Now starting the Unison Codebase Manager (UCM)..."
|
||||
launch currentDir config runtime theCodebase [] (Just baseUrl) downloadBase
|
||||
closeCodebase
|
||||
|
||||
prepareTranscriptDir :: ShouldForkCodebase -> Maybe FilePath -> IO FilePath
|
||||
prepareTranscriptDir shouldFork mcodepath = do
|
||||
prepareTranscriptDir :: ShouldForkCodebase -> Maybe CodebasePathOption -> IO FilePath
|
||||
prepareTranscriptDir shouldFork mCodePathOption = do
|
||||
tmp <- Temp.getCanonicalTemporaryDirectory >>= (`Temp.createTempDirectory` "transcript")
|
||||
let cbInit = SC.init
|
||||
case shouldFork of
|
||||
UseFork -> do
|
||||
getCodebaseOrExit mcodepath
|
||||
path <- Codebase.getCodebaseDir mcodepath
|
||||
PT.putPrettyLn $ P.lines [
|
||||
-- A forked codebase does not need to Create a codebase, because it already exists
|
||||
getCodebaseOrExit mCodePathOption
|
||||
path <- Codebase.getCodebaseDir (fmap codebasePathOptionToPath mCodePathOption)
|
||||
PT.putPrettyLn $ P.lines [
|
||||
P.wrap "Transcript will be run on a copy of the codebase at: ", "",
|
||||
P.indentN 2 (P.string path)
|
||||
]
|
||||
@ -164,7 +186,8 @@ runTranscripts' mcodepath transcriptDir args = do
|
||||
P.indentN 2 $ P.string err])
|
||||
Right stanzas -> do
|
||||
configFilePath <- getConfigFilePath mcodepath
|
||||
(closeCodebase, theCodebase) <- getCodebaseOrExit $ Just transcriptDir
|
||||
-- We don't need to create a codebase through `getCodebaseOrExit` as we've already done so previously.
|
||||
(closeCodebase, theCodebase) <- getCodebaseOrExit (Just (DontCreateCodebaseWhenMissing transcriptDir))
|
||||
mdOut <- TR.run transcriptDir configFilePath stanzas theCodebase
|
||||
closeCodebase
|
||||
let out = currentDir FP.</>
|
||||
@ -187,12 +210,12 @@ runTranscripts
|
||||
:: UsageRenderer
|
||||
-> ShouldForkCodebase
|
||||
-> ShouldSaveCodebase
|
||||
-> Maybe FilePath
|
||||
-> Maybe CodebasePathOption
|
||||
-> NonEmpty String
|
||||
-> IO ()
|
||||
runTranscripts renderUsageInfo shouldFork shouldSaveTempCodebase mcodepath args = do
|
||||
runTranscripts renderUsageInfo shouldFork shouldSaveTempCodebase mCodePathOption args = do
|
||||
progName <- getProgName
|
||||
transcriptDir <- prepareTranscriptDir shouldFork mcodepath
|
||||
transcriptDir <- prepareTranscriptDir shouldFork mCodePathOption
|
||||
completed <-
|
||||
runTranscripts' (Just transcriptDir) transcriptDir args
|
||||
case shouldSaveTempCodebase of
|
||||
@ -222,18 +245,25 @@ launch
|
||||
-> Codebase.Codebase IO Symbol Ann
|
||||
-> [Either Input.Event Input.Input]
|
||||
-> Maybe Server.BaseUrl
|
||||
-> ShouldDownloadBase
|
||||
-> IO ()
|
||||
launch dir config runtime codebase inputs serverBaseUrl =
|
||||
CommandLine.main
|
||||
dir
|
||||
defaultBaseLib
|
||||
initialPath
|
||||
config
|
||||
inputs
|
||||
runtime
|
||||
codebase
|
||||
Version.gitDescribe
|
||||
serverBaseUrl
|
||||
launch dir config runtime codebase inputs serverBaseUrl shouldDownloadBase =
|
||||
let
|
||||
downloadBase = case defaultBaseLib of
|
||||
Just remoteNS | shouldDownloadBase == ShouldDownloadBase -> Welcome.DownloadBase remoteNS
|
||||
_ -> Welcome.DontDownloadBase
|
||||
|
||||
welcome = Welcome.Welcome downloadBase dir Version.gitDescribe
|
||||
in
|
||||
CommandLine.main
|
||||
dir
|
||||
welcome
|
||||
initialPath
|
||||
config
|
||||
inputs
|
||||
runtime
|
||||
codebase
|
||||
serverBaseUrl
|
||||
|
||||
isMarkdown :: String -> Bool
|
||||
isMarkdown md = case FP.takeExtension md of
|
||||
@ -256,13 +286,10 @@ defaultBaseLib :: Maybe ReadRemoteNamespace
|
||||
defaultBaseLib = rightMay $
|
||||
runParser VP.defaultBaseLib "version" (Text.pack Version.gitDescribe)
|
||||
|
||||
getCodebaseOrExit :: Maybe Codebase.CodebasePath -> IO (IO (), Codebase.Codebase IO Symbol Ann)
|
||||
getCodebaseOrExit maybeSpecifiedDir = do
|
||||
-- Likely we should only change codebase format 2? Or both?
|
||||
-- Notes for selves: create a function 'openOrCreateCodebase' which handles v1/v2 codebase provided / no codebase specified
|
||||
-- encode error messages as types. Our spike / idea is below:
|
||||
codebaseDir <- CodebaseInit.homeOrSpecifiedDir maybeSpecifiedDir
|
||||
CodebaseInit.openOrCreateCodebase SC.init "main" codebaseDir >>= \case
|
||||
getCodebaseOrExit :: Maybe CodebasePathOption -> IO (IO (), Codebase.Codebase IO Symbol Ann)
|
||||
getCodebaseOrExit codebasePathOption = do
|
||||
initOptions <- argsToCodebaseInitOptions codebasePathOption
|
||||
CodebaseInit.openOrCreateCodebase SC.init "main" initOptions >>= \case
|
||||
Error dir error ->
|
||||
let
|
||||
message = do
|
||||
@ -271,10 +298,9 @@ getCodebaseOrExit maybeSpecifiedDir = do
|
||||
|
||||
case error of
|
||||
NoCodebaseFoundAtSpecifiedDir ->
|
||||
-- TODO: Perhaps prompt the user to create a codebase in that directory right away?
|
||||
pure (P.lines
|
||||
[ "No codebase exists in " <> pDir <> ".",
|
||||
"Run `" <> executableName <> " --codebase " <> P.string dir <> " init` to create one, then try again!"
|
||||
"Run `" <> executableName <> " --codebase-create " <> P.string dir <> " to create one, then try again!"
|
||||
])
|
||||
|
||||
FoundV1Codebase ->
|
||||
@ -293,7 +319,7 @@ getCodebaseOrExit maybeSpecifiedDir = do
|
||||
CreatedCodebase dir cb -> do
|
||||
pDir <- prettyDir dir
|
||||
PT.putPrettyLn' ""
|
||||
PT.putPrettyLn' . P.indentN 2 . P.wrap $ "I created a new codebase for you at" <> pDir
|
||||
PT.putPrettyLn' . P.indentN 2 . P.wrap $ "I created a new codebase for you at" <> P.blue pDir
|
||||
pure cb
|
||||
|
||||
OpenedCodebase _ cb ->
|
||||
@ -301,3 +327,16 @@ getCodebaseOrExit maybeSpecifiedDir = do
|
||||
|
||||
where
|
||||
prettyDir dir = P.string <$> canonicalizePath dir
|
||||
|
||||
argsToCodebaseInitOptions :: Maybe CodebasePathOption -> IO CodebaseInit.CodebaseInitOptions
|
||||
argsToCodebaseInitOptions pathOption =
|
||||
case pathOption of
|
||||
Just (CreateCodebaseWhenMissing path) -> pure $ Specified (CreateWhenMissing path)
|
||||
Just (DontCreateCodebaseWhenMissing path) -> pure $ Specified (DontCreateWhenMissing path)
|
||||
Nothing -> do Home <$> getHomeDirectory
|
||||
|
||||
codebasePathOptionToPath :: CodebasePathOption -> FilePath
|
||||
codebasePathOptionToPath codebasePathOption =
|
||||
case codebasePathOption of
|
||||
CreateCodebaseWhenMissing p -> p
|
||||
DontCreateCodebaseWhenMissing p -> p
|
12
stack.yaml
12
stack.yaml
@ -22,7 +22,7 @@ packages:
|
||||
- codebase2/util-term
|
||||
|
||||
#compiler-check: match-exact
|
||||
resolver: lts-18.6
|
||||
resolver: lts-18.9
|
||||
|
||||
extra-deps:
|
||||
- github: unisonweb/configurator
|
||||
@ -35,18 +35,8 @@ extra-deps:
|
||||
- prelude-extras-0.4.0.3@sha256:1c10b0123ea13a6423d74a8fcbaeb2d5249b472588abde418a36b47b7c4f48c8,1163
|
||||
- sandi-0.5@sha256:b278d072ca717706ea38f9bd646e023f7f2576a778fb43565b434f93638849aa,3010
|
||||
- strings-1.1@sha256:0285dec4c8ab262359342b3e5ef1eb567074669461b9b38404f1cb870c881c5c,1617
|
||||
- random-1.2.0
|
||||
# remove these when stackage upgrades containers
|
||||
# (these = containers 0.6.4, text-1.2.4, binary-0.8.8, parsec-3.1.14, Cabal-3.2.1.0)
|
||||
# see https://github.com/unisonweb/unison/pull/1807#issuecomment-777069869
|
||||
- containers-0.6.4.1
|
||||
- text-1.2.4.1
|
||||
- binary-0.8.8.0
|
||||
- parsec-3.1.14.0
|
||||
- Cabal-3.2.1.0
|
||||
- fuzzyfind-3.0.0
|
||||
- monad-validate-1.2.0.0@sha256:9850f408431098b28806dd464b6825a88a0b56c84f380d7fe0454c1df9d6f881,3505
|
||||
- optparse-applicative-0.16.1.0 # We need some features from the most recent revision
|
||||
|
||||
ghc-options:
|
||||
# All packages
|
||||
|
@ -669,6 +669,9 @@ cleanup :: Var v => Type v a -> Type v a
|
||||
cleanup t | not Settings.cleanupTypes = t
|
||||
cleanup t = cleanupVars1 . cleanupAbilityLists $ t
|
||||
|
||||
builtinAbilities :: Set Reference
|
||||
builtinAbilities = Set.fromList [builtinIORef, stmRef]
|
||||
|
||||
instance Show a => Show (F a) where
|
||||
showsPrec = go where
|
||||
go _ (Ref r) = shows r
|
||||
|
@ -79,3 +79,94 @@ f x = let
|
||||
.> load scratch.u
|
||||
```
|
||||
|
||||
## Parens around infix patterns
|
||||
|
||||
Regression test for https://github.com/unisonweb/unison/issues/2224
|
||||
|
||||
```unison:hide
|
||||
f : [a] -> a
|
||||
f xs = match xs with
|
||||
x +: (x' +: rest) -> x
|
||||
|
||||
g : [a] -> a
|
||||
g xs = match xs with
|
||||
(rest :+ x') :+ x -> x
|
||||
|
||||
h : [[a]] -> a
|
||||
h xs = match xs with
|
||||
(rest :+ (rest' :+ x)) -> x
|
||||
```
|
||||
|
||||
```ucm
|
||||
.> add
|
||||
.> edit f g
|
||||
.> reflog
|
||||
.> reset-root 2
|
||||
```
|
||||
|
||||
``` ucm
|
||||
.> load scratch.u
|
||||
```
|
||||
|
||||
## Type application inserts necessary parens
|
||||
|
||||
Regression test for https://github.com/unisonweb/unison/issues/2392
|
||||
|
||||
```unison:hide
|
||||
unique ability Zonk where zonk : Nat
|
||||
unique type Foo x y =
|
||||
|
||||
foo : Nat -> Foo ('{Zonk} a) ('{Zonk} b) -> Nat
|
||||
foo n _ = n
|
||||
```
|
||||
|
||||
```ucm
|
||||
.> add
|
||||
.> edit foo Zonk Foo
|
||||
.> reflog
|
||||
.> reset-root 2
|
||||
```
|
||||
|
||||
``` ucm
|
||||
.> load scratch.u
|
||||
```
|
||||
|
||||
## Long lines with repeated operators
|
||||
|
||||
Regression test for https://github.com/unisonweb/unison/issues/1035
|
||||
|
||||
```unison:hide
|
||||
foo : Text
|
||||
foo =
|
||||
"aaaaaaaaaaaaaaaaaaaaaa" ++ "bbbbbbbbbbbbbbbbbbbbbb" ++ "cccccccccccccccccccccc" ++ "dddddddddddddddddddddd"
|
||||
```
|
||||
|
||||
```ucm
|
||||
.> add
|
||||
.> edit foo
|
||||
.> reflog
|
||||
.> reset-root 2
|
||||
```
|
||||
|
||||
``` ucm
|
||||
.> load scratch.u
|
||||
```
|
||||
|
||||
## Emphasis in docs inserts the right number of underscores
|
||||
|
||||
Regression test for https://github.com/unisonweb/unison/issues/2408
|
||||
|
||||
```unison:hide
|
||||
myDoc = {{ **my text** __my text__ **MY_TEXT** ___MY__TEXT___ ~~MY~TEXT~~ **MY*TEXT** }}
|
||||
```
|
||||
|
||||
```ucm
|
||||
.> add
|
||||
.> edit myDoc
|
||||
.> undo
|
||||
```
|
||||
|
||||
``` ucm
|
||||
.> load scratch.u
|
||||
```
|
||||
|
||||
|
@ -34,15 +34,15 @@ x = 1 + 1
|
||||
most recent, along with the command that got us there. Try:
|
||||
|
||||
`fork 2 .old`
|
||||
`fork #pqvd5behc2 .old` to make an old namespace
|
||||
`fork #bt17giel42 .old` to make an old namespace
|
||||
accessible again,
|
||||
|
||||
`reset-root #pqvd5behc2` to reset the root namespace and
|
||||
`reset-root #bt17giel42` to reset the root namespace and
|
||||
its history to that of the
|
||||
specified namespace.
|
||||
|
||||
1. #8rn1an5gj8 : add
|
||||
2. #pqvd5behc2 : builtins.mergeio
|
||||
1. #agadr8gg6g : add
|
||||
2. #bt17giel42 : builtins.mergeio
|
||||
3. #sjg2v58vn2 : (initial reflogged namespace)
|
||||
|
||||
.> reset-root 2
|
||||
@ -116,17 +116,17 @@ Without the above stanza, the `edit` will send the definition to the most recent
|
||||
most recent, along with the command that got us there. Try:
|
||||
|
||||
`fork 2 .old`
|
||||
`fork #pqvd5behc2 .old` to make an old namespace
|
||||
`fork #bt17giel42 .old` to make an old namespace
|
||||
accessible again,
|
||||
|
||||
`reset-root #pqvd5behc2` to reset the root namespace and
|
||||
`reset-root #bt17giel42` to reset the root namespace and
|
||||
its history to that of the
|
||||
specified namespace.
|
||||
|
||||
1. #dbvse9969b : add
|
||||
2. #pqvd5behc2 : reset-root #pqvd5behc2
|
||||
3. #8rn1an5gj8 : add
|
||||
4. #pqvd5behc2 : builtins.mergeio
|
||||
1. #rhf1s808fb : add
|
||||
2. #bt17giel42 : reset-root #bt17giel42
|
||||
3. #agadr8gg6g : add
|
||||
4. #bt17giel42 : builtins.mergeio
|
||||
5. #sjg2v58vn2 : (initial reflogged namespace)
|
||||
|
||||
.> reset-root 2
|
||||
@ -157,7 +157,6 @@ unique type Blah = Blah Boolean Boolean
|
||||
|
||||
f : Blah -> Boolean
|
||||
f x = let
|
||||
0
|
||||
(Blah.Blah a b) = x
|
||||
a
|
||||
```
|
||||
@ -181,11 +180,7 @@ f x = let
|
||||
= Blah Boolean Boolean
|
||||
|
||||
f : Blah -> Boolean
|
||||
f x =
|
||||
0
|
||||
let
|
||||
(Blah a b) = x
|
||||
a
|
||||
f = cases Blah a b -> a
|
||||
|
||||
You can edit them there, then do `update` to replace the
|
||||
definitions currently in this namespace.
|
||||
@ -196,19 +191,19 @@ f x = let
|
||||
most recent, along with the command that got us there. Try:
|
||||
|
||||
`fork 2 .old`
|
||||
`fork #pqvd5behc2 .old` to make an old namespace
|
||||
`fork #bt17giel42 .old` to make an old namespace
|
||||
accessible again,
|
||||
|
||||
`reset-root #pqvd5behc2` to reset the root namespace and
|
||||
`reset-root #bt17giel42` to reset the root namespace and
|
||||
its history to that of the
|
||||
specified namespace.
|
||||
|
||||
1. #53gruvtk78 : add
|
||||
2. #pqvd5behc2 : reset-root #pqvd5behc2
|
||||
3. #dbvse9969b : add
|
||||
4. #pqvd5behc2 : reset-root #pqvd5behc2
|
||||
5. #8rn1an5gj8 : add
|
||||
6. #pqvd5behc2 : builtins.mergeio
|
||||
1. #gj5agagj7s : add
|
||||
2. #bt17giel42 : reset-root #bt17giel42
|
||||
3. #rhf1s808fb : add
|
||||
4. #bt17giel42 : reset-root #bt17giel42
|
||||
5. #agadr8gg6g : add
|
||||
6. #bt17giel42 : builtins.mergeio
|
||||
7. #sjg2v58vn2 : (initial reflogged namespace)
|
||||
|
||||
.> reset-root 2
|
||||
@ -229,3 +224,302 @@ f x = let
|
||||
f : Blah -> Boolean
|
||||
|
||||
```
|
||||
## Parens around infix patterns
|
||||
|
||||
Regression test for https://github.com/unisonweb/unison/issues/2224
|
||||
|
||||
```unison
|
||||
f : [a] -> a
|
||||
f xs = match xs with
|
||||
x +: (x' +: rest) -> x
|
||||
|
||||
g : [a] -> a
|
||||
g xs = match xs with
|
||||
(rest :+ x') :+ x -> x
|
||||
|
||||
h : [[a]] -> a
|
||||
h xs = match xs with
|
||||
(rest :+ (rest' :+ x)) -> x
|
||||
```
|
||||
|
||||
```ucm
|
||||
.> add
|
||||
|
||||
⍟ I've added these definitions:
|
||||
|
||||
f : [a] -> a
|
||||
g : [a] -> a
|
||||
h : [[a]] -> a
|
||||
|
||||
.> edit f g
|
||||
|
||||
☝️
|
||||
|
||||
I added these definitions to the top of
|
||||
/Users/runar/work/unison/scratch.u
|
||||
|
||||
f : [a] -> a
|
||||
f = cases x +: (x' +: rest) -> x
|
||||
|
||||
g : [a] -> a
|
||||
g = cases rest :+ x' :+ x -> x
|
||||
|
||||
You can edit them there, then do `update` to replace the
|
||||
definitions currently in this namespace.
|
||||
|
||||
.> reflog
|
||||
|
||||
Here is a log of the root namespace hashes, starting with the
|
||||
most recent, along with the command that got us there. Try:
|
||||
|
||||
`fork 2 .old`
|
||||
`fork #bt17giel42 .old` to make an old namespace
|
||||
accessible again,
|
||||
|
||||
`reset-root #bt17giel42` to reset the root namespace and
|
||||
its history to that of the
|
||||
specified namespace.
|
||||
|
||||
1. #3igmh2it4p : add
|
||||
2. #bt17giel42 : reset-root #bt17giel42
|
||||
3. #gj5agagj7s : add
|
||||
4. #bt17giel42 : reset-root #bt17giel42
|
||||
5. #rhf1s808fb : add
|
||||
6. #bt17giel42 : reset-root #bt17giel42
|
||||
7. #agadr8gg6g : add
|
||||
8. #bt17giel42 : builtins.mergeio
|
||||
9. #sjg2v58vn2 : (initial reflogged namespace)
|
||||
|
||||
.> reset-root 2
|
||||
|
||||
Done.
|
||||
|
||||
```
|
||||
```ucm
|
||||
.> load scratch.u
|
||||
|
||||
I found and typechecked these definitions in scratch.u. If you
|
||||
do an `add` or `update`, here's how your codebase would
|
||||
change:
|
||||
|
||||
⍟ These new definitions are ok to `add`:
|
||||
|
||||
f : [a] -> a
|
||||
g : [a] -> a
|
||||
|
||||
```
|
||||
## Type application inserts necessary parens
|
||||
|
||||
Regression test for https://github.com/unisonweb/unison/issues/2392
|
||||
|
||||
```unison
|
||||
unique ability Zonk where zonk : Nat
|
||||
unique type Foo x y =
|
||||
|
||||
foo : Nat -> Foo ('{Zonk} a) ('{Zonk} b) -> Nat
|
||||
foo n _ = n
|
||||
```
|
||||
|
||||
```ucm
|
||||
.> add
|
||||
|
||||
⍟ I've added these definitions:
|
||||
|
||||
unique type Foo x y
|
||||
unique ability Zonk
|
||||
foo : Nat -> Foo ('{Zonk} a) ('{Zonk} b) -> Nat
|
||||
|
||||
.> edit foo Zonk Foo
|
||||
|
||||
☝️
|
||||
|
||||
I added these definitions to the top of
|
||||
/Users/runar/work/unison/scratch.u
|
||||
|
||||
unique type Foo x y
|
||||
=
|
||||
|
||||
unique ability Zonk where zonk : {Zonk} Nat
|
||||
|
||||
foo : Nat -> Foo ('{Zonk} a) ('{Zonk} b) -> Nat
|
||||
foo n _ = n
|
||||
|
||||
You can edit them there, then do `update` to replace the
|
||||
definitions currently in this namespace.
|
||||
|
||||
.> reflog
|
||||
|
||||
Here is a log of the root namespace hashes, starting with the
|
||||
most recent, along with the command that got us there. Try:
|
||||
|
||||
`fork 2 .old`
|
||||
`fork #bt17giel42 .old` to make an old namespace
|
||||
accessible again,
|
||||
|
||||
`reset-root #bt17giel42` to reset the root namespace and
|
||||
its history to that of the
|
||||
specified namespace.
|
||||
|
||||
1. #jsnoueu9le : add
|
||||
2. #bt17giel42 : reset-root #bt17giel42
|
||||
3. #3igmh2it4p : add
|
||||
4. #bt17giel42 : reset-root #bt17giel42
|
||||
5. #gj5agagj7s : add
|
||||
6. #bt17giel42 : reset-root #bt17giel42
|
||||
7. #rhf1s808fb : add
|
||||
8. #bt17giel42 : reset-root #bt17giel42
|
||||
9. #agadr8gg6g : add
|
||||
10. #bt17giel42 : builtins.mergeio
|
||||
11. #sjg2v58vn2 : (initial reflogged namespace)
|
||||
|
||||
.> reset-root 2
|
||||
|
||||
Done.
|
||||
|
||||
```
|
||||
```ucm
|
||||
.> load scratch.u
|
||||
|
||||
I found and typechecked these definitions in scratch.u. If you
|
||||
do an `add` or `update`, here's how your codebase would
|
||||
change:
|
||||
|
||||
⍟ These new definitions are ok to `add`:
|
||||
|
||||
unique type Foo x y
|
||||
unique ability Zonk
|
||||
foo : Nat -> Foo ('{Zonk} a) ('{Zonk} b) -> Nat
|
||||
|
||||
```
|
||||
## Long lines with repeated operators
|
||||
|
||||
Regression test for https://github.com/unisonweb/unison/issues/1035
|
||||
|
||||
```unison
|
||||
foo : Text
|
||||
foo =
|
||||
"aaaaaaaaaaaaaaaaaaaaaa" ++ "bbbbbbbbbbbbbbbbbbbbbb" ++ "cccccccccccccccccccccc" ++ "dddddddddddddddddddddd"
|
||||
```
|
||||
|
||||
```ucm
|
||||
.> add
|
||||
|
||||
⍟ I've added these definitions:
|
||||
|
||||
foo : Text
|
||||
|
||||
.> edit foo
|
||||
|
||||
☝️
|
||||
|
||||
I added these definitions to the top of
|
||||
/Users/runar/work/unison/scratch.u
|
||||
|
||||
foo : Text
|
||||
foo =
|
||||
use Text ++
|
||||
"aaaaaaaaaaaaaaaaaaaaaa"
|
||||
++ "bbbbbbbbbbbbbbbbbbbbbb"
|
||||
++ "cccccccccccccccccccccc"
|
||||
++ "dddddddddddddddddddddd"
|
||||
|
||||
You can edit them there, then do `update` to replace the
|
||||
definitions currently in this namespace.
|
||||
|
||||
.> reflog
|
||||
|
||||
Here is a log of the root namespace hashes, starting with the
|
||||
most recent, along with the command that got us there. Try:
|
||||
|
||||
`fork 2 .old`
|
||||
`fork #bt17giel42 .old` to make an old namespace
|
||||
accessible again,
|
||||
|
||||
`reset-root #bt17giel42` to reset the root namespace and
|
||||
its history to that of the
|
||||
specified namespace.
|
||||
|
||||
1. #vbmanbqtlh : add
|
||||
2. #bt17giel42 : reset-root #bt17giel42
|
||||
3. #jsnoueu9le : add
|
||||
4. #bt17giel42 : reset-root #bt17giel42
|
||||
5. #3igmh2it4p : add
|
||||
6. #bt17giel42 : reset-root #bt17giel42
|
||||
7. #gj5agagj7s : add
|
||||
8. #bt17giel42 : reset-root #bt17giel42
|
||||
9. #rhf1s808fb : add
|
||||
10. #bt17giel42 : reset-root #bt17giel42
|
||||
11. #agadr8gg6g : add
|
||||
12. #bt17giel42 : builtins.mergeio
|
||||
13. #sjg2v58vn2 : (initial reflogged namespace)
|
||||
|
||||
.> reset-root 2
|
||||
|
||||
Done.
|
||||
|
||||
```
|
||||
```ucm
|
||||
.> load scratch.u
|
||||
|
||||
I found and typechecked these definitions in scratch.u. If you
|
||||
do an `add` or `update`, here's how your codebase would
|
||||
change:
|
||||
|
||||
⍟ These new definitions are ok to `add`:
|
||||
|
||||
foo : Text
|
||||
|
||||
```
|
||||
## Emphasis in docs inserts the right number of underscores
|
||||
|
||||
Regression test for https://github.com/unisonweb/unison/issues/2408
|
||||
|
||||
```unison
|
||||
myDoc = {{ **my text** __my text__ **MY_TEXT** ___MY__TEXT___ ~~MY~TEXT~~ **MY*TEXT** }}
|
||||
```
|
||||
|
||||
```ucm
|
||||
.> add
|
||||
|
||||
⍟ I've added these definitions:
|
||||
|
||||
myDoc : Doc2
|
||||
|
||||
.> edit myDoc
|
||||
|
||||
☝️
|
||||
|
||||
I added these definitions to the top of
|
||||
/Users/runar/work/unison/scratch.u
|
||||
|
||||
myDoc : Doc2
|
||||
myDoc =
|
||||
{{
|
||||
**my text** __my text__ **MY_TEXT** ___MY__TEXT___
|
||||
~~MY~TEXT~~ **MY*TEXT**
|
||||
}}
|
||||
|
||||
You can edit them there, then do `update` to replace the
|
||||
definitions currently in this namespace.
|
||||
|
||||
.> undo
|
||||
|
||||
Here are the changes I undid
|
||||
|
||||
Added definitions:
|
||||
|
||||
1. myDoc : Doc2
|
||||
|
||||
```
|
||||
```ucm
|
||||
.> load scratch.u
|
||||
|
||||
I found and typechecked these definitions in scratch.u. If you
|
||||
do an `add` or `update`, here's how your codebase would
|
||||
change:
|
||||
|
||||
⍟ These new definitions are ok to `add`:
|
||||
|
||||
myDoc : Doc2
|
||||
|
||||
```
|
||||
|
@ -166,3 +166,34 @@ to actual show that the serialization works.
|
||||
.> io.test tests
|
||||
.> io.test badLoad
|
||||
```
|
||||
|
||||
```unison
|
||||
validateTest : Link.Term ->{IO} Result
|
||||
validateTest l = match Code.lookup l with
|
||||
None -> Fail "Couldn't look up link"
|
||||
Some co -> match Code.validate [(l, co)] with
|
||||
Some f -> Fail "invalid code pre"
|
||||
None -> match Code.deserialize (Code.serialize co) with
|
||||
Left _ -> Fail "code failed deserialization"
|
||||
Right co -> match Code.validate [(l, co)] with
|
||||
Some f -> Fail "invalid code post"
|
||||
None -> Ok "validated"
|
||||
|
||||
vtests : '{IO} [Result]
|
||||
vtests _ =
|
||||
List.map validateTest
|
||||
[ termLink fib10
|
||||
, termLink compose
|
||||
, termLink List.all
|
||||
, termLink hex
|
||||
, termLink isDirectory
|
||||
, termLink delay
|
||||
, termLink printLine
|
||||
, termLink isNone
|
||||
]
|
||||
```
|
||||
|
||||
```ucm
|
||||
.> add
|
||||
.> io.test vtests
|
||||
```
|
||||
|
@ -281,3 +281,67 @@ to actual show that the serialization works.
|
||||
Tip: Use view badLoad to view the source of a test.
|
||||
|
||||
```
|
||||
```unison
|
||||
validateTest : Link.Term ->{IO} Result
|
||||
validateTest l = match Code.lookup l with
|
||||
None -> Fail "Couldn't look up link"
|
||||
Some co -> match Code.validate [(l, co)] with
|
||||
Some f -> Fail "invalid code pre"
|
||||
None -> match Code.deserialize (Code.serialize co) with
|
||||
Left _ -> Fail "code failed deserialization"
|
||||
Right co -> match Code.validate [(l, co)] with
|
||||
Some f -> Fail "invalid code post"
|
||||
None -> Ok "validated"
|
||||
|
||||
vtests : '{IO} [Result]
|
||||
vtests _ =
|
||||
List.map validateTest
|
||||
[ termLink fib10
|
||||
, termLink compose
|
||||
, termLink List.all
|
||||
, termLink hex
|
||||
, termLink isDirectory
|
||||
, termLink delay
|
||||
, termLink printLine
|
||||
, termLink isNone
|
||||
]
|
||||
```
|
||||
|
||||
```ucm
|
||||
|
||||
I found and typechecked these definitions in scratch.u. If you
|
||||
do an `add` or `update`, here's how your codebase would
|
||||
change:
|
||||
|
||||
⍟ These new definitions are ok to `add`:
|
||||
|
||||
validateTest : Link.Term ->{IO} Result
|
||||
vtests : '{IO} [Result]
|
||||
|
||||
```
|
||||
```ucm
|
||||
.> add
|
||||
|
||||
⍟ I've added these definitions:
|
||||
|
||||
validateTest : Link.Term ->{IO} Result
|
||||
vtests : '{IO} [Result]
|
||||
|
||||
.> io.test vtests
|
||||
|
||||
New test results:
|
||||
|
||||
◉ vtests validated
|
||||
◉ vtests validated
|
||||
◉ vtests validated
|
||||
◉ vtests validated
|
||||
◉ vtests validated
|
||||
◉ vtests validated
|
||||
◉ vtests validated
|
||||
◉ vtests validated
|
||||
|
||||
✅ 8 test(s) passing
|
||||
|
||||
Tip: Use view vtests to view the source of a test.
|
||||
|
||||
```
|
||||
|
@ -5,7 +5,7 @@ basicFormatting = {{
|
||||
Paragraphs are separated by one or more blanklines. Sections
|
||||
have a title and 0 or more paragraphs or other section elements.
|
||||
|
||||
Text can be __bold__, *italicized*, ~~strikethrough~~, or
|
||||
Text can be **bold**, __italicized__, ~~strikethrough~~, or
|
||||
''monospaced''.
|
||||
|
||||
You can link to Unison terms, types, and external URLs:
|
||||
@ -20,7 +20,7 @@ basicFormatting = {{
|
||||
This is useful for creating documents programmatically
|
||||
or just including other documents.
|
||||
|
||||
*Next up:* {lists}
|
||||
__Next up:__ {lists}
|
||||
}}
|
||||
|
||||
lists = {{
|
||||
@ -168,7 +168,7 @@ This is an aside. {{ docAside {{ Some extra detail that doesn't belong in main t
|
||||
docBlockquote {{
|
||||
"And what is the use of a book," thought Alice, "without pictures or conversation?"
|
||||
|
||||
*Lewis Carroll, Alice's Adventures in Wonderland* }}
|
||||
_Lewis Carroll, Alice's Adventures in Wonderland_ }}
|
||||
}}
|
||||
|
||||
{{ docTooltip {{Hover over me}} {{Extra detail}} }}
|
||||
|
@ -113,8 +113,8 @@ and the rendered output using `display`:
|
||||
Sections have a title and 0 or more paragraphs or other
|
||||
section elements.
|
||||
|
||||
Text can be __bold__, *italicized*, ~~strikethrough~~, or
|
||||
''monospaced''.
|
||||
Text can be **bold**, __italicized__, ~~strikethrough~~,
|
||||
or ''monospaced''.
|
||||
|
||||
You can link to Unison terms, types, and external URLs:
|
||||
|
||||
@ -129,7 +129,7 @@ and the rendered output using `display`:
|
||||
useful for creating documents programmatically or just
|
||||
including other documents.
|
||||
|
||||
*Next up:* {lists}
|
||||
__Next up:__ {lists}
|
||||
}}
|
||||
|
||||
.> display basicFormatting
|
||||
@ -469,7 +469,7 @@ and the rendered output using `display`:
|
||||
"And what is the use of a book," thought Alice, "without
|
||||
pictures or conversation?"
|
||||
|
||||
*Lewis Carroll, Alice's Adventures in Wonderland*
|
||||
__Lewis Carroll, Alice's Adventures in Wonderland__
|
||||
}} }}
|
||||
|
||||
{{ docTooltip {{ Hover over me }} {{ Extra detail }} }}
|
||||
|
@ -20,442 +20,446 @@ Let's try it!
|
||||
|
||||
1. builtin type Any
|
||||
2. Any.Any : a -> Any
|
||||
3. builtin type Boolean
|
||||
4. Boolean.not : Boolean -> Boolean
|
||||
5. bug : a -> b
|
||||
6. builtin type Bytes
|
||||
7. Bytes.++ : Bytes -> Bytes -> Bytes
|
||||
8. Bytes.at : Nat -> Bytes -> Optional Nat
|
||||
9. Bytes.decodeNat16be : Bytes -> Optional (Nat, Bytes)
|
||||
10. Bytes.decodeNat16le : Bytes -> Optional (Nat, Bytes)
|
||||
11. Bytes.decodeNat32be : Bytes -> Optional (Nat, Bytes)
|
||||
12. Bytes.decodeNat32le : Bytes -> Optional (Nat, Bytes)
|
||||
13. Bytes.decodeNat64be : Bytes -> Optional (Nat, Bytes)
|
||||
14. Bytes.decodeNat64le : Bytes -> Optional (Nat, Bytes)
|
||||
15. Bytes.drop : Nat -> Bytes -> Bytes
|
||||
16. Bytes.empty : Bytes
|
||||
17. Bytes.encodeNat16be : Nat -> Bytes
|
||||
18. Bytes.encodeNat16le : Nat -> Bytes
|
||||
19. Bytes.encodeNat32be : Nat -> Bytes
|
||||
20. Bytes.encodeNat32le : Nat -> Bytes
|
||||
21. Bytes.encodeNat64be : Nat -> Bytes
|
||||
22. Bytes.encodeNat64le : Nat -> Bytes
|
||||
23. Bytes.flatten : Bytes -> Bytes
|
||||
24. Bytes.fromBase16 : Bytes -> Either Text Bytes
|
||||
25. Bytes.fromBase32 : Bytes -> Either Text Bytes
|
||||
26. Bytes.fromBase64 : Bytes -> Either Text Bytes
|
||||
27. Bytes.fromBase64UrlUnpadded : Bytes -> Either Text Bytes
|
||||
28. Bytes.fromList : [Nat] -> Bytes
|
||||
29. Bytes.size : Bytes -> Nat
|
||||
30. Bytes.take : Nat -> Bytes -> Bytes
|
||||
31. Bytes.toBase16 : Bytes -> Bytes
|
||||
32. Bytes.toBase32 : Bytes -> Bytes
|
||||
33. Bytes.toBase64 : Bytes -> Bytes
|
||||
34. Bytes.toBase64UrlUnpadded : Bytes -> Bytes
|
||||
35. Bytes.toList : Bytes -> [Nat]
|
||||
36. builtin type Char
|
||||
37. Char.fromNat : Nat -> Char
|
||||
38. Char.toNat : Char -> Nat
|
||||
39. Char.toText : Char -> Text
|
||||
40. builtin type Code
|
||||
41. Code.cache_ : [(Term, Code)] ->{IO} [Term]
|
||||
42. Code.dependencies : Code -> [Term]
|
||||
43. Code.deserialize : Bytes -> Either Text Code
|
||||
44. Code.isMissing : Term ->{IO} Boolean
|
||||
45. Code.lookup : Term ->{IO} Optional Code
|
||||
46. Code.serialize : Code -> Bytes
|
||||
47. crypto.hash : HashAlgorithm -> a -> Bytes
|
||||
48. builtin type crypto.HashAlgorithm
|
||||
49. crypto.HashAlgorithm.Blake2b_256 : HashAlgorithm
|
||||
50. crypto.HashAlgorithm.Blake2b_512 : HashAlgorithm
|
||||
51. crypto.HashAlgorithm.Blake2s_256 : HashAlgorithm
|
||||
52. crypto.HashAlgorithm.Sha2_256 : HashAlgorithm
|
||||
53. crypto.HashAlgorithm.Sha2_512 : HashAlgorithm
|
||||
54. crypto.HashAlgorithm.Sha3_256 : HashAlgorithm
|
||||
55. crypto.HashAlgorithm.Sha3_512 : HashAlgorithm
|
||||
56. crypto.hashBytes : HashAlgorithm -> Bytes -> Bytes
|
||||
57. crypto.hmac : HashAlgorithm -> Bytes -> a -> Bytes
|
||||
58. crypto.hmacBytes : HashAlgorithm
|
||||
3. Any.unsafeExtract : Any -> a
|
||||
4. builtin type Boolean
|
||||
5. Boolean.not : Boolean -> Boolean
|
||||
6. bug : a -> b
|
||||
7. builtin type Bytes
|
||||
8. Bytes.++ : Bytes -> Bytes -> Bytes
|
||||
9. Bytes.at : Nat -> Bytes -> Optional Nat
|
||||
10. Bytes.decodeNat16be : Bytes -> Optional (Nat, Bytes)
|
||||
11. Bytes.decodeNat16le : Bytes -> Optional (Nat, Bytes)
|
||||
12. Bytes.decodeNat32be : Bytes -> Optional (Nat, Bytes)
|
||||
13. Bytes.decodeNat32le : Bytes -> Optional (Nat, Bytes)
|
||||
14. Bytes.decodeNat64be : Bytes -> Optional (Nat, Bytes)
|
||||
15. Bytes.decodeNat64le : Bytes -> Optional (Nat, Bytes)
|
||||
16. Bytes.drop : Nat -> Bytes -> Bytes
|
||||
17. Bytes.empty : Bytes
|
||||
18. Bytes.encodeNat16be : Nat -> Bytes
|
||||
19. Bytes.encodeNat16le : Nat -> Bytes
|
||||
20. Bytes.encodeNat32be : Nat -> Bytes
|
||||
21. Bytes.encodeNat32le : Nat -> Bytes
|
||||
22. Bytes.encodeNat64be : Nat -> Bytes
|
||||
23. Bytes.encodeNat64le : Nat -> Bytes
|
||||
24. Bytes.flatten : Bytes -> Bytes
|
||||
25. Bytes.fromBase16 : Bytes -> Either Text Bytes
|
||||
26. Bytes.fromBase32 : Bytes -> Either Text Bytes
|
||||
27. Bytes.fromBase64 : Bytes -> Either Text Bytes
|
||||
28. Bytes.fromBase64UrlUnpadded : Bytes -> Either Text Bytes
|
||||
29. Bytes.fromList : [Nat] -> Bytes
|
||||
30. Bytes.size : Bytes -> Nat
|
||||
31. Bytes.take : Nat -> Bytes -> Bytes
|
||||
32. Bytes.toBase16 : Bytes -> Bytes
|
||||
33. Bytes.toBase32 : Bytes -> Bytes
|
||||
34. Bytes.toBase64 : Bytes -> Bytes
|
||||
35. Bytes.toBase64UrlUnpadded : Bytes -> Bytes
|
||||
36. Bytes.toList : Bytes -> [Nat]
|
||||
37. builtin type Char
|
||||
38. Char.fromNat : Nat -> Char
|
||||
39. Char.toNat : Char -> Nat
|
||||
40. Char.toText : Char -> Text
|
||||
41. builtin type Code
|
||||
42. Code.cache_ : [(Term, Code)] ->{IO} [Term]
|
||||
43. Code.dependencies : Code -> [Term]
|
||||
44. Code.deserialize : Bytes -> Either Text Code
|
||||
45. Code.display : Text -> Code -> Text
|
||||
46. Code.isMissing : Term ->{IO} Boolean
|
||||
47. Code.lookup : Term ->{IO} Optional Code
|
||||
48. Code.serialize : Code -> Bytes
|
||||
49. Code.validate : [(Term, Code)] ->{IO} Optional Failure
|
||||
50. crypto.hash : HashAlgorithm -> a -> Bytes
|
||||
51. builtin type crypto.HashAlgorithm
|
||||
52. crypto.HashAlgorithm.Blake2b_256 : HashAlgorithm
|
||||
53. crypto.HashAlgorithm.Blake2b_512 : HashAlgorithm
|
||||
54. crypto.HashAlgorithm.Blake2s_256 : HashAlgorithm
|
||||
55. crypto.HashAlgorithm.Sha2_256 : HashAlgorithm
|
||||
56. crypto.HashAlgorithm.Sha2_512 : HashAlgorithm
|
||||
57. crypto.HashAlgorithm.Sha3_256 : HashAlgorithm
|
||||
58. crypto.HashAlgorithm.Sha3_512 : HashAlgorithm
|
||||
59. crypto.hashBytes : HashAlgorithm -> Bytes -> Bytes
|
||||
60. crypto.hmac : HashAlgorithm -> Bytes -> a -> Bytes
|
||||
61. crypto.hmacBytes : HashAlgorithm
|
||||
-> Bytes
|
||||
-> Bytes
|
||||
-> Bytes
|
||||
59. Debug.watch : Text -> a -> a
|
||||
60. unique type Doc
|
||||
61. Doc.Blob : Text -> Doc
|
||||
62. Doc.Evaluate : Term -> Doc
|
||||
63. Doc.Join : [Doc] -> Doc
|
||||
64. Doc.Link : Link -> Doc
|
||||
65. Doc.Signature : Term -> Doc
|
||||
66. Doc.Source : Link -> Doc
|
||||
67. structural type Either a b
|
||||
68. Either.Left : a -> Either a b
|
||||
69. Either.Right : b -> Either a b
|
||||
70. structural ability Exception
|
||||
71. Exception.raise : Failure ->{Exception} x
|
||||
72. builtin type Float
|
||||
73. Float.* : Float -> Float -> Float
|
||||
74. Float.+ : Float -> Float -> Float
|
||||
75. Float.- : Float -> Float -> Float
|
||||
76. Float./ : Float -> Float -> Float
|
||||
77. Float.abs : Float -> Float
|
||||
78. Float.acos : Float -> Float
|
||||
79. Float.acosh : Float -> Float
|
||||
80. Float.asin : Float -> Float
|
||||
81. Float.asinh : Float -> Float
|
||||
82. Float.atan : Float -> Float
|
||||
83. Float.atan2 : Float -> Float -> Float
|
||||
84. Float.atanh : Float -> Float
|
||||
85. Float.ceiling : Float -> Int
|
||||
86. Float.cos : Float -> Float
|
||||
87. Float.cosh : Float -> Float
|
||||
88. Float.eq : Float -> Float -> Boolean
|
||||
89. Float.exp : Float -> Float
|
||||
90. Float.floor : Float -> Int
|
||||
91. Float.fromRepresentation : Nat -> Float
|
||||
92. Float.fromText : Text -> Optional Float
|
||||
93. Float.gt : Float -> Float -> Boolean
|
||||
94. Float.gteq : Float -> Float -> Boolean
|
||||
95. Float.log : Float -> Float
|
||||
96. Float.logBase : Float -> Float -> Float
|
||||
97. Float.lt : Float -> Float -> Boolean
|
||||
98. Float.lteq : Float -> Float -> Boolean
|
||||
99. Float.max : Float -> Float -> Float
|
||||
100. Float.min : Float -> Float -> Float
|
||||
101. Float.pow : Float -> Float -> Float
|
||||
102. Float.round : Float -> Int
|
||||
103. Float.sin : Float -> Float
|
||||
104. Float.sinh : Float -> Float
|
||||
105. Float.sqrt : Float -> Float
|
||||
106. Float.tan : Float -> Float
|
||||
107. Float.tanh : Float -> Float
|
||||
108. Float.toRepresentation : Float -> Nat
|
||||
109. Float.toText : Float -> Text
|
||||
110. Float.truncate : Float -> Int
|
||||
111. builtin type Int
|
||||
112. Int.* : Int -> Int -> Int
|
||||
113. Int.+ : Int -> Int -> Int
|
||||
114. Int.- : Int -> Int -> Int
|
||||
115. Int./ : Int -> Int -> Int
|
||||
116. Int.and : Int -> Int -> Int
|
||||
117. Int.complement : Int -> Int
|
||||
118. Int.eq : Int -> Int -> Boolean
|
||||
119. Int.fromRepresentation : Nat -> Int
|
||||
120. Int.fromText : Text -> Optional Int
|
||||
121. Int.gt : Int -> Int -> Boolean
|
||||
122. Int.gteq : Int -> Int -> Boolean
|
||||
123. Int.increment : Int -> Int
|
||||
124. Int.isEven : Int -> Boolean
|
||||
125. Int.isOdd : Int -> Boolean
|
||||
126. Int.leadingZeros : Int -> Nat
|
||||
127. Int.lt : Int -> Int -> Boolean
|
||||
128. Int.lteq : Int -> Int -> Boolean
|
||||
129. Int.mod : Int -> Int -> Int
|
||||
130. Int.negate : Int -> Int
|
||||
131. Int.or : Int -> Int -> Int
|
||||
132. Int.popCount : Int -> Nat
|
||||
133. Int.pow : Int -> Nat -> Int
|
||||
134. Int.shiftLeft : Int -> Nat -> Int
|
||||
135. Int.shiftRight : Int -> Nat -> Int
|
||||
136. Int.signum : Int -> Int
|
||||
137. Int.toFloat : Int -> Float
|
||||
138. Int.toRepresentation : Int -> Nat
|
||||
139. Int.toText : Int -> Text
|
||||
140. Int.trailingZeros : Int -> Nat
|
||||
141. Int.truncate0 : Int -> Nat
|
||||
142. Int.xor : Int -> Int -> Int
|
||||
143. unique type io2.BufferMode
|
||||
144. io2.BufferMode.BlockBuffering : BufferMode
|
||||
145. io2.BufferMode.LineBuffering : BufferMode
|
||||
146. io2.BufferMode.NoBuffering : BufferMode
|
||||
147. io2.BufferMode.SizedBlockBuffering : Nat -> BufferMode
|
||||
148. unique type io2.Failure
|
||||
149. io2.Failure.Failure : Type -> Text -> Any -> Failure
|
||||
150. unique type io2.FileMode
|
||||
151. io2.FileMode.Append : FileMode
|
||||
152. io2.FileMode.Read : FileMode
|
||||
153. io2.FileMode.ReadWrite : FileMode
|
||||
154. io2.FileMode.Write : FileMode
|
||||
155. builtin type io2.Handle
|
||||
156. builtin type io2.IO
|
||||
157. io2.IO.clientSocket.impl : Text
|
||||
62. Debug.watch : Text -> a -> a
|
||||
63. unique type Doc
|
||||
64. Doc.Blob : Text -> Doc
|
||||
65. Doc.Evaluate : Term -> Doc
|
||||
66. Doc.Join : [Doc] -> Doc
|
||||
67. Doc.Link : Link -> Doc
|
||||
68. Doc.Signature : Term -> Doc
|
||||
69. Doc.Source : Link -> Doc
|
||||
70. structural type Either a b
|
||||
71. Either.Left : a -> Either a b
|
||||
72. Either.Right : b -> Either a b
|
||||
73. structural ability Exception
|
||||
74. Exception.raise : Failure ->{Exception} x
|
||||
75. builtin type Float
|
||||
76. Float.* : Float -> Float -> Float
|
||||
77. Float.+ : Float -> Float -> Float
|
||||
78. Float.- : Float -> Float -> Float
|
||||
79. Float./ : Float -> Float -> Float
|
||||
80. Float.abs : Float -> Float
|
||||
81. Float.acos : Float -> Float
|
||||
82. Float.acosh : Float -> Float
|
||||
83. Float.asin : Float -> Float
|
||||
84. Float.asinh : Float -> Float
|
||||
85. Float.atan : Float -> Float
|
||||
86. Float.atan2 : Float -> Float -> Float
|
||||
87. Float.atanh : Float -> Float
|
||||
88. Float.ceiling : Float -> Int
|
||||
89. Float.cos : Float -> Float
|
||||
90. Float.cosh : Float -> Float
|
||||
91. Float.eq : Float -> Float -> Boolean
|
||||
92. Float.exp : Float -> Float
|
||||
93. Float.floor : Float -> Int
|
||||
94. Float.fromRepresentation : Nat -> Float
|
||||
95. Float.fromText : Text -> Optional Float
|
||||
96. Float.gt : Float -> Float -> Boolean
|
||||
97. Float.gteq : Float -> Float -> Boolean
|
||||
98. Float.log : Float -> Float
|
||||
99. Float.logBase : Float -> Float -> Float
|
||||
100. Float.lt : Float -> Float -> Boolean
|
||||
101. Float.lteq : Float -> Float -> Boolean
|
||||
102. Float.max : Float -> Float -> Float
|
||||
103. Float.min : Float -> Float -> Float
|
||||
104. Float.pow : Float -> Float -> Float
|
||||
105. Float.round : Float -> Int
|
||||
106. Float.sin : Float -> Float
|
||||
107. Float.sinh : Float -> Float
|
||||
108. Float.sqrt : Float -> Float
|
||||
109. Float.tan : Float -> Float
|
||||
110. Float.tanh : Float -> Float
|
||||
111. Float.toRepresentation : Float -> Nat
|
||||
112. Float.toText : Float -> Text
|
||||
113. Float.truncate : Float -> Int
|
||||
114. builtin type Int
|
||||
115. Int.* : Int -> Int -> Int
|
||||
116. Int.+ : Int -> Int -> Int
|
||||
117. Int.- : Int -> Int -> Int
|
||||
118. Int./ : Int -> Int -> Int
|
||||
119. Int.and : Int -> Int -> Int
|
||||
120. Int.complement : Int -> Int
|
||||
121. Int.eq : Int -> Int -> Boolean
|
||||
122. Int.fromRepresentation : Nat -> Int
|
||||
123. Int.fromText : Text -> Optional Int
|
||||
124. Int.gt : Int -> Int -> Boolean
|
||||
125. Int.gteq : Int -> Int -> Boolean
|
||||
126. Int.increment : Int -> Int
|
||||
127. Int.isEven : Int -> Boolean
|
||||
128. Int.isOdd : Int -> Boolean
|
||||
129. Int.leadingZeros : Int -> Nat
|
||||
130. Int.lt : Int -> Int -> Boolean
|
||||
131. Int.lteq : Int -> Int -> Boolean
|
||||
132. Int.mod : Int -> Int -> Int
|
||||
133. Int.negate : Int -> Int
|
||||
134. Int.or : Int -> Int -> Int
|
||||
135. Int.popCount : Int -> Nat
|
||||
136. Int.pow : Int -> Nat -> Int
|
||||
137. Int.shiftLeft : Int -> Nat -> Int
|
||||
138. Int.shiftRight : Int -> Nat -> Int
|
||||
139. Int.signum : Int -> Int
|
||||
140. Int.toFloat : Int -> Float
|
||||
141. Int.toRepresentation : Int -> Nat
|
||||
142. Int.toText : Int -> Text
|
||||
143. Int.trailingZeros : Int -> Nat
|
||||
144. Int.truncate0 : Int -> Nat
|
||||
145. Int.xor : Int -> Int -> Int
|
||||
146. unique type io2.BufferMode
|
||||
147. io2.BufferMode.BlockBuffering : BufferMode
|
||||
148. io2.BufferMode.LineBuffering : BufferMode
|
||||
149. io2.BufferMode.NoBuffering : BufferMode
|
||||
150. io2.BufferMode.SizedBlockBuffering : Nat -> BufferMode
|
||||
151. unique type io2.Failure
|
||||
152. io2.Failure.Failure : Type -> Text -> Any -> Failure
|
||||
153. unique type io2.FileMode
|
||||
154. io2.FileMode.Append : FileMode
|
||||
155. io2.FileMode.Read : FileMode
|
||||
156. io2.FileMode.ReadWrite : FileMode
|
||||
157. io2.FileMode.Write : FileMode
|
||||
158. builtin type io2.Handle
|
||||
159. builtin type io2.IO
|
||||
160. io2.IO.clientSocket.impl : Text
|
||||
-> Text
|
||||
->{IO} Either Failure Socket
|
||||
158. io2.IO.closeFile.impl : Handle ->{IO} Either Failure ()
|
||||
159. io2.IO.closeSocket.impl : Socket ->{IO} Either Failure ()
|
||||
160. io2.IO.createDirectory.impl : Text
|
||||
161. io2.IO.closeFile.impl : Handle ->{IO} Either Failure ()
|
||||
162. io2.IO.closeSocket.impl : Socket ->{IO} Either Failure ()
|
||||
163. io2.IO.createDirectory.impl : Text
|
||||
->{IO} Either Failure ()
|
||||
161. io2.IO.createTempDirectory.impl : Text
|
||||
164. io2.IO.createTempDirectory.impl : Text
|
||||
->{IO} Either
|
||||
Failure Text
|
||||
162. io2.IO.delay.impl : Nat ->{IO} Either Failure ()
|
||||
163. io2.IO.directoryContents.impl : Text
|
||||
165. io2.IO.delay.impl : Nat ->{IO} Either Failure ()
|
||||
166. io2.IO.directoryContents.impl : Text
|
||||
->{IO} Either
|
||||
Failure [Text]
|
||||
164. io2.IO.fileExists.impl : Text
|
||||
167. io2.IO.fileExists.impl : Text
|
||||
->{IO} Either Failure Boolean
|
||||
165. io2.IO.forkComp : '{IO} a ->{IO} ThreadId
|
||||
166. io2.IO.getBuffering.impl : Handle
|
||||
168. io2.IO.forkComp : '{IO} a ->{IO} ThreadId
|
||||
169. io2.IO.getBuffering.impl : Handle
|
||||
->{IO} Either
|
||||
Failure BufferMode
|
||||
167. io2.IO.getBytes.impl : Handle
|
||||
170. io2.IO.getBytes.impl : Handle
|
||||
-> Nat
|
||||
->{IO} Either Failure Bytes
|
||||
168. io2.IO.getCurrentDirectory.impl : '{IO} Either
|
||||
171. io2.IO.getCurrentDirectory.impl : '{IO} Either
|
||||
Failure Text
|
||||
169. io2.IO.getEnv.impl : Text ->{IO} Either Failure Text
|
||||
170. io2.IO.getFileSize.impl : Text ->{IO} Either Failure Nat
|
||||
171. io2.IO.getFileTimestamp.impl : Text
|
||||
172. io2.IO.getEnv.impl : Text ->{IO} Either Failure Text
|
||||
173. io2.IO.getFileSize.impl : Text ->{IO} Either Failure Nat
|
||||
174. io2.IO.getFileTimestamp.impl : Text
|
||||
->{IO} Either Failure Nat
|
||||
172. io2.IO.getLine.impl : Handle ->{IO} Either Failure Text
|
||||
173. io2.IO.getTempDirectory.impl : '{IO} Either Failure Text
|
||||
174. io2.IO.handlePosition.impl : Handle
|
||||
175. io2.IO.getLine.impl : Handle ->{IO} Either Failure Text
|
||||
176. io2.IO.getTempDirectory.impl : '{IO} Either Failure Text
|
||||
177. io2.IO.handlePosition.impl : Handle
|
||||
->{IO} Either Failure Nat
|
||||
175. io2.IO.isDirectory.impl : Text
|
||||
178. io2.IO.isDirectory.impl : Text
|
||||
->{IO} Either Failure Boolean
|
||||
176. io2.IO.isFileEOF.impl : Handle
|
||||
179. io2.IO.isFileEOF.impl : Handle
|
||||
->{IO} Either Failure Boolean
|
||||
177. io2.IO.isFileOpen.impl : Handle
|
||||
180. io2.IO.isFileOpen.impl : Handle
|
||||
->{IO} Either Failure Boolean
|
||||
178. io2.IO.isSeekable.impl : Handle
|
||||
181. io2.IO.isSeekable.impl : Handle
|
||||
->{IO} Either Failure Boolean
|
||||
179. io2.IO.kill.impl : ThreadId ->{IO} Either Failure ()
|
||||
180. io2.IO.listen.impl : Socket ->{IO} Either Failure ()
|
||||
181. io2.IO.openFile.impl : Text
|
||||
182. io2.IO.kill.impl : ThreadId ->{IO} Either Failure ()
|
||||
183. io2.IO.listen.impl : Socket ->{IO} Either Failure ()
|
||||
184. io2.IO.openFile.impl : Text
|
||||
-> FileMode
|
||||
->{IO} Either Failure Handle
|
||||
182. io2.IO.putBytes.impl : Handle
|
||||
185. io2.IO.putBytes.impl : Handle
|
||||
-> Bytes
|
||||
->{IO} Either Failure ()
|
||||
183. io2.IO.ref : a ->{IO} Ref {IO} a
|
||||
184. io2.IO.removeDirectory.impl : Text
|
||||
186. io2.IO.ref : a ->{IO} Ref {IO} a
|
||||
187. io2.IO.removeDirectory.impl : Text
|
||||
->{IO} Either Failure ()
|
||||
185. io2.IO.removeFile.impl : Text ->{IO} Either Failure ()
|
||||
186. io2.IO.renameDirectory.impl : Text
|
||||
188. io2.IO.removeFile.impl : Text ->{IO} Either Failure ()
|
||||
189. io2.IO.renameDirectory.impl : Text
|
||||
-> Text
|
||||
->{IO} Either Failure ()
|
||||
187. io2.IO.renameFile.impl : Text
|
||||
190. io2.IO.renameFile.impl : Text
|
||||
-> Text
|
||||
->{IO} Either Failure ()
|
||||
188. io2.IO.seekHandle.impl : Handle
|
||||
191. io2.IO.seekHandle.impl : Handle
|
||||
-> SeekMode
|
||||
-> Int
|
||||
->{IO} Either Failure ()
|
||||
189. io2.IO.serverSocket.impl : Optional Text
|
||||
192. io2.IO.serverSocket.impl : Optional Text
|
||||
-> Text
|
||||
->{IO} Either Failure Socket
|
||||
190. io2.IO.setBuffering.impl : Handle
|
||||
193. io2.IO.setBuffering.impl : Handle
|
||||
-> BufferMode
|
||||
->{IO} Either Failure ()
|
||||
191. io2.IO.setCurrentDirectory.impl : Text
|
||||
194. io2.IO.setCurrentDirectory.impl : Text
|
||||
->{IO} Either
|
||||
Failure ()
|
||||
192. io2.IO.socketAccept.impl : Socket
|
||||
195. io2.IO.socketAccept.impl : Socket
|
||||
->{IO} Either Failure Socket
|
||||
193. io2.IO.socketPort.impl : Socket ->{IO} Either Failure Nat
|
||||
194. io2.IO.socketReceive.impl : Socket
|
||||
196. io2.IO.socketPort.impl : Socket ->{IO} Either Failure Nat
|
||||
197. io2.IO.socketReceive.impl : Socket
|
||||
-> Nat
|
||||
->{IO} Either Failure Bytes
|
||||
195. io2.IO.socketSend.impl : Socket
|
||||
198. io2.IO.socketSend.impl : Socket
|
||||
-> Bytes
|
||||
->{IO} Either Failure ()
|
||||
196. io2.IO.stdHandle : StdHandle -> Handle
|
||||
197. io2.IO.systemTime.impl : '{IO} Either Failure Nat
|
||||
198. unique type io2.IOError
|
||||
199. io2.IOError.AlreadyExists : IOError
|
||||
200. io2.IOError.EOF : IOError
|
||||
201. io2.IOError.IllegalOperation : IOError
|
||||
202. io2.IOError.NoSuchThing : IOError
|
||||
203. io2.IOError.PermissionDenied : IOError
|
||||
204. io2.IOError.ResourceBusy : IOError
|
||||
205. io2.IOError.ResourceExhausted : IOError
|
||||
206. io2.IOError.UserError : IOError
|
||||
207. unique type io2.IOFailure
|
||||
208. builtin type io2.MVar
|
||||
209. io2.MVar.isEmpty : MVar a ->{IO} Boolean
|
||||
210. io2.MVar.new : a ->{IO} MVar a
|
||||
211. io2.MVar.newEmpty : '{IO} MVar a
|
||||
212. io2.MVar.put.impl : MVar a -> a ->{IO} Either Failure ()
|
||||
213. io2.MVar.read.impl : MVar a ->{IO} Either Failure a
|
||||
214. io2.MVar.swap.impl : MVar a -> a ->{IO} Either Failure a
|
||||
215. io2.MVar.take.impl : MVar a ->{IO} Either Failure a
|
||||
216. io2.MVar.tryPut.impl : MVar a
|
||||
199. io2.IO.stdHandle : StdHandle -> Handle
|
||||
200. io2.IO.systemTime.impl : '{IO} Either Failure Nat
|
||||
201. unique type io2.IOError
|
||||
202. io2.IOError.AlreadyExists : IOError
|
||||
203. io2.IOError.EOF : IOError
|
||||
204. io2.IOError.IllegalOperation : IOError
|
||||
205. io2.IOError.NoSuchThing : IOError
|
||||
206. io2.IOError.PermissionDenied : IOError
|
||||
207. io2.IOError.ResourceBusy : IOError
|
||||
208. io2.IOError.ResourceExhausted : IOError
|
||||
209. io2.IOError.UserError : IOError
|
||||
210. unique type io2.IOFailure
|
||||
211. builtin type io2.MVar
|
||||
212. io2.MVar.isEmpty : MVar a ->{IO} Boolean
|
||||
213. io2.MVar.new : a ->{IO} MVar a
|
||||
214. io2.MVar.newEmpty : '{IO} MVar a
|
||||
215. io2.MVar.put.impl : MVar a -> a ->{IO} Either Failure ()
|
||||
216. io2.MVar.read.impl : MVar a ->{IO} Either Failure a
|
||||
217. io2.MVar.swap.impl : MVar a -> a ->{IO} Either Failure a
|
||||
218. io2.MVar.take.impl : MVar a ->{IO} Either Failure a
|
||||
219. io2.MVar.tryPut.impl : MVar a
|
||||
-> a
|
||||
->{IO} Either Failure Boolean
|
||||
217. io2.MVar.tryRead.impl : MVar a
|
||||
220. io2.MVar.tryRead.impl : MVar a
|
||||
->{IO} Either
|
||||
Failure (Optional a)
|
||||
218. io2.MVar.tryTake : MVar a ->{IO} Optional a
|
||||
219. unique type io2.SeekMode
|
||||
220. io2.SeekMode.AbsoluteSeek : SeekMode
|
||||
221. io2.SeekMode.RelativeSeek : SeekMode
|
||||
222. io2.SeekMode.SeekFromEnd : SeekMode
|
||||
223. builtin type io2.Socket
|
||||
224. unique type io2.StdHandle
|
||||
225. io2.StdHandle.StdErr : StdHandle
|
||||
226. io2.StdHandle.StdIn : StdHandle
|
||||
227. io2.StdHandle.StdOut : StdHandle
|
||||
228. builtin type io2.STM
|
||||
229. io2.STM.atomically : '{STM} a ->{IO} a
|
||||
230. io2.STM.retry : '{STM} a
|
||||
231. builtin type io2.ThreadId
|
||||
232. builtin type io2.Tls
|
||||
233. builtin type io2.Tls.Cipher
|
||||
234. builtin type io2.Tls.ClientConfig
|
||||
235. io2.Tls.ClientConfig.certificates.set : [SignedCert]
|
||||
221. io2.MVar.tryTake : MVar a ->{IO} Optional a
|
||||
222. unique type io2.SeekMode
|
||||
223. io2.SeekMode.AbsoluteSeek : SeekMode
|
||||
224. io2.SeekMode.RelativeSeek : SeekMode
|
||||
225. io2.SeekMode.SeekFromEnd : SeekMode
|
||||
226. builtin type io2.Socket
|
||||
227. unique type io2.StdHandle
|
||||
228. io2.StdHandle.StdErr : StdHandle
|
||||
229. io2.StdHandle.StdIn : StdHandle
|
||||
230. io2.StdHandle.StdOut : StdHandle
|
||||
231. builtin type io2.STM
|
||||
232. io2.STM.atomically : '{STM} a ->{IO} a
|
||||
233. io2.STM.retry : '{STM} a
|
||||
234. builtin type io2.ThreadId
|
||||
235. builtin type io2.Tls
|
||||
236. builtin type io2.Tls.Cipher
|
||||
237. builtin type io2.Tls.ClientConfig
|
||||
238. io2.Tls.ClientConfig.certificates.set : [SignedCert]
|
||||
-> ClientConfig
|
||||
-> ClientConfig
|
||||
236. io2.TLS.ClientConfig.ciphers.set : [Cipher]
|
||||
239. io2.TLS.ClientConfig.ciphers.set : [Cipher]
|
||||
-> ClientConfig
|
||||
-> ClientConfig
|
||||
237. io2.Tls.ClientConfig.default : Text
|
||||
240. io2.Tls.ClientConfig.default : Text
|
||||
-> Bytes
|
||||
-> ClientConfig
|
||||
238. io2.Tls.ClientConfig.versions.set : [Version]
|
||||
241. io2.Tls.ClientConfig.versions.set : [Version]
|
||||
-> ClientConfig
|
||||
-> ClientConfig
|
||||
239. io2.Tls.decodeCert.impl : Bytes
|
||||
242. io2.Tls.decodeCert.impl : Bytes
|
||||
-> Either Failure SignedCert
|
||||
240. io2.Tls.decodePrivateKey : Bytes -> [PrivateKey]
|
||||
241. io2.Tls.encodeCert : SignedCert -> Bytes
|
||||
242. io2.Tls.encodePrivateKey : PrivateKey -> Bytes
|
||||
243. io2.Tls.handshake.impl : Tls ->{IO} Either Failure ()
|
||||
244. io2.Tls.newClient.impl : ClientConfig
|
||||
243. io2.Tls.decodePrivateKey : Bytes -> [PrivateKey]
|
||||
244. io2.Tls.encodeCert : SignedCert -> Bytes
|
||||
245. io2.Tls.encodePrivateKey : PrivateKey -> Bytes
|
||||
246. io2.Tls.handshake.impl : Tls ->{IO} Either Failure ()
|
||||
247. io2.Tls.newClient.impl : ClientConfig
|
||||
-> Socket
|
||||
->{IO} Either Failure Tls
|
||||
245. io2.Tls.newServer.impl : ServerConfig
|
||||
248. io2.Tls.newServer.impl : ServerConfig
|
||||
-> Socket
|
||||
->{IO} Either Failure Tls
|
||||
246. builtin type io2.Tls.PrivateKey
|
||||
247. io2.Tls.receive.impl : Tls ->{IO} Either Failure Bytes
|
||||
248. io2.Tls.send.impl : Tls -> Bytes ->{IO} Either Failure ()
|
||||
249. builtin type io2.Tls.ServerConfig
|
||||
250. io2.Tls.ServerConfig.certificates.set : [SignedCert]
|
||||
249. builtin type io2.Tls.PrivateKey
|
||||
250. io2.Tls.receive.impl : Tls ->{IO} Either Failure Bytes
|
||||
251. io2.Tls.send.impl : Tls -> Bytes ->{IO} Either Failure ()
|
||||
252. builtin type io2.Tls.ServerConfig
|
||||
253. io2.Tls.ServerConfig.certificates.set : [SignedCert]
|
||||
-> ServerConfig
|
||||
-> ServerConfig
|
||||
251. io2.Tls.ServerConfig.ciphers.set : [Cipher]
|
||||
254. io2.Tls.ServerConfig.ciphers.set : [Cipher]
|
||||
-> ServerConfig
|
||||
-> ServerConfig
|
||||
252. io2.Tls.ServerConfig.default : [SignedCert]
|
||||
255. io2.Tls.ServerConfig.default : [SignedCert]
|
||||
-> PrivateKey
|
||||
-> ServerConfig
|
||||
253. io2.Tls.ServerConfig.versions.set : [Version]
|
||||
256. io2.Tls.ServerConfig.versions.set : [Version]
|
||||
-> ServerConfig
|
||||
-> ServerConfig
|
||||
254. builtin type io2.Tls.SignedCert
|
||||
255. io2.Tls.terminate.impl : Tls ->{IO} Either Failure ()
|
||||
256. builtin type io2.Tls.Version
|
||||
257. unique type io2.TlsFailure
|
||||
258. builtin type io2.TVar
|
||||
259. io2.TVar.new : a ->{STM} TVar a
|
||||
260. io2.TVar.newIO : a ->{IO} TVar a
|
||||
261. io2.TVar.read : TVar a ->{STM} a
|
||||
262. io2.TVar.readIO : TVar a ->{IO} a
|
||||
263. io2.TVar.swap : TVar a -> a ->{STM} a
|
||||
264. io2.TVar.write : TVar a -> a ->{STM} ()
|
||||
265. unique type IsPropagated
|
||||
266. IsPropagated.IsPropagated : IsPropagated
|
||||
267. unique type IsTest
|
||||
268. IsTest.IsTest : IsTest
|
||||
269. unique type Link
|
||||
270. builtin type Link.Term
|
||||
271. Link.Term : Term -> Link
|
||||
272. builtin type Link.Type
|
||||
273. Link.Type : Type -> Link
|
||||
274. builtin type List
|
||||
275. List.++ : [a] -> [a] -> [a]
|
||||
276. List.+: : a -> [a] -> [a]
|
||||
277. List.:+ : [a] -> a -> [a]
|
||||
278. List.at : Nat -> [a] -> Optional a
|
||||
279. List.cons : a -> [a] -> [a]
|
||||
280. List.drop : Nat -> [a] -> [a]
|
||||
281. List.empty : [a]
|
||||
282. List.size : [a] -> Nat
|
||||
283. List.snoc : [a] -> a -> [a]
|
||||
284. List.take : Nat -> [a] -> [a]
|
||||
285. metadata.isPropagated : IsPropagated
|
||||
286. metadata.isTest : IsTest
|
||||
287. builtin type Nat
|
||||
288. Nat.* : Nat -> Nat -> Nat
|
||||
289. Nat.+ : Nat -> Nat -> Nat
|
||||
290. Nat./ : Nat -> Nat -> Nat
|
||||
291. Nat.and : Nat -> Nat -> Nat
|
||||
292. Nat.complement : Nat -> Nat
|
||||
293. Nat.drop : Nat -> Nat -> Nat
|
||||
294. Nat.eq : Nat -> Nat -> Boolean
|
||||
295. Nat.fromText : Text -> Optional Nat
|
||||
296. Nat.gt : Nat -> Nat -> Boolean
|
||||
297. Nat.gteq : Nat -> Nat -> Boolean
|
||||
298. Nat.increment : Nat -> Nat
|
||||
299. Nat.isEven : Nat -> Boolean
|
||||
300. Nat.isOdd : Nat -> Boolean
|
||||
301. Nat.leadingZeros : Nat -> Nat
|
||||
302. Nat.lt : Nat -> Nat -> Boolean
|
||||
303. Nat.lteq : Nat -> Nat -> Boolean
|
||||
304. Nat.mod : Nat -> Nat -> Nat
|
||||
305. Nat.or : Nat -> Nat -> Nat
|
||||
306. Nat.popCount : Nat -> Nat
|
||||
307. Nat.pow : Nat -> Nat -> Nat
|
||||
308. Nat.shiftLeft : Nat -> Nat -> Nat
|
||||
309. Nat.shiftRight : Nat -> Nat -> Nat
|
||||
310. Nat.sub : Nat -> Nat -> Int
|
||||
311. Nat.toFloat : Nat -> Float
|
||||
312. Nat.toInt : Nat -> Int
|
||||
313. Nat.toText : Nat -> Text
|
||||
314. Nat.trailingZeros : Nat -> Nat
|
||||
315. Nat.xor : Nat -> Nat -> Nat
|
||||
316. structural type Optional a
|
||||
317. Optional.None : Optional a
|
||||
318. Optional.Some : a -> Optional a
|
||||
319. builtin type Ref
|
||||
320. Ref.read : Ref g a ->{g} a
|
||||
321. Ref.write : Ref g a -> a ->{g} ()
|
||||
322. builtin type Request
|
||||
323. builtin type Scope
|
||||
324. Scope.ref : a ->{Scope s} Ref {Scope s} a
|
||||
325. Scope.run : (∀ s. '{g, Scope s} r) ->{g} r
|
||||
326. structural type SeqView a b
|
||||
327. SeqView.VElem : a -> b -> SeqView a b
|
||||
328. SeqView.VEmpty : SeqView a b
|
||||
329. unique type Test.Result
|
||||
330. Test.Result.Fail : Text -> Result
|
||||
331. Test.Result.Ok : Text -> Result
|
||||
332. builtin type Text
|
||||
333. Text.!= : Text -> Text -> Boolean
|
||||
334. Text.++ : Text -> Text -> Text
|
||||
335. Text.drop : Nat -> Text -> Text
|
||||
336. Text.empty : Text
|
||||
337. Text.eq : Text -> Text -> Boolean
|
||||
338. Text.fromCharList : [Char] -> Text
|
||||
339. Text.fromUtf8.impl : Bytes -> Either Failure Text
|
||||
340. Text.gt : Text -> Text -> Boolean
|
||||
341. Text.gteq : Text -> Text -> Boolean
|
||||
342. Text.lt : Text -> Text -> Boolean
|
||||
343. Text.lteq : Text -> Text -> Boolean
|
||||
344. Text.repeat : Nat -> Text -> Text
|
||||
345. Text.size : Text -> Nat
|
||||
346. Text.take : Nat -> Text -> Text
|
||||
347. Text.toCharList : Text -> [Char]
|
||||
348. Text.toUtf8 : Text -> Bytes
|
||||
349. Text.uncons : Text -> Optional (Char, Text)
|
||||
350. Text.unsnoc : Text -> Optional (Text, Char)
|
||||
351. todo : a -> b
|
||||
352. structural type Tuple a b
|
||||
353. Tuple.Cons : a -> b -> Tuple a b
|
||||
354. structural type Unit
|
||||
355. Unit.Unit : ()
|
||||
356. Universal.< : a -> a -> Boolean
|
||||
357. Universal.<= : a -> a -> Boolean
|
||||
358. Universal.== : a -> a -> Boolean
|
||||
359. Universal.> : a -> a -> Boolean
|
||||
360. Universal.>= : a -> a -> Boolean
|
||||
361. Universal.compare : a -> a -> Int
|
||||
362. unsafe.coerceAbilities : (a ->{e1} b) -> a ->{e2} b
|
||||
363. builtin type Value
|
||||
364. Value.dependencies : Value -> [Term]
|
||||
365. Value.deserialize : Bytes -> Either Text Value
|
||||
366. Value.load : Value ->{IO} Either [Term] a
|
||||
367. Value.serialize : Value -> Bytes
|
||||
368. Value.value : a -> Value
|
||||
257. builtin type io2.Tls.SignedCert
|
||||
258. io2.Tls.terminate.impl : Tls ->{IO} Either Failure ()
|
||||
259. builtin type io2.Tls.Version
|
||||
260. unique type io2.TlsFailure
|
||||
261. builtin type io2.TVar
|
||||
262. io2.TVar.new : a ->{STM} TVar a
|
||||
263. io2.TVar.newIO : a ->{IO} TVar a
|
||||
264. io2.TVar.read : TVar a ->{STM} a
|
||||
265. io2.TVar.readIO : TVar a ->{IO} a
|
||||
266. io2.TVar.swap : TVar a -> a ->{STM} a
|
||||
267. io2.TVar.write : TVar a -> a ->{STM} ()
|
||||
268. unique type IsPropagated
|
||||
269. IsPropagated.IsPropagated : IsPropagated
|
||||
270. unique type IsTest
|
||||
271. IsTest.IsTest : IsTest
|
||||
272. unique type Link
|
||||
273. builtin type Link.Term
|
||||
274. Link.Term : Term -> Link
|
||||
275. Link.Term.toText : Term -> Text
|
||||
276. builtin type Link.Type
|
||||
277. Link.Type : Type -> Link
|
||||
278. builtin type List
|
||||
279. List.++ : [a] -> [a] -> [a]
|
||||
280. List.+: : a -> [a] -> [a]
|
||||
281. List.:+ : [a] -> a -> [a]
|
||||
282. List.at : Nat -> [a] -> Optional a
|
||||
283. List.cons : a -> [a] -> [a]
|
||||
284. List.drop : Nat -> [a] -> [a]
|
||||
285. List.empty : [a]
|
||||
286. List.size : [a] -> Nat
|
||||
287. List.snoc : [a] -> a -> [a]
|
||||
288. List.take : Nat -> [a] -> [a]
|
||||
289. metadata.isPropagated : IsPropagated
|
||||
290. metadata.isTest : IsTest
|
||||
291. builtin type Nat
|
||||
292. Nat.* : Nat -> Nat -> Nat
|
||||
293. Nat.+ : Nat -> Nat -> Nat
|
||||
294. Nat./ : Nat -> Nat -> Nat
|
||||
295. Nat.and : Nat -> Nat -> Nat
|
||||
296. Nat.complement : Nat -> Nat
|
||||
297. Nat.drop : Nat -> Nat -> Nat
|
||||
298. Nat.eq : Nat -> Nat -> Boolean
|
||||
299. Nat.fromText : Text -> Optional Nat
|
||||
300. Nat.gt : Nat -> Nat -> Boolean
|
||||
301. Nat.gteq : Nat -> Nat -> Boolean
|
||||
302. Nat.increment : Nat -> Nat
|
||||
303. Nat.isEven : Nat -> Boolean
|
||||
304. Nat.isOdd : Nat -> Boolean
|
||||
305. Nat.leadingZeros : Nat -> Nat
|
||||
306. Nat.lt : Nat -> Nat -> Boolean
|
||||
307. Nat.lteq : Nat -> Nat -> Boolean
|
||||
308. Nat.mod : Nat -> Nat -> Nat
|
||||
309. Nat.or : Nat -> Nat -> Nat
|
||||
310. Nat.popCount : Nat -> Nat
|
||||
311. Nat.pow : Nat -> Nat -> Nat
|
||||
312. Nat.shiftLeft : Nat -> Nat -> Nat
|
||||
313. Nat.shiftRight : Nat -> Nat -> Nat
|
||||
314. Nat.sub : Nat -> Nat -> Int
|
||||
315. Nat.toFloat : Nat -> Float
|
||||
316. Nat.toInt : Nat -> Int
|
||||
317. Nat.toText : Nat -> Text
|
||||
318. Nat.trailingZeros : Nat -> Nat
|
||||
319. Nat.xor : Nat -> Nat -> Nat
|
||||
320. structural type Optional a
|
||||
321. Optional.None : Optional a
|
||||
322. Optional.Some : a -> Optional a
|
||||
323. builtin type Ref
|
||||
324. Ref.read : Ref g a ->{g} a
|
||||
325. Ref.write : Ref g a -> a ->{g} ()
|
||||
326. builtin type Request
|
||||
327. builtin type Scope
|
||||
328. Scope.ref : a ->{Scope s} Ref {Scope s} a
|
||||
329. Scope.run : (∀ s. '{g, Scope s} r) ->{g} r
|
||||
330. structural type SeqView a b
|
||||
331. SeqView.VElem : a -> b -> SeqView a b
|
||||
332. SeqView.VEmpty : SeqView a b
|
||||
333. unique type Test.Result
|
||||
334. Test.Result.Fail : Text -> Result
|
||||
335. Test.Result.Ok : Text -> Result
|
||||
336. builtin type Text
|
||||
337. Text.!= : Text -> Text -> Boolean
|
||||
338. Text.++ : Text -> Text -> Text
|
||||
339. Text.drop : Nat -> Text -> Text
|
||||
340. Text.empty : Text
|
||||
341. Text.eq : Text -> Text -> Boolean
|
||||
342. Text.fromCharList : [Char] -> Text
|
||||
343. Text.fromUtf8.impl : Bytes -> Either Failure Text
|
||||
344. Text.gt : Text -> Text -> Boolean
|
||||
345. Text.gteq : Text -> Text -> Boolean
|
||||
346. Text.lt : Text -> Text -> Boolean
|
||||
347. Text.lteq : Text -> Text -> Boolean
|
||||
348. Text.repeat : Nat -> Text -> Text
|
||||
349. Text.size : Text -> Nat
|
||||
350. Text.take : Nat -> Text -> Text
|
||||
351. Text.toCharList : Text -> [Char]
|
||||
352. Text.toUtf8 : Text -> Bytes
|
||||
353. Text.uncons : Text -> Optional (Char, Text)
|
||||
354. Text.unsnoc : Text -> Optional (Text, Char)
|
||||
355. todo : a -> b
|
||||
356. structural type Tuple a b
|
||||
357. Tuple.Cons : a -> b -> Tuple a b
|
||||
358. structural type Unit
|
||||
359. Unit.Unit : ()
|
||||
360. Universal.< : a -> a -> Boolean
|
||||
361. Universal.<= : a -> a -> Boolean
|
||||
362. Universal.== : a -> a -> Boolean
|
||||
363. Universal.> : a -> a -> Boolean
|
||||
364. Universal.>= : a -> a -> Boolean
|
||||
365. Universal.compare : a -> a -> Int
|
||||
366. unsafe.coerceAbilities : (a ->{e1} b) -> a ->{e2} b
|
||||
367. builtin type Value
|
||||
368. Value.dependencies : Value -> [Term]
|
||||
369. Value.deserialize : Bytes -> Either Text Value
|
||||
370. Value.load : Value ->{IO} Either [Term] a
|
||||
371. Value.serialize : Value -> Bytes
|
||||
372. Value.value : a -> Value
|
||||
|
||||
|
||||
.builtin> alias.many 94-104 .mylib
|
||||
@ -464,17 +468,17 @@ Let's try it!
|
||||
|
||||
Added definitions:
|
||||
|
||||
1. Float.gteq : Float -> Float -> Boolean
|
||||
2. Float.log : Float -> Float
|
||||
3. Float.logBase : Float -> Float -> Float
|
||||
4. Float.lt : Float -> Float -> Boolean
|
||||
5. Float.lteq : Float -> Float -> Boolean
|
||||
6. Float.max : Float -> Float -> Float
|
||||
7. Float.min : Float -> Float -> Float
|
||||
8. Float.pow : Float -> Float -> Float
|
||||
9. Float.round : Float -> Int
|
||||
10. Float.sin : Float -> Float
|
||||
11. Float.sinh : Float -> Float
|
||||
1. Float.fromRepresentation : Nat -> Float
|
||||
2. Float.fromText : Text -> Optional Float
|
||||
3. Float.gt : Float -> Float -> Boolean
|
||||
4. Float.gteq : Float -> Float -> Boolean
|
||||
5. Float.log : Float -> Float
|
||||
6. Float.logBase : Float -> Float -> Float
|
||||
7. Float.lt : Float -> Float -> Boolean
|
||||
8. Float.lteq : Float -> Float -> Boolean
|
||||
9. Float.max : Float -> Float -> Float
|
||||
10. Float.min : Float -> Float -> Float
|
||||
11. Float.pow : Float -> Float -> Float
|
||||
|
||||
Tip: You can use `undo` or `reflog` to undo this change.
|
||||
|
||||
@ -534,17 +538,17 @@ I want to incorporate a few more from another namespace:
|
||||
|
||||
.mylib> find
|
||||
|
||||
1. Float.gteq : Float -> Float -> Boolean
|
||||
2. Float.log : Float -> Float
|
||||
3. Float.logBase : Float -> Float -> Float
|
||||
4. Float.lt : Float -> Float -> Boolean
|
||||
5. Float.lteq : Float -> Float -> Boolean
|
||||
6. Float.max : Float -> Float -> Float
|
||||
7. Float.min : Float -> Float -> Float
|
||||
8. Float.pow : Float -> Float -> Float
|
||||
9. Float.round : Float -> Int
|
||||
10. Float.sin : Float -> Float
|
||||
11. Float.sinh : Float -> Float
|
||||
1. Float.fromRepresentation : Nat -> Float
|
||||
2. Float.fromText : Text -> Optional Float
|
||||
3. Float.gt : Float -> Float -> Boolean
|
||||
4. Float.gteq : Float -> Float -> Boolean
|
||||
5. Float.log : Float -> Float
|
||||
6. Float.logBase : Float -> Float -> Float
|
||||
7. Float.lt : Float -> Float -> Boolean
|
||||
8. Float.lteq : Float -> Float -> Boolean
|
||||
9. Float.max : Float -> Float -> Float
|
||||
10. Float.min : Float -> Float -> Float
|
||||
11. Float.pow : Float -> Float -> Float
|
||||
12. List.adjacentPairs : [a] -> [(a, a)]
|
||||
13. List.all : (a ->{g} Boolean) -> [a] ->{g} Boolean
|
||||
14. List.any : (a ->{g} Boolean) -> [a] ->{g} Boolean
|
||||
|
25
unison-src/transcripts/any-extract.md
Normal file
25
unison-src/transcripts/any-extract.md
Normal file
@ -0,0 +1,25 @@
|
||||
# Unit tests for Any.unsafeExtract
|
||||
|
||||
```ucm:hide
|
||||
.> builtins.merge
|
||||
.> cd builtin
|
||||
.> load unison-src/transcripts-using-base/base.u
|
||||
.> add
|
||||
```
|
||||
|
||||
Any.unsafeExtract is a way to extract the value contained in an Any. This is unsafe because it allows the programmer to coerce a value into any type, which would cause undefined behaviour if used to coerce a value to the wrong type.
|
||||
|
||||
```unison
|
||||
|
||||
test> Any.unsafeExtract.works =
|
||||
use Nat !=
|
||||
checks [1 == Any.unsafeExtract (Any 1),
|
||||
not (1 == Any.unsafeExtract (Any 2)),
|
||||
(Some 1) == Any.unsafeExtract (Any (Some 1))
|
||||
]
|
||||
```
|
||||
|
||||
```ucm
|
||||
.> add
|
||||
```
|
||||
|
39
unison-src/transcripts/any-extract.output.md
Normal file
39
unison-src/transcripts/any-extract.output.md
Normal file
@ -0,0 +1,39 @@
|
||||
# Unit tests for Any.unsafeExtract
|
||||
|
||||
Any.unsafeExtract is a way to extract the value contained in an Any. This is unsafe because it allows the programmer to coerce a value into any type, which would cause undefined behaviour if used to coerce a value to the wrong type.
|
||||
|
||||
```unison
|
||||
test> Any.unsafeExtract.works =
|
||||
use Nat !=
|
||||
checks [1 == Any.unsafeExtract (Any 1),
|
||||
not (1 == Any.unsafeExtract (Any 2)),
|
||||
(Some 1) == Any.unsafeExtract (Any (Some 1))
|
||||
]
|
||||
```
|
||||
|
||||
```ucm
|
||||
|
||||
I found and typechecked these definitions in scratch.u. If you
|
||||
do an `add` or `update`, here's how your codebase would
|
||||
change:
|
||||
|
||||
⍟ These new definitions are ok to `add`:
|
||||
|
||||
Any.unsafeExtract.works : [Result]
|
||||
|
||||
Now evaluating any watch expressions (lines starting with
|
||||
`>`)... Ctrl+C cancels.
|
||||
|
||||
3 | checks [1 == Any.unsafeExtract (Any 1),
|
||||
|
||||
✅ Passed Passed
|
||||
|
||||
```
|
||||
```ucm
|
||||
.> add
|
||||
|
||||
⍟ I've added these definitions:
|
||||
|
||||
Any.unsafeExtract.works : [Result]
|
||||
|
||||
```
|
@ -2077,10 +2077,9 @@ rendered = Pretty.get (docFormatConsole doc.guide)
|
||||
(Term.Term
|
||||
(Any
|
||||
'(f x ->
|
||||
f
|
||||
x
|
||||
Nat.+ sqr
|
||||
1))))),
|
||||
f x
|
||||
Nat.+ sqr
|
||||
1))))),
|
||||
!Lit
|
||||
(Right
|
||||
(Plain "-")),
|
||||
|
@ -10,7 +10,7 @@ The `builtins.merge` command adds the known builtins to a `builtin` subnamespace
|
||||
.tmp> ls builtin
|
||||
|
||||
1. Any (builtin type)
|
||||
2. Any/ (1 definition)
|
||||
2. Any/ (2 definitions)
|
||||
3. Boolean (builtin type)
|
||||
4. Boolean/ (1 definition)
|
||||
5. Bytes (builtin type)
|
||||
@ -18,7 +18,7 @@ The `builtins.merge` command adds the known builtins to a `builtin` subnamespace
|
||||
7. Char (builtin type)
|
||||
8. Char/ (3 definitions)
|
||||
9. Code (builtin type)
|
||||
10. Code/ (6 definitions)
|
||||
10. Code/ (8 definitions)
|
||||
11. Debug/ (1 definition)
|
||||
12. Doc (type)
|
||||
13. Doc/ (6 definitions)
|
||||
@ -35,7 +35,7 @@ The `builtins.merge` command adds the known builtins to a `builtin` subnamespace
|
||||
24. IsTest (type)
|
||||
25. IsTest/ (1 definition)
|
||||
26. Link (type)
|
||||
27. Link/ (4 definitions)
|
||||
27. Link/ (5 definitions)
|
||||
28. List (builtin type)
|
||||
29. List/ (10 definitions)
|
||||
30. Nat (builtin type)
|
||||
|
@ -23,7 +23,7 @@ Technically, the definitions all exist, but they have no names. `builtins.merge`
|
||||
|
||||
.foo> ls
|
||||
|
||||
1. builtin/ (368 definitions)
|
||||
1. builtin/ (372 definitions)
|
||||
|
||||
```
|
||||
And for a limited time, you can get even more builtin goodies:
|
||||
@ -35,7 +35,7 @@ And for a limited time, you can get even more builtin goodies:
|
||||
|
||||
.foo> ls
|
||||
|
||||
1. builtin/ (536 definitions)
|
||||
1. builtin/ (540 definitions)
|
||||
|
||||
```
|
||||
More typically, you'd start out by pulling `base.
|
||||
|
66
unison-src/transcripts/fix-2258-if-as-list-element.md
Normal file
66
unison-src/transcripts/fix-2258-if-as-list-element.md
Normal file
@ -0,0 +1,66 @@
|
||||
Tests that `if` statements can appear as list and tuple elements.
|
||||
|
||||
```ucm:hide
|
||||
.> builtins.merge
|
||||
```
|
||||
|
||||
```unison:hide
|
||||
> [ if true then 1 else 0 ]
|
||||
|
||||
> [ if true then 1 else 0, 1]
|
||||
|
||||
> [1, if true then 1 else 0]
|
||||
|
||||
> (if true then 1 else 0, 0)
|
||||
|
||||
> (0, if true then 1 else 0)
|
||||
|
||||
> (1)
|
||||
|
||||
> (1,2)
|
||||
|
||||
> (1,2,3)
|
||||
|
||||
> [1,2,3]
|
||||
|
||||
> []
|
||||
|
||||
> [1]
|
||||
|
||||
> [1,2]
|
||||
|
||||
> [1,2,3]
|
||||
|
||||
> [
|
||||
1,
|
||||
2,
|
||||
3
|
||||
]
|
||||
|
||||
> [
|
||||
1,
|
||||
2,
|
||||
3,]
|
||||
|
||||
> (1,2,3,)
|
||||
|
||||
> (1,
|
||||
2,)
|
||||
|
||||
structural ability Zoot where zoot : ()
|
||||
|
||||
Zoot.handler : Request {Zoot} a -> a
|
||||
Zoot.handler = cases
|
||||
{ a } -> a
|
||||
{ zoot -> k } -> handle !k with Zoot.handler
|
||||
|
||||
fst = cases (x,_) -> x
|
||||
|
||||
> List.size
|
||||
[ if true then (x y -> y)
|
||||
else handle (x y -> x) with fst (Zoot.handler, 42),
|
||||
cases a, b -> a Nat.+ b, -- multi-arg cases lambda
|
||||
cases x, y -> x Nat.+ y
|
||||
]
|
||||
```
|
||||
|
62
unison-src/transcripts/fix-2258-if-as-list-element.output.md
Normal file
62
unison-src/transcripts/fix-2258-if-as-list-element.output.md
Normal file
@ -0,0 +1,62 @@
|
||||
Tests that `if` statements can appear as list and tuple elements.
|
||||
|
||||
```unison
|
||||
> [ if true then 1 else 0 ]
|
||||
|
||||
> [ if true then 1 else 0, 1]
|
||||
|
||||
> [1, if true then 1 else 0]
|
||||
|
||||
> (if true then 1 else 0, 0)
|
||||
|
||||
> (0, if true then 1 else 0)
|
||||
|
||||
> (1)
|
||||
|
||||
> (1,2)
|
||||
|
||||
> (1,2,3)
|
||||
|
||||
> [1,2,3]
|
||||
|
||||
> []
|
||||
|
||||
> [1]
|
||||
|
||||
> [1,2]
|
||||
|
||||
> [1,2,3]
|
||||
|
||||
> [
|
||||
1,
|
||||
2,
|
||||
3
|
||||
]
|
||||
|
||||
> [
|
||||
1,
|
||||
2,
|
||||
3,]
|
||||
|
||||
> (1,2,3,)
|
||||
|
||||
> (1,
|
||||
2,)
|
||||
|
||||
structural ability Zoot where zoot : ()
|
||||
|
||||
Zoot.handler : Request {Zoot} a -> a
|
||||
Zoot.handler = cases
|
||||
{ a } -> a
|
||||
{ zoot -> k } -> handle !k with Zoot.handler
|
||||
|
||||
fst = cases (x,_) -> x
|
||||
|
||||
> List.size
|
||||
[ if true then (x y -> y)
|
||||
else handle (x y -> x) with fst (Zoot.handler, 42),
|
||||
cases a, b -> a Nat.+ b, -- multi-arg cases lambda
|
||||
cases x, y -> x Nat.+ y
|
||||
]
|
||||
```
|
||||
|
@ -112,13 +112,13 @@ We can also delete the fork if we're done with it. (Don't worry, it's still in t
|
||||
Note: The most recent namespace hash is immediately below this
|
||||
message.
|
||||
|
||||
⊙ #nl3sdb3eid
|
||||
⊙ #8bi2fepmci
|
||||
|
||||
- Deletes:
|
||||
|
||||
feature1.y
|
||||
|
||||
⊙ #nt4hpgmam9
|
||||
⊙ #0toe0ni06d
|
||||
|
||||
+ Adds / updates:
|
||||
|
||||
@ -129,26 +129,26 @@ We can also delete the fork if we're done with it. (Don't worry, it's still in t
|
||||
Original name New name(s)
|
||||
feature1.y master.y
|
||||
|
||||
⊙ #hjtrj2kgl4
|
||||
⊙ #8hp71hs6bk
|
||||
|
||||
+ Adds / updates:
|
||||
|
||||
feature1.y
|
||||
|
||||
⊙ #04vktkvglu
|
||||
⊙ #lujhuhd7it
|
||||
|
||||
> Moves:
|
||||
|
||||
Original name New name
|
||||
x master.x
|
||||
|
||||
⊙ #0g638hmb59
|
||||
⊙ #hl2puv6t7v
|
||||
|
||||
+ Adds / updates:
|
||||
|
||||
x
|
||||
|
||||
□ #2f9h2uhlk9 (start of history)
|
||||
□ #rmafm3f1ih (start of history)
|
||||
|
||||
```
|
||||
To resurrect an old version of a namespace, you can learn its hash via the `history` command, then use `fork #namespacehash .newname`.
|
||||
|
70
unison-src/transcripts/records.md
Normal file
70
unison-src/transcripts/records.md
Normal file
@ -0,0 +1,70 @@
|
||||
Ensure that Records keep their syntax after being added to the codebase
|
||||
|
||||
```ucm:hide
|
||||
.> builtins.mergeio
|
||||
.> load unison-src/transcripts-using-base/base.u
|
||||
```
|
||||
|
||||
## Record with 1 field
|
||||
|
||||
```unison:hide
|
||||
unique type Record1 = { a : Text }
|
||||
```
|
||||
|
||||
```ucm:hide
|
||||
.> add
|
||||
```
|
||||
|
||||
```ucm
|
||||
.> view Record1
|
||||
```
|
||||
|
||||
## Record with 2 fields
|
||||
|
||||
```unison:hide
|
||||
unique type Record2 = { a : Text, b : Int }
|
||||
```
|
||||
|
||||
```ucm:hide
|
||||
.> add
|
||||
```
|
||||
|
||||
```ucm
|
||||
.> view Record2
|
||||
```
|
||||
|
||||
## Record with 3 fields
|
||||
|
||||
```unison:hide
|
||||
unique type Record3 = { a : Text, b : Int, c : Nat }
|
||||
```
|
||||
|
||||
```ucm:hide
|
||||
.> add
|
||||
```
|
||||
|
||||
```ucm
|
||||
.> view Record3
|
||||
```
|
||||
|
||||
## Record with many fields
|
||||
|
||||
```unison:hide
|
||||
unique type Record4 =
|
||||
{ a : Text
|
||||
, b : Int
|
||||
, c : Nat
|
||||
, d : Bytes
|
||||
, e : Text
|
||||
, f : Nat
|
||||
, g : [Nat]
|
||||
}
|
||||
```
|
||||
|
||||
```ucm:hide
|
||||
.> add
|
||||
```
|
||||
|
||||
```ucm
|
||||
.> view Record4
|
||||
```
|
65
unison-src/transcripts/records.output.md
Normal file
65
unison-src/transcripts/records.output.md
Normal file
@ -0,0 +1,65 @@
|
||||
Ensure that Records keep their syntax after being added to the codebase
|
||||
|
||||
## Record with 1 field
|
||||
|
||||
```unison
|
||||
unique type Record1 = { a : Text }
|
||||
```
|
||||
|
||||
```ucm
|
||||
.> view Record1
|
||||
|
||||
unique type Record1 = { a : Text }
|
||||
|
||||
```
|
||||
## Record with 2 fields
|
||||
|
||||
```unison
|
||||
unique type Record2 = { a : Text, b : Int }
|
||||
```
|
||||
|
||||
```ucm
|
||||
.> view Record2
|
||||
|
||||
unique type Record2 = { a : Text, b : Int }
|
||||
|
||||
```
|
||||
## Record with 3 fields
|
||||
|
||||
```unison
|
||||
unique type Record3 = { a : Text, b : Int, c : Nat }
|
||||
```
|
||||
|
||||
```ucm
|
||||
.> view Record3
|
||||
|
||||
unique type Record3 = { a : Text, b : Int, c : Nat }
|
||||
|
||||
```
|
||||
## Record with many fields
|
||||
|
||||
```unison
|
||||
unique type Record4 =
|
||||
{ a : Text
|
||||
, b : Int
|
||||
, c : Nat
|
||||
, d : Bytes
|
||||
, e : Text
|
||||
, f : Nat
|
||||
, g : [Nat]
|
||||
}
|
||||
```
|
||||
|
||||
```ucm
|
||||
.> view Record4
|
||||
|
||||
unique type Record4
|
||||
= { a : Text,
|
||||
b : Int,
|
||||
c : Nat,
|
||||
d : Bytes,
|
||||
e : Text,
|
||||
f : Nat,
|
||||
g : [Nat] }
|
||||
|
||||
```
|
@ -59,16 +59,16 @@ y = 2
|
||||
most recent, along with the command that got us there. Try:
|
||||
|
||||
`fork 2 .old`
|
||||
`fork #3n9h2vkhe3 .old` to make an old namespace
|
||||
`fork #12c7nag7oi .old` to make an old namespace
|
||||
accessible again,
|
||||
|
||||
`reset-root #3n9h2vkhe3` to reset the root namespace and
|
||||
`reset-root #12c7nag7oi` to reset the root namespace and
|
||||
its history to that of the
|
||||
specified namespace.
|
||||
|
||||
1. #vfl0sjr6kg : add
|
||||
2. #3n9h2vkhe3 : add
|
||||
3. #2f9h2uhlk9 : builtins.merge
|
||||
1. #sjer10g2l4 : add
|
||||
2. #12c7nag7oi : add
|
||||
3. #rmafm3f1ih : builtins.merge
|
||||
4. #sjg2v58vn2 : (initial reflogged namespace)
|
||||
|
||||
```
|
||||
|
@ -13,7 +13,7 @@ Let's look at some examples. We'll start with a namespace with just the builtins
|
||||
|
||||
|
||||
|
||||
□ #fhun4m3q9g (start of history)
|
||||
□ #7ogvf7kc1m (start of history)
|
||||
|
||||
.> fork builtin builtin2
|
||||
|
||||
@ -42,21 +42,21 @@ Now suppose we `fork` a copy of builtin, then rename `Nat.+` to `frobnicate`, th
|
||||
Note: The most recent namespace hash is immediately below this
|
||||
message.
|
||||
|
||||
⊙ #565pe56252
|
||||
⊙ #b4nitt6goc
|
||||
|
||||
> Moves:
|
||||
|
||||
Original name New name
|
||||
Nat.frobnicate Nat.+
|
||||
|
||||
⊙ #oavs87p39a
|
||||
⊙ #s92i00andp
|
||||
|
||||
> Moves:
|
||||
|
||||
Original name New name
|
||||
Nat.+ Nat.frobnicate
|
||||
|
||||
□ #fhun4m3q9g (start of history)
|
||||
□ #7ogvf7kc1m (start of history)
|
||||
|
||||
```
|
||||
If we merge that back into `builtin`, we get that same chain of history:
|
||||
@ -71,21 +71,21 @@ If we merge that back into `builtin`, we get that same chain of history:
|
||||
Note: The most recent namespace hash is immediately below this
|
||||
message.
|
||||
|
||||
⊙ #565pe56252
|
||||
⊙ #b4nitt6goc
|
||||
|
||||
> Moves:
|
||||
|
||||
Original name New name
|
||||
Nat.frobnicate Nat.+
|
||||
|
||||
⊙ #oavs87p39a
|
||||
⊙ #s92i00andp
|
||||
|
||||
> Moves:
|
||||
|
||||
Original name New name
|
||||
Nat.+ Nat.frobnicate
|
||||
|
||||
□ #fhun4m3q9g (start of history)
|
||||
□ #7ogvf7kc1m (start of history)
|
||||
|
||||
```
|
||||
Let's try again, but using a `merge.squash` (or just `squash`) instead. The history will be unchanged:
|
||||
@ -106,7 +106,7 @@ Let's try again, but using a `merge.squash` (or just `squash`) instead. The hist
|
||||
|
||||
|
||||
|
||||
□ #fhun4m3q9g (start of history)
|
||||
□ #7ogvf7kc1m (start of history)
|
||||
|
||||
```
|
||||
The churn that happened in `mybuiltin` namespace ended up back in the same spot, so the squash merge of that namespace with our original namespace had no effect.
|
||||
@ -485,13 +485,13 @@ This checks to see that squashing correctly preserves deletions:
|
||||
Note: The most recent namespace hash is immediately below this
|
||||
message.
|
||||
|
||||
⊙ #jqps95msh5
|
||||
⊙ #ct8sk813ij
|
||||
|
||||
- Deletes:
|
||||
|
||||
Nat.* Nat.+
|
||||
|
||||
□ #fhun4m3q9g (start of history)
|
||||
□ #7ogvf7kc1m (start of history)
|
||||
|
||||
```
|
||||
Notice that `Nat.+` and `Nat.*` are deleted by the squash, and we see them deleted in one atomic step in the history.
|
||||
|
Loading…
Reference in New Issue
Block a user