debian/changelog: Prepare for next version.
[sod] / src / parser / streams-proto.lisp
index 141d0bc..014ed70 100644 (file)
@@ -7,7 +7,7 @@
 
 ;;;----- Licensing notice ---------------------------------------------------
 ;;;
-;;; This file is part of the Sensble Object Design, an object system for C.
+;;; This file is part of the Sensible Object Design, an object system for C.
 ;;;
 ;;; SOD is free software; you can redistribute it and/or modify
 ;;; it under the terms of the GNU General Public License as published by
@@ -26,7 +26,7 @@
 (cl:in-package #:sod-parser)
 
 ;;;--------------------------------------------------------------------------
-;;; Discovery of file names.
+;;; Discovery of file names and stream positions.
 
 (export 'stream-pathname)
 (defgeneric stream-pathname (stream)
 
   ;; Provide some default methods.  Most streams don't have a pathname.
   ;; File-based streams provide a pathname, but it's usually been merged with
-  ;; *DEFAULT-PATHNAME-DEFAULTS* or some such, which has made it absolute,
+  ;; `*default-pathname-defaults*' or some such, which has made it absolute,
   ;; which isn't ideal.  We'll hack around this in more useful classes later.
   (:method ((stream stream)) nil)
   (:method ((stream file-stream)) (pathname stream)))
 
+(export 'stream-line-and-column)
+(defgeneric stream-line-and-column (stream)
+  (:documentation
+   "Returns the current stream position of STREAM as line/column numbers.
+
+   Returns two values: the line and column numbers of STREAM's input
+   position, or nil if the stream isn't capable of tracking these things.")
+  (:method ((stream stream))
+    (values nil nil)))
+
+;;;--------------------------------------------------------------------------
+;;; Enhanced stream classes.
+
+(export '(position-aware-stream
+         position-aware-stream-file position-aware-stream-line
+         position-aware-stream-column))
+(defclass position-aware-stream (proxy-stream)
+  ((file :initarg :file :initform nil
+        :type (or pathname null) :accessor position-aware-stream-file)
+   (line :initarg :line :initform 1
+        :type fixnum :accessor position-aware-stream-line)
+   (column :initarg :column :initform 0
+          :type fixnum :accessor position-aware-stream-column))
+  (:documentation
+   "Character stream which keeps track of the line and column position.
+
+   A position-aware-stream wraps an existing character stream and tracks the
+   line and column position of the current stream position.  A newline
+   character increases the line number by one and resets the column number to
+   zero; most characters advance the column number by one, but tab advances
+   to the next multiple of eight.  (This is consistent with Emacs, at least.)
+   The position can be read using `stream-line-and-column'.
+
+   This is a base class; you probably want `position-aware-input-stream' or
+   `position-aware-output-stream'."))
+
+(export 'position-aware-input-stream)
+(defclass position-aware-input-stream
+    (position-aware-stream proxy-character-input-stream)
+  ()
+  (:documentation
+   "A character input stream which tracks the input position.
+
+   This is particularly useful for parsers and suchlike, which want to
+   produce accurate error-location information."))
+
+(export 'position-aware-output-stream)
+(defclass position-aware-output-stream
+    (position-aware-stream proxy-character-output-stream)
+  ()
+  (:documentation
+   "A character output stream which tracks the output position.
+
+   This is particularly useful when generating C code: the position can be
+   used to generate `#line' directives referring to the generated code after
+   insertion of some user code."))
+
 ;;;----- That's all, folks --------------------------------------------------