prism 1.9.0 → 2.0.0.rc1

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 (238) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +84 -0
  3. data/Makefile +41 -12
  4. data/README.md +35 -97
  5. data/config.yml +174 -161
  6. data/docs/build_system.md +2 -2
  7. data/docs/configuration.md +5 -4
  8. data/docs/encoding.md +2 -2
  9. data/docs/fuzzing.md +4 -11
  10. data/docs/javascript.md +19 -4
  11. data/docs/mapping.md +1 -1
  12. data/docs/releasing.md +77 -5
  13. data/docs/relocation.md +2 -4
  14. data/docs/serialization.md +21 -24
  15. data/docs/testing.md +46 -29
  16. data/ext/prism/api_node.c +1461 -1401
  17. data/ext/prism/extconf.rb +3 -4
  18. data/ext/prism/extension.c +778 -422
  19. data/ext/prism/extension.h +3 -3
  20. data/include/prism/arena.h +37 -0
  21. data/include/prism/ast.h +2727 -610
  22. data/include/prism/buffer.h +52 -0
  23. data/include/prism/comments.h +55 -0
  24. data/include/prism/compiler/accel.h +24 -0
  25. data/include/prism/compiler/align.h +36 -0
  26. data/include/prism/compiler/assume.h +25 -0
  27. data/include/prism/compiler/exported.h +24 -0
  28. data/include/prism/compiler/fallthrough.h +22 -0
  29. data/include/prism/compiler/filesystem.h +32 -0
  30. data/include/prism/compiler/flex_array.h +19 -0
  31. data/include/prism/compiler/force_inline.h +21 -0
  32. data/include/prism/compiler/format.h +25 -0
  33. data/include/prism/compiler/inline.h +17 -0
  34. data/include/prism/compiler/nodiscard.h +22 -0
  35. data/include/prism/compiler/nonnull.h +18 -0
  36. data/include/prism/compiler/unused.h +18 -0
  37. data/include/prism/constant_pool.h +81 -0
  38. data/include/prism/diagnostic.h +38 -403
  39. data/include/prism/errors_format.h +53 -0
  40. data/include/prism/excludes.h +29 -0
  41. data/include/prism/integer.h +41 -0
  42. data/include/prism/internal/allocator.h +68 -0
  43. data/include/prism/internal/allocator_debug.h +88 -0
  44. data/include/prism/internal/arena.h +108 -0
  45. data/include/prism/internal/bit.h +42 -0
  46. data/include/prism/internal/buffer.h +91 -0
  47. data/include/prism/internal/char.h +145 -0
  48. data/include/prism/internal/comments.h +53 -0
  49. data/include/prism/internal/constant_pool.h +152 -0
  50. data/include/prism/internal/diagnostic.h +389 -0
  51. data/include/prism/{encoding.h → internal/encoding.h} +27 -68
  52. data/include/prism/internal/integer.h +68 -0
  53. data/include/prism/internal/isinf.h +16 -0
  54. data/include/prism/internal/line_offset_list.h +34 -0
  55. data/include/prism/{util/pm_list.h → internal/list.h} +11 -52
  56. data/include/prism/internal/magic_comments.h +23 -0
  57. data/include/prism/internal/memchr.h +15 -0
  58. data/include/prism/internal/node.h +38 -0
  59. data/include/prism/internal/options.h +232 -0
  60. data/include/prism/internal/parser.h +984 -0
  61. data/include/prism/internal/regexp.h +26 -0
  62. data/include/prism/internal/serialize.h +39 -0
  63. data/include/prism/internal/source.h +72 -0
  64. data/include/prism/{static_literals.h → internal/static_literals.h} +26 -47
  65. data/include/prism/internal/stringy.h +35 -0
  66. data/include/prism/{util/pm_strncasecmp.h → internal/strncasecmp.h} +3 -17
  67. data/include/prism/{util/pm_strpbrk.h → internal/strpbrk.h} +7 -20
  68. data/include/prism/internal/tokens.h +11 -0
  69. data/include/prism/json.h +32 -0
  70. data/include/prism/line_offset_list.h +61 -0
  71. data/include/prism/magic_comments.h +35 -0
  72. data/include/prism/node.h +18 -53
  73. data/include/prism/options.h +146 -280
  74. data/include/prism/parser.h +336 -868
  75. data/include/prism/prettyprint.h +6 -9
  76. data/include/prism/serialize.h +115 -0
  77. data/include/prism/source.h +155 -0
  78. data/include/prism/stream.h +28 -0
  79. data/include/prism/string_query.h +63 -0
  80. data/include/prism/stringy.h +72 -0
  81. data/include/prism/version.h +12 -3
  82. data/include/prism.h +43 -320
  83. data/lib/prism/compiler.rb +319 -305
  84. data/lib/prism/desugar_compiler.rb +105 -34
  85. data/lib/prism/dispatcher.rb +646 -473
  86. data/lib/prism/dot_visitor.rb +592 -511
  87. data/lib/prism/dsl.rb +391 -25
  88. data/lib/prism/ffi.rb +252 -90
  89. data/lib/prism/inspect_visitor.rb +357 -325
  90. data/lib/prism/lex_compat.rb +254 -212
  91. data/lib/prism/mutation_compiler.rb +313 -305
  92. data/lib/prism/node.rb +20268 -7030
  93. data/lib/prism/node_ext.rb +180 -187
  94. data/lib/prism/node_find.rb +215 -0
  95. data/lib/prism/parse_result/errors.rb +7 -1
  96. data/lib/prism/parse_result/newlines.rb +276 -8
  97. data/lib/prism/parse_result.rb +453 -139
  98. data/lib/prism/pattern.rb +65 -20
  99. data/lib/prism/reflection.rb +23 -12
  100. data/lib/prism/relocation.rb +149 -87
  101. data/lib/prism/serialize.rb +3443 -535
  102. data/lib/prism/string_query.rb +16 -1
  103. data/lib/prism/translation/parser/builder.rb +10 -2
  104. data/lib/prism/translation/parser/compiler.rb +44 -52
  105. data/lib/prism/translation/parser/lexer.rb +41 -92
  106. data/lib/prism/translation/parser.rb +1 -1
  107. data/lib/prism/translation/parser_current.rb +1 -1
  108. data/lib/prism/translation/ripper/lexer.rb +8 -10
  109. data/lib/prism/translation/ripper/sexp.rb +2 -10
  110. data/lib/prism/translation/ripper/shim.rb +2 -0
  111. data/lib/prism/translation/ripper.rb +967 -209
  112. data/lib/prism/translation/ruby_parser.rb +73 -316
  113. data/lib/prism/translation.rb +2 -0
  114. data/lib/prism/visitor.rb +632 -5
  115. data/lib/prism.rb +79 -9
  116. data/prism.gemspec +122 -60
  117. data/rbi/generated/prism/compiler.rbi +489 -0
  118. data/rbi/generated/prism/desugar_compiler.rbi +306 -0
  119. data/rbi/generated/prism/dispatcher.rbi +1138 -0
  120. data/rbi/generated/prism/dot_visitor.rbi +618 -0
  121. data/rbi/generated/prism/dsl.rbi +751 -0
  122. data/rbi/generated/prism/inspect_visitor.rbi +503 -0
  123. data/rbi/generated/prism/lex_compat.rbi +162 -0
  124. data/rbi/generated/prism/mutation_compiler.rbi +464 -0
  125. data/rbi/generated/prism/node.rbi +13681 -0
  126. data/rbi/generated/prism/node_ext.rbi +259 -0
  127. data/rbi/generated/prism/node_find.rbi +79 -0
  128. data/rbi/generated/prism/parse_result/errors.rbi +21 -0
  129. data/rbi/generated/prism/parse_result/newlines.rbi +208 -0
  130. data/rbi/generated/prism/parse_result.rbi +764 -0
  131. data/rbi/generated/prism/pattern.rbi +134 -0
  132. data/rbi/generated/prism/reflection.rbi +89 -0
  133. data/rbi/generated/prism/relocation.rbi +329 -0
  134. data/rbi/generated/prism/serialize.rbi +181 -0
  135. data/rbi/generated/prism/string_query.rbi +36 -0
  136. data/rbi/generated/prism/translation.rbi +7 -0
  137. data/rbi/generated/prism/visitor.rbi +650 -0
  138. data/rbi/generated/prism.rbi +86 -0
  139. data/rbi/prism/translation/parser_versions.rbi +5 -0
  140. data/rbi/rubyvm/node_find.rbi +14 -0
  141. data/sig/generated/prism/compiler.rbs +492 -0
  142. data/sig/generated/prism/desugar_compiler.rbs +305 -0
  143. data/sig/generated/prism/dispatcher.rbs +1292 -0
  144. data/sig/generated/prism/dot_visitor.rbs +635 -0
  145. data/sig/generated/prism/dsl.rbs +928 -0
  146. data/sig/generated/prism/inspect_visitor.rbs +509 -0
  147. data/sig/generated/prism/lex_compat.rbs +166 -0
  148. data/sig/{prism → generated/prism}/mutation_compiler.rbs +309 -4
  149. data/sig/generated/prism/node.rbs +20160 -0
  150. data/sig/generated/prism/node_ext.rbs +290 -0
  151. data/sig/generated/prism/node_find.rbs +90 -0
  152. data/sig/generated/prism/parse_result/errors.rbs +22 -0
  153. data/sig/generated/prism/parse_result/newlines.rbs +223 -0
  154. data/sig/generated/prism/parse_result.rbs +859 -0
  155. data/sig/generated/prism/pattern.rbs +156 -0
  156. data/sig/generated/prism/reflection.rbs +101 -0
  157. data/sig/generated/prism/relocation.rbs +428 -0
  158. data/sig/generated/prism/serialize.rbs +195 -0
  159. data/sig/generated/prism/string_query.rbs +36 -0
  160. data/sig/generated/prism/translation.rbs +8 -0
  161. data/sig/generated/prism/visitor.rbs +1111 -0
  162. data/sig/generated/prism.rbs +84 -0
  163. data/sig/manifest.yaml +2 -0
  164. data/src/arena.c +117 -0
  165. data/src/{util/pm_buffer.c → buffer.c} +44 -21
  166. data/src/{util/pm_char.c → char.c} +28 -57
  167. data/src/comments.c +454 -0
  168. data/src/constant_pool.c +406 -0
  169. data/src/diagnostic.c +97 -65
  170. data/src/encoding.c +8 -3
  171. data/src/errors_format.c +519 -0
  172. data/src/{util/pm_integer.c → integer.c} +33 -22
  173. data/src/json.c +5733 -0
  174. data/src/line_offset_list.c +100 -0
  175. data/src/list.c +24 -0
  176. data/src/{util/pm_memchr.c → memchr.c} +8 -6
  177. data/src/node.c +3504 -7674
  178. data/src/options.c +162 -49
  179. data/src/parser.c +349 -0
  180. data/src/prettyprint.c +421 -354
  181. data/src/prism.c +8030 -6970
  182. data/src/regexp.c +961 -45
  183. data/src/serialize.c +459 -424
  184. data/src/source.c +518 -0
  185. data/src/static_literals.c +111 -43
  186. data/src/string_query.c +166 -0
  187. data/src/stringy.c +91 -0
  188. data/src/{util/pm_strncasecmp.c → strncasecmp.c} +5 -4
  189. data/src/strpbrk.c +447 -0
  190. data/src/{token_type.c → tokens.c} +39 -18
  191. metadata +122 -61
  192. data/ext/prism/api_pack.c +0 -276
  193. data/include/prism/defines.h +0 -260
  194. data/include/prism/pack.h +0 -163
  195. data/include/prism/regexp.h +0 -43
  196. data/include/prism/util/pm_buffer.h +0 -236
  197. data/include/prism/util/pm_char.h +0 -204
  198. data/include/prism/util/pm_constant_pool.h +0 -218
  199. data/include/prism/util/pm_integer.h +0 -130
  200. data/include/prism/util/pm_memchr.h +0 -29
  201. data/include/prism/util/pm_newline_list.h +0 -113
  202. data/include/prism/util/pm_string.h +0 -200
  203. data/lib/prism/pack.rb +0 -230
  204. data/lib/prism/parse_result/comments.rb +0 -188
  205. data/rbi/prism/compiler.rbi +0 -12
  206. data/rbi/prism/dsl.rbi +0 -524
  207. data/rbi/prism/inspect_visitor.rbi +0 -12
  208. data/rbi/prism/node.rbi +0 -8750
  209. data/rbi/prism/node_ext.rbi +0 -107
  210. data/rbi/prism/parse_result.rbi +0 -404
  211. data/rbi/prism/reflection.rbi +0 -58
  212. data/rbi/prism/string_query.rbi +0 -12
  213. data/rbi/prism/visitor.rbi +0 -473
  214. data/rbi/prism.rbi +0 -63
  215. data/sig/prism/compiler.rbs +0 -9
  216. data/sig/prism/dispatcher.rbs +0 -19
  217. data/sig/prism/dot_visitor.rbs +0 -6
  218. data/sig/prism/dsl.rbs +0 -351
  219. data/sig/prism/inspect_visitor.rbs +0 -22
  220. data/sig/prism/lex_compat.rbs +0 -10
  221. data/sig/prism/node.rbs +0 -4042
  222. data/sig/prism/node_ext.rbs +0 -149
  223. data/sig/prism/pack.rbs +0 -43
  224. data/sig/prism/parse_result/comments.rbs +0 -38
  225. data/sig/prism/parse_result.rbs +0 -197
  226. data/sig/prism/pattern.rbs +0 -13
  227. data/sig/prism/reflection.rbs +0 -50
  228. data/sig/prism/relocation.rbs +0 -185
  229. data/sig/prism/serialize.rbs +0 -8
  230. data/sig/prism/string_query.rbs +0 -11
  231. data/sig/prism/visitor.rbs +0 -169
  232. data/sig/prism.rbs +0 -272
  233. data/src/pack.c +0 -509
  234. data/src/util/pm_constant_pool.c +0 -342
  235. data/src/util/pm_list.c +0 -49
  236. data/src/util/pm_newline_list.c +0 -125
  237. data/src/util/pm_string.c +0 -381
  238. data/src/util/pm_strpbrk.c +0 -206
data/src/options.c CHANGED
@@ -1,18 +1,78 @@
1
- #include "prism/options.h"
1
+ #include "prism/internal/options.h"
2
+
3
+ #include "prism/compiler/inline.h"
4
+
5
+ #include "prism/internal/allocator.h"
6
+ #include "prism/internal/char.h"
7
+ #include "prism/internal/stringy.h"
8
+
9
+ #include <stdlib.h>
10
+ #include <string.h>
11
+
12
+ /**
13
+ * Allocate a new options struct. If the options struct cannot be allocated,
14
+ * this function aborts the process.
15
+ */
16
+ pm_options_t *
17
+ pm_options_new(void) {
18
+ pm_options_t *options = xcalloc(1, sizeof(pm_options_t));
19
+ if (options == NULL) abort();
20
+ return options;
21
+ }
22
+
23
+ /**
24
+ * Free the internal memory associated with the options.
25
+ */
26
+ void
27
+ pm_options_cleanup(pm_options_t *options) {
28
+ pm_string_cleanup(&options->filepath);
29
+ pm_string_cleanup(&options->encoding);
30
+
31
+ for (size_t scope_index = 0; scope_index < options->scopes_count; scope_index++) {
32
+ pm_options_scope_t *scope = &options->scopes[scope_index];
33
+
34
+ for (size_t local_index = 0; local_index < scope->locals_count; local_index++) {
35
+ pm_string_cleanup(&scope->locals[local_index]);
36
+ }
37
+
38
+ xfree_sized(scope->locals, scope->locals_count * sizeof(pm_string_t));
39
+ }
40
+
41
+ xfree_sized(options->scopes, options->scopes_count * sizeof(pm_options_scope_t));
42
+ }
43
+
44
+ /**
45
+ * Free both the held memory of the given options struct and the struct itself.
46
+ *
47
+ * @param options The options struct to free.
48
+ */
49
+ void
50
+ pm_options_free(pm_options_t *options) {
51
+ pm_options_cleanup(options);
52
+ xfree_sized(options, sizeof(pm_options_t));
53
+ }
2
54
 
3
55
  /**
4
56
  * Set the shebang callback option on the given options struct.
5
57
  */
6
- PRISM_EXPORTED_FUNCTION void
58
+ void
7
59
  pm_options_shebang_callback_set(pm_options_t *options, pm_options_shebang_callback_t shebang_callback, void *shebang_callback_data) {
8
60
  options->shebang_callback = shebang_callback;
9
61
  options->shebang_callback_data = shebang_callback_data;
10
62
  }
11
63
 
64
+ /**
65
+ * Get the filepath option on the given options struct.
66
+ */
67
+ const pm_string_t *
68
+ pm_options_filepath(const pm_options_t *options) {
69
+ return &options->filepath;
70
+ }
71
+
12
72
  /**
13
73
  * Set the filepath option on the given options struct.
14
74
  */
15
- PRISM_EXPORTED_FUNCTION void
75
+ void
16
76
  pm_options_filepath_set(pm_options_t *options, const char *filepath) {
17
77
  pm_string_constant_init(&options->filepath, filepath, strlen(filepath));
18
78
  }
@@ -20,7 +80,7 @@ pm_options_filepath_set(pm_options_t *options, const char *filepath) {
20
80
  /**
21
81
  * Set the encoding option on the given options struct.
22
82
  */
23
- PRISM_EXPORTED_FUNCTION void
83
+ void
24
84
  pm_options_encoding_set(pm_options_t *options, const char *encoding) {
25
85
  pm_string_constant_init(&options->encoding, encoding, strlen(encoding));
26
86
  }
@@ -28,7 +88,7 @@ pm_options_encoding_set(pm_options_t *options, const char *encoding) {
28
88
  /**
29
89
  * Set the encoding_locked option on the given options struct.
30
90
  */
31
- PRISM_EXPORTED_FUNCTION void
91
+ void
32
92
  pm_options_encoding_locked_set(pm_options_t *options, bool encoding_locked) {
33
93
  options->encoding_locked = encoding_locked;
34
94
  }
@@ -36,7 +96,7 @@ pm_options_encoding_locked_set(pm_options_t *options, bool encoding_locked) {
36
96
  /**
37
97
  * Set the line option on the given options struct.
38
98
  */
39
- PRISM_EXPORTED_FUNCTION void
99
+ void
40
100
  pm_options_line_set(pm_options_t *options, int32_t line) {
41
101
  options->line = line;
42
102
  }
@@ -44,7 +104,7 @@ pm_options_line_set(pm_options_t *options, int32_t line) {
44
104
  /**
45
105
  * Set the frozen string literal option on the given options struct.
46
106
  */
47
- PRISM_EXPORTED_FUNCTION void
107
+ void
48
108
  pm_options_frozen_string_literal_set(pm_options_t *options, bool frozen_string_literal) {
49
109
  options->frozen_string_literal = frozen_string_literal ? PM_OPTIONS_FROZEN_STRING_LITERAL_ENABLED : PM_OPTIONS_FROZEN_STRING_LITERAL_DISABLED;
50
110
  }
@@ -52,7 +112,7 @@ pm_options_frozen_string_literal_set(pm_options_t *options, bool frozen_string_l
52
112
  /**
53
113
  * Sets the command line option on the given options struct.
54
114
  */
55
- PRISM_EXPORTED_FUNCTION void
115
+ void
56
116
  pm_options_command_line_set(pm_options_t *options, uint8_t command_line) {
57
117
  options->command_line = command_line;
58
118
  }
@@ -60,7 +120,7 @@ pm_options_command_line_set(pm_options_t *options, uint8_t command_line) {
60
120
  /**
61
121
  * Checks if the given slice represents a number.
62
122
  */
63
- static inline bool
123
+ static PRISM_INLINE bool
64
124
  is_number(const char *string, size_t length) {
65
125
  return pm_strspn_decimal_digit((const uint8_t *) string, (ptrdiff_t) length) == length;
66
126
  }
@@ -70,7 +130,7 @@ is_number(const char *string, size_t length) {
70
130
  * string. If the string contains an invalid option, this returns false.
71
131
  * Otherwise, it returns true.
72
132
  */
73
- PRISM_EXPORTED_FUNCTION bool
133
+ bool
74
134
  pm_options_version_set(pm_options_t *options, const char *version, size_t length) {
75
135
  if (version == NULL) {
76
136
  options->version = PM_OPTIONS_VERSION_LATEST;
@@ -123,8 +183,8 @@ pm_options_version_set(pm_options_t *options, const char *version, size_t length
123
183
  }
124
184
  }
125
185
 
126
- if (length >= 6) {
127
- if (strncmp(version, "latest", 7) == 0) { // 7 to compare the \0 as well
186
+ if (length == 6) {
187
+ if (strncmp(version, "latest", 6) == 0) {
128
188
  options->version = PM_OPTIONS_VERSION_LATEST;
129
189
  return true;
130
190
  }
@@ -133,10 +193,28 @@ pm_options_version_set(pm_options_t *options, const char *version, size_t length
133
193
  return false;
134
194
  }
135
195
 
196
+ /**
197
+ * Set the version option on the given options struct to the lowest version of
198
+ * Ruby that prism supports.
199
+ */
200
+ void
201
+ pm_options_version_set_lowest(pm_options_t *options) {
202
+ options->version = PM_OPTIONS_VERSION_CRUBY_3_3;
203
+ }
204
+
205
+ /**
206
+ * Set the version option on the given options struct to the highest version of
207
+ * Ruby that prism supports.
208
+ */
209
+ void
210
+ pm_options_version_set_highest(pm_options_t *options) {
211
+ options->version = PM_OPTIONS_VERSION_LATEST;
212
+ }
213
+
136
214
  /**
137
215
  * Set the main script option on the given options struct.
138
216
  */
139
- PRISM_EXPORTED_FUNCTION void
217
+ void
140
218
  pm_options_main_script_set(pm_options_t *options, bool main_script) {
141
219
  options->main_script = main_script;
142
220
  }
@@ -144,19 +222,57 @@ pm_options_main_script_set(pm_options_t *options, bool main_script) {
144
222
  /**
145
223
  * Set the partial script option on the given options struct.
146
224
  */
147
- PRISM_EXPORTED_FUNCTION void
225
+ void
148
226
  pm_options_partial_script_set(pm_options_t *options, bool partial_script) {
149
227
  options->partial_script = partial_script;
150
228
  }
151
229
 
230
+ /**
231
+ * Get the freeze option on the given options struct.
232
+ */
233
+ bool
234
+ pm_options_freeze(const pm_options_t *options) {
235
+ return options->freeze;
236
+ }
237
+
152
238
  /**
153
239
  * Set the freeze option on the given options struct.
154
240
  */
155
- PRISM_EXPORTED_FUNCTION void
241
+ void
156
242
  pm_options_freeze_set(pm_options_t *options, bool freeze) {
157
243
  options->freeze = freeze;
158
244
  }
159
245
 
246
+ /**
247
+ * Get the attach_comments option on the given options struct.
248
+ */
249
+ bool
250
+ pm_options_attach_comments(const pm_options_t *options) {
251
+ return options->attach_comments;
252
+ }
253
+
254
+ /**
255
+ * Set the attach_comments option on the given options struct.
256
+ */
257
+ void
258
+ pm_options_attach_comments_set(pm_options_t *options, bool attach_comments) {
259
+ options->attach_comments = attach_comments;
260
+ }
261
+
262
+ /**
263
+ * Get the raise_error option on the given options struct.
264
+ */
265
+ uint8_t pm_options_raise_error(const pm_options_t *options) {
266
+ return options->raise_error;
267
+ }
268
+
269
+ /**
270
+ * Set the raise_error option on the given options struct.
271
+ */
272
+ void pm_options_raise_error_set(pm_options_t *options, uint8_t raise_error) {
273
+ options->raise_error = raise_error;
274
+ }
275
+
160
276
  // For some reason, GCC analyzer thinks we're leaking allocated scopes and
161
277
  // locals here, even though we definitely aren't. This is a false positive.
162
278
  // Ideally we wouldn't need to suppress this.
@@ -168,7 +284,7 @@ pm_options_freeze_set(pm_options_t *options, bool freeze) {
168
284
  /**
169
285
  * Allocate and zero out the scopes array on the given options struct.
170
286
  */
171
- PRISM_EXPORTED_FUNCTION bool
287
+ bool
172
288
  pm_options_scopes_init(pm_options_t *options, size_t scopes_count) {
173
289
  options->scopes_count = scopes_count;
174
290
  options->scopes = xcalloc(scopes_count, sizeof(pm_options_scope_t));
@@ -176,10 +292,20 @@ pm_options_scopes_init(pm_options_t *options, size_t scopes_count) {
176
292
  }
177
293
 
178
294
  /**
179
- * Return a pointer to the scope at the given index within the given options.
295
+ * Return a constant pointer to the scope at the given index within the given
296
+ * options.
180
297
  */
181
- PRISM_EXPORTED_FUNCTION const pm_options_scope_t *
182
- pm_options_scope_get(const pm_options_t *options, size_t index) {
298
+ const pm_options_scope_t *
299
+ pm_options_scope(const pm_options_t *options, size_t index) {
300
+ return &options->scopes[index];
301
+ }
302
+
303
+ /**
304
+ * Return a mutable pointer to the scope at the given index within the given
305
+ * options.
306
+ */
307
+ pm_options_scope_t *
308
+ pm_options_scope_mut(pm_options_t *options, size_t index) {
183
309
  return &options->scopes[index];
184
310
  }
185
311
 
@@ -187,49 +313,38 @@ pm_options_scope_get(const pm_options_t *options, size_t index) {
187
313
  * Create a new options scope struct. This will hold a set of locals that are in
188
314
  * scope surrounding the code that is being parsed.
189
315
  */
190
- PRISM_EXPORTED_FUNCTION bool
316
+ void
191
317
  pm_options_scope_init(pm_options_scope_t *scope, size_t locals_count) {
192
318
  scope->locals_count = locals_count;
193
319
  scope->locals = xcalloc(locals_count, sizeof(pm_string_t));
194
320
  scope->forwarding = PM_OPTIONS_SCOPE_FORWARDING_NONE;
195
- return scope->locals != NULL;
321
+ if (scope->locals == NULL) abort();
196
322
  }
197
323
 
198
324
  /**
199
- * Return a pointer to the local at the given index within the given scope.
325
+ * Return a constant pointer to the local at the given index within the given
326
+ * scope.
200
327
  */
201
- PRISM_EXPORTED_FUNCTION const pm_string_t *
202
- pm_options_scope_local_get(const pm_options_scope_t *scope, size_t index) {
328
+ const pm_string_t *
329
+ pm_options_scope_local(const pm_options_scope_t *scope, size_t index) {
203
330
  return &scope->locals[index];
204
331
  }
205
332
 
206
333
  /**
207
- * Set the forwarding option on the given scope struct.
334
+ * Return a mutable pointer to the local at the given index within the given
335
+ * scope.
208
336
  */
209
- PRISM_EXPORTED_FUNCTION void
210
- pm_options_scope_forwarding_set(pm_options_scope_t *scope, uint8_t forwarding) {
211
- scope->forwarding = forwarding;
337
+ pm_string_t *
338
+ pm_options_scope_local_mut(pm_options_scope_t *scope, size_t index) {
339
+ return &scope->locals[index];
212
340
  }
213
341
 
214
342
  /**
215
- * Free the internal memory associated with the options.
343
+ * Set the forwarding option on the given scope struct.
216
344
  */
217
- PRISM_EXPORTED_FUNCTION void
218
- pm_options_free(pm_options_t *options) {
219
- pm_string_free(&options->filepath);
220
- pm_string_free(&options->encoding);
221
-
222
- for (size_t scope_index = 0; scope_index < options->scopes_count; scope_index++) {
223
- pm_options_scope_t *scope = &options->scopes[scope_index];
224
-
225
- for (size_t local_index = 0; local_index < scope->locals_count; local_index++) {
226
- pm_string_free(&scope->locals[local_index]);
227
- }
228
-
229
- xfree(scope->locals);
230
- }
231
-
232
- xfree(options->scopes);
345
+ void
346
+ pm_options_scope_forwarding_set(pm_options_scope_t *scope, uint8_t forwarding) {
347
+ scope->forwarding = forwarding;
233
348
  }
234
349
 
235
350
  /**
@@ -302,6 +417,7 @@ pm_options_read(pm_options_t *options, const char *data) {
302
417
  options->main_script = ((uint8_t) *data++) > 0;
303
418
  options->partial_script = ((uint8_t) *data++) > 0;
304
419
  options->freeze = ((uint8_t) *data++) > 0;
420
+ options->attach_comments = ((uint8_t) *data++) > 0;
305
421
 
306
422
  uint32_t scopes_count = pm_options_read_u32(data);
307
423
  data += 4;
@@ -314,10 +430,7 @@ pm_options_read(pm_options_t *options, const char *data) {
314
430
  data += 4;
315
431
 
316
432
  pm_options_scope_t *scope = &options->scopes[scope_index];
317
- if (!pm_options_scope_init(scope, locals_count)) {
318
- pm_options_free(options);
319
- return;
320
- }
433
+ pm_options_scope_init(scope, locals_count);
321
434
 
322
435
  uint8_t forwarding = (uint8_t) *data++;
323
436
  pm_options_scope_forwarding_set(&options->scopes[scope_index], forwarding);
data/src/parser.c ADDED
@@ -0,0 +1,349 @@
1
+ #include "prism/internal/parser.h"
2
+
3
+ #include "prism/internal/allocator.h"
4
+ #include "prism/internal/comments.h"
5
+ #include "prism/internal/diagnostic.h"
6
+ #include "prism/internal/encoding.h"
7
+ #include "prism/internal/magic_comments.h"
8
+
9
+ #include <stdlib.h>
10
+
11
+ /**
12
+ * Register a callback that will be called whenever prism changes the encoding
13
+ * it is using to parse based on the magic comment.
14
+ */
15
+ void
16
+ pm_parser_encoding_changed_callback_set(pm_parser_t *parser, pm_encoding_changed_callback_t callback) {
17
+ parser->encoding_changed_callback = callback;
18
+ }
19
+
20
+ /**
21
+ * Register a callback that will be called whenever a token is lexed.
22
+ */
23
+ void
24
+ pm_parser_lex_callback_set(pm_parser_t *parser, pm_lex_callback_t callback, void *data) {
25
+ parser->lex_callback.callback = callback;
26
+ parser->lex_callback.data = data;
27
+ }
28
+
29
+ /**
30
+ * Returns the opaque data that is passed to the lex callback when it is called.
31
+ */
32
+ void *
33
+ pm_parser_lex_callback_data(const pm_parser_t *parser) {
34
+ return parser->lex_callback.data;
35
+ }
36
+
37
+ /**
38
+ * Returns the raw pointer to the start of the source that is being parsed.
39
+ */
40
+ const uint8_t *
41
+ pm_parser_start(const pm_parser_t *parser) {
42
+ return parser->start;
43
+ }
44
+
45
+ /**
46
+ * Returns the raw pointer to the end of the source that is being parsed.
47
+ */
48
+ const uint8_t *
49
+ pm_parser_end(const pm_parser_t *parser) {
50
+ return parser->end;
51
+ }
52
+
53
+ /**
54
+ * Returns the line that the parser was considered to have started on.
55
+ *
56
+ * @param parser the parser whose start line we want to get
57
+ * @return the line that the parser was considered to have started on
58
+ */
59
+ int32_t
60
+ pm_parser_start_line(const pm_parser_t *parser) {
61
+ return parser->start_line;
62
+ }
63
+
64
+ /**
65
+ * Returns the name of the encoding that is being used to parse the source.
66
+ */
67
+ const char *
68
+ pm_parser_encoding_name(const pm_parser_t *parser) {
69
+ return parser->encoding->name;
70
+ }
71
+
72
+ /**
73
+ * Returns the width of the character at the given pointer in the encoding that
74
+ * is being used to parse the source.
75
+ */
76
+ size_t
77
+ pm_parser_encoding_char_width(const pm_parser_t *parser, const uint8_t *start, ptrdiff_t remaining) {
78
+ return parser->encoding->char_width(start, remaining);
79
+ }
80
+
81
+ /**
82
+ * Returns whether or not the parser is using the US-ASCII encoding.
83
+ */
84
+ bool
85
+ pm_parser_encoding_us_ascii(const pm_parser_t *parser) {
86
+ return parser->encoding == PM_ENCODING_US_ASCII_ENTRY;
87
+ }
88
+
89
+ /**
90
+ * Returns the filepath that is being used to parse the source.
91
+ */
92
+ const pm_string_t *
93
+ pm_parser_filepath(const pm_parser_t *parser) {
94
+ return &parser->filepath;
95
+ }
96
+
97
+ /**
98
+ * Find a constant in the parser's constant pool. Returns the id of the
99
+ * constant, or 0 if the constant is not found.
100
+ */
101
+ pm_constant_id_t
102
+ pm_parser_constant_find(const pm_parser_t *parser, const uint8_t *start, size_t length) {
103
+ return pm_constant_pool_find(&parser->constant_pool, start, length);
104
+ }
105
+
106
+ /**
107
+ * Returns the frozen string literal value of the parser.
108
+ */
109
+ int8_t
110
+ pm_parser_frozen_string_literal(const pm_parser_t *parser) {
111
+ return parser->frozen_string_literal;
112
+ }
113
+
114
+ /**
115
+ * Returns the line offsets that are associated with the given parser.
116
+ *
117
+ * @param parser the parser whose line offsets we want to get
118
+ * @return the line offsets that are associated with the given parser
119
+ */
120
+ const pm_line_offset_list_t *
121
+ pm_parser_line_offsets(const pm_parser_t *parser) {
122
+ return &parser->line_offsets;
123
+ }
124
+
125
+ /**
126
+ * Returns the location of the __DATA__ section that is associated with the
127
+ * given parser, if it exists.
128
+ */
129
+ const pm_location_t *
130
+ pm_parser_data_loc(const pm_parser_t *parser) {
131
+ return &parser->data_loc;
132
+ }
133
+
134
+ /**
135
+ * Returns whether the given parser is continuable, meaning that it could become
136
+ * valid if more input were appended, as opposed to being definitively invalid.
137
+ */
138
+ bool
139
+ pm_parser_continuable(const pm_parser_t *parser) {
140
+ return parser->continuable;
141
+ }
142
+
143
+ /**
144
+ * Returns the lex state of the parser. Note that this is an internal detail,
145
+ * and we are purposefully not returning an instance of the internal enum that
146
+ * we use to track this. This is only exposed because we need it for some very
147
+ * niche use cases. Most consumers should avoid this function.
148
+ */
149
+ int
150
+ pm_parser_lex_state(const pm_parser_t *parser) {
151
+ return (int) parser->lex_state;
152
+ }
153
+
154
+ /**
155
+ * Returns the location associated with the given comment.
156
+ */
157
+ pm_location_t
158
+ pm_comment_location(const pm_comment_t *comment) {
159
+ return comment->location;
160
+ }
161
+
162
+ /**
163
+ * Returns the type associated with the given comment.
164
+ */
165
+ pm_comment_type_t
166
+ pm_comment_type(const pm_comment_t *comment) {
167
+ return comment->type;
168
+ }
169
+
170
+ /**
171
+ * Returns the number of comments associated with the given parser.
172
+ */
173
+ size_t
174
+ pm_parser_comments_size(const pm_parser_t *parser) {
175
+ return parser->comment_list.size;
176
+ }
177
+
178
+ /**
179
+ * Iterates over the comments associated with the given parser and calls the
180
+ * given callback for each comment.
181
+ */
182
+ void
183
+ pm_parser_comments_each(const pm_parser_t *parser, pm_comment_callback_t callback, void *data) {
184
+ const pm_list_node_t *current = parser->comment_list.head;
185
+ while (current != NULL) {
186
+ const pm_comment_t *comment = (const pm_comment_t *) current;
187
+ callback(comment, data);
188
+ current = current->next;
189
+ }
190
+ }
191
+
192
+ /**
193
+ * Returns the number of comments owned by the given node.
194
+ */
195
+ uint32_t
196
+ pm_node_comments_size(const pm_parser_t *parser, const pm_node_t *node) {
197
+ return pm_parser_comment_range(parser, node->node_id).length;
198
+ }
199
+
200
+ /**
201
+ * Returns the comment at the given index among the comments owned by the given
202
+ * node.
203
+ */
204
+ const pm_comment_t *
205
+ pm_node_comment(const pm_parser_t *parser, const pm_node_t *node, uint32_t index) {
206
+ pm_comment_range_t range = pm_parser_comment_range(parser, node->node_id);
207
+ if (index >= range.length) return NULL;
208
+
209
+ return parser->comment_attachments.comments[parser->comment_attachments.attachments[range.index + index]];
210
+ }
211
+
212
+ /**
213
+ * Returns the index, among the comments associated with the given parser, of
214
+ * the comment at the given index among the comment attachments.
215
+ */
216
+ uint32_t
217
+ pm_parser_comment_attachment(const pm_parser_t *parser, uint32_t index) {
218
+ if (parser->comment_attachments.attachments == NULL || index >= parser->comment_list.size) return UINT32_MAX;
219
+ return parser->comment_attachments.attachments[index];
220
+ }
221
+
222
+ /**
223
+ * Returns the number of node ids that have a comment range.
224
+ */
225
+ uint32_t
226
+ pm_parser_comment_ranges_size(const pm_parser_t *parser) {
227
+ return parser->comment_attachments.ranges_size;
228
+ }
229
+
230
+ /**
231
+ * Returns the range of comment attachments owned by the node with the given id.
232
+ */
233
+ pm_comment_range_t
234
+ pm_parser_comment_range(const pm_parser_t *parser, uint32_t node_id) {
235
+ if (node_id >= parser->comment_attachments.ranges_size) return (pm_comment_range_t) { .index = 0, .length = 0 };
236
+ return parser->comment_attachments.ranges[node_id];
237
+ }
238
+
239
+ /**
240
+ * Returns the location associated with the given magic comment key.
241
+ */
242
+ pm_location_t
243
+ pm_magic_comment_key(const pm_magic_comment_t *magic_comment) {
244
+ return magic_comment->key;
245
+ }
246
+
247
+ /**
248
+ * Returns the location associated with the given magic comment value.
249
+ */
250
+ pm_location_t
251
+ pm_magic_comment_value(const pm_magic_comment_t *magic_comment) {
252
+ return magic_comment->value;
253
+ }
254
+
255
+ /**
256
+ * Returns the number of magic comments associated with the given parser.
257
+ */
258
+ size_t
259
+ pm_parser_magic_comments_size(const pm_parser_t *parser) {
260
+ return parser->magic_comment_list.size;
261
+ }
262
+
263
+ /**
264
+ * Iterates over the magic comments associated with the given parser and calls
265
+ * the given callback for each magic comment.
266
+ */
267
+ void
268
+ pm_parser_magic_comments_each(const pm_parser_t *parser, pm_magic_comment_callback_t callback, void *data) {
269
+ const pm_list_node_t *current = parser->magic_comment_list.head;
270
+ while (current != NULL) {
271
+ const pm_magic_comment_t *magic_comment = (const pm_magic_comment_t *) current;
272
+ callback(magic_comment, data);
273
+ current = current->next;
274
+ }
275
+ }
276
+
277
+ /**
278
+ * Returns the number of errors associated with the given parser.
279
+ */
280
+ size_t
281
+ pm_parser_errors_size(const pm_parser_t *parser) {
282
+ return parser->error_list.size;
283
+ }
284
+
285
+ /**
286
+ * Returns the number of warnings associated with the given parser.
287
+ */
288
+ size_t
289
+ pm_parser_warnings_size(const pm_parser_t *parser) {
290
+ return parser->warning_list.size;
291
+ }
292
+
293
+ static inline void
294
+ pm_parser_diagnostics_each(const pm_list_t *list, pm_diagnostic_callback_t callback, void *data) {
295
+ const pm_list_node_t *current = list->head;
296
+ while (current != NULL) {
297
+ const pm_diagnostic_t *diagnostic = (const pm_diagnostic_t *) current;
298
+ callback(diagnostic, data);
299
+ current = current->next;
300
+ }
301
+ }
302
+
303
+ /**
304
+ * Iterates over the errors associated with the given parser and calls the
305
+ * given callback for each error.
306
+ */
307
+ void
308
+ pm_parser_errors_each(const pm_parser_t *parser, pm_diagnostic_callback_t callback, void *data) {
309
+ pm_parser_diagnostics_each(&parser->error_list, callback, data);
310
+ }
311
+
312
+ /**
313
+ * Iterates over the warnings associated with the given parser and calls the
314
+ * given callback for each warning.
315
+ */
316
+ void
317
+ pm_parser_warnings_each(const pm_parser_t *parser, pm_diagnostic_callback_t callback, void *data) {
318
+ pm_parser_diagnostics_each(&parser->warning_list, callback, data);
319
+ }
320
+
321
+ /**
322
+ * Returns the number of constants in the constant pool associated with the
323
+ * given parser.
324
+ */
325
+ size_t
326
+ pm_parser_constants_size(const pm_parser_t *parser) {
327
+ return parser->constant_pool.size;
328
+ }
329
+
330
+ /**
331
+ * Iterates over the constants in the constant pool associated with the given
332
+ * parser and calls the given callback for each constant.
333
+ */
334
+ void
335
+ pm_parser_constants_each(const pm_parser_t *parser, pm_constant_callback_t callback, void *data) {
336
+ for (uint32_t index = 0; index < parser->constant_pool.size; index++) {
337
+ const pm_constant_t *constant = &parser->constant_pool.constants[index];
338
+ callback(constant, data);
339
+ }
340
+ }
341
+
342
+ /**
343
+ * Returns a pointer to the constant at the given id in the constant pool
344
+ * associated with the given parser.
345
+ */
346
+ const pm_constant_t *
347
+ pm_parser_constant(const pm_parser_t *parser, pm_constant_id_t constant_id) {
348
+ return pm_constant_pool_id_to_constant(&parser->constant_pool, constant_id);
349
+ }