@@ -126,48 +126,53 @@ function _append_nodeids!(graph::SyntaxGraph, ids::Vector{NodeId}, vals::SyntaxL
126126 append! (ids, vals. ids)
127127end
128128
129- function makeleaf (graph:: SyntaxGraph , srcref, proto; attrs... )
129+ # TODO : "proto", if SyntaxTree, is rarely different from srcref. reorganize to:
130+ # newnode/newleaf(ctx, srcref, k::Kind[, attrs])
131+ # makenode/makeleaf(ctx, old::SyntaxTree[, attrs])
132+
133+ function makeleaf (graph:: SyntaxGraph , srcref, proto:: Union{Kind, SyntaxTree} )
130134 id = newnode! (graph)
131135 ex = SyntaxTree (graph, id)
132136 copy_attrs! (ex, proto, true )
133- setattr! (graph, id; source= _unpack_srcref (graph, srcref), attrs ... )
137+ ex . source = _unpack_srcref (graph, srcref)
134138 return ex
135139end
136140
137- function _makenode (graph:: SyntaxGraph , srcref, proto, children; attrs... )
138- id = newnode! (graph)
139- setchildren! (graph, id, children)
140- ex = SyntaxTree (graph, id)
141- copy_attrs! (ex, proto, true )
142- setattr! (graph, id; source= _unpack_srcref (graph, srcref), attrs... )
143- return SyntaxTree (graph, id)
144- end
145- function _makenode (ctx, srcref, proto, children; attrs... )
146- _makenode (syntax_graph (ctx), srcref, proto, children; attrs... )
141+ function makeleaf (ctx:: AbstractLoweringContext , srcref, proto)
142+ makeleaf (syntax_graph (ctx), srcref, proto)
147143end
148144
149- function makenode (ctx, srcref, proto, children... ; attrs... )
150- _makenode (ctx, srcref, proto, _node_ids (syntax_graph (ctx), children... ); attrs... )
145+ function makeleaf (ctx, srcref, proto, @nospecialize (attrs:: AbstractVector ))
146+ graph = syntax_graph (ctx)
147+ ex = makeleaf (graph, srcref, proto)
148+ for (k, v) in attrs
149+ setattr! (graph, ex. _id, k, v)
150+ end
151+ return ex
151152end
152153
153- function makeleaf (ctx, srcref, proto; kws... )
154- makeleaf (syntax_graph (ctx), srcref, proto; kws... )
154+ function makenode (ctx, srcref, proto, children, attrs= nothing )
155+ graph = syntax_graph (ctx)
156+ ex = isnothing (attrs) ? makeleaf (graph, srcref, proto) :
157+ makeleaf (graph, srcref, proto, attrs)
158+ setchildren! (graph, ex. _id, children isa SyntaxList ? children. ids : children)
159+ return ex
155160end
156161
157- function makeleaf (ctx, srcref, k:: Kind , value; kws ... )
158- graph = syntax_graph (ctx)
162+ function newleaf (ctx, srcref, k:: Kind , @nospecialize ( value) )
163+ leaf = makeleaf (ctx, srcref, k )
159164 if k == K " Identifier" || k == K " core" || k == K " top" || k == K " Symbol" ||
160165 k == K " globalref" || k == K " Placeholder" ||
161166 k == K " StrMacroName" || k == K " CmdMacroName"
162- makeleaf (graph, srcref, k; name_val= value, kws ... )
167+ setattr! (leaf . _graph, leaf . _id, : name_val, value )
163168 elseif k == K " BindingId"
164- makeleaf (graph, srcref, k; var_id= value, kws ... )
169+ setattr! (leaf . _graph, leaf . _id, : var_id, value )
165170 elseif k == K " label"
166- makeleaf (graph, srcref, k; id = value, kws ... )
171+ setattr! (leaf . _graph, leaf . _id, :id , value )
167172 elseif k == K " symbolic_label"
168- makeleaf (graph, srcref, k; name_val= value, kws ... )
173+ setattr! (leaf . _graph, leaf . _id, : name_val, value )
169174 elseif k in KSet " TOMBSTONE SourceLocation latestworld latestworld_if_toplevel"
170- makeleaf (graph, srcref, k; kws ... )
175+ # no attributes
171176 else
172177 val = k == K " Integer" ? convert (Int, value) :
173178 k == K " Float" ? convert (Float64, value) :
@@ -177,8 +182,9 @@ function makeleaf(ctx, srcref, k::Kind, value; kws...)
177182 k == K " Bool" ? value :
178183 k == K " VERSION" ? value :
179184 error (" Unexpected leaf kind `$k `" )
180- makeleaf (graph, srcref, k; value= val, kws ... )
185+ setattr! (leaf . _graph, leaf . _id, : value, val )
181186 end
187+ leaf
182188end
183189
184190# TODO : Replace this with makeleaf variant?
192198
193199# Convenience functions to create leaf nodes referring to identifiers within
194200# the Core and Top modules.
195- core_ref (ctx, ex, name) = makeleaf (ctx, ex, K " core" , name)
201+ core_ref (ctx, ex, name) = newleaf (ctx, ex, K " core" , name)
196202svec_type (ctx, ex) = core_ref (ctx, ex, " svec" )
197203nothing_ (ctx, ex) = core_ref (ctx, ex, " nothing" )
198204
@@ -202,7 +208,7 @@ top_ref(ctx, ex, name) = makeleaf(ctx, ex, K"top", name)
202208# Return (variable, assignment_node)
203209function assign_tmp (ctx:: AbstractLoweringContext , ex, name= " tmp" )
204210 var = ssavar (ctx, ex, name)
205- assign_var = makenode (ctx, ex, K " =" , var, ex)
211+ assign_var = makenode (ctx, ex, K " =" , NodeId[ var. _id , ex. _id] )
206212 var, assign_var
207213end
208214
@@ -211,7 +217,7 @@ function emit_assign_tmp(stmts::SyntaxList, ctx, ex, name="tmp")
211217 return ex
212218 end
213219 var = ssavar (ctx, ex, name)
214- push! (stmts, makenode (ctx, ex, K " =" , var, ex))
220+ push! (stmts, makenode (ctx, ex, K " =" , NodeId[ var. _id , ex. _id] ))
215221 var
216222end
217223
@@ -225,31 +231,38 @@ function _match_srcref(ex)
225231 end
226232end
227233
228- function _match_kind (f:: Function , srcref, ex)
234+ function _kw_to_pair (ex)
235+ if ex isa Expr && ex. head === :kw && ex. args[1 ] isa Symbol
236+ (QuoteNode (ex. args[1 ]), esc (ex. args[2 ]))
237+ elseif ex isa Symbol
238+ (QuoteNode (ex), esc (ex))
239+ else
240+ @assert false " invalid keyword form in @ast $ex "
241+ end
242+ end
243+
244+ function _match_kind (srcref, ex)
229245 kws = []
230246 if Meta. isexpr (ex, :call )
231247 kind = esc (ex. args[1 ])
232248 args = ex. args[2 : end ]
233249 if Meta. isexpr (args[1 ], :parameters )
234- kws = map (esc , args[1 ]. args)
250+ kws = map (_kw_to_pair , args[1 ]. args)
235251 popfirst! (args)
236252 end
237253 while length (args) >= 1 && Meta. isexpr (args[end ], :kw )
238- pushfirst! (kws, esc (pop! (args)))
254+ pushfirst! (kws, _kw_to_pair (pop! (args)))
239255 end
240256 if length (args) == 1
241257 srcref_tmp = gensym (" srcref" )
242- return quote
243- $ srcref_tmp = $ (_match_srcref (args[1 ]))
244- $ (f (kind, srcref_tmp, kws))
245- end
258+ return (kind, _match_srcref (args[1 ]), kws)
246259 elseif length (args) > 1
247260 error (" Unexpected: extra srcref argument in `$ex `?" )
248261 end
249262 else
250263 kind = esc (ex)
251264 end
252- f (kind, srcref, kws)
265+ return (kind, srcref, kws)
253266end
254267
255268function _expand_ast_tree (ctx, srcref, tree)
@@ -262,8 +275,12 @@ function _expand_ast_tree(ctx, srcref, tree)
262275 val = nothing
263276 kindspec = tree. args[1 ]
264277 end
265- _match_kind (srcref, kindspec) do kind, srcref, kws
266- :(makeleaf ($ ctx, $ srcref, $ kind, $ (val), $ (kws... )))
278+ let (kind, srcref, kws) = _match_kind (srcref, kindspec)
279+ n = :(newleaf ($ ctx, $ srcref, $ kind, $ val))
280+ for (attr, val) in kws
281+ n = :(setattr! ($ n, $ attr, $ val))
282+ end
283+ n
267284 end
268285 elseif Meta. isexpr (tree, :call ) && tree. args[1 ] === :(=> )
269286 # Leaf node with copied attributes
@@ -292,8 +309,12 @@ function _expand_ast_tree(ctx, srcref, tree)
292309 end
293310 end
294311 push! (child_stmts, :(child_ids))
295- _match_kind (srcref, flatargs[1 ]) do kind, srcref, kws
296- :(_makenode ($ ctx, $ srcref, $ kind, $ children_ex; $ (kws... )))
312+ let (kind, srcref, kws) = _match_kind (srcref, flatargs[1 ])
313+ n = :(makenode ($ ctx, $ srcref, $ kind, $ children_ex))
314+ for (attr, val) in kws
315+ n = :(setattr! ($ n, $ attr, $ val))
316+ end
317+ n
297318 end
298319 elseif Meta. isexpr (tree, :(:= ))
299320 lhs = tree. args[1 ]
@@ -389,17 +410,17 @@ end
389410
390411function copy_attrs! (dest, head:: Union{Kind,JuliaSyntax.SyntaxHead} , all= false )
391412 if all
392- sethead! (dest. _graph, dest. _id, head)
413+ setattr! (dest. _graph, dest. _id, :kind , kind (head))
414+ ! (head isa Kind) && setattr! (dest. _graph, dest. _id, :syntax_flags , flags (head))
393415 end
394416end
395417
396- function mapchildren (f:: Function , ctx, ex:: SyntaxTree , do_map_child:: Function ;
397- extra_attrs... )
418+ function mapchildren (f:: Function , ctx, ex:: SyntaxTree , do_map_child:: Function )
398419 if is_leaf (ex)
399420 return ex
400421 end
401422 orig_children = children (ex)
402- cs = isempty (extra_attrs) ? nothing : SyntaxList (ctx)
423+ cs = nothing
403424 for (i,e) in enumerate (orig_children)
404425 newchild = do_map_child (i) ? f (e) : e
405426 if isnothing (cs)
@@ -418,14 +439,12 @@ function mapchildren(f::Function, ctx, ex::SyntaxTree, do_map_child::Function;
418439 return ex
419440 end
420441 cs:: SyntaxList
421- ex2 = makenode (ctx, ex, head (ex), cs)
422- copy_attrs! (ex2, ex)
423- setattr! (ex2; extra_attrs... )
442+ ex2 = makenode (ctx, ex, ex, cs)
424443 return ex2
425444end
426445
427- function mapchildren (f:: Function , ctx, ex:: SyntaxTree , mapped_children :: AbstractVector{<:Integer} ;
428- extra_attrs ... )
446+ function mapchildren (f:: Function , ctx, ex:: SyntaxTree ,
447+ mapped_children :: AbstractVector{<:Integer} )
429448 j = Ref (firstindex (mapped_children))
430449 function do_map_child (i)
431450 ind = j[]
@@ -436,11 +455,11 @@ function mapchildren(f::Function, ctx, ex::SyntaxTree, mapped_children::Abstract
436455 false
437456 end
438457 end
439- mapchildren (f, ctx, ex, do_map_child; extra_attrs ... )
458+ mapchildren (f, ctx, ex, do_map_child)
440459end
441460
442- function mapchildren (f:: Function , ctx, ex:: SyntaxTree ; extra_attrs ... )
443- mapchildren (f, ctx, ex, i-> true ; extra_attrs ... )
461+ function mapchildren (f:: Function , ctx, ex:: SyntaxTree )
462+ mapchildren (f, ctx, ex, i-> true )
444463end
445464
446465
@@ -477,7 +496,7 @@ function _copy_ast(graph2::SyntaxGraph, graph1::SyntaxGraph,
477496 src1
478497 end
479498 copy_attrs! (SyntaxTree (graph2, id2), SyntaxTree (graph1, id1), true )
480- setattr! (graph2, id2; source= src2)
499+ setattr! (graph2, id2, : source, src2)
481500 if ! is_leaf (graph1, id1)
482501 cs = NodeId[]
483502 for cid in children (graph1, id1)
@@ -491,20 +510,19 @@ end
491510# -------------------------------------------------------------------------------
492511function set_scope_layer (ctx, ex, layer_id, force)
493512 k = kind (ex)
494- scope_layer = force ? layer_id : get (ex, :scope_layer , layer_id)
495- if k == K " module " || k == K " toplevel " || k == K " inert "
496- makenode (ctx, ex, ex, children (ex);
497- scope_layer = scope_layer )
513+ new_layer = force ? layer_id : get (ex, :scope_layer , layer_id)
514+
515+ ex2 = if k == K " module " || k == K " toplevel " || k == K " inert "
516+ makenode (ctx, ex, ex, children (ex) )
498517 elseif k == K " ."
499- makenode (ctx, ex, ex, set_scope_layer (ctx, ex[1 ], layer_id, force), ex[2 ],
500- scope_layer = scope_layer )
518+ children = NodeId[ set_scope_layer (ctx, ex[1 ], layer_id, force), ex[2 ]]
519+ makenode (ctx, ex, ex, children )
501520 elseif ! is_leaf (ex)
502- mapchildren (e-> set_scope_layer (ctx, e, layer_id, force), ctx, ex;
503- scope_layer= scope_layer)
521+ mapchildren (e-> set_scope_layer (ctx, e, layer_id, force), ctx, ex)
504522 else
505- makeleaf (ctx, ex, ex;
506- scope_layer= scope_layer)
523+ makeleaf (ctx, ex, ex)
507524 end
525+ setattr! (ex2, :scope_layer , new_layer)
508526end
509527
510528"""
513531Copy `ex`, adopting the scope layer of `ref`.
514532"""
515533function adopt_scope (ex:: SyntaxTree , scope_layer:: LayerId )
516- set_scope_layer (ex, ex, scope_layer, true )
534+ set_scope_layer (ex. _graph , ex, scope_layer, true )
517535end
518536
519537function adopt_scope (ex:: SyntaxTree , layer:: ScopeLayer )
@@ -539,19 +557,17 @@ end
539557# the middle of a pass.
540558const CompileHints = Base. ImmutableDict{Symbol,Any}
541559
542- function setmeta! (ex:: SyntaxTree ; kws... )
543- @assert length (kws) == 1 # todo relax later ?
544- key = first (keys (kws))
545- value = first (values (kws))
560+ function setmeta! (ex:: SyntaxTree , key:: Symbol , @nospecialize (val))
546561 meta = begin
547562 m = get (ex, :meta , nothing )
548- isnothing (m) ? CompileHints (key, value ) : CompileHints (m, key, value )
563+ isnothing (m) ? CompileHints (key, val ) : CompileHints (m, key, val )
549564 end
550- setattr! (ex; meta= meta)
565+ setattr! (ex, : meta, meta)
551566 ex
552567end
553568
554- setmeta (ex:: SyntaxTree ; kws... ) = setmeta! (copy_node (ex); kws... )
569+ setmeta (ex:: SyntaxTree , k:: Symbol , @nospecialize (v)) =
570+ setmeta! (copy_node (ex), k, v)
555571
556572function getmeta (ex:: SyntaxTree , name:: Symbol , default)
557573 meta = get (ex, :meta , nothing )
0 commit comments