~ubuntu-branches/ubuntu/maverick/slime/maverick

« back to all changes in this revision

Viewing changes to contrib/slime-parse.el

  • Committer: Bazaar Package Importer
  • Author(s): Peter Van Eynde
  • Date: 2009-04-14 22:26:54 UTC
  • mfrom: (1.1.6 upstream) (3.1.4 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090414222654-jnp412xlcfttfks8
Tags: 1:20090409-1
* New upstream version. 
  Code rewrite that (Closes: #410856)
  Also fixes the swank-in-swank problem (Closes: #457648)
* Removed xref.lisp again and added a test in the makefile for it
  (Closes: #517205)
* Fixed typo in swank-loader.lisp that creates spurious warnings.
  (Closes: #477265)
* add a conflict for emacs21. xemacs. Limiting compatiblity to
  emacs22 will already be a challenge.
  (Closes: #517839, #478355)
* Move to debhelper v7 
* updated standard version without any real changes 

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
             (slime-make-form-spec-from-string 
27
27
              (concat (slime-incomplete-sexp-at-point) ")"))))))))
28
28
 
29
 
;; XXX: unused function
30
 
(defun slime-cl-symbol-external-ref-p (symbol)
31
 
  "Does SYMBOL refer to an external symbol?
32
 
FOO:BAR is an external reference.
33
 
FOO::BAR is not, and nor is BAR."
34
 
  (let ((name (if (stringp symbol) symbol (symbol-name symbol))))
35
 
    (and (string-match ":" name)
36
 
         (not (string-match "::" name)))))
37
 
 
38
 
(defun slime-cl-symbol-name (symbol)
39
 
  (let ((n (if (stringp symbol) symbol (symbol-name symbol))))
40
 
    (if (string-match ":\\([^:]*\\)$" n)
41
 
        (let ((symbol-part (match-string 1 n)))
42
 
          (if (string-match "^|\\(.*\\)|$" symbol-part)
43
 
              (match-string 1 symbol-part)
44
 
              symbol-part))
45
 
      n)))
46
 
 
47
 
(defun slime-cl-symbol-package (symbol &optional default)
48
 
  (let ((n (if (stringp symbol) symbol (symbol-name symbol))))
49
 
    (if (string-match "^\\([^:]*\\):" n)
50
 
        (match-string 1 n)
51
 
      default)))
52
 
 
53
 
;; XXX: unused function
54
 
(defun slime-qualify-cl-symbol (symbol-or-name)
55
 
  "Like `slime-qualify-cl-symbol-name', but interns the result."
56
 
  (intern (slime-qualify-cl-symbol-name symbol-or-name)))
57
 
 
58
 
(defun slime-qualify-cl-symbol-name (symbol-or-name)
59
 
  "Return a package-qualified symbol-name that indicates the CL symbol
60
 
SYMBOL. If SYMBOL doesn't already have a package prefix the current
61
 
package is used."
62
 
  (let ((s (if (stringp symbol-or-name)
63
 
               symbol-or-name
64
 
             (symbol-name symbol-or-name))))
65
 
    (if (slime-cl-symbol-package s)
66
 
        s
67
 
      (format "%s::%s"
68
 
              (let* ((package (slime-current-package)))
69
 
                ;; package is a string like ":cl-user" or "CL-USER".
70
 
                (if (and package (string-match "^:" package))
71
 
                    (substring package 1)
72
 
                  package))
73
 
              (slime-cl-symbol-name s)))))
74
 
 
75
 
 
76
29
(defun slime-parse-sexp-at-point (&optional n skip-blanks-p)
77
 
  "Return the sexp at point as a string, otherwise nil.
78
 
If N is given and greater than 1, a list of all such sexps
79
 
following the sexp at point is returned. (If there are not
80
 
as many sexps as N, a list with < N sexps is returned.)
81
 
 
 
30
  "Returns the sexps at point as a list of strings, otherwise nil.
 
31
\(If there are not as many sexps as N, a list with < N sexps is
 
32
returned.\) 
82
33
If SKIP-BLANKS-P is true, leading whitespaces &c are skipped.
83
34
"
84
35
  (interactive "p") (or n (setq n 1))
85
36
  (flet ((sexp-at-point (first-choice)
86
37
           (let ((string (if (eq first-choice :symbol-first)
87
 
                             (or (slime-symbol-name-at-point)
 
38
                             (or (slime-symbol-at-point)
88
39
                                 (thing-at-point 'sexp))
89
40
                             (or (thing-at-point 'sexp)
90
 
                                 (slime-symbol-name-at-point)))))
 
41
                                 (slime-symbol-at-point)))))
91
42
             (if string (substring-no-properties string) nil))))
92
 
    ;; `thing-at-point' depends upon the current syntax table; otherwise
93
 
    ;; keywords like `:foo' are not recognized as sexps. (This function
94
 
    ;; may be called from temporary buffers etc.)
95
 
    (with-syntax-table lisp-mode-syntax-table
96
 
      (save-excursion
97
 
        (when skip-blanks-p ; e.g. `( foo bat)' where point is after ?\(.
98
 
          (slime-forward-blanks))
99
 
        (let ((result nil))
100
 
          (dotimes (i n)
101
 
            ;; `foo(bar baz)' where point is at ?\( or ?\).
102
 
            (if (and (char-after) (member (char-syntax (char-after)) '(?\( ?\) ?\')))
103
 
                (push (sexp-at-point :sexp-first) result)
104
 
                (push (sexp-at-point :symbol-first) result))
105
 
            (ignore-errors (forward-sexp) (slime-forward-blanks))
106
 
            (save-excursion
107
 
              (unless (slime-point-moves-p (ignore-errors (forward-sexp)))
108
 
                (return))))
109
 
          (if (slime-length= result 1)
110
 
              (first result)
111
 
              (nreverse result)))))))
 
43
    (save-excursion
 
44
      (when skip-blanks-p ; e.g. `( foo bat)' where point is after ?\(.
 
45
        (slime-forward-blanks))
 
46
      (let ((result nil))
 
47
        (dotimes (i n)
 
48
          (push (slime-sexp-at-point) result)
 
49
          ;; Skip current sexp
 
50
          (ignore-errors (forward-sexp) (slime-forward-blanks))
 
51
          ;; Is there an additional sexp in front of us?
 
52
          (save-excursion
 
53
            (unless (slime-point-moves-p (ignore-errors (forward-sexp)))
 
54
              (return))))
 
55
        (nreverse result)))))
 
56
 
 
57
(defun slime-has-symbol-syntax-p (string)
 
58
  (if (and string (not (zerop (length string))))
 
59
      (member (char-syntax (aref string 0)) 
 
60
              '(?w ?_ ?\' ?\\))))
112
61
 
113
62
(defun slime-incomplete-sexp-at-point (&optional n)
114
63
  (interactive "p") (or n (setq n 1))
139
88
          (slime-forward-blanks))
140
89
        (when parser
141
90
          (multiple-value-setq (forms indices points)
142
 
            (funcall parser op-name user-point forms indices points))))))
 
91
            ;; We pass the fully qualified name (`current-op'), so it's the
 
92
            ;; fully qualified name that will be sent to SWANK.
 
93
            (funcall parser current-op user-point forms indices points))))))
143
94
  (values forms indices points))
144
95
 
145
96
 
152
103
    ("CERROR"         . (slime-make-extended-operator-parser/look-ahead 2))
153
104
    ("CHANGE-CLASS"   . (slime-make-extended-operator-parser/look-ahead 2))
154
105
    ("DEFMETHOD"      . (slime-make-extended-operator-parser/look-ahead 1))
 
106
    ("DEFINE-COMPILER-MACRO" . (slime-make-extended-operator-parser/look-ahead 1))
155
107
    ("APPLY"          . (slime-make-extended-operator-parser/look-ahead 1))
156
108
    ("DECLARE"        . slime-parse-extended-operator/declare)
157
109
    ("DECLAIM"        . slime-parse-extended-operator/declare)
159
111
 
160
112
(defun slime-make-extended-operator-parser/look-ahead (steps)
161
113
  "Returns a parser that parses the current operator at point
162
 
plus STEPS-many additional sexps on the right side of the
163
 
operator."
 
114
plus (at most) STEPS-many additional sexps on the right side of
 
115
the operator."
164
116
  (lexical-let ((n steps))
165
117
    #'(lambda (name user-point current-forms current-indices current-points)
166
 
        (let ((old-forms (rest current-forms)))
167
 
          (let* ((args (slime-ensure-list (slime-parse-sexp-at-point n)))
168
 
                 (arg-specs (mapcar #'slime-make-form-spec-from-string args)))
169
 
            (setq current-forms (cons `(,name ,@arg-specs) old-forms))))
170
 
        (values current-forms current-indices current-points)
171
 
        )))
 
118
        (let ((old-forms (rest current-forms))
 
119
              (arg-idx   (first current-indices)))
 
120
          (when (and (not (zerop arg-idx)) ; point is at CAR of form?
 
121
                     (not (= (point)       ; point is at end of form?
 
122
                             (save-excursion
 
123
                               (ignore-errors (slime-end-of-list))
 
124
                               (point)))))
 
125
            (let* ((args (slime-parse-sexp-at-point n))
 
126
                   (arg-specs (mapcar #'slime-make-form-spec-from-string args)))
 
127
              (setq current-forms (cons `(,name ,@arg-specs) old-forms))))
 
128
          (values current-forms current-indices current-points)
 
129
          ))))
172
130
 
173
131
(defun slime-parse-extended-operator/declare
174
132
    (name user-point current-forms current-indices current-points)
259
217
                  (mapcar #'(lambda (s)
260
218
                              (assert (not (equal s string))) ; trap against
261
219
                              (slime-make-form-spec-from-string s)) ;  endless recursion.
262
 
                          (slime-ensure-list
263
 
                           (slime-parse-sexp-at-point (1+ n) t))))))))))
 
220
                          (slime-parse-sexp-at-point (1+ n) t)))))))))
264
221
 
265
222
 
266
223
(defun slime-enclosing-form-specs (&optional max-levels)
312
269
      (save-excursion
313
270
        ;; Make sure we get the whole thing at point.
314
271
        (if (not (slime-inside-string-p))
315
 
            (slime-end-of-symbol)
316
 
          (slime-beginning-of-string)
317
 
          (forward-sexp))
 
272
            (slime-end-of-symbol)
 
273
          (slime-beginning-of-string)
 
274
          (forward-sexp))
318
275
        (save-restriction
319
276
          ;; Don't parse more than 20000 characters before point, so we don't spend
320
277
          ;; too much time.
338
295
              (when (member (char-syntax (char-after)) '(?\( ?')) 
339
296
                (incf level)
340
297
                (forward-char 1)
341
 
                (let ((name (slime-symbol-name-at-point)))
 
298
                (let ((name (slime-symbol-at-point)))
342
299
                  (cond
343
300
                    (name
344
301
                     (save-restriction
345
302
                       (widen) ; to allow looking-ahead/back in extended parsing.
346
303
                       (multiple-value-bind (new-result new-indices new-points)
347
 
                           (slime-parse-extended-operator-name initial-point
348
 
                                                               (cons `(,name) result) ; minimal form spec
349
 
                                                               (cons arg-index arg-indices)
350
 
                                                               (cons (point) points))
 
304
                           (slime-parse-extended-operator-name 
 
305
                            initial-point
 
306
                            (cons `(,name) result) ; minimal form spec
 
307
                            (cons arg-index arg-indices)
 
308
                            (cons (point) points))
351
309
                         (setq result new-result)
352
310
                         (setq arg-indices new-indices)
353
311
                         (setq points new-points))))
366
324
  (if (listp thing) thing (list thing)))
367
325
 
368
326
(defun slime-inside-string-p ()
369
 
  (let* ((toplevel-begin (save-excursion (beginning-of-defun) (point)))
370
 
         (parse-result (parse-partial-sexp toplevel-begin (point)))
371
 
         (inside-string-p  (nth 3 parse-result))
372
 
         (string-start-pos (nth 8 parse-result)))
373
 
    (and inside-string-p string-start-pos)))
 
327
  (nth 3 (slime-current-parser-state)))
374
328
 
375
329
(defun slime-beginning-of-string ()
376
 
  (let ((string-start-pos (slime-inside-string-p)))
377
 
    (if string-start-pos
378
 
        (goto-char string-start-pos)
379
 
        (error "We're not within a string"))))
 
330
  (let* ((parser-state (slime-current-parser-state))
 
331
         (inside-string-p  (nth 3 parser-state))
 
332
         (string-start-pos (nth 8 parser-state)))
 
333
    (if inside-string-p
 
334
        (goto-char string-start-pos)
 
335
        (error "We're not within a string"))))
 
336
 
 
337
 
 
338
;;;; Test cases
 
339
 
 
340
(defun slime-check-enclosing-form-specs (wished-form-specs)
 
341
  (slime-test-expect 
 
342
   (format "Enclosing form specs correct in `%s' (at %d)" (buffer-string) (point))
 
343
   wished-form-specs
 
344
   (first (slime-enclosing-form-specs))))
 
345
 
 
346
(def-slime-test enclosing-form-specs.1
 
347
    (buffer-sexpr wished-form-specs)
 
348
    "Check that we correctly determine enclosing forms."
 
349
    '(("(defun *HERE*"                (("defun")))
 
350
      ("(defun foo *HERE*"            (("defun")))
 
351
      ("(defun foo (x y) *HERE*"      (("defun")))
 
352
      ("(defmethod *HERE*"            (("defmethod")))
 
353
      ("(defmethod foo *HERE*"        (("defmethod" "foo")))
 
354
      ("(cerror foo *HERE*"           (("cerror" "foo")))
 
355
      ("(cerror foo bar *HERE*"       (("cerror" "foo" "bar")))
 
356
      ("(make-instance foo *HERE*"    (("make-instance" "foo")))
 
357
      ("(apply 'foo *HERE*"           (("apply" "'foo")))
 
358
      ("(apply #'foo *HERE*"          (("apply" "#'foo")))
 
359
      ("(declare *HERE*"              (("declare")))
 
360
      ("(declare (optimize *HERE*"    ((:declaration ("optimize")) ("declare")))
 
361
      ("(declare (string *HERE*"      ((:declaration ("string")) ("declare")))
 
362
      ("(declare ((vector *HERE*"     ((:type-specifier ("vector"))))
 
363
      ("(declare ((vector bit *HERE*" ((:type-specifier ("vector" "bit")))))
 
364
  (slime-check-top-level)
 
365
  (with-temp-buffer
 
366
    (lisp-mode)
 
367
    (insert buffer-sexpr)
 
368
    (search-backward "*HERE*")
 
369
    (delete-region (match-beginning 0) (match-end 0))
 
370
    (slime-check-enclosing-form-specs wished-form-specs)
 
371
    (insert ")") (backward-char)
 
372
    (slime-check-enclosing-form-specs wished-form-specs)      
 
373
    ))
 
374
 
 
375
 
380
376
 
381
377
(provide 'slime-parse)
382
378