about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--081run_interactive.cc15
-rw-r--r--edit.mu103
2 files changed, 110 insertions, 8 deletions
diff --git a/081run_interactive.cc b/081run_interactive.cc
index 9ef0f8a9..5e6f3f1a 100644
--- a/081run_interactive.cc
+++ b/081run_interactive.cc
@@ -73,32 +73,31 @@ case RUN_INTERACTIVE: {
 bool run_interactive(long long int address, long long int* result) {
   long long int size = Memory[address];
   if (size == 0) {
-//?     trace(1, "foo") << "AAA\n"; //? 1
+//?     trace(1, "foo") << "AAA"; //? 2
     *result = 0;
     return false;
   }
   ostringstream tmp;
-  for (long long int curr = address+1; curr < address+size; ++curr) {
+  for (long long int curr = address+1; curr <= address+size; ++curr) {
     // todo: unicode
     tmp << (char)(int)Memory[curr];
   }
-  assert(Memory[address+size] == 10);  // skip the newline
   if (Recipe_ordinal.find("interactive") == Recipe_ordinal.end())
     Recipe_ordinal["interactive"] = Next_recipe_ordinal++;
   string command = trim(strip_comments(tmp.str()));
   if (command.empty()) return false;
   if (is_integer(command)) {
-//?     trace(1, "foo") << "BBB\n"; //? 1
+//?     trace(1, "foo") << "BBB"; //? 2
     *result = stringified_value_of_location(to_integer(command));
-//?     trace(1, "foo") << *result << " " << result << " " << Memory[*result]; //? 1
+//?     trace(1, "foo") << *result << " " << result << " " << Memory[*result]; //? 2
     return false;
   }
   if (Name[Recipe_ordinal["interactive"]].find(command) != Name[Recipe_ordinal["interactive"]].end()) {
-//?     trace(1, "foo") << "CCC\n"; //? 1
+//?     trace(1, "foo") << "CCC"; //? 2
     *result = stringified_value_of_location(Name[Recipe_ordinal["interactive"]][command]);
     return false;
   }
-//?   trace(1, "foo") << "DDD\n"; //? 1
+//?   trace(1, "foo") << "DDD"; //? 2
   Recipe.erase(Recipe_ordinal["interactive"]);
   // call run(string) but without the scheduling
   load("recipe interactive [\n"+command+"\n]\n");
@@ -126,7 +125,9 @@ string strip_comments(string in) {
 long long int stringified_value_of_location(long long int address) {
   // convert to string
   ostringstream out;
+//?   trace(1, "foo") << "a: " << address; //? 1
   out << Memory[address];
+//?   trace(1, "foo") << "b: " << Memory[address]; //? 1
   return new_string(out.str());
 }
 
diff --git a/edit.mu b/edit.mu
index 17291090..38c9dc78 100644
--- a/edit.mu
+++ b/edit.mu
@@ -484,13 +484,27 @@ recipe event-loop [
   console:address <- next-ingredient
   editor:address:editor-data <- next-ingredient
   {
-    # send each event to each editor
+    # looping over each (keyboard or touch) event as it occurs
+    +next-event
     e:event, console:address, found?:boolean, quit?:boolean <- read-event console:address
     loop-unless found?:boolean
     break-if quit?:boolean  # only in tests
     trace [app], [next-event]
 #?     $print [--- new event
 #? ] #? 1
+    # check for global events that will trigger regardless of which editor has focus
+    {
+      k:address:number <- maybe-convert e:event, keycode:variant
+      break-unless k:address:number
+      # F9? load all code and run all sandboxes.
+      {
+        do-run?:boolean <- equal k:address:number/deref, 65527:literal/F9
+        break-unless do-run?:boolean
+        run-sandboxes editor:address:editor-data, screen:address
+        loop +next-event:label  # done with this event; no need to send to editors
+      }
+    }
+    # if it's not global, locate the editor the event should go to
     curr:address:editor-data <- copy editor:address:editor-data
     {
       break-unless curr:address:editor-data
@@ -1828,6 +1842,93 @@ scenario editor-provides-edited-contents [
   ]
 ]
 
+## running code in editors
+
+scenario run-query-for-location [
+  assume-screen 10:literal/width, 5:literal/height
+  # left editor is empty
+  1:address:array:character <- new []
+  2:address:editor-data <- new-editor 1:address:array:character, screen:address, 0:literal/top, 0:literal/left, 5:literal/right
+  # right editor contains a query for location 12
+  3:address:array:character <- new [12]
+  4:address:address:editor-data <- get-address 2:address:editor-data/deref, next-editor:offset
+  4:address:address:editor-data/deref <- new-editor 3:address:array:character, screen:address, 0:literal/top, 5:literal/left, 10:literal/right
+  reset-focus 2:address:editor-data
+  # run the code in the editors
+  assume-console [
+    press 65527  # F9
+  ]
+  run [
+    # initialize location 12
+    12:number <- copy 34:literal
+    # now run query for it
+    event-loop screen:address, console:address, 2:address:editor-data
+#?     $dump-trace #? 1
+#?     $browse-trace #? 1
+  ]
+  # check that screen prints the value in location 12
+  screen-should-contain [
+    .     12   .
+    .     34   .
+    .          .
+  ]
+  screen-should-contain-in-color 7:literal/white, [
+    .     12   .
+    .          .
+    .          .
+  ]
+  screen-should-contain-in-color 245:literal/grey, [
+    .          .
+    .     34   .
+    .          .
+  ]
+]
+
+recipe run-sandboxes [
+  default-space:address:array:location <- new location:type, 30:literal
+  editor:address:editor-data <- next-ingredient
+  screen:address <- next-ingredient
+  # todo: load code in left editor
+  # compute result of running editor contents
+  curr:address:editor-data <- get editor:address:editor-data/deref, next-editor:offset
+  in:address:array:character <- editor-contents curr:address:editor-data
+  out:address:array:character <- run-interactive in:address:array:character
+  # move cursor
+  # temporarily leave just one line for typing into sandboxes
+  left:number <- get curr:address:editor-data/deref, left:offset
+  top:number <- get curr:address:editor-data/deref, top:offset
+  dest-row:number <- add top:number, 1:literal
+  move-cursor screen:address, dest-row:number, left:number
+  # print result
+  print-string screen:address, out:address:array:character, 245:literal/grey
+  reply screen:address/same-as-ingredient:1
+]
+
+scenario run-instruction-silently [
+  assume-screen 40:literal/width, 5:literal/height
+  # left editor is empty
+  1:address:array:character <- new []
+  2:address:editor-data <- new-editor 1:address:array:character, screen:address, 0:literal/top, 0:literal/left, 5:literal/right
+  # right editor contains an instruction
+  3:address:array:character <- new [12:number <- copy 34:literal]
+  4:address:address:editor-data <- get-address 2:address:editor-data/deref, next-editor:offset
+  4:address:address:editor-data/deref <- new-editor 3:address:array:character, screen:address, 0:literal/top, 5:literal/left, 40:literal/right
+  reset-focus 2:address:editor-data
+  # run the code in the editors
+  assume-console [
+    press 65527  # F9
+  ]
+  run [
+    # now run query for it
+    event-loop screen:address, console:address, 2:address:editor-data
+  ]
+  # check that screen prints the value in location 12
+  screen-should-contain [
+    .     12:number <- copy 34:literal       .
+    .                                        .
+  ]
+]
+
 ## helpers for drawing editor borders
 
 recipe draw-box [