;;; ;;; MAKEFILE: ;;; ========= ;;; ;;; ;;; ::= '(' + "makefile" + * + ')' ;;; ::= ;;; | ;;; | ;;; | ;;; | ;;; | ;;; | ;;; | ;;; | ;;; | ;;; ;;; (define-syntax makefile (syntax-rules () ((makefile ?rule0 ...) (sort-rules () () ?rule0 ...)))) ;;; ;;; Each rule will be transformed into something similar to this: ;;; ;;; (cons () ;;; ("target" ("prereq0" ...) is-out-of-date? (lambda () ?action0 ...))) ;;; ;;; or this ;;; ;;; (cons ("target" ("prereq0" ...) is-out-of-date? (lambda () ?action0 ...) ;;; ())) ;;; ;;; The car of each result then goes into the file-rules-list while the ;;; cdr goes into the common-rules-list. At the end those elements in each ;;; of the file-rules-list and the common-rules-list being empty lists are ;;; removed. The result are the cons-ed remaining lists. ;;; (define-syntax sort-rules (syntax-rules () ((sort-rules (?file0 ...) (?common0 ...)) (let ((file-rules (remove null? (list ?file0 ...))) (common-rules (remove null? (list ?common0 ...)))) (cons file-rules common-rules))) ((sort-rules (?file1 ...) (?common1 ...) ?rule0 ?rule1 ...) (let ((rule-result ?rule0)) (let ((common0 (cdr rule-result)) (file0 (car rule-result))) (sort-rules (file0 ?file1 ...) (common0 ?common1 ...) ?rule1 ...)))))) ;;; ;;; MAKERULE-CLAUSES: ;;; ================= ;;; ;;; ;;; ;;; (define-syntax makefile-rule (syntax-rules () ((makefile-rule ?target ?prereqs ?action0 ...) (file ?target ?prereqs ?action0 ...)))) (define-syntax is-out-of-date? (syntax-rules () ((is-out-of-date? ?target ?prereqs ?action0 ...) (file ?target ?prereqs ?action0 ...)))) (define-syntax file (syntax-rules () ((file ?target (?prereq0 ...) ?action0 ...) (file-tmpvars () ?target (?prereq0 ...) ?action0 ...)))) (define-syntax file-tmpvars (syntax-rules () ((file-tmpvars (tmp1 ...) ?target () ?action0 ...) (let ((target ?target) (prereqs (list tmp1 ...)) (thunk (lambda () ?action0 ...))) (cons (list target prereqs (make-is-out-of-date? target tmp1 ...) (make-file-build-func target prereqs thunk)) (list)))) ((file-tmpvars (tmp1 ...) ?target (?prereq0 ?prereq1 ...) ?action0 ...) (let ((tmp2 ?prereq0)) (file-tmpvars (tmp1 ... tmp2) ?target (?prereq1 ...) ?action0 ...))))) ;;; ;;; ;;; (define-syntax all (syntax-rules () ((makefile-rule ?target ?prereqs ?action0 ...) (file-all ?target ?prereqs ?action0 ...)))) (define-syntax all-out-of-date? (syntax-rules () ((all-out-of-date? ?target ?prereqs ?action0 ...) (file-all ?target ?prereqs ?action0 ...)))) (define-syntax file-all (syntax-rules () ((file-all ?target (?prereq0 ...) ?action0 ...) (file-all-tmpvars () ?target (?prereq0 ...) ?action0 ...)))) (define-syntax file-all-tmpvars (syntax-rules () ((file-all-tmpvars (tmp1 ...) ?target () ?action0 ...) (let ((target ?target) (prereqs (list tmp1 ...)) (thunk (lambda () ?action0 ...))) (cons (list target prereqs (make-all-out-of-date? target tmp1 ...) (make-all-build-func target prereqs thunk)) (list)))) ((file-all-tmpvars (tmp1 ...) ?target (?prereq0 ?prereq1 ...) ?action0 ...) (let ((tmp2 ?prereq0)) (file-all-tmpvars (tmp1 ... tmp2) ?target (?prereq1 ...) ?action0 ...))))) ;;; ;;; ;;; (define-syntax md5 (syntax-rules () ((md5 ?target ?prereqs ?action0 ...) (file-md5 ?target ?prereqs ?action0 ...)))) (define-syntax file-md5 (syntax-rules () ((file-md5 ?target (?prereq0 ...) ?action0 ...) (file-md5-tmpvars () ?target (?prereq0 ...) ?action0 ...)))) (define-syntax file-md5-tmpvars (syntax-rules () ((file-md5-tmpvars (tmp1 ...) ?target () ?action0 ...) (let ((target ?target) (prereqs (list tmp1 ...)) (thunk (lambda () ?action0 ...))) (cons (list target prereqs (make-md5-sum-changed? target tmp1 ...) (make-md5-build-func target prereqs thunk)) (list)))) ((file-md5-tmpvars (tmp1 ...) ?target (?prereq0 ?prereq1 ...) ?action0 ...) (let ((tmp2 ?prereq0)) (file-md5-tmpvars (tmp1 ... tmp2) ?target (?prereq1 ...) ?action0 ...))))) ;;; ;;; ;;; (define-syntax phony (syntax-rules () ((phony ?target ?prereqs ?action0 ...) (file-always ?target ?prereqs ?action0 ...)))) (define-syntax always (syntax-rules () ((always ?target ?prereqs ?action0 ...) (file-always ?target ?prereqs ?action0 ...)))) (define-syntax is-out-of-date! (syntax-rules () ((is-out-of-date! ?target ?prereqs ?action0 ...) (file-always ?target ?prereqs ?action0 ...)))) (define-syntax file-always (syntax-rules () ((file-always ?target ?prereqs ?action0 ...) (file-always-tmpvars () ?target ?prereqs ?action0 ...)))) (define-syntax file-always-tmpvars (syntax-rules () ((file-always-tmpvars (tmp1 ...) ?target () ?action0 ...) (let ((target ?target) (prereqs (list tmp1 ...)) (thunk (lambda () ?action0 ...))) (cons (list target prereqs (make-is-out-of-date! target tmp1 ...) (make-always-build-func target prereqs thunk)) (list)))) ((file-always-tmpvars (tmp1 ...) ?target (?prereq0 ?prereq1 ...) ?action0 ...) (let ((tmp2 ?prereq0)) (file-always-tmpvars (tmp1 ... tmp2) ?target (?prereq1 ...) ?action0 ...))))) ;;; ;;; ;;; (define-syntax once (syntax-rules () ((once ?target ?prereqs ?action0 ...) (file-once ?target ?prereqs ?action0 ...)))) (define-syntax file-once (syntax-rules () ((file-once ?target (?prereq0 ...) ?action0 ...) (file-once-tmpvars () ?target (?prereq0 ...) ?action0 ...)))) (define-syntax file-once-tmpvars (syntax-rules () ((file-once-tmpvars (tmp1 ...) ?target () ?action0 ...) (let ((target ?target) (prereqs (list tmp1 ...)) (thunk (lambda () ?action0 ...))) (cons (list target prereqs (make-once target tmp1 ...) (make-once-build-func target prereqs thunk)) (list)))) ((file-once-tmpvars (tmp1 ...) ?target (?prereq0 ?prereq1 ...) ?action0 ...) (let ((tmp2 ?prereq0)) (file-once-tmpvars (tmp1 ... tmp2) ?target (?prereq1 ...) ?action0 ...))))) ;;; COMMON-MAKERULE-CLAUSES: ;;; ======================== ;;; ;;; ;;; ;;; ;;; (define-syntax common-file (syntax-rules () ((common-file ?target (?prereq0 ...) ?action0 ...) (common-file-tmpvars () ?target (?prereq0 ...) ?action0 ...)))) (define-syntax common-file-tmpvars (syntax-rules () ((common-file-tmpvars (tmp1 ...) ?target () ?action0 ...) (let ((target ?target) (prereqs (list tmp1 ...)) (thunk (lambda () ?action0 ...))) (cons (list) (list target prereqs (make-common-is-out-of-date? target tmp1 ...) (make-common-file-build-func target prereqs thunk))))) ((common-file-tmpvars (tmp1 ...) ?target (?prereq0 ?prereq1 ...) ?action0 ...) (let ((tmp2 ?prereq0)) (common-file-tmpvars (tmp1 ... tmp2) ?target (?prereq1 ...) ?action0 ...))))) ;;; ;;; ;;; ;;; to achieve consistency only file will use the file-tmpvars ;;; macro directly and all other macros use this clause ;;; (define-syntax common-all (syntax-rules () ((common-all ?target ?prereqs ?action0 ...) (common-file-all ?target ?prereqs ?action0 ...)))) (define-syntax common-file-all (syntax-rules () ((common-file-all ?target (?prereq0 ...) ?action0 ...) (common-file-all-tmpvars () ?target (?prereq0 ...) ?action0 ...)))) (define-syntax common-file-all-tmpvars (syntax-rules () ((common-file-all-tmpvars (tmp1 ...) ?target () ?action0 ...) (let ((target ?target) (prereqs (list tmp1 ...)) (thunk (lambda () ?action0 ...))) (cons (list) (list target prereqs (make-common-all-out-of-date? target tmp1 ...) (make-common-all-build-func target prereqs thunk))))) ((common-file-all-tmpvars (tmp1 ...) ?target (?prereq0 ?prereq1 ...) ?action0 ...) (let ((tmp2 ?prereq0)) (common-file-all-tmpvars (tmp1 ... tmp2) ?target (?prereq1 ...) ?action0 ...))))) ;;; ;;; ;;; (define-syntax common-md5 (syntax-rules () ((common-md5 ?target ?prereqs ?action0 ...) (common-file-md5 ?target ?prereqs ?action0 ...)))) (define-syntax common-file-md5 (syntax-rules () ((common-file-md5 ?target (?prereq0 ...) ?action0 ...) (common-file-md5-tmpvars () ?target (?prereq0 ...) ?action0 ...)))) (define-syntax common-file-md5-tmpvars (syntax-rules () ((common-file-md5-tmpvars (tmp1 ...) ?target () ?action0 ...) (let ((target ?target) (prereqs (list tmp1 ...)) (thunk (lambda () ?action0 ...))) (cons (list) (list target prereqs (make-common-md5-sum-changed? target tmp1 ...) (make-common-md5-build-func target prereqs thunk))))) ((common-file-md5-tmpvars (tmp1 ...) ?target (?prereq0 ?prereq1 ...) ?action0 ...) (let ((tmp2 ?prereq0)) (common-file-md5-tmpvars (tmp1 ... tmp2) ?target (?prereq1 ...) ?action0 ...))))) ;;; ;;; ;;; (define-syntax common-always (syntax-rules () ((common-always ?target ?prereqs ?action0 ...) (common-file-always ?target ?prereqs ?action0 ...)))) (define-syntax common-file-always (syntax-rules () ((common-file-always ?target ?prereqs ?action0 ...) (common-file-always-tmpvars () ?target ?prereqs ?action0 ...)))) (define-syntax common-file-always-tmpvars (syntax-rules () ((common-file-always-tmpvars (tmp1 ...) ?target () ?action0 ...) (let ((target ?target) (prereqs (list tmp1 ...)) (thunk (lambda () ?action0 ...))) (cons (list) (list target prereqs (make-common-is-out-of-date! target tmp1 ...) (make-common-always-build-func target prereqs thunk))))) ((common-file-always-tmpvars (tmp1 ...) ?target (?prereq0 ?prereq1 ...) ?action0 ...) (let ((tmp2 ?prereq0)) (common-file-always-tmpvars (tmp1 ... tmp2) ?target (?prereq1 ...) ?action0 ...))))) ;;; ;;; ;;; (define-syntax common-once (syntax-rules () ((common-once ?target ?prereqs ?action0 ...) (common-file-once ?target ?prereqs ?action0 ...)))) (define-syntax common-file-once (syntax-rules () ((common-file-once ?target (?prereq0 ...) ?action0 ...) (common-file-once-tmpvars () ?target (?prereq0 ...) ?action0 ...)))) (define-syntax common-file-once-tmpvars (syntax-rules () ((common-file-once-tmpvars (tmp1 ...) ?target () ?action0 ...) (let ((target ?target) (prereqs (list tmp1 ...)) (thunk (lambda () ?action0 ...))) (cons (list) (list target prereqs (make-common-once target tmp1 ...) (make-common-once-build-func target prereqs thunk))))) ((common-file-once-tmpvars (tmp1 ...) ?target (?prereq0 ?prereq1 ...) ?action0 ...) (let ((tmp2 ?prereq0)) (common-file-once-tmpvars (tmp1 ... tmp2) ?target (?prereq1 ...) ?action0 ...)))))