about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--022arithmetic.cc10
-rw-r--r--025compare.cc94
-rw-r--r--029tools.cc48
-rw-r--r--066stream.mu2
4 files changed, 91 insertions, 63 deletions
diff --git a/022arithmetic.cc b/022arithmetic.cc
index dc06a46a..5dc8bcee 100644
--- a/022arithmetic.cc
+++ b/022arithmetic.cc
@@ -17,7 +17,7 @@ case ADD: {
     raise << Recipe[r].name << ": 'add' yields exactly one product in '" << inst.to_string() << "'\n" << end();
     break;
   }
-  if (!inst.products.empty() && !is_mu_number(inst.products.at(0))) {
+  if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_number(inst.products.at(0))) {
     raise << Recipe[r].name << ": 'add' should yield a number, but got " << inst.products.at(0).original_string << '\n' << end();
     break;
   }
@@ -89,7 +89,7 @@ case SUBTRACT: {
     raise << Recipe[r].name << ": 'subtract' yields exactly one product in '" << inst.to_string() << "'\n" << end();
     break;
   }
-  if (!inst.products.empty() && !is_mu_number(inst.products.at(0))) {
+  if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_number(inst.products.at(0))) {
     raise << Recipe[r].name << ": 'subtract' should yield a number, but got " << inst.products.at(0).original_string << '\n' << end();
     break;
   }
@@ -141,7 +141,7 @@ case MULTIPLY: {
     raise << Recipe[r].name << ": 'multiply' yields exactly one product in '" << inst.to_string() << "'\n" << end();
     break;
   }
-  if (!inst.products.empty() && !is_mu_number(inst.products.at(0))) {
+  if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_number(inst.products.at(0))) {
     raise << Recipe[r].name << ": 'multiply' should yield a number, but got " << inst.products.at(0).original_string << '\n' << end();
     break;
   }
@@ -198,7 +198,7 @@ case DIVIDE: {
     raise << Recipe[r].name << ": 'divide' yields exactly one product in '" << inst.to_string() << "'\n" << end();
     break;
   }
-  if (!inst.products.empty() && !is_mu_number(inst.products.at(0))) {
+  if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_number(inst.products.at(0))) {
     raise << Recipe[r].name << ": 'divide' should yield a number, but got " << inst.products.at(0).original_string << '\n' << end();
     break;
   }
@@ -255,7 +255,7 @@ case DIVIDE_WITH_REMAINDER: {
     break;
   }
   for (long long int i = 0; i < SIZE(inst.products); ++i) {
-    if (!is_mu_number(inst.products.at(i))) {
+    if (!is_dummy(inst.products.at(i)) && !is_mu_number(inst.products.at(i))) {
       raise << Recipe[r].name << ": 'divide-with-remainder' should yield a number, but got " << inst.products.at(i).original_string << '\n' << end();
       goto finish_checking_instruction;
     }
diff --git a/025compare.cc b/025compare.cc
index 619caa03..745111d8 100644
--- a/025compare.cc
+++ b/025compare.cc
@@ -4,12 +4,16 @@
 EQUAL,
 :(before "End Primitive Recipe Numbers")
 Recipe_ordinal["equal"] = EQUAL;
-:(before "End Primitive Recipe Implementations")
+:(before "End Primitive Recipe Checks")
 case EQUAL: {
-  if (SIZE(ingredients) <= 1) {
-    raise << current_recipe_name() << ": 'equal' needs at least two ingredients to compare in '" << current_instruction().to_string() << "'\n" << end();
+  if (SIZE(inst.ingredients) <= 1) {
+    raise << Recipe[r].name << ": 'equal' needs at least two ingredients to compare in '" << inst.to_string() << "'\n" << end();
     break;
   }
+  break;
+}
+:(before "End Primitive Recipe Implementations")
+case EQUAL: {
   vector<double>& exemplar = ingredients.at(0);
   bool result = true;
   for (long long int i = 1; i < SIZE(ingredients); ++i) {
@@ -59,25 +63,28 @@ recipe main [
 GREATER_THAN,
 :(before "End Primitive Recipe Numbers")
 Recipe_ordinal["greater-than"] = GREATER_THAN;
-:(before "End Primitive Recipe Implementations")
+:(before "End Primitive Recipe Checks")
 case GREATER_THAN: {
-  bool result = true;
-  if (SIZE(ingredients) <= 1) {
-    raise << current_recipe_name() << ": 'greater-than' needs at least two ingredients to compare in '" << current_instruction().to_string() << "'\n" << end();
+  if (SIZE(inst.ingredients) <= 1) {
+    raise << Recipe[r].name << ": 'greater-than' needs at least two ingredients to compare in '" << inst.to_string() << "'\n" << end();
     break;
   }
-  for (long long int i = 0; i < SIZE(ingredients); ++i) {
-    if (!scalar(ingredients.at(i))) {
-      raise << current_recipe_name() << ": 'greater-than' can only compare numbers; got " << current_instruction().ingredients.at(i).original_string << '\n' << end();
-      goto finish_greater_than;
+  for (long long int i = 0; i < SIZE(inst.ingredients); ++i) {
+    if (!is_mu_number(inst.ingredients.at(i))) {
+      raise << Recipe[r].name << ": 'greater-than' can only compare numbers; got " << inst.ingredients.at(i).original_string << '\n' << end();
+      goto finish_checking_instruction;
     }
   }
+  break;
+}
+:(before "End Primitive Recipe Implementations")
+case GREATER_THAN: {
+  bool result = true;
   for (long long int i = /**/1; i < SIZE(ingredients); ++i) {
     if (ingredients.at(i-1).at(0) <= ingredients.at(i).at(0)) {
       result = false;
     }
   }
-  finish_greater_than:
   products.resize(1);
   products.at(0).push_back(result);
   break;
@@ -115,25 +122,28 @@ recipe main [
 LESSER_THAN,
 :(before "End Primitive Recipe Numbers")
 Recipe_ordinal["lesser-than"] = LESSER_THAN;
-:(before "End Primitive Recipe Implementations")
+:(before "End Primitive Recipe Checks")
 case LESSER_THAN: {
-  bool result = true;
-  if (SIZE(ingredients) <= 1) {
-    raise << current_recipe_name() << ": 'lesser-than' needs at least two ingredients to compare in '" << current_instruction().to_string() << "'\n" << end();
+  if (SIZE(inst.ingredients) <= 1) {
+    raise << Recipe[r].name << ": 'lesser-than' needs at least two ingredients to compare in '" << inst.to_string() << "'\n" << end();
     break;
   }
-  for (long long int i = 0; i < SIZE(ingredients); ++i) {
-    if (!scalar(ingredients.at(i))) {
-      raise << current_recipe_name() << ": 'lesser-than' can only compare numbers; got " << current_instruction().ingredients.at(i).original_string << '\n' << end();
-      goto finish_lesser_than;
+  for (long long int i = 0; i < SIZE(inst.ingredients); ++i) {
+    if (!is_mu_number(inst.ingredients.at(i))) {
+      raise << Recipe[r].name << ": 'lesser-than' can only compare numbers; got " << inst.ingredients.at(i).original_string << '\n' << end();
+      goto finish_checking_instruction;
     }
   }
+  break;
+}
+:(before "End Primitive Recipe Implementations")
+case LESSER_THAN: {
+  bool result = true;
   for (long long int i = /**/1; i < SIZE(ingredients); ++i) {
     if (ingredients.at(i-1).at(0) >= ingredients.at(i).at(0)) {
       result = false;
     }
   }
-  finish_lesser_than:
   products.resize(1);
   products.at(0).push_back(result);
   break;
@@ -171,25 +181,28 @@ recipe main [
 GREATER_OR_EQUAL,
 :(before "End Primitive Recipe Numbers")
 Recipe_ordinal["greater-or-equal"] = GREATER_OR_EQUAL;
-:(before "End Primitive Recipe Implementations")
+:(before "End Primitive Recipe Checks")
 case GREATER_OR_EQUAL: {
-  bool result = true;
-  if (SIZE(ingredients) <= 1) {
-    raise << current_recipe_name() << ": 'greater-or-equal' needs at least two ingredients to compare in '" << current_instruction().to_string() << "'\n" << end();
+  if (SIZE(inst.ingredients) <= 1) {
+    raise << Recipe[r].name << ": 'greater-or-equal' needs at least two ingredients to compare in '" << inst.to_string() << "'\n" << end();
     break;
   }
-  for (long long int i = 0; i < SIZE(ingredients); ++i) {
-    if (!scalar(ingredients.at(i))) {
-      raise << current_recipe_name() << ": 'greater-or-equal' can only compare numbers; got " << current_instruction().ingredients.at(i).original_string << '\n' << end();
-      goto finish_greater_or_equal;
+  for (long long int i = 0; i < SIZE(inst.ingredients); ++i) {
+    if (!is_mu_number(inst.ingredients.at(i))) {
+      raise << Recipe[r].name << ": 'greater-or-equal' can only compare numbers; got " << inst.ingredients.at(i).original_string << '\n' << end();
+      goto finish_checking_instruction;
     }
   }
+  break;
+}
+:(before "End Primitive Recipe Implementations")
+case GREATER_OR_EQUAL: {
+  bool result = true;
   for (long long int i = /**/1; i < SIZE(ingredients); ++i) {
     if (ingredients.at(i-1).at(0) < ingredients.at(i).at(0)) {
       result = false;
     }
   }
-  finish_greater_or_equal:
   products.resize(1);
   products.at(0).push_back(result);
   break;
@@ -235,25 +248,28 @@ recipe main [
 LESSER_OR_EQUAL,
 :(before "End Primitive Recipe Numbers")
 Recipe_ordinal["lesser-or-equal"] = LESSER_OR_EQUAL;
-:(before "End Primitive Recipe Implementations")
+:(before "End Primitive Recipe Checks")
 case LESSER_OR_EQUAL: {
-  bool result = true;
-  if (SIZE(ingredients) <= 1) {
-    raise << current_recipe_name() << ": 'lesser-or-equal' needs at least two ingredients to compare in '" << current_instruction().to_string() << "'\n" << end();
+  if (SIZE(inst.ingredients) <= 1) {
+    raise << Recipe[r].name << ": 'lesser-or-equal' needs at least two ingredients to compare in '" << inst.to_string() << "'\n" << end();
     break;
   }
-  for (long long int i = 0; i < SIZE(ingredients); ++i) {
-    if (!scalar(ingredients.at(i))) {
-      raise << current_recipe_name() << ": 'lesser-or-equal' can only compare numbers; got " << current_instruction().ingredients.at(i).original_string << '\n' << end();
-      goto finish_lesser_or_equal;
+  for (long long int i = 0; i < SIZE(inst.ingredients); ++i) {
+    if (!is_mu_number(inst.ingredients.at(i))) {
+      raise << Recipe[r].name << ": 'lesser-or-equal' can only compare numbers; got " << inst.ingredients.at(i).original_string << '\n' << end();
+      goto finish_checking_instruction;
     }
   }
+  break;
+}
+:(before "End Primitive Recipe Implementations")
+case LESSER_OR_EQUAL: {
+  bool result = true;
   for (long long int i = /**/1; i < SIZE(ingredients); ++i) {
     if (ingredients.at(i-1).at(0) > ingredients.at(i).at(0)) {
       result = false;
     }
   }
-  finish_lesser_or_equal:
   products.resize(1);
   products.at(0).push_back(result);
   break;
diff --git a/029tools.cc b/029tools.cc
index 0011c6e0..e09b9d7a 100644
--- a/029tools.cc
+++ b/029tools.cc
@@ -10,21 +10,25 @@ recipe main [
 TRACE,
 :(before "End Primitive Recipe Numbers")
 Recipe_ordinal["trace"] = TRACE;
-:(before "End Primitive Recipe Implementations")
+:(before "End Primitive Recipe Checks")
 case TRACE: {
-  if (SIZE(current_instruction().ingredients) < 3) {
-    raise << current_recipe_name() << ": 'trace' takes three or more ingredients rather than '" << current_instruction().to_string() << "'\n" << end();
+  if (SIZE(inst.ingredients) < 3) {
+    raise << Recipe[r].name << ": 'trace' takes three or more ingredients rather than '" << inst.to_string() << "'\n" << end();
     break;
   }
-  if (!scalar(ingredients.at(0))) {
-    raise << current_recipe_name() << ": first ingredient of 'trace' should be a number (depth), but got " << current_instruction().ingredients.at(0).original_string << '\n' << end();
+  if (!is_mu_number(inst.ingredients.at(0))) {
+    raise << Recipe[r].name << ": first ingredient of 'trace' should be a number (depth), but got " << inst.ingredients.at(0).original_string << '\n' << end();
     break;
   }
-  long long int depth = ingredients.at(0).at(0);
-  if (!is_literal_string(current_instruction().ingredients.at(1))) {
-    raise << current_recipe_name() << ": second ingredient of 'trace' should be a literal string (label), but got " << current_instruction().ingredients.at(1).original_string << '\n' << end();
+  if (!is_literal_string(inst.ingredients.at(1))) {
+    raise << Recipe[r].name << ": second ingredient of 'trace' should be a literal string (label), but got " << inst.ingredients.at(1).original_string << '\n' << end();
     break;
   }
+  break;
+}
+:(before "End Primitive Recipe Implementations")
+case TRACE: {
+  long long int depth = ingredients.at(0).at(0);
   string label = current_instruction().ingredients.at(1).name;
   ostringstream out;
   for (long long int i = 2; i < SIZE(current_instruction().ingredients); ++i) {
@@ -175,20 +179,24 @@ recipe main [
 ASSERT,
 :(before "End Primitive Recipe Numbers")
 Recipe_ordinal["assert"] = ASSERT;
-:(before "End Primitive Recipe Implementations")
+:(before "End Primitive Recipe Checks")
 case ASSERT: {
-  if (SIZE(ingredients) != 2) {
-    raise << current_recipe_name() << ": 'assert' takes exactly two ingredients rather than '" << current_instruction().to_string() << "'\n" << end();
+  if (SIZE(inst.ingredients) != 2) {
+    raise << Recipe[r].name << ": 'assert' takes exactly two ingredients rather than '" << inst.to_string() << "'\n" << end();
     break;
   }
-  if (!scalar(ingredients.at(0))) {
-    raise << current_recipe_name() << ": 'assert' requires a boolean for its first ingredient, but got " << current_instruction().ingredients.at(0).original_string << '\n' << end();
+  if (!is_mu_scalar(inst.ingredients.at(0))) {
+    raise << Recipe[r].name << ": 'assert' requires a boolean for its first ingredient, but got " << inst.ingredients.at(0).original_string << '\n' << end();
     break;
   }
-  if (!scalar(ingredients.at(1))) {
-    raise << current_recipe_name() << ": 'assert' requires a literal string for its second ingredient, but got " << current_instruction().ingredients.at(1).original_string << '\n' << end();
+  if (!is_literal_string(inst.ingredients.at(1))) {
+    raise << Recipe[r].name << ": 'assert' requires a literal string for its second ingredient, but got " << inst.ingredients.at(1).original_string << '\n' << end();
     break;
   }
+  break;
+}
+:(before "End Primitive Recipe Implementations")
+case ASSERT: {
   if (!ingredients.at(0).at(0)) {
     raise << current_instruction().ingredients.at(1).name << '\n' << end();
   }
@@ -236,12 +244,16 @@ case _EXIT: {
 _SYSTEM,
 :(before "End Primitive Recipe Numbers")
 Recipe_ordinal["$system"] = _SYSTEM;
-:(before "End Primitive Recipe Implementations")
+:(before "End Primitive Recipe Checks")
 case _SYSTEM: {
-  if (current_instruction().ingredients.empty()) {
-    raise << current_recipe_name() << ": '$system' requires exactly one ingredient, but got none\n" << end();
+  if (inst.ingredients.empty()) {
+    raise << Recipe[r].name << ": '$system' requires exactly one ingredient, but got none\n" << end();
     break;
   }
+  break;
+}
+:(before "End Primitive Recipe Implementations")
+case _SYSTEM: {
   int status = system(current_instruction().ingredients.at(0).name.c_str());
   products.resize(1);
   products.at(0).push_back(status);
diff --git a/066stream.mu b/066stream.mu
index 606d77e7..0ee3e2c1 100644
--- a/066stream.mu
+++ b/066stream.mu
@@ -36,7 +36,7 @@ recipe read-line [
 recipe end-of-stream? [
   local-scope
   in:address:stream <- next-ingredient
-  idx:address:number <- get *in, index:offset
+  idx:number <- get *in, index:offset
   s:address:array:character <- get *in, data:offset
   len:number <- length *s
   result:boolean <- greater-or-equal idx, len