@@ -100,17 +100,49 @@ function toexpr(O, st)
100100 return toexpr (Term {Any} (inv, [ex]), st)
101101 else
102102 return toexpr (Term {Any} (^ , [Term {Any} (inv, [ex]), - args[2 ]]), st)
103- end
104- elseif op === (SymbolicUtils. ifelse)
105- return :($ (toexpr (args[1 ], st)) ? $ (toexpr (args[2 ], st)) : $ (toexpr (args[3 ], st)))
106- elseif op isa Sym && O in st. symbolify
107- return Symbol (string (O))
108- end
103+ end elseif op === (SymbolicUtils. ifelse) return :($ (toexpr (args[1 ], st)) ? $ (toexpr (args[2 ], st)) : $ (toexpr (args[3 ], st))) elseif op isa Sym && O in st. symbolify return Symbol (string (O)) end
109104 return Expr (:call , toexpr (op, st), map (x-> toexpr (x, st), args)... )
110105end
111106
107+ # Call elements of vector arguments by their name.
108+ @matchable struct DestructuredArgs
109+ elems
110+ inds
111+ name
112+ end
113+
114+ function DestructuredArgs (elems, name= gensym (" arg" ); inds= eachindex (elems))
115+ DestructuredArgs (elems, inds, name)
116+ end
117+
118+ """
119+ DestructuredArgs(elems, [name=gensym("arg")])
120+
121+ `elems` is a vector of symbols or call expressions. When it appears as an argument in
122+ `Func`, it expects a vector of the same length and de-structures the vector into its named
123+ components. See example in `Func` for more information.
124+
125+ `name` is the name to be used for the argument in the generated function Expr.
126+ """
127+ DestructuredArgs
128+
129+ toexpr (x:: DestructuredArgs , st) = toexpr (x. name, st)
130+ get_symbolify (args:: DestructuredArgs ) = ()
131+ function get_symbolify (args:: Union{AbstractArray, Tuple} )
132+ cflatten (map (get_symbolify, args))
133+ end
134+ get_symbolify (x) = istree (x) ? (x,) : ()
135+ cflatten (x) = Iterators. flatten (x) |> collect
136+
137+ function get_assignments (d:: DestructuredArgs , st)
138+ name = toexpr (d, st)
139+ map (d. inds, d. elems) do i, a
140+ a ← (i isa Symbol ? :($ name.$ i) : :($ name[$ i]))
141+ end
142+ end
143+
112144@matchable struct Let
113- pairs:: Vector{Assignment} # an iterator of pairs, ordered
145+ pairs:: Vector{Union{ Assignment,DestructuredArgs} } # an iterator of pairs, ordered
114146 body
115147end
116148
@@ -125,13 +157,32 @@ A Let block.
125157Let
126158
127159function toexpr (l:: Let , st)
160+ if all (x-> x isa Assignment && ! (x. lhs isa DestructuredArgs), l. pairs)
161+ dargs = l. pairs
162+ else
163+ dargs = map (l. pairs) do x
164+ if x isa DestructuredArgs
165+ get_assignments (x, st)
166+ elseif x isa Assignment && x. lhs isa DestructuredArgs
167+ [x. lhs. name ← x. rhs, get_assignments (x. lhs, st)... ]
168+ else
169+ (x,)
170+ end
171+ end |> cflatten
172+ # expand and come back
173+ return toexpr (Let (dargs, l. body), st)
174+ end
175+
176+ funkyargs = get_symbolify (map (lhs, dargs))
177+ union! (st. symbolify, funkyargs)
178+
128179 Expr (:let ,
129- Expr (:block , map (p-> toexpr (p, st), l . pairs )... ),
180+ Expr (:block , map (p-> toexpr (p, st), dargs )... ),
130181 toexpr (l. body, st))
131182end
132183
133184@matchable struct Func
134- args
185+ args:: Vector
135186 kwargs
136187 body
137188end
@@ -188,43 +239,12 @@ Func
188239
189240toexpr_kw (f, st) = Expr (:kw , toexpr (f, st). args... )
190241
191- # Call elements of vector arguments by their name.
192- @matchable struct DestructuredArgs
193- elems
194- name
195- end
196-
197- DestructuredArgs (elems) = DestructuredArgs (elems, gensym (" arg" ))
198-
199- """
200- DestructuredArgs(elems, [name=gensym("arg")])
201-
202- `elems` is a vector of symbols or call expressions. When it appears as an argument in
203- `Func`, it expects a vector of the same length and de-structures the vector into its named
204- components. See example in `Func` for more information.
205-
206- `name` is the name to be used for the argument in the generated function Expr.
207- """
208- DestructuredArgs
209-
210- toexpr (x:: DestructuredArgs , st) = x. name
211- get_symbolify (args:: DestructuredArgs ) = get_symbolify (args. elems)
212- function get_symbolify (args:: Union{AbstractArray, Tuple} )
213- cflatten (map (get_symbolify, args))
214- end
215- get_symbolify (x) = istree (x) ? (x,) : ()
216- cflatten (x) = Iterators. flatten (x) |> collect
217-
218- function get_assignments (d:: DestructuredArgs , st)
219- [a ← Expr (:ref , toexpr (d, st), i) for (i, a) in enumerate (d. elems)]
220- end
221-
222242function toexpr (f:: Func , st)
223243 funkyargs = get_symbolify (vcat (f. args, map (lhs, f. kwargs)))
224- dargs = filter (x-> x isa DestructuredArgs, f. args)
225244 union! (st. symbolify, funkyargs)
245+ dargs = filter (x-> x isa DestructuredArgs, f. args)
226246 if ! isempty (dargs)
227- body = Let (cflatten ( map (x -> get_assignments (x, st), dargs)) , f. body)
247+ body = Let (dargs, f. body)
228248 else
229249 body = f. body
230250 end
@@ -324,7 +344,7 @@ function toexpr(a::MakeArray, st)
324344 $ create_array ($ T,
325345 $ elT,
326346 Val {$(size(a.elems))} (),
327- $ (toexpr .(a . elems, (st,) )... ),)
347+ $ (map (x -> toexpr (x, st), a . elems )... ),)
328348 end
329349end
330350
@@ -367,16 +387,23 @@ end
367387end
368388
369389# # LabelledArrays
370- @inline function create_array (A:: Type{<:SLArray} , :: Nothing , d:: Val{dims} , elems... ) where {dims}
371- a = create_array (SArray, nothing , d, elems... )
372- similar_type (A, eltype (a), Size (dims))(a)
373- end
374-
375390@inline function create_array (A:: Type{<:SLArray} , T, d:: Val{dims} , elems... ) where {dims}
376- similar_type (A, T, Size (dims))(create_array (SArray, T, d, elems... ))
391+ a = create_array (SArray, T, d, elems... )
392+ if nfields (dims) === ndims (A)
393+ similar_type (A, eltype (a), Size (dims))(a)
394+ else
395+ a
396+ end
377397end
378398
379- using SparseArrays
399+ @inline function create_array (A:: Type{<:LArray} , T, d:: Val{dims} , elems... ) where {dims}
400+ data = create_array (Array, T, d, elems... )
401+ if nfields (dims) === ndims (A)
402+ LArray {eltype(data),nfields(dims),typeof(data),LabelledArrays.symnames(A)} (data)
403+ else
404+ data
405+ end
406+ end
380407
381408# # We use a separate type for Sparse Arrays to sidestep the need for
382409# # iszero to be defined on the expression type
0 commit comments