From 78357b8852626b510527f3b8d770a7dd8956fcc7 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Fri, 16 Jul 2021 08:38:43 -0700 Subject: . --- html/linux/apps/advent2020/1a.mu.html | 165 +++++++++++++++ html/linux/apps/advent2020/1b.mu.html | 181 ++++++++++++++++ html/linux/apps/advent2020/2a.mu.html | 159 ++++++++++++++ html/linux/apps/advent2020/2b.mu.html | 190 +++++++++++++++++ html/linux/apps/advent2020/3a.mu.html | 175 ++++++++++++++++ html/linux/apps/advent2020/3b.mu.html | 205 ++++++++++++++++++ html/linux/apps/advent2020/4a.mu.html | 142 +++++++++++++ html/linux/apps/advent2020/4b.mu.html | 381 ++++++++++++++++++++++++++++++++++ html/linux/apps/advent2020/5a.mu.html | 146 +++++++++++++ html/linux/apps/advent2020/5b.mu.html | 148 +++++++++++++ 10 files changed, 1892 insertions(+) create mode 100644 html/linux/apps/advent2020/1a.mu.html create mode 100644 html/linux/apps/advent2020/1b.mu.html create mode 100644 html/linux/apps/advent2020/2a.mu.html create mode 100644 html/linux/apps/advent2020/2b.mu.html create mode 100644 html/linux/apps/advent2020/3a.mu.html create mode 100644 html/linux/apps/advent2020/3b.mu.html create mode 100644 html/linux/apps/advent2020/4a.mu.html create mode 100644 html/linux/apps/advent2020/4b.mu.html create mode 100644 html/linux/apps/advent2020/5a.mu.html create mode 100644 html/linux/apps/advent2020/5b.mu.html (limited to 'html/linux/apps/advent2020') diff --git a/html/linux/apps/advent2020/1a.mu.html b/html/linux/apps/advent2020/1a.mu.html new file mode 100644 index 00000000..e75fe8fc --- /dev/null +++ b/html/linux/apps/advent2020/1a.mu.html @@ -0,0 +1,165 @@ + + + + +Mu - linux/apps/advent2020/1a.mu + + + + + + + + + + +https://github.com/akkartik/mu/blob/main/linux/apps/advent2020/1a.mu +
+ 1 # https://adventofcode.com/2020/day/1
+ 2 #
+ 3 # To run (on Linux):
+ 4 #   $ git clone https://github.com/akkartik/mu
+ 5 #   $ cd mu
+ 6 #   $ ./translate apps/advent2020/1a.mu
+ 7 #   $ ./a.elf < input
+ 8 #   found
+ 9 #   1353 667
+10 #   902451
+11 #
+12 # You'll need to register to download the 'input' file for yourself.
+13 
+14 fn main -> _/ebx: int {
+15   # data structure
+16   var numbers-storage: (array int 0x100)  # 256 ints
+17   var numbers/esi: (addr array int) <- address numbers-storage
+18   var numbers-index/ecx: int <- copy 0
+19   # phase 1: parse each line from stdin and add it to numbers
+20   {
+21     var line-storage: (stream byte 0x100)  # 256 bytes
+22     var line/edx: (addr stream byte) <- address line-storage
+23     {
+24 #?       print-string 0, "== iter\n"
+25       # read line from stdin
+26       clear-stream line
+27       read-line-from-real-keyboard line
+28       # if line is empty (not even a newline), quit
+29       var done?/eax: boolean <- stream-empty? line
+30       compare done?, 0/false
+31       break-if-!=
+32 #?       print-stream-to-real-screen line
+33       # convert line to int and append it to numbers
+34       var n/eax: int <- parse-decimal-int-from-stream line
+35 #?       print-int32-decimal 0, n
+36 #?       print-string 0, "\n"
+37       var dest/ebx: (addr int) <- index numbers, numbers-index
+38       copy-to *dest, n
+39       numbers-index <- increment
+40 #?       print-string 0, "== "
+41 #?       print-int32-decimal 0, numbers-index
+42 #?       print-string 0, "\n"
+43       loop
+44     }
+45   }
+46   # phase 2: for each number in the array, check if 2020-it is in the rest of
+47   # the array
+48   var i/eax: int <- copy 0
+49   {
+50     compare i, numbers-index
+51     break-if->=
+52     var src/ebx: (addr int) <- index numbers, i
+53 #?     print-int32-decimal 0, *src
+54 #?     print-string 0, "\n"
+55     var target/ecx: int <- copy 0x7e4  # 2020
+56     target <- subtract *src
+57     {
+58       var found?/eax: boolean <- find-after numbers, i, target
+59       compare found?, 0/false
+60       break-if-=
+61       print-string 0, "found\n"
+62       print-int32-decimal 0, *src
+63       print-string 0, " "
+64       print-int32-decimal 0, target
+65       print-string 0, "\n"
+66       target <- multiply *src
+67       print-int32-decimal 0, target
+68       print-string 0, "\n"
+69       return 0/success
+70     }
+71     i <- increment
+72     loop
+73   }
+74   return 1/not-found
+75 }
+76 
+77 fn find-after _numbers: (addr array int), start: int, _target: int -> _/eax: boolean {
+78   var numbers/esi: (addr array int) <- copy _numbers
+79   var target/edi: int <- copy _target
+80   var len/ecx: int <- length numbers
+81   var i/eax: int <- copy start
+82   i <- increment
+83   {
+84     compare i, len
+85     break-if->=
+86     var src/edx: (addr int) <- index numbers, i
+87     # if *src == target, return true
+88     compare *src, target
+89     {
+90       break-if-!=
+91       return 1/true
+92     }
+93     i <- increment
+94     loop
+95   }
+96   return 0/false
+97 }
+
+ + + diff --git a/html/linux/apps/advent2020/1b.mu.html b/html/linux/apps/advent2020/1b.mu.html new file mode 100644 index 00000000..4346642b --- /dev/null +++ b/html/linux/apps/advent2020/1b.mu.html @@ -0,0 +1,181 @@ + + + + +Mu - linux/apps/advent2020/1b.mu + + + + + + + + + + +https://github.com/akkartik/mu/blob/main/linux/apps/advent2020/1b.mu +
+  1 # https://adventofcode.com/2020/day/1
+  2 #
+  3 # To run (on Linux):
+  4 #   $ git clone https://github.com/akkartik/mu
+  5 #   $ cd mu
+  6 #   $ ./translate apps/advent2020/1b.mu
+  7 #   $ ./a.elf < input
+  8 #   found
+  9 #   143 407 1470
+ 10 #   85555470
+ 11 #
+ 12 # You'll need to register to download the 'input' file for yourself.
+ 13 
+ 14 fn main -> _/ebx: int {
+ 15   # data structure
+ 16   var numbers-storage: (array int 0x100)  # 256 ints
+ 17   var numbers/esi: (addr array int) <- address numbers-storage
+ 18   var numbers-index/ecx: int <- copy 0
+ 19   # phase 1: parse each line from stdin and add it to numbers
+ 20   {
+ 21     var line-storage: (stream byte 0x100)  # 256 bytes
+ 22     var line/edx: (addr stream byte) <- address line-storage
+ 23     {
+ 24 #?       print-string 0, "== iter\n"
+ 25       # read line from stdin
+ 26       clear-stream line
+ 27       read-line-from-real-keyboard line
+ 28       # if line is empty (not even a newline), quit
+ 29       var done?/eax: boolean <- stream-empty? line
+ 30       compare done?, 0/false
+ 31       break-if-!=
+ 32 #?       print-stream-to-real-screen line
+ 33       # convert line to int and append it to numbers
+ 34       var n/eax: int <- parse-decimal-int-from-stream line
+ 35 #?       print-int32-decimal 0, n
+ 36 #?       print-string 0, "\n"
+ 37       var dest/ebx: (addr int) <- index numbers, numbers-index
+ 38       copy-to *dest, n
+ 39       numbers-index <- increment
+ 40 #?       print-string 0, "== "
+ 41 #?       print-int32-decimal 0, numbers-index
+ 42 #?       print-string 0, "\n"
+ 43       loop
+ 44     }
+ 45   }
+ 46   # phase 2: for every pair of distinct numbers, check if the rest of the
+ 47   # array has 2020-it
+ 48   var i/edi: int <- copy 0
+ 49   {
+ 50     compare i, numbers-index
+ 51     break-if->=
+ 52     # for j from i+1 to end
+ 53     var j/edx: int <- copy i
+ 54     j <- increment
+ 55     {
+ 56       compare j, numbers-index
+ 57       break-if->=
+ 58       {
+ 59         compare i, j
+ 60         break-if-=
+ 61         var target/ebx: int <- copy 0x7e4  # 2020
+ 62         var src/edi: (addr int) <- index numbers, i
+ 63         target <- subtract *src
+ 64         var src2/ecx: (addr int) <- index numbers, j
+ 65         target <- subtract *src2
+ 66         {
+ 67           var found?/eax: boolean <- find-after numbers, j, target
+ 68           compare found?, 0/false
+ 69           break-if-=
+ 70           print-string 0, "found\n"
+ 71           print-int32-decimal 0, *src
+ 72           print-string 0, " "
+ 73           print-int32-decimal 0, *src2
+ 74           print-string 0, " "
+ 75           print-int32-decimal 0, target
+ 76           print-string 0, "\n"
+ 77           target <- multiply *src
+ 78           target <- multiply *src2
+ 79           print-int32-decimal 0, target
+ 80           print-string 0, "\n"
+ 81           return 0/success
+ 82         }
+ 83       }
+ 84       j <- increment
+ 85       loop
+ 86     }
+ 87     i <- increment
+ 88     loop
+ 89   }
+ 90   return 1/not-found
+ 91 }
+ 92 
+ 93 fn find-after _numbers: (addr array int), start: int, _target: int -> _/eax: boolean {
+ 94   var numbers/esi: (addr array int) <- copy _numbers
+ 95   var target/edi: int <- copy _target
+ 96   var len/ecx: int <- length numbers
+ 97   var i/eax: int <- copy start
+ 98   i <- increment
+ 99   {
+100     compare i, len
+101     break-if->=
+102     var src/edx: (addr int) <- index numbers, i
+103     # if *src == target, return true
+104     compare *src, target
+105     {
+106       break-if-!=
+107       return 1/true
+108     }
+109     i <- increment
+110     loop
+111   }
+112   return 0/false
+113 }
+
+ + + diff --git a/html/linux/apps/advent2020/2a.mu.html b/html/linux/apps/advent2020/2a.mu.html new file mode 100644 index 00000000..2e6e3488 --- /dev/null +++ b/html/linux/apps/advent2020/2a.mu.html @@ -0,0 +1,159 @@ + + + + +Mu - linux/apps/advent2020/2a.mu + + + + + + + + + + +https://github.com/akkartik/mu/blob/main/linux/apps/advent2020/2a.mu +
+ 1 # https://adventofcode.com/2020/day/2
+ 2 #
+ 3 # To run (on Linux):
+ 4 #   $ git clone https://github.com/akkartik/mu
+ 5 #   $ cd mu
+ 6 #   $ ./translate apps/advent2020/2a.mu
+ 7 #   $ ./a.elf < input
+ 8 #
+ 9 # You'll need to register to download the 'input' file for yourself.
+10 
+11 fn main -> _/ebx: int {
+12   var valid-password-count/edi: int <- copy 0
+13   var line-storage: (stream byte 0x100)  # 256 bytes
+14   var line/edx: (addr stream byte) <- address line-storage
+15   var slice-storage: slice
+16   var slice/ecx: (addr slice) <- address slice-storage
+17   {
+18     # read line from stdin
+19     clear-stream line
+20     read-line-from-real-keyboard line
+21     # if line is empty (not even a newline), quit
+22     var done?/eax: boolean <- stream-empty? line
+23     compare done?, 0/false
+24     break-if-!=
+25     print-stream-to-real-screen line
+26     # slice = next-token(line, '-')
+27     next-token line, 0x2d, slice
+28     # start = parse-int(slice)
+29     var _start/eax: int <- parse-decimal-int-from-slice slice
+30     var start/ebx: int <- copy _start
+31     var dash/eax: byte <- read-byte line  # skip '-'
+32     # slice = next-token(line, ' ')
+33     next-token line, 0x20, slice
+34     var _end/eax: int <- parse-decimal-int-from-slice slice
+35     var end/esi: int <- copy _end
+36     print-int32-decimal 0, start
+37     print-string 0, " "
+38     print-int32-decimal 0, end
+39     print-string 0, "\n"
+40     # letter = next non-space
+41     skip-chars-matching-whitespace line
+42     var letter/eax: byte <- read-byte line
+43     # skip some stuff
+44     {
+45       var colon/eax: byte <- read-byte line  # skip ':'
+46     }
+47     skip-chars-matching-whitespace line
+48     # now check the rest of the line
+49     var valid?/eax: boolean <- valid? start, end, letter, line
+50     compare valid?, 0/false
+51     {
+52       break-if-=
+53       print-string 0, "valid!\n"
+54       valid-password-count <- increment
+55     }
+56     loop
+57   }
+58   print-int32-decimal 0, valid-password-count
+59   print-string 0, "\n"
+60   return 0
+61 }
+62 
+63 fn valid? start: int, end: int, letter: byte, password: (addr stream byte) -> _/eax: boolean {
+64   var letter-count/edi: int <- copy 0
+65   # for every c in password
+66   #   if (c == letter)
+67   #     ++letter-count
+68   {
+69     var done?/eax: boolean <- stream-empty? password
+70     compare done?, 0/false
+71     break-if-!=
+72     var c/eax: byte <- read-byte password
+73     compare c, letter
+74     {
+75       break-if-!=
+76       letter-count <- increment
+77     }
+78     loop
+79   }
+80   # return (start <= letter-count <= end)
+81   compare letter-count, start
+82   {
+83     break-if->=
+84     return 0/false
+85   }
+86   compare letter-count, end
+87   {
+88     break-if-<=
+89     return 0/false
+90   }
+91   return 1/true
+92 }
+
+ + + diff --git a/html/linux/apps/advent2020/2b.mu.html b/html/linux/apps/advent2020/2b.mu.html new file mode 100644 index 00000000..604e06bb --- /dev/null +++ b/html/linux/apps/advent2020/2b.mu.html @@ -0,0 +1,190 @@ + + + + +Mu - linux/apps/advent2020/2b.mu + + + + + + + + + + +https://github.com/akkartik/mu/blob/main/linux/apps/advent2020/2b.mu +
+  1 # https://adventofcode.com/2020/day/2
+  2 #
+  3 # To run (on Linux):
+  4 #   $ git clone https://github.com/akkartik/mu
+  5 #   $ cd mu
+  6 #   $ ./translate apps/advent2020/2b.mu
+  7 #   $ ./a.elf < input
+  8 #
+  9 # You'll need to register to download the 'input' file for yourself.
+ 10 
+ 11 fn main -> _/ebx: int {
+ 12   var valid-password-count/edi: int <- copy 0
+ 13   var line-storage: (stream byte 0x100)  # 256 bytes
+ 14   var line/edx: (addr stream byte) <- address line-storage
+ 15   var slice-storage: slice
+ 16   var slice/ecx: (addr slice) <- address slice-storage
+ 17   {
+ 18     # read line from stdin
+ 19     clear-stream line
+ 20     read-line-from-real-keyboard line
+ 21     # if line is empty (not even a newline), quit
+ 22     var done?/eax: boolean <- stream-empty? line
+ 23     compare done?, 0/false
+ 24     break-if-!=
+ 25     print-stream-to-real-screen line
+ 26     # slice = next-token(line, '-')
+ 27     next-token line, 0x2d, slice
+ 28     # pos1 = parse-int(slice)
+ 29     var _pos1/eax: int <- parse-decimal-int-from-slice slice
+ 30     var pos1/ebx: int <- copy _pos1
+ 31     var dash/eax: byte <- read-byte line  # skip '-'
+ 32     # slice = next-token(line, ' ')
+ 33     next-token line, 0x20, slice
+ 34     var _pos2/eax: int <- parse-decimal-int-from-slice slice
+ 35     var pos2/esi: int <- copy _pos2
+ 36     print-int32-decimal 0, pos1
+ 37     print-string 0, " "
+ 38     print-int32-decimal 0, pos2
+ 39     print-string 0, "\n"
+ 40     compare pos1, pos2
+ 41     {
+ 42       break-if-<=
+ 43       print-string 0, "out of order!\n"
+ 44       return 1
+ 45     }
+ 46     # letter = next non-space
+ 47     skip-chars-matching-whitespace line
+ 48     var letter/eax: byte <- read-byte line
+ 49     # skip some stuff
+ 50     {
+ 51       var colon/eax: byte <- read-byte line  # skip ':'
+ 52     }
+ 53     skip-chars-matching-whitespace line
+ 54     # now check the rest of the line
+ 55     var valid?/eax: boolean <- valid? pos1, pos2, letter, line
+ 56     compare valid?, 0/false
+ 57     {
+ 58       break-if-=
+ 59       print-string 0, "valid!\n"
+ 60       valid-password-count <- increment
+ 61     }
+ 62     loop
+ 63   }
+ 64   print-int32-decimal 0, valid-password-count
+ 65   print-string 0, "\n"
+ 66   return 0
+ 67 }
+ 68 
+ 69 # ideally password would be a random-access array
+ 70 # we'll just track an index
+ 71 # one benefit: we can easily start at 1
+ 72 fn valid? pos1: int, pos2: int, letter: byte, password: (addr stream byte) -> _/eax: boolean {
+ 73   var i/esi: int <- copy 1
+ 74   var letter-count/edi: int <- copy 0
+ 75   # while password stream isn't empty
+ 76   #   c = read byte from password
+ 77   #   if (c == letter)
+ 78   #     if (i == pos1)
+ 79   #       ++letter-count
+ 80   #     if (i == pos2)
+ 81   #       ++letter-count
+ 82   #     ++i
+ 83   {
+ 84 #?     print-string 0, "  "
+ 85 #?     print-int32-decimal 0, i
+ 86 #?     print-string 0, "\n"
+ 87     var done?/eax: boolean <- stream-empty? password
+ 88     compare done?, 0/false
+ 89     break-if-!=
+ 90     var c/eax: byte <- read-byte password
+ 91 #?     {
+ 92 #?       var c2/eax: int <- copy c
+ 93 #?       print-int32-decimal 0, c2
+ 94 #?       print-string 0, "\n"
+ 95 #?     }
+ 96     compare c, letter
+ 97     {
+ 98       break-if-!=
+ 99       compare i, pos1
+100       {
+101         break-if-!=
+102         letter-count <- increment
+103 #?         print-string 0, "  hit\n"
+104       }
+105       compare i, pos2
+106       {
+107         break-if-!=
+108         letter-count <- increment
+109 #?         print-string 0, "  hit\n"
+110       }
+111     }
+112     i <- increment
+113     loop
+114   }
+115   # return (letter-count == 1)
+116   compare letter-count, 1
+117   {
+118     break-if-!=
+119     return 1/true
+120   }
+121   return 0/false
+122 }
+
+ + + diff --git a/html/linux/apps/advent2020/3a.mu.html b/html/linux/apps/advent2020/3a.mu.html new file mode 100644 index 00000000..09d7f160 --- /dev/null +++ b/html/linux/apps/advent2020/3a.mu.html @@ -0,0 +1,175 @@ + + + + +Mu - linux/apps/advent2020/3a.mu + + + + + + + + + + +https://github.com/akkartik/mu/blob/main/linux/apps/advent2020/3a.mu +
+  1 # https://adventofcode.com/2020/day/3
+  2 #
+  3 # To run (on Linux):
+  4 #   $ git clone https://github.com/akkartik/mu
+  5 #   $ cd mu
+  6 #   $ ./translate apps/advent2020/3a.mu
+  7 #   $ ./a.elf < input
+  8 #
+  9 # You'll need to register to download the 'input' file for yourself.
+ 10 
+ 11 fn main -> _/ebx: int {
+ 12   # represent trees in a 2D array of ints
+ 13   # wasteful since each tree is just one bit
+ 14   var trees-storage: (array int 0x2800)  # 10k ints
+ 15   var trees/esi: (addr array int) <- address trees-storage
+ 16   var trees-length/ecx: int <- copy 0
+ 17   var num-rows: int
+ 18   var width: int
+ 19   # phase 1: parse each row of trees from stdin
+ 20   {
+ 21     var line-storage: (stream byte 0x40)  # 64 bytes
+ 22     var line/edx: (addr stream byte) <- address line-storage
+ 23     {
+ 24       # read line from stdin
+ 25       clear-stream line
+ 26       read-line-from-real-keyboard line
+ 27       # if line is empty (not even a newline), quit
+ 28       var done?/eax: boolean <- stream-empty? line
+ 29       compare done?, 0/false
+ 30       break-if-!=
+ 31       # wastefully recompute width on every line
+ 32       # zero error-checking; we assume input lines are all equally long
+ 33       copy-to width, 0
+ 34       # turn each byte into a tree and append it
+ 35       $main:line-loop: {
+ 36         var done?/eax: boolean <- stream-empty? line
+ 37         compare done?, 0/false
+ 38         break-if-!=
+ 39 #?         print-int32-decimal 0, num-rows
+ 40 #?         print-string 0, " "
+ 41 #?         print-int32-decimal 0, width
+ 42 #?         print-string 0, "\n"
+ 43         var dest/ebx: (addr int) <- index trees, trees-length
+ 44         var c/eax: byte <- read-byte line
+ 45         # newline comes only at end of line
+ 46         compare c, 0xa/newline
+ 47         break-if-=
+ 48         # '#' = tree
+ 49         compare c, 0x23/hash
+ 50         {
+ 51           break-if-!=
+ 52           copy-to *dest, 1
+ 53         }
+ 54         # anything else = no tree
+ 55         {
+ 56           break-if-=
+ 57           copy-to *dest, 0
+ 58         }
+ 59         increment width
+ 60         trees-length <- increment
+ 61         loop
+ 62       }
+ 63       increment num-rows
+ 64       loop
+ 65     }
+ 66   }
+ 67   # phase 2: compute
+ 68   print-int32-decimal 0, num-rows
+ 69   print-string 0, "x"
+ 70   print-int32-decimal 0, width
+ 71   print-string 0, "\n"
+ 72   var row/ecx: int <- copy 0
+ 73   var col/edx: int <- copy 0
+ 74   var num-trees-hit/edi: int <- copy 0
+ 75   {
+ 76     compare row, num-rows
+ 77     break-if->=
+ 78     var curr/eax: int <- index2d trees, row, col, width
+ 79     compare curr, 0
+ 80     {
+ 81       break-if-=
+ 82       num-trees-hit <- increment
+ 83     }
+ 84     # right 3, down 1
+ 85     col <- add 3
+ 86     row <- add 1
+ 87     loop
+ 88   }
+ 89   print-int32-decimal 0, num-trees-hit
+ 90   print-string 0, "\n"
+ 91   return 0
+ 92 }
+ 93 
+ 94 fn index2d _arr: (addr array int), _row: int, _col: int, width: int -> _/eax: int {
+ 95   # handle repeating columns of trees
+ 96   var dummy/eax: int <- copy 0
+ 97   var col/edx: int <- copy 0
+ 98   dummy, col <- integer-divide _col, width
+ 99   # compute index
+100   var index/eax: int <- copy _row
+101   index <- multiply width
+102   index <- add col
+103   # look up array
+104   var arr/esi: (addr array int) <- copy _arr
+105   var src/eax: (addr int) <- index arr, index
+106   return *src
+107 }
+
+ + + diff --git a/html/linux/apps/advent2020/3b.mu.html b/html/linux/apps/advent2020/3b.mu.html new file mode 100644 index 00000000..ff64117f --- /dev/null +++ b/html/linux/apps/advent2020/3b.mu.html @@ -0,0 +1,205 @@ + + + + +Mu - linux/apps/advent2020/3b.mu + + + + + + + + + + +https://github.com/akkartik/mu/blob/main/linux/apps/advent2020/3b.mu +
+  1 # https://adventofcode.com/2020/day/3
+  2 #
+  3 # To run (on Linux):
+  4 #   $ git clone https://github.com/akkartik/mu
+  5 #   $ cd mu
+  6 #   $ ./translate apps/advent2020/3a.mu
+  7 #   $ ./a.elf < input
+  8 #
+  9 # You'll need to register to download the 'input' file for yourself.
+ 10 
+ 11 fn main -> _/ebx: int {
+ 12   # represent trees in a 2D array of ints
+ 13   # wasteful since each tree is just one bit
+ 14   var trees-storage: (array int 0x2800)  # 10k ints
+ 15   var trees/esi: (addr array int) <- address trees-storage
+ 16   var trees-length/ecx: int <- copy 0
+ 17   var num-rows: int
+ 18   var width: int
+ 19   # phase 1: parse each row of trees from stdin
+ 20   {
+ 21     var line-storage: (stream byte 0x40)  # 64 bytes
+ 22     var line/edx: (addr stream byte) <- address line-storage
+ 23     {
+ 24       # read line from stdin
+ 25       clear-stream line
+ 26       read-line-from-real-keyboard line
+ 27       # if line is empty (not even a newline), quit
+ 28       var done?/eax: boolean <- stream-empty? line
+ 29       compare done?, 0/false
+ 30       break-if-!=
+ 31       # wastefully recompute width on every line
+ 32       # zero error-checking; we assume input lines are all equally long
+ 33       copy-to width, 0
+ 34       # turn each byte into a tree and append it
+ 35       $main:line-loop: {
+ 36         var done?/eax: boolean <- stream-empty? line
+ 37         compare done?, 0/false
+ 38         break-if-!=
+ 39 #?         print-int32-decimal 0, num-rows
+ 40 #?         print-string 0, " "
+ 41 #?         print-int32-decimal 0, width
+ 42 #?         print-string 0, "\n"
+ 43         var dest/ebx: (addr int) <- index trees, trees-length
+ 44         var c/eax: byte <- read-byte line
+ 45         # newline comes only at end of line
+ 46         compare c, 0xa/newline
+ 47         break-if-=
+ 48         # '#' = tree
+ 49         compare c, 0x23/hash
+ 50         {
+ 51           break-if-!=
+ 52           copy-to *dest, 1
+ 53         }
+ 54         # anything else = no tree
+ 55         {
+ 56           break-if-=
+ 57           copy-to *dest, 0
+ 58         }
+ 59         increment width
+ 60         trees-length <- increment
+ 61         loop
+ 62       }
+ 63       increment num-rows
+ 64       loop
+ 65     }
+ 66   }
+ 67   # phase 2: compute
+ 68   var product/edi: int <- copy 1
+ 69   var result/eax: int <- num-trees-hit trees, width, num-rows, 1, 1
+ 70   print-int32-decimal 0, result
+ 71   print-string 0, " x "
+ 72   product <- multiply result
+ 73   var result/eax: int <- num-trees-hit trees, width, num-rows, 3, 1
+ 74   print-int32-decimal 0, result
+ 75   print-string 0, " x "
+ 76   product <- multiply result
+ 77   var result/eax: int <- num-trees-hit trees, width, num-rows, 5, 1
+ 78   print-int32-decimal 0, result
+ 79   print-string 0, " x "
+ 80   product <- multiply result
+ 81   var result/eax: int <- num-trees-hit trees, width, num-rows, 7, 1
+ 82   print-int32-decimal 0, result
+ 83   print-string 0, " x "
+ 84   product <- multiply result
+ 85   var result/eax: int <- num-trees-hit trees, width, num-rows, 1, 2
+ 86   print-int32-decimal 0, result
+ 87   print-string 0, " = "
+ 88   product <- multiply result
+ 89   print-int32-hex 0, product
+ 90   print-string 0, "\n"
+ 91   return 0
+ 92 }
+ 93 
+ 94 fn num-trees-hit trees: (addr array int), width: int, num-rows: int, right: int, down: int -> _/eax: int {
+ 95 #?   print-string 0, "== "
+ 96 #?   print-int32-decimal 0, right
+ 97 #?   print-string 0, " "
+ 98 #?   print-int32-decimal 0, down
+ 99 #?   print-string 0, "\n"
+100   var row/ecx: int <- copy 0
+101   var col/edx: int <- copy 0
+102   var num-trees-hit/edi: int <- copy 0
+103   {
+104     compare row, num-rows
+105     break-if->=
+106 #?     print-int32-decimal 0, col
+107 #?     print-string 0, "\n"
+108     var curr/eax: int <- index2d trees, row, col, width
+109     compare curr, 0
+110     {
+111       break-if-=
+112       num-trees-hit <- increment
+113     }
+114     col <- add right
+115     row <- add down
+116     loop
+117   }
+118   return num-trees-hit
+119 }
+120 
+121 fn index2d _arr: (addr array int), _row: int, _col: int, width: int -> _/eax: int {
+122   # handle repeating columns of trees
+123   var dummy/eax: int <- copy 0
+124   var col/edx: int <- copy 0
+125   dummy, col <- integer-divide _col, width
+126 #?   print-string 0, "  "
+127 #?   print-int32-decimal 0, col
+128 #?   print-string 0, "\n"
+129   # compute index
+130   var index/eax: int <- copy _row
+131   index <- multiply width
+132   index <- add col
+133   # look up array
+134   var arr/esi: (addr array int) <- copy _arr
+135   var src/eax: (addr int) <- index arr, index
+136   return *src
+137 }
+
+ + + diff --git a/html/linux/apps/advent2020/4a.mu.html b/html/linux/apps/advent2020/4a.mu.html new file mode 100644 index 00000000..6f477717 --- /dev/null +++ b/html/linux/apps/advent2020/4a.mu.html @@ -0,0 +1,142 @@ + + + + +Mu - linux/apps/advent2020/4a.mu + + + + + + + + + + +https://github.com/akkartik/mu/blob/main/linux/apps/advent2020/4a.mu +
+ 1 # https://adventofcode.com/2020/day/4
+ 2 #
+ 3 # To run (on Linux):
+ 4 #   $ git clone https://github.com/akkartik/mu
+ 5 #   $ cd mu
+ 6 #   $ ./translate apps/advent2020/4a.mu
+ 7 #   $ ./a.elf < input
+ 8 #
+ 9 # You'll need to register to download the 'input' file for yourself.
+10 
+11 fn main -> _/ebx: int {
+12   var curr-passport-field-count/esi: int <- copy 0
+13   var valid-passport-count/edi: int <- copy 0
+14   var line-storage: (stream byte 0x100)  # 256 bytes
+15   var line/ecx: (addr stream byte) <- address line-storage
+16   var slice-storage: slice
+17   var slice/edx: (addr slice) <- address slice-storage
+18   $main:line-loop: {
+19     # read line from stdin
+20     clear-stream line
+21     read-line-from-real-keyboard line
+22     # if line is empty (not even a newline), quit
+23     var done?/eax: boolean <- stream-empty? line
+24     compare done?, 0/false
+25     break-if-!=
+26     print-stream-to-real-screen line
+27     # if line has just a newline, process passport
+28     skip-chars-matching-whitespace line
+29     var new-passport?/eax: boolean <- stream-empty? line
+30     {
+31       compare new-passport?, 0/false
+32       break-if-=
+33       compare curr-passport-field-count, 7
+34       {
+35         break-if-!=
+36         valid-passport-count <- increment
+37         print-string 0, "=> "
+38         print-int32-decimal 0, valid-passport-count
+39         print-string 0, "\n"
+40       }
+41       curr-passport-field-count <- copy 0
+42       loop $main:line-loop
+43     }
+44     $main:word-loop: {
+45       next-word line, slice
+46       var done?/eax: boolean <- slice-empty? slice
+47       compare done?, 0/false
+48       break-if-!=
+49       print-string 0, "  "
+50       print-slice-to-real-screen slice
+51       # treat cid as optional
+52       var optional?/eax: boolean <- slice-starts-with? slice, "cid:"
+53       compare optional?, 0/false
+54       {
+55         break-if-!=
+56         # otherwise assume there are no invalid fields and no duplicate fields
+57         curr-passport-field-count <- increment
+58         print-string 0, " => "
+59         print-int32-decimal 0, curr-passport-field-count
+60       }
+61       print-string 0, "\n"
+62       loop
+63     }
+64     loop
+65   }
+66   # process final passport
+67   compare curr-passport-field-count, 7
+68   {
+69     break-if-!=
+70     valid-passport-count <- increment
+71   }
+72   print-int32-decimal 0, valid-passport-count
+73   print-string 0, "\n"
+74   return 0
+75 }
+
+ + + diff --git a/html/linux/apps/advent2020/4b.mu.html b/html/linux/apps/advent2020/4b.mu.html new file mode 100644 index 00000000..47538296 --- /dev/null +++ b/html/linux/apps/advent2020/4b.mu.html @@ -0,0 +1,381 @@ + + + + +Mu - linux/apps/advent2020/4b.mu + + + + + + + + + + +https://github.com/akkartik/mu/blob/main/linux/apps/advent2020/4b.mu +
+  1 # https://adventofcode.com/2020/day/4
+  2 #
+  3 # To run (on Linux):
+  4 #   $ git clone https://github.com/akkartik/mu
+  5 #   $ cd mu
+  6 #   $ ./translate apps/advent2020/4b.mu
+  7 #   $ ./a.elf < input
+  8 #
+  9 # You'll need to register to download the 'input' file for yourself.
+ 10 
+ 11 fn main -> _/ebx: int {
+ 12   var curr-passport-field-count/esi: int <- copy 0
+ 13   var valid-passport-count/edi: int <- copy 0
+ 14   var line-storage: (stream byte 0x100)  # 256 bytes
+ 15   var line/ecx: (addr stream byte) <- address line-storage
+ 16   var key-slice-storage: slice
+ 17   var key-slice/edx: (addr slice) <- address key-slice-storage
+ 18   var val-slice-storage: slice
+ 19   var val-slice/ebx: (addr slice) <- address val-slice-storage
+ 20   $main:line-loop: {
+ 21     # read line from stdin
+ 22     clear-stream line
+ 23     read-line-from-real-keyboard line
+ 24     # if line is empty (not even a newline), quit
+ 25     var done?/eax: boolean <- stream-empty? line
+ 26     compare done?, 0/false
+ 27     break-if-!=
+ 28     print-stream-to-real-screen line
+ 29     # if line has just a newline, process passport
+ 30     skip-chars-matching-whitespace line
+ 31     var new-passport?/eax: boolean <- stream-empty? line
+ 32     {
+ 33       compare new-passport?, 0/false
+ 34       break-if-=
+ 35       compare curr-passport-field-count, 7
+ 36       {
+ 37         break-if-!=
+ 38         valid-passport-count <- increment
+ 39         print-string 0, "=> "
+ 40         print-int32-decimal 0, valid-passport-count
+ 41         print-string 0, "\n"
+ 42       }
+ 43       curr-passport-field-count <- copy 0
+ 44       loop $main:line-loop
+ 45     }
+ 46     $main:word-loop: {
+ 47       skip-chars-matching-whitespace line
+ 48       var done?/eax: boolean <- stream-empty? line
+ 49       compare done?, 0/false
+ 50       break-if-!=
+ 51       next-token line, 0x3a, key-slice  # ':'
+ 52       var dummy/eax: byte <- read-byte line  # skip ':'
+ 53       next-raw-word line, val-slice
+ 54       print-slice-to-real-screen key-slice
+ 55       print-string 0, " : "
+ 56       print-slice-to-real-screen val-slice
+ 57       print-string 0, "\n"
+ 58       # treat cid as optional
+ 59       var cid?/eax: boolean <- slice-equal? key-slice, "cid"
+ 60       compare cid?, 0/false
+ 61       loop-if-!=
+ 62       # increment field count
+ 63       curr-passport-field-count <- increment
+ 64       # - validate fields one by one, setting curr-passport-field-count to impossibly high value to signal invalid
+ 65       # byr
+ 66       {
+ 67         var byr?/eax: boolean <- slice-equal? key-slice, "byr"
+ 68         compare byr?, 0/false
+ 69         break-if-=
+ 70         # 1920 <= byr <= 2002
+ 71         var byr/eax: int <- parse-decimal-int-from-slice val-slice
+ 72         compare byr, 0x780  # 1920
+ 73         {
+ 74           break-if->=
+ 75           print-string 0, "invalid\n"
+ 76           curr-passport-field-count <- copy 8
+ 77         }
+ 78         compare byr, 0x7d2  # 2002
+ 79         {
+ 80           break-if-<=
+ 81           print-string 0, "invalid\n"
+ 82           curr-passport-field-count <- copy 8
+ 83         }
+ 84       }
+ 85       # iyr
+ 86       {
+ 87         var iyr?/eax: boolean <- slice-equal? key-slice, "iyr"
+ 88         compare iyr?, 0/false
+ 89         break-if-=
+ 90         # 2010 <= iyr <= 2020
+ 91         var iyr/eax: int <- parse-decimal-int-from-slice val-slice
+ 92         compare iyr, 0x7da  # 2010
+ 93         {
+ 94           break-if->=
+ 95           print-string 0, "invalid\n"
+ 96           curr-passport-field-count <- copy 8
+ 97         }
+ 98         compare iyr, 0x7e4  # 2020
+ 99         {
+100           break-if-<=
+101           print-string 0, "invalid\n"
+102           curr-passport-field-count <- copy 8
+103         }
+104       }
+105       # eyr
+106       {
+107         var eyr?/eax: boolean <- slice-equal? key-slice, "eyr"
+108         compare eyr?, 0/false
+109         break-if-=
+110         # 2020 <= eyr <= 2030
+111         var eyr/eax: int <- parse-decimal-int-from-slice val-slice
+112         compare eyr, 0x7e4  # 2020
+113         {
+114           break-if->=
+115           print-string 0, "invalid\n"
+116           curr-passport-field-count <- copy 8
+117         }
+118         compare eyr, 0x7ee  # 2030
+119         {
+120           break-if-<=
+121           print-string 0, "invalid\n"
+122           curr-passport-field-count <- copy 8
+123         }
+124       }
+125       # hgt
+126       {
+127         var hgt?/eax: boolean <- slice-equal? key-slice, "hgt"
+128         compare hgt?, 0/false
+129         break-if-=
+130         # convert val
+131         var s: (handle array byte)
+132         var s2/eax: (addr handle array byte) <- address s
+133         _slice-to-string val-slice, s2
+134         var s3/eax: (addr array byte) <- lookup *s2
+135         var s4/ebx: (addr array byte) <- copy s3
+136         # check suffix
+137         var start/edx: int <- length s4
+138         start <- subtract 2  # luckily both 'in' and 'cm' have the same length
+139         {
+140           var suffix-h: (handle array byte)
+141           var suffix-ah/ecx: (addr handle array byte) <- address suffix-h
+142           substring s4, start, 2, suffix-ah
+143           var suffix/eax: (addr array byte) <- lookup *suffix-ah
+144           {
+145             var match?/eax: boolean <- string-equal? suffix, "in"
+146             compare match?, 0/false
+147             break-if-=
+148             # if suffix is "in", 59 <= val <= 96
+149             var num-h: (handle array byte)
+150             var num-ah/ecx: (addr handle array byte) <- address num-h
+151             substring s4, 0, start, num-ah
+152             var num/eax: (addr array byte) <- lookup *num-ah
+153             var val/eax: int <- parse-decimal-int num
+154             compare val, 0x3b  # 59
+155             {
+156               break-if->=
+157           print-string 0, "invalid\n"
+158               curr-passport-field-count <- copy 8
+159             }
+160             compare val, 0x60  # 96
+161             {
+162               break-if-<=
+163           print-string 0, "invalid\n"
+164               curr-passport-field-count <- copy 8
+165             }
+166             loop $main:word-loop
+167           }
+168           {
+169             var match?/eax: boolean <- string-equal? suffix, "cm"
+170             compare match?, 0/false
+171             break-if-=
+172             # if suffix is "cm", 150 <= val <= 193
+173             var num-h: (handle array byte)
+174             var num-ah/ecx: (addr handle array byte) <- address num-h
+175             substring s4, 0, start, num-ah
+176             var num/eax: (addr array byte) <- lookup *num-ah
+177             var val/eax: int <- parse-decimal-int num
+178             compare val, 0x96  # 150
+179             {
+180               break-if->=
+181           print-string 0, "invalid\n"
+182               curr-passport-field-count <- copy 8
+183             }
+184             compare val, 0xc1  # 193
+185             {
+186               break-if-<=
+187           print-string 0, "invalid\n"
+188               curr-passport-field-count <- copy 8
+189             }
+190             loop $main:word-loop
+191           }
+192           print-string 0, "invalid\n"
+193           curr-passport-field-count <- copy 8
+194           loop $main:word-loop
+195         }
+196       }
+197       # hcl
+198       {
+199         var hcl?/eax: boolean <- slice-equal? key-slice, "hcl"
+200         compare hcl?, 0/false
+201         break-if-=
+202         # convert val
+203         var s: (handle array byte)
+204         var s2/eax: (addr handle array byte) <- address s
+205         _slice-to-string val-slice, s2
+206         var s3/eax: (addr array byte) <- lookup *s2
+207         # check length
+208         var len/ebx: int <- length s3
+209         compare len, 7
+210         {
+211           break-if-=
+212           print-string 0, "invalid\n"
+213           curr-passport-field-count <- copy 8
+214           loop $main:word-loop
+215         }
+216         # check first byte
+217         {
+218           var c/eax: (addr byte) <- index s3, 0
+219           var c2/eax: byte <- copy-byte *c
+220           compare c2, 0x23/hash
+221           break-if-=
+222           print-string 0, "invalid2\n"
+223           curr-passport-field-count <- copy 8
+224           loop $main:word-loop
+225         }
+226         # check remaining bytes
+227         var i/ebx: int <- copy 1  # skip 0
+228         {
+229           compare i, 7
+230           break-if->=
+231           var c/eax: (addr byte) <- index s3, i
+232           {
+233             var c2/eax: byte <- copy-byte *c
+234             var valid?/eax: boolean <- hex-digit? c2
+235             compare valid?, 0
+236             loop-if-= $main:word-loop
+237           }
+238           i <- increment
+239           loop
+240         }
+241       }
+242       # ecl
+243       {
+244         var ecl?/eax: boolean <- slice-equal? key-slice, "ecl"
+245         compare ecl?, 0/false
+246         break-if-=
+247         var amb?/eax: boolean <- slice-equal? val-slice, "amb"
+248         compare amb?, 0/false
+249         loop-if-!= $main:word-loop
+250         var blu?/eax: boolean <- slice-equal? val-slice, "blu"
+251         compare blu?, 0/false
+252         loop-if-!= $main:word-loop
+253         var brn?/eax: boolean <- slice-equal? val-slice, "brn"
+254         compare brn?, 0/false
+255         loop-if-!= $main:word-loop
+256         var gry?/eax: boolean <- slice-equal? val-slice, "gry"
+257         compare gry?, 0/false
+258         loop-if-!= $main:word-loop
+259         var grn?/eax: boolean <- slice-equal? val-slice, "grn"
+260         compare grn?, 0/false
+261         loop-if-!= $main:word-loop
+262         var hzl?/eax: boolean <- slice-equal? val-slice, "hzl"
+263         compare hzl?, 0/false
+264         loop-if-!= $main:word-loop
+265         var oth?/eax: boolean <- slice-equal? val-slice, "oth"
+266         compare oth?, 0/false
+267         loop-if-!= $main:word-loop
+268         print-string 0, "invalid\n"
+269         curr-passport-field-count <- copy 8
+270       }
+271       # pid
+272       {
+273         var pid?/eax: boolean <- slice-equal? key-slice, "pid"
+274         compare pid?, 0/false
+275         break-if-=
+276         # convert val
+277         var s: (handle array byte)
+278         var s2/eax: (addr handle array byte) <- address s
+279         _slice-to-string val-slice, s2
+280         var s3/eax: (addr array byte) <- lookup *s2
+281         # check length
+282         var len/eax: int <- length s3
+283         compare len, 9
+284         {
+285           break-if-=
+286           print-string 0, "invalid\n"
+287           curr-passport-field-count <- copy 8
+288           loop $main:word-loop
+289         }
+290         # check valid decimal int
+291         # parse-decimal-int-from-slice currently returns 0 on invalid parse,
+292         # which isn't ideal but suffices for our purposes
+293         var val/eax: int <- parse-decimal-int-from-slice val-slice
+294         compare val, 0
+295         {
+296           break-if->
+297           print-string 0, "invalid\n"
+298           curr-passport-field-count <- copy 8
+299         }
+300       }
+301       loop
+302     }
+303     loop
+304   }
+305   # process final passport
+306   compare curr-passport-field-count, 7
+307   {
+308     break-if-!=
+309     valid-passport-count <- increment
+310   }
+311   print-int32-decimal 0, valid-passport-count
+312   print-string 0, "\n"
+313   return 0
+314 }
+
+ + + diff --git a/html/linux/apps/advent2020/5a.mu.html b/html/linux/apps/advent2020/5a.mu.html new file mode 100644 index 00000000..3c3b535d --- /dev/null +++ b/html/linux/apps/advent2020/5a.mu.html @@ -0,0 +1,146 @@ + + + + +Mu - linux/apps/advent2020/5a.mu + + + + + + + + + + +https://github.com/akkartik/mu/blob/main/linux/apps/advent2020/5a.mu +
+ 1 # https://adventofcode.com/2020/day/5
+ 2 #
+ 3 # To run (on Linux):
+ 4 #   $ git clone https://github.com/akkartik/mu
+ 5 #   $ cd mu
+ 6 #   $ ./translate apps/advent2020/5a.mu
+ 7 #   $ ./a.elf < input
+ 8 #
+ 9 # You'll need to register to download the 'input' file for yourself.
+10 
+11 fn main -> _/ebx: int {
+12   var line-storage: (stream byte 0x10)  # 16 bytes is enough
+13   var line/edx: (addr stream byte) <- address line-storage
+14   var max-seat-id/edi: int <- copy 0
+15   {
+16     # read line from stdin
+17     clear-stream line
+18     read-line-from-real-keyboard line
+19     print-stream-to-real-screen line
+20     # if line is empty (not even a newline), quit
+21     var done?/eax: boolean <- stream-empty? line
+22     compare done?, 0/false
+23     break-if-!=
+24     # process line
+25     var seat-id/eax: int <- convert-from-binary line
+26     compare seat-id, max-seat-id
+27     {
+28       break-if-<=
+29       max-seat-id <- copy seat-id
+30     }
+31     loop
+32   }
+33   print-int32-decimal 0, max-seat-id
+34   print-string 0, "\n"
+35   return 0
+36 }
+37 
+38 fn convert-from-binary in: (addr stream byte) -> _/eax: int {
+39   var result/edi: int <- copy 0
+40   var i/ecx: int <- copy 9  # loop counter and also exponent
+41   {
+42     compare i, 0
+43     break-if-<
+44     var c/eax: byte <- read-byte in
+45 #?     print-string 0, "char: "
+46 #?     {
+47 #?       var c2/eax: int <- copy c
+48 #?       print-int32-hex 0, c2
+49 #?     }
+50 #?     print-string 0, "\n"
+51     var bit/edx: int <- copy 0
+52     {
+53       compare c, 0x42/B
+54       break-if-!=
+55       bit <- copy 1
+56     }
+57     {
+58       compare c, 0x52/R
+59       break-if-!=
+60       bit <- copy 1
+61     }
+62 #?     print-string 0, "bit: "
+63 #?     print-int32-decimal 0, bit
+64 #?     print-string 0, "\n"
+65     var bit-value/eax: int <- repeated-shift-left bit, i
+66 #?     print-string 0, "bit value: "
+67 #?     print-int32-decimal 0, bit-value
+68 #?     print-string 0, "\n"
+69     result <- add bit-value
+70 #?     print-string 0, "result: "
+71 #?     print-int32-decimal 0, result
+72 #?     print-string 0, "\n"
+73     i <- decrement
+74     loop
+75   }
+76   print-int32-decimal 0, result
+77   print-string 0, "\n"
+78   return result
+79 }
+
+ + + diff --git a/html/linux/apps/advent2020/5b.mu.html b/html/linux/apps/advent2020/5b.mu.html new file mode 100644 index 00000000..b5e1892f --- /dev/null +++ b/html/linux/apps/advent2020/5b.mu.html @@ -0,0 +1,148 @@ + + + + +Mu - linux/apps/advent2020/5b.mu + + + + + + + + + + +https://github.com/akkartik/mu/blob/main/linux/apps/advent2020/5b.mu +
+ 1 # https://adventofcode.com/2020/day/5
+ 2 #
+ 3 # To run (on Linux):
+ 4 #   $ git clone https://github.com/akkartik/mu
+ 5 #   $ cd mu
+ 6 #   $ ./translate apps/advent2020/5b.mu
+ 7 #   $ ./a.elf < input
+ 8 #
+ 9 # You'll need to register to download the 'input' file for yourself.
+10 
+11 fn main -> _/ebx: int {
+12   var pass-storage: (array int 0x400)  # 1k ints
+13   var pass/esi: (addr array int) <- address pass-storage
+14   # phase 1: populate pass array
+15   var line-storage: (stream byte 0x10)  # 16 bytes is enough
+16   var line/edx: (addr stream byte) <- address line-storage
+17   {
+18     # read line from stdin
+19     clear-stream line
+20     read-line-from-real-keyboard line
+21     # if line is empty (not even a newline), quit
+22     var done?/eax: boolean <- stream-empty? line
+23     compare done?, 0/false
+24     break-if-!=
+25     # process line
+26     var seat-id/eax: int <- convert-from-binary line
+27     var dest/eax: (addr int) <- index pass, seat-id
+28     copy-to *dest, 1
+29     loop
+30   }
+31   # phase 2: skip empty seats
+32   var i/eax: int <- copy 0
+33   {
+34     compare i, 0x400
+35     break-if->=
+36     var src/ecx: (addr int) <- index pass, i
+37     compare *src, 0
+38     break-if-!=
+39     i <- increment
+40     loop
+41   }
+42   # phase 3: skip non-empty seats
+43   {
+44     compare i, 0x400
+45     break-if->=
+46     var src/ecx: (addr int) <- index pass, i
+47     compare *src, 0
+48     break-if-=
+49     i <- increment
+50     loop
+51   }
+52   print-int32-decimal 0, i
+53   print-string 0, "\n"
+54   return 0
+55 }
+56 
+57 fn convert-from-binary in: (addr stream byte) -> _/eax: int {
+58   var result/edi: int <- copy 0
+59   var i/ecx: int <- copy 9  # loop counter and also exponent
+60   {
+61     compare i, 0
+62     break-if-<
+63     var c/eax: byte <- read-byte in
+64     var bit/edx: int <- copy 0
+65     {
+66       compare c, 0x42/B
+67       break-if-!=
+68       bit <- copy 1
+69     }
+70     {
+71       compare c, 0x52/R
+72       break-if-!=
+73       bit <- copy 1
+74     }
+75     var bit-value/eax: int <- repeated-shift-left bit, i
+76     result <- add bit-value
+77     i <- decrement
+78     loop
+79   }
+80   return result
+81 }
+
+ + + -- cgit 1.4.1-2-gfad0