herb 0.8.10-arm-linux-gnu → 0.9.0-arm-linux-gnu

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 (209) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +11 -3
  3. data/README.md +64 -34
  4. data/Rakefile +48 -40
  5. data/config.yml +317 -34
  6. data/ext/herb/error_helpers.c +367 -140
  7. data/ext/herb/error_helpers.h +1 -0
  8. data/ext/herb/extconf.rb +67 -28
  9. data/ext/herb/extension.c +317 -51
  10. data/ext/herb/extension.h +1 -0
  11. data/ext/herb/extension_helpers.c +23 -14
  12. data/ext/herb/extension_helpers.h +2 -2
  13. data/ext/herb/nodes.c +537 -270
  14. data/ext/herb/nodes.h +1 -0
  15. data/herb.gemspec +3 -2
  16. data/lib/herb/3.0/herb.so +0 -0
  17. data/lib/herb/3.1/herb.so +0 -0
  18. data/lib/herb/3.2/herb.so +0 -0
  19. data/lib/herb/3.3/herb.so +0 -0
  20. data/lib/herb/3.4/herb.so +0 -0
  21. data/lib/herb/4.0/herb.so +0 -0
  22. data/lib/herb/ast/helpers.rb +3 -3
  23. data/lib/herb/ast/node.rb +15 -2
  24. data/lib/herb/ast/nodes.rb +1132 -157
  25. data/lib/herb/bootstrap.rb +87 -0
  26. data/lib/herb/cli.rb +341 -31
  27. data/lib/herb/configuration.rb +248 -0
  28. data/lib/herb/defaults.yml +32 -0
  29. data/lib/herb/engine/compiler.rb +78 -11
  30. data/lib/herb/engine/debug_visitor.rb +13 -3
  31. data/lib/herb/engine/error_formatter.rb +13 -9
  32. data/lib/herb/engine/parser_error_overlay.rb +10 -6
  33. data/lib/herb/engine/validator.rb +8 -3
  34. data/lib/herb/engine/validators/nesting_validator.rb +2 -2
  35. data/lib/herb/engine.rb +82 -35
  36. data/lib/herb/errors.rb +563 -88
  37. data/lib/herb/lex_result.rb +1 -0
  38. data/lib/herb/location.rb +7 -3
  39. data/lib/herb/parse_result.rb +12 -2
  40. data/lib/herb/parser_options.rb +57 -0
  41. data/lib/herb/position.rb +1 -0
  42. data/lib/herb/prism_inspect.rb +116 -0
  43. data/lib/herb/project.rb +923 -331
  44. data/lib/herb/range.rb +1 -0
  45. data/lib/herb/token.rb +7 -1
  46. data/lib/herb/version.rb +1 -1
  47. data/lib/herb/visitor.rb +37 -2
  48. data/lib/herb/warnings.rb +6 -1
  49. data/lib/herb.rb +35 -3
  50. data/sig/herb/ast/helpers.rbs +2 -2
  51. data/sig/herb/ast/node.rbs +12 -2
  52. data/sig/herb/ast/nodes.rbs +641 -128
  53. data/sig/herb/bootstrap.rbs +31 -0
  54. data/sig/herb/configuration.rbs +89 -0
  55. data/sig/herb/engine/compiler.rbs +9 -1
  56. data/sig/herb/engine/debug_visitor.rbs +2 -0
  57. data/sig/herb/engine/validator.rbs +5 -1
  58. data/sig/herb/engine.rbs +17 -3
  59. data/sig/herb/errors.rbs +258 -63
  60. data/sig/herb/location.rbs +4 -0
  61. data/sig/herb/parse_result.rbs +4 -2
  62. data/sig/herb/parser_options.rbs +42 -0
  63. data/sig/herb/position.rbs +1 -0
  64. data/sig/herb/prism_inspect.rbs +28 -0
  65. data/sig/herb/range.rbs +1 -0
  66. data/sig/herb/token.rbs +6 -0
  67. data/sig/herb/visitor.rbs +25 -4
  68. data/sig/herb/warnings.rbs +6 -1
  69. data/sig/herb.rbs +14 -0
  70. data/sig/herb_c_extension.rbs +5 -2
  71. data/sig/serialized_ast_errors.rbs +54 -6
  72. data/sig/serialized_ast_nodes.rbs +60 -6
  73. data/src/analyze/action_view/attribute_extraction_helpers.c +290 -0
  74. data/src/analyze/action_view/content_tag.c +70 -0
  75. data/src/analyze/action_view/link_to.c +143 -0
  76. data/src/analyze/action_view/registry.c +60 -0
  77. data/src/analyze/action_view/tag.c +64 -0
  78. data/src/analyze/action_view/tag_helper_node_builders.c +305 -0
  79. data/src/analyze/action_view/tag_helpers.c +748 -0
  80. data/src/analyze/action_view/turbo_frame_tag.c +88 -0
  81. data/src/analyze/analyze.c +882 -0
  82. data/src/{analyzed_ruby.c → analyze/analyzed_ruby.c} +13 -11
  83. data/src/analyze/builders.c +343 -0
  84. data/src/analyze/conditional_elements.c +594 -0
  85. data/src/analyze/conditional_open_tags.c +640 -0
  86. data/src/analyze/control_type.c +250 -0
  87. data/src/{analyze_helpers.c → analyze/helpers.c} +48 -23
  88. data/src/analyze/invalid_structures.c +193 -0
  89. data/src/{analyze_missing_end.c → analyze/missing_end.c} +33 -22
  90. data/src/analyze/parse_errors.c +84 -0
  91. data/src/analyze/prism_annotate.c +397 -0
  92. data/src/{analyze_transform.c → analyze/transform.c} +17 -3
  93. data/src/ast_node.c +17 -7
  94. data/src/ast_nodes.c +662 -387
  95. data/src/ast_pretty_print.c +190 -6
  96. data/src/errors.c +1076 -520
  97. data/src/extract.c +145 -49
  98. data/src/herb.c +52 -34
  99. data/src/html_util.c +241 -12
  100. data/src/include/analyze/action_view/attribute_extraction_helpers.h +36 -0
  101. data/src/include/analyze/action_view/tag_helper_handler.h +41 -0
  102. data/src/include/analyze/action_view/tag_helper_node_builders.h +70 -0
  103. data/src/include/analyze/action_view/tag_helpers.h +38 -0
  104. data/src/include/{analyze.h → analyze/analyze.h} +14 -4
  105. data/src/include/{analyzed_ruby.h → analyze/analyzed_ruby.h} +3 -3
  106. data/src/include/analyze/builders.h +27 -0
  107. data/src/include/analyze/conditional_elements.h +9 -0
  108. data/src/include/analyze/conditional_open_tags.h +9 -0
  109. data/src/include/analyze/control_type.h +14 -0
  110. data/src/include/{analyze_helpers.h → analyze/helpers.h} +4 -2
  111. data/src/include/analyze/invalid_structures.h +11 -0
  112. data/src/include/analyze/prism_annotate.h +16 -0
  113. data/src/include/ast_node.h +11 -5
  114. data/src/include/ast_nodes.h +117 -38
  115. data/src/include/ast_pretty_print.h +5 -0
  116. data/src/include/element_source.h +3 -8
  117. data/src/include/errors.h +148 -55
  118. data/src/include/extract.h +21 -5
  119. data/src/include/herb.h +18 -6
  120. data/src/include/herb_prism_node.h +13 -0
  121. data/src/include/html_util.h +7 -2
  122. data/src/include/io.h +3 -1
  123. data/src/include/lex_helpers.h +29 -0
  124. data/src/include/lexer.h +1 -1
  125. data/src/include/lexer_peek_helpers.h +87 -13
  126. data/src/include/lexer_struct.h +2 -0
  127. data/src/include/location.h +2 -1
  128. data/src/include/parser.h +27 -2
  129. data/src/include/parser_helpers.h +19 -3
  130. data/src/include/pretty_print.h +10 -5
  131. data/src/include/prism_context.h +45 -0
  132. data/src/include/prism_helpers.h +10 -7
  133. data/src/include/prism_serialized.h +12 -0
  134. data/src/include/token.h +16 -4
  135. data/src/include/token_struct.h +10 -3
  136. data/src/include/utf8.h +2 -1
  137. data/src/include/util/hb_allocator.h +78 -0
  138. data/src/include/util/hb_arena.h +6 -1
  139. data/src/include/util/hb_arena_debug.h +12 -1
  140. data/src/include/util/hb_array.h +7 -3
  141. data/src/include/util/hb_buffer.h +6 -4
  142. data/src/include/util/hb_foreach.h +79 -0
  143. data/src/include/util/hb_narray.h +8 -4
  144. data/src/include/util/hb_string.h +56 -9
  145. data/src/include/util.h +6 -3
  146. data/src/include/version.h +1 -1
  147. data/src/io.c +3 -2
  148. data/src/lexer.c +42 -30
  149. data/src/lexer_peek_helpers.c +12 -74
  150. data/src/location.c +2 -2
  151. data/src/main.c +53 -28
  152. data/src/parser.c +783 -247
  153. data/src/parser_helpers.c +110 -23
  154. data/src/parser_match_tags.c +109 -48
  155. data/src/pretty_print.c +29 -24
  156. data/src/prism_helpers.c +30 -27
  157. data/src/ruby_parser.c +2 -0
  158. data/src/token.c +151 -66
  159. data/src/token_matchers.c +0 -1
  160. data/src/utf8.c +7 -6
  161. data/src/util/hb_allocator.c +341 -0
  162. data/src/util/hb_arena.c +81 -56
  163. data/src/util/hb_arena_debug.c +32 -17
  164. data/src/util/hb_array.c +30 -15
  165. data/src/util/hb_buffer.c +17 -21
  166. data/src/util/hb_narray.c +22 -7
  167. data/src/util/hb_string.c +49 -35
  168. data/src/util.c +21 -11
  169. data/src/visitor.c +47 -0
  170. data/templates/ext/herb/error_helpers.c.erb +24 -11
  171. data/templates/ext/herb/error_helpers.h.erb +1 -0
  172. data/templates/ext/herb/nodes.c.erb +50 -16
  173. data/templates/ext/herb/nodes.h.erb +1 -0
  174. data/templates/java/error_helpers.c.erb +1 -1
  175. data/templates/java/nodes.c.erb +30 -8
  176. data/templates/java/org/herb/ast/Errors.java.erb +24 -1
  177. data/templates/java/org/herb/ast/Nodes.java.erb +80 -21
  178. data/templates/javascript/packages/core/src/errors.ts.erb +16 -3
  179. data/templates/javascript/packages/core/src/node-type-guards.ts.erb +3 -1
  180. data/templates/javascript/packages/core/src/nodes.ts.erb +109 -32
  181. data/templates/javascript/packages/node/extension/error_helpers.cpp.erb +13 -4
  182. data/templates/javascript/packages/node/extension/nodes.cpp.erb +43 -4
  183. data/templates/lib/herb/ast/nodes.rb.erb +88 -31
  184. data/templates/lib/herb/errors.rb.erb +15 -3
  185. data/templates/lib/herb/visitor.rb.erb +2 -2
  186. data/templates/rust/src/ast/nodes.rs.erb +97 -44
  187. data/templates/rust/src/errors.rs.erb +2 -1
  188. data/templates/rust/src/nodes.rs.erb +167 -15
  189. data/templates/rust/src/union_types.rs.erb +60 -0
  190. data/templates/rust/src/visitor.rs.erb +81 -0
  191. data/templates/src/{analyze_missing_end.c.erb → analyze/missing_end.c.erb} +9 -6
  192. data/templates/src/{analyze_transform.c.erb → analyze/transform.c.erb} +2 -2
  193. data/templates/src/ast_nodes.c.erb +34 -26
  194. data/templates/src/ast_pretty_print.c.erb +24 -5
  195. data/templates/src/errors.c.erb +60 -54
  196. data/templates/src/include/ast_nodes.h.erb +6 -2
  197. data/templates/src/include/ast_pretty_print.h.erb +5 -0
  198. data/templates/src/include/errors.h.erb +15 -11
  199. data/templates/src/include/util/hb_foreach.h.erb +20 -0
  200. data/templates/src/parser_match_tags.c.erb +10 -4
  201. data/templates/src/visitor.c.erb +2 -2
  202. data/templates/template.rb +204 -29
  203. data/templates/wasm/error_helpers.cpp.erb +9 -5
  204. data/templates/wasm/nodes.cpp.erb +41 -4
  205. metadata +57 -16
  206. data/src/analyze.c +0 -1608
  207. data/src/element_source.c +0 -12
  208. data/src/include/util/hb_system.h +0 -9
  209. data/src/util/hb_system.c +0 -30
data/src/extract.c CHANGED
@@ -1,42 +1,96 @@
1
1
  #include "include/herb.h"
2
- #include "include/io.h"
3
- #include "include/lexer.h"
2
+ #include "include/util/hb_allocator.h"
4
3
  #include "include/util/hb_array.h"
5
4
  #include "include/util/hb_buffer.h"
5
+ #include "include/util/hb_string.h"
6
6
  #include "include/util/string.h"
7
7
 
8
8
  #include <assert.h>
9
9
  #include <stdlib.h>
10
10
  #include <string.h>
11
11
 
12
- void herb_extract_ruby_to_buffer(const char* source, hb_buffer_T* output) {
13
- hb_array_T* tokens = herb_lex(source);
12
+ const herb_extract_ruby_options_T HERB_EXTRACT_RUBY_DEFAULT_OPTIONS = { .semicolons = true,
13
+ .comments = false,
14
+ .preserve_positions = true };
15
+
16
+ void herb_extract_ruby_to_buffer_with_options(
17
+ const char* source,
18
+ hb_buffer_T* output,
19
+ const herb_extract_ruby_options_T* options,
20
+ hb_allocator_T* allocator
21
+ ) {
22
+ herb_extract_ruby_options_T extract_options = options ? *options : HERB_EXTRACT_RUBY_DEFAULT_OPTIONS;
23
+
24
+ hb_array_T* tokens = herb_lex(source, allocator);
14
25
  bool skip_erb_content = false;
15
26
  bool is_comment_tag = false;
27
+ bool is_erb_comment_tag = false;
28
+ bool need_newline = false;
16
29
 
17
30
  for (size_t i = 0; i < hb_array_size(tokens); i++) {
18
31
  const token_T* token = hb_array_get(tokens, i);
19
32
 
20
33
  switch (token->type) {
21
34
  case TOKEN_NEWLINE: {
22
- hb_buffer_append(output, token->value);
35
+ hb_buffer_append_string(output, token->value);
36
+ need_newline = false;
23
37
  break;
24
38
  }
25
39
 
26
40
  case TOKEN_ERB_START: {
27
- if (string_equals(token->value, "<%#")) {
28
- skip_erb_content = true;
29
- is_comment_tag = true;
30
- } else if (string_equals(token->value, "<%%") || string_equals(token->value, "<%%=")
31
- || string_equals(token->value, "<%graphql")) {
41
+ is_erb_comment_tag = hb_string_equals(token->value, hb_string("<%#"));
42
+
43
+ if (is_erb_comment_tag) {
44
+ if (extract_options.comments) {
45
+ skip_erb_content = false;
46
+ is_comment_tag = false;
47
+
48
+ if (extract_options.preserve_positions) {
49
+ bool is_multiline = false;
50
+
51
+ if (i + 1 < hb_array_size(tokens)) {
52
+ const token_T* next = hb_array_get(tokens, i + 1);
53
+
54
+ if (next->type == TOKEN_ERB_CONTENT && !hb_string_is_null(next->value)
55
+ && memchr(next->value.data, '\n', next->value.length) != NULL) {
56
+ is_multiline = true;
57
+ }
58
+ }
59
+
60
+ if (is_multiline) {
61
+ hb_buffer_append_char(output, '#');
62
+ hb_buffer_append_whitespace(output, 2);
63
+ } else {
64
+ hb_buffer_append_whitespace(output, 2);
65
+ hb_buffer_append_char(output, '#');
66
+ }
67
+ } else {
68
+ if (need_newline) { hb_buffer_append_char(output, '\n'); }
69
+ hb_buffer_append_char(output, '#');
70
+ need_newline = true;
71
+ }
72
+ } else {
73
+ skip_erb_content = true;
74
+ is_comment_tag = true;
75
+ if (extract_options.preserve_positions) { hb_buffer_append_whitespace(output, range_length(token->range)); }
76
+ }
77
+ } else if (hb_string_equals(token->value, hb_string("<%%")) || hb_string_equals(token->value, hb_string("<%%="))
78
+ || hb_string_equals(token->value, hb_string("<%graphql"))) {
32
79
  skip_erb_content = true;
33
80
  is_comment_tag = false;
81
+ if (extract_options.preserve_positions) { hb_buffer_append_whitespace(output, range_length(token->range)); }
34
82
  } else {
35
83
  skip_erb_content = false;
36
84
  is_comment_tag = false;
85
+
86
+ if (extract_options.preserve_positions) {
87
+ hb_buffer_append_whitespace(output, range_length(token->range));
88
+ } else if (need_newline) {
89
+ hb_buffer_append_char(output, '\n');
90
+ need_newline = false;
91
+ }
37
92
  }
38
93
 
39
- hb_buffer_append_whitespace(output, range_length(token->range));
40
94
  break;
41
95
  }
42
96
 
@@ -44,26 +98,65 @@ void herb_extract_ruby_to_buffer(const char* source, hb_buffer_T* output) {
44
98
  if (skip_erb_content == false) {
45
99
  bool is_inline_comment = false;
46
100
 
47
- if (!is_comment_tag && token->value != NULL) {
48
- const char* content = token->value;
101
+ if (!extract_options.comments && !is_comment_tag && !hb_string_is_empty(token->value)) {
102
+ hb_string_T trimmed = hb_string_trim_start(token->value);
49
103
 
50
- while (*content == ' ' || *content == '\t') {
51
- content++;
52
- }
53
-
54
- if (*content == '#' && token->location.start.line == token->location.end.line) {
104
+ if (!hb_string_is_empty(trimmed) && trimmed.data[0] == '#'
105
+ && token->location.start.line == token->location.end.line) {
55
106
  is_comment_tag = true;
56
107
  is_inline_comment = true;
57
108
  }
58
109
  }
59
110
 
60
111
  if (is_inline_comment) {
61
- hb_buffer_append_whitespace(output, range_length(token->range));
112
+ if (extract_options.preserve_positions) { hb_buffer_append_whitespace(output, range_length(token->range)); }
113
+ } else if (is_erb_comment_tag && !hb_string_is_null(token->value)) {
114
+ const char* content = token->value.data;
115
+ size_t content_remaining = token->value.length;
116
+
117
+ while (content_remaining > 0) {
118
+ if (*content == '\n') {
119
+ hb_buffer_append_char(output, '\n');
120
+ content++;
121
+ content_remaining--;
122
+
123
+ if (content_remaining > 0 && extract_options.preserve_positions && *content == ' ') {
124
+ content++;
125
+ content_remaining--;
126
+ }
127
+
128
+ hb_buffer_append_char(output, '#');
129
+ } else {
130
+ hb_buffer_append_char(output, *content);
131
+ content++;
132
+ content_remaining--;
133
+ }
134
+ }
135
+
136
+ if (!extract_options.preserve_positions) { need_newline = true; }
62
137
  } else {
63
- hb_buffer_append(output, token->value);
138
+ hb_buffer_append_string(output, token->value);
139
+
140
+ if (!extract_options.preserve_positions) { need_newline = true; }
64
141
  }
65
142
  } else {
66
- hb_buffer_append_whitespace(output, range_length(token->range));
143
+ if (is_erb_comment_tag && extract_options.preserve_positions && !hb_string_is_null(token->value)) {
144
+ const char* content = token->value.data;
145
+ size_t content_remaining = token->value.length;
146
+
147
+ while (content_remaining > 0) {
148
+ if (*content == '\n') {
149
+ hb_buffer_append_char(output, '\n');
150
+ } else {
151
+ hb_buffer_append_char(output, ' ');
152
+ }
153
+
154
+ content++;
155
+ content_remaining--;
156
+ }
157
+ } else if (extract_options.preserve_positions) {
158
+ hb_buffer_append_whitespace(output, range_length(token->range));
159
+ }
67
160
  }
68
161
 
69
162
  break;
@@ -71,31 +164,43 @@ void herb_extract_ruby_to_buffer(const char* source, hb_buffer_T* output) {
71
164
 
72
165
  case TOKEN_ERB_END: {
73
166
  bool was_comment = is_comment_tag;
167
+ bool was_erb_comment = is_erb_comment_tag;
74
168
  skip_erb_content = false;
75
169
  is_comment_tag = false;
170
+ is_erb_comment_tag = false;
76
171
 
77
- if (was_comment) {
78
- hb_buffer_append_whitespace(output, range_length(token->range));
79
- break;
172
+ if (extract_options.preserve_positions) {
173
+ if (was_comment) {
174
+ hb_buffer_append_whitespace(output, range_length(token->range));
175
+ } else if (was_erb_comment && extract_options.comments) {
176
+ hb_buffer_append_whitespace(output, range_length(token->range));
177
+ } else if (extract_options.semicolons) {
178
+ hb_buffer_append_char(output, ' ');
179
+ hb_buffer_append_char(output, ';');
180
+ hb_buffer_append_whitespace(output, range_length(token->range) - 2);
181
+ } else {
182
+ hb_buffer_append_whitespace(output, range_length(token->range));
183
+ }
80
184
  }
81
185
 
82
- hb_buffer_append_char(output, ' ');
83
- hb_buffer_append_char(output, ';');
84
- hb_buffer_append_whitespace(output, range_length(token->range) - 2);
85
186
  break;
86
187
  }
87
188
 
88
189
  default: {
89
- hb_buffer_append_whitespace(output, range_length(token->range));
190
+ if (extract_options.preserve_positions) { hb_buffer_append_whitespace(output, range_length(token->range)); }
90
191
  }
91
192
  }
92
193
  }
93
194
 
94
- herb_free_tokens(&tokens);
195
+ herb_free_tokens(&tokens, allocator);
196
+ }
197
+
198
+ void herb_extract_ruby_to_buffer(const char* source, hb_buffer_T* output, hb_allocator_T* allocator) {
199
+ herb_extract_ruby_to_buffer_with_options(source, output, NULL, allocator);
95
200
  }
96
201
 
97
- void herb_extract_html_to_buffer(const char* source, hb_buffer_T* output) {
98
- hb_array_T* tokens = herb_lex(source);
202
+ void herb_extract_html_to_buffer(const char* source, hb_buffer_T* output, hb_allocator_T* allocator) {
203
+ hb_array_T* tokens = herb_lex(source, allocator);
99
204
 
100
205
  for (size_t i = 0; i < hb_array_size(tokens); i++) {
101
206
  const token_T* token = hb_array_get(tokens, i);
@@ -104,44 +209,35 @@ void herb_extract_html_to_buffer(const char* source, hb_buffer_T* output) {
104
209
  case TOKEN_ERB_START:
105
210
  case TOKEN_ERB_CONTENT:
106
211
  case TOKEN_ERB_END: hb_buffer_append_whitespace(output, range_length(token->range)); break;
107
- default: hb_buffer_append(output, token->value);
212
+ default: hb_buffer_append_string(output, token->value);
108
213
  }
109
214
  }
110
215
 
111
- herb_free_tokens(&tokens);
216
+ herb_free_tokens(&tokens, allocator);
112
217
  }
113
218
 
114
- char* herb_extract_ruby_with_semicolons(const char* source) {
219
+ char* herb_extract_ruby_with_semicolons(const char* source, hb_allocator_T* allocator) {
115
220
  if (!source) { return NULL; }
116
221
 
117
222
  hb_buffer_T output;
118
- hb_buffer_init(&output, strlen(source));
223
+ hb_buffer_init(&output, strlen(source), allocator);
119
224
 
120
- herb_extract_ruby_to_buffer(source, &output);
225
+ herb_extract_ruby_to_buffer(source, &output, allocator);
121
226
 
122
227
  return output.value;
123
228
  }
124
229
 
125
- char* herb_extract(const char* source, const herb_extract_language_T language) {
230
+ char* herb_extract(const char* source, const herb_extract_language_T language, hb_allocator_T* allocator) {
126
231
  if (!source) { return NULL; }
127
232
 
128
233
  hb_buffer_T output;
129
- hb_buffer_init(&output, strlen(source));
234
+ hb_buffer_init(&output, strlen(source), allocator);
130
235
 
131
236
  switch (language) {
132
- case HERB_EXTRACT_LANGUAGE_RUBY: herb_extract_ruby_to_buffer(source, &output); break;
133
- case HERB_EXTRACT_LANGUAGE_HTML: herb_extract_html_to_buffer(source, &output); break;
237
+ case HERB_EXTRACT_LANGUAGE_RUBY: herb_extract_ruby_to_buffer(source, &output, allocator); break;
238
+ case HERB_EXTRACT_LANGUAGE_HTML: herb_extract_html_to_buffer(source, &output, allocator); break;
134
239
  default: assert(0 && "invalid extract language");
135
240
  }
136
241
 
137
242
  return output.value;
138
243
  }
139
-
140
- char* herb_extract_from_file(const char* path, const herb_extract_language_T language) {
141
- char* source = herb_read_file(path);
142
- char* output = herb_extract(source, language);
143
-
144
- free(source);
145
-
146
- return output;
147
- }
data/src/herb.c CHANGED
@@ -1,21 +1,25 @@
1
1
  #include "include/herb.h"
2
- #include "include/io.h"
2
+ #include "include/analyze/analyze.h"
3
+ #include "include/analyze/prism_annotate.h"
3
4
  #include "include/lexer.h"
4
5
  #include "include/parser.h"
5
6
  #include "include/token.h"
7
+ #include "include/util/hb_allocator.h"
6
8
  #include "include/util/hb_array.h"
7
- #include "include/util/hb_buffer.h"
8
9
  #include "include/version.h"
9
10
 
10
11
  #include <prism.h>
11
12
  #include <stdlib.h>
13
+ #include <string.h>
14
+
15
+ HERB_EXPORTED_FUNCTION hb_array_T* herb_lex(const char* source, hb_allocator_T* allocator) {
16
+ if (!source) { source = ""; }
12
17
 
13
- HERB_EXPORTED_FUNCTION hb_array_T* herb_lex(const char* source) {
14
18
  lexer_T lexer = { 0 };
15
- lexer_init(&lexer, source);
19
+ lexer_init(&lexer, source, allocator);
16
20
 
17
21
  token_T* token = NULL;
18
- hb_array_T* tokens = hb_array_init(128);
22
+ hb_array_T* tokens = hb_array_init(128, allocator);
19
23
 
20
24
  while ((token = lexer_next_token(&lexer))->type != TOKEN_EOF) {
21
25
  hb_array_append(tokens, token);
@@ -26,15 +30,18 @@ HERB_EXPORTED_FUNCTION hb_array_T* herb_lex(const char* source) {
26
30
  return tokens;
27
31
  }
28
32
 
29
- HERB_EXPORTED_FUNCTION AST_DOCUMENT_NODE_T* herb_parse(const char* source, parser_options_T* options) {
33
+ HERB_EXPORTED_FUNCTION AST_DOCUMENT_NODE_T* herb_parse(
34
+ const char* source,
35
+ const parser_options_T* options,
36
+ hb_allocator_T* allocator
37
+ ) {
30
38
  if (!source) { source = ""; }
31
39
 
32
40
  lexer_T lexer = { 0 };
33
- lexer_init(&lexer, source);
41
+ lexer_init(&lexer, source, allocator);
34
42
  parser_T parser = { 0 };
35
43
 
36
44
  parser_options_T parser_options = HERB_DEFAULT_PARSER_OPTIONS;
37
-
38
45
  if (options != NULL) { parser_options = *options; }
39
46
 
40
47
  herb_parser_init(&parser, &lexer, parser_options);
@@ -43,40 +50,28 @@ HERB_EXPORTED_FUNCTION AST_DOCUMENT_NODE_T* herb_parse(const char* source, parse
43
50
 
44
51
  herb_parser_deinit(&parser);
45
52
 
46
- return document;
47
- }
48
-
49
- HERB_EXPORTED_FUNCTION hb_array_T* herb_lex_file(const char* path) {
50
- char* source = herb_read_file(path);
51
- hb_array_T* tokens = herb_lex(source);
52
-
53
- free(source);
54
-
55
- return tokens;
56
- }
57
-
58
- HERB_EXPORTED_FUNCTION void herb_lex_to_buffer(const char* source, hb_buffer_T* output) {
59
- hb_array_T* tokens = herb_lex(source);
60
-
61
- for (size_t i = 0; i < hb_array_size(tokens); i++) {
62
- token_T* token = hb_array_get(tokens, i);
63
-
64
- hb_string_T type = token_to_string(token);
65
- hb_buffer_append_string(output, type);
66
- free(type.data);
67
-
68
- hb_buffer_append(output, "\n");
53
+ if (parser_options.analyze) { herb_analyze_parse_tree(document, source, &parser_options, allocator); }
54
+
55
+ if (parser_options.prism_nodes || parser_options.prism_program) {
56
+ herb_annotate_prism_nodes(
57
+ document,
58
+ source,
59
+ parser_options.prism_nodes,
60
+ parser_options.prism_nodes_deep,
61
+ parser_options.prism_program,
62
+ allocator
63
+ );
69
64
  }
70
65
 
71
- herb_free_tokens(&tokens);
66
+ return document;
72
67
  }
73
68
 
74
- HERB_EXPORTED_FUNCTION void herb_free_tokens(hb_array_T** tokens) {
69
+ HERB_EXPORTED_FUNCTION void herb_free_tokens(hb_array_T** tokens, hb_allocator_T* allocator) {
75
70
  if (!tokens || !*tokens) { return; }
76
71
 
77
72
  for (size_t i = 0; i < hb_array_size(*tokens); i++) {
78
73
  token_T* token = hb_array_get(*tokens, i);
79
- if (token) { token_free(token); }
74
+ if (token) { token_free(token, allocator); }
80
75
  }
81
76
 
82
77
  hb_array_free(tokens);
@@ -89,3 +84,26 @@ HERB_EXPORTED_FUNCTION const char* herb_version(void) {
89
84
  HERB_EXPORTED_FUNCTION const char* herb_prism_version(void) {
90
85
  return PRISM_VERSION;
91
86
  }
87
+
88
+ HERB_EXPORTED_FUNCTION herb_ruby_parse_result_T* herb_parse_ruby(const char* source, size_t length) {
89
+ if (!source) { return NULL; }
90
+
91
+ herb_ruby_parse_result_T* result = malloc(sizeof(herb_ruby_parse_result_T));
92
+ if (!result) { return NULL; }
93
+
94
+ memset(&result->options, 0, sizeof(pm_options_t));
95
+ pm_parser_init(&result->parser, (const uint8_t*) source, length, &result->options);
96
+ result->root = pm_parse(&result->parser);
97
+
98
+ return result;
99
+ }
100
+
101
+ HERB_EXPORTED_FUNCTION void herb_free_ruby_parse_result(herb_ruby_parse_result_T* result) {
102
+ if (!result) { return; }
103
+
104
+ if (result->root) { pm_node_destroy(&result->parser, result->root); }
105
+
106
+ pm_parser_free(&result->parser);
107
+ pm_options_free(&result->options);
108
+ free(result);
109
+ }