From 2a4088119cf41175457414dfa59bd4064b8f0562 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Wed, 1 Jan 2020 17:04:37 -0800 Subject: 5852 --- archive/2.vm/088file.mu | 213 ------------------------------------------------ 1 file changed, 213 deletions(-) delete mode 100644 archive/2.vm/088file.mu (limited to 'archive/2.vm/088file.mu') diff --git a/archive/2.vm/088file.mu b/archive/2.vm/088file.mu deleted file mode 100644 index da3e35d3..00000000 --- a/archive/2.vm/088file.mu +++ /dev/null @@ -1,213 +0,0 @@ -# Wrappers around file system primitives that take a 'resources' object and -# are thus easier to test. -# -# - start-reading - asynchronously open a file, returning a channel source for -# receiving the results -# - start-writing - asynchronously open a file, returning a channel sink for -# the data to write -# - slurp - synchronously read from a file -# - dump - synchronously write to a file - -container resources [ - lock:bool - data:&:@:resource -] - -container resource [ - name:text - contents:text -] - -def start-reading resources:&:resources, filename:text -> contents:&:source:char, error?:bool [ - local-scope - load-inputs - error? <- copy false - { - break-unless resources - # fake file system - contents, error? <- start-reading-from-fake-resource resources, filename - return - } - # real file system - file:num <- $open-file-for-reading filename - return-unless file, null/no-contents, true/error - contents:&:source:char, sink:&:sink:char <- new-channel 30 - start-running receive-from-file file, sink -] - -def slurp resources:&:resources, filename:text -> contents:text, error?:bool [ - local-scope - load-inputs - source:&:source:char, error?:bool <- start-reading resources, filename - return-if error?, null/no-contents - buf:&:buffer:char <- new-buffer 30/capacity - { - c:char, done?:bool, source <- read source - break-if done? - buf <- append buf, c - loop - } - contents <- buffer-to-array buf -] - -def start-reading-from-fake-resource resources:&:resources, resource:text -> contents:&:source:char, error?:bool [ - local-scope - load-inputs - error? <- copy false - i:num <- copy 0 - data:&:@:resource <- get *resources, data:offset - len:num <- length *data - { - done?:bool <- greater-or-equal i, len - break-if done? - tmp:resource <- index *data, i - i <- add i, 1 - curr-resource:text <- get tmp, name:offset - found?:bool <- equal resource, curr-resource - loop-unless found? - contents:&:source:char, sink:&:sink:char <- new-channel 30 - curr-contents:text <- get tmp, contents:offset - start-running receive-from-text curr-contents, sink - return - } - return null/no-such-resource, true/error-found -] - -def receive-from-file file:num, sink:&:sink:char -> sink:&:sink:char [ - local-scope - load-inputs - { - c:char, eof?:bool <- $read-from-file file - break-if eof? - sink <- write sink, c - loop - } - sink <- close sink - file <- $close-file file -] - -def receive-from-text contents:text, sink:&:sink:char -> sink:&:sink:char [ - local-scope - load-inputs - i:num <- copy 0 - len:num <- length *contents - { - done?:bool <- greater-or-equal i, len - break-if done? - c:char <- index *contents, i - sink <- write sink, c - i <- add i, 1 - loop - } - sink <- close sink -] - -def start-writing resources:&:resources, filename:text -> sink:&:sink:char, routine-id:num, error?:bool [ - local-scope - load-inputs - error? <- copy false - source:&:source:char, sink:&:sink:char <- new-channel 30 - { - break-unless resources - # fake file system - routine-id <- start-running transmit-to-fake-resource resources, filename, source - return - } - # real file system - file:num <- $open-file-for-writing filename - return-unless file, null/sink, 0/routine-id, true/error - { - break-if file - msg:text <- append [no such file: ] filename - assert file, msg - } - routine-id <- start-running transmit-to-file file, source -] - -def dump resources:&:resources, filename:text, contents:text -> resources:&:resources, error?:bool [ - local-scope - load-inputs - # todo: really create an empty file - return-unless contents, resources, false/no-error - sink-file:&:sink:char, write-routine:num, error?:bool <- start-writing resources, filename - return-if error? - i:num <- copy 0 - len:num <- length *contents - { - done?:bool <- greater-or-equal i, len - break-if done? - c:char <- index *contents, i - sink-file <- write sink-file, c - i <- add i, 1 - loop - } - close sink-file - # make sure to wait for the file to be actually written to disk - # (Mu practices structured concurrency: http://250bpm.com/blog:71) - wait-for-routine write-routine -] - -def transmit-to-file file:num, source:&:source:char -> source:&:source:char [ - local-scope - load-inputs - { - c:char, done?:bool, source <- read source - break-if done? - $write-to-file file, c - loop - } - file <- $close-file file -] - -def transmit-to-fake-resource resources:&:resources, filename:text, source:&:source:char -> resources:&:resources, source:&:source:char [ - local-scope - load-inputs - lock:location <- get-location *resources, lock:offset - wait-for-reset-then-set lock - # compute new file contents - buf:&:buffer:char <- new-buffer 30 - { - c:char, done?:bool, source <- read source - break-if done? - buf <- append buf, c - loop - } - contents:text <- buffer-to-array buf - new-resource:resource <- merge filename, contents - # write to resources - curr-filename:text <- copy null - data:&:@:resource <- get *resources, data:offset - # replace file contents if it already exists - i:num <- copy 0 - len:num <- length *data - { - done?:bool <- greater-or-equal i, len - break-if done? - tmp:resource <- index *data, i - curr-filename <- get tmp, name:offset - found?:bool <- equal filename, curr-filename - { - break-unless found? - put-index *data, i, new-resource - jump +unlock-and-exit - } - i <- add i, 1 - loop - } - # if file didn't already exist, make room for it - new-len:num <- add len, 1 - new-data:&:@:resource <- new resource:type, new-len - put *resources, data:offset, new-data - # copy over old files - i:num <- copy 0 - { - done?:bool <- greater-or-equal i, len - break-if done? - tmp:resource <- index *data, i - put-index *new-data, i, tmp - } - # write new file - put-index *new-data, len, new-resource - +unlock-and-exit - reset lock -] -- cgit 1.4.1-2-gfad0