You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

245 lines
8.3 KiB

25 years ago
  1. // Basic definitions of numbers
  2. #ifndef _CL_NUMBER_H
  3. #define _CL_NUMBER_H
  4. #include "cl_object.h"
  5. #include "cl_malloc.h"
  6. // Type hierachy:
  7. // Number (N) =
  8. // Real (R) =
  9. // Float (F) =
  10. // Short float (SF)
  11. // Single float (FF)
  12. // Double float (DF)
  13. // Long float (LF)
  14. // Rational (RA) =
  15. // Integer (I) =
  16. // Fixnum (FN)
  17. // Bignum (BN)
  18. // Ratio (RT)
  19. // Complex (C)
  20. // Constructors and assignment operators from C numeric types.
  21. #define CL_DEFINE_INT_CONSTRUCTOR(_class_,_type_) \
  22. inline _class_::_class_ (const _type_ wert) \
  23. { \
  24. word = cl_combine(cl_FN_tag,wert); \
  25. }
  26. #define CL_DEFINE_INT_CONSTRUCTORS(_class_) \
  27. CL_DEFINE_INT_CONSTRUCTOR(_class_, int) \
  28. CL_DEFINE_INT_CONSTRUCTOR(_class_, unsigned int)
  29. #define CL_DEFINE_INT_ASSIGNMENT_OPERATOR(_class_,_type_) \
  30. inline _class_& _class_::operator= (const _type_ wert) \
  31. { \
  32. cl_dec_refcount(*this); \
  33. word = cl_combine(cl_FN_tag,wert); \
  34. return *this; \
  35. }
  36. #define CL_DEFINE_INT_ASSIGNMENT_OPERATORS(_class_) \
  37. CL_DEFINE_INT_ASSIGNMENT_OPERATOR(_class_, int) \
  38. CL_DEFINE_INT_ASSIGNMENT_OPERATOR(_class_, unsigned int)
  39. #if (long_bitsize==32)
  40. // `long' == `sintL', `unsigned long' == `uintL'.
  41. #define CL_DEFINE_LONG_CONSTRUCTORS(_class_) \
  42. inline _class_::_class_ (const long wert) \
  43. { \
  44. extern cl_private_thing cl_I_constructor_from_L (sint32 wert); \
  45. pointer = cl_I_constructor_from_L(wert); \
  46. } \
  47. inline _class_::_class_ (const unsigned long wert) \
  48. { \
  49. extern cl_private_thing cl_I_constructor_from_UL (uint32 wert); \
  50. pointer = cl_I_constructor_from_UL(wert); \
  51. }
  52. #elif (long_bitsize==64)
  53. // `long' == `sintQ', `unsigned long' == `uintQ'.
  54. #define CL_DEFINE_LONG_CONSTRUCTORS(_class_) \
  55. inline _class_::_class_ (const long wert) \
  56. { \
  57. extern cl_private_thing cl_I_constructor_from_Q (sint64 wert); \
  58. pointer = cl_I_constructor_from_Q(wert); \
  59. } \
  60. inline _class_::_class_ (const unsigned long wert) \
  61. { \
  62. extern cl_private_thing cl_I_constructor_from_UQ (uint64 wert); \
  63. pointer = cl_I_constructor_from_UQ(wert); \
  64. }
  65. #endif
  66. #if (long_bitsize==32)
  67. // `long' == `sintL', `unsigned long' == `uintL'.
  68. #define CL_DEFINE_LONG_ASSIGNMENT_OPERATORS(_class_) \
  69. inline _class_& _class_::operator= (const long wert) \
  70. { \
  71. extern cl_private_thing cl_I_constructor_from_L (sint32 wert); \
  72. cl_dec_refcount(*this); \
  73. pointer = cl_I_constructor_from_L(wert); \
  74. return *this; \
  75. } \
  76. inline _class_& _class_::operator= (const unsigned long wert) \
  77. { \
  78. extern cl_private_thing cl_I_constructor_from_UL (uint32 wert); \
  79. cl_dec_refcount(*this); \
  80. pointer = cl_I_constructor_from_UL(wert); \
  81. return *this; \
  82. }
  83. #elif (long_bitsize==64)
  84. // `long' == `sintQ', `unsigned long' == `uintQ'.
  85. #define CL_DEFINE_LONG_ASSIGNMENT_OPERATORS(_class_) \
  86. inline _class_& _class_::operator= (const long wert) \
  87. { \
  88. extern cl_private_thing cl_I_constructor_from_Q (sint64 wert); \
  89. cl_dec_refcount(*this); \
  90. pointer = cl_I_constructor_from_Q(wert); \
  91. return *this; \
  92. } \
  93. inline _class_& _class_::operator= (const unsigned long wert) \
  94. { \
  95. extern cl_private_thing cl_I_constructor_from_UQ (uint64 wert); \
  96. cl_dec_refcount(*this); \
  97. pointer = cl_I_constructor_from_UQ(wert); \
  98. return *this; \
  99. }
  100. #endif
  101. // Conversions to subtypes:
  102. // As(cl_I)(x) returns x as a cl_I. It first checks that x is a cl_I
  103. // and then returns it without change of representation.
  104. #if 0 // no debug information
  105. #define As(type) as_##type
  106. #define CL_DEFINE_AS_CONVERSION(_class_) \
  107. extern const _class_& as_##_class_ (const cl_number& x); \
  108. inline const _class_& as_##_class_ (const _class_& x) { return x; }
  109. #else // Line number information for ease of debugging.
  110. #define As(type) as_##type cl_as_aux
  111. #define cl_as_aux(expr) (expr,__FILE__,__LINE__)
  112. #define CL_DEFINE_AS_CONVERSION(_class_) \
  113. extern const _class_& as_##_class_ (const cl_number& x, const char * filename, int line); \
  114. inline const _class_& as_##_class_ (const _class_& x, const char * filename, int line) { (void)filename; (void)line; return x; }
  115. #endif
  116. // Constructors and assignment operators from C numeric types.
  117. // from `float':
  118. extern cl_private_thing cl_float_to_FF_pointer (const union ffloatjanus& val);
  119. #define CL_DEFINE_FLOAT_CONSTRUCTOR(_class_) \
  120. inline _class_ :: _class_ (const float x) \
  121. { \
  122. pointer = cl_float_to_FF_pointer(*(const union ffloatjanus *)&x); \
  123. } \
  124. inline _class_& _class_::operator= (const float x) \
  125. { \
  126. cl_dec_refcount(*this); \
  127. pointer = cl_float_to_FF_pointer(*(const union ffloatjanus *)&x); \
  128. return *this; \
  129. }
  130. // from `double':
  131. extern struct cl_heap_dfloat * cl_double_to_DF_pointer (const union dfloatjanus& val);
  132. #define CL_DEFINE_DOUBLE_CONSTRUCTOR(_class_) \
  133. inline _class_::_class_ (const double x) \
  134. { \
  135. pointer = cl_double_to_DF_pointer(*(const union dfloatjanus *)&x); \
  136. } \
  137. inline _class_& _class_::operator= (const double x) \
  138. { \
  139. cl_dec_refcount(*this); \
  140. pointer = cl_double_to_DF_pointer(*(const union dfloatjanus *)&x); \
  141. return *this; \
  142. }
  143. // Abstract class of all numbers.
  144. class cl_number : public cl_gcobject {
  145. public:
  146. // Default constructor. (Used for objects with no initializer.)
  147. cl_number ();
  148. // Copy constructor. (Used for function argument passing and function
  149. // return value, and of course for objects with initializers of the same type.)
  150. cl_number (const cl_number& x);
  151. // Converters. (Used for function argument passing and function return values.)
  152. // Assignment operators. (Used for assignments.)
  153. cl_number& operator= (const cl_number&);
  154. // Constructors and assignment operators from C numeric types.
  155. cl_number (const int); // |argument| must be < 2^29
  156. cl_number (const unsigned int); // argument must be < 2^29
  157. cl_number (const long);
  158. cl_number (const unsigned long);
  159. cl_number (const float);
  160. cl_number (const double);
  161. cl_number& operator= (const int); // |argument| must be < 2^29
  162. cl_number& operator= (const unsigned int); // argument must be < 2^29
  163. cl_number& operator= (const long);
  164. cl_number& operator= (const unsigned long);
  165. cl_number& operator= (const float);
  166. cl_number& operator= (const double);
  167. // Other constructors.
  168. // cl_number (const char *);
  169. // Private pointer manipulations.
  170. cl_number (cl_private_thing);
  171. cl_private_thing _as_cl_private_thing () const;
  172. };
  173. // Private constructors.
  174. inline cl_number::cl_number (cl_private_thing ptr) : cl_gcobject (ptr) {}
  175. // The assignment operators:
  176. CL_DEFINE_ASSIGNMENT_OPERATOR(cl_number, cl_number)
  177. // The default constructors.
  178. inline cl_number::cl_number ()
  179. : cl_gcobject ((cl_private_thing) cl_combine(cl_FN_tag,0)) {}
  180. // The copy constructors.
  181. CL_DEFINE_COPY_CONSTRUCTOR2(cl_number,cl_gcobject)
  182. // Constructors and assignment operators from C numeric types.
  183. CL_DEFINE_INT_CONSTRUCTORS(cl_number)
  184. CL_DEFINE_INT_ASSIGNMENT_OPERATORS(cl_number)
  185. CL_DEFINE_LONG_CONSTRUCTORS(cl_number)
  186. CL_DEFINE_LONG_ASSIGNMENT_OPERATORS(cl_number)
  187. CL_DEFINE_FLOAT_CONSTRUCTOR(cl_number)
  188. CL_DEFINE_DOUBLE_CONSTRUCTOR(cl_number)
  189. // Conversion:
  190. //inline cl_N& cl_as_N (const cl_number& x)
  191. //{ return *(cl_N*)(&x); }
  192. // Hack section.
  193. // Conversions to subtypes without checking:
  194. // The(cl_I)(x) converts x to a cl_I, without change of representation!
  195. #define The(type) *(const type *) & cl_identity
  196. // This inline function is for type checking purposes only.
  197. inline const cl_number& cl_identity (const cl_number& x) { return x; }
  198. // Mutable(type,x);
  199. // x should be a variable `const type x' or `const type& x'.
  200. // This macro introduces a new variable `type& x' whose value can be
  201. // modified. Useful for modifying the argument of a function which takes
  202. // a `const type &x'.
  203. // Warning: To apply this to a function's formal parameter, a block { ... }
  204. // must be inserted.
  205. #define Mutable(type,x) \
  206. type __copied_##x = x; \
  207. type& x = __copied_##x;
  208. // DeclareType(type,x);
  209. // x should be a variable of some subtype of `cl_number'. type should be
  210. // a subtype of `cl_number'. A new variable of the given type is declared,
  211. // with name x and which refers to x (by reference, with const attribute).
  212. #define DeclareType(type,x) \
  213. const type& __tmp_##x = *(const type*) &x; \
  214. const type& x = __tmp_##x;
  215. #endif /* _CL_NUMBER_H */