diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2015-07-10 02:00:49 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2015-07-10 02:04:50 -0700 |
commit | 7402ce32ee0cd3301677d0037718b175868a56a8 (patch) | |
tree | efe29f138b11d4029846e27113e0fa06b9e0a3f6 | |
parent | 19323e7afc4b6c4da04c62ecaf05eb3768cacd93 (diff) | |
download | mu-7402ce32ee0cd3301677d0037718b175868a56a8.tar.gz |
1745 - hoist warning/response strings out of editor-data
Still ugly as hell. Some tests failing, but they're most likely wrong. We need to test cursor positioning at the level of the environment and take it away from the responsibilities of individual editors. Also bring back the line at the bottom of each editor. The non-test run ('main' in edit.mu) is completely borked. Sluggish as hell, and I can't seem to switch focus to the sandbox editor.
-rw-r--r-- | 036call_reply.cc | 18 | ||||
-rw-r--r-- | 050scenario.cc | 2 | ||||
-rw-r--r-- | edit.mu | 584 |
3 files changed, 326 insertions, 278 deletions
diff --git a/036call_reply.cc b/036call_reply.cc index 71aa4991..54866765 100644 --- a/036call_reply.cc +++ b/036call_reply.cc @@ -41,7 +41,11 @@ case REPLY: { vector<string> tmp = property(reply_inst.ingredients.at(i), "same-as-ingredient"); assert(SIZE(tmp) == 1); long long int ingredient_index = to_integer(tmp.at(0)); - if (caller_instruction.products.at(i).value != caller_instruction.ingredients.at(ingredient_index).value) + if (ingredient_index >= SIZE(caller_instruction.ingredients)) + raise << current_recipe_name() << ": 'same-as-ingredient' metadata overflows ingredients in: " << caller_instruction.to_string() << '\n'; +//? cerr << caller_instruction.products.size() << ' ' << i << ' ' << caller_instruction.ingredients.size() << ' ' << ingredient_index << '\n'; //? 1 +//? cerr << caller_instruction.to_string() << '\n'; //? 1 + if (!is_dummy(caller_instruction.products.at(i)) && caller_instruction.products.at(i).value != caller_instruction.ingredients.at(ingredient_index).value) raise << current_recipe_name() << ": 'same-as-ingredient' result " << caller_instruction.products.at(i).value << " from call to " << callee << " must be location " << caller_instruction.ingredients.at(ingredient_index).value << '\n'; } } @@ -79,6 +83,18 @@ recipe test1 [ ] +warn: main: 'same-as-ingredient' result 2 from call to test1 must be location 1 +:(scenario reply_same_as_ingredient_dummy) +% Hide_warnings = true; +recipe main [ + 1:number <- copy 0:literal + _ <- test1 1:number # call with different ingredient and product +] +recipe test1 [ + 10:address:number <- next-ingredient + reply 10:address:number/same-as-ingredient:0 +] +$warn: 0 + :(code) string to_string(const vector<double>& in) { if (in.empty()) return "[]"; diff --git a/050scenario.cc b/050scenario.cc index 3b3aa962..a87c1b26 100644 --- a/050scenario.cc +++ b/050scenario.cc @@ -132,7 +132,7 @@ const scenario* Current_scenario = NULL; void run_mu_scenario(const scenario& s) { Current_scenario = &s; bool not_already_inside_test = !Trace_stream; -//? cerr << s.name << '\n'; //? 6 +//? cerr << s.name << '\n'; //? 9 if (not_already_inside_test) { Trace_file = s.name; Trace_stream = new trace_stream; diff --git a/edit.mu b/edit.mu index f21f5ea8..501fdd75 100644 --- a/edit.mu +++ b/edit.mu @@ -10,18 +10,28 @@ recipe main [ reply z:number ]] initial-sandbox:address:array:character <- new [new-add 2:literal, 3:literal] - programming-environment 0:literal/screen, 0:literal/console, initial-recipe:address:array:character, initial-sandbox:address:array:character + env:address:programming-environment-data <- new-programming-environment 0:literal/screen, initial-recipe:address:array:character, initial-sandbox:address:array:character + render-all 0:literal/address, env:address:programming-environment-data + event-loop 0:literal/screen, 0:literal/console, env:address:programming-environment-data ] -recipe programming-environment [ +container programming-environment-data [ + recipes:address:editor-data + recipe-warnings:address:array:character + current-sandbox:address:editor-data + sandbox:sandbox-data + focus-in-sandbox?:boolean # false => focus in recipes; true => focus in current-sandbox +] + +recipe new-programming-environment [ default-space:address:array:location <- new location:type, 30:literal screen:address <- next-ingredient - console:address <- next-ingredient initial-recipe-contents:address:array:character <- next-ingredient initial-sandbox-contents:address:array:character <- next-ingredient width:number <- screen-width screen:address height:number <- screen-height screen:address # top menu + result:address:programming-environment-data <- new programming-environment-data:type draw-horizontal screen:address, 0:literal, 0:literal/left, width:number, 32:literal/space, 0:literal/black, 238:literal/grey button-start:number <- subtract width:number, 20:literal button-on-screen?:boolean <- greater-or-equal button-start:number, 0:literal @@ -33,15 +43,16 @@ recipe programming-environment [ divider:number, _ <- divide-with-remainder width:number, 2:literal draw-vertical screen:address, divider:number, 1:literal/top, height:number, 9482:literal/vertical-dotted # recipe editor on the left - left-editor:address:editor-data <- new-editor initial-recipe-contents:address:array:character, screen:address, 0:literal/left, divider:number/right + recipes:address:address:editor-data <- get-address result:address:programming-environment-data/deref, recipes:offset + recipes:address:address:editor-data/deref <- new-editor initial-recipe-contents:address:array:character, screen:address, 0:literal/left, divider:number/right # sandbox editor on the right new-left:number <- add divider:number, 1:literal new-right:number <- add new-left:number, 5:literal - right-editor:address:editor-data <- new-editor initial-sandbox-contents:address:array:character, screen:address, new-left:number, width:number + current-sandbox:address:address:editor-data <- get-address result:address:programming-environment-data/deref, current-sandbox:offset + current-sandbox:address:address:editor-data/deref <- new-editor initial-sandbox-contents:address:array:character, screen:address, new-left:number, width:number # initialize cursor - update-cursor screen:address, left-editor:address:editor-data, right-editor:address:editor-data, 0:literal/focus-in-recipe - # and we're off! - event-loop screen:address, console:address, left-editor:address:editor-data, right-editor:address:editor-data + update-cursor screen:address, recipes:address:address:editor-data/deref, current-sandbox:address:address:editor-data/deref, 0:literal/focus-in-recipes + reply result:address:programming-environment-data ] scenario editor-initially-prints-string-to-screen [ @@ -60,23 +71,12 @@ scenario editor-initially-prints-string-to-screen [ ## In which we introduce the editor data structure, and show how it displays ## text to the screen. -container programming-environment-data [ - recipes:address:editor-data - current-sandbox:address:editor-data - focus:boolean # false => focus in recipes; true => focus in current-sandbox -] - container editor-data [ # editable text: doubly linked list of characters (head contains a special sentinel) data:address:duplex-list # location before cursor inside data before-cursor:address:duplex-list - # string of non-editable text, in either regular grey.. - response:address:array:character - # ..or red - warnings:address:array:character - # raw bounds of display area on screen # always displays from row 1 and at most until bottom of screen left:number @@ -108,11 +108,6 @@ recipe new-editor [ x:address:number <- get-address result:address:editor-data/deref, cursor-row:offset x:address:number/deref <- copy 1:literal/top x:address:number <- get-address result:address:editor-data/deref, cursor-column:offset - response:address:address:array:character <- get-address result:address:editor-data/deref, response:offset - response:address:address:array:character/deref <- copy 0:literal -#? response:address:address:array:character/deref <- new [aaa] #? 1 - warnings:address:address:array:character <- get-address result:address:editor-data/deref, warnings:offset - warnings:address:address:array:character/deref <- copy 0:literal x:address:number/deref <- copy left:number init:address:address:duplex-list <- get-address result:address:editor-data/deref, data:offset init:address:address:duplex-list/deref <- push-duplex 167:literal/§, 0:literal/tail @@ -139,7 +134,7 @@ recipe new-editor [ y:address:address:duplex-list <- get-address result:address:editor-data/deref, before-cursor:offset y:address:address:duplex-list/deref <- copy init:address:address:duplex-list/deref # perform initial rendering to screen - result:address:editor-data, screen:address <- render screen:address, result:address:editor-data + result:address:editor-data, _, screen:address <- render screen:address, result:address:editor-data reply result:address:editor-data, screen:address/same-as-ingredient:0 ] @@ -152,12 +147,10 @@ scenario editor-initializes-without-data [ memory-should-contain [ # 2 (data) <- just the § sentinel # 3 (before cursor) <- the § sentinel - 4 <- 0 # response - 5 <- 0 # warnings - 6 <- 2 # left - 7 <- 4 # right (inclusive) - 8 <- 1 # cursor row - 9 <- 2 # cursor column + 4 <- 2 # left + 5 <- 4 # right (inclusive) + 6 <- 1 # cursor row + 7 <- 2 # cursor column ] screen-should-contain [ . . @@ -170,7 +163,7 @@ recipe render [ default-space:address:array:location <- new location:type, 40:literal screen:address <- next-ingredient editor:address:editor-data <- next-ingredient - reply-unless editor:address:editor-data, editor:address:editor-data/same-as-ingredient:1, screen:address/same-as-ingredient:0 + reply-unless editor:address:editor-data, editor:address:editor-data/same-as-ingredient:1, 1:literal/top, screen:address/same-as-ingredient:0 left:number <- get editor:address:editor-data/deref, left:offset screen-height:number <- screen-height screen:address right:number <- get editor:address:editor-data/deref, right:offset @@ -252,12 +245,8 @@ recipe render [ above-cursor-row?:boolean <- lesser-than row:number, cursor-row:address:number/deref before-cursor?:boolean <- or before-cursor-on-same-line?:boolean, above-cursor-row?:boolean break-unless before-cursor?:boolean -#? $print [pointed after all text -#? ] #? 1 cursor-row:address:number/deref <- copy row:number cursor-column:address:number/deref <- copy column:number -#? $print [render: cursor moved to ], cursor-row:address:number/deref, [, ], cursor-column:address:number/deref, [ -#? ] #? 1 # line not wrapped but cursor outside bounds? wrap cursor { too-far-right?:boolean <- greater-than cursor-column:address:number/deref, right:number @@ -267,63 +256,10 @@ recipe render [ above-screen-bottom?:boolean <- lesser-than cursor-row:address:number/deref, screen-height:number assert above-screen-bottom?:boolean, [unimplemented: wrapping cursor past bottom of screen] } -#? $print [now ], cursor-row:address:number/deref, [, ], cursor-column:address:number/deref, [ -#? ] #? 1 before-cursor:address:address:duplex-list/deref <- copy prev:address:duplex-list -#? new-prev:character <- get before-cursor:address:address:duplex-list/deref/deref, value:offset #? 1 -#? $print [render Ω: cursor adjusted to after ], new-prev:character, [(], cursor-row:address:number/deref, [, ], cursor-column:address:number/deref, [) -#? ] #? 1 } -#? $print [clearing ], row:number, [ ], column:number, [ ], right:number, [ -#? ] #? 2 clear-line-delimited screen:address, column:number, right:number - row:number <- add row:number, 1:literal - { - # print warnings, or response if no warnings - warnings:address:array:character <- get editor:address:editor-data/deref, warnings:offset - { - break-unless warnings:address:array:character - row:number <- render-string screen:address, warnings:address:array:character, editor:address:editor-data, 1:literal/red, row:number - } - { - break-if warnings:address:array:character - response:address:array:character <- get editor:address:editor-data/deref, response:offset - break-unless response:address:array:character - row:number <- render-string screen:address, response:address:array:character, editor:address:editor-data, 245:literal/grey, row:number - } - } - { - # draw a line after - # hack: not for tests - break-if screen:address - { - break-if left:number # hacky - # left side, recipe editor - draw-horizontal screen:address, row:number, left:number, right:number, 9480:literal/horizontal-dotted - } - { - break-unless left:number - # right side, sandbox editor - draw-horizontal screen:address, row:number, left:number, right:number, 9473:literal/horizontal-double - } - row:number <- add row:number, 1:literal - } - { - # clear one more line just in case we just backspaced out of it - done?:boolean <- greater-or-equal row:number, screen-height:number - break-if done?:boolean - draw-horizontal screen:address, row:number, left:number, right:number, 32:literal/space - } - # update cursor - { - cursor-inside-right-margin?:boolean <- lesser-or-equal cursor-column:address:number/deref, right:number - assert cursor-inside-right-margin?:boolean, [cursor outside right margin] - cursor-inside-left-margin?:boolean <- greater-or-equal cursor-column:address:number/deref, left:number - assert cursor-inside-left-margin?:boolean, [cursor outside left margin] - move-cursor screen:address, cursor-row:address:number/deref, cursor-column:address:number/deref - } - show-screen screen:address - reply editor:address:editor-data/same-as-ingredient:1, screen:address/same-as-ingredient:0 + reply editor:address:editor-data/same-as-ingredient:1, row:number, screen:address/same-as-ingredient:0 ] # row:number <- render-string s:address:array:character, editor:address:editor-data, color:number, row:number @@ -336,6 +272,7 @@ recipe render-string [ editor:address:editor-data <- next-ingredient color:number <- next-ingredient row:number <- next-ingredient + row:number <- add row:number, 1:literal reply-unless s:address:array:character, row:number left:number <- get editor:address:editor-data/deref, left:offset right:number <- get editor:address:editor-data/deref, right:offset @@ -516,16 +453,14 @@ scenario editor-initializes-empty-text [ ## handling events from the keyboard, mouse, touch screen, ... -# takes two editors, sends each event from the console to each editor recipe event-loop [ default-space:address:array:location <- new location:type, 30:literal screen:address <- next-ingredient console:address <- next-ingredient - recipes:address:editor-data <- next-ingredient - current-sandbox:address:editor-data <- next-ingredient - sandbox-in-focus?:boolean <- next-ingredient -#? $print [sandbox in focus? ], sandbox-in-focus?:boolean, [ -#? ] #? 1 + env:address:programming-environment-data <- next-ingredient + recipes:address:editor-data <- get env:address:programming-environment-data/deref, recipes:offset + current-sandbox:address:editor-data <- get env:address:programming-environment-data/deref, current-sandbox:offset + sandbox-in-focus?:boolean <- get env:address:programming-environment-data/deref, focus-in-sandbox?:offset { # looping over each (keyboard or touch) event as it occurs +next-event @@ -533,8 +468,6 @@ recipe event-loop [ 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 @@ -543,9 +476,8 @@ recipe event-loop [ { do-run?:boolean <- equal k:address:number/deref, 65526:literal/F10 break-unless do-run?:boolean -#? trace [app], [run] #? 1 - run-sandboxes recipes:address:editor-data, current-sandbox:address:editor-data - render-all screen:address, recipes:address:editor-data, current-sandbox:address:editor-data, sandbox-in-focus?:boolean + run-sandboxes env:address:programming-environment-data + render-all screen:address, env:address:programming-environment-data loop +next-event:label # done with this event; no need to send to editors } } @@ -553,24 +485,59 @@ recipe event-loop [ { t:address:touch-event <- maybe-convert e:event, touch:variant break-unless t:address:touch-event -#? trace [app], [touch] #? 1 - _ <- move-cursor-in-editor recipes:address:editor-data, t:address:touch-event/deref - sandbox-in-focus?:boolean <- move-cursor-in-editor current-sandbox:address:editor-data, t:address:touch-event/deref - render-all screen:address, recipes:address:editor-data, current-sandbox:address:editor-data, sandbox-in-focus?:boolean + _ <- move-cursor-in-editor screen:address, recipes:address:editor-data, t:address:touch-event/deref + sandbox-in-focus?:boolean <- move-cursor-in-editor screen:address, current-sandbox:address:editor-data, t:address:touch-event/deref + render-all screen:address, env:address:programming-environment-data loop +next-event:label } # if it's not global, send to appropriate editor { { break-if sandbox-in-focus?:boolean -#? $print [event in recipes -#? ] #? 1 handle-event screen:address, console:address, recipes:address:editor-data, e:event } { break-unless sandbox-in-focus?:boolean -#? $print [event in current-sandbox: ], sandbox-in-focus?:boolean, [ -#? ] #? 1 + handle-event screen:address, console:address, current-sandbox:address:editor-data, e:event + } + } + render-all screen:address, env:address:programming-environment-data + loop + } +] + +# takes two editors, sends each event from the console to each editor +recipe editor-event-loop [ + default-space:address:array:location <- new location:type, 30:literal + screen:address <- next-ingredient + console:address <- next-ingredient + recipes:address:editor-data <- next-ingredient + current-sandbox:address:editor-data <- next-ingredient + sandbox-in-focus?:boolean <- next-ingredient + { + # 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] + # 'touch' event - send to both editors + { + t:address:touch-event <- maybe-convert e:event, touch:variant + break-unless t:address:touch-event + _ <- move-cursor-in-editor screen:address, recipes:address:editor-data, t:address:touch-event/deref + sandbox-in-focus?:boolean <- move-cursor-in-editor screen:address, current-sandbox:address:editor-data, t:address:touch-event/deref + update-cursor screen:address, recipes:address:editor-data, current-sandbox:address:editor-data, sandbox-in-focus?:boolean + loop +next-event:label + } + # other events - send to appropriate editor + { + { + break-if sandbox-in-focus?:boolean + handle-event screen:address, console:address, recipes:address:editor-data, e:event + } + { + break-unless sandbox-in-focus?:boolean handle-event screen:address, console:address, current-sandbox:address:editor-data, e:event } } @@ -727,6 +694,7 @@ recipe handle-event [ # todo: ignores menu bar (for now just displays shortcuts) recipe move-cursor-in-editor [ default-space:address:array:location <- new location:type, 30:literal + screen:address <- next-ingredient editor:address:editor-data <- next-ingredient t:touch-event <- next-ingredient reply-unless editor:address:editor-data, 0:literal/false @@ -742,6 +710,7 @@ recipe move-cursor-in-editor [ cursor-row:address:number/deref <- get t:touch-event, row:offset cursor-column:address:number <- get-address editor:address:editor-data/deref, cursor-column:offset cursor-column:address:number/deref <- get t:touch-event, column:offset + editor:address:editor-data <- render screen:address, editor:address:editor-data # gain focus reply 1:literal/true ] @@ -840,12 +809,63 @@ recipe previous-line-length [ recipe render-all [ default-space:address:array:location <- new location:type, 40:literal screen:address <- next-ingredient - recipes:address:editor-data <- next-ingredient - current-sandbox:address:editor-data <- next-ingredient - sandbox-in-focus?:boolean <- next-ingredient - render screen:address, recipes:address:editor-data - render screen:address, current-sandbox:address:editor-data + env:address:programming-environment-data <- next-ingredient + recipes:address:editor-data <- get env:address:programming-environment-data/deref, recipes:offset + current-sandbox:address:editor-data <- get env:address:programming-environment-data/deref, current-sandbox:offset + sandbox-in-focus?:boolean <- get env:address:programming-environment-data/deref, focus-in-sandbox?:offset + recipes:address:editor-data, row:number <- render screen:address, recipes:address:editor-data + # print warnings, or response if no warnings + recipe-warnings:address:array:character <- get env:address:programming-environment-data/deref, recipe-warnings:offset + { + break-unless recipe-warnings:address:array:character + row:number <- render-string screen:address, recipe-warnings:address:array:character, recipes:address:editor-data, 1:literal/red, row:number + } + left:number <- get current-sandbox:address:editor-data/deref, left:offset + _, row:number <- render screen:address, current-sandbox:address:editor-data + sandbox:address:sandbox-data <- get-address env:address:programming-environment-data/deref, sandbox:offset + sandbox-response:address:array:character <- get sandbox:address:sandbox-data/deref, response:offset + sandbox-warnings:address:array:character <- get sandbox:address:sandbox-data/deref, warnings:offset + { + break-unless sandbox-warnings:address:array:character + row:number <- render-string screen:address, sandbox-warnings:address:array:character, current-sandbox:address:editor-data, 1:literal/red, row:number + } + { + break-if sandbox-warnings:address:array:character + row:number <- render-string screen:address, sandbox-response:address:array:character, current-sandbox:address:editor-data, 245:literal/grey, row:number + } +#? { +#? # draw a line after +#? # hack: not for tests +#? break-if screen:address +#? { +#? break-if left:number # hacky +#? # left side, recipe editor +#? draw-horizontal screen:address, row:number, left:number, right:number, 9480:literal/horizontal-dotted +#? } +#? { +#? break-unless left:number +#? # right side, sandbox editor +#? draw-horizontal screen:address, row:number, left:number, right:number, 9473:literal/horizontal-double +#? } +#? row:number <- add row:number, 1:literal +#? } +#? row:number <- add row:number, 1:literal +#? { +#? # clear one more line just in case we just backspaced out of it +#? done?:boolean <- greater-or-equal row:number, screen-height:number +#? break-if done?:boolean +#? draw-horizontal screen:address, row:number, left:number, right:number, 32:literal/space +#? } +#? # update cursor +#? { +#? cursor-inside-right-margin?:boolean <- lesser-or-equal cursor-column:address:number/deref, right:number +#? assert cursor-inside-right-margin?:boolean, [cursor outside right margin] +#? cursor-inside-left-margin?:boolean <- greater-or-equal cursor-column:address:number/deref, left:number +#? assert cursor-inside-left-margin?:boolean, [cursor outside left margin] +#? move-cursor screen:address, cursor-row:address:number/deref, cursor-column:address:number/deref +#? } update-cursor screen:address, recipes:address:editor-data, current-sandbox:address:editor-data, sandbox-in-focus?:boolean + show-screen screen:address ] recipe update-cursor [ @@ -875,7 +895,7 @@ scenario editor-handles-empty-event-queue [ 2:address:editor-data <- new-editor 1:address:array:character, screen:address, 0:literal/left, 10:literal/right assume-console [] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data ] screen-should-contain [ . . @@ -892,7 +912,7 @@ scenario editor-handles-mouse-clicks [ left-click 1, 1 # on the 'b' ] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data 3:number <- get 2:address:editor-data/deref, cursor-row:offset 4:number <- get 2:address:editor-data/deref, cursor-column:offset ] @@ -915,7 +935,7 @@ scenario editor-handles-mouse-clicks-outside-text [ left-click 1, 7 # last line, to the right of text ] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data 3:number <- get 2:address:editor-data/deref, cursor-row:offset 4:number <- get 2:address:editor-data/deref, cursor-column:offset ] @@ -934,7 +954,7 @@ def] left-click 1, 7 # interior line, to the right of text ] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data 3:number <- get 2:address:editor-data/deref, cursor-row:offset 4:number <- get 2:address:editor-data/deref, cursor-column:offset ] @@ -953,7 +973,7 @@ def] left-click 3, 7 # below text ] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data 3:number <- get 2:address:editor-data/deref, cursor-row:offset 4:number <- get 2:address:editor-data/deref, cursor-column:offset ] @@ -973,7 +993,7 @@ scenario editor-handles-mouse-clicks-outside-column [ left-click 3, 8 ] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data 3:number <- get 2:address:editor-data/deref, cursor-row:offset 4:number <- get 2:address:editor-data/deref, cursor-column:offset ] @@ -996,7 +1016,7 @@ scenario editor-inserts-characters-into-empty-editor [ type [abc] ] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data ] screen-should-contain [ . . @@ -1015,7 +1035,7 @@ scenario editor-inserts-characters-at-cursor [ type [d] ] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data ] screen-should-contain [ . . @@ -1033,7 +1053,7 @@ scenario editor-inserts-characters-at-cursor-2 [ type [d] # should append ] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data ] screen-should-contain [ . . @@ -1051,7 +1071,7 @@ scenario editor-inserts-characters-at-cursor-3 [ type [d] # should append ] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data ] screen-should-contain [ . . @@ -1070,7 +1090,7 @@ d] type [e] # should append ] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data ] screen-should-contain [ . . @@ -1090,7 +1110,7 @@ d] type [ef] # should append multiple characters in order ] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data ] screen-should-contain [ . . @@ -1109,7 +1129,7 @@ scenario editor-wraps-line-on-insert [ type [e] ] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data ] # no wrap yet screen-should-contain [ @@ -1123,7 +1143,7 @@ scenario editor-wraps-line-on-insert [ type [f] ] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data ] # now wrap screen-should-contain [ @@ -1142,7 +1162,7 @@ scenario editor-moves-cursor-after-inserting-characters [ type [01] ] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data ] screen-should-contain [ . . @@ -1160,7 +1180,7 @@ scenario editor-wraps-cursor-after-inserting-characters [ type [f] ] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data 3:number <- get 2:address:editor-data/deref, cursor-row:offset 4:number <- get 2:address:editor-data/deref, cursor-column:offset ] @@ -1185,7 +1205,7 @@ scenario editor-wraps-cursor-after-inserting-characters-2 [ type [f] ] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data 3:number <- get 2:address:editor-data/deref, cursor-row:offset 4:number <- get 2:address:editor-data/deref, cursor-column:offset ] @@ -1210,7 +1230,7 @@ scenario editor-moves-cursor-down-after-inserting-newline [ 1] ] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data ] screen-should-contain [ . . @@ -1229,7 +1249,7 @@ scenario editor-moves-cursor-down-after-inserting-newline-2 [ 1] ] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data ] screen-should-contain [ . . @@ -1256,7 +1276,7 @@ scenario editor-clears-previous-line-completely-after-inserting-newline [ . . ] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data ] # line should be fully cleared screen-should-contain [ @@ -1279,7 +1299,7 @@ scenario editor-handles-backspace-key [ 3:event/backspace <- merge 0:literal/text, 8:literal/backspace, 0:literal/dummy, 0:literal/dummy replace-in-console 171:literal/«, 3:event/backspace run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data 4:number <- get 2:address:editor-data/deref, cursor-row:offset 5:number <- get 2:address:editor-data/deref, cursor-column:offset ] @@ -1307,7 +1327,7 @@ d] 3:event/backspace <- merge 0:literal/text, 8:literal/backspace, 0:literal/dummy, 0:literal/dummy replace-in-console 171:literal/«, 3:event/backspace run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data ] screen-should-contain [ . . @@ -1325,7 +1345,7 @@ scenario editor-moves-cursor-right-with-key [ type [0] ] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data ] screen-should-contain [ . . @@ -1347,7 +1367,7 @@ d] type [0] ] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data ] screen-should-contain [ . . @@ -1370,7 +1390,7 @@ d] type [0] ] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data ] screen-should-contain [ . . @@ -1389,7 +1409,7 @@ scenario editor-moves-cursor-to-next-wrapped-line-with-right-arrow [ press 65514 # right arrow ] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data 3:number <- get 2:address:editor-data/deref, cursor-row:offset 4:number <- get 2:address:editor-data/deref, cursor-column:offset ] @@ -1416,7 +1436,7 @@ scenario editor-moves-cursor-to-next-wrapped-line-with-right-arrow-2 [ press 65514 # right arrow ] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data 3:number <- get 2:address:editor-data/deref, cursor-row:offset 4:number <- get 2:address:editor-data/deref, cursor-column:offset ] @@ -1429,7 +1449,7 @@ scenario editor-moves-cursor-to-next-wrapped-line-with-right-arrow-2 [ press 65514 ] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data 3:number <- get 2:address:editor-data/deref, cursor-row:offset 4:number <- get 2:address:editor-data/deref, cursor-column:offset ] @@ -1448,7 +1468,7 @@ scenario editor-moves-cursor-to-next-wrapped-line-with-right-arrow-3 [ press 65514 # right arrow ] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data 3:number <- get 2:address:editor-data/deref, cursor-row:offset 4:number <- get 2:address:editor-data/deref, cursor-column:offset ] @@ -1475,7 +1495,7 @@ d] type [0] ] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data ] screen-should-contain [ . . @@ -1495,7 +1515,7 @@ scenario editor-moves-cursor-left-with-key [ type [0] ] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data ] screen-should-contain [ . . @@ -1516,7 +1536,7 @@ d] press 65515 # left arrow ] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data 3:number <- get 2:address:editor-data/deref, cursor-row:offset 4:number <- get 2:address:editor-data/deref, cursor-column:offset ] @@ -1543,7 +1563,7 @@ g] type [0] ] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data ] screen-should-contain [ . . @@ -1567,7 +1587,7 @@ g] type [0] ] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data ] screen-should-contain [ . . @@ -1592,7 +1612,7 @@ d] type [0] ] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data ] screen-should-contain [ . . @@ -1620,7 +1640,7 @@ scenario editor-moves-across-screen-lines-across-wrap-with-left-arrow [ press 65515 # left arrow ] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data 3:number <- get 2:address:editor-data/deref, cursor-row:offset 4:number <- get 2:address:editor-data/deref, cursor-column:offset ] @@ -1640,7 +1660,7 @@ def] press 65517 # up arrow ] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data 3:number <- get 2:address:editor-data/deref, cursor-row:offset 4:number <- get 2:address:editor-data/deref, cursor-column:offset ] @@ -1660,7 +1680,7 @@ def] press 65516 # down arrow ] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data 3:number <- get 2:address:editor-data/deref, cursor-row:offset 4:number <- get 2:address:editor-data/deref, cursor-column:offset ] @@ -1681,7 +1701,7 @@ def] press 65517 # up arrow ] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data 3:number <- get 2:address:editor-data/deref, cursor-row:offset 4:number <- get 2:address:editor-data/deref, cursor-column:offset ] @@ -1701,7 +1721,7 @@ de] press 65516 # down arrow ] run [ - event-loop screen:address, console:address, 2:address:editor-data + editor-event-loop screen:address, console:address, 2:address:editor-data 3:number <- get 2:address:editor-data/deref, cursor-row:offset 4:number <- get 2:address:editor-data/deref, cursor-column:offset ] @@ -1712,88 +1732,84 @@ de] ] scenario point-at-multiple-editors [ - assume-screen 10:literal/width, 5:literal/height - # initialize recipe editor covering left half of screen + assume-screen 30:literal/width, 5:literal/height + # initialize both halves of screen 1:address:array:character <- new [abc] - 2:address:editor-data <- new-editor 1:address:array:character, screen:address, 0:literal/left, 5:literal/right - # initialize sandbox editor covering right half of screen - 3:address:array:character <- new [def] - 4:address:editor-data <- new-editor 3:address:array:character, screen:address, 5:literal/left, 10:literal/right + 2:address:array:character <- new [def] + 3:address:programming-environment-data <- new-programming-environment screen:address, 1:address:array:character, 2:address:array:character # focus on both sides assume-console [ left-click 1, 1 - left-click 1, 8 + left-click 1, 17 ] # check cursor column in each run [ - event-loop screen:address, console:address, 2:address:editor-data, 4:address:editor-data - 6:number <- get 2:address:editor-data/deref, cursor-column:offset - 7:number <- get 4:address:editor-data/deref, cursor-column:offset + event-loop screen:address, console:address, 3:address:programming-environment-data + 4:address:editor-data <- get 3:address:programming-environment-data/deref, recipes:offset + 5:number <- get 4:address:editor-data/deref, cursor-column:offset + 6:address:editor-data <- get 3:address:programming-environment-data/deref, current-sandbox:offset + 7:number <- get 6:address:editor-data/deref, cursor-column:offset ] memory-should-contain [ - 6 <- 1 - 7 <- 8 + 5 <- 1 + 7 <- 17 ] ] scenario editors-chain-to-cover-multiple-columns [ - assume-screen 10:literal/width, 5:literal/height - # initialize recipe editor covering left half of screen + assume-screen 30:literal/width, 5:literal/height + # initialize both halves of screen 1:address:array:character <- new [abc] - 2:address:editor-data <- new-editor 1:address:array:character, screen:address, 0:literal/left, 5:literal/right - # initialize sandbox editor covering right half of screen - 3:address:array:character <- new [def] - 4:address:editor-data <- new-editor 3:address:array:character, screen:address, 5:literal/left, 10:literal/right + 2:address:array:character <- new [def] + 3:address:programming-environment-data <- new-programming-environment screen:address, 1:address:array:character, 2:address:array:character # type one letter in each of them assume-console [ left-click 1, 1 type [0] - left-click 1, 6 + left-click 1, 17 type [1] ] run [ - event-loop screen:address, console:address, 2:address:editor-data, 4:address:editor-data - 5:number <- get 2:address:editor-data/deref, cursor-column:offset - 6:number <- get 4:address:editor-data/deref, cursor-column:offset + event-loop screen:address, console:address, 3:address:programming-environment-data + 4:address:editor-data <- get 3:address:programming-environment-data/deref, recipes:offset + 5:number <- get 4:address:editor-data/deref, cursor-column:offset + 6:address:editor-data <- get 3:address:programming-environment-data/deref, current-sandbox:offset + 7:number <- get 6:address:editor-data/deref, cursor-column:offset ] screen-should-contain [ - . . - .a0bc d1ef . - . . + . run (F10) . + .a0bc ┊d1ef . + . ┊ . ] memory-should-contain [ 5 <- 2 # cursor column of recipe editor - 6 <- 7 # cursor column of sandbox editor + 7 <- 18 # cursor column of sandbox editor ] # show the cursor at the right window run [ screen:address <- print-character screen:address, 9251:literal/␣ ] screen-should-contain [ - . . - .a0bc d1␣f . - . . + . run (F10) . + .a0bc ┊d1␣f . + . ┊ . ] ] scenario multiple-editors-cover-only-their-own-areas [ - assume-screen 10:literal/width, 5:literal/height + assume-screen 60:literal/width, 10:literal/height run [ - # draw a divider - draw-vertical screen:address, 5:literal/divider, 1:literal/top, 5:literal/height - # initialize editors on both sides of it 1:address:array:character <- new [abc] - 2:address:editor-data <- new-editor 1:address:array:character, screen:address, 0:literal/left, 5:literal/right - 3:address:array:character <- new [def] - 4:address:editor-data <- new-editor 3:address:array:character, screen:address, 6:literal/left, 10:literal/right + 2:address:array:character <- new [def] + 3:address:programming-environment-data <- new-programming-environment screen:address, 1:address:array:character, 2:address:array:character ] # divider isn't messed up screen-should-contain [ - . . - .abc │def . - . │ . - . │ . - . │ . + . run (F10) . + .abc ┊def . + . ┊ . + . ┊ . + . ┊ . ] ] @@ -1804,7 +1820,8 @@ scenario editor-in-focus-keeps-cursor [ # initialize programming environment and highlight cursor assume-console [] run [ - programming-environment screen:address, console:address, 1:address:array:character, 2:address:array:character + 3:address:programming-environment-data <- new-programming-environment screen:address, 1:address:array:character, 2:address:array:character + event-loop screen:address, console:address, 3:address:programming-environment-data screen:address <- print-character screen:address, 9251:literal/␣ ] # is cursor at the right place? @@ -1818,7 +1835,8 @@ scenario editor-in-focus-keeps-cursor [ type [z] ] run [ - programming-environment screen:address, console:address, 1:address:array:character, 2:address:array:character + 3:address:programming-environment-data <- new-programming-environment screen:address, 1:address:array:character, 2:address:array:character + event-loop screen:address, console:address, 3:address:programming-environment-data screen:address <- print-character screen:address, 9251:literal/␣ ] # cursor should still be right @@ -1831,130 +1849,144 @@ scenario editor-in-focus-keeps-cursor [ ## Running code from the editors -recipe editor-contents [ - default-space:address:array:location <- new location:type, 30:literal - editor:address:editor-data <- next-ingredient - buf:address:buffer <- new-buffer 80:literal - curr:address:duplex-list <- get editor:address:editor-data/deref, data:offset - # skip § sentinel - assert curr:address:duplex-list, [editor without data is illegal; must have at least a sentinel] - curr:address:duplex-list <- next-duplex curr:address:duplex-list - { - break-unless curr:address:duplex-list - c:character <- get curr:address:duplex-list/deref, value:offset - buffer-append buf:address:buffer, c:character - curr:address:duplex-list <- next-duplex curr:address:duplex-list - loop - } - result:address:array:character <- buffer-to-array buf:address:buffer - reply result:address:array:character -] - -scenario editor-provides-edited-contents [ - assume-screen 10:literal/width, 5:literal/height - 1:address:array:character <- new [abc] - 2:address:editor-data <- new-editor 1:address:array:character, screen:address, 0:literal/left, 10:literal/right - assume-console [ - left-click 1, 2 - type [def] - ] - run [ - event-loop screen:address, console:address, 2:address:editor-data - 3:address:array:character <- editor-contents 2:address:editor-data - 4:array:character <- copy 3:address:array:character/deref - ] - memory-should-contain [ - 4:string <- [abdefc] - ] +container sandbox-data [ + data:address:array:character + response:address:array:character + warnings:address:array:character ] scenario run-and-show-results [ - assume-screen 60:literal/width, 5:literal/height + assume-screen 120:literal/width, 10:literal/height # recipe editor is empty 1:address:array:character <- new [] - 2:address:editor-data <- new-editor 1:address:array:character, screen:address, 0:literal/left, 5:literal/right # sandbox editor contains an instruction without storing outputs - 3:address:array:character <- new [divide-with-remainder 11:literal, 3:literal] - 4:address:editor-data <- new-editor 3:address:array:character, screen:address, 5:literal/left, 60:literal/right + 2:address:array:character <- new [divide-with-remainder 11:literal, 3:literal] + 3:address:programming-environment-data <- new-programming-environment screen:address, 1:address:array:character, 2:address:array:character # run the code in the editors assume-console [ press 65526 # F10 ] run [ - event-loop screen:address, console:address, 2:address:editor-data, 4:address:editor-data + event-loop screen:address, console:address, 3:address:programming-environment-data ] # check that screen prints the results screen-should-contain [ - . . - . divide-with-remainder 11:literal, 3:literal . - . 3 . - . 2 . - . . + . run (F10) . + . ┊divide-with-remainder 11:literal, 3:literal . + . ┊3 . + . ┊2 . + . ┊ . ] screen-should-contain-in-color 7:literal/white, [ - . . - . divide-with-remainder 11:literal, 3:literal . - . . - . . - . . + . . + . divide-with-remainder 11:literal, 3:literal . + . . + . . + . . ] - screen-should-contain-in-color 245:literal/grey, [ - . . - . . - . 3 . - . 2 . - . . + screen-should-contain-in-color, 245:literal/grey, [ + . . + . ┊ . + . ┊3 . + . ┊2 . + . ┊ . ] + $close-trace # todo: try removing after we fix sluggishness ] recipe run-sandboxes [ default-space:address:array:location <- new location:type, 30:literal - recipes:address:editor-data <- next-ingredient - current-sandbox:address:editor-data <- next-ingredient + env:address:programming-environment-data <- next-ingredient + recipes:address:editor-data <- get env:address:programming-environment-data/deref, recipes:offset + current-sandbox:address:editor-data <- get env:address:programming-environment-data/deref, current-sandbox:offset # load code from recipe editor, save any warnings in:address:array:character <- editor-contents recipes:address:editor-data - warnings:address:address:array:character <- get-address recipes:address:editor-data/deref, warnings:offset - warnings:address:address:array:character/deref <- reload in:address:array:character + recipe-warnings:address:address:array:character <- get-address env:address:programming-environment-data/deref, recipe-warnings:offset + recipe-warnings:address:address:array:character/deref <- reload in:address:array:character # run contents of right editor (sandbox), save any warnings or output in:address:array:character <- editor-contents current-sandbox:address:editor-data - response:address:address:array:character <- get-address current-sandbox:address:editor-data/deref, response:offset - warnings:address:address:array:character <- get-address current-sandbox:address:editor-data/deref, warnings:offset + sandbox:address:sandbox-data <- get-address env:address:programming-environment-data/deref, sandbox:offset + response:address:address:array:character <- get-address sandbox:address:sandbox-data/deref, response:offset + warnings:address:address:array:character <- get-address sandbox:address:sandbox-data/deref, warnings:offset response:address:address:array:character/deref, warnings:address:address:array:character/deref <- run-interactive in:address:array:character ] scenario run-instruction-and-print-warnings [ - assume-screen 60:literal/width, 5:literal/height + assume-screen 120:literal/width, 10: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/left, 5:literal/right # right editor contains an illegal instruction - 3:address:array:character <- new [get 1234:number, foo:offset] - 4:address:editor-data <- new-editor 3:address:array:character, screen:address, 5:literal/left, 60:literal/right + 2:address:array:character <- new [get 1234:number, foo:offset] + 3:address:programming-environment-data <- new-programming-environment screen:address, 1:address:array:character, 2:address:array:character # run the code in the editors assume-console [ press 65526 # F10 ] run [ - event-loop screen:address, console:address, 2:address:editor-data, 4:address:editor-data + event-loop screen:address, console:address, 3:address:programming-environment-data ] # check that screen prints error message in red screen-should-contain [ - . . - . get 1234:number, foo:offset . - . unknown element foo in container number . - . . + . run (F10) . + . ┊get 1234:number, foo:offset . + . ┊unknown element foo in container number . + . ┊ . ] screen-should-contain-in-color 7:literal/white, [ - . . - . get 1234:number, foo:offset . - . . - . . + . . + . get 1234:number, foo:offset . + . . + . . ] screen-should-contain-in-color, 1:literal/red, [ - . . - . . - . unknown element foo in container number . - . . + . . + . . + . unknown element foo in container number . + . . + ] + screen-should-contain-in-color, 245:literal/grey, [ + . . + . ┊ . + . ┊ . + . ┊ . + ] + $close-trace # todo: try removing after we fix sluggishness +] + +recipe editor-contents [ + default-space:address:array:location <- new location:type, 30:literal + editor:address:editor-data <- next-ingredient + buf:address:buffer <- new-buffer 80:literal + curr:address:duplex-list <- get editor:address:editor-data/deref, data:offset + # skip § sentinel + assert curr:address:duplex-list, [editor without data is illegal; must have at least a sentinel] + curr:address:duplex-list <- next-duplex curr:address:duplex-list + { + break-unless curr:address:duplex-list + c:character <- get curr:address:duplex-list/deref, value:offset + buffer-append buf:address:buffer, c:character + curr:address:duplex-list <- next-duplex curr:address:duplex-list + loop + } + result:address:array:character <- buffer-to-array buf:address:buffer + reply result:address:array:character +] + +scenario editor-provides-edited-contents [ + assume-screen 10:literal/width, 5:literal/height + 1:address:array:character <- new [abc] + 2:address:editor-data <- new-editor 1:address:array:character, screen:address, 0:literal/left, 10:literal/right + assume-console [ + left-click 1, 2 + type [def] + ] + run [ + editor-event-loop screen:address, console:address, 2:address:editor-data + 3:address:array:character <- editor-contents 2:address:editor-data + 4:array:character <- copy 3:address:array:character/deref + ] + memory-should-contain [ + 4:string <- [abdefc] ] ] |