https://github.com/akkartik/mu/blob/master/025compare.cc
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 (SIZE(ingredients.at(i)) != SIZE(exemplar)) {
36 result = false;
37 break;
38 }
39 if (!equal(ingredients.at(i).begin(), ingredients.at(i).end(), exemplar.begin())) {
40 result = false;
41 break;
42 }
43 }
44 products.resize(1);
45 products.at(0).push_back(result);
46 break;
47 }
48
49 :(scenario equal)
50 def main [
51 1:num <- copy 34
52 2:num <- copy 33
53 3:bool <- equal 1:num, 2:num
54 ]
55 +mem: location 1 is 34
56 +mem: location 2 is 33
57 +mem: storing 0 in location 3
58
59 :(scenario equal_2)
60 def main [
61 1:num <- copy 34
62 2:num <- copy 34
63 3:bool <- equal 1:num, 2:num
64 ]
65 +mem: location 1 is 34
66 +mem: location 2 is 34
67 +mem: storing 1 in location 3
68
69 :(scenario equal_multiple)
70 def main [
71 1:bool <- equal 34, 34, 34
72 ]
73 +mem: storing 1 in location 1
74
75 :(scenario equal_multiple_2)
76 def main [
77 1:bool <- equal 34, 34, 35
78 ]
79 +mem: storing 0 in location 1
80
81 :(before "End Primitive Recipe Declarations")
82 NOT_EQUAL,
83 :(before "End Primitive Recipe Numbers")
84 put(Recipe_ordinal, "not-equal", NOT_EQUAL);
85 :(before "End Primitive Recipe Checks")
86 case NOT_EQUAL: {
87 if (SIZE(inst.ingredients) != 2) {
88 raise << maybe(get(Recipe, r).name) << "'equal' needs two ingredients to compare in '" << to_original_string(inst) << "'\n" << end();
89 break;
90 }
91 const reagent& exemplar = inst.ingredients.at(0);
92 if (!types_match(inst.ingredients.at(1), exemplar) && !types_match(exemplar, inst.ingredients.at(1))) {
93 raise << maybe(get(Recipe, r).name) << "'equal' expects ingredients to be all of the same type, but got '" << to_original_string(inst) << "'\n" << end();
94 goto finish_checking_instruction;
95 }
96 if (SIZE(inst.products) > 1) {
97 raise << maybe(get(Recipe, r).name) << "'equal' yields exactly one product in '" << to_original_string(inst) << "'\n" << end();
98 break;
99 }
100 if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_boolean(inst.products.at(0))) {
101 raise << maybe(get(Recipe, r).name) << "'equal' should yield a boolean, but got '" << inst.products.at(0).original_string << "'\n" << end();
102 break;
103 }
104 break;
105 }
106 :(before "End Primitive Recipe Implementations")
107 case NOT_EQUAL: {
108 vector<double>& exemplar = ingredients.at(0);
109 products.resize(1);
110 if (SIZE(ingredients.at(1)) != SIZE(exemplar)) {
111 products.at(0).push_back(true);
112 break;
113 }
114 bool equal_ingredients = equal(ingredients.at(1).begin(), ingredients.at(1).end(), exemplar.begin());
115 products.at(0).push_back(!equal_ingredients);
116 break;
117 }
118
119 :(scenario not_equal)
120 def main [
121 1:num <- copy 34
122 2:num <- copy 33
123 3:bool <- not-equal 1:num, 2:num
124 ]
125 +mem: location 1 is 34
126 +mem: location 2 is 33
127 +mem: storing 1 in location 3
128
129 :(scenario not_equal_2)
130 def main [
131 1:num <- copy 34
132 2:num <- copy 34
133 3:bool <- not-equal 1:num, 2:num
134 ]
135 +mem: location 1 is 34
136 +mem: location 2 is 34
137 +mem: storing 0 in location 3
138
139 :(before "End Primitive Recipe Declarations")
140 GREATER_THAN,
141 :(before "End Primitive Recipe Numbers")
142 put(Recipe_ordinal, "greater-than", GREATER_THAN);
143 :(before "End Primitive Recipe Checks")
144 case GREATER_THAN: {
145 if (SIZE(inst.ingredients) <= 1) {
146 raise << maybe(get(Recipe, r).name) << "'greater-than' needs at least two ingredients to compare in '" << to_original_string(inst) << "'\n" << end();
147 break;
148 }
149 for (int i = 0; i < SIZE(inst.ingredients); ++i) {
150 if (!is_mu_number(inst.ingredients.at(i))) {
151 raise << maybe(get(Recipe, r).name) << "'greater-than' can only compare numbers; got '" << inst.ingredients.at(i).original_string << "'\n" << end();
152 goto finish_checking_instruction;
153 }
154 }
155 if (SIZE(inst.products) > 1) {
156 raise << maybe(get(Recipe, r).name) << "'greater-than' yields exactly one product in '" << to_original_string(inst) << "'\n" << end();
157 break;
158 }
159 if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_boolean(inst.products.at(0))) {
160 raise << maybe(get(Recipe, r).name) << "'greater-than' should yield a boolean, but got '" << inst.products.at(0).original_string << "'\n" << end();
161 break;
162 }
163 break;
164 }
165 :(before "End Primitive Recipe Implementations")
166 case GREATER_THAN: {
167 bool result = true;
168 for (int i = 1; i < SIZE(ingredients); ++i) {
169 if (ingredients.at(i-1).at(0) <= ingredients.at(i).at(0)) {
170 result = false;
171 }
172 }
173 products.resize(1);
174 products.at(0).push_back(result);
175 break;
176 }
177
178 :(scenario greater_than)
179 def main [
180 1:num <- copy 34
181 2:num <- copy 33
182 3:bool <- greater-than 1:num, 2:num
183 ]
184 +mem: storing 1 in location 3
185
186 :(scenario greater_than_2)
187 def main [
188 1:num <- copy 34
189 2:num <- copy 34
190 3:bool <- greater-than 1:num, 2:num
191 ]
192 +mem: storing 0 in location 3
193
194 :(scenario greater_than_multiple)
195 def main [
196 1:bool <- greater-than 36, 35, 34
197 ]
198 +mem: storing 1 in location 1
199
200 :(scenario greater_than_multiple_2)
201 def main [
202 1:bool <- greater-than 36, 35, 35
203 ]
204 +mem: storing 0 in location 1
205
206 :(before "End Primitive Recipe Declarations")
207 LESSER_THAN,
208 :(before "End Primitive Recipe Numbers")
209 put(Recipe_ordinal, "lesser-than", LESSER_THAN);
210 :(before "End Primitive Recipe Checks")
211 case LESSER_THAN: {
212 if (SIZE(inst.ingredients) <= 1) {
213 raise << maybe(get(Recipe, r).name) << "'lesser-than' needs at least two ingredients to compare in '" << to_original_string(inst) << "'\n" << end();
214 break;
215 }
216 for (int i = 0; i < SIZE(inst.ingredients); ++i) {
217 if (!is_mu_number(inst.ingredients.at(i))) {
218 raise << maybe(get(Recipe, r).name) << "'lesser-than' can only compare numbers; got '" << inst.ingredients.at(i).original_string << "'\n" << end();
219 goto finish_checking_instruction;
220 }
221 }
222 if (SIZE(inst.products) > 1) {
223 raise << maybe(get(Recipe, r).name) << "'lesser-than' yields exactly one product in '" << to_original_string(inst) << "'\n" << end();
224 break;
225 }
226 if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_boolean(inst.products.at(0))) {
227 raise << maybe(get(Recipe, r).name) << "'lesser-than' should yield a boolean, but got '" << inst.products.at(0).original_string << "'\n" << end();
228 break;
229 }
230 break;
231 }
232 :(before "End Primitive Recipe Implementations")
233 case LESSER_THAN: {
234 bool result = true;
235 for (int i = 1; i < SIZE(ingredients); ++i) {
236 if (ingredients.at(i-1).at(0) >= ingredients.at(i).at(0)) {
237 result = false;
238 }
239 }
240 products.resize(1);
241 products.at(0).push_back(result);
242 break;
243 }
244
245 :(scenario lesser_than)
246 def main [
247 1:num <- copy 32
248 2:num <- copy 33
249 3:bool <- lesser-than 1:num, 2:num
250 ]
251 +mem: storing 1 in location 3
252
253 :(scenario lesser_than_2)
254 def main [
255 1:num <- copy 34
256 2:num <- copy 33
257 3:bool <- lesser-than 1:num, 2:num
258 ]
259 +mem: storing 0 in location 3
260
261 :(scenario lesser_than_multiple)
262 def main [
263 1:bool <- lesser-than 34, 35, 36
264 ]
265 +mem: storing 1 in location 1
266
267 :(scenario lesser_than_multiple_2)
268 def main [
269 1:bool <- lesser-than 34, 35, 35
270 ]
271 +mem: storing 0 in location 1
272
273 :(before "End Primitive Recipe Declarations")
274 GREATER_OR_EQUAL,
275 :(before "End Primitive Recipe Numbers")
276 put(Recipe_ordinal, "greater-or-equal", GREATER_OR_EQUAL);
277 :(before "End Primitive Recipe Checks")
278 case GREATER_OR_EQUAL: {
279 if (SIZE(inst.ingredients) <= 1) {
280 raise << maybe(get(Recipe, r).name) << "'greater-or-equal' needs at least two ingredients to compare in '" << to_original_string(inst) << "'\n" << end();
281 break;
282 }
283 for (int i = 0; i < SIZE(inst.ingredients); ++i) {
284 if (!is_mu_number(inst.ingredients.at(i))) {
285 raise << maybe(get(Recipe, r).name) << "'greater-or-equal' can only compare numbers; got '" << inst.ingredients.at(i).original_string << "'\n" << end();
286 goto finish_checking_instruction;
287 }
288 }
289 if (SIZE(inst.products) > 1) {
290 raise << maybe(get(Recipe, r).name) << "'greater-or-equal' yields exactly one product in '" << to_original_string(inst) << "'\n" << end();
291 break;
292 }
293 if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_boolean(inst.products.at(0))) {
294 raise << maybe(get(Recipe, r).name) << "'greater-or-equal' should yield a boolean, but got '" << inst.products.at(0).original_string << "'\n" << end();
295 break;
296 }
297 break;
298 }
299 :(before "End Primitive Recipe Implementations")
300 case GREATER_OR_EQUAL: {
301 bool result = true;
302 for (int i = 1; i < SIZE(ingredients); ++i) {
303 if (ingredients.at(i-1).at(0) < ingredients.at(i).at(0)) {
304 result = false;
305 }
306 }
307 products.resize(1);
308 products.at(0).push_back(result);
309 break;
310 }
311
312 :(scenario greater_or_equal)
313 def main [
314 1:num <- copy 34
315 2:num <- copy 33
316 3:bool <- greater-or-equal 1:num, 2:num
317 ]
318 +mem: storing 1 in location 3
319
320 :(scenario greater_or_equal_2)
321 def main [
322 1:num <- copy 34
323 2:num <- copy 34
324 3:bool <- greater-or-equal 1:num, 2:num
325 ]
326 +mem: storing 1 in location 3
327
328 :(scenario greater_or_equal_3)
329 def main [
330 1:num <- copy 34
331 2:num <- copy 35
332 3:bool <- greater-or-equal 1:num, 2:num
333 ]
334 +mem: storing 0 in location 3
335
336 :(scenario greater_or_equal_multiple)
337 def main [
338 1:bool <- greater-or-equal 36, 35, 35
339 ]
340 +mem: storing 1 in location 1
341
342 :(scenario greater_or_equal_multiple_2)
343 def main [
344 1:bool <- greater-or-equal 36, 35, 36
345 ]
346 +mem: storing 0 in location 1
347
348 :(before "End Primitive Recipe Declarations")
349 LESSER_OR_EQUAL,
350 :(before "End Primitive Recipe Numbers")
351 put(Recipe_ordinal, "lesser-or-equal", LESSER_OR_EQUAL);
352 :(before "End Primitive Recipe Checks")
353 case LESSER_OR_EQUAL: {
354 if (SIZE(<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Mu - 027call_ingredient.cc</title>
<meta name="Generator" content="Vim/8.0">
<meta name="plugin-version" content="vim7.4_v2">
<meta name="syntax" content="cpp">
<meta name="settings" content="number_lines,use_css,pre_wrap,no_foldcolumn,expand_tabs,line_ids,prevent_copy=">
<meta name="colorscheme" content="minimal-light">
<style type="text/css">
<!--
pre { white-space: pre-wrap; font-family: monospace; color: #000000; background-color: #c6c6c6; }
body { font-size:12pt; font-family: monospace; color: #000000; background-color: #c6c6c6; }
a { color:inherit; }
* { font-size:12pt; font-size: 1em; }
.cSpecial { color: #008000; }
.LineNr { }
.Constant { color: #008787; }
.muRecipe { color: #ff8700; }
.Delimiter { color: #c000c0; }
.Special { color: #d70000; }
.Identifier { color: #af5f00; }
.Normal { color: #000000; background-color: #c6c6c6; padding-bottom: 1px; }
.Comment { color: #005faf; }
.traceContains { color: #005f00; }
-->
</style>
<script type='text/javascript'>
<!--
/* function to open any folds containing a jumped-to line before jumping to it */
function JumpToLine()
{
var lineNum;
lineNum = window.location.hash;
lineNum = lineNum.substr(1); /* strip off '#' */
if (lineNum.indexOf('L') == -1) {
lineNum = 'L'+lineNum;
}
lineElem = document.getElementById(lineNum);
/* Always jump to new location even if the line was hidden inside a fold, or
* we corrected the raw number to a line ID.
*/
if (lineElem) {
lineElem.scrollIntoView(true);
}
return true;
}
if ('onhashchange' in window) {
window.onhashchange = JumpToLine;
}
-->
</script>
</head>
<body onload='JumpToLine();'>
<a href='https://github.com/akkartik/mu/blob/master/027call_ingredient.cc'>https://github.com/akkartik/mu/blob/master/027call_ingredient.cc</a>
<pre id='vimCodeElement'>
<span id="L1" class="LineNr"> 1 </span><span class="Comment">//: Calls can take ingredients just like primitives. To access a recipe's</span>
<span id="L2" class="LineNr"> 2 </span><span class="Comment">//: ingredients, use 'next-ingredient'.</span>
<span id="L3" class="LineNr"> 3 </span>
<span id="L4" class="LineNr"> 4 </span><span class="Delimiter">:(scenario next_ingredient)</span>
<span id="L5" class="LineNr"> 5 </span><span class="muRecipe">def</span> <a href='000organization.cc.html#L113'>main</a> [
<span id="L6" class="LineNr"> 6 </span> f <span class="Constant">2</span>
<span id="L7" class="LineNr"> 7 </span>]
<span id="L8" class="LineNr"> 8 </span><span class="muRecipe">def</span> f [
<span id="L9" class="LineNr"> 9 </span> <span class="Constant">12</span>:num<span class="Special"> <- </span>next-ingredient
<span id="L10" class="LineNr"> 10 </span> <span class="Constant">13</span>:num<span class="Special"> <- </span>add <span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">12</span>:num
<span id="L11" class="LineNr"> 11 </span>]
<span id="L12" class="LineNr"> 12 </span><span class="traceContains">+mem: storing 3 in location 13</span>
<span id="L13" class="LineNr"> 13 </span>
<span id="L14" class="LineNr"> 14 </span><span class="Delimiter">:(scenario next_ingredient_missing)</span>
<span id="L15" class="LineNr"> 15 </span><span class="muRecipe">def</span> <a href='000organization.cc.html#L113'>main</a> [
<span id="L16" class="LineNr"> 16 </span> f
<span id="L17" class="LineNr"> 17 </span>]
<span id="L18" class="LineNr"> 18 </span><span class="muRecipe">def</span> f [
<span id="L19" class="LineNr"> 19 </span> _<span class="Delimiter">,</span> <span class="Constant">12</span>:num<span class="Special"> <- </span>next-ingredient
<span id="L20" class="LineNr"> 20 </span>]
<span id="L21" class="LineNr"> 21 </span><span class="traceContains">+mem: storing 0 in location 12</span>
<span id="L22" class="LineNr"> 22 </span