diff options
48 files changed, 268 insertions, 246 deletions
diff --git a/018type_abbreviations.cc b/018type_abbreviations.cc index 65905702..dad8bb9b 100644 --- a/018type_abbreviations.cc +++ b/018type_abbreviations.cc @@ -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. diff --git a/021check_instruction.cc b/021check_instruction.cc index 48f90078..ee44161a 100644 --- a/021check_instruction.cc +++ b/021check_instruction.cc @@ -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) diff --git a/022constant.cc b/022constant.cc index 800e1b2b..6fc9a019 100644 --- a/022constant.cc +++ b/022constant.cc @@ -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") diff --git a/036lookup.cc b/036lookup.cc index a2647f5d..c95f1c8d 100644 --- a/036lookup.cc +++ b/036lookup.cc @@ -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) { diff --git a/042name.cc b/042name.cc index f183962c..3cfc8587 100644 --- a/042name.cc +++ b/042name.cc @@ -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 ] diff --git a/046check_type_by_name.cc b/046check_type_by_name.cc index 786714b4..c68a9bae 100644 --- a/046check_type_by_name.cc +++ b/046check_type_by_name.cc @@ -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 diff --git a/054static_dispatch.cc b/054static_dispatch.cc index 5f0fb03c..17ffc755 100644 --- a/054static_dispatch.cc +++ b/054static_dispatch.cc @@ -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 [ diff --git a/056shape_shifting_recipe.cc b/056shape_shifting_recipe.cc index f1145803..0c97fcdd 100644 --- a/056shape_shifting_recipe.cc +++ b/056shape_shifting_recipe.cc @@ -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 [ diff --git a/057immutable.cc b/057immutable.cc index d3c633b2..658f301b 100644 --- a/057immutable.cc +++ b/057immutable.cc @@ -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 diff --git a/061text.mu b/061text.mu index 8ef19a9d..4d46319b 100644 --- a/061text.mu +++ b/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 diff --git a/064list.mu b/064list.mu index eca3ded1..d669ec2c 100644 --- a/064list.mu +++ b/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 ] diff --git a/065duplex_list.mu b/065duplex_list.mu index 129da96c..7d369186 100644 --- a/065duplex_list.mu +++ b/065duplex_list.mu @@ -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 ] diff --git a/066stream.mu b/066stream.mu index 86ce26ed..b3202f65 100644 --- a/066stream.mu +++ b/066stream.mu @@ -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 diff --git a/069hash.cc b/069hash.cc index 4400c1e8..8a698d38 100644 --- a/069hash.cc +++ b/069hash.cc @@ -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 diff --git a/072recipe.cc b/072recipe.cc index dd71830d..439b2000 100644 --- a/072recipe.cc +++ b/072recipe.cc @@ -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 [ diff --git a/081print.mu b/081print.mu index df58f831..98ea0f21 100644 --- a/081print.mu +++ b/081print.mu @@ -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 ] diff --git a/088file.mu b/088file.mu index d9c3391d..da3e35d3 100644 --- a/088file.mu +++ b/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 diff --git a/092socket.mu b/092socket.mu index be4e5bb2..b0dca4b7 100644 --- a/092socket.mu +++ b/092socket.mu @@ -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 [ diff --git a/chessboard.mu b/chessboard.mu index 74cda69a..09c85188 100644 --- a/chessboard.mu +++ b/chessboard.mu @@ -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 diff --git a/continuation2.mu b/continuation2.mu index b71e9a11..45a65e9f 100644 --- a/continuation2.mu +++ b/continuation2.mu @@ -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 ] diff --git a/continuation4.mu b/continuation4.mu index d4eb0641..1a523fe9 100644 --- a/continuation4.mu +++ b/continuation4.mu @@ -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 diff --git a/continuation5.mu b/continuation5.mu index 4ae05614..295cb9c9 100644 --- a/continuation5.mu +++ b/continuation5.mu @@ -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 diff --git a/edit/001-editor.mu b/edit/001-editor.mu index 8855395a..963bb1cf 100644 --- a/edit/001-editor.mu +++ b/edit/001-editor.mu @@ -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 [ diff --git a/edit/002-typing.mu b/edit/002-typing.mu index a67fcf3c..ef3f25d2 100644 --- a/edit/002-typing.mu +++ b/edit/002-typing.mu @@ -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 diff --git a/edit/003-shortcuts.mu b/edit/003-shortcuts.mu index b8f49731..872dfcea 100644 --- a/edit/003-shortcuts.mu +++ b/edit/003-shortcuts.mu @@ -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 diff --git a/edit/004-programming-environment.mu b/edit/004-programming-environment.mu index 1065dd64..dec8a2d5 100644 --- a/edit/004-programming-environment.mu +++ b/edit/004-programming-environment.mu @@ -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 [ diff --git a/edit/005-sandbox.mu b/edit/005-sandbox.mu index ae8561a9..96ec804d 100644 --- a/edit/005-sandbox.mu +++ b/edit/005-sandbox.mu @@ -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 diff --git a/edit/006-sandbox-copy.mu b/edit/006-sandbox-copy.mu index 04d22ab5..6af72f77 100644 --- a/edit/006-sandbox-copy.mu +++ b/edit/006-sandbox-copy.mu @@ -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 [ diff --git a/edit/009-sandbox-test.mu b/edit/009-sandbox-test.mu index b871107e..52c1e909 100644 --- a/edit/009-sandbox-test.mu +++ b/edit/009-sandbox-test.mu @@ -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 diff --git a/edit/010-sandbox-trace.mu b/edit/010-sandbox-trace.mu index cc8b2805..23b88833 100644 --- a/edit/010-sandbox-trace.mu +++ b/edit/010-sandbox-trace.mu @@ -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 ] diff --git a/edit/011-errors.mu b/edit/011-errors.mu index 373193d6..47258815 100644 --- a/edit/011-errors.mu +++ b/edit/011-errors.mu @@ -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 diff --git a/edit/012-editor-undo.mu b/edit/012-editor-undo.mu index 42d325bd..871f6c74 100644 --- a/edit/012-editor-undo.mu +++ b/edit/012-editor-undo.mu @@ -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 ] diff --git a/filesystem.mu b/filesystem.mu index acfd39b2..6ea8e08c 100644 --- a/filesystem.mu +++ b/filesystem.mu @@ -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? diff --git a/http-client.mu b/http-client.mu index 9219a76f..8f04c2bc 100644 --- a/http-client.mu +++ b/http-client.mu @@ -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 ] diff --git a/lambda-to-mu.mu b/lambda-to-mu.mu index 1d23cd46..a171b4ca 100644 --- a/lambda-to-mu.mu +++ b/lambda-to-mu.mu @@ -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 ] diff --git a/mu.vim b/mu.vim index 6dfe6318..35d46651 100644 --- a/mu.vim +++ b/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 diff --git a/sandbox/001-editor.mu b/sandbox/001-editor.mu index 8855395a..963bb1cf 100644 --- a/sandbox/001-editor.mu +++ b/sandbox/001-editor.mu @@ -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 [ diff --git a/sandbox/002-typing.mu b/sandbox/002-typing.mu index a67fcf3c..ef3f25d2 100644 --- a/sandbox/002-typing.mu +++ b/sandbox/002-typing.mu @@ -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 diff --git a/sandbox/003-shortcuts.mu b/sandbox/003-shortcuts.mu index db19443d..c9e66d5b 100644 --- a/sandbox/003-shortcuts.mu +++ b/sandbox/003-shortcuts.mu @@ -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 diff --git a/sandbox/004-programming-environment.mu b/sandbox/004-programming-environment.mu index 1208d0e8..1454144b 100644 --- a/sandbox/004-programming-environment.mu +++ b/sandbox/004-programming-environment.mu @@ -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 [ diff --git a/sandbox/005-sandbox.mu b/sandbox/005-sandbox.mu index ae4372a1..632a5df1 100644 --- a/sandbox/005-sandbox.mu +++ b/sandbox/005-sandbox.mu @@ -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 diff --git a/sandbox/006-sandbox-copy.mu b/sandbox/006-sandbox-copy.mu index 4b7222f3..0eae6cf7 100644 --- a/sandbox/006-sandbox-copy.mu +++ b/sandbox/006-sandbox-copy.mu @@ -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 [ diff --git a/sandbox/009-sandbox-test.mu b/sandbox/009-sandbox-test.mu index 3fd4dafc..c22916a7 100644 --- a/sandbox/009-sandbox-test.mu +++ b/sandbox/009-sandbox-test.mu @@ -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 diff --git a/sandbox/010-sandbox-trace.mu b/sandbox/010-sandbox-trace.mu index 6d775322..d544dd8c 100644 --- a/sandbox/010-sandbox-trace.mu +++ b/sandbox/010-sandbox-trace.mu @@ -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 ] diff --git a/sandbox/011-errors.mu b/sandbox/011-errors.mu index 8678989f..2f59d1fe 100644 --- a/sandbox/011-errors.mu +++ b/sandbox/011-errors.mu @@ -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 diff --git a/sandbox/012-editor-undo.mu b/sandbox/012-editor-undo.mu index 23448ea2..69afd207 100644 --- a/sandbox/012-editor-undo.mu +++ b/sandbox/012-editor-undo.mu @@ -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 ] diff --git a/screen.mu b/screen.mu index 1c7a31a1..58ecaa60 100644 --- a/screen.mu +++ b/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 ] diff --git a/vimrc.vim b/vimrc.vim index 218da388..9618a44b 100644 --- a/vimrc.vim +++ b/vimrc.vim @@ -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 |