prism 0.13.0 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -10,6 +10,7 @@ VALUE rb_cPrismToken;
10
10
  VALUE rb_cPrismLocation;
11
11
 
12
12
  VALUE rb_cPrismComment;
13
+ VALUE rb_cPrismMagicComment;
13
14
  VALUE rb_cPrismParseError;
14
15
  VALUE rb_cPrismParseWarning;
15
16
  VALUE rb_cPrismParseResult;
@@ -153,6 +154,35 @@ parser_comments(pm_parser_t *parser, VALUE source) {
153
154
  return comments;
154
155
  }
155
156
 
157
+ // Extract the magic comments out of the parser into an array.
158
+ static VALUE
159
+ parser_magic_comments(pm_parser_t *parser, VALUE source) {
160
+ VALUE magic_comments = rb_ary_new();
161
+
162
+ for (pm_magic_comment_t *magic_comment = (pm_magic_comment_t *) parser->magic_comment_list.head; magic_comment != NULL; magic_comment = (pm_magic_comment_t *) magic_comment->node.next) {
163
+ VALUE key_loc_argv[] = {
164
+ source,
165
+ LONG2FIX(magic_comment->key_start - parser->start),
166
+ LONG2FIX(magic_comment->key_length)
167
+ };
168
+
169
+ VALUE value_loc_argv[] = {
170
+ source,
171
+ LONG2FIX(magic_comment->value_start - parser->start),
172
+ LONG2FIX(magic_comment->value_length)
173
+ };
174
+
175
+ VALUE magic_comment_argv[] = {
176
+ rb_class_new_instance(3, key_loc_argv, rb_cPrismLocation),
177
+ rb_class_new_instance(3, value_loc_argv, rb_cPrismLocation)
178
+ };
179
+
180
+ rb_ary_push(magic_comments, rb_class_new_instance(2, magic_comment_argv, rb_cPrismMagicComment));
181
+ }
182
+
183
+ return magic_comments;
184
+ }
185
+
156
186
  // Extract the errors out of the parser into an array.
157
187
  static VALUE
158
188
  parser_errors(pm_parser_t *parser, rb_encoding *encoding, VALUE source) {
@@ -297,6 +327,7 @@ parse_lex_input(pm_string_t *input, const char *filepath, bool return_nodes) {
297
327
  VALUE result_argv[] = {
298
328
  value,
299
329
  parser_comments(&parser, source),
330
+ parser_magic_comments(&parser, source),
300
331
  parser_errors(&parser, parse_lex_data.encoding, source),
301
332
  parser_warnings(&parser, parse_lex_data.encoding, source),
302
333
  source
@@ -304,7 +335,7 @@ parse_lex_input(pm_string_t *input, const char *filepath, bool return_nodes) {
304
335
 
305
336
  pm_node_destroy(&parser, node);
306
337
  pm_parser_free(&parser);
307
- return rb_class_new_instance(5, result_argv, rb_cPrismParseResult);
338
+ return rb_class_new_instance(6, result_argv, rb_cPrismParseResult);
308
339
  }
309
340
 
310
341
  // Return an array of tokens corresponding to the given string.
@@ -351,12 +382,13 @@ parse_input(pm_string_t *input, const char *filepath) {
351
382
  VALUE result_argv[] = {
352
383
  pm_ast_new(&parser, node, encoding),
353
384
  parser_comments(&parser, source),
385
+ parser_magic_comments(&parser, source),
354
386
  parser_errors(&parser, encoding, source),
355
387
  parser_warnings(&parser, encoding, source),
356
388
  source
357
389
  };
358
390
 
359
- VALUE result = rb_class_new_instance(5, result_argv, rb_cPrismParseResult);
391
+ VALUE result = rb_class_new_instance(6, result_argv, rb_cPrismParseResult);
360
392
 
361
393
  pm_node_destroy(&parser, node);
362
394
  pm_parser_free(&parser);
@@ -461,48 +493,6 @@ named_captures(VALUE self, VALUE source) {
461
493
  return names;
462
494
  }
463
495
 
464
- // Accepts a source string and a type of unescaping and returns the unescaped
465
- // version.
466
- static VALUE
467
- unescape(VALUE source, pm_unescape_type_t unescape_type) {
468
- pm_string_t result;
469
-
470
- if (pm_unescape_string((const uint8_t *) RSTRING_PTR(source), RSTRING_LEN(source), unescape_type, &result)) {
471
- VALUE str = rb_str_new((const char *) pm_string_source(&result), pm_string_length(&result));
472
- pm_string_free(&result);
473
- return str;
474
- } else {
475
- pm_string_free(&result);
476
- return Qnil;
477
- }
478
- }
479
-
480
- // Do not unescape anything in the given string. This is here to provide a
481
- // consistent API.
482
- static VALUE
483
- unescape_none(VALUE self, VALUE source) {
484
- return unescape(source, PM_UNESCAPE_NONE);
485
- }
486
-
487
- // Minimally unescape the given string. This means effectively unescaping just
488
- // the quotes of a string. Returns the unescaped string.
489
- static VALUE
490
- unescape_minimal(VALUE self, VALUE source) {
491
- return unescape(source, PM_UNESCAPE_MINIMAL);
492
- }
493
-
494
- // Escape the given string minimally plus whitespace. Returns the unescaped string.
495
- static VALUE
496
- unescape_whitespace(VALUE self, VALUE source) {
497
- return unescape(source, PM_UNESCAPE_WHITESPACE);
498
- }
499
-
500
- // Unescape everything in the given string. Return the unescaped string.
501
- static VALUE
502
- unescape_all(VALUE self, VALUE source) {
503
- return unescape(source, PM_UNESCAPE_ALL);
504
- }
505
-
506
496
  // Return a hash of information about the given source string's memory usage.
507
497
  static VALUE
508
498
  memsize(VALUE self, VALUE string) {
@@ -589,6 +579,7 @@ Init_prism(void) {
589
579
  rb_cPrismToken = rb_define_class_under(rb_cPrism, "Token", rb_cObject);
590
580
  rb_cPrismLocation = rb_define_class_under(rb_cPrism, "Location", rb_cObject);
591
581
  rb_cPrismComment = rb_define_class_under(rb_cPrism, "Comment", rb_cObject);
582
+ rb_cPrismMagicComment = rb_define_class_under(rb_cPrism, "MagicComment", rb_cObject);
592
583
  rb_cPrismParseError = rb_define_class_under(rb_cPrism, "ParseError", rb_cObject);
593
584
  rb_cPrismParseWarning = rb_define_class_under(rb_cPrism, "ParseWarning", rb_cObject);
594
585
  rb_cPrismParseResult = rb_define_class_under(rb_cPrism, "ParseResult", rb_cObject);
@@ -612,10 +603,6 @@ Init_prism(void) {
612
603
  // internal tasks. We expose these to make them easier to test.
613
604
  VALUE rb_cPrismDebug = rb_define_module_under(rb_cPrism, "Debug");
614
605
  rb_define_singleton_method(rb_cPrismDebug, "named_captures", named_captures, 1);
615
- rb_define_singleton_method(rb_cPrismDebug, "unescape_none", unescape_none, 1);
616
- rb_define_singleton_method(rb_cPrismDebug, "unescape_minimal", unescape_minimal, 1);
617
- rb_define_singleton_method(rb_cPrismDebug, "unescape_whitespace", unescape_whitespace, 1);
618
- rb_define_singleton_method(rb_cPrismDebug, "unescape_all", unescape_all, 1);
619
606
  rb_define_singleton_method(rb_cPrismDebug, "memsize", memsize, 1);
620
607
  rb_define_singleton_method(rb_cPrismDebug, "profile_file", profile_file, 1);
621
608
  rb_define_singleton_method(rb_cPrismDebug, "parse_serialize_file_metadata", parse_serialize_file_metadata, 2);
@@ -1,7 +1,7 @@
1
1
  #ifndef PRISM_EXT_NODE_H
2
2
  #define PRISM_EXT_NODE_H
3
3
 
4
- #define EXPECTED_PRISM_VERSION "0.13.0"
4
+ #define EXPECTED_PRISM_VERSION "0.15.0"
5
5
 
6
6
  #include <ruby.h>
7
7
  #include <ruby/encoding.h>
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
 
@@ -358,8 +361,10 @@ typedef uint16_t pm_node_flags_t;
358
361
 
359
362
  // We store the flags enum in every node in the tree. Some flags are common to
360
363
  // all nodes (the ones listed below). Others are specific to certain node types.
361
- static const pm_node_flags_t PM_NODE_FLAG_NEWLINE = 0x1;
362
- static const pm_node_flags_t PM_NODE_FLAG_STATIC_LITERAL = 0x2;
364
+ #define PM_NODE_FLAG_BITS (sizeof(pm_node_flags_t) * 8)
365
+ static const pm_node_flags_t PM_NODE_FLAG_NEWLINE = (1 << (PM_NODE_FLAG_BITS - 1));
366
+ static const pm_node_flags_t PM_NODE_FLAG_STATIC_LITERAL = (1 << (PM_NODE_FLAG_BITS - 2));
367
+ static const pm_node_flags_t PM_NODE_FLAG_COMMON_MASK = (1 << (PM_NODE_FLAG_BITS - 1)) | (1 << (PM_NODE_FLAG_BITS - 2));
363
368
 
364
369
  // For easy access, we define some macros to check node type
365
370
  #define PM_NODE_TYPE(node) ((enum pm_node_type)node->type)
@@ -474,6 +479,7 @@ typedef struct pm_assoc_splat_node {
474
479
  // Type: PM_BACK_REFERENCE_READ_NODE
475
480
  typedef struct pm_back_reference_read_node {
476
481
  pm_node_t base;
482
+ pm_constant_id_t name;
477
483
  } pm_back_reference_read_node_t;
478
484
 
479
485
  // BeginNode
@@ -559,11 +565,8 @@ typedef struct pm_call_and_write_node {
559
565
  struct pm_node *receiver;
560
566
  pm_location_t call_operator_loc;
561
567
  pm_location_t message_loc;
562
- pm_location_t opening_loc;
563
- struct pm_arguments_node *arguments;
564
- pm_location_t closing_loc;
565
- pm_string_t read_name;
566
- pm_string_t write_name;
568
+ pm_constant_id_t read_name;
569
+ pm_constant_id_t write_name;
567
570
  pm_location_t operator_loc;
568
571
  struct pm_node *value;
569
572
  } pm_call_and_write_node_t;
@@ -583,7 +586,7 @@ typedef struct pm_call_node {
583
586
  struct pm_arguments_node *arguments;
584
587
  pm_location_t closing_loc;
585
588
  struct pm_node *block;
586
- pm_string_t name;
589
+ pm_constant_id_t name;
587
590
  } pm_call_node_t;
588
591
 
589
592
  // CallOperatorWriteNode
@@ -597,11 +600,8 @@ typedef struct pm_call_operator_write_node {
597
600
  struct pm_node *receiver;
598
601
  pm_location_t call_operator_loc;
599
602
  pm_location_t message_loc;
600
- pm_location_t opening_loc;
601
- struct pm_arguments_node *arguments;
602
- pm_location_t closing_loc;
603
- pm_string_t read_name;
604
- pm_string_t write_name;
603
+ pm_constant_id_t read_name;
604
+ pm_constant_id_t write_name;
605
605
  pm_constant_id_t operator;
606
606
  pm_location_t operator_loc;
607
607
  struct pm_node *value;
@@ -618,11 +618,8 @@ typedef struct pm_call_or_write_node {
618
618
  struct pm_node *receiver;
619
619
  pm_location_t call_operator_loc;
620
620
  pm_location_t message_loc;
621
- pm_location_t opening_loc;
622
- struct pm_arguments_node *arguments;
623
- pm_location_t closing_loc;
624
- pm_string_t read_name;
625
- pm_string_t write_name;
621
+ pm_constant_id_t read_name;
622
+ pm_constant_id_t write_name;
626
623
  pm_location_t operator_loc;
627
624
  struct pm_node *value;
628
625
  } pm_call_or_write_node_t;
@@ -1113,6 +1110,61 @@ typedef struct pm_in_node {
1113
1110
  pm_location_t then_loc;
1114
1111
  } pm_in_node_t;
1115
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
+
1116
1168
  // InstanceVariableAndWriteNode
1117
1169
  //
1118
1170
  // Type: PM_INSTANCE_VARIABLE_AND_WRITE_NODE
@@ -1193,11 +1245,11 @@ typedef struct pm_integer_node {
1193
1245
  // PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE
1194
1246
  // PM_REGULAR_EXPRESSION_FLAGS_EXTENDED
1195
1247
  // PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE
1248
+ // PM_REGULAR_EXPRESSION_FLAGS_ONCE
1196
1249
  // PM_REGULAR_EXPRESSION_FLAGS_EUC_JP
1197
1250
  // PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT
1198
1251
  // PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J
1199
1252
  // PM_REGULAR_EXPRESSION_FLAGS_UTF_8
1200
- // PM_REGULAR_EXPRESSION_FLAGS_ONCE
1201
1253
  typedef struct pm_interpolated_match_last_line_node {
1202
1254
  pm_node_t base;
1203
1255
  pm_location_t opening_loc;
@@ -1212,11 +1264,11 @@ typedef struct pm_interpolated_match_last_line_node {
1212
1264
  // PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE
1213
1265
  // PM_REGULAR_EXPRESSION_FLAGS_EXTENDED
1214
1266
  // PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE
1267
+ // PM_REGULAR_EXPRESSION_FLAGS_ONCE
1215
1268
  // PM_REGULAR_EXPRESSION_FLAGS_EUC_JP
1216
1269
  // PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT
1217
1270
  // PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J
1218
1271
  // PM_REGULAR_EXPRESSION_FLAGS_UTF_8
1219
- // PM_REGULAR_EXPRESSION_FLAGS_ONCE
1220
1272
  typedef struct pm_interpolated_regular_expression_node {
1221
1273
  pm_node_t base;
1222
1274
  pm_location_t opening_loc;
@@ -1369,11 +1421,11 @@ typedef struct pm_local_variable_write_node {
1369
1421
  // PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE
1370
1422
  // PM_REGULAR_EXPRESSION_FLAGS_EXTENDED
1371
1423
  // PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE
1424
+ // PM_REGULAR_EXPRESSION_FLAGS_ONCE
1372
1425
  // PM_REGULAR_EXPRESSION_FLAGS_EUC_JP
1373
1426
  // PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT
1374
1427
  // PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J
1375
1428
  // PM_REGULAR_EXPRESSION_FLAGS_UTF_8
1376
- // PM_REGULAR_EXPRESSION_FLAGS_ONCE
1377
1429
  typedef struct pm_match_last_line_node {
1378
1430
  pm_node_t base;
1379
1431
  pm_location_t opening_loc;
@@ -1616,11 +1668,11 @@ typedef struct pm_redo_node {
1616
1668
  // PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE
1617
1669
  // PM_REGULAR_EXPRESSION_FLAGS_EXTENDED
1618
1670
  // PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE
1671
+ // PM_REGULAR_EXPRESSION_FLAGS_ONCE
1619
1672
  // PM_REGULAR_EXPRESSION_FLAGS_EUC_JP
1620
1673
  // PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT
1621
1674
  // PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J
1622
1675
  // PM_REGULAR_EXPRESSION_FLAGS_UTF_8
1623
- // PM_REGULAR_EXPRESSION_FLAGS_ONCE
1624
1676
  typedef struct pm_regular_expression_node {
1625
1677
  pm_node_t base;
1626
1678
  pm_location_t opening_loc;
@@ -1887,44 +1939,44 @@ typedef struct pm_yield_node {
1887
1939
  } pm_yield_node_t;
1888
1940
 
1889
1941
  // CallNodeFlags
1890
- typedef enum {
1891
- PM_CALL_NODE_FLAGS_SAFE_NAVIGATION = 1 << 2,
1892
- PM_CALL_NODE_FLAGS_VARIABLE_CALL = 1 << 3,
1942
+ typedef enum pm_call_node_flags {
1943
+ PM_CALL_NODE_FLAGS_SAFE_NAVIGATION = 1 << 0,
1944
+ PM_CALL_NODE_FLAGS_VARIABLE_CALL = 1 << 1,
1893
1945
  } pm_call_node_flags_t;
1894
1946
 
1895
1947
  // IntegerBaseFlags
1896
- typedef enum {
1897
- PM_INTEGER_BASE_FLAGS_BINARY = 1 << 2,
1898
- PM_INTEGER_BASE_FLAGS_OCTAL = 1 << 3,
1899
- PM_INTEGER_BASE_FLAGS_DECIMAL = 1 << 4,
1900
- PM_INTEGER_BASE_FLAGS_HEXADECIMAL = 1 << 5,
1948
+ typedef enum pm_integer_base_flags {
1949
+ PM_INTEGER_BASE_FLAGS_BINARY = 1 << 0,
1950
+ PM_INTEGER_BASE_FLAGS_OCTAL = 1 << 1,
1951
+ PM_INTEGER_BASE_FLAGS_DECIMAL = 1 << 2,
1952
+ PM_INTEGER_BASE_FLAGS_HEXADECIMAL = 1 << 3,
1901
1953
  } pm_integer_base_flags_t;
1902
1954
 
1903
1955
  // LoopFlags
1904
- typedef enum {
1905
- PM_LOOP_FLAGS_BEGIN_MODIFIER = 1 << 2,
1956
+ typedef enum pm_loop_flags {
1957
+ PM_LOOP_FLAGS_BEGIN_MODIFIER = 1 << 0,
1906
1958
  } pm_loop_flags_t;
1907
1959
 
1908
1960
  // RangeFlags
1909
- typedef enum {
1910
- PM_RANGE_FLAGS_EXCLUDE_END = 1 << 2,
1961
+ typedef enum pm_range_flags {
1962
+ PM_RANGE_FLAGS_EXCLUDE_END = 1 << 0,
1911
1963
  } pm_range_flags_t;
1912
1964
 
1913
1965
  // RegularExpressionFlags
1914
- typedef enum {
1915
- PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE = 1 << 2,
1916
- PM_REGULAR_EXPRESSION_FLAGS_EXTENDED = 1 << 3,
1917
- PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE = 1 << 4,
1918
- PM_REGULAR_EXPRESSION_FLAGS_EUC_JP = 1 << 5,
1919
- PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT = 1 << 6,
1920
- PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J = 1 << 7,
1921
- PM_REGULAR_EXPRESSION_FLAGS_UTF_8 = 1 << 8,
1922
- PM_REGULAR_EXPRESSION_FLAGS_ONCE = 1 << 9,
1966
+ typedef enum pm_regular_expression_flags {
1967
+ PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE = 1 << 0,
1968
+ PM_REGULAR_EXPRESSION_FLAGS_EXTENDED = 1 << 1,
1969
+ PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE = 1 << 2,
1970
+ PM_REGULAR_EXPRESSION_FLAGS_ONCE = 1 << 3,
1971
+ PM_REGULAR_EXPRESSION_FLAGS_EUC_JP = 1 << 4,
1972
+ PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT = 1 << 5,
1973
+ PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J = 1 << 6,
1974
+ PM_REGULAR_EXPRESSION_FLAGS_UTF_8 = 1 << 7,
1923
1975
  } pm_regular_expression_flags_t;
1924
1976
 
1925
1977
  // StringFlags
1926
- typedef enum {
1927
- PM_STRING_FLAGS_FROZEN = 1 << 2,
1978
+ typedef enum pm_string_flags {
1979
+ PM_STRING_FLAGS_FROZEN = 1 << 0,
1928
1980
  } pm_string_flags_t;
1929
1981
 
1930
1982
  #define PRISM_SERIALIZE_ONLY_SEMANTICS_FIELDS false
@@ -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,9 +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;
37
+ pm_node_t *ast_node;
36
38
  struct pm_parameters_node *parameters;
37
39
  pm_node_t *body;
38
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
39
47
  } pm_scope_node_t;
40
48
 
41
49
  #endif // PRISM_NODE_H
@@ -8,6 +8,7 @@
8
8
  #include "prism/util/pm_list.h"
9
9
  #include "prism/util/pm_newline_list.h"
10
10
  #include "prism/util/pm_state_stack.h"
11
+ #include "prism/util/pm_string.h"
11
12
 
12
13
  #include <stdbool.h>
13
14
 
@@ -172,6 +173,11 @@ typedef struct pm_lex_mode {
172
173
  // This is the pointer to the character where lexing should resume
173
174
  // once the heredoc has been completely processed.
174
175
  const uint8_t *next_start;
176
+
177
+ // This is used to track the amount of common whitespace on each
178
+ // line so that we know how much to dedent each line in the case of
179
+ // a tilde heredoc.
180
+ size_t common_whitespace;
175
181
  } heredoc;
176
182
  } as;
177
183
 
@@ -244,6 +250,16 @@ typedef struct pm_comment {
244
250
  pm_comment_type_t type;
245
251
  } pm_comment_t;
246
252
 
253
+ // This is a node in the linked list of magic comments that we've found while
254
+ // parsing.
255
+ typedef struct {
256
+ pm_list_node_t node;
257
+ const uint8_t *key_start;
258
+ const uint8_t *value_start;
259
+ uint32_t key_length;
260
+ uint32_t value_length;
261
+ } pm_magic_comment_t;
262
+
247
263
  // When the encoding that is being used to parse the source is changed by prism,
248
264
  // we provide the ability here to call out to a user-defined function.
249
265
  typedef void (*pm_encoding_changed_callback_t)(pm_parser_t *parser);
@@ -293,6 +309,11 @@ typedef struct pm_scope {
293
309
  // This is necessary to determine if child blocks are allowed to use
294
310
  // numbered parameters.
295
311
  bool numbered_params;
312
+
313
+ // A transparent scope is a scope that cannot have locals set on itself.
314
+ // When a local is set on this scope, it will instead be set on the parent
315
+ // scope's local table.
316
+ bool transparent;
296
317
  } pm_scope_t;
297
318
 
298
319
  // This struct represents the overall parser. It contains a reference to the
@@ -342,6 +363,7 @@ struct pm_parser {
342
363
  const uint8_t *heredoc_end;
343
364
 
344
365
  pm_list_t comment_list; // the list of comments that have been found while parsing
366
+ pm_list_t magic_comment_list; // the list of magic comments that have been found while parsing.
345
367
  pm_list_t warning_list; // the list of warnings that have been found while parsing
346
368
  pm_list_t error_list; // the list of errors that have been found while parsing
347
369
  pm_scope_t *current_scope; // the current local scope
@@ -388,6 +410,10 @@ struct pm_parser {
388
410
  // when we find tokens that we need it for.
389
411
  pm_node_flags_t integer_base;
390
412
 
413
+ // This string is used to pass information from the lexer to the parser. It
414
+ // is particularly necessary because of escape sequences.
415
+ pm_string_t current_string;
416
+
391
417
  // Whether or not we're at the beginning of a command
392
418
  bool command_start;
393
419
 
@@ -21,6 +21,9 @@ typedef struct {
21
21
  // Return the size of the pm_buffer_t struct.
22
22
  PRISM_EXPORTED_FUNCTION size_t pm_buffer_sizeof(void);
23
23
 
24
+ // Initialize a pm_buffer_t with the given capacity.
25
+ bool pm_buffer_init_capacity(pm_buffer_t *buffer, size_t capacity);
26
+
24
27
  // Initialize a pm_buffer_t with its default values.
25
28
  PRISM_EXPORTED_FUNCTION bool pm_buffer_init(pm_buffer_t *buffer);
26
29