<?xml version="1.0" ?>
<?xml-stylesheet type="text/css" href="stylesheet.css" ?>

<!-- Copyright 2003 Steve Folta -->

<cleet-doc xmlns:xlink="http://www.w3.org/1999/xlink">

<title> Standard Classes </title>

<p>
This is not a comprehensive manual for the standard classes; read the
sources to see all the classes, functions, and fields available.  (The
sources are in <path>$CLEET_BASE/Packages/Standard</path>.)  A few of
the classes in the <id>Standard</id> namespace are obsolescent and will
be phased out and removed eventually.  (For example, use <id>List</id>
instead of <id>OwnedObjectList</id>.)
</p>


<header> Object </header>

<p>
Since <id>Object</id> is the root of the class hierarchy, functions in
<id>Object</id> are available for <i>any</i> object.  Here are examples
of some of them:
</p>

<code>the-class: Class = some-object.class;
if (some-object.is-a(SomeClass)) { /* ... */ }
if (some-object.is(my-object)) { /* ... */ }
  // Are they the same object?
if (some-object == my-object) { /* ... */ }
  // Defaults to is(), but overridden by many subclasses,
  // notably String and Int.
some-object.print-string.write();</code>

<p>
Casting is done using the <id>as-a()</id> function.  However, be very
careful, since <id>as-a()</id> is unchecked.  Always check the object
with <id>is-a()</id> first:
</p>

<code>if (some-object.is-a(String))
  some-object.as-a(String).write();
</code>



<header> String </header>

<p>
Here are some examples of string operations:
</p>

<code>string-1: String = "Hello";
string-2: String = string-1 + " there.";
if (string-1.is-empty) { /* ... */ }
string-length: Int = string-1.length;
if (string-1 == string-2) { /* ... */ }
if (string-1 &lt; string-2) { /* ... */ }
if (string-1.starts-with(string-2)) { /* ... */ }
string-3: String = string-1.substr(1, 2);  // string-3 == "el"
string-4: String = string-1.substr(2);     // string-4 == "llo"
index: Int = string-1.find-index-of('o');  // index == 4
character: Int = string-1[3];
first-char: Int = string-1.first-character;
last-char: Int = string-1.last-character;
if (string-1.is-a-substring-of(string-2)) { /* ... */ }
for (character: Int in string) { /* ... */ }
for (line: String in string.lines) { /* ... */ }
value: Int = "34".as-int;
string-1.write();   // writes it to stdout</code>


<header> Int </header>

<p>
<id>Int</id>, along with <id>Bool</id> and <id>BytePtr</id>, is a
"primitive" type.  That means that it is probably treated specially by
the compiler, and there may be restrictions on what you can do with it. 
For instance, using the current compiler, you can't create a subclass of
<id>Int</id> and expect it to work.
</p>

<p>
<id>Int</id> is one of the very few classes whose name is an
abbreviation (for "Integer").
</p>

<p>
In addition to all the usual arithmetic (<id>+</id>, <id>-</id>,
<id>*</id>, <id>/</id>, <id>%</id>) and comparison (<id>==</id>,
<id>!=</id>, <id>&lt;</id>, <id>&gt;</id>, <id>&lt;=</id>,
<id>&gt;=</id>) operators, there are a couple of other functions you
can use:
</p>

<code>string-1: String = 65.string;   // == "65"
string-2: String = 65.char-string;    // == "A" (ASCII 65)</code>



<header> Bool </header>

<p>
<id>Bool</id>, of course, represents a <id>true</id> or <id>false</id>
value.  The <id>&amp;</id>, <id>|</id>, and <id>^</id> operators are
defined, but most often one uses the "short-circuit"
<id>&amp;&amp;</id>, <id>||</id>, and <id>!</id> operators, which are
not functions, but are handled by the compiler.
</p>



<header> Float </header>

<p>
<id>Float</id> is a floating-point number, supporting the usual
arithmetic and comparison operators.
</p>



<header> List </header>

<p>
<id>List</id> is a basic collection class, implemented as a linked list.
Here are some examples of its use:
</p>

<code>list: List of String();
list.append("One");
two: String = "Two";
list.append("Two");
for (string: String in list) { /* ... */ }
if (list.is-empty) { /* ... */ }
num-items: Int = list.count;
start: String = list.first-item;
end: String = list.last-item;
if (list.contains("One")) { /* ... */ }
  // This is actually false, since the two strings,
  // although containing the same text, are actually
  // different objects.
if (list.contains(two)) { /* ... */ }
  // This one will be true.
list.remove(two);</code>

<p>
There are also a couple of functions to use a list as a stack:
</p>

<code>list.push-front("Foo");
popped: String = list.pop-front();</code>



<header> Dictionary </header>

<p>
<id>Dictionary</id> is a collection class that maps Strings to objects. 
It's implemented as an AA-tree, so the main operations take O(log N)
time.  Here are some examples:
</p>

<code>dict: Dictionary of String();
dict["foo"] = "foo value";
dict["bar"] = "bar value";
dict["foo"];           // => "foo value"
dict["baz"];           // => nil
dict.contains("foo");  // => true
dict.is-empty;         // => false
dict.count;            // => 2
for (key: String in dict.keys)
  { /* ... */ }
for (value: String in dict.values)
  { /* ... */ }</code>



<header> Program </header>

<p>
You will create a subclass of <id>Program</id> representing your
program.  Override one or more of the functions as needed.  For example:
</p>

<code>Class: MyClass
Superclass: Program

create(arguments: List of String)
{
  // The arguments are the command-line arguments
  // that the system has passed to your program.
  // The first argument will be the name of your
  // program.
}

create()
{
  // Alternately, if you don't need the arguments,
  // you can declare a create() with no arguments
  // instead.
}

run()
{
  // This is where you would normally do most of
  // the work of your program, although some
  // programs do all their work in create() and
  // don't define run().
}

return-value: Int
{
  // A return value that your program returns to
  // the system when it exits.  The default is to
  // return zero.
  return 0;
}</code>



<header> Class </header>

<p>
Here are some examples of things you can do with a <id>Class</id>:
</p>

<code>a-class: Class = some-object.class;
class-name: String = a-class.name;
the-superclass: Class = a-class.superclass;
if (a-class.is-a-subclass-of(some-other-class)) { /* ... */ }</code>

<p>
Some implementations support full reflection:
</p>

<code>if (a-class.has-field-named("foo")) { /* ... */ }
for (field: Field in a-class.fields)
  (field.name + ": " + field.type + ";\n").write();
for (function: Function in a-class.functions) {
  name: String = function.name;
  return-type: Class = function.return-type;
  num-arguments: Int = function.num-arguments;
  for (argument: FunctionArgument in function.arguments) {
    arg-name: String = argument.name;
    arg-type: Class = argument.type;
    }
  }</code>



<header> File </header>

<p>
Some examples of using the <id>File</id> class:
</p>

<code>file: File("filename");
file-path: String = file.path;
file-size: Int = file.size;
if (file.exists) { /* ... */ }
file-contents: String = file.contents;</code>

<p>
Using the <id>contents</id> function is a quick and easy way of reading
a file.  But since it reads the whole file into memory, it may not be
the best way of reading large files.
</p>



<header> InputStream and FileInStream </header>

<p>
<id>InputStream</id> is a superclass for classes representing streams
that read.  Its only (phantom) function is <id>read-buffer()</id>, so
it really represents a rather low-level stream.  <id>FileInStream</id>
is a subclass of <id>InputStream</id> that reads from a file.  Examples:
</p>

<code>file-stream: FileInStream = file.stream;   // or...
file-stream: FileInStream("filename");
buffer: BytePtr(file-size);
file-stream.read-buffer(buffer, file-size);</code>



<header> OutputStream and FileOutStream </header>

<p>
<id>OutputStream</id> is a little more directly useful that
<id>InputStream</id>, since it includes <id>write(string: String)</id>,
<id>write-line(line: String)</id>, and <id>write-line()</id> functions,
in addition to a "raw" <id>write-buffer()</id>.  <id>FileOutStream</id>
is the subclass that writes to a file:
</p>

<code>out-stream: FileOutStream = file.output-stream;   // or...
out-stream: FileOutStream("new-file-name");
out-stream.write("Hello ");
out-stream.write-line("there.");
out-stream.write-line();
out-stream.write-buffer(buffer, file-size);</code>



<header> FileDirectory </header>

<p>
<id>FileDirectory</id> represents a directory in the filesystem.  Both
<id>FileDirectory</id> and <id>File</id> are subclasses of
<id>FileDirectoryEntry</id>.  Some examples:
</p>

<code>directory: FileDirectory(".");
num-entries: Int = directory.count;
if (directory.contains("name")) { /* ... */ }
if (directory.entry-is-directory("name")) { /* ... */ }
for (entry-name: String in directory.names) {
  entry: FileDirectoryEntry = directory[entry-name];
  if (entry.is-a(File))
    process-file(entry.as-a(File));
  else if (entry.is-a(FileDirectory))
    process-directory(entry.as-a(FileDirectory));
  }</code>



<header> System </header>

<p>
A singleton object that can access various things from the operating
system.  Access the singleton like this:
</p>

<code>System.system</code>

<p>
Here are some examples of the things you can do:
</p>

<code>cleet-base: String =
  System.system.environment-variable("CLEET_BASE");
cur-path: String =
  System.system.current-directory-path;
System.system.run-program("vi", "foo");</code>



<header> Exception and MessageException </header>

<p>
<id>Exception</id> is meant to be the superclass for all exceptions that
are thrown.  (Although there's really nothing stopping you from throwing
any object as an exception.)  <id>Exception</id>'s only (phantom)
function is <id>message</id>, which returns a string describing the
exception.
</p>

<p>
If you want to throw an exception, but don't need it to do anything
fancy, you can throw a <id>MessageException</id>.  It just takes a
string for the message, and that's it.
</p>

<p> Example: </p>

<code>try {
  throw MessageException("Something went wrong.");
  }
catch (exception: Exception) {
  ("Error!: " + exception.message + "\n").write();
  }</code>


<header> BytePtr </header>

<p>
This is a "primitive" type like <id>Int</id> and <id>Bool</id>.  I've
saved it for last because it's a very low-level, dangerous type.  Don't
use it unless you are sure of what you are doing.
</p>

<p> Examples: </p>

<code>ptr: BytePtr = "Test".start;
new-block: BytePtr(block-size);
  // allocates a block of memory
first-byte: Int = ptr.deref;
new-block.deref = 0;
third-byte: Int = ptr.byte-at(2);
new-block.byte-at(2) = 0;
third-32-bit-int: Int = ptr.int-at(2);
new-block.int-at(2) = 0;
object: Object = new-block.object-ptr-at(0);
  // *VERY* dangerous!
new-block.object-ptr-at(3) = some-object;
ptr = new-block.ptr-at(0);
new-block.ptr-at(0) = ptr;
new-block.copy-from(ptr, block-size);
ptr = ptr + 1;
ptr = ptr - 1;
if (ptr &lt; new-block) { /* ... */ }
  // All other comparisons are also available.
length: Int = strlen(ptr);
object: Object = new-block.as-object-ptr;
  // *VERY* dangerous!
new-block.fill-with-byte(0, block-size);</code>



</cleet-doc>
