Ruby 4.1.0dev (2026-10-26 revision 6b15825df0fce73e868b99f98c689755e46cfc8c)
parser.c
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#include "prism/internal/xxh3.h"
9
10#include <assert.h>
11#include <stdlib.h>
12#include <string.h>
13
18void
19pm_parser_encoding_changed_callback_set(pm_parser_t *parser, pm_encoding_changed_callback_t callback) {
20 parser->encoding_changed_callback = callback;
21}
22
26void
27pm_parser_lex_callback_set(pm_parser_t *parser, pm_lex_callback_t callback, void *data) {
28 parser->lex_callback.callback = callback;
29 parser->lex_callback.data = data;
30}
31
35void *
36pm_parser_lex_callback_data(const pm_parser_t *parser) {
37 return parser->lex_callback.data;
38}
39
43const uint8_t *
44pm_parser_start(const pm_parser_t *parser) {
45 return parser->start;
46}
47
51const uint8_t *
52pm_parser_end(const pm_parser_t *parser) {
53 return parser->end;
54}
55
62int32_t
63pm_parser_start_line(const pm_parser_t *parser) {
64 return parser->start_line;
65}
66
70const char *
71pm_parser_encoding_name(const pm_parser_t *parser) {
72 return parser->encoding->name;
73}
74
79size_t
80pm_parser_encoding_char_width(const pm_parser_t *parser, const uint8_t *start, ptrdiff_t remaining) {
81 return parser->encoding->char_width(start, remaining);
82}
83
87bool
88pm_parser_encoding_us_ascii(const pm_parser_t *parser) {
89 return parser->encoding == PM_ENCODING_US_ASCII_ENTRY;
90}
91
95const pm_string_t *
96pm_parser_filepath(const pm_parser_t *parser) {
97 return &parser->filepath;
98}
99
105pm_parser_constant_find(const pm_parser_t *parser, const uint8_t *start, size_t length) {
106 return pm_constant_pool_find(&parser->constant_pool, start, length);
107}
108
114pm_parser_constant_insert(pm_parser_t *parser, const uint8_t *start, size_t length) {
115 pm_constant_id_t id = pm_constant_pool_find(&parser->constant_pool, start, length);
116 if (id != PM_CONSTANT_ID_UNSET) return id;
117
118 const uint8_t *copy = (const uint8_t *) pm_arena_memdup(&parser->metadata_arena, start, length, PRISM_ALIGNOF(uint8_t));
119 return pm_constant_pool_insert_constant(&parser->metadata_arena, &parser->constant_pool, copy, length);
120}
121
125int8_t
126pm_parser_frozen_string_literal(const pm_parser_t *parser) {
127 return parser->frozen_string_literal;
128}
129
137pm_parser_line_offsets(const pm_parser_t *parser) {
138 return &parser->line_offsets;
139}
140
145const pm_location_t *
146pm_parser_data_loc(const pm_parser_t *parser) {
147 return &parser->data_loc;
148}
149
153uint64_t
154pm_parser_checksum(const pm_parser_t *parser) {
155 const uint8_t *end = parser->end;
156
157 if (parser->data_loc.length != 0) {
158 const uint8_t *cursor = parser->start + parser->data_loc.start;
159 const uint8_t *newline = memchr(cursor, '\n', (size_t) (end - cursor));
160 if (newline != NULL) end = newline + 1;
161 }
162
163 return pm_xxh3(parser->start, (size_t) (end - parser->start));
164}
165
170bool
171pm_parser_continuable(const pm_parser_t *parser) {
172 return parser->continuable;
173}
174
181int
182pm_parser_lex_state(const pm_parser_t *parser) {
183 return (int) parser->lex_state;
184}
185
191 return comment->location;
192}
193
199 return comment->type;
200}
201
205const pm_comment_t *
207 return (const pm_comment_t *) comment->node.next;
208}
209
213size_t
214pm_parser_comments_size(const pm_parser_t *parser) {
215 return parser->comment_list.size;
216}
217
221const pm_comment_t *
222pm_parser_comments_first(const pm_parser_t *parser) {
223 return (const pm_comment_t *) parser->comment_list.head;
224}
225
229uint32_t
230pm_node_comments_size(const pm_parser_t *parser, const pm_node_t *node) {
231 return pm_parser_comment_range(parser, node->node_id).length;
232}
233
238const pm_comment_t *
239pm_node_comment(const pm_parser_t *parser, const pm_node_t *node, uint32_t index) {
240 pm_comment_range_t range = pm_parser_comment_range(parser, node->node_id);
241 if (index >= range.length) return NULL;
242
243 return parser->comment_attachments.comments[parser->comment_attachments.attachments[range.index + index]];
244}
245
250uint32_t
251pm_parser_comment_attachment(const pm_parser_t *parser, uint32_t index) {
252 if (parser->comment_attachments.attachments == NULL || index >= parser->comment_list.size) return UINT32_MAX;
253 return parser->comment_attachments.attachments[index];
254}
255
259uint32_t
260pm_parser_comment_ranges_size(const pm_parser_t *parser) {
261 return parser->comment_attachments.ranges_size;
262}
263
268pm_parser_comment_range(const pm_parser_t *parser, uint32_t node_id) {
269 if (node_id >= parser->comment_attachments.ranges_size) return (pm_comment_range_t) { .index = 0, .length = 0 };
270 return parser->comment_attachments.ranges[node_id];
271}
272
280
288
292const pm_magic_comment_t *
296
300size_t
301pm_parser_magic_comments_size(const pm_parser_t *parser) {
302 return parser->magic_comment_list.size;
303}
304
308const pm_magic_comment_t *
309pm_parser_magic_comments_first(const pm_parser_t *parser) {
310 return (const pm_magic_comment_t *) parser->magic_comment_list.head;
311}
312
316size_t
317pm_parser_errors_size(const pm_parser_t *parser) {
318 return parser->error_list.size;
319}
320
324size_t
325pm_parser_warnings_size(const pm_parser_t *parser) {
326 return parser->warning_list.size;
327}
328
332const pm_diagnostic_t *
333pm_parser_errors_first(const pm_parser_t *parser) {
334 return (const pm_diagnostic_t *) parser->error_list.head;
335}
336
340const pm_diagnostic_t *
341pm_parser_warnings_first(const pm_parser_t *parser) {
342 return (const pm_diagnostic_t *) parser->warning_list.head;
343}
344
349size_t
350pm_parser_constants_size(const pm_parser_t *parser) {
351 return parser->constant_pool.size;
352}
353
358const pm_constant_t *
359pm_parser_constant_at(const pm_parser_t *parser, size_t index) {
360 assert(index < parser->constant_pool.size);
361 return &parser->constant_pool.constants[index];
362}
363
368const pm_constant_t *
369pm_parser_constant(const pm_parser_t *parser, pm_constant_id_t constant_id) {
370 return pm_constant_pool_id_to_constant(&parser->constant_pool, constant_id);
371}
#define PRISM_ALIGNOF
Get the alignment requirement of a type.
Definition align.h:15
PRISM_EXPORTED_FUNCTION pm_location_t pm_comment_location(const pm_comment_t *comment) PRISM_NONNULL(1)
Returns the location associated with the given comment.
Definition parser.c:190
PRISM_EXPORTED_FUNCTION pm_comment_type_t pm_comment_type(const pm_comment_t *comment) PRISM_NONNULL(1)
Returns the type associated with the given comment.
Definition parser.c:198
PRISM_EXPORTED_FUNCTION const pm_comment_t * pm_comment_next(const pm_comment_t *comment) PRISM_NONNULL(1)
Returns the comment that follows the given comment among the comments associated with the parser that...
Definition parser.c:206
pm_comment_type_t
This is the type of a comment that we've found while parsing.
Definition comments.h:22
uint32_t pm_constant_id_t
A constant id is a unique identifier for a constant in the constant pool.
PRISM_EXPORTED_FUNCTION pm_location_t pm_magic_comment_value(const pm_magic_comment_t *magic_comment) PRISM_NONNULL(1)
Returns the location of the value associated with the given magic comment.
Definition parser.c:285
PRISM_EXPORTED_FUNCTION pm_location_t pm_magic_comment_key(const pm_magic_comment_t *magic_comment) PRISM_NONNULL(1)
Returns the location of the key associated with the given magic comment.
Definition parser.c:277
PRISM_EXPORTED_FUNCTION const pm_magic_comment_t * pm_magic_comment_next(const pm_magic_comment_t *magic_comment) PRISM_NONNULL(1)
Returns the magic comment that follows the given magic comment among the magic comments associated wi...
Definition parser.c:293
void(* pm_lex_callback_t)(pm_parser_t *parser, pm_token_t *token, void *data)
This is the callback that is called when a token is lexed.
Definition parser.h:59
void(* pm_encoding_changed_callback_t)(pm_parser_t *parser)
When the encoding that is being used to parse the source is changed by prism, we provide the ability ...
Definition parser.h:53
The comments owned by a node, as a slice of the comment attachments of the parser that produced it.
Definition comments.h:34
uint32_t index
The index of the first attachment owned by the node.
Definition comments.h:36
uint32_t length
The number of attachments owned by the node.
Definition comments.h:39
A list of offsets of the start of lines in a string.
This struct represents a slice in the source code, defined by an offset and a length.
Definition ast.h:579
uint32_t start
The offset of the location from the start of the source.
Definition ast.h:581
uint32_t length
The length of the location.
Definition ast.h:584
This is the base structure that represents a node in the syntax tree.
Definition ast.h:1090
uint32_t node_id
The unique identifier for this node, which is deterministic based on the source.
Definition ast.h:1109
A view of a sequence of bytes.
Definition stringy.h:23