|
19 | 19 | ;@---------------------------------------------------------------------------------------------------- |
20 | 20 |
|
21 | 21 |
|
22 | | -;; A short lambda suitable for fusing with a for loop. Needs both single-attribute and |
23 | | -;; multi-attribute versions of the body for different template contexts. |
| 22 | +;; A short lambda suitable for fusing with a for loop. For multi-body lambdas, we need to |
| 23 | +;; separate the prefix forms (all but last) from the result form (the last). |
24 | 24 | (define-syntax-class fuseable-map-lambda |
25 | | - #:attributes (x single-body [multi-body 1]) |
| 25 | + #:attributes (x single-body [multi-body 1] [prefix-forms 1] result-form) |
26 | 26 |
|
27 | | - ;; Lambdas with let expressions that can be refactored - must come first as it's most specific |
| 27 | + ;; Lambdas with let expressions that can be refactored |
28 | 28 | (pattern |
29 | 29 | (_:lambda-by-any-name (x:id) |
30 | 30 | original-body:body-with-refactorable-let-expression) |
31 | | - #:attr [multi-body 1] (attribute original-body.refactored) |
32 | | - ;; For single body, we need to wrap multiple forms in a begin |
| 31 | + #:with (multi-body ...) #'(original-body.refactored ...) |
| 32 | + #:attr [prefix-forms 1] (attribute original-body.refactored) |
| 33 | + #:attr result-form #'(begin) |
33 | 34 | #:attr single-body #'(begin original-body.refactored ...)) |
34 | 35 |
|
35 | 36 | ;; Lambdas with multiple body forms (two or more) |
36 | | - (pattern (_:lambda-by-any-name (x:id) first-form second-form rest-form ...) |
37 | | - #:attr [multi-body 1] (cons (attribute first-form) |
38 | | - (cons (attribute second-form) (attribute rest-form))) |
39 | | - #:attr single-body #'(begin first-form second-form rest-form ...)) |
| 37 | + (pattern (_:lambda-by-any-name (x:id) prefix-form ... last-form) |
| 38 | + #:when (not (null? (attribute prefix-form))) |
| 39 | + #:with (multi-body ...) #'(prefix-form ... last-form) |
| 40 | + #:attr [prefix-forms 1] (attribute prefix-form) |
| 41 | + #:attr result-form #'last-form |
| 42 | + #:attr single-body #'(begin prefix-form ... last-form)) |
40 | 43 |
|
41 | 44 | ;; Short lambdas with a single body form |
42 | 45 | (pattern (_:lambda-by-any-name (x:id) only-form) |
43 | | - #:attr [multi-body 1] (list (attribute only-form)) |
| 46 | + #:with (multi-body ...) #'(only-form) |
| 47 | + #:attr [prefix-forms 1] '() |
| 48 | + #:attr result-form #'only-form |
44 | 49 | #:attr single-body #'only-form)) |
45 | 50 |
|
46 | 51 |
|
|
64 | 69 | ;; Generate the refactored code - fuse as nested clauses |
65 | 70 | (body-before ... |
66 | 71 | (for-id ([function.x (in-list list-expr)] |
67 | | - [y-var (in-list (function.multi-body ...))] |
| 72 | + [y-var (in-list function.single-body)] |
68 | 73 | remaining-clause ...) |
69 | 74 | for-body ...) |
70 | 75 | body-after ...)) |
|
91 | 96 | ;; Generate the refactored code - use internal definition |
92 | 97 | (body-before ... |
93 | 98 | (for-id ([function.x (in-list list-expr)]) |
94 | | - (define y-var function.single-body) |
| 99 | + function.prefix-forms ... |
| 100 | + (define y-var function.result-form) |
95 | 101 | for-body ...) |
96 | 102 | body-after ...)) |
97 | 103 |
|
|
0 commit comments