about summary refs log tree commit diff stats
path: root/linux/tile/grapheme-stack.mu
blob: 0966be6c2708e9fd2a4ab9e1e9419d4f811cbb22 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
type grapheme-stack {
  data: (handle array code-point-utf8)
  top: int
}

fn initialize-grapheme-stack _self: (addr grapheme-stack), n: int {
  var self/esi: (addr grapheme-stack) <- copy _self
  var d/edi: (addr handle array code-point-utf8) <- get self, data
  populate d, n
  var top/eax: (addr int) <- get self, top
  copy-to *top, 0
}

fn clear-grapheme-stack _self: (addr grapheme-stack) {
  var self/esi: (addr grapheme-stack) <- copy _self
  var top/eax: (addr int) <- get self, top
  copy-to *top, 0
}

fn grapheme-stack-empty? _self: (addr grapheme-stack) -> _/eax: boolean {
  var self/esi: (addr grapheme-stack) <- copy _self
  var top/eax: (addr int) <- get self, top
  compare *top, 0
  {
    break-if-!=
    return 1/true
  }
  return 0/false
}

fn push-grapheme-stack _self: (addr grapheme-stack), _val: code-point-utf8 {
  var self/esi: (addr grapheme-stack) <- copy _self
  var top-addr/ecx: (addr int) <- get self, top
  var data-ah/edx: (addr handle array code-point-utf8) <- get self, data
  var data/eax: (addr array code-point-utf8) <- lookup *data-ah
  var top/edx: int <- copy *top-addr
  var dest-addr/edx: (addr code-point-utf8) <- index data, top
  var val/eax: code-point-utf8 <- copy _val
  copy-to *dest-addr, val
  add-to *top-addr, 1
}

fn pop-grapheme-stack _self: (addr grapheme-stack) -> _/eax: code-point-utf8 {
  var self/esi: (addr grapheme-stack) <- copy _self
  var top-addr/ecx: (addr int) <- get self, top
  {
    compare *top-addr, 0
    break-if->
    return -1
  }
  subtract-from *top-addr, 1
  var data-ah/edx: (addr handle array code-point-utf8) <- get self, data
  var data/eax: (addr array code-point-utf8) <- lookup *data-ah
  var top/edx: int <- copy *top-addr
  var result-addr/eax: (addr code-point-utf8) <- index data, top
  return *result-addr
}

fn copy-grapheme-stack _src: (addr grapheme-stack), dest: (addr grapheme-stack) {
  var src/esi: (addr grapheme-stack) <- copy _src
  var data-ah/edi: (addr handle array code-point-utf8) <- get src, data
  var _data/eax: (addr array code-point-utf8) <- lookup *data-ah
  var data/edi: (addr array code-point-utf8) <- copy _data
  var top-addr/ecx: (addr int) <- get src, top
  var i/eax: int <- copy 0
  {
    compare i, *top-addr
    break-if->=
    var g/edx: (addr code-point-utf8) <- index data, i
    push-grapheme-stack dest, *g
    i <- increment
    loop
  }
}

# dump stack to screen from bottom to top
# don't move the cursor or anything
fn render-stack-from-bottom _self: (addr grapheme-stack), screen: (addr screen) {
  var self/esi: (addr grapheme-stack) <- copy _self
  var data-ah/edi: (addr handle array code-point-utf8) <- get self, data
  var _data/eax: (addr array code-point-utf8) <- lookup *data-ah
  var data/edi: (addr array code-point-utf8) <- copy _data
  var top-addr/ecx: (addr int) <- get self, top
  var i/eax: int <- copy 0
  {
    compare i, *top-addr
    break-if->=
    var g/edx: (addr code-point-utf8) <- index data, i
    print-code-point-utf8 screen, *g
    i <- increment
    loop
  }
}

# dump stack to screen from top to bottom
# don't move the cursor or anything
fn render-stack-from-top _self: (addr grapheme-stack), screen: (addr screen) {
  var self/esi: (addr grapheme-stack) <- copy _self
  var data-ah/edi: (addr handle array code-point-utf8) <- get self, data
  var _data/eax: (addr array code-point-utf8) <- lookup *data-ah
  var data/edi: (addr array code-point-utf8) <- copy _data
  var top-addr/ecx: (addr int) <- get self, top
  var i/eax: int <- copy *top-addr
  i <- decrement
  {
    compare i, 0
    break-if-<
    var g/edx: (addr code-point-utf8) <- index data, i
    print-code-point-utf8 screen, *g
    i <- decrement
    loop
  }
}

# compare from bottom
# beware: modifies 'stream', which must be disposed of after a false result
fn prefix-match? _self: (addr grapheme-stack), s: (addr stream byte) -> _/eax: boolean {
  var self/esi: (addr grapheme-stack) <- copy _self
  var data-ah/edi: (addr handle array code-point-utf8) <- get self, data
  var _data/eax: (addr array code-point-utf8) <- lookup *data-ah
  var data/edi: (addr array code-point-utf8) <- copy _data
  var top-addr/ecx: (addr int) <- get self, top
  var i/ebx: int <- copy 0
  {
    compare i, *top-addr
    break-if->=
    # if curr != expected, return false
    {
      var curr-a/edx: (addr code-point-utf8) <- index data, i
      var expected/eax: code-point-utf8 <- read-code-point-utf8 s
      {
        compare expected, *curr-a
        break-if-=
        return 0/false
      }
    }
    i <- increment
    loop
  }
  return 1   # true
}

# compare from bottom
# beware: modifies 'stream', which must be disposed of after a false result
fn suffix-match? _self: (addr grapheme-stack), s: (addr stream byte) -> _/eax: boolean {
  var self/esi: (addr grapheme-stack) <- copy _self
  var data-ah/edi: (addr handle array code-point-utf8) <- get self, data
  var _data/eax: (addr array code-point-utf8) <- lookup *data-ah
  var data/edi: (addr array code-point-utf8) <- copy _data
  var top-addr/eax: (addr int) <- get self, top
  var i/ebx: int <- copy *top-addr
  i <- decrement
  {
    compare i, 0
    break-if-<
    {
      var curr-a/edx: (addr code-point-utf8) <- index data, i
      var expected/eax: code-point-utf8 <- read-code-point-utf8 s
      # if curr != expected, return false
      {
        compare expected, *curr-a
        break-if-=
        return 0/false
      }
    }
    i <- decrement
    loop
  }
  return 1   # true
}

fn grapheme-stack-is-decimal-integer? _self: (addr grapheme-stack) -> _/eax: boolean {
  var self/esi: (addr grapheme-stack) <- copy _self
  var data-ah/eax: (addr handle array code-point-utf8) <- get self, data
  var _data/eax: (addr array code-point-utf8) <- lookup *data-ah
  var data/edx: (addr array code-point-utf8) <- copy _data
  var top-addr/ecx: (addr int) <- get self, top
  var i/ebx: int <- copy 0
  var result/eax: boolean <- copy 1/true
  $grapheme-stack-is-integer?:loop: {
    compare i, *top-addr
    break-if->=
    var g/edx: (addr code-point-utf8) <- index data, i
    result <- decimal-digit? *g
    compare result, 0/false
    break-if-=
    i <- increment
    loop
  }
  return result
}