diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2016-12-11 16:18:18 -0800 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2016-12-11 16:18:18 -0800 |
commit | 294b2ab35983ebe95698835bb54bca8bd3eec101 (patch) | |
tree | fbc74bea6cefd7b8f527d36a7b7c6804dd886414 /html/088file.mu.html | |
parent | d5c86dfd8706e6b3ceee7843464797e6fcad4259 (diff) | |
download | mu-294b2ab35983ebe95698835bb54bca8bd3eec101.tar.gz |
3705 - switch to tested file-system primitives
Diffstat (limited to 'html/088file.mu.html')
-rw-r--r-- | html/088file.mu.html | 65 |
1 files changed, 57 insertions, 8 deletions
diff --git a/html/088file.mu.html b/html/088file.mu.html index 49801745..aae7cae6 100644 --- a/html/088file.mu.html +++ b/html/088file.mu.html @@ -33,6 +33,13 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color <pre id='vimCodeElement'> <span class="Comment"># Wrappers around file system primitives that take a 'resources' object and</span> <span class="Comment"># are thus easier to test.</span> +<span class="Comment">#</span> +<span class="Comment"># - start-reading - asynchronously open a file, returning a channel source for</span> +<span class="Comment"># receiving the results</span> +<span class="Comment"># - start-writing - asynchronously open a file, returning a channel sink for</span> +<span class="Comment"># the data to write</span> +<span class="Comment"># - slurp - synchronously read from a file</span> +<span class="Comment"># - dump - synchronously write to a file</span> <span class="muData">container</span> resources [ lock:bool @@ -44,25 +51,42 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color contents:text ] -<span class="muRecipe">def</span> start-reading resources:&:resources, filename:text<span class="muRecipe"> -> </span>contents:&:source:char [ +<span class="muRecipe">def</span> start-reading resources:&:resources, filename:text<span class="muRecipe"> -> </span>contents:&:source:char, error?:bool [ <span class="Constant">local-scope</span> <span class="Constant">load-ingredients</span> + error? <span class="Special"><-</span> copy <span class="Constant">0/false</span> <span class="Delimiter">{</span> <span class="muControl">break-unless</span> resources <span class="Comment"># fake file system</span> - contents <span class="Special"><-</span> start-reading-from-fake-resources resources, filename + contents, error? <span class="Special"><-</span> start-reading-from-fake-resource resources, filename <span class="muControl">return</span> <span class="Delimiter">}</span> <span class="Comment"># real file system</span> file:num <span class="Special"><-</span> $open-file-for-reading filename - assert file, <span class="Constant">[file not found]</span> + <span class="muControl">return-unless</span> file, <span class="Constant">0/contents</span>, <span class="Constant">1/error?</span> contents:&:source:char, sink:&:sink:char <span class="Special"><-</span> new-channel<span class="Constant"> 30</span> start-running receive-from-file file, sink ] -<span class="muRecipe">def</span> start-reading-from-fake-resources resources:&:resources, resource:text<span class="muRecipe"> -> </span>contents:&:source:char [ +<span class="muRecipe">def</span> slurp resources:&:resources, filename:text<span class="muRecipe"> -> </span>contents:text, error?:bool [ <span class="Constant">local-scope</span> <span class="Constant">load-ingredients</span> + source:&:source:char, error?:bool <span class="Special"><-</span> start-reading resources, filename + <span class="muControl">return-if</span> error?, <span class="Constant">0/contents</span> + buf:&:buffer <span class="Special"><-</span> new-buffer <span class="Constant">30/capacity</span> + <span class="Delimiter">{</span> + c:char, done?:bool, source <span class="Special"><-</span> read source + <span class="muControl">break-if</span> done? + buf <span class="Special"><-</span> append buf, c + <span class="muControl">loop</span> + <span class="Delimiter">}</span> + contents <span class="Special"><-</span> buffer-to-array buf +] + +<span class="muRecipe">def</span> start-reading-from-fake-resource resources:&:resources, resource:text<span class="muRecipe"> -> </span>contents:&:source:char, error?:bool [ + <span class="Constant">local-scope</span> + <span class="Constant">load-ingredients</span> + error? <span class="Special"><-</span> copy <span class="Constant">0/no-error</span> i:num <span class="Special"><-</span> copy<span class="Constant"> 0</span> data:&:@:resource <span class="Special"><-</span> get *resources, <span class="Constant">data:offset</span> len:num <span class="Special"><-</span> length *data @@ -79,7 +103,7 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color start-running receive-from-text curr-contents, sink <span class="muControl">return</span> <span class="Delimiter">}</span> - <span class="muControl">return</span> <span class="Constant">0/not-found</span> + <span class="muControl">return</span> <span class="Constant">0/not-found</span>, <span class="Constant">1/error</span> ] <span class="muRecipe">def</span> receive-from-file file:num, sink:&:sink:char<span class="muRecipe"> -> </span>sink:&:sink:char [ @@ -111,18 +135,20 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color sink <span class="Special"><-</span> close sink ] -<span class="muRecipe">def</span> start-writing resources:&:resources, filename:text<span class="muRecipe"> -> </span>sink:&:sink:char, routine-id:num [ +<span class="muRecipe">def</span> start-writing resources:&:resources, filename:text<span class="muRecipe"> -> </span>sink:&:sink:char, routine-id:num, error?:bool [ <span class="Constant">local-scope</span> <span class="Constant">load-ingredients</span> + error? <span class="Special"><-</span> copy <span class="Constant">0/false</span> source:&:source:char, sink:&:sink:char <span class="Special"><-</span> new-channel<span class="Constant"> 30</span> <span class="Delimiter">{</span> <span class="muControl">break-unless</span> resources <span class="Comment"># fake file system</span> - routine-id <span class="Special"><-</span> start-running transmit-to-fake-file resources, filename, source + routine-id <span class="Special"><-</span> start-running transmit-to-fake-resource resources, filename, source <span class="muControl">return</span> <span class="Delimiter">}</span> <span class="Comment"># real file system</span> file:num <span class="Special"><-</span> $open-file-for-writing filename + <span class="muControl">return-unless</span> file, <span class="Constant">0/sink</span>, <span class="Constant">0/routine-id</span>, <span class="Constant">1/error?</span> <span class="Delimiter">{</span> <span class="muControl">break-if</span> file msg:text <span class="Special"><-</span> append <span class="Constant">[no such file: ]</span> filename @@ -131,6 +157,29 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color routine-id <span class="Special"><-</span> start-running transmit-to-file file, source ] +<span class="muRecipe">def</span> dump resources:&:resources, filename:text, contents:text<span class="muRecipe"> -> </span>resources:&:resources, error?:bool [ + <span class="Constant">local-scope</span> + <span class="Constant">load-ingredients</span> + <span class="Comment"># todo: really create an empty file</span> + <span class="muControl">return-unless</span> contents, resources, <span class="Constant">0/no-error</span> + sink-file:&:sink:char, write-routine:num, error?:bool <span class="Special"><-</span> start-writing resources, filename + <span class="muControl">return-if</span> error? + i:num <span class="Special"><-</span> copy<span class="Constant"> 0</span> + len:num <span class="Special"><-</span> length *contents + <span class="Delimiter">{</span> + done?:bool <span class="Special"><-</span> greater-or-equal i, len + <span class="muControl">break-if</span> done? + c:char <span class="Special"><-</span> index *contents, i + sink-file <span class="Special"><-</span> write sink-file, c + i <span class="Special"><-</span> add i,<span class="Constant"> 1</span> + <span class="muControl">loop</span> + <span class="Delimiter">}</span> + close sink-file + <span class="Comment"># make sure to wait for the file to be actually written to disk</span> + <span class="Comment"># (Mu practices structured concurrency: <a href="http://250bpm.com/blog:71)">http://250bpm.com/blog:71)</a></span> + wait-for-routine write-routine +] + <span class="muRecipe">def</span> transmit-to-file file:num, source:&:source:char<span class="muRecipe"> -> </span>source:&:source:char [ <span class="Constant">local-scope</span> <span class="Constant">load-ingredients</span> @@ -143,7 +192,7 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color file <span class="Special"><-</span> $close-file file ] -<span class="muRecipe">def</span> transmit-to-fake-file resources:&:resources, filename:text, source:&:source:char<span class="muRecipe"> -> </span>resources:&:resources, source:&:source:char [ +<span class="muRecipe">def</span> transmit-to-fake-resource resources:&:resources, filename:text, source:&:source:char<span class="muRecipe"> -> </span>resources:&:resources, source:&:source:char [ <span class="Constant">local-scope</span> <span class="Constant">load-ingredients</span> lock:location <span class="Special"><-</span> get-location *resources, <span class="Constant">lock:offset</span> |