-;;; notmuch-parser.el --- streaming S-expression parser
+;;; notmuch-parser.el --- streaming S-expression parser -*- lexical-binding: t -*-
;;
;; Copyright © Austin Clements
;;
;;; Code:
-(eval-when-compile (require 'cl-lib))
+(require 'cl-lib)
+(require 'pcase)
+(require 'subr-x)
(defun notmuch-sexp-create-parser ()
"Return a new streaming S-expression parser.
buffer. Hence, the caller is allowed to delete any data before
point and may resynchronize after an error by moving point."
(vector 'notmuch-sexp-parser
- ;; List depth
- 0
- ;; Partial parse position marker
- nil
- ;; Partial parse state
- nil))
+ 0 ; List depth
+ nil ; Partial parse position marker
+ nil)) ; Partial parse state
(defmacro notmuch-sexp--depth (sp) `(aref ,sp 1))
(defmacro notmuch-sexp--partial-pos (sp) `(aref ,sp 2))
(forward-char)
(signal 'invalid-read-syntax (list (string (char-before)))))))
-(defun notmuch-sexp-eof (sp)
- "Signal an error if there is more data in SP's buffer.
-
-Moves point to the beginning of any trailing data or to the end
-of the buffer if there is only trailing whitespace."
- (skip-chars-forward " \n\r\t")
- (unless (eobp)
- (error "Trailing garbage following expression")))
-
(defvar notmuch-sexp--parser nil
"The buffer-local notmuch-sexp-parser instance.
move point in the input buffer."
;; Set up the initial state
(unless (local-variable-p 'notmuch-sexp--parser)
- (set (make-local-variable 'notmuch-sexp--parser)
- (notmuch-sexp-create-parser))
- (set (make-local-variable 'notmuch-sexp--state) 'begin))
+ (setq-local notmuch-sexp--parser (notmuch-sexp-create-parser))
+ (setq-local notmuch-sexp--state 'begin))
(let (done)
(while (not done)
(cl-case notmuch-sexp--state
(t (with-current-buffer result-buffer
(funcall result-function result))))))
(end
- ;; Any trailing data is unexpected
- (notmuch-sexp-eof notmuch-sexp--parser)
+ ;; Skip over trailing whitespace.
+ (skip-chars-forward " \n\r\t")
+ ;; Any trailing data is unexpected.
+ (unless (eobp)
+ (error "Trailing garbage following expression"))
(setq done t)))))
;; Clear out what we've parsed
(delete-region (point-min) (point)))