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_scopes;
43ID rb_id_option_version;
45ID rb_id_forwarding_positionals;
46ID rb_id_forwarding_keywords;
47ID rb_id_forwarding_block;
48ID rb_id_forwarding_all;
59check_string(
VALUE value) {
66 return RSTRING_PTR(value);
86 if (!pm_options_scopes_init(options, scopes_count)) {
91 for (
size_t scope_index = 0; scope_index < scopes_count; scope_index++) {
113 for (
size_t name_index = 0; name_index < names_count; name_index++) {
123 if (
id == rb_id_forwarding_positionals) {
125 }
else if (
id == rb_id_forwarding_keywords) {
127 }
else if (
id == rb_id_forwarding_block) {
129 }
else if (
id == rb_id_forwarding_all) {
132 rb_raise(rb_eArgError,
"invalid forwarding value: %" PRIsVALUE, name);
142 pm_options_scope_init(options_scope, locals_count);
145 for (
size_t local_index = 0; local_index < locals_count; local_index++) {
155 pm_string_t *scope_local = pm_options_scope_local_mut(options_scope, local_index);
156 const char *name = rb_id2name(
SYM2ID(local));
157 pm_string_constant_init(scope_local, name, strlen(name));
161 pm_options_scope_forwarding_set(options_scope, forwarding);
173 if (key_id == rb_id_option_filepath) {
174 if (!
NIL_P(value)) pm_options_filepath_set(options, check_string(value));
175 }
else if (key_id == rb_id_option_encoding) {
178 pm_options_encoding_locked_set(options,
true);
180 pm_options_encoding_set(options, rb_enc_name(rb_to_encoding(value)));
183 }
else if (key_id == rb_id_option_line) {
184 if (!
NIL_P(value)) pm_options_line_set(options,
NUM2INT(value));
185 }
else if (key_id == rb_id_option_frozen_string_literal) {
186 if (!
NIL_P(value)) pm_options_frozen_string_literal_set(options,
RTEST(value));
187 }
else if (key_id == rb_id_option_version) {
189 const char *version = check_string(value);
191 if (RSTRING_LEN(value) == 7 && strncmp(version,
"current", 7) == 0) {
192 if (!pm_options_version_set(options,
ruby_version, 3)) {
195 }
else if (RSTRING_LEN(value) == 7 && strncmp(version,
"nearest", 7) == 0) {
196 if (!pm_options_version_set(options,
ruby_version, 3)) {
199 pm_options_version_set_lowest(options);
202 pm_options_version_set_highest(options);
205 }
else if (!pm_options_version_set(options, version, RSTRING_LEN(value))) {
206 rb_raise(rb_eArgError,
"invalid version: %" PRIsVALUE, value);
209 }
else if (key_id == rb_id_option_scopes) {
210 if (!
NIL_P(value)) build_options_scopes(options, value);
211 }
else if (key_id == rb_id_option_command_line) {
213 const char *
string = check_string(value);
214 uint8_t command_line = 0;
216 for (
size_t index = 0; index < strlen(
string); index++) {
217 switch (
string[index]) {
224 default: rb_raise(rb_eArgError,
"invalid command line flag: '%c'",
string[index]);
break;
228 pm_options_command_line_set(options, command_line);
230 }
else if (key_id == rb_id_option_main_script) {
231 if (!
NIL_P(value)) pm_options_main_script_set(options,
RTEST(value));
232 }
else if (key_id == rb_id_option_partial_script) {
233 if (!
NIL_P(value)) pm_options_partial_script_set(options,
RTEST(value));
234 }
else if (key_id == rb_id_option_freeze) {
235 if (!
NIL_P(value)) pm_options_freeze_set(options,
RTEST(value));
237 rb_raise(rb_eArgError,
"unknown keyword: %" PRIsVALUE, key);
258build_options(
VALUE argument) {
269 pm_options_line_set(options, 1);
271 if (!
NIL_P(keywords)) {
276 rb_protect(build_options, (
VALUE) argument, &state);
279 pm_options_free(options);
284 if (!
NIL_P(filepath)) {
286 pm_options_free(options);
290 pm_options_filepath_set(options, RSTRING_PTR(filepath));
304 pm_options_free(options);
308 extract_options(options,
Qnil, keywords);
322 pm_options_free(options);
326 *encoded_filepath = rb_str_encode_ospath(filepath);
327 extract_options(options, *encoded_filepath, keywords);
329 const char *source = (
const char *) pm_string_source(pm_options_filepath(options));
331 pm_source_t *pm_src = pm_source_file_new(source, &result);
337 pm_options_free(options);
340 int e = rb_w32_map_errno(GetLastError());
349 pm_options_free(options);
353 pm_options_free(options);
354 rb_raise(
rb_eRuntimeError,
"Unknown error (%d) initializing file: %s", result, source);
361#ifndef PRISM_EXCLUDE_SERIALIZATION
371dump_input(
const uint8_t *input,
size_t input_length,
const pm_options_t *options) {
381 pm_serialize(parser, node, buffer);
383 VALUE result =
rb_str_new(pm_buffer_value(buffer), pm_buffer_length(buffer));
384 pm_buffer_free(buffer);
386 pm_arena_free(arena);
402 VALUE string = string_options(argc, argv, options);
404 const uint8_t *source = (
const uint8_t *) RSTRING_PTR(
string);
405 size_t length = RSTRING_LEN(
string);
407#ifdef PRISM_BUILD_DEBUG
409 memcpy(dup, source, length);
410 source = (
const uint8_t *) dup;
413 VALUE value = dump_input(source, length, options);
416#ifdef PRISM_BUILD_DEBUG
418 xfree_sized(dup, length);
424 pm_options_free(options);
441 VALUE encoded_filepath;
442 pm_source_t *src = file_options(argc, argv, options, &encoded_filepath);
444 VALUE value = dump_input(pm_source_source(src), pm_source_length(src), options);
446 pm_options_free(options);
462rb_class_new_instance_freeze(
int argc,
const VALUE *argv,
VALUE klass,
bool freeze) {
472parser_location(
VALUE source,
bool freeze, uint32_t start, uint32_t length) {
474 return rb_class_new_instance_freeze(3, argv, rb_cPrismLocation, freeze);
480#define PARSER_LOCATION(source, freeze, location) \
481 parser_location(source, freeze, location.start, location.length)
490 return rb_class_new_instance_freeze(1, argv,
type, freeze);
500parser_comments_each(
const pm_comment_t *comment,
void *data) {
502 VALUE value = parser_comment(each_data->source, each_data->freeze, comment);
514 pm_parser_comments_each(parser, parser_comments_each, &each_data);
528 VALUE key_loc = parser_location(source, freeze, key.start, key.length);
529 VALUE value_loc = parser_location(source, freeze, value.
start, value.
length);
531 VALUE argv[] = { key_loc, value_loc };
532 return rb_class_new_instance_freeze(2, argv, rb_cPrismMagicComment, freeze);
536 VALUE magic_comments;
544 VALUE value = parser_magic_comment(each_data->source, each_data->freeze,
magic_comment);
552parser_magic_comments(
const pm_parser_t *parser,
VALUE source,
bool freeze) {
556 pm_parser_magic_comments_each(parser, parser_magic_comments_each, &each_data);
559 return magic_comments;
570 if (data_loc->
length == 0) {
573 return parser_location(source, freeze, data_loc->
start, data_loc->
length);
590 VALUE location = PARSER_LOCATION(each_data->source, each_data->freeze, pm_diagnostic_location(diagnostic));
595 switch (error_level) {
597 level =
ID2SYM(rb_intern(
"syntax"));
600 level =
ID2SYM(rb_intern(
"argument"));
603 level =
ID2SYM(rb_intern(
"load"));
609 VALUE argv[] = {
type, message, location, level };
610 VALUE value = rb_class_new_instance_freeze(4, argv, rb_cPrismParseError, each_data->freeze);
622 pm_parser_errors_each(parser, parser_errors_each, &each_data);
641 VALUE location = PARSER_LOCATION(each_data->source, each_data->freeze, pm_diagnostic_location(diagnostic));
646 switch (warning_level) {
648 level =
ID2SYM(rb_intern(
"default"));
651 level =
ID2SYM(rb_intern(
"verbose"));
657 VALUE argv[] = {
type, message, location, level };
658 VALUE value = rb_class_new_instance_freeze(4, argv, rb_cPrismParseWarning, each_data->freeze);
670 pm_parser_warnings_each(parser, parser_warnings_each, &each_data);
681 VALUE result_argv[] = {
683 parser_comments(parser, source, freeze),
684 parser_magic_comments(parser, source, freeze),
685 parser_data_loc(parser, source, freeze),
686 parser_errors(parser, encoding, source, freeze),
687 parser_warnings(parser, encoding, source, freeze),
692 return rb_class_new_instance_freeze(8, result_argv,
class, freeze);
720 VALUE value = pm_token_new(parser, token, parse_lex_data->encoding, parse_lex_data->source, parse_lex_data->freeze);
723 if (parse_lex_data->freeze) {
737parse_lex_encoding_changed_callback(
pm_parser_t *parser) {
739 parse_lex_data->encoding = rb_enc_find(pm_parser_encoding_name(parser));
745 VALUE tokens = parse_lex_data->tokens;
748 for (
long index = 0; index <
RARRAY_LEN(tokens); index++) {
755 rb_enc_associate(next_value, parse_lex_data->encoding);
758 VALUE next_token_argv[] = {
759 parse_lex_data->source,
768 if (parse_lex_data->freeze) {
784parse_lex_input(
const uint8_t *input,
size_t input_length,
const pm_options_t *options,
bool return_nodes) {
787 pm_parser_encoding_changed_callback_set(parser, parse_lex_encoding_changed_callback);
791 VALUE source =
rb_funcall(rb_cPrismSource, rb_id_source_for, 3, source_string,
LONG2NUM(pm_parser_start_line(parser)), offsets);
796 .encoding = rb_utf8_encoding(),
797 .freeze = pm_options_freeze(options),
801 pm_parser_lex_callback_set(parser, parse_lex_token, data);
807 rb_encoding *encoding = rb_enc_find(pm_parser_encoding_name(parser));
808 rb_enc_associate(source_string, encoding);
811 for (
size_t index = 0; index < line_offsets->
size; index++) {
815 if (pm_options_freeze(options)) {
825 rb_ary_push(value, pm_ast_new(parser, node, parse_lex_data.encoding, source, pm_options_freeze(options)));
828 result = parse_result_create(rb_cPrismParseLexResult, parser, value, parse_lex_data.encoding, source, pm_options_freeze(options));
830 result = parse_result_create(rb_cPrismLexResult, parser, parse_lex_data.tokens, parse_lex_data.encoding, source, pm_options_freeze(options));
834 pm_arena_free(arena);
850 VALUE string = string_options(argc, argv, options);
852 VALUE result = parse_lex_input((
const uint8_t *) RSTRING_PTR(
string), RSTRING_LEN(
string), options,
false);
853 pm_options_free(options);
870 VALUE encoded_filepath;
871 pm_source_t *src = file_options(argc, argv, options, &encoded_filepath);
873 VALUE value = parse_lex_input(pm_source_source(src), pm_source_length(src), options,
false);
875 pm_options_free(options);
888parse_input(
const uint8_t *input,
size_t input_length,
const pm_options_t *options) {
893 rb_encoding *encoding = rb_enc_find(pm_parser_encoding_name(parser));
895 bool freeze = pm_options_freeze(options);
896 VALUE source = pm_source_new(parser, encoding, freeze);
897 VALUE value = pm_ast_new(parser, node, encoding, source, freeze);
898 VALUE result = parse_result_create(rb_cPrismParseResult, parser, value, encoding, source, freeze);
905 pm_arena_free(arena);
958 VALUE string = string_options(argc, argv, options);
960 const uint8_t *source = (
const uint8_t *) RSTRING_PTR(
string);
961 size_t length = RSTRING_LEN(
string);
963#ifdef PRISM_BUILD_DEBUG
965 memcpy(dup, source, length);
966 source = (
const uint8_t *) dup;
969 VALUE value = parse_input(source, length, options);
971#ifdef PRISM_BUILD_DEBUG
973 xfree_sized(dup, length);
979 pm_options_free(options);
992parse_file(
int argc,
VALUE *argv,
VALUE self) {
995 VALUE encoded_filepath;
996 pm_source_t *src = file_options(argc, argv, options, &encoded_filepath);
998 VALUE value = parse_input(pm_source_source(src), pm_source_length(src), options);
1000 pm_options_free(options);
1009profile_input(
const uint8_t *input,
size_t input_length,
const pm_options_t *options) {
1015 pm_arena_free(arena);
1030 VALUE string = string_options(argc, argv, options);
1032 profile_input((
const uint8_t *) RSTRING_PTR(
string), RSTRING_LEN(
string), options);
1033 pm_options_free(options);
1048profile_file(
int argc,
VALUE *argv,
VALUE self) {
1051 VALUE encoded_filepath;
1052 pm_source_t *src = file_options(argc, argv, options, &encoded_filepath);
1054 profile_input(pm_source_source(src), pm_source_length(src), options);
1055 pm_source_free(src);
1056 pm_options_free(options);
1062parse_stream_eof(
void *stream) {
1073parse_stream_fgets(
char *
string,
int size,
void *stream) {
1081 const char *cstr = RSTRING_PTR(line);
1082 long length = RSTRING_LEN(line);
1084 memcpy(
string, cstr, length);
1085 string[length] =
'\0';
1099parse_stream(
int argc,
VALUE *argv,
VALUE self) {
1105 extract_options(options,
Qnil, keywords);
1107 pm_source_t *src = pm_source_stream_new((
void *) stream, parse_stream_fgets, parse_stream_eof);
1111 pm_node_t *node = pm_parse_stream(&parser, arena, src, options);
1112 rb_encoding *encoding = rb_enc_find(pm_parser_encoding_name(parser));
1114 VALUE source = pm_source_new(parser, encoding, pm_options_freeze(options));
1115 VALUE value = pm_ast_new(parser, node, encoding, source, pm_options_freeze(options));
1116 VALUE result = parse_result_create(rb_cPrismParseResult, parser, value, encoding, source, pm_options_freeze(options));
1118 pm_source_free(src);
1120 pm_arena_free(arena);
1121 pm_options_free(options);
1130parse_input_comments(
const uint8_t *input,
size_t input_length,
const pm_options_t *options) {
1135 rb_encoding *encoding = rb_enc_find(pm_parser_encoding_name(parser));
1137 VALUE source = pm_source_new(parser, encoding, pm_options_freeze(options));
1138 VALUE comments = parser_comments(parser, source, pm_options_freeze(options));
1141 pm_arena_free(arena);
1155parse_comments(
int argc,
VALUE *argv,
VALUE self) {
1157 VALUE string = string_options(argc, argv, options);
1159 VALUE result = parse_input_comments((
const uint8_t *) RSTRING_PTR(
string), RSTRING_LEN(
string), options);
1160 pm_options_free(options);
1174parse_file_comments(
int argc,
VALUE *argv,
VALUE self) {
1177 VALUE encoded_filepath;
1178 pm_source_t *src = file_options(argc, argv, options, &encoded_filepath);
1180 VALUE value = parse_input_comments(pm_source_source(src), pm_source_length(src), options);
1181 pm_source_free(src);
1182 pm_options_free(options);
1203parse_lex(
int argc,
VALUE *argv,
VALUE self) {
1205 VALUE string = string_options(argc, argv, options);
1207 VALUE value = parse_lex_input((
const uint8_t *) RSTRING_PTR(
string), RSTRING_LEN(
string), options,
true);
1208 pm_options_free(options);
1229parse_lex_file(
int argc,
VALUE *argv,
VALUE self) {
1232 VALUE encoded_filepath;
1233 pm_source_t *src = file_options(argc, argv, options, &encoded_filepath);
1235 VALUE value = parse_lex_input(pm_source_source(src), pm_source_length(src), options,
true);
1236 pm_source_free(src);
1237 pm_options_free(options);
1246parse_input_success_p(
const uint8_t *input,
size_t input_length,
const pm_options_t *options) {
1254 pm_arena_free(arena);
1268parse_success_p(
int argc,
VALUE *argv,
VALUE self) {
1270 VALUE string = string_options(argc, argv, options);
1272 VALUE result = parse_input_success_p((
const uint8_t *) RSTRING_PTR(
string), RSTRING_LEN(
string), options);
1273 pm_options_free(options);
1287parse_failure_p(
int argc,
VALUE *argv,
VALUE self) {
1300parse_file_success_p(
int argc,
VALUE *argv,
VALUE self) {
1303 VALUE encoded_filepath;
1304 pm_source_t *src = file_options(argc, argv, options, &encoded_filepath);
1306 VALUE result = parse_input_success_p(pm_source_source(src), pm_source_length(src), options);
1307 pm_source_free(src);
1308 pm_options_free(options);
1322parse_file_failure_p(
int argc,
VALUE *argv,
VALUE self) {
1338 rb_raise(rb_eArgError,
"Invalid or non ascii-compatible encoding");
1358string_query_local_p(
VALUE self,
VALUE string) {
1359 const uint8_t *source = (
const uint8_t *) check_string(
string);
1360 return string_query(pm_string_query_local(source, RSTRING_LEN(
string), rb_enc_get(
string)->name));
1373string_query_constant_p(
VALUE self,
VALUE string) {
1374 const uint8_t *source = (
const uint8_t *) check_string(
string);
1375 return string_query(pm_string_query_constant(source, RSTRING_LEN(
string), rb_enc_get(
string)->name));
1386string_query_method_name_p(
VALUE self,
VALUE string) {
1387 const uint8_t *source = (
const uint8_t *) check_string(
string);
1388 return string_query(pm_string_query_method_name(source, RSTRING_LEN(
string), rb_enc_get(
string)->name));
1398RUBY_FUNC_EXPORTED
void
1402 if (strcmp(pm_version(), EXPECTED_PRISM_VERSION) != 0) {
1405 "The prism library version (%s) does not match the expected version (%s)",
1407 EXPECTED_PRISM_VERSION
1411#ifdef HAVE_RB_EXT_RACTOR_SAFE
1436 rb_cPrismCurrentVersionError =
rb_const_get(rb_cPrism, rb_intern(
"CurrentVersionError"));
1444 rb_id_option_frozen_string_literal =
rb_intern_const(
"frozen_string_literal");
1450 rb_id_source_for = rb_intern(
"for");
1451 rb_id_forwarding_positionals = rb_intern(
"*");
1452 rb_id_forwarding_keywords = rb_intern(
"**");
1453 rb_id_forwarding_block = rb_intern(
"&");
1454 rb_id_forwarding_all = rb_intern(
"...");
1478#ifndef PRISM_EXCLUDE_SERIALIZATION
1488 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.
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
VALUE rb_define_module(const char *name)
Defines a top-level module.
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.
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_eTypeError
TypeError exception.
VALUE rb_eRuntimeError
RuntimeError 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_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)
Just calls rb_obj_freeze_inline() inside.
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.
VALUE rb_assoc_new(VALUE car, VALUE cdr)
Identical to rb_ary_new_from_values(), except it expects exactly two parameters.
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.
#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_get(VALUE obj, ID name)
Identical to rb_iv_get(), except it accepts the name as an ID instead of a C string.
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.