about summary refs log tree commit diff stats
path: root/html/055stream.subx.html
blob: e08d690c3276ef22204e44ba7ce17ab5d6e2a188 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Mu - 055stream.subx</title>
<meta name="Generator" content="Vim/8.1">
<meta name="plugin-version" content="vim8.1_v1">
<meta name="syntax" content="none">
<meta name="settings" content="number_lines,use_css,no_foldcolumn,expand_tabs,line_ids,prevent_copy=">
<meta name="colorscheme" content="minimal-light">
<style type="text/css">
<!--
pre { font-family: monospace; color: #000000; background-color: #c6c6c6; }
body { font-size:12pt; font-family: monospace; color: #000000; background-color: #c6c6c6; }
a { color:inherit; }
* { font-size:12pt; font-size: 1em; }
.subxComment { color: #005faf; }
.subxS2Comment { color: #8a8a8a; }
.LineNr { }
.subxS1Comment { color: #0000af; }
.subxFunction { color: #af5f00; text-decoration: underline; }
.Normal { color: #000000; background-color: #c6c6c6; padding-bottom: 1px; }
.Constant { color: #008787; }
-->
</style>

<script type='text/javascript'>
<!--

/* function to open any folds containing a jumped-to line before jumping to it */
function JumpToLine()
{
  var lineNum;
  lineNum = window.location.hash;
  lineNum = lineNum.substr(1); /* strip off '#' */

  if (lineNum.indexOf('L') == -1) {
    lineNum = 'L'+lineNum;
  }
  var lineElem = document.getElementById(lineNum);
  /* Always jump to new location even if the line was hidden inside a fold, or
   * we corrected the raw number to a line ID.
   */
  if (lineElem) {
    lineElem.scrollIntoView(true);
  }
  return true;
}
if ('onhashchange' in window) {
  window.onhashchange = JumpToLine;
}

-->
</script>
</head>
<body onload='JumpToLine();'>
<a href='https://github.com/akkartik/mu/blob/master/055stream.subx'>https://github.com/akkartik/mu/blob/master/055stream.subx</a>
<pre id='vimCodeElement'>
<span id="L1" class="LineNr"> 1 </span><span class="subxComment"># streams: data structure for operating on arrays in a stateful manner</span>
<span id="L2" class="LineNr"> 2 </span><span class="subxComment">#</span>
<span id="L3" class="LineNr"> 3 </span><span class="subxComment"># A stream looks like this:</span>
<span id="L4" class="LineNr"> 4 </span><span class="subxComment">#   write: int  # index at which writes go</span>
<span id="L5" class="LineNr"> 5 </span><span class="subxComment">#   read: int  # index that we've read until</span>
<span id="L6" class="LineNr"> 6 </span><span class="subxComment">#   data: (array byte)  # prefixed by length as usual</span>
<span id="L7" class="LineNr"> 7 </span><span class="subxComment">#</span>
<span id="L8" class="LineNr"> 8 </span><span class="subxComment"># some primitives for operating on streams:</span>
<span id="L9" class="LineNr"> 9 </span><span class="subxComment">#   - clear-stream (clears everything but the data length)</span>
<span id="L10" class="LineNr">10 </span><span class="subxComment">#   - rewind-stream (resets read pointer)</span>
<span id="L11" class="LineNr">11 </span>
<span id="L12" class="LineNr">12 </span>== code
<span id="L13" class="LineNr">13 </span><span class="subxComment">#   instruction                     effective address                                                   register    displacement    immediate</span>
<span id="L14" class="LineNr">14 </span><span class="subxS1Comment"># . op          subop               mod             rm32          base        index         scale       r32</span>
<span id="L15" class="LineNr">15 </span><span class="subxS1Comment"># . 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</span>
<span id="L16" class="LineNr">16 </span>
<span id="L17" class="LineNr">17 </span><span class="subxFunction">clear-stream</span>:  <span class="subxComment"># f: (addr stream byte)</span>
<span id="L18" class="LineNr">18 </span>    <span class="subxS1Comment"># . prologue</span>
<span id="L19" class="LineNr">19 </span>    55/push-ebp
<span id="L20" class="LineNr">20 </span>    89/copy                         3/mod/direct    5/rm32/ebp   <span class="Normal"> . </span>         <span class="Normal"> . </span>           <span class="Normal"> . </span>          4/r32/esp  <span class="Normal"> . </span>             <span class="Normal"> . </span>                <span class="subxComment"># copy esp to ebp</span>
<span id="L21" class="LineNr">21 </span>    <span class="subxS1Comment"># . save registers</span>
<span id="L22" class="LineNr">22 </span>    50/push-eax
<span id="L23" class="LineNr">23 </span>    51/push-ecx
<span id="L24" class="LineNr">24 </span>    <span class="subxComment"># eax = f</span>
<span id="L25" class="LineNr">25 </span>    8b/copy                         1/mod/*+disp8   5/rm32/ebp   <span class="Normal"> . </span>         <span class="Normal"> . </span>                        0/r32/eax   8/disp8        <span class="Normal"> . </span>                <span class="subxComment"># copy *(ebp+8) to eax</span>
<span id="L26" class="LineNr">26 </span>    <span class="subxComment"># var count/ecx: int = f-&gt;length</span>
<span id="L27" class="LineNr">27 </span>    8b/copy                         1/mod/*+disp8   0/rm32/eax   <span class="Normal"> . </span>         <span class="Normal"> . </span>           <span class="Normal"> . </span>          1/r32/ecx   8/disp8        <span class="Normal"> . </span>                <span class="subxComment"># copy *(eax+8) to ecx</span>
<span id="L28" class="LineNr">28 </span>    <span class="subxComment"># var max/ecx: (addr byte) = &amp;f-&gt;data[f-&gt;length]</span>
<span id="L29" class="LineNr">29 </span>    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/eax  1/index/ecx  <span class="Normal"> . </span>          1/r32/ecx   0xc/disp8      <span class="Normal"> . </span>                <span class="subxComment"># copy eax+ecx+12 to ecx</span>
<span id="L30" class="LineNr">30 </span>    <span class="subxComment"># f-&gt;write = 0</span>
<span id="L31" class="LineNr">31 </span>    c7          0/subop/copy        0/mod/direct    0/rm32/eax   <span class="Normal"> . </span>         <span class="Normal"> . </span>           <span class="Normal"> . </span>         <span class="Normal"> . </span>         <span class="Normal"> . </span>              0/imm32           <span class="subxComment"># copy to *eax</span>
<span id="L32" class="LineNr">32 </span>    <span class="subxComment"># f-&gt;read = 0</span>
<span id="L33" class="LineNr">33 </span>    c7          0/subop/copy        1/mod/*+disp8   0/rm32/eax   <span class="Normal"> . </span>         <span class="Normal"> . </span>           <span class="Normal"> . </span>         <span class="Normal"> . </span>          4/disp8         0/imm32           <span class="subxComment"># copy to *(eax+4)</span>
<span id="L34" class="LineNr">34 </span>    <span class="subxComment"># var curr/eax: (addr byte) = f-&gt;data</span>
<span id="L35" class="LineNr">35 </span>    81          0/subop/add         3/mod/direct    0/rm32/eax   <span class="Normal"> . </span>         <span class="Normal"> . </span>           <span class="Normal"> . </span>         <span class="Normal"> . </span>         <span class="Normal"> . </span>              0xc/imm32         <span class="subxComment"># add to eax</span>
<span id="L36" class="LineNr">36 </span><span class="Constant">$clear-stream:loop</span>:
<span id="L37" class="LineNr">37 </span>    <span class="subxComment"># if (curr &gt;= max) break</span>
<span id="L38" class="LineNr">38 </span>    39/compare                      3/mod/direct    0/rm32/eax   <span class="Normal"> . </span>         <span class="Normal"> . </span>           <span class="Normal"> . </span>          1/r32/ecx  <span class="Normal"> . </span>             <span class="Normal"> . </span>                <span class="subxComment"># compare eax with ecx</span>
<span id="L39" class="LineNr">39 </span>    73/jump-if-addr&gt;=  $clear-stream:end/disp8
<span id="L40" class="LineNr">40 </span>    <span class="subxComment"># *curr = 0</span>
<span id="L41" class="LineNr">41 </span>    c6          0/subop/copy-byte   0/mod/direct    0/rm32/eax   <span class="Normal"> . </span>         <span class="Normal"> . </span>           <span class="Normal"> . </span>         <span class="Normal"> . </span>         <span class="Normal"> . </span>              0/imm8            <span class="subxComment"># copy byte to *eax</span>
<span id="L42" class="LineNr">42 </span>    <span class="subxComment"># ++curr</span>
<span id="L43" class="LineNr">43 </span>    40/increment-eax
<span id="L44" class="LineNr">44 </span>    eb/jump  $clear-stream:<span class="Constant">loop</span>/disp8
<span id="L45" class="LineNr">45 </span><span class="Constant">$clear-stream:end</span>:
<span id="L46" class="LineNr">46 </span>    <span class="subxS1Comment"># . restore registers</span>
<span id="L47" class="LineNr">47 </span>    59/pop-to-ecx
<span id="L48" class="LineNr">48 </span>    58/pop-to-eax
<span id="L49" class="LineNr">49 </span>    <span class="subxS1Comment"># . epilogue</span>
<span id="L50" class="LineNr">50 </span>    89/copy                         3/mod/direct    4/rm32/esp   <span class="Normal"> . </span>         <span class="Normal"> . </span>           <span class="Normal"> . </span>          5/r32/ebp  <span class="Normal"> . </span>             <span class="Normal"> . </span>                <span class="subxComment"># copy ebp to esp</span>
<span id="L51" class="LineNr">51 </span>    5d/pop-to-ebp
<span id="L52" class="LineNr">52 </span>    c3/return
<span id="L53" class="LineNr">53 </span>
<span id="L54" class="LineNr">54 </span><span class="subxFunction">rewind-stream</span>:  <span class="subxComment"># f: (addr stream byte)</span>
<span id="L55" class="LineNr">55 </span>    <span class="subxS1Comment"># . prologue</span>
<span id="L56" class="LineNr">56 </span>    55/push-ebp
<span id="L57" class="LineNr">57 </span>    89/copy                         3/mod/direct    5/rm32/ebp   <span class="Normal"> . </span>         <span class="Normal"> . </span>           <span class="Normal"> . </span>          4/r32/esp  <span class="Normal"> . </span>             <span class="Normal"> . </span>                <span class="subxComment"># copy esp to ebp</span>
<span id="L58" class="LineNr">58 </span>    <span class="subxS1Comment"># . save registers</span>
<span id="L59" class="LineNr">59 </span>    50/push-eax
<span id="L60" class="LineNr">60 </span>    <span class="subxComment"># eax = f</span>
<span id="L61" class="LineNr">61 </span>    8b/copy                         1/mod/*+disp8   5/rm32/ebp   <span class="Normal"> . </span>         <span class="Normal"> . </span>                        0/r32/eax   8/disp8        <span class="Normal"> . </span>                <span class="subxComment"># copy *(ebp+8) to eax</span>
<span id="L62" class="LineNr">62 </span>    <span class="subxComment"># f-&gt;read = 0</span>
<span id="L63" class="LineNr">63 </span>    c7          0/subop/copy        1/mod/*+disp8   0/rm32/eax   <span class="Normal"> . </span>         <span class="Normal"> . </span>           <span class="Normal"> . </span>         <span class="Normal"> . </span>          4/disp8         0/imm32           <span class="subxComment"># copy to *(eax+4)</span>
<span id="L64" class="LineNr">64 </span><span class="Constant">$rewind-stream:end</span>:
<span id="L65" class="LineNr">65 </span>    <span class="subxS1Comment"># . restore registers</span>
<span id="L66" class="LineNr">66 </span>    58/pop-to-eax
<span id="L67" class="LineNr">67 </span>    <span class="subxS1Comment"># . epilogue</span>
<span id="L68" class="LineNr">68 </span>    89/copy                         3/mod/direct    4/rm32/esp   <span class="Normal"> . </span>         <span class="Normal"> . </span>           <span class="Normal"> . </span>          5/r32/ebp  <span class="Normal"> . </span>             <span class="Normal"> . </span>                <span class="subxComment"># copy ebp to esp</span>
<span id="L69" class="LineNr">69 </span>    5d/pop-to-ebp
<span id="L70" class="LineNr">70 </span>    c3/return
<span id="L71" class="LineNr">71 </span>
<span id="L72" class="LineNr">72 </span><span class="subxS2Comment"># . . vim&#0058;nowrap:textwidth=0</span>
</pre>
</body>
</html>
<!-- vim: set foldmethod=manual : -->
"L40" class="LineNr"> 40 </span><span class="Comment">//:</span> <span id="L41" class="LineNr"> 41 </span><span class="Comment">//: -- Richard Gabriel, &quot;The Quality Without A Name&quot;</span> <span id="L42" class="LineNr"> 42 </span><span class="Comment">//: (<a href="http://dreamsongs.com/Files/PatternsOfSoftware.pdf">http://dreamsongs.com/Files/PatternsOfSoftware.pdf</a>, page 42)</span> <span id="L43" class="LineNr"> 43 </span><span class="Comment">//:</span> <span id="L44" class="LineNr"> 44 </span><span class="Comment">//: Directives are powerful; they permit inserting or modifying any point in</span> <span id="L45" class="LineNr"> 45 </span><span class="Comment">//: the program. Using them tastefully requires mapping out specific lines as</span> <span id="L46" class="LineNr"> 46 </span><span class="Comment">//: waypoints for future layers to hook into. Often such waypoints will be in</span> <span id="L47" class="LineNr"> 47 </span><span class="Comment">//: comments, capitalized to hint that other layers rely on their presence.</span> <span id="L48" class="LineNr"> 48 </span><span class="Comment">//:</span> <span id="L49" class="LineNr"> 49 </span><span class="Comment">//: A single waypoint might have many different code fragments hooking into</span> <span id="L50" class="LineNr"> 50 </span><span class="Comment">//: it from all over the codebase. Use 'before' directives to insert</span> <span id="L51" class="LineNr"> 51 </span><span class="Comment">//: code at a location in order, top to bottom, and 'after' directives to</span> <span id="L52" class="LineNr"> 52 </span><span class="Comment">//: insert code in reverse order. By convention waypoints intended for insertion</span> <span id="L53" class="LineNr"> 53 </span><span class="Comment">//: before begin with 'End'. Notice below how the layers line up above the &quot;End</span> <span id="L54" class="LineNr"> 54 </span><span class="Comment">//: Foo&quot; waypoint.</span> <span id="L55" class="LineNr"> 55 </span><span class="Comment">//:</span> <span id="L56" class="LineNr"> 56 </span><span class="Comment">//: File 001 File 002 File 003</span> <span id="L57" class="LineNr"> 57 </span><span class="Comment">//: ============ =================== ===================</span> <span id="L58" class="LineNr"> 58 </span><span class="Comment">//: // Foo</span> <span id="L59" class="LineNr"> 59 </span><span class="Comment">//: ------------</span> <span id="L60" class="LineNr"> 60 </span><span class="Comment">//: &lt;---- :(before &quot;End Foo&quot;)</span> <span id="L61" class="LineNr"> 61 </span><span class="Comment">//: ....</span> <span id="L62" class="LineNr"> 62 </span><span class="Comment">//: ...</span> <span id="L63" class="LineNr"> 63 </span><span class="Comment">//: ------------</span> <span id="L64" class="LineNr"> 64 </span><span class="Comment">//: &lt;---------------------------- :(before &quot;End Foo&quot;)</span> <span id="L65" class="LineNr"> 65 </span><span class="Comment">//: ....</span> <span id="L66" class="LineNr"> 66 </span><span class="Comment">//: ...</span> <span id="L67" class="LineNr"> 67 </span><span class="Comment">//: // End Foo</span> <span id="L68" class="LineNr"> 68 </span><span class="Comment">//: ============</span> <span id="L69" class="LineNr"> 69 </span><span class="Comment">//:</span> <span id="L70" class="LineNr"> 70 </span><span class="Comment">//: Here's part of a layer in color: <a href="http://i.imgur.com/0eONnyX.png">http://i.imgur.com/0eONnyX.png</a>. Directives</span> <span id="L71" class="LineNr"> 71 </span><span class="Comment">//: are shaded dark.</span> <span id="L72" class="LineNr"> 72 </span><span class="Comment">//:</span> <span id="L73" class="LineNr"> 73 </span><span class="Comment">//: Layers do more than just shuffle code around. In a well-organized codebase</span> <span id="L74" class="LineNr"> 74 </span><span class="Comment">//: it should be possible to stop loading after any file/layer, build and run</span> <span id="L75" class="LineNr"> 75 </span><span class="Comment">//: the program, and pass all tests for loaded features. (Relevant is</span> <span id="L76" class="LineNr"> 76 </span><span class="Comment">//: <a href="http://youtube.com/watch?v=c8N72t7aScY">http://youtube.com/watch?v=c8N72t7aScY</a>, a scene from &quot;2001: A Space</span> <span id="L77" class="LineNr"> 77 </span><span class="Comment">//: Odyssey&quot;.) Get into the habit of running the included script called</span> <span id="L78" class="LineNr"> 78 </span><span class="Comment">//: 'test_layers' before you commit any changes.</span> <span id="L79" class="LineNr"> 79 </span><span class="Comment">//:</span> <span id="L80" class="LineNr"> 80 </span><span class="Comment">//: This 'subsetting guarantee' ensures that this directory contains a</span> <span id="L81" class="LineNr"> 81 </span><span class="Comment">//: cleaned-up narrative of the evolution of this codebase. Organizing</span> <span id="L82" class="LineNr"> 82 </span><span class="Comment">//: autobiographically allows newcomers to rapidly orient themselves, reading</span> <span id="L83" class="LineNr"> 83 </span><span class="Comment">//: the first few files to understand a simple gestalt of a program's core</span> <span id="L84" class="LineNr"> 84 </span><span class="Comment">//: purpose and features, and later gradually working their way through other</span> <span id="L85" class="LineNr"> 85 </span><span class="Comment">//: features as the need arises.</span> <span id="L86" class="LineNr"> 86 </span><span class="Comment">//:</span> <span id="L87" class="LineNr"> 87 </span><span class="Comment">//: Programmers shouldn't need to understand everything about a program to</span> <span id="L88" class="LineNr"> 88 </span><span class="Comment">//: hack on it. But they shouldn't be prevented from a thorough understanding</span> <span id="L89" class="LineNr"> 89 </span><span class="Comment">//: of each aspect either. The goal of layers is to reward curiosity.</span> <span id="L90" class="LineNr"> 90 </span> <span id="L91" class="LineNr"> 91 </span><span class="Comment">// Includes</span> <span id="L92" class="LineNr"> 92 </span><span class="Comment">// End Includes</span> <span id="L93" class="LineNr"> 93 </span> <span id="L94" class="LineNr"> 94 </span><span class="Comment">// Types</span> <span id="L95" class="LineNr"> 95 </span><span class="Comment">// End Types</span> <span id="L96" class="LineNr"> 96 </span> <span id="L97" class="LineNr"> 97 </span><span class="Comment">// Function prototypes are auto-generated in the 'build*' scripts; define your</span> <span id="L98" class="LineNr"> 98 </span><span class="Comment">// functions in any order. Just be sure to declare each function header all on</span> <span id="L99" class="LineNr"> 99 </span><span class="Comment">// one line, ending with the '{'. Our auto-generation scripts are too minimal</span> <span id="L100" class="LineNr">100 </span><span class="Comment">// and simple-minded to handle anything else.</span> <span id="L101" class="LineNr">101 </span><span class="Comment">#include &quot;function_list&quot; // by convention, files ending with '_list' are auto-generated</span> <span id="L102" class="LineNr">102 </span> <span id="L103" class="LineNr">103 </span><span class="Comment">// Globals</span> <span id="L104" class="LineNr">104 </span><span class="Comment">//</span> <span id="L105" class="LineNr">105 </span><span class="Comment">// All statements in this section should always define a single variable on a</span> <span id="L106" class="LineNr">106 </span><span class="Comment">// single line. The 'build*' scripts will simple-mindedly auto-generate extern</span> <span id="L107" class="LineNr">107 </span><span class="Comment">// declarations for them. Remember to define (not just declare) constants with</span> <span id="L108" class="LineNr">108 </span><span class="Comment">// extern linkage in this section, since C++ global constants have internal</span> <span id="L109" class="LineNr">109 </span><span class="Comment">// linkage by default.</span> <span id="L110" class="LineNr">110 </span><span class="Comment">//</span> <span id="L111" class="LineNr">111 </span><span class="Comment">// End Globals</span> <span id="L112" class="LineNr">112 </span> <span id="L113" class="LineNr">113 </span><span class="Normal">int</span> <a href='000organization.cc.html#L113'>main</a><span class="Delimiter">(</span><span class="Normal">int</span> argc<span class="Delimiter">,</span> <span class="Normal">char</span>* argv[]<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span id="L114" class="LineNr">114 </span> atexit<span class="Delimiter">(</span><a href='000organization.cc.html#L134'>reset</a><span class="Delimiter">);</span> <span id="L115" class="LineNr">115 </span> <span id="L116" class="LineNr">116 </span> <span class="Comment">// End One-time Setup</span> <span id="L117" class="LineNr">117 </span> <span id="L118" class="LineNr">118 </span> <span class="Comment">// Commandline Parsing</span> <span id="L119" class="LineNr">119 </span> <span class="Comment">// End Commandline Parsing</span> <span id="L120" class="LineNr">120 </span> <span id="L121" class="LineNr">121 </span> <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Comment">// End Main</span> <span id="L122" class="LineNr">122 </span><span class="Delimiter">}</span> <span id="L123" class="LineNr">123 </span> <span id="L124" class="LineNr">124 </span><span class="Comment">// Unit Tests</span> <span id="L125" class="LineNr">125 </span><span class="Comment">// End Unit Tests</span> <span id="L126" class="LineNr">126 </span> <span id="L127" class="LineNr">127 </span><span class="Comment">//: our first directive; insert the following header at the start of the program</span> <span id="L128" class="LineNr">128 </span><span class="Delimiter">:(before &quot;End Includes&quot;)</span> <span id="L129" class="LineNr">129 </span><span class="Comment">#include &lt;stdlib.h&gt;</span> <span id="L130" class="LineNr">130 </span> <span id="L131" class="LineNr">131 </span><span class="Comment">//: Without directives or with the :(code) directive, lines get added at the</span> <span id="L132" class="LineNr">132 </span><span class="Comment">//: end.</span> <span id="L133" class="LineNr">133 </span><span class="Delimiter">:(code)</span> <span id="L134" class="LineNr">134 </span><span class="Normal">void</span> <a href='000organization.cc.html#L134'>reset</a><span class="Delimiter">()</span> <span class="Delimiter">{</span> <span id="L135" class="LineNr">135 </span> <span class="Comment">// End Reset</span> <span id="L136" class="LineNr">136 </span><span class="Delimiter">}</span> </pre> </body> </html> <!-- vim: set foldmethod=manual : -->