Function: verilog-read-always-signals-recurse

verilog-read-always-signals-recurse is a byte-compiled function defined in verilog-mode.el.gz.

Signature

(verilog-read-always-signals-recurse EXIT-KEYWD RVALUE TEMP-NEXT)

Documentation

Recursive routine for parentheses/bracket matching.

EXIT-KEYWD is expression to stop at, nil if top level. RVALUE is true if at right hand side of equal. TEMP-NEXT is true to ignore next token, fake from inside case statement.

Source Code

;; Defined in /usr/src/emacs/lisp/progmodes/verilog-mode.el.gz
(defun verilog-read-always-signals-recurse
    (exit-keywd rvalue temp-next)
  "Recursive routine for parentheses/bracket matching.
EXIT-KEYWD is expression to stop at, nil if top level.
RVALUE is true if at right hand side of equal.
TEMP-NEXT is true to ignore next token, fake from inside case statement."
  (verilog--suppressed-warnings ((lexical sigs-temp sigs-in sigs-out-unk))
    ;; The local variable below are accessed via (symbol-value got-list).
    (defvar sigs-temp) (defvar sigs-in) (defvar sigs-out-unk))
  (let* ((semi-rvalue (equal "endcase" exit-keywd))  ; true if after a ; we are looking for rvalue
	 keywd last-keywd sig-tolk sig-last-tolk gotend got-sig got-list end-else-check
	 ignore-next)
    ;;(if dbg (setq dbg (concat dbg (format "Recursion %S %S %S\n" exit-keywd rvalue temp-next))))
    (while (not (or (eobp) gotend))
      (cond
       ((looking-at "//")
	(search-forward "\n"))
       ((looking-at "/\\*")
	(or (search-forward "*/")
	    (error "%s: Unmatched /* */, at char %d" (verilog-point-text) (point))))
       ((looking-at "(\\*")
	;; To advance past either "(*)" or "(* ... *)" don't forward past first *
	(forward-char 1)
	(or (search-forward "*)")
	    (error "%s: Unmatched (* *), at char %d" (verilog-point-text) (point))))
       (t (setq keywd (buffer-substring-no-properties
		       (point)
		       (save-excursion (when (eq 0 (skip-chars-forward "a-zA-Z0-9$_.%`"))
					 (forward-char 1))
				       (point)))
		sig-last-tolk sig-tolk
		sig-tolk nil)
	  ;;(if dbg (setq dbg (concat dbg (format "\tPt=%S %S\trv=%S in=%S ee=%S gs=%S\n" (point) keywd rvalue ignore-next end-else-check got-sig))))
	  (cond
	   ((equal keywd "\"")
	    (or (re-search-forward "[^\\]\"" nil t)
		(error "%s: Unmatched quotes, at char %d" (verilog-point-text) (point))))
	   ;; else at top level loop, keep parsing
	   ((and end-else-check (equal keywd "else"))
	    ;;(if dbg (setq dbg (concat dbg (format "\tif-check-else %s\n" keywd))))
	    ;; no forward movement, want to see else in lower loop
	    (setq end-else-check nil))
	   ;; End at top level loop
	   ((and end-else-check (looking-at "[^ \t\n\f]"))
	    ;;(if dbg (setq dbg (concat dbg (format "\tif-check-else-other %s\n" keywd))))
	    (setq gotend t))
	   ;; Final statement?
	   ((and exit-keywd (and (or (equal keywd exit-keywd)
                                     (and (equal exit-keywd "'}")
                                          (equal keywd "}")))
                                 (not (looking-at "::"))))
	    (setq gotend t)
	    (forward-char (length keywd)))
	   ;; Standard tokens...
	   ((equal keywd ";")
	    (setq ignore-next nil  rvalue semi-rvalue)
	    ;; Final statement at top level loop?
	    (when (not exit-keywd)
	      ;;(if dbg (setq dbg (concat dbg (format "\ttop-end-check %s\n" keywd))))
	      (setq end-else-check t))
	    (forward-char 1))
	   ((equal keywd "'")
	    (cond ((looking-at "'[sS]?[hdxboHDXBO]?[ \t]*[0-9a-fA-F_xzXZ?]+")
                   (goto-char (match-end 0)))
                  ((looking-at "'{")
                   (forward-char 2)
                   (verilog-read-always-signals-recurse "'}" t nil))
                  (t
                   (forward-char 1))))
           ((equal keywd ":")  ; Case statement, begin/end label, x?y:z
            (cond ((looking-at "::")
                   (forward-char 1))  ; Another forward-char below
                  ((equal "endcase" exit-keywd)  ; case x: y=z; statement next
		   (setq ignore-next nil rvalue nil))
                  ((equal "?" exit-keywd)  ; x?y:z rvalue
                   )  ; NOP
                  ((equal "]" exit-keywd)  ; [x:y] rvalue
                   )  ; NOP
                  ((equal "'}" exit-keywd)  ; Pattern assignment
                   )  ; NOP
                  (got-sig  ; label: statement
		   (setq ignore-next nil rvalue semi-rvalue got-sig nil))
                  ((not rvalue)  ; begin label
		   (setq ignore-next t rvalue nil)))
	    (forward-char 1))
	   ((equal keywd "=")
	    (when got-sig
	      ;;(if dbg (setq dbg (concat dbg (format "\t\tequal got-sig=%S got-list=%s\n" got-sig got-list))))
	      (set got-list (cons got-sig (symbol-value got-list)))
	      (setq got-sig nil))
	    (when (not rvalue)
	      (if (eq (char-before) ?< )
		  (setq sigs-out-d (append sigs-out-d sigs-out-unk)
			sigs-out-unk nil)
		(setq sigs-out-i (append sigs-out-i sigs-out-unk)
		      sigs-out-unk nil)))
	    (setq ignore-next nil rvalue t)
	    (forward-char 1))
	   ((equal keywd "?")
	    (forward-char 1)
	    (verilog-read-always-signals-recurse ":" rvalue nil))
	   ((equal keywd "[")
	    (forward-char 1)
	    (verilog-read-always-signals-recurse "]" t nil))
	   ((equal keywd "(")
	    (forward-char 1)
            (cond (sig-last-tolk  ; Function call; zap last signal
		   (setq got-sig nil)))
	    (cond ((equal last-keywd "for")
		   ;; temp-next: Variables on LHS are lvalues, but generally we want
		   ;; to ignore them, assuming they are loop increments
		   (verilog-read-always-signals-recurse ";" nil t)
		   (verilog-read-always-signals-recurse ";" t nil)
		   (verilog-read-always-signals-recurse ")" nil nil))
		  (t (verilog-read-always-signals-recurse ")" t nil))))
	   ((equal keywd "begin")
	    (skip-syntax-forward "w_")
	    (verilog-read-always-signals-recurse "end" nil nil)
	    ;;(if dbg (setq dbg (concat dbg (format "\tgot-end %s\n" exit-keywd))))
	    (setq ignore-next nil  rvalue semi-rvalue)
	    (if (not exit-keywd) (setq end-else-check t)))
	   ((member keywd '("case" "casex" "casez" "randcase"))
	    (skip-syntax-forward "w_")
	    (verilog-read-always-signals-recurse "endcase" t nil)
	    (setq ignore-next nil  rvalue semi-rvalue)
            (if (not exit-keywd) (setq gotend t)))  ; top level begin/end
           ((string-match "^[$`a-zA-Z_]" keywd)  ; not exactly word constituent
	    (cond ((member keywd '("`ifdef" "`ifndef" "`elsif"))
		   (setq ignore-next t))
		  ((or ignore-next
		       (member keywd verilog-keywords)
                       (string-match "^\\$" keywd))  ; PLI task
		   (setq ignore-next nil))
		  (t
		   (setq keywd (verilog-symbol-detick-denumber keywd))
		   (when got-sig
		     (set got-list (cons got-sig (symbol-value got-list)))
		     ;;(if dbg (setq dbg (concat dbg (format "\t\tgot-sig=%S got-list=%S\n" got-sig got-list))))
		     )
		   (setq got-list (cond (temp-next 'sigs-temp)
					(rvalue 'sigs-in)
					(t 'sigs-out-unk))
			 got-sig (if (or (not keywd)
					 (assoc keywd (symbol-value got-list)))
				     nil (list keywd nil nil))
			 temp-next nil
			 sig-tolk t)))
	    (skip-chars-forward "a-zA-Z0-9$_.%`"))
	   (t
	    (forward-char 1)))
	  ;; End of non-comment token
	  (setq last-keywd keywd)))
      (skip-syntax-forward " "))
    ;; Append the final pending signal
    (when got-sig
      ;;(if dbg (setq dbg (concat dbg (format "\t\tfinal got-sig=%S got-list=%s\n" got-sig got-list))))
      (set got-list (cons got-sig (symbol-value got-list)))
      (setq got-sig nil))
    ;;(if dbg (setq dbg (concat dbg (format "ENDRecursion %s\n" exit-keywd))))
    ))