class Lisp::PrimClassObject

Public Class Methods

add_method_impl(args, env) click to toggle source
# File lib/rubylisp/prim_class_object.rb, line 75
def self.add_method_impl(args, env)
  class_name = args.car
  return Lisp::Debug.process_error("'add-method' requires a class name as it's first argument.", env) unless class_name.string? || class_name.symbol?
  target_class = Object.const_get(class_name.to_s)
  return Lisp::Debug.process_error("'add-method' requires the name of an existing class.", env) if target_class.nil?

  method_name = args.cadr
  return Lisp::Debug.process_error("'add-method' requires a method name as it's second argument.", env) unless class_name.string? || class_name.symbol?

  body = args.caddr
  return Lisp::Debug.process_error("'add-method' requires a function as it's third argument.", env) unless body.function?
  
  target_class.send(:define_method, method_name.to_s) do |*args|
    local_env = Lisp::EnvironmentFrame.extending(env, "#{class_name.to_s}-#{method_name.to_s}")
    local_env.bind_locally(Symbol.named("self"), Lisp::NativeObject.with_value(self))
    processed_args = args.map {|a| Lisp::ClassObject.convert_to_lisp(a)}
    Lisp::PrimClassObject.convert_to_ruby(body.apply_to(Lisp::ConsCell.array_to_list(processed_args), local_env), local_env)
  end
  Lisp::String.with_value("OK")
end
add_static_method_impl(args, env) click to toggle source
# File lib/rubylisp/prim_class_object.rb, line 102
def self.add_static_method_impl(args, env)
  Lisp::String.with_value("NOT IMPLEMENTED")
end
convert_to_lisp(value) click to toggle source
# File lib/rubylisp/prim_class_object.rb, line 40
def self.convert_to_lisp(value)
  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_to_lisp(a)})
  else
    value.lisp_object? ? value : Lisp::NativeObject.with_value(value)
  end
end
convert_to_ruby(a, env) click to toggle source
# File lib/rubylisp/prim_class_object.rb, line 60
def self.convert_to_ruby(a, env)
  if a.nil?
    nil
  elsif a.function?
    proc do 
      a.apply_to(Lisp::ConsCell.new, env)
    end
  elsif a.list?
    a.to_a.map {|i| convert_to_ruby(i, env)}
  else
    a.value
  end
end
extend_impl(args, env) click to toggle source
# File lib/rubylisp/prim_class_object.rb, line 25
def self.extend_impl(args, env)
  class_name = args.car
  return Lisp::Debug.process_error("'extend' requires a name as it's first argument.", env) unless class_name.string? || class_name.symbol?
  super_class = Object.const_get(class_name.to_s)
  return Lisp::Debug.process_error("'extend' requires the name of an existing class as it's first argument.", env) if super_class.nil?

  new_class_name = args.cadr
  return Lisp::Debug.process_error("'extend' requires a name  as it's second argument.", env) unless new_class_name.string? || new_class_name.symbol?
  new_class = Class.new(super_class)
  return Lisp::Debug.process_error("'extend' requires the name of a new (i.e. nonexistant) class as it's second argument.", env) if Lisp.const_defined?(new_class_name.to_s)
  Object.const_set(new_class_name.to_s, new_class)
  ClassObject.with_class(new_class)
end
register() click to toggle source
# File lib/rubylisp/prim_class_object.rb, line 5
def self.register
  Primitive.register("extend", "2", "(extend parent child)\n\nCreates a new class named child that extends (i.e. inherits from) the class parent. The names (parent and child can be either stirngs or symbols). The new class is accessible by name and is returned.") do |args, env|
    Lisp::PrimClassObject::extend_impl(args, env)
  end
  
  Primitive.register("add-method", "3", "(add-method class selector function)\n\nAdd a method named selector to the class named class using function as it’s body. function can be a reference to a named function or, more likely, a lambda expression.") do |args, env|
    Lisp::PrimClassObject::add_method_impl(args, env)
  end
  
  Primitive.register("add-static-method", "Not Implemented.") do |args, env|
    Lisp::PrimClassObject::add_static_method_impl(args, env)
  end
  
  Primitive.register("super", "Not implemented.") do |args, env|
    Lisp::PrimClassObject::super_impl(args, env)
  end
  
end
super_impl(args, env) click to toggle source
# File lib/rubylisp/prim_class_object.rb, line 97
def self.super_impl(args, env)
  Lisp::String.with_value("NOT IMPLEMENTED")
end