56 lines
2.0 KiB
Common Lisp
56 lines
2.0 KiB
Common Lisp
|
(uiop:define-package ambrevar/syntax
|
||
|
(:documentation "Syntax table.")
|
||
|
(:use #:common-lisp)
|
||
|
(:use #:trivia)
|
||
|
(:import-from #:ambrevar/shell)
|
||
|
(:import-from #:ambrevar/file)
|
||
|
(: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)))))))
|
||
|
|
||
|
(defun file-reader (stream char1 char2)
|
||
|
(declare (ignore char1 char2))
|
||
|
(read-until stream #\")
|
||
|
(ambrevar/file:file (read-until stream #\")))
|
||
|
|
||
|
(export-always 'syntax)
|
||
|
(named-readtables:defreadtable 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 #'file-reader))
|