kanayago 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +7 -0
  2. data/.rubocop.yml +15 -0
  3. data/.rubocop_todo.yml +23 -0
  4. data/LICENSE.txt +21 -0
  5. data/README.md +79 -0
  6. data/Rakefile +182 -0
  7. data/ext/kanayago/ccan/check_type/check_type.h +63 -0
  8. data/ext/kanayago/ccan/container_of/container_of.h +142 -0
  9. data/ext/kanayago/ccan/list/list.h +791 -0
  10. data/ext/kanayago/ccan/str/str.h +17 -0
  11. data/ext/kanayago/constant.h +53 -0
  12. data/ext/kanayago/extconf.rb +21 -0
  13. data/ext/kanayago/id.h +347 -0
  14. data/ext/kanayago/id_table.h +39 -0
  15. data/ext/kanayago/internal/array.h +151 -0
  16. data/ext/kanayago/internal/basic_operators.h +64 -0
  17. data/ext/kanayago/internal/bignum.h +244 -0
  18. data/ext/kanayago/internal/bits.h +568 -0
  19. data/ext/kanayago/internal/compile.h +34 -0
  20. data/ext/kanayago/internal/compilers.h +107 -0
  21. data/ext/kanayago/internal/complex.h +29 -0
  22. data/ext/kanayago/internal/encoding.h +36 -0
  23. data/ext/kanayago/internal/error.h +218 -0
  24. data/ext/kanayago/internal/fixnum.h +184 -0
  25. data/ext/kanayago/internal/gc.h +322 -0
  26. data/ext/kanayago/internal/hash.h +191 -0
  27. data/ext/kanayago/internal/imemo.h +261 -0
  28. data/ext/kanayago/internal/io.h +140 -0
  29. data/ext/kanayago/internal/numeric.h +274 -0
  30. data/ext/kanayago/internal/parse.h +117 -0
  31. data/ext/kanayago/internal/rational.h +71 -0
  32. data/ext/kanayago/internal/re.h +28 -0
  33. data/ext/kanayago/internal/ruby_parser.h +125 -0
  34. data/ext/kanayago/internal/sanitizers.h +297 -0
  35. data/ext/kanayago/internal/serial.h +23 -0
  36. data/ext/kanayago/internal/static_assert.h +16 -0
  37. data/ext/kanayago/internal/string.h +186 -0
  38. data/ext/kanayago/internal/symbol.h +45 -0
  39. data/ext/kanayago/internal/thread.h +79 -0
  40. data/ext/kanayago/internal/variable.h +72 -0
  41. data/ext/kanayago/internal/vm.h +137 -0
  42. data/ext/kanayago/internal/warnings.h +16 -0
  43. data/ext/kanayago/internal.h +108 -0
  44. data/ext/kanayago/kanayago.c +420 -0
  45. data/ext/kanayago/kanayago.h +21 -0
  46. data/ext/kanayago/lex.c +302 -0
  47. data/ext/kanayago/method.h +255 -0
  48. data/ext/kanayago/node.c +440 -0
  49. data/ext/kanayago/node.h +111 -0
  50. data/ext/kanayago/node_name.inc +224 -0
  51. data/ext/kanayago/parse.c +26931 -0
  52. data/ext/kanayago/parse.h +244 -0
  53. data/ext/kanayago/parse.tmp.y +16145 -0
  54. data/ext/kanayago/parser_bits.h +564 -0
  55. data/ext/kanayago/parser_node.h +32 -0
  56. data/ext/kanayago/parser_st.c +164 -0
  57. data/ext/kanayago/parser_st.h +162 -0
  58. data/ext/kanayago/parser_value.h +106 -0
  59. data/ext/kanayago/probes.h +4 -0
  60. data/ext/kanayago/ruby_assert.h +14 -0
  61. data/ext/kanayago/ruby_atomic.h +23 -0
  62. data/ext/kanayago/ruby_parser.c +1165 -0
  63. data/ext/kanayago/rubyparser.h +1391 -0
  64. data/ext/kanayago/shape.h +234 -0
  65. data/ext/kanayago/st.c +2339 -0
  66. data/ext/kanayago/symbol.h +123 -0
  67. data/ext/kanayago/thread_pthread.h +168 -0
  68. data/ext/kanayago/universal_parser.c +230 -0
  69. data/ext/kanayago/vm_core.h +2215 -0
  70. data/ext/kanayago/vm_opts.h +67 -0
  71. data/lib/kanayago/version.rb +5 -0
  72. data/lib/kanayago.rb +11 -0
  73. data/sig/kanayago.rbs +4 -0
  74. metadata +116 -0
@@ -0,0 +1,261 @@
1
+ #ifndef INTERNAL_IMEMO_H /*-*-C-*-vi:se ft=c:*/
2
+ #define INTERNAL_IMEMO_H
3
+ /**
4
+ * @author Ruby developers <ruby-core@ruby-lang.org>
5
+ * @copyright This file is a part of the programming language Ruby.
6
+ * Permission is hereby granted, to either redistribute and/or
7
+ * modify this file, provided that the conditions mentioned in the
8
+ * file COPYING are met. Consult the file for details.
9
+ * @brief IMEMO: Internal memo object.
10
+ */
11
+ #include "ruby/internal/config.h"
12
+ #include <stddef.h> /* for size_t */
13
+ #include "internal/array.h" /* for rb_ary_hidden_new_fill */
14
+ #include "ruby/internal/stdbool.h" /* for bool */
15
+ #include "ruby/ruby.h" /* for rb_block_call_func_t */
16
+
17
+ #ifndef IMEMO_DEBUG
18
+ # define IMEMO_DEBUG 0
19
+ #endif
20
+
21
+ #define IMEMO_MASK 0x0f
22
+
23
+ /* FL_USER0 to FL_USER3 is for type */
24
+ #define IMEMO_FL_USHIFT (FL_USHIFT + 4)
25
+ #define IMEMO_FL_USER0 FL_USER4
26
+ #define IMEMO_FL_USER1 FL_USER5
27
+ #define IMEMO_FL_USER2 FL_USER6
28
+ #define IMEMO_FL_USER3 FL_USER7
29
+ #define IMEMO_FL_USER4 FL_USER8
30
+ #define IMEMO_FL_USER5 FL_USER9
31
+
32
+ enum imemo_type {
33
+ imemo_env = 0,
34
+ imemo_cref = 1, /*!< class reference */
35
+ imemo_svar = 2, /*!< special variable */
36
+ imemo_throw_data = 3,
37
+ imemo_ifunc = 4, /*!< iterator function */
38
+ imemo_memo = 5,
39
+ imemo_ment = 6,
40
+ imemo_iseq = 7,
41
+ imemo_tmpbuf = 8,
42
+ imemo_ast = 9, // Obsolete due to the universal parser
43
+ imemo_parser_strterm = 10,
44
+ imemo_callinfo = 11,
45
+ imemo_callcache = 12,
46
+ imemo_constcache = 13,
47
+ };
48
+
49
+ /* CREF (Class REFerence) is defined in method.h */
50
+
51
+ /*! SVAR (Special VARiable) */
52
+ struct vm_svar {
53
+ VALUE flags;
54
+ const VALUE cref_or_me; /*!< class reference or rb_method_entry_t */
55
+ const VALUE lastline;
56
+ const VALUE backref;
57
+ const VALUE others;
58
+ };
59
+
60
+ /*! THROW_DATA */
61
+ struct vm_throw_data {
62
+ VALUE flags;
63
+ VALUE reserved;
64
+ const VALUE throw_obj;
65
+ const struct rb_control_frame_struct *catch_frame;
66
+ int throw_state;
67
+ };
68
+
69
+ #define THROW_DATA_CONSUMED IMEMO_FL_USER0
70
+
71
+ /* IFUNC (Internal FUNCtion) */
72
+
73
+ struct vm_ifunc_argc {
74
+ #if SIZEOF_INT * 2 > SIZEOF_VALUE
75
+ signed int min: (SIZEOF_VALUE * CHAR_BIT) / 2;
76
+ signed int max: (SIZEOF_VALUE * CHAR_BIT) / 2;
77
+ #else
78
+ int min, max;
79
+ #endif
80
+ };
81
+
82
+ /*! IFUNC (Internal FUNCtion) */
83
+ struct vm_ifunc {
84
+ VALUE flags;
85
+ VALUE *svar_lep;
86
+ rb_block_call_func_t func;
87
+ const void *data;
88
+ struct vm_ifunc_argc argc;
89
+ };
90
+ #define IFUNC_YIELD_OPTIMIZABLE IMEMO_FL_USER0
91
+
92
+ struct rb_imemo_tmpbuf_struct {
93
+ VALUE flags;
94
+ VALUE reserved;
95
+ VALUE *ptr; /* malloc'ed buffer */
96
+ struct rb_imemo_tmpbuf_struct *next; /* next imemo */
97
+ size_t cnt; /* buffer size in VALUE */
98
+ };
99
+
100
+ /*! MEMO
101
+ *
102
+ * @see imemo_type
103
+ * */
104
+ struct MEMO {
105
+ VALUE flags;
106
+ VALUE reserved;
107
+ const VALUE v1;
108
+ const VALUE v2;
109
+ union {
110
+ long cnt;
111
+ long state;
112
+ const VALUE value;
113
+ void (*func)(void);
114
+ } u3;
115
+ };
116
+
117
+ #define IMEMO_NEW(T, type, v0) ((T *)rb_imemo_new((type), (v0)))
118
+
119
+ /* ment is in method.h */
120
+
121
+ #define THROW_DATA_P(err) imemo_throw_data_p((VALUE)err)
122
+ #define MEMO_CAST(m) ((struct MEMO *)(m))
123
+ #define MEMO_FOR(type, value) ((type *)RARRAY_PTR(value))
124
+ #define NEW_MEMO_FOR(type, value) \
125
+ ((value) = rb_ary_hidden_new_fill(type_roomof(type, VALUE)), MEMO_FOR(type, value))
126
+ #define NEW_PARTIAL_MEMO_FOR(type, value, member) \
127
+ ((value) = rb_ary_hidden_new_fill(type_roomof(type, VALUE)), \
128
+ rb_ary_set_len((value), offsetof(type, member) / sizeof(VALUE)), \
129
+ MEMO_FOR(type, value))
130
+
131
+ #ifndef RUBY_RUBYPARSER_H
132
+ typedef struct rb_imemo_tmpbuf_struct rb_imemo_tmpbuf_t;
133
+ #endif
134
+ rb_imemo_tmpbuf_t *rb_imemo_tmpbuf_parser_heap(void *buf, rb_imemo_tmpbuf_t *old_heap, size_t cnt);
135
+ struct vm_ifunc *rb_vm_ifunc_new(rb_block_call_func_t func, const void *data, int min_argc, int max_argc);
136
+ static inline enum imemo_type imemo_type(VALUE imemo);
137
+ static inline int imemo_type_p(VALUE imemo, enum imemo_type imemo_type);
138
+ static inline bool imemo_throw_data_p(VALUE imemo);
139
+ static inline struct vm_ifunc *rb_vm_ifunc_proc_new(rb_block_call_func_t func, const void *data);
140
+ static inline VALUE rb_imemo_tmpbuf_auto_free_pointer(void);
141
+ static inline void *RB_IMEMO_TMPBUF_PTR(VALUE v);
142
+ static inline void *rb_imemo_tmpbuf_set_ptr(VALUE v, void *ptr);
143
+ static inline VALUE rb_imemo_tmpbuf_auto_free_pointer_new_from_an_RString(VALUE str);
144
+ static inline void MEMO_V1_SET(struct MEMO *m, VALUE v);
145
+ static inline void MEMO_V2_SET(struct MEMO *m, VALUE v);
146
+
147
+ size_t rb_imemo_memsize(VALUE obj);
148
+ void rb_cc_table_mark(VALUE klass);
149
+ void rb_imemo_mark_and_move(VALUE obj, bool reference_updating);
150
+ void rb_cc_table_free(VALUE klass);
151
+ void rb_imemo_free(VALUE obj);
152
+
153
+ RUBY_SYMBOL_EXPORT_BEGIN
154
+ #if IMEMO_DEBUG
155
+ VALUE rb_imemo_new_debug(enum imemo_type type, VALUE v0, const char *file, int line);
156
+ #define rb_imemo_new(type, v1, v2, v3, v0) rb_imemo_new_debug(type, v1, v2, v3, v0, __FILE__, __LINE__)
157
+ #else
158
+ VALUE rb_imemo_new(enum imemo_type type, VALUE v0);
159
+ #endif
160
+ const char *rb_imemo_name(enum imemo_type type);
161
+ RUBY_SYMBOL_EXPORT_END
162
+
163
+ static inline struct MEMO *
164
+ MEMO_NEW(VALUE a, VALUE b, VALUE c)
165
+ {
166
+ struct MEMO *memo = IMEMO_NEW(struct MEMO, imemo_memo, 0);
167
+ *((VALUE *)&memo->v1) = a;
168
+ *((VALUE *)&memo->v2) = b;
169
+ *((VALUE *)&memo->u3.value) = c;
170
+
171
+ return memo;
172
+ }
173
+
174
+ static inline enum imemo_type
175
+ imemo_type(VALUE imemo)
176
+ {
177
+ return (RBASIC(imemo)->flags >> FL_USHIFT) & IMEMO_MASK;
178
+ }
179
+
180
+ static inline int
181
+ imemo_type_p(VALUE imemo, enum imemo_type imemo_type)
182
+ {
183
+ if (LIKELY(!RB_SPECIAL_CONST_P(imemo))) {
184
+ /* fixed at compile time if imemo_type is given. */
185
+ const VALUE mask = (IMEMO_MASK << FL_USHIFT) | RUBY_T_MASK;
186
+ const VALUE expected_type = (imemo_type << FL_USHIFT) | T_IMEMO;
187
+ /* fixed at runtime. */
188
+ return expected_type == (RBASIC(imemo)->flags & mask);
189
+ }
190
+ else {
191
+ return 0;
192
+ }
193
+ }
194
+
195
+ #define IMEMO_TYPE_P(v, t) imemo_type_p((VALUE)(v), t)
196
+
197
+ static inline bool
198
+ imemo_throw_data_p(VALUE imemo)
199
+ {
200
+ return RB_TYPE_P(imemo, T_IMEMO);
201
+ }
202
+
203
+ static inline struct vm_ifunc *
204
+ rb_vm_ifunc_proc_new(rb_block_call_func_t func, const void *data)
205
+ {
206
+ return rb_vm_ifunc_new(func, data, 0, UNLIMITED_ARGUMENTS);
207
+ }
208
+
209
+ static inline VALUE
210
+ rb_imemo_tmpbuf_auto_free_pointer(void)
211
+ {
212
+ return rb_imemo_new(imemo_tmpbuf, 0);
213
+ }
214
+
215
+ static inline void *
216
+ RB_IMEMO_TMPBUF_PTR(VALUE v)
217
+ {
218
+ const struct rb_imemo_tmpbuf_struct *p = (const void *)v;
219
+ return p->ptr;
220
+ }
221
+
222
+ static inline void *
223
+ rb_imemo_tmpbuf_set_ptr(VALUE v, void *ptr)
224
+ {
225
+ return ((rb_imemo_tmpbuf_t *)v)->ptr = ptr;
226
+ }
227
+
228
+ static inline VALUE
229
+ rb_imemo_tmpbuf_auto_free_pointer_new_from_an_RString(VALUE str)
230
+ {
231
+ const void *src;
232
+ VALUE imemo;
233
+ rb_imemo_tmpbuf_t *tmpbuf;
234
+ void *dst;
235
+ size_t len;
236
+
237
+ StringValue(str);
238
+ /* create tmpbuf to keep the pointer before xmalloc */
239
+ imemo = rb_imemo_tmpbuf_auto_free_pointer();
240
+ tmpbuf = (rb_imemo_tmpbuf_t *)imemo;
241
+ len = RSTRING_LEN(str);
242
+ src = RSTRING_PTR(str);
243
+ dst = ruby_xmalloc(len);
244
+ memcpy(dst, src, len);
245
+ tmpbuf->ptr = dst;
246
+ return imemo;
247
+ }
248
+
249
+ static inline void
250
+ MEMO_V1_SET(struct MEMO *m, VALUE v)
251
+ {
252
+ RB_OBJ_WRITE(m, &m->v1, v);
253
+ }
254
+
255
+ static inline void
256
+ MEMO_V2_SET(struct MEMO *m, VALUE v)
257
+ {
258
+ RB_OBJ_WRITE(m, &m->v2, v);
259
+ }
260
+
261
+ #endif /* INTERNAL_IMEMO_H */
@@ -0,0 +1,140 @@
1
+ #ifndef INTERNAL_IO_H /*-*-C-*-vi:se ft=c:*/
2
+ #define INTERNAL_IO_H
3
+ /**
4
+ * @author Ruby developers <ruby-core@ruby-lang.org>
5
+ * @copyright This file is a part of the programming language Ruby.
6
+ * Permission is hereby granted, to either redistribute and/or
7
+ * modify this file, provided that the conditions mentioned in the
8
+ * file COPYING are met. Consult the file for details.
9
+ * @brief Internal header for IO.
10
+ */
11
+ #include "ruby/ruby.h" /* for VALUE */
12
+
13
+ #define HAVE_RB_IO_T
14
+ struct rb_io;
15
+
16
+ #include "ruby/io.h" /* for rb_io_t */
17
+
18
+ #define IO_WITHOUT_GVL(func, arg) rb_thread_call_without_gvl(func, arg, RUBY_UBF_IO, 0)
19
+ #define IO_WITHOUT_GVL_INT(func, arg) (int)(VALUE)IO_WITHOUT_GVL(func, arg)
20
+
21
+ /** Ruby's IO, metadata and buffers. */
22
+ struct rb_io {
23
+
24
+ /** The IO's Ruby level counterpart. */
25
+ VALUE self;
26
+
27
+ /** stdio ptr for read/write, if available. */
28
+ FILE *stdio_file;
29
+
30
+ /** file descriptor. */
31
+ int fd;
32
+
33
+ /** mode flags: FMODE_XXXs */
34
+ int mode;
35
+
36
+ /** child's pid (for pipes) */
37
+ rb_pid_t pid;
38
+
39
+ /** number of lines read */
40
+ int lineno;
41
+
42
+ /** pathname for file */
43
+ VALUE pathv;
44
+
45
+ /** finalize proc */
46
+ void (*finalize)(struct rb_io*,int);
47
+
48
+ /** Write buffer. */
49
+ rb_io_buffer_t wbuf;
50
+
51
+ /**
52
+ * (Byte) read buffer. Note also that there is a field called
53
+ * ::rb_io_t::cbuf, which also concerns read IO.
54
+ */
55
+ rb_io_buffer_t rbuf;
56
+
57
+ /**
58
+ * Duplex IO object, if set.
59
+ *
60
+ * @see rb_io_set_write_io()
61
+ */
62
+ VALUE tied_io_for_writing;
63
+
64
+ struct rb_io_encoding encs; /**< Decomposed encoding flags. */
65
+
66
+ /** Encoding converter used when reading from this IO. */
67
+ rb_econv_t *readconv;
68
+
69
+ /**
70
+ * rb_io_ungetc() destination. This buffer is read before checking
71
+ * ::rb_io_t::rbuf
72
+ */
73
+ rb_io_buffer_t cbuf;
74
+
75
+ /** Encoding converter used when writing to this IO. */
76
+ rb_econv_t *writeconv;
77
+
78
+ /**
79
+ * This is, when set, an instance of ::rb_cString which holds the "common"
80
+ * encoding. Write conversion can convert strings twice... In case
81
+ * conversion from encoding X to encoding Y does not exist, Ruby finds an
82
+ * encoding Z that bridges the two, so that X to Z to Y conversion happens.
83
+ */
84
+ VALUE writeconv_asciicompat;
85
+
86
+ /** Whether ::rb_io_t::writeconv is already set up. */
87
+ int writeconv_initialized;
88
+
89
+ /**
90
+ * Value of ::rb_io_t::rb_io_enc_t::ecflags stored right before
91
+ * initialising ::rb_io_t::writeconv.
92
+ */
93
+ int writeconv_pre_ecflags;
94
+
95
+ /**
96
+ * Value of ::rb_io_t::rb_io_enc_t::ecopts stored right before initialising
97
+ * ::rb_io_t::writeconv.
98
+ */
99
+ VALUE writeconv_pre_ecopts;
100
+
101
+ /**
102
+ * This is a Ruby level mutex. It avoids multiple threads to write to an
103
+ * IO at once; helps for instance rb_io_puts() to ensure newlines right
104
+ * next to its arguments.
105
+ *
106
+ * This of course doesn't help inter-process IO interleaves, though.
107
+ */
108
+ VALUE write_lock;
109
+
110
+ /**
111
+ * The timeout associated with this IO when performing blocking operations.
112
+ */
113
+ VALUE timeout;
114
+ };
115
+
116
+ /* io.c */
117
+ void ruby_set_inplace_mode(const char *);
118
+ void rb_stdio_set_default_encoding(void);
119
+ VALUE rb_io_flush_raw(VALUE, int);
120
+ size_t rb_io_memsize(const rb_io_t *);
121
+ int rb_stderr_tty_p(void);
122
+ void rb_io_fptr_finalize_internal(void *ptr);
123
+ #ifdef rb_io_fptr_finalize
124
+ # undef rb_io_fptr_finalize
125
+ #endif
126
+ #define rb_io_fptr_finalize rb_io_fptr_finalize_internal
127
+ VALUE rb_io_popen(VALUE pname, VALUE pmode, VALUE env, VALUE opt);
128
+
129
+ VALUE rb_io_prep_stdin(void);
130
+ VALUE rb_io_prep_stdout(void);
131
+ VALUE rb_io_prep_stderr(void);
132
+
133
+ RUBY_SYMBOL_EXPORT_BEGIN
134
+ /* io.c (export) */
135
+ void rb_maygvl_fd_fix_cloexec(int fd);
136
+ int rb_gc_for_fd(int err);
137
+ void rb_write_error_str(VALUE mesg);
138
+ RUBY_SYMBOL_EXPORT_END
139
+
140
+ #endif /* INTERNAL_IO_H */
@@ -0,0 +1,274 @@
1
+ #ifndef INTERNAL_NUMERIC_H /*-*-C-*-vi:se ft=c:*/
2
+ #define INTERNAL_NUMERIC_H
3
+ /**
4
+ * @author Ruby developers <ruby-core@ruby-lang.org>
5
+ * @copyright This file is a part of the programming language Ruby.
6
+ * Permission is hereby granted, to either redistribute and/or
7
+ * modify this file, provided that the conditions mentioned in the
8
+ * file COPYING are met. Consult the file for details.
9
+ * @brief Internal header for Numeric.
10
+ */
11
+ #include "internal/bignum.h" /* for BIGNUM_POSITIVE_P */
12
+ #include "internal/bits.h" /* for RUBY_BIT_ROTL */
13
+ #include "internal/fixnum.h" /* for FIXNUM_POSITIVE_P */
14
+ #include "internal/vm.h" /* for rb_method_basic_definition_p */
15
+ #include "ruby/intern.h" /* for rb_cmperr */
16
+ #include "ruby/ruby.h" /* for USE_FLONUM */
17
+
18
+ #define ROUND_TO(mode, even, up, down) \
19
+ ((mode) == RUBY_NUM_ROUND_HALF_EVEN ? even : \
20
+ (mode) == RUBY_NUM_ROUND_HALF_UP ? up : down)
21
+ #define ROUND_FUNC(mode, name) \
22
+ ROUND_TO(mode, name##_half_even, name##_half_up, name##_half_down)
23
+ #define ROUND_CALL(mode, name, args) \
24
+ ROUND_TO(mode, name##_half_even args, \
25
+ name##_half_up args, name##_half_down args)
26
+
27
+ #ifndef ROUND_DEFAULT
28
+ # define ROUND_DEFAULT RUBY_NUM_ROUND_HALF_UP
29
+ #endif
30
+
31
+ enum ruby_num_rounding_mode {
32
+ RUBY_NUM_ROUND_HALF_UP,
33
+ RUBY_NUM_ROUND_HALF_EVEN,
34
+ RUBY_NUM_ROUND_HALF_DOWN,
35
+ RUBY_NUM_ROUND_DEFAULT = ROUND_DEFAULT,
36
+ };
37
+
38
+ /* same as internal.h */
39
+ #define numberof(array) ((int)(sizeof(array) / sizeof((array)[0])))
40
+ #define roomof(x, y) (((x) + (y) - 1) / (y))
41
+ #define type_roomof(x, y) roomof(sizeof(x), sizeof(y))
42
+
43
+ #if SIZEOF_DOUBLE <= SIZEOF_VALUE
44
+ typedef double rb_float_value_type;
45
+ #else
46
+ typedef struct {
47
+ VALUE values[roomof(SIZEOF_DOUBLE, SIZEOF_VALUE)];
48
+ } rb_float_value_type;
49
+ #endif
50
+
51
+ struct RFloat {
52
+ struct RBasic basic;
53
+ rb_float_value_type float_value;
54
+ };
55
+
56
+ #define RFLOAT(obj) ((struct RFloat *)(obj))
57
+
58
+ /* numeric.c */
59
+ int rb_num_to_uint(VALUE val, unsigned int *ret);
60
+ VALUE ruby_num_interval_step_size(VALUE from, VALUE to, VALUE step, int excl);
61
+ double ruby_float_step_size(double beg, double end, double unit, int excl);
62
+ int ruby_float_step(VALUE from, VALUE to, VALUE step, int excl, int allow_endless);
63
+ int rb_num_negative_p(VALUE);
64
+ VALUE rb_int_succ(VALUE num);
65
+ VALUE rb_float_uminus(VALUE num);
66
+ VALUE rb_int_plus(VALUE x, VALUE y);
67
+ VALUE rb_float_plus(VALUE x, VALUE y);
68
+ VALUE rb_int_minus(VALUE x, VALUE y);
69
+ VALUE rb_float_minus(VALUE x, VALUE y);
70
+ VALUE rb_int_mul(VALUE x, VALUE y);
71
+ VALUE rb_float_mul(VALUE x, VALUE y);
72
+ VALUE rb_float_div(VALUE x, VALUE y);
73
+ VALUE rb_int_idiv(VALUE x, VALUE y);
74
+ VALUE rb_int_modulo(VALUE x, VALUE y);
75
+ VALUE rb_int2str(VALUE num, int base);
76
+ VALUE rb_fix_plus(VALUE x, VALUE y);
77
+ VALUE rb_int_gt(VALUE x, VALUE y);
78
+ VALUE rb_float_gt(VALUE x, VALUE y);
79
+ VALUE rb_int_ge(VALUE x, VALUE y);
80
+ enum ruby_num_rounding_mode rb_num_get_rounding_option(VALUE opts);
81
+ double rb_int_fdiv_double(VALUE x, VALUE y);
82
+ VALUE rb_int_pow(VALUE x, VALUE y);
83
+ VALUE rb_float_pow(VALUE x, VALUE y);
84
+ VALUE rb_int_cmp(VALUE x, VALUE y);
85
+ VALUE rb_int_equal(VALUE x, VALUE y);
86
+ VALUE rb_int_divmod(VALUE x, VALUE y);
87
+ VALUE rb_int_and(VALUE x, VALUE y);
88
+ VALUE rb_int_lshift(VALUE x, VALUE y);
89
+ VALUE rb_int_rshift(VALUE x, VALUE y);
90
+ VALUE rb_int_div(VALUE x, VALUE y);
91
+ int rb_int_positive_p(VALUE num);
92
+ int rb_int_negative_p(VALUE num);
93
+ VALUE rb_check_integer_type(VALUE);
94
+ VALUE rb_num_pow(VALUE x, VALUE y);
95
+ VALUE rb_float_ceil(VALUE num, int ndigits);
96
+ VALUE rb_float_floor(VALUE x, int ndigits);
97
+ VALUE rb_float_abs(VALUE flt);
98
+ static inline VALUE rb_num_compare_with_zero(VALUE num, ID mid);
99
+ static inline int rb_num_positive_int_p(VALUE num);
100
+ static inline int rb_num_negative_int_p(VALUE num);
101
+ static inline double rb_float_flonum_value(VALUE v);
102
+ static inline double rb_float_noflonum_value(VALUE v);
103
+ static inline double rb_float_value_inline(VALUE v);
104
+ static inline VALUE rb_float_new_inline(double d);
105
+ static inline bool INT_POSITIVE_P(VALUE num);
106
+ static inline bool INT_NEGATIVE_P(VALUE num);
107
+ static inline bool FLOAT_ZERO_P(VALUE num);
108
+ #define rb_float_value rb_float_value_inline
109
+ #define rb_float_new rb_float_new_inline
110
+
111
+ RUBY_SYMBOL_EXPORT_BEGIN
112
+ /* numeric.c (export) */
113
+ RUBY_SYMBOL_EXPORT_END
114
+
115
+ VALUE rb_flo_div_flo(VALUE x, VALUE y);
116
+ double ruby_float_mod(double x, double y);
117
+ VALUE rb_float_equal(VALUE x, VALUE y);
118
+ int rb_float_cmp(VALUE x, VALUE y);
119
+ VALUE rb_float_eql(VALUE x, VALUE y);
120
+ VALUE rb_fix_aref(VALUE fix, VALUE idx);
121
+ VALUE rb_int_zero_p(VALUE num);
122
+ VALUE rb_int_even_p(VALUE num);
123
+ VALUE rb_int_odd_p(VALUE num);
124
+ VALUE rb_int_abs(VALUE num);
125
+ VALUE rb_int_bit_length(VALUE num);
126
+ VALUE rb_int_uminus(VALUE num);
127
+ VALUE rb_int_comp(VALUE num);
128
+
129
+ static inline bool
130
+ INT_POSITIVE_P(VALUE num)
131
+ {
132
+ if (FIXNUM_P(num)) {
133
+ return FIXNUM_POSITIVE_P(num);
134
+ }
135
+ else {
136
+ return BIGNUM_POSITIVE_P(num);
137
+ }
138
+ }
139
+
140
+ static inline bool
141
+ INT_NEGATIVE_P(VALUE num)
142
+ {
143
+ if (FIXNUM_P(num)) {
144
+ return FIXNUM_NEGATIVE_P(num);
145
+ }
146
+ else {
147
+ return BIGNUM_NEGATIVE_P(num);
148
+ }
149
+ }
150
+
151
+ static inline bool
152
+ FLOAT_ZERO_P(VALUE num)
153
+ {
154
+ return RFLOAT_VALUE(num) == 0.0;
155
+ }
156
+
157
+ static inline VALUE
158
+ rb_num_compare_with_zero(VALUE num, ID mid)
159
+ {
160
+ VALUE zero = INT2FIX(0);
161
+ VALUE r = rb_check_funcall(num, mid, 1, &zero);
162
+ if (RB_UNDEF_P(r)) {
163
+ rb_cmperr(num, zero);
164
+ }
165
+ return r;
166
+ }
167
+
168
+ static inline int
169
+ rb_num_positive_int_p(VALUE num)
170
+ {
171
+ const ID mid = '>';
172
+
173
+ if (FIXNUM_P(num)) {
174
+ if (rb_method_basic_definition_p(rb_cInteger, mid))
175
+ return FIXNUM_POSITIVE_P(num);
176
+ }
177
+ else if (RB_TYPE_P(num, T_BIGNUM)) {
178
+ if (rb_method_basic_definition_p(rb_cInteger, mid))
179
+ return BIGNUM_POSITIVE_P(num);
180
+ }
181
+ return RTEST(rb_num_compare_with_zero(num, mid));
182
+ }
183
+
184
+ static inline int
185
+ rb_num_negative_int_p(VALUE num)
186
+ {
187
+ const ID mid = '<';
188
+
189
+ if (FIXNUM_P(num)) {
190
+ if (rb_method_basic_definition_p(rb_cInteger, mid))
191
+ return FIXNUM_NEGATIVE_P(num);
192
+ }
193
+ else if (RB_TYPE_P(num, T_BIGNUM)) {
194
+ if (rb_method_basic_definition_p(rb_cInteger, mid))
195
+ return BIGNUM_NEGATIVE_P(num);
196
+ }
197
+ return RTEST(rb_num_compare_with_zero(num, mid));
198
+ }
199
+
200
+ static inline double
201
+ rb_float_flonum_value(VALUE v)
202
+ {
203
+ #if USE_FLONUM
204
+ if (v != (VALUE)0x8000000000000002) { /* LIKELY */
205
+ union {
206
+ double d;
207
+ VALUE v;
208
+ } t;
209
+
210
+ VALUE b63 = (v >> 63);
211
+ /* e: xx1... -> 011... */
212
+ /* xx0... -> 100... */
213
+ /* ^b63 */
214
+ t.v = RUBY_BIT_ROTR((2 - b63) | (v & ~(VALUE)0x03), 3);
215
+ return t.d;
216
+ }
217
+ #endif
218
+ return 0.0;
219
+ }
220
+
221
+ static inline double
222
+ rb_float_noflonum_value(VALUE v)
223
+ {
224
+ #if SIZEOF_DOUBLE <= SIZEOF_VALUE
225
+ return RFLOAT(v)->float_value;
226
+ #else
227
+ union {
228
+ rb_float_value_type v;
229
+ double d;
230
+ } u = {RFLOAT(v)->float_value};
231
+ return u.d;
232
+ #endif
233
+ }
234
+
235
+ static inline double
236
+ rb_float_value_inline(VALUE v)
237
+ {
238
+ if (FLONUM_P(v)) {
239
+ return rb_float_flonum_value(v);
240
+ }
241
+ return rb_float_noflonum_value(v);
242
+ }
243
+
244
+ static inline VALUE
245
+ rb_float_new_inline(double d)
246
+ {
247
+ #if USE_FLONUM
248
+ union {
249
+ double d;
250
+ VALUE v;
251
+ } t;
252
+ int bits;
253
+
254
+ t.d = d;
255
+ bits = (int)((VALUE)(t.v >> 60) & 0x7);
256
+ /* bits contains 3 bits of b62..b60. */
257
+ /* bits - 3 = */
258
+ /* b011 -> b000 */
259
+ /* b100 -> b001 */
260
+
261
+ if (t.v != 0x3000000000000000 /* 1.72723e-77 */ &&
262
+ !((bits-3) & ~0x01)) {
263
+ return (RUBY_BIT_ROTL(t.v, 3) & ~(VALUE)0x01) | 0x02;
264
+ }
265
+ else if (t.v == (VALUE)0) {
266
+ /* +0.0 */
267
+ return 0x8000000000000002;
268
+ }
269
+ /* out of range */
270
+ #endif
271
+ return rb_float_new_in_heap(d);
272
+ }
273
+
274
+ #endif /* INTERNAL_NUMERIC_H */