lib/opal/nodes/call_special.rb in opal-1.3.2 vs lib/opal/nodes/call_special.rb in opal-1.4.0.alpha1
- old
+ new
@@ -67,9 +67,59 @@
children :lhs, :rhs
def compile
sexp = s(:send, lhs, :=~, rhs)
+ # Handle named matches like: /(?<abc>b)/ =~ 'b'
+ if lhs.type == :regexp && lhs.children.first.type == :str
+ re = lhs.children.first.children.first
+ names = re.scan(/\(\?<([^>]*)>/).flatten.map(&:to_sym)
+ unless names.empty?
+ # $m3names = $~ ? $~.named_captures : {}
+ names_def = s(:lvasgn, :$m3names,
+ s(:if,
+ s(:gvar, :$~),
+ s(:send, s(:gvar, :$~), :named_captures),
+ s(:hash)
+ )
+ )
+
+ names = names.map do |name|
+ # abc = $m3names[:abc]
+ s(:lvasgn, name,
+ s(:send,
+ s(:lvar, :$m3names),
+ :[],
+ s(:sym, name)
+ )
+ )
+ end
+
+ if stmt?
+ # We don't care about a return value of this one, so we
+ # ignore it and just assign the local variables.
+ #
+ # (/(?<abc>b)/ =~ 'f')
+ # $m3names = $~ ? $~.named_captures : {}
+ # abc = $m3names[:abc]
+ sexp = s(:begin, sexp, names_def, *names)
+ else
+ # We actually do care about a return value, so we must
+ # keep it saved.
+ #
+ # $m3tmp = (/(?<abc>b)/ =~ 'f')
+ # $m3names = $~ ? $~.named_captures : {}
+ # abc = $m3names[:abc]
+ # $m3tmp
+ sexp = s(:begin,
+ s(:lvasgn, :$m3tmp, sexp),
+ names_def,
+ *names,
+ s(:lvar, :$m3tmp)
+ )
+ end
+ end
+ end
push process(sexp, @level)
end
end
end
end