@@ -119,45 +119,58 @@ function pushmeta!(ex::Expr, sym::Symbol, args::Any...)
119
119
else
120
120
tag = Expr (sym, args... )
121
121
end
122
-
123
- if ex. head == :function
122
+ found, metaex = findmeta (ex)
123
+ if found
124
+ push! (metaex. args, tag)
125
+ else
124
126
body:: Expr = ex. args[2 ]
125
- if ! isempty (body. args) && isa (body. args[1 ], Expr) && (body. args[1 ]:: Expr ). head == :meta
126
- push! ((body. args[1 ]:: Expr ). args, tag)
127
- elseif isempty (body. args)
128
- push! (body. args, Expr (:meta , tag))
129
- push! (body. args, nothing )
130
- else
131
- unshift! (body. args, Expr (:meta , tag))
132
- end
133
- elseif (ex. head == :(= ) && typeof (ex. args[1 ]) == Expr && ex. args[1 ]. head == :call )
134
- ex = Expr (:function , ex. args[1 ], Expr (:block , Expr (:meta , tag), ex. args[2 ]))
135
- # else
136
- # ex = Expr(:withmeta, ex, sym)
127
+ unshift! (body. args, Expr (:meta , tag))
137
128
end
138
129
ex
139
130
end
140
131
141
132
function popmeta! (body:: Expr , sym:: Symbol )
142
- if isa (body. args[1 ],Expr) && (body. args[1 ]:: Expr ). head === :meta
143
- metaargs = (body. args[1 ]:: Expr ). args
144
- for i = 1 : length (metaargs)
145
- if (isa (metaargs[i], Symbol) && metaargs[i] == sym) ||
146
- (isa (metaargs[i], Expr) && metaargs[i]. head == sym)
147
- if length (metaargs) == 1
148
- shift! (body. args) # get rid of :meta Expr
149
- else
150
- deleteat! (metaargs, i) # delete this portion of the metadata
151
- end
133
+ body. head == :block || return false , []
134
+ found, metaex = findmeta_block (body)
135
+ if ! found
136
+ return false , []
137
+ end
138
+ metaargs = metaex. args
139
+ for i = 1 : length (metaargs)
140
+ if isa (metaargs[i], Symbol) && (metaargs[i]:: Symbol ) == sym
141
+ deleteat! (metaargs, i)
142
+ return true , []
143
+ elseif isa (metaargs[i], Expr) && (metaargs[i]:: Expr ). head == sym
144
+ ret = (metaargs[i]:: Expr ). args
145
+ deleteat! (metaargs, i)
146
+ return true , ret
147
+ end
148
+ end
149
+ false , []
150
+ end
151
+ popmeta! (arg, sym) = (false , [])
152
152
153
- if isa (metaargs[i], Symbol)
154
- return (true , [])
155
- elseif isa (metaargs[i], Expr)
156
- return (true , metaargs[i]. args)
153
+ function findmeta (ex:: Expr )
154
+ if ex. head == :function || (ex. head == :(= ) && typeof (ex. args[1 ]) == Expr && ex. args[1 ]. head == :call )
155
+ body:: Expr = ex. args[2 ]
156
+ body. head == :block || error (body, " is not a block expression" )
157
+ return findmeta_block (ex)
158
+ end
159
+ error (ex, " is not a function expression" )
160
+ end
161
+
162
+ function findmeta_block (ex:: Expr )
163
+ for a in ex. args
164
+ if isa (a, Expr)
165
+ if (a:: Expr ). head == :meta
166
+ return true , a:: Expr
167
+ elseif (a:: Expr ). head == :block
168
+ found, exb = findmeta_block (a)
169
+ if found
170
+ return found, exb
157
171
end
158
172
end
159
173
end
160
174
end
161
- return ( false , [] )
175
+ return false , Expr ( :block )
162
176
end
163
- popmeta! (arg, sym) = (false , [])
0 commit comments