Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add plugin interface to allow frontend replacement #35149

Closed
wants to merge 1 commit into from
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
2 changes: 1 addition & 1 deletion base/loading.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1123,7 +1123,7 @@ The optional first argument `mapexpr` can be used to transform the included code
it is evaluated: for each parsed expression `expr` in `path`, the `include` function
actually evaluates `mapexpr(expr)`. If it is omitted, `mapexpr` defaults to [`identity`](@ref).
"""
Base.include # defined in sysimg.jl
Base.include # defined in Base.jl

"""
evalfile(path::AbstractString, args::Vector{String}=String[])
Expand Down
2 changes: 1 addition & 1 deletion src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ FLAGS += -I$(LOCALBASE)/include
endif

RUNTIME_SRCS := \
jltypes gf typemap ast builtins module interpreter symbol \
jltypes gf typemap ast frontend builtins module interpreter symbol \
dlload sys init task array dump staticdata toplevel jl_uv datatype \
simplevector runtime_intrinsics precompile \
threading partr stackwalk gc gc-debug gc-pages gc-stacks method \
Expand Down
94 changes: 40 additions & 54 deletions src/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ static void jl_ast_ctx_leave(jl_ast_context_t *ctx) JL_NOTSAFEPOINT
JL_UNLOCK_NOGC(&flisp_lock);
}

void jl_init_frontend(void)
void jl_init_flisp(void)
{
jl_ptls_t ptls = jl_get_ptls_states();
if (jl_ast_ctx_using || jl_ast_ctx_freed)
Expand All @@ -322,7 +322,10 @@ void jl_init_frontend(void)
// To match the one in jl_ast_ctx_leave
JL_SIGATOMIC_BEGIN();
jl_ast_ctx_leave(&jl_ast_main_ctx);
}

void jl_init_common_symbols(void)
{
empty_sym = jl_symbol("");
call_sym = jl_symbol("call");
invoke_sym = jl_symbol("invoke");
Expand Down Expand Up @@ -400,7 +403,7 @@ JL_DLLEXPORT void jl_lisp_prompt(void)
// Make `--lisp` sigatomic in order to avoid triggering the sigint safepoint.
// We don't have our signal handler registered in that case anyway...
JL_SIGATOMIC_BEGIN();
jl_init_frontend();
jl_init_flisp();
jl_ast_context_t *ctx = jl_ast_ctx_enter();
JL_AST_PRESERVE_PUSH(ctx, old_roots, jl_main_module);
fl_context_t *fl_ctx = &ctx->fl;
Expand Down Expand Up @@ -773,9 +776,8 @@ static value_t julia_to_scm_(fl_context_t *fl_ctx, jl_value_t *v)
}

// parse an entire string like a file, reading multiple expressions
JL_DLLEXPORT jl_value_t *jl_parse_all(const char *str, size_t len, const char *filename, size_t filename_len)
jl_value_t *jl_fl_parse_all(const char *str, size_t len, const char *filename, size_t filename_len)
{
JL_TIMING(PARSING);
jl_ast_context_t *ctx = jl_ast_ctx_enter();
fl_context_t *fl_ctx = &ctx->fl;
value_t s = cvalue_static_cstrn(fl_ctx, str, len);
Expand All @@ -786,16 +788,10 @@ JL_DLLEXPORT jl_value_t *jl_parse_all(const char *str, size_t len, const char *f
return res;
}

// for backwards compat
JL_DLLEXPORT jl_value_t *jl_parse_input_line(const char *str, size_t len, const char *filename, size_t filename_len)
{
return jl_parse_all(str, len, filename, filename_len);
}

// this is for parsing one expression out of a string, keeping track of
// the current position.
JL_DLLEXPORT jl_value_t *jl_parse_string(const char *str, size_t len,
int pos0, int greedy)
jl_value_t *jl_fl_parse_string(const char *str, size_t len,
int pos0, int greedy)
{
JL_TIMING(PARSING);
if (pos0 < 0 || pos0 > len) {
Expand Down Expand Up @@ -826,10 +822,10 @@ JL_DLLEXPORT jl_value_t *jl_parse_string(const char *str, size_t len,
}

// parse and eval a whole file, possibly reading from a string (`content`)
jl_value_t *jl_parse_eval_all(const char *fname,
const char *content, size_t contentlen,
jl_module_t *inmodule,
jl_value_t *mapexpr)
jl_value_t *jl_fl_parse_eval_all(const char *fname,
const char *content, size_t contentlen,
jl_module_t *inmodule,
jl_value_t *mapexpr)
{
jl_ptls_t ptls = jl_get_ptls_states();
if (ptls->in_pure_callback)
Expand Down Expand Up @@ -933,19 +929,6 @@ jl_value_t *jl_parse_eval_all(const char *fname,
return result;
}

JL_DLLEXPORT jl_value_t *jl_load_rewrite_file_string(const char *text, size_t len,
char *filename, jl_module_t *inmodule,
jl_value_t *mapexpr)
{
return jl_parse_eval_all(filename, text, len, inmodule, mapexpr);
}

JL_DLLEXPORT jl_value_t *jl_load_file_string(const char *text, size_t len,
char *filename, jl_module_t *inmodule)
{
return jl_parse_eval_all(filename, text, len, inmodule, NULL);
}

// 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 Expand Up @@ -994,7 +977,7 @@ JL_DLLEXPORT jl_value_t *jl_copy_ast(jl_value_t *expr)
return expr;
}

JL_DLLEXPORT int jl_is_operator(char *sym)
int jl_fl_is_operator(char *sym)
{
jl_ast_context_t *ctx = jl_ast_ctx_enter();
fl_context_t *fl_ctx = &ctx->fl;
Expand All @@ -1003,7 +986,7 @@ JL_DLLEXPORT int jl_is_operator(char *sym)
return res;
}

JL_DLLEXPORT int jl_is_unary_operator(char *sym)
int jl_fl_is_unary_operator(char *sym)
{
jl_ast_context_t *ctx = jl_ast_ctx_enter();
fl_context_t *fl_ctx = &ctx->fl;
Expand All @@ -1012,7 +995,7 @@ JL_DLLEXPORT int jl_is_unary_operator(char *sym)
return res;
}

JL_DLLEXPORT int jl_is_unary_and_binary_operator(char *sym)
int jl_fl_is_unary_and_binary_operator(char *sym)
{
jl_ast_context_t *ctx = jl_ast_ctx_enter();
fl_context_t *fl_ctx = &ctx->fl;
Expand All @@ -1021,7 +1004,7 @@ JL_DLLEXPORT int jl_is_unary_and_binary_operator(char *sym)
return res;
}

JL_DLLEXPORT int jl_operator_precedence(char *sym)
int jl_fl_operator_precedence(char *sym)
{
jl_ast_context_t *ctx = jl_ast_ctx_enter();
fl_context_t *fl_ctx = &ctx->fl;
Expand Down Expand Up @@ -1190,9 +1173,8 @@ static jl_value_t *jl_expand_macros(jl_value_t *expr, jl_module_t *inmodule, str
return expr;
}

JL_DLLEXPORT jl_value_t *jl_macroexpand(jl_value_t *expr, jl_module_t *inmodule)
jl_value_t *jl_fl_macroexpand(jl_value_t *expr, jl_module_t *inmodule)
{
JL_TIMING(LOWERING);
JL_GC_PUSH1(&expr);
expr = jl_copy_ast(expr);
expr = jl_expand_macros(expr, inmodule, NULL, 0);
Expand All @@ -1201,9 +1183,8 @@ JL_DLLEXPORT jl_value_t *jl_macroexpand(jl_value_t *expr, jl_module_t *inmodule)
return expr;
}

JL_DLLEXPORT jl_value_t *jl_macroexpand1(jl_value_t *expr, jl_module_t *inmodule)
jl_value_t *jl_fl_macroexpand1(jl_value_t *expr, jl_module_t *inmodule)
{
JL_TIMING(LOWERING);
JL_GC_PUSH1(&expr);
expr = jl_copy_ast(expr);
expr = jl_expand_macros(expr, inmodule, NULL, 1);
Expand All @@ -1212,17 +1193,10 @@ JL_DLLEXPORT jl_value_t *jl_macroexpand1(jl_value_t *expr, jl_module_t *inmodule
return expr;
}

// Lower an expression tree into Julia's intermediate-representation.
JL_DLLEXPORT jl_value_t *jl_expand(jl_value_t *expr, jl_module_t *inmodule)
{
return jl_expand_with_loc(expr, inmodule, "none", 0);
}

// Lowering, with starting program location specified
JL_DLLEXPORT jl_value_t *jl_expand_with_loc(jl_value_t *expr, jl_module_t *inmodule,
const char *file, int line)
jl_value_t *jl_fl_expand_with_loc(jl_value_t *expr, jl_module_t *inmodule,
const char *file, int line)
{
JL_TIMING(LOWERING);
JL_GC_PUSH1(&expr);
expr = jl_copy_ast(expr);
expr = jl_expand_macros(expr, inmodule, NULL, 0);
Expand All @@ -1232,10 +1206,9 @@ JL_DLLEXPORT jl_value_t *jl_expand_with_loc(jl_value_t *expr, jl_module_t *inmod
}

// Same as the above, but printing warnings when applicable
JL_DLLEXPORT jl_value_t *jl_expand_with_loc_warn(jl_value_t *expr, jl_module_t *inmodule,
const char *file, int line)
jl_value_t *jl_fl_expand_with_loc_warn(jl_value_t *expr, jl_module_t *inmodule,
const char *file, int line)
{
JL_TIMING(LOWERING);
JL_GC_PUSH1(&expr);
expr = jl_copy_ast(expr);
expr = jl_expand_macros(expr, inmodule, NULL, 0);
Expand All @@ -1253,10 +1226,9 @@ JL_DLLEXPORT jl_value_t *jl_expand_with_loc_warn(jl_value_t *expr, jl_module_t *
}

// expand in a context where the expression value is unused
JL_DLLEXPORT jl_value_t *jl_expand_stmt_with_loc(jl_value_t *expr, jl_module_t *inmodule,
const char *file, int line)
jl_value_t *jl_fl_expand_stmt_with_loc(jl_value_t *expr, jl_module_t *inmodule,
const char *file, int line)
{
JL_TIMING(LOWERING);
JL_GC_PUSH1(&expr);
expr = jl_copy_ast(expr);
expr = jl_expand_macros(expr, inmodule, NULL, 0);
Expand All @@ -1265,9 +1237,23 @@ JL_DLLEXPORT jl_value_t *jl_expand_stmt_with_loc(jl_value_t *expr, jl_module_t *
return expr;
}

JL_DLLEXPORT jl_value_t *jl_expand_stmt(jl_value_t *expr, jl_module_t *inmodule)
jl_frontend_t jl_flisp_frontend(void)
{
return jl_expand_stmt_with_loc(expr, inmodule, "none", 0);
jl_frontend_t frontend = {
jl_fl_is_operator,
jl_fl_is_unary_operator,
jl_fl_is_unary_and_binary_operator,
jl_fl_operator_precedence,
jl_fl_parse_all,
jl_fl_parse_string,
jl_fl_macroexpand,
jl_fl_macroexpand1,
jl_fl_expand_with_loc,
jl_fl_expand_stmt_with_loc,
jl_fl_expand_with_loc_warn,
jl_fl_parse_eval_all
};
return frontend;
}

#ifdef __cplusplus
Expand Down
136 changes: 136 additions & 0 deletions src/frontend.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
#include "julia.h"
#include "julia_internal.h"

// Interface shim functions which call through to the functions from
// jl_frontend
static jl_frontend_t jl_frontend;

JL_DLLEXPORT void jl_set_frontend(jl_frontend_t frontend)
{
jl_frontend = frontend;
}

//--------------------------------------------------
// Syntactic queries

JL_DLLEXPORT int jl_is_operator(char *sym)
{
return jl_frontend.is_operator(sym);
}

JL_DLLEXPORT int jl_is_unary_operator(char *sym)
{
return jl_frontend.is_unary_operator(sym);
}

JL_DLLEXPORT int jl_is_unary_and_binary_operator(char *sym)
{
return jl_frontend.is_unary_and_binary_operator(sym);
}

JL_DLLEXPORT int jl_operator_precedence(char *sym)
{
return jl_frontend.operator_precedence(sym);
}

//--------------------------------------------------
// Parsing

JL_DLLEXPORT jl_value_t *jl_parse_all(const char *str, size_t len,
const char *filename, size_t filename_len)
{
JL_TIMING(PARSING);
return jl_frontend.parse_all(str, len, filename, filename_len);
}

JL_DLLEXPORT jl_value_t *jl_parse_string(const char *str, size_t len,
int pos0, int greedy)
{
JL_TIMING(PARSING);
return jl_frontend.parse_string(str, len, pos0, greedy);
}

//--------------------------------------------------
// Macro expansion

JL_DLLEXPORT jl_value_t *jl_macroexpand(jl_value_t *expr, jl_module_t *inmodule)
{
JL_TIMING(LOWERING);
return jl_frontend.macroexpand(expr, inmodule);
}

JL_DLLEXPORT jl_value_t *jl_macroexpand1(jl_value_t *expr, jl_module_t *inmodule)
{
JL_TIMING(LOWERING);
return jl_frontend.macroexpand1(expr, inmodule);
}


//--------------------------------------------------
// Code lowering / "expansion"

JL_DLLEXPORT jl_value_t *jl_expand_with_loc(jl_value_t *expr, jl_module_t *inmodule,
const char *file, int line)
{
JL_TIMING(LOWERING);
return jl_frontend.expand_with_loc(expr, inmodule, file, line);
}

JL_DLLEXPORT jl_value_t *jl_expand_stmt_with_loc(jl_value_t *expr, jl_module_t *inmodule,
const char *file, int line)
{
JL_TIMING(LOWERING);
return jl_frontend.expand_stmt_with_loc(expr, inmodule, file, line);
}

JL_DLLEXPORT jl_value_t *jl_expand_with_loc_warn(jl_value_t *expr, jl_module_t *inmodule,
const char *file, int line)
{
JL_TIMING(LOWERING);
return jl_frontend.expand_with_loc_warn(expr, inmodule, file, line);
}

JL_DLLEXPORT jl_value_t *jl_expand(jl_value_t *expr, jl_module_t *inmodule)
{
return jl_expand_with_loc(expr, inmodule, "none", 0);
}

JL_DLLEXPORT jl_value_t *jl_expand_stmt(jl_value_t *expr, jl_module_t *inmodule)
{
return jl_expand_stmt_with_loc(expr, inmodule, "none", 0);
}


//--------------------------------------------------
// Bundled parse-expand-eval functionality

// parse and eval a whole file, possibly reading from a string (`content`)
jl_value_t *jl_parse_eval_all(const char *fname,
const char *content, size_t contentlen,
jl_module_t *inmodule,
jl_value_t *mapexpr)
{
return jl_frontend.parse_eval_all(fname, content, contentlen, inmodule, mapexpr);
}

JL_DLLEXPORT jl_value_t *jl_load_rewrite_file_string(const char *text, size_t len,
char *filename, jl_module_t *inmodule,
jl_value_t *mapexpr)
{
return jl_parse_eval_all(filename, text, len, inmodule, mapexpr);
}

JL_DLLEXPORT jl_value_t *jl_load_file_string(const char *text, size_t len,
char *filename, jl_module_t *inmodule)
{
return jl_parse_eval_all(filename, text, len, inmodule, NULL);
}


//--------------------------------------------------
// Deprecated
JL_DLLEXPORT jl_value_t *jl_parse_input_line(const char *str, size_t len, const char *filename, size_t filename_len)
{
return jl_parse_all(str, len, filename, filename_len);
}

4 changes: 3 additions & 1 deletion src/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -732,7 +732,9 @@ void _julia_init(JL_IMAGE_SEARCH rel)
#ifdef ENABLE_TIMINGS
jl_root_task->timing_stack = jl_root_timing;
#endif
jl_init_frontend();
jl_init_common_symbols();
jl_init_flisp();
jl_set_frontend(jl_flisp_frontend());
jl_init_serializer();

if (!jl_options.image_file) {
Expand Down
Loading