- Zig 78.6%
- JavaScript 13.4%
- TypeScript 7.9%
|
injuly
f4edda4eb2
Adopt the new `std.Io` interface. This codebase now works with zig master as of the time of writing. **Note**: this commit was authored originally using OpenCode big-pickle, then reviewed a human (me). |
||
|---|---|---|
| .github/workflows | chore: fix benchmark builds | |
| benchmark | chore: fix benchmark builds | |
| src | chore: update code with zig master | |
| tools | chore: update code with zig master | |
| .gitignore | chore: update code with zig master | |
| build.zig | chore: upgrade to zig 0.16/master | |
| build.zig.zon | chore: update code with zig master | |
| LICENSE | chore: update license to MIT | |
| pre-commit | feat(astgen): Add a (generated) child iterator for AST nodes | |
| README.md | chore: update README | |
Jam
A high-performance JavaScript parser and semantic analyzer built from the ground up. Work in progress!
Goals
- Competitive in performance with existing tools.
- Support JS, JSX, and TypeScript out of the box.
- And the
<script>part of VueJS code.
- And the
- Single, small binary.
- Support data flow analysis and call-graphs with an accessible API.
- Expose a capable parsing and scope resolution, such that a bundler, minifier, etc., can be built on top of it.
- API to write lint rules with zig.
- Custom JavaScript plugins.
Roadmap
- Phase 1:
- A fast, 100% Spec compliant JavaScript parser.
- Port ESLint scope to Zig
- JSX parsing.
- Semantic analysis: Control Flow Graphs (WIP).
- TypeScript parsing (WIP).
- Runtime for a linter, with Zig plugin support.
- Formatter with a language agnostic backend.
- Alpha release
- Simple linter with all the base rules from ESLint.
- A prototype for the jam formatter
- Beta release
- Data flow analysis and taint checking
Local development
I've tried to keep the development process hassle-free. You need only a Zig compiler (and optionally an environment variable) to get going.
If you still face any issues, feel free to open an issue
or reach out to me on discord (@in.july), twitter, or e-mail.
I usually respond within a day.
NOTE: If you're willing to contribute, It's a good idea to copy the contents of ./pre-commit to your
./.git/hooks/pre-commit. This will ensure you didn't break any existing functionality before letting you commit changes.
Basic setup
- Ensure you have a
masterbuild of the zig compiler – to seamlessly switch between multiple zig versions, I recommend using zvm. - Clone this project into your development machine.
- Run
zig build run -- <path-to-file.js>to see a parsed AST for the given file. - Run
zig build testto run the unit tests. - Run
zig build bench-parserto run the parser benchmarks.
Checking ECMAScript conformance
To avoid regressions and keep track of spec compliance, we use a results.json and babel-results.json file –
their formats are explained in the tools README.
You'll need to set the JAM_TESTS_262_DIR environment variable to the path of a cloned tc39/test262-parser-tests repository:
git clone --depth 1 https://github.com/tc39/test262-parser-tests.git /tmp/test262-parser-tests
# `tools/ec262-tests` can find the tests if you set the environment variable.
export JAM_TESTS_262_DIR=/tmp/test262-parser-tests
To compare your changes with the existing test results, run zig build test262 -- compare ./tools/results.json.
If it exits normally, you didn't break anything!
To update the test results when you increase conformance, run zig build test262 > ./tools/results.json.
Currently, the format of the results.json file is roughly as follows:
{
// % of test files that either: a) parsed incorrectly, or b) failed to parse.
"fail_percent": 35.703479576399396,
// % of test files that were parsed correctly.
"pass_percent": 64.2965204236006,
// number of test files that parsed but had an incorrect syntax tree.
"unmatching_ast_count": 17,
// results for individual test cases:
"test_cases": {
"2db5219f0ac5dd71.js": "parse_error",
"c532e126a986c1d4.js": "pass",
"d532e126a986c1d4.js": "ast_no_match",
// ...goes on for a few thousand lines...