;; From a patch submitted to SBCL (defun copy-source-path (form original-form &rest forms) "In a macroexpander, indicate that FORM was produced from ORIGINAL-FORM. If ORIGINAL-FORM does not have source path information, then copy source path from first form in FORMS that has source path information. FORMS should be ordered by specificity. The idiom (COPY-SOURCE-PATH form form original-form...) can be used if FORM possibly had source-path information attached earlier, but forms are now augmented with less-specific source-paths in a later pass. Indicating source paths of FORM allows the compiler report precise source locations when compiling code generated by macroexpansion. It is safe to call outside of macroexpansion. It always returns FORM." (if (and (boundp 'sb-c::*source-paths*) (sb-c::source-form-has-path-p form)) (let ((path (some #'sb-c::get-source-path (list* original-form forms)))) (if path (progn (setf (gethash form sb-c::*source-paths*) path) (values form t)) (values form nil))) (values form nil))) (defmacro define-dsl-function (name &body body) (let* ((function-names (mapcar (lambda (x) (declare (ignore x)) (gensym "F")) body))) `(flet ,(mapcar (lambda (name x) (copy-source-path `(,name ()) x)) function-names body) (defun ,name () (list ,@(mapcar (lambda (name) `(sb-introspect:find-definition-source #',name) ;; `(swank/backend:find-source-location #',name) ) function-names)))))) (define-dsl-function main (format t "line a~%") (format t "line b~%")) (main)