@herb-tools/node 0.1.1 → 0.3.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 (61) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/bin/vendor.cjs +103 -0
  3. package/dist/herb-node.esm.js +1 -1
  4. package/extension/extension_helpers.cpp +2 -3
  5. package/extension/herb.cpp +9 -0
  6. package/extension/libherb/analyze.c +138 -43
  7. package/extension/libherb/analyze.h +39 -0
  8. package/extension/libherb/analyze_helpers.c +44 -1
  9. package/extension/libherb/analyze_helpers.h +49 -0
  10. package/extension/libherb/analyzed_ruby.c +10 -1
  11. package/extension/libherb/analyzed_ruby.h +36 -0
  12. package/extension/libherb/array.h +33 -0
  13. package/extension/libherb/ast_node.h +35 -0
  14. package/extension/libherb/ast_nodes.c +103 -1
  15. package/extension/libherb/ast_nodes.h +335 -0
  16. package/extension/libherb/ast_pretty_print.c +60 -0
  17. package/extension/libherb/ast_pretty_print.h +17 -0
  18. package/extension/libherb/buffer.c +60 -27
  19. package/extension/libherb/buffer.h +39 -0
  20. package/extension/libherb/errors.h +125 -0
  21. package/extension/libherb/extract.c +57 -20
  22. package/extension/libherb/extract.h +20 -0
  23. package/extension/libherb/herb.h +32 -0
  24. package/extension/libherb/html_util.h +13 -0
  25. package/extension/libherb/include/analyze.h +3 -0
  26. package/extension/libherb/include/analyze_helpers.h +6 -0
  27. package/extension/libherb/include/analyzed_ruby.h +3 -0
  28. package/extension/libherb/include/ast_nodes.h +32 -0
  29. package/extension/libherb/include/buffer.h +5 -2
  30. package/extension/libherb/include/lexer_peek_helpers.h +2 -2
  31. package/extension/libherb/include/macros.h +2 -2
  32. package/extension/libherb/include/version.h +1 -1
  33. package/extension/libherb/io.h +9 -0
  34. package/extension/libherb/json.h +28 -0
  35. package/extension/libherb/lexer.c +1 -1
  36. package/extension/libherb/lexer.h +13 -0
  37. package/extension/libherb/lexer_peek_helpers.h +23 -0
  38. package/extension/libherb/lexer_struct.h +32 -0
  39. package/extension/libherb/location.h +25 -0
  40. package/extension/libherb/macros.h +10 -0
  41. package/extension/libherb/memory.h +12 -0
  42. package/extension/libherb/parser.c +17 -7
  43. package/extension/libherb/parser.h +22 -0
  44. package/extension/libherb/parser_helpers.h +33 -0
  45. package/extension/libherb/position.h +22 -0
  46. package/extension/libherb/pretty_print.h +53 -0
  47. package/extension/libherb/prism_helpers.h +18 -0
  48. package/extension/libherb/range.h +23 -0
  49. package/extension/libherb/ruby_parser.h +6 -0
  50. package/extension/libherb/token.c +1 -1
  51. package/extension/libherb/token.h +25 -0
  52. package/extension/libherb/token_matchers.h +21 -0
  53. package/extension/libherb/token_struct.h +51 -0
  54. package/extension/libherb/util.c +3 -1
  55. package/extension/libherb/util.h +25 -0
  56. package/extension/libherb/version.h +6 -0
  57. package/extension/libherb/visitor.c +36 -0
  58. package/extension/libherb/visitor.h +11 -0
  59. package/extension/nodes.cpp +117 -0
  60. package/extension/nodes.h +3 -0
  61. package/package.json +12 -20
@@ -0,0 +1,335 @@
1
+ // NOTE: This file is generated by the templates/template.rb script and should not
2
+ // be modified manually. See /Users/marcoroth/Development/herb-release/templates/src/include/ast_nodes.h.erb
3
+
4
+ #ifndef HERB_AST_NODES_H
5
+ #define HERB_AST_NODES_H
6
+
7
+ #include <stdbool.h>
8
+ #include <prism.h>
9
+
10
+ #include "array.h"
11
+ #include "buffer.h"
12
+ #include "position.h"
13
+ #include "location.h"
14
+ #include "token_struct.h"
15
+ #include "analyzed_ruby.h"
16
+
17
+ typedef enum {
18
+ AST_DOCUMENT_NODE,
19
+ AST_LITERAL_NODE,
20
+ AST_HTML_OPEN_TAG_NODE,
21
+ AST_HTML_CLOSE_TAG_NODE,
22
+ AST_HTML_SELF_CLOSE_TAG_NODE,
23
+ AST_HTML_ELEMENT_NODE,
24
+ AST_HTML_ATTRIBUTE_VALUE_NODE,
25
+ AST_HTML_ATTRIBUTE_NAME_NODE,
26
+ AST_HTML_ATTRIBUTE_NODE,
27
+ AST_HTML_TEXT_NODE,
28
+ AST_HTML_COMMENT_NODE,
29
+ AST_HTML_DOCTYPE_NODE,
30
+ AST_WHITESPACE_NODE,
31
+ AST_ERB_CONTENT_NODE,
32
+ AST_ERB_END_NODE,
33
+ AST_ERB_ELSE_NODE,
34
+ AST_ERB_IF_NODE,
35
+ AST_ERB_BLOCK_NODE,
36
+ AST_ERB_WHEN_NODE,
37
+ AST_ERB_CASE_NODE,
38
+ AST_ERB_CASE_MATCH_NODE,
39
+ AST_ERB_WHILE_NODE,
40
+ AST_ERB_UNTIL_NODE,
41
+ AST_ERB_FOR_NODE,
42
+ AST_ERB_RESCUE_NODE,
43
+ AST_ERB_ENSURE_NODE,
44
+ AST_ERB_BEGIN_NODE,
45
+ AST_ERB_UNLESS_NODE,
46
+ AST_ERB_YIELD_NODE,
47
+ AST_ERB_IN_NODE,
48
+ } ast_node_type_T;
49
+
50
+ typedef struct AST_NODE_STRUCT {
51
+ ast_node_type_T type;
52
+ location_T* location;
53
+ // maybe a range too?
54
+ array_T* errors;
55
+ } AST_NODE_T;
56
+
57
+
58
+ typedef struct AST_DOCUMENT_NODE_STRUCT {
59
+ AST_NODE_T base;
60
+ array_T* children;
61
+ } AST_DOCUMENT_NODE_T;
62
+
63
+ typedef struct AST_LITERAL_NODE_STRUCT {
64
+ AST_NODE_T base;
65
+ const char* content;
66
+ } AST_LITERAL_NODE_T;
67
+
68
+ typedef struct AST_HTML_OPEN_TAG_NODE_STRUCT {
69
+ AST_NODE_T base;
70
+ token_T* tag_opening;
71
+ token_T* tag_name;
72
+ token_T* tag_closing;
73
+ array_T* children;
74
+ bool is_void;
75
+ } AST_HTML_OPEN_TAG_NODE_T;
76
+
77
+ typedef struct AST_HTML_CLOSE_TAG_NODE_STRUCT {
78
+ AST_NODE_T base;
79
+ token_T* tag_opening;
80
+ token_T* tag_name;
81
+ token_T* tag_closing;
82
+ } AST_HTML_CLOSE_TAG_NODE_T;
83
+
84
+ typedef struct AST_HTML_SELF_CLOSE_TAG_NODE_STRUCT {
85
+ AST_NODE_T base;
86
+ token_T* tag_opening;
87
+ token_T* tag_name;
88
+ array_T* attributes;
89
+ token_T* tag_closing;
90
+ bool is_void;
91
+ } AST_HTML_SELF_CLOSE_TAG_NODE_T;
92
+
93
+ typedef struct AST_HTML_ELEMENT_NODE_STRUCT {
94
+ AST_NODE_T base;
95
+ struct AST_HTML_OPEN_TAG_NODE_STRUCT* open_tag;
96
+ token_T* tag_name;
97
+ array_T* body;
98
+ struct AST_HTML_CLOSE_TAG_NODE_STRUCT* close_tag;
99
+ bool is_void;
100
+ } AST_HTML_ELEMENT_NODE_T;
101
+
102
+ typedef struct AST_HTML_ATTRIBUTE_VALUE_NODE_STRUCT {
103
+ AST_NODE_T base;
104
+ token_T* open_quote;
105
+ array_T* children;
106
+ token_T* close_quote;
107
+ bool quoted;
108
+ } AST_HTML_ATTRIBUTE_VALUE_NODE_T;
109
+
110
+ typedef struct AST_HTML_ATTRIBUTE_NAME_NODE_STRUCT {
111
+ AST_NODE_T base;
112
+ token_T* name;
113
+ } AST_HTML_ATTRIBUTE_NAME_NODE_T;
114
+
115
+ typedef struct AST_HTML_ATTRIBUTE_NODE_STRUCT {
116
+ AST_NODE_T base;
117
+ struct AST_HTML_ATTRIBUTE_NAME_NODE_STRUCT* name;
118
+ token_T* equals;
119
+ struct AST_HTML_ATTRIBUTE_VALUE_NODE_STRUCT* value;
120
+ } AST_HTML_ATTRIBUTE_NODE_T;
121
+
122
+ typedef struct AST_HTML_TEXT_NODE_STRUCT {
123
+ AST_NODE_T base;
124
+ const char* content;
125
+ } AST_HTML_TEXT_NODE_T;
126
+
127
+ typedef struct AST_HTML_COMMENT_NODE_STRUCT {
128
+ AST_NODE_T base;
129
+ token_T* comment_start;
130
+ array_T* children;
131
+ token_T* comment_end;
132
+ } AST_HTML_COMMENT_NODE_T;
133
+
134
+ typedef struct AST_HTML_DOCTYPE_NODE_STRUCT {
135
+ AST_NODE_T base;
136
+ token_T* tag_opening;
137
+ array_T* children;
138
+ token_T* tag_closing;
139
+ } AST_HTML_DOCTYPE_NODE_T;
140
+
141
+ typedef struct AST_WHITESPACE_NODE_STRUCT {
142
+ AST_NODE_T base;
143
+ token_T* value;
144
+ } AST_WHITESPACE_NODE_T;
145
+
146
+ typedef struct AST_ERB_CONTENT_NODE_STRUCT {
147
+ AST_NODE_T base;
148
+ token_T* tag_opening;
149
+ token_T* content;
150
+ token_T* tag_closing;
151
+ analyzed_ruby_T* analyzed_ruby;
152
+ bool parsed;
153
+ bool valid;
154
+ } AST_ERB_CONTENT_NODE_T;
155
+
156
+ typedef struct AST_ERB_END_NODE_STRUCT {
157
+ AST_NODE_T base;
158
+ token_T* tag_opening;
159
+ token_T* content;
160
+ token_T* tag_closing;
161
+ } AST_ERB_END_NODE_T;
162
+
163
+ typedef struct AST_ERB_ELSE_NODE_STRUCT {
164
+ AST_NODE_T base;
165
+ token_T* tag_opening;
166
+ token_T* content;
167
+ token_T* tag_closing;
168
+ array_T* statements;
169
+ } AST_ERB_ELSE_NODE_T;
170
+
171
+ typedef struct AST_ERB_IF_NODE_STRUCT {
172
+ AST_NODE_T base;
173
+ token_T* tag_opening;
174
+ token_T* content;
175
+ token_T* tag_closing;
176
+ array_T* statements;
177
+ AST_NODE_T* subsequent;
178
+ struct AST_ERB_END_NODE_STRUCT* end_node;
179
+ } AST_ERB_IF_NODE_T;
180
+
181
+ typedef struct AST_ERB_BLOCK_NODE_STRUCT {
182
+ AST_NODE_T base;
183
+ token_T* tag_opening;
184
+ token_T* content;
185
+ token_T* tag_closing;
186
+ array_T* body;
187
+ struct AST_ERB_END_NODE_STRUCT* end_node;
188
+ } AST_ERB_BLOCK_NODE_T;
189
+
190
+ typedef struct AST_ERB_WHEN_NODE_STRUCT {
191
+ AST_NODE_T base;
192
+ token_T* tag_opening;
193
+ token_T* content;
194
+ token_T* tag_closing;
195
+ array_T* statements;
196
+ } AST_ERB_WHEN_NODE_T;
197
+
198
+ typedef struct AST_ERB_CASE_NODE_STRUCT {
199
+ AST_NODE_T base;
200
+ token_T* tag_opening;
201
+ token_T* content;
202
+ token_T* tag_closing;
203
+ array_T* children;
204
+ array_T* conditions;
205
+ struct AST_ERB_ELSE_NODE_STRUCT* else_clause;
206
+ struct AST_ERB_END_NODE_STRUCT* end_node;
207
+ } AST_ERB_CASE_NODE_T;
208
+
209
+ typedef struct AST_ERB_CASE_MATCH_NODE_STRUCT {
210
+ AST_NODE_T base;
211
+ token_T* tag_opening;
212
+ token_T* content;
213
+ token_T* tag_closing;
214
+ array_T* children;
215
+ array_T* conditions;
216
+ struct AST_ERB_ELSE_NODE_STRUCT* else_clause;
217
+ struct AST_ERB_END_NODE_STRUCT* end_node;
218
+ } AST_ERB_CASE_MATCH_NODE_T;
219
+
220
+ typedef struct AST_ERB_WHILE_NODE_STRUCT {
221
+ AST_NODE_T base;
222
+ token_T* tag_opening;
223
+ token_T* content;
224
+ token_T* tag_closing;
225
+ array_T* statements;
226
+ struct AST_ERB_END_NODE_STRUCT* end_node;
227
+ } AST_ERB_WHILE_NODE_T;
228
+
229
+ typedef struct AST_ERB_UNTIL_NODE_STRUCT {
230
+ AST_NODE_T base;
231
+ token_T* tag_opening;
232
+ token_T* content;
233
+ token_T* tag_closing;
234
+ array_T* statements;
235
+ struct AST_ERB_END_NODE_STRUCT* end_node;
236
+ } AST_ERB_UNTIL_NODE_T;
237
+
238
+ typedef struct AST_ERB_FOR_NODE_STRUCT {
239
+ AST_NODE_T base;
240
+ token_T* tag_opening;
241
+ token_T* content;
242
+ token_T* tag_closing;
243
+ array_T* statements;
244
+ struct AST_ERB_END_NODE_STRUCT* end_node;
245
+ } AST_ERB_FOR_NODE_T;
246
+
247
+ typedef struct AST_ERB_RESCUE_NODE_STRUCT {
248
+ AST_NODE_T base;
249
+ token_T* tag_opening;
250
+ token_T* content;
251
+ token_T* tag_closing;
252
+ array_T* statements;
253
+ struct AST_ERB_RESCUE_NODE_STRUCT* subsequent;
254
+ } AST_ERB_RESCUE_NODE_T;
255
+
256
+ typedef struct AST_ERB_ENSURE_NODE_STRUCT {
257
+ AST_NODE_T base;
258
+ token_T* tag_opening;
259
+ token_T* content;
260
+ token_T* tag_closing;
261
+ array_T* statements;
262
+ } AST_ERB_ENSURE_NODE_T;
263
+
264
+ typedef struct AST_ERB_BEGIN_NODE_STRUCT {
265
+ AST_NODE_T base;
266
+ token_T* tag_opening;
267
+ token_T* content;
268
+ token_T* tag_closing;
269
+ array_T* statements;
270
+ struct AST_ERB_RESCUE_NODE_STRUCT* rescue_clause;
271
+ struct AST_ERB_ELSE_NODE_STRUCT* else_clause;
272
+ struct AST_ERB_ENSURE_NODE_STRUCT* ensure_clause;
273
+ struct AST_ERB_END_NODE_STRUCT* end_node;
274
+ } AST_ERB_BEGIN_NODE_T;
275
+
276
+ typedef struct AST_ERB_UNLESS_NODE_STRUCT {
277
+ AST_NODE_T base;
278
+ token_T* tag_opening;
279
+ token_T* content;
280
+ token_T* tag_closing;
281
+ array_T* statements;
282
+ struct AST_ERB_ELSE_NODE_STRUCT* else_clause;
283
+ struct AST_ERB_END_NODE_STRUCT* end_node;
284
+ } AST_ERB_UNLESS_NODE_T;
285
+
286
+ typedef struct AST_ERB_YIELD_NODE_STRUCT {
287
+ AST_NODE_T base;
288
+ token_T* tag_opening;
289
+ token_T* content;
290
+ token_T* tag_closing;
291
+ } AST_ERB_YIELD_NODE_T;
292
+
293
+ typedef struct AST_ERB_IN_NODE_STRUCT {
294
+ AST_NODE_T base;
295
+ token_T* tag_opening;
296
+ token_T* content;
297
+ token_T* tag_closing;
298
+ array_T* statements;
299
+ } AST_ERB_IN_NODE_T;
300
+
301
+ AST_DOCUMENT_NODE_T* ast_document_node_init(array_T* children, position_T* start_position, position_T* end_position, array_T* errors);
302
+ AST_LITERAL_NODE_T* ast_literal_node_init(const char* content, position_T* start_position, position_T* end_position, array_T* errors);
303
+ AST_HTML_OPEN_TAG_NODE_T* ast_html_open_tag_node_init(token_T* tag_opening, token_T* tag_name, token_T* tag_closing, array_T* children, bool is_void, position_T* start_position, position_T* end_position, array_T* errors);
304
+ AST_HTML_CLOSE_TAG_NODE_T* ast_html_close_tag_node_init(token_T* tag_opening, token_T* tag_name, token_T* tag_closing, position_T* start_position, position_T* end_position, array_T* errors);
305
+ AST_HTML_SELF_CLOSE_TAG_NODE_T* ast_html_self_close_tag_node_init(token_T* tag_opening, token_T* tag_name, array_T* attributes, token_T* tag_closing, bool is_void, position_T* start_position, position_T* end_position, array_T* errors);
306
+ AST_HTML_ELEMENT_NODE_T* ast_html_element_node_init(struct AST_HTML_OPEN_TAG_NODE_STRUCT* open_tag, token_T* tag_name, array_T* body, struct AST_HTML_CLOSE_TAG_NODE_STRUCT* close_tag, bool is_void, position_T* start_position, position_T* end_position, array_T* errors);
307
+ AST_HTML_ATTRIBUTE_VALUE_NODE_T* ast_html_attribute_value_node_init(token_T* open_quote, array_T* children, token_T* close_quote, bool quoted, position_T* start_position, position_T* end_position, array_T* errors);
308
+ AST_HTML_ATTRIBUTE_NAME_NODE_T* ast_html_attribute_name_node_init(token_T* name, position_T* start_position, position_T* end_position, array_T* errors);
309
+ AST_HTML_ATTRIBUTE_NODE_T* ast_html_attribute_node_init(struct AST_HTML_ATTRIBUTE_NAME_NODE_STRUCT* name, token_T* equals, struct AST_HTML_ATTRIBUTE_VALUE_NODE_STRUCT* value, position_T* start_position, position_T* end_position, array_T* errors);
310
+ AST_HTML_TEXT_NODE_T* ast_html_text_node_init(const char* content, position_T* start_position, position_T* end_position, array_T* errors);
311
+ AST_HTML_COMMENT_NODE_T* ast_html_comment_node_init(token_T* comment_start, array_T* children, token_T* comment_end, position_T* start_position, position_T* end_position, array_T* errors);
312
+ AST_HTML_DOCTYPE_NODE_T* ast_html_doctype_node_init(token_T* tag_opening, array_T* children, token_T* tag_closing, position_T* start_position, position_T* end_position, array_T* errors);
313
+ AST_WHITESPACE_NODE_T* ast_whitespace_node_init(token_T* value, position_T* start_position, position_T* end_position, array_T* errors);
314
+ AST_ERB_CONTENT_NODE_T* ast_erb_content_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, analyzed_ruby_T* analyzed_ruby, bool parsed, bool valid, position_T* start_position, position_T* end_position, array_T* errors);
315
+ AST_ERB_END_NODE_T* ast_erb_end_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, position_T* start_position, position_T* end_position, array_T* errors);
316
+ AST_ERB_ELSE_NODE_T* ast_erb_else_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, array_T* statements, position_T* start_position, position_T* end_position, array_T* errors);
317
+ AST_ERB_IF_NODE_T* ast_erb_if_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, array_T* statements, AST_NODE_T* subsequent, struct AST_ERB_END_NODE_STRUCT* end_node, position_T* start_position, position_T* end_position, array_T* errors);
318
+ AST_ERB_BLOCK_NODE_T* ast_erb_block_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, array_T* body, struct AST_ERB_END_NODE_STRUCT* end_node, position_T* start_position, position_T* end_position, array_T* errors);
319
+ AST_ERB_WHEN_NODE_T* ast_erb_when_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, array_T* statements, position_T* start_position, position_T* end_position, array_T* errors);
320
+ AST_ERB_CASE_NODE_T* ast_erb_case_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, array_T* children, array_T* conditions, struct AST_ERB_ELSE_NODE_STRUCT* else_clause, struct AST_ERB_END_NODE_STRUCT* end_node, position_T* start_position, position_T* end_position, array_T* errors);
321
+ AST_ERB_CASE_MATCH_NODE_T* ast_erb_case_match_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, array_T* children, array_T* conditions, struct AST_ERB_ELSE_NODE_STRUCT* else_clause, struct AST_ERB_END_NODE_STRUCT* end_node, position_T* start_position, position_T* end_position, array_T* errors);
322
+ AST_ERB_WHILE_NODE_T* ast_erb_while_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, array_T* statements, struct AST_ERB_END_NODE_STRUCT* end_node, position_T* start_position, position_T* end_position, array_T* errors);
323
+ AST_ERB_UNTIL_NODE_T* ast_erb_until_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, array_T* statements, struct AST_ERB_END_NODE_STRUCT* end_node, position_T* start_position, position_T* end_position, array_T* errors);
324
+ AST_ERB_FOR_NODE_T* ast_erb_for_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, array_T* statements, struct AST_ERB_END_NODE_STRUCT* end_node, position_T* start_position, position_T* end_position, array_T* errors);
325
+ AST_ERB_RESCUE_NODE_T* ast_erb_rescue_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, array_T* statements, struct AST_ERB_RESCUE_NODE_STRUCT* subsequent, position_T* start_position, position_T* end_position, array_T* errors);
326
+ AST_ERB_ENSURE_NODE_T* ast_erb_ensure_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, array_T* statements, position_T* start_position, position_T* end_position, array_T* errors);
327
+ AST_ERB_BEGIN_NODE_T* ast_erb_begin_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, array_T* statements, struct AST_ERB_RESCUE_NODE_STRUCT* rescue_clause, struct AST_ERB_ELSE_NODE_STRUCT* else_clause, struct AST_ERB_ENSURE_NODE_STRUCT* ensure_clause, struct AST_ERB_END_NODE_STRUCT* end_node, position_T* start_position, position_T* end_position, array_T* errors);
328
+ AST_ERB_UNLESS_NODE_T* ast_erb_unless_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, array_T* statements, struct AST_ERB_ELSE_NODE_STRUCT* else_clause, struct AST_ERB_END_NODE_STRUCT* end_node, position_T* start_position, position_T* end_position, array_T* errors);
329
+ AST_ERB_YIELD_NODE_T* ast_erb_yield_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, position_T* start_position, position_T* end_position, array_T* errors);
330
+ AST_ERB_IN_NODE_T* ast_erb_in_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, array_T* statements, position_T* start_position, position_T* end_position, array_T* errors);
331
+
332
+ const char* ast_node_type_to_string(AST_NODE_T* node);
333
+ const char* ast_node_human_type(AST_NODE_T* node);
334
+
335
+ #endif
@@ -364,6 +364,47 @@ void ast_pretty_print_node(AST_NODE_T* node, const size_t indent, const size_t r
364
364
 
365
365
  } break;
366
366
 
367
+ case AST_ERB_CASE_MATCH_NODE: {
368
+ const AST_ERB_CASE_MATCH_NODE_T* erb_case_match_node = (AST_ERB_CASE_MATCH_NODE_T*) node;
369
+
370
+ pretty_print_errors(node, indent, relative_indent, false, buffer);
371
+ pretty_print_token_property(erb_case_match_node->tag_opening, "tag_opening", indent, relative_indent, false, buffer);
372
+ pretty_print_token_property(erb_case_match_node->content, "content", indent, relative_indent, false, buffer);
373
+ pretty_print_token_property(erb_case_match_node->tag_closing, "tag_closing", indent, relative_indent, false, buffer);
374
+ pretty_print_array("children", erb_case_match_node->children, indent, relative_indent, false, buffer);
375
+ pretty_print_array("conditions", erb_case_match_node->conditions, indent, relative_indent, false, buffer);
376
+
377
+ pretty_print_label("else_clause", indent, relative_indent, false, buffer);
378
+
379
+ if (erb_case_match_node->else_clause) {
380
+ buffer_append(buffer, "\n");
381
+ pretty_print_indent(buffer, indent);
382
+ pretty_print_indent(buffer, relative_indent + 1);
383
+
384
+ buffer_append(buffer, "└── ");
385
+ ast_pretty_print_node((AST_NODE_T*) erb_case_match_node->else_clause, indent, relative_indent + 2, buffer);
386
+ } else {
387
+ buffer_append(buffer, " ∅\n");
388
+ }
389
+ buffer_append(buffer, "\n");
390
+
391
+
392
+ pretty_print_label("end_node", indent, relative_indent, true, buffer);
393
+
394
+ if (erb_case_match_node->end_node) {
395
+ buffer_append(buffer, "\n");
396
+ pretty_print_indent(buffer, indent);
397
+ pretty_print_indent(buffer, relative_indent + 1);
398
+
399
+ buffer_append(buffer, "└── ");
400
+ ast_pretty_print_node((AST_NODE_T*) erb_case_match_node->end_node, indent, relative_indent + 2, buffer);
401
+ } else {
402
+ buffer_append(buffer, " ∅\n");
403
+ }
404
+ buffer_append(buffer, "\n");
405
+
406
+ } break;
407
+
367
408
  case AST_ERB_WHILE_NODE: {
368
409
  const AST_ERB_WHILE_NODE_T* erb_while_node = (AST_ERB_WHILE_NODE_T*) node;
369
410
 
@@ -584,5 +625,24 @@ void ast_pretty_print_node(AST_NODE_T* node, const size_t indent, const size_t r
584
625
 
585
626
  } break;
586
627
 
628
+ case AST_ERB_YIELD_NODE: {
629
+ const AST_ERB_YIELD_NODE_T* erb_yield_node = (AST_ERB_YIELD_NODE_T*) node;
630
+
631
+ pretty_print_errors(node, indent, relative_indent, false, buffer);
632
+ pretty_print_token_property(erb_yield_node->tag_opening, "tag_opening", indent, relative_indent, false, buffer);
633
+ pretty_print_token_property(erb_yield_node->content, "content", indent, relative_indent, false, buffer);
634
+ pretty_print_token_property(erb_yield_node->tag_closing, "tag_closing", indent, relative_indent, true, buffer);
635
+ } break;
636
+
637
+ case AST_ERB_IN_NODE: {
638
+ const AST_ERB_IN_NODE_T* erb_in_node = (AST_ERB_IN_NODE_T*) node;
639
+
640
+ pretty_print_errors(node, indent, relative_indent, false, buffer);
641
+ pretty_print_token_property(erb_in_node->tag_opening, "tag_opening", indent, relative_indent, false, buffer);
642
+ pretty_print_token_property(erb_in_node->content, "content", indent, relative_indent, false, buffer);
643
+ pretty_print_token_property(erb_in_node->tag_closing, "tag_closing", indent, relative_indent, false, buffer);
644
+ pretty_print_array("statements", erb_in_node->statements, indent, relative_indent, true, buffer);
645
+ } break;
646
+
587
647
  }
588
648
  }
@@ -0,0 +1,17 @@
1
+ // NOTE: This file is generated by the templates/template.rb script and should not
2
+ // be modified manually. See /Users/marcoroth/Development/herb-release/templates/src/include/ast_pretty_print.h.erb
3
+
4
+ #ifndef HERB_AST_PRETTY_PRINT_H
5
+ #define HERB_AST_PRETTY_PRINT_H
6
+
7
+ #include "ast_nodes.h"
8
+ #include "buffer.h"
9
+
10
+ void ast_pretty_print_node(
11
+ AST_NODE_T* node,
12
+ size_t indent,
13
+ size_t relative_indent,
14
+ buffer_T* buffer
15
+ );
16
+
17
+ #endif
@@ -10,7 +10,7 @@
10
10
  bool buffer_init(buffer_T* buffer) {
11
11
  buffer->capacity = 1024;
12
12
  buffer->length = 0;
13
- buffer->value = nullable_safe_malloc(buffer->capacity * sizeof(char));
13
+ buffer->value = nullable_safe_malloc((buffer->capacity + 1) * sizeof(char));
14
14
 
15
15
  if (!buffer->value) {
16
16
  fprintf(stderr, "Error: Failed to initialize buffer with capacity of %zu.\n", buffer->capacity);
@@ -50,32 +50,39 @@ size_t buffer_sizeof(void) {
50
50
  * or null termination.
51
51
  *
52
52
  * @param buffer The buffer to increase capacity for
53
- * @param required_length The additional length needed beyond current buffer length
54
- * @return true if capacity is sufficient (either already or after reallocation),
55
- * false if reallocation failed
53
+ * @param additional_capacity The additional length needed beyond current buffer capacity
54
+ * @return true if capacity was increased, false if reallocation failed
56
55
  */
57
- bool buffer_increase_capacity(buffer_T* buffer, const size_t required_length) {
58
- if (SIZE_MAX - buffer->length < required_length) {
56
+ bool buffer_increase_capacity(buffer_T* buffer, const size_t additional_capacity) {
57
+ if (additional_capacity + 1 >= SIZE_MAX) {
59
58
  fprintf(stderr, "Error: Buffer capacity would overflow system limits.\n");
60
- return false;
59
+ exit(1);
61
60
  }
62
61
 
63
- const size_t required_capacity = buffer->length + required_length;
64
-
65
- if (buffer->capacity >= required_capacity) { return true; }
62
+ const size_t new_capacity = buffer->capacity + additional_capacity;
66
63
 
67
- size_t new_capacity;
68
- if (required_capacity > SIZE_MAX / 2) {
69
- new_capacity = required_capacity + 1024;
64
+ return buffer_resize(buffer, new_capacity);
65
+ }
70
66
 
71
- if (new_capacity < required_capacity) { new_capacity = SIZE_MAX; }
72
- } else {
73
- new_capacity = required_capacity * 2;
67
+ /**
68
+ * Resizes the capacity of the buffer to the specified new capacity.
69
+ *
70
+ * @param buffer The buffer to resize
71
+ * @param new_capacity The new capacity to resize the buffer to
72
+ * @return true if capacity was resized, false if reallocation failed
73
+ */
74
+ bool buffer_resize(buffer_T* buffer, const size_t new_capacity) {
75
+ if (new_capacity + 1 >= SIZE_MAX) {
76
+ fprintf(stderr, "Error: Buffer capacity would overflow system limits.\n");
77
+ exit(1);
74
78
  }
75
79
 
76
- char* new_value = safe_realloc(buffer->value, new_capacity);
80
+ char* new_value = nullable_safe_realloc(buffer->value, new_capacity + 1);
77
81
 
78
- if (unlikely(new_value == NULL)) { return false; }
82
+ if (unlikely(new_value == NULL)) {
83
+ fprintf(stderr, "Error: Failed to resize buffer to %zu.\n", new_capacity);
84
+ exit(1);
85
+ }
79
86
 
80
87
  buffer->value = new_value;
81
88
  buffer->capacity = new_capacity;
@@ -83,6 +90,33 @@ bool buffer_increase_capacity(buffer_T* buffer, const size_t required_length) {
83
90
  return true;
84
91
  }
85
92
 
93
+ /**
94
+ * Expands the capacity of the buffer by doubling its current capacity.
95
+ * This function is a convenience function that calls buffer_increase_capacity
96
+ * with a factor of 2.
97
+ *
98
+ * @param buffer The buffer to expand capacity for
99
+ * @return true if capacity was increased, false if reallocation failed
100
+ */
101
+ bool buffer_expand_capacity(buffer_T* buffer) {
102
+ return buffer_resize(buffer, buffer->capacity * 2);
103
+ }
104
+
105
+ /**
106
+ * Expands the capacity of the buffer if needed to accommodate additional content.
107
+ * This function is a convenience function that calls buffer_has_capacity and
108
+ * buffer_expand_capacity.
109
+ *
110
+ * @param buffer The buffer to expand capacity for
111
+ * @param required_length The additional length needed beyond current buffer capacity
112
+ * @return true if capacity was increased, false if reallocation failed
113
+ */
114
+ bool buffer_expand_if_needed(buffer_T* buffer, const size_t required_length) {
115
+ if (buffer_has_capacity(buffer, required_length)) { return true; }
116
+
117
+ return buffer_resize(buffer, buffer->capacity + (required_length * 2));
118
+ }
119
+
86
120
  /**
87
121
  * Appends a null-terminated string to the buffer.
88
122
  * @note This function requires that 'text' is a properly null-terminated string.
@@ -99,7 +133,7 @@ void buffer_append(buffer_T* buffer, const char* text) {
99
133
 
100
134
  size_t text_length = strlen(text);
101
135
 
102
- if (!buffer_increase_capacity(buffer, text_length)) { return; }
136
+ if (!buffer_expand_if_needed(buffer, text_length)) { return; }
103
137
 
104
138
  memcpy(buffer->value + buffer->length, text, text_length);
105
139
  buffer->length += text_length;
@@ -120,7 +154,7 @@ void buffer_append(buffer_T* buffer, const char* text) {
120
154
  */
121
155
  void buffer_append_with_length(buffer_T* buffer, const char* text, const size_t length) {
122
156
  if (!buffer || !text || length == 0) { return; }
123
- if (!buffer_increase_capacity(buffer, length)) { return; }
157
+ if (!buffer_expand_if_needed(buffer, length)) { return; }
124
158
 
125
159
  memcpy(buffer->value + buffer->length, text, length);
126
160
 
@@ -161,7 +195,7 @@ void buffer_prepend(buffer_T* buffer, const char* text) {
161
195
 
162
196
  size_t text_length = strlen(text);
163
197
 
164
- if (!buffer_increase_capacity(buffer, text_length)) { return; }
198
+ if (!buffer_expand_if_needed(buffer, text_length)) { return; }
165
199
 
166
200
  memmove(buffer->value + text_length, buffer->value, buffer->length + 1);
167
201
  memcpy(buffer->value, text, text_length);
@@ -171,17 +205,16 @@ void buffer_prepend(buffer_T* buffer, const char* text) {
171
205
 
172
206
  void buffer_concat(buffer_T* destination, buffer_T* source) {
173
207
  if (source->length == 0) { return; }
174
- if (!buffer_increase_capacity(destination, source->length)) { return; }
208
+ if (!buffer_expand_if_needed(destination, source->length)) { return; }
175
209
 
176
210
  memcpy(destination->value + destination->length, source->value, source->length);
211
+
177
212
  destination->length += source->length;
178
213
  destination->value[destination->length] = '\0';
179
214
  }
180
215
 
181
- bool buffer_reserve(buffer_T* buffer, const size_t min_capacity) {
182
- const size_t required_length = min_capacity - buffer->length;
183
-
184
- return buffer_increase_capacity(buffer, required_length);
216
+ bool buffer_has_capacity(buffer_T* buffer, const size_t required_length) {
217
+ return (buffer->length + required_length <= buffer->capacity);
185
218
  }
186
219
 
187
220
  void buffer_clear(buffer_T* buffer) {
@@ -192,7 +225,7 @@ void buffer_clear(buffer_T* buffer) {
192
225
  void buffer_free(buffer_T* buffer) {
193
226
  if (!buffer) { return; }
194
227
 
195
- free(buffer->value);
228
+ if (buffer->value != NULL) { free(buffer->value); }
196
229
 
197
230
  buffer->value = NULL;
198
231
  buffer->length = buffer->capacity = 0;
@@ -0,0 +1,39 @@
1
+ #ifndef HERB_BUFFER_H
2
+ #define HERB_BUFFER_H
3
+
4
+ #include <stdbool.h>
5
+ #include <stdlib.h>
6
+
7
+ typedef struct BUFFER_STRUCT {
8
+ char* value;
9
+ size_t length;
10
+ size_t capacity;
11
+ } buffer_T;
12
+
13
+ bool buffer_init(buffer_T* buffer);
14
+ buffer_T buffer_new(void);
15
+
16
+ bool buffer_increase_capacity(buffer_T* buffer, size_t additional_capacity);
17
+ bool buffer_has_capacity(buffer_T* buffer, size_t required_length);
18
+ bool buffer_expand_capacity(buffer_T* buffer);
19
+ bool buffer_expand_if_needed(buffer_T* buffer, size_t required_length);
20
+ bool buffer_resize(buffer_T* buffer, size_t new_capacity);
21
+
22
+ void buffer_append(buffer_T* buffer, const char* text);
23
+ void buffer_append_with_length(buffer_T* buffer, const char* text, size_t length);
24
+ void buffer_append_char(buffer_T* buffer, char character);
25
+ void buffer_append_repeated(buffer_T* buffer, char character, size_t length);
26
+ void buffer_append_whitespace(buffer_T* buffer, size_t length);
27
+ void buffer_prepend(buffer_T* buffer, const char* text);
28
+ void buffer_concat(buffer_T* destination, buffer_T* source);
29
+
30
+ char* buffer_value(const buffer_T* buffer);
31
+
32
+ size_t buffer_length(const buffer_T* buffer);
33
+ size_t buffer_capacity(const buffer_T* buffer);
34
+ size_t buffer_sizeof(void);
35
+
36
+ void buffer_clear(buffer_T* buffer);
37
+ void buffer_free(buffer_T* buffer);
38
+
39
+ #endif