let-macro.scm 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. #| -*-Scheme-*-
  2. Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
  3. 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
  4. 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Massachusetts
  5. Institute of Technology
  6. This file is part of MIT/GNU Scheme.
  7. MIT/GNU Scheme is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or (at
  10. your option) any later version.
  11. MIT/GNU Scheme is distributed in the hope that it will be useful, but
  12. WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. General Public License for more details.
  15. You should have received a copy of the GNU General Public License
  16. along with MIT/GNU Scheme; if not, write to the Free Software
  17. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,
  18. USA.
  19. |#
  20. ;;; Almost right... Make patterns recursive...
  21. (define-syntax let&
  22. (rsc-macro-transformer
  23. (lambda (form defn-env)
  24. (define (make-let&-match pattern access-chain source)
  25. (apply append
  26. (map (lambda (v i)
  27. (cond ((eq? v '_) '())
  28. ((symbol? v)
  29. (list `(,v (ref ,source ,@access-chain ,i))))
  30. ((list? v)
  31. (make-let&-match v (append access-chain (list i)) source))
  32. (else (error "Ill-structured LET&" form))))
  33. pattern (iota (length pattern)))))
  34. (if (list? (cadr form))
  35. (let ((extends (filter (lambda (b) (list? (car b))) (cadr form))))
  36. (if (null? extends)
  37. `(let ,@(cdr form))
  38. (let ((gens (map (lambda (x) (generate-uninterned-symbol)) extends)))
  39. (let ((newbindings
  40. (let loop ((bindings (cadr form)) (gens gens))
  41. (if (null? bindings)
  42. '()
  43. (let ((b (car bindings)))
  44. (cond ((symbol? (car b))
  45. (cons b (loop (cdr bindings) gens)))
  46. ((list? (car b))
  47. (append (make-let&-match (car b) '() (car gens))
  48. (loop (cdr bindings) (cdr gens))))
  49. (else (error "Ill-structured LET&" form))))))))
  50. `(let ,(map (lambda (gen extend)
  51. `(,gen ,(cadr extend)))
  52. gens extends)
  53. (let ,newbindings
  54. ,@(cddr form)))))))
  55. (error "Cannot make named LET&, sorry..." form)))))
  56. #|
  57. (pp
  58. (unsyntax
  59. (syntax
  60. '(let& ((a b) (c d)) e)
  61. user-initial-environment)))
  62. (let ((a b) (c d))
  63. e)
  64. (pp
  65. (unsyntax
  66. (syntax
  67. '(let& ((a b) ((x y) foo) (c d)) e)
  68. user-initial-environment)))
  69. (let ((|G1| foo))
  70. (let ((a b) (x (ref |G1| 0)) (y (ref |G1| 1)) (c d))
  71. e))
  72. (pp
  73. (unsyntax
  74. (syntax
  75. '(let& ((a b) ((x y) foo) ((u v) bar) (c d)) e)
  76. user-initial-environment)))
  77. (let ((|G2| foo) (|G3| bar))
  78. (let ((a b)
  79. (x (ref |G2| 0)) (y (ref |G2| 1))
  80. (u (ref |G3| 0)) (v (ref |G3| 1))
  81. (c d))
  82. e))
  83. ;;; Can use _ to make ignorable reference
  84. (pp
  85. (unsyntax
  86. (syntax
  87. '(let& ((a b) ((x y) foo) ((u _ w) bar) (c d)) e)
  88. user-initial-environment)))
  89. (let ((|G7| foo) (|G8| bar))
  90. (let ((a b)
  91. (x (ref |G7| 0)) (y (ref |G7| 1))
  92. (u (ref |G8| 0)) (w (ref |G8| 2))
  93. (c d))
  94. e))
  95. |#
  96. #|
  97. ;;; Actual use case...
  98. (define ((L m g) state)
  99. (let& (((_ (x y) v) state))
  100. (- (* 1/2 m (square v))
  101. (* m g y))))
  102. (pp L)
  103. (named-lambda (L m g)
  104. (lambda (state)
  105. (let ((G75 state))
  106. (let ((x (ref G75 1 0)) (y (ref G75 1 1)) (v (ref G75 2)))
  107. (- (* 1/2 m (square v)) (* m g y))))))
  108. (((Lagrange-equations (L 'm 'g))
  109. (up (literal-function 'x) (literal-function 'y)))
  110. 't)
  111. #|
  112. (down (* m (((expt D 2) x) t))
  113. (+ (* g m) (* m (((expt D 2) y) t))))
  114. |#
  115. |#