[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Guile-commits] 05/07: Correctly pass on keyword arguments actually pres
From: |
Mikael Djurfeldt |
Subject: |
[Guile-commits] 05/07: Correctly pass on keyword arguments actually present in args list |
Date: |
Mon, 25 Nov 2024 15:54:17 -0500 (EST) |
mdj pushed a commit to branch main
in repository guile.
commit f057e02d9a9cfd98a4e8e18d0d045283647e8f2c
Author: Mikael Djurfeldt <mikael@djurfeldt.com>
AuthorDate: Mon Nov 25 11:17:41 2024 +0100
Correctly pass on keyword arguments actually present in args list
* module/oop/goops.scm (compute-keyword-formal-ids): Renamed from
->keyword-formal-ids; modified to do work both on the list of formals
and the list of formal ids in the next-method call.
(compute-make-procedure): Use compute-keyword-formal-ids.
---
module/oop/goops.scm | 81 +++++++++++++++++++++++++++++++++++++---------------
1 file changed, 58 insertions(+), 23 deletions(-)
diff --git a/module/oop/goops.scm b/module/oop/goops.scm
index 5ef39d17f..12644eba5 100644
--- a/module/oop/goops.scm
+++ b/module/oop/goops.scm
@@ -2221,30 +2221,72 @@ function."
(() (cons (reverse out) '()))
(tail (cons (reverse out) #'tail)))))
- ;; keyword-formal-ids KEYWORD-FORMALS
+ ;; compute-keyword-formal-ids FORMALS KEYWORD-FORMALS
;;
- ;; return a form corresponding to KEYWORD-FORMALS but with
- ;; identifiers only (keywords removed) The value returned has the
- ;; formals-ids format as described above.
+ ;; The main purpose of this beast is to compute the argument list
+ ;; for the actual next-method call for the case where the user calls
+ ;; (next-method). It is invoked in the case where we have keyword
+ ;; formals. Here we have to treat keyword arguments in a special way
+ ;; since we, similar to CLOS, only want to pass on the keyword
+ ;; arguments that were present in the call. We capture those using
+ ;; the rest argument. If not present, we introduce a rest formal.
;;
- ;; The output is used in the next-method application form.
+ ;; FORMALS is the non-keyword part of the formal arguments.
+ ;; KEYWORD-FORMALS is the part of the formal arguments from the
+ ;; first keyword.
;;
- (define (->keyword-formal-ids keyword-formals)
- (let lp ((ls keyword-formals) (out '()))
+ ;; return three values:
+ ;;
+ ;; 1. #'lambda
+ ;; 2. the complete formals list
+ ;; 3. the argument list for next-method in formals-ids format as
+ ;; described above (proper list in CAR, tail in CDR)
+ ;;
+ (define (compute-keyword-formal-ids formals keyword-formals)
+ (define (result formals formal-ids)
+ (values #'lambda* formals formal-ids))
+
+ (define (lp-key ls formals formal-ids)
(syntax-case ls ()
- (((f val) . rest)
- (lp #'rest out))
((#:rest f)
- (cons (reverse out) #'f))
+ (identifier? #'f)
+ (result (append (reverse formals) #'f)
+ (cons (reverse formal-ids) #'f)))
+ (()
+ ;; No rest formal is present, so we need to introduce one.
+ (let ((rest-formal (car (generate-temporaries '(rest)))))
+ (result (append (reverse formals) rest-formal)
+ (cons (reverse formal-ids) rest-formal))))
((f . rest)
- (keyword? (syntax->datum #'f))
- (lp #'rest out))
+ (lp-key #'rest
+ (cons #'f formals) ;keep
+ formal-ids)) ;filter away
+ (tail
+ (result (append (reverse formals) #'tail)
+ (cons (reverse formal-ids) #'tail)))))
+
+ (let ((reversed-formals (reverse formals)))
+ (let lp ((ls keyword-formals)
+ (formals reversed-formals)
+ (formal-ids reversed-formals))
+ (syntax-case ls ()
+ (((f val) . rest)
+ (lp #'rest (cons #'(f val) formals) (cons #'f formal-ids)))
+ ((#:optional . rest)
+ (lp #'rest (cons #:optional formals) formal-ids))
+ ((#:key . rest)
+ (lp-key #'rest (cons #:key formals) formal-ids))
+ ((#:rest f)
+ (identifier? #'f)
+ (result (append (reverse formals) #'f)
+ (cons (reverse formal-ids) #'f)))
((f . rest)
- (lp #'rest (cons #'f out)))
+ (lp #'rest (cons #'f formals) (cons #'f formal-ids)))
(()
- (cons (reverse out) '()))
+ (result (reverse formals) (cons (reverse formal-ids) '())))
(tail
- (cons (reverse out) #'tail)))))
+ (result (append (reverse formals) #'tail)
+ (cons (reverse formal-ids) #'tail)))))))
(define (compute-make-procedure formals keyword-formals body next-method)
(syntax-case body ()
@@ -2255,14 +2297,7 @@ function."
(values #'lambda
formals
(->formal-ids formals))
- (values #'lambda*
- (append formals keyword-formals)
- (let ((keyword-formal-ids
- ;; filter out the identifiers
- (->keyword-formal-ids keyword-formals)))
- ;; input and result in formals-ids format
- (cons (append formals (car keyword-formal-ids))
- (cdr keyword-formal-ids))))))
+ (compute-keyword-formal-ids formals keyword-formals)))
(lambda (lambda-type formals formal-ids)
(with-syntax ((next-method next-method))
(syntax-case formals ()
- [Guile-commits] branch main updated (c51fcfffb -> a3c77cb8d), Mikael Djurfeldt, 2024/11/25
- [Guile-commits] 02/07: GOOPS: Introduce new forms method* and define-method*, Mikael Djurfeldt, 2024/11/25
- [Guile-commits] 03/07: Remove method slot keyword-formals? introduced in 765f1d49, Mikael Djurfeldt, 2024/11/25
- [Guile-commits] 04/07: Distinguish between lambda and lambda* in generated procedures, Mikael Djurfeldt, 2024/11/25
- [Guile-commits] 05/07: Correctly pass on keyword arguments actually present in args list,
Mikael Djurfeldt <=
- [Guile-commits] 06/07: Document method* and define-method*, Mikael Djurfeldt, 2024/11/25
- [Guile-commits] 01/07: GOOPS: Add support for keyword arguments in methods, Mikael Djurfeldt, 2024/11/25
- [Guile-commits] 07/07: Update NEWS, Mikael Djurfeldt, 2024/11/25