Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions base/boot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1015,6 +1015,21 @@ _parse = nothing

_setparser!(parser) = setglobal!(Core, :_parse, parser)


# Binding for the julia lowerer, called as
#
# Core._lower(expr, module, filename, linenum)
#
# Lower Julia code from the buffer `expr`, attributing
# it to `filename`. `expr` must be the result of `_parse`
#
# `_lower` must return an Expr with appropriate internals to be evaled
#
# The internal jl_expand_with_loc_warn will call into Core._lower if not `nothing`.
_lower = nothing

_setlowerer!(lowerer) = setglobal!(Core, :_lower, lowerer)

# support for deprecated uses of builtin functions
_apply(x...) = _apply_iterate(Main.Base.iterate, x...)
const _apply_pure = _apply
Expand Down
101 changes: 64 additions & 37 deletions src/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -1308,47 +1308,74 @@ JL_DLLEXPORT jl_value_t *jl_expand_with_loc_warn(jl_value_t *expr, jl_module_t *
{
JL_TIMING(LOWERING, LOWERING);
jl_timing_show_location(file, line, inmodule, JL_TIMING_DEFAULT_BLOCK);
jl_array_t *kwargs = NULL;
JL_GC_PUSH2(&expr, &kwargs);
expr = jl_copy_ast(expr);
expr = jl_expand_macros(expr, inmodule, NULL, 0, ~(size_t)0, 1);
jl_ast_context_t *ctx = jl_ast_ctx_enter(inmodule);
fl_context_t *fl_ctx = &ctx->fl;
value_t arg = julia_to_scm(fl_ctx, expr);
value_t e = fl_applyn(fl_ctx, 4, symbol_value(symbol(fl_ctx, "jl-expand-to-thunk-warn")), arg,
symbol(fl_ctx, file), fixnum(line), fl_ctx->F);
expr = scm_to_julia(fl_ctx, e, inmodule);
jl_ast_ctx_leave(ctx);
jl_sym_t *warn_sym = jl_symbol("warn");
if (jl_is_expr(expr) && ((jl_expr_t*)expr)->head == warn_sym) {
size_t nargs = jl_expr_nargs(expr);
for (int i = 0; i < nargs - 1; i++) {
jl_value_t *warning = jl_exprarg(expr, i);
size_t nargs = 0;
if (jl_is_expr(warning) && ((jl_expr_t*)warning)->head == warn_sym)
nargs = jl_expr_nargs(warning);
int kwargs_len = (int)nargs - 6;
if (nargs < 6 || kwargs_len % 2 != 0) {
jl_error("julia-logmsg: bad argument list - expected "
":warn level (symbol) group (symbol) id file line msg . kwargs");
}
jl_value_t *level = jl_exprarg(warning, 0);
jl_value_t *group = jl_exprarg(warning, 1);
jl_value_t *id = jl_exprarg(warning, 2);
jl_value_t *file = jl_exprarg(warning, 3);
jl_value_t *line = jl_exprarg(warning, 4);
jl_value_t *msg = jl_exprarg(warning, 5);
kwargs = jl_alloc_vec_any(kwargs_len);
for (int i = 0; i < kwargs_len; ++i) {
jl_array_ptr_set(kwargs, i, jl_exprarg(warning, i + 6));
jl_value_t *core_lower = NULL;
if (jl_core_module) {
core_lower = jl_get_global(jl_core_module, jl_symbol("_lower"));
}
if (!core_lower || core_lower == jl_nothing) {
// In bootstrap, directly call the builtin lowerer.
jl_array_t *kwargs = NULL;
JL_GC_PUSH2(&expr, &kwargs);
expr = jl_copy_ast(expr);
expr = jl_expand_macros(expr, inmodule, NULL, 0, ~(size_t)0, 1);
jl_ast_context_t *ctx = jl_ast_ctx_enter(inmodule);
fl_context_t *fl_ctx = &ctx->fl;
value_t arg = julia_to_scm(fl_ctx, expr);
value_t e = fl_applyn(fl_ctx, 4, symbol_value(symbol(fl_ctx, "jl-expand-to-thunk-warn")), arg,
symbol(fl_ctx, file), fixnum(line), fl_ctx->F);
expr = scm_to_julia(fl_ctx, e, inmodule);
jl_ast_ctx_leave(ctx);
jl_sym_t *warn_sym = jl_symbol("warn");
if (jl_is_expr(expr) && ((jl_expr_t*)expr)->head == warn_sym) {
size_t nargs = jl_expr_nargs(expr);
for (int i = 0; i < nargs - 1; i++) {
jl_value_t *warning = jl_exprarg(expr, i);
size_t nargs = 0;
if (jl_is_expr(warning) && ((jl_expr_t*)warning)->head == warn_sym)
nargs = jl_expr_nargs(warning);
int kwargs_len = (int)nargs - 6;
if (nargs < 6 || kwargs_len % 2 != 0) {
jl_error("julia-logmsg: bad argument list - expected "
":warn level (symbol) group (symbol) id file line msg . kwargs");
}
jl_value_t *level = jl_exprarg(warning, 0);
jl_value_t *group = jl_exprarg(warning, 1);
jl_value_t *id = jl_exprarg(warning, 2);
jl_value_t *file = jl_exprarg(warning, 3);
jl_value_t *line = jl_exprarg(warning, 4);
jl_value_t *msg = jl_exprarg(warning, 5);
kwargs = jl_alloc_vec_any(kwargs_len);
for (int i = 0; i < kwargs_len; ++i) {
jl_array_ptr_set(kwargs, i, jl_exprarg(warning, i + 6));
}
JL_TYPECHK(logmsg, long, level);
jl_log(jl_unbox_long(level), NULL, group, id, file, line, (jl_value_t*)kwargs, msg);
}
JL_TYPECHK(logmsg, long, level);
jl_log(jl_unbox_long(level), NULL, group, id, file, line, (jl_value_t*)kwargs, msg);
expr = jl_exprarg(expr, nargs - 1);
}
expr = jl_exprarg(expr, nargs - 1);
JL_GC_POP();
return expr;
}

jl_value_t **args;
JL_GC_PUSHARGS(args, 5);
args[0] = core_lower;
args[1] = expr;
args[2] = (jl_value_t*) inmodule;
jl_value_t *filename = NULL;
JL_GC_PUSH1(&filename);
filename = jl_cstr_to_string(file);
args[3] = filename;
JL_GC_POP();
return expr;
args[4] = jl_box_long(line);
jl_task_t *ct = jl_current_task;
size_t last_age = ct->world_age;
ct->world_age = jl_atomic_load_acquire(&jl_world_counter);
jl_value_t *result = jl_apply(args, 5);
ct->world_age = last_age;
JL_TYPECHK(parse, expr, result);
JL_GC_POP();
return result;
}

// expand in a context where the expression value is unused
Expand Down
2 changes: 1 addition & 1 deletion src/toplevel.c
Original file line number Diff line number Diff line change
Expand Up @@ -1128,7 +1128,7 @@ static jl_value_t *jl_parse_eval_all(jl_module_t *module, jl_value_t *text,
ast = jl_svecref(jl_parse(jl_string_data(text), jl_string_len(text),
filename, 1, 0, (jl_value_t*)jl_all_sym), 0);
if (!jl_is_expr(ast) || ((jl_expr_t*)ast)->head != jl_toplevel_sym) {
jl_errorf("jl_parse_all() must generate a top level expression");
jl_errorf("jl_parse() must generate a top level expression");
}

jl_task_t *ct = jl_current_task;
Expand Down
7 changes: 5 additions & 2 deletions stdlib/InteractiveUtils/src/macros.jl
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ in the current environment.
When using `@activate`, additional options for a component may be specified in
square brackets `@activate Compiler[:option1, :option]`

Currently `@activate Compiler` is the only available component that may be
Currently `Compiler`, `JuliaSyntax`, and `JuliaLowering` are the only available components that may be
activatived.

For `@activate Compiler`, the following options are available:
Expand All @@ -455,6 +455,9 @@ For `@activate Compiler`, the following options are available:
2. `:codegen` - Activate the compiler for internal codegen purposes. The new compiler
will be invoked whenever the runtime requests compilation.

For `@activate JuliaSyntax`, the following options are available:
1. `:for_lowering` - Activate JuliaSyntax such that it is compatible with JuliaLowering

`@activate Compiler` without options is equivalent to `@activate Compiler[:reflection]`.

"""
Expand All @@ -475,7 +478,7 @@ macro activate(what)
if !isa(Component, Symbol)
error("Usage Error: Component $Component is not a symbol")
end
allowed_components = (:Compiler,)
allowed_components = (:Compiler, :JuliaSyntax, :JuliaLowering)
if !(Component in allowed_components)
error("Usage Error: Component $Component is not recognized. Expected one of $allowed_components")
end
Expand Down
Loading