herb 0.7.2-arm64-darwin → 0.7.4-arm64-darwin
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.
- checksums.yaml +4 -4
- data/Makefile +2 -0
- data/README.md +1 -1
- data/Rakefile +46 -1
- data/config.yml +714 -0
- data/ext/herb/extconf.rb +2 -1
- data/ext/herb/nodes.c +1 -1
- data/herb.gemspec +3 -0
- data/lib/herb/3.0/herb.bundle +0 -0
- data/lib/herb/3.1/herb.bundle +0 -0
- data/lib/herb/3.2/herb.bundle +0 -0
- data/lib/herb/3.3/herb.bundle +0 -0
- data/lib/herb/3.4/herb.bundle +0 -0
- data/lib/herb/engine.rb +8 -1
- data/lib/herb/version.rb +1 -1
- data/src/analyze.c +5 -9
- data/src/analyze_helpers.c +17 -6
- data/src/herb.c +2 -2
- data/src/include/parser.h +2 -2
- data/src/include/pretty_print.h +1 -1
- data/src/include/version.h +1 -1
- data/src/parser.c +3 -2
- data/src/pretty_print.c +1 -1
- data/templates/ext/herb/error_helpers.c.erb +85 -0
- data/templates/ext/herb/error_helpers.h.erb +12 -0
- data/templates/ext/herb/nodes.c.erb +90 -0
- data/templates/ext/herb/nodes.h.erb +9 -0
- data/templates/javascript/packages/core/src/errors.ts.erb +193 -0
- data/templates/javascript/packages/core/src/node-type-guards.ts.erb +325 -0
- data/templates/javascript/packages/core/src/nodes.ts.erb +414 -0
- data/templates/javascript/packages/core/src/visitor.ts.erb +29 -0
- data/templates/javascript/packages/node/extension/error_helpers.cpp.erb +113 -0
- data/templates/javascript/packages/node/extension/error_helpers.h.erb +17 -0
- data/templates/javascript/packages/node/extension/nodes.cpp.erb +111 -0
- data/templates/javascript/packages/node/extension/nodes.h.erb +17 -0
- data/templates/lib/herb/ast/nodes.rb.erb +117 -0
- data/templates/lib/herb/errors.rb.erb +106 -0
- data/templates/lib/herb/visitor.rb.erb +28 -0
- data/templates/sig/serialized_ast_errors.rbs.erb +10 -0
- data/templates/sig/serialized_ast_nodes.rbs.erb +10 -0
- data/templates/src/ast_nodes.c.erb +145 -0
- data/templates/src/ast_pretty_print.c.erb +97 -0
- data/templates/src/errors.c.erb +245 -0
- data/templates/src/include/ast_nodes.h.erb +46 -0
- data/templates/src/include/ast_pretty_print.h.erb +14 -0
- data/templates/src/include/errors.h.erb +58 -0
- data/templates/src/visitor.c.erb +47 -0
- data/templates/template.rb +406 -0
- data/templates/wasm/error_helpers.cpp.erb +93 -0
- data/templates/wasm/error_helpers.h.erb +15 -0
- data/templates/wasm/nodes.cpp.erb +79 -0
- data/templates/wasm/nodes.h.erb +15 -0
- data/vendor/prism/Rakefile +75 -0
- data/vendor/prism/config.yml +4713 -0
- data/vendor/prism/include/prism/ast.h +8190 -0
- data/vendor/prism/include/prism/defines.h +260 -0
- data/vendor/prism/include/prism/diagnostic.h +455 -0
- data/vendor/prism/include/prism/encoding.h +283 -0
- data/vendor/prism/include/prism/node.h +129 -0
- data/vendor/prism/include/prism/options.h +482 -0
- data/vendor/prism/include/prism/pack.h +163 -0
- data/vendor/prism/include/prism/parser.h +933 -0
- data/vendor/prism/include/prism/prettyprint.h +34 -0
- data/vendor/prism/include/prism/regexp.h +43 -0
- data/vendor/prism/include/prism/static_literals.h +121 -0
- data/vendor/prism/include/prism/util/pm_buffer.h +236 -0
- data/vendor/prism/include/prism/util/pm_char.h +204 -0
- data/vendor/prism/include/prism/util/pm_constant_pool.h +218 -0
- data/vendor/prism/include/prism/util/pm_integer.h +130 -0
- data/vendor/prism/include/prism/util/pm_list.h +103 -0
- data/vendor/prism/include/prism/util/pm_memchr.h +29 -0
- data/vendor/prism/include/prism/util/pm_newline_list.h +113 -0
- data/vendor/prism/include/prism/util/pm_string.h +200 -0
- data/vendor/prism/include/prism/util/pm_strncasecmp.h +32 -0
- data/vendor/prism/include/prism/util/pm_strpbrk.h +46 -0
- data/vendor/prism/include/prism/version.h +29 -0
- data/vendor/prism/include/prism.h +408 -0
- data/vendor/prism/src/diagnostic.c +848 -0
- data/vendor/prism/src/encoding.c +5235 -0
- data/vendor/prism/src/node.c +8676 -0
- data/vendor/prism/src/options.c +328 -0
- data/vendor/prism/src/pack.c +509 -0
- data/vendor/prism/src/prettyprint.c +8941 -0
- data/vendor/prism/src/prism.c +23302 -0
- data/vendor/prism/src/regexp.c +790 -0
- data/vendor/prism/src/serialize.c +2268 -0
- data/vendor/prism/src/static_literals.c +617 -0
- data/vendor/prism/src/token_type.c +703 -0
- data/vendor/prism/src/util/pm_buffer.c +357 -0
- data/vendor/prism/src/util/pm_char.c +318 -0
- data/vendor/prism/src/util/pm_constant_pool.c +342 -0
- data/vendor/prism/src/util/pm_integer.c +670 -0
- data/vendor/prism/src/util/pm_list.c +49 -0
- data/vendor/prism/src/util/pm_memchr.c +35 -0
- data/vendor/prism/src/util/pm_newline_list.c +125 -0
- data/vendor/prism/src/util/pm_string.c +383 -0
- data/vendor/prism/src/util/pm_strncasecmp.c +36 -0
- data/vendor/prism/src/util/pm_strpbrk.c +206 -0
- data/vendor/prism/templates/ext/prism/api_node.c.erb +282 -0
- data/vendor/prism/templates/include/prism/ast.h.erb +226 -0
- data/vendor/prism/templates/include/prism/diagnostic.h.erb +130 -0
- data/vendor/prism/templates/java/org/prism/AbstractNodeVisitor.java.erb +22 -0
- data/vendor/prism/templates/java/org/prism/Loader.java.erb +434 -0
- data/vendor/prism/templates/java/org/prism/Nodes.java.erb +403 -0
- data/vendor/prism/templates/javascript/src/deserialize.js.erb +448 -0
- data/vendor/prism/templates/javascript/src/nodes.js.erb +197 -0
- data/vendor/prism/templates/javascript/src/visitor.js.erb +78 -0
- data/vendor/prism/templates/lib/prism/compiler.rb.erb +43 -0
- data/vendor/prism/templates/lib/prism/dispatcher.rb.erb +103 -0
- data/vendor/prism/templates/lib/prism/dot_visitor.rb.erb +189 -0
- data/vendor/prism/templates/lib/prism/dsl.rb.erb +133 -0
- data/vendor/prism/templates/lib/prism/inspect_visitor.rb.erb +131 -0
- data/vendor/prism/templates/lib/prism/mutation_compiler.rb.erb +19 -0
- data/vendor/prism/templates/lib/prism/node.rb.erb +515 -0
- data/vendor/prism/templates/lib/prism/reflection.rb.erb +136 -0
- data/vendor/prism/templates/lib/prism/serialize.rb.erb +602 -0
- data/vendor/prism/templates/lib/prism/visitor.rb.erb +55 -0
- data/vendor/prism/templates/rbi/prism/dsl.rbi.erb +68 -0
- data/vendor/prism/templates/rbi/prism/node.rbi.erb +164 -0
- data/vendor/prism/templates/rbi/prism/visitor.rbi.erb +18 -0
- data/vendor/prism/templates/sig/prism/_private/dot_visitor.rbs.erb +45 -0
- data/vendor/prism/templates/sig/prism/dsl.rbs.erb +31 -0
- data/vendor/prism/templates/sig/prism/mutation_compiler.rbs.erb +7 -0
- data/vendor/prism/templates/sig/prism/node.rbs.erb +132 -0
- data/vendor/prism/templates/sig/prism/visitor.rbs.erb +17 -0
- data/vendor/prism/templates/sig/prism.rbs.erb +89 -0
- data/vendor/prism/templates/src/diagnostic.c.erb +523 -0
- data/vendor/prism/templates/src/node.c.erb +333 -0
- data/vendor/prism/templates/src/prettyprint.c.erb +166 -0
- data/vendor/prism/templates/src/serialize.c.erb +406 -0
- data/vendor/prism/templates/src/token_type.c.erb +369 -0
- data/vendor/prism/templates/template.rb +689 -0
- metadata +112 -2
@@ -0,0 +1,333 @@
|
|
1
|
+
#line <%= __LINE__ + 1 %> "prism/templates/src/<%= File.basename(__FILE__) %>"
|
2
|
+
#include "prism/node.h"
|
3
|
+
|
4
|
+
/**
|
5
|
+
* Attempts to grow the node list to the next size. If there is already
|
6
|
+
* capacity in the list, this function does nothing. Otherwise it reallocates
|
7
|
+
* the list to be twice as large as it was before. If the reallocation fails,
|
8
|
+
* this function returns false, otherwise it returns true.
|
9
|
+
*/
|
10
|
+
static bool
|
11
|
+
pm_node_list_grow(pm_node_list_t *list, size_t size) {
|
12
|
+
size_t requested_size = list->size + size;
|
13
|
+
|
14
|
+
// If the requested size caused overflow, return false.
|
15
|
+
if (requested_size < list->size) return false;
|
16
|
+
|
17
|
+
// If the requested size is within the existing capacity, return true.
|
18
|
+
if (requested_size < list->capacity) return true;
|
19
|
+
|
20
|
+
// Otherwise, reallocate the list to be twice as large as it was before.
|
21
|
+
size_t next_capacity = list->capacity == 0 ? 4 : list->capacity * 2;
|
22
|
+
|
23
|
+
// If multiplying by 2 caused overflow, return false.
|
24
|
+
if (next_capacity < list->capacity) return false;
|
25
|
+
|
26
|
+
// If we didn't get enough by doubling, keep doubling until we do.
|
27
|
+
while (requested_size > next_capacity) {
|
28
|
+
size_t double_capacity = next_capacity * 2;
|
29
|
+
|
30
|
+
// Ensure we didn't overflow by multiplying by 2.
|
31
|
+
if (double_capacity < next_capacity) return false;
|
32
|
+
next_capacity = double_capacity;
|
33
|
+
}
|
34
|
+
|
35
|
+
pm_node_t **nodes = (pm_node_t **) xrealloc(list->nodes, sizeof(pm_node_t *) * next_capacity);
|
36
|
+
if (nodes == NULL) return false;
|
37
|
+
|
38
|
+
list->nodes = nodes;
|
39
|
+
list->capacity = next_capacity;
|
40
|
+
return true;
|
41
|
+
}
|
42
|
+
|
43
|
+
/**
|
44
|
+
* Append a new node onto the end of the node list.
|
45
|
+
*/
|
46
|
+
void
|
47
|
+
pm_node_list_append(pm_node_list_t *list, pm_node_t *node) {
|
48
|
+
if (pm_node_list_grow(list, 1)) {
|
49
|
+
list->nodes[list->size++] = node;
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
/**
|
54
|
+
* Prepend a new node onto the beginning of the node list.
|
55
|
+
*/
|
56
|
+
void
|
57
|
+
pm_node_list_prepend(pm_node_list_t *list, pm_node_t *node) {
|
58
|
+
if (pm_node_list_grow(list, 1)) {
|
59
|
+
memmove(list->nodes + 1, list->nodes, list->size * sizeof(pm_node_t *));
|
60
|
+
list->nodes[0] = node;
|
61
|
+
list->size++;
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
/**
|
66
|
+
* Concatenate the given node list onto the end of the other node list.
|
67
|
+
*/
|
68
|
+
void
|
69
|
+
pm_node_list_concat(pm_node_list_t *list, pm_node_list_t *other) {
|
70
|
+
if (other->size > 0 && pm_node_list_grow(list, other->size)) {
|
71
|
+
memcpy(list->nodes + list->size, other->nodes, other->size * sizeof(pm_node_t *));
|
72
|
+
list->size += other->size;
|
73
|
+
}
|
74
|
+
}
|
75
|
+
|
76
|
+
/**
|
77
|
+
* Free the internal memory associated with the given node list.
|
78
|
+
*/
|
79
|
+
void
|
80
|
+
pm_node_list_free(pm_node_list_t *list) {
|
81
|
+
if (list->capacity > 0) {
|
82
|
+
xfree(list->nodes);
|
83
|
+
*list = (pm_node_list_t) { 0 };
|
84
|
+
}
|
85
|
+
}
|
86
|
+
|
87
|
+
PRISM_EXPORTED_FUNCTION void
|
88
|
+
pm_node_destroy(pm_parser_t *parser, pm_node_t *node);
|
89
|
+
|
90
|
+
/**
|
91
|
+
* Destroy the nodes that are contained within the given node list.
|
92
|
+
*/
|
93
|
+
static void
|
94
|
+
pm_node_list_destroy(pm_parser_t *parser, pm_node_list_t *list) {
|
95
|
+
pm_node_t *node;
|
96
|
+
PM_NODE_LIST_FOREACH(list, index, node) pm_node_destroy(parser, node);
|
97
|
+
pm_node_list_free(list);
|
98
|
+
}
|
99
|
+
|
100
|
+
/**
|
101
|
+
* Deallocate the space for a pm_node_t. Similarly to pm_node_alloc, we're not
|
102
|
+
* using the parser argument, but it's there to allow for the future possibility
|
103
|
+
* of pre-allocating larger memory pools.
|
104
|
+
*/
|
105
|
+
PRISM_EXPORTED_FUNCTION void
|
106
|
+
pm_node_destroy(pm_parser_t *parser, pm_node_t *node) {
|
107
|
+
switch (PM_NODE_TYPE(node)) {
|
108
|
+
<%- nodes.each do |node| -%>
|
109
|
+
#line <%= __LINE__ + 1 %> "prism/templates/src/<%= File.basename(__FILE__) %>"
|
110
|
+
case <%= node.type %>: {
|
111
|
+
<%- if node.fields.any? { |field| ![Prism::Template::LocationField, Prism::Template::OptionalLocationField, Prism::Template::UInt8Field, Prism::Template::UInt32Field, Prism::Template::ConstantField, Prism::Template::OptionalConstantField, Prism::Template::DoubleField].include?(field.class) } -%>
|
112
|
+
pm_<%= node.human %>_t *cast = (pm_<%= node.human %>_t *) node;
|
113
|
+
<%- end -%>
|
114
|
+
<%- node.fields.each do |field| -%>
|
115
|
+
<%- case field -%>
|
116
|
+
<%- when Prism::Template::LocationField, Prism::Template::OptionalLocationField, Prism::Template::UInt8Field, Prism::Template::UInt32Field, Prism::Template::ConstantField, Prism::Template::OptionalConstantField, Prism::Template::DoubleField -%>
|
117
|
+
<%- when Prism::Template::NodeField -%>
|
118
|
+
pm_node_destroy(parser, (pm_node_t *)cast-><%= field.name %>);
|
119
|
+
<%- when Prism::Template::OptionalNodeField -%>
|
120
|
+
if (cast-><%= field.name %> != NULL) {
|
121
|
+
pm_node_destroy(parser, (pm_node_t *)cast-><%= field.name %>);
|
122
|
+
}
|
123
|
+
<%- when Prism::Template::StringField -%>
|
124
|
+
pm_string_free(&cast-><%= field.name %>);
|
125
|
+
<%- when Prism::Template::NodeListField -%>
|
126
|
+
pm_node_list_destroy(parser, &cast-><%= field.name %>);
|
127
|
+
<%- when Prism::Template::ConstantListField -%>
|
128
|
+
pm_constant_id_list_free(&cast-><%= field.name %>);
|
129
|
+
<%- when Prism::Template::IntegerField -%>
|
130
|
+
pm_integer_free(&cast-><%= field.name %>);
|
131
|
+
<%- else -%>
|
132
|
+
<%- raise -%>
|
133
|
+
<%- end -%>
|
134
|
+
<%- end -%>
|
135
|
+
break;
|
136
|
+
}
|
137
|
+
<%- end -%>
|
138
|
+
#line <%= __LINE__ + 1 %> "prism/templates/src/<%= File.basename(__FILE__) %>"
|
139
|
+
default:
|
140
|
+
assert(false && "unreachable");
|
141
|
+
break;
|
142
|
+
}
|
143
|
+
xfree(node);
|
144
|
+
}
|
145
|
+
|
146
|
+
/**
|
147
|
+
* Returns a string representation of the given node type.
|
148
|
+
*/
|
149
|
+
PRISM_EXPORTED_FUNCTION const char *
|
150
|
+
pm_node_type_to_str(pm_node_type_t node_type)
|
151
|
+
{
|
152
|
+
switch (node_type) {
|
153
|
+
<%- nodes.each do |node| -%>
|
154
|
+
case <%= node.type %>:
|
155
|
+
return "<%= node.type %>";
|
156
|
+
<%- end -%>
|
157
|
+
}
|
158
|
+
return "";
|
159
|
+
}
|
160
|
+
|
161
|
+
/**
|
162
|
+
* Visit each of the nodes in this subtree using the given visitor callback. The
|
163
|
+
* callback function will be called for each node in the subtree. If it returns
|
164
|
+
* false, then that node's children will not be visited. If it returns true,
|
165
|
+
* then the children will be visited. The data parameter is treated as an opaque
|
166
|
+
* pointer and is passed to the visitor callback for consumers to use as they
|
167
|
+
* see fit.
|
168
|
+
*/
|
169
|
+
PRISM_EXPORTED_FUNCTION void
|
170
|
+
pm_visit_node(const pm_node_t *node, bool (*visitor)(const pm_node_t *node, void *data), void *data) {
|
171
|
+
if (visitor(node, data)) pm_visit_child_nodes(node, visitor, data);
|
172
|
+
}
|
173
|
+
|
174
|
+
/**
|
175
|
+
* Visit the children of the given node with the given callback. This is the
|
176
|
+
* default behavior for walking the tree that is called from pm_visit_node if
|
177
|
+
* the callback returns true.
|
178
|
+
*/
|
179
|
+
PRISM_EXPORTED_FUNCTION void
|
180
|
+
pm_visit_child_nodes(const pm_node_t *node, bool (*visitor)(const pm_node_t *node, void *data), void *data) {
|
181
|
+
switch (PM_NODE_TYPE(node)) {
|
182
|
+
<%- nodes.each do |node| -%>
|
183
|
+
<%- if (fields = node.fields.select { |field| field.is_a?(Prism::Template::NodeField) || field.is_a?(Prism::Template::OptionalNodeField) || field.is_a?(Prism::Template::NodeListField) }).any? -%>
|
184
|
+
case <%= node.type %>: {
|
185
|
+
const pm_<%= node.human %>_t *cast = (const pm_<%= node.human %>_t *) node;
|
186
|
+
<%- fields.each do |field| -%>
|
187
|
+
|
188
|
+
// Visit the <%= field.name %> field
|
189
|
+
<%- case field -%>
|
190
|
+
<%- when Prism::Template::NodeField -%>
|
191
|
+
pm_visit_node((const pm_node_t *) cast-><%= field.name %>, visitor, data);
|
192
|
+
<%- when Prism::Template::OptionalNodeField -%>
|
193
|
+
if (cast-><%= field.name %> != NULL) {
|
194
|
+
pm_visit_node((const pm_node_t *) cast-><%= field.name %>, visitor, data);
|
195
|
+
}
|
196
|
+
<%- when Prism::Template::NodeListField -%>
|
197
|
+
const pm_node_list_t *<%= field.name %> = &cast-><%= field.name %>;
|
198
|
+
for (size_t index = 0; index < <%= field.name %>->size; index++) {
|
199
|
+
pm_visit_node(<%= field.name %>->nodes[index], visitor, data);
|
200
|
+
}
|
201
|
+
<%- end -%>
|
202
|
+
<%- end -%>
|
203
|
+
|
204
|
+
break;
|
205
|
+
}
|
206
|
+
<%- else -%>
|
207
|
+
case <%= node.type %>:
|
208
|
+
break;
|
209
|
+
<%- end -%>
|
210
|
+
<%- end -%>
|
211
|
+
case PM_SCOPE_NODE:
|
212
|
+
break;
|
213
|
+
}
|
214
|
+
}
|
215
|
+
|
216
|
+
// We optionally support dumping to JSON. For systems that don't want or need
|
217
|
+
// this functionality, it can be turned off with the PRISM_EXCLUDE_JSON define.
|
218
|
+
#ifndef PRISM_EXCLUDE_JSON
|
219
|
+
|
220
|
+
static void
|
221
|
+
pm_dump_json_constant(pm_buffer_t *buffer, const pm_parser_t *parser, pm_constant_id_t constant_id) {
|
222
|
+
const pm_constant_t *constant = pm_constant_pool_id_to_constant(&parser->constant_pool, constant_id);
|
223
|
+
pm_buffer_append_byte(buffer, '"');
|
224
|
+
pm_buffer_append_source(buffer, constant->start, constant->length, PM_BUFFER_ESCAPING_JSON);
|
225
|
+
pm_buffer_append_byte(buffer, '"');
|
226
|
+
}
|
227
|
+
|
228
|
+
static void
|
229
|
+
pm_dump_json_location(pm_buffer_t *buffer, const pm_parser_t *parser, const pm_location_t *location) {
|
230
|
+
uint32_t start = (uint32_t) (location->start - parser->start);
|
231
|
+
uint32_t end = (uint32_t) (location->end - parser->start);
|
232
|
+
pm_buffer_append_format(buffer, "{\"start\":%" PRIu32 ",\"end\":%" PRIu32 "}", start, end);
|
233
|
+
}
|
234
|
+
|
235
|
+
/**
|
236
|
+
* Dump JSON to the given buffer.
|
237
|
+
*/
|
238
|
+
PRISM_EXPORTED_FUNCTION void
|
239
|
+
pm_dump_json(pm_buffer_t *buffer, const pm_parser_t *parser, const pm_node_t *node) {
|
240
|
+
switch (PM_NODE_TYPE(node)) {
|
241
|
+
<%- nodes.each do |node| -%>
|
242
|
+
case <%= node.type %>: {
|
243
|
+
pm_buffer_append_string(buffer, "{\"type\":\"<%= node.name %>\",\"location\":", <%= node.name.bytesize + 22 %>);
|
244
|
+
|
245
|
+
const pm_<%= node.human %>_t *cast = (const pm_<%= node.human %>_t *) node;
|
246
|
+
pm_dump_json_location(buffer, parser, &cast->base.location);
|
247
|
+
<%- [*node.flags, *node.fields].each_with_index do |field, index| -%>
|
248
|
+
|
249
|
+
// Dump the <%= field.name %> field
|
250
|
+
pm_buffer_append_byte(buffer, ',');
|
251
|
+
pm_buffer_append_string(buffer, "\"<%= field.name %>\":", <%= field.name.bytesize + 3 %>);
|
252
|
+
<%- case field -%>
|
253
|
+
<%- when Prism::Template::NodeField -%>
|
254
|
+
pm_dump_json(buffer, parser, (const pm_node_t *) cast-><%= field.name %>);
|
255
|
+
<%- when Prism::Template::OptionalNodeField -%>
|
256
|
+
if (cast-><%= field.name %> != NULL) {
|
257
|
+
pm_dump_json(buffer, parser, (const pm_node_t *) cast-><%= field.name %>);
|
258
|
+
} else {
|
259
|
+
pm_buffer_append_string(buffer, "null", 4);
|
260
|
+
}
|
261
|
+
<%- when Prism::Template::NodeListField -%>
|
262
|
+
const pm_node_list_t *<%= field.name %> = &cast-><%= field.name %>;
|
263
|
+
pm_buffer_append_byte(buffer, '[');
|
264
|
+
|
265
|
+
for (size_t index = 0; index < <%= field.name %>->size; index++) {
|
266
|
+
if (index != 0) pm_buffer_append_byte(buffer, ',');
|
267
|
+
pm_dump_json(buffer, parser, <%= field.name %>->nodes[index]);
|
268
|
+
}
|
269
|
+
pm_buffer_append_byte(buffer, ']');
|
270
|
+
<%- when Prism::Template::StringField -%>
|
271
|
+
const pm_string_t *<%= field.name %> = &cast-><%= field.name %>;
|
272
|
+
pm_buffer_append_byte(buffer, '"');
|
273
|
+
pm_buffer_append_source(buffer, pm_string_source(<%= field.name %>), pm_string_length(<%= field.name %>), PM_BUFFER_ESCAPING_JSON);
|
274
|
+
pm_buffer_append_byte(buffer, '"');
|
275
|
+
<%- when Prism::Template::ConstantField -%>
|
276
|
+
pm_dump_json_constant(buffer, parser, cast-><%= field.name %>);
|
277
|
+
<%- when Prism::Template::OptionalConstantField -%>
|
278
|
+
if (cast-><%= field.name %> != PM_CONSTANT_ID_UNSET) {
|
279
|
+
pm_dump_json_constant(buffer, parser, cast-><%= field.name %>);
|
280
|
+
} else {
|
281
|
+
pm_buffer_append_string(buffer, "null", 4);
|
282
|
+
}
|
283
|
+
<%- when Prism::Template::ConstantListField -%>
|
284
|
+
const pm_constant_id_list_t *<%= field.name %> = &cast-><%= field.name %>;
|
285
|
+
pm_buffer_append_byte(buffer, '[');
|
286
|
+
|
287
|
+
for (size_t index = 0; index < <%= field.name %>->size; index++) {
|
288
|
+
if (index != 0) pm_buffer_append_byte(buffer, ',');
|
289
|
+
pm_dump_json_constant(buffer, parser, <%= field.name %>->ids[index]);
|
290
|
+
}
|
291
|
+
pm_buffer_append_byte(buffer, ']');
|
292
|
+
<%- when Prism::Template::LocationField -%>
|
293
|
+
pm_dump_json_location(buffer, parser, &cast-><%= field.name %>);
|
294
|
+
<%- when Prism::Template::OptionalLocationField -%>
|
295
|
+
if (cast-><%= field.name %>.start != NULL) {
|
296
|
+
pm_dump_json_location(buffer, parser, &cast-><%= field.name %>);
|
297
|
+
} else {
|
298
|
+
pm_buffer_append_string(buffer, "null", 4);
|
299
|
+
}
|
300
|
+
<%- when Prism::Template::UInt8Field -%>
|
301
|
+
pm_buffer_append_format(buffer, "%" PRIu8, cast-><%= field.name %>);
|
302
|
+
<%- when Prism::Template::UInt32Field -%>
|
303
|
+
pm_buffer_append_format(buffer, "%" PRIu32, cast-><%= field.name %>);
|
304
|
+
<%- when Prism::Template::Flags -%>
|
305
|
+
size_t flags = 0;
|
306
|
+
pm_buffer_append_byte(buffer, '[');
|
307
|
+
<%- node.flags.values.each_with_index do |value, index| -%>
|
308
|
+
if (PM_NODE_FLAG_P(cast, PM_<%= node.flags.human.upcase %>_<%= value.name %>)) {
|
309
|
+
if (flags != 0) pm_buffer_append_byte(buffer, ',');
|
310
|
+
pm_buffer_append_string(buffer, "\"<%= value.name %>\"", <%= value.name.bytesize + 2 %>);
|
311
|
+
flags++;
|
312
|
+
}
|
313
|
+
<%- end -%>
|
314
|
+
pm_buffer_append_byte(buffer, ']');
|
315
|
+
<%- when Prism::Template::IntegerField -%>
|
316
|
+
pm_integer_string(buffer, &cast-><%= field.name %>);
|
317
|
+
<%- when Prism::Template::DoubleField -%>
|
318
|
+
pm_buffer_append_format(buffer, "%f", cast-><%= field.name %>);
|
319
|
+
<%- else -%>
|
320
|
+
<%- raise %>
|
321
|
+
<%- end -%>
|
322
|
+
<%- end -%>
|
323
|
+
|
324
|
+
pm_buffer_append_byte(buffer, '}');
|
325
|
+
break;
|
326
|
+
}
|
327
|
+
<%- end -%>
|
328
|
+
case PM_SCOPE_NODE:
|
329
|
+
break;
|
330
|
+
}
|
331
|
+
}
|
332
|
+
|
333
|
+
#endif
|
@@ -0,0 +1,166 @@
|
|
1
|
+
<%# encoding: ASCII -%>
|
2
|
+
#include "prism/prettyprint.h"
|
3
|
+
|
4
|
+
// We optionally support pretty printing nodes. For systems that don't want or
|
5
|
+
// need this functionality, it can be turned off with the
|
6
|
+
// PRISM_EXCLUDE_PRETTYPRINT define.
|
7
|
+
#ifdef PRISM_EXCLUDE_PRETTYPRINT
|
8
|
+
|
9
|
+
void pm_prettyprint(void) {}
|
10
|
+
|
11
|
+
#else
|
12
|
+
|
13
|
+
static inline void
|
14
|
+
prettyprint_location(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm_location_t *location) {
|
15
|
+
pm_line_column_t start = pm_newline_list_line_column(&parser->newline_list, location->start, parser->start_line);
|
16
|
+
pm_line_column_t end = pm_newline_list_line_column(&parser->newline_list, location->end, parser->start_line);
|
17
|
+
pm_buffer_append_format(output_buffer, "(%" PRIi32 ",%" PRIu32 ")-(%" PRIi32 ",%" PRIu32 ")", start.line, start.column, end.line, end.column);
|
18
|
+
}
|
19
|
+
|
20
|
+
static inline void
|
21
|
+
prettyprint_constant(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm_constant_id_t constant_id) {
|
22
|
+
pm_constant_t *constant = pm_constant_pool_id_to_constant(&parser->constant_pool, constant_id);
|
23
|
+
pm_buffer_append_format(output_buffer, ":%.*s", (int) constant->length, constant->start);
|
24
|
+
}
|
25
|
+
|
26
|
+
static void
|
27
|
+
prettyprint_node(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm_node_t *node, pm_buffer_t *prefix_buffer) {
|
28
|
+
switch (PM_NODE_TYPE(node)) {
|
29
|
+
case PM_SCOPE_NODE:
|
30
|
+
// We do not need to print a ScopeNode as it's not part of the AST.
|
31
|
+
return;
|
32
|
+
<%- nodes.each do |node| -%>
|
33
|
+
case <%= node.type %>: {
|
34
|
+
<%- if !node.flags.nil? || node.fields.any? -%>
|
35
|
+
pm_<%= node.human %>_t *cast = (pm_<%= node.human %>_t *) node;
|
36
|
+
<%- end -%>
|
37
|
+
pm_buffer_append_string(output_buffer, "@ <%= node.name %> (location: ", <%= node.name.length + 14 %>);
|
38
|
+
prettyprint_location(output_buffer, parser, &node->location);
|
39
|
+
pm_buffer_append_string(output_buffer, ")\n", 2);
|
40
|
+
<%- (fields = [*node.flags, *node.fields]).each_with_index do |field, index| -%>
|
41
|
+
<%- preadd = index == fields.length - 1 ? " " : "| " -%>
|
42
|
+
|
43
|
+
// <%= field.name %>
|
44
|
+
{
|
45
|
+
pm_buffer_concat(output_buffer, prefix_buffer);
|
46
|
+
pm_buffer_append_string(output_buffer, "+-- <%= field.name %>:", <%= 4 + field.name.length + 1 %>);
|
47
|
+
<%- case field -%>
|
48
|
+
<%- when Prism::Template::NodeField -%>
|
49
|
+
pm_buffer_append_byte(output_buffer, '\n');
|
50
|
+
|
51
|
+
size_t prefix_length = prefix_buffer->length;
|
52
|
+
pm_buffer_append_string(prefix_buffer, "<%= preadd %>", 4);
|
53
|
+
pm_buffer_concat(output_buffer, prefix_buffer);
|
54
|
+
prettyprint_node(output_buffer, parser, (pm_node_t *) cast-><%= field.name %>, prefix_buffer);
|
55
|
+
prefix_buffer->length = prefix_length;
|
56
|
+
<%- when Prism::Template::OptionalNodeField -%>
|
57
|
+
if (cast-><%= field.name %> == NULL) {
|
58
|
+
pm_buffer_append_string(output_buffer, " nil\n", 5);
|
59
|
+
} else {
|
60
|
+
pm_buffer_append_byte(output_buffer, '\n');
|
61
|
+
|
62
|
+
size_t prefix_length = prefix_buffer->length;
|
63
|
+
pm_buffer_append_string(prefix_buffer, "<%= preadd %>", 4);
|
64
|
+
pm_buffer_concat(output_buffer, prefix_buffer);
|
65
|
+
prettyprint_node(output_buffer, parser, (pm_node_t *) cast-><%= field.name %>, prefix_buffer);
|
66
|
+
prefix_buffer->length = prefix_length;
|
67
|
+
}
|
68
|
+
<%- when Prism::Template::StringField -%>
|
69
|
+
pm_buffer_append_string(output_buffer, " \"", 2);
|
70
|
+
pm_buffer_append_source(output_buffer, pm_string_source(&cast-><%= field.name %>), pm_string_length(&cast-><%= field.name %>), PM_BUFFER_ESCAPING_RUBY);
|
71
|
+
pm_buffer_append_string(output_buffer, "\"\n", 2);
|
72
|
+
<%- when Prism::Template::NodeListField -%>
|
73
|
+
pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast-><%= field.name %>.size));
|
74
|
+
|
75
|
+
size_t last_index = cast-><%= field.name %>.size;
|
76
|
+
for (uint32_t index = 0; index < last_index; index++) {
|
77
|
+
size_t prefix_length = prefix_buffer->length;
|
78
|
+
pm_buffer_append_string(prefix_buffer, "<%= preadd %>", 4);
|
79
|
+
pm_buffer_concat(output_buffer, prefix_buffer);
|
80
|
+
pm_buffer_append_string(output_buffer, "+-- ", 4);
|
81
|
+
pm_buffer_append_string(prefix_buffer, (index == last_index - 1) ? " " : "| ", 4);
|
82
|
+
prettyprint_node(output_buffer, parser, (pm_node_t *) cast-><%= field.name %>.nodes[index], prefix_buffer);
|
83
|
+
prefix_buffer->length = prefix_length;
|
84
|
+
}
|
85
|
+
<%- when Prism::Template::ConstantField -%>
|
86
|
+
pm_buffer_append_byte(output_buffer, ' ');
|
87
|
+
prettyprint_constant(output_buffer, parser, cast-><%= field.name %>);
|
88
|
+
pm_buffer_append_byte(output_buffer, '\n');
|
89
|
+
<%- when Prism::Template::OptionalConstantField -%>
|
90
|
+
if (cast-><%= field.name %> == 0) {
|
91
|
+
pm_buffer_append_string(output_buffer, " nil\n", 5);
|
92
|
+
} else {
|
93
|
+
pm_buffer_append_byte(output_buffer, ' ');
|
94
|
+
prettyprint_constant(output_buffer, parser, cast-><%= field.name %>);
|
95
|
+
pm_buffer_append_byte(output_buffer, '\n');
|
96
|
+
}
|
97
|
+
<%- when Prism::Template::ConstantListField -%>
|
98
|
+
pm_buffer_append_string(output_buffer, " [", 2);
|
99
|
+
for (uint32_t index = 0; index < cast-><%= field.name %>.size; index++) {
|
100
|
+
if (index != 0) pm_buffer_append_string(output_buffer, ", ", 2);
|
101
|
+
prettyprint_constant(output_buffer, parser, cast-><%= field.name %>.ids[index]);
|
102
|
+
}
|
103
|
+
pm_buffer_append_string(output_buffer, "]\n", 2);
|
104
|
+
<%- when Prism::Template::LocationField -%>
|
105
|
+
pm_location_t *location = &cast-><%= field.name %>;
|
106
|
+
pm_buffer_append_byte(output_buffer, ' ');
|
107
|
+
prettyprint_location(output_buffer, parser, location);
|
108
|
+
pm_buffer_append_string(output_buffer, " = \"", 4);
|
109
|
+
pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY);
|
110
|
+
pm_buffer_append_string(output_buffer, "\"\n", 2);
|
111
|
+
<%- when Prism::Template::OptionalLocationField -%>
|
112
|
+
pm_location_t *location = &cast-><%= field.name %>;
|
113
|
+
if (location->start == NULL) {
|
114
|
+
pm_buffer_append_string(output_buffer, " nil\n", 5);
|
115
|
+
} else {
|
116
|
+
pm_buffer_append_byte(output_buffer, ' ');
|
117
|
+
prettyprint_location(output_buffer, parser, location);
|
118
|
+
pm_buffer_append_string(output_buffer, " = \"", 4);
|
119
|
+
pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY);
|
120
|
+
pm_buffer_append_string(output_buffer, "\"\n", 2);
|
121
|
+
}
|
122
|
+
<%- when Prism::Template::UInt8Field -%>
|
123
|
+
pm_buffer_append_format(output_buffer, " %" PRIu8 "\n", cast-><%= field.name %>);
|
124
|
+
<%- when Prism::Template::UInt32Field -%>
|
125
|
+
pm_buffer_append_format(output_buffer, " %" PRIu32 "\n", cast-><%= field.name %>);
|
126
|
+
<%- when Prism::Template::Flags -%>
|
127
|
+
bool found = false;
|
128
|
+
<%- field.values.each do |value| -%>
|
129
|
+
if (cast->base.flags & PM_<%= field.human.upcase %>_<%= value.name %>) {
|
130
|
+
if (found) pm_buffer_append_byte(output_buffer, ',');
|
131
|
+
pm_buffer_append_string(output_buffer, " <%= value.name.downcase %>", <%= value.name.bytesize + 1 %>);
|
132
|
+
found = true;
|
133
|
+
}
|
134
|
+
<%- end -%>
|
135
|
+
if (!found) pm_buffer_append_string(output_buffer, " nil", 4);
|
136
|
+
pm_buffer_append_byte(output_buffer, '\n');
|
137
|
+
<%- when Prism::Template::IntegerField -%>
|
138
|
+
const pm_integer_t *integer = &cast-><%= field.name %>;
|
139
|
+
pm_buffer_append_byte(output_buffer, ' ');
|
140
|
+
pm_integer_string(output_buffer, integer);
|
141
|
+
pm_buffer_append_byte(output_buffer, '\n');
|
142
|
+
<%- when Prism::Template::DoubleField -%>
|
143
|
+
pm_buffer_append_format(output_buffer, " %f\n", cast-><%= field.name %>);
|
144
|
+
<%- else -%>
|
145
|
+
<%- raise -%>
|
146
|
+
<%- end -%>
|
147
|
+
}
|
148
|
+
<%- end -%>
|
149
|
+
|
150
|
+
break;
|
151
|
+
}
|
152
|
+
<%- end -%>
|
153
|
+
}
|
154
|
+
}
|
155
|
+
|
156
|
+
/**
|
157
|
+
* Pretty-prints the AST represented by the given node to the given buffer.
|
158
|
+
*/
|
159
|
+
PRISM_EXPORTED_FUNCTION void
|
160
|
+
pm_prettyprint(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm_node_t *node) {
|
161
|
+
pm_buffer_t prefix_buffer = { 0 };
|
162
|
+
prettyprint_node(output_buffer, parser, node, &prefix_buffer);
|
163
|
+
pm_buffer_free(&prefix_buffer);
|
164
|
+
}
|
165
|
+
|
166
|
+
#endif
|