API mostly mirrors Rust version.
You can grab the latest release on Releases page.
- Files prefixed with
web-
are designed to work in the browser - Files prefixes with
nodejs-
are for Node.js only
Alternatively you can include web version from GitHub pages:
<script type="text/javascript" src="https://lib-ruby-parser.github.io/wasm-bindings/lib-ruby-parser.js">
</script>
please note, this URL is not going to be stable or versioned. Moreover, GitHub pages always host what's in the master branch, so better use proper vendoring. This URL is for quick testing only.
If you use vendored version:
- for Node.js:
- make sure that
.wasm
file is callednodejs-lib-ruby-parser.wasm
- put in the same folder as your JS file, it uses a relative hardcoded
require
- make sure that
- for web version:
- name of the
wasm
file is inferred from thejs
file, i.e. for/a/b/c.js
WASM file must be available at/a/b/c.wasm
. JS file literally callsdocument.currentScript.src.replace(/.js$/, '.wasm')
to get WASM file URL.
- name of the
Once both JS and WASM files are included:
- for Node.js run
const LibRubyParser = require('./path/to/nodejs-lib-ruby-parser.js')
- or, in browser,
LibRubyParser
becomes globally available, however, there's an important note. In browser WASM files are loaded asynchronously, and so your code must wait for WASM code to be loaded and executed, there's a hook for that:
LibRubyParser.onLoad(() => {
// lib-ruby-parser is ready to be used
})
const parserResult = LibRubyParser.parse('2 + 2')
here parserResult
is an instance of LibRubyParser.ParserResult
class that fully mirrors Rust API. It has fields:
ast
-undefined | LibRubyParser.Node
,Node
class has a bunch of subclasses located underLibRubyParser.nodes
namespacetokens
-Array<LibRubyParser.Token>
, every token hastoken_type
,token_value
,loc
diagnostics
-Array<LibRubyParser.Diagnostic>
, every diagnostic haslevel
,message
,loc
. All message variants are placed underLibRubyParser.messages
namespace, all of them are inherited fromLibRubyParser.DiagnsoticMessage
class.comments
-Array<LibRubyParser.Comment>
, every comment haslocation
andkind
.magic_comments
-Array<LibRubyParser.MagicComment>
, every magic comment haskind
,key_l
,value_l
input
-LibRubyParser.DecodedInput
withname
,lines
andbytes
It is possible to pass buffer name as the second argument, "(eval)"
is the default value:
const parserResult = LibRubyParser.parse('2 + 2', 'filename.rb')
It is also possible to specify custom decoder if your code has encoding different from UTF-8/ASCII-8BIT/BINARY
:
function decoder(encoding, input) {
// encoding is a string taked from `# encoding: ...` magic comment
// input is a Uint8Array of raw bytes
}
const parserResult = LibRubyParser.parse('2 + 2', null, decoder);
To return decoded input simply return
a new Uint8Array
array.
To return decoding error simply throw
a string with message (that you'll later get back in .diagnostics
list).
Results recoded on 10 Dec 2021:
Rust:
1.7832756400
Ruby:
4.865621000062674
WASM (Node.js):
9.535977154970169
WASM (Headless Chrome):
7.8802999999523164
To run it locally make sure to compile and test Node.js and web versions:
$ TARGET=no-modules make tests/no-modules
$ TARGET=nodejs make tests/nodejs
and run benchmarks:
$ make benchmark/compare
# prints to stdout
$ make benchmark/record
# prints to ./benchmark-out file