changeset 297:abe3141caefe

Added file module and sample
author Michael Pavone <pavone@retrodev.com>
date Thu, 24 Jul 2014 23:53:54 -0700
parents 2a0a88799737
children 647f7a2d253b
files modules/file.tp samples/file.tp
diffstat 2 files changed, 187 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/file.tp	Thu Jul 24 23:53:54 2014 -0700
@@ -0,0 +1,169 @@
+{
+	_getStdin <- {
+		_stdin <- (file fromFD: 0)
+		_getStdin <- { _stdin }
+		_stdin
+	}
+	_getStdout <- {
+		_stdout <- (file fromFD: 1)
+		_getStdout <- { _stdout }
+		_stdout
+	}
+	_getStderr <- {
+		_stderr <- (file fromFD: 2)
+		_getStderr <- { _stderr }
+		_stderr
+	}
+	#{
+		fromFD <- :_fd {
+			_buffers <- #[]
+			_readPos <- 0
+			_buffered <- 0
+			_bufferChunk <- 4096
+			_eof? <- false
+			_addBuffer <- {
+				newbuf <- bytearray normal: _bufferChunk
+				justRead <- os readFrom: _fd to: newbuf
+				if: justRead > 0 {
+					_buffered <- _buffered + justRead
+					_buffers append: (newbuf shrinkTo: justRead)
+				} else: {
+					_eof? <- true
+				}
+			}
+			_lineIter <- :f {
+				iter <- #{
+					foreach <- :self fun {
+						idx <- 0
+						while: { not: (f eof?) } do: {
+							line <- f nextLine
+							fun: idx line
+							idx <- idx + 1
+						}
+						self
+					}
+
+					map <- :fun {
+						new <- #[]
+						foreach: :idx el {
+							new append: (fun: el)
+						}
+						new
+					}
+
+					filter <- :fun {
+						new <- #[]
+						foreach: :idx el {
+							if: (fun: el) {
+								new append: el
+							}
+						}
+						new
+					}
+
+					fold:with <- :acc :fun {
+						foreach: :idx el {
+							acc <- fun: acc el
+						}
+						acc
+					}
+
+					foldr:with <- :acc :fun {
+						(map: :el { el }) foldr: acc with: fun
+					}
+				}
+				_lineIter <- { iter }
+				iter
+			}
+			#{
+				read <- :bytes {
+					while: { bytes > _buffered && (not: _eof?)} do: {
+						_addBuffer:
+					}
+					nextBuffers <- #[]
+					pieces <- #[]
+					toRead <- bytes
+					i <- 0
+					while: { toRead > 0 && i < (_buffers length) } do: {
+						curBuf <- _buffers get: i
+						if: toRead >= (curBuf length) - _readPos {
+							pieces append: (curBuf stringFrom: _readPos to: (curBuf length))
+							_buffered <- _buffered - ((curBuf length) - _readPos)
+							toRead <- toRead - ((curBuf length) - _readPos)
+							_readPos <- 0
+						} else: {
+							nextPos <- _readPos + toRead
+							pieces append: (curBuf stringFrom: _readPos to: nextPos)
+							_readPos <- nextPos
+							_buffered <- _buffered - toRead
+							toRead <- 0
+							nextBuffers append: curBuf
+						}
+						i <- i + 1
+					}
+
+					while: {i < (_buffers length)} do: {
+						nextBuffers append: (_buffers get: i)
+						i <- i + 1
+					}
+					_buffers <- nextBuffers
+					pieces join: ""
+				}
+				write <- :data {
+					//TODO: write buffering for small writes
+					os write: _fd data
+				}
+				nextLine <- {
+					nl <- "\n" byte: 0
+					notfound <- true
+					pos <- 0
+					i <- 0
+					while: { notfound } do: {
+						while: { notfound && i < (_buffers length) } do: {
+							curBuf <- _buffers get: i
+							start <- if: i = 0 { _readPos } else: { 0 }
+							curBuf findChar: nl from: start :idx {
+								notfound <- false
+								pos <- pos + idx + 1
+							} else: {
+								pos <- pos + (curBuf length)
+							}
+
+							i <- i + 1
+						}
+
+						if: notfound && (not: _eof?) {
+							_addBuffer:
+						} else: {
+							notfound <- false
+						}
+					}
+					read: pos - _readPos
+				}
+				lines <- {
+					_lineIter: self
+				}
+				close <- {
+					os close: _fd
+				}
+				eof? <- { _eof? && _buffered <= 0 }
+			}
+		}
+
+		open <- :filename {
+			fromFD: (os open: filename (os O_RDONLY))
+		}
+
+		openWrite <- :filename {
+			fromFD: (os open: filename ((os O_WRONLY) or (os O_CREAT) or (os O_TRUNC)) 0x1B6)
+		}
+
+		openAppend <- :filename {
+			fromFD: (os open: filename ((os O_RDWR) or (os O_CREAT) or (os O_APPEND)) 0x1B6)
+		}
+
+		stdin <- { _getStdin: }
+		stdout <- { _getStdout: }
+		stderr <- { _getStderr: }
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/file.tp	Thu Jul 24 23:53:54 2014 -0700
@@ -0,0 +1,18 @@
+#{
+	import: [
+		stdin
+		stdout
+	] from: file
+	main <- {
+		stdout write: "Hello from the file module!\nWhat's your name?\n"
+		name <- (stdin nextLine) trim
+		stdout write: "Nice to meet you " . name . ". Here's my source code:\n\n"
+		f <- file open: "samples/file.tp"
+		foreach: (f lines) :num text {
+			print: (string: num+1) . ": " . text
+		}
+		print: "\n"
+		f close
+		0
+	}
+}