Skip to content

Commit

Permalink
Neaten up Meta.parse implementation
Browse files Browse the repository at this point in the history
Add parseatom() and parseall()

TODO: integration with the other PR which addresses this
  • Loading branch information
c42f committed Apr 15, 2020
1 parent a7c6fe8 commit 1e42060
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 14 deletions.
5 changes: 1 addition & 4 deletions base/client.jl
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,7 @@ function eval_user_input(errio, @nospecialize(ast), show_value::Bool)
end

function _parse_input_line_core(s::String, filename::String)
JL_PARSE_ALL = 3
ex,_ = ccall(:jl_parse, Any,
(Ptr{UInt8}, Csize_t, Ptr{UInt8}, Csize_t, Csize_t, Cint),
s, sizeof(s), filename, sizeof(filename), 0, JL_PARSE_ALL)
ex = Meta.parseall(s, filename=filename)
if ex isa Expr && ex.head === :toplevel
if isempty(ex.args)
return nothing
Expand Down
41 changes: 31 additions & 10 deletions base/meta.jl
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,24 @@ struct ParseError <: Exception
msg::AbstractString
end

function _jl_parse(text::AbstractString, filename::AbstractString,
pos::Integer, rule::Integer)
if pos < 1 || pos > ncodeunits(text) + 1
throw(BoundsError(text, pos))
end
# Technically only need pointers to UTF-8 buffers here. For now converting
# to a plain String is the easy way to ensure that.
filename = String(filename)
text = String(text)
# Call into the parser which can be replaced globally during bootstrap with
# jl_set_parser
ex,pos = ccall(:jl_parse, Any,
(Ptr{UInt8}, Csize_t, Ptr{UInt8}, Csize_t, Csize_t, Cint),
text, sizeof(text), filename, sizeof(filename), pos-1, rule)
# internally, pos is a zero-based byte offset - convert back.
ex, pos+1
end

"""
parse(str, start; greedy=true, raise=true, depwarn=true)
Expand All @@ -171,25 +189,17 @@ julia> Meta.parse("x = 3, y = 5", 5)
"""
function parse(str::AbstractString, pos::Integer; greedy::Bool=true, raise::Bool=true,
depwarn::Bool=true)
if pos < 1 || pos > ncodeunits(str) + 1
throw(BoundsError(str, pos))
end
filename = "none"
JL_PARSE_ATOM = 1
JL_PARSE_STATEMENT = 2
rule = greedy ? JL_PARSE_STATEMENT : JL_PARSE_ATOM
# For now, assume all parser warnings are depwarns
# TODO: remove parser-depwarn; parser no longer emits warnings.
ex, pos = with_logger(depwarn ? current_logger() : NullLogger()) do
ccall(:jl_parse, Any,
(Ptr{UInt8}, Csize_t, Ptr{UInt8}, Csize_t, Csize_t, Cint),
str, sizeof(str), filename, sizeof(filename), pos-1, rule)
end
ex, pos = _jl_parse(str, "none", pos, rule)
if raise && isa(ex,Expr) && ex.head === :error
throw(ParseError(ex.args[1]))
end
# internal pos is zero-based byte offset
return ex, pos+1
return ex, pos
end

"""
Expand Down Expand Up @@ -229,6 +239,17 @@ function parse(str::AbstractString; raise::Bool=true, depwarn::Bool=true)
return ex
end

function parseatom(text::AbstractString, pos::Integer; filename="none")
JL_PARSE_ATOM = 1
return _jl_parse(text, filename, pos, JL_PARSE_ATOM)
end

function parseall(text::AbstractString; filename="none")
JL_PARSE_ALL = 3
ex,_ = _jl_parse(text, filename, 1, JL_PARSE_ALL)
return ex
end

"""
partially_inline!(code::Vector{Any}, slot_replacements::Vector{Any},
type_signature::Type{<:Tuple}, static_param_values::Vector{Any},
Expand Down

0 comments on commit 1e42060

Please sign in to comment.