about summary refs log tree commit diff stats
path: root/nqueens.mu
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2017-12-05 01:15:10 -0800
committerKartik K. Agaram <vc@akkartik.com>2017-12-05 01:15:10 -0800
commitd51abbf123f2411624b8c849f72624f1c70c4224 (patch)
tree059e03aa80e74df2d2033870bc892e7d641c579a /nqueens.mu
parent26b4bdc8b3b1d1f2f4b4dae1e7d2b89c7e286b1b (diff)
downloadmu-d51abbf123f2411624b8c849f72624f1c70c4224.tar.gz
4139
Diffstat (limited to 'nqueens.mu')
0 files changed, 0 insertions, 0 deletions
ef='#n101'>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 cell {
  type: int
  # type 0: pair; the unit of lists, trees, DAGS or graphs
  left: (handle cell)
  right: (handle cell)
  # type 1: number
  number-data: float
  # type 2: symbol
  # type 3: stream
  text-data: (handle stream byte)
  # type 4: primitive function
  index-data: int
  # type 5: screen
  screen-data: (handle screen)
  # type 6: keyboard
  keyboard-data: (handle gap-buffer)
  # TODO: array, (associative) table
}

fn allocate-symbol _out: (addr handle cell) {
  var out/eax: (addr handle cell) <- copy _out
  allocate out
  var out-addr/eax: (addr cell) <- lookup *out
  var type/ecx: (addr int) <- get out-addr, type
  copy-to *type, 2/symbol
  var dest-ah/eax: (addr handle stream byte) <- get out-addr, text-data
  populate-stream dest-ah, 0x40/max-symbol-size
}

fn initialize-symbol _out: (addr handle cell), val: (addr array byte) {
  var out/eax: (addr handle cell) <- copy _out
  var out-addr/eax: (addr cell) <- lookup *out
  var dest-ah/eax: (addr handle stream byte) <- get out-addr, text-data
  var dest/eax: (addr stream byte) <- lookup *dest-ah
  write dest, val
}

fn new-symbol out: (addr handle cell), val: (addr array byte) {
  allocate-symbol out
  initialize-symbol out, val
}

fn allocate-stream _out: (addr handle cell) {
  var out/eax: (addr handle cell) <- copy _out
  allocate out
  var out-addr/eax: (addr cell) <- lookup *out
  var type/ecx: (addr int) <- get out-addr, type
  copy-to *type, 3/stream
  var dest-ah/eax: (addr handle stream byte) <- get out-addr, text-data
  populate-stream dest-ah, 0x40/max-stream-size
}

fn allocate-number _out: (addr handle cell) {
  var out/eax: (addr handle cell) <- copy _out
  allocate out
  var out-addr/eax: (addr cell) <- lookup *out
  var type/ecx: (addr int) <- get out-addr, type
  copy-to *type, 1/number
}

fn initialize-integer _out: (addr handle cell), n: int {
  var out/eax: (addr handle cell) <- copy _out
  var out-addr/eax: (addr cell) <- lookup *out
  var dest-addr/eax: (addr float) <- get out-addr, number-data
  var src/xmm0: float <- convert n
  copy-to *dest-addr, src
}

fn new-integer out: (addr handle cell), n: int {
  allocate-number out
  initialize-integer out, n
}

fn initialize-float _out: (addr handle cell), n: float {
  var out/eax: (addr handle cell) <- copy _out
  var out-addr/eax: (addr cell) <- lookup *out
  var dest-ah/eax: (addr float) <- get out-addr, number-data
  var src/xmm0: float <- copy n
  copy-to *dest-ah, src
}

fn new-float out: (addr handle cell), n: float {
  allocate-number out
  initialize-float out, n
}

fn allocate-pair out: (addr handle cell) {
  allocate out
  # new cells have type pair by default
}

fn initialize-pair _out: (addr handle cell), left: (handle cell), right: (handle cell) {
  var out/eax: (addr handle cell) <- copy _out
  var out-addr/eax: (addr cell) <- lookup *out
  var dest-ah/ecx: (addr handle cell) <- get out-addr, left
  copy-handle left, dest-ah
  dest-ah <- get out-addr, right
  copy-handle right, dest-ah
}

fn new-pair out: (addr handle cell), left: (handle cell), right: (handle cell) {
  allocate-pair out
  initialize-pair out, left, right
}

fn nil out: (addr handle cell) {
  allocate-pair out
}

fn allocate-primitive-function _out: (addr handle cell) {
  var out/eax: (addr handle cell) <- copy _out
  allocate out
  var out-addr/eax: (addr cell) <- lookup *out
  var type/ecx: (addr int) <- get out-addr, type
  copy-to *type, 4/primitive-function
}

fn initialize-primitive-function _out: (addr handle cell), n: int {
  var out/eax: (addr handle cell) <- copy _out
  var out-addr/eax: (addr cell) <- lookup *out
  var dest-addr/eax: (addr int) <- get out-addr, index-data
  var src/ecx: int <- copy n
  copy-to *dest-addr, src
}

fn new-primitive-function out: (addr handle cell), n: int {
  allocate-primitive-function out
  initialize-primitive-function out, n
}

fn allocate-screen _out: (addr handle cell) {
  var out/eax: (addr handle cell) <- copy _out
  allocate out
  var out-addr/eax: (addr cell) <- lookup *out
  var type/ecx: (addr int) <- get out-addr, type
  copy-to *type, 5/screen
}

fn new-fake-screen _out: (addr handle cell), width: int, height: int {
  var out/eax: (addr handle cell) <- copy _out
  allocate-screen out
  var out-addr/eax: (addr cell) <- lookup *out
  var dest-ah/eax: (addr handle screen) <- get out-addr, screen-data
  allocate dest-ah
  var dest-addr/eax: (addr screen) <- lookup *dest-ah
  initialize-screen dest-addr, width, height
}

fn clear-screen-cell _self-ah: (addr handle cell) {
  var self-ah/eax: (addr handle cell) <- copy _self-ah
  var self/eax: (addr cell) <- lookup *self-ah
  compare self, 0
  {
    break-if-!=
    return
  }
  var screen-ah/eax: (addr handle screen) <- get self, screen-data
  var screen/eax: (addr screen) <- lookup *screen-ah
  clear-screen screen
}

fn allocate-keyboard _out: (addr handle cell) {
  var out/eax: (addr handle cell) <- copy _out
  allocate out
  var out-addr/eax: (addr cell) <- lookup *out
  var type/ecx: (addr int) <- get out-addr, type
  copy-to *type, 6/keyboard
}

fn new-fake-keyboard _out: (addr handle cell), capacity: int {
  var out/eax: (addr handle cell) <- copy _out
  allocate-keyboard out
  var out-addr/eax: (addr cell) <- lookup *out
  var dest-ah/eax: (addr handle gap-buffer) <- get out-addr, keyboard-data
  allocate dest-ah
  var dest-addr/eax: (addr gap-buffer) <- lookup *dest-ah
  initialize-gap-buffer dest-addr, capacity
}

fn rewind-keyboard-cell _self-ah: (addr handle cell) {
  var self-ah/eax: (addr handle cell) <- copy _self-ah
  var self/eax: (addr cell) <- lookup *self-ah
  compare self, 0
  {
    break-if-!=
    return
  }
  var keyboard-ah/eax: (addr handle gap-buffer) <- get self, keyboard-data
  var keyboard/eax: (addr gap-buffer) <- lookup *keyboard-ah
  rewind-gap-buffer keyboard
}
ass="w"> curr-ah loop } copy-object curr-ah, out # modify 'out' right at the end, just in case it's same as 'in' } fn first-grapheme _self: (addr word) -> _/eax: grapheme { var self/esi: (addr word) <- copy _self var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data var data/eax: (addr gap-buffer) <- lookup *data-ah var result/eax: grapheme <- first-grapheme-in-gap-buffer data return result } fn grapheme-before-cursor _self: (addr word) -> _/eax: grapheme { var self/esi: (addr word) <- copy _self var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data var data/eax: (addr gap-buffer) <- lookup *data-ah var result/eax: grapheme <- grapheme-before-cursor-in-gap-buffer data return result } fn add-grapheme-to-word _self: (addr word), c: grapheme { var self/esi: (addr word) <- copy _self var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data var data/eax: (addr gap-buffer) <- lookup *data-ah add-grapheme-at-gap data, c } fn cursor-at-start? _self: (addr word) -> _/eax: boolean { var self/esi: (addr word) <- copy _self var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data var data/eax: (addr gap-buffer) <- lookup *data-ah var result/eax: boolean <- gap-at-start? data return result } fn cursor-at-end? _self: (addr word) -> _/eax: boolean { var self/esi: (addr word) <- copy _self var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data var data/eax: (addr gap-buffer) <- lookup *data-ah var result/eax: boolean <- gap-at-end? data return result } fn cursor-left _self: (addr word) { var self/esi: (addr word) <- copy _self var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data var data/eax: (addr gap-buffer) <- lookup *data-ah var dummy/eax: grapheme <- gap-left data } fn cursor-right _self: (addr word) { var self/esi: (addr word) <- copy _self var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data var data/eax: (addr gap-buffer) <- lookup *data-ah var dummy/eax: grapheme <- gap-right data } fn cursor-to-start _self: (addr word) { var self/esi: (addr word) <- copy _self var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data var data/eax: (addr gap-buffer) <- lookup *data-ah gap-to-start data } fn cursor-to-end _self: (addr word) { var self/esi: (addr word) <- copy _self var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data var data/eax: (addr gap-buffer) <- lookup *data-ah gap-to-end data } fn cursor-index _self: (addr word) -> _/eax: int { var self/esi: (addr word) <- copy _self var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data var data/eax: (addr gap-buffer) <- lookup *data-ah var result/eax: int <- gap-index data return result } fn delete-before-cursor _self: (addr word) { var self/esi: (addr word) <- copy _self var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data var data/eax: (addr gap-buffer) <- lookup *data-ah delete-before-gap data } fn pop-after-cursor _self: (addr word) -> _/eax: grapheme { var self/esi: (addr word) <- copy _self var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data var data/eax: (addr gap-buffer) <- lookup *data-ah var result/eax: grapheme <- pop-after-gap data return result } fn delete-next _self: (addr word) { var self/esi: (addr word) <- copy _self var next-ah/edi: (addr handle word) <- get self, next var next/eax: (addr word) <- lookup *next-ah compare next, 0 break-if-= var next-next-ah/ecx: (addr handle word) <- get next, next var self-ah/esi: (addr handle word) <- get next, prev copy-object next-next-ah, next-ah var new-next/eax: (addr word) <- lookup *next-next-ah compare new-next, 0 break-if-= var dest/eax: (addr handle word) <- get new-next, prev copy-object self-ah, dest } fn print-word screen: (addr screen), _self: (addr word) { var self/esi: (addr word) <- copy _self var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data var data/eax: (addr gap-buffer) <- lookup *data-ah render-gap-buffer screen, data } fn print-words-in-reverse screen: (addr screen), _words-ah: (addr handle word) { var words-ah/eax: (addr handle word) <- copy _words-ah var words-a/eax: (addr word) <- lookup *words-ah compare words-a, 0 break-if-= # recurse var next-ah/ecx: (addr handle word) <- get words-a, next print-words-in-reverse screen, next-ah # print print-word screen, words-a print-string screen, " " } # Gotcha with some word operations: ensure dest-ah isn't in the middle of some # existing chain of words. There are two pointers to patch, and you'll forget # to do the other one. fn copy-words _src-ah: (addr handle word), _dest-ah: (addr handle word) { var src-ah/eax: (addr handle word) <- copy _src-ah var src-a/eax: (addr word) <- lookup *src-ah compare src-a, 0 break-if-= # copy var dest-ah/edi: (addr handle word) <- copy _dest-ah copy-word src-a, dest-ah # recurse var rest: (handle word) var rest-ah/ecx: (addr handle word) <- address rest var next-src-ah/esi: (addr handle word) <- get src-a, next copy-words next-src-ah, rest-ah chain-words dest-ah, rest-ah } fn copy-words-in-reverse _src-ah: (addr handle word), _dest-ah: (addr handle word) { var src-ah/eax: (addr handle word) <- copy _src-ah var _src-a/eax: (addr word) <- lookup *src-ah var src-a/esi: (addr word) <- copy _src-a compare src-a, 0 break-if-= # recurse var next-src-ah/ecx: (addr handle word) <- get src-a, next var dest-ah/edi: (addr handle word) <- copy _dest-ah copy-words-in-reverse next-src-ah, dest-ah # copy-word-at-end src-a, dest-ah } fn copy-word-at-end src: (addr word), _dest-ah: (addr handle word) { var dest-ah/edi: (addr handle word) <- copy _dest-ah # if dest is null, copy and return var dest-a/eax: (addr word) <- lookup *dest-ah compare dest-a, 0 { break-if-!= copy-word src, dest-ah return } # copy current word var new: (handle word) var new-ah/ecx: (addr handle word) <- address new copy-word src, new-ah # append it at the end var curr-ah/edi: (addr handle word) <- copy dest-ah { var curr-a/eax: (addr word) <- lookup *curr-ah # curr-a guaranteed not to be null var next-ah/ecx: (addr handle word) <- get curr-a, next var next-a/eax: (addr word) <- lookup *next-ah compare next-a, 0 break-if-= curr-ah <- copy next-ah loop } chain-words curr-ah, new-ah } fn append-word-at-end-with _dest-ah: (addr handle word), s: (addr array byte) { var dest-ah/edi: (addr handle word) <- copy _dest-ah # if dest is null, copy and return var dest-a/eax: (addr word) <- lookup *dest-ah compare dest-a, 0 { break-if-!= allocate-word-with dest-ah, s return } # otherwise append at end var curr-ah/edi: (addr handle word) <- copy dest-ah { var curr-a/eax: (addr word) <- lookup *curr-ah # curr-a guaranteed not to be null var next-ah/ecx: (addr handle word) <- get curr-a, next var next-a/eax: (addr word) <- lookup *next-ah compare next-a, 0 break-if-= curr-ah <- copy next-ah loop } append-word-with *curr-ah, s } fn copy-word _src-a: (addr word), _dest-ah: (addr handle word) { var dest-ah/eax: (addr handle word) <- copy _dest-ah allocate dest-ah var _dest-a/eax: (addr word) <- lookup *dest-ah var dest-a/eax: (addr word) <- copy _dest-a initialize-word dest-a var dest/edi: (addr handle gap-buffer) <- get dest-a, scalar-data var src-a/eax: (addr word) <- copy _src-a var src/eax: (addr handle gap-buffer) <- get src-a, scalar-data copy-gap-buffer src, dest } # one implication of handles: append must take a handle fn append-word _self-ah: (addr handle word) { var saved-self-storage: (handle word) var saved-self/eax: (addr handle word) <- address saved-self-storage copy-object _self-ah, saved-self #? { #? print-string 0, "self-ah is " #? var foo/eax: int <- copy _self-ah #? print-int32-hex 0, foo #? print-string 0, "\n" #? } var self-ah/esi: (addr handle word) <- copy _self-ah var _self/eax: (addr word) <- lookup *self-ah var self/ebx: (addr word) <- copy _self #? { #? print-string 0, "0: self is " #? var self-ah/eax: (addr handle word) <- copy _self-ah #? var self/eax: (addr word) <- lookup *self-ah #? var foo/eax: int <- copy self #? print-int32-hex 0, foo #? print-string 0, "\n" #? } # allocate new handle var new: (handle word) var new-ah/ecx: (addr handle word) <- address new allocate new-ah var new-addr/eax: (addr word) <- lookup new initialize-word new-addr #? { #? print-string 0, "new is " #? var foo/eax: int <- copy new-addr #? print-int32-hex 0, foo #? print-string 0, "\n" #? } # new->next = self->next var src/esi: (addr handle word) <- get self, next #? { #? print-string 0, "src is " #? var foo/eax: int <- copy src #? print-int32-hex 0, foo #? print-string 0, "\n" #? } var dest/edi: (addr handle word) <- get new-addr, next copy-object src, dest # new->next->prev = new { var next-addr/eax: (addr word) <- lookup *src compare next-addr, 0 break-if-= #? { #? print-string 0, "next-addr is " #? var foo/eax: int <- copy next-addr #? print-int32-hex 0, foo #? print-string 0, "\n" #? } dest <- get next-addr, prev #? #? { #? #? print-string 0, "self-ah is " #? #? var foo/eax: int <- copy _self-ah #? #? print-int32-hex 0, foo #? #? print-string 0, "\n" #? #? print-string 0, "2: self is " #? #? var self-ah/eax: (addr handle word) <- copy _self-ah #? #? var self/eax: (addr word) <- lookup *self-ah #? #? var foo/eax: int <- copy self #? #? print-int32-hex 0, foo #? #? print-string 0, "\n" #? #? } #? { #? print-string 0, "copying new to " #? var foo/eax: int <- copy dest #? print-int32-hex 0, foo #? print-string 0, "\n" #? } copy-object new-ah, dest #? { #? print-string 0, "4: self is " #? var self-ah/eax: (addr handle word) <- copy _self-ah #? var self/eax: (addr word) <- lookup *self-ah #? var foo/eax: int <- copy self #? print-int32-hex 0, foo #? print-string 0, "\n" #? } } # new->prev = saved-self dest <- get new-addr, prev #? { #? print-string 0, "copying " #? var self-ah/esi: (addr handle word) <- copy _self-ah #? var self/eax: (addr word) <- lookup *self-ah #? var foo/eax: int <- copy self #? print-int32-hex 0, foo #? print-string 0, " to " #? foo <- copy dest #? print-int32-hex 0, foo #? print-string 0, "\n" #? } var saved-self-ah/eax: (addr handle word) <- address saved-self-storage copy-object saved-self-ah, dest # self->next = new dest <- get self, next copy-object new-ah, dest } fn chain-words _self-ah: (addr handle word), _next: (addr handle word) { var self-ah/esi: (addr handle word) <- copy _self-ah var _self/eax: (addr word) <- lookup *self-ah var self/ecx: (addr word) <- copy _self var dest/edx: (addr handle word) <- get self, next var next-ah/edi: (addr handle word) <- copy _next copy-object next-ah, dest var next/eax: (addr word) <- lookup *next-ah compare next, 0 break-if-= dest <- get next, prev copy-object self-ah, dest } fn emit-word _self: (addr word), out: (addr stream byte) { var self/esi: (addr word) <- copy _self var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data var data/eax: (addr gap-buffer) <- lookup *data-ah emit-gap-buffer data, out } fn word-to-string _self: (addr word), out: (addr handle array byte) { var self/esi: (addr word) <- copy _self var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data var data/eax: (addr gap-buffer) <- lookup *data-ah gap-buffer-to-string data, out } fn word-is-decimal-integer? _self: (addr word) -> _/eax: boolean { var self/eax: (addr word) <- copy _self var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data var data/eax: (addr gap-buffer) <- lookup *data-ah var result/eax: boolean <- gap-buffer-is-decimal-integer? data return result } # ABSOLUTELY GHASTLY fn word-exists? _haystack-ah: (addr handle word), _needle: (addr word) -> _/ebx: boolean { var needle-name-storage: (handle array byte) var needle-name-ah/eax: (addr handle array byte) <- address needle-name-storage word-to-string _needle, needle-name-ah # profligate leak var _needle-name/eax: (addr array byte) <- lookup *needle-name-ah var needle-name/edi: (addr array byte) <- copy _needle-name # base case var haystack-ah/esi: (addr handle word) <- copy _haystack-ah var curr/eax: (addr word) <- lookup *haystack-ah compare curr, 0 { break-if-!= return 0/false } # check curr var curr-name-storage: (handle array byte) var curr-name-ah/ecx: (addr handle array byte) <- address curr-name-storage word-to-string curr, curr-name-ah # profligate leak var curr-name/eax: (addr array byte) <- lookup *curr-name-ah var found?/eax: boolean <- string-equal? needle-name, curr-name compare found?, 0 { break-if-= return 1/true } # recurse var curr/eax: (addr word) <- lookup *haystack-ah var next-haystack-ah/eax: (addr handle word) <- get curr, next var result/ebx: boolean <- word-exists? next-haystack-ah, _needle return result } fn word-list-length words: (addr handle word) -> _/eax: int { var curr-ah/esi: (addr handle word) <- copy words var result/edi: int <- copy 0 { var curr/eax: (addr word) <- lookup *curr-ah compare curr, 0 break-if-= { var word-len/eax: int <- word-length curr result <- add word-len result <- add 1/inter-word-margin } curr-ah <- get curr, next loop } return result } # out-ah already has a word allocated and initialized fn parse-words in: (addr array byte), out-ah: (addr handle word) { var in-stream: (stream byte 0x100) var in-stream-a/esi: (addr stream byte) <- address in-stream write in-stream-a, in var cursor-word-ah/ebx: (addr handle word) <- copy out-ah $parse-words:loop: { var done?/eax: boolean <- stream-empty? in-stream-a compare done?, 0/false break-if-!= var _g/eax: grapheme <- read-grapheme in-stream-a var g/ecx: grapheme <- copy _g # if not space, insert compare g, 0x20/space { break-if-= var cursor-word/eax: (addr word) <- lookup *cursor-word-ah add-grapheme-to-word cursor-word, g loop $parse-words:loop } # otherwise insert word after and move cursor to it append-word cursor-word-ah var cursor-word/eax: (addr word) <- lookup *cursor-word-ah cursor-to-start cursor-word # reset cursor in each function cursor-word-ah <- get cursor-word, next loop } }