herb 0.7.5 → 0.8.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 (161) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +8 -5
  3. data/config.yml +26 -6
  4. data/ext/herb/error_helpers.c +57 -3
  5. data/ext/herb/error_helpers.h +1 -1
  6. data/ext/herb/extconf.rb +1 -0
  7. data/ext/herb/extension.c +10 -24
  8. data/ext/herb/extension_helpers.c +3 -3
  9. data/ext/herb/extension_helpers.h +1 -1
  10. data/ext/herb/nodes.c +72 -37
  11. data/herb.gemspec +0 -2
  12. data/lib/herb/ast/helpers.rb +11 -0
  13. data/lib/herb/ast/node.rb +15 -6
  14. data/lib/herb/ast/nodes.rb +609 -392
  15. data/lib/herb/cli.rb +31 -0
  16. data/lib/herb/colors.rb +82 -0
  17. data/lib/herb/engine/compiler.rb +140 -14
  18. data/lib/herb/engine/debug_visitor.rb +1 -5
  19. data/lib/herb/engine/parser_error_overlay.rb +1 -1
  20. data/lib/herb/engine.rb +8 -14
  21. data/lib/herb/errors.rb +166 -56
  22. data/lib/herb/location.rb +2 -2
  23. data/lib/herb/project.rb +86 -21
  24. data/lib/herb/token.rb +14 -2
  25. data/lib/herb/version.rb +1 -1
  26. data/lib/herb.rb +1 -0
  27. data/sig/herb/ast/helpers.rbs +3 -0
  28. data/sig/herb/ast/node.rbs +12 -5
  29. data/sig/herb/ast/nodes.rbs +124 -62
  30. data/sig/herb/colors.rbs +35 -0
  31. data/sig/herb/engine/compiler.rbs +23 -1
  32. data/sig/herb/errors.rbs +74 -20
  33. data/sig/herb/token.rbs +8 -0
  34. data/sig/herb_c_extension.rbs +1 -1
  35. data/sig/serialized_ast_errors.rbs +8 -0
  36. data/src/analyze.c +420 -171
  37. data/src/analyze_helpers.c +5 -0
  38. data/src/analyze_missing_end.c +147 -0
  39. data/src/analyze_transform.c +196 -0
  40. data/src/analyzed_ruby.c +23 -2
  41. data/src/ast_node.c +5 -5
  42. data/src/ast_nodes.c +179 -179
  43. data/src/ast_pretty_print.c +232 -232
  44. data/src/element_source.c +7 -6
  45. data/src/errors.c +246 -126
  46. data/src/extract.c +92 -34
  47. data/src/herb.c +37 -49
  48. data/src/html_util.c +34 -96
  49. data/src/include/analyze.h +10 -2
  50. data/src/include/analyze_helpers.h +3 -0
  51. data/src/include/analyzed_ruby.h +4 -2
  52. data/src/include/ast_node.h +2 -2
  53. data/src/include/ast_nodes.h +67 -66
  54. data/src/include/ast_pretty_print.h +2 -2
  55. data/src/include/element_source.h +3 -1
  56. data/src/include/errors.h +30 -14
  57. data/src/include/extract.h +4 -4
  58. data/src/include/herb.h +6 -7
  59. data/src/include/html_util.h +4 -5
  60. data/src/include/lexer.h +1 -3
  61. data/src/include/lexer_peek_helpers.h +14 -14
  62. data/src/include/lexer_struct.h +3 -2
  63. data/src/include/macros.h +4 -0
  64. data/src/include/parser.h +12 -6
  65. data/src/include/parser_helpers.h +25 -15
  66. data/src/include/pretty_print.h +38 -28
  67. data/src/include/token.h +5 -8
  68. data/src/include/utf8.h +3 -2
  69. data/src/include/util/hb_arena.h +31 -0
  70. data/src/include/util/hb_arena_debug.h +8 -0
  71. data/src/include/util/hb_array.h +33 -0
  72. data/src/include/util/hb_buffer.h +34 -0
  73. data/src/include/util/hb_string.h +29 -0
  74. data/src/include/util/hb_system.h +9 -0
  75. data/src/include/util.h +3 -14
  76. data/src/include/version.h +1 -1
  77. data/src/include/visitor.h +1 -1
  78. data/src/io.c +7 -4
  79. data/src/lexer.c +61 -88
  80. data/src/lexer_peek_helpers.c +35 -37
  81. data/src/main.c +19 -23
  82. data/src/parser.c +282 -201
  83. data/src/parser_helpers.c +46 -40
  84. data/src/parser_match_tags.c +316 -0
  85. data/src/pretty_print.c +82 -106
  86. data/src/token.c +18 -65
  87. data/src/utf8.c +4 -4
  88. data/src/util/hb_arena.c +179 -0
  89. data/src/util/hb_arena_debug.c +237 -0
  90. data/src/{array.c → util/hb_array.c} +26 -27
  91. data/src/util/hb_buffer.c +203 -0
  92. data/src/util/hb_string.c +85 -0
  93. data/src/util/hb_system.c +30 -0
  94. data/src/util.c +29 -99
  95. data/src/visitor.c +54 -54
  96. data/templates/ext/herb/error_helpers.c.erb +3 -3
  97. data/templates/ext/herb/error_helpers.h.erb +1 -1
  98. data/templates/ext/herb/nodes.c.erb +11 -6
  99. data/templates/java/error_helpers.c.erb +75 -0
  100. data/templates/java/error_helpers.h.erb +20 -0
  101. data/templates/java/nodes.c.erb +97 -0
  102. data/templates/java/nodes.h.erb +23 -0
  103. data/templates/java/org/herb/ast/Errors.java.erb +121 -0
  104. data/templates/java/org/herb/ast/NodeVisitor.java.erb +14 -0
  105. data/templates/java/org/herb/ast/Nodes.java.erb +220 -0
  106. data/templates/java/org/herb/ast/Visitor.java.erb +56 -0
  107. data/templates/javascript/packages/node/extension/error_helpers.cpp.erb +8 -8
  108. data/templates/javascript/packages/node/extension/error_helpers.h.erb +1 -1
  109. data/templates/javascript/packages/node/extension/nodes.cpp.erb +9 -9
  110. data/templates/javascript/packages/node/extension/nodes.h.erb +1 -1
  111. data/templates/lib/herb/ast/nodes.rb.erb +28 -16
  112. data/templates/lib/herb/errors.rb.erb +17 -12
  113. data/templates/rust/src/ast/nodes.rs.erb +220 -0
  114. data/templates/rust/src/errors.rs.erb +216 -0
  115. data/templates/rust/src/nodes.rs.erb +374 -0
  116. data/templates/src/analyze_missing_end.c.erb +36 -0
  117. data/templates/src/analyze_transform.c.erb +24 -0
  118. data/templates/src/ast_nodes.c.erb +14 -14
  119. data/templates/src/ast_pretty_print.c.erb +36 -36
  120. data/templates/src/errors.c.erb +31 -31
  121. data/templates/src/include/ast_nodes.h.erb +10 -9
  122. data/templates/src/include/ast_pretty_print.h.erb +2 -2
  123. data/templates/src/include/errors.h.erb +6 -6
  124. data/templates/src/parser_match_tags.c.erb +38 -0
  125. data/templates/src/visitor.c.erb +4 -4
  126. data/templates/template.rb +22 -3
  127. data/templates/wasm/error_helpers.cpp.erb +9 -9
  128. data/templates/wasm/error_helpers.h.erb +1 -1
  129. data/templates/wasm/nodes.cpp.erb +9 -9
  130. data/templates/wasm/nodes.h.erb +1 -1
  131. data/vendor/prism/Rakefile +4 -1
  132. data/vendor/prism/config.yml +2 -1
  133. data/vendor/prism/include/prism/ast.h +31 -1
  134. data/vendor/prism/include/prism/diagnostic.h +1 -0
  135. data/vendor/prism/include/prism/version.h +3 -3
  136. data/vendor/prism/src/diagnostic.c +3 -1
  137. data/vendor/prism/src/prism.c +130 -71
  138. data/vendor/prism/src/util/pm_string.c +6 -8
  139. data/vendor/prism/templates/include/prism/ast.h.erb +2 -0
  140. data/vendor/prism/templates/java/org/prism/Loader.java.erb +2 -2
  141. data/vendor/prism/templates/javascript/src/deserialize.js.erb +2 -2
  142. data/vendor/prism/templates/lib/prism/serialize.rb.erb +2 -2
  143. data/vendor/prism/templates/sig/prism.rbs.erb +4 -0
  144. data/vendor/prism/templates/src/diagnostic.c.erb +1 -0
  145. metadata +34 -20
  146. data/lib/herb/libherb/array.rb +0 -51
  147. data/lib/herb/libherb/ast_node.rb +0 -50
  148. data/lib/herb/libherb/buffer.rb +0 -56
  149. data/lib/herb/libherb/extract_result.rb +0 -20
  150. data/lib/herb/libherb/lex_result.rb +0 -32
  151. data/lib/herb/libherb/libherb.rb +0 -52
  152. data/lib/herb/libherb/parse_result.rb +0 -20
  153. data/lib/herb/libherb/token.rb +0 -46
  154. data/lib/herb/libherb.rb +0 -35
  155. data/src/buffer.c +0 -241
  156. data/src/include/array.h +0 -33
  157. data/src/include/buffer.h +0 -39
  158. data/src/include/json.h +0 -28
  159. data/src/include/memory.h +0 -12
  160. data/src/json.c +0 -205
  161. data/src/memory.c +0 -53
@@ -1,10 +1,10 @@
1
- #include "include/array.h"
2
1
  #include "include/errors.h"
3
2
  #include "include/location.h"
4
3
  #include "include/position.h"
5
4
  #include "include/pretty_print.h"
6
5
  #include "include/token.h"
7
6
  #include "include/util.h"
7
+ #include "include/util/hb_array.h"
8
8
 
9
9
  #include <stdio.h>
10
10
  #include <stdbool.h>
@@ -89,8 +89,8 @@ void error_init(ERROR_T* error, const error_type_T type, position_T start, posit
89
89
  return <%= error.human %>;
90
90
  }
91
91
 
92
- void append_<%= error.human %>(<%= (arguments + ["array_T* errors"]).join(", ") %>) {
93
- array_append(errors, <%= error.human %>_init(<%= arguments.map { |argument| argument.split(" ").last.strip }.join(", ") %>));
92
+ void append_<%= error.human %>(<%= (arguments + ["hb_array_T* errors"]).join(", ") %>) {
93
+ hb_array_append(errors, <%= error.human %>_init(<%= arguments.map { |argument| argument.split(" ").last.strip }.join(", ") %>));
94
94
  }
95
95
  <%- end -%>
96
96
 
@@ -158,73 +158,73 @@ void error_free(ERROR_T* error) {
158
158
  }
159
159
 
160
160
  void error_pretty_print_array(
161
- const char* name, array_T* array, const size_t indent, const size_t relative_indent, const bool last_property,
162
- buffer_T* buffer
161
+ const char* name, hb_array_T* array, const size_t indent, const size_t relative_indent, const bool last_property,
162
+ hb_buffer_T* buffer
163
163
  ) {
164
164
  if (array == NULL) {
165
- pretty_print_property(name, "∅", indent, relative_indent, last_property, buffer);
165
+ pretty_print_property(hb_string(name), hb_string("∅"), indent, relative_indent, last_property, buffer);
166
166
 
167
167
  return;
168
168
  }
169
169
 
170
- if (array_size(array) == 0) {
171
- pretty_print_property(name, "[]", indent, relative_indent, last_property, buffer);
170
+ if (hb_array_size(array) == 0) {
171
+ pretty_print_property(hb_string(name), hb_string("[]"), indent, relative_indent, last_property, buffer);
172
172
 
173
173
  return;
174
174
  }
175
175
 
176
- pretty_print_label(name, indent, relative_indent, last_property, buffer);
176
+ pretty_print_label(hb_string(name), indent, relative_indent, last_property, buffer);
177
177
 
178
- buffer_append(buffer, "(");
178
+ hb_buffer_append(buffer, "(");
179
179
 
180
180
  char count[16];
181
- sprintf(count, "%zu", array_size(array));
182
- buffer_append(buffer, count);
183
- buffer_append(buffer, ")\n");
181
+ sprintf(count, "%zu", hb_array_size(array));
182
+ hb_buffer_append(buffer, count);
183
+ hb_buffer_append(buffer, ")\n");
184
184
 
185
185
  if (indent < 20) {
186
- for (size_t i = 0; i < array_size(array); i++) {
187
- ERROR_T* child = array_get(array, i);
186
+ for (size_t i = 0; i < hb_array_size(array); i++) {
187
+ ERROR_T* child = hb_array_get(array, i);
188
188
  pretty_print_indent(buffer, indent);
189
189
  pretty_print_indent(buffer, relative_indent + 1);
190
190
 
191
- if (i == array_size(array) - 1) {
192
- buffer_append(buffer, "└── ");
191
+ if (i == hb_array_size(array) - 1) {
192
+ hb_buffer_append(buffer, "└── ");
193
193
  } else {
194
- buffer_append(buffer, "├── ");
194
+ hb_buffer_append(buffer, "├── ");
195
195
  }
196
196
 
197
197
  error_pretty_print(child, indent + 1, relative_indent + 1, buffer);
198
198
 
199
- if (i != array_size(array) - 1) { pretty_print_newline(indent + 1, relative_indent, buffer); }
199
+ if (i != hb_array_size(array) - 1) { pretty_print_newline(indent + 1, relative_indent, buffer); }
200
200
  }
201
201
  }
202
202
  }
203
203
 
204
204
  <%- errors.each do |error| -%>
205
- static void error_pretty_print_<%= error.human %>(<%= error.struct_type %>* error, const size_t indent, const size_t relative_indent, buffer_T* buffer) {
205
+ static void error_pretty_print_<%= error.human %>(<%= error.struct_type %>* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
206
206
  if (!error) { return; }
207
207
 
208
- buffer_append(buffer, "@ ");
209
- buffer_append(buffer, error_human_type((ERROR_T*) error));
210
- buffer_append(buffer, " ");
208
+ hb_buffer_append(buffer, "@ ");
209
+ hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
210
+ hb_buffer_append(buffer, " ");
211
211
 
212
212
  pretty_print_location(error->base.location, buffer);
213
- buffer_append(buffer, "\n");
213
+ hb_buffer_append(buffer, "\n");
214
214
 
215
- pretty_print_quoted_property("message", error->base.message, indent, relative_indent, <%= error.fields.none? %>, buffer);
215
+ pretty_print_quoted_property(hb_string("message"), hb_string(error->base.message), indent, relative_indent, <%= error.fields.none? %>, buffer);
216
216
  <%- error.fields.each_with_index do |field, index| -%>
217
217
  <%- case field -%>
218
218
  <%- when Herb::Template::PositionField -%>
219
- pretty_print_position_property(error-><%= field.name %>, "<%= field.name %>", indent, relative_indent, <%= error.fields.length - 1 == index %>, buffer);
219
+ pretty_print_position_property(hb_string(error-><%= field.name %>), hb_string("<%= field.name %>"), indent, relative_indent, <%= error.fields.length - 1 == index %>, buffer);
220
220
  <%- when Herb::Template::TokenField -%>
221
- pretty_print_token_property(error-><%= field.name %>, "<%= field.name %>", indent, relative_indent, <%= error.fields.length - 1 == index %>, buffer);
221
+ pretty_print_token_property(error-><%= field.name %>, hb_string("<%= field.name %>"), indent, relative_indent, <%= error.fields.length - 1 == index %>, buffer);
222
222
  <%- when Herb::Template::TokenTypeField -%>
223
- pretty_print_property(token_type_to_string(error-><%= field.name %>), "<%= field.name %>", indent, relative_indent, <%= error.fields.length - 1 == index %>, buffer);
223
+ pretty_print_property(hb_string(token_type_to_string(error-><%= field.name %>)), hb_string("<%= field.name %>"), indent, relative_indent, <%= error.fields.length - 1 == index %>, buffer);
224
224
  <%- when Herb::Template::SizeTField -%>
225
- pretty_print_size_t_property(error-><%= field.name %>, "<%= field.name %>", indent, relative_indent, <%= error.fields.length - 1 == index %>, buffer);
225
+ pretty_print_size_t_property(hb_string(error-><%= field.name %>), hb_string("<%= field.name %>"), indent, relative_indent, <%= error.fields.length - 1 == index %>, buffer);
226
226
  <%- when Herb::Template::StringField -%>
227
- pretty_print_quoted_property("<%= field.name %>", error-><%= field.name %>, indent, relative_indent, <%= error.fields.length - 1 == index %>, buffer);
227
+ pretty_print_quoted_property(hb_string("<%= field.name %>"), hb_string(error-><%= field.name %>), indent, relative_indent, <%= error.fields.length - 1 == index %>, buffer);
228
228
  <%- else -%>
229
229
  <%= field.inspect %>
230
230
  <%- end -%>
@@ -232,7 +232,7 @@ static void error_pretty_print_<%= error.human %>(<%= error.struct_type %>* erro
232
232
  }
233
233
 
234
234
  <%- end -%>
235
- void error_pretty_print(ERROR_T* error, const size_t indent, const size_t relative_indent, buffer_T* buffer) {
235
+ void error_pretty_print(ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
236
236
  if (!error) { return; }
237
237
 
238
238
  switch (error->type) {
@@ -4,13 +4,14 @@
4
4
  #include <stdbool.h>
5
5
  #include <prism.h>
6
6
 
7
- #include "array.h"
8
- #include "buffer.h"
9
- #include "position.h"
10
- #include "location.h"
11
- #include "token_struct.h"
12
7
  #include "analyzed_ruby.h"
13
8
  #include "element_source.h"
9
+ #include "location.h"
10
+ #include "position.h"
11
+ #include "token_struct.h"
12
+ #include "util/hb_array.h"
13
+ #include "util/hb_buffer.h"
14
+ #include "util/hb_string.h"
14
15
 
15
16
  typedef enum {
16
17
  <%- nodes.each do |node| -%>
@@ -22,7 +23,7 @@ typedef struct AST_NODE_STRUCT {
22
23
  ast_node_type_T type;
23
24
  location_T location;
24
25
  // maybe a range too?
25
- array_T* errors;
26
+ hb_array_T* errors;
26
27
  } AST_NODE_T;
27
28
 
28
29
  <%- nodes.each do |node| -%>
@@ -36,11 +37,11 @@ typedef struct <%= node.struct_name %> {
36
37
 
37
38
  <%- nodes.each do |node| -%>
38
39
  <%- node_arguments = node.fields.any? ? node.fields.map { |field| [field.c_type, " ", field.name].join } : [] -%>
39
- <%- arguments = node_arguments + ["position_T start_position", "position_T end_position", "array_T* errors"] -%>
40
+ <%- arguments = node_arguments + ["position_T start_position", "position_T end_position", "hb_array_T* errors"] -%>
40
41
  <%= node.struct_type %>* ast_<%= node.human %>_init(<%= arguments.join(", ") %>);
41
42
  <%- end -%>
42
43
 
43
- const char* ast_node_type_to_string(AST_NODE_T* node);
44
- const char* ast_node_human_type(AST_NODE_T* node);
44
+ hb_string_T ast_node_type_to_string(AST_NODE_T* node);
45
+ hb_string_T ast_node_human_type(AST_NODE_T* node);
45
46
 
46
47
  #endif
@@ -2,13 +2,13 @@
2
2
  #define HERB_AST_PRETTY_PRINT_H
3
3
 
4
4
  #include "ast_nodes.h"
5
- #include "buffer.h"
5
+ #include "util/hb_buffer.h"
6
6
 
7
7
  void ast_pretty_print_node(
8
8
  AST_NODE_T* node,
9
9
  size_t indent,
10
10
  size_t relative_indent,
11
- buffer_T* buffer
11
+ hb_buffer_T* buffer
12
12
  );
13
13
 
14
14
  #endif
@@ -1,12 +1,12 @@
1
1
  #ifndef HERB_ERRORS_H
2
2
  #define HERB_ERRORS_H
3
3
 
4
- #include "array.h"
5
- #include "buffer.h"
6
4
  #include "errors.h"
7
5
  #include "location.h"
8
6
  #include "position.h"
9
7
  #include "token.h"
8
+ #include "util/hb_array.h"
9
+ #include "util/hb_buffer.h"
10
10
 
11
11
  typedef enum {
12
12
  <%- errors.each do |error| -%>
@@ -33,7 +33,7 @@ typedef struct {
33
33
  <%- error_arguments = error.fields.any? ? error.fields.map { |field| [field.c_type, " ", field.name].join } : [] -%>
34
34
  <%- arguments = error_arguments + ["position_T start", "position_T end"] -%>
35
35
  <%= error.struct_type %>* <%= error.human %>_init(<%= arguments.join(", ") %>);
36
- void append_<%= error.human %>(<%= (arguments << "array_T* errors").join(", ") %>);
36
+ void append_<%= error.human %>(<%= (arguments << "hb_array_T* errors").join(", ") %>);
37
37
  <%- end -%>
38
38
 
39
39
  void error_init(ERROR_T* error, error_type_T type, position_T start, position_T end);
@@ -48,11 +48,11 @@ const char* error_human_type(ERROR_T* error);
48
48
 
49
49
  void error_free(ERROR_T* error);
50
50
 
51
- void error_pretty_print(ERROR_T* error, size_t indent, size_t relative_indent, buffer_T* buffer);
51
+ void error_pretty_print(ERROR_T* error, size_t indent, size_t relative_indent, hb_buffer_T* buffer);
52
52
 
53
53
  void error_pretty_print_array(
54
- const char* name, array_T* array, size_t indent, size_t relative_indent, bool last_property,
55
- buffer_T* buffer
54
+ const char* name, hb_array_T* array, size_t indent, size_t relative_indent, bool last_property,
55
+ hb_buffer_T* buffer
56
56
  );
57
57
 
58
58
  #endif
@@ -0,0 +1,38 @@
1
+ #include "include/parser.h"
2
+ #include "include/ast_nodes.h"
3
+ #include "include/util/hb_array.h"
4
+ #include "include/visitor.h"
5
+
6
+ bool match_tags_visitor(const AST_NODE_T* node, void* data) {
7
+ hb_array_T* errors = (hb_array_T*) data;
8
+
9
+ if (node == NULL) { return false; }
10
+
11
+ switch (node->type) {
12
+ <%- nodes.each do |node| -%>
13
+ <%- array_fields = node.fields.select { |f| f.is_a?(Herb::Template::ArrayField) && f.name != "errors" } -%>
14
+ <%- single_node_fields = node.fields.select { |f| f.is_a?(Herb::Template::NodeField) } -%>
15
+
16
+ <%- if array_fields.any? || single_node_fields.any? -%>
17
+ case <%= node.type %>: {
18
+ const <%= node.struct_type %>* <%= node.human %> = (const <%= node.struct_type %>*) node;
19
+
20
+ <%- array_fields.each do |field| -%>
21
+ if (<%= node.human %>-><%= field.name %> != NULL) {
22
+ match_tags_in_node_array(<%= node.human %>-><%= field.name %>, errors);
23
+ }
24
+ <%- end -%>
25
+ <%- single_node_fields.each do |field| -%>
26
+ if (<%= node.human %>-><%= field.name %> != NULL) {
27
+ herb_visit_node((AST_NODE_T*) <%= node.human %>-><%= field.name %>, match_tags_visitor, errors);
28
+ }
29
+ <%- end -%>
30
+ } break;
31
+
32
+ <%- end -%>
33
+ <%- end -%>
34
+ default: break;
35
+ }
36
+
37
+ return false;
38
+ }
@@ -1,9 +1,9 @@
1
1
  #include <stdio.h>
2
2
 
3
- #include "include/array.h"
4
- #include "include/visitor.h"
5
3
  #include "include/ast_node.h"
6
4
  #include "include/ast_nodes.h"
5
+ #include "include/util/hb_array.h"
6
+ #include "include/visitor.h"
7
7
 
8
8
  void herb_visit_node(const AST_NODE_T* node, bool (*visitor)(const AST_NODE_T*, void*), void* data) {
9
9
  if (visitor(node, data) && node != NULL) {
@@ -31,8 +31,8 @@ void herb_visit_child_nodes(const AST_NODE_T *node, bool (*visitor)(const AST_NO
31
31
 
32
32
  <%- when Herb::Template::ArrayField -%>
33
33
  if (<%= node.human %>-><%= field.name %> != NULL) {
34
- for (size_t index = 0; index < array_size(<%= node.human %>-><%= field.name %>); index++) {
35
- herb_visit_node(array_get(<%= node.human %>-><%= field.name %>, index), visitor, data);
34
+ for (size_t index = 0; index < hb_array_size(<%= node.human %>-><%= field.name %>); index++) {
35
+ herb_visit_node(hb_array_get(<%= node.human %>-><%= field.name %>, index), visitor, data);
36
36
  }
37
37
  }
38
38
 
@@ -30,7 +30,7 @@ module Herb
30
30
  end
31
31
 
32
32
  def c_type
33
- "array_T*"
33
+ "hb_array_T*"
34
34
  end
35
35
 
36
36
  def c_item_type
@@ -245,6 +245,10 @@ module Herb
245
245
  type.new(name: field_name, kind: kind)
246
246
  end
247
247
  end
248
+
249
+ def c_type
250
+ @struct_type
251
+ end
248
252
  end
249
253
 
250
254
  class NodeType
@@ -268,6 +272,10 @@ module Herb
268
272
  type.new(name: field_name, kind: kind)
269
273
  end
270
274
  end
275
+
276
+ def c_type
277
+ @struct_type
278
+ end
271
279
  end
272
280
 
273
281
  class PrintfMessageTemplate
@@ -331,6 +339,8 @@ module Herb
331
339
  end
332
340
 
333
341
  def self.render(template_file)
342
+ template_file_display = template_file.delete_prefix("#{File.expand_path("../", __dir__)}/")
343
+
334
344
  name = Pathname.new(template_file)
335
345
  name = if name.absolute?
336
346
  template_file.gsub(
@@ -351,8 +361,6 @@ module Herb
351
361
  )
352
362
  end
353
363
 
354
- puts "Rendering #{template_file.delete_prefix("#{File.expand_path("../", __dir__)}/")} → #{destination}"
355
-
356
364
  template_file = Pathname.new(template_file)
357
365
  template_path = if template_file.absolute?
358
366
  template_file
@@ -367,6 +375,17 @@ module Herb
367
375
 
368
376
  check_gitignore(name)
369
377
 
378
+ if File.exist?(destination)
379
+ existing_content = File.read(destination, encoding: Encoding::UTF_8)
380
+
381
+ if existing_content == content
382
+ puts "[unchanged] #{destination}"
383
+ return
384
+ end
385
+ end
386
+
387
+ puts "Rendering #{template_file_display} → #{destination}"
388
+
370
389
  FileUtils.mkdir_p(File.dirname(destination))
371
390
  File.write(destination, content)
372
391
  rescue SyntaxError => e
@@ -8,12 +8,12 @@
8
8
  #include "extension_helpers.h"
9
9
 
10
10
  extern "C" {
11
- #include "../src/include/herb.h"
12
- #include "../src/include/token.h"
13
- #include "../src/include/array.h"
14
- #include "../src/include/errors.h"
15
11
  #include "../src/include/ast_node.h"
16
12
  #include "../src/include/ast_nodes.h"
13
+ #include "../src/include/errors.h"
14
+ #include "../src/include/herb.h"
15
+ #include "../src/include/token.h"
16
+ #include "../src/include/util/hb_array.h"
17
17
  }
18
18
 
19
19
  using namespace emscripten;
@@ -21,9 +21,9 @@ using namespace emscripten;
21
21
  val CreateLocation(location_T* location);
22
22
  val CreateToken(token_T* token);
23
23
  val NodeFromCStruct(AST_NODE_T* node);
24
- val NodesArrayFromCArray(array_T* array);
24
+ val NodesArrayFromCArray(hb_array_T* array);
25
25
  val ErrorFromCStruct(ERROR_T* error);
26
- val ErrorsArrayFromCArray(array_T* array);
26
+ val ErrorsArrayFromCArray(hb_array_T* array);
27
27
 
28
28
  <%- errors.each do |error| -%>
29
29
  val <%= error.name %>FromCStruct(<%= error.struct_type %>* <%= error.human %>) {
@@ -61,13 +61,13 @@ val <%= error.name %>FromCStruct(<%= error.struct_type %>* <%= error.human %>) {
61
61
 
62
62
  <%- end -%>
63
63
 
64
- val ErrorsArrayFromCArray(array_T* array) {
64
+ val ErrorsArrayFromCArray(hb_array_T* array) {
65
65
  val Array = val::global("Array");
66
66
  val result = Array.new_();
67
67
 
68
68
  if (array) {
69
- for (size_t i = 0; i < array_size(array); i++) {
70
- ERROR_T* error = (ERROR_T*)array_get(array, i);
69
+ for (size_t i = 0; i < hb_array_size(array); i++) {
70
+ ERROR_T* error = (ERROR_T*)hb_array_get(array, i);
71
71
  if (error) {
72
72
  result.call<void>("push", ErrorFromCStruct(error));
73
73
  }
@@ -6,7 +6,7 @@ extern "C" {
6
6
  }
7
7
 
8
8
  emscripten::val ErrorFromCStruct(ERROR_T* error);
9
- emscripten::val ErrorsArrayFromCArray(array_T* array);
9
+ emscripten::val ErrorsArrayFromCArray(hb_array_T* array);
10
10
 
11
11
  <%- errors.each do |error| -%>
12
12
  emscripten::val <%= error.name %>FromCStruct(<%= error.struct_type %>* <%= error.human %>);
@@ -4,24 +4,24 @@
4
4
  #include "error_helpers.h"
5
5
  #include "extension_helpers.h"
6
6
 
7
- #include "../src/include/herb.h"
8
- #include "../src/include/token.h"
9
- #include "../src/include/array.h"
10
7
  #include "../src/include/ast_node.h"
11
8
  #include "../src/include/ast_nodes.h"
9
+ #include "../src/include/herb.h"
12
10
  #include "../src/include/location.h"
11
+ #include "../src/include/token.h"
12
+ #include "../src/include/util/hb_array.h"
13
13
 
14
14
  using namespace emscripten;
15
15
 
16
16
  val NodeFromCStruct(AST_NODE_T* node);
17
- val NodesArrayFromCArray(array_T* array);
17
+ val NodesArrayFromCArray(hb_array_T* array);
18
18
 
19
19
  <%- nodes.each do |node| -%>
20
20
  val <%= node.name %>FromCStruct(<%= node.struct_type %>* <%= node.human %>) {
21
21
  if (!<%= node.human %>) return val::null();
22
22
 
23
23
  val result = val::object();
24
- result.set("type", CreateString(ast_node_type_to_string(&<%= node.human %>->base)));
24
+ result.set("type", CreateStringFromHbString(ast_node_type_to_string(&<%= node.human %>->base)));
25
25
  result.set("location", CreateLocation(<%= node.human %>->base.location));
26
26
  result.set("errors", ErrorsArrayFromCArray(<%= node.human %>->base.errors));
27
27
 
@@ -38,7 +38,7 @@ val <%= node.name %>FromCStruct(<%= node.struct_type %>* <%= node.human %>) {
38
38
  <%- when Herb::Template::ArrayField -%>
39
39
  result.set("<%= field.name %>", NodesArrayFromCArray(<%= node.human %>-><%= field.name %>));
40
40
  <%- when Herb::Template::ElementSourceField -%>
41
- result.set("<%= field.name %>", CreateString(element_source_to_string(<%= node.human %>-><%= field.name %>)));
41
+ result.set("<%= field.name %>", CreateStringFromHbString(element_source_to_string(<%= node.human %>-><%= field.name %>)));
42
42
  <%- else -%>
43
43
  result.set("<%= field.name %>", val::null());
44
44
  <%- end -%>
@@ -62,13 +62,13 @@ val NodeFromCStruct(AST_NODE_T* node) {
62
62
  }
63
63
  }
64
64
 
65
- val NodesArrayFromCArray(array_T* array) {
65
+ val NodesArrayFromCArray(hb_array_T* array) {
66
66
  if (!array) return val::null();
67
67
 
68
68
  val jsArray = val::array();
69
69
 
70
- for (size_t i = 0; i < array_size(array); i++) {
71
- AST_NODE_T* child_node = (AST_NODE_T*) array_get(array, i);
70
+ for (size_t i = 0; i < hb_array_size(array); i++) {
71
+ AST_NODE_T* child_node = (AST_NODE_T*) hb_array_get(array, i);
72
72
 
73
73
  if (child_node) {
74
74
  jsArray.set(i, NodeFromCStruct(child_node));
@@ -6,7 +6,7 @@ extern "C" {
6
6
  }
7
7
 
8
8
  emscripten::val NodeFromCStruct(AST_NODE_T* node);
9
- emscripten::val NodesArrayFromCArray(array_T* array);
9
+ emscripten::val NodesArrayFromCArray(hb_array_T* array);
10
10
 
11
11
  <%- nodes.each do |node| -%>
12
12
  emscripten::val <%= node.human %>NodeFromCStruct(<%= node.struct_type %>* <%= node.human %>);
@@ -11,7 +11,10 @@ desc "Generate all ERB template based files"
11
11
  task templates: Prism::Template::TEMPLATES
12
12
 
13
13
  make = RUBY_PLATFORM.match?(/openbsd|freebsd/) ? "gmake" : "make"
14
- task(make: :templates) { sh(make) }
14
+ task(make: :templates) {
15
+ ENV["MAKEFLAGS"] ||= "-j"
16
+ sh(make)
17
+ }
15
18
  task(make_no_debug: :templates) { sh("#{make} all-no-debug") }
16
19
  task(make_minimal: :templates) { sh("#{make} minimal") }
17
20
 
@@ -60,6 +60,7 @@ errors:
60
60
  - CONDITIONAL_WHILE_PREDICATE
61
61
  - CONSTANT_PATH_COLON_COLON_CONSTANT
62
62
  - DEF_ENDLESS
63
+ - DEF_ENDLESS_PARAMETERS
63
64
  - DEF_ENDLESS_SETTER
64
65
  - DEF_NAME
65
66
  - DEF_PARAMS_TERM
@@ -1800,7 +1801,7 @@ nodes:
1800
1801
  Represents the predicate of the case statement. This can be either `nil` or any [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression).
1801
1802
 
1802
1803
  case true; when false; end
1803
- ^^^^
1804
+ ^^^^
1804
1805
  - name: conditions
1805
1806
  type: node[]
1806
1807
  kind: WhenNode
@@ -2638,7 +2638,7 @@ typedef struct pm_case_node {
2638
2638
  * Represents the predicate of the case statement. This can be either `nil` or any [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression).
2639
2639
  *
2640
2640
  * case true; when false; end
2641
- * ^^^^
2641
+ * ^^^^
2642
2642
  */
2643
2643
  struct pm_node *predicate;
2644
2644
 
@@ -7990,6 +7990,8 @@ typedef enum pm_arguments_node_flags {
7990
7990
 
7991
7991
  /** if the arguments contain multiple splats */
7992
7992
  PM_ARGUMENTS_NODE_FLAGS_CONTAINS_MULTIPLE_SPLATS = 64,
7993
+
7994
+ PM_ARGUMENTS_NODE_FLAGS_LAST,
7993
7995
  } pm_arguments_node_flags_t;
7994
7996
 
7995
7997
  /**
@@ -7998,6 +8000,8 @@ typedef enum pm_arguments_node_flags {
7998
8000
  typedef enum pm_array_node_flags {
7999
8001
  /** if array contains splat nodes */
8000
8002
  PM_ARRAY_NODE_FLAGS_CONTAINS_SPLAT = 4,
8003
+
8004
+ PM_ARRAY_NODE_FLAGS_LAST,
8001
8005
  } pm_array_node_flags_t;
8002
8006
 
8003
8007
  /**
@@ -8015,6 +8019,8 @@ typedef enum pm_call_node_flags {
8015
8019
 
8016
8020
  /** a call that ignores method visibility */
8017
8021
  PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY = 32,
8022
+
8023
+ PM_CALL_NODE_FLAGS_LAST,
8018
8024
  } pm_call_node_flags_t;
8019
8025
 
8020
8026
  /**
@@ -8026,6 +8032,8 @@ typedef enum pm_encoding_flags {
8026
8032
 
8027
8033
  /** internal bytes forced the encoding to binary */
8028
8034
  PM_ENCODING_FLAGS_FORCED_BINARY_ENCODING = 8,
8035
+
8036
+ PM_ENCODING_FLAGS_LAST,
8029
8037
  } pm_encoding_flags_t;
8030
8038
 
8031
8039
  /**
@@ -8043,6 +8051,8 @@ typedef enum pm_integer_base_flags {
8043
8051
 
8044
8052
  /** 0x prefix */
8045
8053
  PM_INTEGER_BASE_FLAGS_HEXADECIMAL = 32,
8054
+
8055
+ PM_INTEGER_BASE_FLAGS_LAST,
8046
8056
  } pm_integer_base_flags_t;
8047
8057
 
8048
8058
  /**
@@ -8054,6 +8064,8 @@ typedef enum pm_interpolated_string_node_flags {
8054
8064
 
8055
8065
  /** mutable by virtue of a `frozen_string_literal: false` comment or `--disable-frozen-string-literal`; only for adjacent string literals like `'a' 'b'` */
8056
8066
  PM_INTERPOLATED_STRING_NODE_FLAGS_MUTABLE = 8,
8067
+
8068
+ PM_INTERPOLATED_STRING_NODE_FLAGS_LAST,
8057
8069
  } pm_interpolated_string_node_flags_t;
8058
8070
 
8059
8071
  /**
@@ -8062,6 +8074,8 @@ typedef enum pm_interpolated_string_node_flags {
8062
8074
  typedef enum pm_keyword_hash_node_flags {
8063
8075
  /** a keyword hash which only has `AssocNode` elements all with symbol keys, which means the elements can be treated as keyword arguments */
8064
8076
  PM_KEYWORD_HASH_NODE_FLAGS_SYMBOL_KEYS = 4,
8077
+
8078
+ PM_KEYWORD_HASH_NODE_FLAGS_LAST,
8065
8079
  } pm_keyword_hash_node_flags_t;
8066
8080
 
8067
8081
  /**
@@ -8070,6 +8084,8 @@ typedef enum pm_keyword_hash_node_flags {
8070
8084
  typedef enum pm_loop_flags {
8071
8085
  /** a loop after a begin statement, so the body is executed first before the condition */
8072
8086
  PM_LOOP_FLAGS_BEGIN_MODIFIER = 4,
8087
+
8088
+ PM_LOOP_FLAGS_LAST,
8073
8089
  } pm_loop_flags_t;
8074
8090
 
8075
8091
  /**
@@ -8078,6 +8094,8 @@ typedef enum pm_loop_flags {
8078
8094
  typedef enum pm_parameter_flags {
8079
8095
  /** a parameter name that has been repeated in the method signature */
8080
8096
  PM_PARAMETER_FLAGS_REPEATED_PARAMETER = 4,
8097
+
8098
+ PM_PARAMETER_FLAGS_LAST,
8081
8099
  } pm_parameter_flags_t;
8082
8100
 
8083
8101
  /**
@@ -8086,6 +8104,8 @@ typedef enum pm_parameter_flags {
8086
8104
  typedef enum pm_parentheses_node_flags {
8087
8105
  /** parentheses that contain multiple potentially void statements */
8088
8106
  PM_PARENTHESES_NODE_FLAGS_MULTIPLE_STATEMENTS = 4,
8107
+
8108
+ PM_PARENTHESES_NODE_FLAGS_LAST,
8089
8109
  } pm_parentheses_node_flags_t;
8090
8110
 
8091
8111
  /**
@@ -8094,6 +8114,8 @@ typedef enum pm_parentheses_node_flags {
8094
8114
  typedef enum pm_range_flags {
8095
8115
  /** ... operator */
8096
8116
  PM_RANGE_FLAGS_EXCLUDE_END = 4,
8117
+
8118
+ PM_RANGE_FLAGS_LAST,
8097
8119
  } pm_range_flags_t;
8098
8120
 
8099
8121
  /**
@@ -8132,6 +8154,8 @@ typedef enum pm_regular_expression_flags {
8132
8154
 
8133
8155
  /** internal bytes forced the encoding to US-ASCII */
8134
8156
  PM_REGULAR_EXPRESSION_FLAGS_FORCED_US_ASCII_ENCODING = 4096,
8157
+
8158
+ PM_REGULAR_EXPRESSION_FLAGS_LAST,
8135
8159
  } pm_regular_expression_flags_t;
8136
8160
 
8137
8161
  /**
@@ -8146,6 +8170,8 @@ typedef enum pm_shareable_constant_node_flags {
8146
8170
 
8147
8171
  /** constant writes that should be modified with shareable constant value experimental copy */
8148
8172
  PM_SHAREABLE_CONSTANT_NODE_FLAGS_EXPERIMENTAL_COPY = 16,
8173
+
8174
+ PM_SHAREABLE_CONSTANT_NODE_FLAGS_LAST,
8149
8175
  } pm_shareable_constant_node_flags_t;
8150
8176
 
8151
8177
  /**
@@ -8163,6 +8189,8 @@ typedef enum pm_string_flags {
8163
8189
 
8164
8190
  /** mutable by virtue of a `frozen_string_literal: false` comment or `--disable-frozen-string-literal` */
8165
8191
  PM_STRING_FLAGS_MUTABLE = 32,
8192
+
8193
+ PM_STRING_FLAGS_LAST,
8166
8194
  } pm_string_flags_t;
8167
8195
 
8168
8196
  /**
@@ -8177,6 +8205,8 @@ typedef enum pm_symbol_flags {
8177
8205
 
8178
8206
  /** internal bytes forced the encoding to US-ASCII */
8179
8207
  PM_SYMBOL_FLAGS_FORCED_US_ASCII_ENCODING = 16,
8208
+
8209
+ PM_SYMBOL_FLAGS_LAST,
8180
8210
  } pm_symbol_flags_t;
8181
8211
 
8182
8212
  /**
@@ -91,6 +91,7 @@ typedef enum {
91
91
  PM_ERR_CONDITIONAL_WHILE_PREDICATE,
92
92
  PM_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT,
93
93
  PM_ERR_DEF_ENDLESS,
94
+ PM_ERR_DEF_ENDLESS_PARAMETERS,
94
95
  PM_ERR_DEF_ENDLESS_SETTER,
95
96
  PM_ERR_DEF_NAME,
96
97
  PM_ERR_DEF_PARAMS_TERM,