dtrg avatar dtrg committed 007620d

Rejigged a lot of the runtime library to be a bit more cowbelly.

Comments (0)

Files changed (20)

include/Application.ch

 #include <Stdlib.ch>
 #include <Array.ch>
 
-/** Returns an immutable array of command line arguments.
- **/
+var Application =
+{
+	/** Returns an immutable array of command line arguments.
+	 **/
+	
+	function Arguments(): Array<string>
+		return
+		{
+			implements Array<string>;
+			
+			function get(i: int): string
+			{
+				var argc = extern(int);
+				extern "${argc} = s_argc;";
+				if (i >= argc)
+					AbortOutOfBounds();
+				
+				var result = extern(string);
+				extern "${result} = s_argv[${i}];";
+				return result;
+			}
+			
+			function set(i: int, value: string)
+				AbortOperationNotSupported();
+			
+			function bounds(): (low: int, high: int)
+			{
+				low = 0;
+				high = extern(int);
+				extern "${high} = s_argc;";
+			}
+		};
 
-function ApplicationArguments(): Array<string>
-	return
+	/** Stops execution.
+	 **/
+	 
+	function Exit(result: int)
 	{
-		implements Array<string>;
+		extern 'exit(${result});';
+	}
+
+	/** Stops execution with a runtime error.
+	 **/
 		
-		function get(i: int): string
-		{
-			var argc = extern(int);
-			extern "${argc} = s_argc;";
-			if (i >= argc)
-				AbortOutOfBounds();
-			
-			var result = extern(string);
-			extern "${result} = s_argv[${i}];";
-			return result;
-		}
+	function Abort(message: string)
+	{
+		extern 'fprintf(stderr, "Runtime error: %s\\n", s_string_cdata(${message}));';
+		extern 'exit(1);'; 
+	}
+
+	/** Stops execution with an 'Out of bounds access' error.
+	 **/
+	 
+	function AbortOutOfBounds()
+	 	Abort("out of bounds access");
+	 	
+	/** Stops execution with an 'Operation not supported' error.
+	 **/
+	 
+	function AbortOperationNotSupported()
+		Abort("operation not supported");
 		
-		function set(i: int, value: string)
-			AbortOperationNotSupported();
+	/** Stops execution with an 'Invalid object state' error.
+	 **/
+	 
+	function AbortInvalidObjectState()
+		Abort("invalid object state");
 		
-		function bounds(): (low: int, high: int)
-		{
-			low = 0;
-			high = extern(int);
-			extern "${high} = s_argc;";
-		}
-	};
-
-/** Stops execution.
- **/
- 
-function Exit(result: int)
-{
-	extern 'exit(${result});';
-}
-
-/** Stops execution with a runtime error.
- **/
-	
-function Abort(message: string)
-{
-	extern 'fprintf(stderr, "Runtime error: %s\\n", s_string_cdata(${message}));';
-	extern 'exit(1);'; 
-}
-
-/** Stops execution with an 'Out of bounds access' error.
- **/
- 
-function AbortOutOfBounds()
- 	Abort("out of bounds access");
- 	
-/** Stops execution with an 'Operation not supported' error.
- **/
- 
-function AbortOperationNotSupported()
-	Abort("operation not supported");
-	
-/** Stops execution with an 'Invalid object state' error.
- **/
- 
-function AbortInvalidObjectState()
-	Abort("invalid object state");
-	
-/** Stops execution with an 'Out of memory' error.
- **/
- 
-function AbortOutOfMemory()
-	Abort("out of memory");
+	/** Stops execution with an 'Out of memory' error.
+	 **/
+	 
+	function AbortOutOfMemory()
+		Abort("out of memory");
+};
 	
 #endif
 		function _boundscheck(i: int)
 		{
 			if (i < 0)
-				AbortOutOfBounds();
+				Application.AbortOutOfBounds();
 			else if (i >= size)
-				AbortOutOfBounds(); 
+				Application.AbortOutOfBounds(); 
 		}
 				
 		function get(i: int): (result: T)
 		function _boundscheck(x: int, y: int)
 		{
 			if (x < 0)
-				AbortOutOfBounds();
+				Application.AbortOutOfBounds();
 			if (x >= width)
-				AbortOutOfBounds();
+				Application.AbortOutOfBounds();
 			if (y < 0)
-				AbortOutOfBounds();
+				Application.AbortOutOfBounds();
 			if (y >= height)
-				AbortOutOfBounds();
+				Application.AbortOutOfBounds();
 		}
 				
 		function get(x: int, y: int): (result: T)

include/Buffer.ch

 	function toString(): string;
 };
 
-/** Creates a 0-based one-dimensional array of bytes.
- **
- ** All entries in the array are initialised to 0.
- **/
- 
-function Buffer(size: int): Buffer
+var Buffer =
 {
-	var capacity = size;
-	var ptr: __extern = extern(__extern);
-	extern "${ptr} = S_ALLOC_DATA(${size});";
+	/** Creates a 0-based one-dimensional array of bytes.
+	 **
+	 ** All entries in the array are initialised to 0.
+	 **/
+	 
+	function New(size: int): Buffer
+	{
+		var capacity = size;
+		var ptr: __extern = extern(__extern);
+		extern "${ptr} = S_ALLOC_DATA(${size});";
+		
+		return
+		{
+			implements Array<int>;
+			implements Buffer;
 	
-	return
+			function _boundscheck(i: int)
+			{
+				if (i < 0)
+					Application.AbortOutOfBounds();
+				else if (i >= size)
+					Application.AbortOutOfBounds(); 
+			}
+					
+			function get(i: int): (result: int)
+			{
+				_boundscheck(i);
+				result = extern(int);
+				extern "${result} = ((uint8_t*)${ptr})[${i}];";
+			}
+			
+			function set(i: int, value: int)
+			{
+				_boundscheck(i);
+				extern "((uint8_t*)${ptr})[${i}] = ${value};";
+			}
+			
+			function bounds(): (low: int, high: int)
+			{
+				low = 0;
+				high = size;
+			}
+			
+			function resize(newsize: int)
+			{
+				if (newsize <= capacity)
+				{
+					size = newsize;
+					return;
+				}
+	
+				var newcapacity = capacity + 1;
+				while (newcapacity < newsize)
+					newcapacity = newcapacity * 2;
+				
+				var newptr: __extern = extern(__extern);
+				extern '${newptr} = S_REALLOC_DATA(${ptr}, ${newcapacity});';
+				if (newptr.isNull())
+					Application.AbortOutOfMemory();
+				
+				var delta = newcapacity - capacity;
+				extern 'memset(${newptr} + ${capacity}, 0, ${delta});';
+				
+				ptr = newptr;
+				capacity = newcapacity;
+				size = newsize;
+			}
+			
+			function append(value: int)
+			{
+				var o = size;
+				resize(size+1);
+				set(o, value);
+			}
+			
+			function toString(): (result: string)
+			{
+				result = extern(string);
+				extern '${result} = s_create_string_val(${ptr}, ${size});';
+			}
+		};
+	}
+	
+	/** Creates an immutable Buffer pointing at the UTF-8 bytes of a string. */
+	
+	function NewFromString(value: string): Buffer
 	{
-		implements Array<int>;
-		implements Buffer;
-
-		function _boundscheck(i: int)
+		var size = extern(int);
+		var ptr = extern(__extern);
+		extern '${size} = ${value}->totallength;';
+		extern '${ptr} = (void*) s_string_cdata(${value});';
+		
+		return
 		{
-			if (i < 0)
-				AbortOutOfBounds();
-			else if (i >= size)
-				AbortOutOfBounds(); 
-		}
-				
-		function get(i: int): (result: int)
-		{
-			_boundscheck(i);
-			result = extern(int);
-			extern "${result} = ((uint8_t*)${ptr})[${i}];";
-		}
-		
-		function set(i: int, value: int)
-		{
-			_boundscheck(i);
-			extern "((uint8_t*)${ptr})[${i}] = ${value};";
-		}
-		
-		function bounds(): (low: int, high: int)
-		{
-			low = 0;
-			high = size;
-		}
-		
-		function resize(newsize: int)
-		{
-			if (newsize <= capacity)
+			implements Array<int>;
+			implements Buffer;
+	
+			function _boundscheck(i: int)
 			{
-				size = newsize;
-				return;
+				if (i < 0)
+					Application.AbortOutOfBounds();
+				else if (i >= size)
+					Application.AbortOutOfBounds(); 
 			}
-
-			var newcapacity = capacity + 1;
-			while (newcapacity < newsize)
-				newcapacity = newcapacity * 2;
+					
+			function get(i: int): (result: int)
+			{
+				_boundscheck(i);
+				result = extern(int);
+				extern "${result} = ((uint8_t*)${ptr})[${i}];";
+			}
 			
-			var newptr: __extern = extern(__extern);
-			extern '${newptr} = S_REALLOC_DATA(${ptr}, ${newcapacity});';
-			if (newptr.isNull())
-				AbortOutOfMemory();
+			function set(i: int, value: int)
+			{
+				Application.AbortOperationNotSupported();
+			}
 			
-			var delta = newcapacity - capacity;
-			extern 'memset(${newptr} + ${capacity}, 0, ${delta});';
+			function bounds(): (low: int, high: int)
+			{
+				low = 0;
+				high = size;
+			}
 			
-			ptr = newptr;
-			capacity = newcapacity;
-			size = newsize;
-		}
-		
-		function append(value: int)
-		{
-			var o = size;
-			resize(size+1);
-			set(o, value);
-		}
-		
-		function toString(): (result: string)
-		{
-			result = extern(string);
-			extern '${result} = s_create_string_val(${ptr}, ${size});';
-		}
-	};
-}
-
-/** Creates an immutable Buffer pointing at the UTF-8 bytes of a string. */
-
-function BufferFromString(value: string): Buffer
-{
-	var size = extern(int);
-	var ptr = extern(__extern);
-	extern '${size} = ${value}->totallength;';
-	extern '${ptr} = (void*) s_string_cdata(${value});';
-	
-	return
-	{
-		implements Array<int>;
-		implements Buffer;
-
-		function _boundscheck(i: int)
-		{
-			if (i < 0)
-				AbortOutOfBounds();
-			else if (i >= size)
-				AbortOutOfBounds(); 
-		}
-				
-		function get(i: int): (result: int)
-		{
-			_boundscheck(i);
-			result = extern(int);
-			extern "${result} = ((uint8_t*)${ptr})[${i}];";
-		}
-		
-		function set(i: int, value: int)
-		{
-			AbortOperationNotSupported();
-		}
-		
-		function bounds(): (low: int, high: int)
-		{
-			low = 0;
-			high = size;
-		}
-		
-		function resize(newsize: int)
-		{
-			AbortOperationNotSupported();
-		}
-		
-		function append(value: int)
-		{
-			AbortOperationNotSupported();
-		}
-		
-		function toString(): (result: string)
-		{
-			return value;
-		}
-	};
-}
+			function resize(newsize: int)
+			{
+				Application.AbortOperationNotSupported();
+			}
+			
+			function append(value: int)
+			{
+				Application.AbortOperationNotSupported();
+			}
+			
+			function toString(): (result: string)
+			{
+				return value;
+			}
+		};
+	}
+};
 
 #endif
 #include <StreamIO.ch>
 
 extern '#include <errno.h>';
+extern '#include <unistd.h>';
 
-/** Represents a file.
+/** Represents an open file.
  **/
  
 type File =
 {
-	/** Attempts to remove the file. Returns 0 on success, or an errno on
-	 ** error. Produces a runtime error if the file is open.
-	 **/
-	 
-	function remove(): int;
-			
 	/** Attempts to close the file. Returns 0 on success, or an errno on
 	 ** error. */
 	 
 	function close(): int;
+
+	/** Flushes the file. Returns 0 on success, or an errno on error.
+	 **/
+	 
+	function flush(): int;
+	
+	/** Returns the length of the file.
+	 **/
+	 
+	function length(): int;
+	
+	/** Writes a byte of data from the file. Returns 0 on success, or an
+	 ** errno on error.
+	 **/
+	 
+	function write(position: int, byte: int): int; 
+	
+	/** Reads a block of data to the file. Returns the byte on success, or
+	 ** -1 on error.
+	 **/
+	 
+	function read(position: int): int;
+};
+
+var File =
+{
+	/** Attempts to change the current working directory. Returns 0 on success,
+	 ** or an errno on error. */
+	 
+	function ChDir(filename: string): (result: int)
+	{
+		result = extern(int);
+		extern 'errno = 0; chdir(s_string_cdata(${filename})); ${result} = errno;';
+	}
+	
+	/** Returns the current working directory.
+	 **/
+	 
+	function GetCWD(): (result: string)
+	{
+		var e = extern(int);
+		result = extern(string);
+		
+		extern 'char buffer[PATH_MAX];';
+		extern 'errno = 0; getcwd(buffer, sizeof(buffer)); ${e} = errno';
+		if (e != 0)
+			Application.Abort("Unable to fetch CWD: " + e.toString());
 			
-	/** Attempts to create the file. Returns 0 on success, or an errno on
+		extern '${result} = s_create_string_val(buffer, strlen(buffer));';
+	}
+		
+	/** Attempts to remove a file. Returns 0 on success, or an errno on
 	 ** error. */
 	 
-	function create(): int;
+	function Remove(filename: string): (result: int)
+	{
+		result = extern(int);
+		extern 'errno = 0; remove(s_string_cdata(${filename})); ${result} = errno;';
+	}
+	
+	/** Attempts to create a directory. Returns 0 on success, or an errno on
+	 ** error. */
+	
+	function MkDir(filename: string): (result: int)
+	{
+		result = extern(int);
+		extern 'errno = 0; mkdir(s_string_cdata(${filename}), 0755); ${result} = errno;';
+	}
+	
+	/** Attempts to remove a directory. Returns 0 on success, or an errno on
+	 ** error. */
+	
+	function RmDir(filename: string): (result: int)
+	{
+		result = extern(int);
+		extern 'errno = 0; rmdir(s_string_cdata(${filename})); ${result} = errno;';
+	}
+	
+	/** Attempts to open a file. Returns a new File object and an errno. On
+	 ** error, the file object will abort if used. */
+	 
+	function Open(filename: string, mode: string): (file: File, errno: int)
+	{
+		var fp = extern(__extern);
+		errno = extern(int);
 		
-	/** Attempts to open the file for read-only access. Returns 0 on success,
-	 ** or an errno on error. Produces a runtime error if the file is already
-	 ** open. */
+		mode = mode + "b";
+		extern 'errno = 0; ${fp} = fopen(s_string_cdata(${filename}), s_string_cdata(${mode})); ${errno} = errno;';
+		
+		function _check_fp()
+		{
+			if (fp.isNull())
+				Application.Abort("invalid File object");
+		}
+		
+		return
+		{
+			implements File;
+			
+			function close(): (errno: int)
+			{
+				_check_fp();
+				errno = extern(int);
+				extern 'errno = 0; fclose((FILE*) ${fp}); ${errno} = errno;';
+				extern '${fp} = NULL;';
+			}
+		
+			function flush(): (errno: int)
+			{
+				_check_fp();
+				errno = extern(int);
+				extern 'errno = 0; fflush((FILE*) ${fp}); ${errno} = errno;';
+			}
+			
+			function length(): (length: int)
+			{
+				_check_fp();
+				length = extern(int);
+				extern '${length} = ftell((FILE*) ${fp});';
+			}
+			
+			function write(position: int, byte: int): (errno: int)
+			{
+				_check_fp();
+				errno = extern(int);
+				extern 'errno = 0;';
+				extern 'fseek((FILE*) ${fp}, ${position}, SEEK_SET);';
+				extern 'fputc(${byte}, (FILE*) ${fp});';
+				extern '${errno} = errno;';
+			} 
+	
+			function read(position: int): (result: int)
+			{
+				_check_fp();
+				result = extern(int);
+				extern 'errno = 0;';
+				extern 'fseek((FILE*) ${fp}, ${position}, SEEK_SET);';
+				extern '${result} = fgetc((FILE*) ${fp});';
+				extern 'if (errno != 0) ${result} = -1;';
+			}
+		};
+	}
+	
+	/** Creates an InputStream from a File object. The InputStream tracks its
+	 ** own position independently of any other streams on the File.
+	 **/
 	 
-	function openReadOnly(): int;
-	
-	/** Attempts to open the file for write-only access. Returns 0 on success,
-	 ** or an errno on error. Produces a runtime error if the file is already
-	 ** open. */
-	 
-	function openWriteOnly(): int;
-	
-	/** Attempts to open the file for read-write access. Returns 0 on success,
-	 ** or an errno on error. Produces a runtime error if the file is already
-	 ** open. */
-	 
-	function openReadWrite(): int;
-	
-	/** Returns the readable stream for the file. Produces a run-time error
-	 ** if the file is not open or is open for writing only. */
-	 
-	function getInputStream(): InputStream;
-	
-	/** Returns the writeable stream for the file. Produces a run-time error
-	 ** if the file is not open or is open for reading only. */
-	 
-	function getOutputStream(): OutputStream;
-};
-
-/** Creates a new File object for a specified path.
- **/
- 
-function File(path: string): File
-{
-	var fp: __extern = extern(__extern);
-	var open: boolean = false;
-	var inputstream = Maybe<InputStream>();
-	var outputstream = Maybe<OutputStream>();
-	
-	function _create_input_stream(fp: __extern): InputStream
+	function InputStream(file: File, pos: int): InputStream
 	{
 		return
 		{
 			implements InputStream;
 			
-			function isEOF(): (result: boolean)
-			{
-				result = extern(boolean);
-				extern '${result} = feof((FILE*) ${fp});';
-			}
+			function isEOF(): boolean
+				return pos >= file.length();
 			
 			function readByte(): (result: int)
 			{
-				result = extern(int);
-				extern '${result} = fgetc((FILE*) ${fp});';
+				result = file.read(pos);
+				if (result != -1)
+					pos = pos + 1;
 			}
 		};
 	}
 	
-	function _create_output_stream(fp: __extern): OutputStream
+	/** Create an OutputStream from a File object. The OutputStream tracks its
+	 ** own position independently of any other streams on the File.
+	 **/
+	
+	function OutputStream(file: File, pos: int): OutputStream
 	{
 		return
 		{
 			implements OutputStream;
 			
 			function writeByte(value: int)
-				extern 'fputc(${value}, (FILE*) ${fp});';
+			{
+				var e = file.write(pos, value);
+				if (e == 0)
+					pos = pos + 1;
+			}
 				
 			function flush()
-				extern 'fflush((FILE*) ${fp});';
+				file.flush();
 		};
 	}
-	
-	return
-	{
-		implements File;
-		
-		function getInputStream(): InputStream
-			return inputstream.get();
-			
-		function getOutputStream(): OutputStream
-			return outputstream.get();
-		
-		function remove(): (result: int)
-		{
-			result = extern(int);
-			if (open)
-				AbortInvalidObjectState();
-			extern 'errno = 0; remove(s_string_cdata(${path})); ${result} = errno;';
-		}
-				
-		function close(): (result: int)
-		{
-			result = extern(int);
-			if (!open)
-				AbortInvalidObjectState();
-			if (outputstream.valid())
-				outputstream.get().flush();
-			extern 'errno = 0; fclose((FILE*) ${fp}); ${result} = errno;';
-			open = false;
-		}
-		
-		function create(): (result: int)
-		{
-			result = extern(int);
-			if (open)
-				AbortInvalidObjectState();
-				
-			extern '#include <sys/types.h>';
-			extern '#include <sys/stat.h>';
-			extern '#include <fcntl.h>';
-			
-			extern 'errno = 0;';
-			extern 'int fd = open(s_string_cdata(${path}), O_CREAT|O_EXCL|O_RDWR, 0644);';
-			extern 'if (fd != -1) ${fp} = fdopen(fd, "r+b");';
-			extern '${result} = errno;';
-			
-			if (result != 0)
-				return;
-				
-			open = true;
-			inputstream = Maybe<InputStream>(_create_input_stream(fp));
-			outputstream = Maybe<OutputStream>(_create_output_stream(fp));
-		}
-		
-		function openReadOnly(): (result: int)
-		{
-			result = extern(int);
-			if (open)
-				AbortInvalidObjectState();
-			
-			extern 'errno = 0;';
-			extern '${fp} = fopen(s_string_cdata(${path}), "rb");';
-			extern '${result} = errno;';
-			
-			if (result != 0)
-				return;
-				
-			open = true;
-			inputstream = Maybe<InputStream>(_create_input_stream(fp));
-		}
-		
-		function openWriteOnly(): (result: int)
-		{
-			result = extern(int);
-			if (open)
-				AbortInvalidFile();
-			
-			extern 'errno = 0;';
-			extern '${fp} = fopen(s_string_cdata(${path}), "wb");';
-			extern '${result} = errno;';
-			
-			if (result != 0)
-				return;
-				
-			open = true;
-			outputstream = Maybe<OutputStream>(_create_output_stream(fp));
-		}
-		
-		function openReadWrite(): (result: int)
-		{
-			result = extern(int);
-			if (open)
-				AbortInvalidFile();
-			
-			extern 'errno = 0;';
-			extern '${fp} = fopen(s_string_cdata(${path}), "r+b");';
-			extern '${result} = errno;';
-			
-			if (result != 0)
-				return;
-				
-			open = true;
-			inputstream = Maybe<InputStream>(_create_input_stream(fp));
-			outputstream = Maybe<OutputStream>(_create_output_stream(fp));
-		}
-	};
-}
+};
 
-function AbortInvalidFile()
-	Abort("invalid operation on File object");
-	
+
 #endif
 	function remove(key: K);
 };
 
-/** Creates a new map based on an AA tree.
- ** 
- ** Keys must be comparable with == and <.
- **/
- 
-function Map<K, V>(): Map<K, V>
+var Map =
 {
-	/* This implementation was taken from here:
-	 *
-	 * http://www.eternallyconfuzzled.com/tuts/datastructures/jsw_tut_andersson.aspx
-	 */
+	/** Creates a new map based on an AA tree.
+	 ** 
+	 ** Keys must be comparable with == and <.
+	 **/
 	 
-	type Node =
+	function New<K, V>(): Map<K, V>
 	{
-			function level(): int;
-			function setLevel(level: int);
-			function left(): Node;
-			function setLeft(left: Node);
-			function right(): Node;
-			function setRight(right: Node);
-			function key(): K;
-			function setKey(key: K);
-			function value(): V;
-			function setValue(value: V);
-	};
-
-	var sentinel: Node =
-	{
-		implements Node;
-		
-		function level(): int
-			return 0;
-		function setLevel(level: int)
-			AbortInvalidObjectState();
-		function left(): Node
-			return sentinel;
-		function setLeft(left: Node)
-			AbortInvalidObjectState();
-		function right(): Node
-			return sentinel;
-		function setRight(right: Node)
-			AbortInvalidObjectState();
-		function key(): (r: K)
-			AbortInvalidObjectState();
-		function setKey(key: K)
-			AbortInvalidObjectState();
-		function value(): V
-			AbortInvalidObjectState();
-		function setValue(value: V)
-			AbortInvalidObjectState();
-	};
+		/* This implementation was taken from here:
+		 *
+		 * http://www.eternallyconfuzzled.com/tuts/datastructures/jsw_tut_andersson.aspx
+		 */
+		 
+		type Node =
+		{
+				function level(): int;
+				function setLevel(level: int);
+				function left(): Node;
+				function setLeft(left: Node);
+				function right(): Node;
+				function setRight(right: Node);
+				function key(): K;
+				function setKey(key: K);
+				function value(): V;
+				function setValue(value: V);
+		};
 	
-	function _makenode(_key: K, _value: V): Node
-	{
-		var _level = 1;
-		var _left = sentinel;
-		var _right = sentinel;
-		
-		return
+		var sentinel: Node =
 		{
 			implements Node;
 			
 			function level(): int
-				return _level;
+				return 0;
 			function setLevel(level: int)
-				_level = level;
+				Application.AbortInvalidObjectState();
 			function left(): Node
-				return _left;
+				return sentinel;
 			function setLeft(left: Node)
-				_left = left;
+				Application.AbortInvalidObjectState();
 			function right(): Node
-				return _right;
+				return sentinel;
 			function setRight(right: Node)
-				_right = right;
-			function key(): K
-				return _key;
+				Application.AbortInvalidObjectState();
+			function key(): (r: K)
+				Application.AbortInvalidObjectState();
 			function setKey(key: K)
-				_key = key;
+				Application.AbortInvalidObjectState();
 			function value(): V
-				return _value;
+				Application.AbortInvalidObjectState();
 			function setValue(value: V)
-				_value = value;
+				Application.AbortInvalidObjectState();
 		};
-	}
-	 	
-	function _skew(root: Node): Node
-	{
-		var rootlevel = root.level();
-		if (rootlevel != 0)
+		
+		function _makenode(_key: K, _value: V): Node
 		{
-			if (root.left().level() == rootlevel)
+			var _level = 1;
+			var _left = sentinel;
+			var _right = sentinel;
+			
+			return
 			{
-				var t = root;
-				root = root.left();
-				t.setLeft(root.right());
-				root.setRight(t);
+				implements Node;
+				
+				function level(): int
+					return _level;
+				function setLevel(level: int)
+					_level = level;
+				function left(): Node
+					return _left;
+				function setLeft(left: Node)
+					_left = left;
+				function right(): Node
+					return _right;
+				function setRight(right: Node)
+					_right = right;
+				function key(): K
+					return _key;
+				function setKey(key: K)
+					_key = key;
+				function value(): V
+					return _value;
+				function setValue(value: V)
+					_value = value;
+			};
+		}
+		 	
+		function _skew(root: Node): Node
+		{
+			var rootlevel = root.level();
+			if (rootlevel != 0)
+			{
+				if (root.left().level() == rootlevel)
+				{
+					var t = root;
+					root = root.left();
+					t.setLeft(root.right());
+					root.setRight(t);
+				}
+				
+				root.setRight(_skew(root.right()));
 			}
 			
-			root.setRight(_skew(root.right()));
+			return root;
 		}
 		
-		return root;
-	}
-	
-	function _split(root: Node): Node
-	{
-		if (root.level() != 0)
+		function _split(root: Node): Node
 		{
-			if (root.right().right().level() == root.level())
+			if (root.level() != 0)
 			{
-				var t = root;
-				root = root.right();
-				t.setRight(root.left());
-				root.setLeft(t);
-				root.setLevel(root.level() + 1);
-				root.setRight(_split(root.right()));
+				if (root.right().right().level() == root.level())
+				{
+					var t = root;
+					root = root.right();
+					t.setRight(root.left());
+					root.setLeft(t);
+					root.setLevel(root.level() + 1);
+					root.setRight(_split(root.right()));
+				}
 			}
+			
+			return root;
 		}
 		
-		return root;
-	}
-	
-	function _insert(root: Node, key: K, value: V): Node
-	{
-		if (root.level() == 0)
-			root = _makenode(key, value);
-		else
+		function _insert(root: Node, key: K, value: V): Node
 		{
-			if (root.key() == key)
-				root.setValue(value);
-			else if (root.key() < key)
-				root.setLeft(_insert(root.left(), key, value));
+			if (root.level() == 0)
+				root = _makenode(key, value);
 			else
-				root.setRight(_insert(root.right(), key, value));
+			{
+				if (root.key() == key)
+					root.setValue(value);
+				else if (root.key() < key)
+					root.setLeft(_insert(root.left(), key, value));
+				else
+					root.setRight(_insert(root.right(), key, value));
+				
+				root = _skew(root);
+				root = _split(root);
+			}
 			
-			root = _skew(root);
-			root = _split(root);
+			return root;
 		}
 		
-		return root;
-	}
-	
-	function _remove(root: Node, key: K): Node
-	{
-		if (root.level() != 0)
+		function _remove(root: Node, key: K): Node
 		{
-			if (root.key() == key)
+			if (root.level() != 0)
 			{
-				if (root.left().level() != 0)
+				if (root.key() == key)
 				{
-					if (root.right().level() != 0)
+					if (root.left().level() != 0)
 					{
-						var heir = root.left();
-						
-						while (heir.right().level() != 0)
-							heir = heir.right();
+						if (root.right().level() != 0)
+						{
+							var heir = root.left();
 							
-						root.setKey(heir.key());
-						root.setValue(heir.value());
-						root.setLeft(_remove(root.left(), key));
+							while (heir.right().level() != 0)
+								heir = heir.right();
+								
+							root.setKey(heir.key());
+							root.setValue(heir.value());
+							root.setLeft(_remove(root.left(), key));
+						}
+					}
+					else
+					{
+						if (root.left().level() != 0)
+							root = root.left();
+						else
+							root = root.right();
 					}
 				}
 				else
 				{
-					if (root.left().level() != 0)
-						root = root.left();
+					if (root.key() < key)
+						root.setLeft(_remove(root.left(), key));
 					else
-						root = root.right();
+						root.setRight(_remove(root.right(), key));
 				}
 			}
-			else
+			
+			if ((root.left().level() < (root.level()-1)) |
+			    (root.right().level() < (root.level()-1)))
 			{
-				if (root.key() < key)
-					root.setLeft(_remove(root.left(), key));
-				else
-					root.setRight(_remove(root.right(), key));
+				root.setLevel(root.level() - 1);
+				if (root.right().level() > root.level())
+					root.right().setLevel(root.level());
+				
+				root = _skew(root);
+				root = _split(root);
 			}
+			
+			return root;
 		}
 		
-		if ((root.left().level() < (root.level()-1)) |
-		    (root.right().level() < (root.level()-1)))
+		function _get(root: Node, key: K): V
 		{
-			root.setLevel(root.level() - 1);
-			if (root.right().level() > root.level())
-				root.right().setLevel(root.level());
-			
-			root = _skew(root);
-			root = _split(root);
+			if (root.level() == 0)
+				Application.Abort("item not in map");
+				
+			if (root.key() == key)
+				return root.value();
+			if (root.key() < key)
+				return _get(root.left(), key);
+			else
+				return _get(root.right(), key);
 		}
 		
-		return root;
+		function _contains(root: Node, key: K): boolean
+		{
+			if (root.level() == 0)
+				return false;
+				
+			if (root.key() == key)
+				return true;
+			if (root.key() < key)
+				return _contains(root.left(), key);
+			else
+				return _contains(root.right(), key);
+		}
+		
+		var root = sentinel;
+		
+		return
+		{
+			implements Map<K, V>;
+			
+			function put(key: K, value: V)
+				root = _insert(root, key, value);
+			
+			function get(key: K): V
+				return _get(root, key);
+				
+			function contains(key: K): boolean
+				return _contains(root, key);
+				
+			function remove(key: K)
+				root = _remove(root, key);
+		};
 	}
-	
-	function _get(root: Node, key: K): V
-	{
-		if (root.level() == 0)
-			Abort("item not in map");
-			
-		if (root.key() == key)
-			return root.value();
-		if (root.key() < key)
-			return _get(root.left(), key);
-		else
-			return _get(root.right(), key);
-	}
-	
-	function _contains(root: Node, key: K): boolean
-	{
-		if (root.level() == 0)
-			return false;
-			
-		if (root.key() == key)
-			return true;
-		if (root.key() < key)
-			return _contains(root.left(), key);
-		else
-			return _contains(root.right(), key);
-	}
-	
-	var root = sentinel;
-	
-	return
-	{
-		implements Map<K, V>;
-		
-		function put(key: K, value: V)
-			root = _insert(root, key, value);
-		
-		function get(key: K): V
-			return _get(root, key);
-			
-		function contains(key: K): boolean
-			return _contains(root, key);
-			
-		function remove(key: K)
-			root = _remove(root, key);
-	};
-}
+};
 
 #endif
 			return false;
 			
 		function get(): T
-			AbortInvalidObjectState();
+			Application.AbortInvalidObjectState();
 	};
 
 /** Construct an immutable Maybe with the specified value.
 		{
 			var error = extern(string);
 			extern '${error} = s_create_string_constant((const char*) ${errore}, 0);';
-			Abort("PCRE compilation error: " + error + " at offset " + offset.toString());
+			Application.Abort("PCRE compilation error: " + error + " at offset " + offset.toString());
 		}
 		
 		extern '${extra} = pcre_study((pcre*)${pattern}, 0, (const char**)&${errore});';
 				var ovectorsize = (capturecount+1) * 3;
 				extern '${ovector} = S_ALLOC_DATA(${ovectorsize} * sizeof(int));';
 				if (ovector.isNull())
-					AbortOutOfMemory();
+					Application.AbortOutOfMemory();
 				
 				var sdata = extern(__extern);
 				extern '${sdata} = (void*)s_string_cdata(${s});';
 	function remove(value: V);
 };
 
-/** Creates a new set.
- ** 
- ** Values must be comparable with == and <.
- **/
- 
-function Set<V>(): Set<V>
+var Set =
 {
-	var map = Map<V, boolean>();
-	
-	return
+	/** Creates a new set.
+	 ** 
+	 ** Values must be comparable with == and <.
+	 **/
+	 
+	function New<V>(): Set<V>
 	{
-		implements Set<V>;
+		var map = Map.New<V, boolean>();
 		
-		function add(value: V)
+		return
 		{
-			map.put(value, true);
-		}
-		
-		function contains(value: V): boolean
-		{
-			return map.contains(value);
-		}
-		
-		function remove(value: V)
-		{
-			map.remove(value);
-		}
-	};
-}
+			implements Set<V>;
+			
+			function add(value: V)
+			{
+				map.put(value, true);
+			}
+			
+			function contains(value: V): boolean
+			{
+				return map.contains(value);
+			}
+			
+			function remove(value: V)
+			{
+				map.remove(value);
+			}
+		};
+	}
+};
 
 #endif

include/StreamIO.ch

 		
 		function readString(): string
 		{
-			var buffer = Buffer(0);
+			var buffer = Buffer.New(0);
 			
 			while (true)
 			{
 		
 		function writeString(s: string)
 		{
-			var buffer = BufferFromString(s);
+			var buffer = Buffer.NewFromString(s);
 			var lo, hi = buffer.bounds();
 			for i = lo, hi
 			{
 # information.
 
 for f in \
+	test/file-test.cow \
 	test/pcre-test.cow \
 	test/buffer-test.cow \
 	test/set-test.cow \
 	test/map-test.cow \
 	test/maps-example.cow \
 	test/mandelbrot.cow \
-	test/file-test.cow \
 	test/failed-inference-test.cow \
 	test/bug-more-failed-inference.cow \
 	test/generics-test.cow \

test/application-test.cow

 #include "SimpleIO.ch"
 #include "Application.ch"
 
-var argv = ApplicationArguments();
+var argv = Application.Arguments();
 var argvlow, argvhigh = argv.bounds();
 for i = argvlow, argvhigh
 {
 	println(i.toString() + " " + argv.get(i));
 }
 
-Exit(12);
+Application.Exit(12);

test/buffer-test.cow

 #include "SimpleIO.ch"
 #include "Buffer.ch"
 
-var b = Buffer(0);
+var b = Buffer.New(0);
 b.append(65);
 b.append(66);
 b.append(67);

test/failed-inference-test.cow

 	
 	function doA(): int
 	{
-		Abort("failed");
+		Application.Abort("failed");
 	}
 };
 

test/file-test.cow

 #include "SimpleIO.ch"
 #include "File.ch"
 
-var file = File("testfile.dat");
-var i = file.create();
-if (i == 0)
+function teste(e: int)
 {
-	println("creating file");
-
-	var outs = file.getOutputStream();
-	for i = 0, 10
-		outs.writeByte(i);
-	file.close();
+	if (e != 0)
+		Application.Abort("errno "+e.toString());
 }
 
-i = file.openReadOnly();
-if (i == -1)
-	Abort("failed to open file: "+i.toString());
+println("creating file");
+var file, e = File.Open("testfile.dat", "w+");
+teste(e);
+var outs = File.OutputStream(file, 0);
+for i = 0, 10
+	outs.writeByte(i);
+file.close();
 
-var ins = file.getInputStream();
+println("reading back file");
+file, e = File.Open("testfile.dat", "r");
+teste(e);
+var ins = File.InputStream(file, 0);
 while (true)
 {
 	var c = ins.readByte();
 	println("c = "+c.toString());
 }
 file.close();
-file.remove();
 
-i = file.create();
-if (i == -1)
-	Abort("failed to create file: "+i.toString());
+println("removing file");
+File.Remove("testfile.dat");
 
+println("recreating file");
+file, e = File.Open("testfile.dat", "w+");
+teste(e);
 {
-	var outs = file.getOutputStream();
+	var outs = File.OutputStream(file, 0);
 	var outw = OutputStreamWriter(outs);
 	outw.writeCodePoint(99);
 	outw.writeCodePoint(1234);
 	outw.writeCodePoint(5678);
 	outw.writeString("fnord\n");
+	file.close();
 }
-file.close();
 
-i = file.openReadOnly();
-if (i == -1)
-	Abort("failed to create file: "+i.toString());
-
+println("reading back file");
+file, e = File.Open("testfile.dat", "r");
+teste(e);
 {
-	var ins = file.getInputStream();
+	var ins = File.InputStream(file, 0);
 	var inr = InputStreamReader(ins);
 	var s = inr.readString();
 	
 	println("read <"+s+">");
 }
+file.close();
 
-file.close();
-file.remove();
+println("removing file, again");
+File.Remove("testfile.dat");
+

test/file-test.cow.log.pristine

 creating file
+reading back file
 c = 0
 c = 1
 c = 2
 c = 7
 c = 8
 c = 9
+removing file
+recreating file
+reading back file
 read <cӒᘮfnord>
+removing file, again

test/inference-test.cow

 o1.toString();
 */
 
-var args = ApplicationArguments();
+var args = Application.Arguments();
 var low, high = args.bounds();
 
 for i = low, high

test/map-test.cow

 #include "SimpleIO.ch"
 #include "Map.ch"
 
-var map = Map<int, string>();
+var map = Map.New<int, string>();
 
 map.put(12, "twelve");
 map.put(42, "forty-two");
 println(map.contains(7).toString());
 println(map.contains(12).toString());
 
-var map1 = Map<string, int>();
+var map1 = Map.New<string, int>();
 map1.put("twelve", 12);
 map1.put("forty-two", 42);
 map1.put("minus four", -4);

test/maps-example.cow

 #include "SimpleIO.ch"
 #include "Map.ch"
 
-var map = Map<int, string>();
+var map = Map.New<int, string>();
 map.put(1, "one");
 map.put(2, "two");
 map.put(3, "three");

test/pcre-test.cow.log.pristine

 matches: 2
 capture 0: one two three
 capture 1: two
+matches: 0
 Exited with 0

test/set-test.cow

 #include "SimpleIO.ch"
 #include "Set.ch"
 
-var set = Set<int>();
+var set = Set.New<int>();
 set.add(1);
 set.add(2);
 set.add(-9);
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.