66# 3. Callback: takes arguments Dictionary × Number of elements matched
77#
88
9- function matcher (val:: Any ; acSets = nothing )
9+ function matcher (val:: Any , acSets)
1010 # if val is a call (like an operation) creates a term matcher or term matcher with defslot
1111 if iscall (val)
1212 # if has two arguments and one of them is a DefSlot, create a term matcher with defslot
@@ -25,7 +25,7 @@ function matcher(val::Any; acSets = nothing)
2525end
2626
2727# acSets is not used but needs to be there in case matcher(::Slot) is directly called from the macro
28- function matcher (slot:: Slot ; acSets = nothing )
28+ function matcher (slot:: Slot , acSets)
2929 function slot_matcher (next, data, bindings)
3030 ! islist (data) && return nothing
3131 val = get (bindings, slot. name, nothing )
4444# this is called only when defslot_term_matcher finds the operation and tries
4545# to match it, so no default value used. So the same function as slot_matcher
4646# can be used
47- function matcher (defslot:: DefSlot ; acSets = nothing )
48- matcher (Slot (defslot. name, defslot. predicate))
47+ function matcher (defslot:: DefSlot , acSets)
48+ matcher (Slot (defslot. name, defslot. predicate), nothing ) # slot matcher doesnt use acsets
4949end
5050
5151# returns n == offset, 0 if failed
@@ -76,7 +76,7 @@ function trymatchexpr(data, value, n)
7676 end
7777end
7878
79- function matcher (segment:: Segment ; acSets= nothing )
79+ function matcher (segment:: Segment , acSets)
8080 function segment_matcher (success, data, bindings)
8181 val = get (bindings, segment. name, nothing )
8282
@@ -105,7 +105,7 @@ function matcher(segment::Segment; acSets=nothing)
105105end
106106
107107function term_matcher_constructor (term, acSets)
108- matchers = (matcher (operation (term); acSets= acSets ), map (x-> matcher (x;acSets = acSets), arguments (term))... ,)
108+ matchers = (matcher (operation (term), acSets), map (x-> matcher (x, acSets), arguments (term))... ,)
109109
110110 function loop (term, bindings′, matchers′) # Get it to compile faster
111111 if ! islist (matchers′)
@@ -181,14 +181,21 @@ function term_matcher_constructor(term, acSets)
181181 operation (term) != = operation (car (data)) && return nothing # if the operation of data is not the correct one, don't even try
182182
183183 T = symtype (car (data))
184- f = operation (car (data))
185- data_args = arguments (car (data))
186-
187- for inds in acSets (eachindex (data_args), length (arguments (term)))
188- candidate = Term {T} (f, @views data_args[inds])
189-
190- result = loop (candidate, bindings, matchers)
191- result != = nothing && length (data_args) == length (inds) && return success (result,1 )
184+ if T <: Number
185+ f = operation (car (data))
186+ data_args = arguments (car (data))
187+
188+ for inds in acSets (eachindex (data_args), length (arguments (term)))
189+ candidate = Term {T} (f, @views data_args[inds])
190+
191+ result = loop (candidate, bindings, matchers)
192+ result != = nothing && length (data_args) == length (inds) && return success (result,1 )
193+ end
194+ # if car(data) does not subtype to number, it might not be commutative
195+ else
196+ # call the normal matcher
197+ result = loop (car (data), bindings, matchers)
198+ result != = nothing && return success (result, 1 )
192199 end
193200 return nothing
194201 end
@@ -214,7 +221,7 @@ function defslot_term_matcher_constructor(term, acSets)
214221 defslot_index = findfirst (x -> isa (x, DefSlot), a) # find the defslot in the term
215222 defslot = a[defslot_index]
216223 if length (a) == 2
217- other_part_matcher = matcher (a[defslot_index == 1 ? 2 : 1 ]; acSets = acSets)
224+ other_part_matcher = matcher (a[defslot_index == 1 ? 2 : 1 ], acSets)
218225 else
219226 others = [a[i] for i in eachindex (a) if i != defslot_index]
220227 T = symtype (term)
0 commit comments