[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/haskell-tng-mode 73e2b11 063/385: the new lexer works!
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/haskell-tng-mode 73e2b11 063/385: the new lexer works! |
Date: |
Tue, 5 Oct 2021 23:59:02 -0400 (EDT) |
branch: elpa/haskell-tng-mode
commit 73e2b11b78d7a3124beefc28149406c57c931875
Author: Tseen She <ts33n.sh3@gmail.com>
Commit: Tseen She <ts33n.sh3@gmail.com>
the new lexer works!
---
haskell-tng-smie.el | 131 +++++++++++++++++++++++-----------------------------
1 file changed, 58 insertions(+), 73 deletions(-)
diff --git a/haskell-tng-smie.el b/haskell-tng-smie.el
index 250cb66..32591bc 100644
--- a/haskell-tng-smie.el
+++ b/haskell-tng-smie.el
@@ -6,24 +6,17 @@
;;; Commentary:
;;
;; SMIE lexer, precedence table (providing s-expression navigation), and
-;; indentation rules.
+;; indentation rules. The lexer is stateful in order to support virtual
tokens,
+;; and Layout aware, see `haskell-tng-layout.el' for more details.
;;
-;; Note that we don't need to support every aspect of the Haskell language in
-;; these grammar rules: only the parts that are relevant for the features that
-;; are provided.
-;;
-;; If we had access to all the operators in scope, and their fixity, we could
-;; create file-specific precendences. However, the complexity-to-benefit
payoff
-;; is minimal.
+;; Note that we don't support every aspect of the Haskell language. e.g. if we
+;; had access to all the operators in scope, and their fixity, we could create
+;; file-specific precendences. However, the complexity-to-benefit payoff is
+;; minimal.
;;
;; Users may consult the SMIE manual to customise their indentation rules:
;; https://www.gnu.org/software/emacs/manual/html_mono/elisp.html#SMIE
;;
-;; The Haskell2010 report's sections 2.7 and 10.3 are particularly pertinent:
-;;
-;; https://www.haskell.org/onlinereport/haskell2010/haskellch2.html
-;; https://www.haskell.org/onlinereport/haskell2010/haskellch10.html
-;;
;;; Code:
(require 'smie)
@@ -31,12 +24,14 @@
(require 'haskell-tng-font-lock)
(require 'haskell-tng-layout)
-;; FIXME: this is all broken, use haskell-tng-layout
-
+;; The list of virtual tokens that must be played back at point, or `t' to
+;; indicate that virtual tokens have already been played back at point and
+;; normal lexing may continue.
+;;
;; TODO: invalidate this state when the lexer jumps around or the user edits
-(defvar-local haskell-tng-smie:multi nil)
+(defvar-local haskell-tng-smie:virtuals nil)
-;; Function to scan forward for the next token.
+;; Implementation of `smie-forward-token' for Haskell, i.e.
;;
;; - Called with no argument should return a token and move to its end.
;; - If no token is found, return nil or the empty string.
@@ -44,63 +39,53 @@
;; use syntax-tables to handle them in efficient C code.
;;
;; https://www.gnu.org/software/emacs/manual/html_mono/elisp.html#SMIE-Lexer
+;;
+;; Note that this implementation is stateful as it can play back multiple
+;; virtual tokens at a single point. This lexer could be made stateless if SMIE
+;; were to support a 4th return type: a list of any of the above.
(defun haskell-tng-smie:forward-token ()
- (interactive) ;; for testing
- (if (stringp (car haskell-tng-smie:multi))
- ;; reading from state
- (pop haskell-tng-smie:multi)
-
- (forward-comment (point-max))
- (let ((done-multi (pop haskell-tng-smie:multi))
- (case-fold-search nil)
- (offside (car haskell-tng-smie:wldos)))
- (cl-flet ((virtual-end () (= (point) (car offside)))
- (virtual-semicolon () (= (current-column) (cdr offside))))
- (cond
- ;; layout
- ((and offside
- (not done-multi)
- (or (virtual-end) (virtual-semicolon)))
- (setq haskell-tng-smie:multi '(t))
- (while (and offside (virtual-end))
- (push "}" haskell-tng-smie:multi)
- (pop haskell-tng-smie:wldos)
- (setq offside (car haskell-tng-smie:wldos)))
- (when (and offside (virtual-semicolon))
- (setq haskell-tng-smie:multi
- (-insert-at (- (length haskell-tng-smie:multi) 1)
- ";" haskell-tng-smie:multi)))
- (pop haskell-tng-smie:multi))
-
- ;; syntax tables (supported by `smie-indent-forward-token')
- ((looking-at (rx (| (syntax open-parenthesis)
- (syntax close-parenthesis)
- (syntax string-quote)
- (syntax string-delimiter))))
- nil)
-
- ;; layout detection
- ((looking-at (rx word-start (| "where" "let" "do" "of") word-end))
- (save-match-data
- (forward-word)
- (forward-comment (point-max))
- (when (not (looking-at "{"))
- (push (haskell-tng:layout-close-and-level)
haskell-tng-smie:wldos)
- (setq haskell-tng-smie:multi '("{" t))))
- (haskell-tng-smie:last-match))
-
- ;; regexps
- ((or
- ;; known identifiers
- (looking-at haskell-tng:regexp:reserved)
- ;; symbols
- (looking-at (rx (+ (| (syntax word) (syntax symbol))))))
- (haskell-tng-smie:last-match))
-
- ;; single char
- (t
- (forward-char)
- (string (char-before))))))))
+ (let (case-fold-search)
+ (if (consp haskell-tng-smie:virtuals)
+ ;; continue replaying virtual tokens
+ (haskell-tng-smie:replay-virtual)
+
+ (forward-comment (point-max))
+ ;; TODO: performance. Only request virtuals when they make sense... e.g.
+ ;; on newlines, or following a WLDO (assuming a lookback is faster).
+ (setq haskell-tng-smie:virtuals
+ (and (not haskell-tng-smie:virtuals)
+ (haskell-tng-layout:virtuals-at-point)))
+ (cond
+ ;; new virtual tokens
+ (haskell-tng-smie:virtuals
+ (haskell-tng-smie:replay-virtual))
+
+ ;; syntax tables (supported by `smie-indent-forward-token')
+ ((looking-at (rx (| (syntax open-parenthesis)
+ (syntax close-parenthesis)
+ (syntax string-quote)
+ (syntax string-delimiter))))
+ nil)
+
+ ;; regexps
+ ((or
+ ;; known identifiers
+ (looking-at haskell-tng:regexp:reserved)
+ ;; symbols
+ (looking-at (rx (+ (| (syntax word) (syntax symbol))))))
+ (haskell-tng-smie:last-match))
+
+ ;; single char
+ (t
+ (forward-char)
+ (string (char-before)))))))
+
+(defun haskell-tng-smie:replay-virtual ()
+ ";; read a virtual token from state, set 't when all done"
+ (unwind-protect
+ (pop haskell-tng-smie:virtuals)
+ (unless haskell-tng-smie:virtuals
+ (setq haskell-tng-smie:virtuals 't))))
(defun haskell-tng-smie:last-match ()
(goto-char (match-end 0))
- [nongnu] elpa/haskell-tng-mode a4ec07a 032/385: fix install instructions, (continued)
- [nongnu] elpa/haskell-tng-mode a4ec07a 032/385: fix install instructions, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 3e8efdc 023/385: type aliases and deriving, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode ad570a0 039/385: out of date comments, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 7326aad 041/385: modules and more efficient none, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 49611c6 042/385: regression tests for fontification, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode c22f7d2 045/385: thoughts on future plans, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode a5f779d 047/385: initial SMIE tests, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode dae43ac 049/385: improvements to the default lexer, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode d76c6ad 053/385: some thoughts on WLDO detection, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 3e53f56 055/385: cleaner lexer test output, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 73e2b11 063/385: the new lexer works!,
ELPA Syncer <=
- [nongnu] elpa/haskell-tng-mode 8e1a225 068/385: sexp tests, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 269be91 072/385: revert broken grammar rules, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 3194e62 074/385: stefan to the rescue, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode b690037 081/385: comment-* support, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 502cc26 085/385: document a failure mode, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 08f924c 088/385: simplify the grammar rules, better s-exps, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 71cf945 048/385: lexer test based on Haskell2010, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 4d6bbfc 050/385: feedback from Stefan, improving lexing, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 96609e4 052/385: thoughts on layout inference, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 06b357c 054/385: hacky closing braces, ELPA Syncer, 2021/10/06