diff options
Diffstat (limited to 'template/prelude.c.tmpl')
-rw-r--r-- | template/prelude.c.tmpl | 79 |
1 files changed, 63 insertions, 16 deletions
diff --git a/template/prelude.c.tmpl b/template/prelude.c.tmpl index dc0a143004..af493dfaca 100644 --- a/template/prelude.c.tmpl +++ b/template/prelude.c.tmpl @@ -141,37 +141,73 @@ COMPILER_WARNING_POP #define PRELUDE_NAME(n) rb_usascii_str_new_static(prelude_name##n, sizeof(prelude_name##n)-1) #define PRELUDE_CODE(n) rb_utf8_str_new_static(prelude_code##n.L0, sizeof(prelude_code##n)) -static rb_ast_t * -prelude_ast(VALUE name, VALUE code, int line) +static VALUE +prelude_ast_value(VALUE name, VALUE code, int line) { - rb_ast_t *ast = rb_parser_compile_string_path(rb_parser_new(), name, code, line); + rb_ast_t *ast; + VALUE ast_value = rb_parser_compile_string_path(rb_parser_new(), name, code, line); + ast = rb_ruby_ast_data_get(ast_value); if (!ast || !ast->body.root) { if (ast) rb_ast_dispose(ast); rb_exc_raise(rb_errinfo()); } - return ast; + return ast_value; +} + +static void +pm_prelude_load(pm_parse_result_t *result, VALUE name, VALUE code, int line) +{ + pm_options_line_set(&result->options, line); + VALUE error = pm_parse_string(result, code, name); + + if (!NIL_P(error)) { + pm_parse_result_free(result); + rb_exc_raise(error); + } } % end % if @builtin_count > 0 -#define PRELUDE_AST(n, name_str, start_line) \ +#define PRELUDE_VAST(n, name_str, start_line) \ (((sizeof(prelude_name<%='##'%><%=%>n) - prefix_len - 2) == namelen) && \ (strncmp(prelude_name<%='##'%><%=%>n + prefix_len, feature_name, namelen) == 0) ? \ - prelude_ast((name_str) = PRELUDE_NAME(n), PRELUDE_CODE(n), start_line) : 0) + prelude_ast_value((name_str) = PRELUDE_NAME(n), PRELUDE_CODE(n), start_line) : Qnil) + +VALUE +rb_builtin_ast_value(const char *feature_name, VALUE *name_str) +{ + const size_t prefix_len = rb_strlen_lit("<internal:"); + size_t namelen = strlen(feature_name); + VALUE ast_value = Qnil; -rb_ast_t * -rb_builtin_ast(const char *feature_name, VALUE *name_str) +% @preludes.each_value do |i, prelude, lines, sub, start_line| +% if sub + if (!NIL_P(ast_value = PRELUDE_VAST(<%=i%><%=%>, *name_str, <%=start_line%>))) return ast_value; +% end +% end + return ast_value; +} + +bool +pm_builtin_ast_value(pm_parse_result_t *result, const char *feature_name, VALUE *name_str) { const size_t prefix_len = rb_strlen_lit("<internal:"); size_t namelen = strlen(feature_name); - rb_ast_t *ast = 0; % @preludes.each_value do |i, prelude, lines, sub, start_line| % if sub - if ((ast = PRELUDE_AST(<%=i%><%=%>, *name_str, <%=start_line%>)) != 0) return ast; + if ( + (sizeof(prelude_name<%= i %>) - prefix_len - 2 == namelen) && + (strncmp(prelude_name<%= i %> + prefix_len, feature_name, namelen) == 0) + ) { + *name_str = PRELUDE_NAME(<%= i %>); + pm_prelude_load(result, *name_str, PRELUDE_CODE(<%= i %>), <%= start_line %>); + return true; + } % end % end - return ast; + + return false; } % end @@ -196,11 +232,22 @@ prelude_eval(VALUE code, VALUE name, int line) 0, /* int debug_level; */ }; - rb_ast_t *ast = prelude_ast(name, code, line); - rb_iseq_eval(rb_iseq_new_with_opt(&ast->body, name, name, Qnil, line, - NULL, 0, ISEQ_TYPE_TOP, &optimization, - Qnil)); - rb_ast_dispose(ast); + if (*rb_ruby_prism_ptr()) { + pm_parse_result_t result = { 0 }; + pm_prelude_load(&result, name, code, line); + rb_iseq_eval(pm_iseq_new_with_opt(&result.node, name, name, Qnil, line, + NULL, 0, ISEQ_TYPE_TOP, &optimization)); + pm_parse_result_free(&result); + } + else { + rb_ast_t *ast; + VALUE ast_value = prelude_ast_value(name, code, line); + ast = rb_ruby_ast_data_get(ast_value); + rb_iseq_eval(rb_iseq_new_with_opt(ast_value, name, name, Qnil, line, + NULL, 0, ISEQ_TYPE_TOP, &optimization, + Qnil)); + rb_ast_dispose(ast); + } } COMPILER_WARNING_POP |