Skip to content

Commit

Permalink
Make trivial interpolations like :($x) work
Browse files Browse the repository at this point in the history
Perhaps surprisingly this is a special case because there's no enclosing
expression.
  • Loading branch information
c42f committed Jul 22, 2024
1 parent eb721cb commit e586a37
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 10 deletions.
3 changes: 3 additions & 0 deletions src/macro_expansion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ end
# Expansion of quoted expressions
function collect_unquoted!(ctx, unquoted, ex, depth)
if kind(ex) == K"$" && depth == 0
# children(ex) is usually length 1, but for double interpolation it may
# be longer and the children may contain K"..." expressions. Wrapping
# in a tuple groups the arguments together correctly in those cases.
push!(unquoted, @ast ctx ex [K"tuple" children(ex)...])
else
inner_depth = kind(ex) == K"quote" ? depth + 1 :
Expand Down
15 changes: 11 additions & 4 deletions src/runtime.jl
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,6 @@ function _interpolate_ast(ctx::InterpolationContext, ex, depth)
end

function interpolate_ast(ex, values...)
if kind(ex) == K"$"
TODO(ex, "\$ in interpolate_ast")
end
# Construct graph for interpolation context. We inherit this from the macro
# context where possible by detecting it using __macro_ctx__. This feels
# hacky though.
Expand All @@ -88,7 +85,17 @@ function interpolate_ast(ex, values...)
# We must copy the AST into our context to use it as the source reference
# of generated expressions.
ex1 = copy_ast(ctx, ex)
_interpolate_ast(ctx, ex1, 0)
if kind(ex1) == K"$"
@assert length(values) == 1
vs = values[1]
if length(vs) > 1
# :($($(xs...))) where xs is more than length 1
throw(LoweringError(ex1, "More than one value in bare `\$` expression"))
end
_interpolated_value(ctx, ex1, only(vs))
else
_interpolate_ast(ctx, ex1, 0)
end
end

# Construct new bare module including only the "default names"
Expand Down
6 changes: 5 additions & 1 deletion test/demo.jl
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,11 @@ src = """
"""

src = """
x = :hi
begin
a = 1
xs = [:(a),]
x = :(:(\$(\$(xs...))))
end
"""

ex = parsestmt(SyntaxTree, src, filename="foo.jl")
Expand Down
4 changes: 2 additions & 2 deletions test/loops.jl
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@ let
end
""") == [2,4]

@test_throws JuliaLowering.LoweringError JuliaLowering.include_string(test_mod, """
@test_throws LoweringError JuliaLowering.include_string(test_mod, """
break
""")

@test_throws JuliaLowering.LoweringError JuliaLowering.include_string(test_mod, """
@test_throws LoweringError JuliaLowering.include_string(test_mod, """
continue
""")

Expand Down
30 changes: 30 additions & 0 deletions test/quoting.jl
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,16 @@ let
end
"""))

# Test that trivial interpolation without any nesting works.
ex = JuliaLowering.include_string(test_mod, """
let
x = 123
:(\$x)
end
""")
@test kind(ex) == K"Value"
@test ex.value == 123

# interpolations at multiple depths
ex = JuliaLowering.include_string(test_mod, """
let
Expand Down Expand Up @@ -102,4 +112,24 @@ ex2 = JuliaLowering.eval(test_mod, ex)
@test JuliaLowering.include_string(test_mod, ":x") isa Symbol
@test JuliaLowering.include_string(test_mod, ":(x)") isa SyntaxTree

# Double interpolation
ex = JuliaLowering.include_string(test_mod, """
let
args = (:(xxx),)
:(:(\$\$(args...)))
end
""")
Base.eval(test_mod, :(xxx = 111))
ex2 = JuliaLowering.eval(test_mod, ex)
@test kind(ex2) == K"Value"
@test ex2.value == 111

double_interp_ex = JuliaLowering.include_string(test_mod, """
let
args = (:(x), :(y))
:(:(\$\$(args...)))
end
""")
@test_throws LoweringError JuliaLowering.eval(test_mod, double_interp_ex)

end
4 changes: 2 additions & 2 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -292,12 +292,12 @@ end == [
]


@test_throws JuliaLowering.LoweringError JuliaLowering.include_string(test_mod, """
@test_throws LoweringError JuliaLowering.include_string(test_mod, """
macro mmm(a; b=2)
end
""")

@test_throws JuliaLowering.LoweringError JuliaLowering.include_string(test_mod, """
@test_throws LoweringError JuliaLowering.include_string(test_mod, """
macro A.b(ex)
end
""")
Expand Down
2 changes: 1 addition & 1 deletion test/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ using JuliaLowering:
Kind, SourceRef, SyntaxTree, NodeId,
makenode, makeleaf, setattr!, sethead!,
haschildren, numchildren, children,
@ast, flattened_provenance, showprov
@ast, flattened_provenance, showprov, LoweringError

function _ast_test_graph()
graph = SyntaxGraph()
Expand Down

0 comments on commit e586a37

Please sign in to comment.