X-Git-Url: https://git.distorted.org.uk/~mdw/sod/blobdiff_plain/284f1fa2ace3e276052ff1bd7d66442500e693da..9b9ad6b931736323a34123c11edfdff97a22623e:/src/frontend.lisp diff --git a/src/frontend.lisp b/src/frontend.lisp index a4625f7..2d20fbc 100644 --- a/src/frontend.lisp +++ b/src/frontend.lisp @@ -24,7 +24,7 @@ ;;; Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. (cl:defpackage #:sod-frontend - (:use #:common-lisp #:optparse #:sod #:sod-parser) + (:use #:common-lisp #:sod-utilities #:optparse #:sod #:sod-parser) (:shadowing-import-from #:optparse #:int)) (cl:in-package #:sod-frontend) @@ -38,6 +38,9 @@ ;;;-------------------------------------------------------------------------- ;;; The main program. +(defvar-unbound *option-parser* + "The program's main option parser.") + (eval-when (:compile-toplevel :load-toplevel :execute) (defopthandler dirpath (var arg) () "Convert the argument into a pathname with a directory component @@ -71,6 +74,18 @@ (setf var path)))))) +(defun update-usage () + (setf *usage* (simple-usage *options* "SOURCES..."))) + +(export 'augment-options) +(defun augment-options (options) + "Add OPTIONS to the program's options list." + (asetf *options* (append it options)) + (setf (op-options *option-parser*) *options*) + (update-usage)) + +(use-package "SOD-FRONTEND" "SOD-USER") + (export 'main) (defun main () @@ -89,7 +104,6 @@ (define-program :help "Process SOD input files to produce (e.g.) C output." :version *sod-version* - :usage "SOURCES..." :options (options (help-options :short-version #\V) "Translator options" @@ -105,20 +119,48 @@ (#\d "directory" (:arg "DIR") ("Write output files to DIR.") (dirpath output-path)) + (#\e "eval" (:arg "LISP") + ("Evaluate raw Lisp code.") + (lambda (lisp) + (handler-case + (let ((*package* (find-package "SOD-USER"))) + (eval (read-from-string lisp))) + (error (error) + (option-parse-error "~A" error))))) + (#\l "load" (:arg "FILE") + ("Load a file of Lisp code.") + (lambda (file) + (let ((file (merge-pathnames file + (make-pathname + :type "LISP" + :case :common)))) + (handler-case + (let ((*package* (find-package "SOD-USER"))) + (find-file *default-pathname-defaults* file + "Lisp file" + (lambda (path true) + (declare (ignore path)) + (load true + :verbose nil + :print nil)))) + (error (error) + (option-parse-error "~A" error)))))) (#\p "stdout" ("Write output files to standard output.") (set stdoutp)) (#\t "type" (:arg "OUT-TYPE") ("Produce output of type OUT-TYPE.") (list output-reasons 'keyword)))) + (update-usage) ;; Actually parse the options. - (unless (and (option-parse-try - (do-options () - (nil (rest) - (setf args rest)))) - (or builtinsp args)) - (die-usage)) + (let ((*option-parser* (make-option-parser))) + (unless (and (option-parse-try + (do-options (:parser *option-parser*) + (nil (rest) + (setf args rest)))) + (or builtinsp args)) + (die-usage))) ;; Do the main parsing job. (labels ((hack-module (module) @@ -182,7 +224,9 @@ ;; Parse and write out the remaining modules. (dolist (arg args) - (hack-module (read-module arg))))) + (let ((module (read-module arg))) + (when (zerop (module-errors module)) + (hack-module module)))))) (if backtracep (hack-modules) (multiple-value-bind (hunoz nerror nwarn)