bindings.lisp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. (import test ())
  2. (import tests/compiler/codegen/codegen-helpers ())
  3. (describe "The codegen"
  4. (section "will generate value wrappers"
  5. (it "for normal arguments"
  6. (affirm-codegen
  7. '(((lambda (x) x) (foo)))
  8. "return (foo())"))
  9. (it "for variadic arguments with a known value set"
  10. (affirm-codegen
  11. '(((lambda (&x) x) (foo) 2))
  12. "return {tag=\"list\", n=2, foo(), 2}"))
  13. (it "unless there are an unknown number of values"
  14. (affirm-codegen
  15. '(((lambda (&x) x) (foo)))
  16. "local x = _pack(foo()) x.tag = \"list\"
  17. return x")))
  18. (section "will which handle lambdas with variadic arguments"
  19. (it "on their own"
  20. (with (fn (lambda (&fst) fst))
  21. (affirm (eq? `() (fn))
  22. (eq? '(1) (fn 1))
  23. (eq? '(1 2) (fn 1 2)))))
  24. (it "at the beginning"
  25. (with (fn (lambda (&fst snd last) (list fst snd last)))
  26. (affirm (eq? `(() 1 ,nil) (fn 1))
  27. (eq? '(() 1 2) (fn 1 2))
  28. (eq? '((1) 2 3) (fn 1 2 3))
  29. (eq? '((1 2) 3 4) (fn 1 2 3 4))
  30. (eq? '((1 2 3) 4 5) (fn 1 2 3 4 5)))))
  31. (it "in the middle"
  32. (with (fn (lambda (fst snd &middle last) (list fst snd middle last)))
  33. (affirm (eq? `(1 ,nil () ,nil) (fn 1))
  34. (eq? `(1 2 () ,nil) (fn 1 2))
  35. (eq? '(1 2 () 3) (fn 1 2 3))
  36. (eq? '(1 2 (3) 4) (fn 1 2 3 4))
  37. (eq? '(1 2 (3 4) 5) (fn 1 2 3 4 5)))))
  38. (it "at the end"
  39. (with (fn (lambda (fst snd &last) (list fst snd last)))
  40. (affirm (eq? `(1 ,nil ()) (fn 1))
  41. (eq? '(1 2 ()) (fn 1 2))
  42. (eq? '(1 2 (3)) (fn 1 2 3))
  43. (eq? '(1 2 (3 4)) (fn 1 2 3 4))
  44. (eq? '(1 2 (3 4 5)) (fn 1 2 3 4 5))))))
  45. (section "generate the appropriate code for lambdas with variadic arguments"
  46. (it "on their own"
  47. (affirm-codegen
  48. '((lambda (&args) 1))
  49. "return function(...)
  50. local args = _pack(...) args.tag = \"list\"
  51. return 1
  52. end"))
  53. (it "at the beginning"
  54. (affirm-codegen
  55. '((lambda (&args x) 1))
  56. "return function(...)
  57. local _n = _select(\"#\", ...) - 1
  58. local args, x
  59. if _n > 0 then
  60. args = {tag=\"list\", n=_n, _unpack(_pack(...), 1, _n)}
  61. x = select(_n + 1, ...)
  62. else
  63. args = {tag=\"list\", n=0}
  64. x = ...
  65. end
  66. return 1
  67. end")))
  68. (section "will which handle bindings with variable arguments"
  69. (section "and a known number of values"
  70. (it "at the beginning"
  71. (affirm (eq? `(() 1 ,nil) ((lambda (&fst snd last) (list fst snd last)) 1))
  72. (eq? `(() 1 2) ((lambda (&fst snd last) (list fst snd last)) 1 2))
  73. (eq? '((1) 2 3) ((lambda (&fst snd last) (list fst snd last)) 1 2 3))
  74. (eq? '((1 2) 3 4) ((lambda (&fst snd last) (list fst snd last)) 1 2 3 4))
  75. (eq? '((1 2 3) 4 5) ((lambda (&fst snd last) (list fst snd last)) 1 2 3 4 5))))
  76. (it "in the middle"
  77. (affirm (eq? `(1 ,nil () ,nil) ((lambda (fst snd &middle last) (list fst snd middle last)) 1))
  78. (eq? `(1 2 () ,nil) ((lambda (fst snd &middle last) (list fst snd middle last)) 1 2))
  79. (eq? '(1 2 () 3) ((lambda (fst snd &middle last) (list fst snd middle last)) 1 2 3))
  80. (eq? '(1 2 (3) 4) ((lambda (fst snd &middle last) (list fst snd middle last)) 1 2 3 4))
  81. (eq? '(1 2 (3 4) 5) ((lambda (fst snd &middle last) (list fst snd middle last)) 1 2 3 4 5))))
  82. (it "at the end"
  83. (affirm (eq? `(1 ,nil ()) ((lambda (fst snd &last) (list fst snd last)) 1))
  84. (eq? '(1 2 ()) ((lambda (fst snd &last) (list fst snd last)) 1 2))
  85. (eq? '(1 2 (3)) ((lambda (fst snd &last) (list fst snd last)) 1 2 3))
  86. (eq? '(1 2 (3 4)) ((lambda (fst snd &last) (list fst snd last)) 1 2 3 4))
  87. (eq? '(1 2 (3 4 5)) ((lambda (fst snd &last) (list fst snd last)) 1 2 3 4 5)))))
  88. (section "and an unknown number of values"
  89. (it "at the beginning"
  90. (affirm (eq? `(() 1 ,nil) ((lambda (&fst snd last) (list fst snd last)) (values-list 1)))
  91. (eq? `(() 1 2) ((lambda (&fst snd last) (list fst snd last)) (values-list 1 2)))
  92. (eq? '((1) 2 3) ((lambda (&fst snd last) (list fst snd last)) (values-list 1 2 3)))
  93. (eq? '((1 2) 3 4) ((lambda (&fst snd last) (list fst snd last)) (values-list 1 2 3 4)))
  94. (eq? '((1 2 3) 4 5) ((lambda (&fst snd last) (list fst snd last)) (values-list 1 2 3 4 5)))))
  95. (it "in the middle"
  96. (affirm (eq? `(1 ,nil () ,nil) ((lambda (fst snd &middle last) (list fst snd middle last)) (values-list 1)))
  97. (eq? `(1 2 () ,nil) ((lambda (fst snd &middle last) (list fst snd middle last)) (values-list 1 2)))
  98. (eq? '(1 2 () 3) ((lambda (fst snd &middle last) (list fst snd middle last)) (values-list 1 2 3)))
  99. (eq? '(1 2 (3) 4) ((lambda (fst snd &middle last) (list fst snd middle last)) (values-list 1 2 3 4)))
  100. (eq? '(1 2 (3 4) 5) ((lambda (fst snd &middle last) (list fst snd middle last)) (values-list 1 2 3 4 5)))))
  101. (it "at the end"
  102. (affirm (eq? `(1 ,nil ()) ((lambda (fst snd &last) (list fst snd last)) (values-list 1)))
  103. (eq? '(1 2 ()) ((lambda (fst snd &last) (list fst snd last)) (values-list 1 2)))
  104. (eq? '(1 2 (3)) ((lambda (fst snd &last) (list fst snd last)) (values-list 1 2 3)))
  105. (eq? '(1 2 (3 4)) ((lambda (fst snd &last) (list fst snd last)) (values-list 1 2 3 4)))
  106. (eq? '(1 2 (3 4 5)) ((lambda (fst snd &last) (list fst snd last)) (values-list 1 2 3 4 5))))))
  107. (section "and a mixture of values"
  108. (it "at the beginning"
  109. (affirm (eq? `((1 7) 8 9) ((lambda (&fst snd last) (list fst snd last)) 1 (values-list 7 8 9)))))
  110. (it "in the middle"
  111. (affirm (eq? `(7 8 () 9) ((lambda (fst snd &middle last) (list fst snd middle last)) (values-list 7 8 9)))
  112. (eq? `(1 7 (8) 9) ((lambda (fst snd &middle last) (list fst snd middle last)) 1 (values-list 7 8 9)))
  113. (eq? '(1 2 (7 8) 9) ((lambda (fst snd &middle last) (list fst snd middle last)) 1 2 (values-list 7 8 9)))))
  114. (it "at the end"
  115. (affirm (eq? `(7 8 (9)) ((lambda (fst snd &last) (list fst snd last)) (values-list 7 8 9)))
  116. (eq? '(1 7 (8 9)) ((lambda (fst snd &last) (list fst snd last)) 1 (values-list 7 8 9)))
  117. (eq? '(1 2 (7 8 9)) ((lambda (fst snd &last) (list fst snd last)) 1 2 (values-list 7 8 9)))))))
  118. )