herb 0.7.1-arm-linux-musl → 0.7.3-arm-linux-musl

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 (137) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +2 -0
  3. data/README.md +1 -1
  4. data/Rakefile +46 -1
  5. data/config.yml +714 -0
  6. data/ext/herb/error_helpers.c +27 -27
  7. data/ext/herb/extconf.rb +2 -1
  8. data/ext/herb/extension.c +6 -6
  9. data/ext/herb/extension_helpers.c +3 -3
  10. data/ext/herb/nodes.c +35 -35
  11. data/herb.gemspec +3 -0
  12. data/lib/herb/3.0/herb.so +0 -0
  13. data/lib/herb/3.1/herb.so +0 -0
  14. data/lib/herb/3.2/herb.so +0 -0
  15. data/lib/herb/3.3/herb.so +0 -0
  16. data/lib/herb/3.4/herb.so +0 -0
  17. data/lib/herb/engine/debug_visitor.rb +41 -21
  18. data/lib/herb/engine.rb +20 -6
  19. data/lib/herb/version.rb +1 -1
  20. data/sig/herb/engine/debug_visitor.rbs +3 -3
  21. data/sig/herb/engine.rbs +5 -0
  22. data/src/analyze.c +5 -9
  23. data/src/analyze_helpers.c +17 -6
  24. data/src/include/pretty_print.h +1 -1
  25. data/src/include/version.h +1 -1
  26. data/src/parser.c +6 -9
  27. data/src/pretty_print.c +1 -1
  28. data/templates/ext/herb/error_helpers.c.erb +85 -0
  29. data/templates/ext/herb/error_helpers.h.erb +12 -0
  30. data/templates/ext/herb/nodes.c.erb +90 -0
  31. data/templates/ext/herb/nodes.h.erb +9 -0
  32. data/templates/javascript/packages/core/src/errors.ts.erb +193 -0
  33. data/templates/javascript/packages/core/src/node-type-guards.ts.erb +325 -0
  34. data/templates/javascript/packages/core/src/nodes.ts.erb +414 -0
  35. data/templates/javascript/packages/core/src/visitor.ts.erb +29 -0
  36. data/templates/javascript/packages/node/extension/error_helpers.cpp.erb +113 -0
  37. data/templates/javascript/packages/node/extension/error_helpers.h.erb +17 -0
  38. data/templates/javascript/packages/node/extension/nodes.cpp.erb +111 -0
  39. data/templates/javascript/packages/node/extension/nodes.h.erb +17 -0
  40. data/templates/lib/herb/ast/nodes.rb.erb +117 -0
  41. data/templates/lib/herb/errors.rb.erb +106 -0
  42. data/templates/lib/herb/visitor.rb.erb +28 -0
  43. data/templates/sig/serialized_ast_errors.rbs.erb +10 -0
  44. data/templates/sig/serialized_ast_nodes.rbs.erb +10 -0
  45. data/templates/src/ast_nodes.c.erb +145 -0
  46. data/templates/src/ast_pretty_print.c.erb +97 -0
  47. data/templates/src/errors.c.erb +245 -0
  48. data/templates/src/include/ast_nodes.h.erb +46 -0
  49. data/templates/src/include/ast_pretty_print.h.erb +14 -0
  50. data/templates/src/include/errors.h.erb +58 -0
  51. data/templates/src/visitor.c.erb +47 -0
  52. data/templates/template.rb +406 -0
  53. data/templates/wasm/error_helpers.cpp.erb +93 -0
  54. data/templates/wasm/error_helpers.h.erb +15 -0
  55. data/templates/wasm/nodes.cpp.erb +79 -0
  56. data/templates/wasm/nodes.h.erb +15 -0
  57. data/vendor/prism/Rakefile +75 -0
  58. data/vendor/prism/config.yml +4713 -0
  59. data/vendor/prism/include/prism/ast.h +8190 -0
  60. data/vendor/prism/include/prism/defines.h +260 -0
  61. data/vendor/prism/include/prism/diagnostic.h +455 -0
  62. data/vendor/prism/include/prism/encoding.h +283 -0
  63. data/vendor/prism/include/prism/node.h +129 -0
  64. data/vendor/prism/include/prism/options.h +482 -0
  65. data/vendor/prism/include/prism/pack.h +163 -0
  66. data/vendor/prism/include/prism/parser.h +933 -0
  67. data/vendor/prism/include/prism/prettyprint.h +34 -0
  68. data/vendor/prism/include/prism/regexp.h +43 -0
  69. data/vendor/prism/include/prism/static_literals.h +121 -0
  70. data/vendor/prism/include/prism/util/pm_buffer.h +236 -0
  71. data/vendor/prism/include/prism/util/pm_char.h +204 -0
  72. data/vendor/prism/include/prism/util/pm_constant_pool.h +218 -0
  73. data/vendor/prism/include/prism/util/pm_integer.h +130 -0
  74. data/vendor/prism/include/prism/util/pm_list.h +103 -0
  75. data/vendor/prism/include/prism/util/pm_memchr.h +29 -0
  76. data/vendor/prism/include/prism/util/pm_newline_list.h +113 -0
  77. data/vendor/prism/include/prism/util/pm_string.h +200 -0
  78. data/vendor/prism/include/prism/util/pm_strncasecmp.h +32 -0
  79. data/vendor/prism/include/prism/util/pm_strpbrk.h +46 -0
  80. data/vendor/prism/include/prism/version.h +29 -0
  81. data/vendor/prism/include/prism.h +408 -0
  82. data/vendor/prism/src/diagnostic.c +848 -0
  83. data/vendor/prism/src/encoding.c +5235 -0
  84. data/vendor/prism/src/node.c +8676 -0
  85. data/vendor/prism/src/options.c +328 -0
  86. data/vendor/prism/src/pack.c +509 -0
  87. data/vendor/prism/src/prettyprint.c +8941 -0
  88. data/vendor/prism/src/prism.c +23302 -0
  89. data/vendor/prism/src/regexp.c +790 -0
  90. data/vendor/prism/src/serialize.c +2268 -0
  91. data/vendor/prism/src/static_literals.c +617 -0
  92. data/vendor/prism/src/token_type.c +703 -0
  93. data/vendor/prism/src/util/pm_buffer.c +357 -0
  94. data/vendor/prism/src/util/pm_char.c +318 -0
  95. data/vendor/prism/src/util/pm_constant_pool.c +342 -0
  96. data/vendor/prism/src/util/pm_integer.c +670 -0
  97. data/vendor/prism/src/util/pm_list.c +49 -0
  98. data/vendor/prism/src/util/pm_memchr.c +35 -0
  99. data/vendor/prism/src/util/pm_newline_list.c +125 -0
  100. data/vendor/prism/src/util/pm_string.c +383 -0
  101. data/vendor/prism/src/util/pm_strncasecmp.c +36 -0
  102. data/vendor/prism/src/util/pm_strpbrk.c +206 -0
  103. data/vendor/prism/templates/ext/prism/api_node.c.erb +282 -0
  104. data/vendor/prism/templates/include/prism/ast.h.erb +226 -0
  105. data/vendor/prism/templates/include/prism/diagnostic.h.erb +130 -0
  106. data/vendor/prism/templates/java/org/prism/AbstractNodeVisitor.java.erb +22 -0
  107. data/vendor/prism/templates/java/org/prism/Loader.java.erb +434 -0
  108. data/vendor/prism/templates/java/org/prism/Nodes.java.erb +403 -0
  109. data/vendor/prism/templates/javascript/src/deserialize.js.erb +448 -0
  110. data/vendor/prism/templates/javascript/src/nodes.js.erb +197 -0
  111. data/vendor/prism/templates/javascript/src/visitor.js.erb +78 -0
  112. data/vendor/prism/templates/lib/prism/compiler.rb.erb +43 -0
  113. data/vendor/prism/templates/lib/prism/dispatcher.rb.erb +103 -0
  114. data/vendor/prism/templates/lib/prism/dot_visitor.rb.erb +189 -0
  115. data/vendor/prism/templates/lib/prism/dsl.rb.erb +133 -0
  116. data/vendor/prism/templates/lib/prism/inspect_visitor.rb.erb +131 -0
  117. data/vendor/prism/templates/lib/prism/mutation_compiler.rb.erb +19 -0
  118. data/vendor/prism/templates/lib/prism/node.rb.erb +515 -0
  119. data/vendor/prism/templates/lib/prism/reflection.rb.erb +136 -0
  120. data/vendor/prism/templates/lib/prism/serialize.rb.erb +602 -0
  121. data/vendor/prism/templates/lib/prism/visitor.rb.erb +55 -0
  122. data/vendor/prism/templates/rbi/prism/dsl.rbi.erb +68 -0
  123. data/vendor/prism/templates/rbi/prism/node.rbi.erb +164 -0
  124. data/vendor/prism/templates/rbi/prism/visitor.rbi.erb +18 -0
  125. data/vendor/prism/templates/sig/prism/_private/dot_visitor.rbs.erb +45 -0
  126. data/vendor/prism/templates/sig/prism/dsl.rbs.erb +31 -0
  127. data/vendor/prism/templates/sig/prism/mutation_compiler.rbs.erb +7 -0
  128. data/vendor/prism/templates/sig/prism/node.rbs.erb +132 -0
  129. data/vendor/prism/templates/sig/prism/visitor.rbs.erb +17 -0
  130. data/vendor/prism/templates/sig/prism.rbs.erb +89 -0
  131. data/vendor/prism/templates/src/diagnostic.c.erb +523 -0
  132. data/vendor/prism/templates/src/node.c.erb +333 -0
  133. data/vendor/prism/templates/src/prettyprint.c.erb +166 -0
  134. data/vendor/prism/templates/src/serialize.c.erb +406 -0
  135. data/vendor/prism/templates/src/token_type.c.erb +369 -0
  136. data/vendor/prism/templates/template.rb +689 -0
  137. metadata +112 -2
@@ -0,0 +1,406 @@
1
+ #include "prism.h"
2
+
3
+ // We optionally support serializing to a binary string. For systems that don't
4
+ // want or need this functionality, it can be turned off with the
5
+ // PRISM_EXCLUDE_SERIALIZATION define.
6
+ #ifndef PRISM_EXCLUDE_SERIALIZATION
7
+
8
+ #include <stdio.h>
9
+
10
+ static inline uint32_t
11
+ pm_ptrdifft_to_u32(ptrdiff_t value) {
12
+ assert(value >= 0 && ((unsigned long) value) < UINT32_MAX);
13
+ return (uint32_t) value;
14
+ }
15
+
16
+ static inline uint32_t
17
+ pm_sizet_to_u32(size_t value) {
18
+ assert(value < UINT32_MAX);
19
+ return (uint32_t) value;
20
+ }
21
+
22
+ static void
23
+ pm_serialize_location(const pm_parser_t *parser, const pm_location_t *location, pm_buffer_t *buffer) {
24
+ assert(location->start);
25
+ assert(location->end);
26
+ assert(location->start <= location->end);
27
+
28
+ pm_buffer_append_varuint(buffer, pm_ptrdifft_to_u32(location->start - parser->start));
29
+ pm_buffer_append_varuint(buffer, pm_ptrdifft_to_u32(location->end - location->start));
30
+ }
31
+
32
+ static void
33
+ pm_serialize_string(const pm_parser_t *parser, const pm_string_t *string, pm_buffer_t *buffer) {
34
+ switch (string->type) {
35
+ case PM_STRING_SHARED: {
36
+ pm_buffer_append_byte(buffer, 1);
37
+ pm_buffer_append_varuint(buffer, pm_ptrdifft_to_u32(pm_string_source(string) - parser->start));
38
+ pm_buffer_append_varuint(buffer, pm_sizet_to_u32(pm_string_length(string)));
39
+ break;
40
+ }
41
+ case PM_STRING_OWNED:
42
+ case PM_STRING_CONSTANT: {
43
+ uint32_t length = pm_sizet_to_u32(pm_string_length(string));
44
+ pm_buffer_append_byte(buffer, 2);
45
+ pm_buffer_append_varuint(buffer, length);
46
+ pm_buffer_append_bytes(buffer, pm_string_source(string), length);
47
+ break;
48
+ }
49
+ #ifdef PRISM_HAS_MMAP
50
+ case PM_STRING_MAPPED:
51
+ assert(false && "Cannot serialize mapped strings.");
52
+ break;
53
+ #endif
54
+ }
55
+ }
56
+
57
+ static void
58
+ pm_serialize_integer(const pm_integer_t *integer, pm_buffer_t *buffer) {
59
+ pm_buffer_append_byte(buffer, integer->negative ? 1 : 0);
60
+ if (integer->values == NULL) {
61
+ pm_buffer_append_varuint(buffer, pm_sizet_to_u32(1));
62
+ pm_buffer_append_varuint(buffer, integer->value);
63
+ } else {
64
+ pm_buffer_append_varuint(buffer, pm_sizet_to_u32(integer->length));
65
+ for (size_t i = 0; i < integer->length; i++) {
66
+ pm_buffer_append_varuint(buffer, integer->values[i]);
67
+ }
68
+ }
69
+ }
70
+
71
+ static void
72
+ pm_serialize_node(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) {
73
+ pm_buffer_append_byte(buffer, (uint8_t) PM_NODE_TYPE(node));
74
+
75
+ size_t offset = buffer->length;
76
+
77
+ <%- if Prism::Template::INCLUDE_NODE_ID -%>
78
+ pm_buffer_append_varuint(buffer, node->node_id);
79
+ <%- end -%>
80
+ pm_serialize_location(parser, &node->location, buffer);
81
+
82
+ switch (PM_NODE_TYPE(node)) {
83
+ // We do not need to serialize a ScopeNode ever as
84
+ // it is not part of the AST
85
+ case PM_SCOPE_NODE:
86
+ return;
87
+ <%- nodes.each do |node| -%>
88
+ case <%= node.type %>: {
89
+ <%- if node.needs_serialized_length? -%>
90
+ // serialize length
91
+ // encoding of location u32s make us need to save this offset.
92
+ size_t length_offset = buffer->length;
93
+ pm_buffer_append_string(buffer, "\0\0\0\0", 4); /* consume 4 bytes, updated below */
94
+ <%- end -%>
95
+ <%- unless Prism::Template::SERIALIZE_ONLY_SEMANTICS_FIELDS && !node.flags -%>
96
+ pm_buffer_append_varuint(buffer, (uint32_t) node->flags);
97
+ <%- end -%>
98
+ <%- node.fields.each do |field| -%>
99
+ <%- case field -%>
100
+ <%- when Prism::Template::NodeField -%>
101
+ pm_serialize_node(parser, (pm_node_t *)((pm_<%= node.human %>_t *)node)-><%= field.name %>, buffer);
102
+ <%- when Prism::Template::OptionalNodeField -%>
103
+ if (((pm_<%= node.human %>_t *)node)-><%= field.name %> == NULL) {
104
+ pm_buffer_append_byte(buffer, 0);
105
+ } else {
106
+ pm_serialize_node(parser, (pm_node_t *)((pm_<%= node.human %>_t *)node)-><%= field.name %>, buffer);
107
+ }
108
+ <%- when Prism::Template::StringField -%>
109
+ pm_serialize_string(parser, &((pm_<%= node.human %>_t *)node)-><%= field.name %>, buffer);
110
+ <%- when Prism::Template::NodeListField -%>
111
+ uint32_t <%= field.name %>_size = pm_sizet_to_u32(((pm_<%= node.human %>_t *)node)-><%= field.name %>.size);
112
+ pm_buffer_append_varuint(buffer, <%= field.name %>_size);
113
+ for (uint32_t index = 0; index < <%= field.name %>_size; index++) {
114
+ pm_serialize_node(parser, (pm_node_t *) ((pm_<%= node.human %>_t *)node)-><%= field.name %>.nodes[index], buffer);
115
+ }
116
+ <%- when Prism::Template::ConstantField, Prism::Template::OptionalConstantField -%>
117
+ pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_<%= node.human %>_t *)node)-><%= field.name %>));
118
+ <%- when Prism::Template::ConstantListField -%>
119
+ uint32_t <%= field.name %>_size = pm_sizet_to_u32(((pm_<%= node.human %>_t *)node)-><%= field.name %>.size);
120
+ pm_buffer_append_varuint(buffer, <%= field.name %>_size);
121
+ for (uint32_t index = 0; index < <%= field.name %>_size; index++) {
122
+ pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_<%= node.human %>_t *)node)-><%= field.name %>.ids[index]));
123
+ }
124
+ <%- when Prism::Template::LocationField -%>
125
+ <%- if field.should_be_serialized? -%>
126
+ pm_serialize_location(parser, &((pm_<%= node.human %>_t *)node)-><%= field.name %>, buffer);
127
+ <%- end -%>
128
+ <%- when Prism::Template::OptionalLocationField -%>
129
+ <%- if field.should_be_serialized? -%>
130
+ if (((pm_<%= node.human %>_t *)node)-><%= field.name %>.start == NULL) {
131
+ pm_buffer_append_byte(buffer, 0);
132
+ } else {
133
+ pm_buffer_append_byte(buffer, 1);
134
+ pm_serialize_location(parser, &((pm_<%= node.human %>_t *)node)-><%= field.name %>, buffer);
135
+ }
136
+ <%- end -%>
137
+ <%- when Prism::Template::UInt8Field -%>
138
+ pm_buffer_append_byte(buffer, ((pm_<%= node.human %>_t *)node)-><%= field.name %>);
139
+ <%- when Prism::Template::UInt32Field -%>
140
+ pm_buffer_append_varuint(buffer, ((pm_<%= node.human %>_t *)node)-><%= field.name %>);
141
+ <%- when Prism::Template::IntegerField -%>
142
+ pm_serialize_integer(&((pm_<%= node.human %>_t *)node)-><%= field.name %>, buffer);
143
+ <%- when Prism::Template::DoubleField -%>
144
+ pm_buffer_append_double(buffer, ((pm_<%= node.human %>_t *)node)-><%= field.name %>);
145
+ <%- else -%>
146
+ <%- raise -%>
147
+ <%- end -%>
148
+ <%- end -%>
149
+ <%- if node.needs_serialized_length? -%>
150
+ // serialize length
151
+ uint32_t length = pm_sizet_to_u32(buffer->length - offset - sizeof(uint32_t));
152
+ memcpy(buffer->value + length_offset, &length, sizeof(uint32_t));
153
+ <%- end -%>
154
+ break;
155
+ }
156
+ <%- end -%>
157
+ }
158
+ }
159
+
160
+ static void
161
+ pm_serialize_newline_list(pm_newline_list_t *list, pm_buffer_t *buffer) {
162
+ uint32_t size = pm_sizet_to_u32(list->size);
163
+ pm_buffer_append_varuint(buffer, size);
164
+
165
+ for (uint32_t i = 0; i < size; i++) {
166
+ uint32_t offset = pm_sizet_to_u32(list->offsets[i]);
167
+ pm_buffer_append_varuint(buffer, offset);
168
+ }
169
+ }
170
+
171
+ static void
172
+ pm_serialize_comment(pm_parser_t *parser, pm_comment_t *comment, pm_buffer_t *buffer) {
173
+ // serialize type
174
+ pm_buffer_append_byte(buffer, (uint8_t) comment->type);
175
+
176
+ // serialize location
177
+ pm_serialize_location(parser, &comment->location, buffer);
178
+ }
179
+
180
+ /**
181
+ * Serialize the given list of comments to the given buffer.
182
+ */
183
+ void
184
+ pm_serialize_comment_list(pm_parser_t *parser, pm_list_t *list, pm_buffer_t *buffer) {
185
+ pm_buffer_append_varuint(buffer, pm_sizet_to_u32(pm_list_size(list)));
186
+
187
+ pm_comment_t *comment;
188
+ for (comment = (pm_comment_t *) list->head; comment != NULL; comment = (pm_comment_t *) comment->node.next) {
189
+ pm_serialize_comment(parser, comment, buffer);
190
+ }
191
+ }
192
+
193
+ static void
194
+ pm_serialize_magic_comment(pm_parser_t *parser, pm_magic_comment_t *magic_comment, pm_buffer_t *buffer) {
195
+ // serialize key location
196
+ pm_buffer_append_varuint(buffer, pm_ptrdifft_to_u32(magic_comment->key_start - parser->start));
197
+ pm_buffer_append_varuint(buffer, pm_sizet_to_u32(magic_comment->key_length));
198
+
199
+ // serialize value location
200
+ pm_buffer_append_varuint(buffer, pm_ptrdifft_to_u32(magic_comment->value_start - parser->start));
201
+ pm_buffer_append_varuint(buffer, pm_sizet_to_u32(magic_comment->value_length));
202
+ }
203
+
204
+ static void
205
+ pm_serialize_magic_comment_list(pm_parser_t *parser, pm_list_t *list, pm_buffer_t *buffer) {
206
+ pm_buffer_append_varuint(buffer, pm_sizet_to_u32(pm_list_size(list)));
207
+
208
+ pm_magic_comment_t *magic_comment;
209
+ for (magic_comment = (pm_magic_comment_t *) list->head; magic_comment != NULL; magic_comment = (pm_magic_comment_t *) magic_comment->node.next) {
210
+ pm_serialize_magic_comment(parser, magic_comment, buffer);
211
+ }
212
+ }
213
+
214
+ static void
215
+ pm_serialize_data_loc(const pm_parser_t *parser, pm_buffer_t *buffer) {
216
+ if (parser->data_loc.end == NULL) {
217
+ pm_buffer_append_byte(buffer, 0);
218
+ } else {
219
+ pm_buffer_append_byte(buffer, 1);
220
+ pm_serialize_location(parser, &parser->data_loc, buffer);
221
+ }
222
+ }
223
+
224
+ static void
225
+ pm_serialize_diagnostic(pm_parser_t *parser, pm_diagnostic_t *diagnostic, pm_buffer_t *buffer) {
226
+ // serialize the type
227
+ pm_buffer_append_varuint(buffer, (uint32_t) diagnostic->diag_id);
228
+
229
+ // serialize message
230
+ size_t message_length = strlen(diagnostic->message);
231
+ pm_buffer_append_varuint(buffer, pm_sizet_to_u32(message_length));
232
+ pm_buffer_append_string(buffer, diagnostic->message, message_length);
233
+
234
+ // serialize location
235
+ pm_serialize_location(parser, &diagnostic->location, buffer);
236
+
237
+ pm_buffer_append_byte(buffer, diagnostic->level);
238
+ }
239
+
240
+ static void
241
+ pm_serialize_diagnostic_list(pm_parser_t *parser, pm_list_t *list, pm_buffer_t *buffer) {
242
+ pm_buffer_append_varuint(buffer, pm_sizet_to_u32(pm_list_size(list)));
243
+
244
+ pm_diagnostic_t *diagnostic;
245
+ for (diagnostic = (pm_diagnostic_t *) list->head; diagnostic != NULL; diagnostic = (pm_diagnostic_t *) diagnostic->node.next) {
246
+ pm_serialize_diagnostic(parser, diagnostic, buffer);
247
+ }
248
+ }
249
+
250
+ /**
251
+ * Serialize the name of the encoding to the buffer.
252
+ */
253
+ void
254
+ pm_serialize_encoding(const pm_encoding_t *encoding, pm_buffer_t *buffer) {
255
+ size_t encoding_length = strlen(encoding->name);
256
+ pm_buffer_append_varuint(buffer, pm_sizet_to_u32(encoding_length));
257
+ pm_buffer_append_string(buffer, encoding->name, encoding_length);
258
+ }
259
+
260
+ static void
261
+ pm_serialize_metadata(pm_parser_t *parser, pm_buffer_t *buffer) {
262
+ pm_serialize_encoding(parser->encoding, buffer);
263
+ pm_buffer_append_varsint(buffer, parser->start_line);
264
+ pm_serialize_newline_list(&parser->newline_list, buffer);
265
+ <%- unless Prism::Template::SERIALIZE_ONLY_SEMANTICS_FIELDS -%>
266
+ pm_serialize_comment_list(parser, &parser->comment_list, buffer);
267
+ <%- end -%>
268
+ pm_serialize_magic_comment_list(parser, &parser->magic_comment_list, buffer);
269
+ pm_serialize_data_loc(parser, buffer);
270
+ pm_serialize_diagnostic_list(parser, &parser->error_list, buffer);
271
+ pm_serialize_diagnostic_list(parser, &parser->warning_list, buffer);
272
+ }
273
+
274
+ #line <%= __LINE__ + 1 %> "prism/templates/src/<%= File.basename(__FILE__) %>"
275
+ /**
276
+ * Serialize the metadata, nodes, and constant pool.
277
+ */
278
+ void
279
+ pm_serialize_content(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) {
280
+ pm_serialize_metadata(parser, buffer);
281
+
282
+ // Here we're going to leave space for the offset of the constant pool in
283
+ // the buffer.
284
+ size_t offset = buffer->length;
285
+ pm_buffer_append_zeroes(buffer, 4);
286
+
287
+ // Next, encode the length of the constant pool.
288
+ pm_buffer_append_varuint(buffer, parser->constant_pool.size);
289
+
290
+ // Now we're going to serialize the content of the node.
291
+ pm_serialize_node(parser, node, buffer);
292
+
293
+ // Now we're going to serialize the offset of the constant pool back where
294
+ // we left space for it.
295
+ uint32_t length = pm_sizet_to_u32(buffer->length);
296
+ memcpy(buffer->value + offset, &length, sizeof(uint32_t));
297
+
298
+ // Now we're going to serialize the constant pool.
299
+ offset = buffer->length;
300
+ pm_buffer_append_zeroes(buffer, parser->constant_pool.size * 8);
301
+
302
+ for (uint32_t index = 0; index < parser->constant_pool.capacity; index++) {
303
+ pm_constant_pool_bucket_t *bucket = &parser->constant_pool.buckets[index];
304
+
305
+ // If we find a constant at this index, serialize it at the correct
306
+ // index in the buffer.
307
+ if (bucket->id != 0) {
308
+ pm_constant_t *constant = &parser->constant_pool.constants[bucket->id - 1];
309
+ size_t buffer_offset = offset + ((((size_t)bucket->id) - 1) * 8);
310
+
311
+ if (bucket->type == PM_CONSTANT_POOL_BUCKET_OWNED || bucket->type == PM_CONSTANT_POOL_BUCKET_CONSTANT) {
312
+ // Since this is an owned or constant constant, we are going to
313
+ // write its contents into the buffer after the constant pool.
314
+ // So effectively in place of the source offset, we have a
315
+ // buffer offset. We will add a leading 1 to indicate that this
316
+ // is a buffer offset.
317
+ uint32_t content_offset = pm_sizet_to_u32(buffer->length);
318
+ uint32_t owned_mask = (uint32_t) (1 << 31);
319
+
320
+ assert(content_offset < owned_mask);
321
+ content_offset |= owned_mask;
322
+
323
+ memcpy(buffer->value + buffer_offset, &content_offset, 4);
324
+ pm_buffer_append_bytes(buffer, constant->start, constant->length);
325
+ } else {
326
+ // Since this is a shared constant, we are going to write its
327
+ // source offset directly into the buffer.
328
+ uint32_t source_offset = pm_ptrdifft_to_u32(constant->start - parser->start);
329
+ memcpy(buffer->value + buffer_offset, &source_offset, 4);
330
+ }
331
+
332
+ // Now we can write the length of the constant into the buffer.
333
+ uint32_t constant_length = pm_sizet_to_u32(constant->length);
334
+ memcpy(buffer->value + buffer_offset + 4, &constant_length, 4);
335
+ }
336
+ }
337
+ }
338
+
339
+ static void
340
+ serialize_token(void *data, pm_parser_t *parser, pm_token_t *token) {
341
+ pm_buffer_t *buffer = (pm_buffer_t *) data;
342
+
343
+ pm_buffer_append_varuint(buffer, token->type);
344
+ pm_buffer_append_varuint(buffer, pm_ptrdifft_to_u32(token->start - parser->start));
345
+ pm_buffer_append_varuint(buffer, pm_ptrdifft_to_u32(token->end - token->start));
346
+ pm_buffer_append_varuint(buffer, parser->lex_state);
347
+ }
348
+
349
+ /**
350
+ * Lex the given source and serialize to the given buffer.
351
+ */
352
+ PRISM_EXPORTED_FUNCTION void
353
+ pm_serialize_lex(pm_buffer_t *buffer, const uint8_t *source, size_t size, const char *data) {
354
+ pm_options_t options = { 0 };
355
+ pm_options_read(&options, data);
356
+
357
+ pm_parser_t parser;
358
+ pm_parser_init(&parser, source, size, &options);
359
+
360
+ pm_lex_callback_t lex_callback = (pm_lex_callback_t) {
361
+ .data = (void *) buffer,
362
+ .callback = serialize_token,
363
+ };
364
+
365
+ parser.lex_callback = &lex_callback;
366
+ pm_node_t *node = pm_parse(&parser);
367
+
368
+ // Append 0 to mark end of tokens.
369
+ pm_buffer_append_byte(buffer, 0);
370
+
371
+ pm_serialize_metadata(&parser, buffer);
372
+
373
+ pm_node_destroy(&parser, node);
374
+ pm_parser_free(&parser);
375
+ pm_options_free(&options);
376
+ }
377
+
378
+ /**
379
+ * Parse and serialize both the AST and the tokens represented by the given
380
+ * source to the given buffer.
381
+ */
382
+ PRISM_EXPORTED_FUNCTION void
383
+ pm_serialize_parse_lex(pm_buffer_t *buffer, const uint8_t *source, size_t size, const char *data) {
384
+ pm_options_t options = { 0 };
385
+ pm_options_read(&options, data);
386
+
387
+ pm_parser_t parser;
388
+ pm_parser_init(&parser, source, size, &options);
389
+
390
+ pm_lex_callback_t lex_callback = (pm_lex_callback_t) {
391
+ .data = (void *) buffer,
392
+ .callback = serialize_token,
393
+ };
394
+
395
+ parser.lex_callback = &lex_callback;
396
+ pm_node_t *node = pm_parse(&parser);
397
+
398
+ pm_buffer_append_byte(buffer, 0);
399
+ pm_serialize(&parser, node, buffer);
400
+
401
+ pm_node_destroy(&parser, node);
402
+ pm_parser_free(&parser);
403
+ pm_options_free(&options);
404
+ }
405
+
406
+ #endif