prism 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +26 -1
- data/README.md +1 -0
- data/config.yml +257 -20
- data/docs/parsing_rules.md +4 -1
- data/ext/prism/extension.c +63 -26
- data/ext/prism/extension.h +1 -1
- data/include/prism/ast.h +559 -327
- data/include/prism/defines.h +27 -0
- data/include/prism/diagnostic.h +5 -1
- data/include/prism/options.h +39 -2
- data/include/prism/parser.h +7 -0
- data/include/prism/util/pm_string.h +27 -4
- data/include/prism/version.h +2 -2
- data/lib/prism/dot_visitor.rb +2 -0
- data/lib/prism/dsl.rb +10 -8
- data/lib/prism/ffi.rb +37 -3
- data/lib/prism/inspect_visitor.rb +1 -1
- data/lib/prism/lex_compat.rb +1 -1
- data/lib/prism/node.rb +132 -89
- data/lib/prism/parse_result.rb +1 -1
- data/lib/prism/reflection.rb +1 -1
- data/lib/prism/serialize.rb +6 -2
- data/lib/prism/translation/parser/lexer.rb +25 -3
- data/lib/prism/translation/ruby_parser.rb +7 -1
- data/prism.gemspec +1 -2
- data/rbi/prism/dsl.rbi +32 -32
- data/rbi/prism/node.rbi +69 -59
- data/rbi/prism.rbi +34 -34
- data/sig/prism/dsl.rbs +24 -24
- data/sig/prism/node.rbs +113 -105
- data/sig/prism.rbs +90 -72
- data/src/diagnostic.c +15 -7
- data/src/node.c +10 -0
- data/src/options.c +58 -27
- data/src/prettyprint.c +10 -0
- data/src/prism.c +588 -385
- data/src/util/pm_string.c +123 -65
- metadata +2 -3
- data/lib/prism/translation/parser/rubocop.rb +0 -73
data/sig/prism.rbs
CHANGED
@@ -10,101 +10,110 @@ module Prism
|
|
10
10
|
|
11
11
|
def self.parse: (
|
12
12
|
String source,
|
13
|
+
?encoding: Encoding | false,
|
13
14
|
?filepath: String,
|
15
|
+
?frozen_string_literal: bool,
|
14
16
|
?line: Integer,
|
17
|
+
?main_script: bool,
|
15
18
|
?offset: Integer,
|
16
|
-
?
|
17
|
-
?
|
18
|
-
?verbose: bool,
|
19
|
-
?scopes: Array[Array[Symbol]]
|
19
|
+
?scopes: Array[Array[Symbol]],
|
20
|
+
?verbose: bool
|
20
21
|
) -> ParseResult
|
21
22
|
|
22
23
|
def self.profile: (
|
23
24
|
String source,
|
25
|
+
?encoding: Encoding | false,
|
24
26
|
?filepath: String,
|
27
|
+
?frozen_string_literal: bool,
|
25
28
|
?line: Integer,
|
29
|
+
?main_script: bool,
|
26
30
|
?offset: Integer,
|
27
|
-
?
|
28
|
-
?
|
29
|
-
?verbose: bool,
|
30
|
-
?scopes: Array[Array[Symbol]]
|
31
|
+
?scopes: Array[Array[Symbol]],
|
32
|
+
?verbose: bool
|
31
33
|
) -> nil
|
32
34
|
|
33
35
|
def self.lex: (
|
34
36
|
String source,
|
37
|
+
?encoding: Encoding | false,
|
35
38
|
?filepath: String,
|
39
|
+
?frozen_string_literal: bool,
|
36
40
|
?line: Integer,
|
41
|
+
?main_script: bool,
|
37
42
|
?offset: Integer,
|
38
|
-
?
|
39
|
-
?
|
40
|
-
?verbose: bool,
|
41
|
-
?scopes: Array[Array[Symbol]]
|
43
|
+
?scopes: Array[Array[Symbol]],
|
44
|
+
?verbose: bool
|
42
45
|
) -> LexResult
|
43
46
|
|
44
47
|
def self.lex_compat: (
|
45
48
|
String source,
|
49
|
+
?encoding: Encoding | false,
|
46
50
|
?filepath: String,
|
51
|
+
?frozen_string_literal: bool,
|
47
52
|
?line: Integer,
|
53
|
+
?main_script: bool,
|
48
54
|
?offset: Integer,
|
49
|
-
?
|
50
|
-
?
|
51
|
-
?verbose: bool,
|
52
|
-
?scopes: Array[Array[Symbol]]
|
55
|
+
?scopes: Array[Array[Symbol]],
|
56
|
+
?verbose: bool
|
53
57
|
) -> LexCompat::Result
|
54
58
|
|
55
59
|
def self.parse_lex: (
|
56
60
|
String source,
|
61
|
+
?encoding: Encoding | false,
|
57
62
|
?filepath: String,
|
63
|
+
?frozen_string_literal: bool,
|
58
64
|
?line: Integer,
|
65
|
+
?main_script: bool,
|
59
66
|
?offset: Integer,
|
60
|
-
?
|
61
|
-
?
|
62
|
-
?verbose: bool,
|
63
|
-
?scopes: Array[Array[Symbol]]
|
67
|
+
?scopes: Array[Array[Symbol]],
|
68
|
+
?verbose: bool
|
64
69
|
) -> ParseLexResult
|
65
70
|
|
66
71
|
def self.dump: (
|
67
72
|
String source,
|
73
|
+
?encoding: Encoding | false,
|
68
74
|
?filepath: String,
|
75
|
+
?frozen_string_literal: bool,
|
69
76
|
?line: Integer,
|
77
|
+
?main_script: bool,
|
70
78
|
?offset: Integer,
|
71
|
-
?
|
72
|
-
?
|
73
|
-
?verbose: bool,
|
74
|
-
?scopes: Array[Array[Symbol]]
|
79
|
+
?scopes: Array[Array[Symbol]],
|
80
|
+
?verbose: bool
|
75
81
|
) -> String
|
76
82
|
|
77
83
|
def self.parse_comments: (
|
78
84
|
String source,
|
85
|
+
?encoding: Encoding | false,
|
79
86
|
?filepath: String,
|
87
|
+
?frozen_string_literal: bool,
|
80
88
|
?line: Integer,
|
89
|
+
?main_script: bool,
|
81
90
|
?offset: Integer,
|
82
|
-
?
|
83
|
-
?
|
84
|
-
?verbose: bool,
|
85
|
-
?scopes: Array[Array[Symbol]]
|
91
|
+
?scopes: Array[Array[Symbol]],
|
92
|
+
?verbose: bool
|
86
93
|
) -> Array[comment]
|
87
94
|
|
88
95
|
def self.parse_success?: (
|
89
96
|
String source,
|
97
|
+
?encoding: Encoding | false,
|
90
98
|
?filepath: String,
|
99
|
+
?frozen_string_literal: bool,
|
91
100
|
?line: Integer,
|
101
|
+
?main_script: bool,
|
92
102
|
?offset: Integer,
|
93
|
-
?
|
94
|
-
?
|
95
|
-
?verbose: bool,
|
96
|
-
?scopes: Array[Array[Symbol]]
|
103
|
+
?scopes: Array[Array[Symbol]],
|
104
|
+
?verbose: bool
|
97
105
|
) -> bool
|
98
106
|
|
99
107
|
def self.parse_failure?: (
|
100
108
|
String source,
|
109
|
+
?encoding: Encoding | false,
|
101
110
|
?filepath: String,
|
111
|
+
?frozen_string_literal: bool,
|
102
112
|
?line: Integer,
|
113
|
+
?main_script: bool,
|
103
114
|
?offset: Integer,
|
104
|
-
?
|
105
|
-
?
|
106
|
-
?verbose: bool,
|
107
|
-
?scopes: Array[Array[Symbol]]
|
115
|
+
?scopes: Array[Array[Symbol]],
|
116
|
+
?verbose: bool
|
108
117
|
) -> bool
|
109
118
|
|
110
119
|
def self.load: (
|
@@ -120,82 +129,90 @@ module Prism
|
|
120
129
|
|
121
130
|
def self.parse_file: (
|
122
131
|
String filepath,
|
132
|
+
?encoding: Encoding | false,
|
133
|
+
?frozen_string_literal: bool,
|
123
134
|
?line: Integer,
|
135
|
+
?main_script: bool,
|
124
136
|
?offset: Integer,
|
125
|
-
?
|
126
|
-
?
|
127
|
-
?verbose: bool,
|
128
|
-
?scopes: Array[Array[Symbol]]
|
137
|
+
?scopes: Array[Array[Symbol]],
|
138
|
+
?verbose: bool
|
129
139
|
) -> ParseResult
|
130
140
|
|
131
141
|
def self.profile_file: (
|
132
142
|
String filepath,
|
143
|
+
?encoding: Encoding | false,
|
144
|
+
?frozen_string_literal: bool,
|
133
145
|
?line: Integer,
|
146
|
+
?main_script: bool,
|
134
147
|
?offset: Integer,
|
135
|
-
?
|
136
|
-
?
|
137
|
-
?verbose: bool,
|
138
|
-
?scopes: Array[Array[Symbol]]
|
148
|
+
?scopes: Array[Array[Symbol]],
|
149
|
+
?verbose: bool
|
139
150
|
) -> nil
|
140
151
|
|
141
152
|
def self.lex_file: (
|
142
153
|
String filepath,
|
154
|
+
?encoding: Encoding | false,
|
155
|
+
?frozen_string_literal: bool,
|
143
156
|
?line: Integer,
|
157
|
+
?main_script: bool,
|
144
158
|
?offset: Integer,
|
145
|
-
?
|
146
|
-
?
|
147
|
-
?verbose: bool,
|
148
|
-
?scopes: Array[Array[Symbol]]
|
159
|
+
?scopes: Array[Array[Symbol]],
|
160
|
+
?verbose: bool
|
149
161
|
) -> LexResult
|
150
162
|
|
151
163
|
def self.parse_lex_file: (
|
152
164
|
String filepath,
|
165
|
+
?encoding: Encoding | false,
|
166
|
+
?frozen_string_literal: bool,
|
153
167
|
?line: Integer,
|
168
|
+
?main_script: bool,
|
154
169
|
?offset: Integer,
|
155
|
-
?
|
156
|
-
?
|
157
|
-
?verbose: bool,
|
158
|
-
?scopes: Array[Array[Symbol]]
|
170
|
+
?scopes: Array[Array[Symbol]],
|
171
|
+
?verbose: bool
|
159
172
|
) -> ParseLexResult
|
160
173
|
|
161
174
|
def self.dump_file: (
|
162
175
|
String filepath,
|
176
|
+
?encoding: Encoding | false,
|
177
|
+
?frozen_string_literal: bool,
|
163
178
|
?line: Integer,
|
179
|
+
?main_script: bool,
|
164
180
|
?offset: Integer,
|
165
|
-
?
|
166
|
-
?
|
167
|
-
?verbose: bool,
|
168
|
-
?scopes: Array[Array[Symbol]]
|
181
|
+
?scopes: Array[Array[Symbol]],
|
182
|
+
?verbose: bool
|
169
183
|
) -> String
|
170
184
|
|
171
185
|
def self.parse_file_comments: (
|
172
186
|
String filepath,
|
187
|
+
?encoding: Encoding | false,
|
188
|
+
?frozen_string_literal: bool,
|
173
189
|
?line: Integer,
|
190
|
+
?main_script: bool,
|
174
191
|
?offset: Integer,
|
175
|
-
?
|
176
|
-
?
|
177
|
-
?verbose: bool,
|
178
|
-
?scopes: Array[Array[Symbol]]
|
192
|
+
?scopes: Array[Array[Symbol]],
|
193
|
+
?verbose: bool
|
179
194
|
) -> Array[comment]
|
180
195
|
|
181
196
|
def self.parse_file_success?: (
|
182
197
|
String filepath,
|
198
|
+
?encoding: Encoding | false,
|
199
|
+
?frozen_string_literal: bool,
|
183
200
|
?line: Integer,
|
201
|
+
?main_script: bool,
|
184
202
|
?offset: Integer,
|
185
|
-
?
|
186
|
-
?
|
187
|
-
?verbose: bool,
|
188
|
-
?scopes: Array[Array[Symbol]]
|
203
|
+
?scopes: Array[Array[Symbol]],
|
204
|
+
?verbose: bool
|
189
205
|
) -> bool
|
190
206
|
|
191
207
|
def self.parse_file_failure?: (
|
192
208
|
String filepath,
|
209
|
+
?encoding: Encoding | false,
|
210
|
+
?frozen_string_literal: bool,
|
193
211
|
?line: Integer,
|
212
|
+
?main_script: bool,
|
194
213
|
?offset: Integer,
|
195
|
-
?
|
196
|
-
?
|
197
|
-
?verbose: bool,
|
198
|
-
?scopes: Array[Array[Symbol]]
|
214
|
+
?scopes: Array[Array[Symbol]],
|
215
|
+
?verbose: bool
|
199
216
|
) -> bool
|
200
217
|
|
201
218
|
interface _Stream
|
@@ -204,12 +221,13 @@ module Prism
|
|
204
221
|
|
205
222
|
def self.parse_stream: (
|
206
223
|
_Stream stream,
|
224
|
+
?encoding: Encoding | false,
|
207
225
|
?filepath: String,
|
226
|
+
?frozen_string_literal: bool,
|
208
227
|
?line: Integer,
|
228
|
+
?main_script: bool,
|
209
229
|
?offset: Integer,
|
210
|
-
?
|
211
|
-
?
|
212
|
-
?verbose: bool,
|
213
|
-
?scopes: Array[Array[Symbol]]
|
230
|
+
?scopes: Array[Array[Symbol]],
|
231
|
+
?verbose: bool
|
214
232
|
) -> ParseResult
|
215
233
|
end
|
data/src/diagnostic.c
CHANGED
@@ -8,7 +8,7 @@
|
|
8
8
|
|
9
9
|
#include "prism/diagnostic.h"
|
10
10
|
|
11
|
-
#define PM_DIAGNOSTIC_ID_MAX
|
11
|
+
#define PM_DIAGNOSTIC_ID_MAX 318
|
12
12
|
|
13
13
|
/** This struct holds the data for each diagnostic. */
|
14
14
|
typedef struct {
|
@@ -108,7 +108,6 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
|
|
108
108
|
[PM_ERR_ARGUMENT_FORMAL_GLOBAL] = { "invalid formal argument; formal argument cannot be a global variable", PM_ERROR_LEVEL_SYNTAX },
|
109
109
|
[PM_ERR_ARGUMENT_FORMAL_IVAR] = { "invalid formal argument; formal argument cannot be an instance variable", PM_ERROR_LEVEL_SYNTAX },
|
110
110
|
[PM_ERR_ARGUMENT_FORWARDING_UNBOUND] = { "unexpected `...` in an non-parenthesized call", PM_ERROR_LEVEL_SYNTAX },
|
111
|
-
[PM_ERR_ARGUMENT_IN] = { "unexpected `in` keyword in arguments", PM_ERROR_LEVEL_SYNTAX },
|
112
111
|
[PM_ERR_ARGUMENT_NO_FORWARDING_AMPERSAND] = { "unexpected `&`; no anonymous block parameter", PM_ERROR_LEVEL_SYNTAX },
|
113
112
|
[PM_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES] = { "unexpected ... when the parent method is not forwarding", PM_ERROR_LEVEL_SYNTAX },
|
114
113
|
[PM_ERR_ARGUMENT_NO_FORWARDING_STAR] = { "unexpected `*`; no anonymous rest parameter", PM_ERROR_LEVEL_SYNTAX },
|
@@ -121,7 +120,7 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
|
|
121
120
|
[PM_ERR_ARRAY_EXPRESSION] = { "expected an expression for the array element", PM_ERROR_LEVEL_SYNTAX },
|
122
121
|
[PM_ERR_ARRAY_EXPRESSION_AFTER_STAR] = { "expected an expression after `*` in the array", PM_ERROR_LEVEL_SYNTAX },
|
123
122
|
[PM_ERR_ARRAY_SEPARATOR] = { "unexpected %s; expected a `,` separator for the array elements", PM_ERROR_LEVEL_SYNTAX },
|
124
|
-
[PM_ERR_ARRAY_TERM] = { "expected a `]` to close the array", PM_ERROR_LEVEL_SYNTAX },
|
123
|
+
[PM_ERR_ARRAY_TERM] = { "unexpected %s; expected a `]` to close the array", PM_ERROR_LEVEL_SYNTAX },
|
125
124
|
[PM_ERR_BEGIN_LONELY_ELSE] = { "unexpected `else` in `begin` block; else without rescue is useless", PM_ERROR_LEVEL_SYNTAX },
|
126
125
|
[PM_ERR_BEGIN_TERM] = { "expected an `end` to close the `begin` statement", PM_ERROR_LEVEL_SYNTAX },
|
127
126
|
[PM_ERR_BEGIN_UPCASE_BRACE] = { "expected a `{` after `BEGIN`", PM_ERROR_LEVEL_SYNTAX },
|
@@ -178,7 +177,7 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
|
|
178
177
|
[PM_ERR_ESCAPE_INVALID_UNICODE_LONG] = { "invalid Unicode escape sequence; maximum length is 6 digits", PM_ERROR_LEVEL_SYNTAX },
|
179
178
|
[PM_ERR_ESCAPE_INVALID_UNICODE_SHORT] = { "too short escape sequence: %.*s", PM_ERROR_LEVEL_SYNTAX },
|
180
179
|
[PM_ERR_ESCAPE_INVALID_UNICODE_TERM] = { "unterminated Unicode escape", PM_ERROR_LEVEL_SYNTAX },
|
181
|
-
[PM_ERR_EXPECT_ARGUMENT] = { "expected an argument", PM_ERROR_LEVEL_SYNTAX },
|
180
|
+
[PM_ERR_EXPECT_ARGUMENT] = { "unexpected %s; expected an argument", PM_ERROR_LEVEL_SYNTAX },
|
182
181
|
[PM_ERR_EXPECT_EOL_AFTER_STATEMENT] = { "unexpected %s, expecting end-of-input", PM_ERROR_LEVEL_SYNTAX },
|
183
182
|
[PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ] = { "expected an expression after `&&=`", PM_ERROR_LEVEL_SYNTAX },
|
184
183
|
[PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ] = { "expected an expression after `||=`", PM_ERROR_LEVEL_SYNTAX },
|
@@ -190,6 +189,7 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
|
|
190
189
|
[PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT] = { "expected an expression after `*` splat in an argument", PM_ERROR_LEVEL_SYNTAX },
|
191
190
|
[PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH] = { "expected an expression after `**` in a hash", PM_ERROR_LEVEL_SYNTAX },
|
192
191
|
[PM_ERR_EXPECT_EXPRESSION_AFTER_STAR] = { "expected an expression after `*`", PM_ERROR_LEVEL_SYNTAX },
|
192
|
+
[PM_ERR_EXPECT_FOR_DELIMITER] = { "unexpected %s; expected a 'do', newline, or ';' after the 'for' loop collection", PM_ERROR_LEVEL_SYNTAX },
|
193
193
|
[PM_ERR_EXPECT_IDENT_REQ_PARAMETER] = { "expected an identifier for the required parameter", PM_ERROR_LEVEL_SYNTAX },
|
194
194
|
[PM_ERR_EXPECT_IN_DELIMITER] = { "expected a delimiter after the patterns of an `in` clause", PM_ERROR_LEVEL_SYNTAX },
|
195
195
|
[PM_ERR_EXPECT_LPAREN_REQ_PARAMETER] = { "expected a `(` to start a required parameter", PM_ERROR_LEVEL_SYNTAX },
|
@@ -198,6 +198,7 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
|
|
198
198
|
[PM_ERR_EXPECT_RPAREN] = { "expected a matching `)`", PM_ERROR_LEVEL_SYNTAX },
|
199
199
|
[PM_ERR_EXPECT_RPAREN_AFTER_MULTI] = { "expected a `)` after multiple assignment", PM_ERROR_LEVEL_SYNTAX },
|
200
200
|
[PM_ERR_EXPECT_RPAREN_REQ_PARAMETER] = { "expected a `)` to end a required parameter", PM_ERROR_LEVEL_SYNTAX },
|
201
|
+
[PM_ERR_EXPECT_SINGLETON_CLASS_DELIMITER] = { "unexpected %s; expected a newline or a ';' after the singleton class", PM_ERROR_LEVEL_SYNTAX },
|
201
202
|
[PM_ERR_EXPECT_STRING_CONTENT] = { "expected string content after opening string delimiter", PM_ERROR_LEVEL_SYNTAX },
|
202
203
|
[PM_ERR_EXPECT_WHEN_DELIMITER] = { "expected a delimiter after the predicates of a `when` clause", PM_ERROR_LEVEL_SYNTAX },
|
203
204
|
[PM_ERR_EXPRESSION_BARE_HASH] = { "unexpected bare hash in expression", PM_ERROR_LEVEL_SYNTAX },
|
@@ -275,8 +276,10 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
|
|
275
276
|
[PM_ERR_MODULE_TERM] = { "expected an `end` to close the `module` statement", PM_ERROR_LEVEL_SYNTAX },
|
276
277
|
[PM_ERR_MULTI_ASSIGN_MULTI_SPLATS] = { "multiple splats in multiple assignment", PM_ERROR_LEVEL_SYNTAX },
|
277
278
|
[PM_ERR_MULTI_ASSIGN_UNEXPECTED_REST] = { "unexpected '%.*s' resulting in multiple splats in multiple assignment", PM_ERROR_LEVEL_SYNTAX },
|
278
|
-
[
|
279
|
+
[PM_ERR_NESTING_TOO_DEEP] = { "nesting too deep", PM_ERROR_LEVEL_SYNTAX },
|
279
280
|
[PM_ERR_NO_LOCAL_VARIABLE] = { "%.*s: no such local variable", PM_ERROR_LEVEL_SYNTAX },
|
281
|
+
[PM_ERR_NON_ASSOCIATIVE_OPERATOR] = { "unexpected %s; %s is a non-associative operator", PM_ERROR_LEVEL_SYNTAX },
|
282
|
+
[PM_ERR_NOT_EXPRESSION] = { "expected an expression after `not`", PM_ERROR_LEVEL_SYNTAX },
|
280
283
|
[PM_ERR_NUMBER_LITERAL_UNDERSCORE] = { "number literal ending with a `_`", PM_ERROR_LEVEL_SYNTAX },
|
281
284
|
[PM_ERR_NUMBERED_PARAMETER_INNER_BLOCK] = { "numbered parameter is already used in inner block", PM_ERROR_LEVEL_SYNTAX },
|
282
285
|
[PM_ERR_NUMBERED_PARAMETER_IT] = { "numbered parameters are not allowed when 'it' is already used", PM_ERROR_LEVEL_SYNTAX },
|
@@ -354,12 +357,13 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
|
|
354
357
|
[PM_ERR_TERNARY_COLON] = { "expected a `:` after the true expression of a ternary operator", PM_ERROR_LEVEL_SYNTAX },
|
355
358
|
[PM_ERR_TERNARY_EXPRESSION_FALSE] = { "expected an expression after `:` in the ternary operator", PM_ERROR_LEVEL_SYNTAX },
|
356
359
|
[PM_ERR_TERNARY_EXPRESSION_TRUE] = { "expected an expression after `?` in the ternary operator", PM_ERROR_LEVEL_SYNTAX },
|
357
|
-
[PM_ERR_UNDEF_ARGUMENT] = { "invalid argument being passed to `undef`; expected a bare word, constant, or symbol argument", PM_ERROR_LEVEL_SYNTAX },
|
358
360
|
[PM_ERR_UNARY_RECEIVER] = { "unexpected %s, expected a receiver for unary `%c`", PM_ERROR_LEVEL_SYNTAX },
|
359
361
|
[PM_ERR_UNARY_DISALLOWED] = { "unexpected %s; unary calls are not allowed in this context", PM_ERROR_LEVEL_SYNTAX },
|
362
|
+
[PM_ERR_UNDEF_ARGUMENT] = { "invalid argument being passed to `undef`; expected a bare word, constant, or symbol argument", PM_ERROR_LEVEL_SYNTAX },
|
360
363
|
[PM_ERR_UNEXPECTED_BLOCK_ARGUMENT] = { "block argument should not be given", PM_ERROR_LEVEL_SYNTAX },
|
361
364
|
[PM_ERR_UNEXPECTED_INDEX_BLOCK] = { "unexpected block arg given in index assignment; blocks are not allowed in index assignment expressions", PM_ERROR_LEVEL_SYNTAX },
|
362
365
|
[PM_ERR_UNEXPECTED_INDEX_KEYWORDS] = { "unexpected keyword arg given in index assignment; keywords are not allowed in index assignment expressions", PM_ERROR_LEVEL_SYNTAX },
|
366
|
+
[PM_ERR_UNEXPECTED_LABEL] = { "unexpected label", PM_ERROR_LEVEL_SYNTAX },
|
363
367
|
[PM_ERR_UNEXPECTED_MULTI_WRITE] = { "unexpected multiple assignment; multiple assignment is not allowed in this context", PM_ERROR_LEVEL_SYNTAX },
|
364
368
|
[PM_ERR_UNEXPECTED_RANGE_OPERATOR] = { "unexpected range operator; .. and ... are non-associative and cannot be chained", PM_ERROR_LEVEL_SYNTAX },
|
365
369
|
[PM_ERR_UNEXPECTED_SAFE_NAVIGATION] = { "&. inside multiple assignment destination", PM_ERROR_LEVEL_SYNTAX },
|
@@ -428,7 +432,6 @@ pm_diagnostic_id_human(pm_diagnostic_id_t diag_id) {
|
|
428
432
|
case PM_ERR_ARGUMENT_FORMAL_GLOBAL: return "argument_formal_global";
|
429
433
|
case PM_ERR_ARGUMENT_FORMAL_IVAR: return "argument_formal_ivar";
|
430
434
|
case PM_ERR_ARGUMENT_FORWARDING_UNBOUND: return "argument_forwarding_unbound";
|
431
|
-
case PM_ERR_ARGUMENT_IN: return "argument_in";
|
432
435
|
case PM_ERR_ARGUMENT_NO_FORWARDING_AMPERSAND: return "argument_no_forwarding_ampersand";
|
433
436
|
case PM_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES: return "argument_no_forwarding_ellipses";
|
434
437
|
case PM_ERR_ARGUMENT_NO_FORWARDING_STAR: return "argument_no_forwarding_star";
|
@@ -512,6 +515,7 @@ pm_diagnostic_id_human(pm_diagnostic_id_t diag_id) {
|
|
512
515
|
case PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT: return "expect_expression_after_splat";
|
513
516
|
case PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH: return "expect_expression_after_splat_hash";
|
514
517
|
case PM_ERR_EXPECT_EXPRESSION_AFTER_STAR: return "expect_expression_after_star";
|
518
|
+
case PM_ERR_EXPECT_FOR_DELIMITER: return "expect_for_delimiter";
|
515
519
|
case PM_ERR_EXPECT_IDENT_REQ_PARAMETER: return "expect_ident_req_parameter";
|
516
520
|
case PM_ERR_EXPECT_IN_DELIMITER: return "expect_in_delimiter";
|
517
521
|
case PM_ERR_EXPECT_LPAREN_REQ_PARAMETER: return "expect_lparen_req_parameter";
|
@@ -520,6 +524,7 @@ pm_diagnostic_id_human(pm_diagnostic_id_t diag_id) {
|
|
520
524
|
case PM_ERR_EXPECT_RPAREN: return "expect_rparen";
|
521
525
|
case PM_ERR_EXPECT_RPAREN_AFTER_MULTI: return "expect_rparen_after_multi";
|
522
526
|
case PM_ERR_EXPECT_RPAREN_REQ_PARAMETER: return "expect_rparen_req_parameter";
|
527
|
+
case PM_ERR_EXPECT_SINGLETON_CLASS_DELIMITER: return "expect_singleton_class_delimiter";
|
523
528
|
case PM_ERR_EXPECT_STRING_CONTENT: return "expect_string_content";
|
524
529
|
case PM_ERR_EXPECT_WHEN_DELIMITER: return "expect_when_delimiter";
|
525
530
|
case PM_ERR_EXPRESSION_BARE_HASH: return "expression_bare_hash";
|
@@ -598,7 +603,9 @@ pm_diagnostic_id_human(pm_diagnostic_id_t diag_id) {
|
|
598
603
|
case PM_ERR_MODULE_TERM: return "module_term";
|
599
604
|
case PM_ERR_MULTI_ASSIGN_MULTI_SPLATS: return "multi_assign_multi_splats";
|
600
605
|
case PM_ERR_MULTI_ASSIGN_UNEXPECTED_REST: return "multi_assign_unexpected_rest";
|
606
|
+
case PM_ERR_NESTING_TOO_DEEP: return "nesting_too_deep";
|
601
607
|
case PM_ERR_NO_LOCAL_VARIABLE: return "no_local_variable";
|
608
|
+
case PM_ERR_NON_ASSOCIATIVE_OPERATOR: return "non_associative_operator";
|
602
609
|
case PM_ERR_NOT_EXPRESSION: return "not_expression";
|
603
610
|
case PM_ERR_NUMBER_LITERAL_UNDERSCORE: return "number_literal_underscore";
|
604
611
|
case PM_ERR_NUMBERED_PARAMETER_INNER_BLOCK: return "numbered_parameter_inner_block";
|
@@ -684,6 +691,7 @@ pm_diagnostic_id_human(pm_diagnostic_id_t diag_id) {
|
|
684
691
|
case PM_ERR_UNEXPECTED_BLOCK_ARGUMENT: return "unexpected_block_argument";
|
685
692
|
case PM_ERR_UNEXPECTED_INDEX_BLOCK: return "unexpected_index_block";
|
686
693
|
case PM_ERR_UNEXPECTED_INDEX_KEYWORDS: return "unexpected_index_keywords";
|
694
|
+
case PM_ERR_UNEXPECTED_LABEL: return "unexpected_label";
|
687
695
|
case PM_ERR_UNEXPECTED_MULTI_WRITE: return "unexpected_multi_write";
|
688
696
|
case PM_ERR_UNEXPECTED_RANGE_OPERATOR: return "unexpected_range_operator";
|
689
697
|
case PM_ERR_UNEXPECTED_SAFE_NAVIGATION: return "unexpected_safe_navigation";
|
data/src/node.c
CHANGED
@@ -3125,6 +3125,11 @@ pm_dump_json(pm_buffer_t *buffer, const pm_parser_t *parser, const pm_node_t *no
|
|
3125
3125
|
pm_buffer_append_string(buffer, "\"ArgumentsNodeFlags\":", 21);
|
3126
3126
|
size_t flags = 0;
|
3127
3127
|
pm_buffer_append_byte(buffer, '[');
|
3128
|
+
if (PM_NODE_FLAG_P(cast, PM_ARGUMENTS_NODE_FLAGS_CONTAINS_FORWARDING)) {
|
3129
|
+
if (flags != 0) pm_buffer_append_byte(buffer, ',');
|
3130
|
+
pm_buffer_append_string(buffer, "\"CONTAINS_FORWARDING\"", 21);
|
3131
|
+
flags++;
|
3132
|
+
}
|
3128
3133
|
if (PM_NODE_FLAG_P(cast, PM_ARGUMENTS_NODE_FLAGS_CONTAINS_KEYWORDS)) {
|
3129
3134
|
if (flags != 0) pm_buffer_append_byte(buffer, ',');
|
3130
3135
|
pm_buffer_append_string(buffer, "\"CONTAINS_KEYWORDS\"", 19);
|
@@ -3140,6 +3145,11 @@ pm_dump_json(pm_buffer_t *buffer, const pm_parser_t *parser, const pm_node_t *no
|
|
3140
3145
|
pm_buffer_append_string(buffer, "\"CONTAINS_SPLAT\"", 16);
|
3141
3146
|
flags++;
|
3142
3147
|
}
|
3148
|
+
if (PM_NODE_FLAG_P(cast, PM_ARGUMENTS_NODE_FLAGS_CONTAINS_MULTIPLE_SPLATS)) {
|
3149
|
+
if (flags != 0) pm_buffer_append_byte(buffer, ',');
|
3150
|
+
pm_buffer_append_string(buffer, "\"CONTAINS_MULTIPLE_SPLATS\"", 26);
|
3151
|
+
flags++;
|
3152
|
+
}
|
3143
3153
|
pm_buffer_append_byte(buffer, ']');
|
3144
3154
|
|
3145
3155
|
// Dump the arguments field
|
data/src/options.c
CHANGED
@@ -57,6 +57,14 @@ pm_options_command_line_set(pm_options_t *options, uint8_t command_line) {
|
|
57
57
|
options->command_line = command_line;
|
58
58
|
}
|
59
59
|
|
60
|
+
/**
|
61
|
+
* Checks if the given slice represents a number.
|
62
|
+
*/
|
63
|
+
static inline bool
|
64
|
+
is_number(const char *string, size_t length) {
|
65
|
+
return pm_strspn_decimal_digit((const uint8_t *) string, (ptrdiff_t) length) == length;
|
66
|
+
}
|
67
|
+
|
60
68
|
/**
|
61
69
|
* Set the version option on the given options struct by parsing the given
|
62
70
|
* string. If the string contains an invalid option, this returns false.
|
@@ -64,40 +72,61 @@ pm_options_command_line_set(pm_options_t *options, uint8_t command_line) {
|
|
64
72
|
*/
|
65
73
|
PRISM_EXPORTED_FUNCTION bool
|
66
74
|
pm_options_version_set(pm_options_t *options, const char *version, size_t length) {
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
return true;
|
72
|
-
}
|
75
|
+
if (version == NULL) {
|
76
|
+
options->version = PM_OPTIONS_VERSION_LATEST;
|
77
|
+
return true;
|
78
|
+
}
|
73
79
|
|
74
|
-
|
75
|
-
|
76
|
-
|
80
|
+
if (length == 3) {
|
81
|
+
if (strncmp(version, "3.3", 3) == 0) {
|
82
|
+
options->version = PM_OPTIONS_VERSION_CRUBY_3_3;
|
83
|
+
return true;
|
84
|
+
}
|
77
85
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
86
|
+
if (strncmp(version, "3.4", 3) == 0) {
|
87
|
+
options->version = PM_OPTIONS_VERSION_LATEST;
|
88
|
+
return true;
|
89
|
+
}
|
82
90
|
|
83
|
-
|
84
|
-
|
85
|
-
return true;
|
86
|
-
}
|
91
|
+
return false;
|
92
|
+
}
|
87
93
|
|
88
|
-
|
89
|
-
|
90
|
-
|
94
|
+
if (length >= 4) {
|
95
|
+
if (strncmp(version, "3.3.", 4) == 0 && is_number(version + 4, length - 4)) {
|
96
|
+
options->version = PM_OPTIONS_VERSION_CRUBY_3_3;
|
97
|
+
return true;
|
98
|
+
}
|
91
99
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
100
|
+
if (strncmp(version, "3.4.", 4) == 0 && is_number(version + 4, length - 4)) {
|
101
|
+
options->version = PM_OPTIONS_VERSION_LATEST;
|
102
|
+
return true;
|
103
|
+
}
|
104
|
+
}
|
96
105
|
|
97
|
-
|
98
|
-
|
99
|
-
|
106
|
+
if (length >= 6) {
|
107
|
+
if (strncmp(version, "latest", 7) == 0) { // 7 to compare the \0 as well
|
108
|
+
options->version = PM_OPTIONS_VERSION_LATEST;
|
109
|
+
return true;
|
110
|
+
}
|
100
111
|
}
|
112
|
+
|
113
|
+
return false;
|
114
|
+
}
|
115
|
+
|
116
|
+
/**
|
117
|
+
* Set the main script option on the given options struct.
|
118
|
+
*/
|
119
|
+
PRISM_EXPORTED_FUNCTION void
|
120
|
+
pm_options_main_script_set(pm_options_t *options, bool main_script) {
|
121
|
+
options->main_script = main_script;
|
122
|
+
}
|
123
|
+
|
124
|
+
/**
|
125
|
+
* Set the partial script option on the given options struct.
|
126
|
+
*/
|
127
|
+
PRISM_EXPORTED_FUNCTION void
|
128
|
+
pm_options_partial_script_set(pm_options_t *options, bool partial_script) {
|
129
|
+
options->partial_script = partial_script;
|
101
130
|
}
|
102
131
|
|
103
132
|
// For some reason, GCC analyzer thinks we're leaking allocated scopes and
|
@@ -233,6 +262,8 @@ pm_options_read(pm_options_t *options, const char *data) {
|
|
233
262
|
options->command_line = (uint8_t) *data++;
|
234
263
|
options->version = (pm_options_version_t) *data++;
|
235
264
|
options->encoding_locked = ((uint8_t) *data++) > 0;
|
265
|
+
options->main_script = ((uint8_t) *data++) > 0;
|
266
|
+
options->partial_script = ((uint8_t) *data++) > 0;
|
236
267
|
|
237
268
|
uint32_t scopes_count = pm_options_read_u32(data);
|
238
269
|
data += 4;
|
data/src/prettyprint.c
CHANGED
@@ -231,6 +231,11 @@ prettyprint_node(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm
|
|
231
231
|
pm_buffer_concat(output_buffer, prefix_buffer);
|
232
232
|
pm_buffer_append_string(output_buffer, "+-- ArgumentsNodeFlags:", 23);
|
233
233
|
bool found = false;
|
234
|
+
if (cast->base.flags & PM_ARGUMENTS_NODE_FLAGS_CONTAINS_FORWARDING) {
|
235
|
+
if (found) pm_buffer_append_byte(output_buffer, ',');
|
236
|
+
pm_buffer_append_string(output_buffer, " contains_forwarding", 20);
|
237
|
+
found = true;
|
238
|
+
}
|
234
239
|
if (cast->base.flags & PM_ARGUMENTS_NODE_FLAGS_CONTAINS_KEYWORDS) {
|
235
240
|
if (found) pm_buffer_append_byte(output_buffer, ',');
|
236
241
|
pm_buffer_append_string(output_buffer, " contains_keywords", 18);
|
@@ -246,6 +251,11 @@ prettyprint_node(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm
|
|
246
251
|
pm_buffer_append_string(output_buffer, " contains_splat", 15);
|
247
252
|
found = true;
|
248
253
|
}
|
254
|
+
if (cast->base.flags & PM_ARGUMENTS_NODE_FLAGS_CONTAINS_MULTIPLE_SPLATS) {
|
255
|
+
if (found) pm_buffer_append_byte(output_buffer, ',');
|
256
|
+
pm_buffer_append_string(output_buffer, " contains_multiple_splats", 25);
|
257
|
+
found = true;
|
258
|
+
}
|
249
259
|
if (!found) pm_buffer_append_string(output_buffer, " nil", 4);
|
250
260
|
pm_buffer_append_byte(output_buffer, '\n');
|
251
261
|
}
|