Commit Graph

603 Commits

Author SHA1 Message Date
Ondřej Šebek
bc480a045d
Add list example (#261)
- encodes `list int` inside `int`
- has unit tests written in swarm language
2021-10-26 19:54:04 +00:00
Brent Yorgey
c982e81790
Delay type (#223)
Make explicit in the type system when evaluation of a computation should be delayed.  This gives the user fine-grained control over selective laziness (for example, once we have sum types and recursive types, one could use this to define lazy infinite data structures).  It also allows us to guarantee that certain commands such as `build` and `reprogram` delay evaluation of their arguments, and lets the user e.g. define their own modified versions of `build` without compromising those guarantees.

- Delay is indicated by curly braces both at the value and type levels, that is, if `t : ty` then `{t} : {ty}`.
- `force : {ty} -> ty` is now exposed in the surface language.
- Change from a CEK machine to a CESK machine. Recursive `let` and `def` delay via allocating a cell in the store.  For now, there is no other way to allocate anything in the store, but see discussion at #150 for some possible future directions.
- change the types of `build` and `reprogram` to require a delayed program, e.g. `build : string -> {cmd a} -> cmd string`
- `if` and `try` also require delayed arguments.
- don't elaborate Build and Reprogram with extra Delay wrappers since one is now required by the type
- Division by zero, negative exponents, and bad comparisons now throw exceptions.

Closes #150.  Closes #226.
2021-10-25 13:28:41 +00:00
Brent Yorgey
4f33b22611 remove redundant import 2021-10-22 11:58:10 -05:00
Brent Yorgey
cdd3aff892 remove https://github.com/jtdaugherty/brick/issues/337 workaround
This issue is fixed in `brick-0.64.2`.
2021-10-22 11:55:32 -05:00
Paul Brauner
b72e09edb1
Use fused-effects for the game logic (#256)
Resolves #228.

I've redefined the missing lens operators in `Utils.hs` in order to keep the diff of the function bodies minimal. Hopefully that will make merges and rebases less painful. Most of the type signatures are modified though, we can't avoid this.
2021-10-21 22:44:56 +00:00
Alexander Block
969b0d191c
Only append entry to REPL history if it is not the same as last entry (#252)
Closes #75. 
A REPL entry is only appended to the REPL history if it is not a duplicate of the last entry.
2021-10-20 21:13:40 +00:00
Ondřej Šebek
400d101736
Add ($) operator (#239)
- add `$` operator to avoid multiple parentheses
2021-10-20 06:54:08 +00:00
Ondřej Šebek
0327595a9e Fix back direction 2021-10-19 21:23:44 +02:00
Ondřej Šebek
fcc915ac18
Cap ticks in model (#246)
- fixes  #245
2021-10-19 19:20:06 +00:00
Ishan Bhanuka
150dc9b396
Test example .sw files to see if they type check (#233)
Closes #180 

Add `Integration.hs` which reads files from `example` folder and runs `processTerm` on the contents. The test passes if creating a term is successful.

Currently only one example i.e. `zigzag.sw` is failing.
2021-10-19 02:49:32 +00:00
Brent Yorgey
22a8de35b6
Add sum types (#224)
Adds sum types (e.g. `int + bool`) along with constants `inl : a -> a + b`, `inr : b -> a + b`, and `case : a + b -> (a -> c) -> (b -> c) -> c`.

I considered whether to automatically wrap the arguments to `case` in `delay`, like the arguments to `if`, but they are already functions anyway so we get a lot of laziness for free.  It would only make a difference if you wrote something like `case foo (let x = blah in \y. ...) (...)` in which case the `let x = blah` is going to be evaluated eagerly, *before* we know which branch we are going to take.  I don't think it's worth bothering about.  In the normal case that you write `case foo (\y. ...) (\z. ...)` then only one of the two functions gets run at all, without us having to do anything special with `delay`.

I also considered whether to make special syntax for case expressions, like `case foo of { inl x -> ... ; inr y -> ... }` but doing it as a simple built-in function is both easier to implement and feels like it fits better with the aesthetic of the language so far.

Closes #46 .
2021-10-16 23:17:42 +00:00
Ondřej Šebek
c30b710a84
Fix operator parsing (#237)
- add check that operator is not followed by another "operator"

Fixes #236
2021-10-16 14:39:49 +00:00
Brent Yorgey
8677861b38 TUTORIAL: fix salvager instructions 2021-10-16 08:30:21 -05:00
Ondřej Šebek
d21cbd6c43 Fix zigzag example 2021-10-16 14:52:39 +02:00
Ishan Bhanuka
07d93a9d49
Refactor robot context information into a single record (#198)
Closes #190
2021-10-16 11:04:29 +00:00
Ishan Bhanuka
4265233637
Generate direction helper methods from consolidated direction information in DirInfo records (#230)
Closes #183
2021-10-16 10:40:16 +00:00
Brent Yorgey
db46f60cb7 center all recipe requirements 2021-10-14 14:42:44 -05:00
Ondřej Šebek
e8f8c61273
Add drill command (#186)
- adds drill capability (from drill entity) (Closes #143)
- adds drilling recipes
- adds (non-portable) entities:
  - mountain tunnel (shows on top of robots)
  - copper vein (blocking, is "inside mountain") 
  - copper mine (Closes #18)
- adds time parameter to (drilling) recipes
- fixes a bug showing seed robots on top of entities
2021-10-14 03:07:21 +00:00
Brent Yorgey
a52bc0557c activate the base when making a recipe from the inventory list
Since the base was not put into the active robots set, it never made
any progress on making the recipe.

Fixes #227.  This just goes to prove @polux's point in #217.
2021-10-13 21:39:58 -05:00
Ishan Bhanuka
a80d2904b4
Refactor getx and gety into whereami command (#220)
Closes #178
2021-10-12 20:19:38 +00:00
Brent Yorgey
50e5345222 emacs syntax highlighting: get // ... and /* ... */ both to work
Learned how to do this from
http://www.gnu.org/software/emacs/manual/html_node/elisp/Syntax-Flags.html .
2021-10-12 15:12:50 -05:00
Brent Yorgey
5d9f302e03
basic syntax highlighting for emacs mode (#219)
There are still some things missing (e.g. operators) but this is a start.  Some remaining issues:

* We should look into auto-generating the lists of keywords so we don't have to manually update every time we add new commands.  Or (fancier) maybe the swarm executable can have a special flag to make it spit out lists of command names, so the emacs mode can dynamically find out what to highlight?
* I am not sure how to get it to highlight both single-line and multi-line comments at the same time.  It must be possible since e.g. `java-mode` does it.  We could also change the comment syntax, I really don't care that much.
2021-10-12 20:07:04 +00:00
Brent Yorgey
7646a779f1
only allow scrolling world view when in Creative mode (#214)
Closes #32.
2021-10-12 18:19:16 +00:00
Brent Yorgey
06dd84cb87
impossible/problematic arithmetic operations return random result (#213)
Also split out a helper function to generate a uniformly random value
using the `StdGen` stored in the `GameState`.

Closes #27.
2021-10-12 18:13:56 +00:00
Brent Yorgey
93649da576
cap maximum ticks per frame at 30 (#215)
Cap the maximum number of ticks per frame (arbitrarily) at 30, to
prevent the "spiral of death" (see
https://gafferongames.com/post/fix_your_timestep/).

To see this in effect, go into Creative mode, crank up the ticks per
second to 32 or so, then (for suitable definitions of `repeat` and
`forever`) execute

`repeat 1000 { build "" {forever {move; turn left}}}`

Without this PR, it should eventually grind to a halt.  With this PR,
the game should keep running, though with lots of lag.

Closes #42 .
2021-10-12 16:35:54 +00:00
Paul Brauner
48f445f1df
Remove idle robots from the active robots set (#200)
Resolves #19. This is a big win for idle robots, but decreases the performance of active robots a bit.

Benchmark results on the main branch:

```
benchmarking run 1000 game ticks/idlers/40
time                 18.93 ms   (18.63 ms .. 19.34 ms)
                     0.999 R²   (0.998 R² .. 1.000 R²)
mean                 18.82 ms   (18.69 ms .. 19.00 ms)
std dev              419.6 μs   (284.8 μs .. 642.9 μs)

benchmarking run 1000 game ticks/trees/40
time                 10.27 ms   (10.21 ms .. 10.32 ms)
                     1.000 R²   (0.999 R² .. 1.000 R²)
mean                 10.16 ms   (10.12 ms .. 10.21 ms)
std dev              142.0 μs   (105.9 μs .. 211.4 μs)

benchmarking run 1000 game ticks/circlers/40
time                 260.2 ms   (257.9 ms .. 262.4 ms)
                     1.000 R²   (1.000 R² .. 1.000 R²)
mean                 257.5 ms   (256.5 ms .. 258.9 ms)
std dev              1.817 ms   (1.235 ms .. 2.674 ms)
variance introduced by outliers: 11% (moderately inflated)

benchmarking run 1000 game ticks/movers/40
time                 785.9 ms   (620.8 ms .. 987.0 ms)
                     0.992 R²   (0.975 R² .. 1.000 R²)
mean                 847.7 ms   (802.5 ms .. 892.8 ms)
std dev              57.17 ms   (30.38 ms .. 69.01 ms)
variance introduced by outliers: 20% (moderately inflated)
```

Benchmark results after removing idle robots from the active robots set:

```
benchmarking run 1000 game ticks/idlers/40
time                 888.4 μs   (877.9 μs .. 904.7 μs)
                     0.998 R²   (0.996 R² .. 1.000 R²)
mean                 870.3 μs   (865.6 μs .. 878.8 μs)
std dev              22.49 μs   (14.50 μs .. 39.52 μs)
variance introduced by outliers: 17% (moderately inflated)

benchmarking run 1000 game ticks/trees/40
time                 4.075 ms   (4.023 ms .. 4.118 ms)
                     0.999 R²   (0.999 R² .. 1.000 R²)
mean                 3.993 ms   (3.974 ms .. 4.016 ms)
std dev              68.87 μs   (55.92 μs .. 87.58 μs)

benchmarking run 1000 game ticks/circlers/40
time                 362.5 ms   (264.8 ms .. 492.7 ms)
                     0.902 R²   (0.838 R² .. 1.000 R²)
mean                 285.1 ms   (266.2 ms .. 340.9 ms)
std dev              47.45 ms   (1.859 ms .. 68.36 ms)
variance introduced by outliers: 41% (moderately inflated)

benchmarking run 1000 game ticks/movers/40
time                 815.1 ms   (642.8 ms .. 1.042 s)
                     0.991 R²   (0.973 R² .. 1.000 R²)
mean                 866.1 ms   (819.0 ms .. 913.2 ms)
std dev              58.40 ms   (28.79 ms .. 73.29 ms)
variance introduced by outliers: 20% (moderately inflated)
```

Idlers are much faster. Trees are also faster because they become idle after they're done growing. Circlers and movers are slower. Inlining the active robot check helps with the circlers:

```
benchmarking run 1000 game ticks/idlers/40
time                 941.6 μs   (932.4 μs .. 951.3 μs)
                     0.999 R²   (0.999 R² .. 1.000 R²)
mean                 933.1 μs   (926.8 μs .. 939.9 μs)
std dev              25.30 μs   (20.66 μs .. 32.12 μs)
variance introduced by outliers: 19% (moderately inflated)

benchmarking run 1000 game ticks/trees/40
time                 3.925 ms   (3.901 ms .. 3.948 ms)
                     1.000 R²   (0.999 R² .. 1.000 R²)
mean                 3.902 ms   (3.888 ms .. 3.919 ms)
std dev              57.08 μs   (47.38 μs .. 76.42 μs)

benchmarking run 1000 game ticks/circlers/40
time                 266.8 ms   (260.1 ms .. 275.4 ms)
                     0.999 R²   (0.998 R² .. 1.000 R²)
mean                 263.2 ms   (261.6 ms .. 266.1 ms)
std dev              3.170 ms   (1.914 ms .. 4.360 ms)
variance introduced by outliers: 11% (moderately inflated)

benchmarking run 1000 game ticks/movers/40
time                 829.2 ms   (692.9 ms .. 1.023 s)
                     0.994 R²   (0.982 R² .. 1.000 R²)
mean                 862.0 ms   (822.4 ms .. 901.8 ms)
std dev              50.46 ms   (21.92 ms .. 66.59 ms)
variance introduced by outliers: 19% (moderately inflated)
```

I'm not sure why the movers don't seem to benefit from the inlining.

The last commit that removes non-sensical tests (waiting after self destruction) has not effect on the performance, but cleans up the logic.
2021-10-12 11:12:55 +00:00
Brent Yorgey
29081bd9b8 bug fix: check for escaping Skolem variables
Fixes #211.  See commentary in
07776b9ab8
for more context.
2021-10-11 14:04:54 -05:00
Brent Yorgey
b5eefab68a salvage command now uses a separate plasma cutter device 2021-10-10 17:37:25 -05:00
Brent Yorgey
4a0d338324 make ishere command require scanner 2021-10-10 17:34:36 -05:00
Brent Yorgey
03665026b3 clean up comment formatting 2021-10-10 17:34:11 -05:00
Brent Yorgey
b78e988c28 give base an orientation
Fixes #204.
2021-10-10 17:28:21 -05:00
Brent Yorgey
01391288fd
leave discovered entities in the inventory forever (#164)
Once an entity has been discovered, it stays in the inventory, even if its count becomes 0.

I think I just deleted the code @fryguybob carefully fixed in #157... =)

Fixes #163.
2021-10-09 15:43:26 +00:00
Brent Yorgey
2b146586d2
Add scrolling for bottom-left info panel and logger device for message logs (#128)
The original main goals of this PR are to (1) solve #36 , that is, make the bottom-left info area fully wrapped and scrollable; and (2) solve #40 , that is, persist the info in that bottom-left info area even when switching to other panels.  In order to address those I ended up making a rather large constellation of related changes, which in the end I hope work well with each other.  Eager to hear others' feedback either from looking at the code or just trying out the game with this PR.

- In order to make the bottom-left area scrollable, split it out into its own panel.  Now we can focus it and then use normal keybindings to scroll it.
- The bottom-left info panel now indicates whether it has additional content scrolled off the top or bottom.
- The bottom-left panel used to display a global list of log/error messages when the inventory was not focused.  So where will those messages be viewable now, if the information displayed in the bottom-left panel persists?  My answer: there is a special `logger` device (#39) which, when focused, now displays the log messages.
    - This means that logs are now per-robot instead of global.
    - The base starts with a `logger` installed.
    - A `log` command can be used to write to a logger.
    - Uncaught exceptions also now write to a logger (instead of using `say`), or are simply discarded if there is no `logger` device installed.
    - The first time a robot's inventory is viewed after a message has been appended to its log, the `logger` device will be automatically focused and the log scrolled all the way to the bottom to show the new entry.  This means that e.g. typing `move` at the REPL will immediately show an exception in the lower left.
- Add a `salvage` command, making it possible to access the log of a dead robot after the fact, once we implement #17 .

There are still a few issues to address which I think can be done in separate PRs:

- The global message log still exists, and the `say` command still appends to it, but there is no way to view it.  Obviously we need to do something with this --- either get rid of it, or figure out a sensible way to view it, etc.
- Exception messages should probably be reformatted to not include any newlines, now that we know they will be wrapped.

Closes #36.  Closes #40.  Closes #39.  Closes #21.
2021-10-08 21:53:16 +00:00
Ishan Bhanuka
e8d387d739
Add entity for reprogramming (#179)
Closes #22
2021-10-07 19:07:08 +00:00
Ondřej Šebek
1500fd127c
use != for not equal (#192)
Closes #188
2021-10-07 01:31:42 +00:00
Paul Brauner
2b023eb7c3
More benchmarks (#187)
Improve the benchmark and add more scenarios.

Improvement are:
- Run each benchmark for 10 seconds to get enough samples in more costly scenarios
- Run benchmark on a blank terrain to avoid crashing into mountain and boulders
- Take advantage of the seed in tests using randomness

New scenarios are:
- A bunch of robots doing nothing. Will be useful for measuring the impact of removing idle robots from the active robots set.
- A bunch of robots moving in circles.
- A bunch of robots moving forward. This surprisingly is slower than moving in circles.
2021-10-06 19:15:32 +00:00
Paul Brauner
96641beaba
Only update robots that are not waiting. (#176)
Resolves #20 by introducing an active robots set and a waiting robots queue as discussed in the issue.

Growing trees benchmark before change:
```
benchmarking run 1000 game ticks/10 trees
time                 141.1 ms   (137.3 ms .. 146.4 ms)
                     0.997 R²   (0.995 R² .. 1.000 R²)
mean                 140.1 ms   (138.5 ms .. 142.2 ms)
std dev              3.807 ms   (2.703 ms .. 5.189 ms)
                   
benchmarking run 1000 game ticks/20 trees
time                 298.9 ms   (281.7 ms .. 326.0 ms)
                     0.989 R²   (0.972 R² .. 0.998 R²)
mean                 301.7 ms   (295.0 ms .. 311.0 ms)
std dev              13.93 ms   (10.02 ms .. 19.92 ms)
                   
benchmarking run 1000 game ticks/30 trees
time                 470.9 ms   (432.0 ms .. 513.0 ms)
                     0.991 R²   (0.978 R² .. 1.000 R²)
mean                 450.1 ms   (441.9 ms .. 468.4 ms)
std dev              18.85 ms   (5.941 ms .. 30.21 ms)
variance introduced by outliers: 11% (moderately inflated)
```

After change:
```
benchmarking run 1000 game ticks/10 trees
time                 4.666 ms   (4.529 ms .. 4.955 ms)
                     0.963 R²   (0.899 R² .. 0.999 R²)
mean                 4.447 ms   (4.361 ms .. 4.668 ms)
std dev              539.2 μs   (185.5 μs .. 1.097 ms)
variance introduced by outliers: 80% (severely inflated)
                   
benchmarking run 1000 game ticks/20 trees
time                 6.955 ms   (6.826 ms .. 7.122 ms)
                     0.996 R²   (0.993 R² .. 0.999 R²)
mean                 6.855 ms   (6.795 ms .. 6.936 ms)
std dev              262.8 μs   (197.0 μs .. 340.6 μs)
variance introduced by outliers: 25% (moderately inflated)
                   
benchmarking run 1000 game ticks/30 trees
time                 10.53 ms   (9.738 ms .. 11.47 ms)
                     0.954 R²   (0.914 R² .. 0.988 R²)
mean                 9.504 ms   (9.226 ms .. 9.974 ms)
std dev              1.211 ms   (809.9 μs .. 1.948 ms)
variance introduced by outliers: 76% (severely inflated)
```
2021-10-05 20:54:12 +00:00
Ondřej Šebek
77c7fd686d
Add seed option to CLI (#170)
- adds CLI option `--seed` and propagates it to `testWorld2` (Closes #14)
- moves the base in the tree shade (Closes #90)
- makes the `random` command depend on initial seed (Closes #13)
2021-10-05 19:43:52 +00:00
Alexander Block
81d680e1a8
Clear the error widget on successful REPL entry (#185)
This pull request combines two changes:

1. When the user hits "Enter" in the REPL and the entry is validated, any previous error is removed from the screen.
2. When the user hits "Enter" while the base is actively running a computation, this is ignored now without triggering a redraw. This change is based on the review comment https://github.com/byorgey/swarm/pull/181#pullrequestreview-770727562 . While using ``continueWithoutRedraw`` for this case is more verbose than factoring out ``continue`` as I did before and the performance impact is most certainly negligible, I think that this solution is semantically cleaner. Of course I am happy to roll back this change if there is a disagreement about this point. 

Closes #76
2021-10-05 15:17:39 +00:00
Ishan Bhanuka
4d24b2f039
Add self naming capability (#174)
* Add self naming capability

* Restyled by fourmolu (#175)

Co-authored-by: Restyled.io <commits@restyled.io>

* Rename self to whoami

* Update data/entities.yaml

Co-authored-by: Brent Yorgey <byorgey@gmail.com>

Co-authored-by: restyled-io[bot] <32688539+restyled-io[bot]@users.noreply.github.com>
Co-authored-by: Restyled.io <commits@restyled.io>
Co-authored-by: Brent Yorgey <byorgey@gmail.com>
2021-10-05 14:03:48 +05:30
Jacob
6a9156d792
Abstract Const commands out of reserved words list (#182)
Now that `constInfo` provides the name of Const values, there is no
need to re-list each command in the reserved words list.  Also
represent reserved words as Text instead of String.
2021-10-04 22:48:35 +00:00
Alexander Block
2dcff25ad0
REPL ignores Enter while working (#181)
When you hit Enter at the REPL the REPL event handler now checks whether the base is currently running a computation. If this is the case, then the Enter key event is ignored. 

Fixes #139
2021-10-04 20:12:35 +00:00
Jens Petersen
6adc150530
stack: update to hashable-1.3.4.1 which builds (#168)
hashable-1.3.4.0 looks broken at least on lts18
2021-10-04 10:59:51 +00:00
Brent Yorgey
d8e3334cad
update CI and include the test suite (#165) 2021-10-03 21:29:08 -05:00
Alexander Block
6a68ecc2a7
advertise ctrl-c to cancel base computation (#166)
While the repl is actively working, the ``[Enter] execute`` hint in the key menu will now be replaced by ``[^c] cancel``. 

Fixes #44
2021-10-04 02:26:54 +00:00
Ondřej Šebek
817925bd5b
Add cabal to HLS configuration (#131)
- allow HLS to use Cabal instead of Stack
  - Cabal works fine, and I do not see any advantage to using Stack
  - someone using Stack should test this does not switch him to Cabal ⚠️  
- ignore `cabal.project.local` so I can put there `ghc-options: -haddock`
  - this flag could lead to errors before GHC 9, but it gives me [docs on hover](https://haskell-language-server.readthedocs.io/en/latest/features.html)
2021-10-03 21:14:04 +00:00
Tristan de Cacqueray
cfd94f3ab1
Handle DocumentDidChange LSP event (#158)
This change enables the LSP server to report diagnostic on
the virtual file, without waiting for a save event.

Not sure how to correctly configure emacs (and why it is not needed
for HLS), but this only works when `flycheck-check-syntax-automatically`
has `idle-change`, e.g.:

  (setq flycheck-check-syntax-automatically '(save mode-enable idle-change))
2021-10-03 20:12:08 +00:00
Ryan Yates
9edf01da7f
bug fix: byName out of sync with counts due to case insensitivity. (#157)
The `Inventory` `counts` and `byName` maps could get out of sync due to missing case insensitivity on deletion.  Perhaps a better fix would be to use something like [https://hackage.haskell.org/package/case-insensitive](https://hackage.haskell.org/package/case-insensitive).
2021-10-03 20:06:12 +00:00
Ishan Bhanuka
8ee15c05f7
Accept filename without .sw extension in run command (#159)
Closes #135
2021-10-03 19:27:28 +00:00
Ishan Bhanuka
29e66e429d
Add hint for using repl history (#160)
Closes #59
2021-10-03 18:01:16 +00:00