Skip to content

Commit

Permalink
Remove flisp code from jl_parse_eval_all
Browse files Browse the repository at this point in the history
This makes the top level parse-lower-eval loop independent of
flisp internals.
  • Loading branch information
c42f committed Mar 30, 2020
1 parent cd5e60d commit 49626e7
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 121 deletions.
2 changes: 1 addition & 1 deletion base/loading.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1083,7 +1083,7 @@ actually evaluates `mapexpr(expr)`. If it is omitted, `mapexpr` defaults to [`i
"""
function include_string(mapexpr::Function, m::Module, txt_::AbstractString, fname::AbstractString="string")
txt = String(txt_)
ccall(:jl_load_rewrite_file_string, Any, (Any, Any, Any, Any),
ccall(:jl_parse_eval_all, Any, (Any, Any, Any, Any),
m, txt, String(fname), mapexpr === identity ? nothing : mapexpr)
end

Expand Down
109 changes: 2 additions & 107 deletions src/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -783,6 +783,8 @@ typedef enum {
JL_PARSE_TOPLEVEL = 3,
} jl_parse_rule_t;

// Parse string `content` starting at byte offset `start_pos` attributing it to
// `filename`. Return an svec of (parse_result, final_pos)
JL_DLLEXPORT jl_value_t *jl_fl_parse(const char *content, size_t content_len,
const char *filename, size_t filename_len,
int start_pos, jl_parse_rule_t rule)
Expand Down Expand Up @@ -856,113 +858,6 @@ JL_DLLEXPORT jl_value_t *jl_parse_input_line(const char *str, size_t len,
return jl_parse_all(str, len, filename, filename_len);
}

// Parse a string `text` at top level, attributing source locations to
// `filename`. Each expression is optionally modified by `mapexpr` (if
// non-NULL) before evaluating in module `inmodule`.
jl_value_t *jl_parse_eval_all(jl_module_t *inmodule, jl_value_t *text,
jl_value_t *filename, jl_value_t *mapexpr)
{
jl_ptls_t ptls = jl_get_ptls_states();
if (ptls->in_pure_callback)
jl_error("cannot use include inside a generated function");
jl_ast_context_t *ctx = jl_ast_ctx_enter();
fl_context_t *fl_ctx = &ctx->fl;
value_t f, ast, expression;
f = cvalue_static_cstrn(fl_ctx, jl_string_data(filename), jl_string_len(filename));
fl_gc_handle(fl_ctx, &f);
{
JL_TIMING(PARSING);
value_t t = cvalue_static_cstrn(fl_ctx, jl_string_data(text),
jl_string_len(text));
fl_gc_handle(fl_ctx, &t);
ast = fl_applyn(fl_ctx, 2, symbol_value(symbol(fl_ctx, "jl-parse-all")), t, f);
fl_free_gc_handles(fl_ctx, 1);
}
fl_free_gc_handles(fl_ctx, 1);
if (ast == fl_ctx->F) {
jl_ast_ctx_leave(ctx);
jl_errorf("could not open file %s", jl_string_data(filename));
}
fl_gc_handle(fl_ctx, &ast);
fl_gc_handle(fl_ctx, &expression);

int last_lineno = jl_lineno;
const char *last_filename = jl_filename;
size_t last_age = jl_get_ptls_states()->world_age;
int lineno = 0;
jl_lineno = 0;
jl_filename = jl_string_data(filename);
jl_module_t *old_module = ctx->module;
ctx->module = inmodule;
jl_value_t *form = NULL;
jl_value_t *result = jl_nothing;
int err = 0;
JL_GC_PUSH2(&form, &result);
JL_TRY {
assert(iscons(ast) && car_(ast) == symbol(fl_ctx, "toplevel"));
ast = cdr_(ast);
while (iscons(ast)) {
expression = car_(ast);
{
JL_TIMING(LOWERING);
if (fl_ctx->T == fl_applyn(fl_ctx, 1, symbol_value(symbol(fl_ctx, "contains-macrocall")), expression)) {
form = scm_to_julia(fl_ctx, expression, inmodule);
if (mapexpr)
form = jl_call1(mapexpr, form);
form = jl_expand_macros(form, inmodule, NULL, 0);
expression = julia_to_scm(fl_ctx, form);
}
else if (mapexpr) {
form = scm_to_julia(fl_ctx, expression, inmodule);
form = jl_call1(mapexpr, form);
expression = julia_to_scm(fl_ctx, form);
}
// expand non-final expressions in statement position (value unused)
expression =
fl_applyn(fl_ctx, 4,
symbol_value(symbol(fl_ctx, "jl-expand-to-thunk-warn")),
expression, symbol(fl_ctx, jl_string_data(filename)),
fixnum(lineno), iscons(cdr_(ast)) ? fl_ctx->T : fl_ctx->F);
}
jl_get_ptls_states()->world_age = jl_world_counter;
form = scm_to_julia(fl_ctx, expression, inmodule);
JL_SIGATOMIC_END();
jl_get_ptls_states()->world_age = jl_world_counter;
if (jl_is_linenode(form)) {
lineno = jl_linenode_line(form);
jl_lineno = lineno;
}
else {
result = jl_toplevel_eval_flex(inmodule, form, 1, 1);
}
JL_SIGATOMIC_BEGIN();
ast = cdr_(ast);
}
}
JL_CATCH {
form = filename;
result = jl_box_long(jl_lineno);
err = 1;
goto finally; // skip jl_restore_excstack
}
finally:
jl_get_ptls_states()->world_age = last_age;
jl_lineno = last_lineno;
jl_filename = last_filename;
fl_free_gc_handles(fl_ctx, 2);
ctx->module = old_module;
jl_ast_ctx_leave(ctx);
if (err) {
if (jl_loaderror_type == NULL)
jl_rethrow();
else
jl_rethrow_other(jl_new_struct(jl_loaderror_type, form, result,
jl_current_exception()));
}
JL_GC_POP();
return result;
}

// returns either an expression or a thunk
jl_value_t *jl_call_scm_on_ast(const char *funcname, jl_value_t *expr, jl_module_t *inmodule)
{
Expand Down
2 changes: 0 additions & 2 deletions src/julia_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -473,8 +473,6 @@ jl_array_t *jl_get_loaded_modules(void);
jl_value_t *jl_toplevel_eval_flex(jl_module_t *m, jl_value_t *e, int fast, int expanded);

jl_value_t *jl_eval_global_var(jl_module_t *m JL_PROPAGATES_ROOT, jl_sym_t *e);
jl_value_t *jl_parse_eval_all(jl_module_t *inmodule, jl_value_t *text,
jl_value_t *filename, jl_value_t *mapexpr);
jl_value_t *jl_interpret_toplevel_thunk(jl_module_t *m, jl_code_info_t *src);
jl_value_t *jl_interpret_toplevel_expr_in(jl_module_t *m, jl_value_t *e,
jl_code_info_t *src,
Expand Down
78 changes: 67 additions & 11 deletions src/toplevel.c
Original file line number Diff line number Diff line change
Expand Up @@ -869,19 +869,75 @@ JL_DLLEXPORT jl_value_t *jl_infer_thunk(jl_code_info_t *thk, jl_module_t *m)
//------------------------------------------------------------------------------
// Code loading: combined parse+eval for include() and include_string()

// Parse julia code from the string `text`, attributing it to `filename`. Eval
// the resulting statements into `module` after applying `mapexpr` to each one
// (if not one of NULL or nothing).
JL_DLLEXPORT jl_value_t *jl_load_rewrite_file_string(jl_module_t *module,
jl_value_t *text,
jl_value_t *filename,
jl_value_t *mapexpr)
// Parse julia code from the string `text` at top level, attributing it to
// `filename`. Each resulting top level expression is optionally transformed by
// `mapexpr` (if not nothing) before being lowered and evaluated in module
// `module`.
JL_DLLEXPORT jl_value_t *jl_parse_eval_all(jl_module_t *module, jl_value_t *text,
jl_value_t *filename, jl_value_t *mapexpr)
{
if (!jl_is_string(text) || !jl_is_string(filename)) {
jl_errorf("Expected `String`s for `text` and `filename`");
}
return jl_parse_eval_all(module, text, filename,
mapexpr == jl_nothing ? NULL : mapexpr);
jl_ptls_t ptls = jl_get_ptls_states();
if (ptls->in_pure_callback)
jl_error("cannot use include inside a generated function");

jl_value_t *result = jl_nothing;
jl_value_t *ast = NULL;
jl_value_t *expression = NULL;
JL_GC_PUSH3(&ast, &result, &expression);

ast = jl_parse_all(jl_string_data(text), jl_string_len(text),
jl_string_data(filename), jl_string_len(filename));
if (!jl_is_expr(ast) || ((jl_expr_t*)ast)->head != toplevel_sym) {
jl_errorf("jl_parse_all() must generate a top level expression");
}

int last_lineno = jl_lineno;
const char *last_filename = jl_filename;
size_t last_age = jl_get_ptls_states()->world_age;
int lineno = 0;
jl_lineno = 0;
jl_filename = jl_string_data(filename);
int err = 0;

JL_TRY {
for (size_t i = 0; i < jl_expr_nargs(ast); i++) {
expression = jl_exprarg(ast, i);
if (jl_is_linenode(expression)) {
// filename is already set above.
lineno = jl_linenode_line(expression);
jl_lineno = lineno;
continue;
}
if (mapexpr != jl_nothing) {
expression = jl_call1(mapexpr, expression);
}
expression = jl_expand_with_loc_warn(expression, module,
jl_string_data(filename), lineno);
jl_get_ptls_states()->world_age = jl_world_counter;
result = jl_toplevel_eval_flex(module, expression, 1, 1);
}
}
JL_CATCH {
result = jl_box_long(jl_lineno); // (ab)use result to root error line
err = 1;
goto finally; // skip jl_restore_excstack
}
finally:
jl_get_ptls_states()->world_age = last_age;
jl_lineno = last_lineno;
jl_filename = last_filename;
if (err) {
if (jl_loaderror_type == NULL)
jl_rethrow();
else
jl_rethrow_other(jl_new_struct(jl_loaderror_type, filename, result,
jl_current_exception()));
}
JL_GC_POP();
return result;
}

// Synchronously read content of entire file into a julia String
Expand Down Expand Up @@ -910,7 +966,7 @@ JL_DLLEXPORT jl_value_t *jl_load_rewrite(jl_module_t *module,
{
jl_value_t *text = jl_file_content_as_string(filename);
JL_GC_PUSH1(&text);
jl_value_t *result = jl_load_rewrite_file_string(module, text, filename, mapexpr);
jl_value_t *result = jl_parse_eval_all(module, text, filename, mapexpr);
JL_GC_POP();
return result;
}
Expand Down Expand Up @@ -938,7 +994,7 @@ JL_DLLEXPORT jl_value_t *jl_load_file_string(const char *text, size_t len,
JL_GC_PUSH2(&text_, &filename_);
text_ = jl_pchar_to_string(text, len);
filename_ = jl_cstr_to_string(filename);
jl_value_t *result = jl_load_rewrite_file_string(module, text_, filename_, jl_nothing);
jl_value_t *result = jl_parse_eval_all(module, text_, filename_, jl_nothing);
JL_GC_POP();
return result;
}
Expand Down

0 comments on commit 49626e7

Please sign in to comment.