From 502d2ea540bbb66f2bb5e649c7c7743973859092 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Wed, 29 Jul 2015 14:37:57 -0700 Subject: 1883 - type-deducing in more .mu files --- 060string.mu | 735 +++++++++++++++++++++++++++--------------------------- 061channel.mu | 187 +++++++------- 062array.mu | 22 +- 063list.mu | 18 +- 065duplex_list.mu | 94 +++---- 066stream.mu | 38 +-- 071print.mu | 454 +++++++++++++++++---------------- 074console.mu | 75 +++--- edit.mu | 2 +- 9 files changed, 792 insertions(+), 833 deletions(-) diff --git a/060string.mu b/060string.mu index ddd50f04..a212b75b 100644 --- a/060string.mu +++ b/060string.mu @@ -3,30 +3,30 @@ recipe string-equal [ local-scope a:address:array:character <- next-ingredient - a-len:number <- length a:address:array:character/lookup + a-len:number <- length *a b:address:array:character <- next-ingredient - b-len:number <- length b:address:array:character/lookup + b-len:number <- length *b # compare lengths { trace [string-equal], [comparing lengths] - length-equal?:boolean <- equal a-len:number, b-len:number - break-if length-equal?:boolean + length-equal?:boolean <- equal a-len, b-len + break-if length-equal? reply 0 } # compare each corresponding character trace [string-equal], [comparing characters] i:number <- copy 0 { - done?:boolean <- greater-or-equal i:number, a-len:number - break-if done?:boolean - a2:character <- index a:address:array:character/lookup, i:number - b2:character <- index b:address:array:character/lookup, i:number + done?:boolean <- greater-or-equal i, a-len + break-if done? + a2:character <- index *a, i + b2:character <- index *b, i { - chars-match?:boolean <- equal a2:character, b2:character - break-if chars-match?:boolean + chars-match?:boolean <- equal a2, b2 + break-if chars-match? reply 0 } - i:number <- add i:number, 1 + i <- add i, 1 loop } reply 1 @@ -36,7 +36,7 @@ scenario string-equal-reflexive [ run [ default-space:address:array:location <- new location:type, 30 x:address:array:character <- new [abc] - 3:boolean/raw <- string-equal x:address:array:character, x:address:array:character + 3:boolean/raw <- string-equal x, x ] memory-should-contain [ 3 <- 1 # x == x for all x @@ -48,7 +48,7 @@ scenario string-equal-identical [ default-space:address:array:location <- new location:type, 30 x:address:array:character <- new [abc] y:address:array:character <- new [abc] - 3:boolean/raw <- string-equal x:address:array:character, y:address:array:character + 3:boolean/raw <- string-equal x, y ] memory-should-contain [ 3 <- 1 # abc == abc @@ -60,7 +60,7 @@ scenario string-equal-distinct-lengths [ default-space:address:array:location <- new location:type, 30 x:address:array:character <- new [abc] y:address:array:character <- new [abcd] - 3:boolean/raw <- string-equal x:address:array:character, y:address:array:character + 3:boolean/raw <- string-equal x, y ] memory-should-contain [ 3 <- 0 # abc != abcd @@ -78,7 +78,7 @@ scenario string-equal-with-empty [ default-space:address:array:location <- new location:type, 30 x:address:array:character <- new [] y:address:array:character <- new [abcd] - 3:boolean/raw <- string-equal x:address:array:character, y:address:array:character + 3:boolean/raw <- string-equal x, y ] memory-should-contain [ 3 <- 0 # "" != abcd @@ -90,7 +90,7 @@ scenario string-equal-common-lengths-but-distinct [ default-space:address:array:location <- new location:type, 30 x:address:array:character <- new [abc] y:address:array:character <- new [abd] - 3:boolean/raw <- string-equal x:address:array:character, y:address:array:character + 3:boolean/raw <- string-equal x, y ] memory-should-contain [ 3 <- 0 # abc != abd @@ -107,47 +107,47 @@ recipe new-buffer [ local-scope #? $print default-space:address:array:location, 10/newline result:address:buffer <- new buffer:type - len:address:number <- get-address result:address:buffer/lookup, length:offset - len:address:number/lookup <- copy 0 - s:address:address:array:character <- get-address result:address:buffer/lookup, data:offset + len:address:number <- get-address *result, length:offset + *len:address:number <- copy 0 + s:address:address:array:character <- get-address *result, data:offset capacity:number, found?:boolean <- next-ingredient - assert found?:boolean, [new-buffer must get a capacity argument] - s:address:address:array:character/lookup <- new character:type, capacity:number -#? $print s:address:address:array:character/lookup, 10/newline - reply result:address:buffer + assert found?, [new-buffer must get a capacity argument] + *s <- new character:type, capacity +#? $print *s, 10/newline + reply result ] recipe grow-buffer [ local-scope in:address:buffer <- next-ingredient # double buffer size - x:address:address:array:character <- get-address in:address:buffer/lookup, data:offset - oldlen:number <- length x:address:address:array:character/lookup/lookup - newlen:number <- multiply oldlen:number, 2 - olddata:address:array:character <- copy x:address:address:array:character/lookup - x:address:address:array:character/lookup <- new character:type, newlen:number + x:address:address:array:character <- get-address *in, data:offset + oldlen:number <- length **x + newlen:number <- multiply oldlen, 2 + olddata:address:array:character <- copy *x + *x <- new character:type, newlen # copy old contents i:number <- copy 0 { - done?:boolean <- greater-or-equal i:number, oldlen:number - break-if done?:boolean - src:character <- index olddata:address:array:character/lookup, i:number - dest:address:character <- index-address x:address:address:array:character/lookup/lookup, i:number - dest:address:character/lookup <- copy src:character - i:number <- add i:number, 1 + done?:boolean <- greater-or-equal i, oldlen + break-if done? + src:character <- index *olddata, i + dest:address:character <- index-address **x, i + *dest <- copy src + i <- add i, 1 loop } - reply in:address:buffer + reply in ] recipe buffer-full? [ local-scope in:address:buffer <- next-ingredient - len:number <- get in:address:buffer/lookup, length:offset - s:address:array:character <- get in:address:buffer/lookup, data:offset - capacity:number <- length s:address:array:character/lookup - result:boolean <- greater-or-equal len:number, capacity:number - reply result:boolean + len:number <- get *in, length:offset + s:address:array:character <- get *in, data:offset + capacity:number <- length *s + result:boolean <- greater-or-equal len, capacity + reply result ] # in:address:buffer <- buffer-append in:address:buffer, c:character @@ -155,49 +155,49 @@ recipe buffer-append [ local-scope in:address:buffer <- next-ingredient c:character <- next-ingredient - len:address:number <- get-address in:address:buffer/lookup, length:offset + len:address:number <- get-address *in, length:offset { # backspace? just drop last character if it exists and return - backspace?:boolean <- equal c:character, 8/backspace - break-unless backspace?:boolean - empty?:boolean <- lesser-or-equal len:address:number/lookup, 0 - reply-if empty?:boolean, in:address:buffer/same-as-ingredient:0 - len:address:number/lookup <- subtract len:address:number/lookup, 1 - reply in:address:buffer/same-as-ingredient:0 + backspace?:boolean <- equal c, 8/backspace + break-unless backspace? + empty?:boolean <- lesser-or-equal *len, 0 + reply-if empty?, in/same-as-ingredient:0 + *len <- subtract *len, 1 + reply in/same-as-ingredient:0 } { # grow buffer if necessary - full?:boolean <- buffer-full? in:address:buffer - break-unless full?:boolean - in:address:buffer <- grow-buffer in:address:buffer + full?:boolean <- buffer-full? in + break-unless full? + in <- grow-buffer in } - s:address:array:character <- get in:address:buffer/lookup, data:offset -#? $print [array underlying buf: ], s:address:array:character, 10/newline -#? $print [index: ], len:address:number/lookup, 10/newline - dest:address:character <- index-address s:address:array:character/lookup, len:address:number/lookup -#? $print [storing ], c:character, [ in ], dest:address:character, 10/newline - dest:address:character/lookup <- copy c:character - len:address:number/lookup <- add len:address:number/lookup, 1 - reply in:address:buffer/same-as-ingredient:0 + s:address:array:character <- get *in, data:offset +#? $print [array underlying buf: ], s, 10/newline +#? $print [index: ], *len, 10/newline + dest:address:character <- index-address *s, *len +#? $print [storing ], c, [ in ], dest, 10/newline + *dest <- copy c + *len <- add *len, 1 + reply in/same-as-ingredient:0 ] scenario buffer-append-works [ run [ local-scope x:address:buffer <- new-buffer 3 - s1:address:array:character <- get x:address:buffer/lookup, data:offset + s1:address:array:character <- get *x:address:buffer, data:offset x:address:buffer <- buffer-append x:address:buffer, 97 # 'a' x:address:buffer <- buffer-append x:address:buffer, 98 # 'b' x:address:buffer <- buffer-append x:address:buffer, 99 # 'c' - s2:address:array:character <- get x:address:buffer/lookup, data:offset + s2:address:array:character <- get *x:address:buffer, data:offset 1:boolean/raw <- equal s1:address:array:character, s2:address:array:character - 2:array:character/raw <- copy s2:address:array:character/lookup + 2:array:character/raw <- copy *s2:address:array:character +buffer-filled x:address:buffer <- buffer-append x:address:buffer, 100 # 'd' - s3:address:array:character <- get x:address:buffer/lookup, data:offset + s3:address:array:character <- get *x:address:buffer, data:offset 10:boolean/raw <- equal s1:address:array:character, s3:address:array:character - 11:number/raw <- get x:address:buffer/lookup, length:offset - 12:array:character/raw <- copy s3:address:array:character/lookup + 11:number/raw <- get *x:address:buffer, length:offset + 12:array:character/raw <- copy *s3:address:array:character ] memory-should-contain [ # before +buffer-filled @@ -227,7 +227,7 @@ scenario buffer-append-handles-backspace [ x:address:buffer <- buffer-append x:address:buffer, 98 # 'b' x:address:buffer <- buffer-append x:address:buffer, 8/backspace s:address:array:character <- buffer-to-array x:address:buffer - 1:array:character/raw <- copy s:address:array:character/lookup + 1:array:character/raw <- copy *s:address:array:character ] memory-should-contain [ 1 <- 1 # length @@ -242,55 +242,53 @@ recipe integer-to-decimal-string [ n:number <- next-ingredient # is it zero? { - break-if n:number + break-if n result:address:array:character <- new [0] - reply result:address:array:character + reply result } # save sign negate-result:boolean <- copy 0 { - negative?:boolean <- lesser-than n:number, 0 - break-unless negative?:boolean - negate-result:boolean <- copy 1 - n:number <- multiply n:number, -1 + negative?:boolean <- lesser-than n, 0 + break-unless negative? + negate-result <- copy 1 + n <- multiply n, -1 } # add digits from right to left into intermediate buffer tmp:address:buffer <- new-buffer 30 digit-base:number <- copy 48 # '0' { - done?:boolean <- equal n:number, 0 - break-if done?:boolean - n:number, digit:number <- divide-with-remainder n:number, 10 - c:character <- add digit-base:number, digit:number - tmp:address:buffer <- buffer-append tmp:address:buffer, c:character + done?:boolean <- equal n, 0 + break-if done? + n, digit:number <- divide-with-remainder n, 10 + c:character <- add digit-base, digit + tmp:address:buffer <- buffer-append tmp, c loop } # add sign { break-unless negate-result:boolean - tmp:address:buffer <- buffer-append tmp:address:buffer, 45 # '-' + tmp <- buffer-append tmp, 45 # '-' } # reverse buffer into string result - len:number <- get tmp:address:buffer/lookup, length:offset - buf:address:array:character <- get tmp:address:buffer/lookup, data:offset - result:address:array:character <- new character:type, len:number - i:number <- subtract len:number, 1 - j:number <- copy 0 + len:number <- get *tmp, length:offset + buf:address:array:character <- get *tmp, data:offset + result:address:array:character <- new character:type, len + i:number <- subtract len, 1 # source index, decreasing + j:number <- copy 0 # destination index, increasing { # while i >= 0 - done?:boolean <- lesser-than i:number, 0 - break-if done?:boolean + done?:boolean <- lesser-than i, 0 + break-if done? # result[j] = tmp[i] - src:character <- index buf:address:array:character/lookup, i:number - dest:address:character <- index-address result:address:array:character/lookup, j:number - dest:address:character/lookup <- copy src:character - # ++i - i:number <- subtract i:number, 1 - # --j - j:number <- add j:number, 1 + src:character <- index *buf, i + dest:address:character <- index-address *result, j + *dest <- copy src + i <- subtract i, 1 + j <- add j, 1 loop } - reply result:address:array:character + reply result ] recipe buffer-to-array [ @@ -298,32 +296,32 @@ recipe buffer-to-array [ in:address:buffer <- next-ingredient { # propagate null buffer - break-if in:address:buffer + break-if in reply 0 } - len:number <- get in:address:buffer/lookup, length:offset -#? $print [size ], len:number, 10/newline - s:address:array:character <- get in:address:buffer/lookup, data:offset + len:number <- get *in, length:offset +#? $print [size ], len, 10/newline + s:address:array:character <- get *in, data:offset # we can't just return s because it is usually the wrong length - result:address:array:character <- new character:type, len:number + result:address:array:character <- new character:type, len i:number <- copy 0 { -#? $print i:number #? 1 - done?:boolean <- greater-or-equal i:number, len:number - break-if done?:boolean - src:character <- index s:address:array:character/lookup, i:number - dest:address:character <- index-address result:address:array:character/lookup, i:number - dest:address:character/lookup <- copy src:character - i:number <- add i:number, 1 +#? $print i #? 1 + done?:boolean <- greater-or-equal i, len + break-if done? + src:character <- index *s, i + dest:address:character <- index-address *result, i + *dest <- copy src + i <- add i, 1 loop } - reply result:address:array:character + reply result ] scenario integer-to-decimal-digit-zero [ run [ 1:address:array:character/raw <- integer-to-decimal-string 0 - 2:array:character/raw <- copy 1:address:array:character/lookup/raw + 2:array:character/raw <- copy *1:address:array:character/raw ] memory-should-contain [ 2:string <- [0] @@ -333,7 +331,7 @@ scenario integer-to-decimal-digit-zero [ scenario integer-to-decimal-digit-positive [ run [ 1:address:array:character/raw <- integer-to-decimal-string 234 - 2:array:character/raw <- copy 1:address:array:character/lookup/raw + 2:array:character/raw <- copy *1:address:array:character/raw ] memory-should-contain [ 2:string <- [234] @@ -343,7 +341,7 @@ scenario integer-to-decimal-digit-positive [ scenario integer-to-decimal-digit-negative [ run [ 1:address:array:character/raw <- integer-to-decimal-string -1 - 2:array:character/raw <- copy 1:address:array:character/lookup/raw + 2:array:character/raw <- copy *1:address:array:character/raw ] memory-should-contain [ 2 <- 2 @@ -357,45 +355,41 @@ recipe string-append [ local-scope # result = new character[a.length + b.length] a:address:array:character <- next-ingredient - a-len:number <- length a:address:array:character/lookup + a-len:number <- length *a b:address:array:character <- next-ingredient - b-len:number <- length b:address:array:character/lookup - result-len:number <- add a-len:number, b-len:number - result:address:array:character <- new character:type, result-len:number + b-len:number <- length *b + result-len:number <- add a-len, b-len + result:address:array:character <- new character:type, result-len # copy a into result result-idx:number <- copy 0 i:number <- copy 0 { # while i < a.length - a-done?:boolean <- greater-or-equal i:number, a-len:number - break-if a-done?:boolean + a-done?:boolean <- greater-or-equal i, a-len + break-if a-done? # result[result-idx] = a[i] - out:address:character <- index-address result:address:array:character/lookup, result-idx:number - in:character <- index a:address:array:character/lookup, i:number - out:address:character/lookup <- copy in:character - # ++i - i:number <- add i:number, 1 - # ++result-idx - result-idx:number <- add result-idx:number, 1 + out:address:character <- index-address *result, result-idx + in:character <- index *a, i + *out <- copy in + i <- add i, 1 + result-idx <- add result-idx, 1 loop } # copy b into result - i:number <- copy 0 + i <- copy 0 { # while i < b.length - b-done?:boolean <- greater-or-equal i:number, b-len:number - break-if b-done?:boolean + b-done?:boolean <- greater-or-equal i, b-len + break-if b-done? # result[result-idx] = a[i] - out:address:character <- index-address result:address:array:character/lookup, result-idx:number - in:character <- index b:address:array:character/lookup, i:number - out:address:character/lookup <- copy in:character - # ++i - i:number <- add i:number, 1 - # ++result-idx - result-idx:number <- add result-idx:number, 1 + out:address:character <- index-address *result, result-idx + in:character <- index *b, i + *out <- copy in + i <- add i, 1 + result-idx <- add result-idx, 1 loop } - reply result:address:array:character + reply result ] scenario string-append-1 [ @@ -403,7 +397,7 @@ scenario string-append-1 [ 1:address:array:character/raw <- new [hello,] 2:address:array:character/raw <- new [ world!] 3:address:array:character/raw <- string-append 1:address:array:character/raw, 2:address:array:character/raw - 4:array:character/raw <- copy 3:address:array:character/raw/lookup + 4:array:character/raw <- copy *3:address:array:character/raw ] memory-should-contain [ 4:string <- [hello, world!] @@ -416,85 +410,78 @@ recipe interpolate [ local-scope template:address:array:character <- next-ingredient # compute result-len, space to allocate for result - tem-len:number <- length template:address:array:character/lookup - result-len:number <- copy tem-len:number + tem-len:number <- length *template + result-len:number <- copy tem-len { # while arg received a:address:array:character, arg-received?:boolean <- next-ingredient - break-unless arg-received?:boolean - # result-len = result-len + arg.length - 1 for the 'underscore' being replaced - a-len:number <- length a:address:array:character/lookup - result-len:number <- add result-len:number, a-len:number - result-len:number <- subtract result-len:number, 1 + break-unless arg-received? + # result-len = result-len + arg.length - 1 (for the 'underscore' being replaced) + a-len:number <- length *a + result-len <- add result-len, a-len + result-len <- subtract result-len, 1 loop } -#? $print tem-len:number, [ ], $result-len:number, 10/newline +#? $print tem-len, [ ], $result-len, 10/newline rewind-ingredients _ <- next-ingredient # skip template - # result = new array:character[result-len] - result:address:array:character <- new character:type, result-len:number + result:address:array:character <- new character:type, result-len # repeatedly copy sections of template and 'holes' into result result-idx:number <- copy 0 i:number <- copy 0 { # while arg received a:address:array:character, arg-received?:boolean <- next-ingredient - break-unless arg-received?:boolean + break-unless arg-received? # copy template into result until '_' { # while i < template.length - tem-done?:boolean <- greater-or-equal i:number, tem-len:number - break-if tem-done?:boolean, +done:label + tem-done?:boolean <- greater-or-equal i, tem-len + break-if tem-done?, +done:label # while template[i] != '_' - in:character <- index template:address:array:character/lookup, i:number - underscore?:boolean <- equal in:character, 95 # '_' - break-if underscore?:boolean + in:character <- index *template, i + underscore?:boolean <- equal in, 95/_ + break-if underscore? # result[result-idx] = template[i] - out:address:character <- index-address result:address:array:character/lookup, result-idx:number - out:address:character/lookup <- copy in:character - # ++i - i:number <- add i:number, 1 - # ++result-idx - result-idx:number <- add result-idx:number, 1 + out:address:character <- index-address *result, result-idx + *out <- copy in + i <- add i, 1 + result-idx <- add result-idx, 1 loop } # copy 'a' into result j:number <- copy 0 { # while j < a.length - arg-done?:boolean <- greater-or-equal j:number, a-len:number - break-if arg-done?:boolean + arg-done?:boolean <- greater-or-equal j, a-len + break-if arg-done? # result[result-idx] = a[j] - in:character <- index a:address:array:character/lookup, j:number - out:address:character <- index-address result:address:array:character/lookup, result-idx:number - out:address:character/lookup <- copy in:character - # ++j - j:number <- add j:number, 1 - # ++result-idx - result-idx:number <- add result-idx:number, 1 + in:character <- index *a, j + out:address:character <- index-address *result, result-idx + *out <- copy in + j <- add j, 1 + result-idx <- add result-idx, 1 loop } # skip '_' in template - i:number <- add i:number, 1 + i <- add i, 1 loop # interpolate next arg } +done # done with holes; copy rest of template directly into result { # while i < template.length - tem-done?:boolean <- greater-or-equal i:number, tem-len:number - break-if tem-done?:boolean + tem-done?:boolean <- greater-or-equal i, tem-len + break-if tem-done? # result[result-idx] = template[i] - in:character <- index template:address:array:character/lookup, i:number - out:address:character <- index-address result:address:array:character/lookup, result-idx:number - out:address:character/lookup <- copy in:character - # ++i - i:number <- add i:number, 1 - # ++result-idx - result-idx:number <- add result-idx:number, 1 + in:character <- index *template, i + out:address:character <- index-address *result, result-idx:number + *out <- copy in + i <- add i, 1 + result-idx <- add result-idx, 1 loop } - reply result:address:array:character + reply result ] scenario interpolate-works [ @@ -503,7 +490,7 @@ scenario interpolate-works [ 1:address:array:character/raw <- new [abc _] 2:address:array:character/raw <- new [def] 3:address:array:character/raw <- interpolate 1:address:array:character/raw, 2:address:array:character/raw - 4:array:character/raw <- copy 3:address:array:character/raw/lookup + 4:array:character/raw <- copy *3:address:array:character/raw ] memory-should-contain [ 4:string <- [abc def] @@ -515,7 +502,7 @@ scenario interpolate-at-start [ 1:address:array:character/raw <- new [_, hello!] 2:address:array:character/raw <- new [abc] 3:address:array:character/raw <- interpolate 1:address:array:character/raw, 2:address:array:character/raw - 4:array:character/raw <- copy 3:address:array:character/raw/lookup + 4:array:character/raw <- copy *3:address:array:character/raw ] memory-should-contain [ 4:string <- [abc, hello!] @@ -528,7 +515,7 @@ scenario interpolate-at-end [ 1:address:array:character/raw <- new [hello, _] 2:address:array:character/raw <- new [abc] 3:address:array:character/raw <- interpolate 1:address:array:character/raw, 2:address:array:character/raw - 4:array:character/raw <- copy 3:address:array:character/raw/lookup + 4:array:character/raw <- copy *3:address:array:character/raw ] memory-should-contain [ 4:string <- [hello, abc] @@ -540,124 +527,123 @@ recipe space? [ local-scope c:character <- next-ingredient # most common case first - result:boolean <- equal c:character, 32/space - jump-if result:boolean, +reply:label - result:boolean <- equal c:character, 10/newline - jump-if result:boolean, +reply:label - result:boolean <- equal c:character, 9/tab - jump-if result:boolean, +reply:label - result:boolean <- equal c:character, 13/carriage-return + result:boolean <- equal c, 32/space + jump-if result +reply:label + result <- equal c, 10/newline + jump-if result, +reply:label + result <- equal c, 9/tab + jump-if result, +reply:label + result <- equal c, 13/carriage-return + jump-if result, +reply:label # remaining uncommon cases in sorted order # http://unicode.org code-points in unicode-set Z and Pattern_White_Space - jump-if result:boolean, +reply:label - result:boolean <- equal c:character, 11/ctrl-k - jump-if result:boolean, +reply:label - result:boolean <- equal c:character, 12/ctrl-l - jump-if result:boolean, +reply:label - result:boolean <- equal c:character, 133/ctrl-0085 - jump-if result:boolean, +reply:label - result:boolean <- equal c:character, 160/no-break-space - jump-if result:boolean, +reply:label - result:boolean <- equal c:character, 5760/ogham-space-mark - jump-if result:boolean, +reply:label - result:boolean <- equal c:character, 8192/en-quad - jump-if result:boolean, +reply:label - result:boolean <- equal c:character, 8193/em-quad - jump-if result:boolean, +reply:label - result:boolean <- equal c:character, 8194/en-space - jump-if result:boolean, +reply:label - result:boolean <- equal c:character, 8195/em-space - jump-if result:boolean, +reply:label - result:boolean <- equal c:character, 8196/three-per-em-space - jump-if result:boolean, +reply:label - result:boolean <- equal c:character, 8197/four-per-em-space - jump-if result:boolean, +reply:label - result:boolean <- equal c:character, 8198/six-per-em-space - jump-if result:boolean, +reply:label - result:boolean <- equal c:character, 8199/figure-space - jump-if result:boolean, +reply:label - result:boolean <- equal c:character, 8200/punctuation-space - jump-if result:boolean, +reply:label - result:boolean <- equal c:character, 8201/thin-space - jump-if result:boolean, +reply:label - result:boolean <- equal c:character, 8202/hair-space - jump-if result:boolean, +reply:label - result:boolean <- equal c:character, 8206/left-to-right - jump-if result:boolean, +reply:label - result:boolean <- equal c:character, 8207/right-to-left - jump-if result:boolean, +reply:label - result:boolean <- equal c:character, 8232/line-separator - jump-if result:boolean, +reply:label - result:boolean <- equal c:character, 8233/paragraph-separator - jump-if result:boolean, +reply:label - result:boolean <- equal c:character, 8239/narrow-no-break-space - jump-if result:boolean, +reply:label - result:boolean <- equal c:character, 8287/medium-mathematical-space - jump-if result:boolean, +reply:label - result:boolean <- equal c:character, 12288/ideographic-space - jump-if result:boolean, +reply:label + result <- equal c, 11/ctrl-k + jump-if result, +reply:label + result <- equal c, 12/ctrl-l + jump-if result, +reply:label + result <- equal c, 133/ctrl-0085 + jump-if result, +reply:label + result <- equal c, 160/no-break-space + jump-if result, +reply:label + result <- equal c, 5760/ogham-space-mark + jump-if result, +reply:label + result <- equal c, 8192/en-quad + jump-if result, +reply:label + result <- equal c, 8193/em-quad + jump-if result, +reply:label + result <- equal c, 8194/en-space + jump-if result, +reply:label + result <- equal c, 8195/em-space + jump-if result, +reply:label + result <- equal c, 8196/three-per-em-space + jump-if result, +reply:label + result <- equal c, 8197/four-per-em-space + jump-if result, +reply:label + result <- equal c, 8198/six-per-em-space + jump-if result, +reply:label + result <- equal c, 8199/figure-space + jump-if result, +reply:label + result <- equal c, 8200/punctuation-space + jump-if result, +reply:label + result <- equal c, 8201/thin-space + jump-if result, +reply:label + result <- equal c, 8202/hair-space + jump-if result, +reply:label + result <- equal c, 8206/left-to-right + jump-if result, +reply:label + result <- equal c, 8207/right-to-left + jump-if result, +reply:label + result <- equal c, 8232/line-separator + jump-if result, +reply:label + result <- equal c, 8233/paragraph-separator + jump-if result, +reply:label + result <- equal c, 8239/narrow-no-break-space + jump-if result, +reply:label + result <- equal c, 8287/medium-mathematical-space + jump-if result, +reply:label + result <- equal c, 12288/ideographic-space + jump-if result, +reply:label +reply - reply result:boolean + reply result ] # result:address:array:character <- trim s:address:array:character recipe trim [ local-scope s:address:array:character <- next-ingredient - len:number <- length s:address:array:character/lookup + len:number <- length *s # left trim: compute start start:number <- copy 0 { { - at-end?:boolean <- greater-or-equal start:number, len:number - break-unless at-end?:boolean + at-end?:boolean <- greater-or-equal start, len + break-unless at-end? result:address:array:character <- new character:type, 0 - reply result:address:array:character + reply result } - curr:character <- index s:address:array:character/lookup, start:number - whitespace?:boolean <- space? curr:character - break-unless whitespace?:boolean - start:number <- add start:number, 1 + curr:character <- index *s, start + whitespace?:boolean <- space? curr + break-unless whitespace? + start <- add start, 1 loop } # right trim: compute end - end:number <- subtract len:number, 1 + end:number <- subtract len, 1 { - not-at-start?:boolean <- greater-than end:number, start:number - assert not-at-start?:boolean [end ran up against start] - curr:character <- index s:address:array:character/lookup, end:number - whitespace?:boolean <- space? curr:character - break-unless whitespace?:boolean - end:number <- subtract end:number, 1 + not-at-start?:boolean <- greater-than end, start + assert not-at-start?, [end ran up against start] + curr:character <- index *s, end + whitespace?:boolean <- space? curr + break-unless whitespace? + end <- subtract end, 1 loop } # result = new character[end+1 - start] - new-len:number <- subtract end:number, start:number, -1 - result:address:array:character <- new character:type, new-len:number + new-len:number <- subtract end, start, -1 + result:address:array:character <- new character:type, new-len # i = start, j = 0 - i:number <- copy start:number + i:number <- copy start j:number <- copy 0 { # while i <= end - done?:boolean <- greater-than i:number, end:number - break-if done?:boolean + done?:boolean <- greater-than i, end + break-if done? # result[j] = s[i] - src:character <- index s:address:array:character/lookup, i:number - dest:address:character <- index-address result:address:array:character/lookup, j:number - dest:address:character/lookup <- copy src:character - # ++i, ++j - i:number <- add i:number, 1 - j:number <- add j:number, 1 + src:character <- index *s, i + dest:address:character <- index-address *result, j + *dest <- copy src + i <- add i, 1 + j <- add j, 1 loop } - reply result:address:array:character + reply result ] scenario trim-unmodified [ run [ 1:address:array:character <- new [abc] 2:address:array:character <- trim 1:address:array:character - 3:array:character <- copy 2:address:array:character/lookup + 3:array:character <- copy *2:address:array:character ] memory-should-contain [ 3:string <- [abc] @@ -668,7 +654,7 @@ scenario trim-left [ run [ 1:address:array:character <- new [ abc] 2:address:array:character <- trim 1:address:array:character - 3:array:character <- copy 2:address:array:character/lookup + 3:array:character <- copy *2:address:array:character ] memory-should-contain [ 3:string <- [abc] @@ -679,7 +665,7 @@ scenario trim-right [ run [ 1:address:array:character <- new [abc ] 2:address:array:character <- trim 1:address:array:character - 3:array:character <- copy 2:address:array:character/lookup + 3:array:character <- copy *2:address:array:character ] memory-should-contain [ 3:string <- [abc] @@ -690,7 +676,7 @@ scenario trim-left-right [ run [ 1:address:array:character <- new [ abc ] 2:address:array:character <- trim 1:address:array:character - 3:array:character <- copy 2:address:array:character/lookup + 3:array:character <- copy *2:address:array:character ] memory-should-contain [ 3:string <- [abc] @@ -702,30 +688,30 @@ scenario trim-newline-tab [ 1:address:array:character <- new [ abc ] 2:address:array:character <- trim 1:address:array:character - 3:array:character <- copy 2:address:array:character/lookup + 3:array:character <- copy *2:address:array:character ] memory-should-contain [ 3:string <- [abc] ] ] -# next-index:number <- find-next text:address:array:character, pattern:character +# next-index:number <- find-next text:address:array:character, pattern:character, idx:number recipe find-next [ local-scope text:address:array:character <- next-ingredient pattern:character <- next-ingredient idx:number <- next-ingredient - len:number <- length text:address:array:character/lookup + len:number <- length *text { - eof?:boolean <- greater-or-equal idx:number, len:number - break-if eof?:boolean - curr:character <- index text:address:array:character/lookup, idx:number - found?:boolean <- equal curr:character, pattern:character - break-if found?:boolean - idx:number <- add idx:number, 1 + eof?:boolean <- greater-or-equal idx, len + break-if eof? + curr:character <- index *text, idx + found?:boolean <- equal curr, pattern + break-if found? + idx <- add idx, 1 loop } - reply idx:number + reply idx ] scenario string-find-next [ @@ -808,6 +794,7 @@ scenario string-find-next-second [ ] ] +# idx:number <- find-substring text:address:array:character, pattern:address:array:character, idx:number # like find-next, but searches for multiple characters # fairly dumb algorithm recipe find-substring [ @@ -815,21 +802,21 @@ recipe find-substring [ text:address:array:character <- next-ingredient pattern:address:array:character <- next-ingredient idx:number <- next-ingredient - first:character <- index pattern:address:array:character/lookup, 0 + first:character <- index *pattern, 0 # repeatedly check for match at current idx - len:number <- length text:address:array:character/lookup + len:number <- length *text { # does some unnecessary work checking for substrings even when there isn't enough of text left - done?:boolean <- greater-or-equal idx:number, len:number - break-if done?:boolean - found?:boolean <- match-at text:address:array:character pattern:address:array:character, idx:number - break-if found?:boolean - idx:number <- add idx:number, 1 + done?:boolean <- greater-or-equal idx, len + break-if done? + found?:boolean <- match-at text, pattern, idx + break-if found? + idx <- add idx, 1 # optimization: skip past indices that definitely won't match - idx:number <- find-next text:address:array:character, first:character, idx:number + idx <- find-next text, first, idx loop } - reply idx:number + reply idx ] scenario find-substring-1 [ @@ -894,29 +881,29 @@ recipe match-at [ text:address:array:character <- next-ingredient pattern:address:array:character <- next-ingredient idx:number <- next-ingredient - pattern-len:number <- length pattern:address:array:character/lookup + pattern-len:number <- length *pattern # check that there's space left for the pattern { - x:number <- length text:address:array:character/lookup - x:number <- subtract x:number, pattern-len:number - enough-room?:boolean <- lesser-or-equal idx:number, x:number - break-if enough-room?:boolean + x:number <- length *text + x <- subtract x, pattern-len + enough-room?:boolean <- lesser-or-equal idx, x + break-if enough-room? reply 0/not-found } # check each character of pattern pattern-idx:number <- copy 0 { - done?:boolean <- greater-or-equal pattern-idx:number, pattern-len:number - break-if done?:boolean - c:character <- index text:address:array:character/lookup, idx:number - exp:character <- index pattern:address:array:character/lookup, pattern-idx:number + done?:boolean <- greater-or-equal pattern-idx, pattern-len + break-if done? + c:character <- index *text, idx + exp:character <- index *pattern, pattern-idx { - match?:boolean <- equal c:character, exp:character - break-if match?:boolean + match?:boolean <- equal c, exp + break-if match? reply 0/not-found } - idx:number <- add idx:number, 1 - pattern-idx:number <- add pattern-idx:number, 1 + idx <- add idx, 1 + pattern-idx <- add pattern-idx, 1 loop } reply 1/found @@ -1025,54 +1012,54 @@ recipe split [ s:address:array:character <- next-ingredient delim:character <- next-ingredient # empty string? return empty array - len:number <- length s:address:array:character/lookup + len:number <- length *s { - empty?:boolean <- equal len:number, 0 - break-unless empty?:boolean + empty?:boolean <- equal len, 0 + break-unless empty? result:address:array:address:array:character <- new location:type, 0 - reply result:address:array:address:array:character + reply result } # count #pieces we need room for count:number <- copy 1 # n delimiters = n+1 pieces idx:number <- copy 0 { - idx:number <- find-next s:address:array:character, delim:character, idx:number - done?:boolean <- greater-or-equal idx:number, len:number - break-if done?:boolean - idx:number <- add idx:number, 1 - count:number <- add count:number, 1 + idx <- find-next s, delim, idx + done?:boolean <- greater-or-equal idx, len + break-if done? + idx <- add idx, 1 + count <- add count, 1 loop } # allocate space - result:address:array:address:array:character <- new location:type, count:number + result:address:array:address:array:character <- new location:type, count # repeatedly copy slices start..end until delimiter into result[curr-result] curr-result:number <- copy 0 start:number <- copy 0 { # while next delim exists - done?:boolean <- greater-or-equal start:number, len:number - break-if done?:boolean - end:number <- find-next s:address:array:character, delim:character, start:number + done?:boolean <- greater-or-equal start, len + break-if done? + end:number <- find-next s, delim, start # copy start..end into result[curr-result] - dest:address:address:array:character <- index-address result:address:array:address:array:character/lookup, curr-result:number - dest:address:address:array:character/lookup <- string-copy s:address:array:character, start:number, end:number + dest:address:address:array:character <- index-address *result, curr-result + *dest <- string-copy s, start, end # slide over to next slice - start:number <- add end:number, 1 - curr-result:number <- add curr-result:number, 1 + start <- add end, 1 + curr-result <- add curr-result, 1 loop } - reply result:address:array:address:array:character + reply result ] scenario string-split-1 [ run [ 1:address:array:character <- new [a/b] 2:address:array:address:array:character <- split 1:address:array:character, 47/slash - 3:number <- length 2:address:array:address:array:character/lookup - 4:address:array:character <- index 2:address:array:address:array:character/lookup, 0 - 5:address:array:character <- index 2:address:array:address:array:character/lookup, 1 - 10:array:character <- copy 4:address:array:character/lookup - 20:array:character <- copy 5:address:array:character/lookup + 3:number <- length *2:address:array:address:array:character + 4:address:array:character <- index *2:address:array:address:array:character, 0 + 5:address:array:character <- index *2:address:array:address:array:character, 1 + 10:array:character <- copy *4:address:array:character + 20:array:character <- copy *5:address:array:character ] memory-should-contain [ 3 <- 2 # length of result @@ -1085,13 +1072,13 @@ scenario string-split-2 [ run [ 1:address:array:character <- new [a/b/c] 2:address:array:address:array:character <- split 1:address:array:character, 47/slash - 3:number <- length 2:address:array:address:array:character/lookup - 4:address:array:character <- index 2:address:array:address:array:character/lookup, 0 - 5:address:array:character <- index 2:address:array:address:array:character/lookup, 1 - 6:address:array:character <- index 2:address:array:address:array:character/lookup, 2 - 10:array:character <- copy 4:address:array:character/lookup - 20:array:character <- copy 5:address:array:character/lookup - 30:array:character <- copy 6:address:array:character/lookup + 3:number <- length *2:address:array:address:array:character + 4:address:array:character <- index *2:address:array:address:array:character, 0 + 5:address:array:character <- index *2:address:array:address:array:character, 1 + 6:address:array:character <- index *2:address:array:address:array:character, 2 + 10:array:character <- copy *4:address:array:character + 20:array:character <- copy *5:address:array:character + 30:array:character <- copy *6:address:array:character ] memory-should-contain [ 3 <- 3 # length of result @@ -1105,9 +1092,9 @@ scenario string-split-missing [ run [ 1:address:array:character <- new [abc] 2:address:array:address:array:character <- split 1:address:array:character, 47/slash - 3:number <- length 2:address:array:address:array:character/lookup - 4:address:array:character <- index 2:address:array:address:array:character/lookup, 0 - 10:array:character <- copy 4:address:array:character/lookup + 3:number <- length *2:address:array:address:array:character + 4:address:array:character <- index *2:address:array:address:array:character, 0 + 10:array:character <- copy *4:address:array:character ] memory-should-contain [ 3 <- 1 # length of result @@ -1119,7 +1106,7 @@ scenario string-split-empty [ run [ 1:address:array:character <- new [] 2:address:array:address:array:character <- split 1:address:array:character, 47/slash - 3:number <- length 2:address:array:address:array:character/lookup + 3:number <- length *2:address:array:address:array:character ] memory-should-contain [ 3 <- 0 # empty result @@ -1130,15 +1117,15 @@ scenario string-split-empty-piece [ run [ 1:address:array:character <- new [a/b//c] 2:address:array:address:array:character <- split 1:address:array:character, 47/slash - 3:number <- length 2:address:array:address:array:character/lookup - 4:address:array:character <- index 2:address:array:address:array:character/lookup, 0 - 5:address:array:character <- index 2:address:array:address:array:character/lookup, 1 - 6:address:array:character <- index 2:address:array:address:array:character/lookup, 2 - 7:address:array:character <- index 2:address:array:address:array:character/lookup, 3 - 10:array:character <- copy 4:address:array:character/lookup - 20:array:character <- copy 5:address:array:character/lookup - 30:array:character <- copy 6:address:array:character/lookup - 40:array:character <- copy 7:address:array:character/lookup + 3:number <- length *2:address:array:address:array:character + 4:address:array:character <- index *2:address:array:address:array:character, 0 + 5:address:array:character <- index *2:address:array:address:array:character, 1 + 6:address:array:character <- index *2:address:array:address:array:character, 2 + 7:address:array:character <- index *2:address:array:address:array:character, 3 + 10:array:character <- copy *4:address:array:character + 20:array:character <- copy *5:address:array:character + 30:array:character <- copy *6:address:array:character + 40:array:character <- copy *7:address:array:character ] memory-should-contain [ 3 <- 4 # length of result @@ -1155,27 +1142,27 @@ recipe split-first [ text:address:array:character <- next-ingredient delim:character <- next-ingredient # empty string? return empty strings - len:number <- length text:address:array:character/lookup + len:number <- length *text { - empty?:boolean <- equal len:number, 0 - break-unless empty?:boolean + empty?:boolean <- equal len, 0 + break-unless empty? x:address:array:character <- new [] y:address:array:character <- new [] - reply x:address:array:character, y:address:array:character + reply x, y } - idx:number <- find-next text:address:array:character, delim:character, 0 - x:address:array:character <- string-copy text:address:array:character, 0, idx:number - idx:number <- add idx:number, 1 - y:address:array:character <- string-copy text:address:array:character, idx:number, len:number - reply x:address:array:character, y:address:array:character + idx:number <- find-next text, delim, 0 + x:address:array:character <- string-copy text, 0, idx + idx <- add idx, 1 + y:address:array:character <- string-copy text, idx, len + reply x, y ] scenario string-split-first [ run [ 1:address:array:character <- new [a/b] 2:address:array:character, 3:address:array:character <- split-first 1:address:array:character, 47/slash - 10:array:character <- copy 2:address:array:character/lookup - 20:array:character <- copy 3:address:array:character/lookup + 10:array:character <- copy *2:address:array:character + 20:array:character <- copy *3:address:array:character ] memory-should-contain [ 10:string <- [a] @@ -1191,32 +1178,32 @@ recipe string-copy [ start:number <- next-ingredient end:number <- next-ingredient # if end is out of bounds, trim it - len:number <- length buf:address:array:character/lookup - end:number <- min len:number, end:number + len:number <- length *buf + end:number <- min len, end # allocate space for result - len:number <- subtract end:number, start:number - result:address:array:character <- new character:type, len:number + len <- subtract end, start + result:address:array:character <- new character:type, len # copy start..end into result[curr-result] - src-idx:number <- copy start:number + src-idx:number <- copy start dest-idx:number <- copy 0 { - done?:boolean <- greater-or-equal src-idx:number, end:number - break-if done?:boolean - src:character <- index buf:address:array:character/lookup, src-idx:number - dest:address:character <- index-address result:address:array:character/lookup, dest-idx:number - dest:address:character/lookup <- copy src:character - src-idx:number <- add src-idx:number, 1 - dest-idx:number <- add dest-idx:number, 1 + done?:boolean <- greater-or-equal src-idx, end + break-if done? + src:character <- index *buf, src-idx + dest:address:character <- index-address *result, dest-idx + *dest <- copy src + src-idx <- add src-idx, 1 + dest-idx <- add dest-idx, 1 loop } - reply result:address:array:character + reply result ] scenario string-copy-copies-substring [ run [ 1:address:array:character <- new [abc] 2:address:array:character <- string-copy 1:address:array:character, 1, 3 - 3:array:character <- copy 2:address:array:character/lookup + 3:array:character <- copy *2:address:array:character ] memory-should-contain [ 3:string <- [bc] @@ -1227,7 +1214,7 @@ scenario string-copy-out-of-bounds [ run [ 1:address:array:character <- new [abc] 2:address:array:character <- string-copy 1:address:array:character, 2, 4 - 3:array:character <- copy 2:address:array:character/lookup + 3:array:character <- copy *2:address:array:character ] memory-should-contain [ 3:string <- [c] @@ -1238,7 +1225,7 @@ scenario string-copy-out-of-bounds-2 [ run [ 1:address:array:character <- new [abc] 2:address:array:character <- string-copy 1:address:array:character, 3, 3 - 3:array:character <- copy 2:address:array:character/lookup + 3:array:character <- copy *2:address:array:character ] memory-should-contain [ 3:string <- [] @@ -1250,11 +1237,11 @@ recipe min [ x:number <- next-ingredient y:number <- next-ingredient { - return-x?:boolean <- lesser-than x:number, y:number - break-if return-x?:boolean - reply y:number + return-x?:boolean <- lesser-than x, y + break-if return-x? + reply y } - reply x:number + reply x ] recipe max [ @@ -1262,9 +1249,9 @@ recipe max [ x:number <- next-ingredient y:number <- next-ingredient { - return-x?:boolean <- greater-than x:number, y:number - break-if return-x?:boolean - reply y:number + return-x?:boolean <- greater-than x, y + break-if return-x? + reply y } - reply x:number + reply x ] diff --git a/061channel.mu b/061channel.mu index 302e93c2..3470cc14 100644 --- a/061channel.mu +++ b/061channel.mu @@ -37,17 +37,17 @@ recipe new-channel [ # result = new channel result:address:channel <- new channel:type # result.first-full = 0 - full:address:number <- get-address result:address:channel/lookup, first-full:offset - full:address:number/lookup <- copy 0 + full:address:number <- get-address *result, first-full:offset + *full <- copy 0 # result.first-free = 0 - free:address:number <- get-address result:address:channel/lookup, first-free:offset - free:address:number/lookup <- copy 0 + free:address:number <- get-address *result, first-free:offset + *free <- copy 0 # result.data = new location[ingredient+1] capacity:number <- next-ingredient - capacity:number <- add capacity:number, 1 # unused slot for 'full?' below - dest:address:address:array:location <- get-address result:address:channel/lookup, data:offset - dest:address:address:array:location/lookup <- new location:type, capacity:number - reply result:address:channel + capacity <- add capacity, 1 # unused slot for 'full?' below + dest:address:address:array:location <- get-address *result, data:offset + *dest <- new location:type, capacity + reply result ] # chan:address:channel <- write chan:address:channel, val:location @@ -57,26 +57,26 @@ recipe write [ val:location <- next-ingredient { # block if chan is full - full:boolean <- channel-full? chan:address:channel - break-unless full:boolean - full-address:address:number <- get-address chan:address:channel/lookup, first-full:offset - wait-for-location full-address:address:number/lookup + full:boolean <- channel-full? chan + break-unless full + full-address:address:number <- get-address *chan, first-full:offset + wait-for-location *full-address } # store val - circular-buffer:address:array:location <- get chan:address:channel/lookup, data:offset - free:address:number <- get-address chan:address:channel/lookup, first-free:offset - dest:address:location <- index-address circular-buffer:address:array:location/lookup, free:address:number/lookup - dest:address:location/lookup <- copy val:location - # increment free - free:address:number/lookup <- add free:address:number/lookup, 1 + circular-buffer:address:array:location <- get *chan, data:offset + free:address:number <- get-address *chan, first-free:offset + dest:address:location <- index-address *circular-buffer, *free + *dest <- copy val + # mark its slot as filled + *free <- add *free, 1 { # wrap free around to 0 if necessary - len:number <- length circular-buffer:address:array:location/lookup - at-end?:boolean <- greater-or-equal free:address:number/lookup, len:number - break-unless at-end?:boolean - free:address:number/lookup <- copy 0 + len:number <- length *circular-buffer + at-end?:boolean <- greater-or-equal *free, len + break-unless at-end? + *free <- copy 0 } - reply chan:address:channel/same-as-ingredient:0 + reply chan/same-as-ingredient:0 ] # result:location, chan:address:channel <- read chan:address:channel @@ -85,43 +85,43 @@ recipe read [ chan:address:channel <- next-ingredient { # block if chan is empty - empty:boolean <- channel-empty? chan:address:channel - break-unless empty:boolean - free-address:address:number <- get-address chan:address:channel/lookup, first-free:offset - wait-for-location free-address:address:number/lookup + empty?:boolean <- channel-empty? chan + break-unless empty? + free-address:address:number <- get-address *chan, first-free:offset + wait-for-location *free-address } # read result - full:address:number <- get-address chan:address:channel/lookup, first-full:offset - circular-buffer:address:array:location <- get chan:address:channel/lookup, data:offset - result:location <- index circular-buffer:address:array:location/lookup, full:address:number/lookup + full:address:number <- get-address *chan, first-full:offset + circular-buffer:address:array:location <- get *chan, data:offset + result:location <- index *circular-buffer, *full # increment full - full:address:number/lookup <- add full:address:number/lookup, 1 + *full <- add *full, 1 { # wrap full around to 0 if necessary - len:number <- length circular-buffer:address:array:location/lookup - at-end?:boolean <- greater-or-equal full:address:number/lookup, len:number - break-unless at-end?:boolean - full:address:number/lookup <- copy 0 + len:number <- length *circular-buffer + at-end?:boolean <- greater-or-equal *full, len + break-unless at-end? + *full <- copy 0 } - reply result:location, chan:address:channel/same-as-ingredient:0 + reply result, chan/same-as-ingredient:0 ] recipe clear-channel [ local-scope chan:address:channel <- next-ingredient { - empty?:boolean <- channel-empty? chan:address:channel - break-if empty?:boolean - _, chan:address:channel <- read chan:address:channel + empty?:boolean <- channel-empty? chan + break-if empty? + _, chan <- read chan } - reply chan:address:channel/same-as-ingredient:0 + reply chan/same-as-ingredient:0 ] scenario channel-initialization [ run [ 1:address:channel <- new-channel 3/capacity - 2:number <- get 1:address:channel/lookup, first-full:offset - 3:number <- get 1:address:channel/lookup, first-free:offset + 2:number <- get *1:address:channel, first-full:offset + 3:number <- get *1:address:channel, first-free:offset ] memory-should-contain [ 2 <- 0 # first-full @@ -133,8 +133,8 @@ scenario channel-write-increments-free [ run [ 1:address:channel <- new-channel 3/capacity 1:address:channel <- write 1:address:channel, 34 - 2:number <- get 1:address:channel/lookup, first-full:offset - 3:number <- get 1:address:channel/lookup, first-free:offset + 2:number <- get *1:address:channel, first-full:offset + 3:number <- get *1:address:channel, first-free:offset ] memory-should-contain [ 2 <- 0 # first-full @@ -147,8 +147,8 @@ scenario channel-read-increments-full [ 1:address:channel <- new-channel 3/capacity 1:address:channel <- write 1:address:channel, 34 _, 1:address:channel <- read 1:address:channel - 2:number <- get 1:address:channel/lookup, first-full:offset - 3:number <- get 1:address:channel/lookup, first-free:offset + 2:number <- get *1:address:channel, first-full:offset + 3:number <- get *1:address:channel, first-free:offset ] memory-should-contain [ 2 <- 1 # first-full @@ -164,14 +164,14 @@ scenario channel-wrap [ 1:address:channel <- write 1:address:channel, 34 _, 1:address:channel <- read 1:address:channel # first-free will now be 1 - 2:number <- get 1:address:channel/lookup, first-free:offset - 3:number <- get 1:address:channel/lookup, first-free:offset + 2:number <- get *1:address:channel, first-free:offset + 3:number <- get *1:address:channel, first-free:offset # write second value, verify that first-free wraps 1:address:channel <- write 1:address:channel, 34 - 4:number <- get 1:address:channel/lookup, first-free:offset + 4:number <- get *1:address:channel, first-free:offset # read second value, verify that first-full wraps _, 1:address:channel <- read 1:address:channel - 5:number <- get 1:address:channel/lookup, first-full:offset + 5:number <- get *1:address:channel, first-full:offset ] memory-should-contain [ 2 <- 1 # first-free after first write @@ -188,10 +188,10 @@ recipe channel-empty? [ local-scope chan:address:channel <- next-ingredient # return chan.first-full == chan.first-free - full:number <- get chan:address:channel/lookup, first-full:offset - free:number <- get chan:address:channel/lookup, first-free:offset - result:boolean <- equal full:number, free:number - reply result:boolean + full:number <- get *chan, first-full:offset + free:number <- get *chan, first-free:offset + result:boolean <- equal full, free + reply result ] # A full channel has first-empty just before first-full, wasting one slot. @@ -200,28 +200,28 @@ recipe channel-full? [ local-scope chan:address:channel <- next-ingredient # tmp = chan.first-free + 1 - tmp:number <- get chan:address:channel/lookup, first-free:offset - tmp:number <- add tmp:number, 1 + tmp:number <- get *chan, first-free:offset + tmp <- add tmp, 1 { # if tmp == chan.capacity, tmp = 0 - len:number <- channel-capacity chan:address:channel - at-end?:boolean <- greater-or-equal tmp:number, len:number - break-unless at-end?:boolean - tmp:number <- copy 0 + len:number <- channel-capacity chan + at-end?:boolean <- greater-or-equal tmp, len + break-unless at-end? + tmp <- copy 0 } # return chan.first-full == tmp - full:number <- get chan:address:channel/lookup, first-full:offset - result:boolean <- equal full:number, tmp:number - reply result:boolean + full:number <- get *chan, first-full:offset + result:boolean <- equal full, tmp + reply result ] # result:number <- channel-capacity chan:address:channel recipe channel-capacity [ local-scope chan:address:channel <- next-ingredient - q:address:array:location <- get chan:address:channel/lookup, data:offset - result:number <- length q:address:array:location/lookup - reply result:number + q:address:array:location <- get *chan, data:offset + result:number <- length *q + reply result ] scenario channel-new-empty-not-full [ @@ -280,8 +280,6 @@ scenario channel-read-not-full [ # out:address:channel <- buffer-lines in:address:channel, out:address:channel recipe buffer-lines [ local-scope -#? $print [buffer-lines: aaa -#? ] in:address:channel <- next-ingredient out:address:channel <- next-ingredient # repeat forever @@ -290,59 +288,46 @@ recipe buffer-lines [ # read characters from 'in' until newline, copy into line { +next-character - c:character, in:address:channel <- read in:address:channel + c:character, in <- read in # drop a character on backspace { # special-case: if it's a backspace - backspace?:boolean <- equal c:character, 8 - break-unless backspace?:boolean + backspace?:boolean <- equal c, 8 + break-unless backspace? # drop previous character -#? close-console #? 2 -#? $print [backspace! -#? ] #? 1 { - buffer-length:address:number <- get-address line:address:buffer/lookup, length:offset - buffer-empty?:boolean <- equal buffer-length:address:number/lookup, 0 - break-if buffer-empty?:boolean -#? $print [before: ], buffer-length:address:number/lookup, 10/newline - buffer-length:address:number/lookup <- subtract buffer-length:address:number/lookup, 1 -#? $print [after: ], buffer-length:address:number/lookup, 10/newline + buffer-length:address:number <- get-address *line, length:offset + buffer-empty?:boolean <- equal *buffer-length, 0 + break-if buffer-empty? + *buffer-length <- subtract *buffer-length, 1 } -#? $exit #? 2 # and don't append this one loop +next-character:label } # append anything else -#? $print [buffer-lines: appending ], c:character, 10/newline - line:address:buffer <- buffer-append line:address:buffer, c:character - line-done?:boolean <- equal c:character, 10/newline - break-if line-done?:boolean + line <- buffer-append line, c + line-done?:boolean <- equal c, 10/newline + break-if line-done? # stop buffering on eof (currently only generated by fake console) - eof?:boolean <- equal c:character, 0/eof - break-if eof?:boolean + eof?:boolean <- equal c, 0/eof + break-if eof? loop } -#? close-console #? 1 # copy line into 'out' -#? $print [buffer-lines: emitting -#? ] i:number <- copy 0 - line-contents:address:array:character <- get line:address:buffer/lookup, data:offset - max:number <- get line:address:buffer/lookup, length:offset + line-contents:address:array:character <- get *line, data:offset + max:number <- get *line, length:offset { - done?:boolean <- greater-or-equal i:number, max:number - break-if done?:boolean - c:character <- index line-contents:address:array:character/lookup, i:number - out:address:channel <- write out:address:channel, c:character -#? $print [writing ], i:number, [: ], c:character, 10/newline - i:number <- add i:number, 1 + done?:boolean <- greater-or-equal i, max + break-if done? + c:character <- index *line-contents, i + out <- write out, c + i <- add i, 1 loop } -#? $dump-trace #? 1 -#? $exit #? 1 loop } - reply out:address:channel/same-as-ingredient:1 + reply out/same-as-ingredient:1 ] scenario buffer-lines-blocks-until-newline [ diff --git a/062array.mu b/062array.mu index dff9d319..c54020c0 100644 --- a/062array.mu +++ b/062array.mu @@ -1,7 +1,7 @@ scenario array-from-args [ run [ 1:address:array:location <- new-array 0, 1, 2 - 2:array:location <- copy 1:address:array:location/lookup + 2:array:location <- copy *1:address:array:location ] memory-should-contain [ 2 <- 3 # array length @@ -18,23 +18,23 @@ recipe new-array [ { # while read curr-value curr-value:location, exists?:boolean <- next-ingredient - break-unless exists?:boolean - capacity:number <- add capacity:number, 1 + break-unless exists? + capacity <- add capacity, 1 loop } - result:address:array:location <- new location:type, capacity:number + result:address:array:location <- new location:type, capacity rewind-ingredients i:number <- copy 0 { # while read curr-value - done?:boolean <- greater-or-equal i:number, capacity:number - break-if done?:boolean + done?:boolean <- greater-or-equal i, capacity + break-if done? curr-value:location, exists?:boolean <- next-ingredient - assert exists?:boolean, [error in rewinding ingredients to new-array] - tmp:address:location <- index-address result:address:array:location/lookup, i:number - tmp:address:location/lookup <- copy curr-value:location - i:number <- add i:number, 1 + assert exists?, [error in rewinding ingredients to new-array] + tmp:address:location <- index-address *result, i + *tmp <- copy curr-value + i <- add i, 1 loop } - reply result:address:array:location + reply result ] diff --git a/063list.mu b/063list.mu index 51a33337..0ae881d4 100644 --- a/063list.mu +++ b/063list.mu @@ -14,27 +14,27 @@ recipe push [ x:location <- next-ingredient in:address:list <- next-ingredient result:address:list <- new list:type - val:address:location <- get-address result:address:list/lookup, value:offset - val:address:location/lookup <- copy x:location - next:address:address:list <- get-address result:address:list/lookup, next:offset - next:address:address:list/lookup <- copy in:address:list - reply result:address:list + val:address:location <- get-address *result, value:offset + *val <- copy x + next:address:address:list <- get-address *result, next:offset + *next <- copy in + reply result ] # result:location <- first in:address:list recipe first [ local-scope in:address:list <- next-ingredient - result:location <- get in:address:list/lookup, value:offset - reply result:location + result:location <- get *in, value:offset + reply result ] # result:address:list <- rest in:address:list recipe rest [ local-scope in:address:list <- next-ingredient - result:address:list <- get in:address:list/lookup, next:offset - reply result:address:list + result:address:list <- get *in, next:offset + reply result ] scenario list-handling [ diff --git a/065duplex_list.mu b/065duplex_list.mu index ba25e303..63ee9974 100644 --- a/065duplex_list.mu +++ b/065duplex_list.mu @@ -12,41 +12,41 @@ recipe push-duplex [ x:location <- next-ingredient in:address:duplex-list <- next-ingredient result:address:duplex-list <- new duplex-list:type - val:address:location <- get-address result:address:duplex-list/lookup, value:offset - val:address:location/lookup <- copy x:location - next:address:address:duplex-list <- get-address result:address:duplex-list/lookup, next:offset - next:address:address:duplex-list/lookup <- copy in:address:duplex-list - reply-unless in:address:duplex-list, result:address:duplex-list - prev:address:address:duplex-list <- get-address in:address:duplex-list/lookup, prev:offset - prev:address:address:duplex-list/lookup <- copy result:address:duplex-list - reply result:address:duplex-list + val:address:location <- get-address *result, value:offset + *val <- copy x + next:address:address:duplex-list <- get-address *result, next:offset + *next <- copy in + reply-unless in, result + prev:address:address:duplex-list <- get-address *in, prev:offset + *prev <- copy result + reply result ] # result:location <- first-duplex in:address:duplex-list recipe first-duplex [ local-scope in:address:duplex-list <- next-ingredient - reply-unless in:address:duplex-list, 0 - result:location <- get in:address:duplex-list/lookup, value:offset - reply result:location + reply-unless in, 0 + result:location <- get *in, value:offset + reply result ] # result:address:duplex-list <- next-duplex in:address:duplex-list recipe next-duplex [ local-scope in:address:duplex-list <- next-ingredient - reply-unless in:address:duplex-list, 0 - result:address:duplex-list <- get in:address:duplex-list/lookup, next:offset - reply result:address:duplex-list + reply-unless in, 0 + result:address:duplex-list <- get *in, next:offset + reply result ] # result:address:duplex-list <- prev-duplex in:address:duplex-list recipe prev-duplex [ local-scope in:address:duplex-list <- next-ingredient - reply-unless in:address:duplex-list, 0 - result:address:duplex-list <- get in:address:duplex-list/lookup, prev:offset - reply result:address:duplex-list + reply-unless in, 0 + result:address:duplex-list <- get *in, prev:offset + reply result ] scenario duplex-list-handling [ @@ -99,24 +99,24 @@ recipe insert-duplex [ x:location <- next-ingredient in:address:duplex-list <- next-ingredient new-node:address:duplex-list <- new duplex-list:type - val:address:location <- get-address new-node:address:duplex-list/lookup, value:offset - val:address:location/lookup <- copy x:location - next-node:address:duplex-list <- get in:address:duplex-list/lookup, next:offset + val:address:location <- get-address *new-node, value:offset + *val <- copy x + next-node:address:duplex-list <- get *in, next:offset # in.next = new-node - y:address:address:duplex-list <- get-address in:address:duplex-list/lookup, next:offset - y:address:address:duplex-list/lookup <- copy new-node:address:duplex-list + y:address:address:duplex-list <- get-address *in, next:offset + *y <- copy new-node # new-node.prev = in - y:address:address:duplex-list <- get-address new-node:address:duplex-list/lookup, prev:offset - y:address:address:duplex-list/lookup <- copy in:address:duplex-list + y <- get-address *new-node, prev:offset + *y <- copy in # new-node.next = next-node - y:address:address:duplex-list <- get-address new-node:address:duplex-list/lookup, next:offset - y:address:address:duplex-list/lookup <- copy next-node:address:duplex-list + y <- get-address *new-node, next:offset + *y <- copy next-node # if next-node is not null - reply-unless next-node:address:duplex-list, new-node:address:duplex-list + reply-unless next-node, new-node # next-node.prev = new-node - y:address:address:duplex-list <- get-address next-node:address:duplex-list/lookup, prev:offset - y:address:address:duplex-list/lookup <- copy new-node:address:duplex-list - reply new-node:address:duplex-list # just signalling something changed; don't rely on the result + y <- get-address *next-node, prev:offset + *y <- copy new-node + reply new-node # just signalling something changed; don't rely on the result ] scenario inserting-into-duplex-list [ @@ -240,30 +240,30 @@ recipe remove-duplex [ local-scope in:address:duplex-list <- next-ingredient # if 'in' is null, return - reply-unless in:address:duplex-list, in:address:duplex-list - next-node:address:duplex-list <- get in:address:duplex-list/lookup, next:offset - prev-node:address:duplex-list <- get in:address:duplex-list/lookup, prev:offset + reply-unless in, in + next-node:address:duplex-list <- get *in, next:offset + prev-node:address:duplex-list <- get *in, prev:offset # null in's pointers - x:address:address:duplex-list <- get-address in:address:duplex-list/lookup, next:offset - x:address:address:duplex-list/lookup <- copy 0 - x:address:address:duplex-list <- get-address in:address:duplex-list/lookup, prev:offset - x:address:address:duplex-list/lookup <- copy 0 + x:address:address:duplex-list <- get-address *in, next:offset + *x <- copy 0 + x <- get-address *in, prev:offset + *x <- copy 0 { # if next-node is not null - break-unless next-node:address:duplex-list + break-unless next-node # next-node.prev = prev-node - x:address:address:duplex-list <- get-address next-node:address:duplex-list/lookup, prev:offset - x:address:address:duplex-list/lookup <- copy prev-node:address:duplex-list + x <- get-address *next-node, prev:offset + *x <- copy prev-node } { # if prev-node is not null - break-unless prev-node:address:duplex-list + break-unless prev-node # prev-node.next = next-node - x:address:address:duplex-list <- get-address prev-node:address:duplex-list/lookup, next:offset - x:address:address:duplex-list/lookup <- copy next-node:address:duplex-list - reply prev-node:address:duplex-list + x <- get-address *prev-node, next:offset + *x <- copy next-node + reply prev-node } - reply next-node:address:duplex-list + reply next-node ] scenario removing-from-duplex-list [ @@ -358,8 +358,8 @@ scenario removing-from-singleton-list [ 1:address:duplex-list <- copy 0 # 1 points to singleton list 1:address:duplex-list <- push-duplex 3, 1:address:duplex-list 2:address:duplex-list <- remove-duplex 1:address:duplex-list - 3:address:duplex-list <- get 1:address:duplex-list/lookup, next:offset - 4:address:duplex-list <- get 1:address:duplex-list/lookup, prev:offset + 3:address:duplex-list <- get *1:address:duplex-list, next:offset + 4:address:duplex-list <- get *1:address:duplex-list, prev:offset ] memory-should-contain [ 2 <- 0 # remove returned null diff --git a/066stream.mu b/066stream.mu index 36c311c1..606d77e7 100644 --- a/066stream.mu +++ b/066stream.mu @@ -7,38 +7,38 @@ container stream [ recipe new-stream [ local-scope result:address:stream <- new stream:type - i:address:number <- get-address result:address:stream/lookup, index:offset - i:address:number/lookup <- copy 0 - d:address:address:array:character <- get-address result:address:stream/lookup, data:offset - d:address:address:array:character/lookup <- next-ingredient - reply result:address:stream + i:address:number <- get-address *result, index:offset + *i <- copy 0 + d:address:address:array:character <- get-address *result, data:offset + *d <- next-ingredient + reply result ] recipe rewind-stream [ local-scope in:address:stream <- next-ingredient - x:address:number <- get-address in:address:stream/lookup, index:offset - x:address:number/lookup <- copy 0 - reply in:address:stream/same-as-arg:0 + x:address:number <- get-address *in, index:offset + *x <- copy 0 + reply in/same-as-arg:0 ] recipe read-line [ local-scope in:address:stream <- next-ingredient - idx:address:number <- get-address in:address:stream/lookup, index:offset - s:address:array:character <- get in:address:stream/lookup, data:offset - next-idx:number <- find-next s:address:array:character, 10/newline, idx:address:number/lookup - result:address:array:character <- string-copy s:address:array:character, idx:address:number/lookup, next-idx:number - idx:address:number/lookup <- add next-idx:number, 1 # skip newline - reply result:address:array:character + idx:address:number <- get-address *in, index:offset + s:address:array:character <- get *in, data:offset + next-idx:number <- find-next s, 10/newline, *idx + result:address:array:character <- string-copy s, *idx, next-idx + *idx <- add next-idx, 1 # skip newline + reply result ] recipe end-of-stream? [ local-scope in:address:stream <- next-ingredient - idx:number <- get in:address:stream/lookup, index:offset - s:address:array:character <- get in:address:stream/lookup, data:offset - len:number <- length s:address:array:character/lookup - result:boolean <- greater-or-equal idx:number, len:number - reply result:boolean + idx:address:number <- get *in, index:offset + s:address:array:character <- get *in, data:offset + len:number <- length *s + result:boolean <- greater-or-equal idx, len + reply result ] diff --git a/071print.mu b/071print.mu index 7b52b920..075318a9 100644 --- a/071print.mu +++ b/071print.mu @@ -17,71 +17,68 @@ container screen-cell [ recipe new-fake-screen [ local-scope result:address:screen <- new screen:type - width:address:number <- get-address result:address:screen/lookup, num-columns:offset - width:address:number/lookup <- next-ingredient - height:address:number <- get-address result:address:screen/lookup, num-rows:offset - height:address:number/lookup <- next-ingredient -#? $print height:address:number/lookup, 10/newline - row:address:number <- get-address result:address:screen/lookup, cursor-row:offset - row:address:number/lookup <- copy 0 - column:address:number <- get-address result:address:screen/lookup, cursor-column:offset - column:address:number/lookup <- copy 0 - bufsize:number <- multiply width:address:number/lookup, height:address:number/lookup - buf:address:address:array:screen-cell <- get-address result:address:screen/lookup, data:offset - buf:address:address:array:screen-cell/lookup <- new screen-cell:type, bufsize:number - clear-screen result:address:screen - reply result:address:screen + width:address:number <- get-address *result, num-columns:offset + *width <- next-ingredient + height:address:number <- get-address *result, num-rows:offset + *height <- next-ingredient + row:address:number <- get-address *result, cursor-row:offset + *row <- copy 0 + column:address:number <- get-address *result, cursor-column:offset + *column <- copy 0 + bufsize:number <- multiply *width, *height + buf:address:address:array:screen-cell <- get-address *result, data:offset + *buf <- new screen-cell:type, bufsize + clear-screen result + reply result ] recipe clear-screen [ local-scope sc:address:screen <- next-ingredient -#? $print [clearing screen -#? ] #? 1 # if x exists { - break-unless sc:address:screen + break-unless sc # clear fake screen - buf:address:array:screen-cell <- get sc:address:screen/lookup, data:offset - max:number <- length buf:address:array:screen-cell/lookup + buf:address:array:screen-cell <- get *sc, data:offset + max:number <- length *buf i:number <- copy 0 { - done?:boolean <- greater-or-equal i:number, max:number - break-if done?:boolean - curr:address:screen-cell <- index-address buf:address:array:screen-cell/lookup, i:number - curr-content:address:character <- get-address curr:address:screen-cell/lookup, contents:offset - curr-content:address:character/lookup <- copy [ ] - curr-color:address:character <- get-address curr:address:screen-cell/lookup, color:offset - curr-color:address:character/lookup <- copy 7/white - i:number <- add i:number, 1 + done?:boolean <- greater-or-equal i, max + break-if done? + curr:address:screen-cell <- index-address *buf, i + curr-content:address:character <- get-address *curr, contents:offset + *curr-content <- copy [ ] + curr-color:address:character <- get-address *curr, color:offset + *curr-color <- copy 7/white + i <- add i, 1 loop } # reset cursor - cur:address:number <- get-address sc:address:screen/lookup, cursor-row:offset - cur:address:number/lookup <- copy 0 - cur:address:number <- get-address sc:address:screen/lookup, cursor-column:offset - cur:address:number/lookup <- copy 0 - reply sc:address:screen/same-as-ingredient:0 + x:address:number <- get-address *sc, cursor-row:offset + *x <- copy 0 + x <- get-address *sc, cursor-column:offset + *x <- copy 0 + reply sc/same-as-ingredient:0 } # otherwise, real screen clear-display - reply sc:address:screen/same-as-ingredient:0 + reply sc/same-as-ingredient:0 ] -recipe fake-screen-is-clear? [ +recipe fake-screen-is-empty? [ local-scope sc:address:screen <- next-ingredient - reply-unless sc:address:screen, 1/true - buf:address:array:screen-cell <- get sc:address:screen/lookup, data:offset + reply-unless sc, 1/true + buf:address:array:screen-cell <- get *sc, data:offset i:number <- copy 0 - len:number <- length buf:address:array:screen-cell/lookup + len:number <- length *buf { - done?:boolean <- greater-or-equal i:number, len:number - break-if done?:boolean - curr:screen-cell <- index buf:address:array:screen-cell/lookup, i:number - curr-contents:character <- get curr:screen-cell, contents:offset - i:number <- add i:number, 1 - loop-unless curr-contents:character + done?:boolean <- greater-or-equal i, len + break-if done? + curr:screen-cell <- index *buf, i + curr-contents:character <- get curr, contents:offset + i <- add i, 1 + loop-unless curr-contents # not 0 reply 0/false } @@ -95,91 +92,91 @@ recipe print-character [ color:number, color-found?:boolean <- next-ingredient { # default color to white - break-if color-found?:boolean - color:number <- copy 7/white + break-if color-found? + color <- copy 7/white } bg-color:number, bg-color-found?:boolean <- next-ingredient { # default bg-color to black - break-if bg-color-found?:boolean - bg-color:number <- copy 0/black + break-if bg-color-found? + bg-color <- copy 0/black } #? trace [app], [print character] #? 1 { # if x exists # (handle special cases exactly like in the real screen) - break-unless sc:address:screen - width:number <- get sc:address:screen/lookup, num-columns:offset - height:number <- get sc:address:screen/lookup, num-rows:offset + break-unless sc + width:number <- get *sc, num-columns:offset + height:number <- get *sc, num-rows:offset # if cursor is out of bounds, silently exit - row:address:number <- get-address sc:address:screen/lookup, cursor-row:offset - legal?:boolean <- greater-or-equal row:address:number/lookup, 0 - reply-unless legal?:boolean, sc:address:screen - legal?:boolean <- lesser-than row:address:number/lookup, height:number - reply-unless legal?:boolean, sc:address:screen - column:address:number <- get-address sc:address:screen/lookup, cursor-column:offset - legal?:boolean <- greater-or-equal column:address:number/lookup, 0 - reply-unless legal?:boolean, sc:address:screen - legal?:boolean <- lesser-than column:address:number/lookup, width:number - reply-unless legal?:boolean, sc:address:screen + row:address:number <- get-address *sc, cursor-row:offset + legal?:boolean <- greater-or-equal *row, 0 + reply-unless legal?, sc + legal? <- lesser-than *row, height + reply-unless legal?, sc + column:address:number <- get-address *sc, cursor-column:offset + legal? <- greater-or-equal *column, 0 + reply-unless legal?, sc + legal? <- lesser-than *column, width + reply-unless legal?, sc # special-case: newline { - newline?:boolean <- equal c:character, 10/newline -#? $print c:character, [ ], newline?:boolean, 10/newline - break-unless newline?:boolean + newline?:boolean <- equal c, 10/newline +#? $print c, [ ], newline?, 10/newline + break-unless newline? { # unless cursor is already at bottom - bottom:number <- subtract height:number, 1 - at-bottom?:boolean <- greater-or-equal row:address:number/lookup, bottom:number - break-if at-bottom?:boolean + bottom:number <- subtract height, 1 + at-bottom?:boolean <- greater-or-equal *row, bottom + break-if at-bottom? # move it to the next row - column:address:number/lookup <- copy 0 - row:address:number/lookup <- add row:address:number/lookup, 1 + *column <- copy 0 + *row <- add *row, 1 } - reply sc:address:screen/same-as-ingredient:0 + reply sc/same-as-ingredient:0 } # save character in fake screen - index:number <- multiply row:address:number/lookup, width:number - index:number <- add index:number, column:address:number/lookup - buf:address:array:screen-cell <- get sc:address:screen/lookup, data:offset - len:number <- length buf:address:array:screen-cell/lookup + index:number <- multiply *row, width + index <- add index, *column + buf:address:array:screen-cell <- get *sc, data:offset + len:number <- length *buf # special-case: backspace { - backspace?:boolean <- equal c:character, 8 - break-unless backspace?:boolean + backspace?:boolean <- equal c, 8 + break-unless backspace? { # unless cursor is already at left margin - at-left?:boolean <- lesser-or-equal column:address:number/lookup, 0 - break-if at-left?:boolean + at-left?:boolean <- lesser-or-equal *column, 0 + break-if at-left? # clear previous location - column:address:number/lookup <- subtract column:address:number/lookup, 1 - index:number <- subtract index:number, 1 - cursor:address:screen-cell <- index-address buf:address:array:screen-cell/lookup, index:number - cursor-contents:address:character <- get-address cursor:address:screen-cell/lookup, contents:offset - cursor-color:address:number <- get-address cursor:address:screen-cell/lookup, color:offset - cursor-contents:address:character/lookup <- copy 32/space - cursor-color:address:number/lookup <- copy 7/white + *column <- subtract *column, 1 + index <- subtract index, 1 + cursor:address:screen-cell <- index-address *buf, index + cursor-contents:address:character <- get-address *cursor, contents:offset + *cursor-contents <- copy 32/space + cursor-color:address:number <- get-address *cursor, color:offset + *cursor-color <- copy 7/white } - reply sc:address:screen/same-as-ingredient:0 + reply sc/same-as-ingredient:0 } -#? $print [saving character ], c:character, [ to fake screen ], cursor:address/screen, 10/newline - cursor:address:screen-cell <- index-address buf:address:array:screen-cell/lookup, index:number - cursor-contents:address:character <- get-address cursor:address:screen-cell/lookup, contents:offset - cursor-color:address:number <- get-address cursor:address:screen-cell/lookup, color:offset - cursor-contents:address:character/lookup <- copy c:character - cursor-color:address:number/lookup <- copy color:number +#? $print [saving character ], c, [ to fake screen ], cursor, 10/newline + cursor:address:screen-cell <- index-address *buf, index + cursor-contents:address:character <- get-address *cursor, contents:offset + *cursor-contents <- copy c + cursor-color:address:number <- get-address *cursor, color:offset + *cursor-color <- copy color # increment column unless it's already all the way to the right { - right:number <- subtract width:number, 1 - at-right?:boolean <- greater-or-equal column:address:number/lookup, right:number - break-if at-right?:boolean - column:address:number/lookup <- add column:address:number/lookup, 1 + right:number <- subtract width, 1 + at-right?:boolean <- greater-or-equal *column, right + break-if at-right? + *column <- add *column, 1 } - reply sc:address:screen/same-as-ingredient:0 + reply sc/same-as-ingredient:0 } # otherwise, real screen - print-character-to-display c:character, color:number, bg-color:number - reply sc:address:screen/same-as-ingredient:0 + print-character-to-display c, color, bg-color + reply sc/same-as-ingredient:0 ] scenario print-character-at-top-left [ @@ -187,8 +184,8 @@ scenario print-character-at-top-left [ #? $start-tracing #? 3 1:address:screen <- new-fake-screen 3/width, 2/height 1:address:screen <- print-character 1:address:screen, 97 # 'a' - 2:address:array:screen-cell <- get 1:address:screen/lookup, data:offset - 3:array:screen-cell <- copy 2:address:array:screen-cell/lookup + 2:address:array:screen-cell <- get *1:address:screen, data:offset + 3:array:screen-cell <- copy *2:address:array:screen-cell ] memory-should-contain [ 3 <- 6 # width*height @@ -202,8 +199,8 @@ scenario print-character-color [ run [ 1:address:screen <- new-fake-screen 3/width, 2/height 1:address:screen <- print-character 1:address:screen, 97/a, 1/red - 2:address:array:screen-cell <- get 1:address:screen/lookup, data:offset - 3:array:screen-cell <- copy 2:address:array:screen-cell/lookup + 2:address:array:screen-cell <- get *1:address:screen, data:offset + 3:array:screen-cell <- copy *2:address:array:screen-cell ] memory-should-contain [ 3 <- 6 # width*height @@ -219,9 +216,9 @@ scenario print-backspace-character [ 1:address:screen <- new-fake-screen 3/width, 2/height 1:address:screen <- print-character 1:address:screen, 97 # 'a' 1:address:screen <- print-character 1:address:screen, 8 # backspace - 2:number <- get 1:address:screen/lookup, cursor-column:offset - 3:address:array:screen-cell <- get 1:address:screen/lookup, data:offset - 4:array:screen-cell <- copy 3:address:array:screen-cell/lookup + 2:number <- get *1:address:screen, cursor-column:offset + 3:address:array:screen-cell <- get *1:address:screen, data:offset + 4:array:screen-cell <- copy *3:address:array:screen-cell ] memory-should-contain [ 2 <- 0 # cursor column @@ -238,9 +235,9 @@ scenario print-extra-backspace-character [ 1:address:screen <- print-character 1:address:screen, 97 # 'a' 1:address:screen <- print-character 1:address:screen, 8 # backspace 1:address:screen <- print-character 1:address:screen, 8 # backspace - 2:number <- get 1:address:screen/lookup, cursor-column:offset - 3:address:array:screen-cell <- get 1:address:screen/lookup, data:offset - 4:array:screen-cell <- copy 3:address:array:screen-cell/lookup + 2:number <- get *1:address:screen, cursor-column:offset + 3:address:array:screen-cell <- get *1:address:screen, data:offset + 4:array:screen-cell <- copy *3:address:array:screen-cell ] memory-should-contain [ 2 <- 0 # cursor column @@ -257,9 +254,9 @@ scenario print-at-right-margin [ 1:address:screen <- print-character 1:address:screen, 97 # 'a' 1:address:screen <- print-character 1:address:screen, 98 # 'b' 1:address:screen <- print-character 1:address:screen, 99 # 'c' - 2:number <- get 1:address:screen/lookup, cursor-column:offset - 3:address:array:screen-cell <- get 1:address:screen/lookup, data:offset - 4:array:screen-cell <- copy 3:address:array:screen-cell/lookup + 2:number <- get *1:address:screen, cursor-column:offset + 3:address:array:screen-cell <- get *1:address:screen, data:offset + 4:array:screen-cell <- copy *3:address:array:screen-cell ] memory-should-contain [ 2 <- 1 # cursor column @@ -278,10 +275,10 @@ scenario print-newline-character [ 1:address:screen <- new-fake-screen 3/width, 2/height 1:address:screen <- print-character 1:address:screen, 97 # 'a' 1:address:screen <- print-character 1:address:screen, 10/newline - 2:number <- get 1:address:screen/lookup, cursor-row:offset - 3:number <- get 1:address:screen/lookup, cursor-column:offset - 4:address:array:screen-cell <- get 1:address:screen/lookup, data:offset - 5:array:screen-cell <- copy 4:address:array:screen-cell/lookup + 2:number <- get *1:address:screen, cursor-row:offset + 3:number <- get *1:address:screen, cursor-column:offset + 4:address:array:screen-cell <- get *1:address:screen, data:offset + 5:array:screen-cell <- copy *4:address:array:screen-cell ] memory-should-contain [ 2 <- 1 # cursor row @@ -299,8 +296,8 @@ scenario print-newline-at-bottom-line [ 1:address:screen <- print-character 1:address:screen, 10/newline 1:address:screen <- print-character 1:address:screen, 10/newline 1:address:screen <- print-character 1:address:screen, 10/newline - 2:number <- get 1:address:screen/lookup, cursor-row:offset - 3:number <- get 1:address:screen/lookup, cursor-column:offset + 2:number <- get *1:address:screen, cursor-row:offset + 3:number <- get *1:address:screen, cursor-column:offset ] memory-should-contain [ 2 <- 1 # cursor row @@ -317,10 +314,10 @@ scenario print-at-bottom-right [ 1:address:screen <- print-character 1:address:screen, 99 # 'c' 1:address:screen <- print-character 1:address:screen, 10/newline 1:address:screen <- print-character 1:address:screen, 100 # 'd' - 2:number <- get 1:address:screen/lookup, cursor-row:offset - 3:number <- get 1:address:screen/lookup, cursor-column:offset - 4:address:array:screen-cell <- get 1:address:screen/lookup, data:offset - 5:array:screen-cell <- copy 4:address:array:screen-cell/lookup + 2:number <- get *1:address:screen, cursor-row:offset + 3:number <- get *1:address:screen, cursor-column:offset + 4:address:array:screen-cell <- get *1:address:screen, data:offset + 5:array:screen-cell <- copy *4:address:array:screen-cell ] memory-should-contain [ 2 <- 1 # cursor row @@ -343,27 +340,27 @@ recipe clear-line [ sc:address:screen <- next-ingredient # if x exists, clear line in fake screen { - break-unless sc:address:screen - width:number <- get sc:address:screen/lookup, num-columns:offset - column:address:number <- get-address sc:address:screen/lookup, cursor-column:offset - original-column:number <- copy column:address:number/lookup + break-unless sc + width:number <- get *sc, num-columns:offset + column:address:number <- get-address *sc, cursor-column:offset + original-column:number <- copy *column # space over the entire line #? $start-tracing #? 1 { -#? $print column:address:number/lookup, 10/newline - right:number <- subtract width:number, 1 - done?:boolean <- greater-or-equal column:address:number/lookup, right:number - break-if done?:boolean - print-character sc:address:screen, [ ] # implicitly updates 'column' +#? $print *column, 10/newline + right:number <- subtract width, 1 + done?:boolean <- greater-or-equal *column, right + break-if done? + print-character sc, [ ] # implicitly updates 'column' loop } # now back to where the cursor was - column:address:number/lookup <- copy original-column:number - reply sc:address:screen/same-as-ingredient:0 + *column <- copy original-column + reply sc/same-as-ingredient:0 } # otherwise, real screen clear-line-on-display - reply sc:address:screen/same-as-ingredient:0 + reply sc/same-as-ingredient:0 ] recipe cursor-position [ @@ -371,13 +368,13 @@ recipe cursor-position [ sc:address:screen <- next-ingredient # if x exists, lookup cursor in fake screen { - break-unless sc:address:screen - row:number <- get sc:address:screen/lookup, cursor-row:offset - column:number <- get sc:address:screen/lookup, cursor-column:offset - reply row:number, column:number, sc:address:screen/same-as-ingredient:0 + break-unless sc + row:number <- get *sc, cursor-row:offset + column:number <- get *sc, cursor-column:offset + reply row, column, sc/same-as-ingredient:0 } - row:number, column:number <- cursor-position-on-display - reply row:number, column:number, sc:address:screen/same-as-ingredient:0 + row, column <- cursor-position-on-display + reply row, column, sc/same-as-ingredient:0 ] recipe move-cursor [ @@ -387,16 +384,16 @@ recipe move-cursor [ new-column:number <- next-ingredient # if x exists, move cursor in fake screen { - break-unless sc:address:screen - row:address:number <- get-address sc:address:screen/lookup, cursor-row:offset - row:address:number/lookup <- copy new-row:number - column:address:number <- get-address sc:address:screen/lookup, cursor-column:offset - column:address:number/lookup <- copy new-column:number - reply sc:address:screen/same-as-ingredient:0 + break-unless sc + row:address:number <- get-address *sc, cursor-row:offset + *row <- copy new-row + column:address:number <- get-address *sc, cursor-column:offset + *column <- copy new-column + reply sc/same-as-ingredient:0 } # otherwise, real screen - move-cursor-on-display new-row:number, new-column:number - reply sc:address:screen/same-as-ingredient:0 + move-cursor-on-display new-row, new-column + reply sc/same-as-ingredient:0 ] scenario clear-line-erases-printed-characters [ @@ -409,8 +406,8 @@ scenario clear-line-erases-printed-characters [ 1:address:screen <- move-cursor 1:address:screen, 0/row, 0/column # clear line 1:address:screen <- clear-line 1:address:screen - 2:address:array:screen-cell <- get 1:address:screen/lookup, data:offset - 3:array:screen-cell <- copy 2:address:array:screen-cell/lookup + 2:address:array:screen-cell <- get *1:address:screen, data:offset + 3:array:screen-cell <- copy *2:address:array:screen-cell ] # screen should be blank memory-should-contain [ @@ -435,25 +432,22 @@ recipe cursor-down [ sc:address:screen <- next-ingredient # if x exists, move cursor in fake screen { - break-unless sc:address:screen + break-unless sc { # if row < height-1 - height:number <- get sc:address:screen/lookup, num-rows:offset - row:address:number <- get-address sc:address:screen/lookup, cursor-row:offset - max:number <- subtract height:number, 1 - at-bottom?:boolean <- greater-or-equal row:address:number/lookup, max:number - break-if at-bottom?:boolean + height:number <- get *sc, num-rows:offset + row:address:number <- get-address *sc, cursor-row:offset + max:number <- subtract height, 1 + at-bottom?:boolean <- greater-or-equal *row, max + break-if at-bottom? # row = row+1 -#? $print [AAA: ], row:address:number, [ -> ], row:address:number/lookup, 10/newline - row:address:number/lookup <- add row:address:number/lookup, 1 -#? $print [BBB: ], row:address:number, [ -> ], row:address:number/lookup, 10/newline -#? $start-tracing #? 1 + *row <- add *row, 1 } - reply sc:address:screen/same-as-ingredient:0 + reply sc/same-as-ingredient:0 } # otherwise, real screen move-cursor-down-on-display - reply sc:address:screen/same-as-ingredient:0 + reply sc/same-as-ingredient:0 ] recipe cursor-up [ @@ -461,20 +455,20 @@ recipe cursor-up [ sc:address:screen <- next-ingredient # if x exists, move cursor in fake screen { - break-unless sc:address:screen + break-unless sc { # if row > 0 - row:address:number <- get-address sc:address:screen/lookup, cursor-row:offset - at-top?:boolean <- lesser-or-equal row:address:number/lookup, 0 - break-if at-top?:boolean + row:address:number <- get-address *sc, cursor-row:offset + at-top?:boolean <- lesser-or-equal *row, 0 + break-if at-top? # row = row-1 - row:address:number/lookup <- subtract row:address:number/lookup, 1 + *row <- subtract *row, 1 } - reply sc:address:screen/same-as-ingredient:0 + reply sc/same-as-ingredient:0 } # otherwise, real screen move-cursor-up-on-display - reply sc:address:screen/same-as-ingredient:0 + reply sc/same-as-ingredient:0 ] recipe cursor-right [ @@ -482,22 +476,22 @@ recipe cursor-right [ sc:address:screen <- next-ingredient # if x exists, move cursor in fake screen { - break-unless sc:address:screen + break-unless sc { # if column < width-1 - width:number <- get sc:address:screen/lookup, num-columns:offset - column:address:number <- get-address sc:address:screen/lookup, cursor-column:offset - max:number <- subtract width:number, 1 - at-bottom?:boolean <- greater-or-equal column:address:number/lookup, max:number - break-if at-bottom?:boolean + width:number <- get *sc, num-columns:offset + column:address:number <- get-address *sc, cursor-column:offset + max:number <- subtract width, 1 + at-bottom?:boolean <- greater-or-equal *column, max + break-if at-bottom? # column = column+1 - column:address:number/lookup <- add column:address:number/lookup, 1 + *column <- add *column, 1 } - reply sc:address:screen/same-as-ingredient:0 + reply sc/same-as-ingredient:0 } # otherwise, real screen move-cursor-right-on-display - reply sc:address:screen/same-as-ingredient:0 + reply sc/same-as-ingredient:0 ] recipe cursor-left [ @@ -505,37 +499,37 @@ recipe cursor-left [ sc:address:screen <- next-ingredient # if x exists, move cursor in fake screen { - break-unless sc:address:screen + break-unless sc { # if column > 0 - column:address:number <- get-address sc:address:screen/lookup, cursor-column:offset - at-top?:boolean <- lesser-or-equal column:address:number/lookup, 0 - break-if at-top?:boolean + column:address:number <- get-address *sc, cursor-column:offset + at-top?:boolean <- lesser-or-equal *column, 0 + break-if at-top? # column = column-1 - column:address:number/lookup <- subtract column:address:number/lookup, 1 + *column <- subtract *column, 1 } - reply sc:address:screen/same-as-ingredient:0 + reply sc/same-as-ingredient:0 } # otherwise, real screen move-cursor-left-on-display - reply sc:address:screen/same-as-ingredient:0 + reply sc/same-as-ingredient:0 ] recipe cursor-to-start-of-line [ local-scope sc:address:screen <- next-ingredient - row:number, _, sc:address:screen <- cursor-position sc:address:screen + row:number, _, sc <- cursor-position sc column:number <- copy 0 - sc:address:screen <- move-cursor sc:address:screen, row:number, column:number - reply sc:address:screen/same-as-ingredient:0 + sc <- move-cursor sc, row, column + reply sc/same-as-ingredient:0 ] recipe cursor-to-next-line [ local-scope screen:address <- next-ingredient - screen:address <- cursor-down screen:address - screen:address <- cursor-to-start-of-line screen:address - reply screen:address/same-as-ingredient:0 + screen <- cursor-down screen + screen <- cursor-to-start-of-line screen + reply screen/same-as-ingredient:0 ] recipe screen-width [ @@ -543,13 +537,13 @@ recipe screen-width [ sc:address:screen <- next-ingredient # if x exists, move cursor in fake screen { - break-unless sc:address:screen - width:number <- get sc:address:screen/lookup, num-columns:offset - reply width:number + break-unless sc + width:number <- get *sc, num-columns:offset + reply width } # otherwise, real screen width:number <- display-width - reply width:number + reply width ] recipe screen-height [ @@ -557,13 +551,13 @@ recipe screen-height [ sc:address:screen <- next-ingredient # if x exists, move cursor in fake screen { - break-unless sc:address:screen - height:number <- get sc:address:screen/lookup, num-rows:offset - reply height:number + break-unless sc + height:number <- get *sc, num-rows:offset + reply height } # otherwise, real screen height:number <- display-height - reply height:number + reply height ] recipe hide-cursor [ @@ -571,12 +565,12 @@ recipe hide-cursor [ screen:address <- next-ingredient # if x exists (not real display), do nothing { - break-unless screen:address - reply screen:address + break-unless screen + reply screen } # otherwise, real screen hide-cursor-on-display - reply screen:address + reply screen ] recipe show-cursor [ @@ -584,12 +578,12 @@ recipe show-cursor [ screen:address <- next-ingredient # if x exists (not real display), do nothing { - break-unless screen:address - reply screen:address + break-unless screen + reply screen } # otherwise, real screen show-cursor-on-display - reply screen:address + reply screen ] recipe hide-screen [ @@ -597,12 +591,12 @@ recipe hide-screen [ screen:address <- next-ingredient # if x exists (not real display), do nothing { - break-unless screen:address - reply screen:address + break-unless screen + reply screen } # otherwise, real screen hide-display - reply screen:address + reply screen ] recipe show-screen [ @@ -610,12 +604,12 @@ recipe show-screen [ screen:address <- next-ingredient # if x exists (not real display), do nothing { - break-unless screen:address - reply screen:address + break-unless screen + reply screen } # otherwise, real screen show-display - reply screen:address + reply screen ] recipe print-string [ @@ -625,26 +619,26 @@ recipe print-string [ color:number, color-found?:boolean <- next-ingredient { # default color to white - break-if color-found?:boolean - color:number <- copy 7/white + break-if color-found? + color <- copy 7/white } bg-color:number, bg-color-found?:boolean <- next-ingredient { # default bg-color to black - break-if bg-color-found?:boolean - bg-color:number <- copy 0/black + break-if bg-color-found? + bg-color <- copy 0/black } - len:number <- length s:address:array:character/lookup + len:number <- length *s i:number <- copy 0 { - done?:boolean <- greater-or-equal i:number, len:number - break-if done?:boolean - c:character <- index s:address:array:character/lookup, i:number - print-character screen:address, c:character, color:number, bg-color:number - i:number <- add i:number, 1 + done?:boolean <- greater-or-equal i, len + break-if done? + c:character <- index *s, i + print-character screen, c, color, bg-color + i <- add i, 1 loop } - reply screen:address/same-as-ingredient:0 + reply screen/same-as-ingredient:0 ] scenario print-string-stops-at-right-margin [ @@ -652,8 +646,8 @@ scenario print-string-stops-at-right-margin [ 1:address:screen <- new-fake-screen 3/width, 2/height 2:address:array:character <- new [abcd] 1:address:screen <- print-string 1:address:screen, 2:address:array:character - 3:address:array:screen-cell <- get 1:address:screen/lookup, data:offset - 4:array:screen-cell <- copy 3:address:array:screen-cell/lookup + 3:address:array:screen-cell <- get *1:address:screen, data:offset + 4:array:screen-cell <- copy *3:address:array:screen-cell ] memory-should-contain [ 4 <- 6 # width*height @@ -674,17 +668,17 @@ recipe print-integer [ color:number, color-found?:boolean <- next-ingredient { # default color to white - break-if color-found?:boolean - color:number <- copy 7/white + break-if color-found? + color <- copy 7/white } bg-color:number, bg-color-found?:boolean <- next-ingredient { # default bg-color to black - break-if bg-color-found?:boolean - bg-color:number <- copy 0/black + break-if bg-color-found? + bg-color <- copy 0/black } # todo: other bases besides decimal - s:address:array:character <- integer-to-decimal-string n:number - print-string screen:address, s:address:array:character, color:number, bg-color:number - reply screen:address/same-as-ingredient:0 + s:address:array:character <- integer-to-decimal-string n + print-string screen, s, color, bg-color + reply screen/same-as-ingredient:0 ] diff --git a/074console.mu b/074console.mu index 031f0781..b60e17cc 100644 --- a/074console.mu +++ b/074console.mu @@ -22,37 +22,35 @@ container console [ recipe new-fake-console [ local-scope result:address:console <- new console:type - buf:address:address:array:character <- get-address result:address:console/lookup, data:offset -#? $start-tracing #? 1 - buf:address:address:array:character/lookup <- next-ingredient -#? $stop-tracing #? 1 - idx:address:number <- get-address result:address:console/lookup, index:offset - idx:address:number/lookup <- copy 0 - reply result:address:console + buf:address:address:array:character <- get-address *result, data:offset + *buf <- next-ingredient + idx:address:number <- get-address *result, index:offset + *idx <- copy 0 + reply result ] recipe read-event [ local-scope x:address:console <- next-ingredient { - break-unless x:address:console - idx:address:number <- get-address x:address:console/lookup, index:offset - buf:address:array:event <- get x:address:console/lookup, data:offset + break-unless x + idx:address:number <- get-address *x, index:offset + buf:address:array:event <- get *x, data:offset { - max:number <- length buf:address:array:event/lookup - done?:boolean <- greater-or-equal idx:address:number/lookup, max:number - break-unless done?:boolean + max:number <- length *buf + done?:boolean <- greater-or-equal *idx, max + break-unless done? dummy:address:event <- new event:type - reply dummy:address:event/lookup, x:address:console/same-as-ingredient:0, 1/found, 1/quit + reply *dummy, x/same-as-ingredient:0, 1/found, 1/quit } - result:event <- index buf:address:array:event/lookup, idx:address:number/lookup - idx:address:number/lookup <- add idx:address:number/lookup, 1 - reply result:event, x:address:console/same-as-ingredient:0, 1/found, 0/quit + result:event <- index *buf, *idx + *idx <- add *idx, 1 + reply result, x/same-as-ingredient:0, 1/found, 0/quit } # real event source is infrequent; avoid polling it too much switch result:event, found?:boolean <- check-for-interaction - reply result:event, x:address:console/same-as-ingredient:0, found?:boolean, 0/quit + reply result, x/same-as-ingredient:0, found?, 0/quit ] # variant of read-event for just keyboard events. Discards everything that @@ -60,20 +58,13 @@ recipe read-event [ # newlines, tabs, ctrl-d.. recipe read-key [ local-scope -#? $print default-space:address:array:location #? 1 -#? $exit #? 1 -#? $start-tracing #? 1 console:address <- next-ingredient - x:event, console:address, found?:boolean, quit?:boolean <- read-event console:address -#? $print [aaa 1] #? 1 - reply-if quit?:boolean, 0, console:address/same-as-ingredient:0, found?:boolean, quit?:boolean -#? $print [aaa 2] #? 1 - reply-unless found?:boolean, 0, console:address/same-as-ingredient:0, found?:boolean, quit?:boolean -#? $print [aaa 3] #? 1 - c:address:character <- maybe-convert x:event, text:variant - reply-unless c:address:character, 0, console:address/same-as-ingredient:0, 0/found, 0/quit -#? $print [aaa 4] #? 1 - reply c:address:character/lookup, console:address/same-as-ingredient:0, 1/found, 0/quit + x:event, console, found?:boolean, quit?:boolean <- read-event console + reply-if quit?, 0, console/same-as-ingredient:0, found?, quit? + reply-unless found?, 0, console/same-as-ingredient:0, found?, quit? + c:address:character <- maybe-convert x, text:variant + reply-unless c, 0, console/same-as-ingredient:0, 0/found, 0/quit + reply *c, console/same-as-ingredient:0, 1/found, 0/quit ] recipe send-keys-to-channel [ @@ -82,23 +73,25 @@ recipe send-keys-to-channel [ chan:address:channel <- next-ingredient screen:address <- next-ingredient { - c:character, console:address, found?:boolean, quit?:boolean <- read-key console:address - loop-unless found?:boolean - break-if quit?:boolean - assert c:character, [invalid event, expected text] - print-character screen:address, c:character - chan:address:channel <- write chan:address:channel, c:character + c:character, console, found?:boolean, quit?:boolean <- read-key console + loop-unless found? + break-if quit? + assert c, [invalid event, expected text] + screen <- print-character screen, c + chan <- write chan, c loop } + reply console/same-as-ingredient:0, chan/same-as-ingredient:1, screen/same-as-ingredient:2 ] recipe wait-for-event [ local-scope console:address <- next-ingredient { - _, console:address, found?:boolean <- read-event console:address - loop-unless found?:boolean + _, console, found?:boolean <- read-event console + loop-unless found? } + reply console/same-as-ingredient:0 ] # use this helper to skip rendering if there's lots of other events queued up @@ -106,10 +99,10 @@ recipe has-more-events? [ local-scope console:address <- next-ingredient { - break-unless console:address + break-unless console # fake consoles should be plenty fast; never skip reply 0/false } result:boolean <- interactions-left? - reply result:boolean + reply result ] diff --git a/edit.mu b/edit.mu index d8df5822..e26872e8 100644 --- a/edit.mu +++ b/edit.mu @@ -2948,7 +2948,7 @@ recipe render-sandboxes [ } { break-if sandbox-warnings - empty-screen?:boolean <- fake-screen-is-clear? sandbox-screen + empty-screen?:boolean <- fake-screen-is-empty? sandbox-screen break-if empty-screen? row, screen <- render-screen screen, sandbox-screen, left, right, row } -- cgit 1.4.1-2-gfad0