;;; -*-lisp-*- ;;; ;;; Finishing touches for Sod ;;; ;;; (c) 2015 Straylight/Edgeware ;;; ;;;----- Licensing notice --------------------------------------------------- ;;; ;;; 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 ;;; the Free Software Foundation; either version 2 of the License, or ;;; (at your option) any later version. ;;; ;;; SOD is distributed in the hope that it will be useful, ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;;; GNU General Public License for more details. ;;; ;;; You should have received a copy of the GNU General Public License ;;; along with SOD; if not, write to the Free Software Foundation, ;;; Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. (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. (export '*debugout-pathname*) (defvar *debugout-pathname* #p"debugout.c") (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." (clear-the-decks) (setf *module-map* (make-hash-table :test #'equal)) (with-open-file (out *debugout-pathname* :direction :output :if-exists :supersede :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 "")) (tokscan (make-instance 'sod-token-scanner :char-scanner charscan :filename ""))) (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 ""))) (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 --------------------------------------------------