herb 0.1.0-x86_64-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 (110) hide show
  1. checksums.yaml +7 -0
  2. data/License.txt +21 -0
  3. data/Makefile +121 -0
  4. data/README.md +166 -0
  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/3.0/herb.so +0 -0
  18. data/lib/herb/3.1/herb.so +0 -0
  19. data/lib/herb/3.2/herb.so +0 -0
  20. data/lib/herb/3.3/herb.so +0 -0
  21. data/lib/herb/3.4/herb.so +0 -0
  22. data/lib/herb/ast/node.rb +61 -0
  23. data/lib/herb/ast/nodes.rb +1542 -0
  24. data/lib/herb/ast.rb +6 -0
  25. data/lib/herb/cli.rb +164 -0
  26. data/lib/herb/errors.rb +352 -0
  27. data/lib/herb/lex_result.rb +20 -0
  28. data/lib/herb/libherb/array.rb +48 -0
  29. data/lib/herb/libherb/ast_node.rb +47 -0
  30. data/lib/herb/libherb/buffer.rb +53 -0
  31. data/lib/herb/libherb/extract_result.rb +17 -0
  32. data/lib/herb/libherb/lex_result.rb +29 -0
  33. data/lib/herb/libherb/libherb.rb +49 -0
  34. data/lib/herb/libherb/parse_result.rb +17 -0
  35. data/lib/herb/libherb/token.rb +43 -0
  36. data/lib/herb/libherb.rb +32 -0
  37. data/lib/herb/location.rb +42 -0
  38. data/lib/herb/parse_result.rb +26 -0
  39. data/lib/herb/position.rb +36 -0
  40. data/lib/herb/project.rb +361 -0
  41. data/lib/herb/range.rb +40 -0
  42. data/lib/herb/result.rb +21 -0
  43. data/lib/herb/token.rb +43 -0
  44. data/lib/herb/token_list.rb +11 -0
  45. data/lib/herb/version.rb +5 -0
  46. data/lib/herb.rb +32 -0
  47. data/src/analyze.c +989 -0
  48. data/src/analyze_helpers.c +241 -0
  49. data/src/analyzed_ruby.c +35 -0
  50. data/src/array.c +137 -0
  51. data/src/ast_node.c +81 -0
  52. data/src/ast_nodes.c +866 -0
  53. data/src/ast_pretty_print.c +588 -0
  54. data/src/buffer.c +199 -0
  55. data/src/errors.c +740 -0
  56. data/src/extract.c +110 -0
  57. data/src/herb.c +103 -0
  58. data/src/html_util.c +143 -0
  59. data/src/include/analyze.h +36 -0
  60. data/src/include/analyze_helpers.h +43 -0
  61. data/src/include/analyzed_ruby.h +33 -0
  62. data/src/include/array.h +33 -0
  63. data/src/include/ast_node.h +35 -0
  64. data/src/include/ast_nodes.h +303 -0
  65. data/src/include/ast_pretty_print.h +17 -0
  66. data/src/include/buffer.h +36 -0
  67. data/src/include/errors.h +125 -0
  68. data/src/include/extract.h +20 -0
  69. data/src/include/herb.h +32 -0
  70. data/src/include/html_util.h +13 -0
  71. data/src/include/io.h +9 -0
  72. data/src/include/json.h +28 -0
  73. data/src/include/lexer.h +13 -0
  74. data/src/include/lexer_peek_helpers.h +23 -0
  75. data/src/include/lexer_struct.h +32 -0
  76. data/src/include/location.h +25 -0
  77. data/src/include/macros.h +10 -0
  78. data/src/include/memory.h +12 -0
  79. data/src/include/parser.h +22 -0
  80. data/src/include/parser_helpers.h +33 -0
  81. data/src/include/position.h +22 -0
  82. data/src/include/pretty_print.h +53 -0
  83. data/src/include/prism_helpers.h +18 -0
  84. data/src/include/range.h +23 -0
  85. data/src/include/ruby_parser.h +6 -0
  86. data/src/include/token.h +25 -0
  87. data/src/include/token_matchers.h +21 -0
  88. data/src/include/token_struct.h +51 -0
  89. data/src/include/util.h +25 -0
  90. data/src/include/version.h +6 -0
  91. data/src/include/visitor.h +11 -0
  92. data/src/io.c +30 -0
  93. data/src/json.c +205 -0
  94. data/src/lexer.c +284 -0
  95. data/src/lexer_peek_helpers.c +59 -0
  96. data/src/location.c +41 -0
  97. data/src/main.c +162 -0
  98. data/src/memory.c +53 -0
  99. data/src/parser.c +704 -0
  100. data/src/parser_helpers.c +161 -0
  101. data/src/position.c +33 -0
  102. data/src/pretty_print.c +242 -0
  103. data/src/prism_helpers.c +50 -0
  104. data/src/range.c +38 -0
  105. data/src/ruby_parser.c +47 -0
  106. data/src/token.c +194 -0
  107. data/src/token_matchers.c +32 -0
  108. data/src/util.c +128 -0
  109. data/src/visitor.c +321 -0
  110. metadata +159 -0
@@ -0,0 +1,302 @@
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/ext/herb/error_helpers.c.erb
3
+
4
+ #include <ruby.h>
5
+
6
+ #include "extension.h"
7
+ #include "extension_helpers.h"
8
+ #include "error_helpers.h"
9
+
10
+ #include "../../src/include/errors.h"
11
+ #include "../../src/include/herb.h"
12
+ #include "../../src/include/token.h"
13
+
14
+ VALUE rb_error_from_c_struct(ERROR_T* error);
15
+
16
+ static VALUE rb_unexpected_error_from_c_struct(UNEXPECTED_ERROR_T* unexpected_error) {
17
+ if (unexpected_error == NULL) { return Qnil; }
18
+
19
+ ERROR_T* error = &unexpected_error->base;
20
+
21
+ VALUE Herb = rb_define_module("Herb");
22
+ VALUE Errors = rb_define_module_under(Herb, "Errors");
23
+ VALUE Error = rb_define_class_under(Errors, "Error", rb_cObject);
24
+ VALUE UnexpectedError = rb_define_class_under(Errors, "UnexpectedError", Error);
25
+
26
+ VALUE type = rb_str_new_cstr(error_type_to_string(error));
27
+ VALUE location = rb_location_from_c_struct(error->location);
28
+ VALUE message = rb_str_new_cstr(error->message);
29
+
30
+ VALUE unexpected_error_description = rb_str_new_cstr(unexpected_error->description);
31
+ VALUE unexpected_error_expected = rb_str_new_cstr(unexpected_error->expected);
32
+ VALUE unexpected_error_found = rb_str_new_cstr(unexpected_error->found);
33
+
34
+ VALUE args[6] = {
35
+ type,
36
+ location,
37
+ message,
38
+ unexpected_error_description,
39
+ unexpected_error_expected,
40
+ unexpected_error_found
41
+ };
42
+
43
+ return rb_class_new_instance(6, args, UnexpectedError);
44
+ };
45
+
46
+ static VALUE rb_unexpected_token_error_from_c_struct(UNEXPECTED_TOKEN_ERROR_T* unexpected_token_error) {
47
+ if (unexpected_token_error == NULL) { return Qnil; }
48
+
49
+ ERROR_T* error = &unexpected_token_error->base;
50
+
51
+ VALUE Herb = rb_define_module("Herb");
52
+ VALUE Errors = rb_define_module_under(Herb, "Errors");
53
+ VALUE Error = rb_define_class_under(Errors, "Error", rb_cObject);
54
+ VALUE UnexpectedTokenError = rb_define_class_under(Errors, "UnexpectedTokenError", Error);
55
+
56
+ VALUE type = rb_str_new_cstr(error_type_to_string(error));
57
+ VALUE location = rb_location_from_c_struct(error->location);
58
+ VALUE message = rb_str_new_cstr(error->message);
59
+
60
+ VALUE unexpected_token_error_expected_type = rb_str_new_cstr(token_type_to_string(unexpected_token_error->expected_type));
61
+ VALUE unexpected_token_error_found = rb_token_from_c_struct(unexpected_token_error->found);
62
+
63
+ VALUE args[5] = {
64
+ type,
65
+ location,
66
+ message,
67
+ unexpected_token_error_expected_type,
68
+ unexpected_token_error_found
69
+ };
70
+
71
+ return rb_class_new_instance(5, args, UnexpectedTokenError);
72
+ };
73
+
74
+ static VALUE rb_missing_opening_tag_error_from_c_struct(MISSING_OPENING_TAG_ERROR_T* missing_opening_tag_error) {
75
+ if (missing_opening_tag_error == NULL) { return Qnil; }
76
+
77
+ ERROR_T* error = &missing_opening_tag_error->base;
78
+
79
+ VALUE Herb = rb_define_module("Herb");
80
+ VALUE Errors = rb_define_module_under(Herb, "Errors");
81
+ VALUE Error = rb_define_class_under(Errors, "Error", rb_cObject);
82
+ VALUE MissingOpeningTagError = rb_define_class_under(Errors, "MissingOpeningTagError", Error);
83
+
84
+ VALUE type = rb_str_new_cstr(error_type_to_string(error));
85
+ VALUE location = rb_location_from_c_struct(error->location);
86
+ VALUE message = rb_str_new_cstr(error->message);
87
+
88
+ VALUE missing_opening_tag_error_closing_tag = rb_token_from_c_struct(missing_opening_tag_error->closing_tag);
89
+
90
+ VALUE args[4] = {
91
+ type,
92
+ location,
93
+ message,
94
+ missing_opening_tag_error_closing_tag
95
+ };
96
+
97
+ return rb_class_new_instance(4, args, MissingOpeningTagError);
98
+ };
99
+
100
+ static VALUE rb_missing_closing_tag_error_from_c_struct(MISSING_CLOSING_TAG_ERROR_T* missing_closing_tag_error) {
101
+ if (missing_closing_tag_error == NULL) { return Qnil; }
102
+
103
+ ERROR_T* error = &missing_closing_tag_error->base;
104
+
105
+ VALUE Herb = rb_define_module("Herb");
106
+ VALUE Errors = rb_define_module_under(Herb, "Errors");
107
+ VALUE Error = rb_define_class_under(Errors, "Error", rb_cObject);
108
+ VALUE MissingClosingTagError = rb_define_class_under(Errors, "MissingClosingTagError", Error);
109
+
110
+ VALUE type = rb_str_new_cstr(error_type_to_string(error));
111
+ VALUE location = rb_location_from_c_struct(error->location);
112
+ VALUE message = rb_str_new_cstr(error->message);
113
+
114
+ VALUE missing_closing_tag_error_opening_tag = rb_token_from_c_struct(missing_closing_tag_error->opening_tag);
115
+
116
+ VALUE args[4] = {
117
+ type,
118
+ location,
119
+ message,
120
+ missing_closing_tag_error_opening_tag
121
+ };
122
+
123
+ return rb_class_new_instance(4, args, MissingClosingTagError);
124
+ };
125
+
126
+ static VALUE rb_tag_names_mismatch_error_from_c_struct(TAG_NAMES_MISMATCH_ERROR_T* tag_names_mismatch_error) {
127
+ if (tag_names_mismatch_error == NULL) { return Qnil; }
128
+
129
+ ERROR_T* error = &tag_names_mismatch_error->base;
130
+
131
+ VALUE Herb = rb_define_module("Herb");
132
+ VALUE Errors = rb_define_module_under(Herb, "Errors");
133
+ VALUE Error = rb_define_class_under(Errors, "Error", rb_cObject);
134
+ VALUE TagNamesMismatchError = rb_define_class_under(Errors, "TagNamesMismatchError", Error);
135
+
136
+ VALUE type = rb_str_new_cstr(error_type_to_string(error));
137
+ VALUE location = rb_location_from_c_struct(error->location);
138
+ VALUE message = rb_str_new_cstr(error->message);
139
+
140
+ VALUE tag_names_mismatch_error_opening_tag = rb_token_from_c_struct(tag_names_mismatch_error->opening_tag);
141
+ VALUE tag_names_mismatch_error_closing_tag = rb_token_from_c_struct(tag_names_mismatch_error->closing_tag);
142
+
143
+ VALUE args[5] = {
144
+ type,
145
+ location,
146
+ message,
147
+ tag_names_mismatch_error_opening_tag,
148
+ tag_names_mismatch_error_closing_tag
149
+ };
150
+
151
+ return rb_class_new_instance(5, args, TagNamesMismatchError);
152
+ };
153
+
154
+ static VALUE rb_quotes_mismatch_error_from_c_struct(QUOTES_MISMATCH_ERROR_T* quotes_mismatch_error) {
155
+ if (quotes_mismatch_error == NULL) { return Qnil; }
156
+
157
+ ERROR_T* error = &quotes_mismatch_error->base;
158
+
159
+ VALUE Herb = rb_define_module("Herb");
160
+ VALUE Errors = rb_define_module_under(Herb, "Errors");
161
+ VALUE Error = rb_define_class_under(Errors, "Error", rb_cObject);
162
+ VALUE QuotesMismatchError = rb_define_class_under(Errors, "QuotesMismatchError", Error);
163
+
164
+ VALUE type = rb_str_new_cstr(error_type_to_string(error));
165
+ VALUE location = rb_location_from_c_struct(error->location);
166
+ VALUE message = rb_str_new_cstr(error->message);
167
+
168
+ VALUE quotes_mismatch_error_opening_quote = rb_token_from_c_struct(quotes_mismatch_error->opening_quote);
169
+ VALUE quotes_mismatch_error_closing_quote = rb_token_from_c_struct(quotes_mismatch_error->closing_quote);
170
+
171
+ VALUE args[5] = {
172
+ type,
173
+ location,
174
+ message,
175
+ quotes_mismatch_error_opening_quote,
176
+ quotes_mismatch_error_closing_quote
177
+ };
178
+
179
+ return rb_class_new_instance(5, args, QuotesMismatchError);
180
+ };
181
+
182
+ static VALUE rb_void_element_closing_tag_error_from_c_struct(VOID_ELEMENT_CLOSING_TAG_ERROR_T* void_element_closing_tag_error) {
183
+ if (void_element_closing_tag_error == NULL) { return Qnil; }
184
+
185
+ ERROR_T* error = &void_element_closing_tag_error->base;
186
+
187
+ VALUE Herb = rb_define_module("Herb");
188
+ VALUE Errors = rb_define_module_under(Herb, "Errors");
189
+ VALUE Error = rb_define_class_under(Errors, "Error", rb_cObject);
190
+ VALUE VoidElementClosingTagError = rb_define_class_under(Errors, "VoidElementClosingTagError", Error);
191
+
192
+ VALUE type = rb_str_new_cstr(error_type_to_string(error));
193
+ VALUE location = rb_location_from_c_struct(error->location);
194
+ VALUE message = rb_str_new_cstr(error->message);
195
+
196
+ VALUE void_element_closing_tag_error_tag_name = rb_token_from_c_struct(void_element_closing_tag_error->tag_name);
197
+ VALUE void_element_closing_tag_error_expected = rb_str_new_cstr(void_element_closing_tag_error->expected);
198
+ VALUE void_element_closing_tag_error_found = rb_str_new_cstr(void_element_closing_tag_error->found);
199
+
200
+ VALUE args[6] = {
201
+ type,
202
+ location,
203
+ message,
204
+ void_element_closing_tag_error_tag_name,
205
+ void_element_closing_tag_error_expected,
206
+ void_element_closing_tag_error_found
207
+ };
208
+
209
+ return rb_class_new_instance(6, args, VoidElementClosingTagError);
210
+ };
211
+
212
+ static VALUE rb_unclosed_element_error_from_c_struct(UNCLOSED_ELEMENT_ERROR_T* unclosed_element_error) {
213
+ if (unclosed_element_error == NULL) { return Qnil; }
214
+
215
+ ERROR_T* error = &unclosed_element_error->base;
216
+
217
+ VALUE Herb = rb_define_module("Herb");
218
+ VALUE Errors = rb_define_module_under(Herb, "Errors");
219
+ VALUE Error = rb_define_class_under(Errors, "Error", rb_cObject);
220
+ VALUE UnclosedElementError = rb_define_class_under(Errors, "UnclosedElementError", Error);
221
+
222
+ VALUE type = rb_str_new_cstr(error_type_to_string(error));
223
+ VALUE location = rb_location_from_c_struct(error->location);
224
+ VALUE message = rb_str_new_cstr(error->message);
225
+
226
+ VALUE unclosed_element_error_opening_tag = rb_token_from_c_struct(unclosed_element_error->opening_tag);
227
+
228
+ VALUE args[4] = {
229
+ type,
230
+ location,
231
+ message,
232
+ unclosed_element_error_opening_tag
233
+ };
234
+
235
+ return rb_class_new_instance(4, args, UnclosedElementError);
236
+ };
237
+
238
+ static VALUE rb_ruby_parse_error_from_c_struct(RUBY_PARSE_ERROR_T* ruby_parse_error) {
239
+ if (ruby_parse_error == NULL) { return Qnil; }
240
+
241
+ ERROR_T* error = &ruby_parse_error->base;
242
+
243
+ VALUE Herb = rb_define_module("Herb");
244
+ VALUE Errors = rb_define_module_under(Herb, "Errors");
245
+ VALUE Error = rb_define_class_under(Errors, "Error", rb_cObject);
246
+ VALUE RubyParseError = rb_define_class_under(Errors, "RubyParseError", Error);
247
+
248
+ VALUE type = rb_str_new_cstr(error_type_to_string(error));
249
+ VALUE location = rb_location_from_c_struct(error->location);
250
+ VALUE message = rb_str_new_cstr(error->message);
251
+
252
+ VALUE ruby_parse_error_error_message = rb_str_new_cstr(ruby_parse_error->error_message);
253
+ VALUE ruby_parse_error_diagnostic_id = rb_str_new_cstr(ruby_parse_error->diagnostic_id);
254
+ VALUE ruby_parse_error_level = rb_str_new_cstr(ruby_parse_error->level);
255
+
256
+ VALUE args[6] = {
257
+ type,
258
+ location,
259
+ message,
260
+ ruby_parse_error_error_message,
261
+ ruby_parse_error_diagnostic_id,
262
+ ruby_parse_error_level
263
+ };
264
+
265
+ return rb_class_new_instance(6, args, RubyParseError);
266
+ };
267
+
268
+
269
+ VALUE rb_error_from_c_struct(ERROR_T* error) {
270
+ if (!error) { return Qnil; }
271
+
272
+ switch (error->type) {
273
+ case UNEXPECTED_ERROR: return rb_unexpected_error_from_c_struct((UNEXPECTED_ERROR_T*) error); break;
274
+ case UNEXPECTED_TOKEN_ERROR: return rb_unexpected_token_error_from_c_struct((UNEXPECTED_TOKEN_ERROR_T*) error); break;
275
+ case MISSING_OPENING_TAG_ERROR: return rb_missing_opening_tag_error_from_c_struct((MISSING_OPENING_TAG_ERROR_T*) error); break;
276
+ case MISSING_CLOSING_TAG_ERROR: return rb_missing_closing_tag_error_from_c_struct((MISSING_CLOSING_TAG_ERROR_T*) error); break;
277
+ case TAG_NAMES_MISMATCH_ERROR: return rb_tag_names_mismatch_error_from_c_struct((TAG_NAMES_MISMATCH_ERROR_T*) error); break;
278
+ case QUOTES_MISMATCH_ERROR: return rb_quotes_mismatch_error_from_c_struct((QUOTES_MISMATCH_ERROR_T*) error); break;
279
+ case VOID_ELEMENT_CLOSING_TAG_ERROR: return rb_void_element_closing_tag_error_from_c_struct((VOID_ELEMENT_CLOSING_TAG_ERROR_T*) error); break;
280
+ case UNCLOSED_ELEMENT_ERROR: return rb_unclosed_element_error_from_c_struct((UNCLOSED_ELEMENT_ERROR_T*) error); break;
281
+ case RUBY_PARSE_ERROR: return rb_ruby_parse_error_from_c_struct((RUBY_PARSE_ERROR_T*) error); break;
282
+ }
283
+
284
+ return Qnil;
285
+ }
286
+
287
+ VALUE rb_errors_array_from_c_array(array_T* array) {
288
+ VALUE rb_array = rb_ary_new();
289
+
290
+ if (array) {
291
+ for (size_t i = 0; i < array_size(array); i++) {
292
+ ERROR_T* child_node = (ERROR_T*) array_get(array, i);
293
+
294
+ if (child_node) {
295
+ VALUE rb_child = rb_error_from_c_struct(child_node);
296
+ rb_ary_push(rb_array, rb_child);
297
+ }
298
+ }
299
+ }
300
+
301
+ return rb_array;
302
+ }
@@ -0,0 +1,15 @@
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/ext/herb/error_helpers.h.erb
3
+
4
+ #ifndef HERB_EXTENSION_ERROR_HELPERS_H
5
+ #define HERB_EXTENSION_ERROR_HELPERS_H
6
+
7
+ #include "../../src/include/errors.h"
8
+ #include "../../src/include/herb.h"
9
+
10
+ #include <ruby.h>
11
+
12
+ VALUE rb_error_from_c_struct(ERROR_T* error);
13
+ VALUE rb_errors_array_from_c_array(array_T* array);
14
+
15
+ #endif
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "mkmf"
4
+
5
+ Dir.chdir(File.expand_path("../..", __dir__)) do
6
+ system("rake templates", exception: true)
7
+ end
8
+
9
+ extension_name = "herb"
10
+
11
+ include_path = File.expand_path("../../src/include", __dir__)
12
+ prism_path = `bundle show prism`.chomp
13
+ prism_src_path = "#{prism_path}/src"
14
+ prism_include_path = "#{prism_path}/include"
15
+
16
+ $VPATH << "$(srcdir)/../../src"
17
+ $VPATH << prism_src_path
18
+ $VPATH << "#{prism_src_path}/util"
19
+
20
+ $INCFLAGS << " -I#{prism_include_path}"
21
+ $INCFLAGS << " -I#{include_path}"
22
+ $INCFLAGS << " -I#{prism_src_path}"
23
+ $INCFLAGS << " -I#{prism_src_path}/util"
24
+
25
+ $CFLAGS << " -DPRISM_EXPORT_SYMBOLS=static "
26
+
27
+ herb_src_files = Dir.glob("#{$srcdir}/../../src/**/*.c").map { |file| file.delete_prefix("../../../../ext/herb/") }.sort
28
+
29
+ prism_main_files = %w[
30
+ diagnostic.c
31
+ encoding.c
32
+ node.c
33
+ options.c
34
+ pack.c
35
+ prettyprint.c
36
+ prism.c
37
+ regexp.c
38
+ serialize.c
39
+ static_literals.c
40
+ token_type.c
41
+ ]
42
+
43
+ prism_util_files = %w[
44
+ pm_buffer.c
45
+ pm_char.c
46
+ pm_constant_pool.c
47
+ pm_integer.c
48
+ pm_list.c
49
+ pm_memchr.c
50
+ pm_newline_list.c
51
+ pm_string.c
52
+ pm_strncasecmp.c
53
+ pm_strpbrk.c
54
+ ]
55
+
56
+ core_src_files = %w[
57
+ extension.c
58
+ nodes.c
59
+ error_helpers.c
60
+ extension_helpers.c
61
+ ]
62
+
63
+ $srcs = core_src_files + herb_src_files + prism_main_files + prism_util_files
64
+
65
+ puts "Sources to be compiled: #{$srcs.inspect}"
66
+
67
+ abort("could not find prism.h") unless find_header("prism.h")
68
+ abort("could not find herb.h") unless find_header("herb.h")
69
+
70
+ abort("could not find nodes.h (run `ruby templates/template.rb` to generate the file)") unless find_header("nodes.h")
71
+ abort("could not find extension.h") unless find_header("extension.h")
72
+ abort("could not find extension_helpers.h") unless find_header("extension_helpers.h")
73
+
74
+ create_header
75
+ create_makefile("#{extension_name}/#{extension_name}")
@@ -0,0 +1,110 @@
1
+ #include <ruby.h>
2
+
3
+ #include "error_helpers.h"
4
+ #include "extension_helpers.h"
5
+ #include "nodes.h"
6
+
7
+ #include "../../src/include/analyze.h"
8
+
9
+ static VALUE Herb_lex(VALUE self, VALUE source) {
10
+ char* string = (char*) check_string(source);
11
+
12
+ array_T* tokens = herb_lex(string);
13
+
14
+ return create_lex_result(tokens, source);
15
+ }
16
+
17
+ static VALUE Herb_lex_file(VALUE self, VALUE path) {
18
+ char* file_path = (char*) check_string(path);
19
+ array_T* tokens = herb_lex_file(file_path);
20
+
21
+ VALUE source_value = read_file_to_ruby_string(file_path);
22
+
23
+ return create_lex_result(tokens, source_value);
24
+ }
25
+
26
+ static VALUE Herb_parse(VALUE self, VALUE source) {
27
+ char* string = (char*) check_string(source);
28
+
29
+ AST_DOCUMENT_NODE_T* root = herb_parse(string);
30
+
31
+ herb_analyze_parse_tree(root, string);
32
+
33
+ return create_parse_result(root, source);
34
+ }
35
+
36
+ static VALUE Herb_parse_file(VALUE self, VALUE path) {
37
+ char* file_path = (char*) check_string(path);
38
+
39
+ VALUE source_value = read_file_to_ruby_string(file_path);
40
+ char* string = (char*) check_string(source_value);
41
+
42
+ AST_DOCUMENT_NODE_T* root = herb_parse(string);
43
+
44
+ return create_parse_result(root, source_value);
45
+ }
46
+
47
+ static VALUE Herb_lex_to_json(VALUE self, VALUE source) {
48
+ char* string = (char*) check_string(source);
49
+ buffer_T output;
50
+
51
+ if (!buffer_init(&output)) { return Qnil; }
52
+
53
+ herb_lex_json_to_buffer(string, &output);
54
+
55
+ VALUE result = rb_str_new(output.value, output.length);
56
+
57
+ buffer_free(&output);
58
+
59
+ return result;
60
+ }
61
+
62
+ static VALUE Herb_extract_ruby(VALUE self, VALUE source) {
63
+ char* string = (char*) check_string(source);
64
+ buffer_T output;
65
+
66
+ if (!buffer_init(&output)) { return Qnil; }
67
+
68
+ herb_extract_ruby_to_buffer(string, &output);
69
+
70
+ VALUE result = rb_str_new_cstr(output.value);
71
+ buffer_free(&output);
72
+
73
+ return result;
74
+ }
75
+
76
+ static VALUE Herb_extract_html(VALUE self, VALUE source) {
77
+ char* string = (char*) check_string(source);
78
+ buffer_T output;
79
+
80
+ if (!buffer_init(&output)) { return Qnil; }
81
+
82
+ herb_extract_html_to_buffer(string, &output);
83
+
84
+ VALUE result = rb_str_new_cstr(output.value);
85
+ buffer_free(&output);
86
+
87
+ return result;
88
+ }
89
+
90
+ static VALUE Herb_version(VALUE self) {
91
+ VALUE gem_version = rb_const_get(self, rb_intern("VERSION"));
92
+ VALUE libherb_version = rb_str_new_cstr(herb_version());
93
+ VALUE libprism_version = rb_str_new_cstr(herb_prism_version());
94
+ VALUE format_string = rb_str_new_cstr("herb gem v%s, libprism v%s, libherb v%s (Ruby C native extension)");
95
+
96
+ return rb_funcall(rb_mKernel, rb_intern("sprintf"), 4, format_string, gem_version, libprism_version, libherb_version);
97
+ }
98
+
99
+ void Init_herb(void) {
100
+ VALUE Herb = rb_define_module("Herb");
101
+
102
+ rb_define_singleton_method(Herb, "parse", Herb_parse, 1);
103
+ rb_define_singleton_method(Herb, "lex", Herb_lex, 1);
104
+ rb_define_singleton_method(Herb, "parse_file", Herb_parse_file, 1);
105
+ rb_define_singleton_method(Herb, "lex_file", Herb_lex_file, 1);
106
+ rb_define_singleton_method(Herb, "lex_to_json", Herb_lex_to_json, 1);
107
+ rb_define_singleton_method(Herb, "extract_ruby", Herb_extract_ruby, 1);
108
+ rb_define_singleton_method(Herb, "extract_html", Herb_extract_html, 1);
109
+ rb_define_singleton_method(Herb, "version", Herb_version, 0);
110
+ }
@@ -0,0 +1,6 @@
1
+ #ifndef HERB_EXTENSION_H
2
+ #define HERB_EXTENSION_H
3
+
4
+ void Init_herb(void);
5
+
6
+ #endif
@@ -0,0 +1,117 @@
1
+ #include <ruby.h>
2
+
3
+ #include "extension_helpers.h"
4
+ #include "nodes.h"
5
+
6
+ #include "../../src/include/herb.h"
7
+ #include "../../src/include/io.h"
8
+ #include "../../src/include/location.h"
9
+ #include "../../src/include/position.h"
10
+ #include "../../src/include/token.h"
11
+
12
+ const char* check_string(VALUE value) {
13
+ if (NIL_P(value)) { return NULL; }
14
+
15
+ if (!RB_TYPE_P(value, T_STRING)) {
16
+ rb_raise(rb_eTypeError, "wrong argument type %" PRIsVALUE " (expected String)", rb_obj_class(value));
17
+ }
18
+
19
+ return RSTRING_PTR(value);
20
+ }
21
+
22
+ VALUE rb_position_from_c_struct(position_T* position) {
23
+ if (!position) { return Qnil; }
24
+
25
+ VALUE args[2];
26
+ args[0] = SIZET2NUM(position->line);
27
+ args[1] = SIZET2NUM(position->column);
28
+
29
+ VALUE Herb = rb_define_module("Herb");
30
+ VALUE Position = rb_define_class_under(Herb, "Position", rb_cObject);
31
+
32
+ return rb_class_new_instance(2, args, Position);
33
+ }
34
+
35
+ VALUE rb_location_from_c_struct(location_T* location) {
36
+ if (!location) { return Qnil; }
37
+
38
+ VALUE args[2];
39
+ args[0] = rb_position_from_c_struct(location->start);
40
+ args[1] = rb_position_from_c_struct(location->end);
41
+
42
+ VALUE Herb = rb_define_module("Herb");
43
+ VALUE Location = rb_define_class_under(Herb, "Location", rb_cObject);
44
+
45
+ return rb_class_new_instance(2, args, Location);
46
+ }
47
+
48
+ VALUE rb_range_from_c_struct(range_T* range) {
49
+ if (!range) { return Qnil; }
50
+
51
+ VALUE args[2];
52
+ args[0] = SIZET2NUM(range->from);
53
+ args[1] = SIZET2NUM(range->to);
54
+
55
+ VALUE Herb = rb_define_module("Herb");
56
+ VALUE Range = rb_define_class_under(Herb, "Range", rb_cObject);
57
+
58
+ return rb_class_new_instance(2, args, Range);
59
+ }
60
+
61
+ VALUE rb_token_from_c_struct(token_T* token) {
62
+ if (!token) { return Qnil; }
63
+
64
+ VALUE value = token->value ? rb_str_new_cstr(token->value) : Qnil;
65
+
66
+ VALUE range = rb_range_from_c_struct(token->range);
67
+ VALUE location = rb_location_from_c_struct(token->location);
68
+ VALUE type = rb_str_new_cstr(token_type_to_string(token->type));
69
+
70
+ VALUE args[4] = { value, range, location, type };
71
+
72
+ VALUE Herb = rb_define_module("Herb");
73
+ VALUE Token = rb_define_class_under(Herb, "Token", rb_cObject);
74
+
75
+ return rb_class_new_instance(4, args, Token);
76
+ }
77
+
78
+ VALUE create_lex_result(array_T* tokens, VALUE source) {
79
+ VALUE value = rb_ary_new();
80
+ VALUE warnings = rb_ary_new();
81
+ VALUE errors = rb_ary_new();
82
+
83
+ for (size_t i = 0; i < array_size(tokens); i++) {
84
+ token_T* token = array_get(tokens, i);
85
+ if (token != NULL) { rb_ary_push(value, rb_token_from_c_struct(token)); }
86
+ }
87
+
88
+ VALUE Herb = rb_define_module("Herb");
89
+ VALUE Result = rb_define_class_under(Herb, "Result", rb_cObject);
90
+ VALUE LexResult = rb_define_class_under(Herb, "LexResult", Result);
91
+
92
+ herb_free_tokens(&tokens);
93
+ VALUE args[4] = { value, source, warnings, errors };
94
+ return rb_class_new_instance(4, args, LexResult);
95
+ }
96
+
97
+ VALUE create_parse_result(AST_DOCUMENT_NODE_T* root, VALUE source) {
98
+ VALUE value = rb_node_from_c_struct((AST_NODE_T*) root);
99
+ VALUE warnings = rb_ary_new();
100
+ VALUE errors = rb_ary_new();
101
+
102
+ VALUE Herb = rb_define_module("Herb");
103
+ VALUE Result = rb_define_class_under(Herb, "Result", rb_cObject);
104
+ VALUE ParseResult = rb_define_class_under(Herb, "ParseResult", Result);
105
+
106
+ VALUE args[4] = { value, source, warnings, errors };
107
+ return rb_class_new_instance(4, args, ParseResult);
108
+ }
109
+
110
+ VALUE read_file_to_ruby_string(const char* file_path) {
111
+ char* source = herb_read_file(file_path);
112
+ VALUE source_value = rb_str_new_cstr(source);
113
+
114
+ free(source);
115
+
116
+ return source_value;
117
+ }
@@ -0,0 +1,24 @@
1
+ #ifndef HERB_EXTENSION_HERB_H
2
+ #define HERB_EXTENSION_HERB_H
3
+
4
+ #include <ruby.h>
5
+
6
+ #include "../../src/include/herb.h"
7
+ #include "../../src/include/location.h"
8
+ #include "../../src/include/position.h"
9
+ #include "../../src/include/range.h"
10
+ #include "../../src/include/token.h"
11
+
12
+ const char* check_string(VALUE value);
13
+ VALUE read_file_to_ruby_string(const char* file_path);
14
+
15
+ VALUE rb_position_from_c_struct(position_T* position);
16
+ VALUE rb_location_from_c_struct(location_T* location);
17
+
18
+ VALUE rb_token_from_c_struct(token_T* token);
19
+ VALUE rb_range_from_c_struct(range_T* range);
20
+
21
+ VALUE create_lex_result(array_T* tokens, VALUE source);
22
+ VALUE create_parse_result(AST_DOCUMENT_NODE_T* root, VALUE source);
23
+
24
+ #endif