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 +++++++++++++++++++++++++++++------------------------------ 1 file changed, 361 insertions(+), 374 deletions(-) (limited to '060string.mu') 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 ] -- cgit 1.4.1-2-gfad0