1 # coding: utf-8
2 # frozen_string_literal: true
3
4
5
6 module Umu
7
8 module Value
9
10 module Core
11
12 module Atom
13
14 module Number
15
16 class Int < Abstract
17 def initialize(val)
18 ASSERT.kind_of val, ::Integer
19
20 super
21 end
22
23
24 define_instance_method(
25 :meth_zero,
26 :zero, [],
27 [], self
28 )
29 def meth_zero(_loc, _env, _event)
30 VC.make_integer 0
31 end
32
33
34 define_instance_method(
35 :meth_is_odd,
36 :odd?, [],
37 [], VCA::Bool
38 )
39 def meth_is_odd(_loc, _env, _event)
40 VC.make_bool self.val.odd?
41 end
42
43
44 define_instance_method(
45 :meth_is_even,
46 :even?, [],
47 [], VCA::Bool
48 )
49 def meth_is_even(_loc, _env, _event)
50 VC.make_bool self.val.even?
51 end
52
53
54 define_instance_method(
55 :meth_is_less_than,
56 :'<', [],
57 [self], VCA::Bool
58 )
59
60
61 define_instance_method(
62 :meth_is_greater_than,
63 :'>', [],
64 [self], VCA::Bool
65 )
66
67
68 define_instance_method(
69 :meth_is_less_equal,
70 :'<=', [],
71 [self], VCA::Bool
72 )
73
74
75 define_instance_method(
76 :meth_is_greater_equal,
77 :'>=', [],
78 [self], VCA::Bool
79 )
80
81
82 define_instance_method(
83 :meth_compare,
84 :'<=>', [],
85 [self], VCAN::Int
86 )
87
88
89 define_instance_method(
90 :meth_to_int,
91 :'to-i', [],
92 [], VCAN::Int
93 )
94 def meth_to_int(_loc, _env, _event)
95 self
96 end
97
98
99 define_instance_method(
100 :meth_succ,
101 :succ, [],
102 [], self
103 )
104 def meth_succ(_loc, _env, _event)
105 VC.make_integer(self.val.succ)
106 end
107
108
109 define_instance_method(
110 :meth_pred,
111 :pred, [],
112 [], self
113 )
114 def meth_pred(_loc, _env, _event)
115 VC.make_integer(self.val.pred)
116 end
117
118
119 define_instance_method(
120 :meth_add,
121 :'+', [],
122 [self], self
123 )
124
125
126 define_instance_method(
127 :meth_sub,
128 :'-', [],
129 [self], self
130 )
131
132
133 define_instance_method(
134 :meth_multiply,
135 :'*', [],
136 [self], self
137 )
138
139
140 define_instance_method(
141 :meth_divide,
142 :'/', [],
143 [self], self
144 )
145
146
147 define_instance_method(
148 :meth_modulo,
149 :mod, [],
150 [self], self
151 )
152
153
154 define_instance_method(
155 :meth_power,
156 :pow, [],
157 [self], self
158 )
159
160
161 define_instance_method(
162 :meth_to,
163 :to, [:'to:'],
164 [self], VCM::Interval
165 )
166 def meth_to(_loc, _env, _event, stop_value)
167 ASSERT.kind_of stop_value, VCAN::Int
168
169 VC.make_interval self, stop_value
170 end
171
172
173 define_instance_method(
174 :meth_to_by,
175 :'to-by', [:'to:by:'],
176 [self, self], VCM::Interval
177 )
178 def meth_to_by(loc, env, _event, stop_value, step_value)
179 ASSERT.kind_of stop_value, VCAN::Int
180 ASSERT.kind_of step_value, VCAN::Int
181
182 if self.val <= stop_value.val
183 unless step_value.val.positive?
184 raise X::ValueError.new(
185 loc,
186 env,
187 "In upto-interval, the step value must be positive," +
188 " but %d : Int",
189 step_value.val
190 )
191 end
192 else
193 unless step_value.val.negative?
194 raise X::ValueError.new(
195 loc,
196 env,
197 "In downto-interval, the step value must be negative," +
198 " but %d : Int",
199 step_value.val
200 )
201 end
202 end
203
204 VC.make_interval self, stop_value, step_value
205 end
206 end
207 Int.freeze
208
209 ZERO = Int.new(0).freeze
210 ONE = Int.new(1).freeze
211
212 end # Umu::Value::Core::Atom::Number
213
214 end # Umu::Value::Core::Atom
215
216
217 module_function
218
219 def make_integer(val)
220 ASSERT.kind_of val, ::Integer
221
222 Atom::Number::Int.new(val).freeze
223 end
224
225
226 def make_integer_zero
227 Atom::Number::ZERO
228 end
229
230
231 def make_integer_one
232 Atom::Number::ONE
233 end
234
235 end # Umu::Value::Core
236
237 end # Umu::Value
238
239 end # Umu