[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/relint 60d5627 21/23: Lazy evaluation of global variabl
From: |
Mattias Engdegård |
Subject: |
[elpa] externals/relint 60d5627 21/23: Lazy evaluation of global variables |
Date: |
Sun, 29 Sep 2019 15:34:54 -0400 (EDT) |
branch: externals/relint
commit 60d5627e06e31c15864b4e38d7d48282981b9e32
Author: Mattias Engdegård <address@hidden>
Commit: Mattias Engdegård <address@hidden>
Lazy evaluation of global variables
This improves performance by over 5 %.
Previously, global variables were evaluated at every reference.
When redefined, the new expression is evaluated eagerly in case it
relies on the old value.
---
relint.el | 39 +++++++++++++++++++++++++++++++--------
test/4.elisp | 14 ++++++++++++++
test/4.expected | 9 +++++++++
3 files changed, 54 insertions(+), 8 deletions(-)
diff --git a/relint.el b/relint.el
index 53acede..c2113be 100644
--- a/relint.el
+++ b/relint.el
@@ -298,8 +298,9 @@ list of list indices to follow to target)."
(nreverse errs)))
(defvar relint--variables nil
- "Alist of global variable definitions seen so far.
- The variable names map to unevaluated forms.")
+ "Alist of global variable definitions.
+Each element is either (NAME expr EXPR), for unevaluated expressions,
+or (NAME val VAL), for values.")
;; List of variables that have been checked, so that we can avoid
;; checking direct uses of it.
@@ -528,8 +529,12 @@ not be evaluated safely."
(throw 'relint-eval 'no-value))
(let ((binding (assq form relint--variables)))
(if binding
- (relint--eval (cdr binding))
- (throw 'relint-eval 'no-value))))))
+ (if (eq (cadr binding) 'val)
+ (caddr binding)
+ (let ((val (relint--eval (caddr binding))))
+ (setcdr binding (list 'val val))
+ val))
+ (throw 'relint-eval 'no-value))))))
(t form))
(let ((head (car form))
(body (cdr form)))
@@ -889,8 +894,13 @@ evaluated are nil."
(let ((local (assq form relint--locals)))
(if local
(and (cdr local) (cadr local))
- (let ((val (cdr (assq form relint--variables))))
- (and val (relint--eval-list val)))))))
+ (let ((binding (assq form relint--variables)))
+ (and binding
+ (if (eq (cadr binding) 'val)
+ (caddr binding)
+ ;; Since we are only doing a list evaluation, don't
+ ;; update the variable here.
+ (relint--eval-list (caddr binding)))))))))
((atom form)
form)
((memq (car form) '(progn ignore-errors eval-when-compile eval-and-compile))
@@ -1012,7 +1022,8 @@ EXPANDED is a list of expanded functions, to prevent
recursion."
;; Check both variable contents and name.
(or (let ((def (assq expr relint--variables)))
(and def
- (relint--regexp-generators (cdr def) expanded)))
+ (eq (cadr def) 'expr)
+ (relint--regexp-generators (caddr def) expanded)))
(and (or (memq expr '(page-delimiter paragraph-separate
paragraph-start sentence-end
comment-start-skip comment-end-skip))
@@ -1496,7 +1507,19 @@ directly."
(relint--check-defcustom-re form name file pos path))
(push name relint--checked-variables))
)
- (push (cons name re-arg) relint--variables))))
+
+ (let* ((old (assq name relint--variables))
+ (new
+ (or (and old
+ ;; Redefinition of the same variable: eagerly
+ ;; evaluate the new expression in case it uses
+ ;; the old value.
+ (let ((val (catch 'relint-eval
+ (list (relint--eval re-arg)))))
+ (and (consp val)
+ (cons 'val val))))
+ (list 'expr re-arg))))
+ (push (cons name new) relint--variables)))))
(`(define-generic-mode ,name ,_ ,_ ,font-lock-list ,auto-mode-list . ,_)
(let ((origin (format "define-generic-mode %s" name)))
(relint--check-font-lock-keywords font-lock-list origin
diff --git a/test/4.elisp b/test/4.elisp
index 4dc8a94..b9ae44a 100644
--- a/test/4.elisp
+++ b/test/4.elisp
@@ -45,3 +45,17 @@
(looking-at (unless nil "c++"))
(looking-at (string-join `("a" ,@(list "$") ,"b")))
(looking-at (pcase 'a ((pred symbolp) "d++"))))
+
+;; Test repeated use of global variable
+(defconst my-var-a "*")
+(defconst my-var-b (concat my-var-a "b"))
+
+(defun test-var-ref ()
+ (looking-at my-var-b)
+ (looking-at (concat my-var-b "c")))
+
+;; Test global variable redefinition
+(defconst my-var-a (concat my-var-a "a"))
+
+(defun test-var-redef ()
+ (looking-at my-var-a))
diff --git a/test/4.expected b/test/4.expected
index d051130..d1897ed 100644
--- a/test/4.expected
+++ b/test/4.expected
@@ -49,3 +49,12 @@
4.elisp:47:15: In call to looking-at: Repetition of repetition (pos 2)
"d++"
..^
+4.elisp:54:15: In call to looking-at: Unescaped literal `*' (pos 0)
+ "*b"
+ ^
+4.elisp:55:15: In call to looking-at: Unescaped literal `*' (pos 0)
+ "*bc"
+ ^
+4.elisp:61:15: In call to looking-at: Unescaped literal `*' (pos 0)
+ "*a"
+ ^
- [elpa] externals/relint 3a27cff 18/23: Handle mutation of local variables in evaluation, (continued)
- [elpa] externals/relint 3a27cff 18/23: Handle mutation of local variables in evaluation, Mattias Engdegård, 2019/09/29
- [elpa] externals/relint d2b7194 19/23: Evaluate `dolist' and `while', Mattias Engdegård, 2019/09/29
- [elpa] externals/relint b2a86b8 04/23: Fix typo in message description and clarify, Mattias Engdegård, 2019/09/29
- [elpa] externals/relint 1cb021a 03/23: Remove relint--eval-error, Mattias Engdegård, 2019/09/29
- [elpa] externals/relint 5137ec6 11/23: Evaluate keywords correctly, Mattias Engdegård, 2019/09/29
- [elpa] externals/relint 6a07508 10/23: Handle rx `eval' form correctly, Mattias Engdegård, 2019/09/29
- [elpa] externals/relint 3a7e82a 05/23: Track some mutation of local variables in phase 2, Mattias Engdegård, 2019/09/29
- [elpa] externals/relint bc1b5a8 16/23: Add word-search-regexp to the list of regexp generating functions, Mattias Engdegård, 2019/09/29
- [elpa] externals/relint b890b5a 15/23: Track mutation in push and lambda in phase 2, Mattias Engdegård, 2019/09/29
- [elpa] externals/relint 02c5dd2 13/23: Prepare for easier testability, Mattias Engdegård, 2019/09/29
- [elpa] externals/relint 60d5627 21/23: Lazy evaluation of global variables,
Mattias Engdegård <=
- [elpa] externals/relint b0f0bee 23/23: Increment version to 1.11, Mattias Engdegård, 2019/09/29
- [elpa] externals/relint 501f87b 20/23: Evaluate `prog1' and `prog2', Mattias Engdegård, 2019/09/29
- [elpa] externals/relint 6212b6f 22/23: Evaluate more functions and macros, Mattias Engdegård, 2019/09/29
- [elpa] externals/relint 7e6b8bf 14/23: Add tests, Mattias Engdegård, 2019/09/29