From 204dae921abff0c70e017215bb3c91fa6ca11aff Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Mon, 26 Dec 2016 11:44:14 -0800 Subject: 3710 Turns out we don't need to explicitly add anchors for each line. Vim's TOhtml has magic for that out of the box. --- html/edit/011-errors.mu.html | 1484 +++++++++++++++++++++--------------------- 1 file changed, 742 insertions(+), 742 deletions(-) (limited to 'html/edit/011-errors.mu.html') diff --git a/html/edit/011-errors.mu.html b/html/edit/011-errors.mu.html index 9d9cc026..73ca5b93 100644 --- a/html/edit/011-errors.mu.html +++ b/html/edit/011-errors.mu.html @@ -57,748 +57,748 @@ if ('onhashchange' in window) {
-  1 ## handling malformed programs
-  2 
-  3 container environment [
-  4   recipe-errors:text
-  5 ]
-  6 
-  7 # copy code from recipe editor, persist to disk, load, save any errors
-  8 def! update-recipes env:&:environment, resources:&:resources, screen:&:screen -> errors-found?:bool, env:&:environment, resources:&:resources, screen:&:screen [
-  9   local-scope
- 10   load-ingredients
- 11   recipes:&:editor <- get *env, recipes:offset
- 12   in:text <- editor-contents recipes
- 13   resources <- dump resources, [lesson/recipes.mu], in
- 14   recipe-errors:text <- reload in
- 15   *env <- put *env, recipe-errors:offset, recipe-errors
- 16   # if recipe editor has errors, stop
- 17   {
- 18     break-unless recipe-errors
- 19     update-status screen, [errors found     ], 1/red
- 20     errors-found? <- copy 1/true
- 21     return
- 22   }
- 23   errors-found? <- copy 0/false
- 24 ]
- 25 
- 26 before <render-components-end> [
- 27   trace 11, [app], [render status]
- 28   recipe-errors:text <- get *env, recipe-errors:offset
- 29   {
- 30     break-unless recipe-errors
- 31     update-status screen, [errors found     ], 1/red
- 32   }
- 33 ]
- 34 
- 35 before <render-recipe-components-end> [
- 36   {
- 37     recipe-errors:text <- get *env, recipe-errors:offset
- 38     break-unless recipe-errors
- 39     row, screen <- render-text screen, recipe-errors, left, right, 1/red, row
- 40   }
- 41 ]
- 42 
- 43 container environment [
- 44   error-index:num  # index of first sandbox with an error (or -1 if none)
- 45 ]
- 46 
- 47 after <programming-environment-initialization> [
- 48   *result <- put *result, error-index:offset, -1
- 49 ]
- 50 
- 51 after <run-sandboxes-begin> [
- 52   *env <- put *env, error-index:offset, -1
- 53 ]
- 54 
- 55 before <run-sandboxes-end> [
- 56   {
- 57     error-index:num <- get *env, error-index:offset
- 58     sandboxes-completed-successfully?:bool <- equal error-index, -1
- 59     break-if sandboxes-completed-successfully?
- 60     errors-found? <- copy 1/true
- 61   }
- 62 ]
- 63 
- 64 before <render-components-end> [
- 65   {
- 66     break-if recipe-errors
- 67     error-index:num <- get *env, error-index:offset
- 68     sandboxes-completed-successfully?:bool <- equal error-index, -1
- 69     break-if sandboxes-completed-successfully?
- 70     error-index-text:text <- to-text error-index
- 71     status:text <- interpolate [errors found (_)    ], error-index-text
- 72     update-status screen, status, 1/red
- 73   }
- 74 ]
- 75 
- 76 container sandbox [
- 77   errors:text
- 78 ]
- 79 
- 80 def! update-sandbox sandbox:&:sandbox, env:&:environment, idx:num -> sandbox:&:sandbox, env:&:environment [
- 81   local-scope
- 82   load-ingredients
- 83   data:text <- get *sandbox, data:offset
- 84   response:text, errors:text, fake-screen:&:screen, trace:text, completed?:bool <- run-sandboxed data
- 85   *sandbox <- put *sandbox, response:offset, response
- 86   *sandbox <- put *sandbox, errors:offset, errors
- 87   *sandbox <- put *sandbox, screen:offset, fake-screen
- 88   *sandbox <- put *sandbox, trace:offset, trace
- 89   {
- 90     break-if errors
- 91     break-if completed?:bool
- 92     errors <- new [took too long!
- 93 ]
- 94     *sandbox <- put *sandbox, errors:offset, errors
- 95   }
- 96   {
- 97     break-unless errors
- 98     error-index:num <- get *env, error-index:offset
- 99     error-not-set?:bool <- equal error-index, -1
-100     break-unless error-not-set?
-101     *env <- put *env, error-index:offset, idx
-102   }
-103 ]
-104 
-105 # make sure we render any trace
-106 after <render-sandbox-trace-done> [
-107   {
-108     sandbox-errors:text <- get *sandbox, errors:offset
-109     break-unless sandbox-errors
-110     *sandbox <- put *sandbox, response-starting-row-on-screen:offset, 0  # no response
-111     row, screen <- render-text screen, sandbox-errors, left, right, 1/red, row
-112     # don't try to print anything more for this sandbox
-113     jump +render-sandbox-end
-114   }
-115 ]
-116 
-117 scenario run-shows-errors-in-get [
-118   local-scope
-119   trace-until 100/app  # trace too long
-120   assume-screen 100/width, 15/height
-121   assume-resources [
-122     [lesson/recipes.mu] <- [
-123       |recipe foo [|
-124       |  get 123:num, foo:offset|
-125       |]|
-126     ]
-127   ]
-128   env:&:environment <- new-programming-environment resources, screen, [foo]
-129   render-all screen, env, render
-130   screen-should-contain [
-131     .                                                                                 run (F4)           .
-132     .recipe foo [                                      ╎foo                                              .
-133     .  get 123:num, foo:offset                         ╎─────────────────────────────────────────────────.
-134     .]                                                 ╎                                                 .
-135     .                                                  ╎                                                 .
-136     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎                                                 .
-137     .                                                  ╎                                                 .
-138   ]
-139   assume-console [
-140     press F4
-141   ]
-142   run [
-143     event-loop screen, console, env, resources
-144   ]
-145   screen-should-contain [
-146     .  errors found                                                                   run (F4)           .
-147     .recipe foo [                                      ╎foo                                              .
-148     .  get 123:num, foo:offset                         ╎─────────────────────────────────────────────────.
-149     .]                                                 ╎                                                 .
-150     .                                                  ╎                                                 .
-151     .foo: unknown element 'foo' in container 'number'  ╎                                                 .
-152     .foo: first ingredient of 'get' should be a contai↩╎                                                 .
-153     .ner, but got '123:num'                            ╎                                                 .
-154     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎                                                 .
-155     .                                                  ╎                                                 .
-156   ]
-157   screen-should-contain-in-color 1/red, [
-158     .  errors found                                                                                      .
-159     .                                                                                                    .
-160     .                                                                                                    .
-161     .                                                                                                    .
-162     .                                                                                                    .
-163     .foo: unknown element 'foo' in container 'number'                                                    .
-164     .foo: first ingredient of 'get' should be a contai                                                   .
-165     .ner, but got '123:num'                                                                              .
-166     .                                                                                                    .
-167   ]
-168 ]
-169 
-170 scenario run-updates-status-with-first-erroneous-sandbox [
-171   local-scope
-172   trace-until 100/app  # trace too long
-173   assume-screen 100/width, 15/height
-174   assume-resources [
-175   ]
-176   env:&:environment <- new-programming-environment resources, screen, []
-177   assume-console [
-178     left-click 3, 80
-179     # create invalid sandbox 1
-180     type [get foo, x:offset]
-181     press F4
-182     # create invalid sandbox 0
-183     type [get foo, x:offset]
-184     press F4
-185   ]
-186   run [
-187     event-loop screen, console, env, resources
-188   ]
-189   # status line shows that error is in first sandbox
-190   screen-should-contain [
-191     .  errors found (0)                                                               run (F4)           .
-192   ]
-193 ]
-194 
-195 scenario run-updates-status-with-first-erroneous-sandbox-2 [
-196   local-scope
-197   trace-until 100/app  # trace too long
-198   assume-screen 100/width, 15/height
-199   assume-resources [
-200   ]
-201   env:&:environment <- new-programming-environment resources, screen, []
-202   assume-console [
-203     left-click 3, 80
-204     # create invalid sandbox 2
-205     type [get foo, x:offset]
-206     press F4
-207     # create invalid sandbox 1
-208     type [get foo, x:offset]
-209     press F4
-210     # create valid sandbox 0
-211     type [add 2, 2]
-212     press F4
-213   ]
-214   run [
-215     event-loop screen, console, env, resources
-216   ]
-217   # status line shows that error is in second sandbox
-218   screen-should-contain [
-219     .  errors found (1)                                                               run (F4)           .
-220   ]
-221 ]
-222 
-223 scenario run-hides-errors-from-past-sandboxes [
-224   local-scope
-225   trace-until 100/app  # trace too long
-226   assume-screen 100/width, 15/height
-227   assume-resources [
-228   ]
-229   env:&:environment <- new-programming-environment resources, screen, [get foo, x:offset]  # invalid
-230   assume-console [
-231     press F4  # generate error
-232   ]
-233   event-loop screen, console, env, resources
-234   assume-console [
-235     left-click 3, 58
-236     press ctrl-k
-237     type [add 2, 2]  # valid code
-238     press F4  # update sandbox
-239   ]
-240   run [
-241     event-loop screen, console, env, resources
-242   ]
-243   # error should disappear
-244   screen-should-contain [
-245     .                                                                                 run (F4)           .
-246     .                                                  ╎                                                 .
-247     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────.
-248     .                                                  ╎0   edit          copy            delete         .
-249     .                                                  ╎add 2, 2                                         .
-250     .                                                  ╎4                                                .
-251     .                                                  ╎─────────────────────────────────────────────────.
-252     .                                                  ╎                                                 .
-253   ]
-254 ]
-255 
-256 scenario run-updates-errors-for-shape-shifting-recipes [
-257   local-scope
-258   trace-until 100/app  # trace too long
-259   assume-screen 100/width, 15/height
-260   # define a shape-shifting recipe with an error
-261   assume-resources [
-262     [lesson/recipes.mu] <- [
-263       |recipe foo x:_elem -> z:_elem [|
-264       |  local-scope|
-265       |  load-ingredients|
-266       |  y:&:num <- copy 0|
-267       |  z <- add x, y|
-268       |]|
-269     ]
-270   ]
-271   env:&:environment <- new-programming-environment resources, screen, [foo 2]
-272   assume-console [
-273     press F4
-274   ]
-275   event-loop screen, console, env, resources
-276   screen-should-contain [
-277     .  errors found (0)                                                               run (F4)           .
-278     .recipe foo x:_elem -> z:_elem [                   ╎                                                 .
-279     .  local-scope                                     ╎─────────────────────────────────────────────────.
-280     .  load-ingredients                                ╎0   edit          copy            delete         .
-281     .  y:&:num <- copy 0                               ╎foo 2                                            .
-282     .  z <- add x, y                                   ╎foo_2: 'add' requires number ingredients, but go↩.
-283     .]                                                 ╎t 'y'                                            .
-284     .                                                  ╎─────────────────────────────────────────────────.
-285     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎                                                 .
-286     .                                                  ╎                                                 .
-287   ]
-288   # now rerun everything
-289   assume-console [
-290     press F4
-291   ]
-292   run [
-293     event-loop screen, console, env, resources
-294   ]
-295   # error should remain unchanged
-296   screen-should-contain [
-297     .  errors found (0)                                                               run (F4)           .
-298     .recipe foo x:_elem -> z:_elem [                   ╎                                                 .
-299     .  local-scope                                     ╎─────────────────────────────────────────────────.
-300     .  load-ingredients                                ╎0   edit          copy            delete         .
-301     .  y:&:num <- copy 0                               ╎foo 2                                            .
-302     .  z <- add x, y                                   ╎foo_3: 'add' requires number ingredients, but go↩.
-303     .]                                                 ╎t 'y'                                            .
-304     .                                                  ╎─────────────────────────────────────────────────.
-305     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎                                                 .
-306     .                                                  ╎                                                 .
-307   ]
-308 ]
-309 
-310 scenario run-avoids-spurious-errors-on-reloading-shape-shifting-recipes [
-311   local-scope
-312   trace-until 100/app  # trace too long
-313   assume-screen 100/width, 15/height
-314   # overload a well-known shape-shifting recipe
-315   assume-resources [
-316     [lesson/recipes.mu] <- [
-317       |recipe length l:&:list:_elem -> n:num [|
-318       |]|
-319     ]
-320   ]
-321   # call code that uses other variants of it, but not it itself
-322   test-sandbox:text <- new [x:&:list:num <- copy 0
-323 to-text x]
-324   env:&:environment <- new-programming-environment resources, screen, test-sandbox
-325   # run it once
-326   assume-console [
-327     press F4
-328   ]
-329   event-loop screen, console, env, resources
-330   # no errors anywhere on screen (can't check anything else, since to-text will return an address)
-331   screen-should-contain-in-color 1/red, [
-332     .                                                                                                    .
-333     .                                                                                                    .
-334     .                                                                                                    .
-335     .                                                                                                    .
-336     .                                                                <-                                  .
-337     .                                                                                                    .
-338     .                                                                                                    .
-339     .                                                                                                    .
-340     .                                                                                                    .
-341     .                                                                                                    .
-342     .                                                                                                    .
-343     .                                                                                                    .
-344     .                                                                                                    .
-345     .                                                                                                    .
-346     .                                                                                                    .
-347   ]
-348   # rerun everything
-349   assume-console [
-350     press F4
-351   ]
-352   run [
-353     event-loop screen, console, env, resources
-354   ]
-355   # still no errors
-356   screen-should-contain-in-color 1/red, [
-357     .                                                                                                    .
-358     .                                                                                                    .
-359     .                                                                                                    .
-360     .                                                                                                    .
-361     .                                                                <-                                  .
-362     .                                                                                                    .
-363     .                                                                                                    .
-364     .                                                                                                    .
-365     .                                                                                                    .
-366     .                                                                                                    .
-367     .                                                                                                    .
-368     .                                                                                                    .
-369     .                                                                                                    .
-370     .                                                                                                    .
-371     .                                                                                                    .
-372   ]
-373 ]
-374 
-375 scenario run-shows-missing-type-errors [
-376   local-scope
-377   trace-until 100/app  # trace too long
-378   assume-screen 100/width, 15/height
-379   assume-resources [
-380     [lesson/recipes.mu] <- [
-381       |recipe foo [|
-382       |  x <- copy 0|
-383       |]|
-384     ]
-385   ]
-386   env:&:environment <- new-programming-environment resources, screen, [foo]
-387   assume-console [
-388     press F4
-389   ]
-390   run [
-391     event-loop screen, console, env, resources
-392   ]
-393   screen-should-contain [
-394     .  errors found                                                                   run (F4)           .
-395     .recipe foo [                                      ╎foo                                              .
-396     .  x <- copy 0                                     ╎─────────────────────────────────────────────────.
-397     .]                                                 ╎                                                 .
-398     .                                                  ╎                                                 .
-399     .foo: missing type for 'x' in 'x <- copy 0'        ╎                                                 .
-400     .foo: can't copy '0' to 'x'; types don't match     ╎                                                 .
-401     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎                                                 .
-402     .                                                  ╎                                                 .
-403   ]
-404 ]
-405 
-406 scenario run-shows-unbalanced-bracket-errors [
-407   local-scope
-408   trace-until 100/app  # trace too long
-409   assume-screen 100/width, 15/height
-410   # recipe is incomplete (unbalanced '[')
-411   assume-resources [
-412     [lesson/recipes.mu] <- [
-413       |recipe foo \\\[|
-414       |  x <- copy 0|
-415     ]
-416   ]
-417   env:&:environment <- new-programming-environment resources, screen, [foo]
-418   assume-console [
-419     press F4
-420   ]
-421   run [
-422     event-loop screen, console, env, resources
-423   ]
-424   screen-should-contain [
-425     .  errors found                                                                   run (F4)           .
-426     .recipe foo \\[                                      ╎foo                                              .
-427     .  x <- copy 0                                     ╎─────────────────────────────────────────────────.
-428     .                                                  ╎                                                 .
-429     .9: unbalanced '\\[' for recipe                      ╎                                                 .
-430     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎                                                 .
-431     .                                                  ╎                                                 .
-432   ]
-433 ]
-434 
-435 scenario run-shows-get-on-non-container-errors [
-436   local-scope
-437   trace-until 100/app  # trace too long
-438   assume-screen 100/width, 15/height
-439   assume-resources [
-440     [lesson/recipes.mu] <- [
-441       |recipe foo [|
-442       |  local-scope|
-443       |  x:&:point <- new point:type|
-444       |  get x:&:point, 1:offset|
-445       |]|
-446     ]
-447   ]
-448   env:&:environment <- new-programming-environment resources, screen, [foo]
-449   assume-console [
-450     press F4
-451   ]
-452   run [
-453     event-loop screen, console, env, resources
-454   ]
-455   screen-should-contain [
-456     .  errors found                                                                   run (F4)           .
-457     .recipe foo [                                      ╎foo                                              .
-458     .  local-scope                                     ╎─────────────────────────────────────────────────.
-459     .  x:&:point <- new point:type                     ╎                                                 .
-460     .  get x:&:point, 1:offset                         ╎                                                 .
-461     .]                                                 ╎                                                 .
-462     .                                                  ╎                                                 .
-463     .foo: first ingredient of 'get' should be a contai↩╎                                                 .
-464     .ner, but got 'x:&:point'                          ╎                                                 .
-465     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎                                                 .
-466     .                                                  ╎                                                 .
-467   ]
-468 ]
-469 
-470 scenario run-shows-non-literal-get-argument-errors [
-471   local-scope
-472   trace-until 100/app  # trace too long
-473   assume-screen 100/width, 15/height
-474   assume-resources [
-475     [lesson/recipes.mu] <- [
-476       |recipe foo [|
-477       |  local-scope|
-478       |  x:num <- copy 0|
-479       |  y:&:point <- new point:type|
-480       |  get *y:&:point, x:num|
-481       |]|
-482     ]
-483   ]
-484   env:&:environment <- new-programming-environment resources, screen, [foo]
-485   assume-console [
-486     press F4
-487   ]
-488   run [
-489     event-loop screen, console, env, resources
-490   ]
-491   screen-should-contain [
-492     .  errors found                                                                   run (F4)           .
-493     .recipe foo [                                      ╎foo                                              .
-494     .  local-scope                                     ╎─────────────────────────────────────────────────.
-495     .  x:num <- copy 0                                 ╎                                                 .
-496     .  y:&:point <- new point:type                     ╎                                                 .
-497     .  get *y:&:point, x:num                           ╎                                                 .
-498     .]                                                 ╎                                                 .
-499     .                                                  ╎                                                 .
-500     .foo: second ingredient of 'get' should have type ↩╎                                                 .
-501     .'offset', but got 'x:num'                         ╎                                                 .
-502     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎                                                 .
-503     .                                                  ╎                                                 .
-504   ]
-505 ]
-506 
-507 scenario run-shows-errors-everytime [
-508   local-scope
-509   trace-until 100/app  # trace too long
-510   assume-screen 100/width, 15/height
-511   # try to run a file with an error
-512   assume-resources [
-513     [lesson/recipes.mu] <- [
-514       |recipe foo [|
-515       |  local-scope|
-516       |  x:num <- copy y:num|
-517       |]|
-518     ]
-519   ]
-520   env:&:environment <- new-programming-environment resources, screen, [foo]
-521   assume-console [
-522     press F4
-523   ]
-524   event-loop screen, console, env, resources
-525   screen-should-contain [
-526     .  errors found                                                                   run (F4)           .
-527     .recipe foo [                                      ╎foo                                              .
-528     .  local-scope                                     ╎─────────────────────────────────────────────────.
-529     .  x:num <- copy y:num                             ╎                                                 .
-530     .]                                                 ╎                                                 .
-531     .                                                  ╎                                                 .
-532     .foo: tried to read ingredient 'y' in 'x:num <- co↩╎                                                 .
-533     .py y:num' but it hasn't been written to yet       ╎                                                 .
-534     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎                                                 .
-535     .                                                  ╎                                                 .
-536   ]
-537   # rerun the file, check for the same error
-538   assume-console [
-539     press F4
-540   ]
-541   run [
-542     event-loop screen, console, env, resources
-543   ]
-544   screen-should-contain [
-545     .  errors found                                                                   run (F4)           .
-546     .recipe foo [                                      ╎foo                                              .
-547     .  local-scope                                     ╎─────────────────────────────────────────────────.
-548     .  x:num <- copy y:num                             ╎                                                 .
-549     .]                                                 ╎                                                 .
-550     .                                                  ╎                                                 .
-551     .foo: tried to read ingredient 'y' in 'x:num <- co↩╎                                                 .
-552     .py y:num' but it hasn't been written to yet       ╎                                                 .
-553     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎                                                 .
-554     .                                                  ╎                                                 .
-555   ]
-556 ]
-557 
-558 scenario run-instruction-and-print-errors [
-559   local-scope
-560   trace-until 100/app  # trace too long
-561   assume-screen 100/width, 10/height
-562   assume-resources [
-563   ]
-564   # sandbox editor contains an illegal instruction
-565   env:&:environment <- new-programming-environment resources, screen, [get 1234:num, foo:offset]
-566   assume-console [
-567     press F4
-568   ]
-569   run [
-570     event-loop screen, console, env, resources
-571   ]
-572   # check that screen prints error message in red
-573   screen-should-contain [
-574     .  errors found (0)                                                               run (F4)           .
-575     .                                                  ╎                                                 .
-576     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────.
-577     .                                                  ╎0   edit          copy            delete         .
-578     .                                                  ╎get 1234:num, foo:offset                         .
-579     .                                                  ╎unknown element 'foo' in container 'number'      .
-580     .                                                  ╎first ingredient of 'get' should be a container,↩.
-581     .                                                  ╎ but got '1234:num'                              .
-582     .                                                  ╎─────────────────────────────────────────────────.
-583     .                                                  ╎                                                 .
-584   ]
-585   screen-should-contain-in-color 7/white, [
-586     .                                                                                                    .
-587     .                                                                                                    .
-588     .                                                                                                    .
-589     .                                                                                                    .
-590     .                                                   get 1234:num, foo:offset                         .
-591     .                                                                                                    .
-592     .                                                                                                    .
-593     .                                                                                                    .
-594   ]
-595   screen-should-contain-in-color 1/red, [
-596     .  errors found (0)                                                                                  .
-597     .                                                                                                    .
-598     .                                                                                                    .
-599     .                                                                                                    .
-600     .                                                                                                    .
-601     .                                                   unknown element 'foo' in container 'number'      .
-602     .                                                   first ingredient of 'get' should be a container, .
-603     .                                                    but got '1234:num'                              .
-604     .                                                                                                    .
-605   ]
-606   screen-should-contain-in-color 245/grey, [
-607     .                                                                                                    .
-608     .                                                  ╎                                                 .
-609     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────.
-610     .                                                  ╎                                                 .
-611     .                                                  ╎                                                 .
-612     .                                                  ╎                                                 .
-613     .                                                  ╎                                                ↩.
-614     .                                                  ╎                                                 .
-615     .                                                  ╎─────────────────────────────────────────────────.
-616     .                                                  ╎                                                 .
-617   ]
-618 ]
-619 
-620 scenario run-instruction-and-print-errors-only-once [
-621   local-scope
-622   trace-until 100/app  # trace too long
-623   assume-screen 100/width, 10/height
-624   assume-resources [
-625   ]
-626   # sandbox editor contains an illegal instruction
-627   env:&:environment <- new-programming-environment resources, screen, [get 1234:num, foo:offset]
-628   # run the code in the editors multiple times
-629   assume-console [
-630     press F4
-631     press F4
-632   ]
-633   run [
-634     event-loop screen, console, env, resources
-635   ]
-636   # check that screen prints error message just once
-637   screen-should-contain [
-638     .  errors found (0)                                                               run (F4)           .
-639     .                                                  ╎                                                 .
-640     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────.
-641     .                                                  ╎0   edit          copy            delete         .
-642     .                                                  ╎get 1234:num, foo:offset                         .
-643     .                                                  ╎unknown element 'foo' in container 'number'      .
-644     .                                                  ╎first ingredient of 'get' should be a container,↩.
-645     .                                                  ╎ but got '1234:num'                              .
-646     .                                                  ╎─────────────────────────────────────────────────.
-647     .                                                  ╎                                                 .
-648   ]
-649 ]
-650 
-651 scenario sandbox-can-handle-infinite-loop [
-652   local-scope
-653   trace-until 100/app  # trace too long
-654   assume-screen 100/width, 20/height
-655   # sandbox editor will trigger an infinite loop
-656   assume-resources [
-657     [lesson/recipes.mu] <- [
-658       |recipe foo [|
-659       |  {|
-660       |    loop|
-661       |  }|
-662       |]|
-663     ]
-664   ]
-665   env:&:environment <- new-programming-environment resources, screen, [foo]
-666   # run the sandbox
-667   assume-console [
-668     press F4
-669   ]
-670   run [
-671     event-loop screen, console, env, resources
-672   ]
-673   screen-should-contain [
-674     .  errors found (0)                                                               run (F4)           .
-675     .recipe foo [                                      ╎                                                 .
-676     .  {                                               ╎─────────────────────────────────────────────────.
-677     .    loop                                          ╎0   edit          copy            delete         .
-678     .  }                                               ╎foo                                              .
-679     .]                                                 ╎took too long!                                   .
-680     .                                                  ╎─────────────────────────────────────────────────.
-681     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎                                                 .
-682     .                                                  ╎                                                 .
-683   ]
-684 ]
-685 
-686 scenario sandbox-with-errors-shows-trace [
-687   local-scope
-688   trace-until 100/app  # trace too long
-689   assume-screen 100/width, 10/height
-690   # generate a stash and a error
-691   assume-resources [
-692     [lesson/recipes.mu] <- [
-693       |recipe foo [|
-694       |  local-scope|
-695       |  a:num <- next-ingredient|
-696       |  b:num <- next-ingredient|
-697       |  stash [dividing by], b|
-698       |  _, c:num <- divide-with-remainder a, b|
-699       |  reply b|
-700       |]|
-701     ]
-702   ]
-703   env:&:environment <- new-programming-environment resources, screen, [foo 4, 0]
-704   # run
-705   assume-console [
-706     press F4
-707   ]
-708   event-loop screen, console, env, resources
-709   # screen prints error message
-710   screen-should-contain [
-711     .  errors found (0)                                                               run (F4)           .
-712     .recipe foo [                                      ╎                                                 .
-713     .  local-scope                                     ╎─────────────────────────────────────────────────.
-714     .  a:num <- next-ingredient                        ╎0   edit          copy            delete         .
-715     .  b:num <- next-ingredient                        ╎foo 4, 0                                         .
-716     .  stash [dividing by], b                          ╎foo: divide by zero in '_, c:num <- divide-with-↩.
-717     .  _, c:num <- divide-with-remainder a, b          ╎remainder a, b'                                  .
-718     .  reply b                                         ╎─────────────────────────────────────────────────.
-719     .]                                                 ╎                                                 .
-720     .                                                  ╎                                                 .
-721   ]
-722   # click on the call in the sandbox
-723   assume-console [
-724     left-click 4, 55
-725   ]
-726   run [
-727     event-loop screen, console, env, resources
-728   ]
-729   # screen should expand trace
-730   screen-should-contain [
-731     .  errors found (0)                                                               run (F4)           .
-732     .recipe foo [                                      ╎                                                 .
-733     .  local-scope                                     ╎─────────────────────────────────────────────────.
-734     .  a:num <- next-ingredient                        ╎0   edit          copy            delete         .
-735     .  b:num <- next-ingredient                        ╎foo 4, 0                                         .
-736     .  stash [dividing by], b                          ╎dividing by 0                                    .
-737     .  _, c:num <- divide-with-remainder a, b          ╎14 instructions run                              .
-738     .  reply b                                         ╎foo: divide by zero in '_, c:num <- divide-with-↩.
-739     .]                                                 ╎remainder a, b'                                  .
-740     .                                                  ╎─────────────────────────────────────────────────.
-741   ]
-742 ]
+  1 ## handling malformed programs
+  2 
+  3 container environment [
+  4   recipe-errors:text
+  5 ]
+  6 
+  7 # copy code from recipe editor, persist to disk, load, save any errors
+  8 def! update-recipes env:&:environment, resources:&:resources, screen:&:screen -> errors-found?:bool, env:&:environment, resources:&:resources, screen:&:screen [
+  9   local-scope
+ 10   load-ingredients
+ 11   recipes:&:editor <- get *env, recipes:offset
+ 12   in:text <- editor-contents recipes
+ 13   resources <- dump resources, [lesson/recipes.mu], in
+ 14   recipe-errors:text <- reload in
+ 15   *env <- put *env, recipe-errors:offset, recipe-errors
+ 16   # if recipe editor has errors, stop
+ 17   {
+ 18     break-unless recipe-errors
+ 19     update-status screen, [errors found     ], 1/red
+ 20     errors-found? <- copy 1/true
+ 21     return
+ 22   }
+ 23   errors-found? <- copy 0/false
+ 24 ]
+ 25 
+ 26 before <render-components-end> [
+ 27   trace 11, [app], [render status]
+ 28   recipe-errors:text <- get *env, recipe-errors:offset
+ 29   {
+ 30     break-unless recipe-errors
+ 31     update-status screen, [errors found     ], 1/red
+ 32   }
+ 33 ]
+ 34 
+ 35 before <render-recipe-components-end> [
+ 36   {
+ 37     recipe-errors:text <- get *env, recipe-errors:offset
+ 38     break-unless recipe-errors
+ 39     row, screen <- render-text screen, recipe-errors, left, right, 1/red, row
+ 40   }
+ 41 ]
+ 42 
+ 43 container environment [
+ 44   error-index:num  # index of first sandbox with an error (or -1 if none)
+ 45 ]
+ 46 
+ 47 after <programming-environment-initialization> [
+ 48   *result <- put *result, error-index:offset, -1
+ 49 ]
+ 50 
+ 51 after <run-sandboxes-begin> [
+ 52   *env <- put *env, error-index:offset, -1
+ 53 ]
+ 54 
+ 55 before <run-sandboxes-end> [
+ 56   {
+ 57     error-index:num <- get *env, error-index:offset
+ 58     sandboxes-completed-successfully?:bool <- equal error-index, -1
+ 59     break-if sandboxes-completed-successfully?
+ 60     errors-found? <- copy 1/true
+ 61   }
+ 62 ]
+ 63 
+ 64 before <render-components-end> [
+ 65   {
+ 66     break-if recipe-errors
+ 67     error-index:num <- get *env, error-index:offset
+ 68     sandboxes-completed-successfully?:bool <- equal error-index, -1
+ 69     break-if sandboxes-completed-successfully?
+ 70     error-index-text:text <- to-text error-index
+ 71     status:text <- interpolate [errors found (_)    ], error-index-text
+ 72     update-status screen, status, 1/red
+ 73   }
+ 74 ]
+ 75 
+ 76 container sandbox [
+ 77   errors:text
+ 78 ]
+ 79 
+ 80 def! update-sandbox sandbox:&:sandbox, env:&:environment, idx:num -> sandbox:&:sandbox, env:&:environment [
+ 81   local-scope
+ 82   load-ingredients
+ 83   data:text <- get *sandbox, data:offset
+ 84   response:text, errors:text, fake-screen:&:screen, trace:text, completed?:bool <- run-sandboxed data
+ 85   *sandbox <- put *sandbox, response:offset, response
+ 86   *sandbox <- put *sandbox, errors:offset, errors
+ 87   *sandbox <- put *sandbox, screen:offset, fake-screen
+ 88   *sandbox <- put *sandbox, trace:offset, trace
+ 89   {
+ 90     break-if errors
+ 91     break-if completed?:bool
+ 92     errors <- new [took too long!
+ 93 ]
+ 94     *sandbox <- put *sandbox, errors:offset, errors
+ 95   }
+ 96   {
+ 97     break-unless errors
+ 98     error-index:num <- get *env, error-index:offset
+ 99     error-not-set?:bool <- equal error-index, -1
+100     break-unless error-not-set?
+101     *env <- put *env, error-index:offset, idx
+102   }
+103 ]
+104 
+105 # make sure we render any trace
+106 after <render-sandbox-trace-done> [
+107   {
+108     sandbox-errors:text <- get *sandbox, errors:offset
+109     break-unless sandbox-errors
+110     *sandbox <- put *sandbox, response-starting-row-on-screen:offset, 0  # no response
+111     row, screen <- render-text screen, sandbox-errors, left, right, 1/red, row
+112     # don't try to print anything more for this sandbox
+113     jump +render-sandbox-end
+114   }
+115 ]
+116 
+117 scenario run-shows-errors-in-get [
+118   local-scope
+119   trace-until 100/app  # trace too long
+120   assume-screen 100/width, 15/height
+121   assume-resources [
+122     [lesson/recipes.mu] <- [
+123       |recipe foo [|
+124       |  get 123:num, foo:offset|
+125       |]|
+126     ]
+127   ]
+128   env:&:environment <- new-programming-environment resources, screen, [foo]
+129   render-all screen, env, render
+130   screen-should-contain [
+131     .                                                                                 run (F4)           .
+132     .recipe foo [                                      ╎foo                                              .
+133     .  get 123:num, foo:offset                         ╎─────────────────────────────────────────────────.
+134     .]                                                 ╎                                                 .
+135     .                                                  ╎                                                 .
+136     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎                                                 .
+137     .                                                  ╎                                                 .
+138   ]
+139   assume-console [
+140     press F4
+141   ]
+142   run [
+143     event-loop screen, console, env, resources
+144   ]
+145   screen-should-contain [
+146     .  errors found                                                                   run (F4)           .
+147     .recipe foo [                                      ╎foo                                              .
+148     .  get 123:num, foo:offset                         ╎─────────────────────────────────────────────────.
+149     .]                                                 ╎                                                 .
+150     .                                                  ╎                                                 .
+151     .foo: unknown element 'foo' in container 'number'  ╎                                                 .
+152     .foo: first ingredient of 'get' should be a contai↩╎                                                 .
+153     .ner, but got '123:num'                            ╎                                                 .
+154     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎                                                 .
+155     .                                                  ╎                                                 .
+156   ]
+157   screen-should-contain-in-color 1/red, [
+158     .  errors found                                                                                      .
+159     .                                                                                                    .
+160     .                                                                                                    .
+161     .                                                                                                    .
+162     .                                                                                                    .
+163     .foo: unknown element 'foo' in container 'number'                                                    .
+164     .foo: first ingredient of 'get' should be a contai                                                   .
+165     .ner, but got '123:num'                                                                              .
+166     .                                                                                                    .
+167   ]
+168 ]
+169 
+170 scenario run-updates-status-with-first-erroneous-sandbox [
+171   local-scope
+172   trace-until 100/app  # trace too long
+173   assume-screen 100/width, 15/height
+174   assume-resources [
+175   ]
+176   env:&:environment <- new-programming-environment resources, screen, []
+177   assume-console [
+178     left-click 3, 80
+179     # create invalid sandbox 1
+180     type [get foo, x:offset]
+181     press F4
+182     # create invalid sandbox 0
+183     type [get foo, x:offset]
+184     press F4
+185   ]
+186   run [
+187     event-loop screen, console, env, resources
+188   ]
+189   # status line shows that error is in first sandbox
+190   screen-should-contain [
+191     .  errors found (0)                                                               run (F4)           .
+192   ]
+193 ]
+194 
+195 scenario run-updates-status-with-first-erroneous-sandbox-2 [
+196   local-scope
+197   trace-until 100/app  # trace too long
+198   assume-screen 100/width, 15/height
+199   assume-resources [
+200   ]
+201   env:&:environment <- new-programming-environment resources, screen, []
+202   assume-console [
+203     left-click 3, 80
+204     # create invalid sandbox 2
+205     type [get foo, x:offset]
+206     press F4
+207     # create invalid sandbox 1
+208     type [get foo, x:offset]
+209     press F4
+210     # create valid sandbox 0
+211     type [add 2, 2]
+212     press F4
+213   ]
+214   run [
+215     event-loop screen, console, env, resources
+216   ]
+217   # status line shows that error is in second sandbox
+218   screen-should-contain [
+219     .  errors found (1)                                                               run (F4)           .
+220   ]
+221 ]
+222 
+223 scenario run-hides-errors-from-past-sandboxes [
+224   local-scope
+225   trace-until 100/app  # trace too long
+226   assume-screen 100/width, 15/height
+227   assume-resources [
+228   ]
+229   env:&:environment <- new-programming-environment resources, screen, [get foo, x:offset]  # invalid
+230   assume-console [
+231     press F4  # generate error
+232   ]
+233   event-loop screen, console, env, resources
+234   assume-console [
+235     left-click 3, 58
+236     press ctrl-k
+237     type [add 2, 2]  # valid code
+238     press F4  # update sandbox
+239   ]
+240   run [
+241     event-loop screen, console, env, resources
+242   ]
+243   # error should disappear
+244   screen-should-contain [
+245     .                                                                                 run (F4)           .
+246     .                                                  ╎                                                 .
+247     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────.
+248     .                                                  ╎0   edit          copy            delete         .
+249     .                                                  ╎add 2, 2                                         .
+250     .                                                  ╎4                                                .
+251     .                                                  ╎─────────────────────────────────────────────────.
+252     .                                                  ╎                                                 .
+253   ]
+254 ]
+255 
+256 scenario run-updates-errors-for-shape-shifting-recipes [
+257   local-scope
+258   trace-until 100/app  # trace too long
+259   assume-screen 100/width, 15/height
+260   # define a shape-shifting recipe with an error
+261   assume-resources [
+262     [lesson/recipes.mu] <- [
+263       |recipe foo x:_elem -> z:_elem [|
+264       |  local-scope|
+265       |  load-ingredients|
+266       |  y:&:num <- copy 0|
+267       |  z <- add x, y|
+268       |]|
+269     ]
+270   ]
+271   env:&:environment <- new-programming-environment resources, screen, [foo 2]
+272   assume-console [
+273     press F4
+274   ]
+275   event-loop screen, console, env, resources
+276   screen-should-contain [
+277     .  errors found (0)                                                               run (F4)           .
+278     .recipe foo x:_elem -> z:_elem [                   ╎                                                 .
+279     .  local-scope                                     ╎─────────────────────────────────────────────────.
+280     .  load-ingredients                                ╎0   edit          copy            delete         .
+281     .  y:&:num <- copy 0                               ╎foo 2                                            .
+282     .  z <- add x, y                                   ╎foo_2: 'add' requires number ingredients, but go↩.
+283     .]                                                 ╎t 'y'                                            .
+284     .                                                  ╎─────────────────────────────────────────────────.
+285     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎                                                 .
+286     .                                                  ╎                                                 .
+287   ]
+288   # now rerun everything
+289   assume-console [
+290     press F4
+291   ]
+292   run [
+293     event-loop screen, console, env, resources
+294   ]
+295   # error should remain unchanged
+296   screen-should-contain [
+297     .  errors found (0)                                                               run (F4)           .
+298     .recipe foo x:_elem -> z:_elem [                   ╎                                                 .
+299     .  local-scope                                     ╎─────────────────────────────────────────────────.
+300     .  load-ingredients                                ╎0   edit          copy            delete         .
+301     .  y:&:num <- copy 0                               ╎foo 2                                            .
+302     .  z <- add x, y                                   ╎foo_3: 'add' requires number ingredients, but go↩.
+303     .]                                                 ╎t 'y'                                            .
+304     .                                                  ╎─────────────────────────────────────────────────.
+305     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎                                                 .
+306     .                                                  ╎                                                 .
+307   ]
+308 ]
+309 
+310 scenario run-avoids-spurious-errors-on-reloading-shape-shifting-recipes [
+311   local-scope
+312   trace-until 100/app  # trace too long
+313   assume-screen 100/width, 15/height
+314   # overload a well-known shape-shifting recipe
+315   assume-resources [
+316     [lesson/recipes.mu] <- [
+317       |recipe length l:&:list:_elem -> n:num [|
+318       |]|
+319     ]
+320   ]
+321   # call code that uses other variants of it, but not it itself
+322   test-sandbox:text <- new [x:&:list:num <- copy 0
+323 to-text x]
+324   env:&:environment <- new-programming-environment resources, screen, test-sandbox
+325   # run it once
+326   assume-console [
+327     press F4
+328   ]
+329   event-loop screen, console, env, resources
+330   # no errors anywhere on screen (can't check anything else, since to-text will return an address)
+331   screen-should-contain-in-color 1/red, [
+332     .                                                                                                    .
+333     .                                                                                                    .
+334     .                                                                                                    .
+335     .                                                                                                    .
+336     .                                                                <-                                  .
+337     .                                                                                                    .
+338     .                                                                                                    .
+339     .                                                                                                    .
+340     .                                                                                                    .
+341     .                                                                                                    .
+342     .                                                                                                    .
+343     .                                                                                                    .
+344     .                                                                                                    .
+345     .                                                                                                    .
+346     .                                                                                                    .
+347   ]
+348   # rerun everything
+349   assume-console [
+350     press F4
+351   ]
+352   run [
+353     event-loop screen, console, env, resources
+354   ]
+355   # still no errors
+356   screen-should-contain-in-color 1/red, [
+357     .                                                                                                    .
+358     .                                                                                                    .
+359     .                                                                                                    .
+360     .                                                                                                    .
+361     .                                                                <-                                  .
+362     .                                                                                                    .
+363     .                                                                                                    .
+364     .                                                                                                    .
+365     .                                                                                                    .
+366     .                                                                                                    .
+367     .                                                                                                    .
+368     .                                                                                                    .
+369     .                                                                                                    .
+370     .                                                                                                    .
+371     .                                                                                                    .
+372   ]
+373 ]
+374 
+375 scenario run-shows-missing-type-errors [
+376   local-scope
+377   trace-until 100/app  # trace too long
+378   assume-screen 100/width, 15/height
+379   assume-resources [
+380     [lesson/recipes.mu] <- [
+381       |recipe foo [|
+382       |  x <- copy 0|
+383       |]|
+384     ]
+385   ]
+386   env:&:environment <- new-programming-environment resources, screen, [foo]
+387   assume-console [
+388     press F4
+389   ]
+390   run [
+391     event-loop screen, console, env, resources
+392   ]
+393   screen-should-contain [
+394     .  errors found                                                                   run (F4)           .
+395     .recipe foo [                                      ╎foo                                              .
+396     .  x <- copy 0                                     ╎─────────────────────────────────────────────────.
+397     .]                                                 ╎                                                 .
+398     .                                                  ╎                                                 .
+399     .foo: missing type for 'x' in 'x <- copy 0'        ╎                                                 .
+400     .foo: can't copy '0' to 'x'; types don't match     ╎                                                 .
+401     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎                                                 .
+402     .                                                  ╎                                                 .
+403   ]
+404 ]
+405 
+406 scenario run-shows-unbalanced-bracket-errors [
+407   local-scope
+408   trace-until 100/app  # trace too long
+409   assume-screen 100/width, 15/height
+410   # recipe is incomplete (unbalanced '[')
+411   assume-resources [
+412     [lesson/recipes.mu] <- [
+413       |recipe foo \\\[|
+414       |  x <- copy 0|
+415     ]
+416   ]
+417   env:&:environment <- new-programming-environment resources, screen, [foo]
+418   assume-console [
+419     press F4
+420   ]
+421   run [
+422     event-loop screen, console, env, resources
+423   ]
+424   screen-should-contain [
+425     .  errors found                                                                   run (F4)           .
+426     .recipe foo \\[                                      ╎foo                                              .
+427     .  x <- copy 0                                     ╎─────────────────────────────────────────────────.
+428     .                                                  ╎                                                 .
+429     .9: unbalanced '\\[' for recipe                      ╎                                                 .
+430     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎                                                 .
+431     .                                                  ╎                                                 .
+432   ]
+433 ]
+434 
+435 scenario run-shows-get-on-non-container-errors [
+436   local-scope
+437   trace-until 100/app  # trace too long
+438   assume-screen 100/width, 15/height
+439   assume-resources [
+440     [lesson/recipes.mu] <- [
+441       |recipe foo [|
+442       |  local-scope|
+443       |  x:&:point <- new point:type|
+444       |  get x:&:point, 1:offset|
+445       |]|
+446     ]
+447   ]
+448   env:&:environment <- new-programming-environment resources, screen, [foo]
+449   assume-console [
+450     press F4
+451   ]
+452   run [
+453     event-loop screen, console, env, resources
+454   ]
+455   screen-should-contain [
+456     .  errors found                                                                   run (F4)           .
+457     .recipe foo [                                      ╎foo                                              .
+458     .  local-scope                                     ╎─────────────────────────────────────────────────.
+459     .  x:&:point <- new point:type                     ╎                                                 .
+460     .  get x:&:point, 1:offset                         ╎                                                 .
+461     .]                                                 ╎                                                 .
+462     .                                                  ╎                                                 .
+463     .foo: first ingredient of 'get' should be a contai↩╎                                                 .
+464     .ner, but got 'x:&:point'                          ╎                                                 .
+465     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎                                                 .
+466     .                                                  ╎                                                 .
+467   ]
+468 ]
+469 
+470 scenario run-shows-non-literal-get-argument-errors [
+471   local-scope
+472   trace-until 100/app  # trace too long
+473   assume-screen 100/width, 15/height
+474   assume-resources [
+475     [lesson/recipes.mu] <- [
+476       |recipe foo [|
+477       |  local-scope|
+478       |  x:num <- copy 0|
+479       |  y:&:point <- new point:type|
+480       |  get *y:&:point, x:num|
+481       |]|
+482     ]
+483   ]
+484   env:&:environment <- new-programming-environment resources, screen, [foo]
+485   assume-console [
+486     press F4
+487   ]
+488   run [
+489     event-loop screen, console, env, resources
+490   ]
+491   screen-should-contain [
+492     .  errors found                                                                   run (F4)           .
+493     .recipe foo [                                      ╎foo                                              .
+494     .  local-scope                                     ╎─────────────────────────────────────────────────.
+495     .  x:num <- copy 0                                 ╎                                                 .
+496     .  y:&:point <- new point:type                     ╎                                                 .
+497     .  get *y:&:point, x:num                           ╎                                                 .
+498     .]                                                 ╎                                                 .
+499     .                                                  ╎                                                 .
+500     .foo: second ingredient of 'get' should have type ↩╎                                                 .
+501     .'offset', but got 'x:num'                         ╎                                                 .
+502     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎                                                 .
+503     .                                                  ╎                                                 .
+504   ]
+505 ]
+506 
+507 scenario run-shows-errors-everytime [
+508   local-scope
+509   trace-until 100/app  # trace too long
+510   assume-screen 100/width, 15/height
+511   # try to run a file with an error
+512   assume-resources [
+513     [lesson/recipes.mu] <- [
+514       |recipe foo [|
+515       |  local-scope|
+516       |  x:num <- copy y:num|
+517       |]|
+518     ]
+519   ]
+520   env:&:environment <- new-programming-environment resources, screen, [foo]
+521   assume-console [
+522     press F4
+523   ]
+524   event-loop screen, console, env, resources
+525   screen-should-contain [
+526     .  errors found                                                                   run (F4)           .
+527     .recipe foo [                                      ╎foo                                              .
+528     .  local-scope                                     ╎─────────────────────────────────────────────────.
+529     .  x:num <- copy y:num                             ╎                                                 .
+530     .]                                                 ╎                                                 .
+531     .                                                  ╎                                                 .
+532     .foo: tried to read ingredient 'y' in 'x:num <- co↩╎                                                 .
+533     .py y:num' but it hasn't been written to yet       ╎                                                 .
+534     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎                                                 .
+535     .                                                  ╎                                                 .
+536   ]
+537   # rerun the file, check for the same error
+538   assume-console [
+539     press F4
+540   ]
+541   run [
+542     event-loop screen, console, env, resources
+543   ]
+544   screen-should-contain [
+545     .  errors found                                                                   run (F4)           .
+546     .recipe foo [                                      ╎foo                                              .
+547     .  local-scope                                     ╎─────────────────────────────────────────────────.
+548     .  x:num <- copy y:num                             ╎                                                 .
+549     .]                                                 ╎                                                 .
+550     .                                                  ╎                                                 .
+551     .foo: tried to read ingredient 'y' in 'x:num <- co↩╎                                                 .
+552     .py y:num' but it hasn't been written to yet       ╎                                                 .
+553     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎                                                 .
+554     .                                                  ╎                                                 .
+555   ]
+556 ]
+557 
+558 scenario run-instruction-and-print-errors [
+559   local-scope
+560   trace-until 100/app  # trace too long
+561   assume-screen 100/width, 10/height
+562   assume-resources [
+563   ]
+564   # sandbox editor contains an illegal instruction
+565   env:&:environment <- new-programming-environment resources, screen, [get 1234:num, foo:offset]
+566   assume-console [
+567     press F4
+568   ]
+569   run [
+570     event-loop screen, console, env, resources
+571   ]
+572   # check that screen prints error message in red
+573   screen-should-contain [
+574     .  errors found (0)                                                               run (F4)           .
+575     .                                                  ╎                                                 .
+576     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────.
+577     .                                                  ╎0   edit          copy            delete         .
+578     .                                                  ╎get 1234:num, foo:offset                         .
+579     .                                                  ╎unknown element 'foo' in container 'number'      .
+580     .                                                  ╎first ingredient of 'get' should be a container,↩.
+581     .                                                  ╎ but got '1234:num'                              .
+582     .                                                  ╎─────────────────────────────────────────────────.
+583     .                                                  ╎                                                 .
+584   ]
+585   screen-should-contain-in-color 7/white, [
+586     .                                                                                                    .
+587     .                                                                                                    .
+588     .                                                                                                    .
+589     .                                                                                                    .
+590     .                                                   get 1234:num, foo:offset                         .
+591     .                                                                                                    .
+592     .                                                                                                    .
+593     .                                                                                                    .
+594   ]
+595   screen-should-contain-in-color 1/red, [
+596     .  errors found (0)                                                                                  .
+597     .                                                                                                    .
+598     .                                                                                                    .
+599     .                                                                                                    .
+600     .                                                                                                    .
+601     .                                                   unknown element 'foo' in container 'number'      .
+602     .                                                   first ingredient of 'get' should be a container, .
+603     .                                                    but got '1234:num'                              .
+604     .                                                                                                    .
+605   ]
+606   screen-should-contain-in-color 245/grey, [
+607     .                                                                                                    .
+608     .                                                  ╎                                                 .
+609     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────.
+610     .                                                  ╎                                                 .
+611     .                                                  ╎                                                 .
+612     .                                                  ╎                                                 .
+613     .                                                  ╎                                                ↩.
+614     .                                                  ╎                                                 .
+615     .                                                  ╎─────────────────────────────────────────────────.
+616     .                                                  ╎                                                 .
+617   ]
+618 ]
+619 
+620 scenario run-instruction-and-print-errors-only-once [
+621   local-scope
+622   trace-until 100/app  # trace too long
+623   assume-screen 100/width, 10/height
+624   assume-resources [
+625   ]
+626   # sandbox editor contains an illegal instruction
+627   env:&:environment <- new-programming-environment resources, screen, [get 1234:num, foo:offset]
+628   # run the code in the editors multiple times
+629   assume-console [
+630     press F4
+631     press F4
+632   ]
+633   run [
+634     event-loop screen, console, env, resources
+635   ]
+636   # check that screen prints error message just once
+637   screen-should-contain [
+638     .  errors found (0)                                                               run (F4)           .
+639     .                                                  ╎                                                 .
+640     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎─────────────────────────────────────────────────.
+641     .                                                  ╎0   edit          copy            delete         .
+642     .                                                  ╎get 1234:num, foo:offset                         .
+643     .                                                  ╎unknown element 'foo' in container 'number'      .
+644     .                                                  ╎first ingredient of 'get' should be a container,↩.
+645     .                                                  ╎ but got '1234:num'                              .
+646     .                                                  ╎─────────────────────────────────────────────────.
+647     .                                                  ╎                                                 .
+648   ]
+649 ]
+650 
+651 scenario sandbox-can-handle-infinite-loop [
+652   local-scope
+653   trace-until 100/app  # trace too long
+654   assume-screen 100/width, 20/height
+655   # sandbox editor will trigger an infinite loop
+656   assume-resources [
+657     [lesson/recipes.mu] <- [
+658       |recipe foo [|
+659       |  {|
+660       |    loop|
+661       |  }|
+662       |]|
+663     ]
+664   ]
+665   env:&:environment <- new-programming-environment resources, screen, [foo]
+666   # run the sandbox
+667   assume-console [
+668     press F4
+669   ]
+670   run [
+671     event-loop screen, console, env, resources
+672   ]
+673   screen-should-contain [
+674     .  errors found (0)                                                               run (F4)           .
+675     .recipe foo [                                      ╎                                                 .
+676     .  {                                               ╎─────────────────────────────────────────────────.
+677     .    loop                                          ╎0   edit          copy            delete         .
+678     .  }                                               ╎foo                                              .
+679     .]                                                 ╎took too long!                                   .
+680     .                                                  ╎─────────────────────────────────────────────────.
+681     .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎                                                 .
+682     .                                                  ╎                                                 .
+683   ]
+684 ]
+685 
+686 scenario sandbox-with-errors-shows-trace [
+687   local-scope
+688   trace-until 100/app  # trace too long
+689   assume-screen 100/width, 10/height
+690   # generate a stash and a error
+691   assume-resources [
+692     [lesson/recipes.mu] <- [
+693       |recipe foo [|
+694       |  local-scope|
+695       |  a:num <- next-ingredient|
+696       |  b:num <- next-ingredient|
+697       |  stash [dividing by], b|
+698       |  _, c:num <- divide-with-remainder a, b|
+699       |  reply b|
+700       |]|
+701     ]
+702   ]
+703   env:&:environment <- new-programming-environment resources, screen, [foo 4, 0]
+704   # run
+705   assume-console [
+706     press F4
+707   ]
+708   event-loop screen, console, env, resources
+709   # screen prints error message
+710   screen-should-contain [
+711     .  errors found (0)                                                               run (F4)           .
+712     .recipe foo [                                      ╎                                                 .
+713     .  local-scope                                     ╎─────────────────────────────────────────────────.
+714     .  a:num <- next-ingredient                        ╎0   edit          copy            delete         .
+715     .  b:num <- next-ingredient                        ╎foo 4, 0                                         .
+716     .  stash [dividing by], b                          ╎foo: divide by zero in '_, c:num <- divide-with-↩.
+717     .  _, c:num <- divide-with-remainder a, b          ╎remainder a, b'                                  .
+718     .  reply b                                         ╎─────────────────────────────────────────────────.
+719     .]                                                 ╎                                                 .
+720     .                                                  ╎                                                 .
+721   ]
+722   # click on the call in the sandbox
+723   assume-console [
+724     left-click 4, 55
+725   ]
+726   run [
+727     event-loop screen, console, env, resources
+728   ]
+729   # screen should expand trace
+730   screen-should-contain [
+731     .  errors found (0)                                                               run (F4)           .
+732     .recipe foo [                                      ╎                                                 .
+733     .  local-scope                                     ╎─────────────────────────────────────────────────.
+734     .  a:num <- next-ingredient                        ╎0   edit          copy            delete         .
+735     .  b:num <- next-ingredient                        ╎foo 4, 0                                         .
+736     .  stash [dividing by], b                          ╎dividing by 0                                    .
+737     .  _, c:num <- divide-with-remainder a, b          ╎14 instructions run                              .
+738     .  reply b                                         ╎foo: divide by zero in '_, c:num <- divide-with-↩.
+739     .]                                                 ╎remainder a, b'                                  .
+740     .                                                  ╎─────────────────────────────────────────────────.
+741   ]
+742 ]
 
-- cgit 1.4.1-2-gfad0