2861 - 'maybe-convert' no longer returns address

This commit is contained in:
Kartik K. Agaram 2016-04-23 17:02:16 -07:00
parent 991d76f328
commit 7bf9212fd4
23 changed files with 322 additions and 263 deletions

View File

@ -660,6 +660,14 @@ def main [
]
+error: main: too few ingredients in '1:point-number <- merge 3, 4'
:(scenario merge_check_reflexive)
% Hide_errors = true;
def main [
1:point <- merge 3, 4
2:point <- merge 1:point
]
$error: 0
//: Since a container can be merged in several ways, we need to be able to
//: backtrack through different possibilities. Later we'll allow creating
//: exclusive containers which contain just one of rather than all of their
@ -721,6 +729,9 @@ void check_merge_call(const vector<reagent>& ingredients, const reagent& product
type_info& container_info = get(Type, container.type->value);
switch (container_info.kind) {
case CONTAINER: {
// degenerate case: merge with the same type always succeeds
if (state.data.top().container_element_index == 0 && types_coercible(container, inst.ingredients.at(ingredient_index)))
return;
reagent expected_ingredient = element_type(container, state.data.top().container_element_index);
trace(9999, "transform") << "checking container " << to_string(container) << " || " << to_string(expected_ingredient) << " vs ingredient " << ingredient_index << end();
// if the current element is the ingredient we expect, move on to the next element/ingredient

View File

@ -60,18 +60,24 @@ def main [
12:number <- copy 1
13:number <- copy 35
14:number <- copy 36
20:address:point <- maybe-convert 12:number-or-point/unsafe, 1:variant
20:point, 22:boolean <- maybe-convert 12:number-or-point/unsafe, 1:variant
]
+mem: storing 13 in location 20
# point
+mem: storing 35 in location 20
+mem: storing 36 in location 21
# boolean
+mem: storing 1 in location 22
:(scenario maybe_convert_fail)
def main [
12:number <- copy 1
13:number <- copy 35
14:number <- copy 36
20:address:number <- maybe-convert 12:number-or-point/unsafe, 0:variant
20:number, 21:boolean <- maybe-convert 12:number-or-point/unsafe, 0:variant
]
+mem: storing 0 in location 20
# number: no write
# boolean
+mem: storing 0 in location 21
:(before "End Primitive Recipe Declarations")
MAYBE_CONVERT,
@ -95,6 +101,10 @@ case MAYBE_CONVERT: {
break;
}
if (inst.products.empty()) break;
if (SIZE(inst.products) != 2) {
raise << maybe(caller.name) << "'maybe-convert' expects exactly 2 products in '" << to_original_string(inst) << "'\n" << end();
break;
}
reagent product = inst.products.at(0);
if (!canonize_type(product)) break;
reagent& offset = inst.ingredients.at(1);
@ -104,11 +114,14 @@ case MAYBE_CONVERT: {
break;
}
reagent variant = variant_type(base, offset.value);
variant.type = new type_tree("address", get(Type_ordinal, "address"), variant.type);
if (!types_coercible(product, variant)) {
raise << maybe(caller.name) << "'maybe-convert " << base.original_string << ", " << inst.ingredients.at(1).original_string << "' should write to " << to_string(variant.type) << " but " << product.name << " has type " << to_string(product.type) << '\n' << end();
break;
}
if (!is_mu_boolean(inst.products.at(1))) {
raise << maybe(get(Recipe, r).name) << "second product yielded by 'maybe-convert' should be a boolean, but tried to write to " << inst.products.at(1).original_string << '\n' << end();
break;
}
break;
}
:(before "End Primitive Recipe Implementations")
@ -121,16 +134,26 @@ case MAYBE_CONVERT: {
break;
}
int tag = current_instruction().ingredients.at(1).value;
int result;
reagent product = current_instruction().products.at(0);
canonize(product);
reagent did_conversion_happen = current_instruction().products.at(1);
canonize(did_conversion_happen);
// optimization: directly write results to only update first product when necessary
if (tag == static_cast<int>(get_or_insert(Memory, base_address))) {
result = base_address+1;
const reagent variant = variant_type(base, tag);
for (int i = 0; i < size_of(variant); ++i) {
double val = get_or_insert(Memory, base_address+1+i);
trace(9999, "mem") << "storing " << no_scientific(val) << " in location " << product.value+i << end();
put(Memory, product.value+i, val);
}
trace(9999, "mem") << "storing 1 in location " << did_conversion_happen.value << end();
put(Memory, did_conversion_happen.value, 1);
}
else {
result = 0;
trace(9999, "mem") << "storing 0 in location " << did_conversion_happen.value << end();
put(Memory, did_conversion_happen.value, 0);
}
products.resize(1);
products.at(0).push_back(result);
break;
goto finish_instruction;
}
:(code)
@ -151,9 +174,9 @@ def main [
12:number <- copy 1
13:number <- copy 35
14:number <- copy 36
20:address:number <- maybe-convert 12:number-or-point/unsafe, 1:variant
20:number, 21:boolean <- maybe-convert 12:number-or-point/unsafe, 1:variant
]
+error: main: 'maybe-convert 12:number-or-point/unsafe, 1:variant' should write to (address point) but 20 has type (address number)
+error: main: 'maybe-convert 12:number-or-point/unsafe, 1:variant' should write to point but 20 has type number
//:: Allow exclusive containers to be defined in mu code.
@ -338,6 +361,21 @@ def main [
]
+error: main: too few ingredients in '1:foo <- merge 1/y, 23'
:(scenario merge_check_exclusive_container_containing_container_4)
exclusive-container foo [
x:number
y:bar
]
container bar [
a:number
b:number
]
def main [
1:bar <- merge 23, 24
3:foo <- merge 1/y, 1:bar
]
$error: 0
//: Since the different variants of an exclusive-container might have
//: different sizes, relax the size mismatch check for 'merge' instructions.
:(before "End size_mismatch(x) Cases")

View File

@ -267,10 +267,12 @@ def main [
12:number <- copy 1
13:number <- copy 35
14:number <- copy 36
20:address:point <- maybe-convert 12:number-or-point/unsafe, p:variant
20:point, 22:boolean <- maybe-convert 12:number-or-point/unsafe, p:variant
]
+name: variant p of type number-or-point has tag 1
+mem: storing 13 in location 20
+mem: storing 35 in location 20
+mem: storing 36 in location 21
+mem: storing 1 in location 22
:(before "End transform_names(inst) Special-cases")
// convert variant names of exclusive containers

View File

@ -65,9 +65,9 @@ def read-key console:address:shared:console -> result:character, console:address
x:event, console, found?:boolean, quit?:boolean <- read-event console
return-if quit?, 0, console/same-as-ingredient:0, found?, quit?
return-unless found?, 0, console/same-as-ingredient:0, found?, quit?
c:address:character <- maybe-convert x, text:variant
return-unless c, 0, console/same-as-ingredient:0, 0/found, 0/quit
return *c, console/same-as-ingredient:0, 1/found, 0/quit
c:character, converted?:boolean <- maybe-convert x, text:variant
return-unless converted?, 0, console/same-as-ingredient:0, 0/found, 0/quit
return c, console/same-as-ingredient:0, 1/found, 0/quit
]
def send-keys-to-channel console:address:shared:console, chan:address:shared:sink:character, screen:address:shared:screen -> console:address:shared:console, chan:address:shared:sink:character, screen:address:shared:screen [

View File

@ -17,7 +17,7 @@ then
# All sorts of strange bugs ensue.
sleep 1
set -v # Darwin's clang and valgrind is shit.
CFLAGS=${CFLAGS:-"-g -O3"} make #test
CFLAGS=${CFLAGS:-"-g -O3"} make test
else
set -v
CXX=${CXX:-clang++} CFLAGS=${CFLAGS:-"-O3 -fsanitize=undefined -Wno-tautological-constant-out-of-range-compare"} make ${2:-valgrind}

View File

@ -25,15 +25,15 @@ def editor-event-loop screen:address:shared:screen, console:address:shared:conso
break-if quit? # only in tests
trace 10, [app], [next-event]
# 'touch' event
t:address:touch-event <- maybe-convert e, touch:variant
t:touch-event, is-touch?:boolean <- maybe-convert e, touch:variant
{
break-unless t
move-cursor-in-editor screen, editor, *t
break-unless is-touch?
move-cursor-in-editor screen, editor, t
loop +next-event:label
}
# keyboard events
{
break-if t
break-if is-touch?
screen, editor, go-render?:boolean <- handle-keyboard-event screen, editor, e
{
break-unless go-render?
@ -177,24 +177,24 @@ def handle-keyboard-event screen:address:shared:screen, editor:address:shared:ed
save-column:number <- copy cursor-column
# character
{
c:address:character <- maybe-convert e, text:variant
break-unless c
c:character, is-unicode?:boolean <- maybe-convert e, text:variant
break-unless is-unicode?
trace 10, [app], [handle-keyboard-event: special character]
# exceptions for special characters go here
<handle-special-character>
# ignore any other special characters
regular-character?:boolean <- greater-or-equal *c, 32/space
regular-character?:boolean <- greater-or-equal c, 32/space
go-render? <- copy 0/false
return-unless regular-character?
# otherwise type it in
<insert-character-begin>
editor, screen, go-render?:boolean <- insert-at-cursor editor, *c, screen
editor, screen, go-render?:boolean <- insert-at-cursor editor, c, screen
<insert-character-end>
return
}
# special key to modify the text or move the cursor
k:address:number <- maybe-convert e:event, keycode:variant
assert k, [event was of unknown type; neither keyboard nor mouse]
k:number, is-keycode?:boolean <- maybe-convert e:event, keycode:variant
assert is-keycode?, [event was of unknown type; neither keyboard nor mouse]
# handlers for each special key will go here
<handle-special-key>
go-render? <- copy 1/true
@ -821,7 +821,7 @@ scenario editor-moves-cursor-down-after-inserting-newline [
after <handle-special-character> [
{
newline?:boolean <- equal *c, 10/newline
newline?:boolean <- equal c, 10/newline
break-unless newline?
<insert-enter-begin>
editor <- insert-new-line-and-indent editor, screen
@ -1003,7 +1003,7 @@ ef]
after <handle-special-key> [
{
paste-start?:boolean <- equal *k, 65507/paste-start
paste-start?:boolean <- equal k, 65507/paste-start
break-unless paste-start?
*editor <- put *editor, indent?:offset, 0/false
go-render? <- copy 1/true
@ -1013,7 +1013,7 @@ after <handle-special-key> [
after <handle-special-key> [
{
paste-end?:boolean <- equal *k, 65506/paste-end
paste-end?:boolean <- equal k, 65506/paste-end
break-unless paste-end?
*editor <- put *editor, indent?:offset, 1/true
go-render? <- copy 1/true

View File

@ -25,7 +25,7 @@ cd]
after <handle-special-character> [
{
tab?:boolean <- equal *c, 9/tab
tab?:boolean <- equal c, 9/tab
break-unless tab?
<insert-character-begin>
editor, screen, go-render?:boolean <- insert-at-cursor editor, 32/space, screen
@ -68,7 +68,7 @@ scenario editor-handles-backspace-key [
after <handle-special-character> [
{
delete-previous-character?:boolean <- equal *c, 8/backspace
delete-previous-character?:boolean <- equal c, 8/backspace
break-unless delete-previous-character?
<backspace-character-begin>
editor, screen, go-render?:boolean, backspaced-cell:address:shared:duplex-list:character <- delete-before-cursor editor, screen
@ -339,7 +339,7 @@ scenario editor-handles-delete-key [
after <handle-special-key> [
{
delete-next-character?:boolean <- equal *k, 65522/delete
delete-next-character?:boolean <- equal k, 65522/delete
break-unless delete-next-character?
<delete-character-begin>
editor, screen, go-render?:boolean, deleted-cell:address:shared:duplex-list:character <- delete-at-cursor editor, screen
@ -415,7 +415,7 @@ scenario editor-moves-cursor-right-with-key [
after <handle-special-key> [
{
move-to-next-character?:boolean <- equal *k, 65514/right-arrow
move-to-next-character?:boolean <- equal k, 65514/right-arrow
break-unless move-to-next-character?
# if not at end of text
next-cursor:address:shared:duplex-list:character <- next before-cursor
@ -699,7 +699,7 @@ scenario editor-moves-cursor-left-with-key [
after <handle-special-key> [
{
move-to-previous-character?:boolean <- equal *k, 65515/left-arrow
move-to-previous-character?:boolean <- equal k, 65515/left-arrow
break-unless move-to-previous-character?
trace 10, [app], [left arrow]
# if not at start of text (before-cursor at § sentinel)
@ -963,7 +963,7 @@ def]
after <handle-special-key> [
{
move-to-previous-line?:boolean <- equal *k, 65517/up-arrow
move-to-previous-line?:boolean <- equal k, 65517/up-arrow
break-unless move-to-previous-line?
<move-cursor-begin>
editor, go-render? <- move-to-previous-line editor
@ -1193,7 +1193,7 @@ def]
after <handle-special-key> [
{
move-to-next-line?:boolean <- equal *k, 65516/down-arrow
move-to-next-line?:boolean <- equal k, 65516/down-arrow
break-unless move-to-next-line?
<move-cursor-begin>
editor, go-render? <- move-to-next-line editor, screen-height
@ -1324,7 +1324,7 @@ scenario editor-moves-to-start-of-line-with-ctrl-a [
after <handle-special-character> [
{
move-to-start-of-line?:boolean <- equal *c, 1/ctrl-a
move-to-start-of-line?:boolean <- equal c, 1/ctrl-a
break-unless move-to-start-of-line?
<move-cursor-begin>
move-to-start-of-line editor
@ -1337,7 +1337,7 @@ after <handle-special-character> [
after <handle-special-key> [
{
move-to-start-of-line?:boolean <- equal *k, 65521/home
move-to-start-of-line?:boolean <- equal k, 65521/home
break-unless move-to-start-of-line?
<move-cursor-begin>
move-to-start-of-line editor
@ -1496,7 +1496,7 @@ scenario editor-moves-to-end-of-line-with-ctrl-e [
after <handle-special-character> [
{
move-to-end-of-line?:boolean <- equal *c, 5/ctrl-e
move-to-end-of-line?:boolean <- equal c, 5/ctrl-e
break-unless move-to-end-of-line?
<move-cursor-begin>
move-to-end-of-line editor
@ -1509,7 +1509,7 @@ after <handle-special-character> [
after <handle-special-key> [
{
move-to-end-of-line?:boolean <- equal *k, 65520/end
move-to-end-of-line?:boolean <- equal k, 65520/end
break-unless move-to-end-of-line?
<move-cursor-begin>
move-to-end-of-line editor
@ -1642,7 +1642,7 @@ scenario editor-deletes-to-start-of-line-with-ctrl-u [
after <handle-special-character> [
{
delete-to-start-of-line?:boolean <- equal *c, 21/ctrl-u
delete-to-start-of-line?:boolean <- equal c, 21/ctrl-u
break-unless delete-to-start-of-line?
<delete-to-start-of-line-begin>
deleted-cells:address:shared:duplex-list:character <- delete-to-start-of-line editor
@ -1776,7 +1776,7 @@ scenario editor-deletes-to-end-of-line-with-ctrl-k [
after <handle-special-character> [
{
delete-to-end-of-line?:boolean <- equal *c, 11/ctrl-k
delete-to-end-of-line?:boolean <- equal c, 11/ctrl-k
break-unless delete-to-end-of-line?
<delete-to-end-of-line-begin>
deleted-cells:address:shared:duplex-list:character <- delete-to-end-of-line editor
@ -2718,7 +2718,7 @@ d]
after <handle-special-character> [
{
page-down?:boolean <- equal *c, 6/ctrl-f
page-down?:boolean <- equal c, 6/ctrl-f
break-unless page-down?
old-top:address:shared:duplex-list:character <- get *editor, top-of-screen:offset
<move-cursor-begin>
@ -2734,7 +2734,7 @@ after <handle-special-character> [
after <handle-special-key> [
{
page-down?:boolean <- equal *k, 65518/page-down
page-down?:boolean <- equal k, 65518/page-down
break-unless page-down?
old-top:address:shared:duplex-list:character <- get *editor, top-of-screen:offset
<move-cursor-begin>
@ -2912,7 +2912,7 @@ d]
after <handle-special-character> [
{
page-up?:boolean <- equal *c, 2/ctrl-b
page-up?:boolean <- equal c, 2/ctrl-b
break-unless page-up?
old-top:address:shared:duplex-list:character <- get *editor, top-of-screen:offset
<move-cursor-begin>
@ -2928,7 +2928,7 @@ after <handle-special-character> [
after <handle-special-key> [
{
page-up?:boolean <- equal *k, 65519/page-up
page-up?:boolean <- equal k, 65519/page-up
break-unless page-up?
old-top:address:shared:duplex-list:character <- get *editor, top-of-screen:offset
<move-cursor-begin>

View File

@ -68,29 +68,29 @@ def event-loop screen:address:shared:screen, console:address:shared:console, env
<handle-event>
# check for global events that will trigger regardless of which editor has focus
{
k:address:number <- maybe-convert e:event, keycode:variant
break-unless k
k:number, is-keycode?:boolean <- maybe-convert e:event, keycode:variant
break-unless is-keycode?
<global-keypress>
}
{
c:address:character <- maybe-convert e:event, text:variant
break-unless c
c:character, is-unicode?:boolean <- maybe-convert e:event, text:variant
break-unless is-unicode?
<global-type>
}
# 'touch' event - send to both sides, see what picks it up
{
t:address:touch-event <- maybe-convert e:event, touch:variant
break-unless t
t:touch-event, is-touch?:boolean <- maybe-convert e:event, touch:variant
break-unless is-touch?
# ignore all but 'left-click' events for now
# todo: test this
touch-type:number <- get *t, type:offset
touch-type:number <- get t, type:offset
is-left-click?:boolean <- equal touch-type, 65513/mouse-left
loop-unless is-left-click?, +next-event:label
# later exceptions for non-editor touches will go here
<global-touch>
# send to both editors
_ <- move-cursor-in-editor screen, recipes, *t
sandbox-in-focus?:boolean <- move-cursor-in-editor screen, current-sandbox, *t
_ <- move-cursor-in-editor screen, recipes, t
sandbox-in-focus?:boolean <- move-cursor-in-editor screen, current-sandbox, t
*env <- put *env, sandbox-in-focus?:offset, sandbox-in-focus?
screen <- update-cursor screen, recipes, current-sandbox, sandbox-in-focus?, env
loop +next-event:label
@ -98,8 +98,8 @@ def event-loop screen:address:shared:screen, console:address:shared:console, env
# 'resize' event - redraw editor
# todo: test this after supporting resize in assume-console
{
r:address:resize-event <- maybe-convert e:event, resize:variant
break-unless r
r:resize-event, is-resize?:boolean <- maybe-convert e:event, resize:variant
break-unless is-resize?
# if more events, we're still resizing; wait until we stop
more-events?:boolean <- has-more-events? console
{
@ -582,7 +582,7 @@ def render-code screen:address:shared:screen, s:address:shared:array:character,
after <global-type> [
{
redraw-screen?:boolean <- equal *c, 12/ctrl-l
redraw-screen?:boolean <- equal c, 12/ctrl-l
break-unless redraw-screen?
screen <- render-all screen, env:address:shared:programming-environment-data
sync-screen screen
@ -595,7 +595,7 @@ after <global-type> [
after <global-type> [
{
switch-side?:boolean <- equal *c, 14/ctrl-n
switch-side?:boolean <- equal c, 14/ctrl-n
break-unless switch-side?
sandbox-in-focus?:boolean <- get *env, sandbox-in-focus?:offset
sandbox-in-focus? <- not sandbox-in-focus?

View File

@ -124,7 +124,7 @@ scenario run-and-show-results [
after <global-keypress> [
# F4? load all code and run all sandboxes.
{
do-run?:boolean <- equal *k, 65532/F4
do-run?:boolean <- equal k, 65532/F4
break-unless do-run?
screen <- update-status screen, [running... ], 245/grey
error?:boolean, env, screen <- run-sandboxes env, screen
@ -614,7 +614,7 @@ scenario scrolling-down-past-bottom-of-sandbox-editor [
after <global-keypress> [
{
break-unless sandbox-in-focus?
down?:boolean <- equal *k, 65516/down-arrow
down?:boolean <- equal k, 65516/down-arrow
break-unless down?
sandbox-bottom:number <- get *current-sandbox, bottom:offset
sandbox-cursor:number <- get *current-sandbox, cursor-row:offset
@ -656,7 +656,7 @@ after <update-cursor-special-cases> [
after <global-keypress> [
{
break-unless sandbox-in-focus?
up?:boolean <- equal *k, 65517/up-arrow
up?:boolean <- equal k, 65517/up-arrow
break-unless up?
render-from:number <- get *env, render-from:offset
at-beginning?:boolean <- equal render-from, -1

View File

@ -66,13 +66,13 @@ after <global-touch> [
# below sandbox editor? pop appropriate sandbox contents back into sandbox editor
{
sandbox-left-margin:number <- get *current-sandbox, left:offset
click-column:number <- get *t, column:offset
click-column:number <- get t, column:offset
on-sandbox-side?:boolean <- greater-or-equal click-column, sandbox-left-margin
break-unless on-sandbox-side?
first-sandbox:address:shared:sandbox-data <- get *env, sandbox:offset
break-unless first-sandbox
first-sandbox-begins:number <- get *first-sandbox, starting-row-on-screen:offset
click-row:number <- get *t, row:offset
click-row:number <- get t, row:offset
below-sandbox-editor?:boolean <- greater-or-equal click-row, first-sandbox-begins
break-unless below-sandbox-editor?
empty-sandbox-editor?:boolean <- empty-editor? current-sandbox

View File

@ -67,7 +67,7 @@ scenario deleting-sandboxes [
after <global-touch> [
# on a sandbox delete icon? process delete
{
was-delete?:boolean <- delete-sandbox *t, env
was-delete?:boolean <- delete-sandbox t, env
break-unless was-delete?
hide-screen screen
screen <- render-sandbox-side screen, env

View File

@ -107,13 +107,13 @@ after <global-touch> [
# check if it's inside the output of any sandbox
{
sandbox-left-margin:number <- get *current-sandbox, left:offset
click-column:number <- get *t, column:offset
click-column:number <- get t, column:offset
on-sandbox-side?:boolean <- greater-or-equal click-column, sandbox-left-margin
break-unless on-sandbox-side?
first-sandbox:address:shared:sandbox-data <- get *env, sandbox:offset
break-unless first-sandbox
first-sandbox-begins:number <- get *first-sandbox, starting-row-on-screen:offset
click-row:number <- get *t, row:offset
click-row:number <- get t, row:offset
below-sandbox-editor?:boolean <- greater-or-equal click-row, first-sandbox-begins
break-unless below-sandbox-editor?
# identify the sandbox whose output is being clicked on

View File

@ -142,13 +142,13 @@ after <global-touch> [
# check if it's inside the code of any sandbox
{
sandbox-left-margin:number <- get *current-sandbox, left:offset
click-column:number <- get *t, column:offset
click-column:number <- get t, column:offset
on-sandbox-side?:boolean <- greater-or-equal click-column, sandbox-left-margin
break-unless on-sandbox-side?
first-sandbox:address:shared:sandbox-data <- get *env, sandbox:offset
break-unless first-sandbox
first-sandbox-begins:number <- get *first-sandbox, starting-row-on-screen:offset
click-row:number <- get *t, row:offset
click-row:number <- get t, row:offset
below-sandbox-editor?:boolean <- greater-or-equal click-row, first-sandbox-begins
break-unless below-sandbox-editor?
# identify the sandbox whose code is being clicked on

View File

@ -63,7 +63,7 @@ container editor-data [
# ctrl-z - undo operation
after <handle-special-character> [
{
undo?:boolean <- equal *c, 26/ctrl-z
undo?:boolean <- equal c, 26/ctrl-z
break-unless undo?
undo:address:shared:list:address:shared:operation <- get *editor, undo:offset
break-unless undo
@ -81,7 +81,7 @@ after <handle-special-character> [
# ctrl-y - redo operation
after <handle-special-character> [
{
redo?:boolean <- equal *c, 25/ctrl-y
redo?:boolean <- equal c, 25/ctrl-y
break-unless redo?
redo:address:shared:list:address:shared:operation <- get *editor, redo:offset
break-unless redo
@ -151,16 +151,17 @@ before <insert-character-end> [
# if previous operation was an insert, coalesce this operation with it
break-unless undo
op:address:shared:operation <- first undo
typing:address:insert-operation <- maybe-convert *op, typing:variant
break-unless typing
previous-coalesce-tag:number <- get *typing, tag:offset
typing:insert-operation, is-insert?:boolean <- maybe-convert *op, typing:variant
break-unless is-insert?
previous-coalesce-tag:number <- get typing, tag:offset
break-unless previous-coalesce-tag
before-cursor:address:shared:duplex-list:character <- get *editor, before-cursor:offset
insert-until:address:shared:duplex-list:character <- next before-cursor
*typing <- put *typing, insert-until:offset, insert-until
*typing <- put *typing, after-row:offset, cursor-row
*typing <- put *typing, after-column:offset, cursor-column
*typing <- put *typing, after-top-of-screen:offset, top-after
typing <- put typing, insert-until:offset, insert-until
typing <- put typing, after-row:offset, cursor-row
typing <- put typing, after-column:offset, cursor-column
typing <- put typing, after-top-of-screen:offset, top-after
*op <- merge 0/insert-operation, typing
break +done-adding-insert-operation:label
}
# if not, create a new operation
@ -210,19 +211,19 @@ def add-operation editor:address:shared:editor-data, op:address:shared:operation
after <handle-undo> [
{
typing:address:insert-operation <- maybe-convert *op, typing:variant
break-unless typing
start:address:shared:duplex-list:character <- get *typing, insert-from:offset
end:address:shared:duplex-list:character <- get *typing, insert-until:offset
typing:insert-operation, is-insert?:boolean <- maybe-convert *op, typing:variant
break-unless is-insert?
start:address:shared:duplex-list:character <- get typing, insert-from:offset
end:address:shared:duplex-list:character <- get typing, insert-until:offset
# assert cursor-row/cursor-column/top-of-screen match after-row/after-column/after-top-of-screen
before-cursor:address:shared:duplex-list:character <- prev start
*editor <- put *editor, before-cursor:offset, before-cursor
remove-between before-cursor, end
cursor-row <- get *typing, before-row:offset
cursor-row <- get typing, before-row:offset
*editor <- put *editor, cursor-row:offset, cursor-row
cursor-column <- get *typing, before-column:offset
cursor-column <- get typing, before-column:offset
*editor <- put *editor, cursor-column:offset, cursor-column
top:address:shared:duplex-list:character <- get *typing, before-top-of-screen:offset
top:address:shared:duplex-list:character <- get typing, before-top-of-screen:offset
*editor <- put *editor, top-of-screen:offset, top
}
]
@ -410,18 +411,18 @@ scenario editor-redo-typing [
after <handle-redo> [
{
typing:address:insert-operation <- maybe-convert *op, typing:variant
break-unless typing
typing:insert-operation, is-insert?:boolean <- maybe-convert *op, typing:variant
break-unless is-insert?
before-cursor <- get *editor, before-cursor:offset
insert-from:address:shared:duplex-list:character <- get *typing, insert-from:offset # ignore insert-to because it's already been spliced away
insert-from:address:shared:duplex-list:character <- get typing, insert-from:offset # ignore insert-to because it's already been spliced away
# assert insert-to matches next(before-cursor)
insert-range before-cursor, insert-from
# assert cursor-row/cursor-column/top-of-screen match after-row/after-column/after-top-of-screen
cursor-row <- get *typing, after-row:offset
cursor-row <- get typing, after-row:offset
*editor <- put *editor, cursor-row:offset, cursor-row
cursor-column <- get *typing, after-column:offset
cursor-column <- get typing, after-column:offset
*editor <- put *editor, cursor-column:offset, cursor-column
top:address:shared:duplex-list:character <- get *typing, after-top-of-screen:offset
top:address:shared:duplex-list:character <- get typing, after-top-of-screen:offset
*editor <- put *editor, top-of-screen:offset, top
}
]
@ -730,14 +731,15 @@ before <move-cursor-end> [
undo:address:shared:list:address:shared:operation <- get *editor, undo:offset
break-unless undo
op:address:shared:operation <- first undo
move:address:move-operation <- maybe-convert *op, move:variant
break-unless move
previous-coalesce-tag:number <- get *move, tag:offset
move:move-operation, is-move?:boolean <- maybe-convert *op, move:variant
break-unless is-move?
previous-coalesce-tag:number <- get move, tag:offset
coalesce?:boolean <- equal undo-coalesce-tag, previous-coalesce-tag
break-unless coalesce?
*move <- put *move, after-row:offset, cursor-row
*move <- put *move, after-column:offset, cursor-column
*move <- put *move, after-top-of-screen:offset, top-after
move <- put move, after-row:offset, cursor-row
move <- put move, after-column:offset, cursor-column
move <- put move, after-top-of-screen:offset, top-after
*op <- merge 1/move-operation, move
break +done-adding-move-operation:label
}
op:address:shared:operation <- new operation:type
@ -748,14 +750,14 @@ before <move-cursor-end> [
after <handle-undo> [
{
move:address:move-operation <- maybe-convert *op, move:variant
break-unless move
move:move-operation, is-move?:boolean <- maybe-convert *op, move:variant
break-unless is-move?
# assert cursor-row/cursor-column/top-of-screen match after-row/after-column/after-top-of-screen
cursor-row <- get *move, before-row:offset
cursor-row <- get move, before-row:offset
*editor <- put *editor, cursor-row:offset, cursor-row
cursor-column <- get *move, before-column:offset
cursor-column <- get move, before-column:offset
*editor <- put *editor, cursor-column:offset, cursor-column
top:address:shared:duplex-list:character <- get *move, before-top-of-screen:offset
top:address:shared:duplex-list:character <- get move, before-top-of-screen:offset
*editor <- put *editor, top-of-screen:offset, top
}
]
@ -1378,14 +1380,14 @@ ghi]
after <handle-redo> [
{
move:address:move-operation <- maybe-convert *op, move:variant
break-unless move
move:move-operation, is-move?:boolean <- maybe-convert *op, move:variant
break-unless is-move?
# assert cursor-row/cursor-column/top-of-screen match after-row/after-column/after-top-of-screen
cursor-row <- get *move, after-row:offset
cursor-row <- get move, after-row:offset
*editor <- put *editor, cursor-row:offset, cursor-row
cursor-column <- get *move, after-column:offset
cursor-column <- get move, after-column:offset
*editor <- put *editor, cursor-column:offset, cursor-column
top:address:shared:duplex-list:character <- get *move, after-top-of-screen:offset
top:address:shared:duplex-list:character <- get move, after-top-of-screen:offset
*editor <- put *editor, top-of-screen:offset, top
}
]
@ -1620,18 +1622,19 @@ before <backspace-character-end> [
# if previous operation was an insert, coalesce this operation with it
break-unless *undo
op:address:shared:operation <- first undo
deletion:address:delete-operation <- maybe-convert *op, delete:variant
break-unless deletion
previous-coalesce-tag:number <- get *deletion, tag:offset
deletion:delete-operation, is-delete?:boolean <- maybe-convert *op, delete:variant
break-unless is-delete?
previous-coalesce-tag:number <- get deletion, tag:offset
coalesce?:boolean <- equal previous-coalesce-tag, 1/coalesce-backspace
break-unless coalesce?
*deletion <- put *deletion, delete-from:offset, before-cursor
backspaced-so-far:address:shared:duplex-list:character <- get *deletion, deleted-text:offset
deletion <- put deletion, delete-from:offset, before-cursor
backspaced-so-far:address:shared:duplex-list:character <- get deletion, deleted-text:offset
insert-range backspaced-cell, backspaced-so-far
*deletion <- put *deletion, deleted-text:offset, backspaced-cell
*deletion <- put *deletion, after-row:offset, cursor-row
*deletion <- put *deletion, after-column:offset, cursor-column
*deletion <- put *deletion, after-top-of-screen:offset, top-after
deletion <- put deletion, deleted-text:offset, backspaced-cell
deletion <- put deletion, after-row:offset, cursor-row
deletion <- put deletion, after-column:offset, cursor-column
deletion <- put deletion, after-top-of-screen:offset, top-after
*op <- merge 2/delete-operation, deletion
break +done-adding-backspace-operation:label
}
# if not, create a new operation
@ -1645,38 +1648,38 @@ before <backspace-character-end> [
after <handle-undo> [
{
deletion:address:delete-operation <- maybe-convert *op, delete:variant
break-unless deletion
anchor:address:shared:duplex-list:character <- get *deletion, delete-from:offset
deletion:delete-operation, is-delete?:boolean <- maybe-convert *op, delete:variant
break-unless is-delete?
anchor:address:shared:duplex-list:character <- get deletion, delete-from:offset
break-unless anchor
deleted:address:shared:duplex-list:character <- get *deletion, deleted-text:offset
deleted:address:shared:duplex-list:character <- get deletion, deleted-text:offset
old-cursor:address:shared:duplex-list:character <- last deleted
insert-range anchor, deleted
# assert cursor-row/cursor-column/top-of-screen match after-row/after-column/after-top-of-screen
before-cursor <- copy old-cursor
cursor-row <- get *deletion, before-row:offset
cursor-row <- get deletion, before-row:offset
*editor <- put *editor, cursor-row:offset, cursor-row
cursor-column <- get *deletion, before-column:offset
cursor-column <- get deletion, before-column:offset
*editor <- put *editor, cursor-column:offset, cursor-column
top:address:shared:duplex-list:character <- get *deletion, before-top-of-screen:offset
top:address:shared:duplex-list:character <- get deletion, before-top-of-screen:offset
*editor <- put *editor, top-of-screen:offset, top
}
]
after <handle-redo> [
{
deletion:address:delete-operation <- maybe-convert *op, delete:variant
break-unless deletion
start:address:shared:duplex-list:character <- get *deletion, delete-from:offset
end:address:shared:duplex-list:character <- get *deletion, delete-until:offset
deletion:delete-operation, is-delete?:boolean <- maybe-convert *op, delete:variant
break-unless is-delete?
start:address:shared:duplex-list:character <- get deletion, delete-from:offset
end:address:shared:duplex-list:character <- get deletion, delete-until:offset
data:address:shared:duplex-list:character <- get *editor, data:offset
remove-between start, end
# assert cursor-row/cursor-column/top-of-screen match after-row/after-column/after-top-of-screen
cursor-row <- get *deletion, after-row:offset
cursor-row <- get deletion, after-row:offset
*editor <- put *editor, cursor-row:offset, cursor-row
cursor-column <- get *deletion, after-column:offset
cursor-column <- get deletion, after-column:offset
*editor <- put *editor, cursor-column:offset, cursor-column
top:address:shared:duplex-list:character <- get *deletion, before-top-of-screen:offset
top:address:shared:duplex-list:character <- get deletion, before-top-of-screen:offset
*editor <- put *editor, top-of-screen:offset, top
}
]
@ -1845,19 +1848,20 @@ before <delete-character-end> [
# if previous operation was an insert, coalesce this operation with it
break-unless undo
op:address:shared:operation <- first undo
deletion:address:delete-operation <- maybe-convert *op, delete:variant
break-unless deletion
previous-coalesce-tag:number <- get *deletion, tag:offset
deletion:delete-operation, is-delete?:boolean <- maybe-convert *op, delete:variant
break-unless is-delete?
previous-coalesce-tag:number <- get deletion, tag:offset
coalesce?:boolean <- equal previous-coalesce-tag, 2/coalesce-delete
break-unless coalesce?
delete-until:address:shared:duplex-list:character <- next before-cursor
*deletion <- put *deletion, delete-until:offset, delete-until
deleted-so-far:address:shared:duplex-list:character <- get *deletion, deleted-text:offset
deletion <- put deletion, delete-until:offset, delete-until
deleted-so-far:address:shared:duplex-list:character <- get deletion, deleted-text:offset
deleted-so-far <- append deleted-so-far, deleted-cell
*deletion <- put *deletion, deleted-text:offset, deleted-so-far
*deletion <- put *deletion, after-row:offset, cursor-row
*deletion <- put *deletion, after-column:offset, cursor-column
*deletion <- put *deletion, after-top-of-screen:offset, top-after
deletion <- put deletion, deleted-text:offset, deleted-so-far
deletion <- put deletion, after-row:offset, cursor-row
deletion <- put deletion, after-column:offset, cursor-column
deletion <- put deletion, after-top-of-screen:offset, top-after
*op <- merge 2/delete-operation, deletion
break +done-adding-delete-operation:label
}
# if not, create a new operation

View File

@ -25,15 +25,15 @@ def editor-event-loop screen:address:shared:screen, console:address:shared:conso
break-if quit? # only in tests
trace 10, [app], [next-event]
# 'touch' event
t:address:touch-event <- maybe-convert e, touch:variant
t:touch-event, is-touch?:boolean <- maybe-convert e, touch:variant
{
break-unless t
move-cursor-in-editor screen, editor, *t
break-unless is-touch?
move-cursor-in-editor screen, editor, t
loop +next-event:label
}
# keyboard events
{
break-if t
break-if is-touch?
screen, editor, go-render?:boolean <- handle-keyboard-event screen, editor, e
{
break-unless go-render?
@ -177,24 +177,24 @@ def handle-keyboard-event screen:address:shared:screen, editor:address:shared:ed
save-column:number <- copy cursor-column
# character
{
c:address:character <- maybe-convert e, text:variant
break-unless c
c:character, is-unicode?:boolean <- maybe-convert e, text:variant
break-unless is-unicode?
trace 10, [app], [handle-keyboard-event: special character]
# exceptions for special characters go here
<handle-special-character>
# ignore any other special characters
regular-character?:boolean <- greater-or-equal *c, 32/space
regular-character?:boolean <- greater-or-equal c, 32/space
go-render? <- copy 0/false
return-unless regular-character?
# otherwise type it in
<insert-character-begin>
editor, screen, go-render?:boolean <- insert-at-cursor editor, *c, screen
editor, screen, go-render?:boolean <- insert-at-cursor editor, c, screen
<insert-character-end>
return
}
# special key to modify the text or move the cursor
k:address:number <- maybe-convert e:event, keycode:variant
assert k, [event was of unknown type; neither keyboard nor mouse]
k:number, is-keycode?:boolean <- maybe-convert e:event, keycode:variant
assert is-keycode?, [event was of unknown type; neither keyboard nor mouse]
# handlers for each special key will go here
<handle-special-key>
go-render? <- copy 1/true
@ -821,7 +821,7 @@ scenario editor-moves-cursor-down-after-inserting-newline [
after <handle-special-character> [
{
newline?:boolean <- equal *c, 10/newline
newline?:boolean <- equal c, 10/newline
break-unless newline?
<insert-enter-begin>
editor <- insert-new-line-and-indent editor, screen
@ -1003,7 +1003,7 @@ ef]
after <handle-special-key> [
{
paste-start?:boolean <- equal *k, 65507/paste-start
paste-start?:boolean <- equal k, 65507/paste-start
break-unless paste-start?
*editor <- put *editor, indent?:offset, 0/false
go-render? <- copy 1/true
@ -1013,7 +1013,7 @@ after <handle-special-key> [
after <handle-special-key> [
{
paste-end?:boolean <- equal *k, 65506/paste-end
paste-end?:boolean <- equal k, 65506/paste-end
break-unless paste-end?
*editor <- put *editor, indent?:offset, 1/true
go-render? <- copy 1/true

View File

@ -25,7 +25,7 @@ cd]
after <handle-special-character> [
{
tab?:boolean <- equal *c, 9/tab
tab?:boolean <- equal c, 9/tab
break-unless tab?
<insert-character-begin>
editor, screen, go-render?:boolean <- insert-at-cursor editor, 32/space, screen
@ -68,7 +68,7 @@ scenario editor-handles-backspace-key [
after <handle-special-character> [
{
delete-previous-character?:boolean <- equal *c, 8/backspace
delete-previous-character?:boolean <- equal c, 8/backspace
break-unless delete-previous-character?
<backspace-character-begin>
editor, screen, go-render?:boolean, backspaced-cell:address:shared:duplex-list:character <- delete-before-cursor editor, screen
@ -339,7 +339,7 @@ scenario editor-handles-delete-key [
after <handle-special-key> [
{
delete-next-character?:boolean <- equal *k, 65522/delete
delete-next-character?:boolean <- equal k, 65522/delete
break-unless delete-next-character?
<delete-character-begin>
editor, screen, go-render?:boolean, deleted-cell:address:shared:duplex-list:character <- delete-at-cursor editor, screen
@ -415,7 +415,7 @@ scenario editor-moves-cursor-right-with-key [
after <handle-special-key> [
{
move-to-next-character?:boolean <- equal *k, 65514/right-arrow
move-to-next-character?:boolean <- equal k, 65514/right-arrow
break-unless move-to-next-character?
# if not at end of text
next-cursor:address:shared:duplex-list:character <- next before-cursor
@ -699,7 +699,7 @@ scenario editor-moves-cursor-left-with-key [
after <handle-special-key> [
{
move-to-previous-character?:boolean <- equal *k, 65515/left-arrow
move-to-previous-character?:boolean <- equal k, 65515/left-arrow
break-unless move-to-previous-character?
trace 10, [app], [left arrow]
# if not at start of text (before-cursor at § sentinel)
@ -963,7 +963,7 @@ def]
after <handle-special-key> [
{
move-to-previous-line?:boolean <- equal *k, 65517/up-arrow
move-to-previous-line?:boolean <- equal k, 65517/up-arrow
break-unless move-to-previous-line?
<move-cursor-begin>
editor, go-render? <- move-to-previous-line editor
@ -1193,7 +1193,7 @@ def]
after <handle-special-key> [
{
move-to-next-line?:boolean <- equal *k, 65516/down-arrow
move-to-next-line?:boolean <- equal k, 65516/down-arrow
break-unless move-to-next-line?
<move-cursor-begin>
editor, go-render? <- move-to-next-line editor, screen-height
@ -1324,7 +1324,7 @@ scenario editor-moves-to-start-of-line-with-ctrl-a [
after <handle-special-character> [
{
move-to-start-of-line?:boolean <- equal *c, 1/ctrl-a
move-to-start-of-line?:boolean <- equal c, 1/ctrl-a
break-unless move-to-start-of-line?
<move-cursor-begin>
move-to-start-of-line editor
@ -1337,7 +1337,7 @@ after <handle-special-character> [
after <handle-special-key> [
{
move-to-start-of-line?:boolean <- equal *k, 65521/home
move-to-start-of-line?:boolean <- equal k, 65521/home
break-unless move-to-start-of-line?
<move-cursor-begin>
move-to-start-of-line editor
@ -1496,7 +1496,7 @@ scenario editor-moves-to-end-of-line-with-ctrl-e [
after <handle-special-character> [
{
move-to-end-of-line?:boolean <- equal *c, 5/ctrl-e
move-to-end-of-line?:boolean <- equal c, 5/ctrl-e
break-unless move-to-end-of-line?
<move-cursor-begin>
move-to-end-of-line editor
@ -1509,7 +1509,7 @@ after <handle-special-character> [
after <handle-special-key> [
{
move-to-end-of-line?:boolean <- equal *k, 65520/end
move-to-end-of-line?:boolean <- equal k, 65520/end
break-unless move-to-end-of-line?
<move-cursor-begin>
move-to-end-of-line editor
@ -1642,7 +1642,7 @@ scenario editor-deletes-to-start-of-line-with-ctrl-u [
after <handle-special-character> [
{
delete-to-start-of-line?:boolean <- equal *c, 21/ctrl-u
delete-to-start-of-line?:boolean <- equal c, 21/ctrl-u
break-unless delete-to-start-of-line?
<delete-to-start-of-line-begin>
deleted-cells:address:shared:duplex-list:character <- delete-to-start-of-line editor
@ -1776,7 +1776,7 @@ scenario editor-deletes-to-end-of-line-with-ctrl-k [
after <handle-special-character> [
{
delete-to-end-of-line?:boolean <- equal *c, 11/ctrl-k
delete-to-end-of-line?:boolean <- equal c, 11/ctrl-k
break-unless delete-to-end-of-line?
<delete-to-end-of-line-begin>
deleted-cells:address:shared:duplex-list:character <- delete-to-end-of-line editor
@ -2718,7 +2718,7 @@ d]
after <handle-special-character> [
{
page-down?:boolean <- equal *c, 6/ctrl-f
page-down?:boolean <- equal c, 6/ctrl-f
break-unless page-down?
old-top:address:shared:duplex-list:character <- get *editor, top-of-screen:offset
<move-cursor-begin>
@ -2734,7 +2734,7 @@ after <handle-special-character> [
after <handle-special-key> [
{
page-down?:boolean <- equal *k, 65518/page-down
page-down?:boolean <- equal k, 65518/page-down
break-unless page-down?
old-top:address:shared:duplex-list:character <- get *editor, top-of-screen:offset
<move-cursor-begin>
@ -2912,7 +2912,7 @@ d]
after <handle-special-character> [
{
page-up?:boolean <- equal *c, 2/ctrl-b
page-up?:boolean <- equal c, 2/ctrl-b
break-unless page-up?
old-top:address:shared:duplex-list:character <- get *editor, top-of-screen:offset
<move-cursor-begin>
@ -2928,7 +2928,7 @@ after <handle-special-character> [
after <handle-special-key> [
{
page-up?:boolean <- equal *k, 65519/page-up
page-up?:boolean <- equal k, 65519/page-up
break-unless page-up?
old-top:address:shared:duplex-list:character <- get *editor, top-of-screen:offset
<move-cursor-begin>

View File

@ -56,35 +56,35 @@ def event-loop screen:address:shared:screen, console:address:shared:console, env
<handle-event>
# check for global events that will trigger regardless of which editor has focus
{
k:address:number <- maybe-convert e:event, keycode:variant
break-unless k
k:number, is-keycode?:boolean <- maybe-convert e:event, keycode:variant
break-unless is-keycode?
<global-keypress>
}
{
c:address:character <- maybe-convert e:event, text:variant
break-unless c
c:character, is-unicode?:boolean <- maybe-convert e:event, text:variant
break-unless is-unicode?
<global-type>
}
# 'touch' event
{
t:address:touch-event <- maybe-convert e:event, touch:variant
break-unless t
t:touch-event, is-touch?:boolean <- maybe-convert e:event, touch:variant
break-unless is-touch?
# ignore all but 'left-click' events for now
# todo: test this
touch-type:number <- get *t, type:offset
touch-type:number <- get t, type:offset
is-left-click?:boolean <- equal touch-type, 65513/mouse-left
loop-unless is-left-click?, +next-event:label
# later exceptions for non-editor touches will go here
<global-touch>
move-cursor-in-editor screen, current-sandbox, *t
move-cursor-in-editor screen, current-sandbox, t
screen <- update-cursor screen, current-sandbox, env
loop +next-event:label
}
# 'resize' event - redraw editor
# todo: test this after supporting resize in assume-console
{
r:address:resize-event <- maybe-convert e:event, resize:variant
break-unless r
r:resize-event, is-resize?:boolean <- maybe-convert e:event, resize:variant
break-unless is-resize?
# if more events, we're still resizing; wait until we stop
more-events?:boolean <- has-more-events? console
{
@ -327,7 +327,7 @@ def render-code screen:address:shared:screen, s:address:shared:array:character,
after <global-type> [
{
redraw-screen?:boolean <- equal *c, 12/ctrl-l
redraw-screen?:boolean <- equal c, 12/ctrl-l
break-unless redraw-screen?
screen <- render-all screen, env:address:shared:programming-environment-data
sync-screen screen

View File

@ -109,7 +109,7 @@ scenario run-and-show-results [
after <global-keypress> [
# F4? load all code and run all sandboxes.
{
do-run?:boolean <- equal *k, 65532/F4
do-run?:boolean <- equal k, 65532/F4
break-unless do-run?
screen <- update-status screen, [running... ], 245/grey
test-recipes:address:shared:array:character, _/optional <- next-ingredient
@ -606,7 +606,7 @@ scenario scrolling-down-past-bottom-of-sandbox-editor [
# down on sandbox side updates render-from when sandbox editor has cursor at bottom
after <global-keypress> [
{
down?:boolean <- equal *k, 65516/down-arrow
down?:boolean <- equal k, 65516/down-arrow
break-unless down?
sandbox-bottom:number <- get *current-sandbox, bottom:offset
sandbox-cursor:number <- get *current-sandbox, cursor-row:offset
@ -646,7 +646,7 @@ after <update-cursor-special-cases> [
# 'up' on sandbox side is like 'down': updates first-sandbox-to-render when necessary
after <global-keypress> [
{
up?:boolean <- equal *k, 65517/up-arrow
up?:boolean <- equal k, 65517/up-arrow
break-unless up?
render-from:number <- get *env, render-from:offset
at-beginning?:boolean <- equal render-from, -1

View File

@ -67,13 +67,13 @@ after <global-touch> [
# below editor? pop appropriate sandbox contents back into sandbox editor provided it's empty
{
sandbox-left-margin:number <- get *current-sandbox, left:offset
click-column:number <- get *t, column:offset
click-column:number <- get t, column:offset
on-sandbox-side?:boolean <- greater-or-equal click-column, sandbox-left-margin
break-unless on-sandbox-side?
first-sandbox:address:shared:sandbox-data <- get *env, sandbox:offset
break-unless first-sandbox
first-sandbox-begins:number <- get *first-sandbox, starting-row-on-screen:offset
click-row:number <- get *t, row:offset
click-row:number <- get t, row:offset
below-sandbox-editor?:boolean <- greater-or-equal click-row, first-sandbox-begins
break-unless below-sandbox-editor?
empty-sandbox-editor?:boolean <- empty-editor? current-sandbox

View File

@ -66,7 +66,7 @@ scenario deleting-sandboxes [
after <global-touch> [
# on a sandbox delete icon? process delete
{
was-delete?:boolean <- delete-sandbox *t, env
was-delete?:boolean <- delete-sandbox t, env
break-unless was-delete?
hide-screen screen
screen <- render-sandbox-side screen, env

View File

@ -106,13 +106,13 @@ after <global-touch> [
# check if it's inside the output of any sandbox
{
sandbox-left-margin:number <- get *current-sandbox, left:offset
click-column:number <- get *t, column:offset
click-column:number <- get t, column:offset
on-sandbox-side?:boolean <- greater-or-equal click-column, sandbox-left-margin
break-unless on-sandbox-side?
first-sandbox:address:shared:sandbox-data <- get *env, sandbox:offset
break-unless first-sandbox
first-sandbox-begins:number <- get *first-sandbox, starting-row-on-screen:offset
click-row:number <- get *t, row:offset
click-row:number <- get t, row:offset
below-sandbox-editor?:boolean <- greater-or-equal click-row, first-sandbox-begins
break-unless below-sandbox-editor?
# identify the sandbox whose output is being clicked on

View File

@ -134,13 +134,13 @@ after <global-touch> [
# check if it's inside the code of any sandbox
{
sandbox-left-margin:number <- get *current-sandbox, left:offset
click-column:number <- get *t, column:offset
click-column:number <- get t, column:offset
on-sandbox-side?:boolean <- greater-or-equal click-column, sandbox-left-margin
break-unless on-sandbox-side?
first-sandbox:address:shared:sandbox-data <- get *env, sandbox:offset
break-unless first-sandbox
first-sandbox-begins:number <- get *first-sandbox, starting-row-on-screen:offset
click-row:number <- get *t, row:offset
click-row:number <- get t, row:offset
below-sandbox-editor?:boolean <- greater-or-equal click-row, first-sandbox-begins
break-unless below-sandbox-editor?
# identify the sandbox whose code is being clicked on

View File

@ -63,7 +63,7 @@ container editor-data [
# ctrl-z - undo operation
after <handle-special-character> [
{
undo?:boolean <- equal *c, 26/ctrl-z
undo?:boolean <- equal c, 26/ctrl-z
break-unless undo?
undo:address:shared:list:address:shared:operation <- get *editor, undo:offset
break-unless undo
@ -81,7 +81,7 @@ after <handle-special-character> [
# ctrl-y - redo operation
after <handle-special-character> [
{
redo?:boolean <- equal *c, 25/ctrl-y
redo?:boolean <- equal c, 25/ctrl-y
break-unless redo?
redo:address:shared:list:address:shared:operation <- get *editor, redo:offset
break-unless redo
@ -151,16 +151,17 @@ before <insert-character-end> [
# if previous operation was an insert, coalesce this operation with it
break-unless undo
op:address:shared:operation <- first undo
typing:address:insert-operation <- maybe-convert *op, typing:variant
break-unless typing
previous-coalesce-tag:number <- get *typing, tag:offset
typing:insert-operation, is-insert?:boolean <- maybe-convert *op, typing:variant
break-unless is-insert?
previous-coalesce-tag:number <- get typing, tag:offset
break-unless previous-coalesce-tag
before-cursor:address:shared:duplex-list:character <- get *editor, before-cursor:offset
insert-until:address:shared:duplex-list:character <- next before-cursor
*typing <- put *typing, insert-until:offset, insert-until
*typing <- put *typing, after-row:offset, cursor-row
*typing <- put *typing, after-column:offset, cursor-column
*typing <- put *typing, after-top-of-screen:offset, top-after
typing <- put typing, insert-until:offset, insert-until
typing <- put typing, after-row:offset, cursor-row
typing <- put typing, after-column:offset, cursor-column
typing <- put typing, after-top-of-screen:offset, top-after
*op <- merge 0/insert-operation, typing
break +done-adding-insert-operation:label
}
# if not, create a new operation
@ -210,19 +211,19 @@ def add-operation editor:address:shared:editor-data, op:address:shared:operation
after <handle-undo> [
{
typing:address:insert-operation <- maybe-convert *op, typing:variant
break-unless typing
start:address:shared:duplex-list:character <- get *typing, insert-from:offset
end:address:shared:duplex-list:character <- get *typing, insert-until:offset
typing:insert-operation, is-insert?:boolean <- maybe-convert *op, typing:variant
break-unless is-insert?
start:address:shared:duplex-list:character <- get typing, insert-from:offset
end:address:shared:duplex-list:character <- get typing, insert-until:offset
# assert cursor-row/cursor-column/top-of-screen match after-row/after-column/after-top-of-screen
before-cursor:address:shared:duplex-list:character <- prev start
*editor <- put *editor, before-cursor:offset, before-cursor
remove-between before-cursor, end
cursor-row <- get *typing, before-row:offset
cursor-row <- get typing, before-row:offset
*editor <- put *editor, cursor-row:offset, cursor-row
cursor-column <- get *typing, before-column:offset
cursor-column <- get typing, before-column:offset
*editor <- put *editor, cursor-column:offset, cursor-column
top:address:shared:duplex-list:character <- get *typing, before-top-of-screen:offset
top:address:shared:duplex-list:character <- get typing, before-top-of-screen:offset
*editor <- put *editor, top-of-screen:offset, top
}
]
@ -410,18 +411,18 @@ scenario editor-redo-typing [
after <handle-redo> [
{
typing:address:insert-operation <- maybe-convert *op, typing:variant
break-unless typing
typing:insert-operation, is-insert?:boolean <- maybe-convert *op, typing:variant
break-unless is-insert?
before-cursor <- get *editor, before-cursor:offset
insert-from:address:shared:duplex-list:character <- get *typing, insert-from:offset # ignore insert-to because it's already been spliced away
insert-from:address:shared:duplex-list:character <- get typing, insert-from:offset # ignore insert-to because it's already been spliced away
# assert insert-to matches next(before-cursor)
insert-range before-cursor, insert-from
# assert cursor-row/cursor-column/top-of-screen match after-row/after-column/after-top-of-screen
cursor-row <- get *typing, after-row:offset
cursor-row <- get typing, after-row:offset
*editor <- put *editor, cursor-row:offset, cursor-row
cursor-column <- get *typing, after-column:offset
cursor-column <- get typing, after-column:offset
*editor <- put *editor, cursor-column:offset, cursor-column
top:address:shared:duplex-list:character <- get *typing, after-top-of-screen:offset
top:address:shared:duplex-list:character <- get typing, after-top-of-screen:offset
*editor <- put *editor, top-of-screen:offset, top
}
]
@ -730,14 +731,15 @@ before <move-cursor-end> [
undo:address:shared:list:address:shared:operation <- get *editor, undo:offset
break-unless undo
op:address:shared:operation <- first undo
move:address:move-operation <- maybe-convert *op, move:variant
break-unless move
previous-coalesce-tag:number <- get *move, tag:offset
move:move-operation, is-move?:boolean <- maybe-convert *op, move:variant
break-unless is-move?
previous-coalesce-tag:number <- get move, tag:offset
coalesce?:boolean <- equal undo-coalesce-tag, previous-coalesce-tag
break-unless coalesce?
*move <- put *move, after-row:offset, cursor-row
*move <- put *move, after-column:offset, cursor-column
*move <- put *move, after-top-of-screen:offset, top-after
move <- put move, after-row:offset, cursor-row
move <- put move, after-column:offset, cursor-column
move <- put move, after-top-of-screen:offset, top-after
*op <- merge 1/move-operation, move
break +done-adding-move-operation:label
}
op:address:shared:operation <- new operation:type
@ -748,14 +750,14 @@ before <move-cursor-end> [
after <handle-undo> [
{
move:address:move-operation <- maybe-convert *op, move:variant
break-unless move
move:move-operation, is-move?:boolean <- maybe-convert *op, move:variant
break-unless is-move?
# assert cursor-row/cursor-column/top-of-screen match after-row/after-column/after-top-of-screen
cursor-row <- get *move, before-row:offset
cursor-row <- get move, before-row:offset
*editor <- put *editor, cursor-row:offset, cursor-row
cursor-column <- get *move, before-column:offset
cursor-column <- get move, before-column:offset
*editor <- put *editor, cursor-column:offset, cursor-column
top:address:shared:duplex-list:character <- get *move, before-top-of-screen:offset
top:address:shared:duplex-list:character <- get move, before-top-of-screen:offset
*editor <- put *editor, top-of-screen:offset, top
}
]
@ -1378,14 +1380,14 @@ ghi]
after <handle-redo> [
{
move:address:move-operation <- maybe-convert *op, move:variant
break-unless move
move:move-operation, is-move?:boolean <- maybe-convert *op, move:variant
break-unless is-move?
# assert cursor-row/cursor-column/top-of-screen match after-row/after-column/after-top-of-screen
cursor-row <- get *move, after-row:offset
cursor-row <- get move, after-row:offset
*editor <- put *editor, cursor-row:offset, cursor-row
cursor-column <- get *move, after-column:offset
cursor-column <- get move, after-column:offset
*editor <- put *editor, cursor-column:offset, cursor-column
top:address:shared:duplex-list:character <- get *move, after-top-of-screen:offset
top:address:shared:duplex-list:character <- get move, after-top-of-screen:offset
*editor <- put *editor, top-of-screen:offset, top
}
]
@ -1620,18 +1622,19 @@ before <backspace-character-end> [
# if previous operation was an insert, coalesce this operation with it
break-unless *undo
op:address:shared:operation <- first undo
deletion:address:delete-operation <- maybe-convert *op, delete:variant
break-unless deletion
previous-coalesce-tag:number <- get *deletion, tag:offset
deletion:delete-operation, is-delete?:boolean <- maybe-convert *op, delete:variant
break-unless is-delete?
previous-coalesce-tag:number <- get deletion, tag:offset
coalesce?:boolean <- equal previous-coalesce-tag, 1/coalesce-backspace
break-unless coalesce?
*deletion <- put *deletion, delete-from:offset, before-cursor
backspaced-so-far:address:shared:duplex-list:character <- get *deletion, deleted-text:offset
deletion <- put deletion, delete-from:offset, before-cursor
backspaced-so-far:address:shared:duplex-list:character <- get deletion, deleted-text:offset
insert-range backspaced-cell, backspaced-so-far
*deletion <- put *deletion, deleted-text:offset, backspaced-cell
*deletion <- put *deletion, after-row:offset, cursor-row
*deletion <- put *deletion, after-column:offset, cursor-column
*deletion <- put *deletion, after-top-of-screen:offset, top-after
deletion <- put deletion, deleted-text:offset, backspaced-cell
deletion <- put deletion, after-row:offset, cursor-row
deletion <- put deletion, after-column:offset, cursor-column
deletion <- put deletion, after-top-of-screen:offset, top-after
*op <- merge 2/delete-operation, deletion
break +done-adding-backspace-operation:label
}
# if not, create a new operation
@ -1645,38 +1648,38 @@ before <backspace-character-end> [
after <handle-undo> [
{
deletion:address:delete-operation <- maybe-convert *op, delete:variant
break-unless deletion
anchor:address:shared:duplex-list:character <- get *deletion, delete-from:offset
deletion:delete-operation, is-delete?:boolean <- maybe-convert *op, delete:variant
break-unless is-delete?
anchor:address:shared:duplex-list:character <- get deletion, delete-from:offset
break-unless anchor
deleted:address:shared:duplex-list:character <- get *deletion, deleted-text:offset
deleted:address:shared:duplex-list:character <- get deletion, deleted-text:offset
old-cursor:address:shared:duplex-list:character <- last deleted
insert-range anchor, deleted
# assert cursor-row/cursor-column/top-of-screen match after-row/after-column/after-top-of-screen
before-cursor <- copy old-cursor
cursor-row <- get *deletion, before-row:offset
cursor-row <- get deletion, before-row:offset
*editor <- put *editor, cursor-row:offset, cursor-row
cursor-column <- get *deletion, before-column:offset
cursor-column <- get deletion, before-column:offset
*editor <- put *editor, cursor-column:offset, cursor-column
top:address:shared:duplex-list:character <- get *deletion, before-top-of-screen:offset
top:address:shared:duplex-list:character <- get deletion, before-top-of-screen:offset
*editor <- put *editor, top-of-screen:offset, top
}
]
after <handle-redo> [
{
deletion:address:delete-operation <- maybe-convert *op, delete:variant
break-unless deletion
start:address:shared:duplex-list:character <- get *deletion, delete-from:offset
end:address:shared:duplex-list:character <- get *deletion, delete-until:offset
deletion:delete-operation, is-delete?:boolean <- maybe-convert *op, delete:variant
break-unless is-delete?
start:address:shared:duplex-list:character <- get deletion, delete-from:offset
end:address:shared:duplex-list:character <- get deletion, delete-until:offset
data:address:shared:duplex-list:character <- get *editor, data:offset
remove-between start, end
# assert cursor-row/cursor-column/top-of-screen match after-row/after-column/after-top-of-screen
cursor-row <- get *deletion, after-row:offset
cursor-row <- get deletion, after-row:offset
*editor <- put *editor, cursor-row:offset, cursor-row
cursor-column <- get *deletion, after-column:offset
cursor-column <- get deletion, after-column:offset
*editor <- put *editor, cursor-column:offset, cursor-column
top:address:shared:duplex-list:character <- get *deletion, before-top-of-screen:offset
top:address:shared:duplex-list:character <- get deletion, before-top-of-screen:offset
*editor <- put *editor, top-of-screen:offset, top
}
]
@ -1845,19 +1848,20 @@ before <delete-character-end> [
# if previous operation was an insert, coalesce this operation with it
break-unless undo
op:address:shared:operation <- first undo
deletion:address:delete-operation <- maybe-convert *op, delete:variant
break-unless deletion
previous-coalesce-tag:number <- get *deletion, tag:offset
deletion:delete-operation, is-delete?:boolean <- maybe-convert *op, delete:variant
break-unless is-delete?
previous-coalesce-tag:number <- get deletion, tag:offset
coalesce?:boolean <- equal previous-coalesce-tag, 2/coalesce-delete
break-unless coalesce?
delete-until:address:shared:duplex-list:character <- next before-cursor
*deletion <- put *deletion, delete-until:offset, delete-until
deleted-so-far:address:shared:duplex-list:character <- get *deletion, deleted-text:offset
deletion <- put deletion, delete-until:offset, delete-until
deleted-so-far:address:shared:duplex-list:character <- get deletion, deleted-text:offset
deleted-so-far <- append deleted-so-far, deleted-cell
*deletion <- put *deletion, deleted-text:offset, deleted-so-far
*deletion <- put *deletion, after-row:offset, cursor-row
*deletion <- put *deletion, after-column:offset, cursor-column
*deletion <- put *deletion, after-top-of-screen:offset, top-after
deletion <- put deletion, deleted-text:offset, deleted-so-far
deletion <- put deletion, after-row:offset, cursor-row
deletion <- put deletion, after-column:offset, cursor-column
deletion <- put deletion, after-top-of-screen:offset, top-after
*op <- merge 2/delete-operation, deletion
break +done-adding-delete-operation:label
}
# if not, create a new operation