fixnum-op.scm 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. ; Copyright (c) 1993-2008 by Richard Kelsey and Jonathan Rees. See file COPYING.
  2. ; Fixnum-only primitive operations
  3. ; These predicates are used to characterize the numeric representations that
  4. ; are implemented in the VM.
  5. (define (unary-lose x)
  6. (raise-exception wrong-type-argument 0 x))
  7. (define (binary-lose x y)
  8. (raise-exception wrong-type-argument 0 x y))
  9. (define-primitive number? (any->)
  10. (lambda (x)
  11. (or (fixnum? x)
  12. (bignum? x)
  13. (ratnum? x)
  14. (double? x)
  15. (extended-number? x)))
  16. return-boolean)
  17. (define-primitive integer? (any->)
  18. (lambda (n)
  19. (cond ((or (fixnum? n)
  20. (bignum? n))
  21. (goto return-boolean #t))
  22. ((or (extended-number? n)
  23. (double? n))
  24. (unary-lose n))
  25. (else
  26. (goto return-boolean #f)))))
  27. (define vm-number-predicate
  28. (lambda (n)
  29. (cond ((or (fixnum? n)
  30. (bignum? n)
  31. (and rationals? (ratnum? n))
  32. (and doubles? (double? n)))
  33. (goto return-boolean #t))
  34. ((extended-number? n)
  35. (unary-lose n))
  36. (else
  37. (goto return-boolean #f)))))
  38. (define-primitive rational? (any->) vm-number-predicate)
  39. (define-primitive real? (any->) vm-number-predicate)
  40. (define-primitive complex? (any->) vm-number-predicate)
  41. ;----------------
  42. ; A macro for defining primitives that only operate on fixnums.
  43. (define-syntax define-fixnum-only
  44. (syntax-rules ()
  45. ((define-fixnum-only (opcode arg) value)
  46. (define-primitive opcode (any->)
  47. (lambda (arg)
  48. (if (fixnum? arg)
  49. (goto return value)
  50. (unary-lose arg)))))
  51. ((define-fixnum-only (opcode arg0 arg1) value)
  52. (define-primitive opcode (any-> any->)
  53. (lambda (arg0 arg1)
  54. (if (and (fixnum? arg0)
  55. (fixnum? arg1))
  56. (goto return value)
  57. (binary-lose arg0 arg1)))))))
  58. ; These primitives have a simple answer in the case of fixnums; for all others
  59. ; they punt to the run-time system.
  60. (define-fixnum-only (exact? n) true)
  61. (define-fixnum-only (real-part n) n)
  62. (define-fixnum-only (imag-part n) (enter-fixnum 0))
  63. (define-fixnum-only (floor n) n)
  64. (define-fixnum-only (numerator n) n)
  65. (define-fixnum-only (denominator n) (enter-fixnum 1))
  66. (define-primitive angle (any->)
  67. (lambda (n)
  68. (if (and (fixnum? n)
  69. (>= n 0))
  70. (goto return (enter-fixnum 0))
  71. (unary-lose n))))
  72. (define-primitive magnitude (any->)
  73. (lambda (n)
  74. (if (fixnum? n)
  75. (abs-carefully n
  76. (lambda (r)
  77. (goto return r))
  78. unary-lose)
  79. (unary-lose n))))
  80. ; These all just raise an exception and let the run-time system do the work.
  81. (define-syntax define-punter
  82. (syntax-rules ()
  83. ((define-punter opcode)
  84. (define-primitive opcode (any->) unary-lose))))
  85. (define-punter exact->inexact)
  86. (define-punter inexact->exact)
  87. (define-punter exp)
  88. (define-punter log)
  89. (define-punter sin)
  90. (define-punter cos)
  91. (define-punter tan)
  92. (define-punter asin)
  93. (define-punter acos)
  94. (define-punter sqrt)
  95. (define-syntax define-punter2
  96. (syntax-rules ()
  97. ((define-punter2 opcode)
  98. (define-primitive opcode (any-> any->) binary-lose))))
  99. (define-punter atan1)
  100. (define-punter2 atan2)
  101. (define-punter2 make-polar)
  102. (define-punter2 make-rectangular)
  103. (define-syntax define-binop
  104. (syntax-rules ()
  105. ((define-binop opcode careful-op)
  106. (define-primitive opcode (any-> any->)
  107. (lambda (x y)
  108. (if (and (fixnum? x)
  109. (fixnum? y))
  110. (goto careful-op x y return binary-lose)
  111. (binary-lose x y)))))))
  112. (define-binop + add-carefully)
  113. (define-binop - subtract-carefully)
  114. (define-binop * multiply-carefully)
  115. (define-binop / divide-carefully)
  116. (define-binop quotient quotient-carefully)
  117. (define-binop remainder remainder-carefully)
  118. (define-binop arithmetic-shift shift-carefully)
  119. (define-fixnum-only (= x y) (enter-boolean (fixnum= x y)))
  120. (define-fixnum-only (< x y) (enter-boolean (fixnum< x y)))
  121. (define-fixnum-only (> x y) (enter-boolean (fixnum> x y)))
  122. (define-fixnum-only (<= x y) (enter-boolean (fixnum<= x y)))
  123. (define-fixnum-only (>= x y) (enter-boolean (fixnum>= x y)))
  124. (define-fixnum-only (bitwise-not x) (fixnum-bitwise-not x))
  125. (define-fixnum-only (bitwise-and x y) (fixnum-bitwise-and x y))
  126. (define-fixnum-only (bitwise-ior x y) (fixnum-bitwise-ior x y))
  127. (define-fixnum-only (bitwise-xor x y) (fixnum-bitwise-xor x y))