yarp 0.11.0 → 0.12.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/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
|