herb 0.0.1 → 0.1.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 (108) hide show
  1. checksums.yaml +5 -5
  2. data/{LICENSE → LICENSE.txt} +4 -3
  3. data/Makefile +121 -0
  4. data/README.md +102 -107
  5. data/Rakefile +184 -0
  6. data/exe/herb +5 -0
  7. data/ext/herb/error_helpers.c +302 -0
  8. data/ext/herb/error_helpers.h +15 -0
  9. data/ext/herb/extconf.rb +75 -0
  10. data/ext/herb/extension.c +110 -0
  11. data/ext/herb/extension.h +6 -0
  12. data/ext/herb/extension_helpers.c +117 -0
  13. data/ext/herb/extension_helpers.h +24 -0
  14. data/ext/herb/nodes.c +936 -0
  15. data/ext/herb/nodes.h +12 -0
  16. data/herb.gemspec +49 -0
  17. data/lib/herb/ast/node.rb +61 -0
  18. data/lib/herb/ast/nodes.rb +1542 -0
  19. data/lib/herb/ast.rb +6 -0
  20. data/lib/herb/cli.rb +164 -0
  21. data/lib/herb/errors.rb +352 -0
  22. data/lib/herb/lex_result.rb +20 -0
  23. data/lib/herb/libherb/array.rb +48 -0
  24. data/lib/herb/libherb/ast_node.rb +47 -0
  25. data/lib/herb/libherb/buffer.rb +53 -0
  26. data/lib/herb/libherb/extract_result.rb +17 -0
  27. data/lib/herb/libherb/lex_result.rb +29 -0
  28. data/lib/herb/libherb/libherb.rb +49 -0
  29. data/lib/herb/libherb/parse_result.rb +17 -0
  30. data/lib/herb/libherb/token.rb +43 -0
  31. data/lib/herb/libherb.rb +32 -0
  32. data/lib/herb/location.rb +42 -0
  33. data/lib/herb/parse_result.rb +26 -0
  34. data/lib/herb/position.rb +36 -0
  35. data/lib/herb/project.rb +361 -0
  36. data/lib/herb/range.rb +40 -0
  37. data/lib/herb/result.rb +21 -0
  38. data/lib/herb/token.rb +43 -0
  39. data/lib/herb/token_list.rb +11 -0
  40. data/lib/herb/version.rb +5 -0
  41. data/lib/herb.rb +21 -68
  42. data/src/analyze.c +989 -0
  43. data/src/analyze_helpers.c +241 -0
  44. data/src/analyzed_ruby.c +35 -0
  45. data/src/array.c +137 -0
  46. data/src/ast_node.c +81 -0
  47. data/src/ast_nodes.c +866 -0
  48. data/src/ast_pretty_print.c +588 -0
  49. data/src/buffer.c +199 -0
  50. data/src/errors.c +740 -0
  51. data/src/extract.c +110 -0
  52. data/src/herb.c +103 -0
  53. data/src/html_util.c +143 -0
  54. data/src/include/analyze.h +36 -0
  55. data/src/include/analyze_helpers.h +43 -0
  56. data/src/include/analyzed_ruby.h +33 -0
  57. data/src/include/array.h +33 -0
  58. data/src/include/ast_node.h +35 -0
  59. data/src/include/ast_nodes.h +303 -0
  60. data/src/include/ast_pretty_print.h +17 -0
  61. data/src/include/buffer.h +36 -0
  62. data/src/include/errors.h +125 -0
  63. data/src/include/extract.h +20 -0
  64. data/src/include/herb.h +32 -0
  65. data/src/include/html_util.h +13 -0
  66. data/src/include/io.h +9 -0
  67. data/src/include/json.h +28 -0
  68. data/src/include/lexer.h +13 -0
  69. data/src/include/lexer_peek_helpers.h +23 -0
  70. data/src/include/lexer_struct.h +32 -0
  71. data/src/include/location.h +25 -0
  72. data/src/include/macros.h +10 -0
  73. data/src/include/memory.h +12 -0
  74. data/src/include/parser.h +22 -0
  75. data/src/include/parser_helpers.h +33 -0
  76. data/src/include/position.h +22 -0
  77. data/src/include/pretty_print.h +53 -0
  78. data/src/include/prism_helpers.h +18 -0
  79. data/src/include/range.h +23 -0
  80. data/src/include/ruby_parser.h +6 -0
  81. data/src/include/token.h +25 -0
  82. data/src/include/token_matchers.h +21 -0
  83. data/src/include/token_struct.h +51 -0
  84. data/src/include/util.h +25 -0
  85. data/src/include/version.h +6 -0
  86. data/src/include/visitor.h +11 -0
  87. data/src/io.c +30 -0
  88. data/src/json.c +205 -0
  89. data/src/lexer.c +284 -0
  90. data/src/lexer_peek_helpers.c +59 -0
  91. data/src/location.c +41 -0
  92. data/src/main.c +162 -0
  93. data/src/memory.c +53 -0
  94. data/src/parser.c +704 -0
  95. data/src/parser_helpers.c +161 -0
  96. data/src/position.c +33 -0
  97. data/src/pretty_print.c +242 -0
  98. data/src/prism_helpers.c +50 -0
  99. data/src/range.c +38 -0
  100. data/src/ruby_parser.c +47 -0
  101. data/src/token.c +194 -0
  102. data/src/token_matchers.c +32 -0
  103. data/src/util.c +128 -0
  104. data/src/visitor.c +321 -0
  105. metadata +126 -82
  106. data/test/helper.rb +0 -7
  107. data/test/helpers_test.rb +0 -25
  108. data/test/parsing_test.rb +0 -110
data/src/ast_nodes.c ADDED
@@ -0,0 +1,866 @@
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/ast_nodes.c.erb
3
+
4
+ #include <stdio.h>
5
+ #include <stdbool.h>
6
+
7
+ #include <prism.h>
8
+
9
+ #include "include/analyzed_ruby.h"
10
+ #include "include/array.h"
11
+ #include "include/ast_node.h"
12
+ #include "include/ast_nodes.h"
13
+ #include "include/errors.h"
14
+ #include "include/token.h"
15
+ #include "include/util.h"
16
+
17
+
18
+ AST_DOCUMENT_NODE_T* ast_document_node_init(array_T* children, position_T* start_position, position_T* end_position, array_T* errors) {
19
+ AST_DOCUMENT_NODE_T* document_node = malloc(sizeof(AST_DOCUMENT_NODE_T));
20
+
21
+ ast_node_init(&document_node->base, AST_DOCUMENT_NODE, start_position, end_position, errors);
22
+
23
+ document_node->children = children;
24
+
25
+ return document_node;
26
+ }
27
+
28
+ AST_LITERAL_NODE_T* ast_literal_node_init(const char* content, position_T* start_position, position_T* end_position, array_T* errors) {
29
+ AST_LITERAL_NODE_T* literal_node = malloc(sizeof(AST_LITERAL_NODE_T));
30
+
31
+ ast_node_init(&literal_node->base, AST_LITERAL_NODE, start_position, end_position, errors);
32
+
33
+ literal_node->content = herb_strdup(content);
34
+
35
+ return literal_node;
36
+ }
37
+
38
+ 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) {
39
+ AST_HTML_OPEN_TAG_NODE_T* html_open_tag_node = malloc(sizeof(AST_HTML_OPEN_TAG_NODE_T));
40
+
41
+ ast_node_init(&html_open_tag_node->base, AST_HTML_OPEN_TAG_NODE, start_position, end_position, errors);
42
+
43
+ html_open_tag_node->tag_opening = token_copy(tag_opening);
44
+ html_open_tag_node->tag_name = token_copy(tag_name);
45
+ html_open_tag_node->tag_closing = token_copy(tag_closing);
46
+ html_open_tag_node->children = children;
47
+ html_open_tag_node->is_void = is_void;
48
+
49
+ return html_open_tag_node;
50
+ }
51
+
52
+ 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) {
53
+ AST_HTML_CLOSE_TAG_NODE_T* html_close_tag_node = malloc(sizeof(AST_HTML_CLOSE_TAG_NODE_T));
54
+
55
+ ast_node_init(&html_close_tag_node->base, AST_HTML_CLOSE_TAG_NODE, start_position, end_position, errors);
56
+
57
+ html_close_tag_node->tag_opening = token_copy(tag_opening);
58
+ html_close_tag_node->tag_name = token_copy(tag_name);
59
+ html_close_tag_node->tag_closing = token_copy(tag_closing);
60
+
61
+ return html_close_tag_node;
62
+ }
63
+
64
+ 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) {
65
+ AST_HTML_SELF_CLOSE_TAG_NODE_T* html_self_close_tag_node = malloc(sizeof(AST_HTML_SELF_CLOSE_TAG_NODE_T));
66
+
67
+ ast_node_init(&html_self_close_tag_node->base, AST_HTML_SELF_CLOSE_TAG_NODE, start_position, end_position, errors);
68
+
69
+ html_self_close_tag_node->tag_opening = token_copy(tag_opening);
70
+ html_self_close_tag_node->tag_name = token_copy(tag_name);
71
+ html_self_close_tag_node->attributes = attributes;
72
+ html_self_close_tag_node->tag_closing = token_copy(tag_closing);
73
+ html_self_close_tag_node->is_void = is_void;
74
+
75
+ return html_self_close_tag_node;
76
+ }
77
+
78
+ 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) {
79
+ AST_HTML_ELEMENT_NODE_T* html_element_node = malloc(sizeof(AST_HTML_ELEMENT_NODE_T));
80
+
81
+ ast_node_init(&html_element_node->base, AST_HTML_ELEMENT_NODE, start_position, end_position, errors);
82
+
83
+ html_element_node->open_tag = open_tag;
84
+ html_element_node->tag_name = token_copy(tag_name);
85
+ html_element_node->body = body;
86
+ html_element_node->close_tag = close_tag;
87
+ html_element_node->is_void = is_void;
88
+
89
+ return html_element_node;
90
+ }
91
+
92
+ 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) {
93
+ AST_HTML_ATTRIBUTE_VALUE_NODE_T* html_attribute_value_node = malloc(sizeof(AST_HTML_ATTRIBUTE_VALUE_NODE_T));
94
+
95
+ ast_node_init(&html_attribute_value_node->base, AST_HTML_ATTRIBUTE_VALUE_NODE, start_position, end_position, errors);
96
+
97
+ html_attribute_value_node->open_quote = token_copy(open_quote);
98
+ html_attribute_value_node->children = children;
99
+ html_attribute_value_node->close_quote = token_copy(close_quote);
100
+ html_attribute_value_node->quoted = quoted;
101
+
102
+ return html_attribute_value_node;
103
+ }
104
+
105
+ 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) {
106
+ AST_HTML_ATTRIBUTE_NAME_NODE_T* html_attribute_name_node = malloc(sizeof(AST_HTML_ATTRIBUTE_NAME_NODE_T));
107
+
108
+ ast_node_init(&html_attribute_name_node->base, AST_HTML_ATTRIBUTE_NAME_NODE, start_position, end_position, errors);
109
+
110
+ html_attribute_name_node->name = token_copy(name);
111
+
112
+ return html_attribute_name_node;
113
+ }
114
+
115
+ 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) {
116
+ AST_HTML_ATTRIBUTE_NODE_T* html_attribute_node = malloc(sizeof(AST_HTML_ATTRIBUTE_NODE_T));
117
+
118
+ ast_node_init(&html_attribute_node->base, AST_HTML_ATTRIBUTE_NODE, start_position, end_position, errors);
119
+
120
+ html_attribute_node->name = name;
121
+ html_attribute_node->equals = token_copy(equals);
122
+ html_attribute_node->value = value;
123
+
124
+ return html_attribute_node;
125
+ }
126
+
127
+ AST_HTML_TEXT_NODE_T* ast_html_text_node_init(const char* content, position_T* start_position, position_T* end_position, array_T* errors) {
128
+ AST_HTML_TEXT_NODE_T* html_text_node = malloc(sizeof(AST_HTML_TEXT_NODE_T));
129
+
130
+ ast_node_init(&html_text_node->base, AST_HTML_TEXT_NODE, start_position, end_position, errors);
131
+
132
+ html_text_node->content = herb_strdup(content);
133
+
134
+ return html_text_node;
135
+ }
136
+
137
+ 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) {
138
+ AST_HTML_COMMENT_NODE_T* html_comment_node = malloc(sizeof(AST_HTML_COMMENT_NODE_T));
139
+
140
+ ast_node_init(&html_comment_node->base, AST_HTML_COMMENT_NODE, start_position, end_position, errors);
141
+
142
+ html_comment_node->comment_start = token_copy(comment_start);
143
+ html_comment_node->children = children;
144
+ html_comment_node->comment_end = token_copy(comment_end);
145
+
146
+ return html_comment_node;
147
+ }
148
+
149
+ 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) {
150
+ AST_HTML_DOCTYPE_NODE_T* html_doctype_node = malloc(sizeof(AST_HTML_DOCTYPE_NODE_T));
151
+
152
+ ast_node_init(&html_doctype_node->base, AST_HTML_DOCTYPE_NODE, start_position, end_position, errors);
153
+
154
+ html_doctype_node->tag_opening = token_copy(tag_opening);
155
+ html_doctype_node->children = children;
156
+ html_doctype_node->tag_closing = token_copy(tag_closing);
157
+
158
+ return html_doctype_node;
159
+ }
160
+
161
+ AST_WHITESPACE_NODE_T* ast_whitespace_node_init(token_T* value, position_T* start_position, position_T* end_position, array_T* errors) {
162
+ AST_WHITESPACE_NODE_T* whitespace_node = malloc(sizeof(AST_WHITESPACE_NODE_T));
163
+
164
+ ast_node_init(&whitespace_node->base, AST_WHITESPACE_NODE, start_position, end_position, errors);
165
+
166
+ whitespace_node->value = token_copy(value);
167
+
168
+ return whitespace_node;
169
+ }
170
+
171
+ 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) {
172
+ AST_ERB_CONTENT_NODE_T* erb_content_node = malloc(sizeof(AST_ERB_CONTENT_NODE_T));
173
+
174
+ ast_node_init(&erb_content_node->base, AST_ERB_CONTENT_NODE, start_position, end_position, errors);
175
+
176
+ erb_content_node->tag_opening = token_copy(tag_opening);
177
+ erb_content_node->content = token_copy(content);
178
+ erb_content_node->tag_closing = token_copy(tag_closing);
179
+ erb_content_node->analyzed_ruby = analyzed_ruby;
180
+ erb_content_node->parsed = parsed;
181
+ erb_content_node->valid = valid;
182
+
183
+ return erb_content_node;
184
+ }
185
+
186
+ 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) {
187
+ AST_ERB_END_NODE_T* erb_end_node = malloc(sizeof(AST_ERB_END_NODE_T));
188
+
189
+ ast_node_init(&erb_end_node->base, AST_ERB_END_NODE, start_position, end_position, errors);
190
+
191
+ erb_end_node->tag_opening = token_copy(tag_opening);
192
+ erb_end_node->content = token_copy(content);
193
+ erb_end_node->tag_closing = token_copy(tag_closing);
194
+
195
+ return erb_end_node;
196
+ }
197
+
198
+ 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) {
199
+ AST_ERB_ELSE_NODE_T* erb_else_node = malloc(sizeof(AST_ERB_ELSE_NODE_T));
200
+
201
+ ast_node_init(&erb_else_node->base, AST_ERB_ELSE_NODE, start_position, end_position, errors);
202
+
203
+ erb_else_node->tag_opening = token_copy(tag_opening);
204
+ erb_else_node->content = token_copy(content);
205
+ erb_else_node->tag_closing = token_copy(tag_closing);
206
+ erb_else_node->statements = statements;
207
+
208
+ return erb_else_node;
209
+ }
210
+
211
+ 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) {
212
+ AST_ERB_IF_NODE_T* erb_if_node = malloc(sizeof(AST_ERB_IF_NODE_T));
213
+
214
+ ast_node_init(&erb_if_node->base, AST_ERB_IF_NODE, start_position, end_position, errors);
215
+
216
+ erb_if_node->tag_opening = token_copy(tag_opening);
217
+ erb_if_node->content = token_copy(content);
218
+ erb_if_node->tag_closing = token_copy(tag_closing);
219
+ erb_if_node->statements = statements;
220
+ erb_if_node->subsequent = subsequent;
221
+ erb_if_node->end_node = end_node;
222
+
223
+ return erb_if_node;
224
+ }
225
+
226
+ 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) {
227
+ AST_ERB_BLOCK_NODE_T* erb_block_node = malloc(sizeof(AST_ERB_BLOCK_NODE_T));
228
+
229
+ ast_node_init(&erb_block_node->base, AST_ERB_BLOCK_NODE, start_position, end_position, errors);
230
+
231
+ erb_block_node->tag_opening = token_copy(tag_opening);
232
+ erb_block_node->content = token_copy(content);
233
+ erb_block_node->tag_closing = token_copy(tag_closing);
234
+ erb_block_node->body = body;
235
+ erb_block_node->end_node = end_node;
236
+
237
+ return erb_block_node;
238
+ }
239
+
240
+ 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) {
241
+ AST_ERB_WHEN_NODE_T* erb_when_node = malloc(sizeof(AST_ERB_WHEN_NODE_T));
242
+
243
+ ast_node_init(&erb_when_node->base, AST_ERB_WHEN_NODE, start_position, end_position, errors);
244
+
245
+ erb_when_node->tag_opening = token_copy(tag_opening);
246
+ erb_when_node->content = token_copy(content);
247
+ erb_when_node->tag_closing = token_copy(tag_closing);
248
+ erb_when_node->statements = statements;
249
+
250
+ return erb_when_node;
251
+ }
252
+
253
+ 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) {
254
+ AST_ERB_CASE_NODE_T* erb_case_node = malloc(sizeof(AST_ERB_CASE_NODE_T));
255
+
256
+ ast_node_init(&erb_case_node->base, AST_ERB_CASE_NODE, start_position, end_position, errors);
257
+
258
+ erb_case_node->tag_opening = token_copy(tag_opening);
259
+ erb_case_node->content = token_copy(content);
260
+ erb_case_node->tag_closing = token_copy(tag_closing);
261
+ erb_case_node->children = children;
262
+ erb_case_node->conditions = conditions;
263
+ erb_case_node->else_clause = else_clause;
264
+ erb_case_node->end_node = end_node;
265
+
266
+ return erb_case_node;
267
+ }
268
+
269
+ 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) {
270
+ AST_ERB_WHILE_NODE_T* erb_while_node = malloc(sizeof(AST_ERB_WHILE_NODE_T));
271
+
272
+ ast_node_init(&erb_while_node->base, AST_ERB_WHILE_NODE, start_position, end_position, errors);
273
+
274
+ erb_while_node->tag_opening = token_copy(tag_opening);
275
+ erb_while_node->content = token_copy(content);
276
+ erb_while_node->tag_closing = token_copy(tag_closing);
277
+ erb_while_node->statements = statements;
278
+ erb_while_node->end_node = end_node;
279
+
280
+ return erb_while_node;
281
+ }
282
+
283
+ 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) {
284
+ AST_ERB_UNTIL_NODE_T* erb_until_node = malloc(sizeof(AST_ERB_UNTIL_NODE_T));
285
+
286
+ ast_node_init(&erb_until_node->base, AST_ERB_UNTIL_NODE, start_position, end_position, errors);
287
+
288
+ erb_until_node->tag_opening = token_copy(tag_opening);
289
+ erb_until_node->content = token_copy(content);
290
+ erb_until_node->tag_closing = token_copy(tag_closing);
291
+ erb_until_node->statements = statements;
292
+ erb_until_node->end_node = end_node;
293
+
294
+ return erb_until_node;
295
+ }
296
+
297
+ 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) {
298
+ AST_ERB_FOR_NODE_T* erb_for_node = malloc(sizeof(AST_ERB_FOR_NODE_T));
299
+
300
+ ast_node_init(&erb_for_node->base, AST_ERB_FOR_NODE, start_position, end_position, errors);
301
+
302
+ erb_for_node->tag_opening = token_copy(tag_opening);
303
+ erb_for_node->content = token_copy(content);
304
+ erb_for_node->tag_closing = token_copy(tag_closing);
305
+ erb_for_node->statements = statements;
306
+ erb_for_node->end_node = end_node;
307
+
308
+ return erb_for_node;
309
+ }
310
+
311
+ 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) {
312
+ AST_ERB_RESCUE_NODE_T* erb_rescue_node = malloc(sizeof(AST_ERB_RESCUE_NODE_T));
313
+
314
+ ast_node_init(&erb_rescue_node->base, AST_ERB_RESCUE_NODE, start_position, end_position, errors);
315
+
316
+ erb_rescue_node->tag_opening = token_copy(tag_opening);
317
+ erb_rescue_node->content = token_copy(content);
318
+ erb_rescue_node->tag_closing = token_copy(tag_closing);
319
+ erb_rescue_node->statements = statements;
320
+ erb_rescue_node->subsequent = subsequent;
321
+
322
+ return erb_rescue_node;
323
+ }
324
+
325
+ 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) {
326
+ AST_ERB_ENSURE_NODE_T* erb_ensure_node = malloc(sizeof(AST_ERB_ENSURE_NODE_T));
327
+
328
+ ast_node_init(&erb_ensure_node->base, AST_ERB_ENSURE_NODE, start_position, end_position, errors);
329
+
330
+ erb_ensure_node->tag_opening = token_copy(tag_opening);
331
+ erb_ensure_node->content = token_copy(content);
332
+ erb_ensure_node->tag_closing = token_copy(tag_closing);
333
+ erb_ensure_node->statements = statements;
334
+
335
+ return erb_ensure_node;
336
+ }
337
+
338
+ 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) {
339
+ AST_ERB_BEGIN_NODE_T* erb_begin_node = malloc(sizeof(AST_ERB_BEGIN_NODE_T));
340
+
341
+ ast_node_init(&erb_begin_node->base, AST_ERB_BEGIN_NODE, start_position, end_position, errors);
342
+
343
+ erb_begin_node->tag_opening = token_copy(tag_opening);
344
+ erb_begin_node->content = token_copy(content);
345
+ erb_begin_node->tag_closing = token_copy(tag_closing);
346
+ erb_begin_node->statements = statements;
347
+ erb_begin_node->rescue_clause = rescue_clause;
348
+ erb_begin_node->else_clause = else_clause;
349
+ erb_begin_node->ensure_clause = ensure_clause;
350
+ erb_begin_node->end_node = end_node;
351
+
352
+ return erb_begin_node;
353
+ }
354
+
355
+ 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) {
356
+ AST_ERB_UNLESS_NODE_T* erb_unless_node = malloc(sizeof(AST_ERB_UNLESS_NODE_T));
357
+
358
+ ast_node_init(&erb_unless_node->base, AST_ERB_UNLESS_NODE, start_position, end_position, errors);
359
+
360
+ erb_unless_node->tag_opening = token_copy(tag_opening);
361
+ erb_unless_node->content = token_copy(content);
362
+ erb_unless_node->tag_closing = token_copy(tag_closing);
363
+ erb_unless_node->statements = statements;
364
+ erb_unless_node->else_clause = else_clause;
365
+ erb_unless_node->end_node = end_node;
366
+
367
+ return erb_unless_node;
368
+ }
369
+
370
+ const char* ast_node_type_to_string(AST_NODE_T* node) {
371
+ switch (node->type) {
372
+ case AST_DOCUMENT_NODE: return "AST_DOCUMENT_NODE";
373
+ case AST_LITERAL_NODE: return "AST_LITERAL_NODE";
374
+ case AST_HTML_OPEN_TAG_NODE: return "AST_HTML_OPEN_TAG_NODE";
375
+ case AST_HTML_CLOSE_TAG_NODE: return "AST_HTML_CLOSE_TAG_NODE";
376
+ case AST_HTML_SELF_CLOSE_TAG_NODE: return "AST_HTML_SELF_CLOSE_TAG_NODE";
377
+ case AST_HTML_ELEMENT_NODE: return "AST_HTML_ELEMENT_NODE";
378
+ case AST_HTML_ATTRIBUTE_VALUE_NODE: return "AST_HTML_ATTRIBUTE_VALUE_NODE";
379
+ case AST_HTML_ATTRIBUTE_NAME_NODE: return "AST_HTML_ATTRIBUTE_NAME_NODE";
380
+ case AST_HTML_ATTRIBUTE_NODE: return "AST_HTML_ATTRIBUTE_NODE";
381
+ case AST_HTML_TEXT_NODE: return "AST_HTML_TEXT_NODE";
382
+ case AST_HTML_COMMENT_NODE: return "AST_HTML_COMMENT_NODE";
383
+ case AST_HTML_DOCTYPE_NODE: return "AST_HTML_DOCTYPE_NODE";
384
+ case AST_WHITESPACE_NODE: return "AST_WHITESPACE_NODE";
385
+ case AST_ERB_CONTENT_NODE: return "AST_ERB_CONTENT_NODE";
386
+ case AST_ERB_END_NODE: return "AST_ERB_END_NODE";
387
+ case AST_ERB_ELSE_NODE: return "AST_ERB_ELSE_NODE";
388
+ case AST_ERB_IF_NODE: return "AST_ERB_IF_NODE";
389
+ case AST_ERB_BLOCK_NODE: return "AST_ERB_BLOCK_NODE";
390
+ case AST_ERB_WHEN_NODE: return "AST_ERB_WHEN_NODE";
391
+ case AST_ERB_CASE_NODE: return "AST_ERB_CASE_NODE";
392
+ case AST_ERB_WHILE_NODE: return "AST_ERB_WHILE_NODE";
393
+ case AST_ERB_UNTIL_NODE: return "AST_ERB_UNTIL_NODE";
394
+ case AST_ERB_FOR_NODE: return "AST_ERB_FOR_NODE";
395
+ case AST_ERB_RESCUE_NODE: return "AST_ERB_RESCUE_NODE";
396
+ case AST_ERB_ENSURE_NODE: return "AST_ERB_ENSURE_NODE";
397
+ case AST_ERB_BEGIN_NODE: return "AST_ERB_BEGIN_NODE";
398
+ case AST_ERB_UNLESS_NODE: return "AST_ERB_UNLESS_NODE";
399
+ }
400
+
401
+ return "Unknown ast_node_type_T";
402
+ }
403
+
404
+ const char* ast_node_human_type(AST_NODE_T* node) {
405
+ switch (node->type) {
406
+ case AST_DOCUMENT_NODE: return "DocumentNode";
407
+ case AST_LITERAL_NODE: return "LiteralNode";
408
+ case AST_HTML_OPEN_TAG_NODE: return "HTMLOpenTagNode";
409
+ case AST_HTML_CLOSE_TAG_NODE: return "HTMLCloseTagNode";
410
+ case AST_HTML_SELF_CLOSE_TAG_NODE: return "HTMLSelfCloseTagNode";
411
+ case AST_HTML_ELEMENT_NODE: return "HTMLElementNode";
412
+ case AST_HTML_ATTRIBUTE_VALUE_NODE: return "HTMLAttributeValueNode";
413
+ case AST_HTML_ATTRIBUTE_NAME_NODE: return "HTMLAttributeNameNode";
414
+ case AST_HTML_ATTRIBUTE_NODE: return "HTMLAttributeNode";
415
+ case AST_HTML_TEXT_NODE: return "HTMLTextNode";
416
+ case AST_HTML_COMMENT_NODE: return "HTMLCommentNode";
417
+ case AST_HTML_DOCTYPE_NODE: return "HTMLDoctypeNode";
418
+ case AST_WHITESPACE_NODE: return "WhitespaceNode";
419
+ case AST_ERB_CONTENT_NODE: return "ERBContentNode";
420
+ case AST_ERB_END_NODE: return "ERBEndNode";
421
+ case AST_ERB_ELSE_NODE: return "ERBElseNode";
422
+ case AST_ERB_IF_NODE: return "ERBIfNode";
423
+ case AST_ERB_BLOCK_NODE: return "ERBBlockNode";
424
+ case AST_ERB_WHEN_NODE: return "ERBWhenNode";
425
+ case AST_ERB_CASE_NODE: return "ERBCaseNode";
426
+ case AST_ERB_WHILE_NODE: return "ERBWhileNode";
427
+ case AST_ERB_UNTIL_NODE: return "ERBUntilNode";
428
+ case AST_ERB_FOR_NODE: return "ERBForNode";
429
+ case AST_ERB_RESCUE_NODE: return "ERBRescueNode";
430
+ case AST_ERB_ENSURE_NODE: return "ERBEnsureNode";
431
+ case AST_ERB_BEGIN_NODE: return "ERBBeginNode";
432
+ case AST_ERB_UNLESS_NODE: return "ERBUnlessNode";
433
+ }
434
+
435
+ return "Unknown ast_node_type_T";
436
+ }
437
+
438
+ void ast_free_base_node(AST_NODE_T* node) {
439
+ if (node == NULL) { return; }
440
+
441
+ if (node->errors) {
442
+ for (size_t i = 0; i < array_size(node->errors); i++) {
443
+ ERROR_T* child = array_get(node->errors, i);
444
+ if (child != NULL) { error_free(child); }
445
+ }
446
+
447
+ array_free(&node->errors);
448
+ }
449
+
450
+ if (node->location) { location_free(node->location); }
451
+
452
+ free(node);
453
+ }
454
+
455
+
456
+ static void ast_free_document_node(AST_DOCUMENT_NODE_T* document_node) {
457
+ if (document_node->children != NULL) {
458
+ for (size_t i = 0; i < array_size(document_node->children); i++) {
459
+ AST_NODE_T* child = array_get(document_node->children, i);
460
+ if (child) { ast_node_free(child); }
461
+ }
462
+
463
+ array_free(&document_node->children);
464
+ }
465
+
466
+ ast_free_base_node(&document_node->base);
467
+ }
468
+
469
+ static void ast_free_literal_node(AST_LITERAL_NODE_T* literal_node) {
470
+ if (literal_node->content != NULL) { free((char*) literal_node->content); }
471
+
472
+ ast_free_base_node(&literal_node->base);
473
+ }
474
+
475
+ static void ast_free_html_open_tag_node(AST_HTML_OPEN_TAG_NODE_T* html_open_tag_node) {
476
+ if (html_open_tag_node->tag_opening != NULL) { token_free(html_open_tag_node->tag_opening); }
477
+ if (html_open_tag_node->tag_name != NULL) { token_free(html_open_tag_node->tag_name); }
478
+ if (html_open_tag_node->tag_closing != NULL) { token_free(html_open_tag_node->tag_closing); }
479
+ if (html_open_tag_node->children != NULL) {
480
+ for (size_t i = 0; i < array_size(html_open_tag_node->children); i++) {
481
+ AST_NODE_T* child = array_get(html_open_tag_node->children, i);
482
+ if (child) { ast_node_free(child); }
483
+ }
484
+
485
+ array_free(&html_open_tag_node->children);
486
+ }
487
+
488
+ ast_free_base_node(&html_open_tag_node->base);
489
+ }
490
+
491
+ static void ast_free_html_close_tag_node(AST_HTML_CLOSE_TAG_NODE_T* html_close_tag_node) {
492
+ if (html_close_tag_node->tag_opening != NULL) { token_free(html_close_tag_node->tag_opening); }
493
+ if (html_close_tag_node->tag_name != NULL) { token_free(html_close_tag_node->tag_name); }
494
+ if (html_close_tag_node->tag_closing != NULL) { token_free(html_close_tag_node->tag_closing); }
495
+
496
+ ast_free_base_node(&html_close_tag_node->base);
497
+ }
498
+
499
+ static void ast_free_html_self_close_tag_node(AST_HTML_SELF_CLOSE_TAG_NODE_T* html_self_close_tag_node) {
500
+ if (html_self_close_tag_node->tag_opening != NULL) { token_free(html_self_close_tag_node->tag_opening); }
501
+ if (html_self_close_tag_node->tag_name != NULL) { token_free(html_self_close_tag_node->tag_name); }
502
+ if (html_self_close_tag_node->attributes != NULL) {
503
+ for (size_t i = 0; i < array_size(html_self_close_tag_node->attributes); i++) {
504
+ AST_NODE_T* child = array_get(html_self_close_tag_node->attributes, i);
505
+ if (child) { ast_node_free(child); }
506
+ }
507
+
508
+ array_free(&html_self_close_tag_node->attributes);
509
+ }
510
+ if (html_self_close_tag_node->tag_closing != NULL) { token_free(html_self_close_tag_node->tag_closing); }
511
+
512
+ ast_free_base_node(&html_self_close_tag_node->base);
513
+ }
514
+
515
+ static void ast_free_html_element_node(AST_HTML_ELEMENT_NODE_T* html_element_node) {
516
+ ast_node_free((AST_NODE_T*) html_element_node->open_tag);
517
+ if (html_element_node->tag_name != NULL) { token_free(html_element_node->tag_name); }
518
+ if (html_element_node->body != NULL) {
519
+ for (size_t i = 0; i < array_size(html_element_node->body); i++) {
520
+ AST_NODE_T* child = array_get(html_element_node->body, i);
521
+ if (child) { ast_node_free(child); }
522
+ }
523
+
524
+ array_free(&html_element_node->body);
525
+ }
526
+ ast_node_free((AST_NODE_T*) html_element_node->close_tag);
527
+
528
+ ast_free_base_node(&html_element_node->base);
529
+ }
530
+
531
+ static void ast_free_html_attribute_value_node(AST_HTML_ATTRIBUTE_VALUE_NODE_T* html_attribute_value_node) {
532
+ if (html_attribute_value_node->open_quote != NULL) { token_free(html_attribute_value_node->open_quote); }
533
+ if (html_attribute_value_node->children != NULL) {
534
+ for (size_t i = 0; i < array_size(html_attribute_value_node->children); i++) {
535
+ AST_NODE_T* child = array_get(html_attribute_value_node->children, i);
536
+ if (child) { ast_node_free(child); }
537
+ }
538
+
539
+ array_free(&html_attribute_value_node->children);
540
+ }
541
+ if (html_attribute_value_node->close_quote != NULL) { token_free(html_attribute_value_node->close_quote); }
542
+
543
+ ast_free_base_node(&html_attribute_value_node->base);
544
+ }
545
+
546
+ static void ast_free_html_attribute_name_node(AST_HTML_ATTRIBUTE_NAME_NODE_T* html_attribute_name_node) {
547
+ if (html_attribute_name_node->name != NULL) { token_free(html_attribute_name_node->name); }
548
+
549
+ ast_free_base_node(&html_attribute_name_node->base);
550
+ }
551
+
552
+ static void ast_free_html_attribute_node(AST_HTML_ATTRIBUTE_NODE_T* html_attribute_node) {
553
+ ast_node_free((AST_NODE_T*) html_attribute_node->name);
554
+ if (html_attribute_node->equals != NULL) { token_free(html_attribute_node->equals); }
555
+ ast_node_free((AST_NODE_T*) html_attribute_node->value);
556
+
557
+ ast_free_base_node(&html_attribute_node->base);
558
+ }
559
+
560
+ static void ast_free_html_text_node(AST_HTML_TEXT_NODE_T* html_text_node) {
561
+ if (html_text_node->content != NULL) { free((char*) html_text_node->content); }
562
+
563
+ ast_free_base_node(&html_text_node->base);
564
+ }
565
+
566
+ static void ast_free_html_comment_node(AST_HTML_COMMENT_NODE_T* html_comment_node) {
567
+ if (html_comment_node->comment_start != NULL) { token_free(html_comment_node->comment_start); }
568
+ if (html_comment_node->children != NULL) {
569
+ for (size_t i = 0; i < array_size(html_comment_node->children); i++) {
570
+ AST_NODE_T* child = array_get(html_comment_node->children, i);
571
+ if (child) { ast_node_free(child); }
572
+ }
573
+
574
+ array_free(&html_comment_node->children);
575
+ }
576
+ if (html_comment_node->comment_end != NULL) { token_free(html_comment_node->comment_end); }
577
+
578
+ ast_free_base_node(&html_comment_node->base);
579
+ }
580
+
581
+ static void ast_free_html_doctype_node(AST_HTML_DOCTYPE_NODE_T* html_doctype_node) {
582
+ if (html_doctype_node->tag_opening != NULL) { token_free(html_doctype_node->tag_opening); }
583
+ if (html_doctype_node->children != NULL) {
584
+ for (size_t i = 0; i < array_size(html_doctype_node->children); i++) {
585
+ AST_NODE_T* child = array_get(html_doctype_node->children, i);
586
+ if (child) { ast_node_free(child); }
587
+ }
588
+
589
+ array_free(&html_doctype_node->children);
590
+ }
591
+ if (html_doctype_node->tag_closing != NULL) { token_free(html_doctype_node->tag_closing); }
592
+
593
+ ast_free_base_node(&html_doctype_node->base);
594
+ }
595
+
596
+ static void ast_free_whitespace_node(AST_WHITESPACE_NODE_T* whitespace_node) {
597
+ if (whitespace_node->value != NULL) { token_free(whitespace_node->value); }
598
+
599
+ ast_free_base_node(&whitespace_node->base);
600
+ }
601
+
602
+ static void ast_free_erb_content_node(AST_ERB_CONTENT_NODE_T* erb_content_node) {
603
+ if (erb_content_node->tag_opening != NULL) { token_free(erb_content_node->tag_opening); }
604
+ if (erb_content_node->content != NULL) { token_free(erb_content_node->content); }
605
+ if (erb_content_node->tag_closing != NULL) { token_free(erb_content_node->tag_closing); }
606
+ // TODO: free
607
+
608
+ ast_free_base_node(&erb_content_node->base);
609
+ }
610
+
611
+ static void ast_free_erb_end_node(AST_ERB_END_NODE_T* erb_end_node) {
612
+ if (erb_end_node->tag_opening != NULL) { token_free(erb_end_node->tag_opening); }
613
+ if (erb_end_node->content != NULL) { token_free(erb_end_node->content); }
614
+ if (erb_end_node->tag_closing != NULL) { token_free(erb_end_node->tag_closing); }
615
+
616
+ ast_free_base_node(&erb_end_node->base);
617
+ }
618
+
619
+ static void ast_free_erb_else_node(AST_ERB_ELSE_NODE_T* erb_else_node) {
620
+ if (erb_else_node->tag_opening != NULL) { token_free(erb_else_node->tag_opening); }
621
+ if (erb_else_node->content != NULL) { token_free(erb_else_node->content); }
622
+ if (erb_else_node->tag_closing != NULL) { token_free(erb_else_node->tag_closing); }
623
+ if (erb_else_node->statements != NULL) {
624
+ for (size_t i = 0; i < array_size(erb_else_node->statements); i++) {
625
+ AST_NODE_T* child = array_get(erb_else_node->statements, i);
626
+ if (child) { ast_node_free(child); }
627
+ }
628
+
629
+ array_free(&erb_else_node->statements);
630
+ }
631
+
632
+ ast_free_base_node(&erb_else_node->base);
633
+ }
634
+
635
+ static void ast_free_erb_if_node(AST_ERB_IF_NODE_T* erb_if_node) {
636
+ if (erb_if_node->tag_opening != NULL) { token_free(erb_if_node->tag_opening); }
637
+ if (erb_if_node->content != NULL) { token_free(erb_if_node->content); }
638
+ if (erb_if_node->tag_closing != NULL) { token_free(erb_if_node->tag_closing); }
639
+ if (erb_if_node->statements != NULL) {
640
+ for (size_t i = 0; i < array_size(erb_if_node->statements); i++) {
641
+ AST_NODE_T* child = array_get(erb_if_node->statements, i);
642
+ if (child) { ast_node_free(child); }
643
+ }
644
+
645
+ array_free(&erb_if_node->statements);
646
+ }
647
+ ast_node_free((AST_NODE_T*) erb_if_node->subsequent);
648
+ ast_node_free((AST_NODE_T*) erb_if_node->end_node);
649
+
650
+ ast_free_base_node(&erb_if_node->base);
651
+ }
652
+
653
+ static void ast_free_erb_block_node(AST_ERB_BLOCK_NODE_T* erb_block_node) {
654
+ if (erb_block_node->tag_opening != NULL) { token_free(erb_block_node->tag_opening); }
655
+ if (erb_block_node->content != NULL) { token_free(erb_block_node->content); }
656
+ if (erb_block_node->tag_closing != NULL) { token_free(erb_block_node->tag_closing); }
657
+ if (erb_block_node->body != NULL) {
658
+ for (size_t i = 0; i < array_size(erb_block_node->body); i++) {
659
+ AST_NODE_T* child = array_get(erb_block_node->body, i);
660
+ if (child) { ast_node_free(child); }
661
+ }
662
+
663
+ array_free(&erb_block_node->body);
664
+ }
665
+ ast_node_free((AST_NODE_T*) erb_block_node->end_node);
666
+
667
+ ast_free_base_node(&erb_block_node->base);
668
+ }
669
+
670
+ static void ast_free_erb_when_node(AST_ERB_WHEN_NODE_T* erb_when_node) {
671
+ if (erb_when_node->tag_opening != NULL) { token_free(erb_when_node->tag_opening); }
672
+ if (erb_when_node->content != NULL) { token_free(erb_when_node->content); }
673
+ if (erb_when_node->tag_closing != NULL) { token_free(erb_when_node->tag_closing); }
674
+ if (erb_when_node->statements != NULL) {
675
+ for (size_t i = 0; i < array_size(erb_when_node->statements); i++) {
676
+ AST_NODE_T* child = array_get(erb_when_node->statements, i);
677
+ if (child) { ast_node_free(child); }
678
+ }
679
+
680
+ array_free(&erb_when_node->statements);
681
+ }
682
+
683
+ ast_free_base_node(&erb_when_node->base);
684
+ }
685
+
686
+ static void ast_free_erb_case_node(AST_ERB_CASE_NODE_T* erb_case_node) {
687
+ if (erb_case_node->tag_opening != NULL) { token_free(erb_case_node->tag_opening); }
688
+ if (erb_case_node->content != NULL) { token_free(erb_case_node->content); }
689
+ if (erb_case_node->tag_closing != NULL) { token_free(erb_case_node->tag_closing); }
690
+ if (erb_case_node->children != NULL) {
691
+ for (size_t i = 0; i < array_size(erb_case_node->children); i++) {
692
+ AST_NODE_T* child = array_get(erb_case_node->children, i);
693
+ if (child) { ast_node_free(child); }
694
+ }
695
+
696
+ array_free(&erb_case_node->children);
697
+ }
698
+ if (erb_case_node->conditions != NULL) {
699
+ for (size_t i = 0; i < array_size(erb_case_node->conditions); i++) {
700
+ AST_NODE_T* child = array_get(erb_case_node->conditions, i);
701
+ if (child) { ast_node_free(child); }
702
+ }
703
+
704
+ array_free(&erb_case_node->conditions);
705
+ }
706
+ ast_node_free((AST_NODE_T*) erb_case_node->else_clause);
707
+ ast_node_free((AST_NODE_T*) erb_case_node->end_node);
708
+
709
+ ast_free_base_node(&erb_case_node->base);
710
+ }
711
+
712
+ static void ast_free_erb_while_node(AST_ERB_WHILE_NODE_T* erb_while_node) {
713
+ if (erb_while_node->tag_opening != NULL) { token_free(erb_while_node->tag_opening); }
714
+ if (erb_while_node->content != NULL) { token_free(erb_while_node->content); }
715
+ if (erb_while_node->tag_closing != NULL) { token_free(erb_while_node->tag_closing); }
716
+ if (erb_while_node->statements != NULL) {
717
+ for (size_t i = 0; i < array_size(erb_while_node->statements); i++) {
718
+ AST_NODE_T* child = array_get(erb_while_node->statements, i);
719
+ if (child) { ast_node_free(child); }
720
+ }
721
+
722
+ array_free(&erb_while_node->statements);
723
+ }
724
+ ast_node_free((AST_NODE_T*) erb_while_node->end_node);
725
+
726
+ ast_free_base_node(&erb_while_node->base);
727
+ }
728
+
729
+ static void ast_free_erb_until_node(AST_ERB_UNTIL_NODE_T* erb_until_node) {
730
+ if (erb_until_node->tag_opening != NULL) { token_free(erb_until_node->tag_opening); }
731
+ if (erb_until_node->content != NULL) { token_free(erb_until_node->content); }
732
+ if (erb_until_node->tag_closing != NULL) { token_free(erb_until_node->tag_closing); }
733
+ if (erb_until_node->statements != NULL) {
734
+ for (size_t i = 0; i < array_size(erb_until_node->statements); i++) {
735
+ AST_NODE_T* child = array_get(erb_until_node->statements, i);
736
+ if (child) { ast_node_free(child); }
737
+ }
738
+
739
+ array_free(&erb_until_node->statements);
740
+ }
741
+ ast_node_free((AST_NODE_T*) erb_until_node->end_node);
742
+
743
+ ast_free_base_node(&erb_until_node->base);
744
+ }
745
+
746
+ static void ast_free_erb_for_node(AST_ERB_FOR_NODE_T* erb_for_node) {
747
+ if (erb_for_node->tag_opening != NULL) { token_free(erb_for_node->tag_opening); }
748
+ if (erb_for_node->content != NULL) { token_free(erb_for_node->content); }
749
+ if (erb_for_node->tag_closing != NULL) { token_free(erb_for_node->tag_closing); }
750
+ if (erb_for_node->statements != NULL) {
751
+ for (size_t i = 0; i < array_size(erb_for_node->statements); i++) {
752
+ AST_NODE_T* child = array_get(erb_for_node->statements, i);
753
+ if (child) { ast_node_free(child); }
754
+ }
755
+
756
+ array_free(&erb_for_node->statements);
757
+ }
758
+ ast_node_free((AST_NODE_T*) erb_for_node->end_node);
759
+
760
+ ast_free_base_node(&erb_for_node->base);
761
+ }
762
+
763
+ static void ast_free_erb_rescue_node(AST_ERB_RESCUE_NODE_T* erb_rescue_node) {
764
+ if (erb_rescue_node->tag_opening != NULL) { token_free(erb_rescue_node->tag_opening); }
765
+ if (erb_rescue_node->content != NULL) { token_free(erb_rescue_node->content); }
766
+ if (erb_rescue_node->tag_closing != NULL) { token_free(erb_rescue_node->tag_closing); }
767
+ if (erb_rescue_node->statements != NULL) {
768
+ for (size_t i = 0; i < array_size(erb_rescue_node->statements); i++) {
769
+ AST_NODE_T* child = array_get(erb_rescue_node->statements, i);
770
+ if (child) { ast_node_free(child); }
771
+ }
772
+
773
+ array_free(&erb_rescue_node->statements);
774
+ }
775
+ ast_node_free((AST_NODE_T*) erb_rescue_node->subsequent);
776
+
777
+ ast_free_base_node(&erb_rescue_node->base);
778
+ }
779
+
780
+ static void ast_free_erb_ensure_node(AST_ERB_ENSURE_NODE_T* erb_ensure_node) {
781
+ if (erb_ensure_node->tag_opening != NULL) { token_free(erb_ensure_node->tag_opening); }
782
+ if (erb_ensure_node->content != NULL) { token_free(erb_ensure_node->content); }
783
+ if (erb_ensure_node->tag_closing != NULL) { token_free(erb_ensure_node->tag_closing); }
784
+ if (erb_ensure_node->statements != NULL) {
785
+ for (size_t i = 0; i < array_size(erb_ensure_node->statements); i++) {
786
+ AST_NODE_T* child = array_get(erb_ensure_node->statements, i);
787
+ if (child) { ast_node_free(child); }
788
+ }
789
+
790
+ array_free(&erb_ensure_node->statements);
791
+ }
792
+
793
+ ast_free_base_node(&erb_ensure_node->base);
794
+ }
795
+
796
+ static void ast_free_erb_begin_node(AST_ERB_BEGIN_NODE_T* erb_begin_node) {
797
+ if (erb_begin_node->tag_opening != NULL) { token_free(erb_begin_node->tag_opening); }
798
+ if (erb_begin_node->content != NULL) { token_free(erb_begin_node->content); }
799
+ if (erb_begin_node->tag_closing != NULL) { token_free(erb_begin_node->tag_closing); }
800
+ if (erb_begin_node->statements != NULL) {
801
+ for (size_t i = 0; i < array_size(erb_begin_node->statements); i++) {
802
+ AST_NODE_T* child = array_get(erb_begin_node->statements, i);
803
+ if (child) { ast_node_free(child); }
804
+ }
805
+
806
+ array_free(&erb_begin_node->statements);
807
+ }
808
+ ast_node_free((AST_NODE_T*) erb_begin_node->rescue_clause);
809
+ ast_node_free((AST_NODE_T*) erb_begin_node->else_clause);
810
+ ast_node_free((AST_NODE_T*) erb_begin_node->ensure_clause);
811
+ ast_node_free((AST_NODE_T*) erb_begin_node->end_node);
812
+
813
+ ast_free_base_node(&erb_begin_node->base);
814
+ }
815
+
816
+ static void ast_free_erb_unless_node(AST_ERB_UNLESS_NODE_T* erb_unless_node) {
817
+ if (erb_unless_node->tag_opening != NULL) { token_free(erb_unless_node->tag_opening); }
818
+ if (erb_unless_node->content != NULL) { token_free(erb_unless_node->content); }
819
+ if (erb_unless_node->tag_closing != NULL) { token_free(erb_unless_node->tag_closing); }
820
+ if (erb_unless_node->statements != NULL) {
821
+ for (size_t i = 0; i < array_size(erb_unless_node->statements); i++) {
822
+ AST_NODE_T* child = array_get(erb_unless_node->statements, i);
823
+ if (child) { ast_node_free(child); }
824
+ }
825
+
826
+ array_free(&erb_unless_node->statements);
827
+ }
828
+ ast_node_free((AST_NODE_T*) erb_unless_node->else_clause);
829
+ ast_node_free((AST_NODE_T*) erb_unless_node->end_node);
830
+
831
+ ast_free_base_node(&erb_unless_node->base);
832
+ }
833
+
834
+ void ast_node_free(AST_NODE_T* node) {
835
+ if (!node) { return; }
836
+
837
+ switch (node->type) {
838
+ case AST_DOCUMENT_NODE: ast_free_document_node((AST_DOCUMENT_NODE_T*) node); break;
839
+ case AST_LITERAL_NODE: ast_free_literal_node((AST_LITERAL_NODE_T*) node); break;
840
+ case AST_HTML_OPEN_TAG_NODE: ast_free_html_open_tag_node((AST_HTML_OPEN_TAG_NODE_T*) node); break;
841
+ case AST_HTML_CLOSE_TAG_NODE: ast_free_html_close_tag_node((AST_HTML_CLOSE_TAG_NODE_T*) node); break;
842
+ case AST_HTML_SELF_CLOSE_TAG_NODE: ast_free_html_self_close_tag_node((AST_HTML_SELF_CLOSE_TAG_NODE_T*) node); break;
843
+ case AST_HTML_ELEMENT_NODE: ast_free_html_element_node((AST_HTML_ELEMENT_NODE_T*) node); break;
844
+ case AST_HTML_ATTRIBUTE_VALUE_NODE: ast_free_html_attribute_value_node((AST_HTML_ATTRIBUTE_VALUE_NODE_T*) node); break;
845
+ case AST_HTML_ATTRIBUTE_NAME_NODE: ast_free_html_attribute_name_node((AST_HTML_ATTRIBUTE_NAME_NODE_T*) node); break;
846
+ case AST_HTML_ATTRIBUTE_NODE: ast_free_html_attribute_node((AST_HTML_ATTRIBUTE_NODE_T*) node); break;
847
+ case AST_HTML_TEXT_NODE: ast_free_html_text_node((AST_HTML_TEXT_NODE_T*) node); break;
848
+ case AST_HTML_COMMENT_NODE: ast_free_html_comment_node((AST_HTML_COMMENT_NODE_T*) node); break;
849
+ case AST_HTML_DOCTYPE_NODE: ast_free_html_doctype_node((AST_HTML_DOCTYPE_NODE_T*) node); break;
850
+ case AST_WHITESPACE_NODE: ast_free_whitespace_node((AST_WHITESPACE_NODE_T*) node); break;
851
+ case AST_ERB_CONTENT_NODE: ast_free_erb_content_node((AST_ERB_CONTENT_NODE_T*) node); break;
852
+ case AST_ERB_END_NODE: ast_free_erb_end_node((AST_ERB_END_NODE_T*) node); break;
853
+ case AST_ERB_ELSE_NODE: ast_free_erb_else_node((AST_ERB_ELSE_NODE_T*) node); break;
854
+ case AST_ERB_IF_NODE: ast_free_erb_if_node((AST_ERB_IF_NODE_T*) node); break;
855
+ case AST_ERB_BLOCK_NODE: ast_free_erb_block_node((AST_ERB_BLOCK_NODE_T*) node); break;
856
+ case AST_ERB_WHEN_NODE: ast_free_erb_when_node((AST_ERB_WHEN_NODE_T*) node); break;
857
+ case AST_ERB_CASE_NODE: ast_free_erb_case_node((AST_ERB_CASE_NODE_T*) node); break;
858
+ case AST_ERB_WHILE_NODE: ast_free_erb_while_node((AST_ERB_WHILE_NODE_T*) node); break;
859
+ case AST_ERB_UNTIL_NODE: ast_free_erb_until_node((AST_ERB_UNTIL_NODE_T*) node); break;
860
+ case AST_ERB_FOR_NODE: ast_free_erb_for_node((AST_ERB_FOR_NODE_T*) node); break;
861
+ case AST_ERB_RESCUE_NODE: ast_free_erb_rescue_node((AST_ERB_RESCUE_NODE_T*) node); break;
862
+ case AST_ERB_ENSURE_NODE: ast_free_erb_ensure_node((AST_ERB_ENSURE_NODE_T*) node); break;
863
+ case AST_ERB_BEGIN_NODE: ast_free_erb_begin_node((AST_ERB_BEGIN_NODE_T*) node); break;
864
+ case AST_ERB_UNLESS_NODE: ast_free_erb_unless_node((AST_ERB_UNLESS_NODE_T*) node); break;
865
+ }
866
+ }