about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--011load.cc48
-rw-r--r--038scheduler.cc4
-rw-r--r--060string.mu72
-rw-r--r--081run_interactive.cc3
-rw-r--r--edit.mu29
5 files changed, 139 insertions, 17 deletions
diff --git a/011load.cc b/011load.cc
index 301dfdf2..8afe076f 100644
--- a/011load.cc
+++ b/011load.cc
@@ -63,7 +63,7 @@ recipe slurp_recipe(istream& in) {
   instruction curr;
   while (next_instruction(in, &curr)) {
     // End Rewrite Instruction(curr)
-//?     cerr << "instruction: " << curr.to_string() << '\n'; //? 2
+//?     cerr << "instruction: " << curr.to_string() << '\n'; //? 3
     result.steps.push_back(curr);
   }
   return result;
@@ -72,27 +72,39 @@ recipe slurp_recipe(istream& in) {
 bool next_instruction(istream& in, instruction* curr) {
   in >> std::noskipws;
   curr->clear();
-  if (in.eof()) return false;
+  if (in.eof()) {
+    raise << "0: unbalanced '[' for recipe\n" << end();
+    return false;
+  }
 //?   show_rest_of_stream(in); //? 1
-  skip_whitespace(in);  if (in.eof()) return false;
+  skip_whitespace(in);
+  if (in.eof()) {
+    raise << "1: unbalanced '[' for recipe\n" << end();
+    return false;
+  }
 //?   show_rest_of_stream(in); //? 1
-  skip_whitespace_and_comments(in);  if (in.eof()) return false;
+  skip_whitespace_and_comments(in);
+  if (in.eof()) {
+    raise << "2: unbalanced '[' for recipe\n" << end();
+    return false;
+  }
 
   vector<string> words;
 //?   show_rest_of_stream(in); //? 1
-  while (in.peek() != '\n') {
-    skip_whitespace(in);  if (in.eof()) return false;
+  while (in.peek() != '\n' && !in.eof()) {
+    skip_whitespace(in);
+    if (in.eof()) {
+      raise << "3: unbalanced '[' for recipe\n" << end();
+      return false;
+    }
 //?     show_rest_of_stream(in); //? 1
-    string word = next_word(in);  if (in.eof()) return false;
-//?     cerr << "AAA: " << word << '\n'; //? 1
+    string word = next_word(in);
     words.push_back(word);
-    skip_whitespace(in);  if (in.eof()) return false;
+    skip_whitespace(in);
   }
-  skip_whitespace_and_comments(in);  if (in.eof()) return false;
-
+  skip_whitespace_and_comments(in);
 //?   if (SIZE(words) == 1) cout << words.at(0) << ' ' << SIZE(words.at(0)) << '\n'; //? 1
   if (SIZE(words) == 1 && words.at(0) == "]") {
-//?     cout << "AAA\n"; //? 1
     return false;  // end of recipe
   }
 
@@ -100,7 +112,11 @@ bool next_instruction(istream& in, instruction* curr) {
     curr->is_label = true;
     curr->label = words.at(0);
     trace("parse") << "label: " << curr->label << end();
-    return !in.eof();
+    if (in.eof()) {
+      raise << "7: unbalanced '[' for recipe\n" << end();
+      return false;
+    }
+    return true;
   }
 
   vector<string>::iterator p = words.begin();
@@ -141,7 +157,11 @@ bool next_instruction(istream& in, instruction* curr) {
   for (vector<reagent>::iterator p = curr->products.begin(); p != curr->products.end(); ++p) {
     trace("parse") << "  product: " << p->to_string() << end();
   }
-  return !in.eof();
+  if (in.eof()) {
+    raise << "9: unbalanced '[' for recipe\n" << end();
+    return false;
+  }
+  return true;
 }
 
 string next_word(istream& in) {
diff --git a/038scheduler.cc b/038scheduler.cc
index dc4d56f1..1b68682d 100644
--- a/038scheduler.cc
+++ b/038scheduler.cc
@@ -212,8 +212,8 @@ recipe f2 [
 //: this scenario will require some careful setup in escaped C++
 //: (straining our tangle capabilities to near-breaking point)
 :(scenario scheduler_skips_completed_routines)
-% recipe_ordinal f1 = load("recipe f1 [\n1:number <- copy 0\n]").front();
-% recipe_ordinal f2 = load("recipe f2 [\n2:number <- copy 0\n]").front();
+% recipe_ordinal f1 = load("recipe f1 [\n1:number <- copy 0\n]\n").front();
+% recipe_ordinal f2 = load("recipe f2 [\n2:number <- copy 0\n]\n").front();
 % Routines.push_back(new routine(f1));  // f1 meant to run
 % Routines.push_back(new routine(f2));
 % Routines.back()->state = COMPLETED;  // f2 not meant to run
diff --git a/060string.mu b/060string.mu
index c7c8bf71..df82ee23 100644
--- a/060string.mu
+++ b/060string.mu
@@ -404,6 +404,78 @@ scenario string-append-1 [
   ]
 ]
 
+scenario replace-character-in-string [
+  run [
+    1:address:array:character/raw <- new [abc]
+    1:address:array:character/raw <- string-replace 1:address:array:character/raw, 98/b, 122/z
+    2:array:character/raw <- copy *1:address:array:character/raw
+  ]
+  memory-should-contain [
+    2:string <- [azc]
+  ]
+]
+
+recipe string-replace [
+  local-scope
+  s:address:array:character <- next-ingredient
+  oldc:character <- next-ingredient
+  newc:character <- next-ingredient
+  from:number <- next-ingredient
+  len:number <- length *s
+  i:number <- find-next s, oldc, from
+  done?:boolean <- greater-or-equal i, len
+  reply-if done?, s/same-as-ingredient:0
+  dest:address:character <- index-address *s, i
+  *dest <- copy newc
+  i <- add i, 1
+  s <- string-replace s, oldc, newc, i
+  reply s/same-as-ingredient:0
+]
+
+scenario replace-character-at-start [
+  run [
+    1:address:array:character/raw <- new [abc]
+    1:address:array:character/raw <- string-replace 1:address:array:character/raw, 97/a, 122/z
+    2:array:character/raw <- copy *1:address:array:character/raw
+  ]
+  memory-should-contain [
+    2:string <- [zbc]
+  ]
+]
+
+scenario replace-character-at-end [
+  run [
+    1:address:array:character/raw <- new [abc]
+    1:address:array:character/raw <- string-replace 1:address:array:character/raw, 99/c, 122/z
+    2:array:character/raw <- copy *1:address:array:character/raw
+  ]
+  memory-should-contain [
+    2:string <- [abz]
+  ]
+]
+
+scenario replace-character-missing [
+  run [
+    1:address:array:character/raw <- new [abc]
+    1:address:array:character/raw <- string-replace 1:address:array:character/raw, 100/d, 122/z
+    2:array:character/raw <- copy *1:address:array:character/raw
+  ]
+  memory-should-contain [
+    2:string <- [abc]
+  ]
+]
+
+scenario replace-all-characters [
+  run [
+    1:address:array:character/raw <- new [banana]
+    1:address:array:character/raw <- string-replace 1:address:array:character/raw, 97/a, 122/z
+    2:array:character/raw <- copy *1:address:array:character/raw
+  ]
+  memory-should-contain [
+    2:string <- [bznznz]
+  ]
+]
+
 # replace underscores in first with remaining args
 # result:address:array:character <- interpolate template:address:array:character, ...
 recipe interpolate [
diff --git a/081run_interactive.cc b/081run_interactive.cc
index e290024d..e97e2898 100644
--- a/081run_interactive.cc
+++ b/081run_interactive.cc
@@ -314,7 +314,8 @@ case RELOAD: {
   }
   Hide_warnings = true;
   Disable_redefine_warnings = true;
-  vector<recipe_ordinal> recipes_reloaded = load(read_mu_string(ingredients.at(0).at(0)));
+  string code = read_mu_string(ingredients.at(0).at(0));
+  vector<recipe_ordinal> recipes_reloaded = load(code);
   for (long long int i = 0; i < SIZE(recipes_reloaded); ++i) {
     Name.erase(recipes_reloaded.at(i));
   }
diff --git a/edit.mu b/edit.mu
index eb4ba61f..4d62e7c6 100644
--- a/edit.mu
+++ b/edit.mu
@@ -6068,6 +6068,35 @@ recipe foo [
   ]
 ]
 
+scenario run-shows-unbalanced-bracket-warnings [
+  $close-trace
+  assume-screen 100/width, 15/height
+  # recipe is incomplete (unbalanced '[')
+  1:address:array:character <- new [ 
+recipe foo «
+  x <- copy 0
+]
+  string-replace 1:address:array:character, 171/«, 91  # '['
+  2:address:array:character <- new [foo]
+  3:address:programming-environment-data <- new-programming-environment screen:address, 1:address:array:character, 2:address:array:character
+  assume-console [
+    press 65532  # F4
+  ]
+  run [
+    event-loop screen:address, console:address, 3:address:programming-environment-data
+  ]
+  screen-should-contain [
+    .  errors found                                                                   run (F4)           .
+    .                                                  ┊foo                                              .
+    .recipe foo \\\[                                      ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
+    .  x <- copy 0                                     ┊                                                 .
+    .                                                  ┊                                                 .
+    .9: unbalanced '\\\[' for recipe                      ┊                                                 .
+    .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊                                                 .
+    .                                                  ┊                                                 .
+  ]
+]
+
 scenario run-shows-get-on-non-container-warnings [
   $close-trace
   assume-screen 100/width, 15/height