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