Skip to content

Commit

Permalink
Do requirements analysis for literal text argument to use (#2211)
Browse files Browse the repository at this point in the history
In the special case that we have something like `use "key"` we can statically know that it requires a `key` device.  For example, this means that now a program like
```
build { move; use "key"; move }
```
will automatically install a `key` device on the built robot.

Closes #1301.
  • Loading branch information
byorgey authored Nov 18, 2024
1 parent 27a08ea commit eb68fcf
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 4 deletions.
9 changes: 6 additions & 3 deletions src/swarm-lang/Swarm/Language/Requirements/Analysis.hs
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,12 @@ requirements tdCtx ctx =
add (singletonCap CLambda)
mapM_ typeRequirements mty
local @ReqCtx (Ctx.delete x) $ go t
-- An application simply requires the union of the capabilities
-- from the left- and right-hand sides. This assumes that the
-- argument will be used at least once by the function.
-- Special case for 'use' with a device literal.
TApp t1@(TConst Use) t2@(TText device) ->
add (singletonDev device) *> go t1 *> go t2
-- In general, an application simply requires the union of the
-- capabilities from the left- and right-hand sides. This assumes
-- that the argument will be used at least once by the function.
TApp t1 t2 -> go t1 *> go t2
-- Similarly, for a let, we assume that the let-bound expression
-- will be used at least once in the body. We delete the let-bound
Expand Down
10 changes: 9 additions & 1 deletion test/unit/TestRequirements.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import Swarm.Language.Capability
import Swarm.Language.Context qualified as Ctx
import Swarm.Language.Pipeline
import Swarm.Language.Requirements.Analysis (requirements)
import Swarm.Language.Requirements.Type (ReqCtx, Requirements, capReqs)
import Swarm.Language.Requirements.Type (ReqCtx, Requirements, capReqs, devReqs)
import Swarm.Language.Syntax.Constants (Const (Move))
import Swarm.Language.Syntax.Util (eraseS)
import Test.Tasty
Expand All @@ -39,6 +39,11 @@ testRequirements =
"def m = move end; def y = \\m. log (format m) end"
(maybe False ((CExecute Move `S.notMember`) . capReqs) . Ctx.lookup "y")
]
, testGroup
"use"
[ testCase "literal argument to use (#1301)" $
"use \"key\"" `requiresDev` "key"
]
]

checkReqCtx :: Text -> (ReqCtx -> Bool) -> Assertion
Expand All @@ -49,3 +54,6 @@ checkRequirements code expect = check code (expect . requirements mempty mempty

requiresCap :: Text -> Capability -> Assertion
requiresCap code cap = checkRequirements code ((cap `S.member`) . capReqs)

requiresDev :: Text -> Text -> Assertion
requiresDev code dev = checkRequirements code ((dev `S.member`) . devReqs)

0 comments on commit eb68fcf

Please sign in to comment.