@ -1,26 +1,26 @@
# grapheme stacks are the smallest unit of editable t e x t
# code-point-utf8 stacks are the smallest unit of editable t e x t
type grapheme -stack {
data: (handle array g r a p h e m e )
type code-point-utf8 -stack {
data: (handle array c o d e - p o i n t - u t f 8 )
top: i n t
}
fn initialize-grapheme-stack _self: (addr grapheme -stack), n: int {
var self/esi: (addr grapheme -stack) <- copy _ s e l f
var d/edi: (addr handle array grapheme ) <- get self, d a t a
fn initialize-code-point-utf8-stack _self: (addr code-point-utf8 -stack), n: int {
var self/esi: (addr code-point-utf8 -stack) <- copy _ s e l f
var d/edi: (addr handle array code-point-utf8 ) <- get self, d a t a
populate d, n
var top/eax: (addr int) <- get self, t o p
copy-to *top, 0
}
fn clear-grapheme-stack _self: (addr grapheme -stack) {
var self/esi: (addr grapheme -stack) <- copy _ s e l f
fn clear-code-point-utf8-stack _self: (addr code-point-utf8 -stack) {
var self/esi: (addr code-point-utf8 -stack) <- copy _ s e l f
var top/eax: (addr int) <- get self, t o p
copy-to *top, 0
}
fn grapheme-stack-empty? _self: (addr grapheme -stack) -> _/eax: boolean {
var self/esi: (addr grapheme -stack) <- copy _ s e l f
fn code-point-utf8-stack-empty? _self: (addr code-point-utf8 -stack) -> _/eax: boolean {
var self/esi: (addr code-point-utf8 -stack) <- copy _ s e l f
var top/eax: (addr int) <- get self, t o p
compare *top, 0
{
@ -30,26 +30,26 @@ fn grapheme-stack-empty? _self: (addr grapheme-stack) -> _/eax: boolean {
return 0 / f a l s e
}
fn grapheme-stack-length _self: (addr grapheme -stack) -> _/eax: int {
var self/esi: (addr grapheme -stack) <- copy _ s e l f
fn code-point-utf8-stack-length _self: (addr code-point-utf8 -stack) -> _/eax: int {
var self/esi: (addr code-point-utf8 -stack) <- copy _ s e l f
var top/eax: (addr int) <- get self, t o p
return * t o p
}
fn push-grapheme-stack _self: (addr grapheme-stack), _val: grapheme {
var self/esi: (addr grapheme -stack) <- copy _ s e l f
fn push-code-point-utf8-stack _self: (addr code-point-utf8-stack), _val: code-point-utf8 {
var self/esi: (addr code-point-utf8 -stack) <- copy _ s e l f
var top-addr/ecx: (addr int) <- get self, t o p
var data-ah/edx: (addr handle array grapheme ) <- get self, d a t a
var data/eax: (addr array grapheme ) <- lookup * d a t a - a h
var data-ah/edx: (addr handle array code-point-utf8 ) <- get self, d a t a
var data/eax: (addr array code-point-utf8 ) <- lookup * d a t a - a h
var top/edx: int <- copy * t o p - a d d r
var dest-addr/edx: (addr grapheme ) <- index data, t o p
var val/eax: grapheme <- copy _ v a l
var dest-addr/edx: (addr code-point-utf8 ) <- index data, t o p
var val/eax: code-point-utf8 <- copy _ v a l
copy-to *dest-addr, v a l
add-to *top-addr, 1
}
fn pop-grapheme-stack _self: (addr grapheme-stack) -> _/eax: grapheme {
var self/esi: (addr grapheme -stack) <- copy _ s e l f
fn pop-code-point-utf8-stack _self: (addr code-point-utf8-stack) -> _/eax: code-point-utf8 {
var self/esi: (addr code-point-utf8 -stack) <- copy _ s e l f
var top-addr/ecx: (addr int) <- get self, t o p
{
compare *top-addr, 0
@ -57,25 +57,25 @@ fn pop-grapheme-stack _self: (addr grapheme-stack) -> _/eax: grapheme {
return -1
}
subtract-from *top-addr, 1
var data-ah/edx: (addr handle array grapheme ) <- get self, d a t a
var data/eax: (addr array grapheme ) <- lookup * d a t a - a h
var data-ah/edx: (addr handle array code-point-utf8 ) <- get self, d a t a
var data/eax: (addr array code-point-utf8 ) <- lookup * d a t a - a h
var top/edx: int <- copy * t o p - a d d r
var result-addr/eax: (addr grapheme ) <- index data, t o p
var result-addr/eax: (addr code-point-utf8 ) <- index data, t o p
return * r e s u l t - a d d r
}
fn copy-grapheme-stack _src: (addr grapheme-stack), dest: (addr grapheme -stack) {
var src/esi: (addr grapheme -stack) <- copy _ s r c
var data-ah/edi: (addr handle array grapheme ) <- get src, d a t a
var _data/eax: (addr array grapheme ) <- lookup * d a t a - a h
var data/edi: (addr array grapheme ) <- copy _ d a t a
fn copy-code-point-utf8-stack _src: (addr code-point-utf8-stack), dest: (addr code-point-utf8 -stack) {
var src/esi: (addr code-point-utf8 -stack) <- copy _ s r c
var data-ah/edi: (addr handle array code-point-utf8 ) <- get src, d a t a
var _data/eax: (addr array code-point-utf8 ) <- lookup * d a t a - a h
var data/edi: (addr array code-point-utf8 ) <- copy _ d a t a
var top-addr/ecx: (addr int) <- get src, t o p
var i/eax: int <- copy 0
{
compare i, * t o p - a d d r
b r e a k - i f - > =
var g/edx: (addr grapheme ) <- index data, i
push-grapheme -stack dest, * g
var g/edx: (addr code-point-utf8 ) <- index data, i
push-code-point-utf8 -stack dest, * g
i <- i n c r e m e n t
l o o p
}
@ -84,12 +84,12 @@ fn copy-grapheme-stack _src: (addr grapheme-stack), dest: (addr grapheme-stack)
# dump stack to screen from bottom to t o p
# hardcoded c o l o r s :
# matching p a r e n
fn render-stack-from-bottom-wrapping-right-then-down screen: (addr screen), _self: (addr grapheme -stack), xmin: int, ymin: int, xmax: int, ymax: int, _x: int, _y: int, highlight-matching-open-paren?: boolean, open-paren-depth: int, color: int, background-color: int -> _/eax: int, _/ecx: int {
var self/esi: (addr grapheme -stack) <- copy _ s e l f
fn render-stack-from-bottom-wrapping-right-then-down screen: (addr screen), _self: (addr code-point-utf8 -stack), xmin: int, ymin: int, xmax: int, ymax: int, _x: int, _y: int, highlight-matching-open-paren?: boolean, open-paren-depth: int, color: int, background-color: int -> _/eax: int, _/ecx: int {
var self/esi: (addr code-point-utf8 -stack) <- copy _ s e l f
var matching-open-paren-index/edx: int <- get-matching-open-paren-index self, highlight-matching-open-paren?, o p e n - p a r e n - d e p t h
var data-ah/edi: (addr handle array grapheme ) <- get self, d a t a
var _data/eax: (addr array grapheme ) <- lookup * d a t a - a h
var data/edi: (addr array grapheme ) <- copy _ d a t a
var data-ah/edi: (addr handle array code-point-utf8 ) <- get self, d a t a
var _data/eax: (addr array code-point-utf8 ) <- lookup * d a t a - a h
var data/edi: (addr array code-point-utf8 ) <- copy _ d a t a
var x/eax: int <- copy _ x
var y/ecx: int <- copy _ y
var top-addr/esi: (addr int) <- get self, t o p
@ -100,7 +100,7 @@ fn render-stack-from-bottom-wrapping-right-then-down screen: (addr screen), _sel
{
var c: c o d e - p o i n t
{
var g/eax: (addr grapheme ) <- index data, i
var g/eax: (addr code-point-utf8 ) <- index data, i
var tmp/eax: code-point <- to-code-point * g
copy-to c, t m p
}
@ -123,7 +123,7 @@ fn render-stack-from-bottom-wrapping-right-then-down screen: (addr screen), _sel
}
# helper for small w o r d s
fn render-stack-from-bottom screen: (addr screen), self: (addr grapheme -stack), x: int, y: int, highlight-matching-open-paren?: boolean, open-paren-depth: int -> _/eax: int {
fn render-stack-from-bottom screen: (addr screen), self: (addr code-point-utf8 -stack), x: int, y: int, highlight-matching-open-paren?: boolean, open-paren-depth: int -> _/eax: int {
var _width/eax: int <- copy 0
var _height/ecx: int <- copy 0
_width, _height <- screen-size s c r e e n
@ -136,16 +136,16 @@ fn render-stack-from-bottom screen: (addr screen), self: (addr grapheme-stack),
}
# dump stack to screen from top to b o t t o m
# optionally render a 'cursor' with the top g r a p h e m e
# optionally render a 'cursor' with the top c o d e - p o i n t - u t f 8
# hard-coded c o l o r s :
# matching p a r e n
# c u r s o r
fn render-stack-from-top-wrapping-right-then-down screen: (addr screen), _self: (addr grapheme -stack), xmin: int, ymin: int, xmax: int, ymax: int, _x: int, _y: int, render-cursor?: boolean, color: int, background-color: int -> _/eax: int, _/ecx: int {
var self/esi: (addr grapheme -stack) <- copy _ s e l f
fn render-stack-from-top-wrapping-right-then-down screen: (addr screen), _self: (addr code-point-utf8 -stack), xmin: int, ymin: int, xmax: int, ymax: int, _x: int, _y: int, render-cursor?: boolean, color: int, background-color: int -> _/eax: int, _/ecx: int {
var self/esi: (addr code-point-utf8 -stack) <- copy _ s e l f
var matching-close-paren-index/edx: int <- get-matching-close-paren-index self, r e n d e r - c u r s o r ?
var data-ah/eax: (addr handle array grapheme ) <- get self, d a t a
var _data/eax: (addr array grapheme ) <- lookup * d a t a - a h
var data/edi: (addr array grapheme ) <- copy _ d a t a
var data-ah/eax: (addr handle array code-point-utf8 ) <- get self, d a t a
var _data/eax: (addr array code-point-utf8 ) <- lookup * d a t a - a h
var data/edi: (addr array code-point-utf8 ) <- copy _ d a t a
var x/eax: int <- copy _ x
var y/ecx: int <- copy _ y
var top-addr/ebx: (addr int) <- get self, t o p
@ -159,7 +159,7 @@ fn render-stack-from-top-wrapping-right-then-down screen: (addr screen), _self:
b r e a k - i f - <
var c: c o d e - p o i n t
{
var g/eax: (addr grapheme ) <- index data, i
var g/eax: (addr code-point-utf8 ) <- index data, i
var tmp/eax: code-point <- to-code-point * g
copy-to c, t m p
}
@ -184,7 +184,7 @@ fn render-stack-from-top-wrapping-right-then-down screen: (addr screen), _self:
#
var c: c o d e - p o i n t
{
var g/eax: (addr grapheme ) <- index data, i
var g/eax: (addr code-point-utf8 ) <- index data, i
var tmp/eax: code-point <- to-code-point * g
copy-to c, t m p
}
@ -196,7 +196,7 @@ fn render-stack-from-top-wrapping-right-then-down screen: (addr screen), _self:
}
# helper for small w o r d s
fn render-stack-from-top screen: (addr screen), self: (addr grapheme -stack), x: int, y: int, render-cursor?: boolean -> _/eax: int {
fn render-stack-from-top screen: (addr screen), self: (addr code-point-utf8 -stack), x: int, y: int, render-cursor?: boolean -> _/eax: int {
var _width/eax: int <- copy 0
var _height/ecx: int <- copy 0
_width, _height <- screen-size s c r e e n
@ -208,190 +208,190 @@ fn render-stack-from-top screen: (addr screen), self: (addr grapheme-stack), x:
return x2 # y2? y o l o
}
fn test-render-grapheme -stack {
fn test-render-code-point-utf8 -stack {
# setup: gs = " a b c "
var gs-storage: g r a p h e m e - s t a c k
var gs/edi: (addr grapheme -stack) <- address g s - s t o r a g e
initialize-grapheme -stack gs, 5
var g/eax: grapheme <- copy 0 x 61 / a
push-grapheme -stack gs, g
var gs-storage: c o d e - p o i n t - u t f 8 - s t a c k
var gs/edi: (addr code-point-utf8 -stack) <- address g s - s t o r a g e
initialize-code-point-utf8 -stack gs, 5
var g/eax: code-point-utf8 <- copy 0 x 61 / a
push-code-point-utf8 -stack gs, g
g <- copy 0 x 62 / b
push-grapheme -stack gs, g
push-code-point-utf8 -stack gs, g
g <- copy 0 x 63 / c
push-grapheme -stack gs, g
push-code-point-utf8 -stack gs, g
# setup: s c r e e n
var screen-storage: s c r e e n
var screen/esi: (addr screen) <- address s c r e e n - s t o r a g e
initialize-screen screen, 5 , 4 , 0 / n o - p i x e l - g r a p h i c s
#
var x/eax: int <- render-stack-from-bottom screen, gs, 0 /x, 0 /y, 0 /no-highlight-matching-open-paren, 0 / o p e n - p a r e n - d e p t h
check-screen-row screen, 0 /y, "abc ", "F - test-render-grapheme -stack from b o t t o m "
check-ints-equal x, 3 , "F - test-render-grapheme -stack from bottom: r e s u l t "
check-background-color-in-screen-row screen, 3 /bg=reverse, 0 /y, " ", "F - test-render-grapheme -stack from bottom: b g "
check-screen-row screen, 0 /y, "abc ", "F - test-render-code-point-utf8 -stack from b o t t o m "
check-ints-equal x, 3 , "F - test-render-code-point-utf8 -stack from bottom: r e s u l t "
check-background-color-in-screen-row screen, 3 /bg=reverse, 0 /y, " ", "F - test-render-code-point-utf8 -stack from bottom: b g "
#
var x/eax: int <- render-stack-from-top screen, gs, 0 /x, 1 /y, 0 / c u r s o r = f a l s e
check-screen-row screen, 1 /y, "cba ", "F - test-render-grapheme -stack from top without c u r s o r "
check-ints-equal x, 3 , "F - test-render-grapheme -stack from top without cursor: r e s u l t "
check-background-color-in-screen-row screen, 3 /bg=reverse, 1 /y, " ", "F - test-render-grapheme -stack from top without cursor: b g "
check-screen-row screen, 1 /y, "cba ", "F - test-render-code-point-utf8 -stack from top without c u r s o r "
check-ints-equal x, 3 , "F - test-render-code-point-utf8 -stack from top without cursor: r e s u l t "
check-background-color-in-screen-row screen, 3 /bg=reverse, 1 /y, " ", "F - test-render-code-point-utf8 -stack from top without cursor: b g "
#
var x/eax: int <- render-stack-from-top screen, gs, 0 /x, 2 /y, 1 / c u r s o r = t r u e
check-screen-row screen, 2 /y, "cba ", "F - test-render-grapheme -stack from top with c u r s o r "
check-ints-equal x, 3 , "F - test-render-grapheme -stack from top with cursor: r e s u l t "
check-background-color-in-screen-row screen, 3 /bg=reverse, 2 /y, "| ", "F - test-render-grapheme -stack from top with cursor: b g "
check-screen-row screen, 2 /y, "cba ", "F - test-render-code-point-utf8 -stack from top with c u r s o r "
check-ints-equal x, 3 , "F - test-render-code-point-utf8 -stack from top with cursor: r e s u l t "
check-background-color-in-screen-row screen, 3 /bg=reverse, 2 /y, "| ", "F - test-render-code-point-utf8 -stack from top with cursor: b g "
}
fn test-render-grapheme -stack-while-highlighting-matching-close-paren {
fn test-render-code-point-utf8 -stack-while-highlighting-matching-close-paren {
# setup: gs = " ( b ) "
var gs-storage: g r a p h e m e - s t a c k
var gs/edi: (addr grapheme -stack) <- address g s - s t o r a g e
initialize-grapheme -stack gs, 5
var g/eax: grapheme <- copy 0 x 29 / c l o s e - p a r e n
push-grapheme -stack gs, g
var gs-storage: c o d e - p o i n t - u t f 8 - s t a c k
var gs/edi: (addr code-point-utf8 -stack) <- address g s - s t o r a g e
initialize-code-point-utf8 -stack gs, 5
var g/eax: code-point-utf8 <- copy 0 x 29 / c l o s e - p a r e n
push-code-point-utf8 -stack gs, g
g <- copy 0 x 62 / b
push-grapheme -stack gs, g
push-code-point-utf8 -stack gs, g
g <- copy 0 x 28 / o p e n - p a r e n
push-grapheme -stack gs, g
push-code-point-utf8 -stack gs, g
# setup: s c r e e n
var screen-storage: s c r e e n
var screen/esi: (addr screen) <- address s c r e e n - s t o r a g e
initialize-screen screen, 5 , 4 , 0 / n o - p i x e l - g r a p h i c s
#
var x/eax: int <- render-stack-from-top screen, gs, 0 /x, 2 /y, 1 / c u r s o r = t r u e
check-screen-row screen, 2 /y, "(b) ", "F - t e s t - r e n d e r - g r a p h e m e - s t a c k - w h i l e - h i g h l i g h t i n g - m a t c h i n g - c l o s e - p a r e n "
check-background-color-in-screen-row screen, 3 /bg=reverse, 2 /y, "| ", "F - test-render-grapheme -stack-while-highlighting-matching-close-paren: c u r s o r "
check-screen-row-in-color screen, 0 xf/fg=white, 2 /y, " ) ", "F - test-render-grapheme -stack-while-highlighting-matching-close-paren: matching p a r e n "
check-screen-row screen, 2 /y, "(b) ", "F - t e s t - r e n d e r - c o d e - p o i n t - u t f 8 - s t a c k - w h i l e - h i g h l i g h t i n g - m a t c h i n g - c l o s e - p a r e n "
check-background-color-in-screen-row screen, 3 /bg=reverse, 2 /y, "| ", "F - test-render-code-point-utf8 -stack-while-highlighting-matching-close-paren: c u r s o r "
check-screen-row-in-color screen, 0 xf/fg=white, 2 /y, " ) ", "F - test-render-code-point-utf8 -stack-while-highlighting-matching-close-paren: matching p a r e n "
}
fn test-render-grapheme -stack-while-highlighting-matching-close-paren-2 {
fn test-render-code-point-utf8 -stack-while-highlighting-matching-close-paren-2 {
# setup: gs = "(a (b)) c "
var gs-storage: g r a p h e m e - s t a c k
var gs/edi: (addr grapheme -stack) <- address g s - s t o r a g e
initialize-grapheme -stack gs, 0 x 10
var g/eax: grapheme <- copy 0 x 63 / c
push-grapheme -stack gs, g
var gs-storage: c o d e - p o i n t - u t f 8 - s t a c k
var gs/edi: (addr code-point-utf8 -stack) <- address g s - s t o r a g e
initialize-code-point-utf8 -stack gs, 0 x 10
var g/eax: code-point-utf8 <- copy 0 x 63 / c
push-code-point-utf8 -stack gs, g
g <- copy 0 x 20 / s p a c e
push-grapheme -stack gs, g
push-code-point-utf8 -stack gs, g
g <- copy 0 x 29 / c l o s e - p a r e n
push-grapheme -stack gs, g
push-code-point-utf8 -stack gs, g
g <- copy 0 x 29 / c l o s e - p a r e n
push-grapheme -stack gs, g
push-code-point-utf8 -stack gs, g
g <- copy 0 x 62 / b
push-grapheme -stack gs, g
push-code-point-utf8 -stack gs, g
g <- copy 0 x 28 / o p e n - p a r e n
push-grapheme -stack gs, g
push-code-point-utf8 -stack gs, g
g <- copy 0 x 20 / s p a c e
push-grapheme -stack gs, g
push-code-point-utf8 -stack gs, g
g <- copy 0 x 61 / a
push-grapheme -stack gs, g
push-code-point-utf8 -stack gs, g
g <- copy 0 x 28 / o p e n - p a r e n
push-grapheme -stack gs, g
push-code-point-utf8 -stack gs, g
# setup: s c r e e n
var screen-storage: s c r e e n
var screen/esi: (addr screen) <- address s c r e e n - s t o r a g e
initialize-screen screen, 5 , 4 , 0 / n o - p i x e l - g r a p h i c s
#
var x/eax: int <- render-stack-from-top screen, gs, 0 /x, 2 /y, 1 / c u r s o r = t r u e
check-screen-row screen, 2 /y, "(a (b)) c ", "F - t e s t - r e n d e r - g r a p h e m e - s t a c k - w h i l e - h i g h l i g h t i n g - m a t c h i n g - c l o s e - p a r e n -2 "
check-background-color-in-screen-row screen, 3 /bg=reverse, 2 /y, "| ", "F - test-render-grapheme -stack-while-highlighting-matching-close-paren-2: c u r s o r "
check-screen-row-in-color screen, 0 xf/fg=white, 2 /y, " ) ", "F - test-render-grapheme -stack-while-highlighting-matching-close-paren-2: matching p a r e n "
check-screen-row screen, 2 /y, "(a (b)) c ", "F - t e s t - r e n d e r - c o d e - p o i n t - u t f 8 - s t a c k - w h i l e - h i g h l i g h t i n g - m a t c h i n g - c l o s e - p a r e n -2 "
check-background-color-in-screen-row screen, 3 /bg=reverse, 2 /y, "| ", "F - test-render-code-point-utf8 -stack-while-highlighting-matching-close-paren-2: c u r s o r "
check-screen-row-in-color screen, 0 xf/fg=white, 2 /y, " ) ", "F - test-render-code-point-utf8 -stack-while-highlighting-matching-close-paren-2: matching p a r e n "
}
fn test-render-grapheme -stack-while-highlighting-matching-open-paren-with-close-paren-at-end {
fn test-render-code-point-utf8 -stack-while-highlighting-matching-open-paren-with-close-paren-at-end {
# setup: gs = " ( b ) "
var gs-storage: g r a p h e m e - s t a c k
var gs/edi: (addr grapheme -stack) <- address g s -