diff options
author | Ludovic Courtès <ludo@gnu.org> | 2021-12-18 17:54:23 +0100 |
---|---|---|
committer | Ludovic Courtès <ludo@gnu.org> | 2021-12-20 16:21:40 +0100 |
commit | ddf9345dfec208611261ab06052de47fe8873f88 (patch) | |
tree | c729962e740548bd7ca5dcfcf98ea9195b21d933 | |
parent | bdaf38a6e04052a22b62ae41c72f32cf16356314 (diff) |
combinators: Add 'define-compile-time-procedure'.
* guix/combinators.scm (procedure-call-location): New syntax parameter.
(define-compile-time-procedure): New macro.
-rw-r--r-- | guix/combinators.scm | 50 |
1 files changed, 48 insertions, 2 deletions
diff --git a/guix/combinators.scm b/guix/combinators.scm index 88ad09dbe6..261d6bb57e 100644 --- a/guix/combinators.scm +++ b/guix/combinators.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org> +;;; Copyright © 2012-2017, 2021 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2014 Eric Bavier <bavier@member.fsf.org> ;;; Copyright © 2020 Arun Isaac <arunisaac@systemreboot.net> ;;; @@ -24,7 +24,9 @@ #:export (fold2 fold-tree fold-tree-leaves - compile-time-value)) + compile-time-value + procedure-call-location + define-compile-time-procedure)) ;;; Commentary: ;;; @@ -100,4 +102,48 @@ evaluate to a simple datum." (_ #`'#,(datum->syntax s val))))))) v)))) +(define-syntax-parameter procedure-call-location + (lambda (s) + (syntax-violation 'procedure-call-location + "'procedure-call-location' may only be used \ +within 'define-compile-time-procedure'" + s))) + +(define-syntax-rule (define-compile-time-procedure (proc (arg pred) ...) + body ...) + "Define PROC as a macro such that, if every actual argument in a \"call\" +matches PRED, then BODY is evaluated at macro-expansion time. BODY must +return a single value in a type that has read syntax--e.g., numbers, strings, +lists, etc. + +BODY can refer to 'procedure-call-location', which is bound to a source +property alist corresponding to the call site. + +This macro is meant to be used primarily for small procedures that validate or +process its arguments in a way that may be equally well performed at +macro-expansion time." + (define-syntax proc + (lambda (s) + (define loc + #`(identifier-syntax + '#,(datum->syntax #'s (syntax-source s)))) + + (syntax-case s () + ((_ arg ...) + (and (pred (syntax->datum #'arg)) ...) + (let ((arg (syntax->datum #'arg)) ...) + (syntax-parameterize ((procedure-call-location + (identifier-syntax (syntax-source s)))) + body ...))) + ((_ actual (... ...)) + #`((lambda (arg ...) + (syntax-parameterize ((procedure-call-location #,loc)) + body ...)) + actual (... ...))) + (id + (identifier? #'id) + #`(lambda (arg ...) + (syntax-parameterize ((procedure-call-location #,loc)) + body ...))))))) + ;;; combinators.scm ends here |