https://github.com/akkartik/mu/blob/main/127next-word.subx
  1 # Tokenize by whitespace.
  2 
  3 == code
  4 #   instruction                     effective address                                                   register    displacement    immediate
  5 # . op          subop               mod             rm32          base        index         scale       r32
  6 # . 1-3 bytes   3 bits              2 bits          3 bits        3 bits      3 bits        2 bits      2 bits      0/1/2/4 bytes   0/1/2/4 bytes
  7 
  8 # (re)compute the bounds of the next word in the line (surrounded by whitespace,
  9 # treating '#' comments as a single word)
 10 # return empty string on reaching end of file
 11 next-word:  # line: (addr stream byte), out: (addr slice)
 12     # . prologue
 13     55/push-ebp
 14     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
 15     # . save registers
 16     50/push-eax
 17     51/push-ecx
 18     56/push-esi
 19     57/push-edi
 20     # esi = line
 21     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           6/r32/esi   8/disp8         .                 # copy *(ebp+8) to esi
 22     # edi = out
 23     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           7/r32/edi   0xc/disp8       .                 # copy *(ebp+12) to edi
 24     # skip-chars-matching-whitespace(line)
 25     # . . push args
 26     ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           8/disp8         .                 # push *(ebp+8)
 27     # . . call
 28     e8/call  skip-chars-matching-whitespace/disp32
 29     # . . discard args
 30     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
 31 $next-word:check0:
 32     # if (line->read >= line->write) clear out and return
 33     # . eax = line->read
 34     8b/copy                         1/mod/*+disp8   6/rm32/esi    .           .             .           0/r32/eax   4/disp8         .                 # copy *(esi+4) to eax
 35     # . if (eax < line->write) goto next check
 36     3b/compare                      0/mod/indirect  6/rm32/esi    .           .             .           0/r32/eax   .               .                 # compare eax with *esi
 37     7c/jump-if-<  $next-word:check-for-comment/disp8
 38     # . return out
 39     c7          0/subop/copy        0/mod/direct    7/rm32/edi    .           .             .           .           .               0/imm32           # copy to *edi
 40     c7          0/subop/copy        1/mod/*+disp8   7/rm32/edi    .           .             .           .           4/disp8         0/imm32           # copy to *(edi+4)
 41     e9/jump  $next-word:end/disp32
 42 $next-word:check-for-comment:
 43     # out->start = &line->data[line->read]
 44     8b/copy                         1/mod/*+disp8   6/rm32/esi    .           .             .           1/r32/ecx   4/disp8         .                 # copy *(esi+4) to ecx
 45     8d/copy-address                 1/mod/*+disp8   4/rm32/sib    6/base/esi  1/index/ecx   .           0/r32/eax   0xc/disp8       .                 # copy esi+ecx+12 to eax
 46     89/copy                         0/mod/indirect  7/rm32/edi    .           .             .           0/r32/eax   .               .                 # copy eax to *edi
 47     # if (line->data[line->read] == '#') return rest of line
 48     # . eax = line->data[line->read]
 49     31/xor                          3/mod/direct    0/rm32/eax    .           .             .           0/r32/eax   .               .                 # clear eax
 50     8a/copy-byte                    1/mod/*+disp8   4/rm32/sib    6/base/esi  1/index/ecx   .           0/r32/AL    0xc/disp8       .                 # copy byte at *(esi+ecx+12) to AL
 51     # . compare
 52     3d/compare-eax-and  0x23/imm32/pound
 53     0f 85/jump-if-!=  $next-word:regular-word/disp32
 54 $next-word:comment:
 55     # out->end = out->start
 56     8d/copy-address                 1/mod/*+disp8   4/rm32/sib    6/base/esi  1/index/ecx   .           0/r32/eax   0xc/disp8       .                 # copy esi+ecx+12 to eax
 57     89/copy                         1/mod/*+disp8   7/rm32/edi    .           .             .           0/r32/eax   4/disp8         .                 # copy eax to *(edi+4)
 58     # var write/ecx: int = line->write
 59     8b/copy                         0/mod/indirect  6/rm32/esi    .           .             .           1/r32/ecx   .               .                 # copy *esi to ecx
 60 $next-word:comment-loop:
 61     # if (line->read >= line->write) break
 62     39/compare                      1/mod/*+disp8   6/rm32/esi    .           .             .           1/r32/ecx   4/disp8         .                 # compare *(esi+4) with ecx
 63     0f 8d/jump-if->=  $next-word:comment-break/disp32
 64     # ++line->read
 65     ff          0/subop/increment   1/mod/*+disp8   6/rm32/esi    .           .             .           .           4/disp8         .                 # increment *(esi+4)
 66     # ++out->end
 67     ff          0/subop/increment   1/mod/*+disp8   7/rm32/edi    .           .             .           .           4/disp8         .                 # increment *(edi+4)
 68     # if (*out->end == newline) break
 69     8b/copy                         1/mod/*+disp8   7/rm32/edi    .           .             .           0/r32/eax   4/disp8         .                 # copy *(edi+4) to eax
 70     8a/copy-byte                    0/mod/indirect  0/rm32/eax    .           .             .           0/r32/AL    .               .                 # copy byte at *eax to AL
 71     25/and-eax-with  0xff/imm32
 72     3d/compare-eax-and  0xa/imm32/newline
 73     0f 84/jump-if-=  $next-word:comment-break/disp32
 74     # loop
 75     e9/jump  $next-word:comment-loop/disp32
 76 $next-word:comment-break:
 77     # return
 78     e9/jump  $next-word:end/disp32
 79 $next-word:regular-word:
 80     # otherwise skip-chars-not-matching-whitespace(line)  # including trailing newline
 81     # . . push args
 82     ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           8/disp8         .                 # push *(ebp+8)
 83     # . . call
 84     e8/call  skip-chars-not-matching-whitespace/disp32
 85     # . . discard args
 86     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
 87     # out->end = &line->data[line->read]
 88     8b/copy                         1/mod/*+disp8   6/rm32/esi    .           .             .           1/r32/ecx   4/disp8         .                 # copy *(esi+4) to ecx
 89     8d/copy-address                 1/mod/*+disp8   4/rm32/sib    6/base/esi  1/index/ecx   .           0/r32/eax   0xc/disp8       .                 # copy esi+ecx+12 to eax
 90     89/copy                         1/mod/*+disp8   7/rm32/edi    .           .             .           0/r32/eax   4/disp8         .                 # copy eax to *(edi+4)
 91 $next-word:end:
 92     # . restore registers
 93     5f/pop-to-edi
 94     5e/pop-to-esi
 95     59/pop-to-ecx
 96     58/pop-to-eax
 97     # . epilogue
 98     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
 99     5d/pop-to-ebp
100     c3/return
101 
102 test-next-word:
103     # . prologue
104     55/push-ebp
105     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
106     # setup
107     # . clear-stream(_test-stream)
108     # . . push args
109     68/push  _test-stream/imm32
110     # . . call
111     e8/call  clear-stream/disp32
112     # . . discard args
113     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
114     # var slice/ecx: slice
115     68/push  0/imm32/end
116     68/push  0/imm32/start
117     89/copy                         3/mod/direct    1/rm32/ecx    .           .             .           4/r32/esp   .               .                 # copy esp to ecx
118     # write(_test-stream, "  ab")
119     # . . push args
120     68/push  "  ab"/imm32
121     68/push  _test-stream/imm32
122     # . . call
123     e8/call  write/disp32
124     # . . discard args
125     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
126     # next-word(_test-stream, slice)
127     # . . push args
128     51/push-ecx
129     68/push  _test-stream/imm32
130     # . . call
131     e8/call  next-word/disp32
132     # . . discard args
133     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
134     # check-ints-equal(slice->start - _test-stream->data, 2, msg)
135     # . check-ints-equal(slice->start - _test-stream, 14, msg)
136     # . . push args
137     68/push  "F - test-next-word: start"/imm32
138     68/push  0xe/imm32
139     # . . push slice->start - _test-stream
140     8b/copy                         0/mod/indirect  1/rm32/ecx    .           .             .           0/r32/eax   .               .                 # copy *ecx to eax
141     81          5/subop/subtract    3/mod/direct    0/rm32/eax    .           .             .           .           .               _test-stream/imm32 # subtract from eax
142     50/push-eax
143     # . . call
144     e8/call  check-ints-equal/disp32
145     # . . discard args
146     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esppre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; 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 */
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><title>Python: module ranger.gui.widgets.pager</title>
</head><body bgcolor="#f0f0f8">

<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
<tr bgcolor="#7799ee">
<td valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="ranger.html"><font color="#ffffff">ranger</font></a>.<a href="ranger.gui.html"><font color="#ffffff">gui</font></a>.<a href="ranger.gui.widgets.html"><font color="#ffffff">widgets</font></a>.pager</strong></big></big></font></td
><td align=right valign=bottom
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/hut/ranger/ranger/gui/widgets/pager.py">/home/hut/ranger/ranger/gui/widgets/pager.py</a></font></td></tr></table>
    <p><tt>The&nbsp;pager&nbsp;displays&nbsp;text&nbsp;and&nbsp;allows&nbsp;you&nbsp;to&nbsp;scroll&nbsp;inside&nbsp;it.</tt></p>
<p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#aa55cc">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
    
<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="re.html">re</a><br>
</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#ee77aa">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
    
<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<td width="100%"><dl>
<dt><font face="helvetica, arial"><a href="ranger.gui.widgets.html#Widget">ranger.gui.widgets.Widget</a>(<a href="ranger.gui.displayable.html#Displayable">ranger.gui.displayable.Displayable</a>)
</font></dt><dd>
<dl>
<dt><font face="helvetica, arial"><a href="ranger.gui.widgets.pager.html#Pager">Pager</a>
</font></dt></dl>
</dd>
</dl>
 <p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#ffc8d8">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#000000" face="helvetica, arial"><a name="Pager">class <strong>Pager</strong></a>(<a href="ranger.gui.widgets.html#Widget">ranger.gui.widgets.Widget</a>)</font></td></tr>
    
<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<td width="100%"><dl><dt>Method resolution order:</dt>
<dd><a href="ranger.gui.widgets.pager.html#Pager">Pager</a></dd>
<dd><a href="ranger.gui.widgets.html#Widget">ranger.gui.widgets.Widget</a></dd>
<dd><a href="ranger.gui.displayable.html#Displayable">ranger.gui.displayable.Displayable</a></dd>
<dd><a href="ranger.shared.html#EnvironmentAware">ranger.shared.EnvironmentAware</a></dd>
<dd><a href="ranger.shared.html#FileManagerAware">ranger.shared.FileManagerAware</a></dd>
<dd><a href="ranger.shared.html#Awareness">ranger.shared.Awareness</a></dd>
<dd><a href="ranger.gui.curses_shortcuts.html#CursesShortcuts">ranger.gui.curses_shortcuts.CursesShortcuts</a></dd>
<dd><a href="ranger.shared.settings.html#SettingsAware">ranger.shared.settings.SettingsAware</a></dd>
<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
</dl>
<hr>
Methods defined here:<br>
<dl><dt><a name="Pager-__init__"><strong>__init__</strong></a>(self, win, embedded<font color="#909090">=False</font>)</dt></dl>

<dl><dt><a name="Pager-click"><strong>click</strong></a>(self, event)</dt></dl>

<dl><dt><a name="Pager-close"><strong>close</strong></a>(self)</dt></dl>

<dl><dt><a name="Pager-draw"><strong>draw</strong></a>(self)</dt></dl>

<dl><dt><a name="Pager-finalize"><strong>finalize</strong></a>(self)</dt></dl>

<dl><dt><a name="Pager-move"><strong>move</strong></a>(self, narg<font color="#909090">=None</font>, **kw)</dt></dl>

<dl><dt><a name="Pager-open"><strong>open</strong></a>(self)</dt></dl>

<dl><dt><a name="Pager-press"><strong>press</strong></a>(self, key)</dt></dl>

<dl><dt><a name="Pager-set_source"><strong>set_source</strong></a>(self, source, strip<font color="#909090">=False</font>)</dt></dl>

<hr>
Data and other attributes defined here:<br>
<dl><dt><strong>old_scroll_begin</strong> = 0</dl>

<dl><dt><strong>old_source</strong> = None</dl>

<dl><dt><strong>old_startx</strong> = 0</dl>

<dl><dt><strong>source</strong> = None</dl