Function: simula-search-backward
simula-search-backward is a byte-compiled function defined in
simula.el.gz.
Signature
(simula-search-backward REGEXP &optional BOUND NOERROR)
Documentation
Search backward from point for regular expression REGEXP, ignoring matches found inside SIMULA comments, string literals, and BEGIN..END blocks. Set point to the end of the occurrence found, and return point. An optional second argument BOUND bounds the search, it is a buffer position. The match found must not extend after that position. Optional third argument NOERROR, if t, means if fail just return nil (no error). If not nil and not t, move to limit of search and return nil.
Source Code
;; Defined in /usr/src/emacs/lisp/progmodes/simula.el.gz
(defun simula-search-backward (regexp &optional bound noerror)
"Search backward from point for regular expression REGEXP,
ignoring matches found inside SIMULA comments, string literals,
and BEGIN..END blocks.
Set point to the end of the occurrence found, and return point.
An optional second argument BOUND bounds the search, it is a buffer position.
The match found must not extend after that position. Optional third argument
NOERROR, if t, means if fail just return nil (no error).
If not nil and not t, move to limit of search and return nil."
(let ((comb-regexp (concat regexp "\\|\\<end\\>"))
(start-point (point))
context match)
(catch 'simula-backward
(while (re-search-backward comb-regexp bound 1)
;; We have a match, check SIMULA context at match-beginning
;; to see if we are outside comments etc.
;; Set MATCH to t if we found a true match,
;; set MATCH to 'BLOCK if we found a BEGIN..END block,
;; else set MATCH to nil.
(save-match-data
(setq context (simula-context))
(cond
((eq context nil)
(setq match (if (looking-at regexp) t 'BLOCK)))
;; A comment-ending `;' is part of the comment, and shouldn't match.
;; ((eq context 0)
;; (setq match (if (eq (following-char) ?\;) t nil)))
((eq context 2)
(setq match (if (and (looking-at regexp)
(looking-at ";\\|\\<end\\>\\|\\<else\\>\\|\\<otherwise\\>\\|\\<when\\>"))
t
(if (looking-at "\\<end\\>") 'BLOCK nil))))
(t (setq match nil))))
;; Exit if true match
(if (eq match t) (throw 'simula-backward (point)))
(if (eq match 'BLOCK)
;; We found the END of a block
(let ((level 0))
(while (natnump level)
(if (re-search-backward "\\<begin\\>\\|\\<end\\>" bound 1)
(let ((context (simula-context)))
;; We found a BEGIN -> decrease level count
(cond ((and (eq context nil)
(memq (following-char) '(?b ?B)))
(setq level (1- level)))
;; END -> increase level count
((and (memq context '(nil 2))
(memq (following-char) '(?e ?E)))
(setq level (1+ level)))))
;; Block search failed. Action depends on noerror.
(if (or (not noerror) (eq noerror t))
(goto-char start-point))
(if (not noerror)
(signal 'search-failed (list regexp)))
(throw 'simula-backward nil))))))
;; Search failed. Action depends on noerror.
(if (or (not noerror) (eq noerror t))
(goto-char start-point))
(if noerror
nil
(signal 'search-failed (list regexp))))))