Skip to content

Commit

Permalink
Parse markdown descriptions (#1106)
Browse files Browse the repository at this point in the history
* use CommonMark to parse simple markdown AST parametrised on inline/block code
* validate swarm code (`Document Text -> Document Syntax`)
* update descriptions to use markdown with following conventions:
  - `move` - valid swarm code (the easy to write default)
  - `wedge`{=entity} - for swarm entities
  - `unit`{=type} - for swarm types
  - `require <a> <b>`{=snippet} - raw snippets for invalid code
  - **Alt-G** - bold for keyboard shortcuts
- highlight code in brick widgets
- closes #309
- closes #545
- precedes #574
- precedes #1406
- precedes #1407
  • Loading branch information
xsebek authored Aug 5, 2023
1 parent e8ea339 commit 1eb2f9c
Show file tree
Hide file tree
Showing 41 changed files with 614 additions and 223 deletions.
120 changes: 83 additions & 37 deletions data/entities.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,11 @@
description:
- A plain wooden workbench, providing space to make other
things using the `make` command.
- 'Example:'
- 'make "log"'
- |
Example:
```
make "log"
```
properties: [portable]
capabilities: [make]

Expand Down Expand Up @@ -343,10 +346,11 @@
description:
- Employs hot lead typesetting to arrange glyphs into a mold for printing.
- |
An equipped `linotype` device enables the `format` command:
- |
`format : a -> text` can turn any value into a suitable text
representation.
An equipped `linotype`{=entity} device enables the `format` command:
```
format : a -> text
```
which can turn any value into a suitable text representation.
properties: [portable]
capabilities: [format]

Expand All @@ -359,7 +363,10 @@
- |
Facilitates the concatenation of text values.
- |
The infix operator `++ : text -> text -> text`
The infix operator
```
++ : text -> text -> text
```
can be used to concatenate two text values. For example,
- |
"Number of widgets: " ++ format numWidgets
Expand All @@ -373,8 +380,10 @@
description:
- Simple, yet accurate measuring device. Can determine the length of a text value.
- |
`chars : text -> int` computes the number of characters in a
`text` value.
```
chars : text -> int
```
computes the number of characters in a `text`{=type} value.
properties: [portable]
capabilities: [charcount]

Expand All @@ -385,10 +394,11 @@
description:
- A simple machine for the textually-inclined; plain but effective.
- |
An equipped `wedge` enables the `split` command:
- |
`split : int -> text -> text * text` splits a `text` value into
two pieces, one before the given index and one after.
An equipped `wedge`{=entity} enables the `split` command:
```
split : int -> text -> text * text
```
splits a `text`{=type} value into two pieces, one before the given index and one after.
properties: [portable]
capabilities: [split]

Expand All @@ -401,7 +411,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 All @@ -410,7 +420,9 @@
The infix operator `++ : text -> text -> text`
can be used to concatenate two text values. For example,
- |
```
"Number of widgets: " ++ format numWidgets
```
- |
`chars : text -> int` computes the number of characters in a
`text` value.
Expand Down Expand Up @@ -446,7 +458,10 @@
- A wild lambda. They are somewhat rare, but regrow when picked. Lambdas
are delicious when cooked into curry.
- Lambdas can also be used to create functions. For example,
- ' def thrice : cmd unit -> cmd unit = \c. c;c;c end'
- |
```
def thrice : cmd unit -> cmd unit = \c. c;c;c end
```
- defines the function `thrice` which repeats a command three times.
properties: [portable, growable]
growth: [100, 200]
Expand Down Expand Up @@ -751,13 +766,19 @@
description:
- Equipping treads on a robot allows it to move and turn.
- The `move` command moves the robot forward one unit.
- 'Example:'
- ' move; move; // move two units'
- |
Example:'
```
move; move; // move two units
```
- The `turn` command takes a direction as an argument, which
can be either absolute (north, west, east, south) or relative
(left, right, forward, back, down).
- 'Example:'
- ' move; turn left; move; turn right'
- |
Example:
```
move; turn left; move; turn right
```
capabilities: [move, turn]
properties: [portable]

Expand All @@ -776,7 +797,7 @@
attr: device
char: '%'
description:
- A "tape drive" allows you to `backup`; that is, to 'drive' in reverse.
- A "tape drive" allows you to `backup`; that is, to `drive` in reverse.
capabilities: [backup]
properties: [portable]

Expand Down Expand Up @@ -818,13 +839,13 @@
char: ''
description:
- A fast grabber is an improved version of the basic grabber - not only
can it 'grab', 'place', and 'give', it can also 'swap'.
- The 'swap' command allows the robot to execute grab and place at the
can it `grab`, `place`, and `give`, it can also `swap`.
- The `swap` command allows the robot to execute grab and place at the
same time so that the location where the robot is standing does not
become empty.
- You can use this to prevent failures where multiple robots
are trying to grab, place or scan a given location.
- In addition you retain the capability to use the 'atomic' command,
- In addition you retain the capability to use the `atomic` command,
with which you can implement other commands that are safe when
run in parallel.
capabilities: [grab, swap, give, place, atomic]
Expand Down Expand Up @@ -935,12 +956,18 @@
- A 3D printer gives you the capability of printing more robots! You
can access the 3D printer via the `build` command.
- 'Example:'
- ' build {move; grab; turn back; move; give base "tree"}'
- |
```
build {move; grab; turn back; move; give base "tree"}
```
- |
builds a robot to get the tree on the cell to the
north (if there is one) and bring it back to the base. The `build` command
always returns a reference to the newly constructed robot. For example,
- ' r <- build {move}; view r'
- |
```
r <- build {move}; view r
```
- |
builds a robot and then views it.
Expand All @@ -955,13 +982,19 @@
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'
- The type annotations in `def` and `let` are optional.
- |
```
def m2 : cmd unit = move; move end
```
- |
```
let x : int = 3 in x^2 + 2*x + 1
```
- The type annotations in `def`{=snippet} are optional.

properties: [portable]
capabilities: [env]
Expand All @@ -977,7 +1010,10 @@
is `if` followed by three arguments: a boolean test and then
two delayed expressions (i.e. expressions in curly braces) of the same type.
- 'Example:'
- 'if (x > 3) {move} {turn right; move}'
- |
```
if (x > 3) {move} {turn right; move}'
```
properties: [portable]
capabilities: [cond]

Expand Down Expand Up @@ -1089,7 +1125,10 @@
- "That way you can view any heard message later either in
the logger or the message window."
- "To wait for a message and get the string value, use:"
- "`l <- listen; log $ \"I have waited for someone to say \" ++ l`"
- |
```
l <- listen; log $ \"I have waited for someone to say \" ++ l
```
properties: [portable]
capabilities: [listen]

Expand Down Expand Up @@ -1167,7 +1206,9 @@
robot's current heading. For example, the following code moves
east and then restores the same heading as before:
- |
```
d <- heading; turn east; move; turn d
```
properties: [portable]
capabilities: [orient]

Expand Down Expand Up @@ -1200,7 +1241,7 @@
char: R
attr: silver
description:
- Enables robots to use the 'watch' command.
- Enables robots to use the `watch` command.
- |
`watch : dir -> cmd unit` will mark an adjacent (in the specified direction) location of interest to monitor for placement or removal of items.
A subsequent call to `wait` will be interrupted upon a change to the location.
Expand Down Expand Up @@ -1235,16 +1276,19 @@
commands in between them. It can be used via the `atomic` command. For example, suppose
robot A executes the following code:"
- |
```
b <- ishere "rock"; if b {grab} {}
```
- "This seems like a safe way to execute `grab` only when there is a
rock to grab. However, it is actually possible for the `grab` to
fail, if some other robot B snatches the rock right after robot A sensed
it and before robot A got around to grabbing it on the next game tick."
- "This will make robot A very sad and it will crash."
- "To prevent this situation, robot A can wrap the commands in `atomic`, like so:"
- |
```
atomic (b <- ishere "rock"; if b {grab} {})
```
properties: [portable]
capabilities: [atomic]
Expand All @@ -1255,9 +1299,11 @@
char: '#'
description:
- A net is a device woven out of many strings. With a net
equipped, you can use the `try` command to catch errors. For example,
equipped, you can use the `try` command to catch errors. For example
- |
`try {move} {turn left}`
```
try {move} {turn left}
```
- will attempt to move, but if that fails, turn left instead.
properties: [portable]
capabilities: [try]
Expand Down Expand Up @@ -1363,7 +1409,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`{=type}, for
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/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
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
Loading

0 comments on commit 1eb2f9c

Please sign in to comment.