Class: Lisp::PrimClassObject
- Defined in:
- lib/rubylisp/prim_class_object.rb
Class Method Summary collapse
- .add_method_impl(args, env) ⇒ Object
- .add_static_method_impl(args, env) ⇒ Object
- .convert_to_lisp(value) ⇒ Object
- .convert_to_ruby(a, env) ⇒ Object
- .extend_impl(args, env) ⇒ Object
- .register ⇒ Object
- .super_impl(args, env) ⇒ Object
Class Method Details
.add_method_impl(args, env) ⇒ Object
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/rubylisp/prim_class_object.rb', line 76 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) ⇒ Object
103 104 105 |
# File 'lib/rubylisp/prim_class_object.rb', line 103 def self.add_static_method_impl(args, env) Lisp::String.with_value("NOT IMPLEMENTED") end |
.convert_to_lisp(value) ⇒ Object
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/rubylisp/prim_class_object.rb', line 41 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) ⇒ Object
61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/rubylisp/prim_class_object.rb', line 61 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) ⇒ Object
26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/rubylisp/prim_class_object.rb', line 26 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 ⇒ Object
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/rubylisp/prim_class_object.rb', line 6 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) ⇒ Object
98 99 100 |
# File 'lib/rubylisp/prim_class_object.rb', line 98 def self.super_impl(args, env) Lisp::String.with_value("NOT IMPLEMENTED") end |