Skip to content

Commit 786d0d8

Browse files
authored
add parseatom and parseall (#724)
1 parent 93b5458 commit 786d0d8

File tree

4 files changed

+106
-1
lines changed

4 files changed

+106
-1
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "Compat"
22
uuid = "34da2185-b29b-5c13-b0c7-acf172513d20"
3-
version = "3.19.0"
3+
version = "3.20.0"
44

55
[deps]
66
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,13 @@ changes in `julia`.
5555

5656
## Supported features
5757

58+
* `Compat.parseatom(text::AbstractString, pos::Integer; filename="none")` parses a single
59+
atom from `text` starting at index `pos`. Returns a `Tuple` consisting of the
60+
parsed expression and the index to resume parsing from. ([#35243]) (since Compat 3.20)
61+
62+
* `Compat.parseall(text::AbstractString; filename="none")` parses the whole string `text`
63+
and returns the parsed expression. ([#35243]) (since Compat 3.20)
64+
5865
* `mul!(C, A, B, alpha, beta)` now performs in-place multiply add ([#29634]). (since Compat 3.19).
5966

6067
* `reinterpret(reshape, T, a::AbstractArray{S})` reinterprets `a` to have eltype `T` while
@@ -211,3 +218,4 @@ Note that you should specify the correct minimum version for `Compat` in the
211218
[#37517]: https://github.com/JuliaLang/julia/pull/37517
212219
[#37559]: https://github.com/JuliaLang/julia/pull/37559
213220
[#29634]: https://github.com/JuliaLang/julia/pull/29634
221+
[#35243]: https://github.com/JuliaLang/julia/pull/35243

src/Compat.jl

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -762,6 +762,50 @@ if VERSION < v"1.3.0-alpha.115"
762762
end
763763
end
764764

765+
# https://github.com/JuliaLang/julia/pull/35243
766+
if VERSION < v"1.6.0-DEV.15"
767+
_replace_filename(@nospecialize(x), filename, line_offset=0) = x
768+
function _replace_filename(x::LineNumberNode, filename, line_offset=0)
769+
return LineNumberNode(x.line + line_offset, filename)
770+
end
771+
function _replace_filename(ex::Expr, filename, line_offset=0)
772+
return Expr(
773+
ex.head,
774+
Any[_replace_filename(i, filename, line_offset) for i in ex.args]...,
775+
)
776+
end
777+
778+
function parseatom(text::AbstractString, pos::Integer; filename="none")
779+
ex, i = Meta.parse(text, pos, greedy=false)
780+
return _replace_filename(ex, Symbol(filename)), i
781+
end
782+
783+
function _skip_newlines(text, line, i)
784+
while i <= lastindex(text) && isspace(text[i])
785+
line += text[i] == '\n'
786+
i = nextind(text, i)
787+
end
788+
return line, i
789+
end
790+
791+
function parseall(text::AbstractString; filename="none")
792+
filename = Symbol(filename)
793+
ex = Expr(:toplevel)
794+
line, prev_i = _skip_newlines(text, 1, firstindex(text))
795+
ex_n, i = Meta.parse(text, prev_i)
796+
while ex_n !== nothing
797+
push!(ex.args, LineNumberNode(line, filename))
798+
push!(ex.args, _replace_filename(ex_n, filename, line-1))
799+
line += count(==('\n'), SubString(text, prev_i:prevind(text, i)))
800+
line, prev_i = _skip_newlines(text, line, i)
801+
ex_n, i = Meta.parse(text, prev_i)
802+
end
803+
return ex
804+
end
805+
else
806+
using .Meta: parseatom, parseall
807+
end
808+
765809
include("iterators.jl")
766810
include("deprecated.jl")
767811

test/runtests.jl

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,59 @@ end
698698
@test Cmut == mul!(Cmut, B, x, alpha, beta) ((B * x * alpha) + (C * beta))
699699
end
700700

701+
# https://github.com/JuliaLang/julia/pull/35243
702+
@testset "parseatom and parseall" begin
703+
@test Compat.parseatom(raw"foo$(@bar)baz", 5; filename="foo") ==
704+
(Expr(:macrocall, Symbol("@bar"), LineNumberNode(1, :foo)), 11)
705+
706+
ex = Compat.parseall(
707+
raw"""
708+
begin
709+
@a b
710+
@c() + 1
711+
end
712+
""";
713+
filename="foo",
714+
)
715+
@test ex == Expr(:toplevel,
716+
LineNumberNode(1, :foo),
717+
Expr(:block,
718+
LineNumberNode(2, :foo),
719+
Expr(:macrocall, Symbol("@a"), LineNumberNode(2, :foo), :b),
720+
LineNumberNode(3, :foo),
721+
Expr(:call,
722+
:+,
723+
Expr(:macrocall, Symbol("@c"), LineNumberNode(3, :foo)),
724+
1,
725+
),
726+
),
727+
)
728+
729+
ex = Compat.parseall(
730+
raw"""
731+
732+
begin a = 1 end
733+
734+
begin
735+
b = 2
736+
end
737+
""";
738+
filename="foo",
739+
)
740+
@test ex == Expr(:toplevel,
741+
LineNumberNode(2, :foo),
742+
Expr(:block,
743+
LineNumberNode(2, :foo),
744+
:(a = 1),
745+
),
746+
LineNumberNode(4, :foo),
747+
Expr(:block,
748+
LineNumberNode(5, :foo),
749+
:(b = 2),
750+
),
751+
)
752+
end
753+
701754
include("iterators.jl")
702755

703756
nothing

0 commit comments

Comments
 (0)