diff options
author | David Thompson <dthompson@vistahigherlearning.com> | 2022-10-05 10:28:37 -0400 |
---|---|---|
committer | David Thompson <dthompson@vistahigherlearning.com> | 2022-10-05 10:55:18 -0400 |
commit | d68ccf7c2ae9516ca2ddacc5f65e2277038b23f6 (patch) | |
tree | 434c875f492b88fb425eb719a35c31ec99f6fa6c | |
parent | 94e8fe134f28296da0f01bd69428783aa06ee205 (diff) |
Add Lisp lexer.
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | syntax-highlight/lisp.scm | 100 |
2 files changed, 101 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am index 47dbb54..2521da5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -44,6 +44,7 @@ SOURCES = \ syntax-highlight/c.scm \ syntax-highlight/css.scm \ syntax-highlight/gitignore.scm \ + syntax-highlight/lisp.scm \ syntax-highlight/scheme.scm \ syntax-highlight/xml.scm \ syntax-highlight.scm diff --git a/syntax-highlight/lisp.scm b/syntax-highlight/lisp.scm new file mode 100644 index 0000000..88d7fba --- /dev/null +++ b/syntax-highlight/lisp.scm @@ -0,0 +1,100 @@ +;;; guile-syntax-highlight --- General-purpose syntax highlighter +;;; Copyright © 2022 David Thompson <davet@gnu.org> +;;; +;;; Guile-syntax-highlight is free software; you can redistribute it +;;; and/or modify it under the terms of the GNU Lesser General Public +;;; License as published by the Free Software Foundation; either +;;; version 3 of the License, or (at your option) any later version. +;;; +;;; Guile-syntax-highlight is distributed in the hope that it will be +;;; useful, but WITHOUT ANY WARRANTY; without even the implied +;;; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +;;; See the GNU Lesser General Public License for more details. +;;; +;;; You should have received a copy of the GNU Lesser General Public +;;; License along with guile-syntax-highlight. If not, see +;;; <http://www.gnu.org/licenses/>. + +;;; Commentary: +;; +;; Syntax highlighting for Lisp. +;; +;;; Code: + +(define-module (syntax-highlight lisp) + #:use-module (ice-9 match) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-11) + #:use-module (srfi srfi-26) + #:use-module (syntax-highlight lexers) + #:export (%default-special-symbols + %default-special-prefixes + make-lisp-lexer + lex-lisp)) + +(define char-set:lisp-delimiters + (char-set-union char-set:whitespace + (char-set #\( #\) #\[ #\] #\{ #\}))) + +(define char-set:lisp-symbol + (char-set-complement char-set:lisp-delimiters)) + +(define %default-special-symbols + '("setq" "setf" + "case" "ccase" "ecase" + "if" "cond" + "prog1" "prog2" "progn" + "lambda" "λ" + "let" "let*" + "and" "or")) + +(define %default-special-prefixes + '("def")) + +(define (lex-special-symbol sym) + (lex-filter (lambda (str) + (string=? sym str)) + (lex-char-set char-set:lisp-symbol))) + +(define (lex-special-symbol symbols prefixes) + (lex-filter (lambda (str) + (or (any (cut string=? symbols <>) symbols) + (any (cut string-prefix? <> str) prefixes))) + (lex-char-set char-set:lisp-symbol))) + +(define (lex-map2 proc lexer) + (lambda (tokens cursor) + (let-values (((result remainder) (lexer tokens cursor))) + (if result + (match (token-take result 2) + ((second first) ; accumulator tokens are in reverse order + (values (token-add (token-drop result 2) + (proc first second)) + remainder))) + (fail))))) + +(define (make-lisp-lexer special-symbols special-prefixes) + "Return a lexer that highlights Lisp source code. Tag strings +that are in SPECIAL-SYMBOLS or match one of the string prefixes in +SPECIAL-PREFIXES with the 'special' tag." + (lex-consume + (lex-any (lex-char-set char-set:whitespace) + (lex-tag 'open (lex-any* (map lex-string '("(" "[" "{")))) + (lex-tag 'close (lex-any* (map lex-string '(")" "]" "}")))) + (lex-tag 'comment (lex-delimited ";" #:until "\n")) + (lex-tag 'special + (lex-filter (lambda (str) + (or (any (cut string=? <> str) + special-symbols) + (any (cut string-prefix? <> str) + special-prefixes))) + (lex-char-set char-set:lisp-symbol))) + (lex-tag 'string (lex-delimited "\"")) + (lex-tag 'keyword + (lex-map2 string-append + (lex-all (lex-string ":") + (lex-char-set char-set:lisp-symbol)))) + (lex-tag 'symbol (lex-char-set char-set:lisp-symbol))))) + +(define lex-lisp + (make-lisp-lexer %default-special-symbols %default-special-prefixes)) |