51 lines
1.9 KiB
Common Lisp
51 lines
1.9 KiB
Common Lisp
(uiop:define-package ambrevar/syntax
|
|
(:documentation "Syntax table.")
|
|
(:use #:common-lisp)
|
|
(:use #:trivia)
|
|
(:import-from #:ambrevar/shell)
|
|
(: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)
|
|
("#"
|
|
(ambrevar/shell:sh (read-until stream #\newline)))
|
|
("!"
|
|
(ambrevar/shell:sh (read-until stream #\newline)))
|
|
("$"
|
|
(ambrevar/shell:$sh (read-until stream #\newline)))
|
|
(otherwise
|
|
(ambrevar/shell: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))
|