1
2
3 :(before "End Primitive Recipe Declarations")
4 EQUAL,
5 :(before "End Primitive Recipe Numbers")
6 put(Recipe_ordinal, "equal", EQUAL);
7 :(before "End Primitive Recipe Checks")
8 case EQUAL: {
9 if (SIZE(inst.ingredients) <= 1) {
10 raise << maybe(get(Recipe, r).name) << "'equal' needs at least two ingredients to compare in '" << to_original_string(inst) << "'\n" << end();
11 break;
12 }
13 const reagent& exemplar = inst.ingredients.at(0);
14 for (int i = 1; i < SIZE(inst.ingredients); ++i) {
15 if (!types_match(inst.ingredients.at(i), exemplar) && !types_match(exemplar, inst.ingredients.at(i))) {
16 raise << maybe(get(Recipe, r).name) << "'equal' expects ingredients to be all of the same type, but got '" << to_original_string(inst) << "'\n" << end();
17 goto finish_checking_instruction;
18 }
19 }
20 if (SIZE(inst.products) > 1) {
21 raise << maybe(get(Recipe, r).name) << "'equal' yields exactly one product in '" << to_original_string(inst) << "'\n" << end();
22 break;
23 }
24 if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_boolean(inst.products.at(0))) {
25 raise << maybe(get(Recipe, r).name) << "'equal' should yield a boolean, but got '" << inst.products.at(0).original_string << "'\n" << end();
26 break;
27 }
28 break;
29 }
30 :(before "End Primitive Recipe Implementations")
31 case EQUAL: {
32 vector<double>& exemplar = ingredients.at(0);
33 bool result = true;
34 for (int i = 1; i < SIZE(ingredients); ++i) {
35 if (!equal(ingredients.at(i).begin(), ingredients.at(i).end(), exemplar.begin())) {
36 result = false;
37 break;
38 }
39 }
40 products.resize(1);
41 products.at(0).push_back(result);
42 break;
43 }
44
45 :(scenario equal)
46 def main [
47 1:num <- copy 34
48 2:num <- copy 33
49 3:bool <- equal 1:num, 2:num
50 ]
51 +mem: location 1 is 34
52 +mem: location 2 is 33
53 +mem: storing 0 in location 3
54
55 :(scenario equal_2)
56 def main [
57 1:num <- copy 34
58 2:num <- copy 34
59 3:bool <- equal 1:num, 2:num
60 ]
61 +mem: location 1 is 34
62 +mem: location 2 is 34
63 +mem: storing 1 in location 3
64
65 :(scenario equal_multiple)
66 def main [
67 1:bool <- equal 34, 34, 34
68 ]
69 +mem: storing 1 in location 1
70
71 :(scenario equal_multiple_2)
72 def main [
73 1:bool <- equal 34, 34, 35
74 ]
75 +mem: storing 0 in location 1
76
77 :(before "End Primitive Recipe Declarations")
78 NOT_EQUAL,
79 :(before "End Primitive Recipe Numbers")
80 put(Recipe_ordinal, "not-equal", NOT_EQUAL);
81 :(before "End Primitive Recipe Checks")
82 case NOT_EQUAL: {
83 if (SIZE(inst.ingredients) != 2) {
84 raise << maybe(get(Recipe, r).name) << "'equal' needs two ingredients to compare in '" << to_original_string(inst) << "'\n" << end();
85 break;
86 }
87 const reagent& exemplar = inst.ingredients.at(0);
88 if (!types_match(inst.ingredients.at(1), exemplar) && !types_match(exemplar, inst.ingredients.at(1))) {
89 raise << maybe(get(Recipe, r).name) << "'equal' expects ingredients to be all of the same type, but got '" << to_original_string(inst) << "'\n" << end();
90 goto finish_checking_instruction;
91 }
92 if (SIZE(inst.products) > 1) {
93 raise << maybe(get(Recipe, r).name) << "'equal' yields exactly one product in '" << to_original_string(inst) << "'\n" << end();
94 break;
95 }
96 if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_boolean(inst.products.at(0))) {
97 raise << maybe(get(Recipe, r).name) << "'equal' should yield a boolean, but got '" << inst.products.at(0).original_string << "'\n" << end();
98 break;
99 }
100 break;
101 }
102 :(before "End Primitive Recipe Implementations")
103 case NOT_EQUAL: {
104 vector<double>& exemplar = ingredients.at(0);
105 products.resize(1);
106 bool equal_ingredients = equal(ingredients.at(1).begin(), ingredients.at(1).end(), exemplar.begin());
107 products.at(0).push_back(!equal_ingredients);
108 break;
109 }
110
111 :(scenario not_equal)
112 def main [
113 1:num <- copy 34
114 2:num <- copy 33
115 3:bool <- not-equal 1:num, 2:num
116 ]
117 +mem: location 1 is 34
118 +mem: location 2 is 33
119 +mem: storing 1 in location 3
120
121 :(scenario not_equal_2)
122 def main [
123 1:num <- copy 34
124 2:num <- copy 34
125 3:bool <- not-equal 1:num, 2:num
126 ]
127 +mem: location 1 is 34
128 +mem: location 2 is 34
129 +mem: storing 0 in location 3
130
131 :(before "End Primitive Recipe Declarations")
132 GREATER_THAN,
133 :(before "End Primitive Recipe Numbers")
134 put(Recipe_ordinal, "greater-than", GREATER_THAN);
135 :(before "End Primitive Recipe Checks")
136 case GREATER_THAN: {
137 if (SIZE(inst.ingredients) <= 1) {
138 raise << maybe(get(Recipe, r).name) << "'greater-than' needs at least two ingredients to compare in '" << to_original_string(inst) << "'\n" << end();
139 break;
140 }
141 for (int i = 0; i < SIZE(inst.ingredients); ++i) {
142 if (!is_mu_number(inst.ingredients.at(i))) {
143 raise << maybe(get(Recipe, r).name) << "'greater-than' can only compare numbers; got '" << inst.ingredients.at(i).original_string << "'\n" << end();
144 goto finish_checking_instruction;
145 }
146 }
147 if (SIZE(inst.products) > 1) {
148 raise << maybe(get(Recipe, r).name) << "'greater-than' yields exactly one product in '" << to_original_string(inst) << "'\n" << end();
149 break;
150 }
151 if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_boolean(inst.products.at(0))) {
152 raise << maybe(get(Recipe, r).name) << "'greater-than' should yield a boolean, but got '" << inst.products.at(0).original_string << "'\n" << end();
153 break;
154 }
155 break;
156 }
157 :(before "End Primitive Recipe Implementations")
158 case GREATER_THAN: {
159 bool result = true;
160 for (int i = 1; i < SIZE(ingredients); ++i) {
161 if (ingredients.at(i-1).at(0) <= ingredients.at(i).at(0)) {
162 result = false;
163 }
164 }
165 products.resize(1);
166 products.at(0).push_back(result);
167 break;
168 }
169
170 :(scenario greater_than)
171 def main [
172 1:num <- copy 34
173 2:num <- copy 33
174 3:bool <- greater-than 1:num, 2:num
175 ]
176 +mem: storing 1 in location 3
177
178 :(scenario greater_than_2)
179 def main [
180 1:num <- copy 34
181 2:num <- copy 34
182 3:bool <- greater-than 1:num, 2:num
183 ]
184 +mem: storing 0 in location 3
185
186 :(scenario greater_than_multiple)
187 def main [
188 1:bool <- greater-than 36, 35, 34
189 ]
190 +mem: storing 1 in location 1
191
192 :(scenario greater_than_multiple_2)
193 def main [
194 1:bool <- greater-than 36, 35, 35
195 ]
196 +mem: storing 0 in location 1
197
198 :(before "End Primitive Recipe Declarations")
199 LESSER_THAN,
200 :(before "End Primitive Recipe Numbers")
201 put(Recipe_ordinal, "lesser-than", LESSER_THAN);
202 :(before "End Primitive Recipe Checks")
203 case LESSER_THAN: {
204 if (SIZE(inst.ingredients) <= 1) {
205 raise << maybe(get(Recipe, r).name) << "'lesser-than' needs at least two ingredients to compare in '" << to_original_string(inst) << "'\n" << end();
206 break;
207 }
208 for (int i = 0; i < SIZE(inst.ingredients); ++i) {
209 if (!is_mu_number(inst.ingredients.at(i))) {
210 raise << maybe(get(Recipe, r).name) << "'lesser-than' can only compare numbers; got '" << inst.ingredients.at(i).original_string << "'\n" << end();
211 goto finish_checking_instruction;
212 }
213 }
214 if (SIZE(inst.products) > 1) {
215 raise << maybe(get(Recipe, r).name) << "'lesser-than' yields exactly one product in '" << to_original_string(inst) << "'\n" << end();
216 break;
217 }
218 if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_boolean(inst.products.at(0))) {
219 raise << maybe(get(Recipe, r).name) << "'lesser-than' should yield a boolean, but got '" << inst.products.at(0).original_string << "'\n" << end();
220 break;
221 }
222 break;
223 }
224 :(before "End Primitive Recipe Implementations")
225 case LESSER_THAN: {
226 bool result = true;
227 for (int i = 1; i < SIZE(ingredients); ++i) {
228 if (ingredients.at(i-1).at(0) >= ingredients.at(i).at(0)) {
229 result = false;
230 }
231 }
232 products.resize(1);
233 products.at(0).push_back(result);
234 break;
235 }
236
237 :(scenario lesser_than)
238 def main [
239 1:num <- copy 32
240 2:num <- copy 33
241 3:bool <- lesser-than 1:num, 2:num
242 ]
243 +mem: storing 1 in location 3
244
245 :(scenario lesser_than_2)
246 def main [
247 1:num <- copy 34
248 2:num <- copy 33
249 3:bool <- lesser-than 1:num, 2:num
250 ]
251 +mem: storing 0 in location 3
252
253 :(scenario lesser_than_multiple)
254 def main [
255 1:bool <- lesser-than 34, 35, 36
256 ]
257 +mem: storing 1 in location 1
258
259 :(scenario lesser_than_multiple_2)
260 def main [
261 1:bool <- lesser-than 34, 35, 35
262 ]
263 +mem: storing 0 in location 1
264
265 :(before "End Primitive Recipe Declarations")
266 GREATER_OR_EQUAL,
267 :(before "End Primitive Recipe Numbers")
268 put(Recipe_ordinal, "greater-or-equal", GREATER_OR_EQUAL);
269 :(before "End Primitive Recipe Checks")
270 case GREATER_OR_EQUAL: {
271 if (SIZE(inst.ingredients) <= 1) {
272 raise << maybe(get(Recipe, r).name) << "'greater-or-equal' needs at least two ingredients to compare in '" << to_original_string(inst) << "'\n" << end();
273 break;
274 }
275 for (int i = 0; i < SIZE(inst.ingredients); ++i) {
276 if (!is_mu_number(inst.ingredients.at(i))) {
277 raise << maybe(get(Recipe, r).name) << "'greater-or-equal' can only compare numbers; got '" << inst.ingredients.at(i).original_string << "'\n" << end();
278 goto finish_checking_instruction;
279 }
280 }
281 if (SIZE(inst.products) > 1) {
282 raise << maybe(get(Recipe, r).name) << "'greater-or-equal' yields exactly one product in '" << to_original_string(inst) << "'\n" << end();
283 break;
284 }
285 if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_boolean(inst.products.at(0))) {
286 raise << maybe(get(Recipe, r).name) << "'greater-or-equal' should yield a boolean, but got '" << inst.products.at(0).original_string << "'\n" << end();
287 break;
288 }
289 break;
290 }
291 :(before "End Primitive Recipe Implementations")
292 case GREATER_OR_EQUAL: {
293 bool result = true;
294 for (int i = 1; i < SIZE(ingredients); ++i) {
295 if (ingredients.at(i-1).at(0) < ingredients.at(i).at(0)) {
296 result = false;
297 }
298 }
299 products.resize(1);
300 products.at(0).push_back(result);
301 break;
302 }
303
304 :(scenario greater_or_equal)
305 def main [
306 1:num <- copy 34
307 2:num <- copy 33
308 3:bool <- greater-or-equal 1:num, 2:num
309 ]
310 +mem: storing 1 in location 3
311
312 :(scenario greater_or_equal_2)
313 def main [
314 1:num <- copy 34
315 2:num <- copy 34
316 3:bool <- greater-or-equal 1:num, 2:num
317 ]
318 +mem: storing 1 in location 3
319
320 :(scenario greater_or_equal_3)
321 def main [
322 1:num <- copy 34
323 2:num <- copy 35
324 3:bool <- greater-or-equal 1:num, 2:num
325 ]
326 +mem: storing 0 in location 3
327
328 :(scenario greater_or_equal_multiple)
329 def main [
330 1:bool <- greater-or-equal 36, 35, 35
331 ]
332 +mem: storing 1 in location 1
333
334 :(scenario greater_or_equal_multiple_2)
335 def main [
336 1:bool <- greater-or-equal 36, 35, 36
337 ]
338 +mem: storing 0 in location 1
339
340 :(before "End Primitive Recipe Declarations")
341 LESSER_OR_EQUAL,
342 :(before "End Primitive Recipe Numbers")
343 put(Recipe_ordinal, "lesser-or-equal", LESSER_OR_EQUAL);
344 :(before "End Primitive Recipe Checks")
345 case LESSER_OR_EQUAL: {
346 if (SIZE(inst.ingredients) <= 1) {
347 raise << maybe(get(Recipe, r).name) << "'lesser-or-equal' needs at least two ingredients to compare in '" << to_original_string(inst) << "'\n" << end();
348 break;
349 }
350 for (int i = 0; i < SIZE(inst.ingredients); ++i) {
351 if (!is_mu_number(inst.ingredients.at(i))) {
352 raise << maybe(get(Recipe, r).name) << "'lesser-or-equal' can only compare numbers; got '" << inst.ingredients.at(i).original_string << "'\n" << end();
353 goto finish_checking_instruction;
354 }
355 }
356 if (SIZE(inst.products) > 1) {
357 raise << maybe(get(Recipe, r).name) << "'greater-or-equal' yields exactly one product in '" << to_original_string(inst) << "'\n" << end();
358 break;
359 }
360 if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_boolean(inst.products.at(0))) {
361 raise << maybe(get(Recipe, r).name) << "'greater-or-equal' should yield a boolean, but got '" << inst.products.at(0).original_string << "'\n" << end();
362 break;
363 }
364 break;
365 }
366 :(before "End Primitive Recipe Implementations")
367 case LESSER_OR_EQUAL: {
368 bool result = true;
369 for (int i = 1; i < SIZE(ingredients); ++i) {
370 if (ingredients.at(i-1).at(0) > ingredients.at(i).at(0)) {
371 result = false;
372 }
373 }
374 products.resize(1);
375 products.at(0).push_back(result);
376 break;
377 }
378
379 :(scenario lesser_or_equal)
380 def main [
381 1:num <- copy 32
382 2:num <- copy 33
383 3:bool <- lesser-or-equal 1:num, 2:num
384 ]
385 +mem: storing 1 in location 3
386
387 :(scenario lesser_or_equal_2)
388 def main [
389 1:num <- copy 33
390 2:num <- copy 33
391 3:bool <- lesser-or-equal 1:num, 2:num
392 ]
393 +mem: storing 1 in location 3
394
395 :(scenario lesser_or_equal_3)
396 def main [
397 1:num <- copy 34
398 2:num <- copy 33
399 3:bool <- lesser-or-equal 1:num, 2:num
400 ]
401 +mem: storing 0 in location 3
402
403 :(scenario lesser_or_equal_multiple)
404 def main [
405 1:bool <- lesser-or-equal 34, 35, 35
406 ]
407 +mem: storing 1 in location 1
408
409 :(scenario lesser_or_equal_multiple_2)
410 def main [
411 1:bool <- lesser-or-equal 34, 35, 34
412 ]
413 +mem: storing 0 in location 1
414
415 :(before "End Primitive Recipe Declarations")
416 MAX,
417 :(before "End Primitive Recipe Numbers")
418 put(Recipe_ordinal, "max", MAX);
419 :(before "End Primitive Recipe Checks")
420 case MAX: {
421 if (SIZE(inst.ingredients) <= 1) {
422 raise << maybe(get(Recipe, r).name) << "'max' needs at least two ingredients to compare in '" << to_original_string(inst) << "'\n" << end();
423 break;
424 }
425 for (int i = 0; i < SIZE(inst.ingredients); ++i) {
426 if (!is_mu_number(inst.ingredients.at(i))) {
427 raise << maybe(get(Recipe, r).name) << "'max' can only compare numbers; got '" << inst.ingredients.at(i).original_string << "'\n" << end();
428 goto finish_checking_instruction;
429 }
430 }
431 if (SIZE(inst.products) > 1) {
432 raise << maybe(get(Recipe, r).name) << "'max' yields exactly one product in '" << to_original_string(inst) << "'\n" << end();
433 break;
434 }
435 if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_number(inst.products.at(0))) {
436 raise << maybe(get(Recipe, r).name) << "'max' should yield a number, but got '" << inst.products.at(0).original_string << "'\n" << end();
437 break;
438 }
439 break;
440 }
441 :(before "End Primitive Recipe Implementations")
442 case MAX: {
443 int result = ingredients.at(0).at(0);
444 for (int i = 1; i < SIZE(ingredients); ++i) {
445 if (ingredients.at(i).at(0) > result) {
446 result = ingredients.at(i).at(0);
447 }
448 }
449 products.resize(1);
450 products.at(0).push_back(result);
451 break;
452 }
453
454 :(before "End Primitive Recipe Declarations")
455 MIN,
456 :(before "End Primitive Recipe Numbers")
457 put(Recipe_ordinal, "min", MIN);
458 :(before "End Primitive Recipe Checks")
459 case MIN: {
460 if (SIZE(inst.ingredients) <= 1) {
461 raise << maybe(get(Recipe, r).name) << "'min' needs at least two ingredients to compare in '" << to_original_string(inst) << "'\n" << end();
462 break;
463 }
464 for (int i = 0; i < SIZE(inst.ingredients); ++i) {
465 if (!is_mu_number(inst.ingredients.at(i))) {
466 raise << maybe(get(Recipe, r).name) << "'min' can only compare numbers; got '" << inst.ingredients.at(i).original_string << "'\n" << end();
467 goto finish_checking_instruction;
468 }
469 }
470 if (SIZE(inst.products) > 1) {
471 raise << maybe(get(Recipe, r).name) << "'min' yields exactly one product in '" << to_original_string(inst) << "'\n" << end();
472 break;
473 }
474 if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_number(inst.products.at(0))) {
475 raise << maybe(get(Recipe, r).name) << "'min' should yield a number, but got '" << inst.products.at(0).original_string << "'\n" << end();
476 break;
477 }
478 break;
479 }
480 :(before "End Primitive Recipe Implementations")
481 case MIN: {
482 int result = ingredients.at(0).at(0);
483 for (int i = 1; i < SIZE(ingredients); ++i) {
484 if (ingredients.at(i).at(0) < result) {
485 result = ingredients.at(i).at(0);
486 }
487 }
488 products.resize(1);
489 products.at(0).push_back(result);
490 break;
491 }