Class: Patm::Rule

Inherits:
Object
  • Object
show all
Defined in:
lib/patm.rb

Defined Under Namespace

Classes: Compiled

Instance Method Summary collapse

Constructor Details

#initialize(&block) ⇒ Rule

Returns a new instance of Rule.



545
546
547
548
549
550
# File 'lib/patm.rb', line 545

def initialize(&block)
  # [[Pattern, Proc]...]
  @rules = []
  @else = nil
  block[self]
end

Instance Method Details

#apply(obj, _self = nil) ⇒ Object



560
561
562
563
564
565
566
567
568
# File 'lib/patm.rb', line 560

def apply(obj, _self = nil)
  match = Match.new
  @rules.each do|(pat, block)|
    if pat.execute(match, obj)
      return block.call(match, _self)
    end
  end
  @else ? @else[obj, _self] : (raise NoMatchError.new(obj))
end

#compileObject



578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
# File 'lib/patm.rb', line 578

def compile
  i = 0
  ctxs = []
  srcs = []
  @rules.each do|pat, block|
    s, c, i = pat.compile_internal(i, '_obj')
    ctxs << c
    ctxs << [block]
    srcs << "if (#{s || 'true'})\n_ctx[#{i}].#{compile_call(block, "::Patm::Match.new(_match)"," _self")}"
    i += 1
  end
  src = srcs.join("\nels")
  if @else
    src << "\nelse\n" unless srcs.empty?
    src << "_ctx[#{i}].#{compile_call(@else, "_obj"," _self")}"
    ctxs << [@else]
    i += 1
  else
    src << "\nelse\n" unless srcs.empty?
    src << "raise ::Patm::NoMatchError.new(_obj)"
  end
  src << "\nend" unless srcs.empty?
  Compiled.new(
    src,
    ctxs.flatten(1)
  )
end

#compile_call(block, *args) ⇒ Object



574
575
576
# File 'lib/patm.rb', line 574

def compile_call(block, *args)
  "call(#{args[0...block.arity].join(', ')})"
end

#else(&block) ⇒ Object



556
557
558
# File 'lib/patm.rb', line 556

def else(&block)
  @else = block
end

#inspectObject



570
571
572
# File 'lib/patm.rb', line 570

def inspect
  "Rule{#{@rules.map(&:first).map(&:inspect).join(', ')}#{@else ? ', _' : ''}}"
end

#on(pat, &block) ⇒ Object



552
553
554
# File 'lib/patm.rb', line 552

def on(pat, &block)
  @rules << [Pattern.build_from(pat), block]
end