prism 2.0.0.rc1 → 2.0.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -2
- data/CODE_OF_CONDUCT.md +1 -1
- data/LICENSE.md +1 -1
- data/docs/serialization.md +20 -6
- data/ext/prism/api_node.c +81 -81
- data/ext/prism/extension.c +54 -69
- data/ext/prism/extension.h +1 -1
- data/include/prism/arena.h +8 -0
- data/include/prism/arena.hpp +42 -0
- data/include/prism/ast.h +11 -1
- data/include/prism/ast.hpp +641 -0
- data/include/prism/buffer.h +8 -0
- data/include/prism/buffer.hpp +55 -0
- data/include/prism/comments.h +17 -0
- data/include/prism/compiler/accel.h +3 -1
- data/include/prism/compiler/branch.h +26 -0
- data/include/prism/compiler/bswap.h +46 -0
- data/include/prism/compiler/cplusplus.hpp +16 -0
- data/include/prism/compiler/endianness.h +34 -0
- data/include/prism/compiler/exceptions.hpp +17 -0
- data/include/prism/compiler/format.h +2 -0
- data/include/prism/compiler/lifetimebound.hpp +25 -0
- data/include/prism/constant_pool.h +25 -0
- data/include/prism/diagnostic.h +18 -0
- data/include/prism/errors_format.h +8 -0
- data/include/prism/internal/buffer.h +3 -0
- data/include/prism/internal/node.h +8 -4
- data/include/prism/internal/parser.h +20 -0
- data/include/prism/internal/stringy.h +1 -6
- data/include/prism/internal/xxh3.h +16 -0
- data/include/prism/json.h +8 -0
- data/include/prism/line_offset_list.h +8 -0
- data/include/prism/magic_comments.h +18 -0
- data/include/prism/node.h +55 -10
- data/include/prism/node.hpp +272 -0
- data/include/prism/node_type.hpp +38 -0
- data/include/prism/options.h +10 -1
- data/include/prism/options.hpp +43 -0
- data/include/prism/parser.h +93 -64
- data/include/prism/parser.hpp +274 -0
- data/include/prism/prettyprint.h +8 -0
- data/include/prism/serialize.h +8 -0
- data/include/prism/source.h +8 -0
- data/include/prism/stream.h +8 -0
- data/include/prism/string_query.h +19 -0
- data/include/prism/stringy.h +16 -27
- data/include/prism/stringy.hpp +31 -0
- data/include/prism/version.h +9 -1
- data/include/prism.h +0 -8
- data/include/prism.hpp +24 -0
- data/lib/prism/ffi.rb +6 -0
- data/lib/prism/node.rb +736 -0
- data/lib/prism/parse_result.rb +23 -8
- data/lib/prism/serialize.rb +2567 -3286
- data/lib/prism/string_query.rb +8 -0
- data/prism.gemspec +21 -4
- data/rbi/generated/prism/node.rbi +2430 -968
- data/rbi/generated/prism/parse_result.rbi +16 -4
- data/rbi/generated/prism/serialize.rbi +8 -4
- data/rbi/generated/prism/string_query.rbi +7 -0
- data/sig/generated/prism/node.rbs +2439 -967
- data/sig/generated/prism/parse_result.rbs +16 -4
- data/sig/generated/prism/serialize.rbs +9 -4
- data/sig/generated/prism/string_query.rbs +7 -0
- data/src/buffer.c +9 -0
- data/src/comments.c +2 -2
- data/src/diagnostic.c +8 -0
- data/src/node.c +216 -368
- data/src/options.c +7 -13
- data/src/parser.c +70 -48
- data/src/prism.c +581 -419
- data/src/regexp.c +0 -1
- data/src/serialize.c +2301 -1950
- data/src/source.c +8 -2
- data/src/string_query.c +14 -0
- data/src/stringy.c +3 -33
- data/src/xxh3.c +292 -0
- metadata +20 -3
data/include/prism/parser.h
CHANGED
|
@@ -16,6 +16,10 @@
|
|
|
16
16
|
#include "prism/magic_comments.h"
|
|
17
17
|
#include "prism/options.h"
|
|
18
18
|
|
|
19
|
+
#ifdef __cplusplus
|
|
20
|
+
extern "C" {
|
|
21
|
+
#endif
|
|
22
|
+
|
|
19
23
|
/**
|
|
20
24
|
* The parser used to parse Ruby source.
|
|
21
25
|
*/
|
|
@@ -150,6 +154,24 @@ PRISM_EXPORTED_FUNCTION const pm_string_t * pm_parser_filepath(const pm_parser_t
|
|
|
150
154
|
*/
|
|
151
155
|
PRISM_EXPORTED_FUNCTION pm_constant_id_t pm_parser_constant_find(const pm_parser_t *parser, const uint8_t *start, size_t length) PRISM_NONNULL(1, 2);
|
|
152
156
|
|
|
157
|
+
/**
|
|
158
|
+
* Add a constant to the parser's constant pool, for naming a node that was not
|
|
159
|
+
* parsed from the source. If the constant is already in the pool, its existing
|
|
160
|
+
* id is returned. Otherwise the parser copies the bytes, so they only need to
|
|
161
|
+
* remain valid for the duration of the call.
|
|
162
|
+
*
|
|
163
|
+
* Adding a constant makes the pool larger, so a cache with one entry per
|
|
164
|
+
* constant built beforehand from pm_parser_constants_size and
|
|
165
|
+
* pm_parser_constant_at does not cover it. Build such caches after adding any
|
|
166
|
+
* constants.
|
|
167
|
+
*
|
|
168
|
+
* @param parser the parser whose constant pool we want to add to
|
|
169
|
+
* @param start a pointer to the start of the string to add
|
|
170
|
+
* @param length the length of the string to add
|
|
171
|
+
* @returns the id of the constant
|
|
172
|
+
*/
|
|
173
|
+
PRISM_EXPORTED_FUNCTION pm_constant_id_t pm_parser_constant_insert(pm_parser_t *parser, const uint8_t *start, size_t length) PRISM_NONNULL(1, 2);
|
|
174
|
+
|
|
153
175
|
/**
|
|
154
176
|
* Returns the frozen string literal value of the parser, as determined by the
|
|
155
177
|
* frozen_string_literal magic comment or the option set on the parser.
|
|
@@ -177,6 +199,27 @@ PRISM_EXPORTED_FUNCTION const pm_line_offset_list_t * pm_parser_line_offsets(con
|
|
|
177
199
|
*/
|
|
178
200
|
PRISM_EXPORTED_FUNCTION const pm_location_t * pm_parser_data_loc(const pm_parser_t *parser) PRISM_NONNULL(1);
|
|
179
201
|
|
|
202
|
+
/**
|
|
203
|
+
* Returns the checksum of the source code that was parsed. The data section
|
|
204
|
+
* after an __END__ marker is not code, so the hash covers the source only up to
|
|
205
|
+
* and including the newline that ends the __END__ line. The __END__ marker is
|
|
206
|
+
* only found by parsing, so this must be called after pm_parse.
|
|
207
|
+
*
|
|
208
|
+
* The hash is computed from the source on each call rather than during
|
|
209
|
+
* parsing, so that parses that never ask for it do not pay for it. This
|
|
210
|
+
* requires the source to still be alive, and callers that need the value more
|
|
211
|
+
* than once should keep it.
|
|
212
|
+
*
|
|
213
|
+
* The hash is currently the 64-bit variant of XXH3 with a seed of 0. It is not
|
|
214
|
+
* cryptographic, and the algorithm may change between versions of prism, so
|
|
215
|
+
* hashes should only be compared against other hashes computed by the same
|
|
216
|
+
* version of prism.
|
|
217
|
+
*
|
|
218
|
+
* @param parser the parser whose checksum we want to get
|
|
219
|
+
* @returns the checksum of the source code that was parsed
|
|
220
|
+
*/
|
|
221
|
+
PRISM_EXPORTED_FUNCTION uint64_t pm_parser_checksum(const pm_parser_t *parser) PRISM_NONNULL(1);
|
|
222
|
+
|
|
180
223
|
/**
|
|
181
224
|
* Returns whether the given parser is continuable, meaning that it could become
|
|
182
225
|
* valid if more input were appended, as opposed to being definitively invalid.
|
|
@@ -206,22 +249,19 @@ PRISM_EXPORTED_FUNCTION int pm_parser_lex_state(const pm_parser_t *parser) PRISM
|
|
|
206
249
|
PRISM_EXPORTED_FUNCTION size_t pm_parser_comments_size(const pm_parser_t *parser) PRISM_NONNULL(1);
|
|
207
250
|
|
|
208
251
|
/**
|
|
209
|
-
*
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
*
|
|
215
|
-
*
|
|
252
|
+
* Returns the first comment associated with the given parser. Iterate over the
|
|
253
|
+
* rest with pm_comment_next, as in:
|
|
254
|
+
*
|
|
255
|
+
* ```c
|
|
256
|
+
* for (const pm_comment_t *comment = pm_parser_comments_first(parser); comment != NULL; comment = pm_comment_next(comment)) {
|
|
257
|
+
* pm_location_t location = pm_comment_location(comment);
|
|
258
|
+
* }
|
|
259
|
+
* ```
|
|
216
260
|
*
|
|
217
261
|
* @param parser the parser whose comments we want to iterate over
|
|
218
|
-
* @
|
|
219
|
-
* will be passed a pointer to the comment and the data parameter passed to
|
|
220
|
-
* this function.
|
|
221
|
-
* @param data the data to pass to the callback function for each comment. This
|
|
222
|
-
* can be NULL if no data needs to be passed to the callback function.
|
|
262
|
+
* @returns the first comment, or NULL if there are no comments
|
|
223
263
|
*/
|
|
224
|
-
PRISM_EXPORTED_FUNCTION
|
|
264
|
+
PRISM_EXPORTED_FUNCTION const pm_comment_t * pm_parser_comments_first(const pm_parser_t *parser) PRISM_NONNULL(1);
|
|
225
265
|
|
|
226
266
|
/**
|
|
227
267
|
* Returns the number of comments owned by the given node. This is 0 if the
|
|
@@ -288,22 +328,13 @@ PRISM_EXPORTED_FUNCTION pm_comment_range_t pm_parser_comment_range(const pm_pars
|
|
|
288
328
|
PRISM_EXPORTED_FUNCTION size_t pm_parser_magic_comments_size(const pm_parser_t *parser) PRISM_NONNULL(1);
|
|
289
329
|
|
|
290
330
|
/**
|
|
291
|
-
*
|
|
292
|
-
|
|
293
|
-
typedef void (*pm_magic_comment_callback_t)(const pm_magic_comment_t *magic_comment, void *data);
|
|
294
|
-
|
|
295
|
-
/**
|
|
296
|
-
* Iterates over the magic comments associated with the given parser and calls the
|
|
297
|
-
* given callback for each magic comment.
|
|
331
|
+
* Returns the first magic comment associated with the given parser. Iterate
|
|
332
|
+
* over the rest with pm_magic_comment_next.
|
|
298
333
|
*
|
|
299
334
|
* @param parser the parser whose magic comments we want to iterate over
|
|
300
|
-
* @
|
|
301
|
-
* function will be passed a pointer to the magic comment and the data
|
|
302
|
-
* parameter passed to this function.
|
|
303
|
-
* @param data the data to pass to the callback function for each magic comment.
|
|
304
|
-
* This can be NULL if no data needs to be passed to the callback function.
|
|
335
|
+
* @returns the first magic comment, or NULL if there are no magic comments
|
|
305
336
|
*/
|
|
306
|
-
PRISM_EXPORTED_FUNCTION
|
|
337
|
+
PRISM_EXPORTED_FUNCTION const pm_magic_comment_t * pm_parser_magic_comments_first(const pm_parser_t *parser) PRISM_NONNULL(1);
|
|
307
338
|
|
|
308
339
|
/**
|
|
309
340
|
* Returns the number of errors associated with the given parser.
|
|
@@ -322,36 +353,22 @@ PRISM_EXPORTED_FUNCTION size_t pm_parser_errors_size(const pm_parser_t *parser)
|
|
|
322
353
|
PRISM_EXPORTED_FUNCTION size_t pm_parser_warnings_size(const pm_parser_t *parser) PRISM_NONNULL(1);
|
|
323
354
|
|
|
324
355
|
/**
|
|
325
|
-
*
|
|
326
|
-
*
|
|
327
|
-
*/
|
|
328
|
-
typedef void (*pm_diagnostic_callback_t)(const pm_diagnostic_t *diagnostic, void *data);
|
|
329
|
-
|
|
330
|
-
/**
|
|
331
|
-
* Iterates over the errors associated with the given parser and calls the
|
|
332
|
-
* given callback for each error.
|
|
356
|
+
* Returns the first error associated with the given parser. Iterate over the
|
|
357
|
+
* rest with pm_diagnostic_next.
|
|
333
358
|
*
|
|
334
359
|
* @param parser the parser whose errors we want to iterate over
|
|
335
|
-
* @
|
|
336
|
-
* will be passed a pointer to the error and the data parameter passed to
|
|
337
|
-
* this function.
|
|
338
|
-
* @param data the data to pass to the callback function for each error. This
|
|
339
|
-
* can be NULL if no data needs to be passed to the callback function.
|
|
360
|
+
* @returns the first error, or NULL if there are no errors
|
|
340
361
|
*/
|
|
341
|
-
PRISM_EXPORTED_FUNCTION
|
|
362
|
+
PRISM_EXPORTED_FUNCTION const pm_diagnostic_t * pm_parser_errors_first(const pm_parser_t *parser) PRISM_NONNULL(1);
|
|
342
363
|
|
|
343
364
|
/**
|
|
344
|
-
*
|
|
345
|
-
*
|
|
365
|
+
* Returns the first warning associated with the given parser. Iterate over the
|
|
366
|
+
* rest with pm_diagnostic_next.
|
|
346
367
|
*
|
|
347
368
|
* @param parser the parser whose warnings we want to iterate over
|
|
348
|
-
* @
|
|
349
|
-
* will be passed a pointer to the warning and the data parameter passed to
|
|
350
|
-
* this function.
|
|
351
|
-
* @param data the data to pass to the callback function for each warning. This
|
|
352
|
-
* can be NULL if no data needs to be passed to the callback function.
|
|
369
|
+
* @returns the first warning, or NULL if there are no warnings
|
|
353
370
|
*/
|
|
354
|
-
PRISM_EXPORTED_FUNCTION
|
|
371
|
+
PRISM_EXPORTED_FUNCTION const pm_diagnostic_t * pm_parser_warnings_first(const pm_parser_t *parser) PRISM_NONNULL(1);
|
|
355
372
|
|
|
356
373
|
/**
|
|
357
374
|
* Returns the number of constants in the constant pool associated with the
|
|
@@ -365,30 +382,38 @@ PRISM_EXPORTED_FUNCTION void pm_parser_warnings_each(const pm_parser_t *parser,
|
|
|
365
382
|
PRISM_EXPORTED_FUNCTION size_t pm_parser_constants_size(const pm_parser_t *parser) PRISM_NONNULL(1);
|
|
366
383
|
|
|
367
384
|
/**
|
|
368
|
-
*
|
|
369
|
-
*
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
*
|
|
375
|
-
*
|
|
385
|
+
* Returns the constant at the given index in the constant pool associated with
|
|
386
|
+
* the given parser. Together with pm_constant_id_index, this lets a caller
|
|
387
|
+
* build a cache with one entry per constant and then find the entry for any
|
|
388
|
+
* constant id, as in:
|
|
389
|
+
*
|
|
390
|
+
* ```c
|
|
391
|
+
* size_t size = pm_parser_constants_size(parser);
|
|
392
|
+
* for (size_t index = 0; index < size; index++) {
|
|
393
|
+
* cache[index] = convert(pm_parser_constant_at(parser, index));
|
|
394
|
+
* }
|
|
395
|
+
*
|
|
396
|
+
* value = cache[pm_constant_id_index(constant_id)];
|
|
397
|
+
* ```
|
|
376
398
|
*
|
|
377
|
-
*
|
|
378
|
-
*
|
|
379
|
-
*
|
|
380
|
-
*
|
|
381
|
-
* @param
|
|
382
|
-
*
|
|
399
|
+
* For any constant id, pm_parser_constant_at(parser,
|
|
400
|
+
* pm_constant_id_index(constant_id)) is pm_parser_constant(parser,
|
|
401
|
+
* constant_id).
|
|
402
|
+
*
|
|
403
|
+
* @param parser the parser whose constant pool we want to look up from
|
|
404
|
+
* @param index the index of the constant, which must be less than
|
|
405
|
+
* pm_parser_constants_size(parser)
|
|
406
|
+
* @returns a pointer to the constant at the given index
|
|
383
407
|
*/
|
|
384
|
-
PRISM_EXPORTED_FUNCTION
|
|
408
|
+
PRISM_EXPORTED_FUNCTION const pm_constant_t * pm_parser_constant_at(const pm_parser_t *parser, size_t index) PRISM_NONNULL(1);
|
|
385
409
|
|
|
386
410
|
/**
|
|
387
411
|
* Returns a pointer to the constant at the given id in the constant pool
|
|
388
412
|
* associated with the given parser.
|
|
389
413
|
*
|
|
390
414
|
* @param parser the parser whose constant pool we want to look up from
|
|
391
|
-
* @param constant_id the id of the constant to look up
|
|
415
|
+
* @param constant_id the id of the constant to look up. Optional constant
|
|
416
|
+
* fields on nodes hold 0 when they are absent, which is not a valid id.
|
|
392
417
|
* @returns a pointer to the constant at the given id
|
|
393
418
|
*/
|
|
394
419
|
PRISM_EXPORTED_FUNCTION const pm_constant_t * pm_parser_constant(const pm_parser_t *parser, pm_constant_id_t constant_id) PRISM_NONNULL(1);
|
|
@@ -401,4 +426,8 @@ PRISM_EXPORTED_FUNCTION const pm_constant_t * pm_parser_constant(const pm_parser
|
|
|
401
426
|
*/
|
|
402
427
|
PRISM_EXPORTED_FUNCTION pm_node_t * pm_parse(pm_parser_t *parser) PRISM_NONNULL(1);
|
|
403
428
|
|
|
429
|
+
#ifdef __cplusplus
|
|
430
|
+
}
|
|
431
|
+
#endif
|
|
432
|
+
|
|
404
433
|
#endif
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file parser.hpp
|
|
3
|
+
*
|
|
4
|
+
* Ownership of parsers from C++, and lookups through a parser into the source,
|
|
5
|
+
* the constant pool, comments, and diagnostics.
|
|
6
|
+
*/
|
|
7
|
+
#ifndef PRISM_PARSER_HPP
|
|
8
|
+
#define PRISM_PARSER_HPP
|
|
9
|
+
|
|
10
|
+
#include "prism/compiler/cplusplus.hpp"
|
|
11
|
+
#include "prism/compiler/lifetimebound.hpp"
|
|
12
|
+
|
|
13
|
+
#include "prism/arena.h"
|
|
14
|
+
#include "prism/constant_pool.h"
|
|
15
|
+
#include "prism/line_offset_list.h"
|
|
16
|
+
#include "prism/parser.h"
|
|
17
|
+
|
|
18
|
+
#include <cassert>
|
|
19
|
+
#include <cstddef>
|
|
20
|
+
#include <cstdint>
|
|
21
|
+
#include <iterator>
|
|
22
|
+
#include <memory>
|
|
23
|
+
#include <string_view>
|
|
24
|
+
|
|
25
|
+
namespace prism {
|
|
26
|
+
|
|
27
|
+
/** Frees a parser with pm_parser_free. */
|
|
28
|
+
struct parser_deleter {
|
|
29
|
+
/**
|
|
30
|
+
* Free the given parser.
|
|
31
|
+
*
|
|
32
|
+
* @param parser The parser to free.
|
|
33
|
+
*/
|
|
34
|
+
void operator()(pm_parser_t *parser) const noexcept { pm_parser_free(parser); }
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/** An owned parser. */
|
|
38
|
+
using unique_parser = std::unique_ptr<pm_parser_t, parser_deleter>;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Allocate a new parser over the given source. The source, the arena, and the
|
|
42
|
+
* options (which may be null) are not copied, so all three must outlive the
|
|
43
|
+
* parser. Allocation failure aborts, so this never throws.
|
|
44
|
+
*
|
|
45
|
+
* @param arena The arena to use for allocations.
|
|
46
|
+
* @param source The source code to parse.
|
|
47
|
+
* @param options The parse options, or null for defaults.
|
|
48
|
+
* @return A unique_parser owning the newly allocated parser.
|
|
49
|
+
*/
|
|
50
|
+
[[nodiscard]] inline unique_parser
|
|
51
|
+
make_parser(pm_arena_t *arena PRISM_LIFETIMEBOUND, std::string_view source PRISM_LIFETIMEBOUND, const pm_options_t *options PRISM_LIFETIMEBOUND = nullptr) noexcept {
|
|
52
|
+
return unique_parser(pm_parser_new(arena, reinterpret_cast<const std::uint8_t *>(source.data()), source.size(), options));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* The name of the constant with the given id, which must not be zero. Fields
|
|
57
|
+
* holding an optional constant use zero for none, so check those first.
|
|
58
|
+
*
|
|
59
|
+
* @param parser The parser containing the constant.
|
|
60
|
+
* @param constant_id The id of the constant.
|
|
61
|
+
* @return The value of the constant.
|
|
62
|
+
*/
|
|
63
|
+
[[nodiscard]] inline std::string_view
|
|
64
|
+
constant(const pm_parser_t *parser PRISM_LIFETIMEBOUND, pm_constant_id_t constant_id) noexcept {
|
|
65
|
+
assert(constant_id != 0);
|
|
66
|
+
const pm_constant_t *entry = pm_parser_constant(parser, constant_id);
|
|
67
|
+
return std::string_view(reinterpret_cast<const char *>(pm_constant_start(entry)), pm_constant_length(entry));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* The bytes of source that the given location covers.
|
|
72
|
+
*
|
|
73
|
+
* @param parser The parser containing the source.
|
|
74
|
+
* @param location The location in the source.
|
|
75
|
+
* @return The bytes of source covered by the location.
|
|
76
|
+
*/
|
|
77
|
+
[[nodiscard]] inline std::string_view
|
|
78
|
+
slice(const pm_parser_t *parser PRISM_LIFETIMEBOUND, pm_location_t location) noexcept {
|
|
79
|
+
return std::string_view(reinterpret_cast<const char *>(pm_parser_start(parser) + location.start), location.length);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* The line and column of the given byte offset into the source. Lines start at
|
|
84
|
+
* the parser's start line, and columns are byte offsets from the line start.
|
|
85
|
+
*
|
|
86
|
+
* @param parser The parser containing the source.
|
|
87
|
+
* @param offset The byte offset into the source.
|
|
88
|
+
* @return The line and column of the byte offset.
|
|
89
|
+
*/
|
|
90
|
+
[[nodiscard]] inline pm_line_column_t
|
|
91
|
+
line_column(const pm_parser_t *parser, std::uint32_t offset) noexcept {
|
|
92
|
+
return pm_line_offset_list_line_column(pm_parser_line_offsets(parser), offset, pm_parser_start_line(parser));
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
namespace detail {
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* The diagnostics, comments, or magic comments found while parsing, usable in a
|
|
99
|
+
* range-based for loop and with the standard algorithms. Each element is a
|
|
100
|
+
* pointer to the C struct, which the C accessors read, and Next is the C
|
|
101
|
+
* function that returns the item after a given one. It refers to the parser
|
|
102
|
+
* rather than copying from it, so the parser must outlive it. It is used
|
|
103
|
+
* through diagnostic_range, comment_range, and magic_comment_range.
|
|
104
|
+
*/
|
|
105
|
+
template <typename T, const T *(*Next)(const T *)> class next_range {
|
|
106
|
+
public:
|
|
107
|
+
/** Steps through the items one after another. */
|
|
108
|
+
class iterator {
|
|
109
|
+
public:
|
|
110
|
+
/** The iterator category, for the standard algorithms. */
|
|
111
|
+
using iterator_category = std::forward_iterator_tag;
|
|
112
|
+
|
|
113
|
+
/** The type of each element. */
|
|
114
|
+
using value_type = const T *;
|
|
115
|
+
|
|
116
|
+
/** The type of the distance between two iterators. */
|
|
117
|
+
using difference_type = std::ptrdiff_t;
|
|
118
|
+
|
|
119
|
+
/** The type of a pointer to an element. */
|
|
120
|
+
using pointer = const value_type *;
|
|
121
|
+
|
|
122
|
+
/** The type of a reference to an element. */
|
|
123
|
+
using reference = const value_type &;
|
|
124
|
+
|
|
125
|
+
/** Create the iterator that marks the end of the items. */
|
|
126
|
+
iterator() noexcept = default;
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Create an iterator at the given item.
|
|
130
|
+
*
|
|
131
|
+
* @param current The current item.
|
|
132
|
+
*/
|
|
133
|
+
explicit iterator(const T *current) noexcept : current_(current) {}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* The item at this position, which must not be the end.
|
|
137
|
+
*
|
|
138
|
+
* @return The current item.
|
|
139
|
+
*/
|
|
140
|
+
reference operator*() const noexcept { return current_; }
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Advance to the next item.
|
|
144
|
+
*
|
|
145
|
+
* @return The iterator after advancing.
|
|
146
|
+
*/
|
|
147
|
+
iterator &
|
|
148
|
+
operator++() noexcept {
|
|
149
|
+
assert(current_ != nullptr);
|
|
150
|
+
current_ = Next(current_);
|
|
151
|
+
return *this;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Advance to the next item, returning the iterator from before.
|
|
156
|
+
*
|
|
157
|
+
* @return The iterator from before advancing.
|
|
158
|
+
*/
|
|
159
|
+
iterator
|
|
160
|
+
operator++(int) noexcept {
|
|
161
|
+
iterator previous = *this;
|
|
162
|
+
++*this;
|
|
163
|
+
return previous;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/** Whether the two iterators are at the same item. */
|
|
167
|
+
friend bool operator==(iterator left, iterator right) noexcept { return left.current_ == right.current_; }
|
|
168
|
+
|
|
169
|
+
/** Whether the two iterators are at different items. */
|
|
170
|
+
friend bool operator!=(iterator left, iterator right) noexcept { return left.current_ != right.current_; }
|
|
171
|
+
|
|
172
|
+
private:
|
|
173
|
+
const T *current_ = nullptr;
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Create a range of the given number of items starting at first.
|
|
178
|
+
*
|
|
179
|
+
* @param first The first item.
|
|
180
|
+
* @param size The number of items.
|
|
181
|
+
*/
|
|
182
|
+
next_range(const T *first, std::size_t size) noexcept : first_(first), size_(size) {}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* An iterator at the first item.
|
|
186
|
+
*
|
|
187
|
+
* @return An iterator at the first item.
|
|
188
|
+
*/
|
|
189
|
+
iterator begin() const noexcept { return iterator(first_); }
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* An iterator past the last item.
|
|
193
|
+
*
|
|
194
|
+
* @return An iterator past the last item.
|
|
195
|
+
*/
|
|
196
|
+
iterator end() const noexcept { return iterator(); }
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* The number of items.
|
|
200
|
+
*
|
|
201
|
+
* @return The number of items.
|
|
202
|
+
*/
|
|
203
|
+
std::size_t size() const noexcept { return size_; }
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Whether there are no items.
|
|
207
|
+
*
|
|
208
|
+
* @return Whether there are no items.
|
|
209
|
+
*/
|
|
210
|
+
[[nodiscard]] bool empty() const noexcept { return size_ == 0; }
|
|
211
|
+
|
|
212
|
+
private:
|
|
213
|
+
const T *first_;
|
|
214
|
+
std::size_t size_;
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/** The errors or warnings found while parsing. */
|
|
220
|
+
using diagnostic_range = detail::next_range<pm_diagnostic_t, pm_diagnostic_next>;
|
|
221
|
+
|
|
222
|
+
/** The comments found while parsing. */
|
|
223
|
+
using comment_range = detail::next_range<pm_comment_t, pm_comment_next>;
|
|
224
|
+
|
|
225
|
+
/** The magic comments found while parsing. */
|
|
226
|
+
using magic_comment_range = detail::next_range<pm_magic_comment_t, pm_magic_comment_next>;
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* The errors found while parsing.
|
|
230
|
+
*
|
|
231
|
+
* @param parser The parser containing the source.
|
|
232
|
+
* @return The range of errors found while parsing.
|
|
233
|
+
*/
|
|
234
|
+
[[nodiscard]] inline diagnostic_range
|
|
235
|
+
errors(const pm_parser_t *parser PRISM_LIFETIMEBOUND) noexcept {
|
|
236
|
+
return diagnostic_range(pm_parser_errors_first(parser), pm_parser_errors_size(parser));
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* The warnings found while parsing.
|
|
241
|
+
*
|
|
242
|
+
* @param parser The parser containing the source.
|
|
243
|
+
* @return The range of warnings found while parsing.
|
|
244
|
+
*/
|
|
245
|
+
[[nodiscard]] inline diagnostic_range
|
|
246
|
+
warnings(const pm_parser_t *parser PRISM_LIFETIMEBOUND) noexcept {
|
|
247
|
+
return diagnostic_range(pm_parser_warnings_first(parser), pm_parser_warnings_size(parser));
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* The comments found while parsing, in source order.
|
|
252
|
+
*
|
|
253
|
+
* @param parser The parser containing the source.
|
|
254
|
+
* @return The range of comments found while parsing.
|
|
255
|
+
*/
|
|
256
|
+
[[nodiscard]] inline comment_range
|
|
257
|
+
comments(const pm_parser_t *parser PRISM_LIFETIMEBOUND) noexcept {
|
|
258
|
+
return comment_range(pm_parser_comments_first(parser), pm_parser_comments_size(parser));
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* The magic comments found while parsing.
|
|
263
|
+
*
|
|
264
|
+
* @param parser The parser containing the source.
|
|
265
|
+
* @return The range of magic comments found while parsing.
|
|
266
|
+
*/
|
|
267
|
+
[[nodiscard]] inline magic_comment_range
|
|
268
|
+
magic_comments(const pm_parser_t *parser PRISM_LIFETIMEBOUND) noexcept {
|
|
269
|
+
return magic_comment_range(pm_parser_magic_comments_first(parser), pm_parser_magic_comments_size(parser));
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
#endif
|
data/include/prism/prettyprint.h
CHANGED
|
@@ -17,6 +17,10 @@
|
|
|
17
17
|
#include "prism/buffer.h"
|
|
18
18
|
#include "prism/parser.h"
|
|
19
19
|
|
|
20
|
+
#ifdef __cplusplus
|
|
21
|
+
extern "C" {
|
|
22
|
+
#endif
|
|
23
|
+
|
|
20
24
|
/**
|
|
21
25
|
* Pretty-prints the AST represented by the given node to the given buffer.
|
|
22
26
|
*
|
|
@@ -26,6 +30,10 @@
|
|
|
26
30
|
*/
|
|
27
31
|
PRISM_EXPORTED_FUNCTION void pm_prettyprint(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm_node_t *node) PRISM_NONNULL(1, 2, 3);
|
|
28
32
|
|
|
33
|
+
#ifdef __cplusplus
|
|
34
|
+
}
|
|
35
|
+
#endif
|
|
36
|
+
|
|
29
37
|
#endif
|
|
30
38
|
|
|
31
39
|
#endif
|
data/include/prism/serialize.h
CHANGED
|
@@ -22,6 +22,10 @@
|
|
|
22
22
|
#include "prism/source.h"
|
|
23
23
|
#include "prism/stream.h"
|
|
24
24
|
|
|
25
|
+
#ifdef __cplusplus
|
|
26
|
+
extern "C" {
|
|
27
|
+
#endif
|
|
28
|
+
|
|
25
29
|
/**
|
|
26
30
|
* Serialize the AST represented by the given node to the given buffer.
|
|
27
31
|
*
|
|
@@ -110,6 +114,10 @@ PRISM_EXPORTED_FUNCTION bool pm_serialize_parse_success_p(const uint8_t *source,
|
|
|
110
114
|
*/
|
|
111
115
|
PRISM_EXPORTED_FUNCTION int8_t pm_serialize_parse_errors_format(pm_buffer_t *buffer, const uint8_t *source, size_t size, const char *data, pm_errors_format_type_t format_type) PRISM_NONNULL(1, 2);
|
|
112
116
|
|
|
117
|
+
#ifdef __cplusplus
|
|
118
|
+
}
|
|
119
|
+
#endif
|
|
120
|
+
|
|
113
121
|
#endif
|
|
114
122
|
|
|
115
123
|
#endif
|
data/include/prism/source.h
CHANGED
|
@@ -15,6 +15,10 @@
|
|
|
15
15
|
#include <stddef.h>
|
|
16
16
|
#include <stdint.h>
|
|
17
17
|
|
|
18
|
+
#ifdef __cplusplus
|
|
19
|
+
extern "C" {
|
|
20
|
+
#endif
|
|
21
|
+
|
|
18
22
|
/**
|
|
19
23
|
* An opaque type representing source code being parsed.
|
|
20
24
|
*/
|
|
@@ -152,4 +156,8 @@ PRISM_EXPORTED_FUNCTION size_t pm_source_length(const pm_source_t *source) PRISM
|
|
|
152
156
|
*/
|
|
153
157
|
PRISM_EXPORTED_FUNCTION const uint8_t * pm_source_source(const pm_source_t *source) PRISM_NONNULL(1);
|
|
154
158
|
|
|
159
|
+
#ifdef __cplusplus
|
|
160
|
+
}
|
|
161
|
+
#endif
|
|
162
|
+
|
|
155
163
|
#endif
|
data/include/prism/stream.h
CHANGED
|
@@ -14,6 +14,10 @@
|
|
|
14
14
|
#include "prism/parser.h"
|
|
15
15
|
#include "prism/source.h"
|
|
16
16
|
|
|
17
|
+
#ifdef __cplusplus
|
|
18
|
+
extern "C" {
|
|
19
|
+
#endif
|
|
20
|
+
|
|
17
21
|
/**
|
|
18
22
|
* Parse a stream of Ruby source and return the tree.
|
|
19
23
|
*
|
|
@@ -25,4 +29,8 @@
|
|
|
25
29
|
*/
|
|
26
30
|
PRISM_EXPORTED_FUNCTION pm_node_t * pm_parse_stream(pm_parser_t **parser, pm_arena_t *arena, pm_source_t *source, const pm_options_t *options) PRISM_NONNULL(1, 2, 3);
|
|
27
31
|
|
|
32
|
+
#ifdef __cplusplus
|
|
33
|
+
}
|
|
34
|
+
#endif
|
|
35
|
+
|
|
28
36
|
#endif
|
|
@@ -13,6 +13,10 @@
|
|
|
13
13
|
#include <stddef.h>
|
|
14
14
|
#include <stdint.h>
|
|
15
15
|
|
|
16
|
+
#ifdef __cplusplus
|
|
17
|
+
extern "C" {
|
|
18
|
+
#endif
|
|
19
|
+
|
|
16
20
|
/**
|
|
17
21
|
* Represents the results of a slice query.
|
|
18
22
|
*/
|
|
@@ -60,4 +64,19 @@ PRISM_EXPORTED_FUNCTION pm_string_query_t pm_string_query_constant(const uint8_t
|
|
|
60
64
|
*/
|
|
61
65
|
PRISM_EXPORTED_FUNCTION pm_string_query_t pm_string_query_method_name(const uint8_t *source, size_t length, const char *encoding_name) PRISM_NONNULL(1, 3);
|
|
62
66
|
|
|
67
|
+
/**
|
|
68
|
+
* Check that the slice is a keyword.
|
|
69
|
+
*
|
|
70
|
+
* @param source The source to check.
|
|
71
|
+
* @param length The length of the source.
|
|
72
|
+
* @param encoding_name The name of the encoding of the source.
|
|
73
|
+
* @returns PM_STRING_QUERY_TRUE if the query is true, PM_STRING_QUERY_FALSE if
|
|
74
|
+
* the query is false, and PM_STRING_QUERY_ERROR if the encoding was invalid.
|
|
75
|
+
*/
|
|
76
|
+
PRISM_EXPORTED_FUNCTION pm_string_query_t pm_string_query_keyword(const uint8_t *source, size_t length, const char *encoding_name) PRISM_NONNULL(1, 3);
|
|
77
|
+
|
|
78
|
+
#ifdef __cplusplus
|
|
79
|
+
}
|
|
80
|
+
#endif
|
|
81
|
+
|
|
63
82
|
#endif
|