diff options
Diffstat (limited to 'ruby_parser.c')
-rw-r--r-- | ruby_parser.c | 494 |
1 files changed, 338 insertions, 156 deletions
diff --git a/ruby_parser.c b/ruby_parser.c index 16a868bc6b..93901ea4d9 100644 --- a/ruby_parser.c +++ b/ruby_parser.c @@ -1,5 +1,6 @@ /* This is a wrapper for parse.y */ +#include "internal/parse.h" #include "internal/re.h" #include "internal/ruby_parser.h" @@ -18,7 +19,6 @@ #include "internal/gc.h" #include "internal/hash.h" #include "internal/io.h" -#include "internal/parse.h" #include "internal/rational.h" #include "internal/re.h" #include "internal/string.h" @@ -32,40 +32,7 @@ #include "vm_core.h" #include "symbol.h" -struct ruby_parser { - rb_parser_t *parser_params; -}; - -static void -parser_mark(void *ptr) -{ - struct ruby_parser *parser = (struct ruby_parser*)ptr; - rb_ruby_parser_mark(parser->parser_params); -} - -static void -parser_free(void *ptr) -{ - struct ruby_parser *parser = (struct ruby_parser*)ptr; - rb_ruby_parser_free(parser->parser_params); -} - -static size_t -parser_memsize(const void *ptr) -{ - struct ruby_parser *parser = (struct ruby_parser*)ptr; - return rb_ruby_parser_memsize(parser->parser_params); -} - -static const rb_data_type_t ruby_parser_data_type = { - "parser", - { - parser_mark, - parser_free, - parser_memsize, - }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY -}; +#define parser_encoding const void static int is_ascii_string2(VALUE str) @@ -76,9 +43,9 @@ is_ascii_string2(VALUE str) RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 6, 0) static VALUE syntax_error_append(VALUE exc, VALUE file, int line, int column, - void *enc, const char *fmt, va_list args) + parser_encoding *enc, const char *fmt, va_list args) { - return rb_syntax_error_append(exc, file, line, column, (rb_encoding *)enc, fmt, args); + return rb_syntax_error_append(exc, file, line, column, enc, fmt, args); } static int @@ -94,9 +61,9 @@ dvar_defined(ID id, const void *p) } static int -is_usascii_enc(void *enc) +is_usascii_enc(parser_encoding *enc) { - return rb_is_usascii_enc((rb_encoding *)enc); + return rb_is_usascii_enc(enc); } static int @@ -118,21 +85,21 @@ is_notop_id2(ID id) } static VALUE -enc_str_new(const char *ptr, long len, void *enc) +enc_str_new(const char *ptr, long len, parser_encoding *enc) { - return rb_enc_str_new(ptr, len, (rb_encoding *)enc); + return rb_enc_str_new(ptr, len, enc); } static int -enc_isalnum(OnigCodePoint c, void *enc) +enc_isalnum(OnigCodePoint c, parser_encoding *enc) { - return rb_enc_isalnum(c, (rb_encoding *)enc); + return rb_enc_isalnum(c, enc); } static int -enc_precise_mbclen(const char *p, const char *e, void *enc) +enc_precise_mbclen(const char *p, const char *e, parser_encoding *enc) { - return rb_enc_precise_mbclen(p, e, (rb_encoding *)enc); + return rb_enc_precise_mbclen(p, e, enc); } static int @@ -148,105 +115,87 @@ mbclen_charfound_len(int len) } static const char * -enc_name(void *enc) +enc_name(parser_encoding *enc) { - return rb_enc_name((rb_encoding *)enc); + return rb_enc_name(enc); } static char * -enc_prev_char(const char *s, const char *p, const char *e, void *enc) +enc_prev_char(const char *s, const char *p, const char *e, parser_encoding *enc) { - return rb_enc_prev_char(s, p, e, (rb_encoding *)enc); + return rb_enc_prev_char(s, p, e, enc); } -static void * +static parser_encoding * enc_get(VALUE obj) { - return (void *)rb_enc_get(obj); + return rb_enc_get(obj); } static int -enc_asciicompat(void *enc) +enc_asciicompat(parser_encoding *enc) { - return rb_enc_asciicompat((rb_encoding *)enc); + return rb_enc_asciicompat(enc); } -static void * +static parser_encoding * utf8_encoding(void) { - return (void *)rb_utf8_encoding(); + return rb_utf8_encoding(); } static VALUE -enc_associate(VALUE obj, void *enc) +enc_associate(VALUE obj, parser_encoding *enc) { - return rb_enc_associate(obj, (rb_encoding *)enc); + return rb_enc_associate(obj, enc); } -static void * +static parser_encoding * ascii8bit_encoding(void) { - return (void *)rb_ascii8bit_encoding(); + return rb_ascii8bit_encoding(); } static int -enc_codelen(int c, void *enc) +enc_codelen(int c, parser_encoding *enc) { - return rb_enc_codelen(c, (rb_encoding *)enc); + return rb_enc_codelen(c, enc); } static int -enc_mbcput(unsigned int c, void *buf, void *enc) +enc_mbcput(unsigned int c, void *buf, parser_encoding *enc) { - return rb_enc_mbcput(c, buf, (rb_encoding *)enc); + return rb_enc_mbcput(c, buf, enc); } -static void * +static parser_encoding * enc_from_index(int idx) { - return (void *)rb_enc_from_index(idx); + return rb_enc_from_index(idx); } static int -enc_isspace(OnigCodePoint c, void *enc) +enc_isspace(OnigCodePoint c, parser_encoding *enc) { - return rb_enc_isspace(c, (rb_encoding *)enc); + return rb_enc_isspace(c, enc); } static ID -intern3(const char *name, long len, void *enc) +intern3(const char *name, long len, parser_encoding *enc) { - return rb_intern3(name, len, (rb_encoding *)enc); + return rb_intern3(name, len, enc); } -static void * -enc_compatible(VALUE str1, VALUE str2) -{ - return (void *)rb_enc_compatible(str1, str2); -} - -static VALUE -enc_from_encoding(void *enc) -{ - return rb_enc_from_encoding((rb_encoding *)enc); -} - -static int -encoding_is_ascii8bit(VALUE obj) -{ - return ENCODING_IS_ASCII8BIT(obj); -} - -static void * +static parser_encoding * usascii_encoding(void) { - return (void *)rb_usascii_encoding(); + return rb_usascii_encoding(); } static int -enc_symname_type(const char *name, long len, void *enc, unsigned int allowed_attrset) +enc_symname_type(const char *name, long len, parser_encoding *enc, unsigned int allowed_attrset) { - return rb_enc_symname_type(name, len, (rb_encoding *)enc, allowed_attrset); + return rb_enc_symname_type(name, len, enc, allowed_attrset); } typedef struct { @@ -267,7 +216,7 @@ reg_named_capture_assign_iter(const OnigUChar *name, const OnigUChar *name_end, long len = name_end - name; const char *s = (const char *)name; - return rb_reg_named_capture_assign_iter_impl(p, s, len, (void *)enc, &arg->succ_block, loc); + return rb_reg_named_capture_assign_iter_impl(p, s, len, enc, &arg->succ_block, loc); } static NODE * @@ -285,12 +234,6 @@ reg_named_capture_assign(struct parser_params* p, VALUE regexp, const rb_code_lo return RNODE_BLOCK(arg.succ_block)->nd_next; } -static VALUE -rbool(VALUE v) -{ - return RBOOL(v); -} - static int rtest(VALUE obj) { @@ -351,12 +294,6 @@ arg_error(void) return rb_eArgError; } -static rb_ast_t * -ast_new(VALUE nb) -{ - return IMEMO_NEW(rb_ast_t, imemo_ast, nb); -} - static VALUE static_id2sym(ID id) { @@ -364,25 +301,25 @@ static_id2sym(ID id) } static long -str_coderange_scan_restartable(const char *s, const char *e, void *enc, int *cr) +str_coderange_scan_restartable(const char *s, const char *e, parser_encoding *enc, int *cr) { - return rb_str_coderange_scan_restartable(s, e, (rb_encoding *)enc, cr); + return rb_str_coderange_scan_restartable(s, e, enc, cr); } static int -enc_mbminlen(void *enc) +enc_mbminlen(parser_encoding *enc) { - return rb_enc_mbminlen((rb_encoding *)enc); + return rb_enc_mbminlen(enc); } static bool -enc_isascii(OnigCodePoint c, void *enc) +enc_isascii(OnigCodePoint c, parser_encoding *enc) { - return rb_enc_isascii(c, (rb_encoding *)enc); + return rb_enc_isascii(c, enc); } static OnigCodePoint -enc_mbc_to_codepoint(const char *p, const char *e, void *enc) +enc_mbc_to_codepoint(const char *p, const char *e, parser_encoding *enc) { const OnigUChar *up = RBIMPL_CAST((const OnigUChar *)p); const OnigUChar *ue = RBIMPL_CAST((const OnigUChar *)e); @@ -390,7 +327,6 @@ enc_mbc_to_codepoint(const char *p, const char *e, void *enc) return ONIGENC_MBC_TO_CODE((rb_encoding *)enc, up, ue); } -VALUE rb_io_gets_internal(VALUE io); extern VALUE rb_eArgError; static const rb_parser_config_t rb_global_parser_config = { @@ -406,8 +342,6 @@ static const rb_parser_config_t rb_global_parser_config = { .nonempty_memcpy = nonempty_memcpy, .xmalloc_mul_add = rb_xmalloc_mul_add, - .ast_new = ast_new, - .compile_callback = rb_suppress_tracing, .reg_named_capture_assign = reg_named_capture_assign, @@ -417,8 +351,6 @@ static const rb_parser_config_t rb_global_parser_config = { .ary_push = rb_ary_push, .ary_new_from_args = rb_ary_new_from_args, .ary_unshift = rb_ary_unshift, - .array_len = rb_array_len, - .array_aref = RARRAY_AREF, .make_temporary_id = rb_make_temporary_id, .is_local_id = is_local_id2, @@ -439,8 +371,6 @@ static const rb_parser_config_t rb_global_parser_config = { .str_catf = rb_str_catf, .str_cat_cstr = rb_str_cat_cstr, - .str_subseq = rb_str_subseq, - .str_new_frozen = rb_str_new_frozen, .str_modify = rb_str_modify, .str_set_len = rb_str_set_len, .str_cat = rb_str_cat, @@ -451,12 +381,10 @@ static const rb_parser_config_t rb_global_parser_config = { .is_ascii_string = is_ascii_string2, .enc_str_new = enc_str_new, .str_vcatf = rb_str_vcatf, - .string_value_cstr = rb_string_value_cstr, .rb_sprintf = rb_sprintf, .rstring_ptr = RSTRING_PTR, .rstring_end = RSTRING_END, .rstring_len = RSTRING_LEN, - .filesystem_str_new_cstr = rb_filesystem_str_new_cstr, .obj_as_string = rb_obj_as_string, .int2num = rb_int2num_inline, @@ -466,7 +394,6 @@ static const rb_parser_config_t rb_global_parser_config = { .io_write = rb_io_write, .io_flush = rb_io_flush, .io_puts = rb_io_puts, - .io_gets_internal = rb_io_gets_internal, .debug_output_stdout = rb_ractor_stdout, .debug_output_stderr = rb_ractor_stderr, @@ -490,9 +417,6 @@ static const rb_parser_config_t rb_global_parser_config = { .enc_isspace = enc_isspace, .enc_coderange_7bit = ENC_CODERANGE_7BIT, .enc_coderange_unknown = ENC_CODERANGE_UNKNOWN, - .enc_compatible = enc_compatible, - .enc_from_encoding = enc_from_encoding, - .encoding_is_ascii8bit = encoding_is_ascii8bit, .usascii_encoding = usascii_encoding, .enc_coderange_broken = ENC_CODERANGE_BROKEN, .enc_mbminlen = enc_mbminlen, @@ -534,11 +458,9 @@ static const rb_parser_config_t rb_global_parser_config = { .scan_digits = ruby_scan_digits, .strtod = ruby_strtod, - .rbool = rbool, .rtest = rtest, .nil_p = nil_p, .qnil = Qnil, - .qtrue = Qtrue, .qfalse = Qfalse, .eArgError = arg_error, .long2int = rb_long2int, @@ -547,7 +469,77 @@ static const rb_parser_config_t rb_global_parser_config = { .static_id2sym = static_id2sym, .str_coderange_scan_restartable = str_coderange_scan_restartable, }; +#endif + +enum lex_type { + lex_type_str, + lex_type_io, + lex_type_array, + lex_type_generic, +}; + +struct ruby_parser { + rb_parser_t *parser_params; + enum lex_type type; + union { + struct lex_pointer_string lex_str; + struct { + VALUE file; + } lex_io; + struct { + VALUE ary; + } lex_array; + } data; +}; + +static void +parser_mark(void *ptr) +{ + struct ruby_parser *parser = (struct ruby_parser*)ptr; + rb_ruby_parser_mark(parser->parser_params); + + switch (parser->type) { + case lex_type_str: + rb_gc_mark(parser->data.lex_str.str); + break; + case lex_type_io: + rb_gc_mark(parser->data.lex_io.file); + break; + case lex_type_array: + rb_gc_mark(parser->data.lex_array.ary); + break; + case lex_type_generic: + /* noop. Caller of rb_parser_compile_generic should mark the objects. */ + break; + } +} + +static void +parser_free(void *ptr) +{ + struct ruby_parser *parser = (struct ruby_parser*)ptr; + rb_ruby_parser_free(parser->parser_params); + xfree(parser); +} + +static size_t +parser_memsize(const void *ptr) +{ + struct ruby_parser *parser = (struct ruby_parser*)ptr; + return rb_ruby_parser_memsize(parser->parser_params); +} + +static const rb_data_type_t ruby_parser_data_type = { + "parser", + { + parser_mark, + parser_free, + parser_memsize, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY +}; +#ifdef UNIVERSAL_PARSER const rb_parser_config_t * rb_ruby_parser_config(void) { @@ -555,16 +547,17 @@ rb_ruby_parser_config(void) } rb_parser_t * -rb_parser_params_allocate(void) +rb_parser_params_new(void) { - return rb_ruby_parser_allocate(&rb_global_parser_config); + return rb_ruby_parser_new(&rb_global_parser_config); } - +#else rb_parser_t * rb_parser_params_new(void) { - return rb_ruby_parser_new(&rb_global_parser_config); + return rb_ruby_parser_new(); } +#endif /* UNIVERSAL_PARSER */ VALUE rb_parser_new(void) @@ -622,65 +615,227 @@ rb_parser_error_tolerant(VALUE vparser) rb_ruby_parser_error_tolerant(parser->parser_params); } -rb_ast_t* +void +rb_parser_keep_tokens(VALUE vparser) +{ + struct ruby_parser *parser; + + TypedData_Get_Struct(vparser, struct ruby_parser, &ruby_parser_data_type, parser); + rb_ruby_parser_keep_tokens(parser->parser_params); +} + +rb_parser_string_t * +rb_parser_lex_get_str(struct parser_params *p, struct lex_pointer_string *ptr_str) +{ + char *beg, *end, *start; + long len; + VALUE s = ptr_str->str; + + beg = RSTRING_PTR(s); + len = RSTRING_LEN(s); + start = beg; + if (ptr_str->ptr) { + if (len == ptr_str->ptr) return 0; + beg += ptr_str->ptr; + len -= ptr_str->ptr; + } + end = memchr(beg, '\n', len); + if (end) len = ++end - beg; + ptr_str->ptr += len; + return rb_str_to_parser_string(p, rb_str_subseq(s, beg - start, len)); +} + +static rb_parser_string_t * +lex_get_str(struct parser_params *p, rb_parser_input_data input, int line_count) +{ + return rb_parser_lex_get_str(p, (struct lex_pointer_string *)input); +} + +static void parser_aset_script_lines_for(VALUE path, rb_parser_ary_t *lines); + +static rb_ast_t* +parser_compile(rb_parser_t *p, rb_parser_lex_gets_func *gets, VALUE fname, rb_parser_input_data input, int line) +{ + rb_ast_t *ast = rb_parser_compile(p, gets, fname, input, line); + parser_aset_script_lines_for(fname, ast->body.script_lines); + return ast; +} + +static rb_ast_t* +parser_compile_string0(struct ruby_parser *parser, VALUE fname, VALUE s, int line) +{ + VALUE str = rb_str_new_frozen(s); + + parser->type = lex_type_str; + parser->data.lex_str.str = str; + parser->data.lex_str.ptr = 0; + + return parser_compile(parser->parser_params, lex_get_str, fname, (rb_parser_input_data)&parser->data, line); +} + +static rb_encoding * +must_be_ascii_compatible(VALUE s) +{ + rb_encoding *enc = rb_enc_get(s); + if (!rb_enc_asciicompat(enc)) { + rb_raise(rb_eArgError, "invalid source encoding"); + } + return enc; +} + +static rb_ast_t* +parser_compile_string_path(struct ruby_parser *parser, VALUE f, VALUE s, int line) +{ + must_be_ascii_compatible(s); + return parser_compile_string0(parser, f, s, line); +} + +static rb_ast_t* +parser_compile_string(struct ruby_parser *parser, const char *f, VALUE s, int line) +{ + return parser_compile_string_path(parser, rb_filesystem_str_new_cstr(f), s, line); +} + +VALUE rb_io_gets_internal(VALUE io); + +static rb_parser_string_t * +lex_io_gets(struct parser_params *p, rb_parser_input_data input, int line_count) +{ + VALUE io = (VALUE)input; + VALUE line = rb_io_gets_internal(io); + if (NIL_P(line)) return 0; + return rb_str_to_parser_string(p, line); +} + +static rb_parser_string_t * +lex_gets_array(struct parser_params *p, rb_parser_input_data data, int index) +{ + VALUE array = (VALUE)data; + VALUE str = rb_ary_entry(array, index); + if (!NIL_P(str)) { + StringValue(str); + if (!rb_enc_asciicompat(rb_enc_get(str))) { + rb_raise(rb_eArgError, "invalid source encoding"); + } + return rb_str_to_parser_string(p, str); + } + else { + return 0; + } +} + +static rb_ast_t* +parser_compile_file_path(struct ruby_parser *parser, VALUE fname, VALUE file, int start) +{ + parser->type = lex_type_io; + parser->data.lex_io.file = file; + + return parser_compile(parser->parser_params, lex_io_gets, fname, (rb_parser_input_data)file, start); +} + +static rb_ast_t* +parser_compile_array(struct ruby_parser *parser, VALUE fname, VALUE array, int start) +{ + parser->type = lex_type_array; + parser->data.lex_array.ary = array; + + return parser_compile(parser->parser_params, lex_gets_array, fname, (rb_parser_input_data)array, start); +} + +static rb_ast_t* +parser_compile_generic(struct ruby_parser *parser, rb_parser_lex_gets_func *lex_gets, VALUE fname, VALUE input, int start) +{ + parser->type = lex_type_generic; + + return parser_compile(parser->parser_params, lex_gets, fname, (rb_parser_input_data)input, start); +} + +static void +ast_free(void *ptr) +{ + rb_ast_t *ast = (rb_ast_t *)ptr; + rb_ast_free(ast); +} + +static const rb_data_type_t ast_data_type = { + "AST", + { + NULL, + ast_free, + NULL, // No dsize() because this object does not appear in ObjectSpace. + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY +}; + +static VALUE +ast_alloc(void) +{ + return TypedData_Wrap_Struct(0, &ast_data_type, NULL); +} + +VALUE rb_parser_compile_file_path(VALUE vparser, VALUE fname, VALUE file, int start) { struct ruby_parser *parser; - rb_ast_t *ast; + VALUE ast_value = ast_alloc(); TypedData_Get_Struct(vparser, struct ruby_parser, &ruby_parser_data_type, parser); - ast = rb_ruby_parser_compile_file_path(parser->parser_params, fname, file, start); + DATA_PTR(ast_value) = parser_compile_file_path(parser, fname, file, start); RB_GC_GUARD(vparser); - return ast; + return ast_value; } -void -rb_parser_keep_tokens(VALUE vparser) +VALUE +rb_parser_compile_array(VALUE vparser, VALUE fname, VALUE array, int start) { struct ruby_parser *parser; + VALUE ast_value = ast_alloc(); TypedData_Get_Struct(vparser, struct ruby_parser, &ruby_parser_data_type, parser); - rb_ruby_parser_keep_tokens(parser->parser_params); + DATA_PTR(ast_value) = parser_compile_array(parser, fname, array, start); + RB_GC_GUARD(vparser); + + return ast_value; } -rb_ast_t* -rb_parser_compile_generic(VALUE vparser, VALUE (*lex_gets)(VALUE, int), VALUE fname, VALUE input, int start) +VALUE +rb_parser_compile_generic(VALUE vparser, rb_parser_lex_gets_func *lex_gets, VALUE fname, VALUE input, int start) { struct ruby_parser *parser; - rb_ast_t *ast; + VALUE ast_value = ast_alloc(); TypedData_Get_Struct(vparser, struct ruby_parser, &ruby_parser_data_type, parser); - ast = rb_ruby_parser_compile_generic(parser->parser_params, lex_gets, fname, input, start); + DATA_PTR(ast_value) = parser_compile_generic(parser, lex_gets, fname, input, start); RB_GC_GUARD(vparser); - return ast; + return ast_value; } -rb_ast_t* +VALUE rb_parser_compile_string(VALUE vparser, const char *f, VALUE s, int line) { struct ruby_parser *parser; - rb_ast_t *ast; + VALUE ast_value = ast_alloc(); TypedData_Get_Struct(vparser, struct ruby_parser, &ruby_parser_data_type, parser); - ast = rb_ruby_parser_compile_string(parser->parser_params, f, s, line); + DATA_PTR(ast_value) = parser_compile_string(parser, f, s, line); RB_GC_GUARD(vparser); - return ast; + return ast_value; } -rb_ast_t* +VALUE rb_parser_compile_string_path(VALUE vparser, VALUE f, VALUE s, int line) { struct ruby_parser *parser; - rb_ast_t *ast; + VALUE ast_value = ast_alloc(); TypedData_Get_Struct(vparser, struct ruby_parser, &ruby_parser_data_type, parser); - ast = rb_ruby_parser_compile_string_path(parser->parser_params, f, s, line); + DATA_PTR(ast_value) = parser_compile_string_path(parser, f, s, line); RB_GC_GUARD(vparser); - return ast; + return ast_value; } VALUE @@ -689,7 +844,7 @@ rb_parser_encoding(VALUE vparser) struct ruby_parser *parser; TypedData_Get_Struct(vparser, struct ruby_parser, &ruby_parser_data_type, parser); - return rb_ruby_parser_encoding(parser->parser_params); + return rb_enc_from_encoding(rb_ruby_parser_encoding(parser->parser_params)); } VALUE @@ -726,12 +881,12 @@ rb_set_script_lines_for(VALUE vparser, VALUE path) rb_ruby_parser_set_script_lines(parser->parser_params); } } -#endif VALUE rb_parser_build_script_lines_from(rb_parser_ary_t *lines) { int i; + if (!lines) return Qnil; if (lines->data_type != PARSER_ARY_DATA_SCRIPT_LINE) { rb_bug("unexpected rb_parser_ary_data_type (%d) for script lines", lines->data_type); } @@ -746,7 +901,7 @@ rb_parser_build_script_lines_from(rb_parser_ary_t *lines) VALUE rb_str_new_parser_string(rb_parser_string_t *str) { - VALUE string = rb_enc_interned_str(str->ptr, str->len, str->enc); + VALUE string = rb_enc_literal_str(str->ptr, str->len, str->enc); rb_enc_str_coderange(string); return string; } @@ -949,12 +1104,12 @@ rb_node_encoding_val(const NODE *node) return rb_enc_from_encoding(RNODE_ENCODING(node)->enc); } -void -rb_parser_aset_script_lines_for(VALUE path, rb_parser_ary_t *lines) +static void +parser_aset_script_lines_for(VALUE path, rb_parser_ary_t *lines) { VALUE hash, script_lines; ID script_lines_id; - if (NIL_P(path) || !lines || FIXNUM_P((VALUE)lines)) return; + if (NIL_P(path) || !lines) return; CONST_ID(script_lines_id, "SCRIPT_LINES__"); if (!rb_const_defined_at(rb_cObject, script_lines_id)) return; hash = rb_const_get_at(rb_cObject, script_lines_id); @@ -963,3 +1118,30 @@ rb_parser_aset_script_lines_for(VALUE path, rb_parser_ary_t *lines) script_lines = rb_parser_build_script_lines_from(lines); rb_hash_aset(hash, path, script_lines); } + +VALUE +rb_ruby_ast_new(const NODE *const root) +{ + rb_ast_t *ast; + VALUE ast_value = TypedData_Make_Struct(0, rb_ast_t, &ast_data_type, ast); +#ifdef UNIVERSAL_PARSER + ast->config = &rb_global_parser_config; +#endif + ast->body = (rb_ast_body_t){ + .root = root, + .frozen_string_literal = -1, + .coverage_enabled = -1, + .script_lines = NULL, + .line_count = 0, + }; + return ast_value; +} + +rb_ast_t * +rb_ruby_ast_data_get(VALUE ast_value) +{ + rb_ast_t *ast; + if (NIL_P(ast_value)) return NULL; + TypedData_Get_Struct(ast_value, rb_ast_t, &ast_data_type, ast); + return ast; +} |