prism 2.0.0.rc1 → 2.0.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.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +13 -2
  3. data/CODE_OF_CONDUCT.md +1 -1
  4. data/LICENSE.md +1 -1
  5. data/docs/serialization.md +20 -6
  6. data/ext/prism/api_node.c +81 -81
  7. data/ext/prism/extension.c +54 -69
  8. data/ext/prism/extension.h +1 -1
  9. data/include/prism/arena.h +8 -0
  10. data/include/prism/arena.hpp +42 -0
  11. data/include/prism/ast.h +11 -1
  12. data/include/prism/ast.hpp +641 -0
  13. data/include/prism/buffer.h +8 -0
  14. data/include/prism/buffer.hpp +55 -0
  15. data/include/prism/comments.h +17 -0
  16. data/include/prism/compiler/accel.h +3 -1
  17. data/include/prism/compiler/branch.h +26 -0
  18. data/include/prism/compiler/bswap.h +46 -0
  19. data/include/prism/compiler/cplusplus.hpp +16 -0
  20. data/include/prism/compiler/endianness.h +34 -0
  21. data/include/prism/compiler/exceptions.hpp +17 -0
  22. data/include/prism/compiler/format.h +2 -0
  23. data/include/prism/compiler/lifetimebound.hpp +25 -0
  24. data/include/prism/constant_pool.h +25 -0
  25. data/include/prism/diagnostic.h +18 -0
  26. data/include/prism/errors_format.h +8 -0
  27. data/include/prism/internal/buffer.h +3 -0
  28. data/include/prism/internal/node.h +8 -4
  29. data/include/prism/internal/parser.h +20 -0
  30. data/include/prism/internal/stringy.h +1 -6
  31. data/include/prism/internal/xxh3.h +16 -0
  32. data/include/prism/json.h +8 -0
  33. data/include/prism/line_offset_list.h +8 -0
  34. data/include/prism/magic_comments.h +18 -0
  35. data/include/prism/node.h +55 -10
  36. data/include/prism/node.hpp +272 -0
  37. data/include/prism/node_type.hpp +38 -0
  38. data/include/prism/options.h +10 -1
  39. data/include/prism/options.hpp +43 -0
  40. data/include/prism/parser.h +93 -64
  41. data/include/prism/parser.hpp +274 -0
  42. data/include/prism/prettyprint.h +8 -0
  43. data/include/prism/serialize.h +8 -0
  44. data/include/prism/source.h +8 -0
  45. data/include/prism/stream.h +8 -0
  46. data/include/prism/string_query.h +19 -0
  47. data/include/prism/stringy.h +16 -27
  48. data/include/prism/stringy.hpp +31 -0
  49. data/include/prism/version.h +9 -1
  50. data/include/prism.h +0 -8
  51. data/include/prism.hpp +24 -0
  52. data/lib/prism/ffi.rb +6 -0
  53. data/lib/prism/node.rb +736 -0
  54. data/lib/prism/parse_result.rb +23 -8
  55. data/lib/prism/serialize.rb +2567 -3286
  56. data/lib/prism/string_query.rb +8 -0
  57. data/prism.gemspec +21 -4
  58. data/rbi/generated/prism/node.rbi +2430 -968
  59. data/rbi/generated/prism/parse_result.rbi +16 -4
  60. data/rbi/generated/prism/serialize.rbi +8 -4
  61. data/rbi/generated/prism/string_query.rbi +7 -0
  62. data/sig/generated/prism/node.rbs +2439 -967
  63. data/sig/generated/prism/parse_result.rbs +16 -4
  64. data/sig/generated/prism/serialize.rbs +9 -4
  65. data/sig/generated/prism/string_query.rbs +7 -0
  66. data/src/buffer.c +9 -0
  67. data/src/comments.c +2 -2
  68. data/src/diagnostic.c +8 -0
  69. data/src/node.c +216 -368
  70. data/src/options.c +7 -13
  71. data/src/parser.c +70 -48
  72. data/src/prism.c +581 -419
  73. data/src/regexp.c +0 -1
  74. data/src/serialize.c +2301 -1950
  75. data/src/source.c +8 -2
  76. data/src/string_query.c +14 -0
  77. data/src/stringy.c +3 -33
  78. data/src/xxh3.c +292 -0
  79. metadata +20 -3
data/src/options.c CHANGED
@@ -17,6 +17,8 @@ pm_options_t *
17
17
  pm_options_new(void) {
18
18
  pm_options_t *options = xcalloc(1, sizeof(pm_options_t));
19
19
  if (options == NULL) abort();
20
+
21
+ options->line = 1;
20
22
  return options;
21
23
  }
22
24
 
@@ -25,16 +27,8 @@ pm_options_new(void) {
25
27
  */
26
28
  void
27
29
  pm_options_cleanup(pm_options_t *options) {
28
- pm_string_cleanup(&options->filepath);
29
- pm_string_cleanup(&options->encoding);
30
-
31
30
  for (size_t scope_index = 0; scope_index < options->scopes_count; scope_index++) {
32
31
  pm_options_scope_t *scope = &options->scopes[scope_index];
33
-
34
- for (size_t local_index = 0; local_index < scope->locals_count; local_index++) {
35
- pm_string_cleanup(&scope->locals[local_index]);
36
- }
37
-
38
32
  xfree_sized(scope->locals, scope->locals_count * sizeof(pm_string_t));
39
33
  }
40
34
 
@@ -74,7 +68,7 @@ pm_options_filepath(const pm_options_t *options) {
74
68
  */
75
69
  void
76
70
  pm_options_filepath_set(pm_options_t *options, const char *filepath) {
77
- pm_string_constant_init(&options->filepath, filepath, strlen(filepath));
71
+ pm_string_init(&options->filepath, (const uint8_t *) filepath, strlen(filepath));
78
72
  }
79
73
 
80
74
  /**
@@ -82,7 +76,7 @@ pm_options_filepath_set(pm_options_t *options, const char *filepath) {
82
76
  */
83
77
  void
84
78
  pm_options_encoding_set(pm_options_t *options, const char *encoding) {
85
- pm_string_constant_init(&options->encoding, encoding, strlen(encoding));
79
+ pm_string_init(&options->encoding, (const uint8_t *) encoding, strlen(encoding));
86
80
  }
87
81
 
88
82
  /**
@@ -395,7 +389,7 @@ pm_options_read(pm_options_t *options, const char *data) {
395
389
  data += 4;
396
390
 
397
391
  if (filepath_length > 0) {
398
- pm_string_constant_init(&options->filepath, data, filepath_length);
392
+ pm_string_init(&options->filepath, (const uint8_t *) data, filepath_length);
399
393
  data += filepath_length;
400
394
  }
401
395
 
@@ -406,7 +400,7 @@ pm_options_read(pm_options_t *options, const char *data) {
406
400
  data += 4;
407
401
 
408
402
  if (encoding_length > 0) {
409
- pm_string_constant_init(&options->encoding, data, encoding_length);
403
+ pm_string_init(&options->encoding, (const uint8_t *) data, encoding_length);
410
404
  data += encoding_length;
411
405
  }
412
406
 
@@ -439,7 +433,7 @@ pm_options_read(pm_options_t *options, const char *data) {
439
433
  uint32_t local_length = pm_options_read_u32(data);
440
434
  data += 4;
441
435
 
442
- pm_string_constant_init(&scope->locals[local_index], data, local_length);
436
+ pm_string_init(&scope->locals[local_index], (const uint8_t *) data, local_length);
443
437
  data += local_length;
444
438
  }
445
439
  }
data/src/parser.c CHANGED
@@ -5,8 +5,11 @@
5
5
  #include "prism/internal/diagnostic.h"
6
6
  #include "prism/internal/encoding.h"
7
7
  #include "prism/internal/magic_comments.h"
8
+ #include "prism/internal/xxh3.h"
8
9
 
10
+ #include <assert.h>
9
11
  #include <stdlib.h>
12
+ #include <string.h>
10
13
 
11
14
  /**
12
15
  * Register a callback that will be called whenever prism changes the encoding
@@ -103,6 +106,19 @@ pm_parser_constant_find(const pm_parser_t *parser, const uint8_t *start, size_t
103
106
  return pm_constant_pool_find(&parser->constant_pool, start, length);
104
107
  }
105
108
 
109
+ /**
110
+ * Add a constant to the parser's constant pool, copying its bytes into the
111
+ * parser's arena only if the constant is not already there.
112
+ */
113
+ pm_constant_id_t
114
+ pm_parser_constant_insert(pm_parser_t *parser, const uint8_t *start, size_t length) {
115
+ pm_constant_id_t id = pm_constant_pool_find(&parser->constant_pool, start, length);
116
+ if (id != PM_CONSTANT_ID_UNSET) return id;
117
+
118
+ const uint8_t *copy = (const uint8_t *) pm_arena_memdup(&parser->metadata_arena, start, length, PRISM_ALIGNOF(uint8_t));
119
+ return pm_constant_pool_insert_constant(&parser->metadata_arena, &parser->constant_pool, copy, length);
120
+ }
121
+
106
122
  /**
107
123
  * Returns the frozen string literal value of the parser.
108
124
  */
@@ -131,6 +147,22 @@ pm_parser_data_loc(const pm_parser_t *parser) {
131
147
  return &parser->data_loc;
132
148
  }
133
149
 
150
+ /**
151
+ * Returns the checksum of the source code that was parsed.
152
+ */
153
+ uint64_t
154
+ pm_parser_checksum(const pm_parser_t *parser) {
155
+ const uint8_t *end = parser->end;
156
+
157
+ if (parser->data_loc.length != 0) {
158
+ const uint8_t *cursor = parser->start + parser->data_loc.start;
159
+ const uint8_t *newline = memchr(cursor, '\n', (size_t) (end - cursor));
160
+ if (newline != NULL) end = newline + 1;
161
+ }
162
+
163
+ return pm_xxh3(parser->start, (size_t) (end - parser->start));
164
+ }
165
+
134
166
  /**
135
167
  * Returns whether the given parser is continuable, meaning that it could become
136
168
  * valid if more input were appended, as opposed to being definitively invalid.
@@ -167,6 +199,14 @@ pm_comment_type(const pm_comment_t *comment) {
167
199
  return comment->type;
168
200
  }
169
201
 
202
+ /**
203
+ * Returns the comment that follows the given comment.
204
+ */
205
+ const pm_comment_t *
206
+ pm_comment_next(const pm_comment_t *comment) {
207
+ return (const pm_comment_t *) comment->node.next;
208
+ }
209
+
170
210
  /**
171
211
  * Returns the number of comments associated with the given parser.
172
212
  */
@@ -176,17 +216,11 @@ pm_parser_comments_size(const pm_parser_t *parser) {
176
216
  }
177
217
 
178
218
  /**
179
- * Iterates over the comments associated with the given parser and calls the
180
- * given callback for each comment.
219
+ * Returns the first comment associated with the given parser.
181
220
  */
182
- void
183
- pm_parser_comments_each(const pm_parser_t *parser, pm_comment_callback_t callback, void *data) {
184
- const pm_list_node_t *current = parser->comment_list.head;
185
- while (current != NULL) {
186
- const pm_comment_t *comment = (const pm_comment_t *) current;
187
- callback(comment, data);
188
- current = current->next;
189
- }
221
+ const pm_comment_t *
222
+ pm_parser_comments_first(const pm_parser_t *parser) {
223
+ return (const pm_comment_t *) parser->comment_list.head;
190
224
  }
191
225
 
192
226
  /**
@@ -252,6 +286,14 @@ pm_magic_comment_value(const pm_magic_comment_t *magic_comment) {
252
286
  return magic_comment->value;
253
287
  }
254
288
 
289
+ /**
290
+ * Returns the magic comment that follows the given magic comment.
291
+ */
292
+ const pm_magic_comment_t *
293
+ pm_magic_comment_next(const pm_magic_comment_t *magic_comment) {
294
+ return (const pm_magic_comment_t *) magic_comment->node.next;
295
+ }
296
+
255
297
  /**
256
298
  * Returns the number of magic comments associated with the given parser.
257
299
  */
@@ -261,17 +303,11 @@ pm_parser_magic_comments_size(const pm_parser_t *parser) {
261
303
  }
262
304
 
263
305
  /**
264
- * Iterates over the magic comments associated with the given parser and calls
265
- * the given callback for each magic comment.
306
+ * Returns the first magic comment associated with the given parser.
266
307
  */
267
- void
268
- pm_parser_magic_comments_each(const pm_parser_t *parser, pm_magic_comment_callback_t callback, void *data) {
269
- const pm_list_node_t *current = parser->magic_comment_list.head;
270
- while (current != NULL) {
271
- const pm_magic_comment_t *magic_comment = (const pm_magic_comment_t *) current;
272
- callback(magic_comment, data);
273
- current = current->next;
274
- }
308
+ const pm_magic_comment_t *
309
+ pm_parser_magic_comments_first(const pm_parser_t *parser) {
310
+ return (const pm_magic_comment_t *) parser->magic_comment_list.head;
275
311
  }
276
312
 
277
313
  /**
@@ -290,32 +326,20 @@ pm_parser_warnings_size(const pm_parser_t *parser) {
290
326
  return parser->warning_list.size;
291
327
  }
292
328
 
293
- static inline void
294
- pm_parser_diagnostics_each(const pm_list_t *list, pm_diagnostic_callback_t callback, void *data) {
295
- const pm_list_node_t *current = list->head;
296
- while (current != NULL) {
297
- const pm_diagnostic_t *diagnostic = (const pm_diagnostic_t *) current;
298
- callback(diagnostic, data);
299
- current = current->next;
300
- }
301
- }
302
-
303
329
  /**
304
- * Iterates over the errors associated with the given parser and calls the
305
- * given callback for each error.
330
+ * Returns the first error associated with the given parser.
306
331
  */
307
- void
308
- pm_parser_errors_each(const pm_parser_t *parser, pm_diagnostic_callback_t callback, void *data) {
309
- pm_parser_diagnostics_each(&parser->error_list, callback, data);
332
+ const pm_diagnostic_t *
333
+ pm_parser_errors_first(const pm_parser_t *parser) {
334
+ return (const pm_diagnostic_t *) parser->error_list.head;
310
335
  }
311
336
 
312
337
  /**
313
- * Iterates over the warnings associated with the given parser and calls the
314
- * given callback for each warning.
338
+ * Returns the first warning associated with the given parser.
315
339
  */
316
- void
317
- pm_parser_warnings_each(const pm_parser_t *parser, pm_diagnostic_callback_t callback, void *data) {
318
- pm_parser_diagnostics_each(&parser->warning_list, callback, data);
340
+ const pm_diagnostic_t *
341
+ pm_parser_warnings_first(const pm_parser_t *parser) {
342
+ return (const pm_diagnostic_t *) parser->warning_list.head;
319
343
  }
320
344
 
321
345
  /**
@@ -328,15 +352,13 @@ pm_parser_constants_size(const pm_parser_t *parser) {
328
352
  }
329
353
 
330
354
  /**
331
- * Iterates over the constants in the constant pool associated with the given
332
- * parser and calls the given callback for each constant.
355
+ * Returns the constant at the given index in the constant pool associated with
356
+ * the given parser.
333
357
  */
334
- void
335
- pm_parser_constants_each(const pm_parser_t *parser, pm_constant_callback_t callback, void *data) {
336
- for (uint32_t index = 0; index < parser->constant_pool.size; index++) {
337
- const pm_constant_t *constant = &parser->constant_pool.constants[index];
338
- callback(constant, data);
339
- }
358
+ const pm_constant_t *
359
+ pm_parser_constant_at(const pm_parser_t *parser, size_t index) {
360
+ assert(index < parser->constant_pool.size);
361
+ return &parser->constant_pool.constants[index];
340
362
  }
341
363
 
342
364
  /**