diff options
-rw-r--r-- | Lisp/conditions.lisp | 31 | ||||
-rw-r--r-- | Lisp/defpackage.lisp | 4 | ||||
-rw-r--r-- | Lisp/init.lisp | 107 | ||||
-rw-r--r-- | Lisp/internal-utilities.lisp | 10 | ||||
-rw-r--r-- | Lisp/libobjcl.lisp | 67 | ||||
-rw-r--r-- | Lisp/utilities.lisp | 123 |
6 files changed, 325 insertions, 17 deletions
diff --git a/Lisp/conditions.lisp b/Lisp/conditions.lisp index 7ed99b0..de65b2b 100644 --- a/Lisp/conditions.lisp +++ b/Lisp/conditions.lisp @@ -37,7 +37,19 @@ ;; The CLHS forbids the use of WITH-SLOTS for conditions. (format stream "~S does not designate a known selector." - (rejected-selector-designator condition))))) + (rejected-selector-designator condition)))) + (:documentation "Someone tried to dereference an invalid method selector. + +## Description: + +A **condition** of **type** __no-such-selector__ is **signal**led when +an attempt is made to retrieve a method selector by name, and that +selector cannot be found. This is most often the case when a typo is +made in the message name part of a method invocation. + +Note that this error will, at present, never be signalled on Mac OS X, +because __find-selector__ automatically interns selectors on that +system. This behaviour is subject to change.")) (define-condition message-not-understood (error) @@ -48,6 +60,19 @@ (:report (lambda (condition stream) (format stream "The Objective-C class ~S does not understand the ~ - message ~S." + message ~S." (rejecting-class condition) - (rejected-selector condition))))) + (rejected-selector condition)))) + (:documentation "The runtime is unable to retrieve the signature of a method. + +## Description: + +A **condition** of **type** __message-not-understood__ is **signal**led +when an attempt is made to call a method on an object that knows nothing +of it and can therefore not provide signature information for the +method. This is most often the case when an object is used at a place +that expects an object of a different Objective-C type (that is, it can +be regarded as a kind of type error), although it can also happen when a +typo is made in the message name part of a method invocation and a +__no-such-selector__ error is not **signal**led (on Mac OS X, for +example).")) diff --git a/Lisp/defpackage.lisp b/Lisp/defpackage.lisp index 34e7f1f..bb345b9 100644 --- a/Lisp/defpackage.lisp +++ b/Lisp/defpackage.lisp @@ -37,8 +37,8 @@ #:objc-equal ;; Macros - #:define-objc-struct - #:define-objc-union + #+(or) #:define-objc-struct + #+(or) #:define-objc-union ;; Special variables #:*trace-method-calls* diff --git a/Lisp/init.lisp b/Lisp/init.lisp index 94c87a1..a290a8d 100644 --- a/Lisp/init.lisp +++ b/Lisp/init.lisp @@ -35,3 +35,110 @@ ((:gnu) 'objcl-features:gnu-runtime) ((:next) 'objcl-features:next-runtime)) *features*)) + + +(setf (documentation '+nil+ 'variable) + "The Objective-C constant value `nil`. + +## Value Type: + +an **object** of type __id__. + + +## Description: + +__+nil+__ is the constant corresponding to the Objective-C `nil` value. + +__+nil+__ is not a value that any method invocation should return. +Whenever `nil` is returned by an Objective-C invocation, It is the job +of Objective-CL to convert it to __nil__. Similarly, __null__ arguments +are converted to `nil` automatically. Still, there may be occasions in +which it is useful to have `nil` as an __id__ instance. Therefore, it +is provided here. + +Note that, in the general case, `nil` is not necessarily equal to +`NULL`.") + + +(setf (documentation '+yes+ 'variable) + "The Objective-C boolean value `YES`. + +## Value Type: + +a **number**. + + +## Description: + +__+yes+__ is the constant corresponding to the Objective-C `YES` value. + +As there is no way to distinguish methods that return booleans from +those that return numbers in the Objective-C runtime, all invocations +that ought to return booleans will actually return one of two +compile-time Objective-C constants: either `YES` or `NO`. Lisp code +using Objective-CL needs to be aware of this and test return values +accordingly. For this to be possible, two **constant**s are defined on +the Lisp side, analogously to Objective-C. These are called __+yes+__ +and __+no+__. + + +## Examples: + + (invoke (find-class 'ns-string) + :is-subclass-of-class (find-class 'ns-object)) + ;=> #.YES + + (invoke (find-class 'ns-object) + :is-subclass-of-class (find-class 'ns-object)) + ;=> #.YES + + (invoke (find-class 'ns-object) + :is-subclass-of-class (find-class 'ns-string)) + ;=> #.NO + + +## See Also: + + __+no+__") + + +(setf (documentation '+no+ 'variable) + "The Objective-C boolean value `NO`. + +## Value Type: + +a **number**. + + +## Description: + +__+no+__ is the constant corresponding to the Objective-C `NO` value. + +As there is no way to distinguish methods that return booleans from +those that return numbers in the Objective-C runtime, all invocations +that ought to return booleans will actually return one of two +compile-time Objective-C constants: either `YES` or `NO`. Lisp code +using Objective-CL needs to be aware of this and test return values +accordingly. For this to be possible, two **constant**s are defined on +the Lisp side, analogously to Objective-C. These are called __+yes+__ +and __+no+__. + + +## Examples: + + (invoke (find-class 'ns-string) + :is-subclass-of-class (find-class 'ns-object)) + ;=> #.YES + + (invoke (find-class 'ns-object) + :is-subclass-of-class (find-class 'ns-object)) + ;=> #.YES + + (invoke (find-class 'ns-object) + :is-subclass-of-class (find-class 'ns-string)) + ;=> #.NO + + +## See Also: + + __+yes+__")
\ No newline at end of file diff --git a/Lisp/internal-utilities.lisp b/Lisp/internal-utilities.lisp index 29196c4..1a117f8 100644 --- a/Lisp/internal-utilities.lisp +++ b/Lisp/internal-utilities.lisp @@ -23,16 +23,6 @@ `(progn ,@body)) -(declaim (ftype (function (symbol * &rest *)))) -(defun apply-macro (macro-name arg &rest args) - "Because FOREIGN-FUNCALL is a macro. Why, oh why is this?" - (funcall - (compile nil - `(lambda () - (,macro-name ,@(butlast (cons arg args)) - ,@(car (last (cons arg args)))))))) - - (defmacro with-foreign-string-pool ((register-fn-name) &body body) (let ((pool-var (gensym))) `(let ((,pool-var (list))) diff --git a/Lisp/libobjcl.lisp b/Lisp/libobjcl.lisp index 5f8d80f..92a3f16 100644 --- a/Lisp/libobjcl.lisp +++ b/Lisp/libobjcl.lisp @@ -270,12 +270,79 @@ conventional case for namespace identifiers in Objective C." (declaim (ftype (function ((or objc-class id exception)) string) objc-class-name)) (defun objc-class-name (class) + "Find the name of a class. + +## Arguments and Values: + +*class* --- an **object** of **type** __objc-id__ or __objc-class__. + +Returns: *name* --- a **string**. + + +## Description: + +__objc-class-name__ returns the name of *class*. + + +## Examples: + + (objc-class-name (find-objc-class 'ns-object)) ;=> \"NSObject\" + + +## Note: + +If *x* is an **object** of **type** __objc-id__ or __objc-class__: + + (objc-eql x (find-objc-class (objc-class-name x))) ;=> T + +If *name* is the name of an existing class: + + (equal name (objc-class-name (find-objc-class name))) ;=> T + + +## See Also: + + __find-objc-class__" (declare (type (or objc-class id exception) class)) (%objcl-class-name (pointer-to class))) (declaim (ftype (function (selector) string) selector-name)) (defun selector-name (selector) + "Find the name of a selector. + +## Arguments and Values: + +*selector* --- an **object** of **type** __selector__. + +Returns: *name* --- a **string**. + + +## Description: + +__selector-name__ returns the name of *selector*. + + +## Examples: + + (selector-name (selector '(:string-with-c-string :encoding))) + ;=> \"stringWithCString:encoding:\" + + +## Note: + +If *x* is an **object** of **type** __selector__: + + (objc-equal x (find-selector (selector-name x))) ;=> T + +If *name* is the name of an existing selector: + + (equal name (selector-name (find-selector name))) ;=> T + + +## See Also: + + __find-selector__, __selector__" (declare (type selector selector)) (%objcl-selector-name (pointer-to selector))) diff --git a/Lisp/utilities.lisp b/Lisp/utilities.lisp index 9702fec..5ead57a 100644 --- a/Lisp/utilities.lisp +++ b/Lisp/utilities.lisp @@ -18,8 +18,127 @@ (in-package #:mulk.objective-cl) -(defgeneric objc-eql (x y)) -(defgeneric objc-equal (x y)) +(defgeneric objc-eql (x y) + (:documentation "Test whether two references point to the same object. + +## Arguments and Values: + +*x* --- an **object**. + +*y* --- an **object**. + +Returns: *the-same-p* --- a **generalized boolean**. + + +## Description: + +If at least one of the **object**s *x* and *y* is not an Objective-C +instance wrapper, __objc-eql__ behaves the same as __eql__. + +For Objective-C instance wrappers, __objc-eql__ compares the pointers +represented by these instances. If the pointers are _pointer-eq_ (see +the [CFFI manual][] for details), __objc-eql__ returns **true**. +Otherwise, it returns **false**. + + +## Examples: + + (objc-eql (find-objc-class 'ns-string) + (find-objc-class 'ns-string)) + ;=> T + + (objc-eql (find-objc-class 'ns-string) + (find-objc-class 'ns-object)) + ;=> NIL + + (setq greeting1 (invoke (find-objc-class 'ns-string) + :string-with-u-t-f-8-string \"Mulk.\")) + ;=> #<GSCBufferString `Mulk.' {8109A38}> + + (setq greeting2 (invoke (find-objc-class 'ns-string) + :string-with-u-t-f-8-string \"Mulk.\")) + ;=> #<GSCBufferString `Mulk.' {8109DB0}> + + (objc-equal greeting1 greeting2) + ;=> T + + (objc-eql greeting1 greeting2) + ;=> NIL + + (objc-equal greeting1 greeting1) + ;=> T + + (objc-eql greeting1 greeting1) + ;=> T + + +## See Also: + + __objc-equal__ + +[CFFI manual]: http://common-lisp.net/project/cffi/manual/html_node/index.html")) + + +(defgeneric objc-equal (x y) + (:documentation "Test whether two objects are equal. + +## Arguments and Values: + +*x* --- an **object**. + +*y* --- an **object**. + +Returns: *equal-p* --- a **generalized boolean**. + + +## Description: + +If at least one of the **object**s *x* and *y* is not an Objective-C +instance wrapper, __objc-equal__ behaves the same as __equal__. + +For Objective-C instance wrappers, __objc-equal__ behaves the same as +`(or (objc-eql x y) (invoke x :is-equal y) (invoke y :is-equal x))`, +except that it converts the return values of the invocations into +**generalized boolean**s before evaluating said expression. (Please +note that, as there is no way to distinguish methods that return +booleans from those that return numbers in the Objective-C runtime, the +invocations will return numbers.) + + +## Examples: + + (objc-equal (find-objc-class 'ns-string) + (find-objc-class 'ns-string)) + ;=> T + + (objc-equal (find-objc-class 'ns-string) + (find-objc-class 'ns-object)) + ;=> NIL + + (setq greeting1 (invoke (find-objc-class 'ns-string) + :string-with-u-t-f-8-string \"Mulk.\")) + ;=> #<GSCBufferString `Mulk.' {8109A38}> + + (setq greeting2 (invoke (find-objc-class 'ns-string) + :string-with-u-t-f-8-string \"Mulk.\")) + ;=> #<GSCBufferString `Mulk.' {8109DB0}> + + (objc-equal greeting1 greeting2) + ;=> T + + (objc-eql greeting1 greeting2) + ;=> NIL + + (objc-equal greeting1 greeting1) + ;=> T + + (objc-eql greeting1 greeting1) + ;=> T + + +## See Also: + + __objc-eql__, __invoke__")) (defun truep (b) |