@@ -48,22 +48,9 @@ _syntax_list(ctx::ExprInterpolationContext) = Any[]
4848_interp_makenode (ctx:: InterpolationContext , ex, args) = makenode (ctx, ex, ex, args)
4949_interp_makenode (ctx:: ExprInterpolationContext , ex, args) = Expr ((ex:: Expr ). head, args... )
5050
51- _to_syntax_tree (ex:: SyntaxTree ) = ex
52- _to_syntax_tree (@nospecialize (ex)) = expr_to_syntaxtree (ex)
53-
54-
55- function _contains_active_interp (ex, depth)
56- k = _interp_kind (ex)
57- if k == K " $" && depth == 0
58- return true
59- elseif _numchildren (ex) == 0
60- return false
61- end
62- inner_depth = k == K " quote" ? depth + 1 :
63- k == K " $" ? depth - 1 :
64- depth
65- return any (_contains_active_interp (c, inner_depth) for c in _children (ex))
66- end
51+ _is_leaf (ex:: SyntaxTree ) = is_leaf (ex)
52+ _is_leaf (ex:: Expr ) = false
53+ _is_leaf (@nospecialize (ex)) = true
6754
6855# Produce interpolated node for `$x` syntax
6956function _interpolated_value (ctx:: InterpolationContext , srcref, ex)
@@ -86,22 +73,17 @@ function _interpolated_value(::ExprInterpolationContext, _, ex)
8673 ex
8774end
8875
89- function copy_ast (:: ExprInterpolationContext , @nospecialize (ex))
90- @ccall (jl_copy_ast (ex:: Any ):: Any )
76+ function _interpolate_ast (ctx:: ExprInterpolationContext , ex:: QuoteNode , depth)
77+ out = _interpolate_ast (ctx, Expr (:inert , ex. value), depth)
78+ QuoteNode (only (out. args))
9179end
9280
93- function _interpolate_ast (ctx, ex, depth)
94- if ctx. current_index[] > length (ctx. values) || ! _contains_active_interp (ex, depth)
95- return ex
96- end
97-
98- # We have an interpolation deeper in the tree somewhere - expand to an
99- # expression which performs the interpolation.
81+ function _interpolate_ast (ctx, @nospecialize (ex), depth)
82+ _is_leaf (ex) && return ex
10083 k = _interp_kind (ex)
10184 inner_depth = k == K " quote" ? depth + 1 :
10285 k == K " $" ? depth - 1 :
10386 depth
104-
10587 expanded_children = _syntax_list (ctx)
10688
10789 for e in _children (ex)
@@ -120,7 +102,10 @@ function _interpolate_ast(ctx, ex, depth)
120102 _interp_makenode (ctx, ex, expanded_children)
121103end
122104
123- function _setup_interpolation (:: Type{SyntaxTree} , ex, values)
105+ # Produced by expanding K"quote". Must create a copy of the AST. Note that
106+ # wrapping `ex` in an extra node handles the edge case where the root `ex` is
107+ # `$` (our recursion is one step removed due to forms like `($ a b)`.)
108+ function interpolate_ast (:: Type{SyntaxTree} , ex:: SyntaxTree , values... )
124109 # Construct graph for interpolation context. We inherit this from the macro
125110 # context where possible by detecting it using __macro_ctx__. This feels
126111 # hacky though.
@@ -137,34 +122,32 @@ function _setup_interpolation(::Type{SyntaxTree}, ex, values)
137122 end
138123 end
139124 if isnothing (graph)
140- graph = ensure_attributes (SyntaxGraph (), kind= Kind, syntax_flags= UInt16, source= SourceAttrType,
141- value= Any, name_val= String, scope_layer= LayerId)
125+ graph = ensure_attributes (
126+ SyntaxGraph (), kind= Kind, syntax_flags= UInt16, source= SourceAttrType,
127+ value= Any, name_val= String, scope_layer= LayerId)
142128 end
143129 ctx = InterpolationContext (graph, values, Ref (1 ))
144- return ctx
145- end
146130
147- function _setup_interpolation (:: Type{Expr} , ex, values)
148- return ExprInterpolationContext (values, Ref (1 ))
131+ # We must copy the AST into our context to use it as the source reference of
132+ # generated expressions.
133+ ex1 = copy_ast (ctx, ex)
134+ out = _interpolate_ast (ctx, @ast (ctx, ex1, [K " None" ex1]), 0 )
135+ length (children (out)) === 1 || throw (
136+ LoweringError (ex1, " More than one value in bare `\$ ` expression" ))
137+ return only (children (out))
149138end
150139
151- function interpolate_ast (:: Type{T} , ex, values... ) where {T}
152- ctx = _setup_interpolation (T, ex, values)
153-
154- # We must copy the AST into our context to use it as the source reference
155- # of generated expressions (and in the Expr case at least, to avoid mutation)
156- ex1 = copy_ast (ctx, ex)
157- if _interp_kind (ex1) == K " $"
158- @assert length (values) == 1
159- vs = values[1 ]
160- if length (vs) > 1
161- # :($($(xs...))) where xs is more than length 1
162- throw (LoweringError (_to_syntax_tree (ex1),
163- " More than one value in bare `\$ ` expression" ))
140+ function interpolate_ast (:: Type{Expr} , @nospecialize (ex), values... )
141+ ctx = ExprInterpolationContext (values, Ref (1 ))
142+ if ex isa Expr && ex. head === :$
143+ @assert length (values) === 1
144+ if length (ex. args) != = 1
145+ throw (LoweringError (
146+ expr_to_syntaxtree (ex), " More than one value in bare `\$ ` expression" ))
164147 end
165- _interpolated_value (ctx, ex1, only (vs) )
148+ only (values[ 1 ] )
166149 else
167- _interpolate_ast (ctx, ex1 , 0 )
150+ _interpolate_ast (ctx, ex , 0 )
168151 end
169152end
170153
0 commit comments