# interactive prompt for mu recipe main [ default-space:address:array:location <- new location:type, 30:literal switch-to-display msg:address:array:character <- new [ready! type in an instruction, then hit enter. ctrl-d exits. ] 0:literal/real-screen <- print-string 0:literal/real-screen, msg:address:array:character { inst:address:array:character, 0:literal/real-keyboard, 0:literal/real-screen <- read-instruction 0:literal/real-keyboard, 0:literal/real-screen break-unless inst:address:array:character 0:literal/real-screen <- print-string 0:literal/real-screen, inst:address:array:character loop } return-to-console ] # basic keyboard input; just text and enter scenario read-instruction1 [ assume-screen 30:literal/width, 5:literal/height assume-keyboard [x <- copy y ] run [ 1:address:array:character <- read-instruction keyboard:address, screen:address 2:address:array:character <- new [=> ] print-string screen:address, 2:address:array:character print-string screen:address, 1:address:array:character ] screen-should-contain [ .x <- copy y . .=> x <- copy y . . . ] screen-should-contain-in-color 7:literal/white, [ .x <- copy y . .=> x <- copy y . . . ] ] # Read characters as they're typed at the keyboard, print them to the screen, # accumulate them in a string, return the string at the end. # Most of the complexity is for the printing to screen, to highlight strings # and comments specially. Especially in the presence of backspacing. recipe read-instruction [ default-space:address:array:location <- new location:type, 60:literal k:address:keyboard <- next-ingredient x:address:screen <- next-ingredient result:address:buffer <- init-buffer 10:literal # string to maybe add to trace [app], [read-instruction] # start state machine by calling slurp-regular-characters, which will return # by calling the complete continuation complete:continuation <- current-continuation # If result is not empty, we've run slurp-regular-characters below, called # the continuation and so bounced back here. We're done. len:number <- get result:address:buffer/deref, length:offset completed?:boolean <- greater-than len:number, 0:literal jump-if completed?:boolean, +completed:label # Otherwise we're just getting started. result:address:buffer, k:address:keyboard, x:address:screen <- slurp-regular-characters result:address:buffer, k:address:keyboard, x:address:screen, complete:continuation trace [error], [slurp-regular-characters should never return normally] +completed result2:address:array:character <- buffer-to-array result:address:buffer trace [app], [exiting read-instruction] reply result2:address:array:character, k:address:keyboard/same-as-ingredient:0, x:address:screen/same-as-ingredient:1 ] # read characters from the keyboard, print them to the screen in *white*. # Transition to other routines for comments and strings. recipe slurp-regular-characters [ default-space:address:array:location <- new location:type, 60:literal result:address:buffer <- next-ingredient k:address:keyboard <- next-ingredient x:address:screen <- next-ingredient complete:continuation <- next-ingredient trace [app], [slurp-regular-characters] characters-slurped:number <- copy 0:literal { +next-character # read character c:character, k:address:keyboard <- wait-for-key k:address:keyboard # quit? { ctrl-d?:boolean <- equal c:character, 4:literal/ctrl-d/eof break-unless ctrl-d?:boolean trace [app], [slurp-regular-characters: ctrl-d] reply 0:literal, k:address:keyboard/same-as-ingredient:1, x:address:screen/same-as-ingredient:2 } { null?:boolean <- equal c:character, 0:literal/null break-unless null?:boolean trace [app], [slurp-regular-characters: null] reply 0:literal, k:address:keyboard/same-as-ingredient:1, x:address:screen/same-as-ingredient:2 } # comment? { comment?:boolean <- equal c:character, 35:literal/hash break-unless comment?:boolean print-character x:address:screen, c:character, 4:literal/blue result:address:buffer <- buffer-append result:address:buffer, c:character result:address:buffer, k:address:keyboard, x:address:screen <- slurp-comment result:address:buffer, k:address:keyboard, x:address:screen, comp
c{0: 0 (((1 string-address) (raw)) <- ((integer-to-decimal-string)) ((0 literal))) -- nil
c{1: 0 ✓ (((1 string-address) (raw)) <- ((integer-to-decimal-string)) ((0 literal)))
cn0: convert-names in main
cn0: (((1 string-address) (raw)) <- ((integer-to-decimal-string)) ((0 literal))) nil nil
cn0: checking arg ((0 literal))
cn0: checking oarg ((1 string-address) (raw))
maybe-add: ((1 string-address) (raw))
cn1: (((1 string-address) (raw)) <- ((integer-to-decimal-string)) ((0 literal)))
schedule: main
run: main 0: (((1 string-address) (raw)) <- ((integer-to-decimal-string)) ((0 literal)))
run: integer-to-decimal-string/main 0: (((default-space space-address)) <- ((new)) ((space literal)) ((30 literal)))
run: integer-to-decimal-string/main 0: 1000 => ((default-space space-address))
run: integer-to-decimal-string/main 1: (((1 integer)) <- ((next-input)))
arg: nil 0 (0)
run: integer-to-decimal-string/main 1: 0 => ((1 integer))
mem: ((1 integer)): 1002 <= 0
run: integer-to-decimal-string/main 2: (((2 boolean)) <- ((equal)) ((1 integer)) ((0 literal)))
mem: ((1 integer)) => 0
run: integer-to-decimal-string/main 2: t => ((2 boolean))
mem: ((2 boolean)): 1003 <= t
run: integer-to-decimal-string/main 3: (((jump-unless)) ((2 boolean)) ((2 offset)))
mem: ((2 boolean)) => t
run: integer-to-decimal-string/main 4: (((3 string-address)) <- ((new)) 0)
run: integer-to-decimal-string/main 4: 1031 => ((3 string-address))
mem: ((3 string-address)): 1004 <= 1031
run: integer-to-decimal-string/main 5: (((reply)) ((3 string-address)))
mem: ((3 string-address)) => 1031
run: main 0: 1031 => ((1 string-address) (raw))
mem: ((1 string-address) (raw)): 1 <= 1031
schedule: done with routine nil
cter:label } # otherwise increment characters-slurped:number <- add characters-slurped:number, 1:literal # done with this instruction? done?:boolean <- equal c:character, 93:literal/close-bracket break-if done?:boolean loop } { break-unless nested-string?:boolean # nested string? return like a normal recipe reply result:address:buffer, characters-slurped:number, k:address:keyboard, x:address:screen } # top-level string call? recurse trace [app], [slurp-string: close-bracket encountered; recursing to regular characters] result:address:buffer, k:address:keyboard, x:address:screen <- slurp-regular-characters result:address:buffer, k:address:keyboard, x:address:screen, complete:continuation # backspaced back into this string trace [app], [slurp-string: backspaced back into string; restarting] jump +next-character:label ] scenario read-instruction-color-comment [ assume-screen 30:literal/width, 5:literal/height assume-keyboard [# comment ] run [ read-instruction keyboard:address, screen:address ] screen-should-contain-in-color 4:literal/blue, [ .# comment . . . ] screen-should-contain-in-color 7:literal/white, [ . . . . ] ] scenario read-instruction-cancel-comment-on-backspace [ assume-screen 30:literal/width, 5:literal/height assume-keyboard [#a<