about summary refs log tree commit diff stats
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
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.
-rw-r--r--087file.cc17
-rw-r--r--088file.mu4
-rw-r--r--filesystem.mu2
3 files changed, 16 insertions, 7 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")
diff --git a/088file.mu b/088file.mu
index b18919d0..651f9e8a 100644
--- a/088file.mu
+++ b/088file.mu
@@ -45,8 +45,8 @@ def transmit-from-file file:number, sink:address:sink:character -> sink:address:
   local-scope
   load-ingredients
   {
-    c:character <- $read-from-file file
-    break-unless c
+    c:character, eof?:boolean <- $read-from-file file
+    break-if eof?
     sink <- write sink, c
     loop
   }
diff --git a/filesystem.mu b/filesystem.mu
index 3e6c45f7..c6374b90 100644
--- a/filesystem.mu
+++ b/filesystem.mu
@@ -10,8 +10,6 @@ def main [
   {
     c:character, done?:boolean, source-file <- read source-file
     break-if done?
-    eof?:boolean <- equal c, -1
-    break-if eof?
     sink-file <- write sink-file, c
     loop
   }