class Destructure::SexpTransformer
Public Class Methods
new(caller_binding)
click to toggle source
# File lib/destructure/sexp_transformer.rb, line 11 def initialize(caller_binding) @caller_binding = caller_binding end
transform(sp, caller_binding)
click to toggle source
# File lib/destructure/sexp_transformer.rb, line 7 def self.transform(sp, caller_binding) SexpTransformer.new(caller_binding).transform(sp) end
Public Instance Methods
transform(sp)
click to toggle source
# File lib/destructure/sexp_transformer.rb, line 15 def transform(sp) _ = DMatch::_ klass_sym = DMatch::Var.new(&method(:is_constant?)) case # '_' (wildcard) when e = dmatch([:call, _, :_, _], sp); _ # object matcher without parameters when e = dmatch([:const, klass_sym], sp) make_obj(e[klass_sym], {}) # namespace-qualified object matcher without parameters when e = dmatch([:colon2, splat(:args)], sp) make_obj(read_fq_const(sp), {}) # '~' (splat) when e = dmatch([:call, var(:identifier_sexp), :~, [:arglist]], sp); splat(unwind_receivers_and_clean(e[:identifier_sexp])) # '!' (variable value) when e = dmatch([:not, var(:value_sexp)], sp) @caller_binding.eval(unwind_receivers_and_clean(e[:value_sexp]).to_s) # '|' (alternative patterns) when e = dmatch([:call, var(:rest), :|, [:arglist, var(:alt)]], sp); DMatch::Or.new(*[e[:rest], e[:alt]].map(&method(:transform))) # generic call when e = dmatch([:call, var(:receiver), var(:msg), var(:arglist)], sp) transform_call(e[:receiver], e[:msg], e[:arglist]) # instance variable when e = dmatch([:ivar, var(:name)], sp); var(e[:name].to_s) # let # ... with local or instance vars when e = dmatch([DMatch::Or.new(:lasgn, :iasgn), var(:lhs), var(:rhs)], sp) let_var(e[:lhs], transform(e[:rhs])) # ... with attributes or something more complicated when e = dmatch([:attrasgn, var(:obj), var(:attr), [:arglist, var(:rhs)]], sp) var_name = unwind_receivers_and_clean([:call, e[:obj], e[:attr].to_s.sub(/=$/,'').to_sym, [:arglist]]) let_var(var_name, transform(e[:rhs])) # literal values when e = dmatch([:lit, var(:value)], sp); e[:value] when e = dmatch([:true], sp); true when e = dmatch([:false], sp); false when e = dmatch([:nil], sp); nil when e = dmatch([:str, var(:s)], sp); e[:s] when e = dmatch([:array, splat(:items)], sp); e[:items].map(&method(:transform)) when e = dmatch([:hash, splat(:kvs)], sp); Hash[*e[:kvs].map(&method(:transform))] else; raise "Unexpected sexp: #{sp.inspect}" end end