chiark / gitweb /
src/method-impl.lisp: Initialize `suppliedp' flags properly.
[sod] / src / final.lisp
index dd8834ff77b06f99689f91cc7e294c99ca47aafd..1b87c26cc2b4090dc05cc7fa98e86913b4bd6fa5 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
 
 (cl:in-package #:sod)
 
+;;;--------------------------------------------------------------------------
+;;; Miscellaneous details.
+
+(export '*sod-version*)
+(defparameter *sod-version* sod-sysdef:*version*
+  "The version of the SOD translator system, as a string.")
+
 ;;;--------------------------------------------------------------------------
 ;;; Debugging utilities.
 
@@ -35,7 +42,6 @@ (export 'test-module)
 (defun test-module (path reason)
   "Reset the translator's state, read a module from PATH and output it with
    REASON, returning the result as a string."
-  (unless *builtin-module* (make-builtin-module))
   (clear-the-decks)
   (setf *module-map* (make-hash-table :test #'equal))
   (with-open-file (out *debugout-pathname*
@@ -44,4 +50,76 @@ (defun test-module (path reason)
                   :if-does-not-exist :create)
     (output-module (read-module path) reason out)))
 
+(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)))))))
+
+(export 'test-parser)
+(defmacro test-parser ((scanner &key) parser input)
+  "Convenient macro for testing parsers at the REPL.
+
+   This is a macro so that the parser can use the fancy syntax.  The name
+   SCANNER is bound to a `sod-token-scanner' reading tokens from the INPUT
+   string.  Then the PARSER is invoked and three values are returned: a
+   `successp' flag indicating whether the parser succeeded; the result,
+   output or error indicator, of the parser; and a list consisting of the
+   lookahead token type and value, and a string containing the untokenized
+   remaining input."
+  (once-only (input)
+    (with-gensyms (char-scanner value winp consumedp where)
+      `(let* ((,char-scanner (make-string-scanner ,input))
+             (,scanner (make-instance 'sod-token-scanner
+                                      :char-scanner ,char-scanner
+                                      :filename "<test-input>")))
+        (with-parser-context (token-scanner-context :scanner ,scanner)
+          (multiple-value-bind (,value ,winp ,consumedp) (parse ,parser)
+            (declare (ignore ,consumedp))
+            (let ((,where (scanner-capture-place ,char-scanner)))
+              (values ,winp ,value
+                      (list (token-type ,scanner) (token-value ,scanner)
+                            (subseq ,input ,where))))))))))
+
+;;;--------------------------------------------------------------------------
+;;; Calisthenics.
+
+(export 'exercise)
+(defun exercise ()
+  "Exercise the pieces of the metaobject protocol.
+
+   In some Lisps, the compiler is run the first time methods are called, to
+   do fancy just-in-time optimization things.  This is great, only the
+   program doesn't actually run for very long and a lot of that work is
+   wasted because we're going to have to do it again next time the program
+   starts.  Only, if we exercise the various methods, or at least a large
+   fraction of them, before we dump an image, then everything will be fast.
+
+   That's the theory anyway.  Call this function before you dump an image and
+   see what happens."
+
+  (clear-the-decks)
+  (dolist (reason '(:h :c))
+    (with-output-to-string (bitbucket)
+      (output-module *builtin-module* reason bitbucket)))
+
+  (clear-the-decks))
+
 ;;;----- That's all, folks --------------------------------------------------