about summary refs log tree commit diff stats
path: root/087file.cc
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2016-08-21 08:13:44 -0700
committerKartik K. Agaram <vc@akkartik.com>2016-08-21 08:13:44 -0700
commit10bbca643f16daf640caf040a1f86eb93e3d66e2 (patch)
tree33c67c87ab6f06602b9bce3dce6edcd5041f106d /087file.cc
parentff16e04f57347e5a327099a61f8b16d5ba50abf3 (diff)
downloadmu-10bbca643f16daf640caf040a1f86eb93e3d66e2.tar.gz
3238
Clean up primitive for reading from file. Never return EOF character.
Stop using null character to indicate EOF as well. Instead, always use a
second product to indicate EOF, and require calls to use it.
Diffstat (limited to '087file.cc')
-rw-r--r--087file.cc17
1 files changed, 14 insertions, 3 deletions
diff --git a/087file.cc b/087file.cc
index b9a16e94..804fee86 100644
--- a/087file.cc
+++ b/087file.cc
@@ -92,14 +92,18 @@ case _READ_FROM_FILE: {
     raise << maybe(get(Recipe, r).name) << "first ingredient of '$read-from-file' should be a number, but got '" << to_string(inst.ingredients.at(0)) << "'\n" << end();
     break;
   }
-  if (SIZE(inst.products) != 1) {
-    raise << maybe(get(Recipe, r).name) << "'$read-from-file' requires exactly one product, but got '" << inst.original_string << "'\n" << end();
+  if (SIZE(inst.products) != 2) {
+    raise << maybe(get(Recipe, r).name) << "'$read-from-file' requires exactly two products, but got '" << inst.original_string << "'\n" << end();
     break;
   }
   if (!is_mu_character(inst.products.at(0))) {
     raise << maybe(get(Recipe, r).name) << "first product of '$read-from-file' should be a character, but got '" << to_string(inst.products.at(0)) << "'\n" << end();
     break;
   }
+  if (!is_mu_boolean(inst.products.at(1))) {
+    raise << maybe(get(Recipe, r).name) << "second product of '$read-from-file' should be a boolean, but got '" << to_string(inst.products.at(1)) << "'\n" << end();
+    break;
+  }
   break;
 }
 :(before "End Primitive Recipe Implementations")
@@ -110,9 +114,10 @@ case _READ_FROM_FILE: {
     raise << maybe(current_recipe_name()) << "can't read from null file in '" << to_string(current_instruction()) << "'\n" << end();
     break;
   }
-  products.resize(1);
+  products.resize(2);
   if (feof(f)) {
     products.at(0).push_back(0);
+    products.at(1).push_back(1);  // eof
     break;
   }
   if (ferror(f)) {
@@ -120,12 +125,18 @@ case _READ_FROM_FILE: {
     break;
   }
   char c = getc(f);  // todo: unicode
+  if (c == EOF) {
+    products.at(0).push_back(0);
+    products.at(1).push_back(1);  // eof
+    break;
+  }
   if (ferror(f)) {
     raise << maybe(current_recipe_name()) << "couldn't read from file in '" << to_string(current_instruction()) << "'\n" << end();
     raise << "  errno: " << errno << '\n' << end();
     break;
   }
   products.at(0).push_back(c);
+  products.at(1).push_back(0);  // not eof
   break;
 }
 :(before "End Includes")