(defvar *debugout-pathname* #p"debugout.c")
(export 'test-module)
-(defun test-module (path &key reason)
+(defun test-module (path &key reason clear backtrace)
"Read a module from PATH, to exercise the machinery.
+ If CLEAR is non-nil, then reset the translator's state before proceeding.
+
If REASON is non-nil, then output the module to `*debugout-pathname*' with
that REASON.
Return a two-element list (NERROR NWARNING) of the number of errors and
warnings encountered while processing the module."
+ (when clear (clear-the-decks))
(multiple-value-bind (module nerror nwarning)
- (count-and-report-errors () (read-module path))
+ (if backtrace (read-module path)
+ (count-and-report-errors () (read-module path)))
(when (and module reason)
(with-open-file (out *debugout-pathname*
:direction :output
(output-module module reason out)))
(list nerror nwarning)))
+(defmacro with-test-scanner ((scanner string) &body body)
+ "Common machinery for `test-parse-MUMBLE' below.
+
+ This is too specialized to make more widely available."
+ (with-gensyms (in charscan)
+ (once-only (string)
+ `(with-input-from-string (,in ,string)
+ (let* ((*module-type-map* (make-hash-table))
+ (,charscan (make-instance 'charbuf-scanner
+ :stream ,in
+ :filename "<string>"))
+ (,scanner (make-instance 'sod-token-scanner
+ :char-scanner ,charscan
+ :filename "<string>")))
+ (with-parser-context (token-scanner-context :scanner ,scanner)
+ ,@body))))))
+
(export 'test-parse-c-type)
(defun test-parse-c-type (string)
"Parse STRING as a C type, with optional kernel, and show the results."
- (with-input-from-string (in string)
- (let* ((*module-type-map* (make-hash-table))
- (charscan (make-instance 'charbuf-scanner
- :stream in
- :filename "<string>"))
- (tokscan (make-instance 'sod-token-scanner
- :char-scanner charscan
- :filename "<string>")))
- (with-parser-context (token-scanner-context :scanner tokscan)
- (multiple-value-bind (value winp consumedp)
- (parse (seq ((decls (parse-c-type tokscan))
- (type (parse-declarator tokscan decls :abstractp t))
- :eof)
- type))
- (declare (ignore consumedp))
- (if winp
- (values t (car value) (cdr value)
- (princ-to-string (car value)))
- (values nil value)))))))
+ (with-test-scanner (scanner string)
+ (multiple-value-bind (value winp consumedp)
+ (parse (seq ((decls (parse-c-type scanner))
+ (type (parse-declarator scanner decls :abstractp t))
+ :eof)
+ type))
+ (declare (ignore consumedp))
+ (if winp
+ (values t (car value) (cdr value)
+ (princ-to-string (car value)))
+ (values nil value)))))
+
+(export 'test-parse-pset)
+(defun test-parse-pset (string)
+ "Parse STRING as a property set, and show the results."
+ (with-test-scanner (scanner string)
+ (multiple-value-bind (value winp consumedp)
+ (parse-property-set scanner)
+ (declare (ignore consumedp))
+ (values winp value))))
(export 'test-parser)
(defmacro test-parser ((scanner &key backtrace) parser input)
,scanner (make-instance
'sod-token-scanner
:char-scanner ,char-scanner))
- (multiple-value-bind (,value ,winp ,consumedp)
- (parse ,parser)
- (declare (ignore ,consumedp))
- (cond (,winp ,value)
- (t (syntax-error ,scanner ,value)
- nil)))))
+ (with-default-error-location (,scanner)
+ (multiple-value-bind (,value ,winp ,consumedp)
+ (parse ,parser)
+ (declare (ignore ,consumedp))
+ (cond (,winp ,value)
+ (t (syntax-error ,scanner ,value)
+ nil))))))
(if ,backtrace (,body)
(count-and-report-errors ()
- (with-default-error-location (,scanner)
- (,body)))))
+ (,body))))
(let ((,where (scanner-capture-place ,char-scanner)))
(values ,value
(list ,nerror ,nwarn)