1 # frozen_string_literal: true
2
3 require "test_helper"
4
5
6 module Umu
7
8 module Test
9
10 module Grammar
11
12 module CoreLanguage
13
14 module Expression
15
16 module InfixOperator
17 =begin
18 <infix-expression> ::=
19 <send-expression>
20 | <pipe-operator-expression>
21 | <composite-operator-expression>
22 | <reserved-operator-expression>
23 | <redefinable-operator-expression>
24 ;
25
26 /* <send-expression> ::= ... See SendExpression */
27
28 <normal-infix-operator> ::= /* Referenced by Atomic::IdentifierTest */
29 | <pipe-operator>
30 | <composite-operator>
31 | <reserved-operator>
32 | <redefinable-operator>
33 ;
34 =end
35
36 class PipeTest < Minitest::Test
37 =begin
38 <pipe-operator-expression> ::=
39 <composite-operator-expression>
40 <pipe-operator>
41 <composite-operator-expression>
42 ;
43
44 <pipe-operator> ::= "|>" | "<|" ;
45 =end
46 def setup
47 @interp = Api.setup_interpreter
48 end
49
50
51 def test_pipe_left
52 value = Api.eval_expr @interp, "3 |> succ"
53 assert_instance_of VCAN::Int, value
54 assert_equal 4, value.val
55
56 value = Api.eval_expr @interp, "3 |> succ |> negate"
57 assert_instance_of VCAN::Int, value
58 assert_equal( -4, value.val)
59
60 value = Api.eval_expr @interp, "3 |> succ |> negate |> to-s"
61 assert_instance_of VCA::String, value
62 assert_equal "-4", value.val
63 end
64
65
66 def test_pipe_right
67 value = Api.eval_expr @interp, "succ <| 3"
68 assert_instance_of VCAN::Int, value
69 assert_equal 4, value.val
70
71 value = Api.eval_expr @interp, "negate <| succ <| 3"
72 assert_instance_of VCAN::Int, value
73 assert_equal( -4, value.val)
74
75 value = Api.eval_expr @interp, "to-s <| negate <| succ <| 3"
76 assert_instance_of VCA::String, value
77 assert_equal "-4", value.val
78 end
79 end
80
81
82
83 class CompositeTest < Minitest::Test
84 =begin
85 <composite-operator-expression> ::=
86 <reserved-operator-expression>
87 <composite-operator>
88 <reserved-operator-expression>
89 ;
90
91 <composite-operator> ::= ">>" | "<<" ;
92 =end
93 def setup
94 @interp = Api.setup_interpreter
95 end
96
97
98 def test_composite_left
99 interp = Api.eval_decls @interp, "val f = succ >> negate"
100 value = Api.eval_expr interp, "f 3"
101 assert_instance_of VCAN::Int, value
102 assert_equal( -4, value.val)
103
104 interp = Api.eval_decls @interp, "val f = succ >> negate >> to-s"
105 value = Api.eval_expr interp, "f 3"
106 assert_instance_of VCA::String, value
107 assert_equal "-4", value.val
108 end
109
110
111 def test_composite_right
112 interp = Api.eval_decls @interp, "val f = negate << succ"
113 value = Api.eval_expr interp, "f 3"
114 assert_instance_of VCAN::Int, value
115 assert_equal( -4, value.val)
116
117 interp = Api.eval_decls @interp, "val f = to-s << negate << succ"
118 value = Api.eval_expr interp, "f 3"
119 assert_instance_of VCA::String, value
120 assert_equal "-4", value.val
121 end
122 end
123
124
125
126 class ReservedTest < Minitest::Test
127 =begin
128 <reserved-operator-expression> ::=
129 <shortcut-operator-expression>
130 | <redefinable-operator-expression> KIND-OF ID
131 ;
132
133 <shortcut-operator-expression> ::=
134 <redefinable-operator-expression>
135 <shortcut-operator-expression>
136 <redefinable-operator-expression>
137 ;
138
139 <shortcut-operator-expression> ::= "&&" | "||" ;
140 =end
141 def setup
142 @interp = Api.setup_interpreter
143 end
144
145
146 def test_kind_of
147 value = Api.eval_expr @interp, "3 kind-of? Int"
148 assert_instance_of VCA::Bool, value
149 assert_equal true, value.val
150
151 value = Api.eval_expr @interp, "3 kind-of? String"
152 assert_instance_of VCA::Bool, value
153 assert_equal false, value.val
154 end
155
156
157 def test_shortcut_and
158 value = Api.eval_expr @interp, "TRUE && TRUE"
159 assert_instance_of VCA::Bool, value
160 assert_equal true, value.val
161
162 value = Api.eval_expr @interp, "FALSE && TRUE"
163 assert_instance_of VCA::Bool, value
164 assert_equal false, value.val
165
166 value = Api.eval_expr @interp, "TRUE && FALSE"
167 assert_instance_of VCA::Bool, value
168 assert_equal false, value.val
169
170 value = Api.eval_expr @interp, "FALSE && FALSE"
171 assert_instance_of VCA::Bool, value
172 assert_equal false, value.val
173 end
174
175
176 def test_shortcut_or
177 value = Api.eval_expr @interp, "TRUE || TRUE"
178 assert_instance_of VCA::Bool, value
179 assert_equal true, value.val
180
181 value = Api.eval_expr @interp, "FALSE || TRUE"
182 assert_instance_of VCA::Bool, value
183 assert_equal true, value.val
184
185 value = Api.eval_expr @interp, "TRUE || FALSE"
186 assert_instance_of VCA::Bool, value
187 assert_equal true, value.val
188
189 value = Api.eval_expr @interp, "FALSE || FALSE"
190 assert_instance_of VCA::Bool, value
191 assert_equal false, value.val
192 end
193 end
194
195
196
197 class RedefinableTest < Minitest::Test
198 =begin
199 <redefinable-operator-expression> ::=
200 <send-expression>
201 <redefinable-operator>
202 <send-expression>
203 ;
204
205 <redefinable-operator> ::=
206 "+" | "-" | "^" | "*" | "/" | MOD | POW
207 | "==" | "<>" | "<" | ">" | "<=" | ">="
208 | "++" | ":="
209 ;
210 =end
211 def setup
212 @interp = Api.setup_interpreter
213 end
214
215
216 def test_add
217 value = Api.eval_expr @interp, "3 + 4"
218 assert_instance_of VCAN::Int, value
219 assert_equal 7, value.val
220 end
221
222
223 def test_sub
224 value = Api.eval_expr @interp, "7 - 4"
225 assert_instance_of VCAN::Int, value
226 assert_equal 3, value.val
227 end
228
229
230 def test_append_string
231 value = Api.eval_expr @interp, '"Apple" ^ "Banana"'
232 assert_instance_of VCA::String, value
233 assert_equal "AppleBanana", value.val
234 end
235
236
237 def test_multiply
238 value = Api.eval_expr @interp, "3 * 4"
239 assert_instance_of VCAN::Int, value
240 assert_equal 12, value.val
241 end
242
243
244 def test_divide
245 value = Api.eval_expr @interp, "7 / 3"
246 assert_instance_of VCAN::Int, value
247 assert_equal 2, value.val
248 end
249
250
251 def test_moduulo
252 value = Api.eval_expr @interp, "7 mod 3"
253 assert_instance_of VCAN::Int, value
254 assert_equal 1, value.val
255 end
256
257
258 def test_power
259 value = Api.eval_expr @interp, "2 pow 3"
260 assert_instance_of VCAN::Int, value
261 assert_equal 8, value.val
262 end
263
264
265 def test_equal
266 value = Api.eval_expr @interp, "3 == 4"
267 assert_instance_of VCA::Bool, value
268 assert_equal false, value.val
269 end
270
271
272 def test_not_equal
273 value = Api.eval_expr @interp, "3 <> 4"
274 assert_instance_of VCA::Bool, value
275 assert_equal true, value.val
276 end
277
278
279 def test_less_than
280 value = Api.eval_expr @interp, "3 < 4"
281 assert_instance_of VCA::Bool, value
282 assert_equal true, value.val
283 end
284
285
286 def test_greater_than
287 value = Api.eval_expr @interp, "3 > 4"
288 assert_instance_of VCA::Bool, value
289 assert_equal false, value.val
290 end
291
292
293 def test_less_equal
294 value = Api.eval_expr @interp, "3 <= 4"
295 assert_instance_of VCA::Bool, value
296 assert_equal true, value.val
297 end
298
299
300 def test_greater_equal
301 value = Api.eval_expr @interp, "3 >= 4"
302 assert_instance_of VCA::Bool, value
303 assert_equal false, value.val
304 end
305
306
307 def test_compare
308 value = Api.eval_expr @interp, "3 <=> 4"
309 assert_instance_of VCAN::Int, value
310 assert_equal( -1, value.val)
311 end
312
313
314 def test_append_morph
315 value = Api.eval_expr @interp, "[1, 2] ++ [3, 4]"
316 assert_instance_of VCM::List::Cons, value
317 [1, 2, 3, 4].zip(value.to_a).each do |expected, actual_value|
318 assert_instance_of VCAN::Int, actual_value
319 assert_equal expected, actual_value.val
320 end
321 end
322
323
324 def test_assigin
325 interp = Api.eval_decls @interp, "val rx = ref 3"
326 value_1 = Api.eval_expr interp, "rx := 4"
327 assert_instance_of VC::Unit, value_1
328
329 value_2 = Api.eval_expr interp, "!!rx"
330 assert_instance_of VCAN::Int, value_2
331 assert_equal 4, value_2.val
332 end
333 end
334
335 end # Umu::Test::Grammar::CoreLanguage::Expression::InfixOperator
336
337 end # Umu::Test::Grammar::CoreLanguage::Expression
338
339 end # Umu::Test::Grammar::CoreLanguage
340
341 end # Umu::Test::Grammar
342
343 end # Umu::Test
344
345 end # Umu