This introduces some fancy macro action that allows us to skip the four calls to `(concat-spec …)` with the different generators and types.
@ErikRauer and I wrestled with this for a _long_ time today, and it turned out that it was absolutely necessary to quote the generators in `gen-type-pairs on lines 10-13. I'm not 100% sure why, but it seems that without that something (perhaps a level of macro-ness) got unwrapped too early and then it couldn't find the generator because it had lost the namespace it belonged in.
Whether this actually _simplifies_ things is really up for debate. If this is as far as we get, it's probably not worth it. If we can find a reasonable way to reduce the other sources of duplication, however, it might be worth it?
Similar to `vector/_first`, this didn't check for the empty vector case, so I've changed it to return `:ignore-instruction` in that case.
There's a lot of duplication between `_first` and `_last`, which makes me think there's some refactoring opportunities.
This adds test.check tests for `vector/_last`. This is _really_ similar to `vector/_first` (and the other vector tests), so I think there are definitely ways to extract common logic from these.
The original version just used the built-in `first`, which returns `nil` if you give it an empty collection, which is almost certainly not a useful behavior.
This changes it to return `:ignore-instruction` if the vector is empty, thereby leaving all the stacks unchanged.
`make-instruction` will ignore any instructions that return `:ignore-instruction`. This allows instructions to be skipped without consuming their arguments.
There were two independent bugs in `vector/_subvec` that were turned up by our `test.check` testing.
The first was that the order of the arguments was wrong and `stop-raw` and `start-raw` were flipped.
The second was that `stop` wasn't max'ed with 0, which meant it could sometimes be negative, leading to an `IndexOutOfBoundsException`.
This is a start on using `test.check` to write tests for the vector instructions. We currently have tests for:
* `vector/_emptyvector`
* `vector/_indexof`
* `vector/_subvec`
There are _lots_ of other functions still to be tested.
This did reveal errors in `vector/_subvec`, which will be addressed in the next commit.
We used macros to make it easy to generate tests for each of the four vector types; this should be extensible to additional vector types in the future if needed.
This change uses the first command-line argument as the problem, which is assumed to be a namespace under `propeller.problems`. This will load the `instructions` and `error-function` from that namespace. If no problem is specified, then a (hopefully) helpful error is generated and the programs exits.
This allows us to call Propeller with calls such as:
```
lein run software.smallest
```
This creates a `push/utils/globals/cljc` similar to that created by @mcgirjau and moved the `max-stack-items` def to that namespace, updating `polymorphic` as necessary.