ambevar-dotfiles/.local/share/common-lisp/source/ambrevar/syntax.lisp

51 lines
1.8 KiB
Common Lisp

(uiop:define-package ambrevar/syntax
(:documentation "Syntax table.")
(:use #:common-lisp)
(:use #:trivia)
(:import-from #:cmd)
(:import-from #:serapeum #:export-always))
(in-package ambrevar/syntax)
(eval-when (:compile-toplevel :load-toplevel :execute)
(trivial-package-local-nicknames:add-package-local-nickname :alex :alexandria)
(trivial-package-local-nicknames:add-package-local-nickname :sera :serapeum))
(defun read-until (stream delimiter)
"Return the string read until DELIMITER."
(concatenate 'string
(loop :for char = (read-char stream nil :eof)
:while (and (not (eq char :eof))
(not (char= char delimiter)))
:collect char)))
(defun cmd-reader (stream char1 char2)
(declare (ignore char1 char2))
(cmd:cmd (read-until stream #\newline)))
(defun $cmd-reader (stream char1 char2)
(declare (ignore char1 char2))
(cmd:$cmd (read-until stream #\newline)))
(defun sh-reader (stream char1 char2)
(declare (ignore char1 char2))
(let ((next-char (read-char stream nil :eof)))
(str:string-case (string next-char)
("#"
(cmd:sh (read-until stream #\newline)))
("!"
(cmd:sh (read-until stream #\newline)))
("$"
(cmd:$sh (read-until stream #\newline)))
(otherwise
(cmd:sh (str:concat (string next-char)
(read-until stream #\newline)))))))
(export-always 'syntax)
(named-readtables:defreadtable ambrevar/syntax::syntax
(:merge :standard)
(:dispatch-macro-char #\# #\# 'sh-reader)
(:dispatch-macro-char #\# #\$ '$cmd-reader)
(:dispatch-macro-char #\# #\! 'cmd-reader)
(:dispatch-macro-char #\# #\? 'interpol:interpol-reader)
(:dispatch-macro-char #\# #\f 'fof/file::file-reader)
(:dispatch-macro-char #\# #\m 'fof/mediafile::mediafile-reader))