Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Parse markdown descriptions #1106

Merged
merged 26 commits into from
Aug 5, 2023
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 8 additions & 8 deletions data/entities.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@
description:
- Employs hot lead typesetting to arrange glyphs into a mold for printing.
- |
An equipped `linotype` device enables the `format` command:
An equipped `linotype`{=entity} device enables the `format` command:
byorgey marked this conversation as resolved.
Show resolved Hide resolved
- |
`format : a -> text` can turn any value into a suitable text
representation.
Expand Down Expand Up @@ -385,7 +385,7 @@
description:
- A simple machine for the textually-inclined; plain but effective.
- |
An equipped `wedge` enables the `split` command:
An equipped `wedge`{=entity} enables the `split` command:
- |
`split : int -> text -> text * text` splits a `text` value into
two pieces, one before the given index and one after.
Expand All @@ -401,7 +401,7 @@
information, made of twisted cotton fibers. Multiple strings can
also be woven into larger configurations such as cloth or nets.
- |
An equipped `string` device enables several commands for working with
An equipped `string`{=entity} device enables several commands for working with
`text` values:
- |
`format : a -> text` can turn any value into a suitable text
Expand Down Expand Up @@ -955,13 +955,13 @@
description:
- |
A dictionary allows a robot to remember definitions and reuse them
later. You can access this ability with either a `def` command,
later. You can access this ability with either a `def`{=snippet} command,
which creates a name for an expression or command that is
available from then on, or with a `let` expression, which names an
available from then on, or with a `let`{=snippet} expression, which names an
expression or command locally within another expression.
- ' def m2 : cmd unit = move; move end'
- ' let x : int = 3 in x^2 + 2*x + 1'
xsebek marked this conversation as resolved.
Show resolved Hide resolved
- The type annotations in `def` and `let` are optional.
- The type annotations in `def`{=snippet} are optional.

properties: [portable]
capabilities: [env]
Expand Down Expand Up @@ -1072,7 +1072,7 @@
char: 'l'
description:
- "Allows a robot to generate and store messages for later viewing,
using the `log` command, which takes a string. Log messages are
using the `log`{=entity} command, which takes a string. Log messages are
xsebek marked this conversation as resolved.
Show resolved Hide resolved
also automatically generated by uncaught exceptions."
properties: [portable]
capabilities: [log]
Expand Down Expand Up @@ -1363,7 +1363,7 @@
installs a custom handler function that can be activated to
respond to keyboard inputs typed at the REPL.
- |
`key : text -> key` constructs values of type `key`, for
`key : text -> key` constructs values of type `key`{=entity}, for
xsebek marked this conversation as resolved.
Show resolved Hide resolved
example `key "Down"` or `key "C-S-x"`.
properties: [portable]
capabilities: [handleinput]
Expand Down
2 changes: 1 addition & 1 deletion data/scenarios/Challenges/Mazes/easy_spiral_maze.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ objectives:
- You find yourself in the middle of a large maze.
- It's straightforward to get out, but the path is long and dull.
- You need to send a robot to the goal square, labelled with an exclamation mark;
you win by `grab`bing the `goal`.
you win by `grab`bing the `goal`{=entity}.
- Beware! The winding corridors are wider then they look!
condition: |
j <- robotNamed "judge";
Expand Down
2 changes: 1 addition & 1 deletion data/scenarios/Challenges/Mazes/invisible_maze.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ objectives:
- There is a maze, but it can't be seen, only sensed... can you
program a robot to navigate it successfully? You need to get a robot
to the goal square, labelled with an exclamation mark; you win by `grab`bing
the `goal`.
the `goal`{=entity}.
- In this challenge, it is guaranteed that the maze is a tree, that is,
there are no loops within the maze.
condition: |
Expand Down
2 changes: 1 addition & 1 deletion data/scenarios/Challenges/Mazes/loopy_maze.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ objectives:
- There is a maze, but it can't be seen, only sensed... can you
program a robot to navigate it successfully? You need to get a robot
to the goal square, labelled with an exclamation mark; you win by `grab`bing
the `goal`.
the `goal`{=entity}.
- In this challenge, you are NOT guaranteed that the maze is a tree, that is,
the maze may contain loops.
condition: |
Expand Down
2 changes: 1 addition & 1 deletion data/scenarios/Challenges/Sliding Puzzles/3x3.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ objectives:
To slide a tile into the empty space, position yourself
behind it and `push`.
- |
Or, if you prefer, `drill` a tile to cause it to slide
Or, if you prefer, `drill`{=entity} a tile to cause it to slide
xsebek marked this conversation as resolved.
Show resolved Hide resolved
into the adjacent empty space. However, you must not drill a tile that
has nowhere to slide. Also, drilling consumes "ink", which will be replenished
after the sliding operation is complete, so avoid drilling too fast in
Expand Down
2 changes: 1 addition & 1 deletion data/scenarios/Challenges/arbitrage.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ objectives:
- |
Each shop offers different wares for trade.
Recipes dictate which items may be exchanged
at any given shop. Use the `drill` on a shop to perform
at any given shop. Use the `drill`{=entity} on a shop to perform
an exchange.
- |
As an itinerant merchant, you may exploit market asymmetry
Expand Down
2 changes: 1 addition & 1 deletion data/scenarios/Challenges/blender.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ objectives:
`grab` the Amulet of Yoneda from the northwest sanctum while
timing your passage carefully to avoid Side Effects (X) on patrol.
- |
To unlock a red door, `drill` it with the "door key" equipped.
To unlock a red door, `drill`{=entity} it with the "door key" equipped.
xsebek marked this conversation as resolved.
Show resolved Hide resolved
condition: |
as base {has "Amulet of Yoneda"}
prerequisite:
Expand Down
2 changes: 1 addition & 1 deletion data/scenarios/Challenges/bucket-brigade.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ objectives:
- Deliver a "coal lump" to the base.
- |
To excavate coal from the "lignite mine" (M), a robot needs to
`drill` while in posession of a "bucketwheel excavator".
`drill`{=entity} while in posession of a "bucketwheel excavator".
- |
To assemble the excavator, you'll need to repurpose
some "treads".
Expand Down
2 changes: 1 addition & 1 deletion data/scenarios/Challenges/gopher.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ objectives:
He will burrow (o) underground awhile, then pop up
anywhere within the rectangular grassy region
to gloat atop his "mound" of dirt for a short time.
`drill` the "mound" while he sits to drive him
`drill`{=entity} the "mound" while he sits to drive him
away. Eventually you should wear down his resolve!
condition: |
try {
Expand Down
2 changes: 1 addition & 1 deletion data/scenarios/Challenges/lights-out.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ objectives:
- teaser: Extinguish lights
goal:
- |
`drill` a light to toggle it and its four direct neighbors
`drill`{=entity} a light to toggle it and its four direct neighbors
between "off" and "on".
- |
The puzzle is won when all lights have been extinguished.
Expand Down
6 changes: 3 additions & 3 deletions data/scenarios/Challenges/word-search.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ seed: 2
creative: false
objectives:
- goal:
- Use the `drill` command (e.g. "drill down" when on top of the
- Use the `drill`{=entity} command (e.g. "drill down" when on top of the
intended letter) to mark the sequence of letters that
spells COW within the designated playfield.
- |
Expand Down Expand Up @@ -117,10 +117,10 @@ objectives:
/**
It's possible we could be one cell away from
a marked cell after finishing, either due
to using a directional `drill` command instead of
to using a directional `drill`{=entity} command instead of
`drill down`, or due to an apparent bug which
does not evaluate the goal condition between the
`drill` and a `move` command.
`drill`{=entity} and a `move` command.
*/
def moveToMarkedCell = \n.
if (n > 0) {
Expand Down
8 changes: 6 additions & 2 deletions data/scenarios/Tutorials/backstory.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@ objectives:
up again where you left off.
- |
When you're ready for your first challenge, we will try the `say` command.
Close this dialog with Esc or Ctrl-G, and type at the prompt:
Close this dialog with **Esc** or **Ctrl+G**, and type at the prompt:
- |
```
say "Ready!"
```
condition: |
try {
l <- robotNamed "listener";
Expand All @@ -48,9 +50,11 @@ entities:
- |
When you're ready for your first tutorial challenge, type at the prompt:
- |
```
say "Ready!"
```
- |
To open the full goal text again, you can hit Ctrl-G.
To open the full goal text again, you can hit **Ctrl+G**.
properties: [known, portable]
robots:
- name: base
Expand Down
14 changes: 8 additions & 6 deletions data/scenarios/Tutorials/bind2.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ objectives:
Build a robot to retrieve and restore the mystery artifact to its proper place!
- |
Note: If you find yourself stuck, you can select "Start over" from
the "Quit" (CTRL+q) dialog.
the "Quit" (**Ctrl+Q**) dialog.
condition: |
try {
p <- robotnamed "floorspot";
Expand All @@ -29,23 +29,25 @@ objectives:
- |
Every command returns a value. However, some simple commands, like
`move`, do not have any meaningful
value to return. Swarm has a special type, `unit`, with only one value,
value to return. Swarm has a special type, `unit`{=type}, with only one value,
called `()`. Since there is only one possible value of type
`unit`, returning it does not convey any information.
Thus, the type of `move` is `cmd unit`.
`unit`{=type}, returning it does not convey any information.
Thus, the type of `move` is `cmd unit`{=type}.
- |
Other commands do return a nontrivial value after executing.
For example, `grab` has type `cmd text`, and returns the name of the
For example, `grab` has type `cmd text`{=type}, and returns the name of the
grabbed entity as a text value.
- |
To use the result of a command later, you need "bind notation", which
consists of a variable name and a leftwards-pointing arrow
before the command. For example:
- |
```
move; t <- grab; place t
```
- |
In the above example, the result returned by `grab` is assigned
to the variable name `t`, which can then be used later.
to the variable name `t`{=snippet}, which can then be used later.
This is useful, for example, if you do not care what you
grabbed and just want to move it to another cell, or if you
are not sure of the name of the thing being grabbed.
Expand Down
6 changes: 3 additions & 3 deletions data/scenarios/Tutorials/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ objectives:
build robots to do the work for you.
You will start in a base ('Ω') that does not move (at least not yet).
- Let's start by building a gardener robot to perform a simple task.
- You can `build` a robot with `build {COMMANDS}`,
where in place of `COMMANDS` you write the sequence
- You can `build` a robot with `build {COMMANDS}`{=snippet},
where in place of `COMMANDS`{=snippet} you write the sequence
of commands for the robot to execute (separated by semicolons).
- |
Build a robot to harvest the "flower" and place it next
Build a robot to harvest the `"flower"` and place it next
to the water.
- |
TIP: Newly built robots start out facing the same
Expand Down
40 changes: 22 additions & 18 deletions data/scenarios/Tutorials/conditionals.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ description: |
objectives:
- goal:
- |
The 4x4 gray square contains 4 `very small rock`s --- so
The 4x4 gray square contains 4 `very small rock`{=entity}s --- so
small they cannot be seen! Your goal is to collect all of
them and bring them back to your base; you win when you have
all 4. There is one rock in each row and column, but
otherwise you can't be sure where they are. Your best bet is
to sweep over the entire 4x4 square and pick up a `very small
rock` any time you detect one.
to sweep over the entire 4x4 square and pick up a `very small rock`{=entity}
any time you detect one.
- |
The `ishere` command, with type `text -> cmd bool`, can be used
for detecting the presence of a specific item such as a `very small rock`.
What we need is a way to take the `bool` output from `ishere`
The `ishere` command, with type `text -> cmd bool`{=type}, can be used
for detecting the presence of a specific item such as a `very small rock`{=entity}.
What we need is a way to take the `bool`{=type} output from `ishere`
and use it to decide whether to `grab` a rock or not.
(Trying to execute `grab` in a cell without anything to grab will
throw an exception, causing the robot to crash.)
Expand All @@ -24,29 +24,33 @@ objectives:
conditional expressions. However, `if` is not special syntax;
it is simply a built-in function of type
- |
if : bool -> {a} -> {a} -> a.
```
if : bool -> {a} -> {a} -> a
```
- |
It takes a boolean expression and then returns either the first or second subsequent
argument, depending on whether the boolean expression is true or false, respectively.
- |
The type variable `a` can stand for any type; `{a}`
indicates a *delayed* expression of type `a`. Normally,
The type variable `a`{=type} can stand for any type; `{a}`{=type}
indicates a *delayed* expression of type `a`{=type}. Normally,
function arguments are evaluated strictly before the function
is called. Delayed expressions, on the other hand, are not
evaluated until needed. In this case, we want to make sure
that only the correct branch is evaluated. To write a value
of type, say, `{int}`, we just surround a value of type `int`
in curly braces, like `{3}`. This is why arguments to `build`
must also be in curly braces: the type of `build` is `{cmd a}
-> cmd robot`.
of type, say, `{int}`{=type}, we just surround a value of type `int`{=type}
in curly braces, like `{3}`{=type}. This is why arguments to `build`
xsebek marked this conversation as resolved.
Show resolved Hide resolved
must also be in curly braces: the type of `build`
is `{cmd a} -> cmd robot`{=type}.
- |
TIP: Note that `if` requires a `bool`, not a `cmd bool`! So you cannot directly say
`if (ishere "very small rock") {...} {...}`. Instead you can write `b <- ishere "very small rock"; if b {...} {...}`. You might enjoy writing your own function of
type `cmd bool -> {cmd a} -> {cmd a} -> cmd a` to encapsulate this pattern.
TIP: Note that `if` requires a `bool`{=type}, not a `cmd bool`{=type}! So you cannot directly say
`if (ishere "very small rock") {...} {...}`{=snippet}.
Instead you can write `b <- ishere "very small rock"; if b {...} {...}`{=snippet}.
You might enjoy writing your own function of
type `cmd bool -> {cmd a} -> {cmd a} -> cmd a`{=type} to encapsulate this pattern.
- |
TIP: the two branches of an `if` must have the same type. In particular,
`if ... {grab} {}` is not
allowed, because `{grab}` has type `{cmd text}` whereas `{}` has type `{cmd unit}`.
`if ... {grab} {}`{=snippet} is not
allowed, because `{grab}` has type `{cmd text}`{=type} whereas `{}` has type `{cmd unit}`{=type}.
In this case `{grab; return ()}` has the right type.
condition: |
try {
Expand Down
6 changes: 3 additions & 3 deletions data/scenarios/Tutorials/craft.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ description: |
objectives:
- goal:
- Robots can use the `make` command to make things, as long as
they have a `workbench` and the proper ingredients. For
they have a `workbench`{=entity} and the proper ingredients. For
example, `make "circuit"` will make a circuit.
- Your base has a few trees in its inventory. Select them to see the
available recipes.
- Your goal is to make a "branch predictor", so you will have to make
some "branch"es first.
- Your goal is to make a `branch predictor`{=entity}, so you will have to make
some `"branch"`es first.
xsebek marked this conversation as resolved.
Show resolved Hide resolved
- |
Note: when used after opening quotes in the REPL, the Tab key can cycle through
possible completions of a name. E.g., type:
Expand Down
8 changes: 5 additions & 3 deletions data/scenarios/Tutorials/crash.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,18 @@ objectives:
- |
In this challenge, you should start by
sending a robot to walk four steps straight east into the mountain,
crashing deliberately. However, you must make sure it has a `logger`,
crashing deliberately. However, you must make sure it has a `logger`{=entity},
so we can see what command failed. The simplest way to ensure
that is to have it execute the `log` command; `build` will
ensure it has the devices it needs to execute its commands.
For example:
- |
```
build {log "Hi!"; turn east; move; move; move; log "3"; move; log "OK"}
```
- |
`wait` for the robot to crash, then execute `view it0` (or whichever
`itN` variable corresponds to the result of the `build`
`wait` for the robot to crash, then execute `view it0`{=snippet} (or whichever
`itN`{=snippet} variable corresponds to the result of the `build`
command) to see how far it got. Further instructions should
appear in the crashed robot's log and `give` you an opportunity to `salvage`
the situation...
Expand Down
10 changes: 6 additions & 4 deletions data/scenarios/Tutorials/def.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ objectives:
has a flower in its inventory.
- |
However, it would be extremely tedious to simply type out all the individual
`move` and `turn` commands required. Your base has a `dictionary` device
`move` and `turn` commands required. Your base has a `dictionary`{=entity} device
that can be used to define new commands. For example:
- |
```
def m4 : cmd unit = move; move; move; move end
- defines a new command `m4`, with type `cmd unit`, as four consecutive `move` commands.
```
- defines a new command `m4`{=snippet}, with type `cmd unit`{=type}, as four consecutive `move` commands.
With judicious
use of new definitions, it should be possible to complete this challenge
in just a few lines of code.
Expand All @@ -24,10 +26,10 @@ objectives:
- |
TIP: the type annotation in a definition is optional. You could also write
`def m4 = move; move; move; move end`, and Swarm would infer
the type of `m4`.
the type of `m4`{=snippet}.
- |
TIP: writing function definitions at the prompt is annoying.
You can also put definitions in a `.sw` file and load it
You can also put definitions in a `.sw`{=path} file and load it
with the `run` command. Check out
https://github.com/swarm-game/swarm/tree/main/editors
for help setting up an external editor with things like
Expand Down