summary refs log blame commit diff stats
path: root/style.css
blob: 696f51b763a99751d09477848b5222a1c75d0fe5 (plain) (tree)
































































                                                                
      

                                          
 










                                  
 
      



                                  
                                                 



                                                     
 

































                                                            



                                             
                                  











































                                                                                                                                
                                     





































                                                     













                                























































                                                             
            





















                                                                           


                




                          



                      
                                             








                     
             


                           
    

                             

 
 
 

                  
 

                                

 






                                       
 
 


                     
/* Taken from https://tug.org/~mseven/style.css */

:root {
  --color-light:hsl(32, 98%, 92%);
  --color-light-semi:hsl(32, 35%, 65%);
  --color-light-faded:hsl(32, 20%, 40%);
  --color-dark:hsl(32, 80%, 8%);
  --color-dark-semi:hsl(32, 35%, 28%);
  --color-dark-faded:hsl(32, 20%, 60%);
  --color-blue:hsl(213, 90%, 33%);
  --color-purple:hsl(280, 90%, 37%);
  --color-light-blue:hsl(213, 85%, 75%);
  --color-light-purple:hsl(280, 84%, 75%);
  --heading-ratio:0.7071067811865476;
  --heading-base:2.5rem;
  --linespread:1.3;
  --margin-big:1rem;
  --margin-small:0.5rem;
  --base-font-size:1.125rem;
  --page-margin:15px;
  --max-page-width:55rem;
  --margin-width:calc((100vw  - var(--max-page-width)) / 2)
}
@media (max-width:55rem) {
  :root {
    --margin-width:var(--page-margin)
  }
}
:root {
  --color-background:var(--color-light);
  --color-text:var(--color-dark);
  --color-link:var(--color-blue);
  --color-link-followed:var(--color-purple);
  --color-faded:var(--color-dark-faded);
  --color-semi:var(--color-dark-semi)
}
@media (prefers-color-scheme:dark) {
  :root {
    --color-background:var(--color-dark);
    --color-text:var(--color-light);
    --color-link:var(--color-light-blue);
    --color-link-followed:var(--color-light-purple);
    --color-faded:var(--color-light-faded);
    --color-semi:var(--color-light-semi)
  }
  img.dark,
  svg {
    filter:invert(1) hue-rotate(180deg) saturate(140%)!important
  }
}
*,
::after,
::before {
  box-sizing:border-box;
  text-rendering:optimizeLegibility
}
[hidden] {
  display:none!important
}
[hidden][aria-hidden=false] {
  position:absolute;
  display:initial!important;
  clip:rect(0,0,0,0);
  clip-path:inset(100%)
}
html {
  color:var(--color-text);
  background-color:var(--color-background)
}
a:link,
a:visited {
  color:var(--color-link);
  text-decoration:none
}
a:visited {
  color:var(--color-link-followed)
}
a:hover,
code .token.url {
  text-decoration:underline
}
body {
  display:grid;
  justify-items:center;
  margin:var(--page-margin);
  font-size:var(--base-font-size);
  font-family:ui-sans-serif,system-ui,sans-serif;
  line-height:var(--linespread);
  hyphens:auto;
  font-variant-ligatures:common-ligatures contextual;
  font-kerning:normal
}
body * {
  min-width:0
}
:focus-visible {
  border-radius:4px;
  outline:2px solid var(--color-text);
  outline-offset:2px
}
::selection {
  background-color:var(--color-faded)
}
:root,
pre {
  scrollbar-width:thin;
  scrollbar-color:var(--color-faded) var(--color-background)
}
:is(:root,
pre)::-webkit-scrollbar {
  width:8px;
  height:8px
}
:is(:root,
pre)::-webkit-scrollbar-track {
  background:var(--color-background)
}
:is(:root,
pre)::-webkit-scrollbar-thumb {
  background-color:var(--color-faded)
}
h1 {
  text-align:center;
  margin-bottom:0;
  margin-top:1rem;
  font-size:max(var(--heading-base),var(--base-font-size));
}
header {
  padding-bottom:0.28rem;
  border-bottom:1px solid var(--color-faded);
  margin-bottom:var(--margin-big);
}
h2 {
  font-size:max(calc(var(--heading-base)*var(--heading-ratio)),var(--base-font-size))
}
h2,
h3,
h4,
h5 {
  margin-top:var(--margin-big);
  margin-bottom:var(--margin-small)
}
h1,
h2,
h3 {
  font-weight:700
}
h3 {
  font-size:max(calc(var(--heading-base)*var(--heading-ratio)*var(--heading-ratio)),var(--base-font-size))
}
h4,
h5 {
  font-weight:500
}
h4 {
  font-size:max(calc(var(--heading-base)*var(--heading-ratio)*var(--heading-ratio)*var(--heading-ratio)),var(--base-font-size));
  font-style:italic
}
h5 {
  font-size:calc(var(--base-font-size)*.9);
  color:var(--color-semi)
}
:is(h1,
h2,
h3,
h4,
h5)+* {
  margin-top:0
}
p {
  margin-top:var(--margin-small);
  margin-bottom:var(--margin-small);
  position:relative
}
code {
  font-family:ui-monospace,monospace;
  overflow-wrap:anywhere;
  hyphens:none
}
article,
body nav,
footer,
header,
section {
  display:block;
  width:100%;
  max-width:var(--max-page-width)
}
code.block {
  display:block;
  max-width:100%
}
footer {
  margin-top:1em;
  padding-top:0;
  border-top:1px solid var(--color-faded)
}
footer ul {
  display:flex;
  flex-wrap:wrap;
  justify-content:flex-end;
  margin:0;
  padding:0
}
footer ul li {
  display:inline;
  list-style-type:none
}
footer ul li:first-of-type {
  margin-right:auto
}
footer li:not(:last-child):not(:first-child)::after {
  content:" • "
}
nav ul {
  display:flex;
  flex-wrap:wrap;
  justify-content:center;
  margin:0;
  padding:0
}
nav ul li {
  display:inline;
  list-style-type:none
}
nav li:not(:last-child)::after {
  content:" • "
}
abbr {
  text-decoration:none;
  font-variant-caps:all-small-caps;
  font-variant-numeric:oldstyle-nums;
  font-size:1.075em
}
svg {
  width:100%;
  height:fit-content;
  max-height:90vh;
  padding:1rem;
  background-color:hsla(0,0%,100%,0%);
  filter:invert(0) hue-rotate(0deg) saturate(120%);
  transition:all 250ms ease-out
}
img.dark:hover,
svg:hover {
  background-color:hsla(0,0%,100%,100%);
  filter:invert(0) hue-rotate(0deg) saturate(100%)!important;
  transition:all 250ms ease-in
}
pre {
  max-width:calc(100vw - var(--page-margin)*2);
  overflow-x:auto;
  hyphens:none;
  margin:calc(2*var(--margin-small))0
}
pre.scroll {
  overflow-y:auto;
  max-height:90vh
}
th {
  text-align:right;
  font-weight:400
}
thead th {
  font-weight:700
}
td,
th {
  padding:0 1ch
}
dd {
  margin-bottom:var(--margin-small)
}
/*
li {
  margin-bottom:var(--margin-small)
}
*/
figure {
  display:flex;
  align-items:center;
  justify-content:center;
  flex-direction:column
}
figcaption {
  font-style:italic
}
@media (min-width:70em) {
  span.sidenote {
    float:left;
    font-size:80%;
    text-align:right;
    position:absolute;
    --sidenote-width:calc(var(--margin-width) - 1rem - var(--page-margin));
    width:var(--sidenote-width);
    left:calc(-1*var(--sidenote-width) - 1rem);
    top:0
  }
}
@media (max-width:70em) {
  span.sidenote {
    display:block;
    font-size:80%;
    margin-top:1em;
    margin-left:3em
  }
}
ul.inline {
  padding-left:0
}
ul.inline>li {
  display:inline;
  list-style-type:none
}
@media (min-width:55rem) {
  ul.inline>li {
    white-space:nowrap
  }
}
:is(ul.inline>li):not(:first-child)::before {
  content:" • "
}
dd>p {
  margin-top:0
}
dl.bold>dt,
summary {
  font-weight:500
}
/* header p {
  font-style:italic;
  position:absolute;
  right:var(--margin-width)
} */
summary {
  list-style-position:outside
}



slot:not([name]) {
  display: none;
}
:host([open]) slot:not([name]) {
  display: revert;
}

summary {
  display: list-item;
  counter-increment: list-item 0;
  list-style: disclosure-closed inside;
}
:host([open]) summary {
  list-style-type: disclosure-open;
}

nav {
  text-align: center;
}
background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
# Structured control flow using break/loop rather than jump.
#
# To run (on Linux):
#   $ ./translate_subx init.linux [012]*.subx apps/subx-params.subx apps/braces.subx
#   $ mv a.elf apps/braces
#
# Example 1:
#   $ cat x.subx
#   {
#     7c/jump-if-< break/disp8
#     74/jump-if-= loop/disp8
#   }
#   $ cat x.subx |apps/braces
#   _loop1:
#     7c/jump-if-< _break1/disp8
#     74/jump-if-= _loop1/disp8
#   _break1:
#
# Example 2:
#   $ cat x.subx
#   {
#     7c/jump-if-< break/disp8
#   }
#   {
#     74/jump-if-= loop/disp8
#   }
#   $ cat x.subx |apps/braces
#   _loop1:
#     7c/jump-if-< _break1/disp8
#   _break1:
#   _loop2:
#     74/jump-if-= _loop2/disp8
#   _break2:
#
# Example 3:
#   $ cat x.subx
#   {
#     {
#       74/jump-if-= loop/disp8
#     }
#     7c/jump-if-< loop/disp8
#   }
#   $ cat x.subx |apps/braces
#   _loop1:
#     _loop2:
#       74/jump-if-= _loop2/disp8
#     _break2:
#     7c/jump-if-< _loop1/disp8
#   _break1:

== code

Entry:  # run tests if necessary, a REPL if not
    # . prologue
    89/<- %ebp 4/r32/esp
    # initialize heap
    (new-segment *Heap-size Heap)
    # if (argc <= 1) goto interactive
    81 7/subop/compare *ebp 1/imm32
    7e/jump-if-<= $subx-braces-main:interactive/disp8
    # if (argv[1] != "test")) goto interactive
    (kernel-string-equal? *(ebp+8) "test")  # => eax
    3d/compare-eax-and 0/imm32/false
    74/jump-if-= $subx-braces-main:interactive/disp8
    #
    (run-tests)
    # syscall(exit, *Num-test-failures)
    8b/-> *Num-test-failures 3/r32/ebx
    eb/jump $subx-braces-main:end/disp8
$subx-braces-main:interactive:
    (subx-braces Stdin Stdout)
    # syscall(exit, 0)
    bb/copy-to-ebx 0/imm32
$subx-braces-main:end:
    e8/call syscall_exit/disp32

subx-braces:  # in: (addr buffered-file), out: (addr buffered-file)
    # pseudocode:
    #   var line: (stream byte 512)
    #   var label-stack: (stack int 32)  # at most 32 levels of nesting
    #   var next-label-id: int = 1
    #   while true
    #     clear-stream(line)
    #     read-line-buffered(in, line)
    #     if (line->write == 0) break                           # end of file
    #     skip-chars-matching-whitespace(line)
    #     if line->data[line->read] == '{'
    #       print(out, "_loop" next-label-id ":\n")
    #       push(label-stack, next-label-id)
    #       ++next-label-id
    #       continue
    #     if line->data[line->read] == '}'
    #       var top = pop(label-stack)
    #       print(out, "_break" top ":\n")
    #       continue
    #     while true
    #       var word-slice: (addr slice) = next-word-or-string(line)
    #       if slice-empty?(word-slice)                         # end of line
    #         break
    #       if slice-starts-with?(word-slice, "#")              # comment
    #         continue
    #       if slice-starts-with?(word-slice, "break/")
    #         var top = top(label-stack)
    #         print(out, "_break" top)
    #         word-slice->start += len("break")
    #       else if slice-starts-with?(word-slice, "loop/")
    #         var top = top(label-stack)
    #         print(out, "_loop" top)
    #         word-slice->start += len("loop")
    #       print(out, word-slice " ")
    #     print(out, "\n")
    #   flush(out)
    # . prologue
    55/push-ebp
    89/<- %ebp 4/r32/esp
    # . save registers
    50/push-eax
    51/push-ecx
    52/push-edx
    53/push-ebx
    56/push-esi
    57/push-edi
    # esi = in
    8b/-> *(ebp+8) 6/r32/esi
    # var line/ecx: (stream byte 512)
    81 5/subop/subtract %esp 0x200/imm32
    68/push 0x200/imm32/length
    68/push 0/imm32/read
    68/push 0/imm32/write
    89/<- %ecx 4/r32/esp
    # var label-stack/edx: (stack int 32)
    81 5/subop/subtract %esp 0x80/imm32
    68/push 0x80/imm32/length
    68/push 0/imm32/top
    89/<- %edx 4/r32/esp
    # var next-label-id/ebx: int = 1
    c7 0/subop/copy %ebx 1/imm32
    # var word-slice/edi: slice
    68/push 0/imm32/end
    68/push 0/imm32/start
    89/<- %edi 4/r32/esp
$subx-braces:line-loop:
    (clear-stream %ecx)
    (read-line-buffered %esi %ecx)
$subx-braces:check0:
    # if (line->write == 0) break
    81 7/subop/compare *ecx 0/imm32
    0f 84/jump-if-=  $subx-braces:break/disp32
    (skip-chars-matching-whitespace %ecx)
$subx-braces:check-for-curly-open:
    # if (line->data[line->read] != '{') goto next check
    # . eax = line->data[line->read]
    8b/-> *(ecx+4) 0/r32/eax
    8a/copy-byte *(ecx+eax+0xc) 0/r32/AL
    81 4/subop/and %eax 0xff/imm32
    # . if (eax != '{') continue
    3d/compare-eax-and 0x7b/imm32/open-curly
    0f 85/jump-if-!= $subx-braces:check-for-curly-closed/disp32
$subx-braces:emit-curly-open:
    # print(out, "_loop" next-label-id ":")
    (write-buffered *(ebp+0xc) "_loop")
    (write-int32-hex-buffered *(ebp+0xc) %ebx)
    (write-buffered *(ebp+0xc) ":")
    # push(label-stack, next-label-id)
    (push %edx %ebx)
    # ++next-label-id
    ff 0/subop/increment %ebx
    # continue
    e9/jump  $subx-braces:next-line/disp32
$subx-braces:check-for-curly-closed:
    # if (line->data[line->read] != '}') goto next check
    3d/compare-eax-and 0x7d/imm32/close-curly
    0f 85/jump-if-= $subx-braces:word-loop/disp32
$subx-braces:emit-curly-closed:
    # eax = pop(label-stack)
    (pop %edx)
    # print(out, "_break" eax ":")
    (write-buffered *(ebp+0xc) "_break")
    (write-int32-hex-buffered *(ebp+0xc) %eax)
    (write-buffered *(ebp+0xc) ":")
    # continue
    e9/jump  $subx-braces:next-line/disp32
$subx-braces:word-loop:
    (next-word-or-string %ecx %edi)
$subx-braces:check1:
    # if (slice-empty?(word-slice)) break
    (slice-empty? %edi)
    3d/compare-eax-and 0/imm32/false
    0f 85/jump-if-!= $subx-braces:next-line/disp32
$subx-braces:check-for-comment:
    # if (slice-starts-with?(word-slice, "#")) continue
    # . eax = *word-slice->start
    8b/-> *edi 0/r32/eax
    8a/copy-byte *eax 0/r32/AL
    81 4/subop/and %eax 0xff/imm32
    # . if (eax == '#') continue
    3d/compare-eax-and 0x23/imm32/hash
    74/jump-if-= $subx-braces:word-loop/disp8
$subx-braces:check-for-break:
    # if (!slice-starts-with?(word-slice, "break/")) goto next check
    # . eax = slice-starts-with?(word-slice, "break/")
    (slice-starts-with? %edi "break/")
    # . if (eax == false) goto next check
    3d/compare-eax-and 0/imm32/false
    74/jump-if-= $subx-braces:check-for-loop/disp8
$subx-braces:emit-break:
    (top %edx)
    # print(out, "_break" eax)
    (write-buffered *(ebp+0xc) "_break")
    (write-int32-hex-buffered *(ebp+0xc) %eax)
    # word-slice->start += len("break")
    81 0/subop/add *edi 5/imm32/strlen
    # emit rest of word as usual
    eb/jump $subx-braces:emit-word-slice/disp8
$subx-braces:check-for-loop:
    # if (!slice-starts-with?(word-slice, "loop/")) emit word
    # . eax = slice-starts-with?(word-slice, "loop/")
    (slice-starts-with? %edi "loop/")
    # . if (eax == false) goto next check
    3d/compare-eax-and 0/imm32/false
    74/jump-if-= $subx-braces:emit-word-slice/disp8
$subx-braces:emit-loop:
    (top %edx)
    # print(out, "_loop" eax)
    (write-buffered *(ebp+0xc) "_loop")
    (write-int32-hex-buffered *(ebp+0xc) %eax)
    # word-slice->start += len("loop")
    81 0/subop/add *edi 4/imm32/strlen
    # fall through
$subx-braces:emit-word-slice:
    # print(out, word-slice " ")
    (write-slice-buffered *(ebp+0xc) %edi)
    (write-buffered *(ebp+0xc) Space)
    # loop to next word
    e9/jump $subx-braces:word-loop/disp32
$subx-braces:next-line:
    # print(out, "\n")
    (write-buffered *(ebp+0xc) Newline)
    # loop to next line
    e9/jump $subx-braces:line-loop/disp32
$subx-braces:break:
    (flush *(ebp+0xc))
$subx-braces:end:
    # . reclaim locals
    81 0/subop/add %esp 0x29c/imm32
    # . restore registers
    5f/pop-to-edi
    5e/pop-to-esi
    5b/pop-to-ebx
    5a/pop-to-edx
    59/pop-to-ecx
    58/pop-to-eax
    # . epilogue
    89/<- %esp 5/r32/ebp
    5d/pop-to-ebp
    c3/return

test-subx-braces-passes-most-words-through:
    # . prologue
    55/push-ebp
    89/<- %ebp 4/r32/esp
    # setup
    (clear-stream _test-input-stream)
    (clear-stream _test-output-stream)
    (clear-stream $_test-input-buffered-file->buffer)
    (clear-stream $_test-output-buffered-file->buffer)
    # test
    (write _test-input-stream "== abcd 0x1")
    (subx-braces _test-input-buffered-file _test-output-buffered-file)
    # check that the line just passed through
    (flush _test-output-buffered-file)
#?     # dump _test-output-stream {{{
#?     (write 2 "^")
#?     (write-stream 2 _test-output-stream)
#?     (write 2 "$\n")
#?     # }}}
    (check-stream-equal _test-output-stream "== abcd 0x1 \n" "F - test-subx-braces-passes-most-words-through")
    # . epilogue
    89/<- %esp 5/r32/ebp
    5d/pop-to-ebp
    c3/return

test-subx-braces-1:
    # input:
    #   {
    #   ab break/imm32
    #   cd loop/imm32
    #   }
    #
    # output:
    #   _loop1:
    #   ab _break1/imm32
    #   cd _loop1/imm32
    #   _break1:
    #
    # . prologue
    55/push-ebp
    89/<- %ebp 4/r32/esp
    # setup
    (clear-stream _test-input-stream)
    (clear-stream _test-output-stream)
    (clear-stream $_test-input-buffered-file->buffer)
    (clear-stream $_test-output-buffered-file->buffer)
    # test
    (write _test-input-stream "{\nab break/imm32\ncd loop/imm32\n}")
    (subx-braces _test-input-buffered-file _test-output-buffered-file)
    # check that the line just passed through
    (flush _test-output-buffered-file)
#?     # dump _test-output-stream {{{
#?     (write 2 "^")
#?     (write-stream 2 _test-output-stream)
#?     (write 2 "$\n")
#?     # }}}
    (check-stream-equal _test-output-stream "_loop0x00000001:\nab _break0x00000001/imm32 \ncd _loop0x00000001/imm32 \n_break0x00000001:\n" "F - test-subx-braces-1")
    # . epilogue
    89/<- %esp 5/r32/ebp
    5d/pop-to-ebp
    c3/return

test-subx-braces-2:
    # input:
    #   {
    #   {
    #   ab break/imm32
    #   }
    #   cd loop/imm32
    #   }
    #
    # output:
    #   _loop1:
    #   _loop2:
    #   ab _break2/imm32
    #   _break2:
    #   cd _loop1/imm32
    #   _break1:
    #
    # . prologue
    55/push-ebp
    89/<- %ebp 4/r32/esp
    # setup
    (clear-stream _test-input-stream)
    (clear-stream _test-output-stream)
    (clear-stream $_test-input-buffered-file->buffer)
    (clear-stream $_test-output-buffered-file->buffer)
    # test
    (write _test-input-stream "{\n{\nab break/imm32\n}\ncd loop/imm32\n}")
    (subx-braces _test-input-buffered-file _test-output-buffered-file)
    # check that the line just passed through
    (flush _test-output-buffered-file)
#?     # dump _test-output-stream {{{
#?     (write 2 "^")
#?     (write-stream 2 _test-output-stream)
#?     (write 2 "$\n")
#?     # }}}
    (check-stream-equal _test-output-stream "_loop0x00000001:\n_loop0x00000002:\nab _break0x00000002/imm32 \n_break0x00000002:\ncd _loop0x00000001/imm32 \n_break0x00000001:\n" "F - test-subx-braces-2")
    # . epilogue
    89/<- %esp 5/r32/ebp
    5d/pop-to-ebp
    c3/return