about summary refs log tree commit diff stats
path: root/dev/git
Commit message (Expand)AuthorAgeFilesLines
* dumped new version 0.3.5Silvino Silva2018-07-161-2/+2
* git index html fixSilvino Silva2018-02-251-5/+11
* development revisionSilvino Silva2017-01-121-0/+343
'#n22'>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
<!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 - 001help.cc</title>
<meta name="Generator" content="Vim/7.4">
<meta name="plugin-version" content="vim7.4_v2">
<meta name="syntax" content="cpp">
<meta name="settings" content="use_css,pre_wrap,no_foldcolumn,expand_tabs,prevent_copy=">
<meta name="colorscheme" content="minimal">
<style type="text/css">
<!--
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 12pt; font-size: 1em; }
.Constant { color: #00a0a0; }
.SalientComment { color: #00ffff; }
.Comment { color: #9090ff; }
.Delimiter { color: #800080; }
.cSpecial { color: #008000; }
.Identifier { color: #fcb165; }
.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; }
.PreProc { color: #800080; }
-->
</style>

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

-->
</script>
</head>
<body>
<pre id='vimCodeElement'>
<span class="Comment">//: Everything this project/binary supports.</span>
<span class="Comment">//: This should give you a sense for what to look forward to in later layers.</span>

<span class="Delimiter">:(before &quot;End Commandline Parsing&quot;)</span>
<span class="Normal">if</span> <span class="Delimiter">(</span>argc &lt;= <span class="Constant">1</span> || is_equal<span class="Delimiter">(</span>argv[<span class="Constant">1</span>]<span class="Delimiter">,</span> <span class="Constant">&quot;--help&quot;</span><span class="Delimiter">))</span> <span class="Delimiter">{</span>
  <span class="Comment">// this is the functionality later layers will provide</span>
  <span class="Comment">// currently no automated tests for commandline arg parsing</span>
  cerr &lt;&lt; <span class="Constant">&quot;To load files and run 'main':</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
       &lt;&lt; <span class="Constant">&quot;  mu file1.mu file2.mu ...</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
       &lt;&lt; <span class="Constant">&quot;To run all tests:</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
       &lt;&lt; <span class="Constant">&quot;  mu test</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
       &lt;&lt; <span class="Constant">&quot;To load files and then run all tests:</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
       &lt;&lt; <span class="Constant">&quot;  mu test file1.mu file2.mu ...</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
       &lt;&lt; <span class="Constant">&quot;To load all files with a numeric prefix in a directory:</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
       &lt;&lt; <span class="Constant">&quot;  mu directory1</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
       &lt;&lt; <span class="Constant">&quot;You can test directories just like files.</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
       &lt;&lt; <span class="Constant">&quot;To pass ingredients to a mu program, provide them after '--':</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
       &lt;&lt; <span class="Constant">&quot;  mu file_or_dir1 file_or_dir2 ... -- ingredient1 ingredient2 ...</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
       &lt;&lt; <span class="Constant">&quot;</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
       &lt;&lt; <span class="Constant">&quot;To browse a trace generated by a previous run:</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
       &lt;&lt; <span class="Constant">&quot;  mu browse-trace file</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
       <span class="Delimiter">;</span>
  <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>

<span class="SalientComment">//:: Helper function used by the above fragment of code (and later layers too,</span>
<span class="SalientComment">//:: who knows?).</span>
<span class="Comment">//: The :(code) directive appends function definitions to the end of the</span>
<span class="Comment">//: project. Regardless of where functions are defined, we can call them</span>
<span class="Comment">//: anywhere we like as long as we format the function header in a specific</span>
<span class="Comment">//: way: put it all on a single line without indent, end the line with ') {'</span>
<span class="Comment">//: and no trailing whitespace. As long as functions uniformly start this</span>
<span class="Comment">//: way, our makefile contains a little command to automatically generate</span>
<span class="Comment">//: declarations for them.</span>
<span class="Delimiter">:(code)</span>
<span class="Normal">bool</span> is_equal<span class="Delimiter">(</span><span class="Normal">char</span>* s<span class="Delimiter">,</span> <span class="Normal">const</span> <span class="Normal">char</span>* lit<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  <span class="Identifier">return</span> strncmp<span class="Delimiter">(</span>s<span class="Delimiter">,</span> lit<span class="Delimiter">,</span> strlen<span class="Delimiter">(</span>lit<span class="Delimiter">))</span> == <span class="Constant">0</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>

<span class="Comment">//: I'll throw some style conventions here for want of a better place for them.</span>
<span class="Comment">//: As a rule I hate style guides. Do what you want, that's my motto. But since</span>
<span class="Comment">//: we're dealing with C/C++, the one big thing we want to avoid is undefined</span>
<span class="Comment">//: behavior. If a compiler ever encounters undefined behavior it can make</span>
<span class="Comment">//: your program do anything it wants.</span>
<span class="Comment">//:</span>
<span class="Comment">//: For reference, my checklist of undefined behaviors to watch out for:</span>
<span class="Comment">//:   out-of-bounds access</span>
<span class="Comment">//:   uninitialized variables</span>
<span class="Comment">//:   use after free</span>
<span class="Comment">//:   dereferencing invalid pointers: null, a new of size 0, others</span>
<span class="Comment">//:</span>
<span class="Comment">//:   casting a large number to a type too small to hold it</span>
<span class="Comment">//:</span>
<span class="Comment">//:   integer overflow</span>
<span class="Comment">//:   division by zero and other undefined expressions</span>
<span class="Comment">//:   left-shift by negative count</span>
<span class="Comment">//:   shifting values by more than or equal to the number of bits they contain</span>
<span class="Comment">//:   bitwise operations on signed numbers</span>
<span class="Comment">//:</span>
<span class="Comment">//:   Converting pointers to types of different alignment requirements</span>
<span class="Comment">//:     T* -&gt; void* -&gt; T*: defined</span>
<span class="Comment">//:     T* -&gt; U* -&gt; T*: defined if non-function pointers and alignment requirements are same</span>
<span class="Comment">//:     function pointers may be cast to other function pointers</span>
<span class="Comment">//:</span>
<span class="Comment">//:       Casting a numeric value into a value that can't be represented by the target type (either directly or via static_cast)</span>
<span class="Comment">//:</span>
<span class="Comment">//: To guard against these, some conventions:</span>
<span class="Comment">//:</span>
<span class="Comment">//: 0. Initialize all primitive variables in functions and constructors.</span>
<span class="Comment">//:</span>
<span class="Comment">//: 1. Minimize use of pointers and pointer arithmetic. Avoid 'new' and</span>
<span class="Comment">//: 'delete' as far as possible. Rely on STL to perform memory management to</span>
<span class="Comment">//: avoid use-after-free issues (and memory leaks).</span>
<span class="Comment">//:</span>
<span class="Comment">//: 2. Avoid naked arrays to avoid out-of-bounds access. Never use operator[]</span>
<span class="Comment">//: except with map. Use at() with STL vectors and so on.</span>
<span class="Comment">//:</span>
<span class="Comment">//: 3. Valgrind all the things.</span>
<span class="Comment">//:</span>
<span class="Comment">//: 4. Avoid unsigned numbers. Not strictly an undefined-behavior issue, but</span>
<span class="Comment">//: the extra range doesn't matter, and it's one less confusing category of</span>
<span class="Comment">//: interaction gotchas to worry about.</span>
<span class="Comment">//:</span>
<span class="Comment">//: Corollary: don't use the size() method on containers, since it returns an</span>
<span class="Comment">//: unsigned and that'll cause warnings about mixing signed and unsigned,</span>
<span class="Comment">//: yadda-yadda. Instead use this macro below to perform an unsafe cast to</span>
<span class="Comment">//: signed. We'll just give up immediately if a container's ever too large.</span>
<span class="Comment">//:</span>
<span class="Comment">//: Addendum to corollary: We're going to uniformly avoid long long int</span>
<span class="Comment">//: everywhere, since Clang on 32-bit platforms doesn't yet support</span>
<span class="Comment">//: multiplication over 64-bit integers, and since that seems like a more</span>
<span class="Comment">//: common situation to end up in than integer overflow.</span>
<span class="Delimiter">:(before &quot;End Includes&quot;)</span>
<span class="PreProc">#define SIZE(X) (assert((X)</span><span class="Delimiter">.</span><span class="PreProc">size() &lt; (</span><span class="Constant">1LL</span><span class="PreProc">&lt;&lt;(</span><span class="Normal">sizeof</span><span class="PreProc">(</span><span class="Normal">int</span><span class="PreProc">)*</span><span class="Constant">8</span><span class="PreProc">-</span><span class="Constant">2</span><span class="PreProc">)))</span><span class="Delimiter">,</span><span class="PreProc"> </span><span class="Normal">static_cast</span><span class="PreProc">&lt;</span><span class="Normal">int</span><span class="PreProc">&gt;((X)</span><span class="Delimiter">.</span><span class="PreProc">size()))</span>
<span class="Comment">//:</span>
<span class="Comment">//: 5. Integer overflow is still impossible to guard against. Maybe after</span>
<span class="Comment">//: reading <a href="http://www.cs.utah.edu/~regehr/papers/overflow12.pdf">http://www.cs.utah.edu/~regehr/papers/overflow12.pdf</a></span>
<span class="Comment">//:</span>
<span class="Comment">//: 6. Map's operator[] being non-const is fucking evil.</span>
<span class="Delimiter">:(before &quot;Globals&quot;)</span>  <span class="Comment">// can't generate prototypes for these</span>
<span class="Comment">// from <a href="http://stackoverflow.com/questions/152643/idiomatic-c-for-reading-from-a-const-map">http://stackoverflow.com/questions/152643/idiomatic-c-for-reading-from-a-const-map</a></span>
<span class="Normal">template</span>&lt;<span class="Normal">typename</span> T&gt; <span class="Normal">typename</span> T::mapped_type&amp; get<span class="Delimiter">(</span>T&amp; map<span class="Delimiter">,</span> <span class="Normal">typename</span> T::key_type <span class="Normal">const</span>&amp; key<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  <span class="Normal">typename</span> T::iterator iter<span class="Delimiter">(</span>map<span class="Delimiter">.</span>find<span class="Delimiter">(</span>key<span class="Delimiter">));</span>
  assert<span class="Delimiter">(</span>iter != map<span class="Delimiter">.</span>end<span class="Delimiter">());</span>
  <span class="Identifier">return</span> iter<span class="Delimiter">-&gt;</span>second<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Normal">template</span>&lt;<span class="Normal">typename</span> T&gt; <span class="Normal">typename</span> T::mapped_type <span class="Normal">const</span>&amp; get<span class="Delimiter">(</span><span class="Normal">const</span> T&amp; map<span class="Delimiter">,</span> <span class="Normal">typename</span> T::key_type <span class="Normal">const</span>&amp; key<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  <span class="Normal">typename</span> T::const_iterator iter<span class="Delimiter">(</span>map<span class="Delimiter">.</span>find<span class="Delimiter">(</span>key<span class="Delimiter">));</span>
  assert<span class="Delimiter">(</span>iter != map<span class="Delimiter">.</span>end<span class="Delimiter">());</span>
  <span class="Identifier">return</span> iter<span class="Delimiter">-&gt;</span>second<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Normal">template</span>&lt;<span class="Normal">typename</span> T&gt; <span class="Normal">typename</span> T::mapped_type <span class="Normal">const</span>&amp; put<span class="Delimiter">(</span>T&amp; map<span class="Delimiter">,</span> <span class="Normal">typename</span> T::key_type <span class="Normal">const</span>&amp; key<span class="Delimiter">,</span> <span class="Normal">typename</span> T::mapped_type <span class="Normal">const</span>&amp; value<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  map[key] = value<span class="Delimiter">;</span>
  <span class="Identifier">return</span> map[key]<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Normal">template</span>&lt;<span class="Normal">typename</span> T&gt; <span class="Normal">bool</span> contains_key<span class="Delimiter">(</span>T&amp; map<span class="Delimiter">,</span> <span class="Normal">typename</span> T::key_type <span class="Normal">const</span>&amp; key<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  <span class="Identifier">return</span> map<span class="Delimiter">.</span>find<span class="Delimiter">(</span>key<span class="Delimiter">)</span> != map<span class="Delimiter">.</span>end<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
<span class="Normal">template</span>&lt;<span class="Normal">typename</span> T&gt; <span class="Normal">typename</span> T::mapped_type&amp; get_or_insert<span class="Delimiter">(</span>T&amp; map<span class="Delimiter">,</span> <span class="Normal">typename</span> T::key_type <span class="Normal">const</span>&amp; key<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  <span class="Identifier">return</span> map[key]<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Comment">//: The contract: any container that relies on get_or_insert should never call</span>
<span class="Comment">//: contains_key.</span>
<span class="Comment">//:</span>
<span class="Comment">//: 7. istreams are a royal pain in the arse. You have to be careful about</span>
<span class="Comment">//: what subclass you try to putback into. You have to watch out for the pesky</span>
<span class="Comment">//: failbit and badbit. Just avoid eof() and use this helper instead.</span>
<span class="Normal">bool</span> has_data<span class="Delimiter">(</span>istream&amp; in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  <span class="Identifier">return</span> in &amp;&amp; !in<span class="Delimiter">.</span>eof<span class="Delimiter">();</span>
<span class="Delimiter">}</span>

<span class="Delimiter">:(before &quot;End Includes&quot;)</span>
<span class="PreProc">#include</span><span class="Constant">&lt;assert.h&gt;</span>

<span class="PreProc">#include</span><span class="Constant">&lt;iostream&gt;</span>
<span class="Normal">using</span> std::istream<span class="Delimiter">;</span>
<span class="Normal">using</span> std::ostream<span class="Delimiter">;</span>
<span class="Normal">using</span> std::iostream<span class="Delimiter">;</span>
<span class="Normal">using</span> std::cin<span class="Delimiter">;</span>
<span class="Normal">using</span> std::cout<span class="Delimiter">;</span>
<span class="Normal">using</span> std::cerr<span class="Delimiter">;</span>
<span class="PreProc">#include</span><span class="Constant">&lt;iomanip&gt;</span>

<span class="PreProc">#include</span><span class="Constant">&lt;cstring&gt;</span>
<span class="PreProc">#include</span><span class="Constant">&lt;string&gt;</span>
<span class="Normal">using</span> std::string<span class="Delimiter">;</span>
</pre>
</body>
</html>
<!-- vim: set foldmethod=manual : -->