prism 2.0.0.rc2 → 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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -2
  3. data/docs/serialization.md +19 -6
  4. data/ext/prism/api_node.c +80 -80
  5. data/ext/prism/extension.c +34 -67
  6. data/ext/prism/extension.h +1 -1
  7. data/include/prism/arena.h +8 -0
  8. data/include/prism/arena.hpp +42 -0
  9. data/include/prism/ast.h +11 -1
  10. data/include/prism/ast.hpp +641 -0
  11. data/include/prism/buffer.h +8 -0
  12. data/include/prism/buffer.hpp +55 -0
  13. data/include/prism/comments.h +17 -0
  14. data/include/prism/compiler/branch.h +26 -0
  15. data/include/prism/compiler/cplusplus.hpp +16 -0
  16. data/include/prism/compiler/exceptions.hpp +17 -0
  17. data/include/prism/compiler/format.h +2 -0
  18. data/include/prism/compiler/lifetimebound.hpp +25 -0
  19. data/include/prism/constant_pool.h +25 -0
  20. data/include/prism/diagnostic.h +18 -0
  21. data/include/prism/errors_format.h +8 -0
  22. data/include/prism/internal/node.h +8 -4
  23. data/include/prism/internal/stringy.h +1 -6
  24. data/include/prism/json.h +8 -0
  25. data/include/prism/line_offset_list.h +8 -0
  26. data/include/prism/magic_comments.h +18 -0
  27. data/include/prism/node.h +55 -10
  28. data/include/prism/node.hpp +272 -0
  29. data/include/prism/node_type.hpp +38 -0
  30. data/include/prism/options.h +10 -1
  31. data/include/prism/options.hpp +43 -0
  32. data/include/prism/parser.h +72 -64
  33. data/include/prism/parser.hpp +274 -0
  34. data/include/prism/prettyprint.h +8 -0
  35. data/include/prism/serialize.h +8 -0
  36. data/include/prism/source.h +8 -0
  37. data/include/prism/stream.h +8 -0
  38. data/include/prism/string_query.h +8 -0
  39. data/include/prism/stringy.h +16 -27
  40. data/include/prism/stringy.hpp +31 -0
  41. data/include/prism/version.h +9 -1
  42. data/include/prism.h +0 -8
  43. data/include/prism.hpp +24 -0
  44. data/lib/prism/serialize.rb +2549 -3281
  45. data/prism.gemspec +14 -1
  46. data/rbi/generated/prism/node.rbi +736 -0
  47. data/rbi/generated/prism/serialize.rbi +6 -5
  48. data/sig/generated/prism/node.rbs +736 -0
  49. data/sig/generated/prism/serialize.rbs +7 -5
  50. data/src/comments.c +2 -2
  51. data/src/diagnostic.c +8 -0
  52. data/src/node.c +216 -368
  53. data/src/options.c +7 -13
  54. data/src/parser.c +52 -48
  55. data/src/prism.c +175 -194
  56. data/src/regexp.c +0 -1
  57. data/src/serialize.c +2300 -1950
  58. data/src/source.c +8 -2
  59. data/src/stringy.c +3 -33
  60. metadata +14 -1
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
@@ -7,6 +7,7 @@
7
7
  #include "prism/internal/magic_comments.h"
8
8
  #include "prism/internal/xxh3.h"
9
9
 
10
+ #include <assert.h>
10
11
  #include <stdlib.h>
11
12
  #include <string.h>
12
13
 
@@ -105,6 +106,19 @@ pm_parser_constant_find(const pm_parser_t *parser, const uint8_t *start, size_t
105
106
  return pm_constant_pool_find(&parser->constant_pool, start, length);
106
107
  }
107
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
+
108
122
  /**
109
123
  * Returns the frozen string literal value of the parser.
110
124
  */
@@ -185,6 +199,14 @@ pm_comment_type(const pm_comment_t *comment) {
185
199
  return comment->type;
186
200
  }
187
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
+
188
210
  /**
189
211
  * Returns the number of comments associated with the given parser.
190
212
  */
@@ -194,17 +216,11 @@ pm_parser_comments_size(const pm_parser_t *parser) {
194
216
  }
195
217
 
196
218
  /**
197
- * Iterates over the comments associated with the given parser and calls the
198
- * given callback for each comment.
219
+ * Returns the first comment associated with the given parser.
199
220
  */
200
- void
201
- pm_parser_comments_each(const pm_parser_t *parser, pm_comment_callback_t callback, void *data) {
202
- const pm_list_node_t *current = parser->comment_list.head;
203
- while (current != NULL) {
204
- const pm_comment_t *comment = (const pm_comment_t *) current;
205
- callback(comment, data);
206
- current = current->next;
207
- }
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;
208
224
  }
209
225
 
210
226
  /**
@@ -270,6 +286,14 @@ pm_magic_comment_value(const pm_magic_comment_t *magic_comment) {
270
286
  return magic_comment->value;
271
287
  }
272
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
+
273
297
  /**
274
298
  * Returns the number of magic comments associated with the given parser.
275
299
  */
@@ -279,17 +303,11 @@ pm_parser_magic_comments_size(const pm_parser_t *parser) {
279
303
  }
280
304
 
281
305
  /**
282
- * Iterates over the magic comments associated with the given parser and calls
283
- * the given callback for each magic comment.
306
+ * Returns the first magic comment associated with the given parser.
284
307
  */
285
- void
286
- pm_parser_magic_comments_each(const pm_parser_t *parser, pm_magic_comment_callback_t callback, void *data) {
287
- const pm_list_node_t *current = parser->magic_comment_list.head;
288
- while (current != NULL) {
289
- const pm_magic_comment_t *magic_comment = (const pm_magic_comment_t *) current;
290
- callback(magic_comment, data);
291
- current = current->next;
292
- }
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;
293
311
  }
294
312
 
295
313
  /**
@@ -308,32 +326,20 @@ pm_parser_warnings_size(const pm_parser_t *parser) {
308
326
  return parser->warning_list.size;
309
327
  }
310
328
 
311
- static inline void
312
- pm_parser_diagnostics_each(const pm_list_t *list, pm_diagnostic_callback_t callback, void *data) {
313
- const pm_list_node_t *current = list->head;
314
- while (current != NULL) {
315
- const pm_diagnostic_t *diagnostic = (const pm_diagnostic_t *) current;
316
- callback(diagnostic, data);
317
- current = current->next;
318
- }
319
- }
320
-
321
329
  /**
322
- * Iterates over the errors associated with the given parser and calls the
323
- * given callback for each error.
330
+ * Returns the first error associated with the given parser.
324
331
  */
325
- void
326
- pm_parser_errors_each(const pm_parser_t *parser, pm_diagnostic_callback_t callback, void *data) {
327
- 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;
328
335
  }
329
336
 
330
337
  /**
331
- * Iterates over the warnings associated with the given parser and calls the
332
- * given callback for each warning.
338
+ * Returns the first warning associated with the given parser.
333
339
  */
334
- void
335
- pm_parser_warnings_each(const pm_parser_t *parser, pm_diagnostic_callback_t callback, void *data) {
336
- 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;
337
343
  }
338
344
 
339
345
  /**
@@ -346,15 +352,13 @@ pm_parser_constants_size(const pm_parser_t *parser) {
346
352
  }
347
353
 
348
354
  /**
349
- * Iterates over the constants in the constant pool associated with the given
350
- * 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.
351
357
  */
352
- void
353
- pm_parser_constants_each(const pm_parser_t *parser, pm_constant_callback_t callback, void *data) {
354
- for (uint32_t index = 0; index < parser->constant_pool.size; index++) {
355
- const pm_constant_t *constant = &parser->constant_pool.constants[index];
356
- callback(constant, data);
357
- }
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];
358
362
  }
359
363
 
360
364
  /**