@@ -29,13 +29,37 @@ def scan(root)
2929
3030 private
3131
32+ def combine_and ( left , right )
33+ -> ( node ) { left . call ( node ) && right . call ( node ) }
34+ end
35+
36+ def combine_or ( left , right )
37+ -> ( node ) { left . call ( node ) || right . call ( node ) }
38+ end
39+
3240 def compile ( pattern )
3341 case pattern
34- in Binary [ left :, operator : :| , right :]
35- compiled_left = compile ( left )
36- compiled_right = compile ( right )
42+ in AryPtn [ constant :, requireds :, rest : nil , posts : [ ] ]
43+ compiled_constant = compile ( constant ) if constant
44+
45+ preprocessed = requireds . map { |required | compile ( required ) }
3746
38- -> ( node ) { compiled_left . call ( node ) || compiled_right . call ( node ) }
47+ compiled_requireds = -> ( node ) do
48+ deconstructed = node . deconstruct
49+
50+ deconstructed . length == preprocessed . length &&
51+ preprocessed . zip ( deconstructed ) . all? do |( matcher , value ) |
52+ matcher . call ( value )
53+ end
54+ end
55+
56+ if compiled_constant
57+ combine_and ( compiled_constant , compiled_requireds )
58+ else
59+ compiled_requireds
60+ end
61+ in Binary [ left :, operator : :| , right :]
62+ combine_or ( compile ( left ) , compile_right )
3963 in Const [ value :] if SyntaxTree . const_defined? ( value )
4064 clazz = SyntaxTree . const_get ( value )
4165
@@ -46,33 +70,48 @@ def compile(pattern)
4670 -> ( node ) { node . is_a? ( clazz ) }
4771 in ConstPathRef [ parent : VarRef [ value : Const [ value : "SyntaxTree" ] ] ]
4872 compile ( pattern . constant )
73+ in DynaSymbol [ parts : [ TStringContent [ value :] ] ]
74+ symbol = value . to_sym
75+
76+ -> ( attribute ) { attribute == value }
4977 in HshPtn [ constant :, keywords :, keyword_rest : nil ]
5078 compiled_constant = compile ( constant )
5179
52- preprocessed_keywords =
80+ preprocessed =
5381 keywords . to_h do |keyword , value |
5482 raise NoMatchingPatternError unless keyword . is_a? ( Label )
5583 [ keyword . value . chomp ( ":" ) . to_sym , compile ( value ) ]
5684 end
5785
5886 compiled_keywords = -> ( node ) do
59- deconstructed = node . deconstruct_keys ( preprocessed_keywords . keys )
60- preprocessed_keywords . all? do |keyword , matcher |
87+ deconstructed = node . deconstruct_keys ( preprocessed . keys )
88+
89+ preprocessed . all? do |keyword , matcher |
6190 matcher . call ( deconstructed [ keyword ] )
6291 end
6392 end
6493
65- -> ( node ) do
66- compiled_constant . call ( node ) && compiled_keywords . call ( node )
94+ if compiled_constant
95+ combine_and ( compiled_constant , compiled_keywords )
96+ else
97+ compiled_keywords
6798 end
6899 in RegexpLiteral [ parts : [ TStringContent [ value :] ] ]
69100 regexp = /#{ value } /
70101
71102 -> ( attribute ) { regexp . match? ( attribute ) }
103+ in StringLiteral [ parts : [ ] ]
104+ -> ( attribute ) { attribute == "" }
72105 in StringLiteral [ parts : [ TStringContent [ value :] ] ]
73106 -> ( attribute ) { attribute == value }
107+ in SymbolLiteral [ value :]
108+ symbol = value . value . to_sym
109+
110+ -> ( attribute ) { attribute == symbol }
74111 in VarRef [ value : Const => value ]
75112 compile ( value )
113+ in VarRef [ value : Kw [ value : "nil" ] ]
114+ -> ( attribute ) { attribute . nil? }
76115 end
77116 rescue NoMatchingPatternError
78117 raise UncompilableError , <<~ERROR
0 commit comments