summaryrefslogtreecommitdiff
path: root/Lisp/policy.lisp
blob: 9179ad696d0ee7addf2c76a67bf79ab55b08343f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
;;;; Objective-CL, an Objective-C bridge for Common Lisp.
;;;; Copyright (C) 2007  Matthias Andreas Benkard.
;;;;
;;;; This program is free software: you can redistribute it and/or
;;;; modify it under the terms of the GNU Lesser General Public License
;;;; as published by the Free Software Foundation, either version 3 of
;;;; the License, or (at your option) any later version.
;;;;
;;;; This program is distributed in the hope that it will be useful, but
;;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
;;;; Lesser General Public License for more details.
;;;;
;;;; You should have received a copy of the GNU Lesser General Public
;;;; License along with this program.  If not, see
;;;; <http://www.gnu.org/licenses/>.

(in-package #:mulk.objective-cl)


(defun define-returns-boolean-exception (selector-designator)
  "Define an exception to the rule that `char` means `BOOL` as a method return type.

## Arguments and Values:

*selector-designator* --- a *selector designator*.


## Description:

Normally, Objective-C treats method return values that are nominally of
type `char` as booleans and converts them to either __t__ or __nil__
depending on whether they are __zerop__.
__define-returns-boolean-exception__ directs Objective-CL to treat
`char` values returned by methods named by *selector-designator* as
numbers instead.

__undefine-returns-boolean-exception__ restores the default behaviour.


## Examples:

    (define-returns-boolean-exception \"charValue\")
    (define-returns-boolean-exception \"characterAtIndex:\")


## Rationale:

The Objective-C runtime offers no way of distinguishing booleans from
chars, even though Foundation defines a `BOOL` type.  In the vast
majority of cases, `char` therefore actually means `BOOL`, but the
`NSString` class, for one, wouldn't always agree with that sentiment, so
the only sane way of handling both booleans and actual `char` values is
to determine the intentional type by method selector.


## See also:

  __undefine-returns-boolean-exception__"
  (let ((key (typecase selector-designator
               (string selector-designator)
               (t (selector-name (selector selector-designator))))))
    (setf (gethash key *boolean-return-exceptions*) t)))


(defun undefine-returns-boolean-exception (selector-designator)
  "Revert the effect of __define-returns-boolean-exception__ for a given selector.

## Arguments and Values:

*selector-designator* --- a *selector designator*.


## Description:

Normally, Objective-C treats method return values that are nominally of
type `char` as booleans and converts them to either __t__ or __nil__
depending on whether they are __zerop__.
__define-returns-boolean-exception__ directs Objective-CL to treat
`char` values returned by methods named by *selector-designator* as
numbers instead.

__undefine-returns-boolean-exception__ restores the default behaviour.


## Examples:

    (undefine-returns-boolean-exception \"boolValue\")
    (undefine-returns-boolean-exception \"isEqual:\")


## Rationale:

The Objective-C runtime offers no way of distinguishing booleans from
chars, even though Foundation defines a `BOOL` type.  In the vast
majority of cases, `char` therefore actually means `BOOL`, but the
`NSString` class, for one, wouldn't always agree with that sentiment, so
the only sane way of handling both booleans and actual `char` values is
to determine the intentional type by method selector.


## See also:

  __define-returns-boolean-exception__"
  (let ((key (typecase selector-designator
               (string selector-designator)
               (t (selector-name (selector selector-designator))))))
    (remhash key *boolean-return-exceptions*)))


(define-returns-boolean-exception "charValue")
(define-returns-boolean-exception "characterAtIndex:")


(defun returned-char-is-bool-p (receiver selector)
  (declare (ignore receiver))
  (gethash (selector-name selector) *boolean-return-exceptions* nil))


(defun objc-char->lisp-value (objc-char char-is-bool-p)
  (if char-is-bool-p
      objc-char
      (not (zerop objc-char))))