]> git.lizzy.rs Git - rust.git/commitdiff
Begin documenting std and add doc generation using naturaldocs
authorBrian Anderson <banderson@mozilla.com>
Mon, 24 Oct 2011 22:25:41 +0000 (15:25 -0700)
committerBrian Anderson <banderson@mozilla.com>
Wed, 26 Oct 2011 01:01:52 +0000 (18:01 -0700)
Naturaldocs isn't really that great but it seems easier to get
something working than with doxygen, for which we would need to
convert rust code to something C++ish. We probably want to just
write a rustdoc utility at some point.

23 files changed:
configure
doc/Languages.txt [new file with mode: 0644]
doc/Topics.txt [new file with mode: 0644]
mk/docs.mk
src/lib/bitv.rs
src/lib/box.rs
src/lib/char.rs
src/lib/comm.rs
src/lib/ctypes.rs
src/lib/deque.rs
src/lib/either.rs
src/lib/extfmt.rs
src/lib/float.rs
src/lib/fs.rs
src/lib/fun_treemap.rs
src/lib/generic_os.rs
src/lib/getopts.rs
src/lib/int.rs
src/lib/io.rs
src/lib/option.rs
src/lib/std.rc
src/lib/treemap.rs
src/lib/vec.rs

index 7158a832e09bae8e0dc591eeef6c9ce3ac024f06..a27aa9b7ecc0f538d8f539cf0982186f8ab5dd2a 100755 (executable)
--- a/configure
+++ b/configure
@@ -387,7 +387,8 @@ rm -f config.mk.bak
 
 step_msg "making directories"
 for i in \
-    doc \
+    doc doc/std \
+    nd nd/std \
     rt rt/isaac rt/bigint rt/sync rt/test rt/arch/i386 \
     rt/libuv rt/libuv/src/ares rt/libuv/src/eio rt/libuv/src/ev \
     rustllvm dl \
diff --git a/doc/Languages.txt b/doc/Languages.txt
new file mode 100644 (file)
index 0000000..b1453d4
--- /dev/null
@@ -0,0 +1,124 @@
+Format: 1.51
+
+# This is the Natural Docs languages file for this project.  If you change
+# anything here, it will apply to THIS PROJECT ONLY.  If you'd like to change
+# something for all your projects, edit the Languages.txt in Natural Docs'
+# Config directory instead.
+
+
+# You can prevent certain file extensions from being scanned like this:
+# Ignore Extensions: [extension] [extension] ...
+
+
+#-------------------------------------------------------------------------------
+# SYNTAX:
+#
+# Unlike other Natural Docs configuration files, in this file all comments
+# MUST be alone on a line.  Some languages deal with the # character, so you
+# cannot put comments on the same line as content.
+#
+# Also, all lists are separated with spaces, not commas, again because some
+# languages may need to use them.
+#
+# Language: [name]
+# Alter Language: [name]
+#    Defines a new language or alters an existing one.  Its name can use any
+#    characters.  If any of the properties below have an add/replace form, you
+#    must use that when using Alter Language.
+#
+#    The language Shebang Script is special.  It's entry is only used for
+#    extensions, and files with those extensions have their shebang (#!) lines
+#    read to determine the real language of the file.  Extensionless files are
+#    always treated this way.
+#
+#    The language Text File is also special.  It's treated as one big comment
+#    so you can put Natural Docs content in them without special symbols.  Also,
+#    if you don't specify a package separator, ignored prefixes, or enum value
+#    behavior, it will copy those settings from the language that is used most
+#    in the source tree.
+#
+# Extensions: [extension] [extension] ...
+# [Add/Replace] Extensions: [extension] [extension] ...
+#    Defines the file extensions of the language's source files.  You can
+#    redefine extensions found in the main languages file.  You can use * to
+#    mean any undefined extension.
+#
+# Shebang Strings: [string] [string] ...
+# [Add/Replace] Shebang Strings: [string] [string] ...
+#    Defines a list of strings that can appear in the shebang (#!) line to
+#    designate that it's part of the language.  You can redefine strings found
+#    in the main languages file.
+#
+# Ignore Prefixes in Index: [prefix] [prefix] ...
+# [Add/Replace] Ignored Prefixes in Index: [prefix] [prefix] ...
+#
+# Ignore [Topic Type] Prefixes in Index: [prefix] [prefix] ...
+# [Add/Replace] Ignored [Topic Type] Prefixes in Index: [prefix] [prefix] ...
+#    Specifies prefixes that should be ignored when sorting symbols in an
+#    index.  Can be specified in general or for a specific topic type.
+#
+#------------------------------------------------------------------------------
+# For basic language support only:
+#
+# Line Comments: [symbol] [symbol] ...
+#    Defines a space-separated list of symbols that are used for line comments,
+#    if any.
+#
+# Block Comments: [opening sym] [closing sym] [opening sym] [closing sym] ...
+#    Defines a space-separated list of symbol pairs that are used for block
+#    comments, if any.
+#
+# Package Separator: [symbol]
+#    Defines the default package separator symbol.  The default is a dot.
+#
+# [Topic Type] Prototype Enders: [symbol] [symbol] ...
+#    When defined, Natural Docs will attempt to get a prototype from the code
+#    immediately following the topic type.  It stops when it reaches one of
+#    these symbols.  Use \n for line breaks.
+#
+# Line Extender: [symbol]
+#    Defines the symbol that allows a prototype to span multiple lines if
+#    normally a line break would end it.
+#
+# Enum Values: [global|under type|under parent]
+#    Defines how enum values are referenced.  The default is global.
+#    global       - Values are always global, referenced as 'value'.
+#    under type   - Values are under the enum type, referenced as
+#               'package.enum.value'.
+#    under parent - Values are under the enum's parent, referenced as
+#               'package.value'.
+#
+# Perl Package: [perl package]
+#    Specifies the Perl package used to fine-tune the language behavior in ways
+#    too complex to do in this file.
+#
+#------------------------------------------------------------------------------
+# For full language support only:
+#
+# Full Language Support: [perl package]
+#    Specifies the Perl package that has the parsing routines necessary for full
+#    language support.
+#
+#-------------------------------------------------------------------------------
+
+# The following languages are defined in the main file, if you'd like to alter
+# them:
+#
+#    Text File, Shebang Script, C/C++, C#, Java, JavaScript, Perl, Python,
+#    PHP, SQL, Visual Basic, Pascal, Assembly, Ada, Tcl, Ruby, Makefile,
+#    ActionScript, ColdFusion, R, Fortran
+
+# If you add a language that you think would be useful to other developers
+# and should be included in Natural Docs by default, please e-mail it to
+# languages [at] naturaldocs [dot] org.
+
+
+Language: Rust
+
+   Extensions: rc rs
+   Line Comment: //
+   Block Comment: /* */
+   Package Separator: ::
+   Function Prototype Enders: ; {
+   Type Prototype Enders: ; }
+   Class Prototype Enders: {
diff --git a/doc/Topics.txt b/doc/Topics.txt
new file mode 100644 (file)
index 0000000..24557ee
--- /dev/null
@@ -0,0 +1,159 @@
+Format: 1.51
+
+# This is the Natural Docs topics file for this project.  If you change anything
+# here, it will apply to THIS PROJECT ONLY.  If you'd like to change something
+# for all your projects, edit the Topics.txt in Natural Docs' Config directory
+# instead.
+
+
+# If you'd like to prevent keywords from being recognized by Natural Docs, you
+# can do it like this:
+# Ignore Keywords: [keyword], [keyword], ...
+#
+# Or you can use the list syntax like how they are defined:
+# Ignore Keywords:
+#    [keyword]
+#    [keyword], [plural keyword]
+#    ...
+
+
+#-------------------------------------------------------------------------------
+# SYNTAX:
+#
+# Topic Type: [name]
+# Alter Topic Type: [name]
+#    Creates a new topic type or alters one from the main file.  Each type gets
+#    its own index and behavior settings.  Its name can have letters, numbers,
+#    spaces, and these charaters: - / . '
+#
+# Plural: [name]
+#    Sets the plural name of the topic type, if different.
+#
+# Keywords:
+#    [keyword]
+#    [keyword], [plural keyword]
+#    ...
+#    Defines or adds to the list of keywords for the topic type.  They may only
+#    contain letters, numbers, and spaces and are not case sensitive.  Plural
+#    keywords are used for list topics.  You can redefine keywords found in the
+#    main topics file.
+#
+# Index: [yes|no]
+#    Whether the topics get their own index.  Defaults to yes.  Everything is
+#    included in the general index regardless of this setting.
+#
+# Scope: [normal|start|end|always global]
+#    How the topics affects scope.  Defaults to normal.
+#    normal        - Topics stay within the current scope.
+#    start         - Topics start a new scope for all the topics beneath it,
+#                    like class topics.
+#    end           - Topics reset the scope back to global for all the topics
+#                    beneath it.
+#    always global - Topics are defined as global, but do not change the scope
+#                    for any other topics.
+#
+# Class Hierarchy: [yes|no]
+#    Whether the topics are part of the class hierarchy.  Defaults to no.
+#
+# Page Title If First: [yes|no]
+#    Whether the topic's title becomes the page title if it's the first one in
+#    a file.  Defaults to no.
+#
+# Break Lists: [yes|no]
+#    Whether list topics should be broken into individual topics in the output.
+#    Defaults to no.
+#
+# Can Group With: [type], [type], ...
+#    Defines a list of topic types that this one can possibly be grouped with.
+#    Defaults to none.
+#-------------------------------------------------------------------------------
+
+# The following topics are defined in the main file, if you'd like to alter
+# their behavior or add keywords:
+#
+#    Generic, Class, Interface, Section, File, Group, Function, Variable,
+#    Property, Type, Constant, Enumeration, Event, Delegate, Macro,
+#    Database, Database Table, Database View, Database Index, Database
+#    Cursor, Database Trigger, Cookie, Build Target
+
+# If you add something that you think would be useful to other developers
+# and should be included in Natural Docs by default, please e-mail it to
+# topics [at] naturaldocs [dot] org.
+
+
+#Topic Type: Crate
+
+#   Plural: Crates
+#   Scope: Always Global
+
+#   Keywords:
+#      crate, crates
+
+Topic Type: Syntax Extension
+
+   Plural: Syntax Extensions
+   Scope: Always Global
+
+   Keywords:
+      syntax extension, syntax extensions
+
+#Alter Topic Type: Class
+
+#   Keywords:
+#      object, objects
+#      tag, tags
+#      resource, resources
+
+Topic Type: Module
+   Plural: Modules
+   Scope: Start
+   Class Hierarchy: Yes
+   Page Title If First: Yes
+
+   Keywords:
+      module, modules
+
+Topic Type: Object
+   Plural: Objects
+   Scope: Start
+   Class Hierarchy: Yes
+
+   Keywords:
+      obj, objs
+
+Topic Type: Tag
+   Plural: Tags
+   Scope: Start
+   Class Hierarchy: Yes
+
+   Keywords:
+      tag, tags
+
+#Alter Topic Type: Function
+
+#   Scope: Start
+#      predicate, predicates
+
+#   Ignore Keywords:
+#      method, methods
+#   Keywords:
+#      variant, variants
+
+Topic Type: Variant
+
+   Plural: Variants
+   Keywords:
+      variant, variants
+
+#Alter Topic Type: Type
+
+#    Keywords:
+#       tag, tags
+
+Topic Type: Predicate
+
+   Plural: Predicates
+   Break Lists: Yes
+
+   Keywords:
+      predicate, predicates
index bab8bf4f6ec1c49c5abf41a9a8f69203fab307ab..72e549bec28f82d5d4b276b72b93876c649bb82a 100644 (file)
@@ -19,3 +19,16 @@ doc/%.html: %.texi doc/version.texi
 docsnap: doc/rust.pdf
        @$(call E, snap: doc/rust-$(shell date +"%Y-%m-%d")-snap.pdf)
        $(Q)mv $< doc/rust-$(shell date +"%Y-%m-%d")-snap.pdf
+
+doc/std/index.html: nd/std/Languages.txt nd/std/Topics.txt \
+                    $(STDLIB_CRATE) $(STDLIB_INPUTS)
+       @$(call E, naturaldocs: $@)
+       naturaldocs -i $(S)src/lib -o HTML doc/std -p nd/std -r
+
+nd/std/Languages.txt: $(S)doc/Languages.txt
+       @$(call E, cp: $@)
+       $(Q)cp $< $@
+
+nd/std/Topics.txt: $(S)doc/Topics.txt
+       @$(call E, cp: $@)
+       $(Q)cp $< $@
index 4bbd4118d323fb46b73338db70c085bea6f35804..023450ec97b02e109d8bace4e23b7e90b5b793a7 100644 (file)
@@ -1,3 +1,8 @@
+/*
+Module: bitv
+
+Bitvectors.
+*/
 
 export t;
 export create;
 //        an optimizing version of this module that produces a different obj
 //        for the case where nbits <= 32.
 
+/*
+Type: t
+
+The bitvector type.
+*/
 type t = @{storage: [mutable uint], nbits: uint};
 
 
 // FIXME: this should be a constant once they work
 fn uint_bits() -> uint { ret 32u + (1u << 32u >> 27u); }
 
+/*
+Function: create
+
+Constructs a bitvector.
+
+Parameters:
+nbits - The number of bits in the bitvector
+init - If true then the bits are initialized to 1, otherwise 0
+*/
 fn create(nbits: uint, init: bool) -> t {
     let elt = if init { !0u } else { 0u };
     let storage = vec::init_elt_mut::<uint>(elt, nbits / uint_bits() + 1u);
index a4322c09be92f54ad3d242f2e4090f3e151a1a8e..821a8428d2c9df56e29a04047f9c4b72c73a564e 100644 (file)
@@ -1,6 +1,15 @@
+/*
+Module: box
+*/
+
 
 export ptr_eq;
 
+/*
+Function: ptr_eq
+
+Determine if two shared boxes point to the same object
+*/
 fn ptr_eq<T>(a: @T, b: @T) -> bool {
     let a_ptr: uint = unsafe::reinterpret_cast(a);
     let b_ptr: uint = unsafe::reinterpret_cast(b);
index cbd8f667b86070b9c39d37917eac649008429ce4..e91e8697dd86e7a459cf0b50e58ebfde43eed98f 100644 (file)
@@ -1,3 +1,18 @@
+/*
+Module: char
+
+Utilities for manipulating the char type
+*/
+
+/*
+Function: is_whitespace
+
+Indicates whether a character is whitespace.
+
+Whitespace characters include space (U+0020), tab (U+0009), line feed
+(U+000A), carriage return (U+000D), and a number of less common
+ASCII and unicode characters.
+*/
 pure fn is_whitespace(c: char) -> bool {
     const ch_space: char = '\u0020';
     const ch_ogham_space_mark: char = '\u1680';
index dbf7bb3df1020b5c7a353381c1a1c25dfb0685f8..dca101b4e59ae5823da35e30ffb00bd4d1244b51 100644 (file)
@@ -1,3 +1,26 @@
+/*
+Module: comm
+
+Communication between tasks
+
+Communication between tasks is facilitated by ports (in the receiving task),
+and channels (in the sending task). Any number of channels may feed into a
+single port.
+
+Example:
+
+> use std::task;
+> use std::comm;
+>
+> let p = comm::port();
+> task::spawn(comm::chan(p), fn (c: chan<str>) {
+>   comm::send(c, "Hello, World");
+> });
+>
+> log comm::recv(p);
+
+*/
+
 import sys;
 import ptr;
 import unsafe;
@@ -30,31 +53,66 @@ fn chan_id_send<unique T>(t: *sys::type_desc,
 
 // It's critical that this only have one variant, so it has a record
 // layout, and will work in the rust_task structure in task.rs.
-tag chan<unique T> { chan_t(task::task, port_id); }
+/*
+Type: chan
+
+A handle through which data may be sent.
+
+Each channel is associated with a single <port>.
+*/
+tag chan<unique T> {
+    chan_t(task::task, port_id);
+}
 
 resource port_ptr(po: *rustrt::rust_port) {
     rustrt::drop_port(po);
     rustrt::del_port(po);
 }
 
+/*
+Type: port
+
+A handle through which data may be received.
+
+Ports may be associated with multiple <chan>s.
+*/
 tag port<unique T> { port_t(@port_ptr); }
 
+/*
+Function: send
+
+Sends data over a channel.
+
+The sent data is moved into the channel, whereupon the caller loses access
+to it.
+*/
 fn send<unique T>(ch: chan<T>, -data: T) {
     let chan_t(t, p) = ch;
     rustrt::chan_id_send(sys::get_type_desc::<T>(), t, p, data);
     task::yield();
 }
 
+/*
+Function: port
+
+Constructs a port.
+*/
 fn port<unique T>() -> port<T> {
-    let p = rustrt::new_port(sys::size_of::<T>());
-    ret port_t(@port_ptr(p));
+    port_t(@port_ptr(rustrt::new_port(sys::size_of::<T>())))
 }
 
-fn recv<unique T>(p: port<T>) -> T {
-    ret rusti::recv(***p);
-}
+/*
+Function: recv
+
+Receive from a port.
+*/
+fn recv<unique T>(p: port<T>) -> T { ret rusti::recv(***p) }
+
+/*
+Function: chan
 
+Constructs a channel.
+*/
 fn chan<unique T>(p: port<T>) -> chan<T> {
-    let id = rustrt::get_port_id(***p);
-    ret chan_t(task::get_task_id(), id);
+    chan_t(task::get_task_id(), rustrt::get_port_id(***p))
 }
index 7e876ed760269f03a4f3aa7930dfdb5daa4037e2..5f4c999126e1368132bc45a648301848d6dec735 100644 (file)
@@ -1,5 +1,12 @@
-// FIXME: This can't be right
+/*
+Module: ctypes
+
+Definitions useful for C interop
+*/
+
+/* Type: size_t */
 type size_t = uint;
+/* Type: ssize_t */
 type ssize_t = int;
-
+/* Type: uint32_t */
 type uint32_t = u32;
index 24aa95bfc28ecb15ba024cd4a8ab4170004730b6..213003e52644226fb8a625f7eb71be387c82f0d1 100644 (file)
@@ -1,21 +1,38 @@
+/*
+Module: deque
 
+A deque.  Untested as of yet.  Likely buggy.
+*/
 
-
-/**
- * A deque, for fun.  Untested as of yet.  Likely buggy.
- */
-type t<T> =
-    obj {
-        fn size() -> uint;
-        fn add_front(T);
-        fn add_back(T);
-        fn pop_front() -> T;
-        fn pop_back() -> T;
-        fn peek_front() -> T;
-        fn peek_back() -> T;
-        fn get(int) -> T;
+/*
+Object: t
+*/
+type t<T> = obj {
+    // Method: size
+    fn size() -> uint;
+    // Method: add_front
+    fn add_front(T);
+    // Method: add_back
+    fn add_back(T);
+    // Method: pop_front
+    fn pop_front() -> T;
+    // Method: pop_back
+    fn pop_back() -> T;
+    // Method: peek_front
+    fn peek_front() -> T;
+    // Method: peek_back
+    fn peek_back() -> T;
+    // Method: get
+    fn get(int) -> T;
     };
 
+/*
+Section: Functions
+*/
+
+/*
+Function: create
+*/
 fn create<T>() -> t<T> {
     type cell<T> = option::t<T>;
 
index 143f0cabe92d1725dc28e6110a2a419caa97d256..a6774144599699fded2410a5369223cf00e83534 100644 (file)
@@ -1,15 +1,46 @@
+/*
+Module: either
+
+A type that represents one of two alternatives
+*/
 
 import option;
 import option::{some, none};
 
-tag t<T, U> { left(T); right(U); }
+/*
+Tag: t
+
+The either type
+*/
+tag t<T, U> {
+    /* Variant: left */
+    left(T);
+    /* Variant: right */
+    right(U);
+}
+
+/* Section: Operations */
+
+/*
+Function: either
+
+Applies a function based on the given either value
 
+If `value` is left(T) then `f_left` is applied to its contents, if
+`value` is right(U) then `f_right` is applied to its contents, and
+the result is returned.
+*/
 fn either<T, U,
           V>(f_left: block(T) -> V, f_right: block(U) -> V, value: t<T, U>) ->
    V {
     alt value { left(l) { f_left(l) } right(r) { f_right(r) } }
 }
 
+/*
+Function: lefts
+
+Extracts from a vector of either all the left values.
+*/
 fn lefts<T, U>(eithers: [t<T, U>]) -> [T] {
     let result: [T] = [];
     for elt: t<T, U> in eithers {
@@ -18,6 +49,11 @@ fn lefts<T, U>(eithers: [t<T, U>]) -> [T] {
     ret result;
 }
 
+/*
+Function: rights
+
+Extracts from a vector of either all the right values
+*/
 fn rights<T, U>(eithers: [t<T, U>]) -> [U] {
     let result: [U] = [];
     for elt: t<T, U> in eithers {
@@ -26,6 +62,14 @@ fn rights<T, U>(eithers: [t<T, U>]) -> [U] {
     ret result;
 }
 
+/*
+Function: partition
+
+Extracts from a vector of either all the left values and right values
+
+Returns a structure containing a vector of left values and a vector of
+right values.
+*/
 fn partition<T, U>(eithers: [t<T, U>]) -> {lefts: [T], rights: [U]} {
     let lefts: [T] = [];
     let rights: [U] = [];
@@ -34,6 +78,7 @@ fn partition<T, U>(eithers: [t<T, U>]) -> {lefts: [T], rights: [U]} {
     }
     ret {lefts: lefts, rights: rights};
 }
+
 //
 // Local Variables:
 // mode: rust
index 3f43707cc1b6753e65455f946c8f66ef309e0930..b6d04397711d4a77e491a8e129adb6df9b6e787b 100644 (file)
@@ -1,19 +1,28 @@
+/*
+Syntax Extension: fmt
 
+Format a string
+
+The 'fmt' extension is modeled on the posix printf system.
+
+A posix conversion ostensibly looks like this
+
+> %[parameter][flags][width][.precision][length]type
+
+Given the different numeric type bestiary we have, we omit the 'length'
+parameter and support slightly different conversions for 'type'
+
+> %[parameter][flags][width][.precision]type
+
+we also only support translating-to-rust a tiny subset of the possible
+combinations at the moment.
+
+Example:
+
+log #fmt("hello, %s!", "world");
+
+*/
 
-/* The 'fmt' extension is modeled on the posix printf system.
- *
- * A posix conversion ostensibly looks like this:
- *
- * %[parameter][flags][width][.precision][length]type
- *
- * Given the different numeric type bestiary we have, we omit the 'length'
- * parameter and support slightly different conversions for 'type':
- *
- * %[parameter][flags][width][.precision]type
- *
- * we also only support translating-to-rust a tiny subset of the possible
- * combinations at the moment.
- */
 import option::{some, none};
 
 
index 1d444b3111af4a387d3eebd31fa6e094ca662e07..04960c193b33b9028fb98e59206ee5a0ded2971f 100644 (file)
@@ -1,7 +1,21 @@
+/*
+Module: float
+*/
+
 /**
- * String conversions
+ * Section: String Conversions
  */
 
+/*
+Function: to_str
+
+Converts a float to a string
+
+Parameters:
+
+num - The float value
+digits: The number of significant digits
+*/
 fn to_str(num: float, digits: uint) -> str {
     let accum = if num < 0.0 { num = -num; "-" } else { "" };
     let trunc = num as uint;
@@ -19,23 +33,30 @@ fn to_str(num: float, digits: uint) -> str {
     ret accum;
 }
 
-/**
- * Convert a string to a float
- *
- * This function accepts strings such as
- * * "3.14"
- * * "+3.14", equivalent to "3.14"
- * * "-3.14"
- * * "2.5E10", or equivalently, "2.5e10"
- * * "2.5E-10"
- * * "", or, equivalently, "." (understood as 0)
- * * "5."
- * * ".5", or, equivalently,  "0.5"
- *
- * @param num A string, possibly empty.
- * @return [NaN] if the string did not represent a valid number.
- * @return Otherwise, the floating-point number represented [num].
- */
+/*
+Function: from_str
+
+Convert a string to a float
+
+This function accepts strings such as
+* "3.14"
+* "+3.14", equivalent to "3.14"
+* "-3.14"
+* "2.5E10", or equivalently, "2.5e10"
+* "2.5E-10"
+* "", or, equivalently, "." (understood as 0)
+* "5."
+* ".5", or, equivalently,  "0.5"
+
+Parameters:
+
+num - A string, possibly empty.
+
+Returns:
+
+<NaN> If the string did not represent a valid number.
+Otherwise, the floating-point number represented [num].
+*/
 fn from_str(num: str) -> float {
    let pos = 0u;                  //Current byte position in the string.
                                   //Used to walk the string in O(n).
@@ -144,17 +165,21 @@ fn from_str(num: str) -> float {
 }
 
 /**
- * Arithmetics
+ * Section: Arithmetics
  */
 
-/**
- * Compute the exponentiation of an integer by another integer as a float.
- *
- *
- * @param x The base.
- * @param pow The exponent.
- * @return [NaN] of both [x] and [pow] are [0u], otherwise [x^pow].
- */
+/*
+Function: pow_uint_to_uint_as_float
+
+Compute the exponentiation of an integer by another integer as a float.
+
+Parameters:
+x - The base.
+pow - The exponent.
+
+Returns:
+<NaN> of both `x` and `pow` are `0u`, otherwise `x^pow`.
+*/
 fn pow_uint_to_uint_as_float(x: uint, pow: uint) -> float {
    if x == 0u {
       if pow == 0u {
@@ -177,20 +202,23 @@ fn pow_uint_to_uint_as_float(x: uint, pow: uint) -> float {
 
 
 /**
- * Constants
+ * Section: Constants
  */
 
 //TODO: Once this is possible, replace the body of these functions
 //by an actual constant.
 
+/* Function: NaN */
 fn NaN() -> float {
    ret 0./0.;
 }
 
+/* Function: infinity */
 fn infinity() -> float {
    ret 1./0.;
 }
 
+/* Function: neg_infinity */
 fn neg_infinity() -> float {
    ret -1./0.;
 }
index 9a539f4b826de3f6bc73f024597d5dc7076c5fd5..5787e9c510c3f2a5b222f8a555f02edc1037fb44 100644 (file)
@@ -1,3 +1,8 @@
+/*
+Module: fs
+
+File system manipulation
+*/
 
 import os::getcwd;
 import os_fs;
     fn rust_file_is_dir(path: str::sbuf) -> int;
 }
 
+/*
+Function: path_sep
+
+Get the default path separator for the host platform
+*/
 fn path_sep() -> str { ret str::from_char(os_fs::path_sep); }
 
+// FIXME: This type should probably be constrained
+/*
+Type: path
+
+A path or fragment of a filesystem path
+*/
 type path = str;
 
+/*
+Function: dirname
+
+Get the directory portion of a path
+
+Returns all of the path up to, but excluding, the final path separator.
+The dirname of "/usr/share" will be "/usr", but the dirname of
+"/usr/share/" is "/usr/share".
+
+If the path is not prefixed with a directory, then "." is returned.
+*/
 fn dirname(p: path) -> path {
     let i: int = str::rindex(p, os_fs::path_sep as u8);
     if i == -1 {
@@ -19,6 +46,17 @@ fn dirname(p: path) -> path {
     ret str::substr(p, 0u, i as uint);
 }
 
+/*
+Function: basename
+
+Get the file name portion of a path
+
+Returns the portion of the path after the final path separator.
+The basename of "/usr/share" will be "share". If there are no
+path separators in the path then the returned path is identical to
+the provided path. If an empty path is provided or the path ends
+with a path separator then an empty path is returned.
+*/
 fn basename(p: path) -> path {
     let i: int = str::rindex(p, os_fs::path_sep as u8);
     if i == -1 {
@@ -32,6 +70,15 @@ fn basename(p: path) -> path {
 
 
 // FIXME: Need some typestate to avoid bounds check when len(pre) == 0
+/*
+Function: connect
+
+Connects to path segments
+
+Given paths `pre` and `post` this function will return a path
+that is equal to `post` appended to `pre`, inserting a path separator
+between the two as needed.
+*/
 fn connect(pre: path, post: path) -> path {
     let len = str::byte_len(pre);
     ret if pre[len - 1u] == os_fs::path_sep as u8 {
@@ -41,6 +88,13 @@ fn connect(pre: path, post: path) -> path {
         } else { pre + path_sep() + post };
 }
 
+/*
+Function: connect_many
+
+Connects a vector of path segments into a single path.
+
+Inserts path separators as needed.
+*/
 fn connect_many(paths: [path]) : vec::is_not_empty(paths) -> path {
     ret if vec::len(paths) == 1u {
         paths[0]
@@ -51,10 +105,20 @@ fn connect_many(paths: [path]) : vec::is_not_empty(paths) -> path {
     }
 }
 
+/*
+Function: file_id_dir
+
+Indicates whether a path represents a directory.
+*/
 fn file_is_dir(p: path) -> bool {
     ret str::as_buf(p, {|buf| rustrt::rust_file_is_dir(buf) != 0 });
 }
 
+/*
+Function: list_dir
+
+Lists the contents of a directory.
+*/
 fn list_dir(p: path) -> [str] {
     let p = p;
     let pl = str::byte_len(p);
@@ -68,14 +132,41 @@ fn list_dir(p: path) -> [str] {
     ret full_paths;
 }
 
+/*
+Function: path_is_absolute
+
+Indicates whether a path is absolute.
+
+A path is considered absolute if it begins at the filesystem root ("/") or,
+on Windows, begins with a drive letter.
+*/
 fn path_is_absolute(p: path) -> bool { ret os_fs::path_is_absolute(p); }
 
 // FIXME: under Windows, we should prepend the current drive letter to paths
 // that start with a slash.
+/*
+Function: make_absolute
+
+Convert a relative path to an absolute path
+
+If the given path is relative, return it prepended with the current working
+directory. If the given path is already an absolute path, return it
+as is.
+*/
 fn make_absolute(p: path) -> path {
     if path_is_absolute(p) { ret p; } else { ret connect(getcwd(), p); }
 }
 
+/*
+Function: split
+
+Split a path into it's individual components
+
+Splits a given path by path separators and returns a vector containing
+each piece of the path. On Windows, if the path is absolute then
+the first element of the returned vector will be the drive letter
+followed by a colon.
+*/
 fn split(p: path) -> [path] {
     let split1 = str::split(p, os_fs::path_sep as u8);
     let split2 = [];
@@ -85,6 +176,13 @@ fn split(p: path) -> [path] {
     ret split2;
 }
 
+/*
+Function: normalize
+
+Removes extra "." and ".." entries from paths.
+
+Does not follow symbolic links.
+*/
 fn normalize(p: path) -> path {
     let s = split(p);
     let s = strip_dots(s);
index 4a65d6191de598bae1ce6538d888726ef01c6493..4e0aea3f31922ca1dc7aa0b74cafea70fecf8aaa 100644 (file)
@@ -1,4 +1,6 @@
 /*
+Module: fun_treemap
+
 A functional key,value store that works on anything.
 
 This works using a binary search tree. In the first version, it's a
 export find;
 export traverse;
 
+/* Section: Types */
+
+/*
+Type: treemap
+*/
+type treemap<K, V> = @tree_node<K, V>;
+
+/*
+Tag: tree_node
+*/
 tag tree_node<K, V> {
     empty;
     node(@K, @V, @tree_node<K, V>, @tree_node<K, V>);
 }
 
-type treemap<K, V> = @tree_node<K, V>;
+/* Section: Operations */
+
+/*
+Function: init
 
+Create a treemap
+*/
 fn init<K, V>() -> treemap<K, V> { @empty }
 
+/*
+Function: insert
+
+Insert a value into the map
+*/
 fn insert<K, V>(m: treemap<K, V>, k: K, v: V) -> treemap<K, V> {
     @alt m {
        @empty. { node(@k, @v, @empty, @empty) }
@@ -41,6 +63,11 @@ fn insert<K, V>(m: treemap<K, V>, k: K, v: V) -> treemap<K, V> {
      }
 }
 
+/*
+Function: find
+
+Find a value based on the key
+*/
 fn find<K, V>(m: treemap<K, V>, k: K) -> option<V> {
     alt *m {
       empty. { none }
@@ -52,8 +79,11 @@ fn find<K, V>(m: treemap<K, V>, k: K) -> option<V> {
     }
 }
 
+/*
+Function: traverse
 
-// Performs an in-order traversal
+Visit all pairs in the map in order.
+*/
 fn traverse<K, V>(m: treemap<K, V>, f: fn(K, V)) {
     alt *m {
       empty. { }
index bb98c0731f81ce9430c4f4713cc9ff78dd1d051f..ebb157c621cd590ac2c9b46c4daaed2d92d571ce 100644 (file)
@@ -1,5 +1,30 @@
+/*
+Module: generic_os
+
+Some miscellaneous platform functions.
+
+These should be rolled into another module.
+*/
+
 import str::sbuf;
 
+// Wow, this is an ugly way to write doc comments
+
+#[cfg(bogus)]
+/*
+Function: getenv
+
+Get the value of an environment variable
+*/
+fn getenv(n: str) -> option::t<str> { }
+
+#[cfg(bogus)]
+/*
+Function: setenv
+
+Set the value of an environment variable
+*/
+fn setenv(n: str, v: str) { }
 
 #[cfg(target_os = "linux")]
 #[cfg(target_os = "macos")]
index beae20a0d910c0ddb7a644b54ea28102ca183c45..b4f9dee8e7228b41879891f02f5f306fe732a7f2 100644 (file)
@@ -1,13 +1,50 @@
+/*
+Module: getopts
 
+Simple getopt alternative. Construct a vector of options, either by using
+reqopt, optopt, and optflag or by building them from components yourself, and
+pass them to getopts, along with a vector of actual arguments (not including
+argv[0]). You'll either get a failure code back, or a match.  You'll have to
+verify whether the amount of 'free' arguments in the match is what you
+expect. Use opt_* accessors to get argument values out of the match object.
+
+Single-character options are expected to appear on the command line with a
+single preceeding dash; multiple-character options are expected to be
+proceeded by two dashes. Options that expect an argument accept their argument
+following either a space or an equals sign.
+
+Example:
+
+The following example shows simple command line parsing for an application
+that requires an input file to be specified, accepts an optional output file
+name following -o, and accepts both -h and --help as optional flags.
+
+> fn main(args: [str]) {
+>   let opts = [
+>     optopt("o"),
+>     optflag("h"),
+>     optflag("help")
+>   ];
+>   let match = alt getopts(vec::shift(args), opts) {
+>     success(m) { m }
+>     failure(f) { fail fail_str(f) }
+>   };
+>   if opt_present(match, "h") || opt_present(match, "help") {
+>     print_usage();
+>     ret;
+>   }
+>   let output = opt_maybe_str(match, "o");
+>   let input = if !vec::is_empty(match.free) {
+>     match.free[0]
+>   } else {
+>     print_usage();
+>     ret;
+>   }
+>   do_work(input, output);
+> }
+
+*/
 
-/* Simple getopt alternative. Construct a vector of options, either by using
- * reqopt, optopt, and optflag or by building them from components yourself,
- * and pass them to getopts, along with a vector of actual arguments (not
- * including argv[0]). You'll either get a failure code back, or a match.
- * You'll have to verify whether the amount of 'free' arguments in the match
- * is what you expect. Use opt_* accessors (bottom of the file) to get
- * argument values out of the match object.
- */
 import option::{some, none};
 export opt;
 export reqopt;
 
 tag occur { req; optional; multi; }
 
+/*
+Type: opt
+
+A description of a possible option
+*/
 type opt = {name: name, hasarg: hasarg, occur: occur};
 
 fn mkname(nm: str) -> name {
@@ -42,28 +84,60 @@ fn mkname(nm: str) -> name {
         } else { long(nm) };
 }
 
+/*
+Function: reqopt
+
+Create an option that is required and takes an argument
+*/
 fn reqopt(name: str) -> opt {
     ret {name: mkname(name), hasarg: yes, occur: req};
 }
 
+/*
+Function: optopt
+
+Create an option that is optional and takes an argument
+*/
 fn optopt(name: str) -> opt {
     ret {name: mkname(name), hasarg: yes, occur: optional};
 }
 
+/*
+Function: optflag
+
+Create an option that is optional and does not take an argument
+*/
 fn optflag(name: str) -> opt {
     ret {name: mkname(name), hasarg: no, occur: optional};
 }
 
+/*
+Function: optflagopt
+
+Create an option that is optional and takes an optional argument
+*/
 fn optflagopt(name: str) -> opt {
     ret {name: mkname(name), hasarg: maybe, occur: optional};
 }
 
+/*
+Function: optmulti
+
+Create an option that is optional, takes an argument, and may occur
+multiple times
+*/
 fn optmulti(name: str) -> opt {
     ret {name: mkname(name), hasarg: yes, occur: multi};
 }
 
 tag optval { val(str); given; }
 
+/*
+Type: match
+
+The result of checking command line arguments. Contains a vector
+of matches and a vector of free strings.
+*/
 type match = {opts: [opt], vals: [mutable [optval]], free: [str]};
 
 fn is_arg(arg: str) -> bool {
@@ -81,6 +155,12 @@ fn find_opt(opts: [opt], nm: name) -> option::t<uint> {
     ret none::<uint>;
 }
 
+/*
+Type: fail_
+
+The type returned when the command line does not conform to the
+expected format. Pass this value to <fail_str> to get an error message.
+*/
 tag fail_ {
     argument_missing(str);
     unrecognized_option(str);
@@ -89,6 +169,11 @@ fn find_opt(opts: [opt], nm: name) -> option::t<uint> {
     unexpected_argument(str);
 }
 
+/*
+Function: fail_str
+
+Convert a <fail_> tag into an error string
+*/
 fn fail_str(f: fail_) -> str {
     ret alt f {
           argument_missing(nm) { "Argument to option '" + nm + "' missing." }
@@ -103,8 +188,29 @@ fn fail_str(f: fail_) -> str {
         };
 }
 
+/*
+Type: result
+
+The result of parsing a command line with a set of options
+
+Variants:
+
+success(match) - Returned from getopts on success
+failure(fail_) - Returned from getopts on failure
+*/
 tag result { success(match); failure(fail_); }
 
+/*
+Function: getopts
+
+Parse command line arguments according to the provided options
+
+Returns:
+
+success(match) - On success. Use functions such as <opt_present>
+                 <opt_str>, etc. to interrogate results.
+failure(fail_) - On failure. Use <fail_str> to get an error message.
+*/
 fn getopts(args: [str], opts: [opt]) -> result {
     let n_opts = vec::len::<opt>(opts);
     fn f(_x: uint) -> [optval] { ret []; }
@@ -208,14 +314,35 @@ fn opt_vals(m: match, nm: str) -> [optval] {
 
 fn opt_val(m: match, nm: str) -> optval { ret opt_vals(m, nm)[0]; }
 
+/*
+Function: opt_present
+
+Returns true if an option was matched
+*/
 fn opt_present(m: match, nm: str) -> bool {
     ret vec::len::<optval>(opt_vals(m, nm)) > 0u;
 }
 
+/*
+Function: opt_str
+
+Returns the string argument supplied to a matching option
+
+Failure:
+
+- If the option was not matched
+- If the match did not take an argument
+*/
 fn opt_str(m: match, nm: str) -> str {
     ret alt opt_val(m, nm) { val(s) { s } _ { fail } };
 }
 
+/*
+Function: opt_str
+
+Returns a vector of the arguments provided to all matches of the given option.
+Used when an option accepts multiple values.
+*/
 fn opt_strs(m: match, nm: str) -> [str] {
     let acc: [str] = [];
     for v: optval in opt_vals(m, nm) {
@@ -224,6 +351,11 @@ fn opt_strs(m: match, nm: str) -> [str] {
     ret acc;
 }
 
+/*
+Function: opt_str
+
+Returns the string argument supplied to a matching option or none
+*/
 fn opt_maybe_str(m: match, nm: str) -> option::t<str> {
     let vals = opt_vals(m, nm);
     if vec::len::<optval>(vals) == 0u { ret none::<str>; }
@@ -231,9 +363,15 @@ fn opt_maybe_str(m: match, nm: str) -> option::t<str> {
 }
 
 
-/// Returns none if the option was not present, `def` if the option was
-/// present but no argument was provided, and the argument if the option was
-/// present and an argument was provided.
+/*
+Function: opt_default
+
+Returns the matching string, a default, or none
+
+Returns none if the option was not present, `def` if the option was
+present but no argument was provided, and the argument if the option was
+present and an argument was provided.
+*/
 fn opt_default(m: match, nm: str, def: str) -> option::t<str> {
     let vals = opt_vals(m, nm);
     if vec::len::<optval>(vals) == 0u { ret none::<str>; }
index 7b08b1d8df3d282889e80dddbab8e77b18d04ca6..464ac9deea50c3b8575addda8162417182f0a7be 100644 (file)
+/*
+Module: int
+*/
+
+/*
+Function: max_value
+
+The maximum value of an integer
+*/
 fn max_value() -> int {
   ret min_value() - 1;
 }
 
+/*
+Function: min_value
+
+The minumum value of an integer
+*/
 fn min_value() -> int {
   ret (-1 << (sys::size_of::<int>()  * 8u as int - 1)) as int;
 }
 
-
+/* Function: add */
 pure fn add(x: int, y: int) -> int { ret x + y; }
 
+/* Function: sub */
 pure fn sub(x: int, y: int) -> int { ret x - y; }
 
+/* Function: mul */
 pure fn mul(x: int, y: int) -> int { ret x * y; }
 
+/* Function: div */
 pure fn div(x: int, y: int) -> int { ret x / y; }
 
+/* Function: rem */
 pure fn rem(x: int, y: int) -> int { ret x % y; }
 
+/* Predicate: lt */
 pure fn lt(x: int, y: int) -> bool { ret x < y; }
 
+/* Predicate: le */
 pure fn le(x: int, y: int) -> bool { ret x <= y; }
 
+/* Predicate: eq */
 pure fn eq(x: int, y: int) -> bool { ret x == y; }
 
+/* Predicate: ne */
 pure fn ne(x: int, y: int) -> bool { ret x != y; }
 
+/* Predicate: ge */
 pure fn ge(x: int, y: int) -> bool { ret x >= y; }
 
+/* Predicate: gt */
 pure fn gt(x: int, y: int) -> bool { ret x > y; }
 
+/* Predicate: positive */
 pure fn positive(x: int) -> bool { ret x > 0; }
 
+/* Predicate: negative */
 pure fn negative(x: int) -> bool { ret x < 0; }
 
+/* Predicate: nonpositive */
 pure fn nonpositive(x: int) -> bool { ret x <= 0; }
 
+/* Predicate: nonnegative */
 pure fn nonnegative(x: int) -> bool { ret x >= 0; }
 
 
 // FIXME: Make sure this works with negative integers.
+/*
+Function: hash
+
+Produce a uint suitable for use in a hash table
+*/
 fn hash(x: int) -> uint { ret x as uint; }
 
+// FIXME: This is redundant
 fn eq_alias(x: int, y: int) -> bool { ret x == y; }
 
+/*
+Function: range
+
+Iterate over the range [`lo`..`hi`)
+*/
 fn range(lo: int, hi: int, it: block(int)) {
     while lo < hi { it(lo); lo += 1; }
 }
 
+/*
+Function: parse_buf
+
+Parse a buffer of bytes
+
+Parameters:
+
+buf - A byte buffer
+radix - The base of the number
+
+Failure:
+
+buf must not be empty
+*/
 fn parse_buf(buf: [u8], radix: uint) -> int {
     if vec::len::<u8>(buf) == 0u {
         log_err "parse_buf(): buf is empty";
@@ -68,16 +121,41 @@ fn parse_buf(buf: [u8], radix: uint) -> int {
     fail;
 }
 
+/*
+Function: from_str
+
+Parse a string to an int
+
+Failure:
+
+s must not be empty
+*/
 fn from_str(s: str) -> int { parse_buf(str::bytes(s), 10u) }
 
+/*
+Function: to_str
+
+Convert to a string in a given base
+*/
 fn to_str(n: int, radix: uint) -> str {
     assert (0u < radix && radix <= 16u);
     ret if n < 0 {
             "-" + uint::to_str(-n as uint, radix)
         } else { uint::to_str(n as uint, radix) };
 }
+
+/*
+Function: str
+
+Convert to a string
+*/
 fn str(i: int) -> str { ret to_str(i, 10u); }
 
+/*
+Function: pow
+
+Returns `base` raised to the power of `exponent`
+*/
 fn pow(base: int, exponent: uint) -> int {
     if exponent == 0u { ret 1; } //Not mathemtically true if [base == 0]
     if base     == 0  { ret 0; }
index 57ea12d3850fd038e6241a382cb0a4103aed12a6..ab93699f8e53f39c0d0bf0f8e38b8651cba36e73 100644 (file)
@@ -1,4 +1,3 @@
-
 import os::libc;
 
 native "c-stack-cdecl" mod rustrt {
index 50240c3087b4e51b34000d73ca806ab65bb7aa58..970349c7d31a3a6798a2f82e749032233a9f7206 100644 (file)
@@ -1,30 +1,85 @@
-// lib/option::rs
+/*
+Module: option
 
-tag t<T> { none; some(T); }
+Represents the presence or absence of a value.
 
+Every option<T> value can either be some(T) or none. Where in other languages
+you might use a nullable type, in Rust you would use an option type.
+*/
+
+/*
+Tag: t
+
+The option type
+*/
+tag t<T> {
+    /* Variant: none */
+    none;
+    /* Variant: some */
+    some(T);
+}
+
+/* Section: Operations */
+
+/*
+Function: get
+
+Gets the value out of an option
+
+Failure:
+
+Fails if the value equals `none`.
+*/
 fn get<T>(opt: t<T>) -> &T {
     alt opt { some(x) { ret x; } none. { fail "option none"; } }
 }
 
+/*
+*/
 fn map<T, U>(f: block(T) -> U, opt: t<T>) -> t<U> {
     alt opt { some(x) { some(f(x)) } none. { none } }
 }
 
+/*
+Function: is_none
+
+Returns true if the option equals none
+*/
 fn is_none<T>(opt: t<T>) -> bool {
     alt opt { none. { true } some(_) { false } }
 }
 
+/*
+Function: is_some
+
+Returns true if the option contains some value
+*/
 fn is_some<T>(opt: t<T>) -> bool { !is_none(opt) }
 
+/*
+Function: from_maybe
+
+Returns the contained value or a default
+*/
 fn from_maybe<T>(def: T, opt: t<T>) -> T {
     alt opt { some(x) { x } none. { def } }
 }
 
+/*
+Function: maybe
+
+Applies a function to the contained value or returns a default
+*/
 fn maybe<T, U>(def: U, f: block(T) -> U, opt: t<T>) -> U {
     alt opt { none. { def } some(t) { f(t) } }
 }
 
-// Can be defined in terms of the above when/if we have const bind.
+// FIXME: Can be defined in terms of the above when/if we have const bind.
+/*
+Function: may
+
+Performs an operation on the contained value or does nothing
+*/
 fn may<T>(f: block(T), opt: t<T>) {
     alt opt { none. {/* nothing */ } some(t) { f(t); } }
 }
index 89b47685d8a35dc4b71e42d70ebc22a5dbb0e38e..7f2539fd4c594f6de2632bdc5b51b371e043bc30 100644 (file)
@@ -1,4 +1,3 @@
-
 #[link(name = "std",
        vers = "0.1",
        uuid = "122bed0b-c19b-4b82-b0b7-7ae8aead7297",
index a361bd20cdb26e9ab6cffdd4d8fd44ba6f77bf85..68d732449c65b821ebb156dc63b1f5f213179db7 100644 (file)
@@ -1,4 +1,6 @@
 /*
+Module: treemap
+
 A key,value store that works on anything.
 
 This works using a binary search tree. In the first version, it's a
 export find;
 export traverse;
 
-tag tree_node<K, V> { empty; node(@K, @V, treemap<K, V>, treemap<K, V>); }
+/* Section: Types */
 
+/*
+Type: treemap
+*/
 type treemap<K, V> = @mutable tree_node<K, V>;
 
+/*
+Tag: tree_node
+*/
+tag tree_node<K, V> { empty; node(@K, @V, treemap<K, V>, treemap<K, V>); }
+
+/* Section: Operations */
+
+/*
+Function: init
+
+Create a treemap
+*/
 fn init<K, V>() -> treemap<K, V> { @mutable empty }
 
+/*
+Function: insert
+
+Insert a value into the map
+*/
 fn insert<K, V>(m: treemap<K, V>, k: K, v: V) {
     alt m {
       @empty. { *m = node(@k, @v, @mutable empty, @mutable empty); }
@@ -36,6 +58,11 @@ fn insert<K, V>(m: treemap<K, V>, k: K, v: V) {
     }
 }
 
+/*
+Function: find
+
+Find a value based on the key
+*/
 fn find<K, V>(m: treemap<K, V>, k: K) -> option<V> {
     alt *m {
       empty. { none }
@@ -51,7 +78,11 @@ fn find<K, V>(m: treemap<K, V>, k: K) -> option<V> {
     }
 }
 
-// Performs an in-order traversal
+/*
+Function: traverse
+
+Visit all pairs in the map in order.
+*/
 fn traverse<K, V>(m: treemap<K, V>, f: fn@(K, V)) {
     alt *m {
       empty. { }
index e0184767e9d20aa1ec3476ef942b94d522f4ef89..08c8aa52a8a56056e16b7a80b5e32c145f2b3fa5 100644 (file)
@@ -1,4 +1,6 @@
-// Interior vector utility functions.
+/*
+Module: vec
+*/
 
 import option::{some, none};
 import uint::next_power_of_two;
@@ -17,15 +19,40 @@ fn vec_from_buf_shared<T>(t: *sys::type_desc,
                               count: uint) -> [T];
 }
 
-/// Reserves space for `n` elements in the given vector.
+/*
+Function: reserve
+
+Reserves capacity for `n` elements in the given vector.
+
+If the capacity for `v` is already equal to or greater than the requested
+capacity, then no action is taken.
+
+Parameters:
+
+v - A vector
+n - The number of elements to reserve space for
+*/
 fn reserve<T>(&v: [mutable? T], n: uint) {
     rustrt::vec_reserve_shared(sys::get_type_desc::<T>(), v, n);
 }
 
 pure fn len<T>(v: [mutable? T]) -> uint { unchecked { rusti::vec_len(v) } }
 
+/*
+Type: init_op
+
+A function used to initialize the elements of a vector.
+*/
 type init_op<T> = fn@(uint) -> T;
 
+/*
+Function: init_fn
+
+Creates and initializes an immutable vector.
+
+Creates an immutable vector of size `n_elts` and initializes the elements
+to the value returned by the function `op`.
+*/
 fn init_fn<T>(op: init_op<T>, n_elts: uint) -> [T] {
     let v = [];
     reserve(v, n_elts);
@@ -35,6 +62,14 @@ fn init_fn<T>(op: init_op<T>, n_elts: uint) -> [T] {
 }
 
 // TODO: Remove me once we have slots.
+/*
+Function: init_fn
+
+Creates and initializes a mutable vector.
+
+Creates a mutable vector of size `n_elts` and initializes the elements to
+the value returned by the function `op`.
+*/
 fn init_fn_mut<T>(op: init_op<T>, n_elts: uint) -> [mutable T] {
     let v = [mutable];
     reserve(v, n_elts);
@@ -43,6 +78,14 @@ fn init_fn_mut<T>(op: init_op<T>, n_elts: uint) -> [mutable T] {
     ret v;
 }
 
+/*
+Function: init_elt
+
+Creates and initializes an immutable vector.
+
+Creates an immutable vector of size `n_elts` and initializes the elements
+to the value `t`.
+*/
 fn init_elt<T>(t: T, n_elts: uint) -> [T] {
     let v = [];
     reserve(v, n_elts);
@@ -52,6 +95,14 @@ fn init_elt<T>(t: T, n_elts: uint) -> [T] {
 }
 
 // TODO: Remove me once we have slots.
+/*
+Function: init_elt_mut
+
+Creates and initializes a mutable vector.
+
+Creates a mutable vector of size `n_elts` and initializes the elements
+to the value `t`.
+*/
 fn init_elt_mut<T>(t: T, n_elts: uint) -> [mutable T] {
     let v = [mutable];
     reserve(v, n_elts);
@@ -62,6 +113,11 @@ fn init_elt_mut<T>(t: T, n_elts: uint) -> [mutable T] {
 
 // FIXME: Possible typestate postcondition:
 // len(result) == len(v) (needs issue #586)
+/*
+Function: to_mut
+
+Produces a mutable vector from an immutable vector.
+*/
 fn to_mut<T>(v: [T]) -> [mutable T] {
     let vres = [mutable];
     for t: T in v { vres += [mutable t]; }
@@ -69,43 +125,91 @@ fn to_mut<T>(v: [T]) -> [mutable T] {
 }
 
 // Same comment as from_mut
+/*
+Function: from_mut
+
+Produces an immutable vector from a mutable vector.
+*/
 fn from_mut<T>(v: [mutable T]) -> [T] {
     let vres = [];
     for t: T in v { vres += [t]; }
     ret vres;
 }
 
-// Predicates
+/*
+Predicate: is_empty
+
+Returns true if a vector contains no elements.
+*/
 pure fn is_empty<T>(v: [mutable? T]) -> bool {
     // FIXME: This would be easier if we could just call len
     for t: T in v { ret false; }
     ret true;
 }
 
+/*
+Predicate: is_not_empty
+
+Returns true if a vector contains some elements.
+*/
 pure fn is_not_empty<T>(v: [mutable? T]) -> bool { ret !is_empty(v); }
 
 // Accessors
 
-/// Returns the first element of a vector
+/*
+Function: head
+
+Returns the first element of a vector
+
+Predicates:
+<is_not_empty> (v)
+*/
 fn head<T>(v: [mutable? T]) : is_not_empty(v) -> T { ret v[0]; }
 
-/// Returns all but the first element of a vector
+/*
+Function: tail
+
+Returns all but the first element of a vector
+
+Predicates:
+<is_not_empty> (v)
+*/
 fn tail<T>(v: [mutable? T]) : is_not_empty(v) -> [T] {
     ret slice(v, 1u, len(v));
 }
 
-/// Returns the last element of `v`.
+/*
+Function: last
+
+Returns the last element of `v`
+
+Returns:
+
+An option containing the last element of `v` if `v` is not empty, or
+none if `v` is empty.
+*/
 fn last<T>(v: [mutable? T]) -> option::t<T> {
     if len(v) == 0u { ret none; }
     ret some(v[len(v) - 1u]);
 }
 
-/// Returns the last element of a non-empty vector `v`.
+/*
+Function: last_total
+
+Returns the last element of a non-empty vector `v`
+
+Predicates:
+<is_not_empty> (v)
+*/
 fn last_total<T>(v: [mutable? T]) : is_not_empty(v) -> T {
     ret v[len(v) - 1u];
 }
 
-/// Returns a copy of the elements from [`start`..`end`) from `v`.
+/*
+Function: slice
+
+Returns a copy of the elements from [`start`..`end`) from `v`.
+*/
 fn slice<T>(v: [mutable? T], start: uint, end: uint) -> [T] {
     assert (start <= end);
     assert (end <= len(v));
@@ -117,6 +221,11 @@ fn slice<T>(v: [mutable? T], start: uint, end: uint) -> [T] {
 }
 
 // TODO: Remove me once we have slots.
+/*
+Function: slice_mut
+
+Returns a copy of the elements from [`start`..`end`) from `v`.
+*/
 fn slice_mut<T>(v: [mutable? T], start: uint, end: uint) -> [mutable T] {
     assert (start <= end);
     assert (end <= len(v));
@@ -130,6 +239,11 @@ fn slice_mut<T>(v: [mutable? T], start: uint, end: uint) -> [mutable T] {
 
 // Mutators
 
+/*
+Function: shift
+
+Removes the first element from a vector and return it
+*/
 fn shift<T>(&v: [mutable? T]) -> T {
     let ln = len::<T>(v);
     assert (ln > 0u);
@@ -139,6 +253,11 @@ fn shift<T>(&v: [mutable? T]) -> T {
 }
 
 // TODO: Write this, unsafely, in a way that's not O(n).
+/*
+Function: pop
+
+Remove the last element from a vector and return it
+*/
 fn pop<T>(&v: [mutable? T]) -> T {
     let ln = len(v);
     assert (ln > 0u);
@@ -153,7 +272,17 @@ fn pop<T>(&v: [mutable? T]) -> T {
 
 // Appending
 
-/// Expands the given vector in-place by appending `n` copies of `initval`.
+/*
+Function: grow
+
+Expands a vector in place, initializing the new elements to a given value
+
+Parameters:
+
+v - The vector to grow
+n - The number of elements to add
+initval - The value for the new elements
+*/
 fn grow<T>(&v: [T], n: uint, initval: T) {
     reserve(v, next_power_of_two(len(v) + n));
     let i: uint = 0u;
@@ -161,23 +290,54 @@ fn grow<T>(&v: [T], n: uint, initval: T) {
 }
 
 // TODO: Remove me once we have slots.
+// FIXME: Can't grow take a [mutable? T]
+/*
+Function: grow_mut
+
+Expands a vector in place, initializing the new elements to a given value
+
+Parameters:
+
+v - The vector to grow
+n - The number of elements to add
+initval - The value for the new elements
+*/
 fn grow_mut<T>(&v: [mutable T], n: uint, initval: T) {
     reserve(v, next_power_of_two(len(v) + n));
     let i: uint = 0u;
     while i < n { v += [mutable initval]; i += 1u; }
 }
 
-/// Calls `f` `n` times and appends the results of these calls to the given
-/// vector.
+/*
+Function: grow_fn
+
+Expands a vector in place, initializing the new elements to the result of a
+function
+
+Function `init_fn` is called `n` times with the values [0..`n`)
+
+Parameters:
+
+v - The vector to grow
+n - The number of elements to add
+init_fn - A function to call to retreive each appended element's value
+*/
 fn grow_fn<T>(&v: [T], n: uint, init_fn: fn(uint) -> T) {
     reserve(v, next_power_of_two(len(v) + n));
     let i: uint = 0u;
     while i < n { v += [init_fn(i)]; i += 1u; }
 }
 
-/// Sets the element at position `index` to `val`. If `index` is past the end
-/// of the vector, expands the vector by replicating `initval` to fill the
-/// intervening space.
+/*
+Function: grow_set
+
+Sets the value of a vector element at a given index, growing the vector as
+needed
+
+Sets the element at position `index` to `val`. If `index` is past the end
+of the vector, expands the vector by replicating `initval` to fill the
+intervening space.
+*/
 fn grow_set<T>(&v: [mutable T], index: uint, initval: T, val: T) {
     if index >= len(v) { grow_mut(v, index - len(v) + 1u, initval); }
     v[index] = val;
@@ -186,6 +346,11 @@ fn grow_set<T>(&v: [mutable T], index: uint, initval: T, val: T) {
 
 // Functional utilities
 
+/*
+Function: map
+
+Apply a function to each element of a vector and return the results
+*/
 fn map<T, U>(f: block(T) -> U, v: [mutable? T]) -> [U] {
     let result = [];
     reserve(result, len(v));
@@ -196,6 +361,11 @@ fn map<T, U>(f: block(T) -> U, v: [mutable? T]) -> [U] {
     ret result;
 }
 
+/*
+Function: map2
+
+Apply a function to each pair of elements and return the results
+*/
 fn map2<T, U, V>(f: block(T, U) -> V, v0: [T], v1: [U]) -> [V] {
     let v0_len = len::<T>(v0);
     if v0_len != len::<U>(v1) { fail; }
@@ -205,6 +375,14 @@ fn map2<T, U, V>(f: block(T, U) -> V, v0: [T], v1: [U]) -> [V] {
     ret u;
 }
 
+/*
+Function: filter_map
+
+Apply a function to each element of a vector and return the results
+
+If function `f` returns `none` then that element is excluded from
+the resulting vector.
+*/
 fn filter_map<T, U>(f: block(T) -> option::t<U>, v: [mutable? T]) -> [U] {
     let result = [];
     for elem: T in v {
@@ -217,6 +395,15 @@ fn filter_map<T, U>(f: block(T) -> option::t<U>, v: [mutable? T]) -> [U] {
     ret result;
 }
 
+/*
+Function: filter
+
+Construct a new vector from the elements of a vector for which some predicate
+holds.
+
+Apply function `f` to each element of `v` and return a vector containing
+only those elements for which `f` returned true.
+*/
 fn filter<T>(f: block(T) -> bool, v: [mutable? T]) -> [T] {
     let result = [];
     for elem: T in v {
@@ -228,6 +415,11 @@ fn filter<T>(f: block(T) -> bool, v: [mutable? T]) -> [T] {
     ret result;
 }
 
+/*
+Function: foldl
+
+FIXME: This looks like it's actually foldr
+*/
 fn foldl<T, U>(p: block(U, T) -> U, z: U, v: [mutable? T]) -> U {
     let sz = len(v);
     if sz == 0u { ret z; }
@@ -236,44 +428,97 @@ fn foldl<T, U>(p: block(U, T) -> U, z: U, v: [mutable? T]) -> U {
     ret p(foldl(p, z, rest), first);
 }
 
+/*
+Function: any
+
+Return true if a predicate matches any elements
+
+If the vector contains no elements then false is returned.
+*/
 fn any<T>(f: block(T) -> bool, v: [T]) -> bool {
     for elem: T in v { if f(elem) { ret true; } }
     ret false;
 }
 
+/*
+Function: all
+
+Return true if a predicate matches all elements
+
+If the vector contains no elements then true is returned.
+*/
 fn all<T>(f: block(T) -> bool, v: [T]) -> bool {
     for elem: T in v { if !f(elem) { ret false; } }
     ret true;
 }
 
+/*
+Function: member
+
+Return true if a vector contains an element with the given value
+*/
 fn member<T>(x: T, v: [T]) -> bool {
     for elt: T in v { if x == elt { ret true; } }
     ret false;
 }
 
+/*
+Function: count
+
+Returns the number of elements that are equal to a given value
+*/
 fn count<T>(x: T, v: [mutable? T]) -> uint {
     let cnt = 0u;
     for elt: T in v { if x == elt { cnt += 1u; } }
     ret cnt;
 }
 
+/*
+Function: find
+
+Search for an element that matches a given predicate
+
+Apply function `f` to each element of `v`, starting from the first.
+When function `f` matches then an option containing the element
+is returned. If `f` matches no elements then none is returned.
+*/
 fn find<T>(f: block(T) -> bool, v: [T]) -> option::t<T> {
     for elt: T in v { if f(elt) { ret some(elt); } }
     ret none;
 }
 
+/*
+Function: position
+
+Find the first index containing a matching value
+
+Returns:
+
+option::some(uint) - The first index containing a matching value
+option::none - No elements matched
+*/
 fn position<T>(x: T, v: [T]) -> option::t<uint> {
     let i: uint = 0u;
     while i < len(v) { if x == v[i] { ret some::<uint>(i); } i += 1u; }
     ret none;
 }
 
+/*
+Function: position_pred
+
+Find the first index for which the value matches some predicate
+*/
 fn position_pred<T>(f: fn(T) -> bool, v: [T]) -> option::t<uint> {
     let i: uint = 0u;
     while i < len(v) { if f(v[i]) { ret some::<uint>(i); } i += 1u; }
     ret none;
 }
 
+/*
+Predicate: same_length
+
+Returns true if two vectors have the same length
+*/
 pure fn same_length<T, U>(xs: [T], ys: [U]) -> bool {
     vec::len(xs) == vec::len(ys)
 }
@@ -282,12 +527,34 @@ fn position_pred<T>(f: fn(T) -> bool, v: [T]) -> option::t<uint> {
 // saying the two result lists have the same length -- or, could
 // return a nominal record with a constraint saying that, instead of
 // returning a tuple (contingent on issue #869)
+/*
+Function: unzip
+
+Convert a vector of pairs into a pair of vectors
+
+Returns a tuple containing two vectors where the i-th element of the first
+vector contains the first element of the i-th tuple of the input vector,
+and the i-th element of the second vector contains the second element
+of the i-th tuple of the input vector.
+*/
 fn unzip<T, U>(v: [(T, U)]) -> ([T], [U]) {
     let as = [], bs = [];
     for (a, b) in v { as += [a]; bs += [b]; }
     ret (as, bs);
 }
 
+/*
+Function: zip
+
+Convert two vectors to a vector of pairs
+
+Returns a vector of tuples, where the i-th tuple contains contains the
+i-th elements from each of the input vectors.
+
+Preconditions:
+
+<same_length> (v, u)
+*/
 fn zip<T, U>(v: [T], u: [U]) : same_length(v, u) -> [(T, U)] {
     let zipped = [];
     let sz = len(v), i = 0u;
@@ -296,14 +563,27 @@ fn zip<T, U>(v: [T], u: [U]) : same_length(v, u) -> [(T, U)] {
     ret zipped;
 }
 
-// Swaps two elements in a vector
+/*
+Function: swap
+
+Swaps two elements in a vector
+
+Parameters:
+v - The input vector
+a - The index of the first element
+b - The index of the second element
+*/
 fn swap<T>(v: [mutable T], a: uint, b: uint) {
     let t: T = v[a];
     v[a] = v[b];
     v[b] = t;
 }
 
-// In place vector reversal
+/*
+Function: reverse
+
+Reverse the order of elements in a vector, in place
+*/
 fn reverse<T>(v: [mutable T]) {
     let i: uint = 0u;
     let ln = len::<T>(v);
@@ -311,7 +591,11 @@ fn reverse<T>(v: [mutable T]) {
 }
 
 
-// Functional vector reversal. Returns a reversed copy of v.
+/*
+Function: reversed
+
+Returns a vector with the order of elements reversed
+*/
 fn reversed<T>(v: [T]) -> [T] {
     let rs: [T] = [];
     let i = len::<T>(v);
@@ -321,7 +605,12 @@ fn reversed<T>(v: [T]) -> [T] {
     ret rs;
 }
 
-// Generating vecs.
+// FIXME: Seems like this should take char params. Maybe belongs in char
+/*
+Function: enum_chars
+
+Returns a vector containing a range of chars
+*/
 fn enum_chars(start: u8, end: u8) : u8::le(start, end) -> [char] {
     let i = start;
     let r = [];
@@ -329,6 +618,12 @@ fn enum_chars(start: u8, end: u8) : u8::le(start, end) -> [char] {
     ret r;
 }
 
+// FIXME: Probably belongs in uint. Compare to uint::range
+/*
+Function: enum_uints
+
+Returns a vector containing a range of uints
+*/
 fn enum_uints(start: uint, end: uint) : uint::le(start, end) -> [uint] {
     let i = start;
     let r = [];
@@ -336,6 +631,14 @@ fn enum_uints(start: uint, end: uint) : uint::le(start, end) -> [uint] {
     ret r;
 }
 
+/*
+Function: eachi
+
+Iterates over a vector's elements and indexes
+
+Iterates over vector `v` and, for each element, calls function `f`
+with the element's value and index.
+*/
 fn eachi<T>(f: block(T, uint) -> (), v: [mutable? T]) {
     let i = 0u;
     let l = len(v);
@@ -346,33 +649,75 @@ fn eachi<T>(f: block(T, uint) -> (), v: [mutable? T]) {
     }
 }
 
-// Iterate over a list with with the indexes
+/*
+Function: iter2
+
+FIXME: This is exactly the same as eachi
+*/
 fn iter2<T>(v: [T], it: block(uint, T)) {
     let i = 0u;
     for x in v { it(i, x); i += 1u; }
 }
 
+/*
+Function: to_ptr
+
+FIXME: We don't need this wrapper
+*/
+unsafe fn to_ptr<T>(v: [T]) -> *T { ret unsafe::to_ptr(v); }
+
+/*
+Module: unsafe
+*/
 mod unsafe {
     type vec_repr = {mutable fill: uint, mutable alloc: uint, data: u8};
 
+    /*
+    Function: from_buf
+
+    Constructs a vector from an unsafe pointer to a buffer
+
+    Parameters:
+
+    ptr - An unsafe pointer to a buffer of `T`
+    elts - The number of elements in the buffer
+    */
     unsafe fn from_buf<T>(ptr: *T, elts: uint) -> [T] {
         ret rustrt::vec_from_buf_shared(sys::get_type_desc::<T>(),
                                         ptr, elts);
     }
 
+    /*
+    Function: set_len
+
+    Sets the length of a vector
+
+    This well explicitly set the size of the vector, without actually
+    modifing its buffers, so it is up to the caller to ensure that
+    the vector is actually the specified size.
+    */
     unsafe fn set_len<T>(&v: [T], new_len: uint) {
         let repr: **vec_repr = ::unsafe::reinterpret_cast(addr_of(v));
         (**repr).fill = new_len * sys::size_of::<T>();
     }
 
+    /*
+    Function: to_ptr
+
+    Returns an unsafe pointer to the vector's buffer
+
+    The caller must ensure that the vector outlives the pointer this
+    function returns, or else it will end up pointing to garbage.
+
+    Modifying the vector may cause its buffer to be reallocated, which
+    would also make any pointers to it invalid.
+    */
     unsafe fn to_ptr<T>(v: [T]) -> *T {
         let repr: **vec_repr = ::unsafe::reinterpret_cast(addr_of(v));
         ret ::unsafe::reinterpret_cast(addr_of((**repr).data));
     }
 }
 
-unsafe fn to_ptr<T>(v: [T]) -> *T { ret unsafe::to_ptr(v); }
-
 // Local Variables:
 // mode: rust;
 // fill-column: 78;