recfun.scm 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. ;;; recfun: an example Pre-Scheme program
  2. (define-record-type vec2 :vec2
  3. (%make-vec2 x y)
  4. (x integer vec2-x)
  5. (y integer vec2-y))
  6. (define-syntax vec2
  7. (syntax-rules ()
  8. ((vec2 x y)
  9. (%make-vec2 x y))))
  10. (define (vec2+ a b)
  11. (vec2 (+ (vec2-x a) (vec2-x b))
  12. (+ (vec2-y a) (vec2-y b))))
  13. (define (vec2- a b)
  14. (vec2 (- (vec2-x a) (vec2-x b))
  15. (- (vec2-y a) (vec2-y b))))
  16. (define (write-vec2 a port)
  17. (write-string "#<vec2 " port)
  18. (write-integer (vec2-x a) port)
  19. (write-char #\space port)
  20. (write-integer (vec2-y a) port)
  21. (write-char #\> port))
  22. (define-record-type rect :rect
  23. (%make-rect tl wh)
  24. (tl vec2 %rect-tl)
  25. (wh vec2 %rect-wh))
  26. (define-syntax rect
  27. (syntax-rules ()
  28. ((rect x y w h)
  29. (%make-rect (vec2 x y) (vec2 w h)))))
  30. (define (rect-left a) (vec2-x (%rect-tl a)))
  31. (define (rect-top a) (vec2-y (%rect-tl a)))
  32. (define (rect-width a) (vec2-x (%rect-wh a)))
  33. (define (rect-height a) (vec2-y (%rect-wh a)))
  34. (define (rect-bottom a) (+ (rect-top a) (rect-height a)))
  35. (define (rect-right a) (+ (rect-left a) (rect-width a)))
  36. (define (rect-top-left a) (vec2 (rect-left a) (rect-top a)))
  37. (define (rect-top-right a) (vec2 (rect-right a) (rect-top a)))
  38. (define (rect-bottom-left a) (vec2 (rect-left a) (rect-bottom a)))
  39. (define (rect-bottom-right a) (vec2 (rect-right a) (rect-bottom a)))
  40. (define (write-rect a port)
  41. (write-string "#<rect " port)
  42. (write-integer (rect-left a) port)
  43. (write-char #\space port)
  44. (write-integer (rect-top a) port)
  45. (write-char #\space port)
  46. (write-integer (rect-width a) port)
  47. (write-char #\space port)
  48. (write-integer (rect-height a) port)
  49. (write-char #\> port))
  50. (define (main)
  51. (define out (current-output-port))
  52. (let ((a (rect 10 10 2 2))
  53. (write-corner (lambda (name corner out)
  54. (write-string name out)
  55. (write-string ": " out)
  56. (write-vec2 corner out)
  57. (newline out)
  58. (deallocate corner)
  59. (unspecific))))
  60. (write-rect a out)
  61. (newline out)
  62. (write-corner "top-left" (rect-top-left a) out)
  63. (write-corner "top-right" (rect-top-right a) out)
  64. (write-corner "bottom-left" (rect-bottom-left a) out)
  65. (write-corner "bottom-right" (rect-bottom-right a) out))
  66. 0)