362
362
frame = prepare_thunk(mod::Module, expr::Expr)
363
363
364
364
Prepare `expr` for evaluation in `mod`. `expr` should be a "straightforward" expression,
365
- one that does not require special top-level handling (see [`JuliaInterpreter.prepare_toplevel `](@ref)).
365
+ one that does not require special top-level handling (see [`JuliaInterpreter.split_expressions `](@ref)).
366
366
"""
367
367
function prepare_thunk (mod:: Module , thunk:: Expr , recursive= false )
368
368
if isexpr (thunk, :thunk )
@@ -382,7 +382,7 @@ function prepare_thunk((mod, ex)::Tuple{Module,Expr})
382
382
if isexpr (lwr, :thunk )
383
383
return prepare_thunk (mod, lwr)
384
384
# elseif isexpr(lwr, :toplevel)
385
- # return prepare_toplevel !(frames, docexprs, lex, mod, lwr; extract_docexprs=extract_docexprs, filename=filename)
385
+ # return split_expressions !(frames, docexprs, lex, mod, lwr; extract_docexprs=extract_docexprs, filename=filename)
386
386
# elseif isa(lwr, Expr) && (lwr.head == :export || lwr.head == :using || lwr.head == :import)
387
387
# @show lwr
388
388
# push!(modexs, (mod, ex, lwr))
@@ -394,15 +394,20 @@ function prepare_thunk((mod, ex)::Tuple{Module,Expr})
394
394
end
395
395
396
396
"""
397
- modexs, docexprs = prepare_toplevel (mod::Module, expr::Expr; extract_docexprs=false)
397
+ modexs, docexprs = split_expressions (mod::Module, expr::Expr; extract_docexprs=false)
398
398
399
- Break `expr` into a list `modexs` of blocks to be successively executed at top level.
400
- This is used when `expr` defines new structs, new methods, or new modules .
399
+ Break `expr` into a list `modexs` of sequential blocks. This is often needed when `expr`
400
+ needs to be evaluated at top level .
401
401
402
- `modexs[i]` is a `(Module, Expr)` tuple. A prototype of how to use these is:
402
+ `modexs[i]` is a `(mod::Module, ex::Expr)` tuple, where `ex` is to be evaluated in `mod`.
403
+
404
+ # Toplevel evaluation
405
+
406
+ For code that defines new structs, new methods, or new macros, it can be important to evaluate
407
+ these expressions carefully:
403
408
404
409
stack = JuliaStackFrame[]
405
- for modex in modexs
410
+ for modex in modexs # or use `for (mod, ex) in modexs` to split the tuple
406
411
frame = JuliaInterpreter.prepare_thunk(modex)
407
412
while true
408
413
JuliaInterpreter.through_methoddef_or_done!(stack, frame) === nothing && break
@@ -412,21 +417,22 @@ This is used when `expr` defines new structs, new methods, or new modules.
412
417
The `while` loop here deserves some explanation. Occasionally, a frame may define new methods
413
418
(e.g., anonymous or local functions) and then call those methods. In such cases, running
414
419
the entire frame as a single block (e.g., with [`JuliaInterpreter.finish_and_return!`](@ref)
415
- can trigger "method is too new..." errors. Instead, this runs each frame, but returns to the caller
416
- after any new method is defined. When this loop is running at top level (e.g., in the REPL),
417
- this allows the world age to update and thus avoid "method is too new..." errors.
420
+ can trigger "method is too new..." errors. Instead, the approach above runs each frame,
421
+ but returns to the caller after any new method is defined. When this loop is running at
422
+ top level (e.g., in the REPL), this allows the world age to update and thus avoid
423
+ "method is too new..." errors.
418
424
419
- Putting the above nested loop inside a function defeats the entire purpose of
420
- `prepare_toplevel` . If necessary, run that loop as
425
+ Putting the above nested loop inside a function defeats its purpose, because inside a
426
+ compiled function the world age will not update . If necessary, use the following strategy:
421
427
422
428
Core.eval(somemodule, Expr(:toplevel, quote
423
429
body
424
430
))
425
431
426
- where `body` executes the loop plus any preparatory statements required to make the
432
+ where `body` contains the nested loop, plus any preparatory statements required to make the
427
433
necessary variables available at top level in `somemodule`.
428
434
"""
429
- function prepare_toplevel (mod:: Module , expr:: Expr ; filename= nothing , kwargs... )
435
+ function split_expressions (mod:: Module , expr:: Expr ; filename= nothing , kwargs... )
430
436
modexs = Tuple{Module,Expr}[]
431
437
docexprs = Dict {Module,Vector{Expr}} ()
432
438
if filename === nothing
@@ -437,7 +443,7 @@ function prepare_toplevel(mod::Module, expr::Expr; filename=nothing, kwargs...)
437
443
filename= " toplevel"
438
444
end
439
445
end
440
- return prepare_toplevel ! (modexs, docexprs, mod, expr; filename= filename, kwargs... )
446
+ return split_expressions ! (modexs, docexprs, mod, expr; filename= filename, kwargs... )
441
447
end
442
448
443
449
"""
@@ -459,18 +465,18 @@ function isdocexpr(ex)
459
465
return false
460
466
end
461
467
462
- prepare_toplevel ! (modexs, docexprs, mod:: Module , ex:: Expr ; kwargs... ) =
463
- prepare_toplevel ! (modexs, docexprs, Expr (:block ), mod, ex; kwargs... )
468
+ split_expressions ! (modexs, docexprs, mod:: Module , ex:: Expr ; kwargs... ) =
469
+ split_expressions ! (modexs, docexprs, Expr (:block ), mod, ex; kwargs... )
464
470
465
- function prepare_toplevel ! (modexs, docexprs, lex:: Expr , mod:: Module , ex:: Expr ; extract_docexprs= false , filename= " toplevel" )
471
+ function split_expressions ! (modexs, docexprs, lex:: Expr , mod:: Module , ex:: Expr ; extract_docexprs= false , filename= " toplevel" )
466
472
# lex is the expression we'll lower; it will accumulate LineNumberNodes and a
467
473
# single top-level expression. We split blocks, module defs, etc.
468
474
if ex. head == :toplevel || ex. head == :block
469
- prepare_toplevel ! (modexs, docexprs, lex, mod, ex. args; extract_docexprs= extract_docexprs, filename= filename)
475
+ split_expressions ! (modexs, docexprs, lex, mod, ex. args; extract_docexprs= extract_docexprs, filename= filename)
470
476
elseif ex. head == :module
471
477
modname = ex. args[2 ]:: Symbol
472
478
newmod = isdefined (mod, modname) ? getfield (mod, modname) : Core. eval (mod, :(module $ modname end ))
473
- prepare_toplevel ! (modexs, docexprs, lex, newmod, ex. args[3 ]; extract_docexprs= extract_docexprs, filename= filename)
479
+ split_expressions ! (modexs, docexprs, lex, newmod, ex. args[3 ]; extract_docexprs= extract_docexprs, filename= filename)
474
480
elseif extract_docexprs && isdocexpr (ex)
475
481
docexs = get (docexprs, mod, nothing )
476
482
if docexs === nothing
@@ -479,7 +485,7 @@ function prepare_toplevel!(modexs, docexprs, lex::Expr, mod::Module, ex::Expr; e
479
485
push! (docexs, ex)
480
486
body = ex. args[4 ]
481
487
if isa (body, Expr) && body. head != :call
482
- prepare_toplevel ! (modexs, docexprs, lex, mod, body; extract_docexprs= extract_docexprs, filename= filename)
488
+ split_expressions ! (modexs, docexprs, lex, mod, body; extract_docexprs= extract_docexprs, filename= filename)
483
489
end
484
490
else
485
491
if isempty (lex. args)
@@ -492,10 +498,10 @@ function prepare_toplevel!(modexs, docexprs, lex::Expr, mod::Module, ex::Expr; e
492
498
return modexs, docexprs
493
499
end
494
500
495
- function prepare_toplevel ! (frames, docexprs, lex, mod:: Module , args:: Vector{Any} ; filename= " toplevel" , kwargs... )
501
+ function split_expressions ! (frames, docexprs, lex, mod:: Module , args:: Vector{Any} ; filename= " toplevel" , kwargs... )
496
502
for a in args
497
503
if isa (a, Expr)
498
- prepare_toplevel ! (frames, docexprs, lex, mod, a; filename= filename, kwargs... )
504
+ split_expressions ! (frames, docexprs, lex, mod, a; filename= filename, kwargs... )
499
505
elseif isa (a, LineNumberNode)
500
506
if a. file === nothing # happens with toplevel expressions on Julia 1.2
501
507
push! (lex. args, LineNumberNode (a. line, Symbol (filename)))
0 commit comments