; main driver for frontend and backend (in-package "VERRAZANO") ; a structure representing the configuration of a binding (defstruct configuration binding-name binding-nicknames included-files symbols-exported overrides) ; create a binding given an input configuration file (defun create-binding (filename) (let ((cfg (parse-configuration-file filename))) (generate-temporary-c-file cfg) (run-gccxml) (let ((ir (parse-gccxml-output "__temporary.xml"))) (simplify-ir ir) (write-declarations (generate-declarations ir cfg) cfg)) (cleanup))) ; a function to parse a configuration file (defun parse-configuration-file (filename) (with-open-file (file filename :direction :input) (let ((pfile (read file)) (cfg (make-configuration))) (set-binding-name pfile cfg) (set-binding-nicknames pfile cfg) (set-binding-includes pfile cfg) (set-binding-exports pfile cfg) cfg))) ; set the name of a binding (defun set-binding-name (pfile cfg) (setf (configuration-binding-name cfg) (second pfile))) ; get a section in the configuration file (defun find-section (pfile str) (let ((found nil)) (dolist (fragment pfile found) (when (and (listp fragment) (equal (symbol-name (car fragment)) str)) (setf found fragment))))) ; set a list of the nicknames of a binding (defun set-binding-nicknames (pfile cfg) (let ((sect (find-section pfile "NICKNAMES"))) (setf (configuration-binding-nicknames cfg) (cdr sect)))) ; set a list of the included files in a binding (defun set-binding-includes (pfile cfg) (let ((sect (find-section pfile "INCLUDE"))) (setf (configuration-included-files cfg) (cdr sect)))) ; set the exports the included files in a binding (defun set-binding-exports (pfile cfg) (let ((sect (find-section pfile "EXPORT"))) (setf (configuration-symbols-exported cfg) (cdr sect)))) ; generate a temporary C file for a binding generation (defun generate-temporary-c-file (cfg) (with-open-file (out "__temporary.c" :direction :output :if-exists :supersede) (dolist (inc (configuration-included-files cfg)) (format out "#include \"~A\"~%" inc)) (format out "const int __verrazano_binding = 1;"))) ; run gccxml on the temporary file (defun run-gccxml () (let ((cmd "gccxml -fxml=__temporary.xml __temporary.c")) (asdf:run-shell-command cmd))) ; apply given simplifications to ir (defun simplify-ir (ir) (name-anonymous-types ir) (mark-artificial-types ir) (ensure-everything-defined ir)) ; write declarations to a file (defun write-declarations (defns cfg) (with-open-file (out (concatenate 'string (configuration-binding-name cfg) ".lisp") :direction :output :if-exists :supersede) (dolist (defn defns) (format out "~A~%" defn)))) ; cleanup temporary files (defun cleanup () (asdf:run-shell-command "rm -f __temporary.xml __temporary.c"))