class Lisp::FfiSend

Public Class Methods

new(name) click to toggle source
# File lib/rubylisp/ffi_send.rb, line 5
def initialize(name)
  @value = name.to_sym
end

Public Instance Methods

apply_to(args, env) click to toggle source
# File lib/rubylisp/ffi_send.rb, line 9
def apply_to(args, env)
  apply_to_without_evaluating(Lisp::ConsCell.array_to_list(args.to_a.map {|a| a.evaluate(env)}), env)
end
apply_to_without_evaluating(args, env) click to toggle source
# File lib/rubylisp/ffi_send.rb, line 55
def apply_to_without_evaluating(args, env)
  target = args.car
  return Lisp::Debug.process_error("Send target of '#{@value}' evaluated to nil.", env) if target.nil?
  return Lisp::Debug.process_error("Target of an FFI send of '#{@value}' must be a wrapped ObjC object, was #{target}", env) unless target.object?

  # puts "Sending #{@value} to #{target.to_s} with raw args #{args}"

  arguments = args.cdr.nil? ? [] : args.cdr.to_a.map {|a| process_arg(a, env)}      
  result = nil
  
  begin
    result = if arguments[-1].instance_of?(Proc)
               target.value.send(@value, *(arguments[0..-2]), &arguments[-1])
             else
               # puts "Sending #{@value} to #{target} with processed args #{arguments}"
               target.value.send(@value, *arguments)
             end
  rescue Exception => e
    return Lisp::Debug.process_error("Exception sending #{@value} - #{e.name}", env)
  end

  convert_value(result)
end
convert_value(value) click to toggle source

convert a rubymotion arg to a lisp arg

# File lib/rubylisp/ffi_send.rb, line 14
def convert_value(value)
  #puts "convert_value(#{value.to_s})\n"
  case value.class.name
  when "Fixnum", "Float"
    Lisp::Number.with_value(value)
  when "TrueClass"
    Lisp::Boolean.TRUE
  when "FalseClass"
    Lisp::Boolean.FALSE
  when "String"
    Lisp::String.with_value(value)
  when "Symbol"
    Lisp::Symbol.named(value)
  when "Array"
    Lisp::ConsCell.array_to_list(value.map {|a| convert_value(a)})
  else
    Lisp::NativeObject.with_value(value)
  end
end
primitive?() click to toggle source
# File lib/rubylisp/ffi_send.rb, line 83
def primitive?
  true
end
process_arg(a, env) click to toggle source

convert a lisp arg to a rubymotion arg

# File lib/rubylisp/ffi_send.rb, line 36
def process_arg(a, env)
  #puts "process_arg(#{a.to_s})"
  if a.function?
    #puts "function arg"
    proc do #|*args|
      #puts "Proc argument invoked"
      # arg_list = args.empty? ? nil : Lisp::ConsCell.array_to_list(args.collect {|arg| convert_value(arg) })
      # puts "Applying #{@a.to_s} to #{arg_list}"
     
      a.apply_to(nil, env)
    end
  elsif a.list?
    a.to_a.map {|i| process_arg(i, env)}
  else
    a.value
  end
end
to_s() click to toggle source
# File lib/rubylisp/ffi_send.rb, line 79
def to_s
  ".#{@value}"
end
type() click to toggle source
# File lib/rubylisp/ffi_send.rb, line 87
def type
  :primitive
end