4261 - start using literals for 'true' and 'false'
They uncovered one bug: in edit/003-shortcuts.mu <scroll-down> was returning 0 for an address in one place where I thought it was returning 0 for a boolean. Now we've eliminated this bad interaction between tangling and punning literals.
This commit is contained in:
parent
b89b822439
commit
dd66068298
|
@ -86,27 +86,10 @@ def main [
|
|||
]
|
||||
$error: 0
|
||||
|
||||
:(scenario write_boolean_to_number_allowed)
|
||||
def main [
|
||||
1:bool <- copy 1/true
|
||||
2:num <- copy 1:bool
|
||||
]
|
||||
+mem: storing 1 in location 2
|
||||
$error: 0
|
||||
|
||||
:(scenario write_number_to_boolean_disallowed)
|
||||
% Hide_errors = true;
|
||||
def main [
|
||||
1:num <- copy 34
|
||||
2:bool <- copy 1:num
|
||||
]
|
||||
+error: main: can't copy '1:num' to '2:bool'; types don't match
|
||||
|
||||
:(code)
|
||||
// types_match with some leniency
|
||||
bool types_coercible(const reagent& to, const reagent& from) {
|
||||
if (types_match(to, from)) return true;
|
||||
if (is_mu_boolean(from) && is_real_mu_number(to)) return true;
|
||||
if (is_real_mu_number(from) && is_mu_character(to)) return true;
|
||||
// End types_coercible Special-cases
|
||||
return false;
|
||||
|
@ -122,7 +105,7 @@ bool types_match(const reagent& to, const reagent& from) {
|
|||
// allow writing 0 to any address
|
||||
if (is_mu_address(to)) return from.name == "0";
|
||||
if (!to.type) return false;
|
||||
if (is_mu_boolean(to)) return from.name == "0" || from.name == "1";
|
||||
// End Literal types_match Special-cases
|
||||
return size_of(to) == 1; // literals are always scalars
|
||||
}
|
||||
return types_strictly_match(to, from);
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
//: A few literal constants.
|
||||
|
||||
:(before "End Mu Types Initialization")
|
||||
put(Type_ordinal, "literal-boolean", 0);
|
||||
|
||||
:(scenario true)
|
||||
def main [
|
||||
1:boolean <- copy true
|
||||
]
|
||||
+mem: storing 1 in location 1
|
||||
|
||||
:(before "End Parsing reagent")
|
||||
if (name == "true") {
|
||||
if (type != NULL) {
|
||||
raise << "'true' is a literal and can't take a type\n" << end();
|
||||
return;
|
||||
}
|
||||
type = new type_tree("literal-boolean");
|
||||
set_value(1);
|
||||
}
|
||||
:(before "End Literal types_match Special-cases")
|
||||
if (is_mu_boolean(to)) return from.name == "false" || from.name == "true";
|
||||
|
||||
:(scenario false)
|
||||
def main [
|
||||
1:boolean <- copy false
|
||||
]
|
||||
+mem: storing 0 in location 1
|
||||
|
||||
:(before "End Parsing reagent")
|
||||
if (name == "false") {
|
||||
if (type != NULL) {
|
||||
raise << "'false' is a literal and can't take a type\n" << end();
|
||||
return;
|
||||
}
|
||||
type = new type_tree("literal-boolean");
|
||||
set_value(0);
|
||||
}
|
|
@ -34,27 +34,27 @@ case AND: {
|
|||
|
||||
:(scenario and)
|
||||
def main [
|
||||
1:bool <- copy 1
|
||||
2:bool <- copy 0
|
||||
1:bool <- copy true
|
||||
2:bool <- copy false
|
||||
3:bool <- and 1:bool, 2:bool
|
||||
]
|
||||
+mem: storing 0 in location 3
|
||||
|
||||
:(scenario and_2)
|
||||
def main [
|
||||
1:bool <- and 1, 1
|
||||
1:bool <- and true, true
|
||||
]
|
||||
+mem: storing 1 in location 1
|
||||
|
||||
:(scenario and_multiple)
|
||||
def main [
|
||||
1:bool <- and 1, 1, 0
|
||||
1:bool <- and true, true, false
|
||||
]
|
||||
+mem: storing 0 in location 1
|
||||
|
||||
:(scenario and_multiple_2)
|
||||
def main [
|
||||
1:bool <- and 1, 1, 1
|
||||
1:bool <- and true, true, true
|
||||
]
|
||||
+mem: storing 1 in location 1
|
||||
|
||||
|
@ -92,27 +92,27 @@ case OR: {
|
|||
|
||||
:(scenario or)
|
||||
def main [
|
||||
1:bool <- copy 1
|
||||
2:bool <- copy 0
|
||||
1:bool <- copy true
|
||||
2:bool <- copy false
|
||||
3:bool <- or 1:bool, 2:bool
|
||||
]
|
||||
+mem: storing 1 in location 3
|
||||
|
||||
:(scenario or_2)
|
||||
def main [
|
||||
1:bool <- or 0, 0
|
||||
1:bool <- or false, false
|
||||
]
|
||||
+mem: storing 0 in location 1
|
||||
|
||||
:(scenario or_multiple)
|
||||
def main [
|
||||
1:bool <- and 0, 0, 0
|
||||
1:bool <- or false, false, false
|
||||
]
|
||||
+mem: storing 0 in location 1
|
||||
|
||||
:(scenario or_multiple_2)
|
||||
def main [
|
||||
1:bool <- or 0, 0, 1
|
||||
1:bool <- or false, false, true
|
||||
]
|
||||
+mem: storing 1 in location 1
|
||||
|
||||
|
@ -152,14 +152,14 @@ case NOT: {
|
|||
|
||||
:(scenario not)
|
||||
def main [
|
||||
1:bool <- copy 1
|
||||
1:bool <- copy true
|
||||
2:bool <- not 1:bool
|
||||
]
|
||||
+mem: storing 0 in location 2
|
||||
|
||||
:(scenario not_multiple)
|
||||
def main [
|
||||
1:bool, 2:bool, 3:bool <- not 1, 0, 1
|
||||
1:bool, 2:bool, 3:bool <- not true, false, true
|
||||
]
|
||||
+mem: storing 0 in location 1
|
||||
+mem: storing 1 in location 2
|
||||
|
|
|
@ -154,9 +154,9 @@ def main [
|
|||
:(scenario jump_fails_without_target_2)
|
||||
% Hide_errors = true;
|
||||
def main [
|
||||
jump-if 1/true
|
||||
jump-if true
|
||||
]
|
||||
+error: main: 'jump-if 1/true' expects 2 ingredients but got 1
|
||||
+error: main: 'jump-if true' expects 2 ingredients but got 1
|
||||
|
||||
:(scenario recipe_fails_on_duplicate_jump_target)
|
||||
% Hide_errors = true;
|
||||
|
|
|
@ -154,7 +154,7 @@ def foo [ # dummy
|
|||
def main [
|
||||
local-scope
|
||||
0:space/names:foo <- copy 0 # specify surrounding space
|
||||
x:bool <- copy 1/true
|
||||
x:bool <- copy true
|
||||
x:num/space:1 <- copy 34
|
||||
x/space:1 <- copy 35
|
||||
]
|
||||
|
|
|
@ -362,7 +362,7 @@ def add2 x:num, y:num [
|
|||
def foo -> x:num [
|
||||
local-scope
|
||||
x:num <- copy 0
|
||||
z:bool <- copy 0/false
|
||||
z:bool <- copy false
|
||||
return-if z, z
|
||||
]
|
||||
+error: foo: replied with the wrong type at 'return-if z, z'
|
||||
|
@ -580,7 +580,7 @@ def add2 x:num, y:num -> z:num [
|
|||
local-scope
|
||||
load-ingredients
|
||||
z <- add x, y # no type for z
|
||||
return-if 0/false, 34
|
||||
return-if false, 34
|
||||
]
|
||||
+mem: storing 8 in location 1
|
||||
|
||||
|
|
|
@ -192,17 +192,12 @@ string best_variant(const instruction& inst, const recipe& caller_recipe) {
|
|||
candidates = strictly_matching_variants(inst, variants);
|
||||
if (!candidates.empty()) return best_variant(inst, candidates).name;
|
||||
|
||||
// Static Dispatch Phase 2
|
||||
//? cerr << inst.name << " phase 2\n";
|
||||
candidates = strictly_matching_variants_except_literal_against_address_or_boolean(inst, variants);
|
||||
if (!candidates.empty()) return best_variant(inst, candidates).name;
|
||||
|
||||
//? cerr << inst.name << " phase 3\n";
|
||||
// Static Dispatch Phase 3
|
||||
// Static Dispatch Phase 2
|
||||
//: (shape-shifting recipes in a later layer)
|
||||
// End Static Dispatch Phase 3
|
||||
// End Static Dispatch Phase 2
|
||||
|
||||
// Static Dispatch Phase 4
|
||||
// Static Dispatch Phase 3
|
||||
//? cerr << inst.name << " phase 4\n";
|
||||
candidates = matching_variants(inst, variants);
|
||||
if (!candidates.empty()) return best_variant(inst, candidates).name;
|
||||
|
@ -270,46 +265,7 @@ bool all_header_reagents_strictly_match(const instruction& inst, const recipe& v
|
|||
return true;
|
||||
}
|
||||
|
||||
// phase 2
|
||||
vector<recipe_ordinal> strictly_matching_variants_except_literal_against_address_or_boolean(const instruction& inst, const vector<recipe_ordinal>& variants) {
|
||||
vector<recipe_ordinal> result;
|
||||
for (int i = 0; i < SIZE(variants); ++i) {
|
||||
if (variants.at(i) == -1) continue;
|
||||
trace(9992, "transform") << "checking variant (strict except literal-against-boolean) " << i << ": " << header_label(variants.at(i)) << end();
|
||||
if (all_header_reagents_strictly_match_except_literal_against_address_or_boolean(inst, get(Recipe, variants.at(i))))
|
||||
result.push_back(variants.at(i));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool all_header_reagents_strictly_match_except_literal_against_address_or_boolean(const instruction& inst, const recipe& variant) {
|
||||
for (int i = 0; i < min(SIZE(inst.ingredients), SIZE(variant.ingredients)); ++i) {
|
||||
if (!types_strictly_match_except_literal_against_address_or_boolean(variant.ingredients.at(i), inst.ingredients.at(i))) {
|
||||
trace(9993, "transform") << "match failed: ingredient " << i << end();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < min(SIZE(variant.products), SIZE(inst.products)); ++i) {
|
||||
if (is_dummy(inst.products.at(i))) continue;
|
||||
if (!types_strictly_match_except_literal_against_address_or_boolean(variant.products.at(i), inst.products.at(i))) {
|
||||
trace(9993, "transform") << "match failed: product " << i << end();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool types_strictly_match_except_literal_against_address_or_boolean(const reagent& to, const reagent& from) {
|
||||
if (is_literal(from) && is_mu_boolean(to))
|
||||
return from.name == "0" || from.name == "1";
|
||||
// Match Literal Zero Against Address {
|
||||
if (is_literal(from) && is_mu_address(to))
|
||||
return from.name == "0";
|
||||
// }
|
||||
return types_strictly_match(to, from);
|
||||
}
|
||||
|
||||
// phase 4
|
||||
// phase 3
|
||||
vector<recipe_ordinal> matching_variants(const instruction& inst, const vector<recipe_ordinal>& variants) {
|
||||
vector<recipe_ordinal> result;
|
||||
for (int i = 0; i < SIZE(variants); ++i) {
|
||||
|
@ -422,15 +378,15 @@ def main [
|
|||
1:num <- copy 34
|
||||
2:num <- copy 34
|
||||
3:bool <- equal 1:num, 2:num
|
||||
4:bool <- copy 0/false
|
||||
5:bool <- copy 0/false
|
||||
4:bool <- copy false
|
||||
5:bool <- copy false
|
||||
6:bool <- equal 4:bool, 5:bool
|
||||
]
|
||||
# temporarily hardcode number equality to always fail
|
||||
def equal x:num, y:num -> z:bool [
|
||||
local-scope
|
||||
load-ingredients
|
||||
z <- copy 0/false
|
||||
z <- copy false
|
||||
]
|
||||
# comparing numbers used overload
|
||||
+mem: storing 0 in location 3
|
||||
|
@ -524,37 +480,15 @@ def foo x:num -> y:num [
|
|||
+error: main: ingredient 0 has the wrong type at '1:num/raw <- foo x'
|
||||
-mem: storing 34 in location 1
|
||||
|
||||
:(scenario static_dispatch_dispatches_literal_to_boolean_before_character)
|
||||
:(scenario static_dispatch_dispatches_literal_to_character)
|
||||
def main [
|
||||
1:num/raw <- foo 0 # valid literal for boolean
|
||||
1:num/raw <- foo 97
|
||||
]
|
||||
def foo x:char -> y:num [
|
||||
local-scope
|
||||
load-ingredients
|
||||
return 34
|
||||
]
|
||||
def foo x:bool -> y:num [
|
||||
local-scope
|
||||
load-ingredients
|
||||
return 35
|
||||
]
|
||||
# boolean variant is preferred
|
||||
+mem: storing 35 in location 1
|
||||
|
||||
:(scenario static_dispatch_dispatches_literal_to_character_when_out_of_boolean_range)
|
||||
def main [
|
||||
1:num/raw <- foo 97 # not a valid literal for boolean
|
||||
]
|
||||
def foo x:char -> y:num [
|
||||
local-scope
|
||||
load-ingredients
|
||||
return 34
|
||||
]
|
||||
def foo x:bool -> y:num [
|
||||
local-scope
|
||||
load-ingredients
|
||||
return 35
|
||||
]
|
||||
# character variant is preferred
|
||||
+mem: storing 34 in location 1
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ container foo:_a:_b [
|
|||
y:_b
|
||||
]
|
||||
def main [
|
||||
1:foo:num:bool <- merge 34, 1/true
|
||||
1:foo:num:bool <- merge 34, true
|
||||
]
|
||||
$error: 0
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ if (Current_routine->calls.front().running_step_index == 0
|
|||
:(before "End Matching Types For Literal(to)")
|
||||
if (contains_type_ingredient_name(to)) return false;
|
||||
|
||||
:(after "Static Dispatch Phase 3")
|
||||
:(after "Static Dispatch Phase 2")
|
||||
candidates = strictly_matching_shape_shifting_variants(inst, variants);
|
||||
if (!candidates.empty()) {
|
||||
recipe_ordinal exemplar = best_shape_shifting_variant(inst, candidates);
|
||||
|
@ -68,10 +68,6 @@ if (contains_key(Recipe, inst.operation) && !is_primitive(inst.operation)
|
|||
return;
|
||||
}
|
||||
|
||||
:(replace{} "Match Literal Zero Against Address")
|
||||
if (is_literal(from) && is_mu_address(to))
|
||||
return from.name == "0" && !contains_type_ingredient_name(to);
|
||||
|
||||
:(code)
|
||||
// phase 3 of static dispatch
|
||||
vector<recipe_ordinal> strictly_matching_shape_shifting_variants(const instruction& inst, const vector<recipe_ordinal>& variants) {
|
||||
|
@ -1111,7 +1107,7 @@ def foo a:_elem [
|
|||
]
|
||||
# tangle some code that refers to the type ingredient
|
||||
after <label1> [
|
||||
b:bool <- copy 0 # type abbreviation
|
||||
b:bool <- copy false # type abbreviation
|
||||
]
|
||||
# trigger specialization
|
||||
def main [
|
||||
|
|
20
061text.mu
20
061text.mu
|
@ -5,15 +5,15 @@ def equal a:text, b:text -> result:bool [
|
|||
load-inputs
|
||||
an:num, bn:num <- deaddress a, b
|
||||
address-equal?:boolean <- equal an, bn
|
||||
return-if address-equal?, 1/true
|
||||
return-unless a, 0/false
|
||||
return-unless b, 0/false
|
||||
return-if address-equal?, true
|
||||
return-unless a, false
|
||||
return-unless b, false
|
||||
a-len:num <- length *a
|
||||
b-len:num <- length *b
|
||||
# compare lengths
|
||||
trace 99, [text-equal], [comparing lengths]
|
||||
length-equal?:bool <- equal a-len, b-len
|
||||
return-unless length-equal?, 0/false
|
||||
return-unless length-equal?, false
|
||||
# compare each corresponding character
|
||||
trace 99, [text-equal], [comparing characters]
|
||||
i:num <- copy 0
|
||||
|
@ -23,11 +23,11 @@ def equal a:text, b:text -> result:bool [
|
|||
a2:char <- index *a, i
|
||||
b2:char <- index *b, i
|
||||
chars-match?:bool <- equal a2, b2
|
||||
return-unless chars-match?, 0/false
|
||||
return-unless chars-match?, false
|
||||
i <- add i, 1
|
||||
loop
|
||||
}
|
||||
return 1/true
|
||||
return true
|
||||
]
|
||||
|
||||
scenario text-equal-reflexive [
|
||||
|
@ -358,7 +358,7 @@ def buffer-to-array in:&:buffer:_elem -> result:&:@:_elem [
|
|||
def blank? x:&:@:_elem -> result:bool [
|
||||
local-scope
|
||||
load-inputs
|
||||
return-unless x, 1/true
|
||||
return-unless x, true
|
||||
len:num <- length *x
|
||||
result <- equal len, 0
|
||||
]
|
||||
|
@ -997,7 +997,7 @@ def match-at text:text, pattern:text, idx:num -> result:bool [
|
|||
x:num <- length *text
|
||||
x <- subtract x, pattern-len
|
||||
enough-room?:bool <- lesser-or-equal idx, x
|
||||
return-unless enough-room?, 0/not-found
|
||||
return-unless enough-room?, false/not-found
|
||||
# check each character of pattern
|
||||
pattern-idx:num <- copy 0
|
||||
{
|
||||
|
@ -1006,12 +1006,12 @@ def match-at text:text, pattern:text, idx:num -> result:bool [
|
|||
c:char <- index *text, idx
|
||||
exp:char <- index *pattern, pattern-idx
|
||||
match?:bool <- equal c, exp
|
||||
return-unless match?, 0/not-found
|
||||
return-unless match?, false/not-found
|
||||
idx <- add idx, 1
|
||||
pattern-idx <- add pattern-idx, 1
|
||||
loop
|
||||
}
|
||||
return 1/found
|
||||
return true/found
|
||||
]
|
||||
|
||||
scenario match-at-checks-pattern-at-index [
|
||||
|
|
|
@ -591,15 +591,15 @@ def match x:&:duplex-list:_elem, y:&:@:_elem -> result:bool [
|
|||
done?:bool <- greater-or-equal i, max
|
||||
break-if done?
|
||||
expected:_elem <- index *y, i
|
||||
return-unless x, 0/no-match
|
||||
return-unless x, false/no-match
|
||||
curr:_elem <- first x
|
||||
curr-matches?:bool <- equal curr, expected
|
||||
return-unless curr-matches?, 0/no-match
|
||||
return-unless curr-matches?, false/no-match
|
||||
x <- next x
|
||||
i <- add i, 1
|
||||
loop
|
||||
}
|
||||
return 1/successful-match
|
||||
return true/successful-match
|
||||
]
|
||||
|
||||
scenario duplex-list-match [
|
||||
|
|
|
@ -24,7 +24,7 @@ def read in:&:stream:_elem -> result:_elem, empty?:bool, in:&:stream:_elem [
|
|||
local-scope
|
||||
load-inputs
|
||||
assert in, [cannot read; stream has no data]
|
||||
empty? <- copy 0/false
|
||||
empty? <- copy false
|
||||
idx:num <- get *in, index:offset
|
||||
s:&:@:_elem <- get *in, data:offset
|
||||
len:num <- length *s
|
||||
|
@ -32,7 +32,7 @@ def read in:&:stream:_elem -> result:_elem, empty?:bool, in:&:stream:_elem [
|
|||
{
|
||||
break-unless at-end?
|
||||
empty-result:&:_elem <- new _elem:type
|
||||
return *empty-result, 1/true
|
||||
return *empty-result, true
|
||||
}
|
||||
result <- index *s, idx
|
||||
idx <- add idx, 1
|
||||
|
@ -43,7 +43,7 @@ def peek in:&:stream:_elem -> result:_elem, empty?:bool [
|
|||
local-scope
|
||||
load-inputs
|
||||
assert in, [cannot peek; stream has no data]
|
||||
empty?:bool <- copy 0/false
|
||||
empty?:bool <- copy false
|
||||
idx:num <- get *in, index:offset
|
||||
s:&:@:_elem <- get *in, data:offset
|
||||
len:num <- length *s
|
||||
|
@ -51,7 +51,7 @@ def peek in:&:stream:_elem -> result:_elem, empty?:bool [
|
|||
{
|
||||
break-unless at-end?
|
||||
empty-result:&:_elem <- new _elem:type
|
||||
return *empty-result, 1/true
|
||||
return *empty-result, true
|
||||
}
|
||||
result <- index *s, idx
|
||||
]
|
||||
|
|
|
@ -5,7 +5,7 @@ def random generator:&:stream:num -> result:num, fail?:bool, generator:&:stream:
|
|||
break-if generator
|
||||
# generator is 0? use real random-number generator
|
||||
result <- real-random
|
||||
return result, 0/false
|
||||
return result, false
|
||||
}
|
||||
result, fail?, generator <- read generator
|
||||
]
|
||||
|
|
|
@ -76,7 +76,7 @@ def put-index table:&:table:_key:_value, key:_key, value:_value -> table:&:table
|
|||
occupied?:bool <- get x, occupied?:offset
|
||||
not-occupied?:bool <- not occupied?:bool
|
||||
assert not-occupied?, [can't handle collisions yet]
|
||||
new-row:table-row:_key:_value <- merge 1/true, key, value
|
||||
new-row:table-row:_key:_value <- merge true, key, value
|
||||
*table-data <- put-index *table-data, hash-key, new-row
|
||||
]
|
||||
|
||||
|
|
|
@ -106,7 +106,7 @@ def read in:&:source:_elem -> result:_elem, eof?:bool, in:&:source:_elem [
|
|||
local-scope
|
||||
load-inputs
|
||||
assert in, [read on null channel]
|
||||
eof? <- copy 0/false # default result
|
||||
eof? <- copy false # default result
|
||||
chan:&:channel:_elem <- get *in, chan:offset
|
||||
# block until lock is acquired AND queue has data
|
||||
lock:location <- get-location *chan, lock:offset
|
||||
|
@ -327,13 +327,13 @@ def close x:&:source:_elem -> x:&:source:_elem [
|
|||
local-scope
|
||||
load-inputs
|
||||
chan:&:channel:_elem <- get *x, chan:offset
|
||||
*chan <- put *chan, closed?:offset, 1/true
|
||||
*chan <- put *chan, closed?:offset, true
|
||||
]
|
||||
def close x:&:sink:_elem -> x:&:sink:_elem [
|
||||
local-scope
|
||||
load-inputs
|
||||
chan:&:channel:_elem <- get *x, chan:offset
|
||||
*chan <- put *chan, closed?:offset, 1/true
|
||||
*chan <- put *chan, closed?:offset, true
|
||||
]
|
||||
|
||||
# once a channel is closed from one side, no further operations are expected from that side
|
||||
|
@ -352,7 +352,7 @@ after <channel-read-empty> [
|
|||
break-unless closed?
|
||||
empty-result:&:_elem <- new _elem:type
|
||||
current-routine-is-unblocked
|
||||
return *empty-result, 1/true
|
||||
return *empty-result, true
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -401,7 +401,7 @@ def buffer-lines in:&:source:char, buffered-out:&:sink:char -> buffered-out:&:si
|
|||
local-scope
|
||||
load-inputs
|
||||
# repeat forever
|
||||
eof?:bool <- copy 0/false
|
||||
eof?:bool <- copy false
|
||||
{
|
||||
line:&:buffer:char <- new-buffer 30
|
||||
# read characters from 'in' until newline, copy into line
|
||||
|
|
|
@ -152,7 +152,7 @@ case CALL_WITH_CONTINUATION_MARK: {
|
|||
|
||||
:(scenario next_ingredient_inside_continuation)
|
||||
recipe main [
|
||||
call-with-continuation-mark 233/mark, f, 1/true
|
||||
call-with-continuation-mark 233/mark, f, true
|
||||
]
|
||||
recipe f [
|
||||
10:bool <- next-input
|
||||
|
@ -162,7 +162,7 @@ recipe f [
|
|||
:(scenario delimited_continuation_out_of_recipe_variable)
|
||||
recipe main [
|
||||
x:recipe <- copy f
|
||||
call-with-continuation-mark 233/mark, x, 1/true
|
||||
call-with-continuation-mark 233/mark, x, true
|
||||
]
|
||||
recipe f [
|
||||
10:bool <- next-input
|
||||
|
|
26
081print.mu
26
081print.mu
|
@ -39,7 +39,7 @@ def new-fake-screen w:num, h:num -> result:&:screen [
|
|||
assert non-zero-height?, [screen can't have zero height]
|
||||
bufsize:num <- multiply w, h
|
||||
data:&:@:screen-cell <- new screen-cell:type, bufsize
|
||||
*result <- merge h/num-rows, w/num-columns, 0/cursor-row, 0/cursor-column, data, 0/pending-scroll?, 0/top-idx
|
||||
*result <- merge h/num-rows, w/num-columns, 0/cursor-row, 0/cursor-column, data, false/pending-scroll?, 0/top-idx
|
||||
result <- clear-screen result
|
||||
]
|
||||
|
||||
|
@ -75,7 +75,7 @@ def fake-screen-is-empty? screen:&:screen -> result:bool [
|
|||
local-scope
|
||||
load-inputs
|
||||
#? stash [fake-screen-is-empty?]
|
||||
return-unless screen, 1/true # do nothing for real screens
|
||||
return-unless screen, true # do nothing for real screens
|
||||
buf:&:@:screen-cell <- get *screen, data:offset
|
||||
i:num <- copy 0
|
||||
len:num <- length *buf
|
||||
|
@ -87,9 +87,9 @@ def fake-screen-is-empty? screen:&:screen -> result:bool [
|
|||
i <- add i, 1
|
||||
loop-unless curr-contents
|
||||
# not 0
|
||||
return 0/false
|
||||
return false
|
||||
}
|
||||
return 1/true
|
||||
return true
|
||||
]
|
||||
|
||||
def print screen:&:screen, c:char -> screen:&:screen [
|
||||
|
@ -150,7 +150,7 @@ def print screen:&:screen, c:char -> screen:&:screen [
|
|||
break-unless pending-scroll?
|
||||
#? stash [scroll]
|
||||
scroll-fake-screen screen
|
||||
*screen <- put *screen, pending-scroll?:offset, 0/false
|
||||
*screen <- put *screen, pending-scroll?:offset, false
|
||||
}
|
||||
#? $print [print-character (], row, [, ], column, [): ], c, 10/newline
|
||||
# special-case: newline
|
||||
|
@ -196,7 +196,7 @@ def print screen:&:screen, c:char -> screen:&:screen [
|
|||
break-unless past-bottom?
|
||||
# queue up a scroll
|
||||
#? stash [pending scroll]
|
||||
*screen <- put *screen, pending-scroll?:offset, 1/true
|
||||
*screen <- put *screen, pending-scroll?:offset, true
|
||||
row <- subtract row, 1 # update cursor as if scroll already happened
|
||||
}
|
||||
*screen <- put *screen, cursor-row:offset, row
|
||||
|
@ -455,7 +455,7 @@ scenario print-character-at-bottom-right [
|
|||
10:num/raw <- get *fake-screen, cursor-row:offset
|
||||
11:num/raw <- get *fake-screen, cursor-column:offset
|
||||
12:num/raw <- get *fake-screen, top-idx:offset
|
||||
13:num/raw <- get *fake-screen, pending-scroll?:offset
|
||||
13:bool/raw <- get *fake-screen, pending-scroll?:offset
|
||||
cell:&:@:screen-cell <- get *fake-screen, data:offset
|
||||
20:@:screen-cell/raw <- copy *cell
|
||||
]
|
||||
|
@ -607,7 +607,7 @@ def move-cursor screen:&:screen, new-row:num, new-column:num -> screen:&:screen
|
|||
scroll?:bool <- greater-or-equal new-column, width
|
||||
break-if scroll?
|
||||
#? stash [resetting pending-scroll?]
|
||||
*screen <- put *screen, pending-scroll?:offset, 0/false
|
||||
*screen <- put *screen, pending-scroll?:offset, false
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -884,8 +884,14 @@ def print screen:&:screen, n:bool -> screen:&:screen [
|
|||
break-if bg-color-found?
|
||||
bg-color <- copy 0/black
|
||||
}
|
||||
n2:num <- copy n
|
||||
screen <- print screen, n2, color, bg-color
|
||||
{
|
||||
break-if n
|
||||
screen <- print screen, [false], color, bg-color
|
||||
}
|
||||
{
|
||||
break-unless n
|
||||
screen <- print screen, [true], color, bg-color
|
||||
}
|
||||
]
|
||||
|
||||
def print screen:&:screen, n:&:_elem -> screen:&:screen [
|
||||
|
|
|
@ -44,16 +44,16 @@ def read-event console:&:console -> result:event, found?:bool, quit?:bool, conso
|
|||
done?:bool <- greater-or-equal current-event-index, max
|
||||
break-unless done?
|
||||
dummy:&:event <- new event:type
|
||||
return *dummy, 1/found, 1/quit
|
||||
return *dummy, true/found, true/quit
|
||||
}
|
||||
result <- index *buf, current-event-index
|
||||
current-event-index <- add current-event-index, 1
|
||||
*console <- put *console, current-event-index:offset, current-event-index
|
||||
return result, 1/found, 0/quit
|
||||
return result, true/found, false/quit
|
||||
}
|
||||
switch # real event source is infrequent; avoid polling it too much
|
||||
result:event, found?:bool <- check-for-interaction
|
||||
return result, found?, 0/quit
|
||||
return result, found?, false/quit
|
||||
]
|
||||
|
||||
# variant of read-event for just keyboard events. Discards everything that
|
||||
|
@ -66,8 +66,8 @@ def read-key console:&:console -> result:char, found?:bool, quit?:bool, console:
|
|||
return-if quit?, 0, found?, quit?
|
||||
return-unless found?, 0, found?, quit?
|
||||
c:char, converted?:bool <- maybe-convert x, text:variant
|
||||
return-unless converted?, 0, 0/found, 0/quit
|
||||
return c, 1/found, 0/quit
|
||||
return-unless converted?, 0, false/found, false/quit
|
||||
return c, true/found, false/quit
|
||||
]
|
||||
|
||||
def send-keys-to-channel console:&:console, chan:&:sink:char, screen:&:screen -> console:&:console, chan:&:sink:char, screen:&:screen [
|
||||
|
@ -99,6 +99,6 @@ def wait-for-event console:&:console -> console:&:console [
|
|||
def has-more-events? console:&:console -> result:bool [
|
||||
local-scope
|
||||
load-inputs
|
||||
return-if console, 0/false # fake events are processed as soon as they arrive
|
||||
return-if console, false # fake events are processed as soon as they arrive
|
||||
result <- interactions-left?
|
||||
]
|
||||
|
|
14
088file.mu
14
088file.mu
|
@ -21,7 +21,7 @@ container resource [
|
|||
def start-reading resources:&:resources, filename:text -> contents:&:source:char, error?:bool [
|
||||
local-scope
|
||||
load-inputs
|
||||
error? <- copy 0/false
|
||||
error? <- copy false
|
||||
{
|
||||
break-unless resources
|
||||
# fake file system
|
||||
|
@ -30,7 +30,7 @@ def start-reading resources:&:resources, filename:text -> contents:&:source:char
|
|||
}
|
||||
# real file system
|
||||
file:num <- $open-file-for-reading filename
|
||||
return-unless file, 0/contents, 1/error?
|
||||
return-unless file, 0/contents, true/error
|
||||
contents:&:source:char, sink:&:sink:char <- new-channel 30
|
||||
start-running receive-from-file file, sink
|
||||
]
|
||||
|
@ -53,7 +53,7 @@ def slurp resources:&:resources, filename:text -> contents:text, error?:bool [
|
|||
def start-reading-from-fake-resource resources:&:resources, resource:text -> contents:&:source:char, error?:bool [
|
||||
local-scope
|
||||
load-inputs
|
||||
error? <- copy 0/no-error
|
||||
error? <- copy false
|
||||
i:num <- copy 0
|
||||
data:&:@:resource <- get *resources, data:offset
|
||||
len:num <- length *data
|
||||
|
@ -70,7 +70,7 @@ def start-reading-from-fake-resource resources:&:resources, resource:text -> con
|
|||
start-running receive-from-text curr-contents, sink
|
||||
return
|
||||
}
|
||||
return 0/not-found, 1/error
|
||||
return 0/not-found, true/error-found
|
||||
]
|
||||
|
||||
def receive-from-file file:num, sink:&:sink:char -> sink:&:sink:char [
|
||||
|
@ -105,7 +105,7 @@ def receive-from-text contents:text, sink:&:sink:char -> sink:&:sink:char [
|
|||
def start-writing resources:&:resources, filename:text -> sink:&:sink:char, routine-id:num, error?:bool [
|
||||
local-scope
|
||||
load-inputs
|
||||
error? <- copy 0/false
|
||||
error? <- copy false
|
||||
source:&:source:char, sink:&:sink:char <- new-channel 30
|
||||
{
|
||||
break-unless resources
|
||||
|
@ -115,7 +115,7 @@ def start-writing resources:&:resources, filename:text -> sink:&:sink:char, rout
|
|||
}
|
||||
# real file system
|
||||
file:num <- $open-file-for-writing filename
|
||||
return-unless file, 0/sink, 0/routine-id, 1/error?
|
||||
return-unless file, 0/sink, 0/routine-id, true/error
|
||||
{
|
||||
break-if file
|
||||
msg:text <- append [no such file: ] filename
|
||||
|
@ -128,7 +128,7 @@ def dump resources:&:resources, filename:text, contents:text -> resources:&:reso
|
|||
local-scope
|
||||
load-inputs
|
||||
# todo: really create an empty file
|
||||
return-unless contents, resources, 0/no-error
|
||||
return-unless contents, resources, false/no-error
|
||||
sink-file:&:sink:char, write-routine:num, error?:bool <- start-writing resources, filename
|
||||
return-if error?
|
||||
i:num <- copy 0
|
||||
|
|
|
@ -259,7 +259,7 @@ def read-move stdin:&:source:char, screen:&:screen -> result:&:move, quit?:bool,
|
|||
return-if error?, 0/dummy
|
||||
*result <- put *result, from-rank:offset, from-rank
|
||||
error? <- expect-from-channel stdin, 45/dash, screen
|
||||
return-if error?, 0/dummy, 0/quit
|
||||
return-if error?, 0/dummy, false/quit
|
||||
to-file:num, quit?, error? <- read-file stdin, screen
|
||||
return-if quit?, 0/dummy
|
||||
return-if error?, 0/dummy
|
||||
|
@ -269,7 +269,7 @@ def read-move stdin:&:source:char, screen:&:screen -> result:&:move, quit?:bool,
|
|||
return-if error?, 0/dummy
|
||||
*result <- put *result, to-rank:offset, to-rank
|
||||
error? <- expect-from-channel stdin, 10/newline, screen
|
||||
return-if error?, 0/dummy, 0/quit
|
||||
return-if error?, 0/dummy, false/quit
|
||||
]
|
||||
|
||||
# valid values for file: 0-7
|
||||
|
@ -277,18 +277,18 @@ def read-file stdin:&:source:char, screen:&:screen -> file:num, quit:bool, error
|
|||
local-scope
|
||||
load-inputs
|
||||
c:char, eof?:bool, stdin <- read stdin
|
||||
return-if eof?, 0/dummy, 1/quit, 0/error
|
||||
return-if eof?, 0/dummy, true/quit, false/no-error
|
||||
q-pressed?:bool <- equal c, 81/Q
|
||||
return-if q-pressed?, 0/dummy, 1/quit, 0/error
|
||||
return-if q-pressed?, 0/dummy, true/quit, false/no-error
|
||||
q-pressed? <- equal c, 113/q
|
||||
return-if q-pressed?, 0/dummy, 1/quit, 0/error
|
||||
return-if q-pressed?, 0/dummy, true/quit, false/no-error
|
||||
empty-fake-keyboard?:bool <- equal c, 0/eof
|
||||
return-if empty-fake-keyboard?, 0/dummy, 1/quit, 0/error
|
||||
return-if empty-fake-keyboard?, 0/dummy, true/quit, false/no-error
|
||||
{
|
||||
newline?:bool <- equal c, 10/newline
|
||||
break-unless newline?
|
||||
print screen, [that's not enough]
|
||||
return 0/dummy, 0/quit, 1/error
|
||||
return 0/dummy, false/don't-quit, true/error
|
||||
}
|
||||
file:num <- subtract c, 97/a
|
||||
# 'a' <= file <= 'h'
|
||||
|
@ -298,16 +298,16 @@ def read-file stdin:&:source:char, screen:&:screen -> file:num, quit:bool, error
|
|||
print screen, [file too low: ]
|
||||
print screen, c
|
||||
cursor-to-next-line screen
|
||||
return 0/dummy, 0/quit, 1/error
|
||||
return 0/dummy, false/don't-quit, true/error
|
||||
}
|
||||
{
|
||||
below-max:bool <- lesser-than file, 8
|
||||
break-if below-max
|
||||
print screen, [file too high: ]
|
||||
print screen, c
|
||||
return 0/dummy, 0/quit, 1/error
|
||||
return 0/dummy, false/don't-quit, true/error
|
||||
}
|
||||
return file, 0/quit, 0/error
|
||||
return file, false/don't-quit, false/no-error
|
||||
]
|
||||
|
||||
# valid values for rank: 0-7
|
||||
|
@ -315,18 +315,18 @@ def read-rank stdin:&:source:char, screen:&:screen -> rank:num, quit?:bool, erro
|
|||
local-scope
|
||||
load-inputs
|
||||
c:char, eof?:bool, stdin <- read stdin
|
||||
return-if eof?, 0/dummy, 1/quit, 0/error
|
||||
return-if eof?, 0/dummy, true/quit, false/no-error
|
||||
q-pressed?:bool <- equal c, 81/Q
|
||||
return-if q-pressed?, 0/dummy, 1/quit, 0/error
|
||||
return-if q-pressed?, 0/dummy, true/quit, false/no-error
|
||||
q-pressed? <- equal c, 113/q
|
||||
return-if q-pressed?, 0/dummy, 1/quit, 0/error
|
||||
return-if q-pressed?, 0/dummy, true/quit, false/no-error
|
||||
empty-fake-keyboard?:bool <- equal c, 0/eof
|
||||
return-if empty-fake-keyboard?, 0/dummy, 1/quit, 0/error
|
||||
return-if empty-fake-keyboard?, 0/dummy, true/quit, false/no-error
|
||||
{
|
||||
newline?:bool <- equal c, 10 # newline
|
||||
break-unless newline?
|
||||
print screen, [that's not enough]
|
||||
return 0/dummy, 0/quit, 1/error
|
||||
return 0/dummy, false/don't-quite, true/error
|
||||
}
|
||||
rank:num <- subtract c, 49/'1'
|
||||
# assert'1' <= rank <= '8'
|
||||
|
@ -335,16 +335,16 @@ def read-rank stdin:&:source:char, screen:&:screen -> rank:num, quit?:bool, erro
|
|||
break-if above-min
|
||||
print screen, [rank too low: ]
|
||||
print screen, c
|
||||
return 0/dummy, 0/quit, 1/error
|
||||
return 0/dummy, false/don't-quite, true/error
|
||||
}
|
||||
{
|
||||
below-max:bool <- lesser-or-equal rank, 7
|
||||
break-if below-max
|
||||
print screen, [rank too high: ]
|
||||
print screen, c
|
||||
return 0/dummy, 0/quit, 1/error
|
||||
return 0/dummy, false/don't-quite, true/error
|
||||
}
|
||||
return rank, 0/quit, 0/error
|
||||
return rank, false/don't-quite, false/no-error
|
||||
]
|
||||
|
||||
# read a character from the given channel and check that it's what we expect
|
||||
|
@ -353,7 +353,7 @@ def expect-from-channel stdin:&:source:char, expected:char, screen:&:screen -> r
|
|||
local-scope
|
||||
load-inputs
|
||||
c:char, eof?:bool, stdin <- read stdin
|
||||
return-if eof? 1/true
|
||||
return-if eof? true
|
||||
{
|
||||
match?:bool <- equal c, expected
|
||||
break-if match?
|
||||
|
|
|
@ -31,7 +31,7 @@ def create-yielder l:&:list:num -> n:num, done?:bool [
|
|||
load-inputs
|
||||
return-continuation-until-mark 100/mark
|
||||
done? <- equal l, 0/nil
|
||||
return-if done?, 0/false
|
||||
return-if done?, false
|
||||
n <- first l
|
||||
l <- rest l
|
||||
]
|
||||
|
|
|
@ -43,5 +43,5 @@ def create-yielder l:&:list:num -> n:num, done?:bool [
|
|||
# return. Calling functions should stop calling its continuation after this
|
||||
# point.
|
||||
return-continuation-until-mark 100/mark, -1, done?
|
||||
assert 0/false, [called too many times, ran out of continuations to return]
|
||||
assert false, [called too many times, ran out of continuations to return]
|
||||
]
|
||||
|
|
|
@ -45,5 +45,5 @@ def create-yielder l:&:list:num -> n:num, done?:bool [
|
|||
loop
|
||||
}
|
||||
return-continuation-until-mark 100/mark, -1, done?
|
||||
assert 0/false, [called too many times, ran out of continuations to return]
|
||||
assert false, [called too many times, ran out of continuations to return]
|
||||
]
|
||||
|
|
|
@ -50,23 +50,23 @@ def editor-event-loop screen:&:screen, console:&:console, editor:&:editor -> scr
|
|||
def move-cursor editor:&:editor, screen:&:screen, t:touch-event -> in-focus?:bool, editor:&:editor [
|
||||
local-scope
|
||||
load-inputs
|
||||
return-unless editor, 0/false
|
||||
return-unless editor, false
|
||||
click-row:num <- get t, row:offset
|
||||
return-unless click-row, 0/false # ignore clicks on 'menu'
|
||||
return-unless click-row, false # ignore clicks on 'menu'
|
||||
click-column:num <- get t, column:offset
|
||||
left:num <- get *editor, left:offset
|
||||
too-far-left?:bool <- lesser-than click-column, left
|
||||
return-if too-far-left?, 0/false
|
||||
return-if too-far-left?, false
|
||||
right:num <- get *editor, right:offset
|
||||
too-far-right?:bool <- greater-than click-column, right
|
||||
return-if too-far-right?, 0/false
|
||||
return-if too-far-right?, false
|
||||
# position cursor
|
||||
<begin-move-cursor>
|
||||
editor <- snap-cursor editor, screen, click-row, click-column
|
||||
undo-coalesce-tag:num <- copy 0/never
|
||||
<end-move-cursor>
|
||||
# gain focus
|
||||
return 1/true
|
||||
return true
|
||||
]
|
||||
|
||||
# Variant of 'render' that only moves the cursor (coordinates and
|
||||
|
@ -166,7 +166,7 @@ def snap-cursor editor:&:editor, screen:&:screen, target-row:num, target-column:
|
|||
def handle-keyboard-event screen:&:screen, editor:&:editor, e:event -> go-render?:bool, screen:&:screen, editor:&:editor [
|
||||
local-scope
|
||||
load-inputs
|
||||
return-unless editor, 0/don't-render
|
||||
return-unless editor, false/don't-render
|
||||
screen-width:num <- screen-width screen
|
||||
screen-height:num <- screen-height screen
|
||||
left:num <- get *editor, left:offset
|
||||
|
@ -185,7 +185,7 @@ def handle-keyboard-event screen:&:screen, editor:&:editor, e:event -> go-render
|
|||
<handle-special-character>
|
||||
# ignore any other special characters
|
||||
regular-character?:bool <- greater-or-equal c, 32/space
|
||||
return-unless regular-character?, 0/don't-render
|
||||
return-unless regular-character?, false/don't-render
|
||||
# otherwise type it in
|
||||
<begin-insert-character>
|
||||
go-render? <- insert-at-cursor editor, c, screen
|
||||
|
@ -197,7 +197,7 @@ def handle-keyboard-event screen:&:screen, editor:&:editor, e:event -> go-render
|
|||
assert is-keycode?, [event was of unknown type; neither keyboard nor mouse]
|
||||
# handlers for each special key will go here
|
||||
<handle-special-key>
|
||||
return 1/go-render
|
||||
return true/go-render
|
||||
]
|
||||
|
||||
def insert-at-cursor editor:&:editor, c:char, screen:&:screen -> go-render?:bool, editor:&:editor, screen:&:screen [
|
||||
|
@ -232,7 +232,7 @@ def insert-at-cursor editor:&:editor, c:char, screen:&:screen -> go-render?:bool
|
|||
break-if overflow?
|
||||
move-cursor screen, save-row, save-column
|
||||
print screen, c
|
||||
return 0/don't-render
|
||||
return false/don't-render
|
||||
}
|
||||
{
|
||||
# not at right margin? print the character and rest of line
|
||||
|
@ -245,7 +245,7 @@ def insert-at-cursor editor:&:editor, c:char, screen:&:screen -> go-render?:bool
|
|||
{
|
||||
# hit right margin? give up and let caller render
|
||||
at-right?:bool <- greater-than curr-column, right
|
||||
return-if at-right?, 1/go-render
|
||||
return-if at-right?, true/go-render
|
||||
break-unless curr
|
||||
# newline? done.
|
||||
currc:char <- get *curr, value:offset
|
||||
|
@ -256,9 +256,9 @@ def insert-at-cursor editor:&:editor, c:char, screen:&:screen -> go-render?:bool
|
|||
curr <- next curr
|
||||
loop
|
||||
}
|
||||
return 0/don't-render
|
||||
return false/don't-render
|
||||
}
|
||||
return 1/go-render
|
||||
return true/go-render
|
||||
]
|
||||
|
||||
# helper for tests
|
||||
|
@ -708,7 +708,7 @@ after <insert-character-special-case> [
|
|||
at-end-of-line? <- equal next-character, 10/newline
|
||||
}
|
||||
# break unless ((eol? and at-wrap?) or (~eol? and just-before-wrap?))
|
||||
move-cursor-to-next-line?:bool <- copy 0/false
|
||||
move-cursor-to-next-line?:bool <- copy false
|
||||
{
|
||||
break-if at-end-of-line?
|
||||
move-cursor-to-next-line? <- copy just-before-wrap?
|
||||
|
@ -735,7 +735,7 @@ after <insert-character-special-case> [
|
|||
break-unless below-screen?
|
||||
<scroll-down>
|
||||
}
|
||||
return 1/go-render
|
||||
return true/go-render
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -829,7 +829,7 @@ container editor [
|
|||
]
|
||||
|
||||
after <editor-initialization> [
|
||||
*result <- put *result, indent?:offset, 1/true
|
||||
*result <- put *result, indent?:offset, true
|
||||
]
|
||||
|
||||
scenario editor-moves-cursor-down-after-inserting-newline [
|
||||
|
@ -859,7 +859,7 @@ after <handle-special-character> [
|
|||
<begin-insert-enter>
|
||||
insert-new-line-and-indent editor, screen
|
||||
<end-insert-enter>
|
||||
return 1/go-render
|
||||
return true/go-render
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -885,7 +885,7 @@ def insert-new-line-and-indent editor:&:editor, screen:&:screen -> editor:&:edit
|
|||
{
|
||||
below-screen?:bool <- greater-or-equal cursor-row, screen-height # must be equal, never greater
|
||||
break-unless below-screen?
|
||||
<scroll-down>
|
||||
<scroll-down2>
|
||||
cursor-row <- subtract cursor-row, 1 # bring back into screen range
|
||||
*editor <- put *editor, cursor-row:offset, cursor-row
|
||||
}
|
||||
|
@ -915,16 +915,16 @@ def at-start-of-wrapped-line? editor:&:editor -> result:bool [
|
|||
left:num <- get *editor, left:offset
|
||||
cursor-column:num <- get *editor, cursor-column:offset
|
||||
cursor-at-left?:bool <- equal cursor-column, left
|
||||
return-unless cursor-at-left?, 0/false
|
||||
return-unless cursor-at-left?, false
|
||||
before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset
|
||||
before-before-cursor:&:duplex-list:char <- prev before-cursor
|
||||
return-unless before-before-cursor, 0/false # cursor is at start of editor
|
||||
return-unless before-before-cursor, false # cursor is at start of editor
|
||||
char-before-cursor:char <- get *before-cursor, value:offset
|
||||
cursor-after-newline?:bool <- equal char-before-cursor, 10/newline
|
||||
return-if cursor-after-newline?, 0/false
|
||||
return-if cursor-after-newline?, false
|
||||
# if cursor is at left margin and not at start, but previous character is not a newline,
|
||||
# then we're at start of a wrapped line
|
||||
return 1/true
|
||||
return true
|
||||
]
|
||||
|
||||
# takes a pointer 'curr' into the doubly-linked list and its sentinel, counts
|
||||
|
@ -1095,8 +1095,8 @@ after <handle-special-key> [
|
|||
{
|
||||
paste-start?:bool <- equal k, 65507/paste-start
|
||||
break-unless paste-start?
|
||||
*editor <- put *editor, indent?:offset, 0/false
|
||||
return 1/go-render
|
||||
*editor <- put *editor, indent?:offset, false
|
||||
return true/go-render
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -1104,8 +1104,8 @@ after <handle-special-key> [
|
|||
{
|
||||
paste-end?:bool <- equal k, 65506/paste-end
|
||||
break-unless paste-end?
|
||||
*editor <- put *editor, indent?:offset, 1/true
|
||||
return 1/go-render
|
||||
*editor <- put *editor, indent?:offset, true
|
||||
return true/go-render
|
||||
}
|
||||
]
|
||||
|
||||
|
|
|
@ -113,7 +113,7 @@ def delete-before-cursor editor:&:editor, screen:&:screen -> go-render?:bool, ba
|
|||
data:&:duplex-list:char <- get *editor, data:offset
|
||||
# if at start of text (before-cursor at § sentinel), return
|
||||
prev:&:duplex-list:char <- prev before-cursor
|
||||
return-unless prev, 0/no-more-render, 0/nothing-deleted
|
||||
return-unless prev, false/no-more-render, 0/nothing-deleted
|
||||
trace 10, [app], [delete-before-cursor]
|
||||
original-row:num <- get *editor, cursor-row:offset
|
||||
scroll?:bool <- move-cursor-coordinates-left editor
|
||||
|
@ -121,13 +121,13 @@ def delete-before-cursor editor:&:editor, screen:&:screen -> go-render?:bool, ba
|
|||
data <- remove before-cursor, data # will also neatly trim next/prev pointers in backspaced-cell/before-cursor
|
||||
before-cursor <- copy prev
|
||||
*editor <- put *editor, before-cursor:offset, before-cursor
|
||||
return-if scroll?, 1/go-render
|
||||
return-if scroll?, true/go-render
|
||||
screen-width:num <- screen-width screen
|
||||
cursor-row:num <- get *editor, cursor-row:offset
|
||||
cursor-column:num <- get *editor, cursor-column:offset
|
||||
# did we just backspace over a newline?
|
||||
same-row?:bool <- equal cursor-row, original-row
|
||||
return-unless same-row?, 1/go-render
|
||||
return-unless same-row?, true/go-render
|
||||
left:num <- get *editor, left:offset
|
||||
right:num <- get *editor, right:offset
|
||||
curr:&:duplex-list:char <- next before-cursor
|
||||
|
@ -136,7 +136,7 @@ def delete-before-cursor editor:&:editor, screen:&:screen -> go-render?:bool, ba
|
|||
{
|
||||
# hit right margin? give up and let caller render
|
||||
at-right?:bool <- greater-or-equal curr-column, right
|
||||
return-if at-right?, 1/go-render
|
||||
return-if at-right?, true/go-render
|
||||
break-unless curr
|
||||
# newline? done.
|
||||
currc:char <- get *curr, value:offset
|
||||
|
@ -150,13 +150,13 @@ def delete-before-cursor editor:&:editor, screen:&:screen -> go-render?:bool, ba
|
|||
# we're guaranteed not to be at the right margin
|
||||
space:char <- copy 32/space
|
||||
screen <- print screen, space
|
||||
go-render? <- copy 0/false
|
||||
go-render? <- copy false
|
||||
]
|
||||
|
||||
def move-cursor-coordinates-left editor:&:editor -> go-render?:bool, editor:&:editor [
|
||||
local-scope
|
||||
load-inputs
|
||||
go-render?:bool <- copy 0/false
|
||||
go-render?:bool <- copy false
|
||||
before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset
|
||||
cursor-row:num <- get *editor, cursor-row:offset
|
||||
cursor-column:num <- get *editor, cursor-column:offset
|
||||
|
@ -180,7 +180,7 @@ def move-cursor-coordinates-left editor:&:editor -> go-render?:bool, editor:&:ed
|
|||
{
|
||||
break-unless top-of-screen?
|
||||
<scroll-up>
|
||||
go-render? <- copy 1/true
|
||||
go-render? <- copy true
|
||||
}
|
||||
{
|
||||
# case 1: if previous character was newline, figure out how long the previous line is
|
||||
|
@ -376,11 +376,11 @@ def delete-at-cursor editor:&:editor, screen:&:screen -> go-render?:bool, delete
|
|||
before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset
|
||||
data:&:duplex-list:char <- get *editor, data:offset
|
||||
deleted-cell:&:duplex-list:char <- next before-cursor
|
||||
return-unless deleted-cell, 0/don't-render
|
||||
return-unless deleted-cell, false/don't-render
|
||||
currc:char <- get *deleted-cell, value:offset
|
||||
data <- remove deleted-cell, data
|
||||
deleted-newline?:bool <- equal currc, 10/newline
|
||||
return-if deleted-newline?, 1/go-render
|
||||
return-if deleted-newline?, true/go-render
|
||||
# wasn't a newline? render rest of line
|
||||
curr:&:duplex-list:char <- next before-cursor # refresh after remove above
|
||||
cursor-row:num <- get *editor, cursor-row:offset
|
||||
|
@ -391,7 +391,7 @@ def delete-at-cursor editor:&:editor, screen:&:screen -> go-render?:bool, delete
|
|||
{
|
||||
# hit right margin? give up and let caller render
|
||||
at-right?:bool <- greater-or-equal curr-column, screen-width
|
||||
return-if at-right?, 1/go-render
|
||||
return-if at-right?, true/go-render
|
||||
break-unless curr
|
||||
currc:char <- get *curr, value:offset
|
||||
at-newline?:bool <- equal currc, 10/newline
|
||||
|
@ -404,7 +404,7 @@ def delete-at-cursor editor:&:editor, screen:&:screen -> go-render?:bool, delete
|
|||
# we're guaranteed not to be at the right margin
|
||||
space:char <- copy 32/space
|
||||
screen <- print screen, space
|
||||
go-render? <- copy 0/false
|
||||
go-render? <- copy false
|
||||
]
|
||||
|
||||
# right arrow
|
||||
|
@ -468,11 +468,11 @@ def move-cursor-coordinates-right editor:&:editor, screen-height:num -> go-rende
|
|||
cursor-column <- copy left
|
||||
*editor <- put *editor, cursor-column:offset, cursor-column
|
||||
below-screen?:bool <- greater-or-equal cursor-row, screen-height # must be equal
|
||||
return-unless below-screen?, 0/don't-render
|
||||
return-unless below-screen?, false/don't-render
|
||||
<scroll-down>
|
||||
cursor-row <- subtract cursor-row, 1 # bring back into screen range
|
||||
*editor <- put *editor, cursor-row:offset, cursor-row
|
||||
return 1/go-render
|
||||
return true/go-render
|
||||
}
|
||||
# if the line wraps, move cursor to start of next row
|
||||
{
|
||||
|
@ -491,16 +491,16 @@ def move-cursor-coordinates-right editor:&:editor, screen-height:num -> go-rende
|
|||
cursor-column <- copy left
|
||||
*editor <- put *editor, cursor-column:offset, cursor-column
|
||||
below-screen?:bool <- greater-or-equal cursor-row, screen-height # must be equal
|
||||
return-unless below-screen?, 0/no-more-render
|
||||
return-unless below-screen?, false/no-more-render
|
||||
<scroll-down>
|
||||
cursor-row <- subtract cursor-row, 1 # bring back into screen range
|
||||
*editor <- put *editor, cursor-row:offset, cursor-row
|
||||
return 1/go-render
|
||||
return true/go-render
|
||||
}
|
||||
# otherwise move cursor one character right
|
||||
cursor-column <- add cursor-column, 1
|
||||
*editor <- put *editor, cursor-column:offset, cursor-column
|
||||
go-render? <- copy 0/false
|
||||
go-render? <- copy false
|
||||
]
|
||||
|
||||
scenario editor-moves-cursor-to-next-line-with-right-arrow [
|
||||
|
@ -722,7 +722,7 @@ after <handle-special-key> [
|
|||
trace 10, [app], [left arrow]
|
||||
# if not at start of text (before-cursor at § sentinel)
|
||||
prev:&:duplex-list:char <- prev before-cursor
|
||||
return-unless prev, 0/don't-render
|
||||
return-unless prev, false/don't-render
|
||||
<begin-move-cursor>
|
||||
go-render? <- move-cursor-coordinates-left editor
|
||||
before-cursor <- copy prev
|
||||
|
@ -1000,7 +1000,7 @@ after <handle-special-key> [
|
|||
def move-to-previous-line editor:&:editor -> go-render?:bool, editor:&:editor [
|
||||
local-scope
|
||||
load-inputs
|
||||
go-render?:bool <- copy 0/false
|
||||
go-render?:bool <- copy false
|
||||
cursor-row:num <- get *editor, cursor-row:offset
|
||||
cursor-column:num <- get *editor, cursor-column:offset
|
||||
before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset
|
||||
|
@ -1056,7 +1056,7 @@ def move-to-previous-line editor:&:editor -> go-render?:bool, editor:&:editor [
|
|||
# if cursor already at top, scroll up
|
||||
break-unless already-at-top?
|
||||
<scroll-up>
|
||||
return 1/go-render
|
||||
return true/go-render
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -1411,7 +1411,7 @@ def move-to-next-line editor:&:editor, screen-height:num -> go-render?:bool, edi
|
|||
break-if before-cursor
|
||||
{
|
||||
break-if at-bottom-of-screen?
|
||||
return 0/don't-render
|
||||
return false/don't-render
|
||||
}
|
||||
{
|
||||
break-unless at-bottom-of-screen?
|
||||
|
@ -1423,7 +1423,7 @@ def move-to-next-line editor:&:editor, screen-height:num -> go-render?:bool, edi
|
|||
break-if next
|
||||
{
|
||||
break-if at-bottom-of-screen?
|
||||
return 0/don't-render
|
||||
return false/don't-render
|
||||
}
|
||||
{
|
||||
break-unless at-bottom-of-screen?
|
||||
|
@ -1452,7 +1452,7 @@ def move-to-next-line editor:&:editor, screen-height:num -> go-render?:bool, edi
|
|||
break-if next
|
||||
{
|
||||
break-if at-bottom-of-screen?
|
||||
return 0/don't-render
|
||||
return false/don't-render
|
||||
}
|
||||
{
|
||||
break-unless at-bottom-of-screen?
|
||||
|
@ -1476,11 +1476,11 @@ def move-to-next-line editor:&:editor, screen-height:num -> go-render?:bool, edi
|
|||
*editor <- put *editor, before-cursor:offset, before-cursor
|
||||
*editor <- put *editor, cursor-column:offset, cursor-column
|
||||
*editor <- put *editor, cursor-row:offset, cursor-row
|
||||
return 0/don't-render
|
||||
return false/don't-render
|
||||
}
|
||||
+try-to-scroll
|
||||
<scroll-down>
|
||||
go-render? <- copy 1/true
|
||||
go-render? <- copy true
|
||||
]
|
||||
|
||||
scenario editor-adjusts-column-at-next-line [
|
||||
|
@ -1589,7 +1589,7 @@ after <handle-special-character> [
|
|||
move-to-start-of-screen-line editor
|
||||
undo-coalesce-tag:num <- copy 0/never
|
||||
<end-move-cursor>
|
||||
return 0/don't-render
|
||||
return false/don't-render
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -1601,7 +1601,7 @@ after <handle-special-key> [
|
|||
move-to-start-of-screen-line editor
|
||||
undo-coalesce-tag:num <- copy 0/never
|
||||
<end-move-cursor>
|
||||
return 0/don't-render
|
||||
return false/don't-render
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -1814,7 +1814,7 @@ after <handle-special-character> [
|
|||
move-to-end-of-line editor
|
||||
undo-coalesce-tag:num <- copy 0/never
|
||||
<end-move-cursor>
|
||||
return 0/don't-render
|
||||
return false/don't-render
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -1826,7 +1826,7 @@ after <handle-special-key> [
|
|||
move-to-end-of-line editor
|
||||
undo-coalesce-tag:num <- copy 0/never
|
||||
<end-move-cursor>
|
||||
return 0/don't-render
|
||||
return false/don't-render
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -2025,7 +2025,7 @@ def minimal-render-for-ctrl-u screen:&:screen, editor:&:editor, deleted-cells:&:
|
|||
{
|
||||
# if we have a wrapped line, give up and render the whole screen
|
||||
wrap?:bool <- greater-or-equal i, right
|
||||
return-if wrap?, 1/go-render
|
||||
return-if wrap?, true/go-render
|
||||
curr <- next curr
|
||||
break-unless curr
|
||||
c:char <- get *curr, value:offset
|
||||
|
@ -2041,11 +2041,11 @@ def minimal-render-for-ctrl-u screen:&:screen, editor:&:editor, deleted-cells:&:
|
|||
left:num <- get *editor, left:offset
|
||||
end:num <- subtract right, left
|
||||
wrap?:bool <- greater-or-equal old-row-len, end
|
||||
return-if wrap?, 1/go-render
|
||||
return-if wrap?, true/go-render
|
||||
curr-line:text <- buffer-to-array buf
|
||||
curr-row:num <- get *editor, cursor-row:offset
|
||||
render-code screen, curr-line, curr-column, right, curr-row
|
||||
return 0/dont-render
|
||||
return false/dont-render
|
||||
]
|
||||
|
||||
def delete-to-start-of-line editor:&:editor -> result:&:duplex-list:char, editor:&:editor [
|
||||
|
@ -2054,7 +2054,7 @@ def delete-to-start-of-line editor:&:editor -> result:&:duplex-list:char, editor
|
|||
# compute range to delete
|
||||
init:&:duplex-list:char <- get *editor, data:offset
|
||||
top-of-screen:&:duplex-list:char <- get *editor, top-of-screen:offset
|
||||
update-top-of-screen?:bool <- copy 0/false
|
||||
update-top-of-screen?:bool <- copy false
|
||||
before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset
|
||||
start:&:duplex-list:char <- copy before-cursor
|
||||
end:&:duplex-list:char <- next before-cursor
|
||||
|
@ -2595,7 +2595,7 @@ def minimal-render-for-ctrl-k screen:&:screen, editor:&:editor, deleted-cells:&:
|
|||
local-scope
|
||||
load-inputs
|
||||
# if we deleted nothing, there's nothing to render
|
||||
return-unless deleted-cells, 0/dont-render
|
||||
return-unless deleted-cells, false/dont-render
|
||||
# if the line used to wrap before, give up and render the whole screen
|
||||
curr-column:num <- get *editor, cursor-column:offset
|
||||
num-deleted-cells:num <- length deleted-cells
|
||||
|
@ -2604,9 +2604,9 @@ def minimal-render-for-ctrl-k screen:&:screen, editor:&:editor, deleted-cells:&:
|
|||
right:num <- get *editor, right:offset
|
||||
end:num <- subtract right, left
|
||||
wrap?:bool <- greater-or-equal old-row-len, end
|
||||
return-if wrap?, 1/go-render
|
||||
return-if wrap?, true/go-render
|
||||
clear-line-until screen, right
|
||||
return 0/dont-render
|
||||
return false/dont-render
|
||||
]
|
||||
|
||||
def delete-to-end-of-line editor:&:editor -> result:&:duplex-list:char, editor:&:editor [
|
||||
|
@ -2839,7 +2839,20 @@ after <scroll-down> [
|
|||
top-of-screen <- before-start-of-next-line top-of-screen, max
|
||||
*editor <- put *editor, top-of-screen:offset, top-of-screen
|
||||
no-movement?:bool <- equal old-top, top-of-screen
|
||||
return-if no-movement?, 0/don't-render
|
||||
return-if no-movement?, false/don't-render
|
||||
]
|
||||
|
||||
after <scroll-down2> [
|
||||
trace 10, [app], [scroll down]
|
||||
top-of-screen:&:duplex-list:char <- get *editor, top-of-screen:offset
|
||||
left:num <- get *editor, left:offset
|
||||
right:num <- get *editor, right:offset
|
||||
max:num <- subtract right, left
|
||||
old-top:&:duplex-list:char <- copy top-of-screen
|
||||
top-of-screen <- before-start-of-next-line top-of-screen, max
|
||||
*editor <- put *editor, top-of-screen:offset, top-of-screen
|
||||
no-movement?:bool <- equal old-top, top-of-screen
|
||||
return-if no-movement?
|
||||
]
|
||||
|
||||
# Takes a pointer into the doubly-linked list, scans ahead at most 'max'
|
||||
|
@ -3210,7 +3223,7 @@ after <scroll-up> [
|
|||
top-of-screen <- before-previous-screen-line top-of-screen, editor
|
||||
*editor <- put *editor, top-of-screen:offset, top-of-screen
|
||||
no-movement?:bool <- equal old-top, top-of-screen
|
||||
return-if no-movement?, 0/don't-render
|
||||
return-if no-movement?, false/don't-render
|
||||
]
|
||||
|
||||
scenario editor-scrolls-up-past-wrapped-line-using-arrow-keys [
|
||||
|
@ -4262,7 +4275,7 @@ def render-line-from-start screen:&:screen, editor:&:editor, right-margin:num ->
|
|||
curr:&:duplex-list:char <- copy line-start
|
||||
{
|
||||
render-all?:bool <- greater-or-equal i, end
|
||||
return-if render-all?, 1/go-render
|
||||
return-if render-all?, true/go-render
|
||||
break-unless curr
|
||||
c:char <- get *curr, value:offset
|
||||
newline?:bool <- equal c, 10/newline
|
||||
|
@ -4274,7 +4287,7 @@ def render-line-from-start screen:&:screen, editor:&:editor, right-margin:num ->
|
|||
loop
|
||||
}
|
||||
clear-line-until screen, right
|
||||
return 0/dont-render
|
||||
return false/dont-render
|
||||
]
|
||||
|
||||
def before-start-of-screen-line editor:&:editor -> result:&:duplex-list:char [
|
||||
|
|
|
@ -32,7 +32,7 @@ def new-programming-environment resources:&:resources, screen:&:screen, test-san
|
|||
current-sandbox:&:editor <- new-editor test-sandbox-editor-contents, sandbox-left, width/right
|
||||
*result <- put *result, recipes:offset, recipes
|
||||
*result <- put *result, current-sandbox:offset, current-sandbox
|
||||
*result <- put *result, sandbox-in-focus?:offset, 0/false
|
||||
*result <- put *result, sandbox-in-focus?:offset, false
|
||||
<programming-environment-initialization>
|
||||
]
|
||||
|
||||
|
@ -45,8 +45,8 @@ def event-loop screen:&:screen, console:&:console, env:&:environment, resources:
|
|||
# if we fall behind we'll stop updating the screen, but then we have to
|
||||
# render the entire screen when we catch up.
|
||||
# todo: test this
|
||||
render-recipes-on-no-more-events?:bool <- copy 0/false
|
||||
render-sandboxes-on-no-more-events?:bool <- copy 0/false
|
||||
render-recipes-on-no-more-events?:bool <- copy false
|
||||
render-sandboxes-on-no-more-events?:bool <- copy false
|
||||
{
|
||||
# looping over each (keyboard or touch) event as it occurs
|
||||
+next-event
|
||||
|
@ -113,12 +113,12 @@ def event-loop screen:&:screen, console:&:console, env:&:environment, resources:
|
|||
break-if more-events?
|
||||
{
|
||||
break-unless render-recipes-on-no-more-events?
|
||||
render-recipes-on-no-more-events? <- copy 0/false
|
||||
render-recipes-on-no-more-events? <- copy false
|
||||
screen <- render-recipes screen, env, render
|
||||
}
|
||||
{
|
||||
break-unless render-sandboxes-on-no-more-events?
|
||||
render-sandboxes-on-no-more-events? <- copy 0/false
|
||||
render-sandboxes-on-no-more-events? <- copy false
|
||||
screen <- render-sandbox-side screen, env, render
|
||||
}
|
||||
}
|
||||
|
|
|
@ -201,7 +201,7 @@ def update-recipes env:&:environment, resources:&:resources, screen:&:screen ->
|
|||
in:text <- editor-contents recipes
|
||||
resources <- dump resources, [lesson/recipes.mu], in
|
||||
reload in
|
||||
errors-found? <- copy 0/false
|
||||
errors-found? <- copy false
|
||||
]
|
||||
|
||||
# replaced in a later layer
|
||||
|
|
|
@ -142,7 +142,7 @@ def should-attempt-copy? click-row:num, click-column:num, env:&:environment -> r
|
|||
load-inputs
|
||||
# are we below the sandbox editor?
|
||||
click-sandbox-area?:bool <- click-on-sandbox-area? click-row, click-column, env
|
||||
return-unless click-sandbox-area?, 0/false
|
||||
return-unless click-sandbox-area?, false
|
||||
# narrower, is the click in the columns spanning the 'copy' button?
|
||||
first-sandbox:&:editor <- get *env, current-sandbox:offset
|
||||
assert first-sandbox, [!!]
|
||||
|
@ -150,7 +150,7 @@ def should-attempt-copy? click-row:num, click-column:num, env:&:environment -> r
|
|||
sandbox-right-margin:num <- get *first-sandbox, right:offset
|
||||
_, _, copy-button-left:num, copy-button-right:num <- sandbox-menu-columns sandbox-left-margin, sandbox-right-margin
|
||||
copy-button-vertical-area?:bool <- within-range? click-column, copy-button-left, copy-button-right
|
||||
return-unless copy-button-vertical-area?, 0/false
|
||||
return-unless copy-button-vertical-area?, false
|
||||
# finally, is sandbox editor empty?
|
||||
current-sandbox:&:editor <- get *env, current-sandbox:offset
|
||||
result <- empty-editor? current-sandbox
|
||||
|
@ -161,15 +161,15 @@ def try-copy-sandbox click-row:num, env:&:environment -> clicked-on-copy-button?
|
|||
load-inputs
|
||||
# identify the sandbox to copy, if the click was actually on the 'copy' button
|
||||
sandbox:&:sandbox <- find-sandbox env, click-row
|
||||
return-unless sandbox, 0/false
|
||||
clicked-on-copy-button? <- copy 1/true
|
||||
return-unless sandbox, false
|
||||
clicked-on-copy-button? <- copy true
|
||||
text:text <- get *sandbox, data:offset
|
||||
current-sandbox:&:editor <- get *env, current-sandbox:offset
|
||||
current-sandbox <- insert-text current-sandbox, text
|
||||
# reset scroll
|
||||
*env <- put *env, render-from:offset, -1
|
||||
# position cursor in sandbox editor
|
||||
*env <- put *env, sandbox-in-focus?:offset, 1/true
|
||||
*env <- put *env, sandbox-in-focus?:offset, true
|
||||
]
|
||||
|
||||
def find-sandbox env:&:environment, click-row:num -> result:&:sandbox [
|
||||
|
@ -193,9 +193,9 @@ def click-on-sandbox-area? click-row:num, click-column:num, env:&:environment ->
|
|||
current-sandbox:&:editor <- get *env, current-sandbox:offset
|
||||
sandbox-left-margin:num <- get *current-sandbox, left:offset
|
||||
on-sandbox-side?:bool <- greater-or-equal click-column, sandbox-left-margin
|
||||
return-unless on-sandbox-side?, 0/false
|
||||
return-unless on-sandbox-side?, false
|
||||
first-sandbox:&:sandbox <- get *env, sandbox:offset
|
||||
return-unless first-sandbox, 0/false
|
||||
return-unless first-sandbox, false
|
||||
first-sandbox-begins:num <- get *first-sandbox, starting-row-on-screen:offset
|
||||
result <- greater-or-equal click-row, first-sandbox-begins
|
||||
]
|
||||
|
@ -349,7 +349,7 @@ after <global-touch> [
|
|||
break-unless copy?
|
||||
modified?:bool <- prepend-sandbox-into-recipe-side click-row, env
|
||||
break-unless modified?
|
||||
*env <- put *env, sandbox-in-focus?:offset, 0/false
|
||||
*env <- put *env, sandbox-in-focus?:offset, false
|
||||
screen <- render-recipes screen, env, render
|
||||
screen <- update-cursor screen, recipes, current-sandbox, sandbox-in-focus?, env
|
||||
loop +next-event
|
||||
|
@ -362,7 +362,7 @@ def should-copy-to-recipe? click-row:num, click-column:num, env:&:environment ->
|
|||
load-inputs
|
||||
# are we below the sandbox editor?
|
||||
click-sandbox-area?:bool <- click-on-sandbox-area? click-row, click-column, env
|
||||
return-unless click-sandbox-area?, 0/false
|
||||
return-unless click-sandbox-area?, false
|
||||
# narrower, is the click in the columns spanning the 'copy' button?
|
||||
first-sandbox:&:editor <- get *env, current-sandbox:offset
|
||||
assert first-sandbox, [!!]
|
||||
|
@ -376,7 +376,7 @@ def prepend-sandbox-into-recipe-side click-row:num, env:&:environment -> clicked
|
|||
local-scope
|
||||
load-inputs
|
||||
sandbox:&:sandbox <- find-sandbox env, click-row
|
||||
return-unless sandbox, 0/false
|
||||
return-unless sandbox, false
|
||||
recipe-editor:&:editor <- get *env, recipes:offset
|
||||
recipe-data:&:duplex-list:char <- get *recipe-editor, data:offset
|
||||
# make the newly inserted code easy to delineate
|
||||
|
@ -391,5 +391,5 @@ def prepend-sandbox-into-recipe-side click-row:num, env:&:environment -> clicked
|
|||
*recipe-editor <- put *recipe-editor, before-cursor:offset, recipe-data
|
||||
*recipe-editor <- put *recipe-editor, cursor-row:offset, 1
|
||||
*recipe-editor <- put *recipe-editor, cursor-column:offset, 0
|
||||
return 1/true
|
||||
return true
|
||||
]
|
||||
|
|
|
@ -85,7 +85,7 @@ def should-attempt-delete? click-row:num, click-column:num, env:&:environment ->
|
|||
load-inputs
|
||||
# are we below the sandbox editor?
|
||||
click-sandbox-area?:bool <- click-on-sandbox-area? click-row, click-column, env
|
||||
return-unless click-sandbox-area?, 0/false
|
||||
return-unless click-sandbox-area?, false
|
||||
# narrower, is the click in the columns spanning the 'copy' button?
|
||||
first-sandbox:&:editor <- get *env, current-sandbox:offset
|
||||
assert first-sandbox, [!!]
|
||||
|
@ -100,8 +100,8 @@ def try-delete-sandbox click-row:num, env:&:environment -> clicked-on-delete-but
|
|||
load-inputs
|
||||
# identify the sandbox to delete, if the click was actually on the 'delete' button
|
||||
sandbox:&:sandbox <- find-sandbox env, click-row
|
||||
return-unless sandbox, 0/false
|
||||
clicked-on-delete-button? <- copy 1/true
|
||||
return-unless sandbox, false
|
||||
clicked-on-delete-button? <- copy true
|
||||
env <- delete-sandbox env, sandbox
|
||||
]
|
||||
|
||||
|
|
|
@ -125,7 +125,7 @@ def should-attempt-edit? click-row:num, click-column:num, env:&:environment -> r
|
|||
load-inputs
|
||||
# are we below the sandbox editor?
|
||||
click-sandbox-area?:bool <- click-on-sandbox-area? click-row, click-column, env
|
||||
return-unless click-sandbox-area?, 0/false
|
||||
return-unless click-sandbox-area?, false
|
||||
# narrower, is the click in the columns spanning the 'edit' button?
|
||||
first-sandbox:&:editor <- get *env, current-sandbox:offset
|
||||
assert first-sandbox, [!!]
|
||||
|
@ -133,7 +133,7 @@ def should-attempt-edit? click-row:num, click-column:num, env:&:environment -> r
|
|||
sandbox-right-margin:num <- get *first-sandbox, right:offset
|
||||
edit-button-left:num, edit-button-right:num, _ <- sandbox-menu-columns sandbox-left-margin, sandbox-right-margin
|
||||
edit-button-vertical-area?:bool <- within-range? click-column, edit-button-left, edit-button-right
|
||||
return-unless edit-button-vertical-area?, 0/false
|
||||
return-unless edit-button-vertical-area?, false
|
||||
# finally, is sandbox editor empty?
|
||||
current-sandbox:&:editor <- get *env, current-sandbox:offset
|
||||
result <- empty-editor? current-sandbox
|
||||
|
@ -144,8 +144,8 @@ def try-edit-sandbox click-row:num, env:&:environment -> clicked-on-edit-button?
|
|||
load-inputs
|
||||
# identify the sandbox to edit, if the click was actually on the 'edit' button
|
||||
sandbox:&:sandbox <- find-sandbox env, click-row
|
||||
return-unless sandbox, 0/false
|
||||
clicked-on-edit-button? <- copy 1/true
|
||||
return-unless sandbox, false
|
||||
clicked-on-edit-button? <- copy true
|
||||
# 'edit' button = 'copy' button + 'delete' button
|
||||
text:text <- get *sandbox, data:offset
|
||||
current-sandbox:&:editor <- get *env, current-sandbox:offset
|
||||
|
@ -154,7 +154,7 @@ def try-edit-sandbox click-row:num, env:&:environment -> clicked-on-edit-button?
|
|||
# reset scroll
|
||||
*env <- put *env, render-from:offset, -1
|
||||
# position cursor in sandbox editor
|
||||
*env <- put *env, sandbox-in-focus?:offset, 1/true
|
||||
*env <- put *env, sandbox-in-focus?:offset, true
|
||||
]
|
||||
|
||||
scenario sandbox-with-print-can-be-edited [
|
||||
|
|
|
@ -17,10 +17,10 @@ def! update-recipes env:&:environment, resources:&:resources, screen:&:screen ->
|
|||
{
|
||||
break-unless recipe-errors
|
||||
update-status screen, [errors found ], 1/red
|
||||
errors-found? <- copy 1/true
|
||||
errors-found? <- copy true
|
||||
return
|
||||
}
|
||||
errors-found? <- copy 0/false
|
||||
errors-found? <- copy false
|
||||
]
|
||||
|
||||
after <begin-run-sandboxes-on-F4> [
|
||||
|
@ -73,7 +73,7 @@ before <end-run-sandboxes> [
|
|||
error-index:num <- get *env, error-index:offset
|
||||
sandboxes-completed-successfully?:bool <- equal error-index, -1
|
||||
break-if sandboxes-completed-successfully?
|
||||
errors-found? <- copy 1/true
|
||||
errors-found? <- copy true
|
||||
}
|
||||
]
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ after <handle-special-character> [
|
|||
redo <- push op, redo
|
||||
*editor <- put *editor, redo:offset, redo
|
||||
<handle-undo>
|
||||
return 1/go-render
|
||||
return true/go-render
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -94,7 +94,7 @@ after <handle-special-character> [
|
|||
undo <- push op, undo
|
||||
*editor <- put *editor, undo:offset, undo
|
||||
<handle-redo>
|
||||
return 1/go-render
|
||||
return true/go-render
|
||||
}
|
||||
]
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
|
||||
def main [
|
||||
local-scope
|
||||
foo 0/no-exception
|
||||
foo 1/raise-exception
|
||||
foo false/no-exception
|
||||
foo true/raise-exception
|
||||
]
|
||||
|
||||
# example showing exception handling
|
||||
|
|
|
@ -13,8 +13,8 @@ exclusive-container error-or:_elem [
|
|||
|
||||
def main [
|
||||
local-scope
|
||||
foo 0/no-exception
|
||||
foo 1/raise-exception
|
||||
foo false/no-exception
|
||||
foo true/raise-exception
|
||||
]
|
||||
|
||||
# example showing exception handling
|
||||
|
|
|
@ -56,14 +56,14 @@ def new-pair a:&:cell, b:&:cell -> result:&:cell [
|
|||
def is-atom? x:&:cell -> result:bool [
|
||||
local-scope
|
||||
load-inputs
|
||||
return-unless x, 0/false
|
||||
return-unless x, false
|
||||
_, result <- maybe-convert *x, atom:variant
|
||||
]
|
||||
|
||||
def is-pair? x:&:cell -> result:bool [
|
||||
local-scope
|
||||
load-inputs
|
||||
return-unless x, 0/false
|
||||
return-unless x, false
|
||||
_, result <- maybe-convert *x, pair:variant
|
||||
]
|
||||
|
||||
|
@ -97,7 +97,7 @@ def atom-match? x:&:cell, pat:text -> result:bool [
|
|||
local-scope
|
||||
load-inputs
|
||||
s:text, is-atom?:bool <- maybe-convert *x, atom:variant
|
||||
return-unless is-atom?, 0/false
|
||||
return-unless is-atom?, false
|
||||
result <- equal pat, s
|
||||
]
|
||||
|
||||
|
|
1
mu.vim
1
mu.vim
|
@ -54,6 +54,7 @@ syntax match muLiteral %[^ ]\+:label/[^ ,]*\|[^ ]\+:label\>%
|
|||
syntax match muLiteral %[^ ]\+:type/[^ ,]*\|[^ ]\+:type\>%
|
||||
syntax match muLiteral %[^ ]\+:offset/[^ ,]*\|[^ ]\+:offset\>%
|
||||
syntax match muLiteral %[^ ]\+:variant/[^ ,]*\|[^ ]\+:variant\>%
|
||||
syntax match muLiteral % true\(\/[^ ]*\)\?\| false\(\/[^ ]*\)\?% " literals will never be the first word in an instruction
|
||||
highlight link muLiteral Constant
|
||||
|
||||
" sources of action at a distance
|
||||
|
|
|
@ -66,11 +66,11 @@ def conflicting-file? curr:square, queens:&:list:square -> result:bool [
|
|||
q:square <- first queens
|
||||
qfile:num <- get q, file:offset
|
||||
file-match?:bool <- equal curr-file, qfile
|
||||
return-if file-match?, 1/conflict-found
|
||||
return-if file-match?, true/conflict-found
|
||||
queens <- rest queens
|
||||
loop
|
||||
}
|
||||
return 0/no-conflict-found
|
||||
return false/no-conflict-found
|
||||
]
|
||||
|
||||
def conflicting-diagonal? curr:square, queens:&:list:square -> result:bool [
|
||||
|
@ -88,11 +88,11 @@ def conflicting-diagonal? curr:square, queens:&:list:square -> result:bool [
|
|||
rank-delta <- abs rank-delta
|
||||
file-delta <- abs file-delta
|
||||
diagonal-match?:bool <- equal rank-delta, file-delta
|
||||
return-if diagonal-match?, 1/conflict-found
|
||||
return-if diagonal-match?, true/conflict-found
|
||||
queens <- rest queens
|
||||
loop
|
||||
}
|
||||
return 0/no-conflict-found
|
||||
return false/no-conflict-found
|
||||
]
|
||||
|
||||
def main [
|
||||
|
|
|
@ -38,7 +38,7 @@ def same-fringe a:&:tree:_elem, b:&:tree:_elem -> result:bool [
|
|||
break-if a-done?
|
||||
break-if b-done?
|
||||
match?:bool <- equal x, y
|
||||
return-unless match?, 0/false
|
||||
return-unless match?, false
|
||||
loop
|
||||
}
|
||||
result <- and a-done?, b-done?
|
||||
|
@ -51,8 +51,8 @@ def process t:&:tree:_elem [
|
|||
return-continuation-until-mark 100/mark # initial
|
||||
traverse t
|
||||
zero-val:&:_elem <- new _elem:type
|
||||
return-continuation-until-mark 100/mark, *zero-val, 1/done # final
|
||||
assert 0/false, [continuation called past done]
|
||||
return-continuation-until-mark 100/mark, *zero-val, true/done # final
|
||||
assert false, [continuation called past done]
|
||||
]
|
||||
|
||||
# core traversal
|
||||
|
@ -68,7 +68,7 @@ def traverse t:&:tree:_elem [
|
|||
return-if r
|
||||
# leaf
|
||||
v:_elem <- get *t, val:offset
|
||||
return-continuation-until-mark 100/mark, v, 0/not-done
|
||||
return-continuation-until-mark 100/mark, v, false/not-done
|
||||
]
|
||||
|
||||
# details
|
||||
|
|
|
@ -50,23 +50,23 @@ def editor-event-loop screen:&:screen, console:&:console, editor:&:editor -> scr
|
|||
def move-cursor editor:&:editor, screen:&:screen, t:touch-event -> in-focus?:bool, editor:&:editor [
|
||||
local-scope
|
||||
load-inputs
|
||||
return-unless editor, 0/false
|
||||
return-unless editor, false
|
||||
click-row:num <- get t, row:offset
|
||||
return-unless click-row, 0/false # ignore clicks on 'menu'
|
||||
return-unless click-row, false # ignore clicks on 'menu'
|
||||
click-column:num <- get t, column:offset
|
||||
left:num <- get *editor, left:offset
|
||||
too-far-left?:bool <- lesser-than click-column, left
|
||||
return-if too-far-left?, 0/false
|
||||
return-if too-far-left?, false
|
||||
right:num <- get *editor, right:offset
|
||||
too-far-right?:bool <- greater-than click-column, right
|
||||
return-if too-far-right?, 0/false
|
||||
return-if too-far-right?, false
|
||||
# position cursor
|
||||
<begin-move-cursor>
|
||||
editor <- snap-cursor editor, screen, click-row, click-column
|
||||
undo-coalesce-tag:num <- copy 0/never
|
||||
<end-move-cursor>
|
||||
# gain focus
|
||||
return 1/true
|
||||
return true
|
||||
]
|
||||
|
||||
# Variant of 'render' that only moves the cursor (coordinates and
|
||||
|
@ -166,7 +166,7 @@ def snap-cursor editor:&:editor, screen:&:screen, target-row:num, target-column:
|
|||
def handle-keyboard-event screen:&:screen, editor:&:editor, e:event -> go-render?:bool, screen:&:screen, editor:&:editor [
|
||||
local-scope
|
||||
load-inputs
|
||||
return-unless editor, 0/don't-render
|
||||
return-unless editor, false/don't-render
|
||||
screen-width:num <- screen-width screen
|
||||
screen-height:num <- screen-height screen
|
||||
left:num <- get *editor, left:offset
|
||||
|
@ -185,7 +185,7 @@ def handle-keyboard-event screen:&:screen, editor:&:editor, e:event -> go-render
|
|||
<handle-special-character>
|
||||
# ignore any other special characters
|
||||
regular-character?:bool <- greater-or-equal c, 32/space
|
||||
return-unless regular-character?, 0/don't-render
|
||||
return-unless regular-character?, false/don't-render
|
||||
# otherwise type it in
|
||||
<begin-insert-character>
|
||||
go-render? <- insert-at-cursor editor, c, screen
|
||||
|
@ -197,7 +197,7 @@ def handle-keyboard-event screen:&:screen, editor:&:editor, e:event -> go-render
|
|||
assert is-keycode?, [event was of unknown type; neither keyboard nor mouse]
|
||||
# handlers for each special key will go here
|
||||
<handle-special-key>
|
||||
return 1/go-render
|
||||
return true/go-render
|
||||
]
|
||||
|
||||
def insert-at-cursor editor:&:editor, c:char, screen:&:screen -> go-render?:bool, editor:&:editor, screen:&:screen [
|
||||
|
@ -232,7 +232,7 @@ def insert-at-cursor editor:&:editor, c:char, screen:&:screen -> go-render?:bool
|
|||
break-if overflow?
|
||||
move-cursor screen, save-row, save-column
|
||||
print screen, c
|
||||
return 0/don't-render
|
||||
return false/don't-render
|
||||
}
|
||||
{
|
||||
# not at right margin? print the character and rest of line
|
||||
|
@ -245,7 +245,7 @@ def insert-at-cursor editor:&:editor, c:char, screen:&:screen -> go-render?:bool
|
|||
{
|
||||
# hit right margin? give up and let caller render
|
||||
at-right?:bool <- greater-than curr-column, right
|
||||
return-if at-right?, 1/go-render
|
||||
return-if at-right?, true/go-render
|
||||
break-unless curr
|
||||
# newline? done.
|
||||
currc:char <- get *curr, value:offset
|
||||
|
@ -256,9 +256,9 @@ def insert-at-cursor editor:&:editor, c:char, screen:&:screen -> go-render?:bool
|
|||
curr <- next curr
|
||||
loop
|
||||
}
|
||||
return 0/don't-render
|
||||
return false/don't-render
|
||||
}
|
||||
return 1/go-render
|
||||
return true/go-render
|
||||
]
|
||||
|
||||
# helper for tests
|
||||
|
@ -708,7 +708,7 @@ after <insert-character-special-case> [
|
|||
at-end-of-line? <- equal next-character, 10/newline
|
||||
}
|
||||
# break unless ((eol? and at-wrap?) or (~eol? and just-before-wrap?))
|
||||
move-cursor-to-next-line?:bool <- copy 0/false
|
||||
move-cursor-to-next-line?:bool <- copy false
|
||||
{
|
||||
break-if at-end-of-line?
|
||||
move-cursor-to-next-line? <- copy just-before-wrap?
|
||||
|
@ -735,7 +735,7 @@ after <insert-character-special-case> [
|
|||
break-unless below-screen?
|
||||
<scroll-down>
|
||||
}
|
||||
return 1/go-render
|
||||
return true/go-render
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -829,7 +829,7 @@ container editor [
|
|||
]
|
||||
|
||||
after <editor-initialization> [
|
||||
*result <- put *result, indent?:offset, 1/true
|
||||
*result <- put *result, indent?:offset, true
|
||||
]
|
||||
|
||||
scenario editor-moves-cursor-down-after-inserting-newline [
|
||||
|
@ -859,7 +859,7 @@ after <handle-special-character> [
|
|||
<begin-insert-enter>
|
||||
insert-new-line-and-indent editor, screen
|
||||
<end-insert-enter>
|
||||
return 1/go-render
|
||||
return true/go-render
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -885,7 +885,7 @@ def insert-new-line-and-indent editor:&:editor, screen:&:screen -> editor:&:edit
|
|||
{
|
||||
below-screen?:bool <- greater-or-equal cursor-row, screen-height # must be equal, never greater
|
||||
break-unless below-screen?
|
||||
<scroll-down>
|
||||
<scroll-down2>
|
||||
cursor-row <- subtract cursor-row, 1 # bring back into screen range
|
||||
*editor <- put *editor, cursor-row:offset, cursor-row
|
||||
}
|
||||
|
@ -915,16 +915,16 @@ def at-start-of-wrapped-line? editor:&:editor -> result:bool [
|
|||
left:num <- get *editor, left:offset
|
||||
cursor-column:num <- get *editor, cursor-column:offset
|
||||
cursor-at-left?:bool <- equal cursor-column, left
|
||||
return-unless cursor-at-left?, 0/false
|
||||
return-unless cursor-at-left?, false
|
||||
before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset
|
||||
before-before-cursor:&:duplex-list:char <- prev before-cursor
|
||||
return-unless before-before-cursor, 0/false # cursor is at start of editor
|
||||
return-unless before-before-cursor, false # cursor is at start of editor
|
||||
char-before-cursor:char <- get *before-cursor, value:offset
|
||||
cursor-after-newline?:bool <- equal char-before-cursor, 10/newline
|
||||
return-if cursor-after-newline?, 0/false
|
||||
return-if cursor-after-newline?, false
|
||||
# if cursor is at left margin and not at start, but previous character is not a newline,
|
||||
# then we're at start of a wrapped line
|
||||
return 1/true
|
||||
return true
|
||||
]
|
||||
|
||||
# takes a pointer 'curr' into the doubly-linked list and its sentinel, counts
|
||||
|
@ -1095,8 +1095,8 @@ after <handle-special-key> [
|
|||
{
|
||||
paste-start?:bool <- equal k, 65507/paste-start
|
||||
break-unless paste-start?
|
||||
*editor <- put *editor, indent?:offset, 0/false
|
||||
return 1/go-render
|
||||
*editor <- put *editor, indent?:offset, false
|
||||
return true/go-render
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -1104,8 +1104,8 @@ after <handle-special-key> [
|
|||
{
|
||||
paste-end?:bool <- equal k, 65506/paste-end
|
||||
break-unless paste-end?
|
||||
*editor <- put *editor, indent?:offset, 1/true
|
||||
return 1/go-render
|
||||
*editor <- put *editor, indent?:offset, true
|
||||
return true/go-render
|
||||
}
|
||||
]
|
||||
|
||||
|
|
|
@ -113,7 +113,7 @@ def delete-before-cursor editor:&:editor, screen:&:screen -> go-render?:bool, ba
|
|||
data:&:duplex-list:char <- get *editor, data:offset
|
||||
# if at start of text (before-cursor at § sentinel), return
|
||||
prev:&:duplex-list:char <- prev before-cursor
|
||||
return-unless prev, 0/no-more-render, 0/nothing-deleted
|
||||
return-unless prev, false/no-more-render, 0/nothing-deleted
|
||||
trace 10, [app], [delete-before-cursor]
|
||||
original-row:num <- get *editor, cursor-row:offset
|
||||
move-cursor-coordinates-left editor
|
||||
|
@ -126,7 +126,7 @@ def delete-before-cursor editor:&:editor, screen:&:screen -> go-render?:bool, ba
|
|||
cursor-column:num <- get *editor, cursor-column:offset
|
||||
# did we just backspace over a newline?
|
||||
same-row?:bool <- equal cursor-row, original-row
|
||||
return-unless same-row?, 1/go-render
|
||||
return-unless same-row?, true/go-render
|
||||
left:num <- get *editor, left:offset
|
||||
right:num <- get *editor, right:offset
|
||||
curr:&:duplex-list:char <- next before-cursor
|
||||
|
@ -135,7 +135,7 @@ def delete-before-cursor editor:&:editor, screen:&:screen -> go-render?:bool, ba
|
|||
{
|
||||
# hit right margin? give up and let caller render
|
||||
at-right?:bool <- greater-or-equal curr-column, right
|
||||
return-if at-right?, 1/go-render
|
||||
return-if at-right?, true/go-render
|
||||
break-unless curr
|
||||
# newline? done.
|
||||
currc:char <- get *curr, value:offset
|
||||
|
@ -149,7 +149,7 @@ def delete-before-cursor editor:&:editor, screen:&:screen -> go-render?:bool, ba
|
|||
# we're guaranteed not to be at the right margin
|
||||
space:char <- copy 32/space
|
||||
screen <- print screen, space
|
||||
go-render? <- copy 0/false
|
||||
go-render? <- copy false
|
||||
]
|
||||
|
||||
def move-cursor-coordinates-left editor:&:editor -> editor:&:editor [
|
||||
|
@ -373,11 +373,11 @@ def delete-at-cursor editor:&:editor, screen:&:screen -> go-render?:bool, delete
|
|||
before-cursor:&:duplex-list:char <- get *editor, before-cursor:offset
|
||||
data:&:duplex-list:char <- get *editor, data:offset
|
||||
deleted-cell:&:duplex-list:char <- next before-cursor
|
||||
return-unless deleted-cell, 0/don't-render
|
||||
return-unless deleted-cell, false/don't-render
|
||||
currc:char <- get *deleted-cell, value:offset
|
||||
data <- remove deleted-cell, data
|
||||
deleted-newline?:bool <- equal currc, 10/newline
|
||||
return-if deleted-newline?, 1/go-render
|
||||
return-if deleted-newline?, true/go-render
|
||||
# wasn't a newline? render rest of line
|
||||
curr:&:duplex-list:char <- next before-cursor # refresh after remove above
|
||||
cursor-row:num <- get *editor, cursor-row:offset
|
||||
|
@ -388,7 +388,7 @@ def delete-at-cursor editor:&:editor, screen:&:screen -> go-render?:bool, delete
|
|||
{
|
||||
# hit right margin? give up and let caller render
|
||||
at-right?:bool <- greater-or-equal curr-column, screen-width
|
||||
return-if at-right?, 1/go-render
|
||||
return-if at-right?, true/go-render
|
||||
break-unless curr
|
||||
currc:char <- get *curr, value:offset
|
||||
at-newline?:bool <- equal currc, 10/newline
|
||||
|
@ -401,7 +401,7 @@ def delete-at-cursor editor:&:editor, screen:&:screen -> go-render?:bool, delete
|
|||
# we're guaranteed not to be at the right margin
|
||||
space:char <- copy 32/space
|
||||
screen <- print screen, space
|
||||
go-render? <- copy 0/false
|
||||
go-render? <- copy false
|
||||
]
|
||||
|
||||
# right arrow
|
||||
|
@ -465,10 +465,10 @@ def move-cursor-coordinates-right editor:&:editor, screen-height:num -> go-rende
|
|||
cursor-column <- copy left
|
||||
*editor <- put *editor, cursor-column:offset, cursor-column
|
||||
below-screen?:bool <- greater-or-equal cursor-row, screen-height # must be equal
|
||||
return-unless below-screen?, 0/don't-render
|
||||
return-unless below-screen?, false/don't-render
|
||||
cursor-row <- subtract cursor-row, 1 # bring back into screen range
|
||||
*editor <- put *editor, cursor-row:offset, cursor-row
|
||||
return 1/go-render
|
||||
return true/go-render
|
||||
}
|
||||
# if the line wraps, move cursor to start of next row
|
||||
{
|
||||
|
@ -487,15 +487,15 @@ def move-cursor-coordinates-right editor:&:editor, screen-height:num -> go-rende
|
|||
cursor-column <- copy left
|
||||
*editor <- put *editor, cursor-column:offset, cursor-column
|
||||
below-screen?:bool <- greater-or-equal cursor-row, screen-height # must be equal
|
||||
return-unless below-screen?, 0/no-more-render
|
||||
return-unless below-screen?, false/no-more-render
|
||||
cursor-row <- subtract cursor-row, 1 # bring back into screen range
|
||||
*editor <- put *editor, cursor-row:offset, cursor-row
|
||||
return 1/go-render
|
||||
return true/go-render
|
||||
}
|
||||
# otherwise move cursor one character right
|
||||
cursor-column <- add cursor-column, 1
|
||||
*editor <- put *editor, cursor-column:offset, cursor-column
|
||||
go-render? <- copy 0/false
|
||||
go-render? <- copy false
|
||||
]
|
||||
|
||||
scenario editor-moves-cursor-to-next-line-with-right-arrow [
|
||||
|
@ -717,7 +717,7 @@ after <handle-special-key> [
|
|||
trace 10, [app], [left arrow]
|
||||
# if not at start of text (before-cursor at § sentinel)
|
||||
prev:&:duplex-list:char <- prev before-cursor
|
||||
return-unless prev, 0/don't-render
|
||||
return-unless prev, false/don't-render
|
||||
<begin-move-cursor>
|
||||
move-cursor-coordinates-left editor
|
||||
before-cursor <- copy prev
|
||||
|
@ -1511,7 +1511,7 @@ after <handle-special-character> [
|
|||
move-to-start-of-screen-line editor
|
||||
undo-coalesce-tag:num <- copy 0/never
|
||||
<end-move-cursor>
|
||||
return 0/don't-render
|
||||
return false/don't-render
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -1523,7 +1523,7 @@ after <handle-special-key> [
|
|||
move-to-start-of-screen-line editor
|
||||
undo-coalesce-tag:num <- copy 0/never
|
||||
<end-move-cursor>
|
||||
return 0/don't-render
|
||||
return false/don't-render
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -1736,7 +1736,7 @@ after <handle-special-character> [
|
|||
move-to-end-of-line editor
|
||||
undo-coalesce-tag:num <- copy 0/never
|
||||
<end-move-cursor>
|
||||
return 0/don't-render
|
||||
return false/don't-render
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -1748,7 +1748,7 @@ after <handle-special-key> [
|
|||
move-to-end-of-line editor
|
||||
undo-coalesce-tag:num <- copy 0/never
|
||||
<end-move-cursor>
|
||||
return 0/don't-render
|
||||
return false/don't-render
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -1947,7 +1947,7 @@ def minimal-render-for-ctrl-u screen:&:screen, editor:&:editor, deleted-cells:&:
|
|||
{
|
||||
# if we have a wrapped line, give up and render the whole screen
|
||||
wrap?:bool <- greater-or-equal i, right
|
||||
return-if wrap?, 1/go-render
|
||||
return-if wrap?, true/go-render
|
||||
curr <- next curr
|
||||
break-unless curr
|
||||
c:char <- get *curr, value:offset
|
||||
|
@ -1963,11 +1963,11 @@ def minimal-render-for-ctrl-u screen:&:screen, editor:&:editor, deleted-cells:&:
|
|||
left:num <- get *editor, left:offset
|
||||
end:num <- subtract right, left
|
||||
wrap?:bool <- greater-or-equal old-row-len, end
|
||||
return-if wrap?, 1/go-render
|
||||
return-if wrap?, true/go-render
|
||||
curr-line:text <- buffer-to-array buf
|
||||
curr-row:num <- get *editor, cursor-row:offset
|
||||
render-code screen, curr-line, curr-column, right, curr-row
|
||||
return 0/dont-render
|
||||
return false/dont-render
|
||||
]
|
||||
|
||||
def delete-to-start-of-line editor:&:editor -> result:&:duplex-list:char, editor:&:editor [
|
||||
|
@ -2332,7 +2332,7 @@ def minimal-render-for-ctrl-k screen:&:screen, editor:&:editor, deleted-cells:&:
|
|||
local-scope
|
||||
load-inputs
|
||||
# if we deleted nothing, there's nothing to render
|
||||
return-unless deleted-cells, 0/dont-render
|
||||
return-unless deleted-cells, false/dont-render
|
||||
# if the line used to wrap before, give up and render the whole screen
|
||||
curr-column:num <- get *editor, cursor-column:offset
|
||||
num-deleted-cells:num <- length deleted-cells
|
||||
|
@ -2341,9 +2341,9 @@ def minimal-render-for-ctrl-k screen:&:screen, editor:&:editor, deleted-cells:&:
|
|||
right:num <- get *editor, right:offset
|
||||
end:num <- subtract right, left
|
||||
wrap?:bool <- greater-or-equal old-row-len, end
|
||||
return-if wrap?, 1/go-render
|
||||
return-if wrap?, true/go-render
|
||||
clear-line-until screen, right
|
||||
return 0/dont-render
|
||||
return false/dont-render
|
||||
]
|
||||
|
||||
def delete-to-end-of-line editor:&:editor -> result:&:duplex-list:char, editor:&:editor [
|
||||
|
@ -2613,7 +2613,7 @@ def render-line-from-start screen:&:screen, editor:&:editor, right-margin:num ->
|
|||
curr:&:duplex-list:char <- copy line-start
|
||||
{
|
||||
render-all?:bool <- greater-or-equal i, end
|
||||
return-if render-all?, 1/go-render
|
||||
return-if render-all?, true/go-render
|
||||
break-unless curr
|
||||
c:char <- get *curr, value:offset
|
||||
newline?:bool <- equal c, 10/newline
|
||||
|
@ -2625,7 +2625,7 @@ def render-line-from-start screen:&:screen, editor:&:editor, right-margin:num ->
|
|||
loop
|
||||
}
|
||||
clear-line-until screen, right
|
||||
return 0/dont-render
|
||||
return false/dont-render
|
||||
]
|
||||
|
||||
def before-start-of-screen-line editor:&:editor -> result:&:duplex-list:char [
|
||||
|
|
|
@ -31,7 +31,7 @@ def event-loop screen:&:screen, console:&:console, env:&:environment, resources:
|
|||
# if we fall behind we'll stop updating the screen, but then we have to
|
||||
# render the entire screen when we catch up.
|
||||
# todo: test this
|
||||
render-all-on-no-more-events?:bool <- copy 0/false
|
||||
render-all-on-no-more-events?:bool <- copy false
|
||||
{
|
||||
# looping over each (keyboard or touch) event as it occurs
|
||||
+next-event
|
||||
|
@ -86,7 +86,7 @@ def event-loop screen:&:screen, console:&:console, env:&:environment, resources:
|
|||
{
|
||||
break-if more-events?
|
||||
break-unless render-all-on-no-more-events?
|
||||
render-all-on-no-more-events? <- copy 0/false
|
||||
render-all-on-no-more-events? <- copy false
|
||||
screen <- render-all screen, env, render
|
||||
}
|
||||
screen <- update-cursor screen, current-sandbox, env
|
||||
|
|
|
@ -188,7 +188,7 @@ def update-recipes env:&:environment, resources:&:resources, screen:&:screen ->
|
|||
load-inputs
|
||||
in:text <- slurp resources, [lesson/recipes.mu]
|
||||
reload in
|
||||
errors-found? <- copy 0/false
|
||||
errors-found? <- copy false
|
||||
]
|
||||
|
||||
# replaced in a later layer
|
||||
|
|
|
@ -154,7 +154,7 @@ def should-attempt-copy? click-row:num, click-column:num, env:&:environment -> r
|
|||
load-inputs
|
||||
# are we below the sandbox editor?
|
||||
click-sandbox-area?:bool <- click-on-sandbox-area? click-row, env
|
||||
return-unless click-sandbox-area?, 0/false
|
||||
return-unless click-sandbox-area?, false
|
||||
# narrower, is the click in the columns spanning the 'copy' button?
|
||||
first-sandbox:&:editor <- get *env, current-sandbox:offset
|
||||
assert first-sandbox, [!!]
|
||||
|
@ -162,7 +162,7 @@ def should-attempt-copy? click-row:num, click-column:num, env:&:environment -> r
|
|||
sandbox-right-margin:num <- get *first-sandbox, right:offset
|
||||
_, _, copy-button-left:num, copy-button-right:num, _ <- sandbox-menu-columns sandbox-left-margin, sandbox-right-margin
|
||||
copy-button-vertical-area?:bool <- within-range? click-column, copy-button-left, copy-button-right
|
||||
return-unless copy-button-vertical-area?, 0/false
|
||||
return-unless copy-button-vertical-area?, false
|
||||
# finally, is sandbox editor empty?
|
||||
current-sandbox:&:editor <- get *env, current-sandbox:offset
|
||||
result <- empty-editor? current-sandbox
|
||||
|
@ -173,8 +173,8 @@ def try-copy-sandbox click-row:num, env:&:environment -> clicked-on-copy-button?
|
|||
load-inputs
|
||||
# identify the sandbox to copy, if the click was actually on the 'copy' button
|
||||
sandbox:&:sandbox <- find-sandbox env, click-row
|
||||
return-unless sandbox, 0/false
|
||||
clicked-on-copy-button? <- copy 1/true
|
||||
return-unless sandbox, false
|
||||
clicked-on-copy-button? <- copy true
|
||||
text:text <- get *sandbox, data:offset
|
||||
current-sandbox:&:editor <- get *env, current-sandbox:offset
|
||||
current-sandbox <- insert-text current-sandbox, text
|
||||
|
@ -201,7 +201,7 @@ def click-on-sandbox-area? click-row:num, env:&:environment -> result:bool [
|
|||
local-scope
|
||||
load-inputs
|
||||
first-sandbox:&:sandbox <- get *env, sandbox:offset
|
||||
return-unless first-sandbox, 0/false
|
||||
return-unless first-sandbox, false
|
||||
first-sandbox-begins:num <- get *first-sandbox, starting-row-on-screen:offset
|
||||
result <- greater-or-equal click-row, first-sandbox-begins
|
||||
]
|
||||
|
|
|
@ -82,7 +82,7 @@ def should-attempt-delete? click-row:num, click-column:num, env:&:environment ->
|
|||
load-inputs
|
||||
# are we below the sandbox editor?
|
||||
click-sandbox-area?:bool <- click-on-sandbox-area? click-row, env
|
||||
return-unless click-sandbox-area?, 0/false
|
||||
return-unless click-sandbox-area?, false
|
||||
# narrower, is the click in the columns spanning the 'copy' button?
|
||||
first-sandbox:&:editor <- get *env, current-sandbox:offset
|
||||
assert first-sandbox, [!!]
|
||||
|
@ -97,8 +97,8 @@ def try-delete-sandbox click-row:num, env:&:environment -> clicked-on-delete-but
|
|||
load-inputs
|
||||
# identify the sandbox to delete, if the click was actually on the 'delete' button
|
||||
sandbox:&:sandbox <- find-sandbox env, click-row
|
||||
return-unless sandbox, 0/false
|
||||
clicked-on-delete-button? <- copy 1/true
|
||||
return-unless sandbox, false
|
||||
clicked-on-delete-button? <- copy true
|
||||
env <- delete-sandbox env, sandbox
|
||||
]
|
||||
|
||||
|
|
|
@ -125,7 +125,7 @@ def should-attempt-edit? click-row:num, click-column:num, env:&:environment -> r
|
|||
load-inputs
|
||||
# are we below the sandbox editor?
|
||||
click-sandbox-area?:bool <- click-on-sandbox-area? click-row, env
|
||||
return-unless click-sandbox-area?, 0/false
|
||||
return-unless click-sandbox-area?, false
|
||||
# narrower, is the click in the columns spanning the 'edit' button?
|
||||
first-sandbox:&:editor <- get *env, current-sandbox:offset
|
||||
assert first-sandbox, [!!]
|
||||
|
@ -133,7 +133,7 @@ def should-attempt-edit? click-row:num, click-column:num, env:&:environment -> r
|
|||
sandbox-right-margin:num <- get *first-sandbox, right:offset
|
||||
edit-button-left:num, edit-button-right:num, _ <- sandbox-menu-columns sandbox-left-margin, sandbox-right-margin
|
||||
edit-button-vertical-area?:bool <- within-range? click-column, edit-button-left, edit-button-right
|
||||
return-unless edit-button-vertical-area?, 0/false
|
||||
return-unless edit-button-vertical-area?, false
|
||||
# finally, is sandbox editor empty?
|
||||
current-sandbox:&:editor <- get *env, current-sandbox:offset
|
||||
result <- empty-editor? current-sandbox
|
||||
|
@ -144,8 +144,8 @@ def try-edit-sandbox click-row:num, env:&:environment -> clicked-on-edit-button?
|
|||
load-inputs
|
||||
# identify the sandbox to edit, if the click was actually on the 'edit' button
|
||||
sandbox:&:sandbox <- find-sandbox env, click-row
|
||||
return-unless sandbox, 0/false
|
||||
clicked-on-edit-button? <- copy 1/true
|
||||
return-unless sandbox, false
|
||||
clicked-on-edit-button? <- copy true
|
||||
# 'edit' button = 'copy' button + 'delete' button
|
||||
text:text <- get *sandbox, data:offset
|
||||
current-sandbox:&:editor <- get *env, current-sandbox:offset
|
||||
|
|
|
@ -15,10 +15,10 @@ def! update-recipes env:&:environment, resources:&:resources, screen:&:screen ->
|
|||
{
|
||||
break-unless recipe-errors
|
||||
update-status screen, [errors found ], 1/red
|
||||
errors-found? <- copy 1/true
|
||||
errors-found? <- copy true
|
||||
return
|
||||
}
|
||||
errors-found? <- copy 0/false
|
||||
errors-found? <- copy false
|
||||
]
|
||||
|
||||
before <end-render-components> [
|
||||
|
@ -47,7 +47,7 @@ before <end-run-sandboxes> [
|
|||
error-index:num <- get *env, error-index:offset
|
||||
sandboxes-completed-successfully?:bool <- equal error-index, -1
|
||||
break-if sandboxes-completed-successfully?
|
||||
errors-found? <- copy 1/true
|
||||
errors-found? <- copy true
|
||||
}
|
||||
]
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ after <handle-special-character> [
|
|||
redo <- push op, redo
|
||||
*editor <- put *editor, redo:offset, redo
|
||||
<handle-undo>
|
||||
return 1/go-render
|
||||
return true/go-render
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -92,7 +92,7 @@ after <handle-special-character> [
|
|||
undo <- push op, undo
|
||||
*editor <- put *editor, undo:offset, undo
|
||||
<handle-redo>
|
||||
return 1/go-render
|
||||
return true/go-render
|
||||
}
|
||||
]
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ function! HighlightTangledFile()
|
|||
syntax match muLiteral %[^ ]\+:type/[^ ,]*\|[^ ]\+:type\>%
|
||||
syntax match muLiteral %[^ ]\+:offset/[^ ,]*\|[^ ]\+:offset\>%
|
||||
syntax match muLiteral %[^ ]\+:variant/[^ ,]*\|[^ ]\+:variant\>%
|
||||
syntax keyword muLiteral true false null
|
||||
highlight link muLiteral Constant
|
||||
syntax match muAssign " <- \|\<raw\>" | highlight link muAssign SpecialChar
|
||||
" common keywords
|
||||
|
|
Loading…
Reference in New Issue