prism 2.0.0.rc2 → 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 +9 -2
- data/docs/serialization.md +19 -6
- data/ext/prism/api_node.c +80 -80
- data/ext/prism/extension.c +34 -67
- 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/branch.h +26 -0
- data/include/prism/compiler/cplusplus.hpp +16 -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/node.h +8 -4
- data/include/prism/internal/stringy.h +1 -6
- 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 +72 -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 +8 -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/serialize.rb +2549 -3281
- data/prism.gemspec +14 -1
- data/rbi/generated/prism/node.rbi +736 -0
- data/rbi/generated/prism/serialize.rbi +6 -5
- data/sig/generated/prism/node.rbs +736 -0
- data/sig/generated/prism/serialize.rbs +7 -5
- 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 +52 -48
- data/src/prism.c +175 -194
- data/src/regexp.c +0 -1
- data/src/serialize.c +2300 -1950
- data/src/source.c +8 -2
- data/src/stringy.c +3 -33
- metadata +14 -1
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file node.hpp
|
|
3
|
+
*
|
|
4
|
+
* Checked casts between node structs, iteration over lists of nodes, and
|
|
5
|
+
* walking the tree from C++.
|
|
6
|
+
*/
|
|
7
|
+
#ifndef PRISM_NODE_HPP
|
|
8
|
+
#define PRISM_NODE_HPP
|
|
9
|
+
|
|
10
|
+
#include "prism/compiler/cplusplus.hpp"
|
|
11
|
+
#include "prism/compiler/exceptions.hpp"
|
|
12
|
+
#include "prism/compiler/lifetimebound.hpp"
|
|
13
|
+
|
|
14
|
+
#include "prism/ast.hpp"
|
|
15
|
+
#include "prism/node.h"
|
|
16
|
+
#include "prism/node_type.hpp"
|
|
17
|
+
|
|
18
|
+
#include <cassert>
|
|
19
|
+
#include <cstddef>
|
|
20
|
+
#include <exception>
|
|
21
|
+
#include <functional>
|
|
22
|
+
#include <memory>
|
|
23
|
+
#include <type_traits>
|
|
24
|
+
|
|
25
|
+
namespace prism {
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Whether the given node, which must not be null, is of the given struct
|
|
29
|
+
*
|
|
30
|
+
* @tparam T The node struct type to check against.
|
|
31
|
+
* @param node The node to check.
|
|
32
|
+
* @return True if the node is of the given struct, false otherwise.
|
|
33
|
+
*/
|
|
34
|
+
template <typename T> [[nodiscard]] bool
|
|
35
|
+
isa(const pm_node_t *node) noexcept {
|
|
36
|
+
static_assert(is_node_v<T>, "isa<T> requires a node struct declared in ast.h");
|
|
37
|
+
assert(node != nullptr);
|
|
38
|
+
return node->type == node_type_v<T>;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Cast the given node, which must not be null and must be of the given struct,
|
|
43
|
+
* to that struct. The type is checked in debug builds.
|
|
44
|
+
*
|
|
45
|
+
* @tparam T The node struct type to cast to.
|
|
46
|
+
* @param node The node to cast.
|
|
47
|
+
* @return The node cast to the given struct.
|
|
48
|
+
*/
|
|
49
|
+
template <typename T> [[nodiscard]] T *
|
|
50
|
+
cast(pm_node_t *node) noexcept {
|
|
51
|
+
assert(isa<T>(node));
|
|
52
|
+
return reinterpret_cast<T *>(node);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Cast the given node, which must not be null and must be of the given struct,
|
|
57
|
+
* to that struct. The type is checked in debug builds.
|
|
58
|
+
*
|
|
59
|
+
* @tparam T The node struct type to cast to.
|
|
60
|
+
* @param node The node to cast.
|
|
61
|
+
* @return The node cast to the given struct.
|
|
62
|
+
*/
|
|
63
|
+
template <typename T> [[nodiscard]] const T *
|
|
64
|
+
cast(const pm_node_t *node) noexcept {
|
|
65
|
+
assert(isa<T>(node));
|
|
66
|
+
return reinterpret_cast<const T *>(node);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Cast the given node to the given struct if it is of that struct, and return
|
|
71
|
+
* null otherwise. The node may be null, in which case this returns null.
|
|
72
|
+
*
|
|
73
|
+
* @tparam T The node struct type to cast to.
|
|
74
|
+
* @param node The node to cast.
|
|
75
|
+
* @return The node cast to the given struct if it is of that struct, or null
|
|
76
|
+
* otherwise.
|
|
77
|
+
*/
|
|
78
|
+
template <typename T> [[nodiscard]] T *
|
|
79
|
+
dyn_cast(pm_node_t *node) noexcept {
|
|
80
|
+
return (node != nullptr && isa<T>(node)) ? reinterpret_cast<T *>(node) : nullptr;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Cast the given node to the given struct if it is of that struct, and return
|
|
85
|
+
* null otherwise. The node may be null, in which case this returns null.
|
|
86
|
+
*
|
|
87
|
+
* @tparam T The node struct type to cast to.
|
|
88
|
+
* @param node The node to cast.
|
|
89
|
+
* @return The node cast to the given struct if it is of that struct, or null
|
|
90
|
+
* otherwise.
|
|
91
|
+
*/
|
|
92
|
+
template <typename T> [[nodiscard]] const T *
|
|
93
|
+
dyn_cast(const pm_node_t *node) noexcept {
|
|
94
|
+
return (node != nullptr && isa<T>(node)) ? reinterpret_cast<const T *>(node) : nullptr;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Return the pm_node_t embedded at the start of the given node struct.
|
|
99
|
+
*
|
|
100
|
+
* @tparam T The node struct type.
|
|
101
|
+
* @param node The node struct to upcast.
|
|
102
|
+
* @return The pm_node_t embedded at the start of the node struct.
|
|
103
|
+
*/
|
|
104
|
+
template <typename T> [[nodiscard]] pm_node_t *
|
|
105
|
+
upcast(T *node) noexcept {
|
|
106
|
+
static_assert(is_node_v<T>, "upcast requires a node struct declared in ast.h");
|
|
107
|
+
return &node->base;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Return the pm_node_t embedded at the start of the given node struct.
|
|
112
|
+
*
|
|
113
|
+
* @tparam T The node struct type.
|
|
114
|
+
* @param node The node struct to upcast.
|
|
115
|
+
* @return The pm_node_t embedded at the start of the node struct.
|
|
116
|
+
*/
|
|
117
|
+
template <typename T> [[nodiscard]] const pm_node_t *
|
|
118
|
+
upcast(const T *node) noexcept {
|
|
119
|
+
static_assert(is_node_v<T>, "upcast requires a node struct declared in ast.h");
|
|
120
|
+
return &node->base;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* The nodes in a list, usable in a range-based for loop. It refers to the list
|
|
125
|
+
* rather than copying it, so the list must outlive it.
|
|
126
|
+
*/
|
|
127
|
+
class node_range {
|
|
128
|
+
public:
|
|
129
|
+
/**
|
|
130
|
+
* Create a range over the nodes in the given list.
|
|
131
|
+
*
|
|
132
|
+
* @param list The list of nodes to create a range for.
|
|
133
|
+
*/
|
|
134
|
+
explicit node_range(const pm_node_list_t &list PRISM_LIFETIMEBOUND) noexcept : list_(&list) {}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* A pointer to the first node.
|
|
138
|
+
*
|
|
139
|
+
* @return A pointer to the first node, or null if the list is empty.
|
|
140
|
+
*/
|
|
141
|
+
pm_node_t *const *begin() const noexcept { return list_->nodes; }
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* A pointer one past the last node.
|
|
145
|
+
*
|
|
146
|
+
* @return A pointer one past the last node, or null if the list is empty.
|
|
147
|
+
*/
|
|
148
|
+
pm_node_t *const *end() const noexcept { return list_->nodes + list_->size; }
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* The number of nodes.
|
|
152
|
+
*
|
|
153
|
+
* @return The number of nodes.
|
|
154
|
+
*/
|
|
155
|
+
std::size_t size() const noexcept { return list_->size; }
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Whether there are no nodes.
|
|
159
|
+
*
|
|
160
|
+
* @return True if there are no nodes, false otherwise.
|
|
161
|
+
*/
|
|
162
|
+
[[nodiscard]] bool empty() const noexcept { return list_->size == 0; }
|
|
163
|
+
|
|
164
|
+
private:
|
|
165
|
+
const pm_node_list_t *list_;
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
namespace detail {
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* The state shared between a walk and its C callback, passed through the C
|
|
172
|
+
* function's void * data parameter.
|
|
173
|
+
*/
|
|
174
|
+
template <typename F> struct visit_context {
|
|
175
|
+
/**
|
|
176
|
+
* The context for a visit, holding the visitor and any exception thrown.
|
|
177
|
+
*
|
|
178
|
+
* @param visitor The visitor callable to be used for each node.
|
|
179
|
+
*/
|
|
180
|
+
explicit visit_context(F *visitor) noexcept : callable(visitor) {}
|
|
181
|
+
|
|
182
|
+
/** The visitor that the walk calls for each node. */
|
|
183
|
+
F *callable;
|
|
184
|
+
|
|
185
|
+
#ifdef PRISM_HAS_EXCEPTIONS
|
|
186
|
+
/** The exception thrown by the visitor, if any. */
|
|
187
|
+
std::exception_ptr exception;
|
|
188
|
+
#endif
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Forwards the C visitor callback to a C++ callable. An exception cannot unwind
|
|
193
|
+
* through the C frames that call this function, so one thrown by the callable
|
|
194
|
+
* is caught here and the walk is stopped. The function that started the walk
|
|
195
|
+
* rethrows it once the C walk has returned. Without exceptions, the callable
|
|
196
|
+
* cannot throw, so it is called directly.
|
|
197
|
+
*
|
|
198
|
+
* @tparam F The type of the visitor callable.
|
|
199
|
+
* @param node The current node being visited.
|
|
200
|
+
* @param data The visit context containing the visitor and exception state.
|
|
201
|
+
* @return The result of the visit, indicating whether to descend, skip, or stop.
|
|
202
|
+
*/
|
|
203
|
+
template <typename F> pm_visit_result_t
|
|
204
|
+
visit_callback(const pm_node_t *node, void *data) noexcept {
|
|
205
|
+
visit_context<F> *context = static_cast<visit_context<F> *>(data);
|
|
206
|
+
|
|
207
|
+
#ifdef PRISM_HAS_EXCEPTIONS
|
|
208
|
+
try {
|
|
209
|
+
return std::invoke(*context->callable, node);
|
|
210
|
+
} catch (...) {
|
|
211
|
+
context->exception = std::current_exception();
|
|
212
|
+
return PM_VISIT_STOP;
|
|
213
|
+
}
|
|
214
|
+
#else
|
|
215
|
+
return std::invoke(*context->callable, node);
|
|
216
|
+
#endif
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Walk the tree rooted at the given node in pre-order, calling the visitor with
|
|
223
|
+
* each node. The visitor returns PM_VISIT_DESCEND to continue into that node's
|
|
224
|
+
* children, PM_VISIT_SKIP to continue past them, or PM_VISIT_STOP to end the
|
|
225
|
+
* walk. Returns false if the walk was stopped. If the visitor throws, the walk
|
|
226
|
+
* stops and the exception propagates from this function.
|
|
227
|
+
*
|
|
228
|
+
* @tparam F The type of the visitor callable.
|
|
229
|
+
* @param node The root node to start the walk from.
|
|
230
|
+
* @param visitor The visitor callable to invoke for each node.
|
|
231
|
+
* @return True if the walk completed, false if it was stopped.
|
|
232
|
+
*/
|
|
233
|
+
template <typename F> bool
|
|
234
|
+
visit_node(const pm_node_t *node, F &&visitor) {
|
|
235
|
+
static_assert(std::is_invocable_r_v<pm_visit_result_t, F &, const pm_node_t *>, "visit_node requires a callable taking const pm_node_t * and returning pm_visit_result_t");
|
|
236
|
+
detail::visit_context<std::remove_reference_t<F>> context(std::addressof(visitor));
|
|
237
|
+
bool completed = pm_visit_node(node, detail::visit_callback<std::remove_reference_t<F>>, &context);
|
|
238
|
+
|
|
239
|
+
#ifdef PRISM_HAS_EXCEPTIONS
|
|
240
|
+
if (context.exception) std::rethrow_exception(context.exception);
|
|
241
|
+
#endif
|
|
242
|
+
|
|
243
|
+
return completed;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Walk the children of the given node, as visit_node does for every node whose
|
|
248
|
+
* visitor returns PM_VISIT_DESCEND. Returns false if the walk was stopped. If
|
|
249
|
+
* the visitor throws, the walk stops and the exception propagates from this
|
|
250
|
+
* function.
|
|
251
|
+
*
|
|
252
|
+
* @tparam F The type of the visitor callable.
|
|
253
|
+
* @param node The node whose children to walk.
|
|
254
|
+
* @param visitor The visitor callable to invoke for each child node.
|
|
255
|
+
* @return True if the walk completed, false if it was stopped.
|
|
256
|
+
*/
|
|
257
|
+
template <typename F> bool
|
|
258
|
+
visit_child_nodes(const pm_node_t *node, F &&visitor) {
|
|
259
|
+
static_assert(std::is_invocable_r_v<pm_visit_result_t, F &, const pm_node_t *>, "visit_child_nodes requires a callable taking const pm_node_t * and returning pm_visit_result_t");
|
|
260
|
+
detail::visit_context<std::remove_reference_t<F>> context(std::addressof(visitor));
|
|
261
|
+
bool completed = pm_visit_child_nodes(node, detail::visit_callback<std::remove_reference_t<F>>, &context);
|
|
262
|
+
|
|
263
|
+
#ifdef PRISM_HAS_EXCEPTIONS
|
|
264
|
+
if (context.exception) std::rethrow_exception(context.exception);
|
|
265
|
+
#endif
|
|
266
|
+
|
|
267
|
+
return completed;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
#endif
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file node_type.hpp
|
|
3
|
+
*
|
|
4
|
+
* The traits that map node structs to node types. The specialization for each
|
|
5
|
+
* node struct is generated into ast.hpp.
|
|
6
|
+
*/
|
|
7
|
+
#ifndef PRISM_NODE_TYPE_HPP
|
|
8
|
+
#define PRISM_NODE_TYPE_HPP
|
|
9
|
+
|
|
10
|
+
#include "prism/compiler/cplusplus.hpp"
|
|
11
|
+
|
|
12
|
+
#include "prism/ast.h"
|
|
13
|
+
|
|
14
|
+
#include <type_traits>
|
|
15
|
+
|
|
16
|
+
namespace prism {
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Maps a node struct to its node type, as in node_type<pm_call_node_t>::value
|
|
20
|
+
* being PM_CALL_NODE. Only the node structs declared in ast.h have a value.
|
|
21
|
+
*/
|
|
22
|
+
template <typename T> struct node_type {};
|
|
23
|
+
|
|
24
|
+
/** The node type of the given node struct. */
|
|
25
|
+
template <typename T> inline constexpr pm_node_type_t node_type_v = node_type<T>::value;
|
|
26
|
+
|
|
27
|
+
/** Whether the given type is one of the node structs declared in ast.h. */
|
|
28
|
+
template <typename T, typename = void> struct is_node : std::false_type {};
|
|
29
|
+
|
|
30
|
+
/** Whether the given type is one of the node structs declared in ast.h. */
|
|
31
|
+
template <typename T> struct is_node<T, std::void_t<decltype(node_type<T>::value)>> : std::true_type {};
|
|
32
|
+
|
|
33
|
+
/** Whether the given type is one of the node structs declared in ast.h. */
|
|
34
|
+
template <typename T> inline constexpr bool is_node_v = is_node<T>::value;
|
|
35
|
+
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
#endif
|
data/include/prism/options.h
CHANGED
|
@@ -15,6 +15,10 @@
|
|
|
15
15
|
#include <stdbool.h>
|
|
16
16
|
#include <stddef.h>
|
|
17
17
|
|
|
18
|
+
#ifdef __cplusplus
|
|
19
|
+
extern "C" {
|
|
20
|
+
#endif
|
|
21
|
+
|
|
18
22
|
/**
|
|
19
23
|
* A scope of locals surrounding the code that is being parsed.
|
|
20
24
|
*/
|
|
@@ -335,7 +339,8 @@ PRISM_EXPORTED_FUNCTION const pm_string_t * pm_options_scope_local(const pm_opti
|
|
|
335
339
|
|
|
336
340
|
/**
|
|
337
341
|
* Return a mutable pointer to the local at the given index within the given
|
|
338
|
-
* scope.
|
|
342
|
+
* scope, for setting the local's name with pm_string_init. The parser copies
|
|
343
|
+
* the name when it is created, so its bytes must remain valid until then.
|
|
339
344
|
*
|
|
340
345
|
* @param scope The scope struct to get the local from.
|
|
341
346
|
* @param index The index of the local to get.
|
|
@@ -351,4 +356,8 @@ PRISM_EXPORTED_FUNCTION pm_string_t * pm_options_scope_local_mut(pm_options_scop
|
|
|
351
356
|
*/
|
|
352
357
|
PRISM_EXPORTED_FUNCTION void pm_options_scope_forwarding_set(pm_options_scope_t *scope, uint8_t forwarding) PRISM_NONNULL(1);
|
|
353
358
|
|
|
359
|
+
#ifdef __cplusplus
|
|
360
|
+
}
|
|
361
|
+
#endif
|
|
362
|
+
|
|
354
363
|
#endif
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file options.hpp
|
|
3
|
+
*
|
|
4
|
+
* Ownership of parse options from C++.
|
|
5
|
+
*/
|
|
6
|
+
#ifndef PRISM_OPTIONS_HPP
|
|
7
|
+
#define PRISM_OPTIONS_HPP
|
|
8
|
+
|
|
9
|
+
#include "prism/compiler/cplusplus.hpp"
|
|
10
|
+
|
|
11
|
+
#include "prism/options.h"
|
|
12
|
+
|
|
13
|
+
#include <memory>
|
|
14
|
+
|
|
15
|
+
namespace prism {
|
|
16
|
+
|
|
17
|
+
/** Frees options with pm_options_free. */
|
|
18
|
+
struct options_deleter {
|
|
19
|
+
/**
|
|
20
|
+
* Free the given options.
|
|
21
|
+
*
|
|
22
|
+
* @param options The options to free.
|
|
23
|
+
*/
|
|
24
|
+
void operator()(pm_options_t *options) const noexcept { pm_options_free(options); }
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/** An owned set of options. */
|
|
28
|
+
using unique_options = std::unique_ptr<pm_options_t, options_deleter>;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Allocate a new set of options with every option at its default. Allocation
|
|
32
|
+
* failure aborts, so this never throws.
|
|
33
|
+
*
|
|
34
|
+
* @return A unique_options owning the newly allocated options.
|
|
35
|
+
*/
|
|
36
|
+
[[nodiscard]] inline unique_options
|
|
37
|
+
make_options() noexcept {
|
|
38
|
+
return unique_options(pm_options_new());
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
#endif
|
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.
|
|
@@ -227,22 +249,19 @@ PRISM_EXPORTED_FUNCTION int pm_parser_lex_state(const pm_parser_t *parser) PRISM
|
|
|
227
249
|
PRISM_EXPORTED_FUNCTION size_t pm_parser_comments_size(const pm_parser_t *parser) PRISM_NONNULL(1);
|
|
228
250
|
|
|
229
251
|
/**
|
|
230
|
-
*
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
*
|
|
236
|
-
*
|
|
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
|
+
* ```
|
|
237
260
|
*
|
|
238
261
|
* @param parser the parser whose comments we want to iterate over
|
|
239
|
-
* @
|
|
240
|
-
* will be passed a pointer to the comment and the data parameter passed to
|
|
241
|
-
* this function.
|
|
242
|
-
* @param data the data to pass to the callback function for each comment. This
|
|
243
|
-
* 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
|
|
244
263
|
*/
|
|
245
|
-
PRISM_EXPORTED_FUNCTION
|
|
264
|
+
PRISM_EXPORTED_FUNCTION const pm_comment_t * pm_parser_comments_first(const pm_parser_t *parser) PRISM_NONNULL(1);
|
|
246
265
|
|
|
247
266
|
/**
|
|
248
267
|
* Returns the number of comments owned by the given node. This is 0 if the
|
|
@@ -309,22 +328,13 @@ PRISM_EXPORTED_FUNCTION pm_comment_range_t pm_parser_comment_range(const pm_pars
|
|
|
309
328
|
PRISM_EXPORTED_FUNCTION size_t pm_parser_magic_comments_size(const pm_parser_t *parser) PRISM_NONNULL(1);
|
|
310
329
|
|
|
311
330
|
/**
|
|
312
|
-
*
|
|
313
|
-
|
|
314
|
-
typedef void (*pm_magic_comment_callback_t)(const pm_magic_comment_t *magic_comment, void *data);
|
|
315
|
-
|
|
316
|
-
/**
|
|
317
|
-
* Iterates over the magic comments associated with the given parser and calls the
|
|
318
|
-
* 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.
|
|
319
333
|
*
|
|
320
334
|
* @param parser the parser whose magic comments we want to iterate over
|
|
321
|
-
* @
|
|
322
|
-
* function will be passed a pointer to the magic comment and the data
|
|
323
|
-
* parameter passed to this function.
|
|
324
|
-
* @param data the data to pass to the callback function for each magic comment.
|
|
325
|
-
* 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
|
|
326
336
|
*/
|
|
327
|
-
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);
|
|
328
338
|
|
|
329
339
|
/**
|
|
330
340
|
* Returns the number of errors associated with the given parser.
|
|
@@ -343,36 +353,22 @@ PRISM_EXPORTED_FUNCTION size_t pm_parser_errors_size(const pm_parser_t *parser)
|
|
|
343
353
|
PRISM_EXPORTED_FUNCTION size_t pm_parser_warnings_size(const pm_parser_t *parser) PRISM_NONNULL(1);
|
|
344
354
|
|
|
345
355
|
/**
|
|
346
|
-
*
|
|
347
|
-
*
|
|
348
|
-
*/
|
|
349
|
-
typedef void (*pm_diagnostic_callback_t)(const pm_diagnostic_t *diagnostic, void *data);
|
|
350
|
-
|
|
351
|
-
/**
|
|
352
|
-
* Iterates over the errors associated with the given parser and calls the
|
|
353
|
-
* given callback for each error.
|
|
356
|
+
* Returns the first error associated with the given parser. Iterate over the
|
|
357
|
+
* rest with pm_diagnostic_next.
|
|
354
358
|
*
|
|
355
359
|
* @param parser the parser whose errors we want to iterate over
|
|
356
|
-
* @
|
|
357
|
-
* will be passed a pointer to the error and the data parameter passed to
|
|
358
|
-
* this function.
|
|
359
|
-
* @param data the data to pass to the callback function for each error. This
|
|
360
|
-
* 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
|
|
361
361
|
*/
|
|
362
|
-
PRISM_EXPORTED_FUNCTION
|
|
362
|
+
PRISM_EXPORTED_FUNCTION const pm_diagnostic_t * pm_parser_errors_first(const pm_parser_t *parser) PRISM_NONNULL(1);
|
|
363
363
|
|
|
364
364
|
/**
|
|
365
|
-
*
|
|
366
|
-
*
|
|
365
|
+
* Returns the first warning associated with the given parser. Iterate over the
|
|
366
|
+
* rest with pm_diagnostic_next.
|
|
367
367
|
*
|
|
368
368
|
* @param parser the parser whose warnings we want to iterate over
|
|
369
|
-
* @
|
|
370
|
-
* will be passed a pointer to the warning and the data parameter passed to
|
|
371
|
-
* this function.
|
|
372
|
-
* @param data the data to pass to the callback function for each warning. This
|
|
373
|
-
* 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
|
|
374
370
|
*/
|
|
375
|
-
PRISM_EXPORTED_FUNCTION
|
|
371
|
+
PRISM_EXPORTED_FUNCTION const pm_diagnostic_t * pm_parser_warnings_first(const pm_parser_t *parser) PRISM_NONNULL(1);
|
|
376
372
|
|
|
377
373
|
/**
|
|
378
374
|
* Returns the number of constants in the constant pool associated with the
|
|
@@ -386,30 +382,38 @@ PRISM_EXPORTED_FUNCTION void pm_parser_warnings_each(const pm_parser_t *parser,
|
|
|
386
382
|
PRISM_EXPORTED_FUNCTION size_t pm_parser_constants_size(const pm_parser_t *parser) PRISM_NONNULL(1);
|
|
387
383
|
|
|
388
384
|
/**
|
|
389
|
-
*
|
|
390
|
-
*
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
/**
|
|
395
|
-
* Iterates over the constants in the constant pool associated with the given
|
|
396
|
-
* parser and calls the given callback for each constant.
|
|
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:
|
|
397
389
|
*
|
|
398
|
-
*
|
|
399
|
-
*
|
|
400
|
-
*
|
|
401
|
-
*
|
|
402
|
-
*
|
|
403
|
-
*
|
|
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
|
+
* ```
|
|
398
|
+
*
|
|
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
|
|
404
407
|
*/
|
|
405
|
-
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);
|
|
406
409
|
|
|
407
410
|
/**
|
|
408
411
|
* Returns a pointer to the constant at the given id in the constant pool
|
|
409
412
|
* associated with the given parser.
|
|
410
413
|
*
|
|
411
414
|
* @param parser the parser whose constant pool we want to look up from
|
|
412
|
-
* @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.
|
|
413
417
|
* @returns a pointer to the constant at the given id
|
|
414
418
|
*/
|
|
415
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);
|
|
@@ -422,4 +426,8 @@ PRISM_EXPORTED_FUNCTION const pm_constant_t * pm_parser_constant(const pm_parser
|
|
|
422
426
|
*/
|
|
423
427
|
PRISM_EXPORTED_FUNCTION pm_node_t * pm_parse(pm_parser_t *parser) PRISM_NONNULL(1);
|
|
424
428
|
|
|
429
|
+
#ifdef __cplusplus
|
|
430
|
+
}
|
|
431
|
+
#endif
|
|
432
|
+
|
|
425
433
|
#endif
|