https://github.com/akkartik/mu/blob/master/022arithmetic.cc
1
2
3 :(before "End Primitive Recipe Declarations")
4 ADD,
5 :(before "End Primitive Recipe Numbers")
6 put(Recipe_ordinal, "add", ADD);
7 :(before "End Primitive Recipe Checks")
8 case ADD: {
9
10 for (int i = 0; i < SIZE(inst.ingredients); ++i) {
11 if (!is_mu_number(inst.ingredients.at(i))) {
12 raise << maybe(get(Recipe, r).name) << "'add' requires number ingredients, but got '" << inst.ingredients.at(i).original_string << "'\n" << end();
13 goto finish_checking_instruction;
14 }
15 }
16 if (SIZE(inst.products) > 1) {
17 raise << maybe(get(Recipe, r).name) << "'add' yields exactly one product in '" << to_original_string(inst) << "'\n" << end();
18 break;
19 }
20 if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_number(inst.products.at(0))) {
21 raise << maybe(get(Recipe, r).name) << "'add' should yield a number, but got '" << inst.products.at(0).original_string << "'\n" << end();
22 break;
23 }
24 break;
25 }
26 :(before "End Primitive Recipe Implementations")
27 case ADD: {
28 double result = 0;
29 for (int i = 0; i < SIZE(ingredients); ++i) {
30 result += ingredients.at(i).at(0);
31 }
32 products.resize(1);
33 products.at(0).push_back(result);
34 break;
35 }
36
37 :(scenario add_literal)
38 def main [
39 1:num <- add 23, 34
40 ]
41 +mem: storing 57 in location 1
42
43 :(scenario add)
44 def main [
45 1:num <- copy 23
46 2:num <- copy 34
47 3:num <- add 1:num, 2:num
48 ]
49 +mem: storing 57 in location 3
50
51 :(scenario add_multiple)
52 def main [
53 1:num <- add 3, 4, 5
54 ]
55 +mem: storing 12 in location 1
56
57 :(scenario add_checks_type)
58 % Hide_errors = true;
59 def main [
60 1:num <- add 2:bool, 1
61 ]
62 +error: main: 'add' requires number ingredients, but got '2:bool'
63
64 :(scenario add_checks_return_type)
65 % Hide_errors = true;
66 def main [
67 1:&:num <- add 2, 2
68 ]
69 +error: main: 'add' should yield a number, but got '1:&:num'
70
71 :(before "End Primitive Recipe Declarations")
72 SUBTRACT,
73 :(before "End Primitive Recipe Numbers")
74 put(Recipe_ordinal, "subtract", SUBTRACT);
75 :(before "End Primitive Recipe Checks")
76 case SUBTRACT: {
77 if (inst.ingredients.empty()) {
78 raise << maybe(get(Recipe, r).name) << "'subtract' has no ingredients\n" << end();
79 break;
80 }
81 for (int i = 0; i < SIZE(inst.ingredients); ++i) {
82 if (!is_mu_number(inst.ingredients.at(i))) {
83 raise << maybe(get(Recipe, r).name) << "'subtract' requires number ingredients, but got '" << inst.ingredients.at(i).original_string << "'\n" << end();
84 goto finish_checking_instruction;
85 }
86 }
87 if (SIZE(inst.products) > 1) {
88 raise << maybe(get(Recipe, r).name) << "'subtract' yields exactly one product in '" << to_original_string(inst) << "'\n" << end();
89 break;
90 }
91 if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_number(inst.products.at(0))) {
92 raise << maybe(get(Recipe, r).name) << "'subtract' should yield a number, but got '" << inst.products.at(0).original_string << "'\n" << end();
93 break;
94 }
95 break;
96 }
97 :(before "End Primitive Recipe Implementations")
98 case SUBTRACT: {
99 double result = ingredients.at(0).at(0);
100 for (int i = 1; i < SIZE(ingredients); ++i)
101 result -= ingredients.at(i).at(0);
102 products.resize(1);
103 products.at(0).push_back(result);
104 break;
105 }
106
107 :(scenario subtract_literal)
108 def main [
109 1:num <- subtract 5, 2
110 ]
111 +mem: storing 3 in location 1
112
113 :(scenario subtract)
114 def main [
115 1:num <- copy 23
116 2:num <- copy 34
117 3:num <- subtract 1:num, 2:num
118 ]
119 +mem: storing -11 in location 3
120
121 :(scenario subtract_multiple)
122 def main [
123 1:num <- subtract 6, 3, 2
124 ]
125 +mem: storing 1 in location 1
126
127 :(before "End Primitive Recipe Declarations")
128 MULTIPLY,
129 :(before "End Primitive Recipe Numbers")
130 put(Recipe_ordinal, "multiply", MULTIPLY);
131 :(before "End Primitive Recipe Checks")
132 case MULTIPLY: {
133 for (int i = 0; i < SIZE(inst.ingredients); ++i) {
134 if (!is_mu_number(inst.ingredients.at(i))) {
135 raise << maybe(get(Recipe, r).name) << "'multiply' requires number ingredients, but got '" << inst.ingredients.at(i).original_string << "'\n" << end();
136 goto finish_checking_instruction;
137 }
138 }
139 if (SIZE(inst.products) > 1) {
140 raise << maybe(get(Recipe, r).name) << "'multiply' yields exactly one product in '" << to_original_string(inst) << "'\n" << end();
141 break;
142 }
143 if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_number(inst.products.at(0))) {
144 raise << maybe(get(Recipe, r).name) << "'multiply' should yield a number, but got '" << inst.products.at(0).original_string << "'\n" << end();
145 break;
146 }
147 break;
148 }
149 :(before "End Primitive Recipe Implementations")
150 case MULTIPLY: {
151 double result = 1;
152 for (int i = 0; i < SIZE(ingredients); ++i) {
153 result *= ingredients.at(i).at(0);
154 }
155 products.resize(1);
156 products.at(0).push_back(result);
157 break;
158 }
159
160 :(scenario multiply_literal)
161 def main [
162 1:num <- multiply 2, 3
163 ]
164 +mem: storing 6 in location 1
165
166 :(scenario multiply)
167 def main [
168 1:num <- copy 4
169 2:num <- copy 6
170 3:num <- multiply 1:num, 2:num
171 ]
172 +mem: storing 24 in location 3
173
174 :(scenario multiply_multiple)
175 def main [
176 1:num <- multiply 2, 3, 4
177 ]
178 +mem: storing 24 in location 1
179
180 :(before "End Primitive Recipe Declarations")
181 DIVIDE,
182 :(before "End Primitive Recipe Numbers")
183 put(Recipe_ordinal, "divide", DIVIDE);
184 :(before "End Primitive Recipe Checks")
185 case DIVIDE: {
186 if (inst.ingredients.empty()) {
187 raise << maybe(get(Recipe, r).name) << "'divide' has no ingredients\n" << end();
188 break;
189 }
190 for (int i = 0; i < SIZE(inst.ingredients); ++i) {
191 if (!is_mu_number(inst.ingredients.at(i))) {
192 raise << maybe(get(Recipe, r).name) << "'divide' requires number ingredients, but got '" << inst.ingredients.at(i).original_string << "'\n" << end();
193 goto finish_checking_instruction;
194 }
195 }
196 if (SIZE(inst.products) > 1) {
197 raise << maybe(get(Recipe, r).name) << "'divide' yields exactly one product in '" << to_original_string(inst) << "'\n" << end();
198 break;
199 }
200 if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_number(inst.products.at(0))) {
201 raise << maybe(get(Recipe, r).name) << "'divide' should yield a number, but got '" << inst.products.at(0).original_string << "'\n" << end();
202 break;
203 }
204 break;
205 }
206 :(before "End Primitive Recipe Implementations")
207 case DIVIDE: {
208 double result = ingredients.at(0).at(0);
209 for (int i = 1; i < SIZE(ingredients); ++i)
210 result /= ingredients.at(i).at(0);
211 products.resize(1);
212 products.at(0).push_back(result);
213 break;
214 }
215
216 :(scenario divide_literal)
217 def main [
218 1:num <- divide 8, 2
219 ]
220 +mem: storing 4 in location 1
221
222 :(scenario divide)
223 def main [
224 1:num <- copy 27
225 2:num <- copy 3
226 3:num <- divide 1:num, 2:num
227 ]
228 +mem: storing 9 in location 3
229
230 :(scenario divide_multiple)
231 def main [
232 1:num <- divide 12, 3, 2
233 ]
234 +mem: storing 2 in location 1
235
236
237
238 :(before "End Primitive Recipe Declarations")
239 DIVIDE_WITH_REMAINDER,
240 :(before "End Primitive Recipe Numbers")
241 put(Recipe_ordinal, "divide-with-remainder", DIVIDE_WITH_REMAINDER);
242 :(before "End Primitive Recipe Checks")
243 case DIVIDE_WITH_REMAINDER: {
244 if (SIZE(inst.ingredients) != 2) {
245 raise << maybe(get(Recipe, r).name) << "'divide-with-remainder' requires exactly two ingredients, but got '" << to_original_string(inst) << "'\n" << end();
246 break;
247 }
248 if (!is_mu_number(inst.ingredients.at(0)) || !is_mu_number(inst.ingredients.at(1))) {
249 raise << maybe(get(Recipe, r).name) << "'divide-with-remainder' requires number ingredients, but got '" << to_original_string(inst) << "'\n" << end();
250 break;
251 }
252 if (SIZE(inst.products) > 2) {
253 raise << maybe(get(Recipe, r).name) << "'divide-with-remainder' yields two products in '" << to_original_string(inst) << "'\n" << end();
254 break;
255 }
256 for (int i = 0; i < SIZE(inst.products); ++i) {
257 if (!is_dummy(inst.products.at(i)) && !is_mu_number(inst.products.at(i))) {
258 raise << maybe(get(Recipe, r).name) << "'divide-with-remainder' should yield a number, but got '" << inst.products.at(i).original_string << "'\n" << end();
259 goto finish_checking_instruction;
260 }
261 }
262 break;
263 }
264 :(before "End Primitive Recipe Implementations")
265 case DIVIDE_WITH_REMAINDER: {
266 products.resize(2);
267
268 long long int a = static_cast<long long int>(ingredients.at(0).at(0));
269 long long int b = static_cast<long long int>(ingredients.at(1).at(0));
270 if (b == 0) {
271 raise << maybe(current_recipe_name()) << "divide by zero in '" << to_original_string(current_instruction()) << "'\n" << end();
272 products.resize(2);
273 products.at(0).push_back(0);
274 products.at(1).push_back(0);
275 break;
276 }
277 long long int quotient = a / b;
278 long long int remainder = a % b;
279 products.at(0).push_back(static_cast<double>(quotient));
280 products.at(1).push_back(static_cast<double>(remainder));
281 break;
282 }
283
284 :(scenario divide_with_remainder_literal)
285 def main [
286 1:num, 2:num <- divide-with-remainder 9, 2
287 ]
288 +mem: storing 4 in location 1
289 +mem: storing 1 in location 2
290
291 :(scenario divide_with_remainder)
292 def main [
293 1:num <- copy 27
294 2:num <- copy 11
295 3:num, 4:num <- divide-with-remainder 1:num, 2:num
296 ]
297 +mem: storing 2 in location 3
298 +mem: storing 5 in location 4
299
300 :(scenario divide_with_decimal_point)
301 def main [
302 1:num <- divide 5, 2
303 ]
304 +mem: storing 2.5 in location 1
305
306 :(scenario divide_by_zero)
307 def main [
308 1:num <- divide 4, 0
309 ]
310 +mem: storing inf in location 1
311
312 :(scenario divide_by_zero_2)
313 % Hide_errors = true;
314 def main [
315 1:num <- divide-with-remainder 4, 0
316 ]
317
318 +error: main: divide by zero in '1:num <- divide-with-remainder 4, 0'
319
320
321
322 :(before "End Primitive Recipe Declarations")
323 SHIFT_LEFT,
324 :(before "End Primitive Recipe Numbers")
325 put(Recipe_ordinal, "shift-left", SHIFT_LEFT);
326 :(before "End Primitive Recipe Checks")
327 case SHIFT_LEFT: {
328 if (SIZE(inst.ingredients) != 2) {
329 raise << maybe(get(Recipe, r).name) << "'shift-left' requires exactly two ingredients, but got '" << to_original_string(inst) << "'\n" << end();
330 break;
331 }
332 if (!is_mu_number(inst.ingredients.at(0)) || !is_mu_number(inst.ingredients.at(1))) {
333 raise << maybe(get(Recipe, r).name) << "'shift-left' requires number ingredients, but got '" << to_original_string(inst) << "'\n" << end();
334 break;
335 }
336 if (SIZE(inst.products) > 1) {
337 raise << maybe(get(Recipe, r).name) << "'shift-left' yields one product in '" << to_original_string(inst) << "'\n" << end();
338 break;
339 }
340 if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_number(inst.products.at(0))) {
341 raise << maybe(get(Recipe, r).name) << "'shift-left' should yield a number, but got '" << inst.products.at(0).original_string << "'\n" << end();
342 goto finish_checking_instruction;
343 }
344 break;
345 }
346 :(before "End Primitive Recipe Implementations")
347 case SHIFT_LEFT: {
348
349 int a = static_cast<int>(ingredients.at(0).at(0));
350 int b = static_cast<int>(ingredients.at(1).at(0));
351 products.resize(1);
352 if (b < 0) {
353 raise << maybe(current_recipe_name()) << "second ingredient can't be negative in '" << to_original_string(current_instruction()) << "'\n" << end();
354 products.at(0).push_back(0);
355 break;
356 }
357 products.at(0).push_back(a<<b);
358 break;
359 }
360
361 :(scenario shift_left_by_zero)
362 def main [
363 1:num <- shift-left 1, 0
364 ]
365 +mem: storing 1 in location 1
366
367 :(scenario shift_left_1)
368 def main [
369 1:num <- shift-left 1, 4
370 ]
371 +mem: storing 16 in location 1
372
373 :(scenario shift_left_2)
374 def main [
375 1:num <- shift-left 3, 2
376 ]
377 +mem: storing 12 in location 1
378
379 :(scenario shift_left_by_negative)
380 % Hide_errors = true;
381 def main [
382 1:num <- shift-left 3, -1
383 ]
384 +error: main: second ingredient can't be negative in '1:num <- shift-left 3, -1'
385
386 :(scenario shift_left_ignores_fractional_part)
387 def main [
388 1:num <- divide 3, 2
389 2:num <- shift-left 1:num, 1
390 ]
391 +mem: storing 2 in location 2
392
393 :(before "End Primitive Recipe Declarations")
394 SHIFT_RIGHT,
395 :(before "End Primitive Recipe Numbers")
396 put(Recipe_ordinal, "shift-right", SHIFT_RIGHT);
397 :(before "End Primitive Recipe Checks")
398 case SHIFT_RIGHT: {
399 if (SIZE(inst.ingredients) != 2) {
400 raise << maybe(get(Recipe, r).name) << "'shift-right' requires exactly two ingredients, but got '" << to_original_string(inst) << "'\n" << end();
401 break;
402 }
403 if (!is_mu_number(inst.ingredients.at(0)) || !is_mu_number(inst.ingredients.at(1))) {
404 raise << maybe(get(Recipe, r).name) << "'shift-right' requires number ingredients, but got '" << to_original_string(inst) << "'\n" << end();
405 break;
406 }
407 if (SIZE(inst.products) > 1) {
408 raise << maybe(get(Recipe, r).name) << "'shift-right' yields one product in '" << to_original_string(inst) << "'\n" << end();
409 break;
410 }
411 if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_number(inst.products.at(0))) {
412 raise << maybe(get(Recipe, r).name) << "'shift-right' should yield a number, but got '" << inst.products.at(0).original_string << "'\n" << end();
413 goto finish_checking_instruction;
414 }
415 break;
416 }
417 :(before "End Primitive Recipe Implementations")
418 case SHIFT_RIGHT: {
419
420 int a = static_cast<int>(ingredients.at(0).at(0));
421 int b = static_cast<int>(ingredients.at(1).at(0));
422 products.resize(1);
423 if (b < 0) {
424 raise << maybe(current_recipe_name()) << "second ingredient can't be negative in '" << to_original_string(current_instruction()) << "'\n" << end();
425 products.at(0).push_back(0);
426 break;
427 }
428 products.at(0).push_back(a>>b);
429 break;
430 }
431
432 :(scenario shift_right_by_zero)
433 def main [
434 1:num <- shift-right 1, 0
435 ]
436 +mem: storing 1 in location 1
437
438 :(scenario shift_right_1)
439 def main [
440 1:num <- shift-right 1024, 1
441 ]
442 +mem: storing 512 in location 1
443
444 :(scenario shift_right_2)
445 def main [
446 1:num <- shift-right 3, 1
447 ]
448 +mem: storing 1 in location 1
449
450 :(scenario shift_right_by_negative)
451 % Hide_errors = true;
452 def main [
453 1:num <- shift-right 4, -1
454 ]
455 +error: main: second ingredient can't be negative in '1:num <- shift-right 4, -1'
456
457 :(scenario shift_right_ignores_fractional_part)
458 def main [
459 1:num <- divide 3, 2
460 2:num <- shift-right 1:num, 1
461 ]
462 +mem: storing 0 in location 2
463
464 :(before "End Primitive Recipe Declarations")
465 AND_BITS,
466 :(before "End Primitive Recipe Numbers")
467 put(Recipe_ordinal, "and-bits", AND_BITS);
468 :(before "End Primitive Recipe Checks")
469 case AND_BITS: {
470 if (SIZE(inst.ingredients) != 2) {
471 raise << maybe(get(Recipe, r).name) << "'and-bits' requires exactly two ingredients, but got '" << to_original_string(inst) << "'\n" << end();
472 break;
473 }
474 if (!is_mu_number(inst.ingredients.at(0)) || !is_mu_number(inst.ingredients.at(1))) {
475 raise << maybe(get(Recipe, r).name) << "'and-bits' requires number ingredients, but got '" << to_original_string(inst) << "'\n" << end();
476 break;
477 }
478 if (SIZE(inst.products) > 1) {
479 raise << maybe(get(Recipe, r).name) << "'and-bits' yields one product in '" << to_original_string(inst) << "'\n" << end();
480 break;
481 }
482 if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_number(inst.products.at(0))) {
483 raise << maybe(get(Recipe, r).name) << "'and-bits' should yield a number, but got '" << inst.products.at(0).original_string << "'\n" << end();
484 goto finish_checking_instruction;
485 }
486 break;
487 }
488 :(before "End Primitive Recipe Implementations")
489 case AND_BITS: {
490
491 int a = static_cast<int>(ingredients.at(0).at(0));
492 int b = static_cast<int>(ingredients.at(1).at(0));
493 products.resize(1);
494 products.at(0).push_back(a&b);
495 break;
496 }
497
498 :(scenario and_bits_1)
499 def main [
500 1:num <- and-bits 8, 3
501 ]
502 +mem: storing 0 in location 1
503
504 :(scenario and_bits_2)
505 def main [
506 1:num <- and-bits 3, 2
507 ]
508 +mem: storing 2 in location 1
509
510 :(scenario and_bits_3)
511 def main [
512 1:num <- and-bits 14, 3
513 ]
514 +mem: storing 2 in location 1
515
516 :(scenario and_bits_negative)
517 def main [
518 1:num <- and-bits -3, 4
519 ]
520 +mem: storing 4 in location 1
521
522 :(before "End Primitive Recipe Declarations")
523 OR_BITS,
524 :(before "End Primitive Recipe Numbers")
525 put(Recipe_ordinal, "or-bits", OR_BITS);
526 :(before "End Primitive Recipe Checks")
527 case OR_BITS: {
528 if (SIZE(inst.ingredients) != 2) {
529 raise << maybe(get(Recipe, r).name) << "'or-bits' requires exactly two ingredients, but got '" << to_original_string(inst) << "'\n" << end();
530 break;
531 }
532 if (!is_mu_number(inst.ingredients.at(0)) || !is_mu_number(inst.ingredients.at(1))) {
533 raise << maybe(get(Recipe, r).name) << "'or-bits' requires number ingredients, but got '" << to_original_string(inst) << "'\n" << end();
534 break;
535 }
536 if (SIZE(inst.products) > 1) {
537 raise << maybe(get(Recipe, r).name) << "'or-bits' yields one product in '" << to_original_string(inst) << "'\n" << end();
538 break;
539 }
540 if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_number(inst.products.at(0))) {
541 raise << maybe(get(Recipe, r).name) << "'or-bits' should yield a number, but got '" << inst.products.at(0).original_string << "'\n" << end();
542 goto finish_checking_instruction;
543 }
544 break;
545 }
546 :(before "End Primitive Recipe Implementations")
547 case OR_BITS: {
548
549 int a = static_cast<int>(ingredients.at(0).at(0));
550 int b = static_cast<int>(ingredients.at(1).at(0));
551 products.resize(1);
552 products.at(0).push_back(a|b);
553 break;
554 }
555
556 :(scenario or_bits_1)
557 def main [
558 1:num <- or-bits 3, 8
559 ]
560 +mem: storing 11 in location 1
561
562 :(scenario or_bits_2)
563 def main [
564 1:num <- or-bits 3, 10
565 ]
566 +mem: storing 11 in location 1
567
568 :(scenario or_bits_3)
569 def main [
570 1:num <- or-bits 4, 6
571 ]
572 +mem: storing 6 in location 1
573
574 :(before "End Primitive Recipe Declarations")
575 XOR_BITS,
576 :(before "End Primitive Recipe Numbers")
577 put(Recipe_ordinal, "xor-bits", XOR_BITS);
578 :(before "End Primitive Recipe Checks")
579 case XOR_BITS: {
580 if (SIZE(inst.ingredients) != 2) {
581 raise << maybe(get(Recipe, r).name) << "'xor-bits' requires exactly two ingredients, but got '" << to_original_string(inst) << "'\n" << end();
582 break;
583 }
584 if (!is_mu_number(inst.ingredients.at(0)) || !is_mu_number(inst.ingredients.at(1))) {
585 raise << maybe(get(Recipe, r).name) << "'xor-bits' requires number ingredients, but got '" << to_original_string(inst) << "'\n" << end();
586 break;
587 }
588 if (SIZE(inst.products) > 1) {
589 raise << maybe(get(Recipe, r).name) << "'xor-bits' yields one product in '" << to_original_string(inst) << "'\n" << end();
590 break;
591 }
592 if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_number(inst.products.at(0))) {
593 raise << maybe(get(Recipe, r).name) << "'xor-bits' should yield a number, but got '" << inst.products.at(0).original_string << "'\n" << end();
594 goto finish_checking_instruction;
595 }
596 break;
597 }
598 :(before "End Primitive Recipe Implementations")
599 case XOR_BITS: {
600
601 int a = static_cast<int>(ingredients.at(0).at(0));
602 int b = static_cast<int>(ingredients.at(1).at(0));
603 products.resize(1);
604 products.at(0).push_back(a^b);
605 break;
606 }
607
608 :(scenario xor_bits_1)
609 def main [
610 1:num <- xor-bits 3, 8
611 ]
612 +mem: storing 11 in location 1
613
614 :(scenario xor_bits_2)
615 def main [
616 1:num <- xor-bits 3, 10
617 ]
618 +mem: storing 9 in location 1
619
620 :(scenario xor_bits_3)
621 def main [
622 1:num <- xor-bits 4, 6
623 ]
624 +mem: storing 2 in location 1
625
626 :(before "End Primitive Recipe Declarations")
627 FLIP_BITS,
628 :(before "End Primitive Recipe Numbers")
629 put(Recipe_ordinal, "flip-bits", FLIP_BITS);
630 :(before "End Primitive Recipe Checks")
631 case FLIP_BITS: {
632 if (SIZE(inst.ingredients) != 1) {
633 raise << maybe(get(Recipe, r).name) << "'flip-bits' requires exactly one ingredient, but got '" << to_original_string(inst) << "'\n" << end();
634 break;
635 }
636 if (!is_mu_number(inst.ingredients.at(0))) {
637 raise << maybe(get(Recipe, r).name) << "'flip-bits' requires a number ingredient, but got '" << to_original_string(inst) << "'\n" << end();
638 break;
639 }
640 if (SIZE(inst.products) > 1) {
641 raise << maybe(get(Recipe, r).name) << "'flip-bits' yields one product in '" << to_original_string(inst) << "'\n" << end();
642 break;
643 }
644 if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_number(inst.products.at(0))) {
645 raise << maybe(get(Recipe, r).name) << "'flip-bits' should yield a number, but got '" << inst.products.at(0).original_string << "'\n" << end();
646 goto finish_checking_instruction;
647 }
648 break;
649 }
650 :(before "End Primitive Recipe Implementations")
651 case FLIP_BITS: {
652
653 int a = static_cast<int>(ingredients.at(0).at(0));
654 products.resize(1);
655 products.at(0).push_back(~a);
656 break;
657 }
658
659 :(scenario flip_bits_zero)
660 def main [
661 1:num <- flip-bits 0
662 ]
663 +mem: storing -1 in location 1
664
665 :(scenario flip_bits_negative)
666 def main [
667 1:num <- flip-bits -1
668 ]
669 +mem: storing 0 in location 1
670
671 :(scenario flip_bits_1)
672 def main [
673 1:num <- flip-bits 3
674 ]
675 +mem: storing -4 in location 1
676
677 :(scenario flip_bits_2)
678 def main [
679 1:num <- flip-bits 12
680 ]
681 +mem: storing -13 in location 1
682
683 :(before "End Primitive Recipe Declarations")
684 ROUND,
685 :(before "End Primitive Recipe Numbers")
686 put(Recipe_ordinal, "round", ROUND);
687 :(before "End Primitive Recipe Checks")
688 case ROUND: {
689 if (SIZE(inst.ingredients) != 1) {
690 raise << maybe(get(Recipe, r).name) << "'round' requires exactly one ingredient, but got '" << to_original_string(inst) << "'\n" << end();
691 break;
692 }
693 if (!is_mu_number(inst.ingredients.at(0))) {
694 raise << maybe(get(Recipe, r).name) << "first ingredient of 'round' should be a number, but got '" << inst.ingredients.at(0).original_string << "'\n" << end();
695 break;
696 }
697 break;
698 }
699 :(before "End Primitive Recipe Implementations")
700 case ROUND: {
701 products.resize(1);
702 products.at(0).push_back(rint(ingredients.at(0).at(0)));
703 break;
704 }
705
706 :(scenario round_to_nearest_integer)
707 def main [
708 1:num <- round 12.2
709 ]
710 +mem: storing 12 in location 1
711
712 :(scenario round_halves_toward_zero)
713 def main [
714 1:num <- round 12.5
715 ]
716 +mem: storing 12 in location 1
717
718 :(scenario round_halves_toward_zero_2)
719 def main [
720 1:num <- round -12.5
721 ]
722 +mem: storing -12 in location 1
723
724 :(before "End Primitive Recipe Declarations")
725 TRUNCATE,
726 :(before "End Primitive Recipe Numbers")
727 put(Recipe_ordinal, "truncate", TRUNCATE);
728 :(before "End Primitive Recipe Checks")
729 case TRUNCATE: {
730 if (SIZE(inst.ingredients) != 1) {
731 raise << maybe(get(Recipe, r).name) << "'truncate' requires exactly one ingredient, but got '" << to_original_string(inst) << "'\n" << end();
732 break;
733 }
734 if (!is_mu_number(inst.ingredients.at(0))) {
735 raise << maybe(get(Recipe, r).name) << "first ingredient of 'truncate' should be a number, but got '" << inst.ingredients.at(0).original_string << "'\n" << end();
736 break;
737 }
738 break;
739 }
740 :(before "End Primitive Recipe Implementations")
741 case TRUNCATE: {
742 products.resize(1);
743 products.at(0).push_back(trunc(ingredients.at(0).at(0)));
744 break;
745 }
746
747 :(scenario truncate_to_nearest_integer)
748 def main [
749 1:num <- truncate 12.2
750 ]
751 +mem: storing 12 in location 1
752
753 :(scenario truncate_negative)
754 def main [
755 1:num <- truncate -12.2
756 ]
757 +mem: storing -12 in location 1
758
759 :(before "End Primitive Recipe Declarations")
760 SQUARE_ROOT,
761 :(before "End Primitive Recipe Numbers")
762 put(Recipe_ordinal, "square-root", SQUARE_ROOT);
763 :(before "End Primitive Recipe Checks")
764 case SQUARE_ROOT: {
765 if (SIZE(inst.ingredients) != 1) {
766 raise << maybe(get(Recipe, r).name) << "'square-root' requires exactly one ingredient, but got '" << to_original_string(inst) << "'\n" << end();
767 break;
768 }
769 if (!is_mu_number(inst.ingredients.at(0))) {
770 raise << maybe(get(Recipe, r).name) << "first ingredient of 'square-root' should be a number, but got '" << inst.ingredients.at(0).original_string << "'\n" << end();
771 break;
772 }
773 break;
774 }
775 :(before "End Primitive Recipe Implementations")
776 case SQUARE_ROOT: {
777 products.resize(1);
778 products.at(0).push_back(sqrt(ingredients.at(0).at(0)));
779 break;
780 }
781
782 :(before "End Primitive Recipe Declarations")
783 CHARACTER_TO_CODE,
784 :(before "End Primitive Recipe Numbers")
785 put(Recipe_ordinal, "character-to-code", CHARACTER_TO_CODE);
786 :(before "End Primitive Recipe Checks")
787 case CHARACTER_TO_CODE: {
788 if (SIZE(inst.ingredients) != 1) {
789 raise << maybe(get(Recipe, r).name) << "'character-to-code' requires exactly one ingredient, but got '" << to_original_string(inst) << "'\n" << end();
790 break;
791 }
792 if (!is_mu_character(inst.ingredients.at(0))) {
793 raise << maybe(get(Recipe, r).name) << "first ingredient of 'character-to-code' should be a character, but got '" << inst.ingredients.at(0).original_string << "'\n" << end();
794 break;
795 }
796 if (SIZE(inst.products) != 1) {
797 raise << maybe(get(Recipe, r).name) << "'character-to-code' requires exactly one product, but got '" << to_original_string(inst) << "'\n" << end();
798 break;
799 }
800 if (!is_mu_number(inst.products.at(0))) {
801 raise << maybe(get(Recipe, r).name) << "first product of 'character-to-code' should be a number, but got '" << inst.products.at(0).original_string << "'\n" << end();
802 break;
803 }
804 break;
805 }
806 :(before "End Primitive Recipe Implementations")
807 case CHARACTER_TO_CODE: {
808 double result = 0;
809 for (int i = 0; i < SIZE(ingredients); ++i) {
810 result += ingredients.at(i).at(0);
811 }
812 products.resize(1);
813 products.at(0).push_back(result);
814 break;
815 }
816
817 :(before "End Includes")
818