Skip to content

Commit

Permalink
More flexibility in freezing parser world age
Browse files Browse the repository at this point in the history
This separates the decision about whether to freeze the parser world age
from Core.Compiler.parse. The builtin _apply_in_world allows this to be
done with more flexibility from outside (for example, one might want to
do some argument conversion in the current world before calling through
to a fixed world for the parser internals.
  • Loading branch information
c42f committed May 2, 2020
1 parent 76d7868 commit e8567db
Showing 1 changed file with 15 additions and 14 deletions.
29 changes: 15 additions & 14 deletions base/compiler/parsing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,33 @@ function fl_parse(text::Union{Core.SimpleVector,String},
end

function fl_parse(text::AbstractString, filename::AbstractString, offset, options)
# By default fl_parse is frozen in an early world, where conversion from
# String doesn't necessarily work. Use invokelatest to allow users to be
# able to pass AbstractString.
fl_parse(invokelatest(String, text), invokelatest(String, filename),
offset, options)
fl_parse(String(text), String(filename), offset, options)
end

_current_parser = nothing

"""
set_parser(func)
Swap the parser used for all juila code to the given `func`.
When installing a parser, it may be appropriate to freeze it to a given world
age:
```
let world = unsafe_load(cglobal(:jl_world_counter, Csize_t))
function your_parser_entry_point(text, filename, offset, options)
Core._apply_in_world(\$world, your_parser, (text, filename, offset, options))
end
end
```
!!! note
Experimental! May be removed at any time.
"""
function set_parser(func)
world = unsafe_load(cglobal(:jl_world_counter, Csize_t))
global _current_parser = (func,world)
global _parser = func
end

set_parser(fl_parse)
_parser = fl_parse

"""
parse(text, filename, offset, options)
Expand All @@ -55,8 +59,5 @@ as it's defined.
Experimental! May be removed at any time.
"""
function parse(text, filename, offset, options)
# In future it might be nice to wrap up this (parser,world) and
# _apply_in_world pattern into a FrozenWorld type which inference knows about.
parser,world = _current_parser
Core._apply_in_world(world, parser, (text, filename, offset, options))
_parser(text, filename, offset, options)
end

0 comments on commit e8567db

Please sign in to comment.