* rename force_wrap to force
* add a bunch of builder methods to Term<Name>
* refactor one tiny location to show off builder methods
* split generate into `generate` and `generate_test`
* create wrap_as_multi_validator function
Co-authored-by: Kasey White <kwhitemsg@gmail.com>
And disable multi-patterns clauses. I was originally just controlling
whether we did disable that from the parser but then I figured we
could actually support multi-patterns clauses quite easily by simply
desugaring a multi-pattern into multiple clauses.
This is only a syntactic sugar, which means that the cost of writing
that on-chain is as expensive as writing the fully expanded form; yet
it seems like a useful shorthand; especially for short clause
expressions.
This commit however disables multi-pattern when clauses, which we do
not support in the code-generation. Instead, one pattern on tuples for
that.
Isolated doc comments causes the compiler to panic with:
```
'no consecutive empty lines'
```
This is reproducible when doc comments are wrapped in sandwich between
comments and newlines.
The typed-AST produced as a result of type-checking the program will
no longer contain unused let-bindings. They still raise warnings in
the code so that developers are aware that they are being ignore.
This is mainly done to prevent mistakes for people coming from an
imperative background who may think that things like:
```
let _ = foo(...)
```
should have some side-effects. It does not, and it's similar to
assigned variables that are never used / evaluated. We now properly
strip those elements from the AST when encountered and raise proper
warnings, even for discarded values.
It's generally a bad idea to use equality on enum variants because this won't trigger any compiler errors in the future yet could have hazardous effects if adding new variants. So it's usually preferrable to use exauhstive pattern matching and let the compiler warn missing cases in places where it matters.
This leads to more consistent formatting across entire Aiken programs.
Before that commit, only long expressions would be formatted on a
newline, causing non-consistent formatting and additional reading
barrier when looking at source code.
Programs also now take more vertical space, which is better for more
friendly diffing in version control systems (especially git).
It is now possible to leave a hole in a type annotation and have the compiler fill-in the expected type of us.
This is a pretty useful debugging tool when playing with complex functions.
The difference between 'FlexBreak' and 'Break(Mode::Strict/Flexible)' as always confused me; and turned out that the 'FlexBreak' thingy is never used. This is dead-code, so I removed it.
Rules are now as follows:
- If a pipeline contains a newline, then the entire pipeline is formatted over multiple lines.
- If it doesn't, then it's formatted as a single-line UNLESS it cannot fit; in which case, we fallback to multiline again.
This was a bit tricky and I ended up breaking things down a lot and
trying different path. This commit is the result of the most
satisfying one.
It introduces a new 'concept' and types: Definitions and Reference.
These elements are meant to reflect JSON pointers and JSON-schema
definitions which we now use for pretty much all user-defined
data-types.
In fact, Schemas are no longer inlined, but are always referencing
some schema under "definitions".
This indirection is necessary in order to cope with recursive types.
And while it's only truly necessary for recursive types, using it
consistently makes it both easier to produce and easier to consume.
---
The blueprint generation for recursive types here also works thanks to
the 'Definitions' data-structure wrapper around a BTreeMap. This uses
a strategy where:
(1) schemas are only generated if they haven't been seen before
(2) schemas are marked as seen BEFORE actually being generated (to
effectively stop a recursive generation).
This relies on one important aspect: the key must be uniquely
identifying a given schema. Which means that we have to monomorphize
data-types with generic parameters also here, and use keys that are
specialized in one data-type.
---
In this large overhaul we've also lost one thing which I didn't bother
re-introducing yet to keep the work manageable: title for record
fields. Before, we use to pull those from record constructor when
available, yet now, every record constructor has been replaced by a
`$ref`. We could theoritically attach a title to the reference. I'll
try to quickly add that in a later commit.