prism 0.19.0 → 0.20.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +29 -1
- data/Makefile +5 -0
- data/README.md +8 -6
- data/config.yml +236 -38
- data/docs/build_system.md +19 -2
- data/docs/cruby_compilation.md +27 -0
- data/docs/parser_translation.md +34 -0
- data/docs/parsing_rules.md +19 -0
- data/docs/releasing.md +3 -3
- data/docs/ruby_api.md +1 -1
- data/docs/serialization.md +17 -5
- data/ext/prism/api_node.c +101 -81
- data/ext/prism/extension.c +74 -11
- data/ext/prism/extension.h +1 -1
- data/include/prism/ast.h +1699 -504
- data/include/prism/defines.h +8 -0
- data/include/prism/diagnostic.h +39 -2
- data/include/prism/encoding.h +10 -0
- data/include/prism/options.h +40 -14
- data/include/prism/parser.h +33 -17
- data/include/prism/util/pm_buffer.h +9 -0
- data/include/prism/util/pm_constant_pool.h +7 -0
- data/include/prism/util/pm_newline_list.h +0 -11
- data/include/prism/version.h +2 -2
- data/include/prism.h +19 -2
- data/lib/prism/debug.rb +11 -5
- data/lib/prism/dot_visitor.rb +36 -14
- data/lib/prism/dsl.rb +22 -22
- data/lib/prism/ffi.rb +2 -2
- data/lib/prism/node.rb +1020 -737
- data/lib/prism/node_ext.rb +2 -2
- data/lib/prism/parse_result.rb +17 -9
- data/lib/prism/serialize.rb +53 -29
- data/lib/prism/translation/parser/compiler.rb +1831 -0
- data/lib/prism/translation/parser/lexer.rb +335 -0
- data/lib/prism/translation/parser/rubocop.rb +37 -0
- data/lib/prism/translation/parser.rb +163 -0
- data/lib/prism/translation.rb +11 -0
- data/lib/prism.rb +1 -0
- data/prism.gemspec +12 -5
- data/rbi/prism.rbi +150 -88
- data/rbi/prism_static.rbi +15 -3
- data/sig/prism.rbs +996 -961
- data/sig/prism_static.rbs +123 -46
- data/src/diagnostic.c +259 -219
- data/src/encoding.c +4 -8
- data/src/node.c +2 -6
- data/src/options.c +24 -5
- data/src/prettyprint.c +174 -42
- data/src/prism.c +1136 -328
- data/src/serialize.c +12 -9
- data/src/token_type.c +353 -4
- data/src/util/pm_buffer.c +11 -0
- data/src/util/pm_constant_pool.c +12 -11
- data/src/util/pm_newline_list.c +2 -14
- metadata +10 -3
- data/docs/building.md +0 -29
data/docs/build_system.md
CHANGED
@@ -53,7 +53,7 @@ Because of course those files are not part of the git repository.
|
|
53
53
|
|
54
54
|
### Building prism as part of CRuby
|
55
55
|
|
56
|
-
[This script](https://github.com/ruby/ruby/blob/
|
56
|
+
[This script](https://github.com/ruby/ruby/blob/5124f9ac7513eb590c37717337c430cb93caa151/tool/sync_default_gems.rb#L399-L422) imports prism sources in CRuby.
|
57
57
|
|
58
58
|
The script generates the templates when importing.
|
59
59
|
|
@@ -71,4 +71,21 @@ and links to `libprism.a` (to avoid exporting symbols, so no conflict when insta
|
|
71
71
|
|
72
72
|
### Building prism as part of JRuby
|
73
73
|
|
74
|
-
TODO,
|
74
|
+
TODO, similar to TruffleRuby.
|
75
|
+
|
76
|
+
### Building prism from source as a C library
|
77
|
+
|
78
|
+
All of the source files match `src/**/*.c` and all of the headers match `include/**/*.h`.
|
79
|
+
|
80
|
+
If you want to build prism as a shared library and link against it, you should compile with:
|
81
|
+
|
82
|
+
* `-fPIC -shared` - Compile as a shared library
|
83
|
+
* `-DPRISM_EXPORT_SYMBOLS` - Export the symbols (by default nothing is exported)
|
84
|
+
|
85
|
+
#### Flags
|
86
|
+
|
87
|
+
`make` respects the `MAKEFLAGS` environment variable. As such, to speed up the build you can run:
|
88
|
+
|
89
|
+
```
|
90
|
+
MAKEFLAGS="-j10" bundle exec rake compile
|
91
|
+
```
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# Compiling Prism's AST
|
2
|
+
|
3
|
+
One important class of consumers of Prism's AST is compilers. Currently [CRuby](https://github.com/ruby/ruby), [JRuby](https://github.com/jruby/jruby), [TruffleRuby](https://github.com/oracle/truffleruby), and [Natalie](https://github.com/natalie-lang/natalie) have all built compilation code on top of Prism's AST.
|
4
|
+
|
5
|
+
This document will describe, at a high level, how CRuby's compilation of Prism's AST works.
|
6
|
+
|
7
|
+
As described in the [build system documentation](build_system.md), there is a "push" Webhook set up within the Prism repo triggered on each new commit to send information about the commit to [git.ruby-lang.org](https://github.com/ruby/git.ruby-lang.org). This in turn runs [a script](https://github.com/ruby/ruby/blob/master/tool/sync_default_gems.rb) to sync over new changes in Prism to their corresponding files in Ruby. Any failures in this sync script will show alerts in the #alerts-sync channel in the RubyLang Slack. The result of this step is that files are synced from Prism into ruby/ruby for its use. It is also worth noting that [`common.mk`](https://github.com/ruby/ruby/blob/master/common.mk) contains a list of Prism files which it needs to correctly compile. If there are new Prism files added, this file should also be updated.
|
8
|
+
|
9
|
+
ruby/ruby uses the Prism code to generate an AST from which it can generate instruction sequences. Compilation in ruby/ruby has three main steps:
|
10
|
+
|
11
|
+
1. Compute an AST
|
12
|
+
|
13
|
+
Syncing over the Prism code allows ruby/ruby to compute the AST using Prism. It currently does this within [`iseq.c`](https://github.com/ruby/ruby/blob/master/iseq.c) using the `pm_parser_init` fuction.
|
14
|
+
|
15
|
+
2. Run a first pass of compilation
|
16
|
+
|
17
|
+
Once the AST has been created, it is recursively descended in order to compute the appropriate instruction sequences. This is the crux of compilation, and we go into more detail about nuances in the following paragraphs.
|
18
|
+
|
19
|
+
The code for this step is almost exclusively in [`prism_compile.c`](https://github.com/ruby/ruby/blob/master/prism_compile.c). The main function used for compilation is `pm_compile_node` which is essentially a huge switch statement over practically every node type which computes the appropriate instruction sequences for that node type. There are several convenience helpers, such as `PM_COMPILE`, `PM_COMPILE_POPPED`, `PM_COMPILE_NOT_POPPED` which all call into the `pm_compile_node` function.
|
20
|
+
|
21
|
+
There are also several functions, like `parse_string`, `parse_integer` which consume Prism nodes and return CRuby values. These are all called for their relevant types within the big switch statement.
|
22
|
+
|
23
|
+
The Prism compiler also uses a concept of "scope nodes" which are not standard Prism nodes in the AST, but instead nodes constructed within the compiler for the sole purpose of making compilation easier. Scope nodes are defined in [`prism_compile.h`](https://github.com/ruby/ruby/blob/master/prism_compile.h) and store information such as locals, local table size, local depth offset and the index lookup tables. Scope nodes can be generated for node types which have their own "scope".
|
24
|
+
|
25
|
+
3. Run an optimization pass of compilation
|
26
|
+
|
27
|
+
After the instruction sequences are initially computed, there is an existing (non-Prism based) optimization pass of the instruction sequences. There are several optimizations currently inlined into step 2, however, most of them happen in this step. Specifically, any peephole optimizations happen in this step. By the end of step 2, however, the instruction sequences take the same form regardless of if the initial AST was generated by Prism or not. Therefore, step 3 is agnostic to the parser, and should not require any Prism specific code.
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# parser translation
|
2
|
+
|
3
|
+
Prism ships with the ability to translate its syntax tree into the syntax tree used by the [whitequark/parser](https://github.com/whitequark/parser) gem. This allows you to use tools built on top of the `parser` gem with the `prism` parser.
|
4
|
+
|
5
|
+
## Usage
|
6
|
+
|
7
|
+
The `parser` gem provides multiple parsers to support different versions of the Ruby grammar. This includes all of the Ruby versions going back to 1.8, as well as third-party parsers like MacRuby and RubyMotion. The `prism` gem provides another parser that uses the `prism` parser to build the syntax tree.
|
8
|
+
|
9
|
+
You can use the `prism` parser like you would any other. After requiring the parser, you should be able to call any of the regular `Parser::Base` APIs that you would normally use.
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
require "prism/translation/parser"
|
13
|
+
|
14
|
+
Prism::Translation::Parser.parse_file("path/to/file.rb")
|
15
|
+
```
|
16
|
+
|
17
|
+
### RuboCop
|
18
|
+
|
19
|
+
To run RuboCop using the `prism` gem as the parser, you will need to require the `prism/translation/parser/rubocop` file. This file injects `prism` into the known options for both `rubocop` and `rubocop-ast`, such that you can specify it in your `.rubocop.yml` file. Unfortunately `rubocop` doesn't support any direct way to do this, so we have to get a bit hacky.
|
20
|
+
|
21
|
+
First, set the `TargetRubyVersion` in your RuboCop configuration file to `80_82_73_83_77.33`. This is the version of Ruby that `prism` reports itself as. (The leading numbers are the ASCII values for `PRISM`.)
|
22
|
+
|
23
|
+
```yaml
|
24
|
+
AllCops:
|
25
|
+
TargetRubyVersion: 80_82_73_83_77.33
|
26
|
+
```
|
27
|
+
|
28
|
+
Now when you run `rubocop` you will need to require the `prism/translation/parser/rubocop` file before executing so that it can inject the `prism` parser into the known options.
|
29
|
+
|
30
|
+
```
|
31
|
+
bundle exec ruby -rprism/translation/parser/rubocop $(bundle exec which rubocop)
|
32
|
+
```
|
33
|
+
|
34
|
+
This should run RuboCop using the `prism` parser.
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# Rules
|
2
|
+
|
3
|
+
This document contains information related to the rules of the parser for Ruby source code.
|
4
|
+
|
5
|
+
As an example, in the documentation of many of the fields of nodes, it's mentioned that a field follows the lexing rules for `identifier` or `constant`. This document describes what those rules are.
|
6
|
+
|
7
|
+
## Constants
|
8
|
+
|
9
|
+
Constants in Ruby begin with an upper-case letter. This is followed by any number of underscores, alphanumeric, or non-ASCII characters. The definition of "alphanumeric" and "upper-case letter" are encoding-dependent.
|
10
|
+
|
11
|
+
## Non-void expression
|
12
|
+
|
13
|
+
Most expressions in CRuby are non-void. This means the expression they represent resolves to a value. For example, `1 + 2` is a non-void expression, because it resolves to a method call. Even things like `class Foo; end` is a non-void expression, because it returns the last evaluated expression in the body of the class (or `nil`).
|
14
|
+
|
15
|
+
Certain nodes, however, are void expressions, and cannot be combined to form larger expressions. For example, `BEGIN {}`, `END {}`, `alias foo bar`, and `undef foo`.
|
16
|
+
|
17
|
+
## Identifiers
|
18
|
+
|
19
|
+
Identifiers in Ruby begin with an underscore or lower-case letter. This is followed by any number of underscores, alphanumeric, or non-ASCII characters. The definition of "alphanumeric" and "lower-case letter" are encoding-dependent.
|
data/docs/releasing.md
CHANGED
@@ -13,13 +13,13 @@ To release a new version of Prism, perform the following steps:
|
|
13
13
|
* `ext/prism/extension.h` in the `EXPECTED_PRISM_VERSION` macro
|
14
14
|
* `include/prism/version.h` in the version macros
|
15
15
|
* `javascript/package.json` in the `version` field
|
16
|
-
* `rust/prism-sys/tests/utils_tests.rs` in the `version_test` function
|
16
|
+
* `rust/ruby-prism-sys/tests/utils_tests.rs` in the `version_test` function
|
17
17
|
* `templates/java/org/prism/Loader.java.erb` in the `load` function
|
18
18
|
* `templates/javascript/src/deserialize.js.erb` in the version constants
|
19
19
|
* `templates/lib/prism/serialize.rb.erb` in the version constants
|
20
20
|
* Run `bundle install` to update the `Gemfile.lock` file.
|
21
|
-
* Update `rust/prism-sys/Cargo.toml` to match the new version and run `cargo build`
|
22
|
-
* Update `rust/prism/Cargo.toml` to match the new version and run `cargo build`
|
21
|
+
* Update `rust/ruby-prism-sys/Cargo.toml` to match the new version and run `cargo build`
|
22
|
+
* Update `rust/ruby-prism/Cargo.toml` to match the new version and run `cargo build`
|
23
23
|
* Commit all of the updated files.
|
24
24
|
|
25
25
|
## Publishing
|
data/docs/ruby_api.md
CHANGED
@@ -14,7 +14,7 @@ The full API is documented below.
|
|
14
14
|
|
15
15
|
## API
|
16
16
|
|
17
|
-
* `Prism.dump(source
|
17
|
+
* `Prism.dump(source)` - parse the syntax tree corresponding to the given source string, and serialize it to a string
|
18
18
|
* `Prism.dump_file(filepath)` - parse the syntax tree corresponding to the given source file and serialize it to a string
|
19
19
|
* `Prism.lex(source)` - parse the tokens corresponding to the given source string and return them as an array within a parse result
|
20
20
|
* `Prism.lex_file(filepath)` - parse the tokens corresponding to the given source file and return them as an array within a parse result
|
data/docs/serialization.md
CHANGED
@@ -51,12 +51,21 @@ The comment type is one of:
|
|
51
51
|
| location | the location of the key of the magic comment |
|
52
52
|
| location | the location of the value of the magic comment |
|
53
53
|
|
54
|
-
###
|
54
|
+
### error
|
55
55
|
|
56
56
|
| # bytes | field |
|
57
57
|
| --- | --- |
|
58
|
-
| string |
|
59
|
-
| location | the location in the source this
|
58
|
+
| string | error message (ASCII-only characters) |
|
59
|
+
| location | the location in the source this error applies to |
|
60
|
+
| `1` | the level of the error: `0` for `fatal` |
|
61
|
+
|
62
|
+
## warning
|
63
|
+
|
64
|
+
| # bytes | field |
|
65
|
+
| --- | --- |
|
66
|
+
| string | warning message (ASCII-only characters) |
|
67
|
+
| location | the location in the source this warning applies to |
|
68
|
+
| `1` | the level of the warning: `0` for `default` and `1` for `verbose` |
|
60
69
|
|
61
70
|
## Structure
|
62
71
|
|
@@ -82,9 +91,9 @@ The header is structured like the following table:
|
|
82
91
|
| magic comment* | magic comments |
|
83
92
|
| location? | the optional location of the `__END__` keyword and its contents |
|
84
93
|
| varuint | number of errors |
|
85
|
-
|
|
94
|
+
| error* | errors |
|
86
95
|
| varuint | number of warnings |
|
87
|
-
|
|
96
|
+
| warning* | warnings |
|
88
97
|
| `4` | content pool offset |
|
89
98
|
| varuint | content pool size |
|
90
99
|
|
@@ -175,9 +184,12 @@ The final argument to `pm_serialize_parse` is an optional string that controls t
|
|
175
184
|
| ... | the encoding bytes |
|
176
185
|
| `1` | frozen string literal |
|
177
186
|
| `1` | suppress warnings |
|
187
|
+
| `1` | syntax version, see [pm_options_version_t](https://github.com/ruby/prism/blob/main/include/prism/options.h) for valid values |
|
178
188
|
| `4` | the number of scopes |
|
179
189
|
| ... | the scopes |
|
180
190
|
|
191
|
+
Scopes are ordered from the outermost scope to the innermost one.
|
192
|
+
|
181
193
|
Each scope is layed out as follows:
|
182
194
|
|
183
195
|
| # bytes | field |
|
data/ext/prism/api_node.c
CHANGED
@@ -171,7 +171,7 @@ pm_location_new(pm_parser_t *parser, const uint8_t *start, const uint8_t *end, V
|
|
171
171
|
|
172
172
|
VALUE
|
173
173
|
pm_token_new(pm_parser_t *parser, pm_token_t *token, rb_encoding *encoding, VALUE source) {
|
174
|
-
ID type = rb_intern(
|
174
|
+
ID type = rb_intern(pm_token_type_name(token->type));
|
175
175
|
VALUE location = pm_location_new(parser, token->start, token->end, source);
|
176
176
|
|
177
177
|
VALUE argv[] = {
|
@@ -1362,23 +1362,27 @@ pm_ast_new(pm_parser_t *parser, pm_node_t *node, rb_encoding *encoding) {
|
|
1362
1362
|
#line 144 "api_node.c.erb"
|
1363
1363
|
case PM_BLOCK_LOCAL_VARIABLE_NODE: {
|
1364
1364
|
pm_block_local_variable_node_t *cast = (pm_block_local_variable_node_t *) node;
|
1365
|
-
VALUE argv[
|
1365
|
+
VALUE argv[3];
|
1366
|
+
|
1367
|
+
// flags
|
1368
|
+
#line 192 "api_node.c.erb"
|
1369
|
+
argv[0] = ULONG2NUM(node->flags & ~PM_NODE_FLAG_COMMON_MASK);
|
1366
1370
|
|
1367
1371
|
// name
|
1368
1372
|
#line 167 "api_node.c.erb"
|
1369
1373
|
assert(cast->name != 0);
|
1370
|
-
argv[
|
1374
|
+
argv[1] = rb_id2sym(constants[cast->name - 1]);
|
1371
1375
|
|
1372
1376
|
// location
|
1373
|
-
argv[
|
1377
|
+
argv[2] = pm_location_new(parser, node->location.start, node->location.end, source);
|
1374
1378
|
|
1375
|
-
rb_ary_push(value_stack, rb_class_new_instance(
|
1379
|
+
rb_ary_push(value_stack, rb_class_new_instance(3, argv, rb_cPrismBlockLocalVariableNode));
|
1376
1380
|
break;
|
1377
1381
|
}
|
1378
1382
|
#line 144 "api_node.c.erb"
|
1379
1383
|
case PM_BLOCK_NODE: {
|
1380
1384
|
pm_block_node_t *cast = (pm_block_node_t *) node;
|
1381
|
-
VALUE argv[
|
1385
|
+
VALUE argv[6];
|
1382
1386
|
|
1383
1387
|
// locals
|
1384
1388
|
#line 173 "api_node.c.erb"
|
@@ -1388,52 +1392,52 @@ pm_ast_new(pm_parser_t *parser, pm_node_t *node, rb_encoding *encoding) {
|
|
1388
1392
|
rb_ary_push(argv[0], rb_id2sym(constants[cast->locals.ids[index] - 1]));
|
1389
1393
|
}
|
1390
1394
|
|
1391
|
-
// locals_body_index
|
1392
|
-
#line 189 "api_node.c.erb"
|
1393
|
-
argv[1] = ULONG2NUM(cast->locals_body_index);
|
1394
|
-
|
1395
1395
|
// parameters
|
1396
1396
|
#line 155 "api_node.c.erb"
|
1397
|
-
argv[
|
1397
|
+
argv[1] = rb_ary_pop(value_stack);
|
1398
1398
|
|
1399
1399
|
// body
|
1400
1400
|
#line 155 "api_node.c.erb"
|
1401
|
-
argv[
|
1401
|
+
argv[2] = rb_ary_pop(value_stack);
|
1402
1402
|
|
1403
1403
|
// opening_loc
|
1404
1404
|
#line 180 "api_node.c.erb"
|
1405
|
-
argv[
|
1405
|
+
argv[3] = pm_location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source);
|
1406
1406
|
|
1407
1407
|
// closing_loc
|
1408
1408
|
#line 180 "api_node.c.erb"
|
1409
|
-
argv[
|
1409
|
+
argv[4] = pm_location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source);
|
1410
1410
|
|
1411
1411
|
// location
|
1412
|
-
argv[
|
1412
|
+
argv[5] = pm_location_new(parser, node->location.start, node->location.end, source);
|
1413
1413
|
|
1414
|
-
rb_ary_push(value_stack, rb_class_new_instance(
|
1414
|
+
rb_ary_push(value_stack, rb_class_new_instance(6, argv, rb_cPrismBlockNode));
|
1415
1415
|
break;
|
1416
1416
|
}
|
1417
1417
|
#line 144 "api_node.c.erb"
|
1418
1418
|
case PM_BLOCK_PARAMETER_NODE: {
|
1419
1419
|
pm_block_parameter_node_t *cast = (pm_block_parameter_node_t *) node;
|
1420
|
-
VALUE argv[
|
1420
|
+
VALUE argv[5];
|
1421
|
+
|
1422
|
+
// flags
|
1423
|
+
#line 192 "api_node.c.erb"
|
1424
|
+
argv[0] = ULONG2NUM(node->flags & ~PM_NODE_FLAG_COMMON_MASK);
|
1421
1425
|
|
1422
1426
|
// name
|
1423
|
-
argv[
|
1427
|
+
argv[1] = cast->name == 0 ? Qnil : rb_id2sym(constants[cast->name - 1]);
|
1424
1428
|
|
1425
1429
|
// name_loc
|
1426
1430
|
#line 183 "api_node.c.erb"
|
1427
|
-
argv[
|
1431
|
+
argv[2] = cast->name_loc.start == NULL ? Qnil : pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source);
|
1428
1432
|
|
1429
1433
|
// operator_loc
|
1430
1434
|
#line 180 "api_node.c.erb"
|
1431
|
-
argv[
|
1435
|
+
argv[3] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source);
|
1432
1436
|
|
1433
1437
|
// location
|
1434
|
-
argv[
|
1438
|
+
argv[4] = pm_location_new(parser, node->location.start, node->location.end, source);
|
1435
1439
|
|
1436
|
-
rb_ary_push(value_stack, rb_class_new_instance(
|
1440
|
+
rb_ary_push(value_stack, rb_class_new_instance(5, argv, rb_cPrismBlockParameterNode));
|
1437
1441
|
break;
|
1438
1442
|
}
|
1439
1443
|
#line 144 "api_node.c.erb"
|
@@ -2288,7 +2292,7 @@ pm_ast_new(pm_parser_t *parser, pm_node_t *node, rb_encoding *encoding) {
|
|
2288
2292
|
#line 144 "api_node.c.erb"
|
2289
2293
|
case PM_DEF_NODE: {
|
2290
2294
|
pm_def_node_t *cast = (pm_def_node_t *) node;
|
2291
|
-
VALUE argv[
|
2295
|
+
VALUE argv[13];
|
2292
2296
|
|
2293
2297
|
// name
|
2294
2298
|
#line 167 "api_node.c.erb"
|
@@ -2319,38 +2323,34 @@ pm_ast_new(pm_parser_t *parser, pm_node_t *node, rb_encoding *encoding) {
|
|
2319
2323
|
rb_ary_push(argv[5], rb_id2sym(constants[cast->locals.ids[index] - 1]));
|
2320
2324
|
}
|
2321
2325
|
|
2322
|
-
// locals_body_index
|
2323
|
-
#line 189 "api_node.c.erb"
|
2324
|
-
argv[6] = ULONG2NUM(cast->locals_body_index);
|
2325
|
-
|
2326
2326
|
// def_keyword_loc
|
2327
2327
|
#line 180 "api_node.c.erb"
|
2328
|
-
argv[
|
2328
|
+
argv[6] = pm_location_new(parser, cast->def_keyword_loc.start, cast->def_keyword_loc.end, source);
|
2329
2329
|
|
2330
2330
|
// operator_loc
|
2331
2331
|
#line 183 "api_node.c.erb"
|
2332
|
-
argv[
|
2332
|
+
argv[7] = cast->operator_loc.start == NULL ? Qnil : pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source);
|
2333
2333
|
|
2334
2334
|
// lparen_loc
|
2335
2335
|
#line 183 "api_node.c.erb"
|
2336
|
-
argv[
|
2336
|
+
argv[8] = cast->lparen_loc.start == NULL ? Qnil : pm_location_new(parser, cast->lparen_loc.start, cast->lparen_loc.end, source);
|
2337
2337
|
|
2338
2338
|
// rparen_loc
|
2339
2339
|
#line 183 "api_node.c.erb"
|
2340
|
-
argv[
|
2340
|
+
argv[9] = cast->rparen_loc.start == NULL ? Qnil : pm_location_new(parser, cast->rparen_loc.start, cast->rparen_loc.end, source);
|
2341
2341
|
|
2342
2342
|
// equal_loc
|
2343
2343
|
#line 183 "api_node.c.erb"
|
2344
|
-
argv[
|
2344
|
+
argv[10] = cast->equal_loc.start == NULL ? Qnil : pm_location_new(parser, cast->equal_loc.start, cast->equal_loc.end, source);
|
2345
2345
|
|
2346
2346
|
// end_keyword_loc
|
2347
2347
|
#line 183 "api_node.c.erb"
|
2348
|
-
argv[
|
2348
|
+
argv[11] = cast->end_keyword_loc.start == NULL ? Qnil : pm_location_new(parser, cast->end_keyword_loc.start, cast->end_keyword_loc.end, source);
|
2349
2349
|
|
2350
2350
|
// location
|
2351
|
-
argv[
|
2351
|
+
argv[12] = pm_location_new(parser, node->location.start, node->location.end, source);
|
2352
2352
|
|
2353
|
-
rb_ary_push(value_stack, rb_class_new_instance(
|
2353
|
+
rb_ary_push(value_stack, rb_class_new_instance(13, argv, rb_cPrismDefNode));
|
2354
2354
|
break;
|
2355
2355
|
}
|
2356
2356
|
#line 144 "api_node.c.erb"
|
@@ -3442,29 +3442,33 @@ pm_ast_new(pm_parser_t *parser, pm_node_t *node, rb_encoding *encoding) {
|
|
3442
3442
|
#line 144 "api_node.c.erb"
|
3443
3443
|
case PM_KEYWORD_REST_PARAMETER_NODE: {
|
3444
3444
|
pm_keyword_rest_parameter_node_t *cast = (pm_keyword_rest_parameter_node_t *) node;
|
3445
|
-
VALUE argv[
|
3445
|
+
VALUE argv[5];
|
3446
|
+
|
3447
|
+
// flags
|
3448
|
+
#line 192 "api_node.c.erb"
|
3449
|
+
argv[0] = ULONG2NUM(node->flags & ~PM_NODE_FLAG_COMMON_MASK);
|
3446
3450
|
|
3447
3451
|
// name
|
3448
|
-
argv[
|
3452
|
+
argv[1] = cast->name == 0 ? Qnil : rb_id2sym(constants[cast->name - 1]);
|
3449
3453
|
|
3450
3454
|
// name_loc
|
3451
3455
|
#line 183 "api_node.c.erb"
|
3452
|
-
argv[
|
3456
|
+
argv[2] = cast->name_loc.start == NULL ? Qnil : pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source);
|
3453
3457
|
|
3454
3458
|
// operator_loc
|
3455
3459
|
#line 180 "api_node.c.erb"
|
3456
|
-
argv[
|
3460
|
+
argv[3] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source);
|
3457
3461
|
|
3458
3462
|
// location
|
3459
|
-
argv[
|
3463
|
+
argv[4] = pm_location_new(parser, node->location.start, node->location.end, source);
|
3460
3464
|
|
3461
|
-
rb_ary_push(value_stack, rb_class_new_instance(
|
3465
|
+
rb_ary_push(value_stack, rb_class_new_instance(5, argv, rb_cPrismKeywordRestParameterNode));
|
3462
3466
|
break;
|
3463
3467
|
}
|
3464
3468
|
#line 144 "api_node.c.erb"
|
3465
3469
|
case PM_LAMBDA_NODE: {
|
3466
3470
|
pm_lambda_node_t *cast = (pm_lambda_node_t *) node;
|
3467
|
-
VALUE argv[
|
3471
|
+
VALUE argv[7];
|
3468
3472
|
|
3469
3473
|
// locals
|
3470
3474
|
#line 173 "api_node.c.erb"
|
@@ -3474,34 +3478,30 @@ pm_ast_new(pm_parser_t *parser, pm_node_t *node, rb_encoding *encoding) {
|
|
3474
3478
|
rb_ary_push(argv[0], rb_id2sym(constants[cast->locals.ids[index] - 1]));
|
3475
3479
|
}
|
3476
3480
|
|
3477
|
-
// locals_body_index
|
3478
|
-
#line 189 "api_node.c.erb"
|
3479
|
-
argv[1] = ULONG2NUM(cast->locals_body_index);
|
3480
|
-
|
3481
3481
|
// operator_loc
|
3482
3482
|
#line 180 "api_node.c.erb"
|
3483
|
-
argv[
|
3483
|
+
argv[1] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source);
|
3484
3484
|
|
3485
3485
|
// opening_loc
|
3486
3486
|
#line 180 "api_node.c.erb"
|
3487
|
-
argv[
|
3487
|
+
argv[2] = pm_location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source);
|
3488
3488
|
|
3489
3489
|
// closing_loc
|
3490
3490
|
#line 180 "api_node.c.erb"
|
3491
|
-
argv[
|
3491
|
+
argv[3] = pm_location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source);
|
3492
3492
|
|
3493
3493
|
// parameters
|
3494
3494
|
#line 155 "api_node.c.erb"
|
3495
|
-
argv[
|
3495
|
+
argv[4] = rb_ary_pop(value_stack);
|
3496
3496
|
|
3497
3497
|
// body
|
3498
3498
|
#line 155 "api_node.c.erb"
|
3499
|
-
argv[
|
3499
|
+
argv[5] = rb_ary_pop(value_stack);
|
3500
3500
|
|
3501
3501
|
// location
|
3502
|
-
argv[
|
3502
|
+
argv[6] = pm_location_new(parser, node->location.start, node->location.end, source);
|
3503
3503
|
|
3504
|
-
rb_ary_push(value_stack, rb_class_new_instance(
|
3504
|
+
rb_ary_push(value_stack, rb_class_new_instance(7, argv, rb_cPrismLambdaNode));
|
3505
3505
|
break;
|
3506
3506
|
}
|
3507
3507
|
#line 144 "api_node.c.erb"
|
@@ -3989,53 +3989,61 @@ pm_ast_new(pm_parser_t *parser, pm_node_t *node, rb_encoding *encoding) {
|
|
3989
3989
|
#line 144 "api_node.c.erb"
|
3990
3990
|
case PM_OPTIONAL_KEYWORD_PARAMETER_NODE: {
|
3991
3991
|
pm_optional_keyword_parameter_node_t *cast = (pm_optional_keyword_parameter_node_t *) node;
|
3992
|
-
VALUE argv[
|
3992
|
+
VALUE argv[5];
|
3993
|
+
|
3994
|
+
// flags
|
3995
|
+
#line 192 "api_node.c.erb"
|
3996
|
+
argv[0] = ULONG2NUM(node->flags & ~PM_NODE_FLAG_COMMON_MASK);
|
3993
3997
|
|
3994
3998
|
// name
|
3995
3999
|
#line 167 "api_node.c.erb"
|
3996
4000
|
assert(cast->name != 0);
|
3997
|
-
argv[
|
4001
|
+
argv[1] = rb_id2sym(constants[cast->name - 1]);
|
3998
4002
|
|
3999
4003
|
// name_loc
|
4000
4004
|
#line 180 "api_node.c.erb"
|
4001
|
-
argv[
|
4005
|
+
argv[2] = pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source);
|
4002
4006
|
|
4003
4007
|
// value
|
4004
4008
|
#line 155 "api_node.c.erb"
|
4005
|
-
argv[
|
4009
|
+
argv[3] = rb_ary_pop(value_stack);
|
4006
4010
|
|
4007
4011
|
// location
|
4008
|
-
argv[
|
4012
|
+
argv[4] = pm_location_new(parser, node->location.start, node->location.end, source);
|
4009
4013
|
|
4010
|
-
rb_ary_push(value_stack, rb_class_new_instance(
|
4014
|
+
rb_ary_push(value_stack, rb_class_new_instance(5, argv, rb_cPrismOptionalKeywordParameterNode));
|
4011
4015
|
break;
|
4012
4016
|
}
|
4013
4017
|
#line 144 "api_node.c.erb"
|
4014
4018
|
case PM_OPTIONAL_PARAMETER_NODE: {
|
4015
4019
|
pm_optional_parameter_node_t *cast = (pm_optional_parameter_node_t *) node;
|
4016
|
-
VALUE argv[
|
4020
|
+
VALUE argv[6];
|
4021
|
+
|
4022
|
+
// flags
|
4023
|
+
#line 192 "api_node.c.erb"
|
4024
|
+
argv[0] = ULONG2NUM(node->flags & ~PM_NODE_FLAG_COMMON_MASK);
|
4017
4025
|
|
4018
4026
|
// name
|
4019
4027
|
#line 167 "api_node.c.erb"
|
4020
4028
|
assert(cast->name != 0);
|
4021
|
-
argv[
|
4029
|
+
argv[1] = rb_id2sym(constants[cast->name - 1]);
|
4022
4030
|
|
4023
4031
|
// name_loc
|
4024
4032
|
#line 180 "api_node.c.erb"
|
4025
|
-
argv[
|
4033
|
+
argv[2] = pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source);
|
4026
4034
|
|
4027
4035
|
// operator_loc
|
4028
4036
|
#line 180 "api_node.c.erb"
|
4029
|
-
argv[
|
4037
|
+
argv[3] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source);
|
4030
4038
|
|
4031
4039
|
// value
|
4032
4040
|
#line 155 "api_node.c.erb"
|
4033
|
-
argv[
|
4041
|
+
argv[4] = rb_ary_pop(value_stack);
|
4034
4042
|
|
4035
4043
|
// location
|
4036
|
-
argv[
|
4044
|
+
argv[5] = pm_location_new(parser, node->location.start, node->location.end, source);
|
4037
4045
|
|
4038
|
-
rb_ary_push(value_stack, rb_class_new_instance(
|
4046
|
+
rb_ary_push(value_stack, rb_class_new_instance(6, argv, rb_cPrismOptionalParameterNode));
|
4039
4047
|
break;
|
4040
4048
|
}
|
4041
4049
|
#line 144 "api_node.c.erb"
|
@@ -4343,37 +4351,45 @@ pm_ast_new(pm_parser_t *parser, pm_node_t *node, rb_encoding *encoding) {
|
|
4343
4351
|
#line 144 "api_node.c.erb"
|
4344
4352
|
case PM_REQUIRED_KEYWORD_PARAMETER_NODE: {
|
4345
4353
|
pm_required_keyword_parameter_node_t *cast = (pm_required_keyword_parameter_node_t *) node;
|
4346
|
-
VALUE argv[
|
4354
|
+
VALUE argv[4];
|
4355
|
+
|
4356
|
+
// flags
|
4357
|
+
#line 192 "api_node.c.erb"
|
4358
|
+
argv[0] = ULONG2NUM(node->flags & ~PM_NODE_FLAG_COMMON_MASK);
|
4347
4359
|
|
4348
4360
|
// name
|
4349
4361
|
#line 167 "api_node.c.erb"
|
4350
4362
|
assert(cast->name != 0);
|
4351
|
-
argv[
|
4363
|
+
argv[1] = rb_id2sym(constants[cast->name - 1]);
|
4352
4364
|
|
4353
4365
|
// name_loc
|
4354
4366
|
#line 180 "api_node.c.erb"
|
4355
|
-
argv[
|
4367
|
+
argv[2] = pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source);
|
4356
4368
|
|
4357
4369
|
// location
|
4358
|
-
argv[
|
4370
|
+
argv[3] = pm_location_new(parser, node->location.start, node->location.end, source);
|
4359
4371
|
|
4360
|
-
rb_ary_push(value_stack, rb_class_new_instance(
|
4372
|
+
rb_ary_push(value_stack, rb_class_new_instance(4, argv, rb_cPrismRequiredKeywordParameterNode));
|
4361
4373
|
break;
|
4362
4374
|
}
|
4363
4375
|
#line 144 "api_node.c.erb"
|
4364
4376
|
case PM_REQUIRED_PARAMETER_NODE: {
|
4365
4377
|
pm_required_parameter_node_t *cast = (pm_required_parameter_node_t *) node;
|
4366
|
-
VALUE argv[
|
4378
|
+
VALUE argv[3];
|
4379
|
+
|
4380
|
+
// flags
|
4381
|
+
#line 192 "api_node.c.erb"
|
4382
|
+
argv[0] = ULONG2NUM(node->flags & ~PM_NODE_FLAG_COMMON_MASK);
|
4367
4383
|
|
4368
4384
|
// name
|
4369
4385
|
#line 167 "api_node.c.erb"
|
4370
4386
|
assert(cast->name != 0);
|
4371
|
-
argv[
|
4387
|
+
argv[1] = rb_id2sym(constants[cast->name - 1]);
|
4372
4388
|
|
4373
4389
|
// location
|
4374
|
-
argv[
|
4390
|
+
argv[2] = pm_location_new(parser, node->location.start, node->location.end, source);
|
4375
4391
|
|
4376
|
-
rb_ary_push(value_stack, rb_class_new_instance(
|
4392
|
+
rb_ary_push(value_stack, rb_class_new_instance(3, argv, rb_cPrismRequiredParameterNode));
|
4377
4393
|
break;
|
4378
4394
|
}
|
4379
4395
|
#line 144 "api_node.c.erb"
|
@@ -4440,23 +4456,27 @@ pm_ast_new(pm_parser_t *parser, pm_node_t *node, rb_encoding *encoding) {
|
|
4440
4456
|
#line 144 "api_node.c.erb"
|
4441
4457
|
case PM_REST_PARAMETER_NODE: {
|
4442
4458
|
pm_rest_parameter_node_t *cast = (pm_rest_parameter_node_t *) node;
|
4443
|
-
VALUE argv[
|
4459
|
+
VALUE argv[5];
|
4460
|
+
|
4461
|
+
// flags
|
4462
|
+
#line 192 "api_node.c.erb"
|
4463
|
+
argv[0] = ULONG2NUM(node->flags & ~PM_NODE_FLAG_COMMON_MASK);
|
4444
4464
|
|
4445
4465
|
// name
|
4446
|
-
argv[
|
4466
|
+
argv[1] = cast->name == 0 ? Qnil : rb_id2sym(constants[cast->name - 1]);
|
4447
4467
|
|
4448
4468
|
// name_loc
|
4449
4469
|
#line 183 "api_node.c.erb"
|
4450
|
-
argv[
|
4470
|
+
argv[2] = cast->name_loc.start == NULL ? Qnil : pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source);
|
4451
4471
|
|
4452
4472
|
// operator_loc
|
4453
4473
|
#line 180 "api_node.c.erb"
|
4454
|
-
argv[
|
4474
|
+
argv[3] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source);
|
4455
4475
|
|
4456
4476
|
// location
|
4457
|
-
argv[
|
4477
|
+
argv[4] = pm_location_new(parser, node->location.start, node->location.end, source);
|
4458
4478
|
|
4459
|
-
rb_ary_push(value_stack, rb_class_new_instance(
|
4479
|
+
rb_ary_push(value_stack, rb_class_new_instance(5, argv, rb_cPrismRestParameterNode));
|
4460
4480
|
break;
|
4461
4481
|
}
|
4462
4482
|
#line 144 "api_node.c.erb"
|