1#include "prism/extension.h"
16VALUE rb_cPrismLocation;
18VALUE rb_cPrismComment;
19VALUE rb_cPrismInlineComment;
20VALUE rb_cPrismEmbDocComment;
21VALUE rb_cPrismMagicComment;
22VALUE rb_cPrismParseError;
23VALUE rb_cPrismParseWarning;
25VALUE rb_cPrismParseResult;
26VALUE rb_cPrismLexResult;
27VALUE rb_cPrismParseLexResult;
28VALUE rb_cPrismStringQuery;
30VALUE rb_cPrismCurrentVersionError;
32VALUE rb_cPrismDebugEncoding;
34ID rb_id_option_command_line;
35ID rb_id_option_encoding;
36ID rb_id_option_filepath;
37ID rb_id_option_freeze;
38ID rb_id_option_frozen_string_literal;
40ID rb_id_option_main_script;
41ID rb_id_option_partial_script;
42ID rb_id_option_raise_error;
43ID rb_id_option_scopes;
44ID rb_id_option_version;
48ID rb_id_forwarding_positionals;
49ID rb_id_forwarding_keywords;
50ID rb_id_forwarding_block;
51ID rb_id_forwarding_all;
53ID rb_id_raise_error_plain;
54ID rb_id_raise_error_style;
55ID rb_id_raise_error_color;
70result_ok(
VALUE value) {
71 return (
result_t) { .type = RESULT_OK, .value = value };
75result_err(
VALUE value) {
76 return (
result_t) { .type = RESULT_ERR, .value = value };
81 if (result.type == RESULT_OK) {
97check_string(
VALUE value) {
104 return RSTRING_PTR(value);
123 if (!pm_options_scopes_init(options, scopes_count)) {
128 for (
size_t scope_index = 0; scope_index < scopes_count; scope_index++) {
150 for (
size_t name_index = 0; name_index < names_count; name_index++) {
160 if (
id == rb_id_forwarding_positionals) {
162 }
else if (
id == rb_id_forwarding_keywords) {
164 }
else if (
id == rb_id_forwarding_block) {
166 }
else if (
id == rb_id_forwarding_all) {
169 rb_raise(rb_eArgError,
"invalid forwarding value: %" PRIsVALUE, name);
179 pm_options_scope_init(options_scope, locals_count);
182 for (
size_t local_index = 0; local_index < locals_count; local_index++) {
192 pm_string_t *scope_local = pm_options_scope_local_mut(options_scope, local_index);
193 const char *name = rb_id2name(
SYM2ID(local));
194 pm_string_constant_init(scope_local, name, strlen(name));
198 pm_options_scope_forwarding_set(options_scope, forwarding);
210 if (key_id == rb_id_option_filepath) {
211 if (!
NIL_P(value)) pm_options_filepath_set(options, check_string(value));
212 }
else if (key_id == rb_id_option_encoding) {
215 pm_options_encoding_locked_set(options,
true);
217 pm_options_encoding_set(options, rb_enc_name(rb_to_encoding(value)));
220 }
else if (key_id == rb_id_option_line) {
221 if (!
NIL_P(value)) pm_options_line_set(options,
NUM2INT(value));
222 }
else if (key_id == rb_id_option_frozen_string_literal) {
223 if (!
NIL_P(value)) pm_options_frozen_string_literal_set(options,
RTEST(value));
224 }
else if (key_id == rb_id_option_version) {
226 const char *version = check_string(value);
228 if (RSTRING_LEN(value) == 7 && strncmp(version,
"current", 7) == 0) {
229 if (!pm_options_version_set(options,
ruby_version, 3)) {
232 }
else if (RSTRING_LEN(value) == 7 && strncmp(version,
"nearest", 7) == 0) {
233 if (!pm_options_version_set(options,
ruby_version, 3)) {
236 pm_options_version_set_lowest(options);
239 pm_options_version_set_highest(options);
242 }
else if (!pm_options_version_set(options, version, RSTRING_LEN(value))) {
243 rb_raise(rb_eArgError,
"invalid version: %" PRIsVALUE, value);
246 }
else if (key_id == rb_id_option_scopes) {
247 if (!
NIL_P(value)) build_options_scopes(options, value);
248 }
else if (key_id == rb_id_option_command_line) {
250 const char *
string = check_string(value);
251 uint8_t command_line = 0;
253 for (
size_t index = 0; index < strlen(
string); index++) {
254 switch (
string[index]) {
261 default: rb_raise(rb_eArgError,
"invalid command line flag: '%c'",
string[index]);
break;
265 pm_options_command_line_set(options, command_line);
267 }
else if (key_id == rb_id_option_main_script) {
268 if (!
NIL_P(value)) pm_options_main_script_set(options,
RTEST(value));
269 }
else if (key_id == rb_id_option_partial_script) {
270 if (!
NIL_P(value)) pm_options_partial_script_set(options,
RTEST(value));
271 }
else if (key_id == rb_id_option_freeze) {
272 if (!
NIL_P(value)) pm_options_freeze_set(options,
RTEST(value));
273 }
else if (key_id == rb_id_option_raise_error) {
275 if (value ==
Qtrue) {
285 const char *no_color = getenv(
"NO_COLOR");
286 if (no_color == NULL || no_color[0] ==
'\0') {
300 if (value_id == rb_id_raise_error_plain) {
302 }
else if (value_id == rb_id_raise_error_style) {
304 }
else if (value_id == rb_id_raise_error_color) {
307 rb_raise(rb_eArgError,
"invalid raise_error value: %" PRIsVALUE, value);
312 rb_raise(rb_eArgError,
"unknown keyword: %" PRIsVALUE, key);
333build_options(
VALUE argument) {
344 pm_options_line_set(options, 1);
346 if (!
NIL_P(keywords)) {
351 rb_protect(build_options, (
VALUE) argument, &state);
354 pm_options_free(options);
359 if (!
NIL_P(filepath)) {
361 pm_options_free(options);
365 pm_options_filepath_set(options, RSTRING_PTR(filepath));
379 pm_options_free(options);
383 extract_options(options,
Qnil, keywords);
397 filepath = rb_protect(rb_get_path, filepath, &state);
399 pm_options_free(options);
403 *encoded_filepath = rb_str_encode_ospath(filepath);
404 extract_options(options, *encoded_filepath, keywords);
406 const char *source = (
const char *) pm_string_source(pm_options_filepath(options));
408 pm_source_t *pm_src = pm_source_file_new(source, &result);
414 pm_options_free(options);
417 int e = rb_w32_map_errno(GetLastError());
426 pm_options_free(options);
430 pm_options_free(options);
431 rb_raise(
rb_eRuntimeError,
"Unknown error (%d) initializing file: %s", result, source);
445 if (pm_parser_errors_size(parser) == 0)
return result_ok(
Qnil);
447 uint8_t raise_error = pm_options_raise_error(options);
448 if (raise_error == 0)
return result_ok(
Qnil);
451 if (buffer == NULL) {
461 VALUE message = rb_enc_str_new(pm_buffer_value(buffer), (
long) pm_buffer_length(buffer), message_encoding);
462 pm_buffer_free(buffer);
465 switch (error_level) {
469 rb_encoding *path_encoding_normal = path_encoding == NULL ? rb_utf8_encoding() : path_encoding;
470 VALUE path = rb_enc_str_new((
const char *) pm_string_source(pm_options_filepath(options)), pm_string_length(pm_options_filepath(options)), path_encoding_normal);
485 return result_err(error);
488#ifndef PRISM_EXCLUDE_SERIALIZATION
498dump_input(
const uint8_t *input,
size_t input_length,
const pm_options_t *options,
rb_encoding *path_encoding) {
503 result_t result = check_raise_error_option(parser, options, path_encoding);
504 if (result.type == RESULT_OK) {
507 pm_serialize(parser, node, buffer);
508 result = result_ok(
rb_str_new(pm_buffer_value(buffer), pm_buffer_length(buffer)));
509 pm_buffer_free(buffer);
518 pm_arena_free(arena);
534 VALUE string = string_options(argc, argv, options);
536 const uint8_t *source = (
const uint8_t *) RSTRING_PTR(
string);
537 size_t length = RSTRING_LEN(
string);
539#ifdef PRISM_BUILD_DEBUG
541 memcpy(dup, source, length);
542 source = (
const uint8_t *) dup;
545 result_t result = dump_input(source, length, options, NULL);
547#ifdef PRISM_BUILD_DEBUG
549 xfree_sized(dup, length);
555 pm_options_free(options);
556 return result_get(result);
571 VALUE encoded_filepath;
572 pm_source_t *src = file_options(argc, argv, options, &encoded_filepath);
574 result_t result = dump_input(pm_source_source(src), pm_source_length(src), options, rb_enc_get(encoded_filepath));
576 pm_options_free(options);
578 return result_get(result);
592rb_class_new_instance_freeze(
int argc,
const VALUE *argv,
VALUE klass,
bool freeze) {
602parser_location(
VALUE source,
bool freeze, uint32_t start, uint32_t length) {
604 return rb_class_new_instance_freeze(3, argv, rb_cPrismLocation, freeze);
610#define PARSER_LOCATION(source, freeze, location) \
611 parser_location(source, freeze, location.start, location.length)
620 return rb_class_new_instance_freeze(1, argv,
type, freeze);
630parser_comments_each(
const pm_comment_t *comment,
void *data) {
632 VALUE value = parser_comment(each_data->source, each_data->freeze, comment);
644 pm_parser_comments_each(parser, parser_comments_each, &each_data);
658 VALUE key_loc = parser_location(source, freeze, key.start, key.length);
659 VALUE value_loc = parser_location(source, freeze, value.
start, value.
length);
661 VALUE argv[] = { key_loc, value_loc };
662 return rb_class_new_instance_freeze(2, argv, rb_cPrismMagicComment, freeze);
666 VALUE magic_comments;
674 VALUE value = parser_magic_comment(each_data->source, each_data->freeze,
magic_comment);
682parser_magic_comments(
const pm_parser_t *parser,
VALUE source,
bool freeze) {
686 pm_parser_magic_comments_each(parser, parser_magic_comments_each, &each_data);
689 return magic_comments;
700 if (data_loc->
length == 0) {
703 return parser_location(source, freeze, data_loc->
start, data_loc->
length);
720 VALUE location = PARSER_LOCATION(each_data->source, each_data->freeze, pm_diagnostic_location(diagnostic));
725 switch (error_level) {
727 level =
ID2SYM(rb_intern(
"syntax"));
730 level =
ID2SYM(rb_intern(
"argument"));
733 level =
ID2SYM(rb_intern(
"load"));
739 VALUE argv[] = {
type, message, location, level };
740 VALUE value = rb_class_new_instance_freeze(4, argv, rb_cPrismParseError, each_data->freeze);
752 pm_parser_errors_each(parser, parser_errors_each, &each_data);
771 VALUE location = PARSER_LOCATION(each_data->source, each_data->freeze, pm_diagnostic_location(diagnostic));
776 switch (warning_level) {
778 level =
ID2SYM(rb_intern(
"default"));
781 level =
ID2SYM(rb_intern(
"verbose"));
787 VALUE argv[] = {
type, message, location, level };
788 VALUE value = rb_class_new_instance_freeze(4, argv, rb_cPrismParseWarning, each_data->freeze);
800 pm_parser_warnings_each(parser, parser_warnings_each, &each_data);
811 VALUE result_argv[] = {
813 parser_comments(parser, source, freeze),
814 parser_magic_comments(parser, source, freeze),
815 parser_data_loc(parser, source, freeze),
816 parser_errors(parser, encoding, source, freeze),
817 parser_warnings(parser, encoding, source, freeze),
822 return rb_class_new_instance_freeze(8, result_argv,
class, freeze);
850 VALUE value = pm_token_new(parser, token, parse_lex_data->encoding, parse_lex_data->source, parse_lex_data->freeze);
860parse_lex_encoding_changed_callback(
pm_parser_t *parser) {
862 parse_lex_data->encoding = rb_enc_find(pm_parser_encoding_name(parser));
868 VALUE tokens = parse_lex_data->tokens;
871 for (
long index = 0; index <
RARRAY_LEN(tokens); index++) {
876 rb_enc_associate(next_value, parse_lex_data->encoding);
879 VALUE next_token_argv[] = {
880 parse_lex_data->source,
889 if (parse_lex_data->freeze) {
904parse_lex_input(
const uint8_t *input,
size_t input_length,
const pm_options_t *options,
rb_encoding *path_encoding,
bool return_nodes) {
907 pm_parser_encoding_changed_callback_set(parser, parse_lex_encoding_changed_callback);
911 VALUE source =
rb_funcall(rb_cPrismSource, rb_id_source_for, 3, source_string,
LONG2NUM(pm_parser_start_line(parser)), offsets);
916 .encoding = rb_enc_find(pm_parser_encoding_name(parser)),
917 .freeze = pm_options_freeze(options),
921 pm_parser_lex_callback_set(parser, parse_lex_token, data);
925 result_t result = check_raise_error_option(parser, options, path_encoding);
926 if (result.type == RESULT_OK) {
929 rb_encoding *encoding = rb_enc_find(pm_parser_encoding_name(parser));
930 rb_enc_associate(source_string, encoding);
933 for (
size_t index = 0; index < line_offsets->
size; index++) {
937 if (pm_options_freeze(options)) {
946 rb_ary_push(value, pm_ast_new(parser, node, parse_lex_data.encoding, source, pm_options_freeze(options)));
949 result = result_ok(parse_result_create(rb_cPrismParseLexResult, parser, value, parse_lex_data.encoding, source, pm_options_freeze(options)));
951 result = result_ok(parse_result_create(rb_cPrismLexResult, parser, parse_lex_data.tokens, parse_lex_data.encoding, source, pm_options_freeze(options)));
956 pm_arena_free(arena);
972 VALUE string = string_options(argc, argv, options);
974 result_t result = parse_lex_input((
const uint8_t *) RSTRING_PTR(
string), RSTRING_LEN(
string), options, NULL,
false);
975 pm_options_free(options);
977 return result_get(result);
992 VALUE encoded_filepath;
993 pm_source_t *src = file_options(argc, argv, options, &encoded_filepath);
995 result_t result = parse_lex_input(pm_source_source(src), pm_source_length(src), options, rb_enc_get(encoded_filepath),
false);
997 pm_options_free(options);
999 return result_get(result);
1010parse_input(
const uint8_t *input,
size_t input_length,
const pm_options_t *options,
rb_encoding *path_encoding) {
1016 result_t result = check_raise_error_option(parser, options, path_encoding);
1017 if (result.type == RESULT_OK) {
1018 rb_encoding *encoding = rb_enc_find(pm_parser_encoding_name(parser));
1020 bool freeze = pm_options_freeze(options);
1021 VALUE source = pm_source_new(parser, encoding, freeze);
1022 VALUE value = pm_ast_new(parser, node, encoding, source, freeze);
1023 result = result_ok(parse_result_create(rb_cPrismParseResult, parser, value, encoding, source, freeze));
1031 pm_arena_free(arena);
1098 VALUE string = string_options(argc, argv, options);
1100 const uint8_t *source = (
const uint8_t *) RSTRING_PTR(
string);
1101 size_t length = RSTRING_LEN(
string);
1103#ifdef PRISM_BUILD_DEBUG
1105 memcpy(dup, source, length);
1106 source = (
const uint8_t *) dup;
1109 result_t result = parse_input(source, length, options, NULL);
1111#ifdef PRISM_BUILD_DEBUG
1113 xfree_sized(dup, length);
1119 pm_options_free(options);
1120 return result_get(result);
1132parse_file(
int argc,
VALUE *argv,
VALUE self) {
1135 VALUE encoded_filepath;
1136 pm_source_t *src = file_options(argc, argv, options, &encoded_filepath);
1138 result_t result = parse_input(pm_source_source(src), pm_source_length(src), options, rb_enc_get(encoded_filepath));
1139 pm_source_free(src);
1140 pm_options_free(options);
1142 return result_get(result);
1149profile_input(
const uint8_t *input,
size_t input_length,
const pm_options_t *options,
rb_encoding *path_encoding) {
1155 result_t result = check_raise_error_option(parser, options, path_encoding);
1157 pm_arena_free(arena);
1174 VALUE string = string_options(argc, argv, options);
1176 result_t result = profile_input((
const uint8_t *) RSTRING_PTR(
string), RSTRING_LEN(
string), options, NULL);
1177 pm_options_free(options);
1193profile_file(
int argc,
VALUE *argv,
VALUE self) {
1196 VALUE encoded_filepath;
1197 pm_source_t *src = file_options(argc, argv, options, &encoded_filepath);
1199 result_t result = profile_input(pm_source_source(src), pm_source_length(src), options, rb_enc_get(encoded_filepath));
1200 pm_source_free(src);
1201 pm_options_free(options);
1208parse_stream_eof(
void *stream) {
1227#define MAX_ENC_LEN 6
1235parse_stream_fgets(
char *
string,
int size,
void *stream) {
1254 const char *cstr = RSTRING_PTR(line);
1255 long length = RSTRING_LEN(line);
1262 if (length > (
long) (size - 1)) {
1263 length = (long) (size - 1);
1266 memcpy(
string, cstr, (
size_t) length);
1267 string[length] =
'\0';
1283parse_stream(
int argc,
VALUE *argv,
VALUE self) {
1289 extract_options(options,
Qnil, keywords);
1291 pm_source_t *src = pm_source_stream_new((
void *) stream, parse_stream_fgets, parse_stream_eof);
1295 pm_node_t *node = pm_parse_stream(&parser, arena, src, options);
1297 result_t result = check_raise_error_option(parser, options, NULL);
1298 if (result.type == RESULT_OK) {
1299 rb_encoding *encoding = rb_enc_find(pm_parser_encoding_name(parser));
1301 VALUE source = pm_source_new(parser, encoding, pm_options_freeze(options));
1302 VALUE value = pm_ast_new(parser, node, encoding, source, pm_options_freeze(options));
1303 result = result_ok(parse_result_create(rb_cPrismParseResult, parser, value, encoding, source, pm_options_freeze(options)));
1306 pm_source_free(src);
1308 pm_arena_free(arena);
1309 pm_options_free(options);
1311 return result_get(result);
1318parse_input_comments(
const uint8_t *input,
size_t input_length,
const pm_options_t *options,
rb_encoding *path_encoding) {
1324 result_t result = check_raise_error_option(parser, options, path_encoding);
1325 if (result.type == RESULT_OK) {
1326 rb_encoding *encoding = rb_enc_find(pm_parser_encoding_name(parser));
1328 VALUE source = pm_source_new(parser, encoding, pm_options_freeze(options));
1329 result = result_ok(parser_comments(parser, source, pm_options_freeze(options)));
1333 pm_arena_free(arena);
1347parse_comments(
int argc,
VALUE *argv,
VALUE self) {
1349 VALUE string = string_options(argc, argv, options);
1351 result_t result = parse_input_comments((
const uint8_t *) RSTRING_PTR(
string), RSTRING_LEN(
string), options, NULL);
1352 pm_options_free(options);
1354 return result_get(result);
1366parse_file_comments(
int argc,
VALUE *argv,
VALUE self) {
1369 VALUE encoded_filepath;
1370 pm_source_t *src = file_options(argc, argv, options, &encoded_filepath);
1372 result_t result = parse_input_comments(pm_source_source(src), pm_source_length(src), options, rb_enc_get(encoded_filepath));
1373 pm_source_free(src);
1374 pm_options_free(options);
1376 return result_get(result);
1395parse_lex(
int argc,
VALUE *argv,
VALUE self) {
1397 VALUE string = string_options(argc, argv, options);
1399 result_t result = parse_lex_input((
const uint8_t *) RSTRING_PTR(
string), RSTRING_LEN(
string), options, NULL,
true);
1400 pm_options_free(options);
1402 return result_get(result);
1421parse_lex_file(
int argc,
VALUE *argv,
VALUE self) {
1424 VALUE encoded_filepath;
1425 pm_source_t *src = file_options(argc, argv, options, &encoded_filepath);
1427 result_t result = parse_lex_input(pm_source_source(src), pm_source_length(src), options, rb_enc_get(encoded_filepath),
true);
1428 pm_source_free(src);
1429 pm_options_free(options);
1431 return result_get(result);
1438parse_input_success_p(
const uint8_t *input,
size_t input_length,
const pm_options_t *options,
rb_encoding *path_encoding) {
1443 result_t result = check_raise_error_option(parser, options, path_encoding);
1444 if (result.type == RESULT_OK) {
1445 result = result_ok(pm_parser_errors_size(parser) == 0 ?
Qtrue :
Qfalse);
1449 pm_arena_free(arena);
1463parse_success_p(
int argc,
VALUE *argv,
VALUE self) {
1465 VALUE string = string_options(argc, argv, options);
1467 result_t result = parse_input_success_p((
const uint8_t *) RSTRING_PTR(
string), RSTRING_LEN(
string), options, NULL);
1468 pm_options_free(options);
1470 return result_get(result);
1482parse_failure_p(
int argc,
VALUE *argv,
VALUE self) {
1495parse_file_success_p(
int argc,
VALUE *argv,
VALUE self) {
1498 VALUE encoded_filepath;
1499 pm_source_t *src = file_options(argc, argv, options, &encoded_filepath);
1501 result_t result = parse_input_success_p(pm_source_source(src), pm_source_length(src), options, rb_enc_get(encoded_filepath));
1502 pm_source_free(src);
1503 pm_options_free(options);
1505 return result_get(result);
1517parse_file_failure_p(
int argc,
VALUE *argv,
VALUE self) {
1533 rb_raise(rb_eArgError,
"Invalid or non ascii-compatible encoding");
1553string_query_local_p(
VALUE self,
VALUE string) {
1554 const uint8_t *source = (
const uint8_t *) check_string(
string);
1555 return string_query(pm_string_query_local(source, RSTRING_LEN(
string), rb_enc_get(
string)->name));
1568string_query_constant_p(
VALUE self,
VALUE string) {
1569 const uint8_t *source = (
const uint8_t *) check_string(
string);
1570 return string_query(pm_string_query_constant(source, RSTRING_LEN(
string), rb_enc_get(
string)->name));
1581string_query_method_name_p(
VALUE self,
VALUE string) {
1582 const uint8_t *source = (
const uint8_t *) check_string(
string);
1583 return string_query(pm_string_query_method_name(source, RSTRING_LEN(
string), rb_enc_get(
string)->name));
1593RUBY_FUNC_EXPORTED
void
1597 if (strcmp(pm_version(), EXPECTED_PRISM_VERSION) != 0) {
1600 "The prism library version (%s) does not match the expected version (%s)",
1602 EXPECTED_PRISM_VERSION
1606#ifdef HAVE_RB_EXT_RACTOR_SAFE
1611 rb_cPrism = rb_define_module(
"Prism");
1612 rb_cPrismNode = rb_define_class_under(rb_cPrism,
"Node",
rb_cObject);
1613 rb_cPrismSource = rb_define_class_under(rb_cPrism,
"Source",
rb_cObject);
1614 rb_cPrismToken = rb_define_class_under(rb_cPrism,
"Token",
rb_cObject);
1615 rb_cPrismLocation = rb_define_class_under(rb_cPrism,
"Location",
rb_cObject);
1616 rb_cPrismComment = rb_define_class_under(rb_cPrism,
"Comment",
rb_cObject);
1617 rb_cPrismInlineComment = rb_define_class_under(rb_cPrism,
"InlineComment", rb_cPrismComment);
1618 rb_cPrismEmbDocComment = rb_define_class_under(rb_cPrism,
"EmbDocComment", rb_cPrismComment);
1619 rb_cPrismMagicComment = rb_define_class_under(rb_cPrism,
"MagicComment",
rb_cObject);
1620 rb_cPrismParseError = rb_define_class_under(rb_cPrism,
"ParseError",
rb_cObject);
1621 rb_cPrismParseWarning = rb_define_class_under(rb_cPrism,
"ParseWarning",
rb_cObject);
1622 rb_cPrismResult = rb_define_class_under(rb_cPrism,
"Result",
rb_cObject);
1623 rb_cPrismParseResult = rb_define_class_under(rb_cPrism,
"ParseResult", rb_cPrismResult);
1624 rb_cPrismLexResult = rb_define_class_under(rb_cPrism,
"LexResult", rb_cPrismResult);
1625 rb_cPrismParseLexResult = rb_define_class_under(rb_cPrism,
"ParseLexResult", rb_cPrismResult);
1626 rb_cPrismStringQuery = rb_define_class_under(rb_cPrism,
"StringQuery",
rb_cObject);
1627 rb_cPrismScope = rb_define_class_under(rb_cPrism,
"Scope",
rb_cObject);
1629 rb_cPrismCurrentVersionError =
rb_const_get(rb_cPrism, rb_intern(
"CurrentVersionError"));
1637 rb_id_option_frozen_string_literal =
rb_intern_const(
"frozen_string_literal");
1645 rb_id_source_for = rb_intern(
"for");
1647 rb_id_forwarding_positionals = rb_intern(
"*");
1648 rb_id_forwarding_keywords = rb_intern(
"**");
1649 rb_id_forwarding_block = rb_intern(
"&");
1650 rb_id_forwarding_all = rb_intern(
"...");
1677#ifndef PRISM_EXCLUDE_SERIALIZATION
1686 Init_prism_api_node();
#define RUBY_ASSERT(...)
Asserts that the given expression is truthy if and only if RUBY_DEBUG is truthy.
#define rb_define_singleton_method(klass, mid, func, arity)
Defines klass.mid.
pm_warning_level_t
The levels of warnings generated during parsing.
@ PM_WARNING_LEVEL_DEFAULT
For warnings which should be emitted if $VERBOSE != nil.
@ PM_WARNING_LEVEL_VERBOSE
For warnings which should be emitted if $VERBOSE == true.
pm_error_level_t
The levels of errors generated during parsing.
@ PM_ERROR_LEVEL_ARGUMENT
For errors that should raise an argument error.
@ PM_ERROR_LEVEL_LOAD
For errors that should raise a load error.
@ PM_ERROR_LEVEL_SYNTAX
For errors that should raise a syntax error.
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Retrieves argument from argc and argv to given VALUE references according to the format string.
#define T_STRING
Old name of RUBY_T_STRING.
#define xfree
Old name of ruby_xfree.
#define INT2FIX
Old name of RB_INT2FIX.
#define ID2SYM
Old name of RB_ID2SYM.
#define ULONG2NUM
Old name of RB_ULONG2NUM.
#define SYM2ID
Old name of RB_SYM2ID.
#define xmalloc
Old name of ruby_xmalloc.
#define LONG2FIX
Old name of RB_INT2FIX.
#define LONG2NUM
Old name of RB_LONG2NUM.
#define Qtrue
Old name of RUBY_Qtrue.
#define NUM2INT
Old name of RB_NUM2INT.
#define Qnil
Old name of RUBY_Qnil.
#define Qfalse
Old name of RUBY_Qfalse.
#define T_ARRAY
Old name of RUBY_T_ARRAY.
#define NIL_P
Old name of RB_NIL_P.
#define T_SYMBOL
Old name of RUBY_T_SYMBOL.
#define SYMBOL_P
Old name of RB_SYMBOL_P.
void rb_exc_raise(VALUE mesg)
Raises an exception in the current thread.
void rb_syserr_fail(int e, const char *mesg)
Raises appropriate exception that represents a C errno.
VALUE rb_eNoMemError
NoMemoryError exception.
VALUE rb_eLoadError
LoadError exception.
VALUE rb_eTypeError
TypeError exception.
VALUE rb_eRuntimeError
RuntimeError exception.
VALUE rb_exc_new_str(VALUE etype, VALUE str)
Identical to rb_exc_new_cstr(), except it takes a Ruby's string instead of C's.
VALUE rb_eSyntaxError
SyntaxError exception.
VALUE rb_cObject
Object class.
VALUE rb_class_new_instance(int argc, const VALUE *argv, VALUE klass)
Allocates, then initialises an instance of the given class.
VALUE rb_stderr
STDERR constant.
VALUE rb_obj_class(VALUE obj)
Queries the class of an object.
VALUE rb_obj_is_kind_of(VALUE obj, VALUE klass)
Queries if the given object is an instance (of possibly descendants) of the given class.
VALUE rb_obj_freeze(VALUE obj)
Same as RB_OBJ_FREEZE(), but returns the given object.
VALUE rb_enc_str_new_cstr(const char *ptr, rb_encoding *enc)
Identical to rb_enc_str_new(), except it assumes the passed pointer is a pointer to a C string.
VALUE rb_funcall(VALUE recv, ID mid, int n,...)
Calls a method.
VALUE rb_ary_replace(VALUE copy, VALUE orig)
Replaces the contents of the former object with the contents of the latter.
VALUE rb_ary_new(void)
Allocates a new, empty array.
VALUE rb_ary_new_capa(long capa)
Identical to rb_ary_new(), except it additionally specifies how many rooms of objects it should alloc...
VALUE rb_ary_push(VALUE ary, VALUE elem)
Special case of rb_ary_cat() that it adds only one element.
VALUE rb_ary_entry(VALUE ary, long off)
Queries an element of an array.
void rb_ary_store(VALUE ary, long key, VALUE val)
Destructively stores the passed value to the passed array's passed index.
void rb_ext_ractor_safe(bool flag)
Asserts that the extension library that calls this function is aware of Ractor.
#define rb_str_new(str, len)
Allocates an instance of rb_cString.
#define rb_exc_new_cstr(exc, str)
Identical to rb_exc_new(), except it assumes the passed pointer is a pointer to a C string.
VALUE rb_str_dup(VALUE str)
Duplicates a string.
VALUE rb_str_freeze(VALUE str)
This is the implementation of String#freeze.
VALUE rb_check_string_type(VALUE obj)
Try converting an object to its stringised representation using its to_str method,...
#define rb_str_new_cstr(str)
Identical to rb_str_new, except it assumes the passed pointer is a pointer to a C string.
VALUE rb_const_get(VALUE space, ID name)
Identical to rb_const_defined(), except it returns the actual defined value.
VALUE rb_ivar_set(VALUE obj, ID name, VALUE val)
Identical to rb_iv_set(), except it accepts the name as an ID instead of a C string.
VALUE rb_ivar_get(VALUE obj, ID name)
Identical to rb_iv_get(), except it accepts the name as an ID instead of a C string.
int rb_respond_to(VALUE obj, ID mid)
Queries if the object responds to the method.
static ID rb_intern_const(const char *str)
This is a "tiny optimisation" over rb_intern().
const char ruby_version[]
Stringised version.
VALUE type(ANYARGS)
ANYARGS-ed function type.
void rb_hash_foreach(VALUE q, int_type *w, VALUE e)
Iteration over the given hash.
static const uint8_t PM_OPTIONS_COMMAND_LINE_E
A bit representing whether or not the command line -e option was set.
static const uint8_t PM_OPTIONS_COMMAND_LINE_L
A bit representing whether or not the command line -l option was set.
static const uint8_t PM_OPTIONS_COMMAND_LINE_A
A bit representing whether or not the command line -a option was set.
static const uint8_t PM_OPTIONS_SCOPE_FORWARDING_NONE
The default value for parameters.
static const uint8_t PM_OPTIONS_SCOPE_FORWARDING_ALL
When the scope is forwarding with the ... parameter.
static const uint8_t PM_OPTIONS_SCOPE_FORWARDING_POSITIONALS
When the scope is forwarding with the * parameter.
static const uint8_t PM_OPTIONS_SCOPE_FORWARDING_KEYWORDS
When the scope is forwarding with the ** parameter.
static const uint8_t PM_OPTIONS_COMMAND_LINE_N
A bit representing whether or not the command line -n option was set.
static const uint8_t PM_OPTIONS_COMMAND_LINE_X
A bit representing whether or not the command line -x option was set.
static const uint8_t PM_OPTIONS_SCOPE_FORWARDING_BLOCK
When the scope is forwarding with the & parameter.
static const uint8_t PM_OPTIONS_COMMAND_LINE_P
A bit representing whether or not the command line -p option was set.
PRISM_EXPORTED_FUNCTION PRISM_NODISCARD pm_parser_t * pm_parser_new(pm_arena_t *arena, const uint8_t *source, size_t size, const pm_options_t *options) PRISM_NONNULL(1)
Allocate and initialize a parser with the given start and end pointers.
PRISM_EXPORTED_FUNCTION void pm_parser_free(pm_parser_t *parser) PRISM_NONNULL(1)
Free both the memory held by the given parser and the parser itself.
PRISM_EXPORTED_FUNCTION pm_node_t * pm_parse(pm_parser_t *parser) PRISM_NONNULL(1)
Initiate the parser with the given parser.
#define RARRAY_LEN
Just another name of rb_array_len.
#define errno
Ractor-aware version of errno.
pm_source_init_result_t
Represents the result of initializing a source from a file.
@ PM_SOURCE_INIT_ERROR_GENERIC
Indicates a generic error from a source init function, where the type of error should be read from er...
@ PM_SOURCE_INIT_SUCCESS
Indicates that the source was successfully initialized.
@ PM_SOURCE_INIT_ERROR_DIRECTORY
Indicates that the file that was attempted to be opened was a directory.
#define RTEST
This is an old name of RB_TEST.
pm_string_query_t
Represents the results of a slice query.
@ PM_STRING_QUERY_TRUE
Returned if the result of the slice query is true.
@ PM_STRING_QUERY_ERROR
Returned if the encoding given to a slice query was invalid.
@ PM_STRING_QUERY_FALSE
Returned if the result of the slice query is false.
We need a struct here to pass through rb_protect and it has to be a single value.
This struct gets stored in the parser and passed in to the lex callback any time a new token is found...
A list of offsets of the start of lines in a string.
uint32_t * offsets
The list of offsets.
size_t size
The number of offsets in the list.
This struct represents a slice in the source code, defined by an offset and a length.
uint32_t start
The offset of the location from the start of the source.
uint32_t length
The length of the location.
This is the base structure that represents a node in the syntax tree.
A generic string type that can have various ownership semantics.
This struct represents a token in the Ruby source.
uintptr_t ID
Type that represents a Ruby identifier such as a variable name.
uintptr_t VALUE
Type that represents a Ruby object.
static bool RB_TYPE_P(VALUE obj, enum ruby_value_type t)
Queries if the given object is of given type.