about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-09-10 12:02:17 -0700
committerKartik K. Agaram <vc@akkartik.com>2015-09-10 12:02:17 -0700
commita17ffca8c1487008ec417d3d75309f541df7268e (patch)
tree0136b9476a2974f5e4d82a57860fa40384ffdc5e
parentf5465e1220d73e237c51897b7d1211ec53b0dc04 (diff)
downloadmu-a17ffca8c1487008ec417d3d75309f541df7268e.tar.gz
2178 - don't die on divide by 0
-rw-r--r--021arithmetic.cc31
1 files changed, 25 insertions, 6 deletions
diff --git a/021arithmetic.cc b/021arithmetic.cc
index 81cbb544..107f0853 100644
--- a/021arithmetic.cc
+++ b/021arithmetic.cc
@@ -51,7 +51,7 @@ case SUBTRACT: {
   }
   if (!scalar(ingredients.at(0))) {
     raise << current_recipe_name() << ": 'subtract' requires number ingredients, but got " << current_instruction().ingredients.at(0).original_string << '\n' << end();
-    goto finish_instruction;
+    break;
   }
   double result = ingredients.at(0).at(0);
   for (long long int i = 1; i < SIZE(ingredients); ++i) {
@@ -137,7 +137,7 @@ case DIVIDE: {
   }
   if (!scalar(ingredients.at(0))) {
     raise << current_recipe_name() << ": 'divide' requires number ingredients, but got " << current_instruction().ingredients.at(0).original_string << '\n' << end();
-    goto finish_instruction;
+    break;
   }
   double result = ingredients.at(0).at(0);
   for (long long int i = 1; i < SIZE(ingredients); ++i) {
@@ -187,10 +187,16 @@ case DIVIDE_WITH_REMAINDER: {
   }
   if (!scalar(ingredients.at(0)) || !scalar(ingredients.at(1))) {
     raise << current_recipe_name() << ": 'divide-with-remainder' requires number ingredients, but got '" << current_instruction().to_string() << "'\n" << end();
-    goto finish_instruction;
+    break;
   }
-  long long int quotient = ingredients.at(0).at(0) / ingredients.at(1).at(0);
-  long long int remainder = static_cast<long long int>(ingredients.at(0).at(0)) % static_cast<long long int>(ingredients.at(1).at(0));
+  long long int a = static_cast<long long int>(ingredients.at(0).at(0));
+  long long int b = static_cast<long long int>(ingredients.at(1).at(0));
+  if (b == 0) {
+    raise << current_recipe_name() << ": divide by zero in '" << current_instruction().to_string() << "'\n" << end();
+    break;
+  }
+  long long int quotient = a / b;
+  long long int remainder = a % b;
   // very large integers will lose precision
   products.at(0).push_back(quotient);
   products.at(1).push_back(remainder);
@@ -215,11 +221,24 @@ recipe main [
 
 :(scenario divide_with_decimal_point)
 recipe main [
-  # todo: literal floats?
   1:number <- divide 5, 2
 ]
 +mem: storing 2.5 in location 1
 
+:(scenario divide_by_zero)
+recipe main [
+  1:number <- divide 4, 0
+]
++mem: storing inf in location 1
+
+:(scenario divide_by_zero_2)
+% Hide_warnings = true;
+recipe main [
+  1:number <- divide-with-remainder 4, 0
+]
+# integer division can't return floating-point infinity
++warn: main: divide by zero in '1:number <- divide-with-remainder 4, 0'
+
 :(code)
 inline bool scalar(const vector<long long int>& x) {
   return SIZE(x) == 1;