Skip to content

Commit

Permalink
more of the same
Browse files Browse the repository at this point in the history
  • Loading branch information
fcard committed Sep 16, 2017
1 parent 59cfc35 commit 6e414de
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 48 deletions.
1 change: 0 additions & 1 deletion src/Analyzer/Function.jl
Expand Up @@ -20,7 +20,6 @@ end
const newstate = AnalysisState
AnalysisState(state, tree::PatternTree) = newstate(tree, state.literal, state.mod, state.consts)
AnalysisState(state, literal::Bool) = newstate(state.tree, literal, state.mod, state.consts)
AnalysisState(state, mod::Module) = newstate(state.tree, state.literal, mod, state.consts)


#-----------------------------------------------------------------------------------
Expand Down
93 changes: 48 additions & 45 deletions src/Matching/Comparison.jl
Expand Up @@ -4,7 +4,7 @@ using ...PatternStructure.Trees
using ...PatternStructure.Checks
using ...PatternStructure.Special
using ...PatternStructure.SlurpTypes
import Base: ==,
import Base: ==, , ;
export compare_trees, conflicts, ;

==(a::PatternTree, b::PatternTree) = compare_trees(a,b) == :equal
Expand Down Expand Up @@ -32,17 +32,18 @@ PatternData(p) = PatternGenericData(p)
struct PatternCmp{P<:Union{PatternTree, PatternCheck}}
data::PatternData{P}
vars::Variables
freeze::Bool

function PatternCmp(p::P, vars=Variables(), repeats=1) where P <: PatternNode
new{P}(PatternNodeData(p, 1, repeats, length(p.children)), vars)
function PatternCmp(p::P, vars=Variables(), freeze=false, repeats=1) where P <: PatternNode
new{P}(PatternNodeData(p, 1, repeats, length(p.children)), vars, freeze)
end

function PatternCmp(p::P, vars=Variables()) where P
new{P}(PatternGenericData(p), vars)
function PatternCmp(p::P, vars=Variables(), freeze=false) where P
new{P}(PatternGenericData(p), vars, freeze)
end

function PatternCmp(d::PatternData{P}, vars) where P
new{P}(d, vars)
function PatternCmp(d::PatternData{P}, vars, freeze=false) where P
new{P}(d, vars, freeze)
end
end

Expand All @@ -57,7 +58,7 @@ macro cmp(a::Union{Expr,Symbol})

root, fields_f = dotroot(a)

esc(:($PatternCmp($(fields_f(root)), $root.vars)))
esc(:($PatternCmp($(fields_f(root)), $root.vars, $root.freeze)))
end
end

Expand All @@ -78,7 +79,7 @@ finished(p::PC{P}) where P <: PatternNode =
getchild(p::PC{P}) where P <: PatternNode =
finished(p) ?
throw(BoundsError(pattern(p).children, p.data.index)) :
PatternCmp(pattern(p).children[max(1, p.data.index%(p.data.real_length+1))], p.vars)
PatternCmp(pattern(p).children[max(1, p.data.index%(p.data.real_length+1))], p.vars, is_slurp(pattern(p)) || p.freeze)

function setchild!(p::PC{P}, i) where P <: PatternNode
p.data.index = i
Expand Down Expand Up @@ -110,27 +111,34 @@ function compare_children(a, b)
reverse_comparison_result(compare_children(b, a))
end
else
let result=:equal, onfailure=Tuple{Int,Int}[]
while !finished(a) && !finished(b)
result = update_result(result, compare_child(a, b, onfailure))
let result=:equal, onfailure=Tuple{Int,Int,Symbol}[]
while true

if !finished(a) && !finished(b)
result = update_result(result, compare_child(a, b, onfailure))

elseif !finished(a)
result = is_slurp(pattern(getchild(a))) ? update_result(result, :superset) : :unequal
next_child!(a)

elseif !finished(b)
result = is_slurp(pattern(getchild(b))) ? update_result(result, :subset) : :unequal
next_child!(b)

else
return result
end

if result in (:conflicts, :unequal)
if isempty(onfailure)
return result
else
indexes = pop!(onfailure)
setchild!(a, indexes[1])
setchild!(b, indexes[2])
a_index, b_index, result = pop!(onfailure)
setchild!(a, a_index)
setchild!(b, b_index)
end
end
end

if !finished(a)
is_slurp(pattern(getchild(a))) ? update_result(result, :superset) : :unequal
elseif !finished(b)
is_slurp(pattern(getchild(b))) ? update_result(result, :subset) : :unequal
else
result
end
end
end
end
Expand All @@ -144,8 +152,8 @@ function compare_child(a, b, onfailure)
if isla && islb
let result = compare_slurps(ca, cb)
if result in (:equal, :subset, :superset)
push!(onfailure, (a.data.index, b.data.index+1))
push!(onfailure, (a.data.index+1, b.data.index))
push!(onfailure, (a.data.index, b.data.index+1, :superset))
push!(onfailure, (a.data.index+1, b.data.index, :subset))
next_child!(a)
next_child!(b)
return result
Expand All @@ -155,20 +163,19 @@ function compare_child(a, b, onfailure)
end
elseif isla
ca = repeat(ca, Inf)
while !finished(b) && compare_trees(getchild(ca), cb) in (:superset, :equal)
cb = getchild(b)
push!(onfailure, (a.data.index+1, b.data.index))
while !finished(b) && compare_trees(getchild(ca), getchild(b)) in (:superset, :equal)
push!(onfailure, (a.data.index+1, b.data.index, :superset))
next_child!(ca)
next_child!(b)
end
next_child!(a)
return :superset

elseif islb
let rev_onfailure=Tuple{Int,Int}[]
let rev_onfailure=Tuple{Int,Int,Symbol}[]
compare_child(b, a, rev_onfailure)
for onf in rev_onfailure
push!(onfailure, (onf[2], onf[1]))
push!(onfailure, (onf[2], onf[1], reverse_comparison_result(onf[3])))
end
return :subset
end
Expand Down Expand Up @@ -199,12 +206,6 @@ function compare_slurps(a, b)
end
end

function compare_child(a, b, pa, pb)
next_child!(pa)
next_child!(pb)
compare_trees(a, b)
end

function compare_trees(a::PC{PatternGate}, b::PC{PatternGate})
checks = compare_checks(@cmp(a.check), @cmp(b.check))
checks == :equal ?
Expand All @@ -221,16 +222,22 @@ function compare_trees(a, b::PC{PatternGate})
checks == :subset ? :subset : :unequal
end

function compare_checks(a::PC{Binding}, b::PC{Binding})
compare_checks(a::PC{Binding}, b::PC{Binding}) =
a.freeze ? check_frozen_variable(a, b) :
b.freeze ? check_frozen_variable(b, a) :
match_variable!(a.vars, pattern(a).name, pattern(b).name) &&
match_variable!(b.vars, pattern(b).name, pattern(a).name) ? :equal : :unequal
end

compare_checks(a::PC{Binding}, b) =
match_variable!(a.vars, pattern(a).name, pattern(b)) ? :superset : :unequal
a.freeze ? check_frozen_variable(a, b) : check_and_match_variable(a, b)

compare_checks(a, b::PC{Binding}) =
match_variable!(b.vars, pattern(b).name, pattern(a)) ? :subset : :unequal
compare_checks(a, b::PC{Binding}) = reverse_comparison_result(compare_checks(b, a))

check_frozen_variable(a, b) =
!haskey(a.vars, pattern(a).name) || a.vars[pattern(a).name] == pattern(b) ? :superset : :unequal

check_and_match_variable(a, b) =
match_variable!(a.vars, pattern(a).name, pattern(b)) ? :superset : :unequal

compare_checks(a::PC{EqualityCheck{T}}, b::PC{EqualityCheck{T}}) where T =
pattern(a).value == pattern(b).value ? :equal : :unequal
Expand All @@ -249,10 +256,6 @@ compare_checks(a, b) = :unequal
compare_trees(a::PC{PatternLeaf}, b::PC{PatternLeaf}) = :equal
compare_trees(a, b) = :unequal

process_result_list(list) =
:subset in list && :superset in list ?
:conflicts : reduce(update_result, :equal, list)

update_result(final, result) =
result == :equal ? final :
final == :equal ? result :
Expand Down
1 change: 0 additions & 1 deletion src/PatternStructure/Special.jl
Expand Up @@ -27,7 +27,6 @@ is_slurp(node::PatternNode) = isa(node.head, SlurpHead)
is_slurp(x) = false

is_special(node::PatternNode) = node.head in special_heads || is_slurp(node)
is_special(x) = false

slurptype(node::PatternNode) =
isa(node.head, LazySlurp) ? :? :
Expand Down
19 changes: 18 additions & 1 deletion test/extra.jl
Expand Up @@ -5,7 +5,10 @@ using Base.Test
using ExpressionPatterns
using ExpressionPatterns.Helper

@test ExpressionPatterns.path("x") == "x/x.jl"
cd("../src")
@test isfile(ExpressionPatterns.path("Analyzer"))
cd("../test")

@test clean_code(quote x end).args == [:x]


Expand Down Expand Up @@ -53,4 +56,18 @@ cd("../../test")

end

module TreeComparison
using Base.Test
using ExpressionPatterns.Analyzer
using ExpressionPatterns.Matching.Comparison

totree(x) = analyze(x, TreeComparison)

@test totree(:(a,*{x})) totree(:(*{x},))
@test totree(:(*{x},)) totree(:(a,*{x}))
@test totree(:(*{x},1)) totree(:(*{x},2,1))
@test totree(:(*{x},2,1)) totree(:(*{x},1))

end

end
8 changes: 8 additions & 0 deletions test/matching.jl
Expand Up @@ -176,4 +176,12 @@ end
:(import a.b.c) => false
end

# line number nodes

@testmatch LineNumberNode(1) begin
LineNumberNode(1) => true
LineNumberNode(2) => true
Expr(:line, 10) => true
end

end

0 comments on commit 6e414de

Please sign in to comment.