4262 - literal 'null'
This commit is contained in:
parent
dd66068298
commit
01ce563dfe
|
@ -90,13 +90,6 @@ type foo = bar
|
|||
type foo = baz
|
||||
+error: 'type' conflict: 'foo' defined as both 'bar' and 'baz'
|
||||
|
||||
:(scenario type_abbreviation_for_compound)
|
||||
type foo = address:number
|
||||
def main [
|
||||
a:foo <- copy 0
|
||||
]
|
||||
+transform: product type after expanding abbreviations: ("address" "number")
|
||||
|
||||
//: cleaning up type abbreviations between tests and before exiting
|
||||
|
||||
:(before "End save_snapshots")
|
||||
|
@ -129,13 +122,6 @@ put(Type_abbreviations, "num", new_type_tree("number"));
|
|||
put(Type_abbreviations, "bool", new_type_tree("boolean"));
|
||||
put(Type_abbreviations, "char", new_type_tree("character"));
|
||||
|
||||
:(scenario use_type_abbreviations_when_declaring_type_abbreviations)
|
||||
type foo = &:num
|
||||
def main [
|
||||
a:foo <- copy 0
|
||||
]
|
||||
+transform: product type after expanding abbreviations: ("address" "number")
|
||||
|
||||
//:: Expand type aliases before running.
|
||||
//: We'll do this in a transform so that we don't need to define abbreviations
|
||||
//: before we use them.
|
||||
|
|
|
@ -102,15 +102,19 @@ bool types_match(const reagent& to, const reagent& from) {
|
|||
if (is_literal(from)) {
|
||||
if (is_mu_array(to)) return false;
|
||||
// End Matching Types For Literal(to)
|
||||
// allow writing 0 to any address
|
||||
if (is_mu_address(to)) return from.name == "0";
|
||||
if (!to.type) return false;
|
||||
if (is_mu_address(to)) return types_match_literal_to_address(from);
|
||||
// End Literal types_match Special-cases
|
||||
return size_of(to) == 1; // literals are always scalars
|
||||
}
|
||||
return types_strictly_match(to, from);
|
||||
}
|
||||
|
||||
bool types_match_literal_to_address(const reagent& from) {
|
||||
// End Literal->Address types_match(from) Special-cases
|
||||
return false;
|
||||
}
|
||||
|
||||
//: copy arguments for later layers
|
||||
bool types_strictly_match(reagent/*copy*/ to, reagent/*copy*/ from) {
|
||||
// End Preprocess types_strictly_match(reagent to, reagent from)
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
:(before "End Mu Types Initialization")
|
||||
put(Type_ordinal, "literal-boolean", 0);
|
||||
|
||||
//: 'true'
|
||||
|
||||
:(scenario true)
|
||||
def main [
|
||||
1:boolean <- copy true
|
||||
|
@ -21,6 +23,8 @@ if (name == "true") {
|
|||
:(before "End Literal types_match Special-cases")
|
||||
if (is_mu_boolean(to)) return from.name == "false" || from.name == "true";
|
||||
|
||||
//: 'false'
|
||||
|
||||
:(scenario false)
|
||||
def main [
|
||||
1:boolean <- copy false
|
||||
|
@ -36,3 +40,50 @@ if (name == "false") {
|
|||
type = new type_tree("literal-boolean");
|
||||
set_value(0);
|
||||
}
|
||||
|
||||
//: 'null'
|
||||
|
||||
:(scenario null)
|
||||
def main [
|
||||
1:address:number <- copy null
|
||||
]
|
||||
+mem: storing 0 in location 1
|
||||
|
||||
:(scenario null_has_wildcard_type)
|
||||
def main [
|
||||
1:address:boolean <- copy null
|
||||
]
|
||||
+mem: storing 0 in location 1
|
||||
|
||||
:(before "End Mu Types Initialization")
|
||||
put(Type_ordinal, "literal-address", 0);
|
||||
|
||||
:(before "End Parsing reagent")
|
||||
if (name == "null") {
|
||||
if (type != NULL) {
|
||||
raise << "'null' is a literal and can't take a type\n" << end();
|
||||
return;
|
||||
}
|
||||
type = new type_tree("literal-address");
|
||||
set_value(0);
|
||||
}
|
||||
|
||||
:(before "End Literal->Address types_match(from) Special-cases")
|
||||
// allow writing null to any address
|
||||
if (from.name == "null") return true;
|
||||
|
||||
//: scenarios for type abbreviations that we couldn't write until now
|
||||
|
||||
:(scenario type_abbreviation_for_compound)
|
||||
type foo = address:number
|
||||
def main [
|
||||
1:foo <- copy null
|
||||
]
|
||||
+transform: product type after expanding abbreviations: ("address" "number")
|
||||
|
||||
:(scenario use_type_abbreviations_when_declaring_type_abbreviations)
|
||||
type foo = &:num
|
||||
def main [
|
||||
1:foo <- copy null
|
||||
]
|
||||
+transform: product type after expanding abbreviations: ("address" "number")
|
||||
|
|
|
@ -31,7 +31,7 @@ canonize(x);
|
|||
:(scenario store_to_0_fails)
|
||||
% Hide_errors = true;
|
||||
def main [
|
||||
1:address:num <- copy 0
|
||||
1:address:num <- copy null
|
||||
1:address:num/lookup <- copy 34
|
||||
]
|
||||
-mem: storing 34 in location 0
|
||||
|
@ -41,7 +41,7 @@ def main [
|
|||
:(scenario lookup_0_fails)
|
||||
% Hide_errors = true;
|
||||
def main [
|
||||
1:address:num <- copy 0
|
||||
1:address:num <- copy null
|
||||
2:num <- copy 1:address:num/lookup
|
||||
]
|
||||
+error: main: tried to lookup 0 in '2:num <- copy 1:address:num/lookup'
|
||||
|
@ -49,14 +49,14 @@ def main [
|
|||
:(scenario lookup_0_dumps_callstack)
|
||||
% Hide_errors = true;
|
||||
def main [
|
||||
foo 0
|
||||
foo null
|
||||
]
|
||||
def foo [
|
||||
1:address:num <- next-input
|
||||
2:num <- copy 1:address:num/lookup
|
||||
]
|
||||
+error: foo: tried to lookup 0 in '2:num <- copy 1:address:num/lookup'
|
||||
+error: called from main: foo 0
|
||||
+error: called from main: foo null
|
||||
|
||||
:(code)
|
||||
void canonize(reagent& x) {
|
||||
|
|
|
@ -245,7 +245,7 @@ else {
|
|||
|
||||
:(scenario transform_names_transforms_container_elements)
|
||||
def main [
|
||||
p:&:point <- copy 0
|
||||
p:&:point <- copy null
|
||||
a:num <- get *p:&:point, y:offset
|
||||
b:num <- get *p:&:point, x:offset
|
||||
]
|
||||
|
|
|
@ -153,7 +153,7 @@ def foo [ # dummy
|
|||
]
|
||||
def main [
|
||||
local-scope
|
||||
0:space/names:foo <- copy 0 # specify surrounding space
|
||||
0:space/names:foo <- copy null # specify surrounding space
|
||||
x:bool <- copy true
|
||||
x:num/space:1 <- copy 34
|
||||
x/space:1 <- copy 35
|
||||
|
|
|
@ -439,33 +439,6 @@ container foo [
|
|||
]
|
||||
$error: 0
|
||||
|
||||
:(scenario static_dispatch_prefers_literals_to_be_numbers_rather_than_addresses)
|
||||
def main [
|
||||
1:num <- foo 0
|
||||
]
|
||||
def foo x:&:num -> y:num [
|
||||
return 34
|
||||
]
|
||||
def foo x:num -> y:num [
|
||||
return 35
|
||||
]
|
||||
+mem: storing 35 in location 1
|
||||
|
||||
:(scenario static_dispatch_prefers_literals_to_be_numbers_rather_than_addresses_2)
|
||||
def main [
|
||||
1:num <- foo 0 0
|
||||
]
|
||||
# Both variants need to bind 0 to address in first ingredient.
|
||||
# We still want to prefer the variant with a number rather than address for
|
||||
# _subsequent_ ingredients.
|
||||
def foo x:&:num y:&:num -> z:num [ # put the bad match before the good one
|
||||
return 34
|
||||
]
|
||||
def foo x:&:num y:num -> z:num [
|
||||
return 35
|
||||
]
|
||||
+mem: storing 35 in location 1
|
||||
|
||||
:(scenario static_dispatch_on_non_literal_character_ignores_variant_with_numbers)
|
||||
% Hide_errors = true;
|
||||
def main [
|
||||
|
|
|
@ -178,7 +178,7 @@ bool concrete_type_names_strictly_match(const type_tree* to, const type_tree* fr
|
|||
if (to->atom && is_type_ingredient_name(to->name)) return true; // type ingredient matches anything
|
||||
if (!to->atom && to->right == NULL && to->left != NULL && to->left->atom && is_type_ingredient_name(to->left->name)) return true;
|
||||
if (from->atom && is_mu_address(to))
|
||||
return from->name == "literal" && rhs_reagent.name == "0";
|
||||
return from->name == "literal-address" && rhs_reagent.name == "null";
|
||||
if (!from->atom && !to->atom)
|
||||
return concrete_type_names_strictly_match(to->left, from->left, rhs_reagent)
|
||||
&& concrete_type_names_strictly_match(to->right, from->right, rhs_reagent);
|
||||
|
@ -330,7 +330,7 @@ void compute_type_ingredient_mappings(const recipe& exemplar, const instruction&
|
|||
const reagent& exemplar_reagent = exemplar.ingredients.at(i);
|
||||
reagent/*copy*/ ingredient = inst.ingredients.at(i);
|
||||
canonize_type(ingredient);
|
||||
if (is_mu_address(exemplar_reagent) && ingredient.name == "0") continue; // assume it matches
|
||||
if (is_mu_address(exemplar_reagent) && ingredient.name == "null") continue; // assume it matches
|
||||
accumulate_type_ingredients(exemplar_reagent, ingredient, mappings, exemplar, inst, caller_recipe, error);
|
||||
}
|
||||
limit = min(SIZE(inst.products), SIZE(exemplar.products));
|
||||
|
@ -662,7 +662,7 @@ def main [
|
|||
def bar x:_t -> result:&:_t [
|
||||
local-scope
|
||||
load-ingredients
|
||||
result <- copy 0
|
||||
result <- copy null
|
||||
]
|
||||
$error: 0
|
||||
|
||||
|
@ -782,7 +782,7 @@ def foo x:_elem -> y:_elem [
|
|||
def main [
|
||||
local-scope
|
||||
# permit '0' to map to address to shape-shifting type-ingredient
|
||||
1:&:char/raw <- foo 0
|
||||
1:&:char/raw <- foo null
|
||||
]
|
||||
def foo x:&:_elem -> y:&:_elem [
|
||||
local-scope
|
||||
|
@ -953,7 +953,7 @@ def foo x:&:_elem -> y:num [
|
|||
# version with headers padded with lots of unrelated concrete types
|
||||
def main [
|
||||
1:num <- copy 23
|
||||
2:&:@:num <- copy 0
|
||||
2:&:@:num <- copy null
|
||||
3:num <- foo 2:&:@:num, 1:num
|
||||
]
|
||||
# variant with concrete type
|
||||
|
@ -1023,7 +1023,7 @@ def foo x:&:_elem -> y:num [
|
|||
|
||||
:(scenario specialize_literal_as_address)
|
||||
def main [
|
||||
1:num <- foo 0
|
||||
1:num <- foo null
|
||||
]
|
||||
# variant with concrete address type
|
||||
def foo x:&:num -> y:num [
|
||||
|
|
|
@ -110,7 +110,7 @@ def foo x:&:num [
|
|||
local-scope
|
||||
load-ingredients
|
||||
# modify the address, not the payload
|
||||
x <- copy 0
|
||||
x <- copy null
|
||||
]
|
||||
$error: 0
|
||||
|
||||
|
@ -207,7 +207,7 @@ def main [
|
|||
def foo a:&:foo [
|
||||
local-scope
|
||||
load-ingredients
|
||||
b:foo <- merge 0
|
||||
b:foo <- merge null
|
||||
# modify b, completely unrelated to immutable ingredient a
|
||||
x:&:@:num <- get b, x:offset
|
||||
*x <- put-index *x, 0, 34
|
||||
|
@ -596,7 +596,7 @@ container test-list [
|
|||
def foo x:&:test-list/contained-in:result -> result:&:test-list [
|
||||
local-scope
|
||||
load-ingredients
|
||||
result <- copy 0
|
||||
result <- copy null
|
||||
]
|
||||
$error: 0
|
||||
|
||||
|
|
12
061text.mu
12
061text.mu
|
@ -86,10 +86,10 @@ scenario text-equal-with-empty [
|
|||
scenario text-equal-with-null [
|
||||
local-scope
|
||||
x:text <- new [abcd]
|
||||
y:text <- copy 0
|
||||
y:text <- copy null
|
||||
run [
|
||||
10:bool/raw <- equal x, 0
|
||||
11:bool/raw <- equal 0, x
|
||||
10:bool/raw <- equal x, null
|
||||
11:bool/raw <- equal null, x
|
||||
12:bool/raw <- equal x, y
|
||||
13:bool/raw <- equal y, x
|
||||
14:bool/raw <- equal y, y
|
||||
|
@ -339,7 +339,7 @@ def buffer-to-array in:&:buffer:_elem -> result:&:@:_elem [
|
|||
local-scope
|
||||
load-inputs
|
||||
# propagate null buffer
|
||||
return-unless in, 0
|
||||
return-unless in, null
|
||||
len:num <- get *in, length:offset
|
||||
s:&:@:_elem <- get *in, data:offset
|
||||
# we can't just return s because it is usually the wrong length
|
||||
|
@ -406,7 +406,7 @@ scenario text-append-1 [
|
|||
|
||||
scenario text-append-null [
|
||||
local-scope
|
||||
x:text <- copy 0
|
||||
x:text <- copy null
|
||||
y:text <- new [ world!]
|
||||
run [
|
||||
z:text <- append x, y
|
||||
|
@ -420,7 +420,7 @@ scenario text-append-null [
|
|||
scenario text-append-null-2 [
|
||||
local-scope
|
||||
x:text <- new [hello,]
|
||||
y:text <- copy 0
|
||||
y:text <- copy null
|
||||
run [
|
||||
z:text <- append x, y
|
||||
10:@:char/raw <- copy *z
|
||||
|
|
28
064list.mu
28
064list.mu
|
@ -30,7 +30,7 @@ def rest in:&:list:_elem -> result:&:list:_elem/contained-in:in [
|
|||
scenario list-handling [
|
||||
run [
|
||||
local-scope
|
||||
x:&:list:num <- push 3, 0
|
||||
x:&:list:num <- push 3, null
|
||||
x <- push 4, x
|
||||
x <- push 5, x
|
||||
10:num/raw <- first x
|
||||
|
@ -73,7 +73,7 @@ def insert x:_elem, in:&:list:_elem -> in:&:list:_elem [
|
|||
|
||||
scenario inserting-into-list [
|
||||
local-scope
|
||||
list:&:list:num <- push 3, 0
|
||||
list:&:list:num <- push 3, null
|
||||
list <- push 4, list
|
||||
list <- push 5, list
|
||||
run [
|
||||
|
@ -99,7 +99,7 @@ scenario inserting-into-list [
|
|||
|
||||
scenario inserting-at-end-of-list [
|
||||
local-scope
|
||||
list:&:list:num <- push 3, 0
|
||||
list:&:list:num <- push 3, null
|
||||
list <- push 4, list
|
||||
list <- push 5, list
|
||||
run [
|
||||
|
@ -126,7 +126,7 @@ scenario inserting-at-end-of-list [
|
|||
|
||||
scenario inserting-after-start-of-list [
|
||||
local-scope
|
||||
list:&:list:num <- push 3, 0
|
||||
list:&:list:num <- push 3, null
|
||||
list <- push 4, list
|
||||
list <- push 5, list
|
||||
run [
|
||||
|
@ -160,7 +160,7 @@ def remove x:&:list:_elem/contained-in:in, in:&:list:_elem -> in:&:list:_elem [
|
|||
return-unless x
|
||||
next-node:&:list:_elem <- rest x
|
||||
# clear next pointer of 'x'
|
||||
*x <- put *x, next:offset, 0
|
||||
*x <- put *x, next:offset, null
|
||||
# if 'x' is at the head of 'in', return the new head
|
||||
at-head?:bool <- equal x, in
|
||||
return-if at-head?, next-node
|
||||
|
@ -180,13 +180,13 @@ def remove x:&:list:_elem/contained-in:in, in:&:list:_elem -> in:&:list:_elem [
|
|||
|
||||
scenario removing-from-list [
|
||||
local-scope
|
||||
list:&:list:num <- push 3, 0
|
||||
list:&:list:num <- push 3, null
|
||||
list <- push 4, list
|
||||
list <- push 5, list
|
||||
run [
|
||||
list2:&:list:num <- rest list # second element
|
||||
list <- remove list2, list
|
||||
10:bool/raw <- equal list2, 0
|
||||
10:bool/raw <- equal list2, null
|
||||
# check structure like before
|
||||
list2 <- copy list
|
||||
11:num/raw <- first list2
|
||||
|
@ -204,7 +204,7 @@ scenario removing-from-list [
|
|||
|
||||
scenario removing-from-start-of-list [
|
||||
local-scope
|
||||
list:&:list:num <- push 3, 0
|
||||
list:&:list:num <- push 3, null
|
||||
list <- push 4, list
|
||||
list <- push 5, list
|
||||
run [
|
||||
|
@ -225,7 +225,7 @@ scenario removing-from-start-of-list [
|
|||
|
||||
scenario removing-from-end-of-list [
|
||||
local-scope
|
||||
list:&:list:num <- push 3, 0
|
||||
list:&:list:num <- push 3, null
|
||||
list <- push 4, list
|
||||
list <- push 5, list
|
||||
run [
|
||||
|
@ -233,7 +233,7 @@ scenario removing-from-end-of-list [
|
|||
list2:&:list:num <- rest list
|
||||
list2 <- rest list2
|
||||
list <- remove list2, list
|
||||
10:bool/raw <- equal list2, 0
|
||||
10:bool/raw <- equal list2, null
|
||||
# check structure like before
|
||||
list2 <- copy list
|
||||
11:num/raw <- first list2
|
||||
|
@ -251,7 +251,7 @@ scenario removing-from-end-of-list [
|
|||
|
||||
scenario removing-from-singleton-list [
|
||||
local-scope
|
||||
list:&:list:num <- push 3, 0
|
||||
list:&:list:num <- push 3, null
|
||||
run [
|
||||
list <- remove list, list
|
||||
1:num/raw <- deaddress list
|
||||
|
@ -275,7 +275,7 @@ def reverse list:&:list:_elem temp:&:list:_elem/contained-in:result -> result:&:
|
|||
|
||||
scenario reverse-list [
|
||||
local-scope
|
||||
list:&:list:num <- push 1, 0
|
||||
list:&:list:num <- push 1, null
|
||||
list <- push 2, list
|
||||
list <- push 3, list
|
||||
run [
|
||||
|
@ -291,7 +291,7 @@ scenario reverse-list [
|
|||
|
||||
scenario stash-list [
|
||||
local-scope
|
||||
list:&:list:num <- push 1, 0
|
||||
list:&:list:num <- push 1, null
|
||||
list <- push 2, list
|
||||
list <- push 3, list
|
||||
run [
|
||||
|
@ -356,7 +356,7 @@ def to-buffer in:&:list:_elem, buf:&:buffer:char -> buf:&:buffer:char [
|
|||
|
||||
scenario stash-empty-list [
|
||||
local-scope
|
||||
x:&:list:num <- copy 0
|
||||
x:&:list:num <- copy null
|
||||
run [
|
||||
stash x
|
||||
]
|
||||
|
|
|
@ -10,7 +10,7 @@ def push x:_elem, in:&:duplex-list:_elem/contained-in:result -> result:&:duplex-
|
|||
local-scope
|
||||
load-inputs
|
||||
result:&:duplex-list:_elem <- new {(duplex-list _elem): type}
|
||||
*result <- merge x, in, 0
|
||||
*result <- merge x, in, null
|
||||
return-unless in
|
||||
put *in, prev:offset, result
|
||||
]
|
||||
|
@ -18,21 +18,27 @@ def push x:_elem, in:&:duplex-list:_elem/contained-in:result -> result:&:duplex-
|
|||
def first in:&:duplex-list:_elem -> result:_elem [
|
||||
local-scope
|
||||
load-inputs
|
||||
return-unless in, 0
|
||||
{
|
||||
break-if in
|
||||
zero:&:_elem <- new _elem:type
|
||||
zero-result:_elem <- copy *zero
|
||||
abandon zero
|
||||
return zero-result
|
||||
}
|
||||
result <- get *in, value:offset
|
||||
]
|
||||
|
||||
def next in:&:duplex-list:_elem -> result:&:duplex-list:_elem/contained-in:in [
|
||||
local-scope
|
||||
load-inputs
|
||||
return-unless in, 0
|
||||
return-unless in, null
|
||||
result <- get *in, next:offset
|
||||
]
|
||||
|
||||
def prev in:&:duplex-list:_elem -> result:&:duplex-list:_elem/contained-in:in [
|
||||
local-scope
|
||||
load-inputs
|
||||
return-unless in, 0
|
||||
return-unless in, null
|
||||
result <- get *in, prev:offset
|
||||
return result
|
||||
]
|
||||
|
@ -43,7 +49,7 @@ scenario duplex-list-handling [
|
|||
# reserve locations 0-9 to check for missing null check
|
||||
10:num/raw <- copy 34
|
||||
11:num/raw <- copy 35
|
||||
list:&:duplex-list:num <- push 3, 0
|
||||
list:&:duplex-list:num <- push 3, null
|
||||
list <- push 4, list
|
||||
list <- push 5, list
|
||||
list2:&:duplex-list:num <- copy list
|
||||
|
@ -108,7 +114,7 @@ def insert x:_elem, in:&:duplex-list:_elem -> in:&:duplex-list:_elem [
|
|||
|
||||
scenario inserting-into-duplex-list [
|
||||
local-scope
|
||||
list:&:duplex-list:num <- push 3, 0
|
||||
list:&:duplex-list:num <- push 3, null
|
||||
list <- push 4, list
|
||||
list <- push 5, list
|
||||
run [
|
||||
|
@ -145,7 +151,7 @@ scenario inserting-into-duplex-list [
|
|||
|
||||
scenario inserting-at-end-of-duplex-list [
|
||||
local-scope
|
||||
list:&:duplex-list:num <- push 3, 0
|
||||
list:&:duplex-list:num <- push 3, null
|
||||
list <- push 4, list
|
||||
list <- push 5, list
|
||||
run [
|
||||
|
@ -183,7 +189,7 @@ scenario inserting-at-end-of-duplex-list [
|
|||
|
||||
scenario inserting-after-start-of-duplex-list [
|
||||
local-scope
|
||||
list:&:duplex-list:num <- push 3, 0
|
||||
list:&:duplex-list:num <- push 3, null
|
||||
list <- push 4, list
|
||||
list <- push 5, list
|
||||
run [
|
||||
|
@ -229,8 +235,8 @@ def remove x:&:duplex-list:_elem/contained-in:in, in:&:duplex-list:_elem -> in:&
|
|||
next-node:&:duplex-list:_elem <- get *x, next:offset
|
||||
prev-node:&:duplex-list:_elem <- get *x, prev:offset
|
||||
# null x's pointers
|
||||
*x <- put *x, next:offset, 0
|
||||
*x <- put *x, prev:offset, 0
|
||||
*x <- put *x, next:offset, null
|
||||
*x <- put *x, prev:offset, null
|
||||
# if next-node is not null, set its prev pointer
|
||||
{
|
||||
break-unless next-node
|
||||
|
@ -249,13 +255,13 @@ def remove x:&:duplex-list:_elem/contained-in:in, in:&:duplex-list:_elem -> in:&
|
|||
|
||||
scenario removing-from-duplex-list [
|
||||
local-scope
|
||||
list:&:duplex-list:num <- push 3, 0
|
||||
list:&:duplex-list:num <- push 3, null
|
||||
list <- push 4, list
|
||||
list <- push 5, list
|
||||
run [
|
||||
list2:&:duplex-list:num <- next list # second element
|
||||
list <- remove list2, list
|
||||
10:bool/raw <- equal list2, 0
|
||||
10:bool/raw <- equal list2, null
|
||||
# check structure like before
|
||||
list2 <- copy list
|
||||
11:num/raw <- first list2
|
||||
|
@ -278,7 +284,7 @@ scenario removing-from-duplex-list [
|
|||
|
||||
scenario removing-from-start-of-duplex-list [
|
||||
local-scope
|
||||
list:&:duplex-list:num <- push 3, 0
|
||||
list:&:duplex-list:num <- push 3, null
|
||||
list <- push 4, list
|
||||
list <- push 5, list
|
||||
run [
|
||||
|
@ -304,7 +310,7 @@ scenario removing-from-start-of-duplex-list [
|
|||
|
||||
scenario removing-from-end-of-duplex-list [
|
||||
local-scope
|
||||
list:&:duplex-list:num <- push 3, 0
|
||||
list:&:duplex-list:num <- push 3, null
|
||||
list <- push 4, list
|
||||
list <- push 5, list
|
||||
run [
|
||||
|
@ -312,7 +318,7 @@ scenario removing-from-end-of-duplex-list [
|
|||
list2:&:duplex-list:num <- next list
|
||||
list2 <- next list2
|
||||
list <- remove list2, list
|
||||
10:bool/raw <- equal list2, 0
|
||||
10:bool/raw <- equal list2, null
|
||||
# check structure like before
|
||||
list2 <- copy list
|
||||
11:num/raw <- first list2
|
||||
|
@ -335,7 +341,7 @@ scenario removing-from-end-of-duplex-list [
|
|||
|
||||
scenario removing-from-singleton-duplex-list [
|
||||
local-scope
|
||||
list:&:duplex-list:num <- push 3, 0
|
||||
list:&:duplex-list:num <- push 3, null
|
||||
run [
|
||||
list <- remove list, list
|
||||
1:num/raw <- deaddress list
|
||||
|
@ -364,7 +370,7 @@ def remove x:&:duplex-list:_elem/contained-in:in, n:num, in:&:duplex-list:_elem
|
|||
|
||||
scenario removing-multiple-from-duplex-list [
|
||||
local-scope
|
||||
list:&:duplex-list:num <- push 3, 0
|
||||
list:&:duplex-list:num <- push 3, null
|
||||
list <- push 4, list
|
||||
list <- push 5, list
|
||||
run [
|
||||
|
@ -391,21 +397,21 @@ def remove-between start:&:duplex-list:_elem, end:&:duplex-list:_elem/contained-
|
|||
assert next, [malformed duplex list]
|
||||
# start->next->prev = 0
|
||||
# start->next = end
|
||||
*next <- put *next, prev:offset, 0
|
||||
*next <- put *next, prev:offset, null
|
||||
*start <- put *start, next:offset, end
|
||||
return-unless end
|
||||
# end->prev->next = 0
|
||||
# end->prev = start
|
||||
prev:&:duplex-list:_elem <- get *end, prev:offset
|
||||
assert prev, [malformed duplex list - 2]
|
||||
*prev <- put *prev, next:offset, 0
|
||||
*prev <- put *prev, next:offset, null
|
||||
*end <- put *end, prev:offset, start
|
||||
]
|
||||
|
||||
scenario remove-range [
|
||||
# construct a duplex list with six elements [13, 14, 15, 16, 17, 18]
|
||||
local-scope
|
||||
list:&:duplex-list:num <- push 18, 0
|
||||
list:&:duplex-list:num <- push 18, null
|
||||
list <- push 17, list
|
||||
list <- push 16, list
|
||||
list <- push 15, list
|
||||
|
@ -416,7 +422,7 @@ scenario remove-range [
|
|||
# first pointer: to the third element
|
||||
list2:&:duplex-list:num <- next list
|
||||
list2 <- next list2
|
||||
list2 <- remove-between list2, 0
|
||||
list2 <- remove-between list2, null
|
||||
# now check the list
|
||||
10:num/raw <- get *list, value:offset
|
||||
list <- next list
|
||||
|
@ -436,7 +442,7 @@ scenario remove-range [
|
|||
scenario remove-range-to-final [
|
||||
local-scope
|
||||
# construct a duplex list with six elements [13, 14, 15, 16, 17, 18]
|
||||
list:&:duplex-list:num <- push 18, 0
|
||||
list:&:duplex-list:num <- push 18, null
|
||||
list <- push 17, list
|
||||
list <- push 16, list
|
||||
list <- push 15, list
|
||||
|
@ -471,7 +477,7 @@ scenario remove-range-to-final [
|
|||
scenario remove-range-empty [
|
||||
local-scope
|
||||
# construct a duplex list with three elements [13, 14, 15]
|
||||
list:&:duplex-list:num <- push 15, 0
|
||||
list:&:duplex-list:num <- push 15, null
|
||||
list <- push 14, list
|
||||
list <- push 13, list
|
||||
run [
|
||||
|
@ -498,7 +504,7 @@ scenario remove-range-empty [
|
|||
scenario remove-range-to-end [
|
||||
local-scope
|
||||
# construct a duplex list with six elements [13, 14, 15, 16, 17, 18]
|
||||
list:&:duplex-list:num <- push 18, 0
|
||||
list:&:duplex-list:num <- push 18, null
|
||||
list <- push 17, list
|
||||
list <- push 16, list
|
||||
list <- push 15, list
|
||||
|
@ -507,7 +513,7 @@ scenario remove-range-to-end [
|
|||
run [
|
||||
# remove the third element and beyond
|
||||
list2:&:duplex-list:num <- next list
|
||||
remove-between list2, 0
|
||||
remove-between list2, null
|
||||
# now check the list
|
||||
10:num/raw <- get *list, value:offset
|
||||
list <- next list
|
||||
|
@ -604,7 +610,7 @@ def match x:&:duplex-list:_elem, y:&:@:_elem -> result:bool [
|
|||
|
||||
scenario duplex-list-match [
|
||||
local-scope
|
||||
list:&:duplex-list:char <- push 97/a, 0
|
||||
list:&:duplex-list:char <- push 97/a, null
|
||||
list <- push 98/b, list
|
||||
list <- push 99/c, list
|
||||
list <- push 100/d, list
|
||||
|
@ -649,7 +655,7 @@ def dump-from x:&:duplex-list:_elem [
|
|||
|
||||
scenario stash-duplex-list [
|
||||
local-scope
|
||||
list:&:duplex-list:num <- push 1, 0
|
||||
list:&:duplex-list:num <- push 1, null
|
||||
list <- push 2, list
|
||||
list <- push 3, list
|
||||
run [
|
||||
|
@ -714,7 +720,7 @@ def to-buffer in:&:duplex-list:_elem, buf:&:buffer:char -> buf:&:buffer:char [
|
|||
|
||||
scenario stash-empty-duplex-list [
|
||||
local-scope
|
||||
x:&:duplex-list:num <- copy 0
|
||||
x:&:duplex-list:num <- copy null
|
||||
run [
|
||||
stash x
|
||||
]
|
||||
|
|
|
@ -7,7 +7,7 @@ container stream:_elem [
|
|||
def new-stream s:&:@:_elem -> result:&:stream:_elem [
|
||||
local-scope
|
||||
load-inputs
|
||||
return-unless s, 0/null
|
||||
return-unless s, null
|
||||
result <- new {(stream _elem): type}
|
||||
*result <- put *result, index:offset, 0
|
||||
*result <- put *result, data:offset, s
|
||||
|
|
|
@ -183,7 +183,7 @@ def main [
|
|||
|
||||
:(scenario hash_of_zero_address)
|
||||
def main [
|
||||
1:&:num <- copy 0
|
||||
1:&:num <- copy null
|
||||
2:num <- hash 1:&:num
|
||||
]
|
||||
+mem: storing 0 in location 2
|
||||
|
|
|
@ -389,7 +389,7 @@ if (is_mu_recipe(to)) {
|
|||
:(scenario call_variable_compound_ingredient)
|
||||
def main [
|
||||
{1: (recipe (address number) -> number)} <- copy f
|
||||
2:&:num <- copy 0
|
||||
2:&:num <- copy null
|
||||
3:num <- call {1: (recipe (address number) -> number)}, 2:&:num
|
||||
]
|
||||
def f x:&:num -> y:num [
|
||||
|
|
|
@ -909,6 +909,6 @@ def print screen:&:screen, n:&:_elem -> screen:&:screen [
|
|||
break-if bg-color-found?
|
||||
bg-color <- copy 0/black
|
||||
}
|
||||
n2:num <- copy n
|
||||
n2:num <- deaddress n
|
||||
screen <- print screen, n2, color, bg-color
|
||||
]
|
||||
|
|
10
088file.mu
10
088file.mu
|
@ -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, true/error
|
||||
return-unless file, null/no-contents, true/error
|
||||
contents:&:source:char, sink:&:sink:char <- new-channel 30
|
||||
start-running receive-from-file file, sink
|
||||
]
|
||||
|
@ -39,7 +39,7 @@ def slurp resources:&:resources, filename:text -> contents:text, error?:bool [
|
|||
local-scope
|
||||
load-inputs
|
||||
source:&:source:char, error?:bool <- start-reading resources, filename
|
||||
return-if error?, 0/contents
|
||||
return-if error?, null/no-contents
|
||||
buf:&:buffer:char <- new-buffer 30/capacity
|
||||
{
|
||||
c:char, done?:bool, source <- read source
|
||||
|
@ -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, true/error-found
|
||||
return null/no-such-resource, true/error-found
|
||||
]
|
||||
|
||||
def receive-from-file file:num, sink:&:sink:char -> sink:&:sink:char [
|
||||
|
@ -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, true/error
|
||||
return-unless file, null/sink, 0/routine-id, true/error
|
||||
{
|
||||
break-if file
|
||||
msg:text <- append [no such file: ] filename
|
||||
|
@ -175,7 +175,7 @@ def transmit-to-fake-resource resources:&:resources, filename:text, source:&:sou
|
|||
contents:text <- buffer-to-array buf
|
||||
new-resource:resource <- merge filename, contents
|
||||
# write to resources
|
||||
curr-filename:text <- copy 0
|
||||
curr-filename:text <- copy null
|
||||
data:&:@:resource <- get *resources, data:offset
|
||||
# replace file contents if it already exists
|
||||
i:num <- copy 0
|
||||
|
|
|
@ -7,14 +7,14 @@ scenario example-server-test [
|
|||
# that way repeatedly running the test will give ports time to timeout and
|
||||
# close before reusing them
|
||||
make-random-nondeterministic
|
||||
port:num <- random-in-range 0/real-random-numbers, 8000, 8100
|
||||
port:num <- random-in-range null/real-random-numbers, 8000, 8100
|
||||
run [
|
||||
socket:num <- $open-server-socket port
|
||||
assert socket, [
|
||||
F - example-server-test: $open-server-socket failed]
|
||||
handler-routine:number <- start-running serve-one-request socket, example-handler
|
||||
]
|
||||
source:&:source:char <- start-reading-from-network 0/real-resources, [localhost/], port
|
||||
source:&:source:char <- start-reading-from-network null/real-resources, [localhost/], port
|
||||
response:text <- drain source
|
||||
10:@:char/raw <- copy *response
|
||||
memory-should-contain [
|
||||
|
|
|
@ -4,16 +4,16 @@
|
|||
def main [
|
||||
local-scope
|
||||
open-console # take control of screen, keyboard and mouse
|
||||
clear-screen 0/screen # non-scrolling app
|
||||
clear-screen null/screen # non-scrolling app
|
||||
|
||||
# The chessboard function takes keyboard and screen objects as inputs.
|
||||
#
|
||||
# In Mu it is good form (though not required) to explicitly state what
|
||||
# hardware a function needs.
|
||||
#
|
||||
# Here the console and screen are both 0, which usually indicates real
|
||||
# Here the console and screen are both null, which usually indicates real
|
||||
# hardware rather than a fake for testing as you'll see below.
|
||||
chessboard 0/screen, 0/console
|
||||
chessboard null/screen, null/console
|
||||
|
||||
close-console # clean up screen, keyboard and mouse
|
||||
]
|
||||
|
@ -249,27 +249,27 @@ def read-move stdin:&:source:char, screen:&:screen -> result:&:move, quit?:bool,
|
|||
local-scope
|
||||
load-inputs
|
||||
from-file:num, quit?:bool, error?:bool <- read-file stdin, screen
|
||||
return-if quit?, 0/dummy
|
||||
return-if error?, 0/dummy
|
||||
return-if quit?, null/dummy
|
||||
return-if error?, null/dummy
|
||||
# construct the move object
|
||||
result:&:move <- new move:type
|
||||
*result <- put *result, from-file:offset, from-file
|
||||
from-rank:num, quit?, error? <- read-rank stdin, screen
|
||||
return-if quit?, 0/dummy
|
||||
return-if error?, 0/dummy
|
||||
return-if quit?, null/dummy
|
||||
return-if error?, null/dummy
|
||||
*result <- put *result, from-rank:offset, from-rank
|
||||
error? <- expect-from-channel stdin, 45/dash, screen
|
||||
return-if error?, 0/dummy, false/quit
|
||||
return-if error?, null/dummy, false/quit
|
||||
to-file:num, quit?, error? <- read-file stdin, screen
|
||||
return-if quit?, 0/dummy
|
||||
return-if error?, 0/dummy
|
||||
return-if quit?, null/dummy
|
||||
return-if error?, null/dummy
|
||||
*result <- put *result, to-file:offset, to-file
|
||||
to-rank:num, quit?, error? <- read-rank stdin, screen
|
||||
return-if quit?, 0/dummy
|
||||
return-if error?, 0/dummy
|
||||
return-if quit?, null/dummy
|
||||
return-if error?, null/dummy
|
||||
*result <- put *result, to-rank:offset, to-rank
|
||||
error? <- expect-from-channel stdin, 10/newline, screen
|
||||
return-if error?, 0/dummy, false/quit
|
||||
return-if error?, null/dummy, false/quit
|
||||
]
|
||||
|
||||
# valid values for file: 0-7
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
def main [
|
||||
local-scope
|
||||
l:&:list:num <- copy 0
|
||||
l:&:list:num <- copy null
|
||||
l <- push 3, l
|
||||
l <- push 2, l
|
||||
l <- push 1, l
|
||||
|
@ -30,8 +30,8 @@ def create-yielder l:&:list:num -> n:num, done?:bool [
|
|||
local-scope
|
||||
load-inputs
|
||||
return-continuation-until-mark 100/mark
|
||||
done? <- equal l, 0/nil
|
||||
return-if done?, false
|
||||
done? <- equal l, null
|
||||
return-if done?, 0/dummy
|
||||
n <- first l
|
||||
l <- rest l
|
||||
]
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
def main [
|
||||
local-scope
|
||||
l:&:list:num <- copy 0
|
||||
l:&:list:num <- copy null
|
||||
l <- push 3, l
|
||||
l <- push 2, l
|
||||
l <- push 1, l
|
||||
|
@ -32,7 +32,7 @@ def create-yielder l:&:list:num -> n:num, done?:bool [
|
|||
local-scope
|
||||
load-inputs
|
||||
{
|
||||
done? <- equal l, 0
|
||||
done? <- equal l, null
|
||||
break-if done?
|
||||
n <- first l
|
||||
l <- rest l
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
def main [
|
||||
local-scope
|
||||
l:&:list:num <- copy 0
|
||||
l:&:list:num <- copy null
|
||||
l <- push 3, l
|
||||
l <- push 2, l
|
||||
l <- push 1, l
|
||||
|
@ -36,7 +36,7 @@ def create-yielder l:&:list:num -> n:num, done?:bool [
|
|||
load-inputs
|
||||
a:num <- copy 0
|
||||
{
|
||||
done? <- equal l, 0
|
||||
done? <- equal l, null
|
||||
break-if done?
|
||||
n <- first l
|
||||
l <- rest l
|
||||
|
|
|
@ -6,10 +6,10 @@ def main text:text [
|
|||
local-scope
|
||||
load-inputs
|
||||
open-console
|
||||
clear-screen 0/screen # non-scrolling app
|
||||
clear-screen null/screen # non-scrolling app
|
||||
e:&:editor <- new-editor text, 0/left, 5/right
|
||||
render 0/screen, e
|
||||
wait-for-event 0/console
|
||||
render null/screen, e
|
||||
wait-for-event null/console
|
||||
close-console
|
||||
]
|
||||
|
||||
|
@ -61,7 +61,7 @@ def new-editor s:text, left:num, right:num -> result:&:editor [
|
|||
*result <- put *result, cursor-row:offset, 1/top
|
||||
*result <- put *result, cursor-column:offset, left
|
||||
# initialize empty contents
|
||||
init:&:duplex-list:char <- push 167/§, 0/tail
|
||||
init:&:duplex-list:char <- push 167/§, null
|
||||
*result <- put *result, data:offset, init
|
||||
*result <- put *result, top-of-screen:offset, init
|
||||
*result <- put *result, before-cursor:offset, init
|
||||
|
@ -80,7 +80,7 @@ scenario editor-initializes-without-data [
|
|||
local-scope
|
||||
assume-screen 5/width, 3/height
|
||||
run [
|
||||
e:&:editor <- new-editor 0/data, 2/left, 5/right
|
||||
e:&:editor <- new-editor null/data, 2/left, 5/right
|
||||
2:editor/raw <- copy *e
|
||||
]
|
||||
memory-should-contain [
|
||||
|
|
|
@ -6,10 +6,10 @@ def! main text:text [
|
|||
local-scope
|
||||
load-inputs
|
||||
open-console
|
||||
clear-screen 0/screen # non-scrolling app
|
||||
clear-screen null/screen # non-scrolling app
|
||||
editor:&:editor <- new-editor text, 5/left, 45/right
|
||||
editor-render 0/screen, editor
|
||||
editor-event-loop 0/screen, 0/console, editor
|
||||
editor-render null/screen, editor
|
||||
editor-event-loop null/screen, null/console, editor
|
||||
close-console
|
||||
]
|
||||
|
||||
|
@ -223,7 +223,7 @@ def insert-at-cursor editor:&:editor, c:char, screen:&:screen -> go-render?:bool
|
|||
next:&:duplex-list:char <- next before-cursor
|
||||
{
|
||||
# at end of all text? no need to scroll? just print the character and leave
|
||||
at-end?:bool <- equal next, 0/null
|
||||
at-end?:bool <- equal next, null
|
||||
break-unless at-end?
|
||||
bottom:num <- subtract screen-height, 1
|
||||
at-bottom?:bool <- equal save-row, bottom
|
||||
|
@ -701,7 +701,7 @@ after <insert-character-special-case> [
|
|||
just-before-wrap?:bool <- greater-or-equal cursor-column, before-wrap-column
|
||||
next:&:duplex-list:char <- next before-cursor
|
||||
# at end of line? next == 0 || next.value == 10/newline
|
||||
at-end-of-line?:bool <- equal next, 0
|
||||
at-end-of-line?:bool <- equal next, null
|
||||
{
|
||||
break-if at-end-of-line?
|
||||
next-character:char <- get *next, value:offset
|
||||
|
|
|
@ -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, false/no-more-render, 0/nothing-deleted
|
||||
return-unless prev, false/no-more-render, null/nothing-deleted
|
||||
trace 10, [app], [delete-before-cursor]
|
||||
original-row:num <- get *editor, cursor-row:offset
|
||||
scroll?:bool <- move-cursor-coordinates-left editor
|
||||
|
@ -2616,7 +2616,7 @@ def delete-to-end-of-line editor:&:editor -> result:&:duplex-list:char, editor:&
|
|||
start:&:duplex-list:char <- get *editor, before-cursor:offset
|
||||
end:&:duplex-list:char <- next start
|
||||
{
|
||||
at-end-of-text?:bool <- equal end, 0/null
|
||||
at-end-of-text?:bool <- equal end, null
|
||||
break-if at-end-of-text?
|
||||
curr:char <- get *end, value:offset
|
||||
at-end-of-line?:bool <- equal curr, 10/newline
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
def! main [
|
||||
local-scope
|
||||
open-console
|
||||
clear-screen 0/screen # non-scrolling app
|
||||
env:&:environment <- new-programming-environment 0/filesystem, 0/screen
|
||||
render-all 0/screen, env, render
|
||||
event-loop 0/screen, 0/console, env, 0/filesystem
|
||||
clear-screen null/screen # non-scrolling app
|
||||
env:&:environment <- new-programming-environment null/filesystem, null/screen
|
||||
render-all null/screen, env, render
|
||||
event-loop null/screen, null/console, env, null/filesystem
|
||||
]
|
||||
|
||||
container environment [
|
||||
|
|
|
@ -10,11 +10,11 @@
|
|||
def! main [
|
||||
local-scope
|
||||
open-console
|
||||
clear-screen 0/screen # non-scrolling app
|
||||
env:&:environment <- new-programming-environment 0/filesystem, 0/screen
|
||||
env <- restore-sandboxes env, 0/filesystem
|
||||
render-all 0/screen, env, render
|
||||
event-loop 0/screen, 0/console, env, 0/filesystem
|
||||
clear-screen null/screen # non-scrolling app
|
||||
env:&:environment <- new-programming-environment null/filesystem, null/screen
|
||||
env <- restore-sandboxes env, null/filesystem
|
||||
render-all null/screen, env, render
|
||||
event-loop null/screen, null/console, env, null/filesystem
|
||||
]
|
||||
|
||||
container environment [
|
||||
|
@ -170,7 +170,7 @@ def run-sandboxes env:&:environment, resources:&:resources, screen:&:screen -> e
|
|||
# needs to be before running them, in case we die when running
|
||||
save-sandboxes env, resources
|
||||
# clear sandbox editor
|
||||
init:&:duplex-list:char <- push 167/§, 0/tail
|
||||
init:&:duplex-list:char <- push 167/§, null
|
||||
*current-sandbox <- put *current-sandbox, data:offset, init
|
||||
*current-sandbox <- put *current-sandbox, top-of-screen:offset, init
|
||||
}
|
||||
|
@ -475,8 +475,8 @@ def restore-sandboxes env:&:environment, resources:&:resources -> env:&:environm
|
|||
load-inputs
|
||||
# read all scenarios, pushing them to end of a list of scenarios
|
||||
idx:num <- copy 0
|
||||
curr:&:sandbox <- copy 0
|
||||
prev:&:sandbox <- copy 0
|
||||
curr:&:sandbox <- copy null
|
||||
prev:&:sandbox <- copy null
|
||||
{
|
||||
filename:text <- append [lesson/], idx
|
||||
contents:text <- slurp resources, filename
|
||||
|
@ -686,7 +686,7 @@ def editor-contents editor:&:editor -> result:text [
|
|||
# skip § sentinel
|
||||
assert curr, [editor without data is illegal; must have at least a sentinel]
|
||||
curr <- next curr
|
||||
return-unless curr, 0
|
||||
return-unless curr, null
|
||||
{
|
||||
break-unless curr
|
||||
c:char <- get *curr, value:offset
|
||||
|
@ -939,15 +939,15 @@ after <global-keypress> [
|
|||
]
|
||||
|
||||
# sandbox belonging to 'env' whose next-sandbox is 'in'
|
||||
# return 0 if there's no such sandbox, either because 'in' doesn't exist in 'env', or because it's the first sandbox
|
||||
# return null if there's no such sandbox, either because 'in' doesn't exist in 'env', or because it's the first sandbox
|
||||
def previous-sandbox env:&:environment, in:&:sandbox -> out:&:sandbox [
|
||||
local-scope
|
||||
load-inputs
|
||||
curr:&:sandbox <- get *env, sandbox:offset
|
||||
return-unless curr, 0/nil
|
||||
return-unless curr, null
|
||||
next:&:sandbox <- get *curr, next-sandbox:offset
|
||||
{
|
||||
return-unless next, 0/nil
|
||||
return-unless next, null
|
||||
found?:bool <- equal next, in
|
||||
break-if found?
|
||||
curr <- copy next
|
||||
|
|
|
@ -184,7 +184,7 @@ def find-sandbox env:&:environment, click-row:num -> result:&:sandbox [
|
|||
curr-sandbox <- get *curr-sandbox, next-sandbox:offset
|
||||
loop
|
||||
}
|
||||
return 0/not-found
|
||||
return null/not-found
|
||||
]
|
||||
|
||||
def click-on-sandbox-area? click-row:num, click-column:num, env:&:environment -> result:bool [
|
||||
|
|
|
@ -171,9 +171,9 @@ def find-click-in-sandbox-output env:&:environment, click-row:num -> sandbox:&:s
|
|||
}
|
||||
# return sandbox if click is in its output region
|
||||
response-starting-row:num <- get *sandbox, response-starting-row-on-screen:offset
|
||||
return-unless response-starting-row, 0/no-click-in-sandbox-output, 0/sandbox-index
|
||||
return-unless response-starting-row, null/no-click-in-sandbox-output, 0/sandbox-index
|
||||
click-in-response?:bool <- greater-or-equal click-row, response-starting-row
|
||||
return-unless click-in-response?, 0/no-click-in-sandbox-output, 0/sandbox-index
|
||||
return-unless click-in-response?, null/no-click-in-sandbox-output, 0/sandbox-index
|
||||
return sandbox, sandbox-index
|
||||
]
|
||||
|
||||
|
@ -184,7 +184,7 @@ def toggle-expected-response sandbox:&:sandbox -> sandbox:&:sandbox [
|
|||
{
|
||||
# if expected-response is set, reset
|
||||
break-unless expected-response
|
||||
*sandbox <- put *sandbox, expected-response:offset, 0
|
||||
*sandbox <- put *sandbox, expected-response:offset, null
|
||||
}
|
||||
{
|
||||
# if not, set expected response to the current response
|
||||
|
|
|
@ -235,7 +235,7 @@ def find-click-in-sandbox-code env:&:environment, click-row:num -> sandbox:&:san
|
|||
click-on-sandbox-code?:bool <- and click-above-response?, click-below-menu?
|
||||
{
|
||||
break-if click-on-sandbox-code?
|
||||
return 0/no-click-in-sandbox-output
|
||||
return null/no-click-in-sandbox-output
|
||||
}
|
||||
return sandbox
|
||||
]
|
||||
|
|
|
@ -310,7 +310,7 @@ scenario run-updates-errors-for-shape-shifting-recipes [
|
|||
|recipe foo x:_elem -> z:_elem [|
|
||||
| local-scope|
|
||||
| load-ingredients|
|
||||
| y:&:num <- copy 0|
|
||||
| y:&:num <- copy null|
|
||||
| z <- add x, y|
|
||||
|]|
|
||||
]
|
||||
|
@ -326,7 +326,7 @@ scenario run-updates-errors-for-shape-shifting-recipes [
|
|||
.recipe foo x:_elem -> z:_elem [ ┊ .
|
||||
. local-scope ┊─────────────────────────────────────────────────.
|
||||
. load-ingredients ┊0 edit copy to recipe delete .
|
||||
. y:&:num <- copy 0 ┊foo 2 .
|
||||
. y:&:num <- copy null ┊foo 2 .
|
||||
. z <- add x, y ┊foo_2: 'add' requires number ingredients, but go↩.
|
||||
.] ┊t 'y' .
|
||||
. ┊─────────────────────────────────────────────────.
|
||||
|
@ -346,7 +346,7 @@ scenario run-updates-errors-for-shape-shifting-recipes [
|
|||
.recipe foo x:_elem -> z:_elem [ ┊ .
|
||||
. local-scope ┊─────────────────────────────────────────────────.
|
||||
. load-ingredients ┊0 edit copy to recipe delete .
|
||||
. y:&:num <- copy 0 ┊foo 2 .
|
||||
. y:&:num <- copy null ┊foo 2 .
|
||||
. z <- add x, y ┊foo_3: 'add' requires number ingredients, but go↩.
|
||||
.] ┊t 'y' .
|
||||
. ┊─────────────────────────────────────────────────.
|
||||
|
@ -367,7 +367,7 @@ scenario run-avoids-spurious-errors-on-reloading-shape-shifting-recipes [
|
|||
]
|
||||
]
|
||||
# call code that uses other variants of it, but not it itself
|
||||
test-sandbox:text <- new [x:&:list:num <- copy 0
|
||||
test-sandbox:text <- new [x:&:list:num <- copy null
|
||||
to-text x]
|
||||
env:&:environment <- new-programming-environment resources, screen, test-sandbox
|
||||
render-all screen, env, render
|
||||
|
|
|
@ -206,7 +206,7 @@ def add-operation editor:&:editor, op:&:operation -> editor:&:editor [
|
|||
undo <- push op undo
|
||||
*editor <- put *editor, undo:offset, undo
|
||||
redo:&:list:&:operation <- get *editor, redo:offset
|
||||
redo <- copy 0
|
||||
redo <- copy null
|
||||
*editor <- put *editor, redo:offset, redo
|
||||
]
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
|
||||
def main [
|
||||
local-scope
|
||||
source-file:&:source:char <- start-reading 0/real-filesystem, [/tmp/mu-x]
|
||||
sink-file:&:sink:char, write-routine:num <- start-writing 0/real-filesystem, [/tmp/mu-y]
|
||||
source-file:&:source:char <- start-reading null/real-filesystem, [/tmp/mu-x]
|
||||
sink-file:&:sink:char, write-routine:num <- start-writing null/real-filesystem, [/tmp/mu-y]
|
||||
{
|
||||
c:char, done?:bool, source-file <- read source-file
|
||||
break-if done?
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
def main [
|
||||
local-scope
|
||||
$print [aaa] 10/newline
|
||||
google:&:source:char <- start-reading-from-network 0/real-resources, [google.com/]
|
||||
google:&:source:char <- start-reading-from-network null/real-resources, [google.com/]
|
||||
$print [bbb] 10/newline
|
||||
n:num <- copy 0
|
||||
buf:&:buffer:char <- new-buffer 30
|
||||
|
@ -21,9 +21,9 @@ def main [
|
|||
}
|
||||
result:text <- buffer-to-array buf
|
||||
open-console
|
||||
clear-screen 0/screen # non-scrolling app
|
||||
clear-screen null/screen # non-scrolling app
|
||||
len:num <- length *result
|
||||
print 0/real-screen, result
|
||||
print null/real-screen, result
|
||||
wait-for-some-interaction
|
||||
close-console
|
||||
]
|
||||
|
|
|
@ -22,7 +22,7 @@ result <- add a t1]
|
|||
def lambda-to-mu in:text -> out:text [
|
||||
local-scope
|
||||
load-inputs
|
||||
out <- copy 0
|
||||
out <- copy null
|
||||
cells:&:cell <- parse in
|
||||
out <- to-mu cells
|
||||
]
|
||||
|
@ -84,7 +84,7 @@ scenario pair-is-not-atom [
|
|||
# construct (a . nil)
|
||||
s:text <- new [a]
|
||||
x:&:cell <- new-atom s
|
||||
y:&:cell <- new-pair x, 0/nil
|
||||
y:&:cell <- new-pair x, null
|
||||
10:bool/raw <- is-atom? y
|
||||
11:bool/raw <- is-pair? y
|
||||
memory-should-contain [
|
||||
|
@ -114,7 +114,7 @@ def first x:&:cell -> result:&:cell [
|
|||
local-scope
|
||||
load-inputs
|
||||
pair:pair, pair?:bool <- maybe-convert *x, pair:variant
|
||||
return-unless pair?, 0/nil
|
||||
return-unless pair?, null
|
||||
result <- get pair, first:offset
|
||||
]
|
||||
|
||||
|
@ -122,7 +122,7 @@ def rest x:&:cell -> result:&:cell [
|
|||
local-scope
|
||||
load-inputs
|
||||
pair:pair, pair?:bool <- maybe-convert *x, pair:variant
|
||||
return-unless pair?, 0/nil
|
||||
return-unless pair?, null
|
||||
result <- get pair, rest:offset
|
||||
]
|
||||
|
||||
|
@ -161,7 +161,7 @@ scenario cell-operations-on-pair [
|
|||
# construct (a . nil)
|
||||
s:text <- new [a]
|
||||
x:&:cell <- new-atom s
|
||||
y:&:cell <- new-pair x, 0/nil
|
||||
y:&:cell <- new-pair x, null
|
||||
x2:&:cell <- first y
|
||||
10:bool/raw <- equal x, x2
|
||||
11:&:cell/raw <- rest y
|
||||
|
@ -187,7 +187,7 @@ def parse in:&:stream:char -> out:&:cell, in:&:stream:char [
|
|||
# skip whitespace
|
||||
in <- skip-whitespace in
|
||||
c:char, eof?:bool <- peek in
|
||||
return-if eof?, 0/nil
|
||||
return-if eof?, null
|
||||
pair?:bool <- equal c, 40/open-paren
|
||||
{
|
||||
break-if pair?
|
||||
|
@ -223,7 +223,7 @@ def parse in:&:stream:char -> out:&:cell, in:&:stream:char [
|
|||
close-paren?:bool <- equal c, 41/close-paren
|
||||
break-if close-paren?
|
||||
first:&:cell, in <- parse in
|
||||
*out <- merge 1/pair, first, 0/nil
|
||||
*out <- merge 1/pair, first, null
|
||||
}
|
||||
# read in any remaining elements
|
||||
curr:&:cell <- copy out
|
||||
|
@ -245,7 +245,7 @@ def parse in:&:stream:char -> out:&:cell, in:&:stream:char [
|
|||
is-dot?:bool <- atom-match? next, [.]
|
||||
{
|
||||
break-if is-dot?
|
||||
next-curr:&:cell <- new-pair next, 0/nil
|
||||
next-curr:&:cell <- new-pair next, null
|
||||
curr <- set-rest curr, next-curr
|
||||
curr <- rest curr
|
||||
}
|
||||
|
@ -276,7 +276,7 @@ def skip-whitespace in:&:stream:char -> in:&:stream:char [
|
|||
load-inputs
|
||||
{
|
||||
done?:bool <- end-of-stream? in
|
||||
return-if done?, 0/null
|
||||
return-if done?, null
|
||||
c:char <- peek in
|
||||
space?:bool <- space? c
|
||||
break-unless space?
|
||||
|
@ -586,5 +586,5 @@ def to-mu in:&:cell, buf:&:buffer:char -> buf:&:buffer:char, result-name:text [
|
|||
# null cell? no change.
|
||||
# pair with all atoms? gensym a new variable
|
||||
# pair containing other pairs? recurse
|
||||
result-name <- copy 0
|
||||
result-name <- copy null
|
||||
]
|
||||
|
|
1
mu.vim
1
mu.vim
|
@ -55,6 +55,7 @@ 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
|
||||
syntax match muLiteral % null\(\/[^ ]*\)\?%
|
||||
highlight link muLiteral Constant
|
||||
|
||||
" sources of action at a distance
|
||||
|
|
|
@ -6,10 +6,10 @@ def main text:text [
|
|||
local-scope
|
||||
load-inputs
|
||||
open-console
|
||||
clear-screen 0/screen # non-scrolling app
|
||||
clear-screen null/screen # non-scrolling app
|
||||
e:&:editor <- new-editor text, 0/left, 5/right
|
||||
render 0/screen, e
|
||||
wait-for-event 0/console
|
||||
render null/screen, e
|
||||
wait-for-event null/console
|
||||
close-console
|
||||
]
|
||||
|
||||
|
@ -61,7 +61,7 @@ def new-editor s:text, left:num, right:num -> result:&:editor [
|
|||
*result <- put *result, cursor-row:offset, 1/top
|
||||
*result <- put *result, cursor-column:offset, left
|
||||
# initialize empty contents
|
||||
init:&:duplex-list:char <- push 167/§, 0/tail
|
||||
init:&:duplex-list:char <- push 167/§, null
|
||||
*result <- put *result, data:offset, init
|
||||
*result <- put *result, top-of-screen:offset, init
|
||||
*result <- put *result, before-cursor:offset, init
|
||||
|
@ -80,7 +80,7 @@ scenario editor-initializes-without-data [
|
|||
local-scope
|
||||
assume-screen 5/width, 3/height
|
||||
run [
|
||||
e:&:editor <- new-editor 0/data, 2/left, 5/right
|
||||
e:&:editor <- new-editor null/data, 2/left, 5/right
|
||||
2:editor/raw <- copy *e
|
||||
]
|
||||
memory-should-contain [
|
||||
|
|
|
@ -6,10 +6,10 @@ def! main text:text [
|
|||
local-scope
|
||||
load-inputs
|
||||
open-console
|
||||
clear-screen 0/screen # non-scrolling app
|
||||
clear-screen null/screen # non-scrolling app
|
||||
editor:&:editor <- new-editor text, 5/left, 45/right
|
||||
editor-render 0/screen, editor
|
||||
editor-event-loop 0/screen, 0/console, editor
|
||||
editor-render null/screen, editor
|
||||
editor-event-loop null/screen, null/console, editor
|
||||
close-console
|
||||
]
|
||||
|
||||
|
@ -223,7 +223,7 @@ def insert-at-cursor editor:&:editor, c:char, screen:&:screen -> go-render?:bool
|
|||
next:&:duplex-list:char <- next before-cursor
|
||||
{
|
||||
# at end of all text? no need to scroll? just print the character and leave
|
||||
at-end?:bool <- equal next, 0/null
|
||||
at-end?:bool <- equal next, null
|
||||
break-unless at-end?
|
||||
bottom:num <- subtract screen-height, 1
|
||||
at-bottom?:bool <- equal save-row, bottom
|
||||
|
@ -701,7 +701,7 @@ after <insert-character-special-case> [
|
|||
just-before-wrap?:bool <- greater-or-equal cursor-column, before-wrap-column
|
||||
next:&:duplex-list:char <- next before-cursor
|
||||
# at end of line? next == 0 || next.value == 10/newline
|
||||
at-end-of-line?:bool <- equal next, 0
|
||||
at-end-of-line?:bool <- equal next, null
|
||||
{
|
||||
break-if at-end-of-line?
|
||||
next-character:char <- get *next, value:offset
|
||||
|
|
|
@ -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, false/no-more-render, 0/nothing-deleted
|
||||
return-unless prev, false/no-more-render, null/nothing-deleted
|
||||
trace 10, [app], [delete-before-cursor]
|
||||
original-row:num <- get *editor, cursor-row:offset
|
||||
move-cursor-coordinates-left editor
|
||||
|
@ -2353,7 +2353,7 @@ def delete-to-end-of-line editor:&:editor -> result:&:duplex-list:char, editor:&
|
|||
start:&:duplex-list:char <- get *editor, before-cursor:offset
|
||||
end:&:duplex-list:char <- next start
|
||||
{
|
||||
at-end-of-text?:bool <- equal end, 0/null
|
||||
at-end-of-text?:bool <- equal end, null
|
||||
break-if at-end-of-text?
|
||||
curr:char <- get *end, value:offset
|
||||
at-end-of-line?:bool <- equal curr, 10/newline
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
def! main [
|
||||
local-scope
|
||||
open-console
|
||||
clear-screen 0/screen # non-scrolling app
|
||||
env:&:environment <- new-programming-environment 0/filesystem, 0/screen
|
||||
render-all 0/screen, env, render
|
||||
event-loop 0/screen, 0/console, env, 0/filesystem
|
||||
clear-screen null/screen # non-scrolling app
|
||||
env:&:environment <- new-programming-environment null/filesystem, null/screen
|
||||
render-all null/screen, env, render
|
||||
event-loop null/screen, null/console, env, null/filesystem
|
||||
]
|
||||
|
||||
container environment [
|
||||
|
|
|
@ -10,11 +10,11 @@
|
|||
def! main [
|
||||
local-scope
|
||||
open-console
|
||||
clear-screen 0/screen # non-scrolling app
|
||||
env:&:environment <- new-programming-environment 0/filesystem, 0/screen
|
||||
env <- restore-sandboxes env, 0/filesystem
|
||||
render-all 0/screen, env, render
|
||||
event-loop 0/screen, 0/console, env, 0/filesystem
|
||||
clear-screen null/screen # non-scrolling app
|
||||
env:&:environment <- new-programming-environment null/filesystem, null/screen
|
||||
env <- restore-sandboxes env, null/filesystem
|
||||
render-all null/screen, env, render
|
||||
event-loop null/screen, null/console, env, null/filesystem
|
||||
]
|
||||
|
||||
container environment [
|
||||
|
@ -160,7 +160,7 @@ def run-sandboxes env:&:environment, resources:&:resources, screen:&:screen -> e
|
|||
# needs to be before running them, in case we die when running
|
||||
save-sandboxes env, resources
|
||||
# clear sandbox editor
|
||||
init:&:duplex-list:char <- push 167/§, 0/tail
|
||||
init:&:duplex-list:char <- push 167/§, null
|
||||
*current-sandbox <- put *current-sandbox, data:offset, init
|
||||
*current-sandbox <- put *current-sandbox, top-of-screen:offset, init
|
||||
}
|
||||
|
@ -458,8 +458,8 @@ def restore-sandboxes env:&:environment, resources:&:resources -> env:&:environm
|
|||
load-inputs
|
||||
# read all scenarios, pushing them to end of a list of scenarios
|
||||
idx:num <- copy 0
|
||||
curr:&:sandbox <- copy 0
|
||||
prev:&:sandbox <- copy 0
|
||||
curr:&:sandbox <- copy null
|
||||
prev:&:sandbox <- copy null
|
||||
{
|
||||
filename:text <- append [lesson/], idx
|
||||
contents:text <- slurp resources, filename
|
||||
|
@ -668,7 +668,7 @@ def editor-contents editor:&:editor -> result:text [
|
|||
# skip § sentinel
|
||||
assert curr, [editor without data is illegal; must have at least a sentinel]
|
||||
curr <- next curr
|
||||
return-unless curr, 0
|
||||
return-unless curr, null
|
||||
{
|
||||
break-unless curr
|
||||
c:char <- get *curr, value:offset
|
||||
|
@ -817,15 +817,15 @@ after <global-keypress> [
|
|||
]
|
||||
|
||||
# sandbox belonging to 'env' whose next-sandbox is 'in'
|
||||
# return 0 if there's no such sandbox, either because 'in' doesn't exist in 'env', or because it's the first sandbox
|
||||
# return null if there's no such sandbox, either because 'in' doesn't exist in 'env', or because it's the first sandbox
|
||||
def previous-sandbox env:&:environment, in:&:sandbox -> out:&:sandbox [
|
||||
local-scope
|
||||
load-inputs
|
||||
curr:&:sandbox <- get *env, sandbox:offset
|
||||
return-unless curr, 0/nil
|
||||
return-unless curr, null
|
||||
next:&:sandbox <- get *curr, next-sandbox:offset
|
||||
{
|
||||
return-unless next, 0/nil
|
||||
return-unless next, null
|
||||
found?:bool <- equal next, in
|
||||
break-if found?
|
||||
curr <- copy next
|
||||
|
|
|
@ -194,7 +194,7 @@ def find-sandbox env:&:environment, click-row:num -> result:&:sandbox [
|
|||
curr-sandbox <- get *curr-sandbox, next-sandbox:offset
|
||||
loop
|
||||
}
|
||||
return 0/not-found
|
||||
return null/not-found
|
||||
]
|
||||
|
||||
def click-on-sandbox-area? click-row:num, env:&:environment -> result:bool [
|
||||
|
|
|
@ -173,9 +173,9 @@ def find-click-in-sandbox-output env:&:environment, click-row:num -> sandbox:&:s
|
|||
}
|
||||
# return sandbox if click is in its output region
|
||||
response-starting-row:num <- get *sandbox, response-starting-row-on-screen:offset
|
||||
return-unless response-starting-row, 0/no-click-in-sandbox-output, 0/sandbox-index
|
||||
return-unless response-starting-row, null/no-click-in-sandbox-output, 0/sandbox-index
|
||||
click-in-response?:bool <- greater-or-equal click-row, response-starting-row
|
||||
return-unless click-in-response?, 0/no-click-in-sandbox-output, 0/sandbox-index
|
||||
return-unless click-in-response?, null/no-click-in-sandbox-output, 0/sandbox-index
|
||||
return sandbox, sandbox-index
|
||||
]
|
||||
|
||||
|
@ -186,7 +186,7 @@ def toggle-expected-response sandbox:&:sandbox -> sandbox:&:sandbox [
|
|||
{
|
||||
# if expected-response is set, reset
|
||||
break-unless expected-response
|
||||
*sandbox <- put *sandbox, expected-response:offset, 0
|
||||
*sandbox <- put *sandbox, expected-response:offset, null
|
||||
}
|
||||
{
|
||||
# if not, set expected response to the current response
|
||||
|
|
|
@ -225,7 +225,7 @@ def find-click-in-sandbox-code env:&:environment, click-row:num -> sandbox:&:san
|
|||
click-on-sandbox-code?:bool <- and click-above-response?, click-below-menu?
|
||||
{
|
||||
break-if click-on-sandbox-code?
|
||||
return 0/no-click-in-sandbox-output
|
||||
return null/no-click-in-sandbox-output
|
||||
}
|
||||
return sandbox
|
||||
]
|
||||
|
|
|
@ -253,7 +253,7 @@ scenario run-updates-errors-for-shape-shifting-recipes [
|
|||
|recipe foo x:_elem -> z:_elem [|
|
||||
| local-scope|
|
||||
| load-ingredients|
|
||||
| y:&:num <- copy 0|
|
||||
| y:&:num <- copy null|
|
||||
| z <- add x, y|
|
||||
|]|
|
||||
]
|
||||
|
@ -308,7 +308,7 @@ scenario run-avoids-spurious-errors-on-reloading-shape-shifting-recipes [
|
|||
]
|
||||
]
|
||||
# call code that uses other variants of it, but not it itself
|
||||
test-sandbox:text <- new [x:&:list:num <- copy 0
|
||||
test-sandbox:text <- new [x:&:list:num <- copy null
|
||||
to-text x]
|
||||
env:&:environment <- new-programming-environment resources, screen, test-sandbox
|
||||
render-all screen, env, render
|
||||
|
|
|
@ -204,7 +204,7 @@ def add-operation editor:&:editor, op:&:operation -> editor:&:editor [
|
|||
undo <- push op undo
|
||||
*editor <- put *editor, undo:offset, undo
|
||||
redo:&:list:&:operation <- get *editor, redo:offset
|
||||
redo <- copy 0
|
||||
redo <- copy null
|
||||
*editor <- put *editor, redo:offset, redo
|
||||
]
|
||||
|
||||
|
|
38
screen.mu
38
screen.mu
|
@ -4,26 +4,26 @@
|
|||
# screens.
|
||||
def main [
|
||||
open-console
|
||||
clear-screen 0/screen # non-scrolling app
|
||||
clear-screen null/screen # non-scrolling app
|
||||
10:char <- copy 97/a
|
||||
print 0/screen, 10:char/a, 1/red, 2/green
|
||||
1:num/raw, 2:num/raw <- cursor-position 0/screen
|
||||
wait-for-event 0/console
|
||||
clear-screen 0/screen
|
||||
move-cursor 0/screen, 0/row, 4/column
|
||||
print null/screen, 10:char/a, 1/red, 2/green
|
||||
1:num/raw, 2:num/raw <- cursor-position null/screen
|
||||
wait-for-event null/console
|
||||
clear-screen null/screen
|
||||
move-cursor null/screen, 0/row, 4/column
|
||||
10:char <- copy 98/b
|
||||
print 0/screen, 10:char
|
||||
wait-for-event 0/console
|
||||
move-cursor 0/screen, 0/row, 0/column
|
||||
clear-line 0/screen
|
||||
wait-for-event 0/console
|
||||
cursor-down 0/screen
|
||||
wait-for-event 0/console
|
||||
cursor-right 0/screen
|
||||
wait-for-event 0/console
|
||||
cursor-left 0/screen
|
||||
wait-for-event 0/console
|
||||
cursor-up 0/screen
|
||||
wait-for-event 0/console
|
||||
print null/screen, 10:char
|
||||
wait-for-event null/console
|
||||
move-cursor null/screen, 0/row, 0/column
|
||||
clear-line null/screen
|
||||
wait-for-event null/console
|
||||
cursor-down null/screen
|
||||
wait-for-event null/console
|
||||
cursor-right null/screen
|
||||
wait-for-event null/console
|
||||
cursor-left null/screen
|
||||
wait-for-event null/console
|
||||
cursor-up null/screen
|
||||
wait-for-event null/console
|
||||
close-console
|
||||
]
|
||||
|
|
|
@ -31,7 +31,8 @@ function! HighlightTangledFile()
|
|||
syntax match muLiteral %[^ ]\+:type/[^ ,]*\|[^ ]\+:type\>%
|
||||
syntax match muLiteral %[^ ]\+:offset/[^ ,]*\|[^ ]\+:offset\>%
|
||||
syntax match muLiteral %[^ ]\+:variant/[^ ,]*\|[^ ]\+:variant\>%
|
||||
syntax keyword muLiteral true false null
|
||||
syntax match muLiteral % true\(\/[^ ]*\)\?\| false\(\/[^ ]*\)\?% " literals will never be the first word in an instruction
|
||||
syntax match muLiteral % null\(\/[^ ]*\)\?%
|
||||
highlight link muLiteral Constant
|
||||
syntax match muAssign " <- \|\<raw\>" | highlight link muAssign SpecialChar
|
||||
" common keywords
|
||||
|
|
Loading…
Reference in New Issue