Sha256: a1d84a2a8b28dea1294716a655dea3b15f9341df598976384d87b1b7e6f5d34c

Contents?: true

Size: 1.43 KB

Versions: 23

Compression:

Stored size: 1.43 KB

Contents

module Tracksperanto::ShakeGrammar
  # Will replay funcalls through to methods if such methods exist in the public insntance
  class Catcher < Lexer
  
    def push(atom_array)
      atom_name = atom_array[0]
      if atom_name == :funcall
        func, funcargs = atom_array[1], atom_array[2..-1]
        meth_for_shake_func = func.downcase
        if can_handle_meth?(meth_for_shake_func)
          super([:retval, exec_funcall(meth_for_shake_func, funcargs)])
        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
      elsif atom_name == :comment
        # Skip comments
      else
        super
      end
    end
    
    private
    
    def get_variable_name
      @stack[-2][1]
    end
    
    def can_handle_meth?(m)
      self.class.public_instance_methods(false).include?(m)
    end
    
    def exec_funcall(methname, args)
      ruby_args = unwrap_atoms_in_args(args)
      send(methname, *ruby_args)
    end
    
    def unwrap_atoms_in_args(args)
      args.map do | arg |
        (arg.is_a?(Array) && arg[0].is_a?(Symbol)) ? unwrap_atom(arg) : arg
      end
    end
    
    def unwrap_atom(atom)
      kind = atom.shift
      case kind
        when :retval, :atom_i, :atom_c, :atom_f
          atom.shift
        else
          :unknown
      end
    end

  end
end

Version data entries

23 entries across 23 versions & 1 rubygems

Version Path
tracksperanto-1.2.2 lib/import/shake_grammar/catcher.rb
tracksperanto-1.2.1 lib/import/shake_grammar/catcher.rb
tracksperanto-1.2.0 lib/import/shake_grammar/catcher.rb