about summary refs log tree commit diff stats
path: root/subx/068read-line.subx
blob: 961fc52126fa2d4db75a4c46f2ea667886c0a5fd (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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
== code
#   instruction                     effective address                                                   register    displacement    immediate
# . op          subop               mod             rm32          base        index         scale       r32
# . 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

# main:
    e8/call  run-tests/disp32  # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'.
    # syscall(exit, Num-test-failures)
    8b/copy                         0/mod/indirect  5/rm32/.disp32            .             .           3/r32/EBX   Num-test-failures/disp32          # copy *Num-test-failures to EBX
    b8/copy-to-EAX  1/imm32/exit
    cd/syscall  0x80/imm8

# read bytes from 'f' until (and including) a newline and store them into 's'
# return true if no data found, false otherwise
# just abort if 's' is too small
read-line:  # f : (address buffered-file), s : (address stream byte) -> eof?/EAX
    # pseudocode:
    #   loop:
    #     if (s->write >= s->length) abort
    #     if (f->read >= f->write) populate stream from file
    #     if (f->write == 0) break
    #     AL = f->data[f->read]
    #     s->data[s->write] = AL
    #     ++f->read
    #     ++s->write
    #     if AL == '\n' break
    # . prolog
    55/push-EBP
    89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
    # . save registers
    51/push-ECX
    52/push-EDX
    56/push-ESI
    57/push-EDI
    # ESI = f
    8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           6/r32/ESI   8/disp8         .                 # copy *(EBP+8) to ESI
    # ECX = f->read
    8b/copy                         1/mod/*+disp8   6/rm32/ESI    .           .             .           1/r32/ECX   8/disp8         .                 # copy *(ESI+8) to ECX
    # EDI = s
    8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           7/r32/EDI   0xc/disp8       .                 # copy *(EBP+12) to EDI
    # EDX = s->write
    8b/copy                         0/mod/indirect  7/rm32/EDI    .           .             .           2/r32/EDX   .               .                 # copy *EDI to EDX
$read-line:loop:
    # if (s->write >= s->length) abort
    3b/compare                      1/mod/*+disp8   7/rm32/EDI    .           .             .           2/r32/EDX   8/disp8         .                 # compare EDX with *(EDI+8)
    7d/jump-if-greater-or-equal  $read-line:abort/disp8
    # if (f->read >= f->write) populate stream from file
    3b/compare                      1/mod/*+disp8   6/rm32/ESI    .           .             .           1/r32/ECX   4/disp8         .                 # compare ECX with *(ESI+4)
    7c/jump-if-lesser  $read-line:from-stream/disp8
    # . clear-stream(stream = f+4)
    # . . push args
    8d/copy-address                 1/mod/*+disp8   6/rm32/ESI    .           .             .           0/r32/EAX   4/disp8         .                 # copy ESI+4 to EAX
    50/push-EAX
    # . . call
    e8/call  clear-stream/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
    # . f->read must now be 0; update its cache at ECX
    31/xor                          3/mod/direct    1/rm32/ECX    .           .             .           1/r32/ECX   .               .                 # clear ECX
    # . EAX = read(f->fd, stream = f+4)
    # . . push args
    50/push-EAX
    ff          6/subop/push        0/mod/indirect  6/rm32/ESI    .           .             .           .           .               .                 # push *ESI
    # . . call
    e8/call  read/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
    # if f->write == 0 return true
    # . if EAX == 0 return true
    81          7/subop/compare     3/mod/direct    0/rm32/EAX    .           .             .           .           .               0/imm32           # compare EAX
    75/jump-if-not-equal  $read-line:from-stream/disp8
    b8/copy-to-EAX  0xffffffff/imm32
    eb/jump  $read-line:end/disp8
$read-line:from-stream:
    # AL = f->data[f->read]
    31/xor                          3/mod/direct    0/rm32/EAX    .           .             .           0/r32/EAX   .               .                 # clear EAX
    8a/copy-byte                    1/mod/*+disp8   4/rm32/sib    6/base/ESI  1/index/ECX   .           0/r32/AL    0x10/disp8      .                 # copy byte at *(ESI+ECX+16) to AL
    # s->data[s->write] = AL
    88/copy-byte                    1/mod/*+disp8   4/rm32/sib    7/base/EDI  2/index/EDX   .           0/r32/AL    0xc/disp8       .                 # copy AL to *(EDI+EDX+12)
    # ++f->read
    41/increment-ECX
    # ++s->write
    42/increment-EDX
    # if AL == '\n' return false
    81          7/subop/compare     3/mod/direct    0/rm32/EAX    .           .             .           .           .               0xa/imm32         # compare EAX
    75/jump-if-not-equal  $read-line:loop/disp8
    31/xor                          3/mod/direct    0/rm32/EAX    .           .             .           0/r32/EAX   .               .                 # clear EAX
$read-line:end:
    # save f->read
    89/copy                         1/mod/*+disp8   6/rm32/ESI    .           .             .           1/r32/ECX   8/disp8         .                 # copy ECX to *(ESI+8)
    # save s->write
    89/copy                         0/mod/indirect  7/rm32/EDI    .           .             .           2/r32/EDX   .               .                 # copy EDX to *EDI
    # . restore registers
    5f/pop-to-EDI
    5e/pop-to-ESI
    5a/pop-to-EDX
    59/pop-to-ECX
    # . epilog
    89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
    5d/pop-to-EBP
    c3/return

$read-line:abort:
    # . _write(2/stderr, error)
    # . . push args
    68/push  "read-line: line too long"/imm32
    68/push  2/imm32/stderr
    # . . call
    e8/call  _write/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
    # . syscall(exit, 1)
    bb/copy-to-EBX  1/imm32
    b8/copy-to-EAX  1/imm32/exit
    cd/syscall  0x80/imm8
    # never gets here

test-read-line:
    # - check that read-line stops at a newline
    # setup
    # . clear-stream(_test-stream)
    # . . push args
    68/push  _test-stream/imm32
    # . . call
    e8/call  clear-stream/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
    # . clear-stream(_test-buffered-file+4)
    # . . push args
    b8/copy-to-EAX  _test-buffered-file/imm32
    05/add-to-EAX  4/imm32
    50/push-EAX
    # . . call
    e8/call  clear-stream/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
    # . clear-stream(_test-stream-buffer)
    # . . push args
    68/push  _test-stream-buffer/imm32
    # . . call
    e8/call  clear-stream/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
    # write(_test-stream, "ab\ncd")
    # . write(_test-stream, "ab")
    # . . push args
    68/push  "ab"/imm32
    68/push  _test-stream/imm32
    # . . call
    e8/call  write/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
    # . write(_test-stream, "\n")
    # . . push args
    68/push Newline/imm32
    68/push  _test-stream/imm32
    # . . call
    e8/call  write/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
    # . write(_test-stream, "cd")
    # . . push args
    68/push  "cd"/imm32
    68/push  _test-stream/imm32
    # . . call
    e8/call  write/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
    # read a line from _test-stream (buffered by _test-buffered-file) into _test-stream-buffer
    # . EAX = read-line(_test-buffered-file, _test-stream-buffer)
    # . . push args
    68/push  _test-stream-buffer/imm32
    68/push  _test-buffered-file/imm32
    # . . call
    e8/call  read-line/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
    # check-ints-equal(EAX, 0/not-at-eof, msg)
    # . . push args
    68/push  "F - test-read-line: return value"/imm32
    68/push  0/imm32/not-at-eof
    50/push-EAX
    # . . call
    e8/call  check-ints-equal/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
    # check-ints-equal(*_test-stream-buffer->data, 61/a 62/b 0a/newline 00, msg)
    # . . push args
    68/push  "F - test-read-line"/imm32
    68/push  0x000a6261/imm32
    # . . push *_test-stream->data
    b8/copy-to-EAX  _test-stream-buffer/imm32
    ff          6/subop/push        1/mod/*+disp8   0/rm32/EAX    .           .             .           .           0xc/disp8       .                 # push *(EAX+12)
    # . . call
    e8/call  check-ints-equal/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
    # end
    c3/return

test-read-line-returns-true-on-eof:
    # setup
    # . clear-stream(_test-stream)
    # . . push args
    68/push  _test-stream/imm32
    # . . call
    e8/call  clear-stream/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
    # . clear-stream(_test-buffered-file+4)
    # . . push args
    b8/copy-to-EAX  _test-buffered-file/imm32
    05/add-to-EAX  4/imm32
    50/push-EAX
    # . . call
    e8/call  clear-stream/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
    # . clear-stream(_test-stream-buffer)
    # . . push args
    68/push  _test-stream-buffer/imm32
    # . . call
    e8/call  clear-stream/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
    # write nothing
    # EAX = read-line(_test-buffered-file, _test-stream-buffer)
    # . . push args
    68/push  _test-stream-buffer/imm32
    68/push  _test-buffered-file/imm32
    # . . call
    e8/call  read-line/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
    # check-ints-equal(EAX, eof, msg)
    # . . push args
    68/push  "F - test-read-line-returns-true-on-eof"/imm32
    68/push  0xffffffff/imm32/not-at-eof
    50/push-EAX
    # . . call
    e8/call  check-ints-equal/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
    # end
    c3/return

test-read-line-reads-final-line-until-eof:
    # setup
    # . clear-stream(_test-stream)
    # . . push args
    68/push  _test-stream/imm32
    # . . call
    e8/call  clear-stream/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
    # . clear-stream(_test-buffered-file+4)
    # . . push args
    b8/copy-to-EAX  _test-buffered-file/imm32
    05/add-to-EAX  4/imm32
    50/push-EAX
    # . . call
    e8/call  clear-stream/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
    # . clear-stream(_test-stream-buffer)
    # . . push args
    68/push  _test-stream-buffer/imm32
    # . . call
    e8/call  clear-stream/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
    # write(_test-stream, "cd")
    # . . push args
    68/push  "cd"/imm32
    68/push  _test-stream/imm32
    # . . call
    e8/call  write/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
    # read a line from _test-stream (buffered by _test-buffered-file) into _test-stream-buffer
    # . EAX = read-line(_test-buffered-file, _test-stream-buffer)
    # . . push args
    68/push  _test-stream-buffer/imm32
    68/push  _test-buffered-file/imm32
    # . . call
    e8/call  read-line/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
    # check-ints-equal(EAX, eof, msg)
    # . . push args
    68/push  "F - test-read-line-reads-final-line-until-eof: return value"/imm32
    68/push  0xffffffff/imm32/not-at-eof
    50/push-EAX
    # . . call
    e8/call  check-ints-equal/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
    # check-ints-equal(*_test-stream-buffer->data, 63/c 64/d 00 00, msg)
    # . . push args
    68/push  "F - test-read-line-reads-final-line-until-eof"/imm32
    68/push  0x00006463/imm32
    # . . push *_test-stream->data
    b8/copy-to-EAX  _test-stream-buffer/imm32
    ff          6/subop/push        1/mod/*+disp8   0/rm32/EAX    .           .             .           .           0xc/disp8       .                 # push *(EAX+12)
    # . . call
    e8/call  check-ints-equal/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
    # end
    c3/return

# . . vim:nowrap:textwidth=0
                                                                                                                                         
                         















































































                                                                                                                                                                                                                 


                                                                                                                                                   
                                                                         

                                                                                                                                                   





                                                                                     
                                                                                                                                                    

                                                                                                                                                    
                                                                                                                                                                         


                                                                                                                                                    
                                                                                                                                                     

                                                                                                                                                     

                                                                                     
                                                                                                                                                                                                                                                                                                                                       
                                                                                                                                                                   










                                                                                                                                                                                            
                                                                                                                                                       
                                                                                                           
                                                                                                


                                                                                                                                                   
                                                                                                                                                                                             
                                                                          

       
                                     
<!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 - 000organization.cc</title>
<meta name="Generator" content="Vim/8.0">
<meta name="plugin-version" content="vim7.4_v2">
<meta name="syntax" content="cpp">
<meta name="settings" content="number_lines,use_css,pre_wrap,no_foldcolumn,expand_tabs,line_ids,prevent_copy=">
<meta name="colorscheme" content="minimal-light">
<style type="text/css">
<!--
pre { white-space: pre-wrap; 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; }
.LineNr { }
.Constant { color: #008787; }
.Delimiter { color: #c000c0; }
.Identifier { color: #af5f00; }
.Normal { color: #000000; background-color: #c6c6c6; padding-bottom: 1px; }
.Comment { color: #005faf; }
-->
</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;
  }
  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/000organization.cc'>https://github.com/akkartik/mu/blob/master/000organization.cc</a>
<pre id='vimCodeElement'>
<span id="L1" class="LineNr">  1 </span><span class="Comment">//: You guessed right: the '000' prefix means you should start reading here.</span>
<span id="L2" class="LineNr">  2 </span><span class="Comment">//:</span>
<span id="L3" class="LineNr">  3 </span><span class="Comment">//: This project is set up to load all files with a numeric prefix. Just</span>
<span id="L4" class="LineNr">  4 </span><span class="Comment">//: create a new file and start hacking.</span>
<span id="L5" class="LineNr">  5 </span><span class="Comment">//:</span>
<span id="L6" class="LineNr">  6 </span><span class="Comment">//: The first few files (00*) are independent of what this program does, an</span>
<span id="L7" class="LineNr">  7 </span><span class="Comment">//: experimental skeleton that will hopefully make it both easier for others to</span>
<span id="L8" class="LineNr">  8 </span><span class="Comment">//: understand and more malleable, easier to rewrite and remould into radically</span>
<span id="L9" class="LineNr">  9 </span><span class="Comment">//: different shapes without breaking in subtle corner cases. The premise is</span>
<span id="L10" class="LineNr"> 10 </span><span class="Comment">//: that understandability and rewrite-friendliness are related in a virtuous</span>
<span id="L11" class="LineNr"> 11 </span><span class="Comment">//: cycle. Doing one well makes it easier to do the other.</span>
<span id="L12" class="LineNr"> 12 </span><span class="Comment">//:</span>
<span id="L13" class="LineNr"> 13 </span><span class="Comment">//: Lower down, this file contains a legal, bare-bones C++ program. It doesn't</span>
<span id="L14" class="LineNr"> 14 </span><span class="Comment">//: do anything yet; subsequent files will contain :(...) directives to insert</span>
<span id="L15" class="LineNr"> 15 </span><span class="Comment">//: lines into it. For example:</span>
<span id="L16" class="LineNr"> 16 </span><span class="Comment">//:   :(after &quot;more events&quot;)</span>
<span id="L17" class="LineNr"> 17 </span><span class="Comment">//: This directive means: insert the following lines after a line in the</span>
<span id="L18" class="LineNr"> 18 </span><span class="Comment">//: program containing the words &quot;more events&quot;.</span>
<span id="L19" class="LineNr"> 19 </span><span class="Comment">//:</span>
<span id="L20" class="LineNr"> 20 </span><span class="Comment">//: A simple tool is included to 'tangle' all the files together in sequence</span>
<span id="L21" class="LineNr"> 21 </span><span class="Comment">//: according to their directives into a single source file containing all the</span>
<span id="L22" class="LineNr"> 22 </span><span class="Comment">//: code for the project, and then feed the source file to the compiler.</span>
<span id="L23" class="LineNr"> 23 </span><span class="Comment">//: (It'll drop these comments starting with a '//:' prefix that only make</span>
<span id="L24" class="LineNr"> 24 </span><span class="Comment">//: sense before tangling.)</span>
<span id="L25" class="LineNr"> 25 </span><span class="Comment">//:</span>
<span id="L26" class="LineNr"> 26 </span><span class="Comment">//: Directives free up the programmer to order code for others to read rather</span>
<span id="L27" class="LineNr"> 27 </span><span class="Comment">//: than as forced by the computer or compiler. Each individual feature can be</span>
<span id="L28" class="LineNr"> 28 </span><span class="Comment">//: organized in a self-contained 'layer' that adds code to many different data</span>
<span id="L29" class="LineNr"> 29 </span><span class="Comment">//: structures and functions all over the program. The right decomposition into</span>
<span id="L30" class="LineNr"> 30 </span><span class="Comment">//: layers will let each layer make sense in isolation.</span>
<span id="L31" class="LineNr"> 31 </span><span class="Comment">//:</span>
<span id="L32" class="LineNr"> 32 </span><span class="Comment">//:   &quot;If I look at any small part of it, I can see what is going on -- I don't</span>
<span id="L33" class="LineNr"> 33 </span><span class="Comment">//:   need to refer to other parts to understand what something is doing.</span>
<span id="L34" class="LineNr"> 34 </span><span class="Comment">//:</span>
<span id="L35" class="LineNr"> 35 </span><span class="Comment">//:   If I look at any large part in overview, I can see what is going on -- I</span>
<span id="L36" class="LineNr"> 36 </span><span class="Comment">//:   don't need to know all the details to get it.</span>
<span id="L37" class="LineNr"> 37 </span><span class="Comment">//:</span>
<span id="L38" class="LineNr"> 38 </span><span class="Comment">//:   Every level of detail is as locally coherent and as well thought-out as</span>
<span id="L39" class="LineNr"> 39 </span><span class="Comment">//:   any other level.&quot;</span>
<span id="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 : -->