prism 0.23.0 → 0.25.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/BSDmakefile +58 -0
- data/CHANGELOG.md +65 -1
- data/Makefile +5 -2
- data/README.md +45 -6
- data/config.yml +499 -4
- data/docs/build_system.md +31 -0
- data/docs/configuration.md +2 -0
- data/docs/cruby_compilation.md +1 -1
- data/docs/parser_translation.md +14 -9
- data/docs/releasing.md +3 -3
- data/docs/ripper_translation.md +50 -0
- data/docs/ruby_api.md +1 -0
- data/docs/serialization.md +26 -5
- data/ext/prism/api_node.c +2342 -1801
- data/ext/prism/api_pack.c +9 -0
- data/ext/prism/extconf.rb +27 -11
- data/ext/prism/extension.c +313 -66
- data/ext/prism/extension.h +5 -4
- data/include/prism/ast.h +213 -64
- data/include/prism/defines.h +106 -2
- data/include/prism/diagnostic.h +134 -71
- data/include/prism/encoding.h +22 -4
- data/include/prism/node.h +93 -0
- data/include/prism/options.h +82 -7
- data/include/prism/pack.h +11 -0
- data/include/prism/parser.h +198 -53
- data/include/prism/prettyprint.h +8 -0
- data/include/prism/static_literals.h +118 -0
- data/include/prism/util/pm_buffer.h +65 -2
- data/include/prism/util/pm_constant_pool.h +18 -1
- data/include/prism/util/pm_integer.h +119 -0
- data/include/prism/util/pm_list.h +1 -1
- data/include/prism/util/pm_newline_list.h +12 -3
- data/include/prism/util/pm_string.h +26 -2
- data/include/prism/version.h +2 -2
- data/include/prism.h +59 -1
- data/lib/prism/compiler.rb +8 -1
- data/lib/prism/debug.rb +46 -3
- data/lib/prism/desugar_compiler.rb +225 -80
- data/lib/prism/dispatcher.rb +29 -0
- data/lib/prism/dot_visitor.rb +87 -16
- data/lib/prism/dsl.rb +315 -300
- data/lib/prism/ffi.rb +165 -84
- data/lib/prism/lex_compat.rb +17 -15
- data/lib/prism/mutation_compiler.rb +11 -0
- data/lib/prism/node.rb +4857 -3750
- data/lib/prism/node_ext.rb +77 -29
- data/lib/prism/pack.rb +4 -0
- data/lib/prism/parse_result/comments.rb +34 -17
- data/lib/prism/parse_result/newlines.rb +3 -1
- data/lib/prism/parse_result.rb +88 -34
- data/lib/prism/pattern.rb +16 -4
- data/lib/prism/polyfill/string.rb +12 -0
- data/lib/prism/serialize.rb +960 -327
- data/lib/prism/translation/parser/compiler.rb +152 -50
- data/lib/prism/translation/parser/lexer.rb +103 -22
- data/lib/prism/translation/parser/rubocop.rb +47 -11
- data/lib/prism/translation/parser.rb +134 -10
- data/lib/prism/translation/parser33.rb +12 -0
- data/lib/prism/translation/parser34.rb +12 -0
- data/lib/prism/translation/ripper/sexp.rb +125 -0
- data/lib/prism/translation/ripper/shim.rb +5 -0
- data/lib/prism/translation/ripper.rb +3248 -379
- data/lib/prism/translation/ruby_parser.rb +35 -18
- data/lib/prism/translation.rb +3 -1
- data/lib/prism/visitor.rb +10 -0
- data/lib/prism.rb +8 -2
- data/prism.gemspec +35 -4
- data/rbi/prism/compiler.rbi +14 -0
- data/rbi/prism/desugar_compiler.rbi +5 -0
- data/rbi/prism/mutation_compiler.rbi +5 -0
- data/rbi/prism/node.rbi +8221 -0
- data/rbi/prism/node_ext.rbi +102 -0
- data/rbi/prism/parse_result.rbi +304 -0
- data/rbi/prism/translation/parser/compiler.rbi +13 -0
- data/rbi/prism/translation/ripper/ripper_compiler.rbi +5 -0
- data/rbi/prism/translation/ripper.rbi +25 -0
- data/rbi/prism/translation/ruby_parser.rbi +11 -0
- data/rbi/prism/visitor.rbi +470 -0
- data/rbi/prism.rbi +39 -7749
- data/sig/prism/compiler.rbs +9 -0
- data/sig/prism/dispatcher.rbs +16 -0
- data/sig/prism/dot_visitor.rbs +6 -0
- data/sig/prism/dsl.rbs +462 -0
- data/sig/prism/mutation_compiler.rbs +158 -0
- data/sig/prism/node.rbs +3529 -0
- data/sig/prism/node_ext.rbs +78 -0
- data/sig/prism/pack.rbs +43 -0
- data/sig/prism/parse_result.rbs +127 -0
- data/sig/prism/pattern.rbs +13 -0
- data/sig/prism/serialize.rbs +7 -0
- data/sig/prism/visitor.rbs +168 -0
- data/sig/prism.rbs +188 -4767
- data/src/diagnostic.c +575 -230
- data/src/encoding.c +211 -108
- data/src/node.c +7526 -447
- data/src/options.c +36 -12
- data/src/pack.c +33 -17
- data/src/prettyprint.c +1297 -1388
- data/src/prism.c +3665 -1121
- data/src/regexp.c +17 -2
- data/src/serialize.c +47 -28
- data/src/static_literals.c +552 -0
- data/src/token_type.c +1 -0
- data/src/util/pm_buffer.c +147 -20
- data/src/util/pm_char.c +4 -4
- data/src/util/pm_constant_pool.c +35 -11
- data/src/util/pm_integer.c +629 -0
- data/src/util/pm_list.c +1 -1
- data/src/util/pm_newline_list.c +20 -8
- data/src/util/pm_string.c +134 -5
- data/src/util/pm_string_list.c +2 -2
- metadata +37 -6
- data/docs/ripper.md +0 -36
- data/rbi/prism_static.rbi +0 -207
- data/sig/prism_static.rbs +0 -201
data/include/prism/parser.h
CHANGED
@@ -6,8 +6,8 @@
|
|
6
6
|
#ifndef PRISM_PARSER_H
|
7
7
|
#define PRISM_PARSER_H
|
8
8
|
|
9
|
-
#include "prism/ast.h"
|
10
9
|
#include "prism/defines.h"
|
10
|
+
#include "prism/ast.h"
|
11
11
|
#include "prism/encoding.h"
|
12
12
|
#include "prism/options.h"
|
13
13
|
#include "prism/util/pm_constant_pool.h"
|
@@ -173,7 +173,7 @@ typedef struct pm_lex_mode {
|
|
173
173
|
* This is the character set that should be used to delimit the
|
174
174
|
* tokens within the regular expression.
|
175
175
|
*/
|
176
|
-
uint8_t breakpoints[
|
176
|
+
uint8_t breakpoints[7];
|
177
177
|
} regexp;
|
178
178
|
|
179
179
|
struct {
|
@@ -206,7 +206,7 @@ typedef struct pm_lex_mode {
|
|
206
206
|
* This is the character set that should be used to delimit the
|
207
207
|
* tokens within the string.
|
208
208
|
*/
|
209
|
-
uint8_t breakpoints[
|
209
|
+
uint8_t breakpoints[7];
|
210
210
|
} string;
|
211
211
|
|
212
212
|
struct {
|
@@ -234,6 +234,9 @@ typedef struct pm_lex_mode {
|
|
234
234
|
* a tilde heredoc.
|
235
235
|
*/
|
236
236
|
size_t common_whitespace;
|
237
|
+
|
238
|
+
/** True if the previous token ended with a line continuation. */
|
239
|
+
bool line_continuation;
|
237
240
|
} heredoc;
|
238
241
|
} as;
|
239
242
|
|
@@ -265,12 +268,30 @@ typedef enum {
|
|
265
268
|
/** a begin statement */
|
266
269
|
PM_CONTEXT_BEGIN,
|
267
270
|
|
271
|
+
/** an ensure statement with an explicit begin */
|
272
|
+
PM_CONTEXT_BEGIN_ENSURE,
|
273
|
+
|
274
|
+
/** a rescue else statement with an explicit begin */
|
275
|
+
PM_CONTEXT_BEGIN_ELSE,
|
276
|
+
|
277
|
+
/** a rescue statement with an explicit begin */
|
278
|
+
PM_CONTEXT_BEGIN_RESCUE,
|
279
|
+
|
268
280
|
/** expressions in block arguments using braces */
|
269
281
|
PM_CONTEXT_BLOCK_BRACES,
|
270
282
|
|
271
283
|
/** expressions in block arguments using do..end */
|
272
284
|
PM_CONTEXT_BLOCK_KEYWORDS,
|
273
285
|
|
286
|
+
/** an ensure statement within a do..end block */
|
287
|
+
PM_CONTEXT_BLOCK_ENSURE,
|
288
|
+
|
289
|
+
/** a rescue else statement within a do..end block */
|
290
|
+
PM_CONTEXT_BLOCK_ELSE,
|
291
|
+
|
292
|
+
/** a rescue statement within a do..end block */
|
293
|
+
PM_CONTEXT_BLOCK_RESCUE,
|
294
|
+
|
274
295
|
/** a case when statements */
|
275
296
|
PM_CONTEXT_CASE_WHEN,
|
276
297
|
|
@@ -280,12 +301,33 @@ typedef enum {
|
|
280
301
|
/** a class declaration */
|
281
302
|
PM_CONTEXT_CLASS,
|
282
303
|
|
304
|
+
/** an ensure statement within a class statement */
|
305
|
+
PM_CONTEXT_CLASS_ENSURE,
|
306
|
+
|
307
|
+
/** a rescue else statement within a class statement */
|
308
|
+
PM_CONTEXT_CLASS_ELSE,
|
309
|
+
|
310
|
+
/** a rescue statement within a class statement */
|
311
|
+
PM_CONTEXT_CLASS_RESCUE,
|
312
|
+
|
283
313
|
/** a method definition */
|
284
314
|
PM_CONTEXT_DEF,
|
285
315
|
|
316
|
+
/** an ensure statement within a method definition */
|
317
|
+
PM_CONTEXT_DEF_ENSURE,
|
318
|
+
|
319
|
+
/** a rescue else statement within a method definition */
|
320
|
+
PM_CONTEXT_DEF_ELSE,
|
321
|
+
|
322
|
+
/** a rescue statement within a method definition */
|
323
|
+
PM_CONTEXT_DEF_RESCUE,
|
324
|
+
|
286
325
|
/** a method definition's parameters */
|
287
326
|
PM_CONTEXT_DEF_PARAMS,
|
288
327
|
|
328
|
+
/** a defined? expression */
|
329
|
+
PM_CONTEXT_DEFINED,
|
330
|
+
|
289
331
|
/** a method definition's default parameter */
|
290
332
|
PM_CONTEXT_DEFAULT_PARAMS,
|
291
333
|
|
@@ -298,12 +340,6 @@ typedef enum {
|
|
298
340
|
/** an interpolated expression */
|
299
341
|
PM_CONTEXT_EMBEXPR,
|
300
342
|
|
301
|
-
/** an ensure statement */
|
302
|
-
PM_CONTEXT_ENSURE,
|
303
|
-
|
304
|
-
/** an ensure statement within a method definition */
|
305
|
-
PM_CONTEXT_ENSURE_DEF,
|
306
|
-
|
307
343
|
/** a for loop */
|
308
344
|
PM_CONTEXT_FOR,
|
309
345
|
|
@@ -319,12 +355,30 @@ typedef enum {
|
|
319
355
|
/** a lambda expression with do..end */
|
320
356
|
PM_CONTEXT_LAMBDA_DO_END,
|
321
357
|
|
358
|
+
/** an ensure statement within a lambda expression */
|
359
|
+
PM_CONTEXT_LAMBDA_ENSURE,
|
360
|
+
|
361
|
+
/** a rescue else statement within a lambda expression */
|
362
|
+
PM_CONTEXT_LAMBDA_ELSE,
|
363
|
+
|
364
|
+
/** a rescue statement within a lambda expression */
|
365
|
+
PM_CONTEXT_LAMBDA_RESCUE,
|
366
|
+
|
322
367
|
/** the top level context */
|
323
368
|
PM_CONTEXT_MAIN,
|
324
369
|
|
325
370
|
/** a module declaration */
|
326
371
|
PM_CONTEXT_MODULE,
|
327
372
|
|
373
|
+
/** an ensure statement within a module statement */
|
374
|
+
PM_CONTEXT_MODULE_ENSURE,
|
375
|
+
|
376
|
+
/** a rescue else statement within a module statement */
|
377
|
+
PM_CONTEXT_MODULE_ELSE,
|
378
|
+
|
379
|
+
/** a rescue statement within a module statement */
|
380
|
+
PM_CONTEXT_MODULE_RESCUE,
|
381
|
+
|
328
382
|
/** a parenthesized expression */
|
329
383
|
PM_CONTEXT_PARENS,
|
330
384
|
|
@@ -337,20 +391,23 @@ typedef enum {
|
|
337
391
|
/** a BEGIN block */
|
338
392
|
PM_CONTEXT_PREEXE,
|
339
393
|
|
340
|
-
/** a rescue
|
341
|
-
|
394
|
+
/** a modifier rescue clause */
|
395
|
+
PM_CONTEXT_RESCUE_MODIFIER,
|
342
396
|
|
343
|
-
/** a
|
344
|
-
|
397
|
+
/** a singleton class definition */
|
398
|
+
PM_CONTEXT_SCLASS,
|
345
399
|
|
346
|
-
/**
|
347
|
-
|
400
|
+
/** an ensure statement with a singleton class */
|
401
|
+
PM_CONTEXT_SCLASS_ENSURE,
|
348
402
|
|
349
|
-
/** a rescue statement
|
350
|
-
|
403
|
+
/** a rescue else statement with a singleton class */
|
404
|
+
PM_CONTEXT_SCLASS_ELSE,
|
351
405
|
|
352
|
-
/** a singleton class
|
353
|
-
|
406
|
+
/** a rescue statement with a singleton class */
|
407
|
+
PM_CONTEXT_SCLASS_RESCUE,
|
408
|
+
|
409
|
+
/** a ternary expression */
|
410
|
+
PM_CONTEXT_TERNARY,
|
354
411
|
|
355
412
|
/** an unless statement */
|
356
413
|
PM_CONTEXT_UNLESS,
|
@@ -445,42 +502,80 @@ typedef struct {
|
|
445
502
|
void (*callback)(void *data, pm_parser_t *parser, pm_token_t *token);
|
446
503
|
} pm_lex_callback_t;
|
447
504
|
|
505
|
+
/** The type of shareable constant value that can be set. */
|
506
|
+
typedef uint8_t pm_shareable_constant_value_t;
|
507
|
+
static const pm_shareable_constant_value_t PM_SCOPE_SHAREABLE_CONSTANT_NONE = 0x0;
|
508
|
+
static const pm_shareable_constant_value_t PM_SCOPE_SHAREABLE_CONSTANT_LITERAL = 0x1;
|
509
|
+
static const pm_shareable_constant_value_t PM_SCOPE_SHAREABLE_CONSTANT_EXPERIMENTAL_EVERYTHING = 0x2;
|
510
|
+
static const pm_shareable_constant_value_t PM_SCOPE_SHAREABLE_CONSTANT_EXPERIMENTAL_COPY = 0x4;
|
511
|
+
|
512
|
+
/**
|
513
|
+
* This tracks an individual local variable in a certain lexical context, as
|
514
|
+
* well as the number of times is it read.
|
515
|
+
*/
|
516
|
+
typedef struct {
|
517
|
+
/** The name of the local variable. */
|
518
|
+
pm_constant_id_t name;
|
519
|
+
|
520
|
+
/** The location of the local variable in the source. */
|
521
|
+
pm_location_t location;
|
522
|
+
|
523
|
+
/** The index of the local variable in the local table. */
|
524
|
+
uint32_t index;
|
525
|
+
|
526
|
+
/** The number of times the local variable is read. */
|
527
|
+
uint32_t reads;
|
528
|
+
|
529
|
+
/** The hash of the local variable. */
|
530
|
+
uint32_t hash;
|
531
|
+
} pm_local_t;
|
532
|
+
|
533
|
+
/**
|
534
|
+
* This is a set of local variables in a certain lexical context (method, class,
|
535
|
+
* module, etc.). We need to track how many times these variables are read in
|
536
|
+
* order to warn if they only get written.
|
537
|
+
*/
|
538
|
+
typedef struct pm_locals {
|
539
|
+
/** The number of local variables in the set. */
|
540
|
+
uint32_t size;
|
541
|
+
|
542
|
+
/** The capacity of the local variables set. */
|
543
|
+
uint32_t capacity;
|
544
|
+
|
545
|
+
/** The nullable allocated memory for the local variables in the set. */
|
546
|
+
pm_local_t *locals;
|
547
|
+
} pm_locals_t;
|
548
|
+
|
448
549
|
/**
|
449
550
|
* This struct represents a node in a linked list of scopes. Some scopes can see
|
450
551
|
* into their parent scopes, while others cannot.
|
451
552
|
*/
|
452
553
|
typedef struct pm_scope {
|
453
|
-
/** The IDs of the locals in the given scope. */
|
454
|
-
pm_constant_id_list_t locals;
|
455
|
-
|
456
554
|
/** A pointer to the previous scope in the linked list. */
|
457
555
|
struct pm_scope *previous;
|
458
556
|
|
459
|
-
/**
|
460
|
-
|
461
|
-
* If closed is true, then the scope cannot see into its parent.
|
462
|
-
*/
|
463
|
-
bool closed;
|
464
|
-
|
465
|
-
/**
|
466
|
-
* A boolean indicating whether or not this scope has explicit parameters.
|
467
|
-
* This is necessary to determine whether or not numbered parameters are
|
468
|
-
* allowed.
|
469
|
-
*/
|
470
|
-
bool explicit_params;
|
557
|
+
/** The IDs of the locals in the given scope. */
|
558
|
+
pm_locals_t locals;
|
471
559
|
|
472
560
|
/**
|
473
|
-
*
|
474
|
-
*
|
561
|
+
* This is a bitfield that indicates the parameters that are being used in
|
562
|
+
* this scope. It is a combination of the PM_SCOPE_PARAMS_* constants. There
|
563
|
+
* are three different kinds of parameters that can be used in a scope:
|
475
564
|
*
|
476
|
-
*
|
477
|
-
*
|
478
|
-
*
|
479
|
-
*
|
480
|
-
*
|
565
|
+
* - Ordinary parameters (e.g., def foo(bar); end)
|
566
|
+
* - Numbered parameters (e.g., def foo; _1; end)
|
567
|
+
* - The it parameter (e.g., def foo; it; end)
|
568
|
+
*
|
569
|
+
* If ordinary parameters are being used, then certain parameters can be
|
570
|
+
* forwarded to another method/structure. Those are indicated by four
|
571
|
+
* additional bits in the params field. For example, some combinations of:
|
572
|
+
*
|
573
|
+
* - def foo(*); end
|
574
|
+
* - def foo(**); end
|
575
|
+
* - def foo(&); end
|
576
|
+
* - def foo(...); end
|
481
577
|
*/
|
482
|
-
|
483
|
-
uint8_t forwarding_params;
|
578
|
+
uint8_t parameters;
|
484
579
|
|
485
580
|
/**
|
486
581
|
* An integer indicating the number of numbered parameters on this scope.
|
@@ -488,13 +583,34 @@ typedef struct pm_scope {
|
|
488
583
|
* numbered parameters, and to pass information to consumers of the AST
|
489
584
|
* about how many numbered parameters exist.
|
490
585
|
*/
|
491
|
-
|
586
|
+
int8_t numbered_parameters;
|
587
|
+
|
588
|
+
/**
|
589
|
+
* The current state of constant shareability for this scope. This is
|
590
|
+
* changed by magic shareable_constant_value comments.
|
591
|
+
*/
|
592
|
+
pm_shareable_constant_value_t shareable_constant;
|
593
|
+
|
594
|
+
/**
|
595
|
+
* A boolean indicating whether or not this scope can see into its parent.
|
596
|
+
* If closed is true, then the scope cannot see into its parent.
|
597
|
+
*/
|
598
|
+
bool closed;
|
492
599
|
} pm_scope_t;
|
493
600
|
|
494
|
-
static const uint8_t
|
495
|
-
static const uint8_t
|
496
|
-
static const uint8_t
|
497
|
-
static const uint8_t
|
601
|
+
static const uint8_t PM_SCOPE_PARAMETERS_NONE = 0x0;
|
602
|
+
static const uint8_t PM_SCOPE_PARAMETERS_ORDINARY = 0x1;
|
603
|
+
static const uint8_t PM_SCOPE_PARAMETERS_NUMBERED = 0x2;
|
604
|
+
static const uint8_t PM_SCOPE_PARAMETERS_IT = 0x4;
|
605
|
+
static const uint8_t PM_SCOPE_PARAMETERS_TYPE_MASK = 0x7;
|
606
|
+
|
607
|
+
static const uint8_t PM_SCOPE_PARAMETERS_FORWARDING_POSITIONALS = 0x8;
|
608
|
+
static const uint8_t PM_SCOPE_PARAMETERS_FORWARDING_KEYWORDS = 0x10;
|
609
|
+
static const uint8_t PM_SCOPE_PARAMETERS_FORWARDING_BLOCK = 0x20;
|
610
|
+
static const uint8_t PM_SCOPE_PARAMETERS_FORWARDING_ALL = 0x40;
|
611
|
+
|
612
|
+
static const int8_t PM_SCOPE_NUMBERED_PARAMETERS_DISALLOWED = -1;
|
613
|
+
static const int8_t PM_SCOPE_NUMBERED_PARAMETERS_NONE = 0;
|
498
614
|
|
499
615
|
/**
|
500
616
|
* This struct represents the overall parser. It contains a reference to the
|
@@ -688,12 +804,41 @@ struct pm_parser {
|
|
688
804
|
*/
|
689
805
|
const pm_encoding_t *explicit_encoding;
|
690
806
|
|
691
|
-
/**
|
692
|
-
|
807
|
+
/**
|
808
|
+
* When parsing block exits (e.g., break, next, redo), we need to validate
|
809
|
+
* that they are in correct contexts. For the most part we can do this by
|
810
|
+
* looking at our parent contexts. However, modifier while and until
|
811
|
+
* expressions can change that context to make block exits valid. In these
|
812
|
+
* cases, we need to keep track of the block exits and then validate them
|
813
|
+
* after the expression has been parsed.
|
814
|
+
*
|
815
|
+
* We use a pointer here because we don't want to keep a whole list attached
|
816
|
+
* since this will only be used in the context of begin/end expressions.
|
817
|
+
*/
|
818
|
+
pm_node_list_t *current_block_exits;
|
693
819
|
|
694
820
|
/** The version of prism that we should use to parse. */
|
695
821
|
pm_options_version_t version;
|
696
822
|
|
823
|
+
/** The command line flags given from the options. */
|
824
|
+
uint8_t command_line;
|
825
|
+
|
826
|
+
/**
|
827
|
+
* Whether or not we have found a frozen_string_literal magic comment with
|
828
|
+
* a true or false value.
|
829
|
+
* May be:
|
830
|
+
* - PM_OPTIONS_FROZEN_STRING_LITERAL_DISABLED
|
831
|
+
* - PM_OPTIONS_FROZEN_STRING_LITERAL_ENABLED
|
832
|
+
* - PM_OPTIONS_FROZEN_STRING_LITERAL_UNSET
|
833
|
+
*/
|
834
|
+
int8_t frozen_string_literal;
|
835
|
+
|
836
|
+
/**
|
837
|
+
* Whether or not we are parsing an eval string. This impacts whether or not
|
838
|
+
* we should evaluate if block exits/yields are valid.
|
839
|
+
*/
|
840
|
+
bool parsing_eval;
|
841
|
+
|
697
842
|
/** Whether or not we're at the beginning of a command. */
|
698
843
|
bool command_start;
|
699
844
|
|
@@ -723,10 +868,10 @@ struct pm_parser {
|
|
723
868
|
bool semantic_token_seen;
|
724
869
|
|
725
870
|
/**
|
726
|
-
*
|
727
|
-
*
|
871
|
+
* True if the current regular expression being lexed contains only ASCII
|
872
|
+
* characters.
|
728
873
|
*/
|
729
|
-
bool
|
874
|
+
bool current_regular_expression_ascii_only;
|
730
875
|
};
|
731
876
|
|
732
877
|
#endif
|
data/include/prism/prettyprint.h
CHANGED
@@ -8,6 +8,12 @@
|
|
8
8
|
|
9
9
|
#include "prism/defines.h"
|
10
10
|
|
11
|
+
#ifdef PRISM_EXCLUDE_PRETTYPRINT
|
12
|
+
|
13
|
+
void pm_prettyprint(void);
|
14
|
+
|
15
|
+
#else
|
16
|
+
|
11
17
|
#include <stdio.h>
|
12
18
|
|
13
19
|
#include "prism/ast.h"
|
@@ -24,3 +30,5 @@
|
|
24
30
|
PRISM_EXPORTED_FUNCTION void pm_prettyprint(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm_node_t *node);
|
25
31
|
|
26
32
|
#endif
|
33
|
+
|
34
|
+
#endif
|
@@ -0,0 +1,118 @@
|
|
1
|
+
/**
|
2
|
+
* @file static_literals.h
|
3
|
+
*
|
4
|
+
* A set of static literal nodes that can be checked for duplicates.
|
5
|
+
*/
|
6
|
+
#ifndef PRISM_STATIC_LITERALS_H
|
7
|
+
#define PRISM_STATIC_LITERALS_H
|
8
|
+
|
9
|
+
#include "prism/defines.h"
|
10
|
+
#include "prism/ast.h"
|
11
|
+
#include "prism/node.h"
|
12
|
+
#include "prism/parser.h"
|
13
|
+
|
14
|
+
#include <assert.h>
|
15
|
+
#include <stdbool.h>
|
16
|
+
|
17
|
+
/**
|
18
|
+
* An internal hash table for a set of nodes.
|
19
|
+
*/
|
20
|
+
typedef struct {
|
21
|
+
/** The array of nodes in the hash table. */
|
22
|
+
pm_node_t **nodes;
|
23
|
+
|
24
|
+
/** The size of the hash table. */
|
25
|
+
uint32_t size;
|
26
|
+
|
27
|
+
/** The space that has been allocated in the hash table. */
|
28
|
+
uint32_t capacity;
|
29
|
+
} pm_node_hash_t;
|
30
|
+
|
31
|
+
/**
|
32
|
+
* Certain sets of nodes (hash keys and when clauses) check for duplicate nodes
|
33
|
+
* to alert the user of potential issues. To do this, we keep a set of the nodes
|
34
|
+
* that have been seen so far, and compare whenever we find a new node.
|
35
|
+
*
|
36
|
+
* We bucket the nodes based on their type to minimize the number of comparisons
|
37
|
+
* that need to be performed.
|
38
|
+
*/
|
39
|
+
typedef struct {
|
40
|
+
/**
|
41
|
+
* This is the set of IntegerNode and SourceLineNode instances.
|
42
|
+
*/
|
43
|
+
pm_node_hash_t integer_nodes;
|
44
|
+
|
45
|
+
/**
|
46
|
+
* This is the set of FloatNode instances.
|
47
|
+
*/
|
48
|
+
pm_node_hash_t float_nodes;
|
49
|
+
|
50
|
+
/**
|
51
|
+
* This is the set of RationalNode and ImaginaryNode instances.
|
52
|
+
*/
|
53
|
+
pm_node_hash_t number_nodes;
|
54
|
+
|
55
|
+
/**
|
56
|
+
* This is the set of StringNode and SourceFileNode instances.
|
57
|
+
*/
|
58
|
+
pm_node_hash_t string_nodes;
|
59
|
+
|
60
|
+
/**
|
61
|
+
* This is the set of RegularExpressionNode instances.
|
62
|
+
*/
|
63
|
+
pm_node_hash_t regexp_nodes;
|
64
|
+
|
65
|
+
/**
|
66
|
+
* This is the set of SymbolNode instances.
|
67
|
+
*/
|
68
|
+
pm_node_hash_t symbol_nodes;
|
69
|
+
|
70
|
+
/**
|
71
|
+
* A pointer to the last TrueNode instance that was inserted, or NULL.
|
72
|
+
*/
|
73
|
+
pm_node_t *true_node;
|
74
|
+
|
75
|
+
/**
|
76
|
+
* A pointer to the last FalseNode instance that was inserted, or NULL.
|
77
|
+
*/
|
78
|
+
pm_node_t *false_node;
|
79
|
+
|
80
|
+
/**
|
81
|
+
* A pointer to the last NilNode instance that was inserted, or NULL.
|
82
|
+
*/
|
83
|
+
pm_node_t *nil_node;
|
84
|
+
|
85
|
+
/**
|
86
|
+
* A pointer to the last SourceEncodingNode instance that was inserted, or
|
87
|
+
* NULL.
|
88
|
+
*/
|
89
|
+
pm_node_t *source_encoding_node;
|
90
|
+
} pm_static_literals_t;
|
91
|
+
|
92
|
+
/**
|
93
|
+
* Add a node to the set of static literals.
|
94
|
+
*
|
95
|
+
* @param parser The parser that created the node.
|
96
|
+
* @param literals The set of static literals to add the node to.
|
97
|
+
* @param node The node to add to the set.
|
98
|
+
* @return A pointer to the node that is being overwritten, if there is one.
|
99
|
+
*/
|
100
|
+
pm_node_t * pm_static_literals_add(const pm_parser_t *parser, pm_static_literals_t *literals, pm_node_t *node);
|
101
|
+
|
102
|
+
/**
|
103
|
+
* Free the internal memory associated with the given static literals set.
|
104
|
+
*
|
105
|
+
* @param literals The set of static literals to free.
|
106
|
+
*/
|
107
|
+
void pm_static_literals_free(pm_static_literals_t *literals);
|
108
|
+
|
109
|
+
/**
|
110
|
+
* Create a string-based representation of the given static literal.
|
111
|
+
*
|
112
|
+
* @param buffer The buffer to write the string to.
|
113
|
+
* @param parser The parser that created the node.
|
114
|
+
* @param node The node to create a string representation of.
|
115
|
+
*/
|
116
|
+
PRISM_EXPORTED_FUNCTION void pm_static_literal_inspect(pm_buffer_t *buffer, const pm_parser_t *parser, const pm_node_t *node);
|
117
|
+
|
118
|
+
#endif
|
@@ -7,6 +7,7 @@
|
|
7
7
|
#define PRISM_BUFFER_H
|
8
8
|
|
9
9
|
#include "prism/defines.h"
|
10
|
+
#include "prism/util/pm_char.h"
|
10
11
|
|
11
12
|
#include <assert.h>
|
12
13
|
#include <stdbool.h>
|
@@ -59,7 +60,7 @@ PRISM_EXPORTED_FUNCTION bool pm_buffer_init(pm_buffer_t *buffer);
|
|
59
60
|
* @param buffer The buffer to get the value of.
|
60
61
|
* @returns The value of the buffer.
|
61
62
|
*/
|
62
|
-
PRISM_EXPORTED_FUNCTION char * pm_buffer_value(pm_buffer_t *buffer);
|
63
|
+
PRISM_EXPORTED_FUNCTION char * pm_buffer_value(const pm_buffer_t *buffer);
|
63
64
|
|
64
65
|
/**
|
65
66
|
* Return the length of the buffer.
|
@@ -67,7 +68,7 @@ PRISM_EXPORTED_FUNCTION char * pm_buffer_value(pm_buffer_t *buffer);
|
|
67
68
|
* @param buffer The buffer to get the length of.
|
68
69
|
* @returns The length of the buffer.
|
69
70
|
*/
|
70
|
-
PRISM_EXPORTED_FUNCTION size_t pm_buffer_length(pm_buffer_t *buffer);
|
71
|
+
PRISM_EXPORTED_FUNCTION size_t pm_buffer_length(const pm_buffer_t *buffer);
|
71
72
|
|
72
73
|
/**
|
73
74
|
* Append the given amount of space as zeroes to the buffer.
|
@@ -128,6 +129,33 @@ void pm_buffer_append_varuint(pm_buffer_t *buffer, uint32_t value);
|
|
128
129
|
*/
|
129
130
|
void pm_buffer_append_varsint(pm_buffer_t *buffer, int32_t value);
|
130
131
|
|
132
|
+
/**
|
133
|
+
* Append a double to the buffer.
|
134
|
+
*
|
135
|
+
* @param buffer The buffer to append to.
|
136
|
+
* @param value The double to append.
|
137
|
+
*/
|
138
|
+
void pm_buffer_append_double(pm_buffer_t *buffer, double value);
|
139
|
+
|
140
|
+
/**
|
141
|
+
* The different types of escaping that can be performed by the buffer when
|
142
|
+
* appending a slice of Ruby source code.
|
143
|
+
*/
|
144
|
+
typedef enum {
|
145
|
+
PM_BUFFER_ESCAPING_RUBY,
|
146
|
+
PM_BUFFER_ESCAPING_JSON
|
147
|
+
} pm_buffer_escaping_t;
|
148
|
+
|
149
|
+
/**
|
150
|
+
* Append a slice of source code to the buffer.
|
151
|
+
*
|
152
|
+
* @param buffer The buffer to append to.
|
153
|
+
* @param source The source code to append.
|
154
|
+
* @param length The length of the source code to append.
|
155
|
+
* @param escaping The type of escaping to perform.
|
156
|
+
*/
|
157
|
+
void pm_buffer_append_source(pm_buffer_t *buffer, const uint8_t *source, size_t length, pm_buffer_escaping_t escaping);
|
158
|
+
|
131
159
|
/**
|
132
160
|
* Prepend the given string to the buffer.
|
133
161
|
*
|
@@ -145,6 +173,41 @@ void pm_buffer_prepend_string(pm_buffer_t *buffer, const char *value, size_t len
|
|
145
173
|
*/
|
146
174
|
void pm_buffer_concat(pm_buffer_t *destination, const pm_buffer_t *source);
|
147
175
|
|
176
|
+
/**
|
177
|
+
* Clear the buffer by reducing its size to 0. This does not free the allocated
|
178
|
+
* memory, but it does allow the buffer to be reused.
|
179
|
+
*
|
180
|
+
* @param buffer The buffer to clear.
|
181
|
+
*/
|
182
|
+
void pm_buffer_clear(pm_buffer_t *buffer);
|
183
|
+
|
184
|
+
/**
|
185
|
+
* Strip the whitespace from the end of the buffer.
|
186
|
+
*
|
187
|
+
* @param buffer The buffer to strip.
|
188
|
+
*/
|
189
|
+
void pm_buffer_rstrip(pm_buffer_t *buffer);
|
190
|
+
|
191
|
+
/**
|
192
|
+
* Checks if the buffer includes the given value.
|
193
|
+
*
|
194
|
+
* @param buffer The buffer to check.
|
195
|
+
* @param value The value to check for.
|
196
|
+
* @returns The index of the first occurrence of the value in the buffer, or
|
197
|
+
* SIZE_MAX if the value is not found.
|
198
|
+
*/
|
199
|
+
size_t pm_buffer_index(const pm_buffer_t *buffer, char value);
|
200
|
+
|
201
|
+
/**
|
202
|
+
* Insert the given string into the buffer at the given index.
|
203
|
+
*
|
204
|
+
* @param buffer The buffer to insert into.
|
205
|
+
* @param index The index to insert at.
|
206
|
+
* @param value The string to insert.
|
207
|
+
* @param length The length of the string to insert.
|
208
|
+
*/
|
209
|
+
void pm_buffer_insert(pm_buffer_t *buffer, size_t index, const char *value, size_t length);
|
210
|
+
|
148
211
|
/**
|
149
212
|
* Free the memory associated with the buffer.
|
150
213
|
*
|
@@ -51,6 +51,14 @@ typedef struct {
|
|
51
51
|
*/
|
52
52
|
void pm_constant_id_list_init(pm_constant_id_list_t *list);
|
53
53
|
|
54
|
+
/**
|
55
|
+
* Initialize a list of constant ids with a given capacity.
|
56
|
+
*
|
57
|
+
* @param list The list to initialize.
|
58
|
+
* @param capacity The initial capacity of the list.
|
59
|
+
*/
|
60
|
+
void pm_constant_id_list_init_capacity(pm_constant_id_list_t *list, size_t capacity);
|
61
|
+
|
54
62
|
/**
|
55
63
|
* Append a constant id to a list of constant ids. Returns false if any
|
56
64
|
* potential reallocations fail.
|
@@ -61,6 +69,15 @@ void pm_constant_id_list_init(pm_constant_id_list_t *list);
|
|
61
69
|
*/
|
62
70
|
bool pm_constant_id_list_append(pm_constant_id_list_t *list, pm_constant_id_t id);
|
63
71
|
|
72
|
+
/**
|
73
|
+
* Insert a constant id into a list of constant ids at the specified index.
|
74
|
+
*
|
75
|
+
* @param list The list to insert into.
|
76
|
+
* @param index The index at which to insert.
|
77
|
+
* @param id The id to insert.
|
78
|
+
*/
|
79
|
+
void pm_constant_id_list_insert(pm_constant_id_list_t *list, size_t index, pm_constant_id_t id);
|
80
|
+
|
64
81
|
/**
|
65
82
|
* Checks if the current constant id list includes the given constant id.
|
66
83
|
*
|
@@ -186,7 +203,7 @@ pm_constant_id_t pm_constant_pool_insert_shared(pm_constant_pool_t *pool, const
|
|
186
203
|
* @param length The length of the constant.
|
187
204
|
* @return The id of the constant.
|
188
205
|
*/
|
189
|
-
pm_constant_id_t pm_constant_pool_insert_owned(pm_constant_pool_t *pool,
|
206
|
+
pm_constant_id_t pm_constant_pool_insert_owned(pm_constant_pool_t *pool, uint8_t *start, size_t length);
|
190
207
|
|
191
208
|
/**
|
192
209
|
* Insert a constant into a constant pool from memory that is constant. Returns
|