From 5a5cccb6ac8b4511195b5a1348e29b3ee1cba4ad Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Mon, 29 Mar 2021 18:35:01 -0400 Subject: [PATCH] lisp/progmodes/verilog-mode.el: Prepare for lexical-binding. * lisp/progmodes/verilog-mode.el: Activate lexical-binding. Insert newlines to avoid some situations where arguments were easy to misunderstand. (verilog-set-compile-command): Strength-reduce `eval` to `symbol-value`. (verilog-error-regexp-add-emacs): Replace `mapcar` => `mapc` since the result is not used. (verilog-surelint-off): Remove always-nil var `dir`. (verilog-do-indent): Minor simplification of the code. (verilog-pred): Delete var. It was always nil. (verilog-flag): Delete var; pass the corresponding data via explicit arguments instead. (verilog-keyword-completion): Use `dolist`. (verilog-completion-response): Rename to `verilog--complete-with-action`. Change calling convention to match that of `complete-with-action`. Use `complete-with-action` instead when available. Adjust all callers. (verilog-completion, verilog-comp-defun): Change arg names so they don't collide with dynamically scoped vars, and let-bind `verilog-str` explicitly instead. Use `with-current-buffer`. (verilog-batch-execute-func): Use `with-current-buffer`. (verilog-complete-word): Don't convert the completion list into a completion alist, since lists work just as well. (verilog-showscopes): Use `with-current-buffer`. (verilog-symbol-detick, verilog-symbol-detick-text) (verilog-signals-matching-enum): Strength-reduce `eval` to `symbol-value`. (verilog--insert-indent): Rename from `verilog--insert-indent`. Add `indent-pt` argument. (verilog-insert-indent): New macro wrapper to provide the old calling convention. (verilog-auto-assign-modport, verilog-auto-inout-modport): Remove always-nil var `direction-re`. (verilog--auto-inst-first): Rename from `verilog-auto-inst-first`. Add `indent-pt` argument. (verilog-auto-inst-port): Adjust call accordingly. --- lisp/progmodes/verilog-mode.el | 289 +++++++++++++++++---------------- 1 file changed, 145 insertions(+), 144 deletions(-) diff --git a/lisp/progmodes/verilog-mode.el b/lisp/progmodes/verilog-mode.el index 9f7285ca40c..8ba3483bcca 100644 --- a/lisp/progmodes/verilog-mode.el +++ b/lisp/progmodes/verilog-mode.el @@ -9,7 +9,7 @@ ;; Keywords: languages ;; The "Version" is the date followed by the decimal rendition of the Git ;; commit hex. -;; Version: 2021.03.29.211984233 +;; Version: 2021.03.29.215531170 ;; Yoni Rabkin contacted the maintainer of this ;; file on 19/3/2008, and the maintainer agreed that when a bug is @@ -124,7 +124,7 @@ ;; ;; This variable will always hold the version number of the mode -(defconst verilog-mode-version "2021-03-29-ca29f69-vpo-GNU" +(defconst verilog-mode-version "2021-03-29-cd8bea2-vpo-GNU" "Version of this Verilog mode.") (defconst verilog-mode-release-emacs t "If non-nil, this version of Verilog mode was released with Emacs itself.") @@ -2013,9 +2013,10 @@ portion, will be substituted." (t (set (make-local-variable 'compile-command) (if verilog-tool - (if (string-match "%s" (eval verilog-tool)) - (format (eval verilog-tool) (or buffer-file-name "")) - (concat (eval verilog-tool) " " (or buffer-file-name ""))) + (let ((cmd (symbol-value verilog-tool))) + (if (string-match "%s" cmd) + (format cmd (or buffer-file-name "")) + (concat cmd " " (or buffer-file-name "")))) "")))) (verilog-modify-compile-command)) @@ -2102,7 +2103,7 @@ find the errors." (interactive) (when (boundp 'compilation-error-regexp-alist-alist) (when (not (assoc 'verilog-xl-1 compilation-error-regexp-alist-alist)) - (mapcar + (mapc (lambda (item) (push (car item) compilation-error-regexp-alist) (push item compilation-error-regexp-alist-alist)) @@ -5459,8 +5460,7 @@ becomes: (let* ((code (match-string 2)) (file (match-string 3)) (line (match-string 4)) - (buffer (get-file-buffer file)) - dir filename) + (buffer (get-file-buffer file))) (unless buffer (progn (setq buffer @@ -5472,9 +5472,8 @@ becomes: (read-file-name (format "Find this error in: (default %s) " file) - dir file t)))) - (if (file-directory-p name) - (setq name (expand-file-name filename name))) + nil ;; dir + file t)))) (setq buffer (and (file-exists-p name) (find-file-noselect name)))))))) @@ -5617,12 +5616,11 @@ Save the result unless optional NO-SAVE is t." ;; Process the files (mapc (lambda (buf) (when (buffer-file-name buf) - (save-excursion - (if (not (file-exists-p (buffer-file-name buf))) - (error - "File not found: %s" (buffer-file-name buf))) - (message "Processing %s" (buffer-file-name buf)) - (set-buffer buf) + (if (not (file-exists-p (buffer-file-name buf))) + (error + "File not found: %s" (buffer-file-name buf))) + (message "Processing %s" (buffer-file-name buf)) + (with-current-buffer buf (funcall funref) (verilog-star-cleanup) (when (and (not no-save) @@ -6864,16 +6862,19 @@ Only look at a few lines to determine indent level." (indent-line-to val))) (t (goto-char here) - (let ((val)) - (verilog-beg-of-statement-1) - (if (and (< (point) here) - (verilog-re-search-forward "=[ \t]*" here 'move) - ;; not at a |=>, #=#, or [=n] operator - (not (string-match "\\[=.\\|#=#\\||=>" - (or (buffer-substring (- (point) 2) (1+ (point))) - "")))) ; don't let buffer over/under-run spoil the party - (setq val (current-column)) - (setq val (eval (cdr (assoc type verilog-indent-alist))))) + (verilog-beg-of-statement-1) + (let ((val + (if (and (< (point) here) + (verilog-re-search-forward "=[ \t]*" here 'move) + ;; not at a |=>, #=#, or [=n] operator + (not (string-match "\\[=.\\|#=#\\||=>" + (or (buffer-substring + (- (point) 2) (1+ (point))) + ;; Don't let buffer over/under + ;; run spoil the party. + "")))) + (current-column) + (eval (cdr (assoc type verilog-indent-alist)))))) (goto-char here) (indent-line-to val)))))) @@ -7309,7 +7310,8 @@ BASEIND is the base indent to offset everything." (if (verilog-re-search-backward (or (and verilog-indent-declaration-macros verilog-declaration-re-1-macro) - verilog-declaration-re-1-no-macro) lim t) + verilog-declaration-re-1-no-macro) + lim t) (progn (goto-char (match-end 0)) (skip-chars-forward " \t") @@ -7427,9 +7429,7 @@ BEG and END." ;; (defvar verilog-str nil) (defvar verilog-all nil) -(defvar verilog-pred nil) (defvar verilog-buffer-to-use nil) -(defvar verilog-flag nil) (defvar verilog-toggle-completions nil "True means \\\\[verilog-complete-word] should try all possible completions one by one. Repeated use of \\[verilog-complete-word] will show you all of them. @@ -7576,9 +7576,7 @@ TYPE is `module', `tf' for task or function, or t if unknown." (while (verilog-re-search-forward verilog-str (point-max) t) (progn (setq match (buffer-substring (match-beginning 2) (match-end 2))) - (if (or (null verilog-pred) - (funcall verilog-pred match)) - (setq verilog-all (cons match verilog-all))))) + (setq verilog-all (cons match verilog-all)))) (if (match-beginning 0) (goto-char (match-beginning 0))))) @@ -7598,9 +7596,7 @@ for matches of `str' and adding the occurrence tp `all' through point END." (not (match-end 1))) (setq match (buffer-substring (match-beginning 0) (match-end 0))) (if (string-match (concat "\\<" verilog-str) match) - (if (or (null verilog-pred) - (funcall verilog-pred match)) - (setq verilog-all (cons match verilog-all))))) + (setq verilog-all (cons match verilog-all)))) (forward-line 1))) verilog-all) @@ -7615,28 +7611,25 @@ for matches of `str' and adding the occurrence tp `all' through point END." (defun verilog-keyword-completion (keyword-list) "Give list of all possible completions of keywords in KEYWORD-LIST." - (mapcar (lambda (s) - (if (string-match (concat "\\<" verilog-str) s) - (if (or (null verilog-pred) - (funcall verilog-pred s)) - (setq verilog-all (cons s verilog-all))))) - keyword-list)) - - -(defun verilog-completion (verilog-str verilog-pred verilog-flag) - "Function passed to `completing-read', `try-completion' or `all-completions'. -Called to get completion on VERILOG-STR. If VERILOG-PRED is non-nil, it -must be a function to be called for every match to check if this should -really be a match. If VERILOG-FLAG is t, the function returns a list of -all possible completions. If VERILOG-FLAG is nil it returns a string, -the longest possible completion, or t if VERILOG-STR is an exact match. -If VERILOG-FLAG is `lambda', the function returns t if VERILOG-STR is an -exact match, nil otherwise." - (save-excursion - (let ((verilog-all nil)) - ;; Set buffer to use for searching labels. This should be set - ;; within functions which use verilog-completions - (set-buffer verilog-buffer-to-use) + (dolist (s keyword-list) + (if (string-match (concat "\\<" verilog-str) s) + (push s verilog-all)))) + + +(defun verilog-completion (str pred flag) + "Completion table for Verilog tokens. +Function passed to `completing-read', `try-completion' or `all-completions'. +Called to get completion on STR. +If FLAG is t, the function returns a list of all possible completions. +If FLAG is nil it returns a string, the longest possible completion, +or t if STR is an exact match. +If FLAG is `lambda', the function returns t if STR is an exact match, +nil otherwise." + (let ((verilog-str str) + (verilog-all nil)) + ;; Set buffer to use for searching labels. This should be set + ;; within functions which use verilog-completions + (with-current-buffer verilog-buffer-to-use ;; Determine what should be completed (let ((state (car (verilog-calculate-indent)))) @@ -7678,43 +7671,47 @@ exact match, nil otherwise." (verilog-keyword-completion verilog-separator-keywords)))) ;; Now we have built a list of all matches. Give response to caller - (verilog-completion-response)))) - -(defun verilog-completion-response () - (cond ((or (equal verilog-flag 'lambda) (null verilog-flag)) - ;; This was not called by all-completions - (if (null verilog-all) - ;; Return nil if there was no matching label - nil - ;; Get longest string common in the labels - ;; FIXME: Why not use `try-completion'? - (let* ((elm (cdr verilog-all)) - (match (car verilog-all)) - (min (length match)) - tmp) - (if (string= match verilog-str) - ;; Return t if first match was an exact match - (setq match t) - (while (not (null elm)) - ;; Find longest common string - (if (< (setq tmp (verilog-string-diff match (car elm))) min) - (progn - (setq min tmp) - (setq match (substring match 0 min)))) - ;; Terminate with match=t if this is an exact match - (if (string= (car elm) verilog-str) - (progn - (setq match t) - (setq elm nil)) - (setq elm (cdr elm))))) - ;; If this is a test just for exact match, return nil ot t - (if (and (equal verilog-flag 'lambda) (not (equal match 't))) - nil - match)))) - ;; If flag is t, this was called by all-completions. Return - ;; list of all possible completions - (verilog-flag - verilog-all))) + (verilog--complete-with-action flag verilog-all verilog-str pred)))) + + +(defalias 'verilog--complete-with-action + (if (fboundp 'complete-with-action) + #'complete-with-action + (lambda (flag collection string _predicate) + (cond ((or (equal flag 'lambda) (null flag)) + ;; This was not called by all-completions + (if (null collection) + ;; Return nil if there was no matching label + nil + ;; Get longest string common in the labels + (let* ((elm (cdr collection)) + (match (car collection)) + (min (length match)) + tmp) + (if (string= match string) + ;; Return t if first match was an exact match + (setq match t) + (while (not (null elm)) + ;; Find longest common string + (if (< (setq tmp (verilog-string-diff match (car elm))) + min) + (progn + (setq min tmp) + (setq match (substring match 0 min)))) + ;; Terminate with match=t if this is an exact match + (if (string= (car elm) string) + (progn + (setq match t) + (setq elm nil)) + (setq elm (cdr elm))))) + ;; If this is a test just for exact match, return nil ot t + (if (and (equal flag 'lambda) (not (equal match 't))) + nil + match)))) + ;; If flag is t, this was called by all-completions. Return + ;; list of all possible completions + (flag + collection))))) (defvar verilog-last-word-numb 0) (defvar verilog-last-word-shown nil) @@ -7748,9 +7745,7 @@ and `verilog-separator-keywords'.)" (verilog-str (buffer-substring b e)) (allcomp (nth 2 comp-info)) (match (if verilog-toggle-completions - "" (try-completion - verilog-str (mapcar (lambda (elm) - (cons elm 0)) allcomp))))) + "" (try-completion verilog-str allcomp)))) ;; Delete old string (delete-region b e) @@ -7822,39 +7817,38 @@ With optional second ARG non-nil, STR is the complete name of the instruction." (setq str (concat str "[a-zA-Z0-9_]*"))) (concat "^\\s-*\\(function\\|task\\|module\\)[ \t]+\\(?:\\(?:static\\|automatic\\)\\s-+\\)?\\(" str "\\)\\>")) -(defun verilog-comp-defun (verilog-str verilog-pred verilog-flag) - "Function passed to `completing-read', `try-completion' or `all-completions'. -Returns a completion on any function name based on VERILOG-STR prefix. If -VERILOG-PRED is non-nil, it must be a function to be called for every match -to check if this should really be a match. If VERILOG-FLAG is t, the -function returns a list of all possible completions. If it is nil it -returns a string, the longest possible completion, or t if VERILOG-STR is -an exact match. If VERILOG-FLAG is `lambda', the function returns t if -VERILOG-STR is an exact match, nil otherwise." - (save-excursion - (let ((verilog-all nil) - match) - - ;; Set buffer to use for searching labels. This should be set - ;; within functions which use verilog-completions - (set-buffer verilog-buffer-to-use) +(defun verilog-comp-defun (str pred flag) + "Completion table for function names. +Function passed to `completing-read', `try-completion' or `all-completions'. +Returns a completion on any function name based on STR prefix. +If FLAG is t, the function returns a list of all possible completions. +If it is nil it returns a string, the longest possible completion, +or t if STR is an exact match. +If FLAG is `lambda', the function returns t if STR is an exact match, +nil otherwise." + (let ((verilog-all nil) + (verilog-str str) + match) + + ;; Set buffer to use for searching labels. This should be set + ;; within functions which use verilog-completions + (with-current-buffer verilog-buffer-to-use (let ((verilog-str verilog-str)) ;; Build regular expression for functions - (if (string= verilog-str "") - (setq verilog-str (verilog-build-defun-re "[a-zA-Z_]")) - (setq verilog-str (verilog-build-defun-re verilog-str))) + (setq verilog-str + (verilog-build-defun-re (if (string= verilog-str "") + "[a-zA-Z_]" + verilog-str))) (goto-char (point-min)) ;; Build a list of all possible completions (while (verilog-re-search-forward verilog-str nil t) (setq match (buffer-substring (match-beginning 2) (match-end 2))) - (if (or (null verilog-pred) - (funcall verilog-pred match)) - (setq verilog-all (cons match verilog-all))))) + (setq verilog-all (cons match verilog-all)))) ;; Now we have built a list of all matches. Give response to caller - (verilog-completion-response)))) + (verilog--complete-with-action flag verilog-all verilog-str pred)))) (defun verilog-goto-defun () "Move to specified Verilog module/interface/task/function. @@ -7931,10 +7925,9 @@ If search fails, other files are checked based on (tag (format "%3d" linenum)) (empty (make-string (length tag) ?\ )) tem) - (save-excursion - (setq tem (make-marker)) - (set-marker tem (point)) - (set-buffer standard-output) + (setq tem (make-marker)) + (set-marker tem (point)) + (with-current-buffer standard-output (setq occur-pos-list (cons tem occur-pos-list)) (or first (zerop nlines) (insert "--------\n")) @@ -10098,7 +10091,7 @@ If undefined, and WING-IT, return just SYMBOL without the tick, else nil." ;; variable in only one buffer returns t in another. ;; This can confuse, so check for nil. ;; Namespace intentionally short for AUTOs and compatibility - (let ((val (eval (intern (concat "vh-" symbol))))) + (let ((val (symbol-value (intern (concat "vh-" symbol))))) (if (eq val nil) (if wing-it symbol nil) val)) @@ -10137,7 +10130,7 @@ This function is intended for use in AUTO_TEMPLATE Lisp expressions." ;; variable in only one buffer returns t in another. ;; This can confuse, so check for nil. ;; Namespace intentionally short for AUTOs and compatibility - (setq val (eval (intern (concat "vh-" symbol))))) + (setq val (symbol-value (intern (concat "vh-" symbol))))) (setq text (replace-match val nil nil text))) (t (setq ok nil))))) text) @@ -10492,7 +10485,7 @@ those clocking block's signals." ;; New scheme ;; Namespace intentionally short for AUTOs and compatibility (let* ((enumvar (intern (concat "venum-" enum)))) - (dolist (en (and (boundp enumvar) (eval enumvar))) + (dolist (en (and (boundp enumvar) (symbol-value enumvar))) (let ((sig (list en))) (unless (member sig out-list) (push sig out-list))))) @@ -10697,9 +10690,7 @@ When MODI is non-null, also add to modi-cache, for tracking." (verilog-insert "// " (verilog-sig-comment sig) "\n")) (setq sigs (cdr sigs))))) -(defvar indent-pt) ;; Local used by `verilog-insert-indent'. - -(defun verilog-insert-indent (&rest stuff) +(defun verilog--insert-indent (indent-pt &rest stuff) "Indent to position stored in local `indent-pt' variable, then insert STUFF. Presumes that any newlines end a list element." (let ((need-indent t)) @@ -10709,6 +10700,10 @@ Presumes that any newlines end a list element." (verilog-insert (car stuff)) (setq need-indent (string-match "\n$" (car stuff)) stuff (cdr stuff))))) + +(defmacro verilog-insert-indent (&rest stuff) + `(verilog--insert-indent indent-pt ,@stuff)) + ;;(let ((indent-pt 10)) (verilog-insert-indent "hello\n" "addon" "there\n")) (defun verilog-forward-or-insert-line () @@ -11517,7 +11512,8 @@ See the example in `verilog-auto-inout-modport'." (inst-name (nth 2 params)) (regexp (nth 3 params)) (prefix (nth 4 params)) - direction-re submodi) ; direction argument not supported until requested + ;; direction-re ; direction argument not supported until requested + submodi) ;; Lookup position, etc of co-module ;; Note this may raise an error (when (setq submodi (verilog-modi-lookup submod t)) @@ -11538,11 +11534,11 @@ See the example in `verilog-auto-inout-modport'." (setq sig-list-i (verilog-signals-edit-wire-reg (verilog-signals-matching-dir-re (verilog-signals-matching-regexp sig-list-i regexp) - "input" direction-re)) + "input" nil)) ;; direction-re sig-list-o (verilog-signals-edit-wire-reg (verilog-signals-matching-dir-re (verilog-signals-matching-regexp sig-list-o regexp) - "output" direction-re))) + "output" nil))) ;; direction-re (setq sig-list-i (sort (copy-alist sig-list-i) #'verilog-signals-sort-compare)) (setq sig-list-o (sort (copy-alist sig-list-o) #'verilog-signals-sort-compare)) (when (or sig-list-i sig-list-o) @@ -11683,7 +11679,7 @@ If PAR-VALUES replace final strings with these parameter values." (setq tpl-net (verilog-string-replace-matches "\\[\\]" vl-bits nil nil tpl-net))) ;; Insert it (when (or tpl-ass (not verilog-auto-inst-template-required)) - (verilog-auto-inst-first section) + (verilog--auto-inst-first indent-pt section) (indent-to indent-pt) (insert "." port) (unless (and verilog-auto-inst-dot-name @@ -11722,7 +11718,7 @@ If PAR-VALUES replace final strings with these parameter values." (defvar verilog-auto-inst-first-any nil "Local first-in-any-section for `verilog-auto-inst-first'.") -(defun verilog-auto-inst-first (section) +(defun verilog--auto-inst-first (indent-pt section) "Insert , and SECTION before port, as part of \\[verilog-auto-inst]." ;; Do we need a trailing comma? ;; There maybe an ifdef or something similar before us. What a mess. Thus @@ -12956,21 +12952,25 @@ that expression are included." (verilog-signals-not-matching-regexp (verilog-signals-matching-dir-re (verilog-signals-matching-regexp sig-list-i regexp) - "input" direction-re) not-re)) + "input" direction-re) + not-re)) sig-list-o (verilog-signals-edit-wire-reg (verilog-signals-not-matching-regexp (verilog-signals-matching-dir-re (verilog-signals-matching-regexp sig-list-o regexp) - "output" direction-re) not-re)) + "output" direction-re) + not-re)) sig-list-io (verilog-signals-edit-wire-reg (verilog-signals-not-matching-regexp (verilog-signals-matching-dir-re (verilog-signals-matching-regexp sig-list-io regexp) - "inout" direction-re) not-re)) + "inout" direction-re) + not-re)) sig-list-if (verilog-signals-not-matching-regexp (verilog-signals-matching-dir-re (verilog-signals-matching-regexp sig-list-if regexp) - "interface" direction-re) not-re)) + "interface" direction-re) + not-re)) (when v2k (verilog-repair-open-comma)) (when (or sig-list-i sig-list-o sig-list-io sig-list-if) (verilog-insert-indent "// Beginning of automatic in/out/inouts (from specific module)\n") @@ -13256,7 +13256,8 @@ driver/monitor using AUTOINST in the testbench." (modport-re (nth 1 params)) (regexp (nth 2 params)) (prefix (nth 3 params)) - direction-re submodi) ; direction argument not supported until requested + ;; direction-re ; direction argument not supported until requested + submodi) ;; Lookup position, etc of co-module ;; Note this may raise an error (when (setq submodi (verilog-modi-lookup submod t)) @@ -13287,7 +13288,7 @@ driver/monitor using AUTOINST in the testbench." (verilog-signals-add-prefix (verilog-signals-matching-dir-re (verilog-signals-matching-regexp sig-list-i regexp) - "input" direction-re) + "input" nil) ;; direction-re prefix) (verilog-decls-get-ports moddecls))) sig-list-o (verilog-signals-edit-wire-reg @@ -13295,7 +13296,7 @@ driver/monitor using AUTOINST in the testbench." (verilog-signals-add-prefix (verilog-signals-matching-dir-re (verilog-signals-matching-regexp sig-list-o regexp) - "output" direction-re) + "output" nil) ;; direction-re prefix) (verilog-decls-get-ports moddecls))) sig-list-io (verilog-signals-edit-wire-reg @@ -13303,7 +13304,7 @@ driver/monitor using AUTOINST in the testbench." (verilog-signals-add-prefix (verilog-signals-matching-dir-re (verilog-signals-matching-regexp sig-list-io regexp) - "inout" direction-re) + "inout" nil) ;; direction-re prefix) (verilog-decls-get-ports moddecls)))) (when v2k (verilog-repair-open-comma)) -- 2.39.2