Commit Graph

1307 Commits

Author SHA1 Message Date
Karl Ostmo
6087be535f
Remove let-binding workarounds (#2012)
The bug which necessitated the workaround was fixed in #1928.
2024-07-06 14:43:38 +00:00
Karl Ostmo
54bf8f9215
Update spelling dictionary (#2011)
Re-ran this:
```
scripts/gen/autopopulate-spellchecker.sh
```
2024-07-06 02:44:10 +00:00
Brent Yorgey
9b1b6985fa
On C-c, only cancel base CESK if it is currently running (#2008)
Fixes #2007.  After #1928, we handle exceptions a little differently, so it no longer works to simply set the base's CESK machine to an `Up` (exception) state no matter what.  Instead we have to first check if the base is running, and if so set it to `Up` as before; if not, do nothing (except clear the REPL prompt).
2024-07-01 19:04:43 +00:00
Brent Yorgey
6b58979b3a
Focus REPL panel on click (#2005)
Closes #1486.

I'm not entirely sure I understand why this is necessary but it seems like for anything with a brick `viewport` it's not enough to just rely on wrapping it in `clickable`.  We have to actually set their focus explicitly depending on the identity of the clicked viewport.
2024-07-01 10:41:30 +00:00
Karl Ostmo
9a5fe48a24
nonempty grid rows (#1933)
Closes #1843

Towards #1981
2024-07-01 02:09:23 +00:00
Karl Ostmo
1688f1e407
Use 'enumerate' from the 'extra' package (#2003)
Use [`enumerate`](https://hackage.haskell.org/package/extra-1.7.16/docs/Data-List-Extra.html#v:enumerate) instead of defining `listEnums` ourselves.

Also discovered a "safer" implementation of nonempty enumerations, which lets of remove the `Data.List.NonEmpty.fromList` hlint exclusion.
2024-07-01 00:12:01 +00:00
Nitin Prakash
40159975ad
Remove duplicate transformers dependency (#1996)
Closes #1993
2024-06-28 05:03:37 +00:00
Brent Yorgey
6471de6179
Change meetAll to return a list (#1999)
Closes #1998.
2024-06-27 19:56:16 +00:00
Karl Ostmo
d9382ad21e
Remove grid overlay truncation behavior (#1995)
In the implementation of #1826, I decided to preserve the old truncating behavior as the default.  But after some consideration, there's no real use case for the old behavior, so let's take it out to simplify the code.
2024-06-27 01:42:34 +00:00
Brent Yorgey
1735416689
Add imap to world DSL, with examples (#1990)
Adds a new primitive `imap`, aka index map, primitive to the world DSL.  `imap` has type `World int -> World int -> World a -> World a`.  Think of it like `(Coords -> Coords) -> World a -> World a`, i.e. given a coordinate mapping, it creates a new world by looking up the cell at the transformed coordinates in the given base world.  However, since there are no lambdas we cannot directly give it that type; instead, the first `World int` represents a function `Coords -> int` which gives an x coordinate, and the second gives the y coordinate.  All told, `imap wx wy wa` is like `\c -> wa (wx c, wy c)`.  For example, `imap (-x) y w` is a reflection of `w` across the y-axis.

Adds a description of `imap` to the language reference, as well as adding a few examples.

Also removes the `rot` and `reflect` primitives, since they can now be simply implemented in terms of `imap`.

Depends on merging #1989 first.  Closes #1584.
2024-06-26 20:08:30 +00:00
Brent Yorgey
939ecf3129
Fix world DSL hash primitive to depend on seed (#1989)
It turns out that the `hash` primitive was always computing the same deterministic hash of the coordinates regardless of the seed.  This meant that *e.g.* any world features placed in a way that depended on the hash were always in the same locations, and if you created a world that only relied on `hash` and not on, say, Perlin noise, it would always look the same regardless of the seed.  This does not seem desirable.

This PR fixes the DSL interpreter by passing the seed to the `murmur3` hash function (we used to always pass the constant seed 0).  In theory, this does mean that all the "classic" worlds are now slightly different than what they used to be (except for seed 0).  However, there's no way to tell the difference between one random placement and another.  The only scenario where we really depend on the particular locations of entities for a particular seed is the `world101` tutorial, but that used seed 0 anyway, which did not change.

Depends on merging #1988 first.
2024-06-25 21:55:09 +00:00
Brent Yorgey
a687d54c76
Fix world DSL coordinate bug (#1988)
The special variables `x` and `y` in the world DSL did not refer to the correct thing --- in the interpreter apparently I forgot to convert from `Coords` to `Location` and just used the row, column in `Coords` as the `x` and `y`.  I have also fixed up all the scenarios which used `x` and `y` in their world description so that they now look identical to before, by replacing every use of `x` with `-y` and every use of `y` with `x` (though in some cases where the result would be algebraically equal I did not literally do this replacement, *e.g.* `(x + y) % 2` is equal to `((-y) + x) % 2`, so I left it alone).
2024-06-25 21:31:43 +00:00
Karl Ostmo
6801cdd8a8
remove 'unGrid' accessor (#1982)
Towards #1981
2024-06-25 16:39:22 +00:00
Brent Yorgey
02af5248bc
Bring tutorial in line with #1957 (#1983) 2024-06-24 20:40:08 +00:00
Brent Yorgey
dc7ea65006
Add failing test case for #231 (#1984) 2024-06-24 16:03:59 +00:00
Noah Yorgey
56299ea25a
Add Custom Widget Names. (#1977)
Add Custom Widget Names.

Closes #1976.
2024-06-23 21:06:56 +00:00
Nitin Prakash
8403cce726
Add hie.yaml to gitignore (#1975) 2024-06-23 19:02:07 +00:00
Nitin Prakash
92a652496e
Reset scroll position when switching modals (#1971)
Closes #1901 

When switching description modals or info panel in the bottom left corner, the viewport used to retail the scrolled state.
This PR attempts to reset the scroll position when we switch modals.
2024-06-23 18:38:23 +00:00
Brent Yorgey
9fe1184dd3
Apply bindings before returning unification mismatch error (#1972)
Closes #1888.  When we discovered a type mismatch, we were not fully substituting everything we had learned about the types (via `applyBindings`) before reporting the error.  For example, in #1888 we had `2 : u1` and a unification constraint `u1 = Int -> u2`, but we were just reporting the type of `2` as `u1` rather than first substituting `Int -> u2` for `u1`.

I think we have had this problem for a while, but the recent rewrite of the unification engine possibly made the effects more noticeable.

This incidentally improved a couple more error messages in the test suite. =)
2024-06-23 13:07:44 +00:00
Brent Yorgey
8dda395560
Add Windows build to CI (#1974)
Closes #1622.
2024-06-23 04:12:39 +00:00
Brent Yorgey
f67e476f09
Update copyright (#1973)
Closes #1945.
2024-06-23 03:59:08 +00:00
Nitin Prakash
1cbc22e2de
Clear inventory search state when switching menus (#1968)
closes #1967
2024-06-21 18:53:29 +00:00
Brent Yorgey
eb156a688f
Get rid of memoizing delay + switch to a strict store (#1949)
Closes #1948; see that issue for a much more in-depth discussion.

Depends on merging #1928 first.

A lot of this PR consists in deleting code that is either (1) ugly or (2) overly clever! 🥳 

The short version is that the `Store` used to incorporate some laziness + memoization: when a cell was first allocated, it was an unevaluated thunk; it then got evaluated the first time it was referenced.  However, this wasn't really needed to handle recursive definitions (which is the only thing we were using it for).  Getting rid of it means we can get rid of a lot of weird ugly code needed to wrap free variables in extra calls to `force` and so on.

The new and improved `Store` just stores `Value`s, period.  A special `VBlackhole` value was added, to be used while evaluating a recursive `let`.

Note that `VRef` is no longer really used, but I left it there for use in implementing #1660 .  Once we have mutable references we can use them + delay/force to implement lazy cells.
2024-06-19 20:17:22 +00:00
Brent Yorgey
23b5398dc0
Refactor CESK machine to track environments through new Suspended state (#1928)
The big idea of this PR is to add a new type of CESK machine state, `Suspended`, which is a state the base robot automatically goes into after completing execution of a program entered at the REPL.  It is as if the base robot is still within the local context of any definitions etc. entered previously, just printed out an "intermediate result", and is now waiting to find out what the next term to be executed will be.  This allows us to treat `def` as syntax sugar for `let` and results in a much cleaner way to manage the context of definitions, which in turn allows us to remove a whole lot of special cases and fixes several annoying bugs.  See #1087 for more explanation and discussion.

Things that are **deleted** (!) by this PR:
- `TDef` (`def` is now just syntax sugar for `let`) (#997)
- `VResult` (we no longer need to return anything other than plain values)
- `FUnionEnv`, `FDiscardEnv`, `FLoadEnv` (we no longer need machinery to collect up definitions while evaluating terms)
- `ProcessedTerm` (just a plain `TSyntax` (i.e. `Syntax' Polytype`) is now enough)
- `Module` (it only existed to package up some contexts with typechecked terms, but we don't need them anymore)
- `RobotContext` and `topContext` (we don't need to store those things separately any more, they are just stored in the `CESK` machine where they belong)

Additions/changes:
- The `Requirement` module is split into `Requirements.Type` and `Requirements.Analysis` to avoid circular module imports
- New `Suspended` state for the CESK machine
- `def` and `tydef` are now allowed anywhere (even nested inside other definitions etc.) since `def x = y end; z` is just syntax sugar for `let x = y in z` (see #349)
- Code size decreased slightly for many programs using `def`, since `def` is now a synonym for `let`, and consecutive `def`s therefore do not require a `bind`.

Closes #1087.  Fixes #681 (hence also #736, #1796). Fixes #1032. Closes #1047. Closes #997. Fixes #1900. Fixes #1466. Fixes #1424.

See also #636.
2024-06-19 19:56:22 +00:00
Ondřej Šebek
6a4ddb3352
Highlight error part in REPL (#1957)
Closes #1956
2024-06-19 18:06:11 +00:00
Noah Yorgey
53fe43d0b6
Delete stack.yaml (#1963)
Delete stack.yaml

Closes #1960.
2024-06-19 17:50:39 +00:00
Nitin Prakash
54fdc95418
Get rid of unused packages (#1961)
Some of the packages are not used to build the swarm executable.
It's probably a good idea to get rid of those.
2024-06-19 10:41:21 +00:00
Nitin Prakash
4dc0976fc1
Generate operators for all editors (#1950)
Currently, operator names are generated only for vscode only using the command `cabal run swarm:swarm-docs -- editors --code`.
With this PR, I intend to bring that behaviour to all the editors.

Changes include:
- `cabal run swarm:swarm-docs -- editors` command now supports `vim` as well.
- `operatorNames` can generate operator list catering to all the editors supporting Swarm.
- Update operator list in `swarm-mode.el`, `swarm.vim` and `swarm.tmLanguage.yaml`.

How to test emacs syntax:
- Open `editors/emacs/swarm-mode.el` in emacs.
- Then `M-x eval-buffer`
- Open up any of the `.sw` file under `examples`.
- Then `M-x swarm-mode`

How to test vim syntax:
- Copy swarm.vim to vim directory using `cp editors/vim/swarm.vim ~/.vim/syntax/sw.vim`
- Setup auto detect in vim. `echo 'autocmd BufRead,BufNewFile *.sw set filetype=sw' > ~/.vim/ftdetect/sw.vim`
- Open up any of the `.sw` files under `examples`. (Also ensure that you have syntax on in vim. `ESC :syntax on`)
2024-06-18 17:01:37 +00:00
Brent Yorgey
de12501a56
Automatically insert matching close brackets at REPL (#1953)
Closes #1952.  Whenever you type `(`, `[`, or `{` at the REPL, a matching close bracket is automatically inserted.

I suppose the next level would be to have it delete both brackets if you hit backspace immediately after inserting an open bracket, but I'll leave that for another PR.  Doesn't seem that important anyway.
2024-06-18 14:27:31 +00:00
Noah Yorgey
a66c7c8cc4
Stop printing context after a definition. (#1936)
Fixes #1336.
2024-06-17 20:27:54 +00:00
Nitin Prakash
f607470113
Unit tests for prettyTextWidth (#1942)
Includes tests for `prettyTextWidth` on type signatures. It should verify that line breaks are
introduced appropriately given number of allowed characters in a line.
2024-06-16 17:52:41 +00:00
Nitin Prakash
f69f6fd566
Remove duplicated test case (#1941) 2024-06-16 04:56:45 +00:00
Nitin Prakash
e94dd54429
Pretty print code blocks according to widget size (#1897)
Closes #1794 

Changes include:
- Introduce `prettyTextWidth` that takes in number of allowed characters in a line as an argument.
- Introduce `pparens'` which is mostly similar to `pparens` except that it only encloses a document
  in parantheses and does not do anything else.
- Make type signatures in renderers aware of the widget width.
- Replace usage of `hardline` with `softline` for multiline pretty printing.
2024-06-16 04:18:21 +00:00
Karl Ostmo
fa6b87abc9
Enforce palette usage (#1938)
Enforces that ever entry in the palette for a given (sub-)structure is used in its map.

Also in the PR, moved the `Coords` module to the `topography` sublibrary.
2024-06-16 02:49:47 +00:00
Karl Ostmo
85d5d9bf65
Enforce rectangular map grids (#1935)
This is a "gotcha" I've run into a few times.
2024-06-15 20:15:02 +00:00
Karl Ostmo
1ebe7fa8f5
Make structures parseable independently of entity definitions (#1924)
This refactoring makes structures parseable independently of `Entity` and `Robot `definitions.

We can define a `Palette` that maps to an arbitrary type, for example `RGBColor` instead of `Cell Entity`.

## Testing
```
scripts/test/run-tests.sh standalone-topography
```
2024-06-15 18:21:39 +00:00
Brent Yorgey
66956ef67d
Refactor some functions to use case (#1927)
I used to define functions with multiple clauses in a style like
```
f pat1 = ...
f pat2 = ...
f pat3 = ...
```
but since then have been convinced (by [this blog post](https://ro-che.info/articles/2014-05-09-clauses) and my own experience) that it is superior for multiple reasons to prefer using `case` (or `\case`), like
```
f = \case
  pat1 -> ...
  pat2 -> ...
  pat3 -> ...
```
This PR refactors several functions that were still using the old style.
2024-06-13 16:18:55 +00:00
Brent Yorgey
08730162bd
Don't set it variable when an exception was raised (#1922)
Fixes #1899.  It turned out the problem was not specifically with infinite loop detection but simply any time an exception was thrown and bubbled up to the top level.  After logging the exception the CESK machine returned `VUnit` and there was no way for the UI to tell the difference between a computation that ended successfully with value `VUnit` and one with an uncaught exception.  This PR adds a new special value `VExc` to denote the result of a computation that threw an exception.  The UI can then check for this and not set the `it` variable in that case.
2024-06-10 19:14:45 +00:00
Karl Ostmo
1eabd556b9
simplify parsing in WorldDescription (#1921)
More use of `RecordWildCards`, towards #1878

Also split off a new `integrateArea` function to encapsulate scope.
2024-06-10 03:18:47 +00:00
Brent Yorgey
58fade9291
Longer timeout for 479-atomic-race test (#1919)
I have seen the `479-atomic-race` integration test timeout several times recently (most recently in #1917).  Increase the timeout for that test from the default 1s to 2s.
2024-06-09 18:58:23 +00:00
Ondřej Šebek
478b62ccf9
Update VSCode plugin (#1895)
* Update VSCode plugin NPM package
* Update VSCode syntax
  * Rewrite the `definition` rule to make it simpler and work with multiline types
    * Use shared `#types` group with added support for `rec`
  * Refactor groups to use ordered include `patterns` and unordered `repository` of named subgroups
  * Add escape sequences to strings
* Fix a typo in a regular expression that broke syntax highlighting
* Generate the syntax JSON file from YAML
---

* Closes #1887
2024-06-09 18:44:26 +00:00
Brent Yorgey
c3f5690ad6
Fix variable lookup during requirements analysis (#1915)
When I refactored requirements analysis during #1906 I didn't properly update the variable case: the code continued to look up the variable in `ctx` which used to be the name of the local context being passed around; after the refactoring, however, `ctx` was the name of the initial context passed to the top-level `requirements` function, and the local context was passed around as a `Reader` effect.  Thus, the lambda case (for example) was correctly deleting the bound variable from the context, but then when checking the variable inside the body of the lambda we looked up its requirements in the initial, global context instead of the modified local one.

This PR fixes the issue and also adds some test cases, one of which was failing before this fix.

Fixes #1914.
2024-06-09 18:29:33 +00:00
Ondřej Šebek
665949d9c7
Fix non-exhaustive pattern in LSP (#1896)
* fix an LSP exception on top level comment

Found while testing #1895.
2024-06-09 18:14:44 +00:00
Ondřej Šebek
cbaf54d76f
Fix Lazy IO opening too many files in integration tests (#1917)
When running on macOS, the integration tests open too many file handles,
even when you do not need to run any swarm file tests.
```sh
> cabal run -O0 swarm-integration -- -p editors
swarm-integration: data/scenarios/Challenges/_bucket-brigade/hauler.sw: openFile: resource exhausted (Too many open files)
```
The solution is to get the file paths only and safely open them as needed.
Surprisingly, this even makes the integration test code simpler.

* discovered while fixing failing tests in #1895
2024-06-09 17:38:45 +00:00
Brent Yorgey
a51f059dd6
minimize some To/FromJSON instances (#1908)
Towards #1907.  For the most part, eschew the default To/FromJSON deriving in favor of `sumEncoding = ObjectWithSingleField`, which encodes `Constructor val` as something like `Constructor: val` instead of `{tag: Constructor, contents: val}`.  Also omit empty `Comments` records.

In the context of #1907, this reduced the size of the generated JSON by about half.
2024-06-08 00:12:06 +00:00
Nitin Prakash
c983ab8af3
Restructure hyperloop definition (#1913)
Closes #1910 

I'd argue that the code is behaving correctly and as intended. Snippets wrapped with backticks are/should be treated as regular texts with highlighting. Introducing line breaks inside a snippet should trigger add a newline character to the text before being rendered (which is what was happening in the first place).

This PR readjusts the description a bit to make sure that the snippets are in one line and do not have any line breaks in between.
2024-06-07 11:10:37 +00:00
Brent Yorgey
f4175d6110
pass tydefs from inferred module into requirements analysis (#1912)
Closes #1911.  I understand the bug now: when inferring the type of a term, we also return a context of type alias definitions in the term.  However, those type aliases might occur in types later in the term itself, so we need to pass those additional type aliases into the `requirements` function (which now looks at types and needs to be able to unfold type aliases).

(Once again, it's not really correct to be doing requirements analysis separately from type checking, and leads to bugs like this.  See #231.)

What I am still really confused by is why the test suite did not catch this problem.  The unit tests do in fact contain some terms like this, which contain a `tydef` followed by a use of the defined type.  And the tests in `TestLanguagePipeline` call `processTerm` which seems like it should have triggered this...
2024-06-07 10:52:14 +00:00
Brent Yorgey
0eca315400
Add device to provide rectypes capability (#1906)
Closes #1898.  Adds the `hyperloop` device (recipe: `ADT calculator` + `strange loop`) which provides the ability to use recursive types (#1894).  Also refactors requirements analysis code and adds the ability for types to trigger capability requirements.
2024-06-06 18:29:40 +00:00
Brent Yorgey
de0d025b8d
Recursive types (#1894)
Implements recursive types.  Example:
```
tydef List a = rec l. Unit + a * l end

def nil : List a = inl () end
def cons : a -> List a -> List a = \x. \l. inr (x, l) end

def foldr : (a -> b -> b) -> b -> List a -> b = \f. \z. \xs.
  case xs
    (\_. z)
    (\c. f (fst c) (foldr f z (snd c)))
end

def map : (a -> b) -> List a -> List b = \f.
  foldr (\y. cons (f y)) nil
end
```
As discussed at #154, this uses the syntax `rec x. F(x)` to define the type `x` which is a solution to `x = F(x)`.  However, unlike the discussion there, I ended up going with *equirecursive* types (so a recursive type is *equal to* its unfolding). For example, as you can see above, if we have a value of type `List a` (defined as `rec l. Unit + a * l`), then it actually has the equivalent type `Unit + a * List a`, so we can simply do a `case` on it, without having to `unroll` first.  This actually turned out to be *easier* to implement (and it is cooler).

There are multiple built-in functions that conceptually return a list but currently do something different (like return a fold, or take an index and return a single element, etc.)  We should consider changing them to actually return lists, but that should definitely be in a separate PR.

Closes #154.
2024-06-06 15:02:11 +00:00
Brent Yorgey
e7a3bec39f
Bring speedrun scenarios in line with classic scenario (#1905)
At some point in the past a `welder` device and 50 `clock`s were added to the equipment and inventory, respectively, of the `base` robot in the `classic` scenario.  This just updates the speedrun scenarios to match.
2024-06-06 11:26:00 +00:00