yarp 0.11.0 → 0.12.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/config.yml +105 -6
- data/ext/yarp/api_node.c +200 -34
- data/ext/yarp/extension.c +8 -1
- data/ext/yarp/extension.h +1 -1
- data/include/yarp/ast.h +246 -293
- data/include/yarp/diagnostic.h +7 -2
- data/include/yarp/enc/yp_encoding.h +1 -1
- data/include/yarp/parser.h +44 -16
- data/include/yarp/util/yp_char.h +21 -5
- data/include/yarp/version.h +2 -2
- data/lib/yarp/mutation_visitor.rb +28 -3
- data/lib/yarp/node.rb +3507 -85
- data/lib/yarp/serialize.rb +146 -136
- data/lib/yarp.rb +57 -42
- data/src/diagnostic.c +6 -1
- data/src/enc/yp_unicode.c +5 -5
- data/src/node.c +87 -8
- data/src/prettyprint.c +85 -21
- data/src/serialize.c +59 -19
- data/src/util/yp_char.c +57 -9
- data/src/util/yp_constant_pool.c +69 -18
- data/src/yarp.c +1528 -1018
- data/yarp.gemspec +1 -1
- metadata +3 -3
data/include/yarp/diagnostic.h
CHANGED
@@ -32,6 +32,7 @@ typedef enum {
|
|
32
32
|
YP_ERR_ARGUMENT_SPLAT_AFTER_ASSOC_SPLAT,
|
33
33
|
YP_ERR_ARGUMENT_SPLAT_AFTER_SPLAT,
|
34
34
|
YP_ERR_ARGUMENT_TERM_PAREN,
|
35
|
+
YP_ERR_ARGUMENT_UNEXPECTED_BLOCK,
|
35
36
|
YP_ERR_ARRAY_ELEMENT,
|
36
37
|
YP_ERR_ARRAY_EXPRESSION,
|
37
38
|
YP_ERR_ARRAY_EXPRESSION_AFTER_STAR,
|
@@ -49,7 +50,7 @@ typedef enum {
|
|
49
50
|
YP_ERR_CANNOT_PARSE_STRING_PART,
|
50
51
|
YP_ERR_CASE_EXPRESSION_AFTER_CASE,
|
51
52
|
YP_ERR_CASE_EXPRESSION_AFTER_WHEN,
|
52
|
-
|
53
|
+
YP_ERR_CASE_MISSING_CONDITIONS,
|
53
54
|
YP_ERR_CASE_TERM,
|
54
55
|
YP_ERR_CLASS_IN_METHOD,
|
55
56
|
YP_ERR_CLASS_NAME,
|
@@ -129,6 +130,7 @@ typedef enum {
|
|
129
130
|
YP_ERR_INVALID_NUMBER_DECIMAL,
|
130
131
|
YP_ERR_INVALID_NUMBER_HEXADECIMAL,
|
131
132
|
YP_ERR_INVALID_NUMBER_OCTAL,
|
133
|
+
YP_ERR_INVALID_NUMBER_UNDERSCORE,
|
132
134
|
YP_ERR_INVALID_PERCENT,
|
133
135
|
YP_ERR_INVALID_TOKEN,
|
134
136
|
YP_ERR_INVALID_VARIABLE_GLOBAL,
|
@@ -150,7 +152,10 @@ typedef enum {
|
|
150
152
|
YP_ERR_MULTI_ASSIGN_MULTI_SPLATS,
|
151
153
|
YP_ERR_NOT_EXPRESSION,
|
152
154
|
YP_ERR_NUMBER_LITERAL_UNDERSCORE,
|
155
|
+
YP_ERR_NUMBERED_PARAMETER_NOT_ALLOWED,
|
156
|
+
YP_ERR_NUMBERED_PARAMETER_OUTER_SCOPE,
|
153
157
|
YP_ERR_OPERATOR_MULTI_ASSIGN,
|
158
|
+
YP_ERR_OPERATOR_WRITE_BLOCK,
|
154
159
|
YP_ERR_PARAMETER_ASSOC_SPLAT_MULTI,
|
155
160
|
YP_ERR_PARAMETER_BLOCK_MULTI,
|
156
161
|
YP_ERR_PARAMETER_NAME_REPEAT,
|
@@ -194,11 +199,11 @@ typedef enum {
|
|
194
199
|
YP_ERR_TERNARY_COLON,
|
195
200
|
YP_ERR_TERNARY_EXPRESSION_FALSE,
|
196
201
|
YP_ERR_TERNARY_EXPRESSION_TRUE,
|
197
|
-
YP_ERR_UNDEF_ARGUMENT,
|
198
202
|
YP_ERR_UNARY_RECEIVER_BANG,
|
199
203
|
YP_ERR_UNARY_RECEIVER_MINUS,
|
200
204
|
YP_ERR_UNARY_RECEIVER_PLUS,
|
201
205
|
YP_ERR_UNARY_RECEIVER_TILDE,
|
206
|
+
YP_ERR_UNDEF_ARGUMENT,
|
202
207
|
YP_ERR_UNTIL_TERM,
|
203
208
|
YP_ERR_WHILE_TERM,
|
204
209
|
YP_ERR_WRITE_TARGET_READONLY,
|
@@ -60,7 +60,7 @@ size_t yp_encoding_utf_8_alnum_char(const uint8_t *b, ptrdiff_t n);
|
|
60
60
|
|
61
61
|
// This lookup table is referenced in both the UTF-8 encoding file and the
|
62
62
|
// parser directly in order to speed up the default encoding processing.
|
63
|
-
extern uint8_t yp_encoding_unicode_table[256];
|
63
|
+
extern const uint8_t yp_encoding_unicode_table[256];
|
64
64
|
|
65
65
|
// These are the encodings that are supported by the parser. They are defined in
|
66
66
|
// their own files in the src/enc directory.
|
data/include/yarp/parser.h
CHANGED
@@ -277,12 +277,22 @@ typedef struct yp_scope {
|
|
277
277
|
// The IDs of the locals in the given scope.
|
278
278
|
yp_constant_id_list_t locals;
|
279
279
|
|
280
|
+
// A pointer to the previous scope in the linked list.
|
281
|
+
struct yp_scope *previous;
|
282
|
+
|
280
283
|
// A boolean indicating whether or not this scope can see into its parent.
|
281
284
|
// If closed is true, then the scope cannot see into its parent.
|
282
285
|
bool closed;
|
283
286
|
|
284
|
-
// A
|
285
|
-
|
287
|
+
// A boolean indicating whether or not this scope has explicit parameters.
|
288
|
+
// This is necessary to determine whether or not numbered parameters are
|
289
|
+
// allowed.
|
290
|
+
bool explicit_params;
|
291
|
+
|
292
|
+
// A boolean indicating whether or not this scope has numbered parameters.
|
293
|
+
// This is necessary to determine if child blocks are allowed to use
|
294
|
+
// numbered parameters.
|
295
|
+
bool numbered_params;
|
286
296
|
} yp_scope_t;
|
287
297
|
|
288
298
|
// This struct represents the overall parser. It contains a reference to the
|
@@ -291,7 +301,6 @@ typedef struct yp_scope {
|
|
291
301
|
// it's considering.
|
292
302
|
struct yp_parser {
|
293
303
|
yp_lex_state_t lex_state; // the current state of the lexer
|
294
|
-
bool command_start; // whether or not we're at the beginning of a command
|
295
304
|
int enclosure_nesting; // tracks the current nesting of (), [], and {}
|
296
305
|
|
297
306
|
// Used to temporarily track the nesting of enclosures to determine if a {
|
@@ -338,17 +347,11 @@ struct yp_parser {
|
|
338
347
|
yp_scope_t *current_scope; // the current local scope
|
339
348
|
|
340
349
|
yp_context_node_t *current_context; // the current parsing context
|
341
|
-
bool recovering; // whether or not we're currently recovering from a syntax error
|
342
350
|
|
343
351
|
// The encoding functions for the current file is attached to the parser as
|
344
352
|
// it's parsing so that it can change with a magic comment.
|
345
353
|
yp_encoding_t encoding;
|
346
354
|
|
347
|
-
// Whether or not the encoding has been changed by a magic comment. We use
|
348
|
-
// this to provide a fast path for the lexer instead of going through the
|
349
|
-
// function pointer.
|
350
|
-
bool encoding_changed;
|
351
|
-
|
352
355
|
// When the encoding that is being used to parse the source is changed by
|
353
356
|
// YARP, we provide the ability here to call out to a user-defined function.
|
354
357
|
yp_encoding_changed_callback_t encoding_changed_callback;
|
@@ -367,13 +370,6 @@ struct yp_parser {
|
|
367
370
|
// be called whenever a new token is lexed by the parser.
|
368
371
|
yp_lex_callback_t *lex_callback;
|
369
372
|
|
370
|
-
// This flag indicates that we are currently parsing a pattern matching
|
371
|
-
// expression and impacts that calculation of newlines.
|
372
|
-
bool pattern_matching_newlines;
|
373
|
-
|
374
|
-
// This flag indicates that we are currently parsing a keyword argument.
|
375
|
-
bool in_keyword_arg;
|
376
|
-
|
377
373
|
// This is the path of the file being parsed
|
378
374
|
// We use the filepath when constructing SourceFileNodes
|
379
375
|
yp_string_t filepath_string;
|
@@ -384,6 +380,38 @@ struct yp_parser {
|
|
384
380
|
|
385
381
|
// This is the list of newline offsets in the source file.
|
386
382
|
yp_newline_list_t newline_list;
|
383
|
+
|
384
|
+
// We want to add a flag to integer nodes that indicates their base. We only
|
385
|
+
// want to parse these once, but we don't have space on the token itself to
|
386
|
+
// communicate this information. So we store it here and pass it through
|
387
|
+
// when we find tokens that we need it for.
|
388
|
+
yp_node_flags_t integer_base;
|
389
|
+
|
390
|
+
// Whether or not we're at the beginning of a command
|
391
|
+
bool command_start;
|
392
|
+
|
393
|
+
// Whether or not we're currently recovering from a syntax error
|
394
|
+
bool recovering;
|
395
|
+
|
396
|
+
// Whether or not the encoding has been changed by a magic comment. We use
|
397
|
+
// this to provide a fast path for the lexer instead of going through the
|
398
|
+
// function pointer.
|
399
|
+
bool encoding_changed;
|
400
|
+
|
401
|
+
// This flag indicates that we are currently parsing a pattern matching
|
402
|
+
// expression and impacts that calculation of newlines.
|
403
|
+
bool pattern_matching_newlines;
|
404
|
+
|
405
|
+
// This flag indicates that we are currently parsing a keyword argument.
|
406
|
+
bool in_keyword_arg;
|
407
|
+
|
408
|
+
// Whether or not the parser has seen a token that has semantic meaning
|
409
|
+
// (i.e., a token that is not a comment or whitespace).
|
410
|
+
bool semantic_token_seen;
|
411
|
+
|
412
|
+
// Whether or not we have found a frozen_string_literal magic comment with
|
413
|
+
// a true value.
|
414
|
+
bool frozen_string_literal;
|
387
415
|
};
|
388
416
|
|
389
417
|
#endif // YARP_PARSER_H
|
data/include/yarp/util/yp_char.h
CHANGED
@@ -31,19 +31,31 @@ size_t yp_strspn_decimal_digit(const uint8_t *string, ptrdiff_t length);
|
|
31
31
|
size_t yp_strspn_hexadecimal_digit(const uint8_t *string, ptrdiff_t length);
|
32
32
|
|
33
33
|
// Returns the number of characters at the start of the string that are octal
|
34
|
-
// digits or underscores.
|
34
|
+
// digits or underscores. Disallows searching past the given maximum number of
|
35
35
|
// characters.
|
36
|
-
|
36
|
+
//
|
37
|
+
// If multiple underscores are found in a row or if an underscore is
|
38
|
+
// found at the end of the number, then the invalid pointer is set to the index
|
39
|
+
// of the first invalid underscore.
|
40
|
+
size_t yp_strspn_octal_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid);
|
37
41
|
|
38
42
|
// Returns the number of characters at the start of the string that are decimal
|
39
43
|
// digits or underscores. Disallows searching past the given maximum number of
|
40
44
|
// characters.
|
41
|
-
|
45
|
+
//
|
46
|
+
// If multiple underscores are found in a row or if an underscore is
|
47
|
+
// found at the end of the number, then the invalid pointer is set to the index
|
48
|
+
// of the first invalid underscore.
|
49
|
+
size_t yp_strspn_decimal_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid);
|
42
50
|
|
43
51
|
// Returns the number of characters at the start of the string that are
|
44
52
|
// hexadecimal digits or underscores. Disallows searching past the given maximum
|
45
53
|
// number of characters.
|
46
|
-
|
54
|
+
//
|
55
|
+
// If multiple underscores are found in a row or if an underscore is
|
56
|
+
// found at the end of the number, then the invalid pointer is set to the index
|
57
|
+
// of the first invalid underscore.
|
58
|
+
size_t yp_strspn_hexadecimal_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid);
|
47
59
|
|
48
60
|
// Returns the number of characters at the start of the string that are regexp
|
49
61
|
// options. Disallows searching past the given maximum number of characters.
|
@@ -52,7 +64,11 @@ size_t yp_strspn_regexp_option(const uint8_t *string, ptrdiff_t length);
|
|
52
64
|
// Returns the number of characters at the start of the string that are binary
|
53
65
|
// digits or underscores. Disallows searching past the given maximum number of
|
54
66
|
// characters.
|
55
|
-
|
67
|
+
//
|
68
|
+
// If multiple underscores are found in a row or if an underscore is
|
69
|
+
// found at the end of the number, then the invalid pointer is set to the index
|
70
|
+
// of the first invalid underscore.
|
71
|
+
size_t yp_strspn_binary_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid);
|
56
72
|
|
57
73
|
// Returns true if the given character is a whitespace character.
|
58
74
|
bool yp_char_is_whitespace(const uint8_t b);
|
data/include/yarp/version.h
CHANGED
@@ -10,8 +10,13 @@ module YARP
|
|
10
10
|
# visited. This is useful for consumers that want to mutate the tree, as you
|
11
11
|
# can change subtrees in place without effecting the rest of the tree.
|
12
12
|
class MutationVisitor < BasicVisitor
|
13
|
-
# Copy a
|
14
|
-
def
|
13
|
+
# Copy a AliasGlobalVariableNode node
|
14
|
+
def visit_alias_global_variable_node(node)
|
15
|
+
node.copy(new_name: visit(node.new_name), old_name: visit(node.old_name))
|
16
|
+
end
|
17
|
+
|
18
|
+
# Copy a AliasMethodNode node
|
19
|
+
def visit_alias_method_node(node)
|
15
20
|
node.copy(new_name: visit(node.new_name), old_name: visit(node.old_name))
|
16
21
|
end
|
17
22
|
|
@@ -335,6 +340,11 @@ module YARP
|
|
335
340
|
node.copy(numeric: visit(node.numeric))
|
336
341
|
end
|
337
342
|
|
343
|
+
# Copy a ImplicitNode node
|
344
|
+
def visit_implicit_node(node)
|
345
|
+
node.copy(value: visit(node.value))
|
346
|
+
end
|
347
|
+
|
338
348
|
# Copy a InNode node
|
339
349
|
def visit_in_node(node)
|
340
350
|
node.copy(pattern: visit(node.pattern), statements: visit(node.statements))
|
@@ -375,6 +385,11 @@ module YARP
|
|
375
385
|
node.copy
|
376
386
|
end
|
377
387
|
|
388
|
+
# Copy a InterpolatedMatchLastLineNode node
|
389
|
+
def visit_interpolated_match_last_line_node(node)
|
390
|
+
node.copy(parts: visit_all(node.parts))
|
391
|
+
end
|
392
|
+
|
378
393
|
# Copy a InterpolatedRegularExpressionNode node
|
379
394
|
def visit_interpolated_regular_expression_node(node)
|
380
395
|
node.copy(parts: visit_all(node.parts))
|
@@ -445,6 +460,11 @@ module YARP
|
|
445
460
|
node.copy(value: visit(node.value))
|
446
461
|
end
|
447
462
|
|
463
|
+
# Copy a MatchLastLineNode node
|
464
|
+
def visit_match_last_line_node(node)
|
465
|
+
node.copy
|
466
|
+
end
|
467
|
+
|
448
468
|
# Copy a MatchPredicateNode node
|
449
469
|
def visit_match_predicate_node(node)
|
450
470
|
node.copy(value: visit(node.value), pattern: visit(node.pattern))
|
@@ -455,6 +475,11 @@ module YARP
|
|
455
475
|
node.copy(value: visit(node.value), pattern: visit(node.pattern))
|
456
476
|
end
|
457
477
|
|
478
|
+
# Copy a MatchWriteNode node
|
479
|
+
def visit_match_write_node(node)
|
480
|
+
node.copy(call: visit(node.call))
|
481
|
+
end
|
482
|
+
|
458
483
|
# Copy a MissingNode node
|
459
484
|
def visit_missing_node(node)
|
460
485
|
node.copy
|
@@ -507,7 +532,7 @@ module YARP
|
|
507
532
|
|
508
533
|
# Copy a ParametersNode node
|
509
534
|
def visit_parameters_node(node)
|
510
|
-
node.copy(requireds: visit_all(node.requireds), optionals: visit_all(node.optionals),
|
535
|
+
node.copy(requireds: visit_all(node.requireds), optionals: visit_all(node.optionals), rest: visit(node.rest), posts: visit_all(node.posts), keywords: visit_all(node.keywords), keyword_rest: visit(node.keyword_rest), block: visit(node.block))
|
511
536
|
end
|
512
537
|
|
513
538
|
# Copy a ParenthesesNode node
|