prism 1.0.0 → 1.1.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 +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
|
}
|