Sha256: ad0a81a33aa364e5a5381dc32a65f52506a0c216f3ec8d55b1a24053395044b3

Contents?: true

Size: 1.77 KB

Versions: 42

Compression:

Stored size: 1.77 KB

Contents

# -*- encoding : utf-8 -*-
module Tracksperanto::ShakeGrammar
  # Will replay funcalls through to methods if such methods exist in the public insntance
  class Catcher < Lexer
    class At
      attr_accessor :at, :value
      include Comparable
      def initialize(a, v)
        @at, @value = a, v
      end
      
      def <=>(o)
        [@at, @value] <=> [o.at, o.value]
      end
      
      def inspect
        "(#{@value.inspect}@#{@at.inspect})"
      end
    end
    
    def push(atom)
      
      # Send everything but funcalls to parent
      return super unless atom.is_a?(Array) && atom[0] == :funcall
      
      meth_for_shake_func, args = atom[1].downcase, atom[2..-1]
      if can_handle_meth?(meth_for_shake_func)
        super([:retval, exec_funcall(meth_for_shake_func, args)])
      else
        # This is a funcall we cannot perform, replace the return result of the funcall
        # with a token to signify that some unknown function's result would have been here
        super([:unknown_func])
      end
    end
    
    private
    
    # Suppress comment output
    def push_comment
    end
    
    def can_handle_meth?(m)
      # Ruby 1.9 - match on stringified methname
      @meths ||= self.class.public_instance_methods(false).map{|mn| mn.to_s }
      @meths.include?(m.to_s)
    end
    
    def exec_funcall(methname, args)
      ruby_args = args.map {|a| unwrap_atom(a) }
      send(methname, *ruby_args)
    end
    
    def unwrap_atom(atom)
      return atom unless atom.is_a?(Array)
      
      kind = atom.shift
      case kind
        when :arr
          atom[0].map{|e| unwrap_atom(e)}
        when :retval
          atom.shift
        when :value_at
          At.new(atom.shift, unwrap_atom(atom.shift))
        else
          :unknown
      end
    end

  end
end

Version data entries

42 entries across 42 versions & 1 rubygems

Version Path
tracksperanto-3.5.9 lib/import/shake_grammar/catcher.rb
tracksperanto-3.5.8 lib/import/shake_grammar/catcher.rb
tracksperanto-3.5.7 lib/import/shake_grammar/catcher.rb
tracksperanto-3.5.6 lib/import/shake_grammar/catcher.rb
tracksperanto-3.5.5 lib/import/shake_grammar/catcher.rb
tracksperanto-3.5.4 lib/import/shake_grammar/catcher.rb
tracksperanto-3.5.2 lib/import/shake_grammar/catcher.rb
tracksperanto-3.5.1 lib/import/shake_grammar/catcher.rb
tracksperanto-3.5.0 lib/import/shake_grammar/catcher.rb
tracksperanto-3.4.1 lib/import/shake_grammar/catcher.rb
tracksperanto-3.4.0 lib/import/shake_grammar/catcher.rb
tracksperanto-3.3.13 lib/import/shake_grammar/catcher.rb
tracksperanto-3.3.12 lib/import/shake_grammar/catcher.rb
tracksperanto-3.3.11 lib/import/shake_grammar/catcher.rb
tracksperanto-3.3.10 lib/import/shake_grammar/catcher.rb
tracksperanto-3.3.9 lib/import/shake_grammar/catcher.rb
tracksperanto-3.3.8 lib/import/shake_grammar/catcher.rb
tracksperanto-3.3.7 lib/import/shake_grammar/catcher.rb
tracksperanto-3.3.6 lib/import/shake_grammar/catcher.rb
tracksperanto-3.3.0.pre lib/import/shake_grammar/catcher.rb