prism 0.14.0 → 0.15.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.
data/include/prism/ast.h CHANGED
@@ -277,79 +277,82 @@ enum pm_node_type {
277
277
  PM_IMAGINARY_NODE = 66,
278
278
  PM_IMPLICIT_NODE = 67,
279
279
  PM_IN_NODE = 68,
280
- PM_INSTANCE_VARIABLE_AND_WRITE_NODE = 69,
281
- PM_INSTANCE_VARIABLE_OPERATOR_WRITE_NODE = 70,
282
- PM_INSTANCE_VARIABLE_OR_WRITE_NODE = 71,
283
- PM_INSTANCE_VARIABLE_READ_NODE = 72,
284
- PM_INSTANCE_VARIABLE_TARGET_NODE = 73,
285
- PM_INSTANCE_VARIABLE_WRITE_NODE = 74,
286
- PM_INTEGER_NODE = 75,
287
- PM_INTERPOLATED_MATCH_LAST_LINE_NODE = 76,
288
- PM_INTERPOLATED_REGULAR_EXPRESSION_NODE = 77,
289
- PM_INTERPOLATED_STRING_NODE = 78,
290
- PM_INTERPOLATED_SYMBOL_NODE = 79,
291
- PM_INTERPOLATED_X_STRING_NODE = 80,
292
- PM_KEYWORD_HASH_NODE = 81,
293
- PM_KEYWORD_PARAMETER_NODE = 82,
294
- PM_KEYWORD_REST_PARAMETER_NODE = 83,
295
- PM_LAMBDA_NODE = 84,
296
- PM_LOCAL_VARIABLE_AND_WRITE_NODE = 85,
297
- PM_LOCAL_VARIABLE_OPERATOR_WRITE_NODE = 86,
298
- PM_LOCAL_VARIABLE_OR_WRITE_NODE = 87,
299
- PM_LOCAL_VARIABLE_READ_NODE = 88,
300
- PM_LOCAL_VARIABLE_TARGET_NODE = 89,
301
- PM_LOCAL_VARIABLE_WRITE_NODE = 90,
302
- PM_MATCH_LAST_LINE_NODE = 91,
303
- PM_MATCH_PREDICATE_NODE = 92,
304
- PM_MATCH_REQUIRED_NODE = 93,
305
- PM_MATCH_WRITE_NODE = 94,
306
- PM_MISSING_NODE = 95,
307
- PM_MODULE_NODE = 96,
308
- PM_MULTI_TARGET_NODE = 97,
309
- PM_MULTI_WRITE_NODE = 98,
310
- PM_NEXT_NODE = 99,
311
- PM_NIL_NODE = 100,
312
- PM_NO_KEYWORDS_PARAMETER_NODE = 101,
313
- PM_NUMBERED_REFERENCE_READ_NODE = 102,
314
- PM_OPTIONAL_PARAMETER_NODE = 103,
315
- PM_OR_NODE = 104,
316
- PM_PARAMETERS_NODE = 105,
317
- PM_PARENTHESES_NODE = 106,
318
- PM_PINNED_EXPRESSION_NODE = 107,
319
- PM_PINNED_VARIABLE_NODE = 108,
320
- PM_POST_EXECUTION_NODE = 109,
321
- PM_PRE_EXECUTION_NODE = 110,
322
- PM_PROGRAM_NODE = 111,
323
- PM_RANGE_NODE = 112,
324
- PM_RATIONAL_NODE = 113,
325
- PM_REDO_NODE = 114,
326
- PM_REGULAR_EXPRESSION_NODE = 115,
327
- PM_REQUIRED_DESTRUCTURED_PARAMETER_NODE = 116,
328
- PM_REQUIRED_PARAMETER_NODE = 117,
329
- PM_RESCUE_MODIFIER_NODE = 118,
330
- PM_RESCUE_NODE = 119,
331
- PM_REST_PARAMETER_NODE = 120,
332
- PM_RETRY_NODE = 121,
333
- PM_RETURN_NODE = 122,
334
- PM_SELF_NODE = 123,
335
- PM_SINGLETON_CLASS_NODE = 124,
336
- PM_SOURCE_ENCODING_NODE = 125,
337
- PM_SOURCE_FILE_NODE = 126,
338
- PM_SOURCE_LINE_NODE = 127,
339
- PM_SPLAT_NODE = 128,
340
- PM_STATEMENTS_NODE = 129,
341
- PM_STRING_CONCAT_NODE = 130,
342
- PM_STRING_NODE = 131,
343
- PM_SUPER_NODE = 132,
344
- PM_SYMBOL_NODE = 133,
345
- PM_TRUE_NODE = 134,
346
- PM_UNDEF_NODE = 135,
347
- PM_UNLESS_NODE = 136,
348
- PM_UNTIL_NODE = 137,
349
- PM_WHEN_NODE = 138,
350
- PM_WHILE_NODE = 139,
351
- PM_X_STRING_NODE = 140,
352
- PM_YIELD_NODE = 141,
280
+ PM_INDEX_AND_WRITE_NODE = 69,
281
+ PM_INDEX_OPERATOR_WRITE_NODE = 70,
282
+ PM_INDEX_OR_WRITE_NODE = 71,
283
+ PM_INSTANCE_VARIABLE_AND_WRITE_NODE = 72,
284
+ PM_INSTANCE_VARIABLE_OPERATOR_WRITE_NODE = 73,
285
+ PM_INSTANCE_VARIABLE_OR_WRITE_NODE = 74,
286
+ PM_INSTANCE_VARIABLE_READ_NODE = 75,
287
+ PM_INSTANCE_VARIABLE_TARGET_NODE = 76,
288
+ PM_INSTANCE_VARIABLE_WRITE_NODE = 77,
289
+ PM_INTEGER_NODE = 78,
290
+ PM_INTERPOLATED_MATCH_LAST_LINE_NODE = 79,
291
+ PM_INTERPOLATED_REGULAR_EXPRESSION_NODE = 80,
292
+ PM_INTERPOLATED_STRING_NODE = 81,
293
+ PM_INTERPOLATED_SYMBOL_NODE = 82,
294
+ PM_INTERPOLATED_X_STRING_NODE = 83,
295
+ PM_KEYWORD_HASH_NODE = 84,
296
+ PM_KEYWORD_PARAMETER_NODE = 85,
297
+ PM_KEYWORD_REST_PARAMETER_NODE = 86,
298
+ PM_LAMBDA_NODE = 87,
299
+ PM_LOCAL_VARIABLE_AND_WRITE_NODE = 88,
300
+ PM_LOCAL_VARIABLE_OPERATOR_WRITE_NODE = 89,
301
+ PM_LOCAL_VARIABLE_OR_WRITE_NODE = 90,
302
+ PM_LOCAL_VARIABLE_READ_NODE = 91,
303
+ PM_LOCAL_VARIABLE_TARGET_NODE = 92,
304
+ PM_LOCAL_VARIABLE_WRITE_NODE = 93,
305
+ PM_MATCH_LAST_LINE_NODE = 94,
306
+ PM_MATCH_PREDICATE_NODE = 95,
307
+ PM_MATCH_REQUIRED_NODE = 96,
308
+ PM_MATCH_WRITE_NODE = 97,
309
+ PM_MISSING_NODE = 98,
310
+ PM_MODULE_NODE = 99,
311
+ PM_MULTI_TARGET_NODE = 100,
312
+ PM_MULTI_WRITE_NODE = 101,
313
+ PM_NEXT_NODE = 102,
314
+ PM_NIL_NODE = 103,
315
+ PM_NO_KEYWORDS_PARAMETER_NODE = 104,
316
+ PM_NUMBERED_REFERENCE_READ_NODE = 105,
317
+ PM_OPTIONAL_PARAMETER_NODE = 106,
318
+ PM_OR_NODE = 107,
319
+ PM_PARAMETERS_NODE = 108,
320
+ PM_PARENTHESES_NODE = 109,
321
+ PM_PINNED_EXPRESSION_NODE = 110,
322
+ PM_PINNED_VARIABLE_NODE = 111,
323
+ PM_POST_EXECUTION_NODE = 112,
324
+ PM_PRE_EXECUTION_NODE = 113,
325
+ PM_PROGRAM_NODE = 114,
326
+ PM_RANGE_NODE = 115,
327
+ PM_RATIONAL_NODE = 116,
328
+ PM_REDO_NODE = 117,
329
+ PM_REGULAR_EXPRESSION_NODE = 118,
330
+ PM_REQUIRED_DESTRUCTURED_PARAMETER_NODE = 119,
331
+ PM_REQUIRED_PARAMETER_NODE = 120,
332
+ PM_RESCUE_MODIFIER_NODE = 121,
333
+ PM_RESCUE_NODE = 122,
334
+ PM_REST_PARAMETER_NODE = 123,
335
+ PM_RETRY_NODE = 124,
336
+ PM_RETURN_NODE = 125,
337
+ PM_SELF_NODE = 126,
338
+ PM_SINGLETON_CLASS_NODE = 127,
339
+ PM_SOURCE_ENCODING_NODE = 128,
340
+ PM_SOURCE_FILE_NODE = 129,
341
+ PM_SOURCE_LINE_NODE = 130,
342
+ PM_SPLAT_NODE = 131,
343
+ PM_STATEMENTS_NODE = 132,
344
+ PM_STRING_CONCAT_NODE = 133,
345
+ PM_STRING_NODE = 134,
346
+ PM_SUPER_NODE = 135,
347
+ PM_SYMBOL_NODE = 136,
348
+ PM_TRUE_NODE = 137,
349
+ PM_UNDEF_NODE = 138,
350
+ PM_UNLESS_NODE = 139,
351
+ PM_UNTIL_NODE = 140,
352
+ PM_WHEN_NODE = 141,
353
+ PM_WHILE_NODE = 142,
354
+ PM_X_STRING_NODE = 143,
355
+ PM_YIELD_NODE = 144,
353
356
  PM_SCOPE_NODE
354
357
  };
355
358
 
@@ -361,7 +364,7 @@ typedef uint16_t pm_node_flags_t;
361
364
  #define PM_NODE_FLAG_BITS (sizeof(pm_node_flags_t) * 8)
362
365
  static const pm_node_flags_t PM_NODE_FLAG_NEWLINE = (1 << (PM_NODE_FLAG_BITS - 1));
363
366
  static const pm_node_flags_t PM_NODE_FLAG_STATIC_LITERAL = (1 << (PM_NODE_FLAG_BITS - 2));
364
- static const pm_node_flags_t PM_NODE_FLAG_COMMON_MASK = PM_NODE_FLAG_NEWLINE | PM_NODE_FLAG_STATIC_LITERAL;
367
+ static const pm_node_flags_t PM_NODE_FLAG_COMMON_MASK = (1 << (PM_NODE_FLAG_BITS - 1)) | (1 << (PM_NODE_FLAG_BITS - 2));
365
368
 
366
369
  // For easy access, we define some macros to check node type
367
370
  #define PM_NODE_TYPE(node) ((enum pm_node_type)node->type)
@@ -476,6 +479,7 @@ typedef struct pm_assoc_splat_node {
476
479
  // Type: PM_BACK_REFERENCE_READ_NODE
477
480
  typedef struct pm_back_reference_read_node {
478
481
  pm_node_t base;
482
+ pm_constant_id_t name;
479
483
  } pm_back_reference_read_node_t;
480
484
 
481
485
  // BeginNode
@@ -561,9 +565,6 @@ typedef struct pm_call_and_write_node {
561
565
  struct pm_node *receiver;
562
566
  pm_location_t call_operator_loc;
563
567
  pm_location_t message_loc;
564
- pm_location_t opening_loc;
565
- struct pm_arguments_node *arguments;
566
- pm_location_t closing_loc;
567
568
  pm_constant_id_t read_name;
568
569
  pm_constant_id_t write_name;
569
570
  pm_location_t operator_loc;
@@ -599,9 +600,6 @@ typedef struct pm_call_operator_write_node {
599
600
  struct pm_node *receiver;
600
601
  pm_location_t call_operator_loc;
601
602
  pm_location_t message_loc;
602
- pm_location_t opening_loc;
603
- struct pm_arguments_node *arguments;
604
- pm_location_t closing_loc;
605
603
  pm_constant_id_t read_name;
606
604
  pm_constant_id_t write_name;
607
605
  pm_constant_id_t operator;
@@ -620,9 +618,6 @@ typedef struct pm_call_or_write_node {
620
618
  struct pm_node *receiver;
621
619
  pm_location_t call_operator_loc;
622
620
  pm_location_t message_loc;
623
- pm_location_t opening_loc;
624
- struct pm_arguments_node *arguments;
625
- pm_location_t closing_loc;
626
621
  pm_constant_id_t read_name;
627
622
  pm_constant_id_t write_name;
628
623
  pm_location_t operator_loc;
@@ -1115,6 +1110,61 @@ typedef struct pm_in_node {
1115
1110
  pm_location_t then_loc;
1116
1111
  } pm_in_node_t;
1117
1112
 
1113
+ // IndexAndWriteNode
1114
+ //
1115
+ // Type: PM_INDEX_AND_WRITE_NODE
1116
+ // Flags:
1117
+ // PM_CALL_NODE_FLAGS_SAFE_NAVIGATION
1118
+ // PM_CALL_NODE_FLAGS_VARIABLE_CALL
1119
+ typedef struct pm_index_and_write_node {
1120
+ pm_node_t base;
1121
+ struct pm_node *receiver;
1122
+ pm_location_t call_operator_loc;
1123
+ pm_location_t opening_loc;
1124
+ struct pm_arguments_node *arguments;
1125
+ pm_location_t closing_loc;
1126
+ struct pm_node *block;
1127
+ pm_location_t operator_loc;
1128
+ struct pm_node *value;
1129
+ } pm_index_and_write_node_t;
1130
+
1131
+ // IndexOperatorWriteNode
1132
+ //
1133
+ // Type: PM_INDEX_OPERATOR_WRITE_NODE
1134
+ // Flags:
1135
+ // PM_CALL_NODE_FLAGS_SAFE_NAVIGATION
1136
+ // PM_CALL_NODE_FLAGS_VARIABLE_CALL
1137
+ typedef struct pm_index_operator_write_node {
1138
+ pm_node_t base;
1139
+ struct pm_node *receiver;
1140
+ pm_location_t call_operator_loc;
1141
+ pm_location_t opening_loc;
1142
+ struct pm_arguments_node *arguments;
1143
+ pm_location_t closing_loc;
1144
+ struct pm_node *block;
1145
+ pm_constant_id_t operator;
1146
+ pm_location_t operator_loc;
1147
+ struct pm_node *value;
1148
+ } pm_index_operator_write_node_t;
1149
+
1150
+ // IndexOrWriteNode
1151
+ //
1152
+ // Type: PM_INDEX_OR_WRITE_NODE
1153
+ // Flags:
1154
+ // PM_CALL_NODE_FLAGS_SAFE_NAVIGATION
1155
+ // PM_CALL_NODE_FLAGS_VARIABLE_CALL
1156
+ typedef struct pm_index_or_write_node {
1157
+ pm_node_t base;
1158
+ struct pm_node *receiver;
1159
+ pm_location_t call_operator_loc;
1160
+ pm_location_t opening_loc;
1161
+ struct pm_arguments_node *arguments;
1162
+ pm_location_t closing_loc;
1163
+ struct pm_node *block;
1164
+ pm_location_t operator_loc;
1165
+ struct pm_node *value;
1166
+ } pm_index_or_write_node_t;
1167
+
1118
1168
  // InstanceVariableAndWriteNode
1119
1169
  //
1120
1170
  // Type: PM_INSTANCE_VARIABLE_AND_WRITE_NODE
@@ -158,6 +158,7 @@ typedef enum {
158
158
  PM_ERR_NUMBERED_PARAMETER_NOT_ALLOWED,
159
159
  PM_ERR_NUMBERED_PARAMETER_OUTER_SCOPE,
160
160
  PM_ERR_OPERATOR_MULTI_ASSIGN,
161
+ PM_ERR_OPERATOR_WRITE_ARGUMENTS,
161
162
  PM_ERR_OPERATOR_WRITE_BLOCK,
162
163
  PM_ERR_PARAMETER_ASSOC_SPLAT_MULTI,
163
164
  PM_ERR_PARAMETER_BLOCK_MULTI,
data/include/prism/node.h CHANGED
@@ -33,10 +33,17 @@ PRISM_EXPORTED_FUNCTION const char * pm_node_type_to_str(pm_node_type_t node_typ
33
33
  // declare them here to avoid generating them.
34
34
  typedef struct pm_scope_node {
35
35
  pm_node_t base;
36
+ struct pm_scope_node *previous;
36
37
  pm_node_t *ast_node;
37
38
  struct pm_parameters_node *parameters;
38
39
  pm_node_t *body;
39
40
  pm_constant_id_list_t locals;
41
+ pm_parser_t *parser;
42
+
43
+ // We don't have the CRuby types ID and st_table within Prism
44
+ // so we use void *
45
+ void *constants; // ID *constants
46
+ void *index_lookup_table; // st_table *index_lookup_table
40
47
  } pm_scope_node_t;
41
48
 
42
49
  #endif // PRISM_NODE_H
@@ -39,9 +39,21 @@ size_t pm_constant_id_list_memsize(pm_constant_id_list_t *list);
39
39
  // Free the memory associated with a list of constant ids.
40
40
  void pm_constant_id_list_free(pm_constant_id_list_t *list);
41
41
 
42
+ // Constant pool buckets can have a couple of different types.
43
+ typedef unsigned int pm_constant_pool_bucket_type_t;
44
+
45
+ // By default, each constant is a slice of the source.
46
+ static const pm_constant_pool_bucket_type_t PM_CONSTANT_POOL_BUCKET_DEFAULT = 0;
47
+
48
+ // An owned constant is one for which memory has been allocated.
49
+ static const pm_constant_pool_bucket_type_t PM_CONSTANT_POOL_BUCKET_OWNED = 1;
50
+
51
+ // A constant constant is known at compile time.
52
+ static const pm_constant_pool_bucket_type_t PM_CONSTANT_POOL_BUCKET_CONSTANT = 2;
53
+
42
54
  typedef struct {
43
- unsigned int id: 31;
44
- bool owned: 1;
55
+ unsigned int id: 30;
56
+ pm_constant_pool_bucket_type_t type: 2;
45
57
  uint32_t hash;
46
58
  } pm_constant_pool_bucket_t;
47
59
 
@@ -63,10 +75,8 @@ typedef struct {
63
75
  // Initialize a new constant pool with a given capacity.
64
76
  bool pm_constant_pool_init(pm_constant_pool_t *pool, uint32_t capacity);
65
77
 
66
- static inline pm_constant_t* pm_constant_pool_id_to_constant(pm_constant_pool_t *pool, pm_constant_id_t constant_id) {
67
- assert(constant_id > 0 && constant_id <= pool->size);
68
- return &pool->constants[constant_id - 1];
69
- }
78
+ // Return a pointer to the constant indicated by the given constant id.
79
+ pm_constant_t * pm_constant_pool_id_to_constant(pm_constant_pool_t *pool, pm_constant_id_t constant_id);
70
80
 
71
81
  // Insert a constant into a constant pool that is a slice of a source string.
72
82
  // Returns the id of the constant, or 0 if any potential calls to resize fail.
@@ -77,6 +87,10 @@ pm_constant_id_t pm_constant_pool_insert_shared(pm_constant_pool_t *pool, const
77
87
  // resize fail.
78
88
  pm_constant_id_t pm_constant_pool_insert_owned(pm_constant_pool_t *pool, const uint8_t *start, size_t length);
79
89
 
90
+ // Insert a constant into a constant pool from memory that is constant. Returns
91
+ // the id of the constant, or 0 if any potential calls to resize fail.
92
+ pm_constant_id_t pm_constant_pool_insert_constant(pm_constant_pool_t *pool, const uint8_t *start, size_t length);
93
+
80
94
  // Free the memory associated with a constant pool.
81
95
  void pm_constant_pool_free(pm_constant_pool_t *pool);
82
96
 
@@ -1,4 +1,4 @@
1
1
  #define PRISM_VERSION_MAJOR 0
2
- #define PRISM_VERSION_MINOR 14
2
+ #define PRISM_VERSION_MINOR 15
3
3
  #define PRISM_VERSION_PATCH 0
4
- #define PRISM_VERSION "0.14.0"
4
+ #define PRISM_VERSION "0.15.0"
data/include/prism.h CHANGED
@@ -34,7 +34,7 @@ void pm_print_node(pm_parser_t *parser, pm_node_t *node);
34
34
  void pm_parser_metadata(pm_parser_t *parser, const char *metadata);
35
35
 
36
36
  // Generate a scope node from the given node.
37
- void pm_scope_node_init(pm_node_t *node, pm_scope_node_t *dest);
37
+ void pm_scope_node_init(const pm_node_t *node, pm_scope_node_t *scope, pm_scope_node_t *previous, pm_parser_t *parser);
38
38
 
39
39
  // The prism version and the serialization format.
40
40
  PRISM_EXPORTED_FUNCTION const char * pm_version(void);
@@ -243,6 +243,15 @@ module Prism
243
243
  # Compile a InNode node
244
244
  alias visit_in_node visit_child_nodes
245
245
 
246
+ # Compile a IndexAndWriteNode node
247
+ alias visit_index_and_write_node visit_child_nodes
248
+
249
+ # Compile a IndexOperatorWriteNode node
250
+ alias visit_index_operator_write_node visit_child_nodes
251
+
252
+ # Compile a IndexOrWriteNode node
253
+ alias visit_index_or_write_node visit_child_nodes
254
+
246
255
  # Compile a InstanceVariableAndWriteNode node
247
256
  alias visit_instance_variable_and_write_node visit_child_nodes
248
257
 
data/lib/prism/debug.rb CHANGED
@@ -45,29 +45,16 @@ module Prism
45
45
  # For the given source, compiles with CRuby and returns a list of all of the
46
46
  # sets of local variables that were encountered.
47
47
  def self.cruby_locals(source)
48
- verbose = $VERBOSE
49
- $VERBOSE = nil
48
+ verbose, $VERBOSE = $VERBOSE, nil
50
49
 
51
50
  begin
52
51
  locals = []
53
52
  stack = [ISeq.new(RubyVM::InstructionSequence.compile(source).to_a)]
54
53
 
55
54
  while (iseq = stack.pop)
56
- if iseq.type != :once
57
- names = iseq.local_table
58
-
59
- # CRuby will push on a special local variable when there are keyword
60
- # arguments. We get rid of that here.
61
- names = names.grep_v(Integer)
62
-
63
- # For some reason, CRuby occasionally pushes this special local
64
- # variable when there are splat arguments. We get rid of that here.
65
- names = names.grep_v(:"#arg_rest")
66
-
67
- # Now push them onto the list of locals.
68
- locals << names
69
- end
70
-
55
+ # For some reason, CRuby occasionally pushes this special local
56
+ # variable when there are splat arguments. We get rid of that here.
57
+ locals << (iseq.local_table - [:"#arg_rest"])
71
58
  iseq.each_child { |child| stack << child }
72
59
  end
73
60
 
@@ -77,6 +64,8 @@ module Prism
77
64
  end
78
65
  end
79
66
 
67
+ AnonymousLocal = Object.new
68
+
80
69
  # For the given source, parses with prism and returns a list of all of the
81
70
  # sets of local variables that were encountered.
82
71
  def self.prism_locals(source)
@@ -97,20 +86,27 @@ module Prism
97
86
  # order here so that we can compare properly.
98
87
  if params
99
88
  sorted = [
100
- *params.requireds.grep(RequiredParameterNode).map(&:name),
89
+ *params.requireds.map do |required|
90
+ if required.is_a?(RequiredParameterNode)
91
+ required.name
92
+ else
93
+ AnonymousLocal
94
+ end
95
+ end,
101
96
  *params.optionals.map(&:name),
102
97
  *((params.rest.name || :*) if params.rest && params.rest.operator != ","),
103
- *params.posts.grep(RequiredParameterNode).map(&:name),
98
+ *params.posts.map do |post|
99
+ if post.is_a?(RequiredParameterNode)
100
+ post.name
101
+ else
102
+ AnonymousLocal
103
+ end
104
+ end,
104
105
  *params.keywords.reject(&:value).map(&:name),
105
106
  *params.keywords.select(&:value).map(&:name)
106
107
  ]
107
108
 
108
- # TODO: When we get a ... parameter, we should be pushing * and &
109
- # onto the local list. We don't do that yet, so we need to add them
110
- # in here.
111
- if params.keyword_rest.is_a?(ForwardingParameterNode)
112
- sorted.push(:*, :&, :"...")
113
- end
109
+ sorted << AnonymousLocal if params.keywords.any?
114
110
 
115
111
  # Recurse down the parameter tree to find any destructured
116
112
  # parameters and add them after the other parameters.
@@ -129,11 +125,19 @@ module Prism
129
125
  names = sorted.concat(names - sorted)
130
126
  end
131
127
 
128
+ names.map!.with_index do |name, index|
129
+ if name == AnonymousLocal
130
+ names.length - index + 1
131
+ else
132
+ name
133
+ end
134
+ end
135
+
132
136
  locals << names
133
137
  when ClassNode, ModuleNode, ProgramNode, SingletonClassNode
134
138
  locals << node.locals
135
139
  when ForNode
136
- locals << []
140
+ locals << [2]
137
141
  when PostExecutionNode
138
142
  locals.push([], [])
139
143
  when InterpolatedRegularExpressionNode
@@ -608,6 +608,30 @@ module Prism
608
608
  listeners[:on_in_node_leave]&.each { |listener| listener.on_in_node_leave(node) }
609
609
  end
610
610
 
611
+ # Dispatch enter and leave events for IndexAndWriteNode nodes and continue
612
+ # walking the tree.
613
+ def visit_index_and_write_node(node)
614
+ listeners[:on_index_and_write_node_enter]&.each { |listener| listener.on_index_and_write_node_enter(node) }
615
+ super
616
+ listeners[:on_index_and_write_node_leave]&.each { |listener| listener.on_index_and_write_node_leave(node) }
617
+ end
618
+
619
+ # Dispatch enter and leave events for IndexOperatorWriteNode nodes and continue
620
+ # walking the tree.
621
+ def visit_index_operator_write_node(node)
622
+ listeners[:on_index_operator_write_node_enter]&.each { |listener| listener.on_index_operator_write_node_enter(node) }
623
+ super
624
+ listeners[:on_index_operator_write_node_leave]&.each { |listener| listener.on_index_operator_write_node_leave(node) }
625
+ end
626
+
627
+ # Dispatch enter and leave events for IndexOrWriteNode nodes and continue
628
+ # walking the tree.
629
+ def visit_index_or_write_node(node)
630
+ listeners[:on_index_or_write_node_enter]&.each { |listener| listener.on_index_or_write_node_enter(node) }
631
+ super
632
+ listeners[:on_index_or_write_node_leave]&.each { |listener| listener.on_index_or_write_node_leave(node) }
633
+ end
634
+
611
635
  # Dispatch enter and leave events for InstanceVariableAndWriteNode nodes and continue
612
636
  # walking the tree.
613
637
  def visit_instance_variable_and_write_node(node)
@@ -1607,6 +1631,24 @@ module Prism
1607
1631
  listeners[:on_in_node_leave]&.each { |listener| listener.on_in_node_leave(node) }
1608
1632
  end
1609
1633
 
1634
+ # Dispatch enter and leave events for IndexAndWriteNode nodes.
1635
+ def visit_index_and_write_node(node)
1636
+ listeners[:on_index_and_write_node_enter]&.each { |listener| listener.on_index_and_write_node_enter(node) }
1637
+ listeners[:on_index_and_write_node_leave]&.each { |listener| listener.on_index_and_write_node_leave(node) }
1638
+ end
1639
+
1640
+ # Dispatch enter and leave events for IndexOperatorWriteNode nodes.
1641
+ def visit_index_operator_write_node(node)
1642
+ listeners[:on_index_operator_write_node_enter]&.each { |listener| listener.on_index_operator_write_node_enter(node) }
1643
+ listeners[:on_index_operator_write_node_leave]&.each { |listener| listener.on_index_operator_write_node_leave(node) }
1644
+ end
1645
+
1646
+ # Dispatch enter and leave events for IndexOrWriteNode nodes.
1647
+ def visit_index_or_write_node(node)
1648
+ listeners[:on_index_or_write_node_enter]&.each { |listener| listener.on_index_or_write_node_enter(node) }
1649
+ listeners[:on_index_or_write_node_leave]&.each { |listener| listener.on_index_or_write_node_leave(node) }
1650
+ end
1651
+
1610
1652
  # Dispatch enter and leave events for InstanceVariableAndWriteNode nodes.
1611
1653
  def visit_instance_variable_and_write_node(node)
1612
1654
  listeners[:on_instance_variable_and_write_node_enter]&.each { |listener| listener.on_instance_variable_and_write_node_enter(node) }
data/lib/prism/dsl.rb CHANGED
@@ -88,8 +88,8 @@ module Prism
88
88
  end
89
89
 
90
90
  # Create a new BackReferenceReadNode node
91
- def BackReferenceReadNode(location = Location())
92
- BackReferenceReadNode.new(location)
91
+ def BackReferenceReadNode(name, location = Location())
92
+ BackReferenceReadNode.new(name, location)
93
93
  end
94
94
 
95
95
  # Create a new BeginNode node
@@ -128,8 +128,8 @@ module Prism
128
128
  end
129
129
 
130
130
  # Create a new CallAndWriteNode node
131
- def CallAndWriteNode(receiver, call_operator_loc, message_loc, opening_loc, arguments, closing_loc, flags, read_name, write_name, operator_loc, value, location = Location())
132
- CallAndWriteNode.new(receiver, call_operator_loc, message_loc, opening_loc, arguments, closing_loc, flags, read_name, write_name, operator_loc, value, location)
131
+ def CallAndWriteNode(receiver, call_operator_loc, message_loc, flags, read_name, write_name, operator_loc, value, location = Location())
132
+ CallAndWriteNode.new(receiver, call_operator_loc, message_loc, flags, read_name, write_name, operator_loc, value, location)
133
133
  end
134
134
 
135
135
  # Create a new CallNode node
@@ -138,13 +138,13 @@ module Prism
138
138
  end
139
139
 
140
140
  # Create a new CallOperatorWriteNode node
141
- def CallOperatorWriteNode(receiver, call_operator_loc, message_loc, opening_loc, arguments, closing_loc, flags, read_name, write_name, operator, operator_loc, value, location = Location())
142
- CallOperatorWriteNode.new(receiver, call_operator_loc, message_loc, opening_loc, arguments, closing_loc, flags, read_name, write_name, operator, operator_loc, value, location)
141
+ def CallOperatorWriteNode(receiver, call_operator_loc, message_loc, flags, read_name, write_name, operator, operator_loc, value, location = Location())
142
+ CallOperatorWriteNode.new(receiver, call_operator_loc, message_loc, flags, read_name, write_name, operator, operator_loc, value, location)
143
143
  end
144
144
 
145
145
  # Create a new CallOrWriteNode node
146
- def CallOrWriteNode(receiver, call_operator_loc, message_loc, opening_loc, arguments, closing_loc, flags, read_name, write_name, operator_loc, value, location = Location())
147
- CallOrWriteNode.new(receiver, call_operator_loc, message_loc, opening_loc, arguments, closing_loc, flags, read_name, write_name, operator_loc, value, location)
146
+ def CallOrWriteNode(receiver, call_operator_loc, message_loc, flags, read_name, write_name, operator_loc, value, location = Location())
147
+ CallOrWriteNode.new(receiver, call_operator_loc, message_loc, flags, read_name, write_name, operator_loc, value, location)
148
148
  end
149
149
 
150
150
  # Create a new CapturePatternNode node
@@ -382,6 +382,21 @@ module Prism
382
382
  InNode.new(pattern, statements, in_loc, then_loc, location)
383
383
  end
384
384
 
385
+ # Create a new IndexAndWriteNode node
386
+ def IndexAndWriteNode(receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, flags, operator_loc, value, location = Location())
387
+ IndexAndWriteNode.new(receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, flags, operator_loc, value, location)
388
+ end
389
+
390
+ # Create a new IndexOperatorWriteNode node
391
+ def IndexOperatorWriteNode(receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, flags, operator, operator_loc, value, location = Location())
392
+ IndexOperatorWriteNode.new(receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, flags, operator, operator_loc, value, location)
393
+ end
394
+
395
+ # Create a new IndexOrWriteNode node
396
+ def IndexOrWriteNode(receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, flags, operator_loc, value, location = Location())
397
+ IndexOrWriteNode.new(receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, flags, operator_loc, value, location)
398
+ end
399
+
385
400
  # Create a new InstanceVariableAndWriteNode node
386
401
  def InstanceVariableAndWriteNode(name, name_loc, operator_loc, value, location = Location())
387
402
  InstanceVariableAndWriteNode.new(name, name_loc, operator_loc, value, location)
data/lib/prism/ffi.rb CHANGED
@@ -25,8 +25,8 @@ module Prism
25
25
  # void -> :void
26
26
  #
27
27
  def self.resolve_type(type)
28
- type = type.strip.delete_prefix("const ")
29
- type.end_with?("*") ? :pointer : type.to_sym
28
+ type = type.strip
29
+ type.end_with?("*") ? :pointer : type.delete_prefix("const ").to_sym
30
30
  end
31
31
 
32
32
  # Read through the given header file and find the declaration of each of the