diff options
Diffstat (limited to 'Lisp/reader-syntax.lisp')
-rw-r--r-- | Lisp/reader-syntax.lisp | 110 |
1 files changed, 109 insertions, 1 deletions
diff --git a/Lisp/reader-syntax.lisp b/Lisp/reader-syntax.lisp index ccb4ff0..497253e 100644 --- a/Lisp/reader-syntax.lisp +++ b/Lisp/reader-syntax.lisp @@ -2,7 +2,115 @@ (defun install-reader-syntax () - "FIXME" + "Install an Objective-C-like **reader macro** for Objective C method + calls. + +## Description: + +The **reader macro** installed by __install-reader-syntax__ closely +resembles the conventional method call syntax of Objective C. In fact, +any differences between standard Objective C method call syntax and this +**reader macro** that are not documented here is probably a bug and +should be reported to the maintainer. + + +## Reader Macro: + +[\\{*receiver* | *class-name*\\} *message-name-part [[argument [[message-name-arg-pair]]*\\**]]*] + +message-name-arg-pair ::= *message-name-part argument* + + +## Reader Macro Arguments and Values: + +*receiver* --- an **object**. + +*class-name* --- a **symbol** (not evaluated). + +*message-name-part* --- a **symbol** (not evaluated). + +*argument* -- an **object**. + +Returns: *result* --- the result of the method invocation. + + +## Reader Macro Description: + +First, it is determined whether to regard the first element of the +form as an object or as a class name according to the following rules: + +1. If the element is no **symbol**, it is regarded as an object. + +2. Otherwise, if it is a **symbol** whose **name** starts with a +**lowercase** letter, it is regarded as an object. + +3. Otherwise, it is regarded as a class name. + +Next, the method call is parsed by alternately +reading *message name parts* and *arguments* separated by +whitespace. *Message name parts* are expected to consist of +**alphanumeric** **character**s and **colon**s, while *arguments* may +be arbitrary Lisp expressions. If any but the first *message name part* +does not end with a **colon**, the effects are undefined. Likewise, the +effects are undefined if any *message name part* contains a **colon** in +a position other than the end. + +After the parsing is done, all *message name parts* are concatenated in +order to form a single **string** that is used as if as the second +**argument** to __invoke-by-name__, and all *arguments* are collected in +order and the resulting **list** used as if as a **list** of additional +arguments to __invoke-by-name__. + + +## Reader Macro Examples: + + [NSString stringWithCString: \"Mulk.\"] + ;=> #<GSCBufferString `Mulk.' {5B36087}> + + [NSObject self] + ;=> #<NSObject `NSObject' {16ECF598}> + + [NSObject name] + ;=> \"NSObject\" + + [[[NSObject self] self] name] + ;=> \"NSObject\" + + [NSString stringWithCString: \"Mulk.\" encoding: 4] + ;=> #<GSCBufferString `Mulk.' {5B36087}> + + + +## Rationale: + +Objective C method names tend to be relatively verbose and are +frequently composed of many short words like \"of\" and \"by\". As a +result, using __invoke__ can be quite cumbersome at times and waste +screen real estate. One need only compare the example call + + (invoke (find-objc-class 'ns-string) + :string-with-c-string \"Mulk.\" + :encoding 4) + +with its reader macro counterpart + + [NSString stringWithCString: \"Mulk.\" encoding: 4] + +to be able to see an improvement in length as well as readability. + +In any case, it is a matter of taste whether to prefer __invoke__ or +Objective C syntax as it is whether to prefer the standard Common Lisp +__loop__ facility or a widespread and well-known alternative called +\"Iterate\". In both cases, one can argue that one of the forms +sacrifices an elusive quality of \"lispiness\" as well as text editor +friendliness in favor of natural-language-style readability and +conciseness. + + +## See also: + + __invoke__, __invoke-by-name__" + (set-macro-character #\] (get-macro-character #\))) (set-macro-character #\[ #'(lambda (stream char) |