; main declaration generator for CFFI binding (in-package "VERRAZANO") ; the state of the backend as it processes tree fragments (defstruct cffi-state symbols) ; generate a package containing declarations for dq (defmethod generate-package ((bk (eql :cffi-backend)) dq cfg) (declare (ignorable bk)) (let* ((bst (make-cffi-state :symbols (make-hash-table :test #'equal))) (decls (generate-declarations dq bst)) (stripped (strip-nils decls))) (write-declarations stripped cfg bst))) ; generate the declarations corresponding to dq (defun generate-declarations (dq bst) (mapcar #'(lambda (def) (output (car def) (cadr def) (caddr def) bst)) dq)) ; macro to ease writing matchers (defmacro generate-for (args &rest body) (let* ((par (car args)) (edg (cadr args)) (tgt (caddr args)) (st (cadddr args)) (tgtn (car tgt)) (tgtl (if (listp (cadr tgt)) (cadr tgt) (list (cadr tgt))))) `(progn ,@(mapcar #'(lambda (tp) `(defmethod output (,par ,edg (,tgtn ,tp) ,st) ,@body)) tgtl)))) ; output Lisp declarations for pattern in IR (defgeneric output (par edg tgt bst)) ; by default, output nothing (generate-for ((par node) (edg edge) (tgt node) bst) nil) ; collect the output of edges from node (defun collect-output (tgt bst &optional kind) (mapcar #'(lambda (e) (when (match-optional (type-of e) kind) (output tgt e (edge-target e) bst))) (node-edges tgt))) ; add a symbol to the symbol table (defun define-symbol (symname symtype symval bstate) (when (not (gethash symtype (cffi-state-symbols bstate))) (setf (gethash symtype (cffi-state-symbols bstate)) (make-hash-table :test #'equal))) (setf (gethash symname (gethash symtype (cffi-state-symbols bstate))) symval))