* New parser built with Winnow
This new parser uses [winnow](docs.rs/winnow) to replace the handwritten recursive parser.
## Differences
I think the Winnow parser is more readable than handwritten one, due to reusing standard combinators. If you have a parsre like `p` or `q` you can combine them with standard functions like `repeat(0..4, p)`, `opt(p)`, `alt((p, q))` and `separated1(p, ", ")`. This IMO makes it more readable once you know what those standard functions do.
It's also more accurate now -- e.g. the parser no longer swallows whitespace between comments, or inserts it where there was none before. It no longer changes // comments to /* comments depending on the surrounding whitespace.
Primary form of testing was running the same KCL program through both the old and new parsers and asserting that both parsers produce the same AST. See the test `parser::parser_impl::tests::check_parsers_work_the_same`. But occasionally the new and old parsers disagree. This is either:
- Innocuous (e.g. disagreeing on whether a comment starts at the preceding whitespace or at the //)
- Helpful (e.g. new parser recognizes comments more accurately, preserving the difference between // and /* comments)
- Acceptably bad (e.g. new parser sometimes outputs worse error messages, TODO in #784)
so those KCL programs have their own unit tests in `parser_impl.rs` demonstrating the behaviour.
If you'd like to review this PR, it's arguably more important to review changes to the existing unit tests rather than the new parser itself. Because changes to the unit tests show where my parser changes behaviour -- usually for the better, occasionally for the worse (e.g. a worse error message than before). I think overall the improvements are worth it that I'd like to merge it without spending another week fixing it up -- we can fix the error messages in a follow-up PR.
## Performance
| Benchmark | Old parser (this branch) | New parser (this branch) | Speedup |
| ------------- | ------------- | ------------- | ------------- |
| Pipes on pipes | 922 ms | 42 ms | 21x |
| Kitt SVG | 148 ms | 7 ms | 21x |
There's definitely still room to improve performance:
- https://github.com/KittyCAD/modeling-app/issues/839
- https://github.com/KittyCAD/modeling-app/issues/840
## Winnow
Y'all know I love [Nom](docs.rs/nom) and I've blogged about it a lot. But I'm very happy using Winnow, a fork. It's got some really nice usability improvements. While writing this PR I found some bugs or unclear docs in Winnow:
- https://github.com/winnow-rs/winnow/issues/339
- https://github.com/winnow-rs/winnow/issues/341
- https://github.com/winnow-rs/winnow/issues/342
- https://github.com/winnow-rs/winnow/issues/344
The maintainer was quick to close them and release new versions within a few hours, so I feel very confident building the parser on this library. It's a clear improvement over Nom and it's used in toml-edit (and therefore within Cargo) and Gitoxide, so it's becoming a staple of the Rust ecosystem, which adds confidence.
Closes#716Closes#815Closes#599
* Basic CRA to Vite conversion
* Restore ESLint support
* Remove semicolons from vite config
* Add vite client types to tsconfig
* Migrate to Vitest for testing (not working on Mac)
* some test progress (#175)
* some test progress
* something maybe working
* remove local lib
* small clean up
* tweaks
* fix dependency
* clean up deps
* remove vitest import
* vitest config is needed even though we're not using vitest
* more tweaks to vite config
---------
Co-authored-by: Kurt Hutten <k.hutten@protonmail.ch>
* port recast to rust with massaged serialisation
* remove logs
* fix the last of white space test failures
* remove ts recastor
* clean up imports
* use serde serialise features
* unneeded async
* final clean up recast.ts
* more clean up tweaks
* improve Rust BinaryPart types
* Comments, fix warnings
* Run clippy --fix
* Remove unused variable
* serialise none_code_nodes manual to force strings to numbers
---------
Co-authored-by: Adam Chalmers <adam.s.chalmers@gmail.com>
We can create a enginelessExecutor that can be used for many of the
executor tests that will be much more performant for tests that don't
need the engine to actually do any modeling work.
* Intital async of executor
The execture now sends websocket message instead of calling functions
directly from the engine, When it does so it holds onto the id.
The engine is still returning geo/polys directly but I'm working make it
so that the UI doesn't need to know about that, so that we can switch
over the streaming ui.
Things left to do:
- it is still making both direct function calls and websockets, and the former should be removed.
- It does highlighting of segments and sourceRanges not through websockets and that needs to be fixed.
- Tests have not been adjusted for these changes.
- Selecting the head of a segment is not working correctly again yet.
* Rough engine prep changes (#135)
* rough changes for engine prep
* mouse movements working again
* connect to engine for startsketch, line, close and extrude
* Refactor getNodePathFromSourceRange
getNodePathFromSourceRange wouldn't go as deep as it should have,
stopping at pipe expressions, when it should have followed as deep
into the ast as possible.
The fact that it stopped early then had other part of the code base that
expected this behaviour and it effected a lot, so a rather large refactor
* overhaul of getNodePathFromSourceRange
* quick fix for moreNodePathFromSourceRange
* minor bugs in moreNodePathFromSourceRange
* couple more tests
* add moveValueIntoNewVariable
* add UI for replacing valuse with variable
* update button text
* button style tweak
* Remove duplication constraint ast transforms
* giveSketchFnCallTag to return if line already had a tag
* remove duplication
* update tag name to referenceSegName
* Update transform shape to return key details about the transform
* add modal to hor vert distance workflow
* fix browser env stuff from breaking tests
* fmt
* add segLen help to lang std
* adding helpers functions to sketchConstraints
* update tokeniser tests because they were annoying me not being 100%
* compare async lexer with sync lexer instead
* add helper functions
* remove unneeded nesting
* update add ast modifier function for angledLine
* initial equal ast modification
It adds a tag to the primary line, and converts any secondary lines to angledLine, but doesn't reference the taged/primary line yet
* Update fn call with refernce to previous line using segLen
* add test for giveSketchFnCallTag
* fix excutor bug, executing call expression in array expression
* fix small issue in executor
* add CallExpressions to BinaryExpressions
* add unary Expressions
* tweaks to unaryExpression logic
* add recasting for unaryExpressions and CallExpressions in BinaryExpressions
* ensure pipe substitution info is passed down to unary expressions and others
* allow binary expressions in function argumentns
* inital setup, new way of organising sketch fn transforms
Starting with equal length
* overhaul equalLength button
* add equal length support for angledLine
* line with one variable supports signed legLength
* fix indentation when recasting long arrayExpressions in a pipeExpression
* improve modifyAst consision
* further modify ast tidy
* equalLength transfroms far angledLineOfXLength
* add transforms for line-yRelative
* add equal constraint for angledLineOfYLength
* quick test fix
* add equal length constrain transforms for lineTo
* add equal length constraints for angledLineToX
* add equalLength constraints for angledLineToY
* test tidy
* setup new vertical-horizontal constraints
* Add equal Length constraints for vertical/horizontal lines
* migrate old tests, and refactor callback tag
* tweaks and refactor horzVert component
* fix leg len with small negative leg length
* functional sketch working
With old sketch block still there
* get all version of lines working with add line and update line
* remove old ui state types
* some clean up
* rename some things
* add todo for multi cursor
* shorten useStore repitition
* small type improvement
* big overhaul to group sketch function and they ast modifying helpers together
* unneeded tweak
* ruthlessly rip out sketch logic
* clean up path keyword
* getting sketch on face working again with all the new sketch line types
* add a bunch of tests and re-arrage file structure