swarm-0.1.0.0: src/Swarm/Language/Capability.hs
-- |
-- Module : Swarm.Language.Capability
-- Copyright : Brent Yorgey
-- Maintainer : byorgey@gmail.com
--
-- SPDX-License-Identifier: BSD-3-Clause
--
-- Capabilities needed to evaluate and execute programs. Language
-- constructs or commands require certain capabilities, and in turn
-- capabilities are provided by various devices. A robot must have an
-- appropriate device installed in order to make use of each language
-- construct or command.
module Swarm.Language.Capability (
Capability (..),
capabilityName,
constCaps,
) where
import Data.Aeson (FromJSONKey, ToJSONKey)
import Data.Char (toLower)
import Data.Data (Data)
import Data.Hashable (Hashable)
import Data.Text (Text)
import Data.Text qualified as T
import Data.Yaml
import GHC.Generics (Generic)
import Swarm.Language.Syntax
import Text.Read (readMaybe)
import Witch (from)
import Prelude hiding (lookup)
-- | Various capabilities which robots can have.
data Capability
= -- | Be powered, i.e. execute anything at all
CPower
| -- | Execute the 'Move' command
CMove
| -- | Execute the 'Move' command for a heavy robot
CMoveheavy
| -- | Execute the 'Turn' command
--
-- NOTE: using cardinal directions is separate 'COrient' capability
CTurn
| -- | Execute the 'Selfdestruct' command
CSelfdestruct
| -- | Execute the 'Grab' command
CGrab
| -- | Execute the 'Harvest' command
CHarvest
| -- | Execute the 'Place' command
CPlace
| -- | Execute the 'Give' command
CGive
| -- | Execute the 'Install' command
CInstall
| -- | Execute the 'Make' command
CMake
| -- | Execute the 'Count' command
CCount
| -- | Execute the 'Build' command
CBuild
| -- | Execute the 'Salvage' command
CSalvage
| -- | Execute the 'Drill' command
CDrill
| -- | Execute the 'Whereami' command
CSenseloc
| -- | Execute the 'Blocked' command
CSensefront
| -- | Execute the 'Ishere' command
CSensehere
| -- | Execute the 'Scan' command
CScan
| -- | Execute the 'Random' command
CRandom
| -- | Execute the 'Appear' command
CAppear
| -- | Execute the 'Create' command
CCreate
| -- | Execute the 'Listen' command and passively log messages if also has 'CLog'
CListen
| -- | Execute the 'Log' command
CLog
| -- | Manipulate text values
CText
| -- | Don't drown in liquid
CFloat
| -- | Evaluate conditional expressions
CCond
| -- | Negate boolean value
CNegation
| -- | Evaluate comparison operations
CCompare
| -- | Use cardinal direction constants.
COrient
| -- | Evaluate arithmetic operations
CArith
| -- | Store and look up definitions in an environment
CEnv
| -- | Interpret lambda abstractions
CLambda
| -- | Enable recursive definitions
CRecursion
| -- | Execute the 'Reprogram' command
CReprogram
| -- | Capability to introspect and see its own name
CWhoami
| -- | Capability to set its own name
CSetname
| -- | Capability to move unrestricted to any place
CTeleport
| -- | Capability to run commands atomically
CAtomic
| -- | Capability to execute swap (grab and place atomically at the same time).
CSwap
| -- | Capabiltiy to do time-related things, like `wait` and get the
-- current time.
CTime
| -- | Capability to execute `try`.
CTry
| -- | Capability for working with sum types.
CSum
| -- | Capability for working with product types.
CProd
| -- | God-like capabilities. For e.g. commands intended only for
-- checking challenge mode win conditions, and not for use by
-- players.
CGod
deriving (Eq, Ord, Show, Read, Enum, Bounded, Generic, Hashable, Data, FromJSONKey, ToJSONKey)
capabilityName :: Capability -> Text
capabilityName = from @String . map toLower . drop 1 . show
instance ToJSON Capability where
toJSON = String . capabilityName
instance FromJSON Capability where
parseJSON = withText "Capability" tryRead
where
tryRead :: Text -> Parser Capability
tryRead t = case readMaybe . from . T.cons 'C' . T.toTitle $ t of
Just c -> return c
Nothing -> fail $ "Unknown capability " ++ from t
-- | Capabilities needed to evaluate or execute a constant.
constCaps :: Const -> Maybe Capability
constCaps = \case
-- ----------------------------------------------------------------
-- Some built-in constants that don't require any special capability.
Noop -> Nothing
AppF -> Nothing
Force -> Nothing
Return -> Nothing
Parent -> Nothing
Base -> Nothing
Setname -> Nothing
Undefined -> Nothing
Fail -> Nothing
Has -> Nothing
Installed -> Nothing
-- speaking is natural to robots (unlike listening)
Say -> Nothing
-- TODO: #495
-- the require command will be inlined once the Issue is fixed
-- so the capabilities of the run commands will be checked instead
Run -> Nothing
-- ----------------------------------------------------------------
-- Some straightforward ones.
Listen -> Just CListen
Log -> Just CLog
Selfdestruct -> Just CSelfdestruct
Move -> Just CMove
Turn -> Just CTurn
Grab -> Just CGrab
Harvest -> Just CHarvest
Place -> Just CPlace
Give -> Just CGive
Install -> Just CInstall
Make -> Just CMake
Count -> Just CCount
If -> Just CCond
Blocked -> Just CSensefront
Scan -> Just CScan
Ishere -> Just CSensehere
Upload -> Just CScan
Build -> Just CBuild
Salvage -> Just CSalvage
Reprogram -> Just CReprogram
Drill -> Just CDrill
Neg -> Just CArith
Add -> Just CArith
Sub -> Just CArith
Mul -> Just CArith
Div -> Just CArith
Exp -> Just CArith
Whoami -> Just CWhoami
Self -> Just CWhoami
Swap -> Just CSwap
Atomic -> Just CAtomic
Time -> Just CTime
Wait -> Just CTime
-- ----------------------------------------------------------------
-- Text operations
Format -> Just CText
Concat -> Just CText
Split -> Just CText
Chars -> Just CText
-- ----------------------------------------------------------------
-- Some God-like abilities.
As -> Just CGod
RobotNamed -> Just CGod
RobotNumbered -> Just CGod
Create -> Just CGod
-- ----------------------------------------------------------------
-- arithmetic
Eq -> Just CCompare
Neq -> Just CCompare
Lt -> Just CCompare
Gt -> Just CCompare
Leq -> Just CCompare
Geq -> Just CCompare
-- ----------------------------------------------------------------
-- boolean logic
And -> Just CCond
Or -> Just CCond
Not -> Just CNegation
-- ----------------------------------------------------------------
-- exceptions
Try -> Just CTry
-- ----------------------------------------------------------------
-- type-level arithmetic
Inl -> Just CSum
Inr -> Just CSum
Case -> Just CSum
Fst -> Just CProd
Snd -> Just CProd
-- XXX pair syntax should require CProd too
-- ----------------------------------------------------------------
-- Some additional straightforward ones, which however currently
-- cannot be used in classic mode since there is no craftable item
-- which conveys their capability. TODO: #26
Teleport -> Just CTeleport -- Some space-time machine like Tardis?
Appear -> Just CAppear -- paint?
Whereami -> Just CSenseloc -- GPS?
Random -> Just CRandom -- randomness device (with bitcoins)?
-- ----------------------------------------------------------------
-- Some more constants which *ought* to have their own capability but
-- currently don't. TODO: #26
View -> Nothing -- XXX this should also require something.
Knows -> Nothing