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.

247 lines
8.4 KiB

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