X-Git-Url: https://git.distorted.org.uk/~mdw/sod/blobdiff_plain/450a4be6a6d832ce1e54169d9cc7740f5a04dc89..40d95de71fca4c3b7b145d5ba73d1420e8854673:/src/lexer-impl.lisp?ds=sidebyside diff --git a/src/lexer-impl.lisp b/src/lexer-impl.lisp index f00994a..42370c0 100644 --- a/src/lexer-impl.lisp +++ b/src/lexer-impl.lisp @@ -39,15 +39,12 @@ ;;;-------------------------------------------------------------------------- ;;; Indicators and error messages. -(defun show-char (stream char &optional colonp atsignp) - "Format CHAR to STREAM in a readable way. - - Usable in `format''s ~/.../ command." - (declare (ignore colonp atsignp)) - (cond ((null char) (write-string "" stream)) +(defun show-char (char) + "Format CHAR as a string in a readable way." + (cond ((null char) "") ((and (graphic-char-p char) (char/= char #\space)) - (format stream "`~C'" char)) - (t (format stream "<~(~:C~)>" char)))) + (format nil "`~C'" char)) + (t (format nil "<~(~:C~)>" char)))) (defun skip-until (scanner token-types &key keep-end) "This is the implementation of the `skip-until' parser." @@ -101,7 +98,18 @@ (parse (many (acc init (+ (* acc radix) it) :min min) (label (list :digit radix) (filter (lambda (ch) - (digit-char-p ch radix)))))))) + (digit-char-p ch radix))))))) + (start-floc () + ;; This is a little nasty. We scan the first token during + ;; instance initialization, as a result of `shared-initialize' + ;; on `token-scanner'. Unfortunately, this happens before + ;; we've had a chance to initialize our own `filename' slot. + ;; This means that we can't use the SCANNER as a file + ;; location, however tempting it might be. So we have this + ;; hack. + (make-file-location (scanner-filename char-scanner) + (scanner-line scanner) + (scanner-column scanner)))) ;; Skip initial junk, and remember the place. (loop @@ -128,13 +136,25 @@ (progn (write-char it out) out) :final (get-output-stream-string out)) (or (and #\\ :any) (not quote)))) - (nil (char quote))) + (nil (or (char quote) + (seq (:eof) + (lexer-error char-scanner (list quote)) + (info-with-location + (start-floc) "Literal started here"))))) (ecase quote (#\" contents) (#\' (case (length contents) (1 (char contents 0)) - (0 (cerror* "Empty character literal") #\?) - (t (cerror* "Too many characters in literal") + (0 (cerror*-with-location (start-floc) + 'simple-lexer-error + :format-control + "Empty character literal") + #\?) + (t (cerror*-with-location (start-floc) + 'simple-lexer-error + :format-control + "Too many characters ~ + in character literal") (char contents 0)))))) (values (etypecase it (character :char)