# some primitives for moving the cursor without making assumptions about # raster order fn move-cursor-left screen: (addr screen) { var cursor-x/eax: int <- copy 0 var cursor-y/ecx: int <- copy 0 cursor-x, cursor-y <- cursor-position screen compare cursor-x, 0 { break-if-> return } cursor-x <- decrement set-cursor-position screen, cursor-x, cursor-y } fn move-cursor-right screen: (addr screen) { var _width/eax: int <- copy 0 var dummy/ecx: int <- copy 0 _width, dummy <- screen-size screen var limit/edx: int <- copy _width limit <- decrement var cursor-x/eax: int <- copy 0 var cursor-y/ecx: int <- copy 0 cursor-x, cursor-y <- cursor-position screen compare cursor-x, limit { break-if-< return } cursor-x <- increment set-cursor-position screen, cursor-x, cursor-y } fn move-cursor-up screen: (addr screen) { var cursor-x/eax: int <- copy 0 var cursor-y/ecx: int <- copy 0 cursor-x, cursor-y <- cursor-position screen compare cursor-y, 0 { break-if-> return } cursor-y <- decrement set-cursor-position screen, cursor-x, cursor-y } fn move-cursor-down screen: (addr screen) { var dummy/eax: int <- copy 0 var _height/ecx: int <- copy 0 dummy, _height <- screen-size screen var limit/edx: int <- copy _height limit <- decrement var cursor-x/eax: int <- copy 0 var cursor-y/ecx: int <- copy 0 cursor-x, cursor-y <- cursor-position screen compare cursor-y, limit { break-if-< return } cursor-y <- increment set-cursor-position screen, cursor-x, cursor-y } fn move-cursor-to-left-margin-of-next-line screen: (addr screen) { var dummy/eax: int <- copy 0 var _height/ecx: int <- copy 0 dummy, _height <- screen-size screen var limit/edx: int <- copy _height limit <- decrement var cursor-x/eax: int <- copy 0 var cursor-y/ecx: int <- copy 0 cursor-x, cursor-y <- cursor-position screen compare cursor-y, limit { break-if-< return } cursor-y <- increment cursor-x <- copy 0 set-cursor-position screen, cursor-x, cursor-y } fn draw-grapheme-at-cursor screen: (addr screen), g: grapheme, color: int, background-color: int { var cursor-x/eax: int <- copy 0 var cursor-y/ecx: int <- copy 0 cursor-x, cursor-y <- cursor-position screen draw-grapheme screen, g, cursor-x, cursor-y, color, background-color } # we can't really render non-ASCII yet, but when we do we'll be ready fn draw-code-point-at-cursor screen: (addr screen), c: code-point, color: int, background-color: int { var g/eax: grapheme <- copy c draw-grapheme-at-cursor screen, g, color, background-color } # draw a single line of text from x, y to xmax # return the next 'x' coordinate # if there isn't enough space, truncate fn draw-text-rightward screen: (addr screen), text: (addr array byte), x: int, xmax: int, y: int, color: int, background-color: int -> _/eax: int { var stream-storage: (stream byte 0x200/print-buffer-size) var stream/esi: (addr stream byte) <- address stream-storage write stream, text var xcurr/eax: int <- draw-stream-rightward screen, stream, x, xmax, y, color, background-color return xcurr } # draw a single-line stream from x, y to xmax # return the next 'x' coordinate # if there isn't enough space, truncate fn draw-stream-rightward screen: (addr screen), stream: (addr stream byte), x: int, xmax: int, y: int, color: int, background-color: int -> _/eax: int { var xcurr/ecx: int <- copy x { var g/eax: grapheme <- read-grapheme stream compare g, 0xffffffff/end-of-file break-if-= draw-grapheme screen, g, xcurr, y, color, background-color xcurr <- increment loop } set-cursor-position screen, xcurr, y ret
parse/0: instruction: 1
parse/0: ingredient: {name: "0", value: 0, type: 0, properties: ["0": "literal"]}
parse/0: product: {name: "1", value: 0, type: 1, properties: ["1": "integer"]}
parse/0: label: {
parse/0: instruction: 29
parse/0: ingredient: {name: "+foo", value: 0, type: 0, properties: ["+foo": "offset"]}
parse/0: label: }
brace/0: 1000: push (open, 1)
brace/0: push (close, 3)
after-brace/0: recipe main
after-brace/0: copy ...
after-brace/0: jump +foo:offset