Function ======== abs acos add_method add_var ancestors anticipate_assignmeasin atan nt atan2 atomic backup bind_function bind_port buf_replace buf_to_str buf_to_strings bufgraft bufidx buflen cache_info call_trace caller cancel children chparents clear_var close_connection config connection cos create crypt ctime cwrite cwritef data dblog debug_callers definer del_method del_objname del_var delete destroy dict_add dict_contains dict_del dict_keys dict_union dict_values error execute exp explode fchmod fclose feof fflush file files find_method find_next_method fmkdir fopen fread fremove frename frmdir frob_class frob_handler frob_value fromliteral fseek fstat fwrite get_var has_ancestor insert join list_method listgraft listidx listlen localtime log lookup lowercase match_begin match_crypted match_pattern match_regexp match_template max method method_access method_bytecode method_flags method_info methods min mtime objname objnum open_connection pad parents pass pause pow random reassign_connectionrefresh regexp rename_method replace resume rethrow sender set_heartbeat set_method_access set_method_flags set_objname set_user set_var setadd setremove shutdown sin size split sqrt stack str_to_buf strcmp strfmt strgraft stridx strings_to_buf strlen strsed strsub subbuf sublist substr suspend tan task_id task_info tasks this throw tick ticks_left toerr tofloat toint toliteral toobjnum tostr tosym traceback type unbind_function unbind_port union uppercase user valid variables Cold Help System ================ ___ _ _ _ _ _ ___ _ / __|___| |__| | | || |___| |_ __ / __|_ _ __| |_ ___ _ __ | (__/ _ \ / _` | | __ / -_) | '_ \ \__ \ || (_-< _/ -_) ' \ \___\___/_\__,_| |_||_\___|_| .__/ |___/\_, /__/\__\___|_|_|_| |_| |__/ Welcome to ColdCore. This is a hypertext help system. If you are on an interactive login you can type @help help for help on how to use this help system. You can also access this help system from a web browser . Help How to use this help system (READ FIRST!) General General Information Building Extending your Environment Programming Topics about programming Reference Core Reference Information Administration ColdCore Administration You may also want to see the list of Server Administrators for ColdCore, the Credit and Copyright Information Page, and perhaps a list of recent Updates and Changes to the documentation. Help|@help ========== This is a hypertext help system. Hypertext is a dynamic form of text, where words within a document may have special meaning, and point to other documents or portions of the document. These words are called hyperlinks. In a windowed browser hyperlinks may be displayed differently from the regular text by colorization. Over a terminal hyperlinks are specified by enclosing them in square brackets ([]), such as: Help You can use the command @help to navigate the ColdCore's help system, when on an interactive connection. To activate a hyperlink from a page you are reading, type @help and the name of the hyperlink. For instance, if the hyperlink was General, typing @help General would activate the link. For convenience, you can also use the command shortcut ? instead of @help, such as: ?General. Additional Recommended Reading: Hierarchy Help hierarchy (organization) Options Options and shortcuts to @help Searching Hints on searching Help Options ======= Available options for the command @help are: -h?istory Display your help page history -b?ack Go back one page in your history -b?ack name Go back to page name in your history -f?orward Go forward one page your history -f?orward name Go forward to page name in your history -u?p Go up to the parent node of the current node -fix Fix your history, useful if it becomes corrupt -l?inks List all of the links off the current help page The question mark ? in the above options specifies that characters following it are optional, (following the standard Command Matching Conventions). Option Shortcuts Options have shorthand equivalents, as follows: ? -history < -back -forward >name -forward name ^ -up ! -fix # -links Searching ========= You may encounter conflicts of link and node names while navigating help. This may occur if you do not specify the entire link name. Make sure when you activate a link you include enough of the link name to get a precise match (you do not always need to specify the entire link name). If you are still getting a conflict you can narrow the search parameters. First, to better understand what happens when you activate a link keep in mind the following search order: 1) Search in current page links 2) Search in current page group 3) Search in current page's index 4) Search in all other help indices If you are having a conflict you can prefix what you are searching for with either group=, link= or index= and it will search only in the respective area. For instance, if you were to type: ?index=narf It would bypass any links or group nodes to narf, and only search in the current index and subsequent indices. Furthermore, if you specify a word other than the above, it will attempt to match only in the relevant index. Example: ?core=narf Would search only in the core index, assuming it existed. Furthermore, when searching a specific index if the search word you specify is simply a hash-mark #, it will set the current index as the help node. General Information =================== General topics are covered in this area. If you need to know about describing and extending your Virtual Environment read about Building and Extending. Help on a specific object may be obtained by typing @help followed by the full object name. Programming help is also available. Conventions Conventions used in these documents Objects Learn about Objects Environment How Objects are used in your Environment Appearance Changing something's appearance Settings Configurable Settings Commands Learn about commands Interaction How to interact with others Interface How to personalize your interface Security How ColdCore security works Conventions =========== Throughout these documents certain conventions are used. If a document is explaining a command to be typed, it will begin with a greater-than sign (>), such as: > command If a document shows the syntax for a command a few conventions are used. First, words grouped within greater-than and less-than (<>) signs are variables and should be replaced with what you actually type. Second, words or variables within square brackets ([]) are optional. You may also see an ellipsis (...) inside square brackets. This simply means that it will accept multiple instances of the last word or variable. The following example shows the first variable argument is required, and more may be added: Syntax: @command [ ...] If a document is explaining how ColdC code may be evaluated when interpreted, the first line is the ColdC code and the second line begins with a text arrow pointing to the right (=>) and is followed by a ColdC data value. This represents what the example would evaluate to and return. For instance, calling the function ctime() could return the value "Sun Feb 25 17:06:38 1996". The function call and resulting value would be listed using this convention as: ctime() => "Sun Feb 25 17:06:38 1996" Objects ======= Objects are the primary element of Cold. An object is an abstract concept used to aid in program design. In simple terms an object is something which contains information (data) and instructions for manipulating this information (methods or functions). If you are unfamiliar with the concepts of Objects and Object Oriented Programming and you want to learn more, you may want to read about Object Oriented Programming in the ColdC Reference Manual (following this link is not for the faint of heart!) Even if you do not intend to program, it is important to know about objects. If you want to specify an object that is not in your Environment, you can do it by using the object database name (sometimes called an objref or dbref). Object database names are single words (no spaces), beginning with a dollar sign $. The following are all object names: $root, $sys, $user_joe Environment =========== Your environment is where the system tries to find things, when you name something. It does this by first checking everything in your contents, and everything in the location you are in. Context ------- The system will also check your recent context. The server records the last object you named, as well as all of the last objects you named (with a gender). You can list your recent context with the command @context, receiving a result similar to: Last thing: the Magazine Rack Last it: the Magazine Rack Last her: Squeak the lemming Last him: Miro When the system is attempting to find a named object, it first checks in your context. This allows you to name objects by their gender (if you remember it correctly). For instance: > get bottle You take the bottle. > drop it You drop the bottle. Multiple Matches ---------------- In the case where multiple objects would match a single name, you can use ordinal references, such as the 3rd bottle or the second key. Posessive Matching ------------------ If something is located in something else, in your environment (either being carried by somebody, or in a box, etc), you can refer to it posessively. For instance, if the user 'Joe' is holding a note, you can look at it with the command: > look at Joe's note Keywords -------- There are also two words known by the system. The first is me, which is always you. The second is here, which is always your location. Remembering ----------- If you are having a hard time remembering an items object name, or typing it's full name, you can remember it as a shorter name, with the command @remember. Appearance ========== Anything in the virtual environment will always have some common attributes, such as name, description and gender. If you manage the item, you can change these attributes and alter its appearance (this includes yourself). Everything that can be changed is described in more detail in the following sections: * Names * Description * Gender * Wearing Names ===== An object has three different types of names, its Object Name, VR Name and Name Templates. The Object Name is unique to each object. No other object will ever have the same Object Name as another object in the database. The Object Name is formatted as a dollar sign followed by any number of alphanumeric characters (a-z 0-9) or the underscore ('_'). Additional help on Object Names can be found in the Programming Help. An example of an object name is: $root The VR Name is the name the object has in its Environment. The VR Name is not unique to the object, and other objects can also have the same name. VR Names are also broken into three types: Proper, Unique and Normal. The type of name will decide what articles are put with it, when formatting (You do not normally include the article in a name). Proper names have no article. Unique names use the article the, and Normal names use the article a or an. Normally, when you set a name you can just use the article for the type of name you want. If you desire a different behaviour you can type +ignore in the name and it will override any automatic article settings. Name Templates -------------- Name Templates are additional helpful hints for the name matching system. Name Templates match differently than VR Names, so care should be given in knowing how each type of name matches before specifying a Name Template, as often times the Name Template is unnecessary. When the system tries to match a name to an object, it will match the beginning of any word in a name. For instance, if an object has the name "Mad Hatter" both "mad" and "hatter" would match. Furthermore, "hat" would also match, as it is the beginning of the second word. To supplement matching you can add Name Templates. Name Templates use the Template Matching system. Templates are not matched like names. The most common use of templates with names would be partial matching a word. For instance, the exit "Glass Door" may have the Template "e?ast". The Question Mark ('?') is used to specify that any character past that point is optional. For more information on Template Matching see the section Matching Conventions. Commands used with names are: @rename Description =========== If you are the manager of an item you can change it's description with the command @describe. Descriptions are entered as CML, but you do not need to know CML to describe something--just to use its features. Gender ====== If you are the manager of an item you can change it's gender. By default all genders are neuter. An item's gender is changed using the command @set with the gender setting, such as: @set me:gender=male If you do not specify a gender, all of the possibilities will be listed. Wearing ======= Any virtually alive item (something which is descended from the $body object) can wear things--generally clothing. Anything worn is a Wearable Frob, and must be from the object $wearable_frob or one of its descendants. A new article of clothing can be created by typing: @new $wearable_frob named Trenchcoat After it is created you will be holding it. At this point it is worn with the command wear and removed with the command shed. Example: wear trenchoat Security ======== There are several facets to how security is handled in coldcore, both in code relationships and in the VR. From a coding point of view, Object-Level security and Groups are used to handle most of the security functionality. Additional mechanisms exist in some places, such as the command stipulation for some command methods which requires that the method is only called from the command parser. Most of the security checks are managed through the .perms() method. VR Security primarily uses groups or logic locks in the form of a key (as would be used to lock a door or box). See Also: Object-Level and Groups Security. Object-Levels ============= Object-Level security is what managest most of the security in the database. It is a set of four levels, where each level encompasses all of the privileges of the previous level. All access for object-levels is on a per-object basis--allowing one or more objects a certain level of privilege to another object depending upon the level it is defined in. Any object or user can manage objects, be a writer on objects and a trustee on other objects. User classes (i.e. builder, programmer, admin) are not associated with any security level, they exist simply to group commands and more powerful interfaces. The levels are: System Level ------------ This level is the top level, encompassing administrators and system-level objects (such as $root and $sys). By default Administrators do not have this level enabled (it can be enabled each session with the command @mojo). Manager Level ------------- Every object has a manager. The manager has full permissions on the specific object. Quota usage is also based off the object Manager. Writer Level ------------ An object can have any number of writers. Writer Level permissions give full access to an object, with a few exceptions: * Writers cannot change any access permissions on an object (this includes adding other writers or changing the Manager). * Writers cannot change the object's parents. * Writers cannot destroy the object. Trustee Level ------------- An object trustee is simply another object that is trusted more than random objects but less than a writer. The amount of access given depends upon the subsystem. For instance, adding a user as a trustee to a location they are not a Manager or Writer of will give them the ability to extend other rooms from it. Groups ====== The group system is an all purpose classification system which can be used for a wide array of purposes. Groups can work in one of two ways: either they are simply a list of objects, and can be tested against for permissions sake, or they use a logical expression as their condition. Object Groups ------------- Object groups are hierarchical, so for an example consider the following group hierarchy: $group [*-mvc] $staff_group [*-mvc] $building_group [*fmvc] If a user is added to the staff group, and something tests against the building group, the staff members are included so it will evaluate true--even though they are not in the building group. Groups and Security ------------------- Groups can be specified as a writer on an object, and when testing against writer permissions for that object, it will also include anybody in the group, or evaluate against the condition of the group. This is highly useful for projects, where many objects are edited by a group of people. By using groups, people in the project only have to be added and removed from one place (the group) rather than each individual project. Programmer API -------------- To use a group in ColdC code, simply call the method .includes() on the group, with a single argument of the object which is in question. Available Groups ---------------- To see a list of all available groups, use the command: @descend $group +all +only=core All groups have a setting of 'group', which is a list of objects--except for $conditional_group and its descendants, where it is a logical expression. Commands ======== This section outlines some of the basics of commands, from understanding the logic behind why they are named what they are, to using them, to programming them. (Programmer's note: Commands in the Cold Dark are handled entirely in the database, the driver is oblivious to the intent or meaning of what it is you type). VR vs Non-VR The difference between the two Types Local, remote, shortcuts and aliases Matching Conventions used in matching commands Enhanced ColdCore's Enhanced Commands All Commands An index of all commands Programming Programming Commands VR vs Non-VR ============ To help classify commands, a distinction has been made. This distinction is based upon how the command is used, and what it effects. If the command is a Non-VR command (it does not follow the Virtual Environment guidelines) it begins with an at-sign ('@'). Otherwise, it does not. The best way to decide if a command is VR or Non-VR is to ask yourself the question: Is it something I could do in real-life? For instance, you do not simply declare, "I am wearing pink polka dotted clothes", and suddenly you are. However, in the Cold Dark you have the ability to directly change how you look from moment to moment. Therefore this command (@describe) is a Non-VR command, and begins with an at-sign. Types ===== Each command is associated with a specific method. When a command match is found, that method is executed with arguments depending upon what you typed. The Cold Dark recognizes three types of commands: Local Commands Local commands are any non-directed command, or any command which does not require a target in the command template. Matching for local commands uses ColdC template matching. The parser looks for local commands on the user, the user's ancestry, and the user's location (but not anything the user is carrying or in the user's location). Remote Commands Remote commands differ from Local Commands in that they require the target of the command, in the command string. For instance, "get button" would be a remote command, because it requires the target of button to function correctly. Matching for Remote Commands uses ColdC template matching Shortcuts Shortcuts are intented as wrap-arounds for commands, using ColdC pattern matching instead of template matching. Aliases Command aliases are personal shortcuts added by the user. They are very similar to command shortcuts, with the primary difference being their scope. A command alias is defined on a per-user basis. To add a command alias for more than one person, use a shortcut and add it to a command-ui object. See also: @add-command, @del-command, @add-shortcut, @del-shortcut, @commands, @add-command-alias, @del-command-alias, @command-aliases Matching Conventions ==================== Two types of general matching systems are used in Cold. The base matching system is pattern matching. The asterisk character ('*') in a pattern match is used to represent a wildcard. It can be placed anywhere in the pattern. It tells the interpreter that when matching the pattern with a string, anything can match the wildcard. This becomes useful for matching different strings. Some examples: Pattern: "match *" String: "match anything after this" Wildcard Match: "anything after this" Pattern: "match *t not this" String: "match only this but not this" Wildcard Match: "only this bu" Template matching expands upon the basic idea of pattern matching. Template matching is a little smarter about matching. It recognizes words as anything bounded by spaces or the beginning and end of the string. In a template the wildcard must be its own word--it must have spaces around it. Templates also add two more special characters; the question mark ('?') for optional matching and the pipe character ('|') for multiple matches. If a question mark is placed within a word, it means that the word must match up to the point of the question mark, but everything after that point is optional. For instance, all of the following would be valid against the specified template: Template: "th?is" String: "th" String: "thi" String: "this" The pipe character (|) is used to specify several different words that can match the place of one. For instance, the template "this|that|there" would match "this" OR "that" OR "there". It is easiest to logically think of the pipe character as OR. With these elements drawn together you get a simple yet dynamic matching system. Some full template examples: "l?ook at *" "give|put * to|in *" "@who *" "@lock * to|with *" Interaction =========== The following common interaction commands exist: say Speak and talk to others emote Do free-form actions to Direct messages to people in the room whisper Privately talk to somebody think Thinks something out loud spoof Similar to eval, but formatted differently @page Talk to somebody not in the room @paste Paste a block of text to people shortcuts Additional unnamed interaction shortcuts Interface ========= You can alter your interface in many ways. Client Using a Client Format Your output format Settings Configurable Settings Clients ======= When you connect to a Virtual Environment System you use a client. A client is simply a program you run from your machine. This program connects you with the server somewhere on the network. If you used telnet to get here, your client is telnet. This system is not designed for use with telnet. It has many customized aspects for which telnet simply does not support. Because of this it is suggested for your own benefit and enjoyment that you get a more robust client. These include tinyfugue, pueblo and any other mud-specific client you can digup. Some client links: TinyFugue tkMOO-lite Savitar Format ====== By default your output format is plaintext (text/plain). You can change this to other formats by setting your Content-Type. Currently supported alternate types are: * Plain Text (text/plain) * ANSI Text (text/ansi) * HTML Text (text/html) * Pueblo Browser Text (text/pueblo) * TkMoo Text (text/tkmoo) * Wrapped Text (text/wrapped) These formats can easily be extended to include others. To change your output format use the command: @set content-type=type Where type is one of the MIME encodings of the above types ie: text/plain. Use text/wrapped if your client doesn't wrap text automatically. Settings ======== There are many configurable settings available for you to use in customizing your environment. The command @set is used to make these changes. If you type @set with no arguments it will list all of your current settings. To change a setting you simply type @set followed by the setting name, an equals sign and the new value. If the value does not conform to the setting requirements you will be notified appropriately. For example, the following will turn on the capability to receive variable termination on messages (i.e. you can receive text prompts that are not terminated with newlines): @set non-terminated-tell=on There may also exist user-info settings. These define Real-Life aspects of you. They work slightly different. By default all user-info settings are private, and may not be seen by anybody else unless you include +public at the beginning of the setting, such as: @set real-name=+public Brandon Gilespie Read about the @set command for more information. Enhanced Command Templates ========================== The Cold Dark further expands upon the above matching systems, specifying certain types of arguments which can be accepted for a command, where the wildcard ('*') is located. These are specified within less-than and greater-than signs (< and >). These tags simply tell the parser what type of arguments to accept in that location on the command line. An example would be: push Where must be a valid user of the system, some more examples follow. "l?ook at " "get|take from " "@who " "@show " More information on Enhanced Command Templates can be found in the section Programming Commands. Building ======== Building in ColdCore is considered anything from describing yourself or an object you carry, to designing and creating full areas. Theme The VR Theme Dynamic Text The Cold text Markup Language Places How Places work Messages Dynamic Messages Commands Overview of Building Commands CML|Cold Markup Language ======================== CML is used to markup text for dynamic generation and formatting. CML text is compiled to an internal abstraction called Ctext which can be easily decompiled to plain text, HTML or any other format that may be desired. Ctext is also dynamically interpreted for each interface receiving the text. This gives extreme power in the final result, and is much faster than older MUD systems which use %x replacements in strings to achieve the same result. The CML syntax is made of tags embedded within the text. Tags can be formatted one of two ways depending upon if they are for dynamic text generation (Generator) or as a formatting or other directive (Formatter): Generator Format: [ :] Directive Format: { :} Specific tag names may vary depending upon the system. For more information on the specific tags for this system see help on Formatters and Generators. The exact behaviour of a tag may be controlled using options (sometimes called flags). Options can be in any order, and are specified in one of two ways: key=value sets the option named key to value key sets the option named key to true (if unspecified it will be false). NOTE: If you need it include more than one word as the value, you have to backslash-escape the spaces, you cannot include the value in quotes. Arguments (anything following the colon) Are optional, and depend upon the tag. How Arguments Are handled depends on whether the tag is a Generator or a Formatter. A Generator will treat it's Arguments as a space separated list. A formatter will treat it's Argument as a single string, stArting at the first non-space chAracter following the colon. Arguments may contain other tags. All tags with the exception of quote follow this syntax. quote can be used to include literal unparsed text in a document. It is similar to HTML's
 in
that it includes any literal formatting of white space. However, it does NOT
parse any formatters or generators within it's body. quote is formatted as:

        {quote }

Where  is anything, including curly braces. Note: there is no colon
following quote, and there are no options for quote. Further information on
CML and Ctext can be found at:

        Formatters             About CML Formatters
        Generators             About CML Generators
        Customizing            Customizing Ctext


Formatters
==========


The standard formatter tags are loosely based on HTML 3.0:

    action  One flag of cmd, which is run if the action is triggered (either
            by clicking on it, or using the action-trigger command '>'.
    b       Bold or strong.
    br      Line Break. Differs from {p} in that it can be stacked multiple
            times, for multiple breaks. Use of {p} is preferred.
    dd      Dictionary Definition, must be an argument to a Dictionary List
            (dl).
    detail  Generate a description detail. One required option of name which
            is unique to this detail throughout the entire description.
            Details may be nested.
    dfn     Definition. Used to indent a block of text. Arguments can be
            ind, which is an integer representing the spaces to indent (in
            plaintext this defaults to eight); and nobound, which effects
            the line breaks after the definition.
    dl      Dictionary list. Arguments can contain tags dt (dictionary
            title) and dd (dictionary definition).
    dt      Dictionary Title, must be an argument to a Dictionary List (dl)
    i       Italics or Emphasis.
    img     Place image in description. Image is only visible in HTML
            formats.
    lh      List Header, must be an argument for ol or ul.
    li      List Element, must be an argument for ol or ul.
    link    Creates a hypertext link to the help node (as an objname)
            specified with the option node.
    np      New Paragraph, similar to {p}, but in plaintext it breaks with
            two lines rather than one.
    ol      Ordered list. Within arguments use tags lh (list header) and li
            (list element).
    p       Paragraph Break, similar to {np}, but in plaintext it only
            breaks with one line.
    subj    Roughly equivalent to HTML's header  tags. Argument level
            specifies which level of subject to use (1-4) and defaults to a
            value of 4.
    table   Similar to tables in HTML. Options are ind (how many spaces to
            indent the table before formatting) and cols (column
            definition). cols must be defined. It is a comma separated list
            of column specs, which can either be in specific character units
            or percentages (the whole list must be either one or the other).
            Arguments consist of tr (table row) tags.
    td      Table Cell, options include colspan and rowspan which can be
            used to span columns and rows with the Table Cell.
    tr      Table Row, arguments consist of td tags for each table cell in
            the row.
    tt      Fixed-width font (typewriter), also used for literal text.
    ul      Unordered list. Within arguments use tags lh (list header) and
            li (list element).
    web     Creates a www hypertext link. This tag requires src and name
            options. The src should have a valid URL as the value and the
            name should have the name of the URL to be displayed.



Generators
==========



    columnize  Generates a list of columnized strings taken from the
               argument list. Option cols defines column information.
    def        Requires option var which is the name of a variable. Creates
               a new variable generator with that name, which has the value
               of the first argument. Will not evaluate arguments, instead
               stores the unparsed first argument. Similar to set
    english    Generates an english-formatted list from the arguments.
               Options can include sep (element separator, defaulting to
               ","), empty (what to print if the argument list is empty,
               defaulting to "nothing"), and (what to print as a separator
               before the last element, defaulting to "and")
    foreach    Requires option list. Will iterate over body for each element
               in list. Additional option var may be defined for iteration
               variable, defaults to iterator
    join       Joins arguments. Options can include separator which is
               either none, english or a string literal. If none the list is
               forwarded to the caller, rather than joined to a string
    name       Generates the names of the objects in the arguments list.
               Options can include separator which is either none, english
               or a string literal. If none is given a list is generated,
               otherwise a string is generated
    pro        Generates a pronoun. Required option is obj which defines the
               object for the pronoun generation. First argument is taken as
               the type of pronoun to use, as defined on $gender
    random     Returns a random number ranging from low to high which are
               given as options. Low can be omitted, one is used then
               instead.
    servname   The name of the server, as is set on @set $motd:server-name
    set        Requires option var which is the name of a variable. Creates
               a new variable generator with that name, which has the value
               of the first argument. Will evaluate arguments and store
               results. Similar to def
    switch     Requires option value which is evaluated. The resulting value
               is then used to select a result. Currently switch uses every
               other item in the argument list as a case/value pair (use the
               join generator for arguments with spaces). If there is a
               remaining odd element is is considered the default result
    time       Arguments are sent to the native method $time.format()
    vars       Returns the names of variables available. Option separator is
               the same as in name generator

Other tags

Each cml processor can also create extra generators. Also, caller to the cml
can create extra variables that are available for generators.


Customizing Ctext
=================



Interface

Ctext frobs are created by calling the .compile_cml() method off the cml
compiler object. On a ctext frob, you may call .uncompile() to return the
original text. A call to .eval_ctext() evaluates the generators, but will not
touch the formatters. This is used to speed up message dispatching. Calling
format() provides the final formatting of the ctext, evaluating everything,
including the formatters. You can add/modify variables on a ctext frob by
calling .set_var(variable, value), or .set_vars(dict), which does the same,
but assigning multiple variables at once.

Adding new evaluators

An evaluator is an object which contains methods for generation or formatting.
An evaluation object that is descended from a vanilla evaluator (like
$bs_eval) will try to store the evaluation results in a list, and is therefore
most suitable for adding new generators. On the other hand, evaluators
descended from a formatter object create a string, and try to evaluate and
concatenate lists until a string is obtained. Hence, they should be used for
formatting. To add a new generator or formatter, simply add a do_format or
gen_generator method on the object, where 'format' or 'generator' is the name
of the new tag that you wish to add. Make sure that the object is in the
evaluation path (by explicitly adding an 'evaluator, 'formatter or even an
'uncompiler field to the ctext frob.)


Places
======


Places are a form of location in the Virtual Environment. Locations are the
key factor of a Virtual Reality--everything must exist somewhere. It is
possible for a location to be a location itself, such as a box which can hold
something and also be located in a room or on a patio.

Places have more information than the rudimentary Location. They are generally
not located Locations, but instead represent a physical area in the Virtual
Environment, such as a room in a building or a sidewalk outside of a building.
They also define Pathways to other Places, Realms and environment conditions.

Realms are a form of meta-place. Multiple places can be grouped into a single
realm. Realms can be defined hierarchically, so you can have a building in a
realm which is a district of a city, which is in the city's realm, which is in
the country's realm, and so forth. The realm defines broad aspects of the
Virtual Environment, such as Permissions and Environmental Conditions like
Weather.

 See Also: Realms, Pathways, Environmental Conditions, Permissions


Realms
======


Realms are used to group places, and can exist in a hierarchy structure. For
instance, all rooms within a building would exist within one realm for that
building, and that realm would exist within a realm for that sector of the
city, which exists within a realm for the entire city. Realms are useful not
only for grouping, but also for events and searching. When an event occurs it
can be broadcast to the entire realm, rather than just to the local room.

New realms are created with the command @spawn, such as:

        @spawn $realm named the Clocktower

When creating a realm make sure to create it from the right parent, so as to
keep the hierarchy intact. For instance, the above realm might be better
spawned from a realm for the city.

Realms keep track of all the rooms they contain. When room is created or
destroyed, its realm is updated accordingly. You can change the room's realm
using its :realm setting.

Realms also keep track of realm properties. You can add your own realm
property as you would add any other setting, but make sure that +get method is
set to get_realm_setting (read @def-setting helpnode for information about
this). Realm properties have special inheritance scheme: rooms inherit them
from their realm, and realms inherit it from their parents. There are two
default realm properties: propagate, which controls propagation mask from the
parent realm, and weather-time, which sets the weather and time for the realm.

You can announce a message to all the players in a realm using realm_announce
method on the realm object. Note that it will be propagated using the
propagation masks.


Pathways|paths|exits|entrances
==============================


Paths connect places to each other. A path can have one or more ways, but
usually only have two ways (i.e. down the path and up the path). When you
build a place you have the option to specify the exit, or in other words, one
way for the path. You can use either the command @build, or the command @dig,
depending upon if you want an interactive or passive user interface.

Before you can link paths from a place you have to be able to build from it.
For more information in this regard, see the section Building Permissions. You
can create a place disconnected from the rest of the Virtual Environment with
the command:

        @dig My New Room

Which will create a new place with the name "My New Room", which is in the
realm of Creation (no realm).


Environment Conditions
======================


Environment Conditions in a room include how light or dark it is (which can
effect how visible things are) and if the place is outside this also includes
the weather and other atmospheric conditions.

The core place has a few common settings. To see the current settings, type
''@set YOURPLACE:'' or ''@set here:'' if you are currently in the location.
Use the command @set to change settings.

Visibility and Darkness
-----------------------
 All objects in the Virtual Environment have a visibility setting. This is a
number from +10 to -10, representing the object's relative visibility. Numbers
above zero are highly visible (such as a neon sign) and those below zero are
less visible (such as a black key sitting on a cluttered table).

Visibility is relative to the room's Darkness rating. Darkness is rated on the
same scale as Visibility. Numbers above zero increase the light in a room,
where numbers below zero decrease the light in a room (to -10 being
pitch-dark). The darkness rating can be changed by VR actions such as turning
on a light switch or bringing a torch into the room.

When determining if an object is visible in the room, its visibility rating
must be greater than or equal to the location's darkness rating.

Realm
-----
 The realm setting defines what realm the place is a part of. See the Realms
section for more information.

Public-Home
-----------
 If this is true, other builders can build from this room and any user can
make it be their home with ''@set me:home=here''.

Restrict-Entry
--------------
 Not currently setup.

Other
-----
 Additional settings are defined which need to be documented, such as mapping
and sound propagation.


Permissions|Builder Permissions|perms
=====================================


Building Permissions are those which allow you to build pathways from one
location to another. There are a few ways to allow people to build: adding
them as a writer or trustee to a room (this only allows them to build from the
current room), set the room as a public home (same as adding them as a
writer), or add them as a trustee to the realm or one of the realms in the
hierarchy of realms above the current room. The latter option is the most
preferrable for wide-spread building.

For example. Consider a room with the name of Broom Closet. This room is
defined as a member of the $realm_of_the_inn, which is also in the
$realm_of_the_city. If somebody were to be added as a trustee to the
$realm_of_the_city, they would be able to build a pathway from the Broom
Closet (because the city is an ancestral realm of the Broom Closet). They
would also be able to write to any other place defined within the realm of the
city. For more granularity, somebody could only be added to the
$realm_of_the_inn, which would restrict them to building within the Inn.

To add a trustee type: ''@chown REALM +trustee=WHO'', such as:

        @chown $realm_of_the_city +t=Levi


Commands|Building|Builder
=========================

Builder Commands Listing

The following commands are available to builders:

    @attach               Attaches an exit to a $place
    @build                A script-like interface to simplify the building
                          process.
    @child?ren            Lists the object's children and shows some brief
                          information about them.
    @def-msg              Used to define messages on an object
    @destroy              Destroys an object.
    @dig                  Makes a new place and can attach exits with a
                          single command.
    @msg?s                Used to view and set messages on objects.
    @move                 Moves an object to another location.
    @new                  Creates a new object.
    @par?ents             Lists parents of the object.
    @realm?s              Shows all known realms.
    @teleport or @go      Moves you a specified location.
    @undef-msg            Removes a message from an object.



Programming
===========


Be warned: anything from this section down is not complete.

        OOP                    Object Oriented Programming
        Programming a Method   Overview on creating a method
        ColdC                  ColdC Reference Manual
        Functions              Function Reference
        Commands               Overview of Programming Commands


Programming Commands
====================

Programmer Commands Listing

The following commands are available to programmers:

    @add-command          Adds a command to a specific method.
    @add-parent           Adds a parent to the target object.
    @add-shortcut         Adds a shortcut to a specified command.
    @add-variable         Adds a variable to the object.
    @ancestors            Shows the objects "tree" of parents.
    @chp?arents           Changes parents of object
    @chmod                Modifies the access flags on the object or method.
    @config-set?ting      Allows you to modify the options set when the
                          setting was created.
    @d?isplay             Displays general information about an object, and
                          optionally shows methods.
    @def-set?ting         Creates new settings on objects.
    @del-c?ommand         Removes a command from the object
    @del-m?ethod          Deletes a method from an object.
    @del-p?arent          Removes a parent from an object.
    @del-s?hortcut        Removes a defined shortcut to a command.
    @del-v?ariable        Removes a variable from the object.
    @descend?ants         Lists the objects the have that object as an
                          ancestor.
    @dump                 gives a complete textdump of an object
    @eval                 Used to test methods without programing them.
    @grep                 Used to search methods on an object for specific
                          text.
    @hl?ist               Shows a help node in CML text.
    @hw?rite              A one chance input to enter CML text for a help
                          node.
    @id                   Summary information similar to @display
    @join                 Teleports you to a user.
    @list                 Lists source code for the method.
    @move                 Moves methods or objects to another location
    @copy                 Copies methods to another location
    @new-help-node        Creates a new help node.
    @program              Allows user to input data and then save and
                          compile the text with a "." on a blank line.
    @rehash               Updates your command cache.
    @show                 Displays methods, variables, messages, and other
                          information about an object or method
    @spawn                Creates a new object
    @trace                Returns where and object receives an inherited
                          method.
    @undef-set?ting       Removes a setting from an object.
    @which                Tells you where the method behind the command is.



ColdC Reference Manual
======================


ColdC was initially created by Greg Hudson with ColdMUD, and was later
developed and evolved by many enterprising individuals. ColdC is a low-profile
object oriented database language. It is intended for network servers which
require run-time morphism (such as Virtual/Interactive Environment Servers).

This reference manual is written by Brandon Gillespie, with portions being
taken from the ColdMUD Reference manual written by Greg Hudson and additions
by various Cold contributors.

For the most part, this manual specifies the language definition for ColdC
1.1. Some sections may be in addition to this specification (such as Native
Methods).

  * Object Oriented Programming
  * Conventions used in this Document
  * ColdC Objects
    + Referencing Objects
    + Methods
    + Variables
    + Special Objects
  * Language Structure
    + Tokens
    + Data Types
    + Expressions
    + Statements
  * Implementation Reference
    + Methods
    + Frames and Tasks
    + Errors
    + Security
    + Networking
    + Regular Expressions
    + Files
  * Textdump Structure
  * Function Reference
  * Native Method Reference


Object Oriented Programming|OOP
===============================


Object Oriented Programming (OOP) is a style of programming which not only
groups procedures and data by functionality but which also applies a few
common rules to how this grouping occurs. In OOP designers group procedures
and data into modules. By doing this it helps to define the purpose of the
program, and also gives the added benefit of portability (porting a modular
segment of code to another program is much easier than porting an integrated
segment of code).

These modules (or objects) will generally follow a few guidelines:

  1) Abstraction and Encapsulation of Data
  2) Inheritance

Because data and procedures are grouped together, all procedures which handle
the specific data should be included within the module. Abstraction and
Encapsulation occurs when the module abstracts and controls access to the data
it manipulates. The internal representation of data used by a module is most
likely irrelevant to external sources (with the interface being the primary
concern).

An example of Abstraction and Encapsulation would be a table of people and
their pets. The 'People and Pets' module has several procedures:

  Add Person
    Add a Person to the table. This procedure is passed the person, and their
    pet.
  Remove Person
    Remove a Person from the table. This procedure is passed the person to be
    removed.
  Get Pet
    This procedure finds the pet for a given person. It is passed the person
    and returns the Pet associated with that person.

In the People and Pets module the table can be internalized in any form. The
form is irrelevant to external programs which may use it.

Inheritance is the ability of another module to take on the functionality an
existing module and further expand upon it. For instance, a 'People, Pets and
their Names' module could be created which takes on the functionality of
'People and Pets', but expands it to include the names of the pets.

Inheritance is extremely useful because code becomes reusable and extendable
without having to re-create each portion or module for different
functionality.

In inheritance a module taking on the functionality of another object is
called deriving from that object. For instance, 'People, Pets and their Names'
is derived from 'People and Pets'. The module 'People, Pets and their Names'
is a child of 'People and Pets', with 'People and Pets' being the parent of
'People, Pets and their Names'.


Objects
=======


An object in ColdC is both a data type and a database record. Objects are
structured with parents and children in a tree (geneology-style) hierarchy
known as the object hierarchy. An object has both ColdC procedures (methods)
and ColdC Data (variables) bound to it. The object variables are accessed and
modified by the methods defined on the object.

  * Referencing Objects
  * Methods
  * Variables
  * Special Objects


Referencing Objects
===================


Objects exist within the database, and are referenced with a unique number or
Object Number (objnum), which is assigned to the object upon its creation in
the database. Object numbers cannot be changed after an object is created.
When an object is destroyed, it's objnum is not re-used by the driver unless
the database is decompiled to text and recompiled.

An object can also have an Object Name assigned to it, which can be changed
throughout the life of the object. Object Name's are only unique to that
object, while the object has the name. Once the name is changed the old name
can be taken by another object. Object Names exist for practical
functionality, as it is easier to remember references which consist of
alphabetic and numeric characters, compared to references which are simply
numeric.

In ColdC an object number is designated with a hash mark ('#') followed by the
object's number. For instance #23 refers to object number 23. An object name
is designated as an identifier beginning with a dollar sign ($). For instance,
if the object #23 has the name object_23 assigned to it, it would be formatted
in ColdC as: $object_23.

A negative object number will appear if there is no object in the database
with the given object number--i.e. if it is an invalid object number. This is
true for all cases, except #-1, which is the generic Invalid Object Number.

Both the object number and object name are generically called database
references (dbrefs). When the driver formats a database reference the Object
Name will take precedence over an Object Number, because the name is generally
easier to remember and comprehend.

When the interpreter encounters an object name, it looks up the number
associated with that name in a table. If no object has been assigned to that
name, a ~namenf error is thrown; otherwise the object name is equivalent to
the object number when executing.


Methods
=======


A method is a series of ColdC statements which are grouped together as a
procedure, to perform a task. Method's are given a name and bound to a
specific object. Methods determine the object's behavior.
Methods have a specific structure to them. The number of arguments they will
accept is defined at the beginning of the method, followed by the definition
all of the variables used within the method. Subsequent lines compose the
actual method (See Defining Methods for more information on method structure).
When descendants of an object wish to change their behavior, they may define
their own methods, or override a method defined on an ancestor. A method is
overridden by simply naming it the same as an existing method on an ancestor
of the object. When a method is called, the interpreter looks for it first on
the object, then on the object's ancestors. If this occurs, it is possible for
a method overriding another to stop executing and pass back to the method on
its ancestor, and then resume executing when the overridden method completes
executing.
It is possible for a method to disallow descendants to override a method, see
Defining Methods.


Variables
=========


In ColdC there are two types of variables, local variables and object
variables. An object variable is defined on the object, and can be accessed by
any method defined on the same object. Object variables exist outside of the
scope of methods. Local variables are defined within a method, with their
scope being limited to that method. Object variables will always exist until
they are explicitly removed. Local variables only exist while the method
defining them is executing.
If a variable is used within the body of a method, but it is not defined as an
argument or a local variable (at the top of the method), it is assumed to be
an object variable. When the method is executed the interpreter looks on the
object for the variable. If the interpreter cannot find the variable on the
object, the error ~varnf is thrown.
It is important to remember that object variables may only be accessed by
methods defined by same object defining the variable. No other method may
reference that variable. For instance, assume two objects exist as $obj_a and
$obj_b, where $obj_b is a child of $obj_a. $obj_a defines the variable text
and the methods set_text and get_text:

        object $obj_a: $root;
        var $obj_a text;

        public method $obj_a.get_text {
            return text;
        };

        public method $obj_a.set_text {
            arg new_text;

            text = new_text;
        };

Calling $obj_a.set_text("text") will set $obj_a's instance of the object
variable text to "text". $obj_b does inherit the ability to use and write to
it's own instance of text (using methods defined on $obj_a), but it does not
inherit values assigned to the same object variable on it's ancestors. For
instance, calling $obj_b.get_text() will currently return 0 (the default unset
value), as it's instance of text has not yet been defined, even though
$obj_a's instance of text has been defined. This is called encapsulation.
Calling $obj_b.set_text("more") would set $obj_b's instance of text to "more".
If, following this, $obj_b were to override the method get_text defined on
$obj_a as:

        public method $obj_b.get_text {
            return "more text: " + text;
        };

Calling $obj_b.get_text() would cause the error ~varnf to be thrown, rather
than having "more text: more" returned. This is because the object variable
text is not defined by $obj_b (where the new get_text is defined), even though
it has it's own instance from $obj_a.
Another way to look at this is from a C++ perspective. All object variables in
ColdC are equivalent to being private object variables in C++.


Special Object Status
=====================


There are always two objects which exists within a ColdC database. The first
object is $root (#1). The root object has no parents, and is the base for all
other objects. This is a requirement in order to allow for a secure database
to be created.
The second object is $sys (#0). The system object is the only object the
driver directly calls methods on, with without previously setting up with the
driver (i.e. connections). These methods include $sys.startup(),
$sys.heartbeat() and $sys.signal().
The root and system objects are automatically created by the database compiler.


Language Structure
==================

This node isn't written yet


Tokens
======


Tokens are the base elements of ColdC. Tokens are simply abstract groupings of
text imbued with a specific meaning. There are many different types of tokens
ranging from single characters to long words. The following characters and
pairs of characters are tokens in ColdC:

        {   }   [   ]   #[  ]   `[  ]   (   )   (|  |)  (>  <)
        ,   ;   =   +=  -=  *=  /=  !   -   +   *   /   %   ..
        ==  !=  >   >=  <   <=  .   ||  &&  ?   |   @   --  ++

The above tokens are used as operators and punctuation in ColdC expressions
and statements.

Identifier

An identifier is another type of ColdC token which is a sequence of alphabetic
and numeric characters or underlines not beginning with a number. Identifiers
in ColdC are case-sensitive, so the identifiers Car and car are not
equivalent. The following are all valid identifiers:

        we_3_kings
        obj
        a

Without additional tokens, identifiers usually represent variables. However,
certain identifiers have special meanings to the parser. These reserved words
are used in writing certain kinds of statements and expressions. They are:

        var, if, else, while, for, switch, case, default,
        break, continue, return, catch, any, with handler,
        pass, to, in


Data Types
==========


All ColdC data has a type and a logical truth value it will return when
evaluated as an expression. The following is a list of ColdC data types along
with their names and literal representation in ColdC:

        Type             Name             Representation
        Integer          'integer         42
        Float            'float           1.0
        String           'string          "This String"
        Buffer           'buffer          `[]
        Symbol           'symbol          'identifier
        List             'list            [1, 2, 3, 4]
        Object Number    'objnum          #1234
        Object Name      'objname         $identifier
        Dictionary       'dictionary      #[["key", $value]]
        Error Code       'error           ~identifier
        Frob             'frob            


The type of data being manipulated can be determined using the type() function.


Integer|Number
==============


An integer is a rational number (in mathematical terms). Integers can reliably
be from 2147483647 to -2147483647 (unless the driver has been compiled with
BIG_NUMBERS, in which case they are larger). An integer is logically true if
it is not zero (negative numbers are logically true). Integers are denoted in
ColdC with a series of digits, optionally preceded with a plus (+) or minus
(-) sign.

See also: Numeric Functions


Float
=====


A float is a real number (in mathematical terms). A float is logically true if
it is not zero. Floats are denoted in ColdC with two numbers separated by a
period and optionally preceded with a plus (+) or minus (-) sign. Floats may
be printed in scientific notation--both forms are acceptable. The interpreter
will print floats in whichever format will give the greatest precision with
the least amount of space.

See also: Numeric Functions


String
======


A string is a sequence of printable characters. A string is logically true if
it is not empty. A string is denoted in ColdC by enclosing the printable
characters within double quote characters ("). To include a double quote
inside a string precede it with a backslash. Any other occurrence of a
backslash in a string has no special meaning, unless it follows another
backslash (at which point it is assumed to be escaping itself, and reduces as
appropriate). The following are some examples of strings:

        "foo"
        "\"foo\" is a metasyntactic variable."
        "The backslash (`\') is a much-abused character in many languages."

See Also: String Functions


Symbol
======


A symbol is similar to a string, but it has been abstracted into a ColdC
identifier. This makes comparisons between symbols much faster than with
strings, as when comparing a string each character in the string must be
compared, but when comparing a symbol only one comparison occurs.
Symbols are denoted in ColdC by preceding the identifier with an apostrophe
('). Symbols are not terminated with an apostrophe. Symbols are always
logically true.


List
====


A list is an ordered grouping of data. The data contained within a list can be
of any type, and does not have to be the same type throughout the list. Lists
are useful for grouping different data elements together. A list is logically
true if it contains one or more elements, and is logically false if it is
empty. A list is constructed by enclosing a comma-separated series of data
elements within square brackets. For example both of the following are both
valid lists:

        [1, 2, 3]
        [1, ["foo", 'bar], $sys]

See Also: List Functions


Object Number|objnum|Object Name|objname|dbref
==============================================


Object numbers and object names are explained in detail in the section
Referencing Objects. Object numbers and names are always logically true.


Dictionary
==========


A dictionary is a collection of data associations, each of which has a key and
a value. Dictionaries are similar to lists, however, lookup in a dictionary is
with the key (returning the value), rather than with the location in the list.
Dictionaries generally take up more storage space in memory than lists, and
are slightly slower to add to and remove from than lists, but searching for
items in dictionaries is much faster than searching for items in a list.

Dictionaries are denoted by a list of two-element lists, preceded with a hash
mark (#). Each of the two-element lists is an association, where the first
element is the key and the second element is the value. Dictionaries are
logically true unless empty. The following are all valid dictionaries:

        #[["foo", 3], ['bar, 'baz]]
        #[["something", 'blue], ["one", 1], ["two", 2]]

When evaluating the key for the value in the dictionary is indexed, rather
than the position as in a list, such as:

        dict=#[["foo", 3], ['bar, 'baz]];
        dict['bar];
        => 'baz

See Also: Dictionary Functions


Error Codes|errors
==================


An error code identifies an error. Both the ColdC interpreter and ColdC
methods use error codes to identify types of errors when they occur. See
section Errors for information about how errors in ColdC are handled. Errors
are denoted in ColdC by preceding an identifier with a tilde (~). Error codes
are always logically false.


Frob
====


Frobs are an abstract data type used for dynamically handling data when using
it as the receiver of a method-call expression. Normally, when data is used as
the receiver for a method call, the interpreter will actually lookup and use
an object with an object name that is the same as the type of data being used
(such as an object named $string if the data is a 'string). In the case of a
frob, the receiver is specified within the frob, as the Frob Class. Frobs also
give the ability to specify special method to handle the call with.

 Frobs are useful for grouping, abstracting and encapsulating a set of similar
data by associating it with a handler object. Frobs are constructed by
enclosing the class and representation within a less-than sign (<) and a
greater-than sign (>), separated by a comma. All of the following are valid
frobs:
        <$thing_frob, #[['desc, "worthless"], ['name, "coin"]]>
        <$coins, [923]>
        <#73, [1, 2]>

The usefulness of a frob becomes apparent when used as the recipient in a
method-call expression. In this instance the frob class becomes the recipient
and the frob value becomes the first argument sent to the method. For
instance, the following two method calls are equivalent:

        (<$list, [1, 2, 3]>).reverse('do_this)
        $list.reverse([1, 2, 3], 'do_this)

Furthermore, if a handler is used, the handler is called as the method, and
the expected method is sent as a symbol argument. The following two method
calls are equivalent:

        (<$obj, #[], 'handle_it>).tell("foof")
        $obj.handle_it(#[], 'tell, "foof")

Because of the difference in how a frob method is called, it is possible to
define a method as a frob-only method. If a method is defined as a frob-only
method it is only called when called by a frob. Calling it in the standard
syntax would not retrieve the frob-only method, but would instead look for the
same method further up the ancestor hierarchy. For more information see
Defining Methods.

Frobs are always logically true.

See Also: frob_class(), frob_value() and frob_handler()


Buffer
======


A buffer is an array of integers which are interpreted to unsigned eight-bit
values. Keep this in mind, as the range of an integer in a buffer is only 0
through 255, any other number will be cast to an eight bit unsigned value.

Buffers are intended for handling character values outside of the normal
printable range used by ColdC strings. A buffer is constructed by prefixing a
list of integers with an accent mark (`), where each integer is the decimal
value of the respective character. Buffers are logically true if not empty.
The following buffer and string are equivalent:

        `[98, 117, 102, 102, 101, 114]
        "buffer"


Expressions
===========


Expressions are ColdC tokens and operators which--when evaluated--perform
their defined behavior and take on a value after completion (also known as the
return value). If they evaluated without error, the return value is a standard
ColdC data type. If an error occurred, the return value is an error data type,
and execution of the method is halted.

There are many different types of expressions:

  * Data
  * Operators
  * Variable
  * Function Call
  * Method Call
  * Error Handling
  * Looping


Data
====


All ColdC data has a type and a logical truth value it will take on when
evaluated as an expression. Each data type is explained in the section Data
Types.


Operators
=========


Operators are tokens used to perform simple operations on expression values,
such as adding two values together. ColdC provides a variety of operators to
perform arithmetic and logical operations on data. Most of these operators
fall into two categories: unary operators and binary operators.

Unary operators act on a single expression value. In ColdC, all unary
operators are single characters which precede expressions. For example, !str
is the logical negation of the variable str.

Binary operators act on two expression values. For example, a + b is the sum
of the variables a and b.

Some operators are neither unary nor binary. More information on these
operators can be found in each sub section:

  * Operator Precedence
  * Index Operators
  * Arithmetic Operators
  * Assignment Operators
  * Logical Operators
  * Conditional Operators
  * List Splice Operator


Operator Precedence
===================


When the interpreter executes an expression it evaluates each operator it in a
certain order. It is easy to write an expression which has an unclear order of
evaluation. For instance, the expression A - B + C could be parsed as A - B
followed by the result plus C or as A minus B + C. To resolve these
ambiguities, each operator has two properties when interpreted: precedence and
association.

Precedence determines whether an operator is more important than another
operator; for instance, A + B * C is equivalent to A + (B * C) because
multiplication has higher precedence (is more important) than addition.

Association determines whether operators at the same precedence level
associate left to right or right to left; A - B - C is equivalent to (A - B) -
C because subtraction associates left to right.

Here is a list of operators grouped by precedence, in order from highest to
lowest:

        []
        .
        -- ++
        ! - (unary)
        * / %
        + - (binary)
        == != > >= < <=
        in
        &&
        ||
        ?:
        = += -= /= *= ?=

All operators associate from left to right except the Logical Operators (&&,
||, and ?|), which associate from right to left. Parentheses may be used to
group expressions and clarify evaluation.


Index Operators
===============


Indexing involves lookup in either a string, list, buffer and in some
instances a dictionary. Depending upon the specific operator used indexing can
return either the position of a desired element, or it can return the element
at the specified position. There are two indexing operators, each performing
one of these roles:

        []
        in

The binary operator index-lookup (in) is used to find the position of an
element. It may only be used with strings, lists and buffers. When used this
operator will return an integer representing the position within the right
side data where the left side specified element exists. If the specified
element does not exist, a zero (0) is returned. Indexing is case-insensitive,
when using strings. Example:

        "C" in "abcdefg"
        => 3

The expression find and the functions stridx(), listidx() and bufidx() may
also be used in finding the positional index of an element.

The index-retrieve operator ([]) is used to retrieve an element found within
the data. It may be used with strings, lists, buffers and dictionaries. It is
a binary operator, although its syntax is not as standard as others:

        data expression[data expression]

The right data expression is used as the key to lookup within the left data
expression. In all but the dictionary the right data expression must result in
an integer, which represents the position in the right data expression to
retrieve from. With a dictionary the right data expression may be any data
type (see Dictionaries).


Arithmetic Operators
====================


ColdC provides several operators for performing arithmetic operations. These
operators apply primarily to integers and floats, but some of them may be used
with non-integer data for easier formatting and manipulation. If any
arithmetic operator is used with inappropriate data the error ~type is thrown.

If both sides of a binary arithmetic expression are integers, the result will
always be an integer, even if the result would have floating precision. If one
side of the expression is a float, the result will always be a float. For
instance, 3 / 2 (both integers) would result in 1, whereas 3 / 2.0 would
result in 1.500000.

The arithmetic operators are:

        +      ignored       (unary)
        -      negate        (unary)
        +      addition      (binary)
        -      subtraction   (binary)
        *      multiply      (binary)
        /      divide        (binary)
        %      modulo        (binary)
        ++     increment     (unary)
        --     decrement     (unary)


The unary - operator negates the numeric value (reverses its positive/negative
value). The unary + operator has no effect on its argument, and is provided
simply for completeness. The binary operators + and - add and subtract their
arguments.

The binary multiplication operator * multiplies the left argument by the right
argument. The binary division operator / divides the left argument by the
right argument, returning the whole result. The binary modulus operator %
divides the left argument by the right argument and returns the remainder
result.

The unary Increment and Decrement operators serve a dual function, and are
explained further in their own section.

  * Increment / Decrement Operators
  * Non-Numeric Use


Increment|Decrement
===================


The unary Increment (++) and Decrement (--) operators perform a dual purpose.
They either add or subtract one from a numeric variable (respectively),
assigning the result back to the variable. They must be used directly on a
variable. All of the following are equivalent:

        i = i + 1
        i++
        i = i - 1
        i--

The result returned from an increment or decrement expression will will depend
upon what side of the variable it is placed. If the operator is on the left
side of the variable, the value of the variable is modified before it is
returned. If the operator is on the right side of the variable, the value of
the variable is returned first and then the variable is incremented or
decremented.

In the examples below assume i is 10. Assuming this, in the first example x is
assigned the value 10 where in the second example it is assigned the value 11.

        x = i++
        x=++i


Non-Numeric Use
===============


The binary + operator can also be applied to strings, lists and buffers. Using
it in this way will cause it to concatenate the two values. For instance, the
expression ("foo" + "bar") would evaluate to "foobar", and the expression
(["foo", "bar"] + ["baz"]) would result in the list ["foo", "bar", "baz"].

As long as both sides of the operator are the same data type (which is
restricted to strings, lists and buffers) no error will be raised. If one side
of the operator is a string (either side), and the other side is not a string,
it will be converted to its literal representation and joined with the string.
For example, the expression ("list: " + [1, 2, 3]) would evaluate to "list:
[1, 2, 3]".

The binary * may be applied with a string on the left side and an integer on
the right side. In this situation the left side string is duplicated by the
number of times specified by the right side integer. Example: ("-" * 5) would
result in "-----".

Dual Role Assignment operators also behave in the same way, as is applicable.
For instance, the dual role arithmetic operator += would behave the same as
the standard arithmetic operator + when evaluating the addition expression.


Assignments
===========


Data is stored in a variable through an assignment. Assignments can either be
Simple, Scattered, Dual Role or Default. Simple Assignments store the result
of an expression to a single variable. A Scatter Assignment stores each
element in the result of a list expression across multiple variables. Dual
Role Assignments join another operator and the simple assignment operator into
one for the purpose of simplicity and optimizing, such as += which is both the
addition operator and the assignment operator. Default assignments only assign
the value if the current value of the variable is false. More information can
be found in each section:

  * Simple Assignments
  * Scatter Assignments
  * Dual Role Assignments
  * Default Assignments


Simple
======


Both simple and scatter assignments use the same equals sign = operator. A
simple assignment stores the result of the expression on the right into the
variable on the left, such as:

        variable = expression

The function set_var() may also be used for the same purpose, but only on an
object variable (see Variables).


Scatter
=======


In a scatter assignment multiple variables are specified within a square
brackets on the left, and each element from the list expression on the right
is assigned to the respective variable on the left, with any remaining
elements in the list being discarded. For example:

        [var1, var2, var3] = ["this", ["for"], 1, 'that]

In this example var1 is assigned the string "this", var2 is assigned the list
["for"], var3 is assigned the integer 1 and the remaining symbol 'that is
discarded.

The remaining elements may all be grouped in a new list which is stored in the
last variable by using the List Splice operator on the last variable in the
scatter list, such as:

        [var1, var2, @var3] = ["this", ["for"], 1, 'that]

In this example var3 would have the value [1, 'that]. The List Splice operator
may only be used this way on the last variable in the scatter list.

Scatter Assignments may also be nested, assuming the list expression is a
nested list in the same order as the scatter list. For example:

        [var1, [var2, @var3], var4] = ["this", ["for", 1, 2, 3], 'that]

In this example var1 is assigned "this", var2 is assigned "for", var3 is
assigned the new list [1, 2, 3] and var4 is assigned the remaining symbol
'that.


Dual
====


Dual Role Assignment operators join an arithmetic operator and the simple
assignment operator into one for the purpose of simplicity and optimization.
The Dual Role Assignment operators are:

        +=
        -=
        *=
        /=

These operators must have a variable as the left argument. When used, the
arithmetic expression is evaluated as normal, and the result is assigned back
into the variable on the left. The following examples are equivalent:

        x = x + 5
        x += 5

When evaluating the arithmetic expression the operator behaves the same as the
equivalent Arithmetic Operator, including any Non-Arithmetic Behaviour.


Default
=======


The default assignment is used to assign a value to a variable if the current
value of the variable is logically false. The default assignment operator is:

        ?=

And the syntax is:

        variable ?= value expression

When executed the driver tests the logical value of variable. If it is false,
it assigns the result of value expression, otherwise it is untouched. Example:

        len ?= 79;

Will assign 79 to len if it is false (for instance, if it is zero). This
operator is equivalent to a combination of the Simple Assignment and the
if-else Conditional Expression:

        len = len ? len : 79;


Logical Operators
=================


ColdC provides a number of relational and logical operators. These operators
are primarily useful for expressing conditions, since they return either true
or false, represented by the integers 1 and 0.

The binary operators == and != test the left and right arguments for equality
and inequality, respectively. The arguments are equal if each side has the
same data type and contains the same value. Equality of strings is not
case-sensitive, but equality of symbols is, so ("foo" == "fOo") is true, but
('car == 'CAr) is false. Lists are equal if all of the elements in each list
are equal and are in the same order.

The <, <=, >=, and > operators test whether their left-hand arguments are less
than, less than or equal to, greater than or equal to, or greater than their
right-hand arguments, respectively. Arguments to these operators must both be
of the same type, and must be either numeric or a string. String comparison is
not case-sensitive, so ("fooa" < "fooB") is true, even though the ASCII value
of `a' is greater than that of `B' (the function strcmp() may be used for a
true lexical case-sensitive comparison of strings).

The unary ! operator tests whether its argument is false, thus acting as a
logical NOT operation.


Conditional
===========


The || and && operators act as logical OR and AND operators, respectively. The
expression (this || that) is equivalent to this OR that, where the return
value of the expression is this if this is logically true. If this is not
logically true then the return value of the expression is that.

The expression (this && that) is equivalent to this AND that, where the return
value of the expression is logically true when both this and that are also
logically true. If either this or that are not logically true then the return
value is false.

ColdC's conditional operators are short-circuit operators, meaning that the
right-hand argument is never evaluated if the left-hand argument is sufficient
to determine the value of the expression. This is important if the right-hand
argument has side-effects or could cause an error. For instance, because of
this it is possible to have the following expression:

        (| dict[key] |) || throw(~nope, "Nope, doesn't exist");

With this expression if key is in the dictionary dict then the return value is
the related value to key. If it is not, the error ~keynf is thrown by the
index operator ([]). However, the expression is a critical expression. Because
of this the left value becomes ~keynf, which is logically false, and the
interpreter moves onto the throw function.

The ? : operator is a trinary operator, with the following syntax:

        condition ? true-expr : false-expr

The result of this expression is the result of true-expr if condition is true,
or the result of false-expr if condition is false. This is similar to the
Conditional if-else Statement.


List Splice Operator
====================


Splicing is used to either expand a list or in scatter assignments and method
calls to group remaining arguments into a list. The splice operator is an at
sign (@).

Splice can be used to expand a list in three situations: within a method call,
within a function call or within another list When expanding, elements within
the list to be spliced are placed starting at the appropriate position within
the spliced list. For example:

        [1, @['a, 'b, 'c], 2, 3]
        [1, 'a, 'b, 'c, 2, 3]

Note: the function listgraft() behaves in the same manner. When using splice
to expand a list as arguments to a function it looks similar:

        others = [1, "this"];
        $string.do_something(this, that, @others);

When the method do_something is called it would be called with four arguments,
and the last two arguments would have a value of 1 and "this".

The splicing operator is always evaluated last, and is not listed in the
operator precedence list (see section Precedence). Because of its restricted
nature the splicing operator never causes ambiguity.


Variable Expression
===================


ColdC provides two kinds of variables, local variables and object variables.
Local variables are used within methods to temporarily store data. In order
for a local variable to be used it must first be declared at the top of the
method in a var declaration (see section Defining Methods). Object variables
are defined on an object, and can be used to store data for an indefinite
period of time (at least until the object is destroyed). More information on
Variables can be found in the section Objects and Variables.

When a variable is evaluated as an expression, its value is that of its
contents (the data stored in the variable name). Initially variables will
contain the integer data value of zero (0). To set the contents of a variable,
use the assignment expression.

The value of a local variable is specific to the currently executing method
frame. When the method is invoked at another time all of the local variables
begin again with the value of zero (0).

If the variable is a local variable, it must be declared as a local variable
at the top of the method (see Defining Methods). If it is not declared at the
top of the method, the interpreter will assume it is an object variable. In
the case that both a local variable and an object variable have the same name,
the local variable will take precedence.

It is possible to indirectly access and set data on an object variable using
the functions get_var() and set_var(). Normally, an object variable is
accessed and set just as if it were a local variable. These functions are
useful for indirectly setting or accessing the variable, or for when there is
a possible conflict with a local variable. If the variable is not declared in
the method, the interpreter will always assume it is an object variable.


Function Call Expression
========================


Functions are driver-defined procedures which perform a certain action which
ColdC is incapable of (such as opening a network connection), or which the
driver can handle more efficiently. A function is called using the function
call expression, which has the following syntax:

        function(arg1, arg2, ...)

In this example function is an identifier naming the function, and arg1, arg2
are expressions. There are no limits to the amount of arguments a function can
accept. However, even if there are no arguments the parentheses must be
present. Arguments are evaluated from left to right.

As an example, the pad() function pads a string argument with spaces to a
certain length. When evaluated with the string "foo" and a length of six
characters:

        pad("foo", 6)
        => "foo "

There are driver functions available for a variety of tasks. A comprehensive
explanation of the available functions is available in the section Function
Reference.


Method Call Expression
======================


Methods defined on an object can be executed with the method-call expression,
which has the following syntax:

        receiver.method(arg1, arg2, ...)

In this example receiver is the object where method may be called, and arg1,
arg2 are expressions. There are is no limit to the number of arguments sent,
although even if there are no arguments the parenthesis must exist. Arguments
are evaluated from left to right.

The receiver may be omitted, in which case it is assumed to be the current
object. If receiver does not exist in the database, the error ~objnf is
thrown.

Any ColdC Data (with the exception of Frobs) may be used in place of the
object as the receiver. If a method is called in this manner, the interpreter
will lookup an object with an object name that is the same as the type of data
being used (such as an object named $string if the data is a 'string). If an
object is found in the database with this name, the method is called on that
object and the data is sent as the first argument (subsequent arguments will
still be sent). If not, the error ~objnf is thrown.

If a Frob is used in place of receiver, the class object for the frob becomes
the receiver and the representation of the frob is sent as the first argument.
Because of this difference it is possible to have a special method that only a
frob may call. For more information on frobbed methods see Defining Methods.

method must be either the name of the method, or an expression which results
in a symbol for the name of the method. If method cannot be found on receiver
or any of receiver's ancestors, then the error ~methodnf is thrown.

The result from a method-call expression is the value returned by the method.
If the method does not return a value, the result is receiver. If receiver is
a frob, then the method is called on the frob's class object, with the frob's
representation inserted as the first argument (other arguments are placed
after the representation).

Here are some examples of method-call expressions:

        .tell("I don't see that here.");
        => $brandon

        $sys.admins();
        => [$lynx, $dancer, $jenner]

        ([1, 2, 3]).reverse()
        => [3, 2, 1]

        $parser.(tosym(what + "_mesg"))(messages)
        => $parser

        (<$thing_frob, #[['myname, "coins"], ['amount, 300]]>).name()
        => "300 coins"

In order to prevent incidents of infinite recursion, there is a maximum
calling depth for methods. If calling a method would exceed the maximum
calling depth, the error ~maxdepth is thrown.

If a method is overridden it is still possible for it to be called. For more
information see the section Calling Overridden Methods.


Overridden Methods|override
===========================


If a method overrides another method defined on an ancestor, the overriding
method can call the overridden method using the function pass(). Arguments to
pass() are sent to the overridden method as if the method were called
normally. The return value of pass() is the normal return value of the
overridden method.

For instance, passing to an overridden method with:

        pass("this arg", 2);

Would be roughly equivalent to calling the same method, if it was not
overridden, with:

        obj.method("this arg", 2);

When executed in this manner, the overridden method sees the same object,
sender, and caller as the current method.

In the situation where a descendant overrides a method defined on two of its
ancestors, you can determine which method is passed to using the function
find_next_method(). The following method (assuming a ColdCore database) can
also be of use:

        arg obj, method;
        var trace, current;

        current = (> obj.find_method(method) <);
        trace = [];
        while (current) {
            trace += [current];
            current = (| obj.find_next_method(method, current) |);
        }
        return trace;


Error Handling Expression
=========================


Two mechanisms exist for handling errors in expressions. These are the
critical expression and the propagation expression. The critical expression is
used to ignore any errors thrown from inside the expression. It has the
following syntax:

        (| expression |)

If an error occurs in expression the interpreter will stop evaluating
expression and continue to execute the current method as if it had succeeded
evaluating expression. The value of expression will be the error code for the
error which occurred.

The propagation expression causes any error thrown by a method call within the
expression to be thrown as if the current method threw it. It has the
following syntax:

        (> expression <)


If an error occurs in expression it will propagate to the calling method as if
the error had originated in the calling method and not in the current method.
Otherwise, the calling method will receive the error as ~methoderr.

Critical expressions override the behavior of catch statements so that errors
which occur within critical expressions do not trigger catch error handlers.
Propagation expressions do not override critical expressions or catch
statements, however. They do not prevent errors from being caught; they only
determine how errors propagate if they are not caught.

For more information on handling errors, see section Errors.


Looping Expressions
===================


Cold offers several expressions that enable looping through lists,
dictionaries or integer ranges. Their main advantages over looping statements
are brevity and preallocating of lists/dictionaries they return (for greater
speed). The loop expressions are:

  * map
  * hash
  * find
  * filter


map
===


The map expression loops a variable through a list, dictionary or integer
range, evaluating an expression for each iteration. Results from each
iteration are collected into a list and returned when the loop is completed.
The syntax for map can be either of the following:

        map var in (what expr) to (iteration expr)
        map var in [lower expr .. upper expr] to (iteration expr)

Examples:

        map x in ([1, 2, 3]) to (tostr(x))
        => ["1", "2", "3"]

        map x in [5 .. 15] to (x)
        => [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]


hash
====


The hash expression loops a variable through a list, dictionary or integer
range, evaluating an expression for each iteration. Results from each
iteration must be contained within a two element list. The list is inserted as
the key/value pair into a dictionary. After the loop completes the final
dictionary is returned. The syntax for hash can be either of the following:

        hash x in ([1, 2, 3]) to ([toobjnum(x).name(), x])
        => #[["$root", 1], ["Brandon", 2], ["Dancer", 3]]

        hash x in [1 .. 3] to (.random_pair())
        => #[["Dancer", 1], ["Miro", 7], ["$root", 1]]

In the above example the method .random_pair() returns a random two element
key/value pair.


find
====


The find expression is used to find the position of something in a list or
dictionary. It does this by looping through the given list or dictionary and
testing the iteration expression. When the iteration expression evaluates true
it stops and returns the given position. The syntax of find is:

        find var in (what expr) where (iteration expr)
        find var in [lower expr .. upper expr] where (iteration expr)

If iteration expression never evaluated true, find returns a zero. The
following examples assume the variable list is set as:

        ["First line","second line","3rd line"]

        list[find x in (list) where (x.match_regexp("co"))]
        => "second line"

        find x in [1 .. listlen(list)] where (list[x].match_regexp("co"))
        => 2


filter
======


The filter expression is used to selectively pull elements from a list or
dictionary. It loops through the given list or dictionary and adds each
element to a new list if the iteration expression tests true. The final list
is returned after filter finishes looping. The syntax of filter is:

        filter var in (what expr) where (iteration expr)
        filter var in [lower expr .. upper expr] where (iteration expr)

The following examples assume the variable list is set as:

        ["First line", "second line", "3rd line"]

        filter x in (list) where (x.match_regexp("co"))
        => ["second line"]

        filter x in [1 .. list.length()] where (list[x].match_regexp("co"));
        => [2]


Statements
==========


A statement is a complete instruction to the interpreter. Statements are
composed of expressions or constructs. Statements can be simple (such as
comments), or they can be complex (such as loops and conditionals). Most
statement types in ColdC have simple structures. Because statements can
include other statements (using a compound statement) they can be used to
build complex directives for the interpreter. Statements are grouped into four
categories:

  * Simple
  * Conditional
  * Error Handling
  * Looping


Simple
======


Simple statements evaluate one instruction, once. There are four different
simple statements in ColdC:

  * Comment
  * Expression
  * Compound
  * Return


Comment
=======


The comment statement does nothing. A comment statement is used for including
notes within ColdC code. It is formatted as two forward slashes followed by
any characters up to the end of the line, such as:

        // This is a comment.

The interpreter ignores comment statements completely; they are for the
benefit of human readers. Note that comments in ColdC are actual statements,
unlike comments in other languages, which are usually discarded by the
preprocessor.


Expression
==========


The expression statement evaluates a complete expression, discarding the
result. The syntax of an expression statement is an expression followed by a
semi colon, such as:

        expression;

Examples:

        "this";
        y = x + 50;


Compound
========


The compound statement is used to group one or more statements as a single
statement. The compound statement is formatted as any number of statements
contained within left and right curly braces, such as:

        {
                statement1
                statement2
                ..
                ..
                ..
        }

The interpreter evaluates each statement in the compound block in turn.


Return
======


The return statement stops executing the current method and (optionally)
returns a specific value. The return statement can have either of the
following two forms:

        return expression;
        return;

If expression exists the interpreter evaluates and returns its result from the
method. Otherwise, if no expression is given the current object is returned.


Conditional
===========


Conditional statements execute other statements if a test condition evaluates
true. There are three types of conditional statements in ColdC:

  * if
  * if-else
  * switch

Because the if statement and the if-else statement are similar, they can
sometimes be ambiguous. The following code will produce unexpected results:

        if (a)
            if (b) c;
        else
            d;

The indentation suggests that the else clause should apply to the first if
clause, but in fact it applies to the more recent one. Ambiguities like this
can be avoided by using braces to create compound statements out of
conditional and looping statements, even if there is only one statement. A
less ambiguous way to write the above is:

        if (a) {
            if (b)
                c;
        } else {
            d;
        }


if
==


The if statement is used to selectively execute code. It will only execute the
code if the condition expression evaluates true. It has the following syntax:

        if (condition expression)
            statement

When the interpreter encounters the if statement it will first evaluate the
condition expression. If the value of the condition expression is true then it
will evaluate the statement. If it is not true it will skip the statement. The
compound statement can be used to group multiple statements.


if-else|else
============


The if-else statement is similar to the if statement. It further extends the
if statement's syntax to include a second statement for when the condition
expression evaluates false. It has the following syntax:

        if (condition expression)
            true statement
        else
            false statement

When the interpreter encounters the if-else statement it will first evaluate
the condition expression. If the value of the condition expression is true, it
will execute the true expression, otherwise it will execute the false
expression. The compound statement can be used to group multiple statements.


switch
======


The switch statement is used to compare one value against a series of other
values. The switch statement is the most complicated statement in ColdC, and
does vary from it's counterpart in C, so rather than using abstract
explanations we will start with an example:

        switch (val) {
            case 0:
                cwrite("The value is zero.");
            case 1 .. 10:
                cwrite("The value is between one and ten inclusive.");
            case 11 .. a:
                cwrite("The value is between eleven and a inclusive.");
            case "foo", "bar".."baz":
                cwrite("The value is \"foo\" or between \"bar\" and \"baz\"");
            case a .. b, c .. d, 42:
                count = count + 1;
                cwrite("The value is in the counted area.");
            case ~perm:
                cwrite("Permission denied while getting the value.");
            default:
                cwrite("Did not recognize value.");
        }

This example illustrates all of the capabilities of the switch statement. The
expression given by val in the example is the controlling expression, and is
compared against each of the cases inside the switch body until a match is
found. Each case has a value or list of values to compare against. The values
can be of any type, and need not be constant expressions. Ranges are specified
using two dots (..) to separate the lower and upper bounds. The keyword
default specifies an action to perform if no cases were matched by the
controlling expression.

Here is a more formal description of the syntax of the switch statement:

        switch (controlling-expression) {
            case expr-or-range, expr-or-range, ..:
                statement
            case expr-or-range, expr-or-range, ..:
                statement
            ..
            default:
                default-statement
        }

When executing a switch statement, the interpreter scans through the list of
cases and compares the controlling-expression against each of the cases,
evaluating the case from left to right until there is a match. When using a
range, the lower and upper bounds must be of the same type and must be either
integers or strings. If they are not the error ~type is thrown. When the
interpreter finds a match, it will execute the statement for that case. The
interpreter will not continue checking cases after a match.

If the interpreter does not find a match, it will execute instead execute the
default-statement. A default statement does not need to be defined. If a
default is not defined nothing in the switch is executed.

C programmers should note that switch statements in ColdC differ from switch
statements in C in several respects. Because case values do not have to be
constants, they may conflict, in which case the first match will take
precedence. Also, there is no fall-through in ColdC switch statements; only
the statements corresponding to the matching case will be executed. Because
there is no fall-through, the break statement does not apply to switch
statements. Finally, the default case must be placed last in the list of cases
if it is given.


Error-Handling|catch
====================


The catch statement is used to catch and recuperate from errors. The catch
statement has the following syntax:

        catch error code, error code, ..
            body-statement
        with
            handler-statement

The keyword any can be substituted for the list of errors to to catch all
errors. The handler statement is optional, and does not need to be defined.

If an error listed in the error list is thrown inside the body-statement, the
interpreter will catch the error and start executing handler-statement rather
than aborting the method. After the handler is done, the interpreter continues
executing after the end of the catch statement, as if body-statement had
completed with no errors.

Inside the handler statement, the function error() can be used to retrieve the
error code which triggered the handler and the function traceback() can be
used to retrieve the propagated error stack. The function rethrow() is used to
continue propagating an error. The function throw() can be used at any time to
throw an error.

Here is an example of how a catch statement could intelligently handle a
~methodnf error thrown from the list_method() function:

        catch ~methodnf
            code = list_method(method_name);
        with
            .tell("There is no method named " + tostr(method_name) + ".");

Note that critical expressions inside body-statement will override the
behavior of the catch statement.


Looping Statements
==================


ColdC provides three kinds of looping statements. These statements are used to
traverse a list or a range of numbers, or to execute a statement as long as a
certain condition is true. ColdC also provides two kinds of jump statements
which are used to prematurely exit from a loop or continue onto the next
iteration of a loop.

  * for-list
  * for-range
  * while
  * break
  * continue


for-list
========


The for-list statement is used to traverse a list. It has the following syntax:

        for iteration-variable in (what expr)
            statement

iteration-variable must be a local variable (it cannot be an object variable),
and what expr must be an expression resulting in a list or dictionary type.
The interpreter executes statement once for each element in what, assigning
the current element to the iteration-variable for the iteration. Here is an
example of using a for-list statement on a list:

        for s in (["foo", "bar", "baz"])
            .tell(s);

When executed, the method tell is called three times, the first time with an
argument of "foo" (the first element in the list), the second time with "bar"
(the second element in the list), and the third time with "baz" (the last
element in the list).

When using a dictionary as what expr, the interpreter assigns each association
in the dictionary to the iteration variable (see Dictionaries). For example,
if the dictionary #[['count, 21], ['name, "foo"]] were to be used as the what
expr, the first iteration would set iteration variable to ['count, 21], and
the second iteration would set it to ['name, "foo"].

Assigning to the iteration variable within a for-list statement will not
change the status of the loop; the interpreter remembers where it is at in
what and will continue as normal.


for-range
=========


The for-range statement is used to traverse a range of integers. The range is
specified by separating the lower and upper bounds of the range with the range
operator (..), contained within the left and right square brackets ([ and ]).
A for-list statement of this nature would look like:

        for variable in [lower .. upper]
            statement

lower and upper must be expressions resulting in an integer type (unlike a
range in a switch). The interpreter executes statement once for each number
from lower to upper, with variable being assigned the current number in the
range. An example of using a range in a list is:

        for i in [1 .. 10]
            .tell("iteration " + i);

Assigning to variable within a for-list statement will not change the status
of the loop; the interpreter remembers where it is at in what and will
continue as normal.


while
=====


The while statement is used to execute code as long as the condition
expression is true. The while statement has the following syntax:

        while (condition expression)
            statement

The interpreter continually evaluates expression and executes statement until
the return value of expression is false. Here is an example using a while
statement:

        a = 1;
        while (a < 35)
            a *= 2;
        .tell("total: " + a);


break
=====


The break statement is used to exit a looping statement prematurely. The break
statement has the following syntax:

        break;

The interpreter jumps to the end of the innermost for-list, for-range, or
while statement and continues executing. It is important to note this, as when
executing multiple nested looping statements the break statement will only
break out of the innermost loop.


continue
========


The continue statement is used to jump to the next iteration of a loop. The
continue statement has the following syntax:

        continue;

The interpreter skips the remainder of the loop body and begins another
iteration of the innermost looping statement. As with the break statement the
continue statement only is relevant to the innermost looping statement.


Implementation
==============

This node isn't written yet


Methods
=======


A method consists of five different aspects: Arguments, Variables, ColdC Code,
Access and Flags. Arguments, Variables and ColdC Code are all defined within
the Method Code. Access and Flags are set and changed outside the method
definition. Arguments define how the method can be called. Variables define
any local variables used in the method. Code consists of the rest of the
method instructions. Access defines how the method may be called and Flags
define any other functionality and behaviour of the method.

  * Method Code
  * Method Flags
  * Method Access


Code
====


Arguments, Local Variables and the ColdC Code for a method are defined all at
once, within one block of text formatted as:

        arg arg1, arg2, .., @rest;
        var var1, var2, ..;

        statement1
        statement2
        ..
        ..

The first line is the Argument Declaration. The second line is the Local
Variable Declaration. Any remaining lines are standard ColdC statements, also
known generically as ColdC Code.

The arg declaration gives a list of argument variables, whose values will
correspond to the arguments passed with the message. The arg declaration may
be omitted if the method does not take any arguments. If the final argument
variable is preceeded with the splice operator (an at-sign `@`), then the
method can accept any number of arguments; the variable rest will contain a
list of the remaining arguments. If the final argument is not defined in this
way, the method can only accept the defined number of arguments, and sending
any more will cause a ~numargs error to be thrown.

The var declaration is used to define local variables. Any variable given in
the list will exist during the execution of the method. In the case of
conflicts with object variables, the local variable is used first. The var
declaration may be omitted if no local variables are declared.

Once the method begins normal execution, both arguments and local variables
are treated the same (as local variables). The statements statement1,
statement2, .. compose the ColdC Code body.

A Method is defined using the ColdC function add_method(), or within a
Textdump.


Flags
=====


Method flags define certain behaviour features of the method. Currently the
following method flags exist:

    nooverride    Methods which specify nooverride cannot be overridden by
                  any of the defining object's descendants.
    lock          This locks all aspects of a method. Locked methods cannot
                  have their access or flags changed, nor can they be
                  recompiled during run-time. Locked methods can be changed
                  outside of the regular running environment (such as in a
                  textdb, or with coldcc).
    forked        This is used to specify that the method forks from the
                  current task. The return value of a forked method is the
                  task id of the new task.
    native        This specifies a native method. Native methods are not
                  really methods, but are actually functions acting as a
                  method. Because of this native methods cannot be listed or
                  manipulated in most of the usual ways.

All method flags, with the exception of native, can be manipulated using the
functions method_flags() and set_method_flags().


Access
======


It is possible to restrict what calls a method by setting the method's access.
By default all methods are public methods. The available settings for method
access are:

    public     This access state is the default. A public method can be
               called by any object.
    protected  Protected methods can only be called by the defining object,
               or descendants of the defining object (sender() must be
               this()).
    private    Private methods can only be called by the object they were
               defined on (caller() must be this()).
    root       Root methods can only be called by the $root object (caller()
               must be $root).
    driver     Driver methods can only be called by the driver.
    frob       This access state only allows Frobbed Method Calls.

Method access can be manipulated using the functions method_access() and
set_method_access().


Frobbed
=======


Frobbed Method calls behave slightly different than any other access
restriction. First, a frobbed method may only be called from a frob. That is,
it must be called where the frob is the receiver, such as:

        (<$object, #[]>).method()

If it is called in the normal way, it will be as if the frobbed method does
not exist. For example, assume $obj_a is a parent of $obj_b. $obj_a defines
the method .name() as a standard method, but $obj_b overrides it and defines
it as a frobbed method. Calling $obj_b.name() will actually skip the frobbed
method and execute the method defined on $obj_a where calling (<$obj_b,
#[]>).name() will execute the frobbed method defined on $obj_b.

When a Frobbed Method passes back to an overridden method it will look first
for another Frobbed method, and then for a standard method.

If a method is defined as non-overridable, it may still be overridden by a
Frobbed Method. This allows for Frob Class objects to emulate real object
systems in the database, with frobs.


Tasks and Frames
================


The state of a method as it is being evaluated is called the Execution Frame.
Each frame has a few unique values associated with it, which may or may not
propagate to the next execution frame.

One or more frames executed in a series is called a Task. Tasks will originate
from either a connection, a heartbeat, or by a fork in another task. There is
no restriction on how many frames a task can execute.

It is possible to stop an executing frame, refresh the ticks it has and then
continue executing. This is called Preempting. When a task is preempted it
stops executing and is queued behind other current tasks. When these tasks are
finished executing the preempted task continues, with a refreshed tick amount.
Further information is given in the following sections:

  * Execution Frame
  * Task


Frames
======


The state of a method as it is being evaluated is called the execution frame.
Each frame has a few unique values associated with it, including the maximum
operations it can execute, the method itself, the current object and the
object defining the method being executed. These values are only relevant to
the current frame, and may or may not propagate to the next execution frame.

The maximum operations a frame can execute are also referred to as the ticks.
If a frame runs out of ticks before it finishes executing, the ~ticks error is
thrown by the interpreter.

These values can be determined by calling the following functions, as is
appropriate:

    FUNCTION         RETURNS
    ticks_left()     The ticks remaining in the frame
    method()         The current method
    this()           The current object
    definer()        The object defining the method
    sender()         The object which called this method (the last frame's
                     current object)
    caller()         The object defining the method which called this method
                     (the last frame's definer)



Tasks
=====


One or more frames executed in a series is called a task. Tasks will originate
from either a connection, a heartbeat, or by a fork in another task. There is
no restriction on how many frames a task can execute.

Several different functions return information about a task, or are used on a
task-wide scale:

    FUNCTION         BEHAVIOUR
    task_id()        Returns unique ID for the current task
    task_info()      Returns information on a task
    tasks()          Returns a list of all paused or preempted tasks
    stack()          Returns full execution frame stack
    user()           Returns task user
    set_user()       Sets task user
    atomic()         Used to turn on/off Atomic execution



Preempting
==========


When a task is preempted it stops executing and is queued behind other current
tasks. When these tasks are finished executing the preempted task continues,
with a refreshed tick amount. Preempting can be caused by calling either
pause() or refresh(). pause() will always preempt immediately. refresh() will
only preempt if the tick count is nearly exhausted. Furthermore, if executing
atomically refresh() will not preempt, but will immediately refresh the tick
count and continue executing.

Tasks may also be suspended indefinitely by using the function suspend(). The
function resume() will resume a suspended task. The function cancel() will
cancel a suspended task.

For more information see A Preempting Example.


Example
=======



An example of suspending a task is when reading an indefinite amount of input
from a connection. Input arrives through the parse method on an object (see
Networking), which we define as follows, assuming the object variables
reading, read, buffer and lines. reading is used to store a boolean value of
true or false, depending upon if we are reading input or not. read is used to
store what we have already read from the connection. buffer is used to store
incoming information which is not yet parsable by the function
buf_to_strings() (i.e. there is no carriage return yet). lines is used to
buffer lines converted by buf_to_strings() from the connection which we have
not parsed yet. It is important to use an object variable for both buffer and
lines, because if the task suspends all information stored in either variable
would be suspended along with that instance of the task.

    driver method .parse() {
        arg incoming;
        var line;

        lines = buf_to_strings(buffer + incoming));
        buffer = lines[listlen(lines)];
        lines = delete(lines, listlen(lines));

        // now parse the lines
        for line in (buf_to_strings(incoming)) {
            if (reading) {
                if (line == ".")
                    .done_reading();
                else
                    read += [line];
            } else {
                .parse_line(line);
            }
        }
    }

We will not define the method parse_line, just assume that it parses the line
as a command. When an object wishes to start reading from the connection it
calls the method .read() on the connection object:

    public method .read() {
        // reading just has to be true, so lets save space and store the
        // task id there as well, instead of storing it in another variable.
        reading = task_id();

        // make sure this is an empty list
        read = [];

        // suspend the task, have our return value be the return value
        // of suspend (which is whatever resume() sends)
        return suspend();
    }

When a period is found as the line being read, the connection is done reading
(the period is insignificant, and is only used in this example for
convenience), and the method done_reading is called:

    protected method .done_reading() {
        var info, task;

        // get a local copy of what we read, and the task id
        info = read;
        task = reading;

        // reset the object variables first
        read = [];
        reading = 0;

        // resume the task, send what we read as the return
        // value for suspend()
        resume(task, info);
    }

Now, all that has to happen to read input from a connection is to call the
method .read() on the connection object, and the input read is returned from
the method call.

It is possible to set a task as atomic. Atomic tasks cannot be preempted or
suspended. If an attempt is made to preempt or suspend an atomic task the
error ~atomic is thrown instead. However, calling refresh() while executing
atomically will always refresh the current frame's ticks. A task's atomic
state is toggled using the function atomic().

Note: be very cautious when using atomic tasks. Atomic tasks can easily
disrupt the regular integrity of an online environment. See the section on
Security.


Errors
======


When something goes wrong in a ColdC method an error is thrown. The
interpreter will throw errors, and methods can throw custom errors (using the
throw() function). An error consists of an error code (the type of error), a
string describing the error, and--optionally--data relative to the error.

When the interpreter throws an error, it checks to see how the current method
handles that error type. If the error occured in a critical expression (see
Error-Handling Expressions), then the interpreter will cease evaluating the
critical expression. Processing of the method will continue as if the
interpreter had completed evaluation of the critical expression. The return
value of the critical expression will be the error code associated with the
thrown error. In this case, the traceback is not accessible from traceback();
in order to get a traceback, a catch statement must be used.

If the error did not occur in a critical expression, but occurred in a catch
statement which catches the error code (either because it is a catch all
statement or because it lists the error code (see Error-Handling Statements).
Then the processing of the method jumps to the error handler, if one was
provided, or to the end of the catch statement if not.

If the error did not occur in a critical expression or in an appropriate catch
statement, then the current method aborts, and the interpreter throws an error
in the calling method. Normally, the error thrown in the calling routine will
have the error code ~methoderr unless the original error occurred within a
propagation expression. If the error occurred within a propagation expression
then the error code will be the same as it was for the original error. A
propagation expression has no effect on how an error is handled except to
cause the error code to propagate differently to the calling routine.

Errors are thrown using the throw() function. This does not throw an error in
the current method; instead, it exits the current method and throws an error
in the calling method. Thus a method cannot ignore an error which it threw
itself using throw().

There is one case in which a method cannot catch an interpreter-generated
error. Methods have a limited amount of time to run, measured in ticks. A
method will generally only run out of ticks if it gets stuck in an infinite
loop. If a method runs out of ticks, then the interpreter will throw a ~ticks
error, which the method cannot catch. This causes the method to abort, which
in turn causes the interpreter to throw a ~methoderr error in the calling
routine.

Critical expressions should be used when calling code which is possibly buggy
or when the method may be undefined, and it is undesirable for the current
method to stop executing as a result. For instance, a method which announces a
string to every object in a container should probably ignore errors in the
methods for each individual object which handle receiving the string.

Catch statements should be used to handle errors in any way other than
ignoring them. The catch statement is much more powerful than the critical
expression, and is ideal for situations in which fine-grain control over error
handling is required.

Propagation expressions should be used when the current method is an
intermediary between an outside object and an internal feature. For instance,
a method which checks permissions and calls an object function such as
list_method() is acting as an intermediary. In this case, the method should
throw the same errors as the list_method() function, so the function call
should be enclosed within a propagation expression.


Security
========


As the ColdC driver does not know what sort of environment the database
defines, by default all functions are callable by any object in the database.
In order to preserve integrity it is strongly suggested that the database
builds a hierarchy of trusted objects. Bind administrative-level functions to
these objects using the function bind_function() and restrict access to them.

It is suggested that the following functions always be bound and secured:

    atomic()              cancel()              create()
    backup()              shutdown()            set_heartbeat()
    bind_port()           unbind_port()         open_connection()
    fopen()               fstat()               fchmod()
    fmkdir()              frmdir()              files()
    fremove()             frename()             fclose()
    fseek()               feof()                fwrite()
    fread()               execute()             fflush()
    bind_function()       unbind_function()

It is also suggested that any additional function which modifies an object or
which alters/retrieves data on an object be bound.

The database can further be secured by solidifying key methods in its internal
security scheme (if one exists) and locking them (by setting the 'lock method
flag, see section Defining Methods).


Networking
==========


ColdC gives the ability to handle network sockets with the following
functions:

    bind_port()           close_connection()    connection()
    cwrite()              cwritef()             open_connection()
    unbind_port()         reassign_connection()

Connections are bound to a connection object. The driver will use the
following methods on a connection object:

        .connect()
        .disconnect()
        .failed()
        .parse()

There are two types of connections which can be created. The first is a server
connection, or a passive connection. To do this the driver listens on a
network port and waits for incoming connections. The second type is an client
connection, or a active connection. This type of connection is established by
the driver to another network host.


Server Connection
=================


To establish a server connection first call the function bind_port(). The
argument to this function is the network port to listen on. Note: most
operating systems will restrict low numbered ports (usually anything below
1024 is restricted, and can only be opened with special privileges). If there
are no errors, the current object is listening as a server on the specified
port.

When an external client opens a connection the driver will call the method
.connect() with two arguments. The first argument is a STRING, specifying the
remote IP address of the client. The second argument is an INTEGER, specifying
the socket where the connection was established. In general this number can be
ignored.

Data received on the connection will be sent as a buffer to the method
.parse(), after the method .connect() is called. Data is sent to the
connection using the functions cwrite() and cwritef().

If the client terminates the connection, the method .disconnect() is called.
Note: this method will not be called if the object terminates the connection
through close_connection().

If multiple connections will be received on the network port, it is suggested
that when a connection is started the connection object either reassigns the
connection to another connection object (using the function
reassign_connection()), or it notifies a new connection object to re-bind the
port to itself. If this is not done, new connections will preempt and close
the older connection (as only one connection can be on an object at a time).


Client Connection
=================


To establish a client connection call the function open_connection() with the
first argument as a STRING specifying the IP address of the host, and the
second argument an INTEGER specifying the network port to connect on. This
function is not a blocking function. Calling it will simply start the process
of opening a connection. If there are no immediate errors the function will
return normally.

When a connection is opened the driver will call the method .connect() on the
current object, with the argument being an INTEGER task_id for the task which
called open_connection(). Connection code may wish to suspend() after calling
open_connection(), then have the method .connect() resume the task when it is
received.

If the connection could not be established, the method .failed() is called
instead. The first argument is once again the task id, the second argument is
an ERROR representing why the connection could not be established.

Once the connection is established, input and output is handled the same as on
a server connection.


Regexps|Regular Expressions
===========================


ColdC Regular Expressions use Henry Spencer's Regular Expression package with
further extensions similar to those Perl has implemented.

A Regular Expression is an abstract way of matching text. The simplest Regular
Expression is a direct match. For instance, the string "that" exists within
the string "this and that are here.", therefore "that" is a Regular
Expression.

However, regular expressions can be much more complex than this case, as there
are many possibilities which may be matched in strings. Wildcard matching is a
common way of matching more than a simple instance of text. Wildcard matching
generally matches any number of anything where a `*' is found in the wildcard.
Although useful it does have its restrictions. Wildcard matching is not used
in Regular Expressions because of its lack of control.

The following is a list of all possible special characters in a regular
expression which have special meaning:

    \      Escape Mechanism, changes the meaning of the next character
    ^      Match the beginning of a string, or if at the beginning of a
           range, logically inverts the value (i.e. anything NOT in this
           range)
    $      Match the end of a string
    |      Branch Separator
    ()     Grouping
    []     Range
    .      Match any one character
    *      Match zero or more of the previous
    +      Match one or more of the previous
    ?      Match zero or one of the previous


ColdC Regular Expressions Explained
-----------------------------------

The first concept of Regular Expressions are branches. There can be zero or
more branches in a Regular Expression, separated by the pipe character ("|").
A Regular Expression will match anything in one of the branches. An example of
this is:

        this|that|there

This Regular Expression will match "this" OR "that" OR "there". It is easiest
to logically think of branches in this manner.

A branch is further defined as zero or more pieces joined together. A piece is
an atom possibly followed by an asterisk, a plus sign, or a question mark
("*", "+", or "?"). The asterisk, plus sign, or question mark defines how to
match the atom. An atom followed by an asterisk matches zero or more
occurrences of the atom. An atom followed by a plus sign matches one or more
occurrences of the atom. An atom followed by a question mark matches zero or
one occurrence of the atom.

An atom is either a Regular Expression Group or Range (see below), or one of
the following: a period ("."), a carat ("^"), a dollar sign ("$"), a
back-slash ("\") followed by a single character, or a single character with no
other significance. A period matches any single character in the input text, a
carat matches the beginning of the input text, a dollar-sign matches the end
of the input text, and a back-slash followed by a single character either has
special significance--such as matching all white space or all digits--or it
removes special significance from the following character. For instance, "$"
would match a dollar-sign in the input text, rather than matching the end of
the line (which is what the dollar-sign usually does).

A Group is anything enclosed within a set of parenthesis ("()"). Groups will
help to clarify how the Regular Expression should match, in addition to what
results should be returned from the Regular Expression. If one or more groups
exist, the result of the regular expression will include the groups, possibly
in addition to the entire area matched in the string (what is returned will
depend upon the function).

A range is a sequence of characters enclosed in square brackets ("[]"). It
normally matches any single character contained within the range sequence.
Characters which normally have special significance (such as a dollar-sign,
period and a back-slash) loose that significance when enclosed in a range.
However, a range has its own special characters. If the range begins with a
carat ("^"), it matches any single character which is not in the sequence. If
two characters in the sequence are separated by a dash ("-"), the full range
of ASCII characters between the two are matched, including the two. For
instance, "[0-9]" matches any single decimal digit from zero to nine. To
include a literal square bracket ("]") in the sequence do not use the
back-slash to escape it (as the back-slash does not have special meaning when
in a range), instead place it at the beginning of the range (following a
possible "^"). To include a literal dash ("-") place it the start or end of
the range.

Consider the following examples:

    a?                                   Match zero or one 'a' characters
    (this|that)*                         Match zero or more occurrences of
                                         "this" or "that"
    [a-z]+                               Match one or more occurrences of any
                                         alphabetic character (a through z)
    [^0-9]?                              Match zero or one occurrence of any
                                         non-digit character

The following characters have special meaning when matching (similar to PERL
Regular Expressions):

    "\w"   Match a word word character (alphanumeric plus "_")
    "\W"   Match a non-word character
    "\s"   Match a whitespace character
    "\S"   Match a non-whitespace character
    "\d"   Match a digit character
    "\D"   Match a non-digit character

Note: the above escape characters have not yet been integrated into the
regular expression matcher.


Files
=====


ColdC gives the ability to handle files with the following functions:

    execute()         fchmod()          fclose()          feof()
    fflush()          file()            files()           fmkdir()
    fopen()           frmdir()          fstat()           fread()
    fremove()         frename()         fseek()           fwrite()

When a file is opened it is associated (i.e. bound) with the current object.
Therefore, most file functions assume there is a file associated with the
current object when used (such as fwrite()). If there is not a file, the error
~file is thrown.

If the driver was compiled with RESTRICTIVE_FILES, the driver will restrict
where on the filesystem files can be manipulated (usually the ./root
directory, with the exception of the function execute(), which will use the
directory ./dbbin. More information on where the directories are given in the
Genesis Manual).

A file is opened using the function fopen(), and is closed using the function
fclose(). Reaching the end of a file will not close it. Destroying the object
for a file will close the file.

Example of opening, writing to and closing a simple text logfile:

        fopen("log");
        fwrite("[" + $time.format("%d %b %y %H:%M") + "] " + message);
        fclose();

Example of reading an image file:

        stat = fopen("image.gif", "-");
        buffer = fread(stat[2]);
        fclose();


Textdump
========

This node isn't written yet


Functions
=========


Buffer        Data          Dictionary    Error         File
List          Method        Misc          Network       Numeric
Object        String        System        Task          Variable


Variable
========


add_var()      clear_var()    del_var()      get_var()      set_var()
variables()


add_var()
=========


        INTEGER add_var(SYMBOL name)

This function defines an object variable on the current object. The name of
the variable is defined by the symbol name. If an object variable already
exists by the desired name, the error ~varexists is thrown. add_var() returns
1 if it is successful.


clear_var()
===========


        INTEGER clear_var(SYMBOL name)

This function clears the instance of an object variable, on a descendant. The
variable specified by name must be defined on the same ancestor defining the
method which is calling clear_var(). If not, the error ~varnf is thrown. If
this function is not called before an an ancestor is removed, variables
defined on that ancestor and set on the current object will remain (due to
encapsulation). This function is also useful in reducing database usage, as a
cleared variable takes up no space, where a set variable (even to a value of
0) does. Upon successful execution clear_var() returns 1.

See the section Objects and Variables for more information on the instance of
an object variable.


del_var()
=========


        INTEGER del_var(SYMBOL name)

This function deletes the object variable pointed to by the argument name
defined on the current object (it does not delete an instance of a variable).
If the object variable is not defined on the current object, the error ~varnf
is thrown. Upon successful execution del_var() returns 1.


get_var()
=========


        ANY get_var(SYMBOL name)

This function returns the current object's instance of the object variable
specified to by the argument name. The variable must be defined on the same
object which defined the method which calls get_var(). If the object variable
is not defined, the error ~varnf is thrown. Otherwise the current object's
value for the variable is returned.

This is an obtuse way of retrieving the value of an object variable, and is
generally only used when there is confusion with a local variable. For more
information see Variable Expressions.


set_var()
=========


        ANY set_var(SYMBOL name, ANY value)

This function sets the instance of an object variable on the current object.
The variable must be defined on the same object which defined the method which
calls set_var(). Using this function is the same as using the assignment
operator. If the object variable is not defined, the error ~varnf is thrown.
The return value for set_var() is the second argument value. The following two
examples are equivalent:

        set_var('time_stamp, time())
        => 855723496

        time_stamp = time()


variables()
===========


        LIST variables()

This function is used to determine all of the object variables defined on the
current object (not the instances of all variables). A list of symbols naming
each variable is returned.


Method
======


add_method()           del_method()           find_method()
find_next_method()     list_method()          method_access()
method_bytecode()      method_flags()         method_info()
methods()              rename_method()        set_method_access()
set_method_flags()


add_method()
============


        LIST add_method(LIST code, SYMBOL name)

This function compiles code (which should be a list of strings) and uses the
result as the definition of the method named by the symbol name. If there were
errors in compiling, a list of strings describing the errors is returned,
otherwise an empty list is returned. Examples:

        add_method(["cwrite(\"foo\");"], 'foo)
        => []

        add_method(["cwrite(\"foo\")"], 'foo)
        => ["Line 2: parse error"]


list_method()
=============


        LIST list_method(SYMBOL name[, INTEGER indent[, INTEGER flags]])

This function is used to decompile a method. It accepts a symbol, assuming it
to be the name of a method. If the method is defined on the current object it
is decompiled and returned as a list of strings. If the method is not found,
the error ~methodnf is thrown.

The second argument indent can be given to specify an alternate indentation to
use (default is four spaces). The third argument can be specified to change
the default formatting behaviour. The argument is an integer which can have
three different values:

        1                      Full Parenthesis
        2                      Full Braces
        3                      Full Parenthesis and Braces


del_method()
============


        INTEGER del_method(SYMBOL name)

This function removes the method named by the symbol name from the current
object. del_method() returns 1 if there was a method named name on the current
object; otherwise, a ~methodnf error is thrown.


find_method()
=============


        OBJNUM find_method(SYMBOL name)

This function searches for the first occurrence of the method named by the
symbol name, on an ancestor of the current object. If a method is found, the
ancestor is returned. Otherwise the error ~methodnf is thrown.


find_next_method()
==================


        OBJNUM find_next_method(SYMBOL name, OBJNUM after)

This function searches for the occurrence of the method named by the symbol
name, after the ancestor after. If a method is found, the ancestor is
returned. Otherwise the error ~methodnf is thrown.


method_bytecode()
=================


        LIST method_bytecode(SYMBOL name)

Returns the bytecode for the specified method, defined on the current object.
For instance, consider the following method:

        public method .test() {
            return "test";
        };

Would return the following bytecode:

        method_bytecode('test)
        => ['STRING, "test", 'RETURN_EXPR, 'RETURN]


method_access()
===============


        SYMBOL method_access(SYMBOL name)

This function returns the method access for the method specified with the
argument name. See Methods for more information on method access.


method_flags()
==============


        LIST method_flags(SYMBOL name)

This function finds the method specified with the argument name and returns
the list of flags currently set on the method. Method flags are fully
explained in the section on Defining Methods. If the method name cannot be
found, the error ~methodnf is thrown.


method_info()
=============


        LIST method_info(SYMBOL name)

This function returns a list of miscellaneous information on the method named
by name. If the method is not found, the error ~methodnf is thrown. Otherwise
a list is returned. The elements in the list are (in order):

  1) STRING args
  2) INTEGER number of arguments
  3) INTEGER number of local variables defined
  4) INTEGER number of opcodes used
  5) SYMBOL method access
  6) LIST method flags


methods()
=========


        LIST methods()

This function returns a list of symbols naming each method defined on the
current object.


rename_method()
===============


        INTEGER rename_method(SYMBOL old_name, SYMBOL new_name)

This function changes the name of the method on the current object, specified
by the argument old_name, and changes it to the name specified by the argument
new_name. If no method can be found by the name old_name, the error ~methodnf
is thrown.


set_method_access()
===================


        INTEGER set_method_access(SYMBOL name, SYMBOL access)

This function sets the method access for the method name. See Methods for more
information on method access.


set_method_flags()
==================


        INTEGER set_method_flags(SYMBOL name, LIST flags)

This function sets the method flags for the method specified with the first
argument name. The flags are specified as a list of symbols in flags. Full
information on method flags can be found in the section Method Flags. Example:

        set_method_flags('tell, ['nooverride])
        => 1


Object
======


ancestors()       children()        chparents()       create()
data()            del_objname()     destroy()         has_ancestor()
lookup()          objname()         objnum()          parents()
set_objname()


ancestors()
===========


        LIST ancestors([SYMBOL order])

This function returns a list of the ancestors of the current object. The order
of the list is specified by sending either 'depth or 'breadth (for a
depth-first or breadth-first order, respectively). If no order is specified,
the order is depth-first (similar to methods). The current object is always
the first element in this list. The hierarchy:

            $root
            /   \
        $obj_a   |
           |     |
        $obj_b $obj_c
            \   /
           $obj_d

Is used in the following examples, as called from $obj_d:

        ancestors()
        => [$obj_d, $obj_b, $obj_a, $obj_c, $root]

        ancestors('breadth)
        => [$obj_d, $obj_b, $obj_c, $obj_a, $root]


children()
==========


        LIST children()

This function returns a list of object numbers for the children of the current
object, in no particular order.


chparents()
===========


        INTEGER chparents(LIST parents)

This function changes the parents of the current object to the list of objnums
in parents. If any of the objnums in parents do not refer to an existing
object, then the error ~objnf is thrown. If any of the parents have the
current object as an ancestor, or are the current object, then the error
~parent is thrown. If parents is an empty list, then ~perm is thrown.
Otherwise a 1 is returned.


create()
========


        OBJNUM create(LIST parents)

This function creates and returns the objnum of an object with the parents in
the list parents, which should be a list of objnums referring to existing
objects. If any of the parent objnums do not refer to existing objects, then
create() throws the error ~objnf.


data()
======


        DICTIONARY data([OBJNUM ancestor])

This administrative function is used to retrieve all instances of object
variables the current object has, as well as the values of any object variable
they define. If ancestor is not defined it will return all instances defined
by any ancestor. If ancestor is defined it will only return data which is
defined by the specific ancestor.

The data is returned in a dictionary, where each object variable is a key and
the association to the key is the value for the object variable. If no
ancestor is specified and all instances are returned, each ancestor's values
are contained within another dictionary, where the key is the ancestor.

If an ancestor defines an object variable, but no instance of that variable
has been created for the current object (or the instance has been cleared with
the function clear_var()), it is not included in the dictionary.

The keys in a dictionary returned by data() do not have any particular
ordering.


del_objname()
=============


        INTEGER del_objname()

This function deletes an objname associated with the current object. When an
objname is deleted the object may only be referenced with it's objnum (for
more information on objnames and objnums read Referencing Objects). If the
current object does not have an objname, the error ~namenf is thrown.


destroy()
=========


        INTEGER destroy()

This function marks the current object for removal from the database. The
object is destroyed when all methods executing on it are completed (suspended
and preempted methods as well as the current task). Objects left orphaned by
the destruction of their only parent are reparented to the parents of the
parent which was destroyed.

Attempts to destroy the root or system objects will fail with the error ~perm.


has_ancestor()
==============


        INTEGER has_ancestor(OBJNUM ancestor)

This function returns one (1) if the current object has ancestor as an
ancestor, or zero (0) if it does not.


lookup()
========


        OBJNUM lookup(SYMBOL name)

This function finds the object number for the object name specified by the
argument name. If no object exists with that name, the error ~namenf is
thrown. Example:

        lookup('root)
        => #1


objname()
=========


        SYMBOL objname()

This function returns the symbol representation of the current object's name.
If the current object does not have an object name assigned, this function
throws the error ~namenf.


objnum()
========


        INTEGER objnum()

This function returns an integer representing the current object's object
number.


parents()
=========


        LIST parents()

This function returns a list of the objnums for the parents of the current
object.


set_objname()
=============


        INTEGER set_objname(SYMBOL name)

This function sets the argument name as the current object's objname. If
another object already has the object name name, the error ~error is thrown.
If the current object already has an object name, it is replaced with the new
name. Example:

        set_objname('user_bob)
        => 1


System
======


anticipate_assignment()     backup()
cache_info()                config()
set_heartbeat()             shutdown()


backup()
========


        INTEGER backup()

This function synchronizes the running database to disk and starts an
asyncrynous backup (Genesis copies the files to the file binary.bak, where
binary is the binary database directory name specified upon bootup). This
function executes atomically, and a slight pause may be noticed while it
synchronizes the object cache to disk and copies the index files.

The return value of backup() is always 1, and should be ignored. If a backup
is in progress the error ~perm is thrown. The error ~file is thrown if there
are file or directory problems. When the asyncrynous backup is finished the
driver calls $sys.backup_done().


set_heartbeat()
===============


        INTEGER set_heartbeat(INTEGER interval)

This function sets the periodic global heartbeat for the database to the
argument interval, where interval is in the delay in seconds. The heartbeat
can be disabled by setting the interval to zero or a negative number. The
default heartbeat interval is five seconds. The heartbeat is sent by the
driver calling the method $sys.heartbeat().


shutdown()
==========


        INTEGER shutdown()

This function completes all of the current tasks, syncronizes the database,
flushes all output and shuts down the server.


anticipate_assignment()
=======================


        INTEGER anticipate_assignment()

Do not use this unless you know exactly what you are doing, and how stacks and
frames work in the ColdC driver.

This function is used to reduce the amount of references to data on the stack,
in order to keep from unnecessarily copying data. It does this by breaking
encapsulation and looking at the calling frame's execution stack. If an
assignment will be made to data passed as an argument, as a result of the
current method's return--the variable is cleared of any references before the
data is modified in the current frame.

Because of how this works be careful to only call anticipate_assignment()
after any Errors are thrown. Any errors thrown after this function is called
will have the potential of losing data in the calling method.


config()
========


        ANY config(SYMBOL what[, ANY value])

This administrative function is used to change run-time values for the driver
and execution states. Current Genesis only partially implements this
function--it recognizes the changes but does not fully comply with them. The
value is specified with the argument what. If no second argument is given the
current value is returned. If a second argument is given, the value is set to
that value, if appropriate--if the new value is inappropriate the error ~type
is thrown. Values are:

        'datasize     Maximum Data Size (in bytes)
        'forkdepth    Maximum fork depth
        'calldepth    Maximum call depth
        'recursion    Maximum Swapping
        'objswap      Object Swapping



cache_info()
============


        LIST cache_info()

This administrative function returns a visual map of the active memory cache
for database objects. The list returned will have three elements, where each
element is:

  1) Cache Width (INT)
  2) Cache Depth (INT)
  3) Cache Map (LIST)

The Cache Map is a list of strings containing a single character entry for
each point in the cache (where the list is width wide, and there are depth).
The characters can be a lower or uppercase i or a. The character a refers to
active objects and the character i refers to inactive objects. If it is
capitalized, the object is marked dirty.


Task
====


atomic()           call_trace()       caller()
cancel()           debug_callers()    definer()
method()           pass()             pause()
refresh()          resume()           sender()
set_user()         stack()            suspend()
task_id()          task_info()        tasks()
this()             tick()             ticks_left()
user()


atomic()
========


        INTEGER atomic(INTEGER goatomic)

This function is used to turn on and off atomic execution. When executing
atomically no other tasks will be run. This also means that any function that
normally preempts will throw an error (with the exception of refresh()). If
the argument is false (zero) the interpreter stops executing atomically. If
the argument is true (non-zero) the interpreter starts executing atomically.
Note: read the section Frames and Tasks before using atomic().


caller()
========


        OBJNUM caller()

This function returns the objnum of the object which defines the method which
called the current method. If the current method was called by the driver zero
(0) is returned instead.


cancel()
========


        INTEGER cancel(INTEGER task_id)

This function cancels the suspended or preempted task with the task id given
by task_id. If the task does not exist, ~type is thrown.


definer()
=========


        OBJNUM definer()

This function returns the objnum of the object which defines the current
method.


method()
========


        SYMBOL method()

This function returns the name of the current method, as a symbol.


pause()
=======


        INTEGER pause()

This function instantly preempts the current task, letting other tasks execute
before it resumes execution with a refreshed tick count. See Frames and Tasks
for more information on preempting and task control.


refresh()
=========


        INTEGER refresh()

When the server is running non-atomically this function checks the current
frame's tick count and preempts the task if it is nearly depleted (similar to
pause()), resuming it with a new tick count after all other current tasks have
completed, otherwise it does nothing. If the server is running atomically the
task will not preempt, but the tick count will automatically be refreshed. See
Frames and Tasks for more information on task preempting.


resume()
========


        INTEGER resume(INTEGER task_id[, ANY value])

This function resumes the suspended task specified by the argument task_id.
The error ~type is thrown if the task does not exist. The optional second
argument value is used as the return value for the function suspend(). If a
second argument is not specified the return value of suspend() is zero. See
Frames and Tasks for more information on preempting and task control.


sender()
========


        OBJNUM sender()

This function returns the objnum of the object which called the current
method. If the current method was called by the driver, zero (0) is returned
instead. Further information can be found in the section Tasks and Frames.


stack()
=======


        LIST stack()

This function returns the call stack for the current task. Each element in the
list is a list itself, representing a specific frame. The first element
represents the first frame, and so on, up to the current frame.

Each frame list is ordered as follows:

  1) OBJNUM sender
  2) OBJNUM caller
  3) SYMBOL method name
  4) INTEGER line number
  5) INTEGER current op code


suspend()
=========


        ANY suspend()

This function suspends the current task indefinitely. A suspended task is
resumed by calling the function (in another task) resume(). The return value
of suspend is given as the second argument to resume(). If no second argument
is given, the return value of suspend() is zero. See Frames and Tasks for more
information on task control.


task_id()
=========


        INTEGER task_id()

This function returns the task id for the current task. See Frames and Tasks
for more information on preempting and task control.


tasks()
=======


        LIST tasks()

This function returns a list of integers, where each integer is the task id
for a currently suspended or preempted task.


this()
======


        OBJNUM this()

This function returns the objnum of the current object.


tick()
======


        INTEGER tick()

This function returns the current system-wide tick. It exists for backwards
compatability, and should not be used.


ticks_left()
============


        INTEGER ticks_left()

This function returns the ticks remaining for the current frame. See Frames
and Tasks for more information on frames and ticks.


set_user()
==========


        INTEGER set_user()

This function sets the task's user to the current object. Later calls to the
function user() will return this object, until this function is called again.
If no user is set, zero is returned instead. This is intended as an easy means
to define a controlling object for a task.


user()
======


        INTEGER user()

This function returns the task's user, as it was set with set_user(). If no
user was set, zero is returned instead. This is intended as an easy means to
define a controlling object for a task.


pass()
======


        ANY pass(...)

This function is used to call an overridden method, from the current method.
When called any arguments sent to pass() are sent to the overridden method, as
if it was called with those arguments. When passing to a method, the current
frame's values do not change (i.e. the caller and sender stay the same as in
the method that is passing back). For more information see the section
Overridden Methods.


task_info()
===========


        LIST task_info(INTEGER task_id)

This function returns full information on the task specified with the argument
task_id. If the task does not exist, ~type is thrown. The returned list
contains a minimum of seven elements, with subsequent elements defining the
specific frames, these are:

  1) INTEGER task id
  2) INTEGER preempted
  3) INTEGER datasize limit
  4) INTEGER fork limit
  5) INTEGER recursion limit
  6) INTEGER objswap limit
  7) INTEGER calldepth limit
  8) LIST frame
  9) ...

The second element preempted is true if this task was preempted, false if it
was suspended. For more information on the limit elements, see config().
Remaining frame elements are eight element lists formatted as:

  1) OBJNUM current object
  2) OBJNUM caller
  3) OBJNUM sender
  4) OBJNUM user
  5) INTEGER current opcode
  6) INTEGER last opcode
  7) INTEGER ticks remaining
  8) SYMBOL method name


call_trace()
============


        LIST|INTEGER call_trace()

Depending on the debug mode, one of the following will be returned:

mode 0
Return 0

mode 1
Returns a list samples gathered by debugger. Each method call is sampled as
the following list:

        [tick#, this, definer, method]


        tick#                  tick in which the call occured
        this                   receiver of the call
        definer                definer of the called method
        method                 method name (a symbol)

Each method return is sampled as a tick#.

Note: The tick counts will be off if the task has been preepmpted and another
task executed during the pause.

mode 2
In addition to the above, each method call has fifth element, giving the list
of all the arguments passed in the call. Optional arguments (those defined as
@rest in the arg list) are gathered into a list and placed into the result as
a single element.

This function will automatically set the debug mode to 0.


debug_callers()
===============


        INTEGER debug_callers(INTEGER mode)

This function sets the mode for call_trace function. If mode is set to
non-zero value, the method calling sampler will automatically start. The
result of this function is 0.


Error
=====


error()        rethrow()      throw()        traceback()


error()
=======


        ERROR error()

This function returns the error code associated with the current error. This
function can only be called from within an error handler. For more information
see the section on Errors.


rethrow()
=========


        rethrow(ERROR code)

This function continues propagation of an error condition. The interpreter
will abort the current method and throw the error specified by code in the
calling method. Calling this function outside of an error handler will result
in the error ~error.


throw()
=======


        throw(ERROR code, STRING explanation[, ANY additional])

This function throws an error with the code code in the calling method, not
the current method. The current method does not have the ability to stop an
error originating in itself. The variables explanation and additional appear
in the traceback. For more information on error handling see traceback() and
Errors. Example:

        throw(~perm, "Sender is not the system object.");


traceback()
===========


        LIST traceback()

This function returns the propogated error stack. The first element in the
traceback list is the error condition, the second element is what caused the
error. The subsequent errors describe the method call stack from the point of
origin. The error condition list is ordered as follows:

  1) ERROR code
  2) STRING explanation
  3) ANY additional

The second element (what caused the error) will vary, depending upon where the
error came from. If the error came from an operator, function or native
method, it is a two element list:

  1) SYMBOL which is one of 'opcode, 'function or 'native
  2) SYMBOL what operator, or the name of the function/native method.

If the error originated in a method, this list is ordered as:

  1) 'method
  2) SYMBOL method name
  3) OBJNUM current object
  4) OBJNUM defining object
  5) INTEGER line in method

All other elements are ordered as:

  1) ERROR error code
  2) SYMBOL method name
  3) OBJNUM current object
  4) OBJNUM defining object
  5) INTEGER line in method

Keep in mind that the error code will change to ~methoderr when it propogates,
unless the propogate expression is used. See the section Errors for more
information. A full traceback might look like:

        [[~numargs, "Called with no arguments, requires one.", 0],
        ['function, 'listlen],
        [~numargs, 'foo, $brandon, $brandon, 1],
        [~methoderr, 'tmp_eval_855796437, $brandon, $brandon, 6]]


Network
=======


bind_port()              close_connection()       connection()
cwrite()                 cwritef()                open_connection()
reassign_connection()    unbind_port()


bind_port()
===========


        INTEGER bind_port(INTEGER port[, STRING addr])

This function binds a network port to the current object. If successful, the
current object will receive connections on the port. The first argument
specifies the port to bind to. Positive port numbers represent the TCP
protocol. Negative port numbers represent the UDP protocol. The second
optional argument is the address to bind to, which must be a standard IP
address (not an internet domain name). This is usually not required, but can
be useful if multiple addresses exist on the system and only one must be
bound.

If the port is pre-bound (see the Genesis documentation) but the address does
not match up, the error ~preaddr may be thrown. If the port is pre-bound and
the protocols do not match, the error ~pretype is thrown. If the given address
is not a valid IP address the error ~address is thrown. Other errors may be
thrown as ~socket or ~bind if other problems arise.


close_connection()
==================


        INTEGER close_connection()

This function closes the connection on the current object. If there is no
connection on the current object, zero is returned.


connection()
============


        LIST connection()

This function returns a list of information on the current connection. If no
connection exists, ~net is thrown. The list is ordered as:

  1) INTEGER boolean (true if the connection is readable)
  2) INTEGER boolean (true if the connection is writable)
  3) INTEGER boolean (true if the connection is dead)
  4) INTEGER file descriptor

Most of this information is useful only for debugging, as it can change
immediately (all but the file descriptor). This function is useful for
determining if the current object has a valid connection.


cwrite()
========


        INTEGER cwrite(BUFFER buffer)

This function writes the buffer data in the argument buffer to the connection
on the current object. If there is no connection on the current object a zero
is returned. Otherwise a one is returned.


cwritef()
=========


        INTEGER cwritef(STRING file_path[, INTEGER block])

This function opens the file specified by file_path and writes it's contents
directly to the connection. The block size it reads and writes (defaulting to
the driver defined variable in defs.h DEF_BLOCKSIZE, usually this is 512) can
be changed by specifying an optional second argument. If the second is a
negative one (-1) it will attempt to read the entire file at once, and write
it to the connection (the old coldmud behavior). The size of the file (in
bytes) is returned. If a problem arises the error ~file is thrown.


open_connection()
=================


        INTEGER open_connection(STRING host, INTEGER port)

This function opens an outbound connection to host at port port, on the
current object. If the host address host is invalid, the error ~address is
thrown. If the socket could not be established, ~socket is thrown. For more
information, see the section on Networking.


reassign_connection()
=====================


        INTEGER reassign_connection(OBJNUM new)

This function changes the controlling object for a connection from the current
object to the object specified by the argument new. If the new object does not
exist, ~objnf is thrown. If the new object already has a connection, the error
~perm is thrown.


unbind_port()
=============


        INTEGER unbind_port(INTEGER port)

This function stops listening to the port specified by port. If the object is
not listening to the specified port, ~servnf is thrown.


File
====


dblog()      execute()    fchmod()     fclose()     feof()
fflush()     file()       files()      fmkdir()     fopen()
fread()      fremove()    frename()    frmdir()     fseek()
fstat()      fwrite()


dblog()
=======


        INTEGER dblog(STRING line)

This function writes line to the database logfile (specified on startup,
defaulting to logs/db.log).


execute()
=========


        INTEGER execute(STRING program, LIST args[, INTEGER nb])

This function executes the program named by program with the arguments given
in the list arguments. Each argument must be a string. By default, calling
this function will block execution of genesis until the called program
returns. If the optional third argument is specified as a true value, the
program is forked and executed in a non-blocking manner. The return value is
the return value of the program, or, in the case of a non-blocking execution
it is zero.

This function looks for the program in the executable directory specified upon
startup by the driver. This usually defaults to dbbin.

In the future input and output for the program may be handled as if it were a
file.


fchmod()
========


        INTEGER fchmod(STRING mode[, STRING file])

This function changes the mode of a file or directory. The mode is an octal
number constructed by logically OR-ing the following values:

        4000                   set-user-ID-on-execution
        2000                   set-group-ID-on-execution
        1000                   sticky bit, see the unix manual on chmod
        0400                   read by owner
        0200                   write by owner
        0100                   execute (or search for directories) by owner
        0070                   read, write, execute/search by group
        0007                   read, write, execute/search by others

The read, write, and execute/search values for group and others are en- coded
as described for owner. Example:

        fchmod("0644", "home.html")
        => 1

If the RESTRICTIVE_FILES option has been compiled into the driver, sticky and
setuid/setgid bits cannot be changed.


fclose()
========


        INTEGER fclose()

This function closes the file on the current object and returns one (1). If no
file is open on the current object, the error ~file is thrown.


feof()
======


        INTEGER feof()

This function returns true (1) if the open file on the current object is at
it's end, or false (0) if it is not. If the current object does not have an
open file, ~file is thrown.


fflush()
========


        INTEGER fflush()

This function flushes any buffered output for the open file on the current
object and returns one (1). If there is no file on the current object the
error ~file is thrown.


file()
======


        LIST file()

This function returns the following ordered list of information on the file on
the current object:

  1) BOOLEAN file is readable
  2) BOOLEAN file is writable
  3) BOOLEAN file is closed
  4) BOOLEAN file is binary
  5) STRING file path

If no file is bound to the current object, the error ~file is thrown.


files()
=======


        LIST files(STRING directory)

This function returns a lit of files in the specified directory. The current
and previous directory ("." and "..") are not included in this listing. Each
element in the list is a string. Example:

        files("html/");
        => ["index.html", "tCD.gif", "Intro", "history.html"]


fmkdir()
========


        INTEGER fmkdir(STRING path)

This function creates the directory specified by path. If a file or directory
already exists by that designation, the error ~file is thrown. Otherwise the
directory is created with read, write and execute permission for the owner,
and no permissions for group or others (these permissions can be changed with
the function fchmod().


fopen()
=======


        LIST fopen(STRING filename[, STRING mode])

This function is used to open a file on the current object. It is called with
one or two arguments. The first argument is the name of the file to open. If
the driver was compiled with the RESTRICTIVE_FILES option, the filename will
have restrictions (see the section on Files for more information). If
RESTRICTIVE_FILES was compiled, all files will have the root directory
prepended to them (this directory is defined by a command line argument to
Genesis). If it was not compiled, but the file does not begin with a slash
("/"), the root directory will still be prepended.

The second argument is the mode for the file. If the mode begins with "<" or
nothing, the file is opened for reading. If the mode begins with ">", the file
is truncated to zero length or created for writing. If the mode begins with
">>", the file is opend for appending. If the second argument is not
specified, the mode of file defaults to "<".

A "+" may be placed before ">" or "<" to specify both read and write access to
the file. Ending a mode with a "-" sets it as a binary file, meaning that
input and output to the file is through buffers, rather than ColdC strings.

If successful, the return value of fopen() is stat information in the format
returned by fstat().

Examples:

        stat = fopen("log", ">>")

        stat = fopen("/usr/home/test.info", "+>-")


fread()
=======


        STRING|BUFFER fread([INTEGER block])

Read from the existing file bound to this object. If the file is a binary
file, a buffer is returned. If the file is a text file (default), a string is
returned. If the file is at the end, the ~eof error is thrown. With binary
files an optional block size may be specified. The default block size is 512
characters. Example:

                catch ~eof {
                    while (1) {
                        line = fread();
                        .tell(line);
                    }
                }



fremove()
=========


        INTEGER fremove(STRING path)

This function removes a file. If the argument path is given, it will attempt
to remove that file.


frename()
=========



        INTEGER frename(ANY from, STRING to)

This function renames the file specified by the argument from, to the name
specified by the argument to. If from is not a string or is logically false,
the driver renames the file on the current object. Do not rename the file on
the current object by specifying the file's name, as the driver will not know
the name has changed and this may cause confusion at a later time. Example:

        frename("", "old.txt")
        => 1


frmdir()
========


        INTEGER frmdir(STRING path)

This function removes the directory specified by path. If an error occurs,
~file is thrown (the error explanation will vary depending upon what occurred).


fseek()
=======


        INTEGER fseek(INTEGER offset, SYMBOL whence)

This function changes the file position to offset. The variable whence is
either 'SEEK_SET, 'SEEK_CUR, 'SEEK_END. Read the unix manual page for the
function fseek, for more information.

If the file is not both readable and writable, this function cannot be used.


fstat()
=======


        LIST fstat([STRING path])

This function returns information on a file. If the file is not specified as
path, then it returns information on the open file on the current object. The
information is returned as an ordered list:

  1) STRING octal file mode (see fchmod())
  2) INTEGER file size (in bytes)
  3) INTEGER time when the file was last accessed
  4) INTEGER time when the file data was last modified
  5) INTEGER time when the file status was last changed

For more information refer to the unix manual page on stat. The octal file
mode will likely include additional bit fields from what is commonly seen.
These represent file attributes, such as directories, FIFO, etc. The last four
bits will refer to the permissions. For instance:

        fstat("html")
        => ["40775", 512, 855442283, 851293545, 855435595]


fwrite()
========


        INTEGER fwrite(STRING|BUFFER info)

Write to an existing file bound to this object. The argument is either a
buffer (if it is a binary file), or a string (if it is a text file). The
return value is an integer representing an offset value of characters which
were not written out (due to an error). In normal operating conditions the
return value will be zero.

Using fwrite() with strings will always terminate the string with a newline
character (ASCII 10).


Misc
====


bind_function()      ctime()              localtime()
mtime()              time()               unbind_function()


bind_function()
===============


        INTEGER bind_function(SYMBOL function, OBJNUM obj)

This function is used to secure other ColdC functions which may have potential
security problems. It binds the function specified by the argument function to
the object specified by obj. After a function is bound to an object, only
methods defined on that object may call the function. The error ~perm is
thrown if methods defined on descendants of the object or on any other object
call a bound function which is not bound to them.


ctime()
=======



        STRING ctime([INTEGER time])

This function converts the integer time into a string format, using the
operating system's ctime library call. This call may handle any time
conversions automatically (such as Daylight Savings and Leap Years). If time
is not specified, then ctime() uses the current time. Example:

        ctime(739180536)
        => "Fri Jun 4 03:55:36 1993"


localtime()
===========


        LIST localtime([INTEGER time])

This function returns an 11 element list representing the specified by the
argument time. If no argument is given, it will use the current time instead.
The elements are taken from struct tm in C and altered as needed to begin at
one instead of zero. Elements are broken down in the list as follows:

  1) INTEGER time (same as returned by the function time())
  2) INTEGER seconds (1-60)
  3) INTEGER minutes (1-60)
  4) INTEGER hours (1-24))
  5) INTEGER day of month (1-31)
  6) INTEGER month in year (1-12)
  7) INTEGER year (use year + 1900 for the full year)
  8) INTEGER week day (1-7, Sunday=1)
  9) INTEGER year day (1-366)
  10) INTEGER is daylight savings in effect?
  11) STRING time zone name
  12) INTEGER timezone offset in seconds from GMT

Note: there is one bug, in order to optimize the speed of this function the
timezone name (as a string) is cached. This will mean that if the timezone
name changes while genesis is running the name will not update correctly.


mtime()
=======


        INTEGER mtime()

If the system the server is on does not have the unix function gettimeofday()
then this function will return -1. If it does, this function will return the
current microseconds, from the C structure struct timeval. This is useful in
certain situations, but in general its granularity is too fine for most cases.
This will only work if cold is running on some unix systems.


time()
======


        INTEGER time()

This function returns the system time in seconds since midnight GMT, January
1, 1970--likely adjusted for the local timezone (this is OS dependant). The
functions ctime(), localtime() and the native method $time.format() can be
used in manipulating this number.


unbind_function()
=================


        INTEGER unbind_function(SYMBOL function)

This function unbinds a function from an object. The function is specified by
the argument function.


Data
====


class()          fromliteral()    size()           toerr()
tofloat()        toint()          toliteral()      toobjnum()
tostr()          tosym()          type()           valid()


frob_class()
============


        OBJNUM frob_class(FROB frob)

This function returns the class of a frob. See Frobs for more details on Frobs.


size()
======


        INTEGER size([ANY data])

This function is used for sizing data. If no arguments are specified, it will
return the size of the current object, including all of the methods and object
variable instances defined on it. Otherwise it returns the size of the first
argument. Note: specifying an objnum as the argument will return the size of
the objnum, not the size of the object it represents!
The number returned represents the size, in bytes, on disk. Because data is
packed when written to the disk database, what is returned will not be
comparable to runtime memory footprints.
Examples:

        size(#1234)
        => 4

        size([1, 2, 3, 4])
        => 15

        size(#[['key1, 1], ['key2, "test"]])
        => 45

        size(<$root, #[['name, "foo"]]>);
        => 37

        size()
        => 5822


toerr()
=======


        ERROR toerr(SYMBOL errname)

This function converts the argument specified by errname to an error code.


tofloat()
=========


        FLOAT tofloat(STRING|INTEGER|OBJNUM data)

This function accepts a STRING, INTEGER or OBJNUM data type and converts it to
a FLOAT data type. Specifying any other data type will result in a ~type error.


toint()
=======


        INTEGER toint(FLOAT|STRING|OBJNUM data)

This function accepts a FLOAT, STRING or OBJNUM data type and converts it to
an integer data type. Specifying any other data type will result in a ~type
error.


toliteral()
===========


        STRING toliteral(ANY data)

This function converts any data to a literal representation of itself, which,
if re-compiled, would result in the same data.


toobjnum()
==========


        OBJNUM toobjnum(INTEGER number)

This function converts the integer data type specified by number to an objnum
data type. The returned objnum may or may not point to a valid object.


tostr()
=======


        STRING tostr(ANY data)

This function returns a simple representation of the data specified by data.
It is not a literal representation, as toliteral() does, but insteads is more
succinct. For instance, with complex data types such as lists, the returned
representation is simply "[list]". Less complex data types such as integers
will still return the correct integer value.


tosym()
=======


        SYMBOL tosym(STRING input)

This function creates a symbol from the string input. Symbols can only contain
alphanumeric characters, and the underscore character. If a string is
specified with more than these characters, the error ~symbol is thrown.


type()
======


        SYMBOL type(ANY data)

This function returns a symbol name for the data type of data. The following
symbols represent the respective types:

        INTEGER                'integer
        FLOAT                  'float
        STRING                 'string
        SYMBOL                 'symbol
        LIST                   'list
        OBJNUM                 'objnum
        DICTIONARY             'dictionary
        ERROR                  'error
        FROB                   'frob
        BUFFER                 'buffer

More information can be found in the section on Data Types.


valid()
=======


        INTEGER valid(OBJNUM objnum)

This function returns one (true) if the object pointed to by objnum exists, or
zero (false) if it does not.


fromliteral()
=============



        ANY fromliteral(STRING data)

This function takes the literal representation of the data given in the string
argument data and parses it to actual data, returning the result. If it cannot
parse the data, the error ~type is thrown. Example:

        fromliteral("[1, 'foo]")
        => [1, 'foo]


frob_value()
============


        DATA frob_value(FROB frob)

This function returns the value of a frob. See Frobs for more details on Frobs.


frob_handler()
==============


        SYMBOL frob_handler(FROB frob)

This function returns the handler of a frob. See Frobs for more details on
Frobs.


Buffer
======


buf_replace()       buf_to_str()        buf_to_strings()
bufgraft()          bufidx()            buflen()
str_to_buf()        strings_to_buf()    subbuf()


buf_replace()
=============


        BUFFER buf_replace(BUFFER buf, INTEGER pos, INTEGER char)

This function replaces the character in the buffer at position pos with the
character specified by the integer char. Example:

        buf_replace(`[98, 111, 111], 1, 102)
        => `[102, 111, 111]

The function bufgraft() performs a similar role.


buf_to_str()
============


        BUFFER buf_to_str(BUFFER buf[, BUFFER sep])

This function converts the buffer specified by buf to a list of printable
strings, with a final buffer element. Each string is a line in the buffer,
terminated by a newline. If any characters remain unterminated, they are
placed in the last element as a buffer. The last element will always be a
buffer, regarless of whether any characters are in it.

buf_to_strings() will alternatively split the strings based off the optional
second argument. Note: it is not necessary to specify both a carriage return
and a newline as the separator--if both exist--as the newline will be
sufficient to break the string, and the carriage return will be discarded as
an unprintable character in the string.


buf_to_strings()
================


        LIST buf_to_strings(BUFFER buf[, BUFFER sep])

This function converts the buffer specified by buf to a list of printable
strings, with a final buffer element. Each string is a line in the buffer,
terminated by a newline. If any characters remain unterminated, they are
placed in the last element as a buffer. The last element will always be a
buffer, regardless of whether any characters are in it.

buf_to_strings() will alternatively split the strings based off the optional
second argument. Note: it is not necessary to specify both a carriage return
and a newline as the separator--if both exist--as the newline will be
sufficient to break the string, and the carriage return will be discarded as
an unprintable character in the string.


bufgraft()
==========


        BUFFER bufgraft(BUFFER buf, INTEGER pos, BUFFER what)

This function will graft the buffer what into the buffer buf at pos. Example:

        bufgraft(`[1, 2, 3, 4], 2, `[100, 100])
        => `[1, 100, 100, 2, 3, 4]


buflen()
========


        INTEGER buflen(BUFFER buf)

This function returns the length of the buffer buf.


str_to_buf()
============


        BUFFER str_to_buf(STRING str)

This function converts the string specified by the argument str to a buffer.
The character sequence "\n" will be converted to a carriage return and line feed (ASCII 13 and 10).


strings_to_buf()
================


        BUFFER strings_to_buf(LIST strings[, BUFFER sep])

This function builds a buffer from the strings given in the list strings. Each
string represents a line which is terminated with a carriage return and a
newline (ASCII 13 and 10). If the argument sep is specified, each string is
terminated with it instead. Examples:

        strings_to_buf(["a", "b", "c"])
        => `[97, 13, 10, 98, 13, 10, 99, 13, 10]

        strings_to_buf(["a", "b", "c"], `[9])
        => `[97, 9, 98, 9, 99, 9]


subbuf()
========


        BUFFER subbuf(BUFFER buf, INTEGER start[, INTEGER length])

This function returns a subrange of the buffer specified by buf. The subrange
starts at position start, and continues length characters. If length is
unspecified, it will continue to the end of the buffer. If start is outside of
the range of the buffer, or length will extend past the end of the buffer, the
error ~range is thrown. Example:

        subbuf(`[1, 2, 3, 4], 2, 2)
        => `[2, 3]


bufidx()
========


        INTEGER bufidx(BUFFER buf, BUFFER|INTEGER what[, INTEGER origin])

This function returns the position in buf where what exists--starting from
origin--or a zero if it does not exist. If origin is not specified it will
default to 1. If what is an integer, it is equivalent to `[what]. The origin
represents where to start searching in the buffer. If it is a positive number
it starts that many elements into the buffer. If it is a negative number it
starts that many elements from the end of the buffer, and searches
backwards--from the end of the buffer to the start. Examples:

        bufidx(`[1, 7, 1, 6, 7, 1], 7)
        => 2

        bufidx(`[1, 7, 1, 6, 7, 1], 7, -1)
        => 5

        bufidx(`[1, 7, 1, 6, 7, 1], `[6, 7])
        => 4

        bufidx(`[1, 7, 1, 6, 7, 1], `[6, 8])
        => 0


Dictionary
==========


dict_add()         dict_contains()    dict_del()
dict_keys()        dict_union()       dict_values()


dict_add()
==========


        DICTIONARY dict_add(DICTIONARY dict, ANY key, ANY value)

This function adds an association to the dictionary dict. The key and value of
the association are given as the key and value arguments. The new dictionary
is returned. If key already exists in dict, then the value of the existing key
is replaced with value. Examples:

        dict_add(#[["foo", "bar"]], 3, 'quux)
        => #[["foo", "bar"], [3, 'quux]]

        dict_add(#[["foo", 1], ["bar", 2], ["baz", 3]], "bar", 4)
        => #[["foo", 1], ["bar", 4], ["baz", 3]]


dict_contains()
===============


        INTEGER dict_contains(DICTIONARY dict, ANY key)

This function returns 1 if there is an association in dict with the specified
key, or 0 otherwise. Examples:

        dict_contains(#[["foo", "bar"]], "foo")
        => 1

        dict_contains(#[["foo", "bar"]], "bar")
        => 0


dict_del()
==========


        DICTIONARY dict_del(DICTIONARY dict, ANY key)

This function the key value association from the dictionary dict and returns
the result. If there is no association with the specified key, then the error
~keynf is thrown. Example:

        dict_del(#[["foo", 1], ["bar", 2]], "foo")
        => #[["bar", 2]]


dict_keys()
===========


        LIST dict_keys(DICTIONARY dict)

This function returns a correctly ordered list of the keys of the associations
in dict. Example:

        dict_keys(#[["foo", 1], ["bar", 2], ['baz, 3]])
        => ["foo", "bar", 'baz]


dict_union()
============


        DICTIONARY dict_union(DICTIONARY dict1, DICTIONARY dict2)

This function merges the two dictionaries by adding each association from
dict2 into dict1. In the case of conflicts, the values in dict2 take
precedence. Example:

        dict_union(#[["foo", 1], ['baz, 3]], #[["foo", 2], ["bar", 2]])
        => #[["foo", 2], ['baz, 3], ["bar", 2]]


dict_values()
=============


        LIST dict_values(DICTIONARY dict)

This function returns a correctly ordered list of the keys of the associations
in dict. Example:

        dict_values(#[["foo", 1], ["bar", 2], ['baz, 3]])
        => [1, 2, 3]


List
====


delete()       insert()       join()         listgraft()    listidx()
listlen()      replace()      setadd()       setremove()    sublist()
union()


delete()
========


        LIST delete(LIST list, INTEGER pos)

This function deletes the element in the argument list, pointed to by the
position argument pos, and returns the result. If position is less than 1 or
is greater than the length of list, then delete() throws a ~range error.
Example:

        delete([2, 3, 4], 2)
        => [2, 4]


insert()
========


        LIST insert(LIST list, INTEGER pos, ANY value)

This function inserts value into list before the element specified by the
integer pos. If pos is outside the range of the list, the error ~range is
thrown. Examples:

        insert([2, 3, 4], 3, 'foo)
        => [2, 3, 'foo, 4]

        insert(["foo", 'bar, ~none], 4, 'baz)
        => ["foo", 'bar, ~none, 'baz]

The function listgraft() performs a similar role to insert().


join()
======


        LIST join(LIST list[, STRING separator])

This function joins a list together as a string. The second argument is used
to specify what separates each element in the list. If the second argument is
unspecified, this will default to a single space. If any element in the list
is not a string, it will have a literal representation used instead, in the
same manner as when using Non Arithmetic Operators. Examples:

        join(["Joe", "Sally", "Bob", "Sue"])
        => "Joe Sally Bob Sue"

        join(["This", "That", 'there, 10], ", ")
        => "This, That, there, 10"


listgraft()
===========


        LIST listgraft(LIST list1, INTEGER pos, LIST list2)

This function is similar to the splice operator and insert(), except it grafts
a list into another list, rather than inserting an element at a point in the
list. It will take the list specified by list2 and place each element in that
list into the list specified by list1, starting at the position specified by
pos. Example:

        listgraft([1, 2, 3, 4, 5], 3, ["foo", "bar", "baz"])
        => [1, 2, "foo", "bar", "baz", 3, 4, 5]


listlen()
=========


        INTEGER listlen(LIST list)

This function returns the length of list.


replace()
=========


        LIST replace(LIST list, INTEGER pos, ANY value)

This function replaces the element in the argument list--pointed to by the
position argument pos--with the argument value, and returns the result. If the
position argument is outside the range of the list, the error ~range is
thrown. Example:

        replace([2, 3, 4], 2, 'foo)
        => [2, 'foo, 4]


setadd()
========


        LIST setadd(LIST list, ANY value)

This function appends the argument value to the argument list if it is not
already in the list, and returns the result. If value is already in the list,
it does not add it. Examples:

        setadd([2, 3, 4], 'foo)
        => [2, 3, 4, 'foo]

        setadd([2, 3, 4], 3)
        => [2, 3, 4]


setremove()
===========


        LIST setremove(LIST list, ANY value)

This function removes the argument value from the argument list, if it exists,
and returns the result. Examples:

        setremove([2, 3, 4, 'foo], 'foo)
        => [2, 3, 4]

        setremove([2, 3, 4], 5)
        => [2, 3, 4]

        setremove([2, 3, 2, 4], 2)
        => [3, 2, 4]


sublist()
=========


        LIST sublist(LIST list, INTEGER start[, INTEGER length])

This function returns a subrange of the list specified by list. The subrange
starts at position start, and continues length elements. If length is
unspecified, it will continue to the end of the list. If start is outside of
the range of the list, or length will extend past the end of the list, the
error ~range is thrown. Examples:

        sublist([2, 3, 4, 5, 6, 7], 2, 3)
        => [3, 4, 5]

        sublist([2, 3, 4, 5, 6, 7], 3)
        => [4, 5, 6, 7]

        sublist([2, 3, 4, 5, 6, 7], 7)
        => []


union()
=======


        LIST union(LIST list1, LIST list2)

This function adds each element of list2 to list1 which does not already exist
in list1. Elements which exist more than once in list2 will only be added to
list1 once, but duplicate elements in list1 will remain. Examples:

        union([2, 3, 4], [4, 5, 4, 6])
        => [2, 3, 4, 5, 6]

        union([2, 2, 4, 5], [4, 5, 6, 6, 7])
        => [2, 2, 4, 5, 6, 7])


listidx()
=========


        INTEGER listidx(LIST list, ANY what[, INTEGER origin])

This function returns the position in the list where what exists--starting
from origin--or a zero if it does not exist. If origin is not specified it
will default to 1. The origin represents where to start searching in the list.
If it is a positive number it starts that many elements into the list. If it
is a negative number it starts that many elements from the end of the list,
and searches backwards--from the end of the list to the start. Examples:

        listidx([4, "this", [], 'bar], [])
        => 3

        listidx([4, "this", [], "this", 'bar], "this", -1)
        => 4

        listidx([4, "this", [], "this", 'bar], "this", -3)
        => 2


String
======


crypt()             explode()           lowercase()
match_begin()       match_crypted()     match_pattern()
match_regexp()      match_template()    pad()
regexp()            split()             strcmp()
strfmt()            strgraft()          stridx()
strlen()            strsed()            strsub()
substr()            uppercase()


crypt()
=======


        STRING crypt(STRING str[, STRING salt])

This function performs one-way encryption on str, using the SHA encryption
routine. If salt is not specified, it is chosen randomly. The return value of
crypt() is the encrypted string.

The encryption performed by this function has the property that it is very
difficult to find a string which will produce a given result; however, a given
string and a given salt will always yield the same encrypted string. Example:

        crypt("foo", "ab")
        => "$2$ab$TmSIW.xT3sTkwqUhTLxCH192J37"

When matching an encrypted string versus a non-encrypted string, the function
match_crypted() should be used, as it will take into consideration any
possible future changes to the crypt() implementation.


explode()
=========


        LIST explode(STRING str[, STRING sep[, INTEGER want-blanks]])

This function breaks string into a list of strings, using the string sep as
the delimiter. If sep is unspecified it uses spaces as the delimiter. If
want-blanks is specified and is true explode() will include zero-length
strings in the final list, otherwise it will not. The function split() is
similar, but uses a regular expression as the delimiter. Examples:

        explode(" foo bar baz")
        => ["foo", "bar", "baz"]

        explode("foo:bar::baz", ":")
        => ["foo", "bar", "baz"]

        explode("foo:bar::baz", ":", 1)
        => ["foo", "bar", "", "baz"]


lowercase()
===========


        STRING lowercase(STRING str)

This function changes each character in str to it's lowercase value and
returns the result.


match_begin()
=============


        INTEGER match_begin(STRING str, STRING search[, STRING sep])

This function looks for the string search at the beginning of each word in
str. The word separator is given by the string sep if it is specified;
otherwise, a space (" ") is used. The return value of match_begin() is 1 if
search was found at the beginning of a word in string, or 0 if not. Examples:

        match_begin("foo:bar:baz", "fo", ":")
        => 1

        match_begin("foo bar baz", "ar")
        => 0


match_pattern()
===============


        LIST match_pattern(STRING string, STRING pattern)

This function matches the wildcard pattern pattern against string. A wildcard
pattern is a string with asterixes (`*') signifying wildcards. A regular
character matches itself, while a wildcard matches any number of arbitrary
characters. The return value of match_pattern() is a list of the substrings of
string which matched the wildcards in pattern, or 0 if the match fails. More
information on pattern matching can be found in the section Matching
Conventions. Examples:

        match_pattern("foobar", "*")
        => ["foobar"]

        match_pattern("foo quux bar quuux baz", "foo * bar * baz")
        => ["quux", "quuux"]

        match_pattern("narf:fnord", "narf:*")
        => ["fnord"]

        match_pattern("foo baz", "foo * bar")
        => 0


match_regexp()
==============


        LIST match_regexp(STRING str, STRING regexp[, INTEGER cs])

This function matches the regular expression argument regexp against the
argument str. If cs is specified and is true, the match is case-sensitive;
otherwise, it is case-insensitive. If the match succeeds, match_regexp()
returns a ten-element list giving the substitutions for the match (see below);
otherwise, match_regexp() returns 0. If the argument regexp is not a valid
regular expression, the error ~regexp is thrown.

This function is often used when all that is desired is whether a match was
made or not. The function regexp() is better for handling the full results of
a regexp match. For more information on ColdC Regular Expressions see the
section ColdC Regular Expressions.

The substitutions are the text in str which matches the parenthesized
subexpressions in regexp. The first substitution is the text in str which
matches the whole regexp. Thus, a regular expression can contain no more than
nine parenthesized subexpressions. Substitutions are returned as two-element
lists [start, len] giving the index of the matching text in str and the length
of the text.

Examples:

        match_regexp("fooBAR", "bar")
        => [[4, 3], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0],
        [0, 0], [0, 0]]

        match_regexp("Greg says, 'Hello.'", "^([^ ]+) says, '(.*)'$")
        => [[1, 19], [1, 4], [13, 6], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0],
        [0, 0], [0, 0]]

        match_regexp(" 300 100 200 ", "[0-9]+")
        => [[2, 3], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0],
        [0, 0], [0, 0]]

        match_regexp("foo", "bar")
        => 0

        match_regexp("Foo", "foo", 1)
        => 0


match_template()
================


        LIST match_template(STRING string, STRING template)

This function matches the template template against the command string. The
return value of match_template() is a list of fields resulting from the
template match, or 0 if the match fails or if template is an invalid template.

General information on matching can be found in the section Matching
Conventions. Templates are composed of word-patterns and wildcards.
Word-patterns may contain a mix of the partial-match operator and the or
operator.

A word-pattern is any sequence of characters bounded by spaces, or the
beginning or end of the string. The pattern may include a question mark ('?'),
which is the partial-match operator; or it may include any number of pipe
characters ('|'), which is the or operator. The result from a word-pattern
match is the string which matched the word-pattern.

The partial-match operator is used to indicate that partial matches that
extend at least as far as the question mark are ok. For instance, the
word-pattern "ex?am" matches any of the words "ex", "exa" and "exam".

The or operator is used to group more than one word where any of the words in
the group can be matched as one word. For instance, the template
"this|that|there" would match "this" OR "that" OR "there".

Wildcards can be either simple or coupled. A simple wildcard is represented by
an asterix ('*'). A simple wildcard matches any number of words in string, and
must be bounded by spaces or the beginning or end of the template. If the
wildcard is followed in the template by a word-pattern, then it can also match
a quoted wildcard match.

A quoted wildcard match is just like a ColdC string literal: it begins and
ends with a double quote ('"'), and can include a literal double quote or
backslash by preceding the character with a backslash ('\'). If the simple
wildcard is followed by a word-pattern, and the words in string that the
wildcard would match begin with a double quote, then the match must be a
quoted wildcard match or the match fails, even if the match would have
succeeded if the words were not treated as a quoted wildcard match. However,
if the words that the wildcard would match begin with a backslash followed by
a double quote, then the backslash is ignored and the double quote and the
text following it are treated as regular words.

The following template using a simple wildcard "* bar" matches any of the
following strings:

        foo bar
        foo baz bar
        "foo bar " baz" bar
        "foo baz bar

Matching against a simple wildcard produces one result per wildcard--the words
that the simple wildcard matched. If the wildcard matches a quoted wildcard
match, then the beginning and ending double quotes are stripped out of the
result, as well as any backslashes used to escape characters inside the double
quotes.

A coupled wildcard is represented by the three-character sequence '*=*'. It
matches any sequence of words containing an equal sign ('='), and results in
two strings, the text before the equal sign and the text after it. Any spaces
surrounding the equal sign in the matched string are ignored and do not show
up in the results. The text before the equal sign can be a quoted wildcard
match (as before, if it begins with a double quote, then it must be a quoted
wildcard match or the match fails, unless the initial double quote is escaped
by a backslash). If the coupled wildcard is followed by a word pattern, then
the text after the equal sign can also be a quoted wildcard match. The coupled
wildcard is a special feature intended for parsing TinyMUD command formats.

 Examples:

        match_template("@descr me as foobar", "@desc?ribe * as *")
        => ["@descr", "me", "as", "foobar"]

        match_template("@desc \"as is\" as foobar", "@desc?ribe * as *")
        => ["@desc", "as is", "as", "foobar"]

        match_template("@desc \"as\" is as foobar", "@desc?ribe * as *")
        => 0

        match_template("@desc \"as" is as foobar", "@desc?ribe * as *")
        => ["@desc", "\"as\" is", "as", "foobar"]

        match_template("@descr me =foobar", "@desc?ribe *=*")
        => ["@descr", "me", "foobar"]

        match_template("@desc "2+2=4"= an equation", "@desc?ribe *=*")
        => ["@desc", "2+2=4", "an equation"]

        match_template("look at rose", "l?ook|ex?amine *")
        => ["look", "at rose"]


pad()
=====


        STRING pad(STRING str, INTEGER length[, STRING filler])

This function pads or truncates the argument string to the length given with
the argument length. If the argument filler is specified, then it is used to
pad the string, otherwise a space is used. If length is greater than the
length of string, then pad adds filler characters on the right. If the length
is a negative amount, filler will be added on the left instead. The function
strfmt() may also be used for string padding. Examples:

        pad("foo", 6)
        => "foo "

        pad("foobar", 3)
        => "foo"

        pad(tostr(29), -4, "0")
        => "0029"

        pad("what", 20, "!?!")
        => "what!?!!?!!?!!?!!?!!"


regexp()
========


        LIST regexp(STRING str, STRING regexp[, INTEGER cs])

This function matches the regular expression argument regexp against the
argument str. If cs is specified and is true, the match is case-sensitive;
otherwise, it is case-insensitive. If the match succeeds, regexp() returns a
list of the matches in string, or zero if it did not match. If regexp is not a
valid regular expression the error ~regexp is thrown.

For more information on Regular Expressions see the section ColdC Regular
Expressions. The function match_regexp() is similar, and better when all that
is desired is whether the regexp matches or not. Examples:

        regexp("fooBAR", "bar")
        => ["BAR"]

        regexp("Greg says, 'Hello.'", "^([^ ]+) says, '(.*)'$")
        => ["Greg", "Hello."]

        regexp(" 300 100 200 ", "[0-9]+")
        => ["300"]

        regexp("bar", "foo")
        => 0

        regexp("Foo", "foo", 1)
        => 0


strcmp()
========


        INTEGER strcmp(STRING str1, STRING str2)

This function compares str1 against str2 and returns zero if they are equal,
greater than zero if string1 is lexically greater than string2, and less than
zero if string1 is lexically less than string2. The comparison performed by
strcmp() is case-sensitive. Examples:

        strcmp("Foo", "bar")
        => -28

        strcmp("cashmir", "cashmiR")
        => 32

        strcmp("foo", "foo")
        => 0


strfmt()
========


        STRING strfmt(STRING format, ANY arg, ...)

This function formats its arguments and returns the result. How the arguments
are formatted depends upon the argument format. The format contains two types
of sequences: plain characters, which are simply copied to the new string, and
format specifications, each of which causes printing of the next successive
argument. The format begins with a percent character (%), followed by:

  Pad Length
    The pad length is an integer which specifies the length of characters to
    pad the argument in. Pad Length is optional. Specifying a zero pad length
    will be ignored, and is equivalent to not specifying a pad length.
  Precision
    A period (.), followed by an integer specifies the precision, which
    specifies the number of digits to appear after the decimal point when
    printing FLOAT arguments. Precision is optional, and does not have to be
    specified. If it is specified it must come after the Pad Length (if
    specified), and before the Filler (if specified) or Format Type.
  Filler
    Filler specifies what is used when padding a string within the Pad
    Length. Filler is specified within curly braces ({ and }). To include a
    curly brace in the filler prefix it with a backslash. The Filler must
    come after Pad Length or Precision, if they are specified, and before
    Format Type.
  Format Type
    Format type must be specified last, and is not optional. Format Type
    specifies how the argument is to be handled. It is one of the following
    characters:

      d or D
        literal data
      s or S or l or L
        any data, align left
      r or R
        any data, align right
      c or C
        any data, align centered
      e
        any data, align left with an ellipsis

    If the Format Type is anything but d or D, the data will be converted as
    if it were "added" to a string using the arithmetic operator. If an
    uppercase character is used in the Format Type, any argument which has a
    length longer than the Pad Length will be truncated accordingly.
    Otherwise the argument will not be truncated. If an ellipsis is used, the
    argument will always be truncated three characters shorter than the Pad
    Length, with "..." being placed at the end.

Examples:

        strfmt("%r", "test")
        => "test"

        strfmt("%l", "test")
        => "test"

        strfmt("%c", "test")
        => "test"

        strfmt("%d", "test")
        => ""test""

        strfmt("%10r", "test")
        => " test"

        strfmt("%10l", "test")
        => "test "

        strfmt("%10c", "test")
        => " test "

        strfmt("%10{|>}r", "test")
        => "|>|>|>test"

        strfmt("%10{|>}l", "test")
        => "test|>|>|>"

        strfmt("%10{|>}c", "test")
        => "|>|test|>|"

        strfmt("%.2l", 1.1214)
        => "1.12"

        strfmt("%10.3{0}r", 1.1214)
        => "000001.121"

        strfmt("%10.3{0}r", 1.1214)
        => "1.12100000"

        strfmt("%5e", "testing")
        => "te..."

        strfmt("%s parents: %25e", "$user", [$body, $interaction, $mail_ui]);
        => "$user parents: [$body, $interaction, ..."


strgraft()
==========


        STRING strgraft(STRING str, INTEGER pos, STRING str2)

This function grafts a string into another string. It will take the string
specified by str2 and insert it into str, starting at the position specified
by pos. Example:

        strgraft("this string", 6, "is a ")
        => "this is a string"


strlen()
========


        INTEGER strlen(STRING string)

This function returns the length of string.


strsed()
========


        STR strsed(STR rx, STR str, STR replace[, STR flags[, INT count]])

This functions similar sed in many unix systems. It searches for any
occurrences of regexp in string and replaces them with replace, returning the
result. The optional fourth argument is used to specify flags for sed. Flags
are specified as a string containing any of the following alphabetic
characters:

    g  Match the regular expression globally throughout the string
    s* Single match--Match the first occurrence only (default)
    c  Case matters when matching
    i* Case doesn't matter when matching (default)

Flags followed by an asterisk (*) represent default behaviour if no flags are
specified. For more information, see the section on Regular Expressions.

Examples:

        strsed("foObar", "o+", "X")
        => "fXbar"

        strsed("foObar", "o+", "X", "c")
        => "fXObar"

The string ranges matched by the regular expression n the first string may be
re-inserted into the resulting string by using '%n' tokens, where n represents
the branch, from one to nine. This currently only works with branched regular
expressions. Future revisions will expand upon this functionality.

Example:

        strsed("foObar", "(o+)", "<%1>")
        => "fXbar"

        strsed("foObar", "(o+)", "<%1>", "c")
        => "fXObar"


The fifth argument count is intended to optimize the use of this function, and
is generally not used. It is simply an optimizing guideline which specifies
how many expected occurrences of the regular expression are expected in the
string. This value is used when computing the initial size of the resulting
string, to lower the amount of memory allocations which may have to be
performed.


strsub()
========


        STRING strsub(STRING str, STRING what, STRING replace[, STRING flags])

This function searches for occurrences of the string what within the string
str and replaces them with replace. By default it will replace any occurrence,
and will do case-insensitive comparisons. The optional fourth argument can be
any of the following characters within the string:

    g  Match globally throughout the string (default)
    s  Single match--Match the first occurrence only
    c  Case matters when matching
    i  Case doesn't matter when matching (default)

Examples:

        strsub("fooBar", "bar", "baz")
        => "foobaz"

        strsub("fooBar", "bar", "baz", "c")
        => "fooBar"


substr()
========


        STRING substr(STRING str, INTEGER start[, INTEGER length])

This function returns a subrange of string. The subrange starts at the
character specified by start and continues length characters. If length is
unspecified it continues to the end of the string. If start is outside of the
range of the string, or length will extend past the end of the string, the
error ~range is thrown. Examples:

        substr("foobar", 2, 3)
        => "oob"

        substr("foobar", 3)
        => "obar"

        substr("foobar", 7)
        => ""


uppercase()
===========


        STRING uppercase(STRING str)

This function changes each character in str to it's uppercase value and
returns the result.


match_crypted()
===============


        LIST match_crypted(STRING crypted, STRING matchwith)

This function is used to match strings encrypted with the crypt() function.
This function should be used instead of directly comparing the result, as it
will take into account possible older encryption methods. It returns one if
there is a correct match, or zero if there is not. Example:

        match_crypted("$SHA1$dEqOGo3d$.lpP/K19QevbwpgSiCsGVnCnrv2", "foo")
        => 1


split()
=======


        LIST split(STRING str, STRING regexp[, INTEGER regexp-args])

This function breaks string into a list of strings, using the second argument
regexp (a regular expression) as a delimiter. The third argument is optional,
and is a string containing character flags which can change the behaviour of
split(). Flags can be any:

    b  Keep blank entries (default is to ignore)
    c  Case sensitive match
    i  Case insensitive match (default)

Examples:

        split(" foo bar baz", " +")
        => ["foo", "bar", "baz"]

        split("foo:bar::baz", ":", "b")
        => ["foo", "bar", "", "baz"]

        split("fobibobIbidilly", "i")
        => ["fob", "bob", "b", "d", "lly"]

        split("fobIbobibidIlly", "i", "cb")
        => ["fobIbob", "b", "dIlly"]


stridx()
========


        INTEGER stridx(BUFFER str, STRING what[, INTEGER origin])

This function returns the position in str where what exists--starting from
origin--or a zero if it does not exist. If origin is not specified it will
default to 1. The origin represents where to start searching in the string. If
it is a positive number it starts that many elements into the string. If it is
a negative number it starts that many elements from the end of the string, and
searches backwards--from the end of the string to the start. Examples:

        stridx("this test ok", "e")
        => 7

        stridx("this test ok", "t", -1)
        => 9

        stridx("this test ok", "t", -5)
        => 6

        stridx("this test ok", "alf")
        => 0


Numeric
=======


abs()       acos()      asin()      atan()      atan2()     cos()
exp()       log()       Math        max()       min()       pow()
random()    sin()       sqrt()      tan()


abs()
=====


        INTEGER|FLOAT abs(INTEGER|FLOAT number)

This function returns the absolute value of number, where number can be either
a float or an integer (and the same type of value is returned). Examples:

        abs(-6)
        => 6

        abs(7)
        => 7

        abs(-000.12)
        => 0.120000


Math|sin()|exp()|log()|cos()|tan()|sqrt()|asin()|acos()|atan()|pow()|atan2()
============================================================================


        FLOAT sin(FLOAT x)
        FLOAT exp(FLOAT x)
        FLOAT log(FLOAT x)
        FLOAT cos(FLOAT x)
        FLOAT tan(FLOAT x)
        FLOAT sqrt(FLOAT x)
        FLOAT asin(FLOAT x)
        FLOAT acos(FLOAT x)
        FLOAT atan(FLOAT x)
        FLOAT pow(FLOAT x, FLOAT y)
        FLOAT atan2(FLOAT x, FLOAT y)

These functions perform the relevant mathematic function on the argument(s)
and returns the result. Further information on each function can be found in
the unix man page on the same relative function, in C. The precision of the
function may vary by the implementation. If a floating point exception occurs,
the error ~fpe is thrown.


max()
=====


        ANY max(ANY arg, ...)

This function returns the maximum of its arguments. All of the arguments must
be of the same type, and must be integers, floats, or strings.

        max(3, 7, 9, 5)
        => 9

        max("Foo", "aardvark", "bar", "Quux")
        => "Quux"


min()
=====


        ANY min(ANY arg, ...)

This function returns the minimum of its arguments. All of the arguments must
be of the same type, and must be integers, floats, or strings.

        min(3, 7, 9, 5)
        => 3

        min("Foo", "aardvark", "bar", "Quux")
        => "aardvark"


random()
========


        INTEGER random(INTEGER max)

This function returns a random integer between one and max. Example:

        random(10)
        => 3


Native Method Reference
=======================

This node isn't written yet


Reference Library
=================


Nodes from this point down are for core subsystem documentation and
documentation on specific objects.

        Subsystem              Subsystems Index
        Object                 Core Objects Index


Updates
=======


  24-Jan-2002
    Theme


Administration
==============


Unfortunately, this document is still in development. For now, see:

         

In addition, the following documents are also defined:

        Traceback Recording    How tracebacks from core objects are handled


Admin Commands
==============

Administrative Commands Listing

The following commands are available for administrators:

    @adjust               Promotes a user to builder, programmer, or admin.
    @core                 Makes the object a core object.
    @kick                 "Kicks" a user off the server.
    @new-password         Makes a new password for a user.
    @quota                Changes a users quota.
    @rehash-all           Updates ALL command caches in memory.
    @task?s               Shows Database and Driver tasks (processes).
    @backup               Starts the database backup process.
    @kill                 Kills a task.
    @mojo                 Turns on or off mojo. (full system privileges)
    @reap                 Used to show players who have not logged on for a
                          specified amount of time. (default 3 months)
    @shutdown             Shutsdown the game. Can be time delayed.



Traceback Recording
===================


Tracebacks are recorded when they arise from certain actions, including all
tracebacks caused by a command, and all tracebacks during creation and
destruction of an object. The traceback is stored along with relevant
information on the administrator-only mail list *tracebacks (limited to
administrators because it may contain privileged information, such as commands
typed by users).

To receive notification of the tracebacks as they occur, make sure to
subscribe to the *tracebacks mailing list.

Whether a user see's tracebacks or not depends upon what their user class is,
in relation to the system setting:

        $sys:traceback-for

Which is a user class specifying what classes will see real tracebacks. If the
user is not a descendant of this class, they will instead receive a polite
message about the error.


Credit
======


ColdCore is authored by many people. Although most if not all of the core has
been rewritten from its origins in Cold World, the following is a list of
primary contributors from the beginning--in alphabetical order:

          * Jeff Bellgarde
          * Robert de Forest
          * Brandon Gillespie
          * Greg Hudson
          * Wyatt Miler
          * Bruce Mitchener
          * Brad Roberts
          * Miroslav Silovic
          * Alex Stewart

In addition, the following people may have--in some way or another--also
helped with ColdCore:

        Jon Lambert, Brian Buchanan, Ken Brush, Ted Kanzinsky, Jeff
        Kesselman, Dancer, Jordan Baker, Colin McCormack.

Because Copyrights must be held by a legal entity, the COPYRIGHT for ColdCore
is held by Brandon Gillespie.


COPYRIGHT
=========


ColdCore is authored by many people, and is Copyright 1994-2002 by Brandon
Gillespie, unless otherwise stated on a specific method or object.

The following terms apply to all objects associated with ColdCore unless
explicitly disclaimed.

The authors hereby grant permission to use, copy, modify, distribute, and
license this software and its documentation for any purpose, provided that
existing copyright notices are retained in all copies and that this notice is
included verbatim in any distributions. Notices must be displayed or provided
as appropriate, to avoid mis-representation when alterations and personal
enhancements are made to the core. No written agreement, license, or royalty
fee is required for any of the authorized uses. Modifications to this software
may be copyrighted by their authors and need not follow the licensing terms
described here, provided that the new terms are clearly indicated on each
object or method where they apply.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN
IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS
IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
Core Help Root
==============

This node isn't written yet


Commands
========

This node is simply a place holder, and should not be linked in through an
index or anything. If you see it, something has gone wrong.


say
===


The interaction command say is used to speak and talk to others. For
convenience, the double-quote character may also be used as a shortcut.
Examples:

        > say Hi
        Brandon says, "Hi"

        > "whats up?
        Brandon says, "whats up?"


emote
=====


The interaction command emote is used for free-form actions. For convenience,
the colon character may also be used as a shortcut. Examples:

        > emote waves to everybody
        Brandon waves to everybody

        > :jumps up and down
        Brandon jumps up and down

You can get rid of the space after your name, by doubling up the colon:

        > ::'s head hurts
        Brandon's head hurts


to say
======


Syntax: to  say 

The interaction command to is used to speak and talk to a specific person
(). For convenience, the single-quote character may be used as a
shortcut. Examples:

        > to Miro say Hi
        Brandon (to Miro) says, "Hi"

        > 'Miro whats up?
        Brandon (to Miro) says, "whats up?"

As with any directed interaction command, you can double up the shortcut
character to send to the last person you directed to. Example:

        > 'Miro say Hi
        Brandon (to Miro) says, "Hi"
        > ''how is the weather?
        Brandon (to Miro) asks, "How is the weather?"


whisper
=======


Syntax: whisper  to 

The interaction command whisper is used to speak and talk privately to a
specific person (). Example:

        > whisper the Red Man is in Tibet to Brian
        You whisper, "the Red Man is in Tibet" to Brian


@page
=====


Syntax: @page [,..] with 

The non-VR interaction command @page is used to interact with one or more
people not in the room. For convenience, the dash character may also be used
as a shortcut. Examples:

        > @page Amy with dinner tonight?
        [to Amy] Brandon says, "dinner tonight?"

        > -Miro Hi
        [to Miro] Brandon says, "Hi"

The people receiving the message see your location inside the square brackets,
instead of who it is being directed to, such as [from The Pit] instead of [to
Amy]. The default style of interaction is speach (similar to say), you can
also emote in page, by beginning your message with a colon:

        > @page Brian with :waves
        [to Brian] Brandon waves

As with any directed interaction command, you can double up the shortcut
character to send to the last person you directed to. Example:

        > -Brian :waves
        [to Brian] Brandon waves
        > --how goes it?
        [to Brian] Brandon says, "how goes it?"


think
=====


The interaction command think is used to think something out loud. For
convenience, the percent character may also be used as a shortcut. Examples:

        > think oops
        Brandon . o O ( oops )

        > %I think everybody can see my thoughts
        Brandon . o O ( I think everybody can see my thoughts )


spoof
=====


The interaction command spoof is used similar to emote, except your name does
not start the line. This is usually used to format your actions in a different
way, but can be used to 'spoof' actions from other players--which can be
considered rude (be careful when using it so as to not offend anybody). If
your name does not appear as a word in the line, it will be appended for
attribution. For convenience, the exclaimation point may also be used as a
shortcut. Examples:

        > spoof Miro slips and falls.
        Miro slips and falls. -- Brandon

        > !The big beast pounces on Brandon, pummelling him silly
        The big beast pounces on Brandon, pummelling him silly


@paste|@paste-to
================


Syntax: @paste [to ]

The non-VR interaction command @paste is used to display blocks of text either
to the room or to a specific person (). If no target is specified, it
is displayed to the room. You will be prompted for the text. When you are
finished typing in the text, type a period at the beginning of a line,
followed by no other characters. Example:

        > @paste
        Receiving input. Enter "." to finish or "@abort" to abort.
        > USER     PID   %CPU %MEM   VSZ  RSS  COMMAND
        > brandon  10267  0.0 19.4  5800 5928  ./genesis
        > .
        -------------- Brandon (@paste's) ---------------
        USER     PID   %CPU %MEM   VSZ  RSS  COMMAND
        brandon  10267  0.0 19.4  5800 5928  ./genesis
        ------------------- + Finis + -------------------
        2 lines of text pasted


Unnamed Interaction Shortcuts
=============================


In addition to the standard interaction commands there are also a few which do
not have names:

    |      This is used to display one line of information, such as:

                   > |test
                   Brandon | test

    ,,     This is like say, but it lets you put your own text before what
           you say, such as:

                   > ,nods, That is correct
                   Brandon nods, "That is correct"




@display
========


PROGRAMMER COMMAND

        Syntax: @d?isplay  [options]

Shows general information about an object, including it's size, owner,
parents, location, and what permissions it has. You can optionally have it
list all the public methods you have defined on an object, or all the
variables, and which object defines them as below.

Example:
        >@display $vampire
        Object:   $vampire (Vampire)
        Created:  Mon Jan 13 18:19:17 1997
        Quota:    75000 bytes
        Perms:
        Size:     6,132 bytes (on disk)
        Manager:  $vampire (Vampire)
        Writers:  (none)
        Parents:  $admin (Generic Admin) and $antisocial
        Location: $the_pit (The Pit)
        ---

        >@display $vampire,
        Object Variables matching "*"
          ,test_dict: #[]
          ,test: 0


        >@display $vampire.
        Public Methods matching "*":
         ----   34 .edit_cmd(cmdstr, com, args)
         ----   14 .quit_editor()
         ----   49 .pulse()
         ----   24 .startup()
         ----    8 .dict_test(cmdstr, cmd, @str)
         ----   51 .tmp_pulse()

 Options can be:

    +c?hop        Chops lines longer than the players cols setting.
    +g?enerations Sets which object to go back from.



@program
========


PROGRAMMER COMMAND

        Syntax @program . [options] [with ]

Sets the code for  on .

 Options can be:

    +warnings             Do not warn about recursion.
    +edited[=message]     Set or override the edited comment. (admin only).
    +access=permission    Set the method access to one of public, protected,
                          private, root or driver.
    +flags=flags          Set the flags to some of nooverride, locked, fork
                          or native.

Optionally, 'with' preposition causes it to read the code from the command
line instead of prompting the user for it.


@set
====


Syntax: @set [options] [:][[=]]

This command is used to display and change configurable settings on objects.
If  is left unspecified it will default to you. To view all settings
on an object do not specify a setting name or value, such as either of the
following two:

        @set
        @set here:

The first example will show all settings on you. The second example will show
all settings on here. To change a setting include the setting name after the
target followed by an equals sign and a value, such as:

        @set here:realm=Taobh Thiar

If the option +definer is given, it will list all of the definers for each
setting instance. If a value for definer is given it will only list instances
of the settings defined by the given objref, such as:

        @set +definer=$place here:

Which will only show the settings defined on here and defined by place.

If the option +clear is given, it will ignore any value specified for the
setting and will instead clear the value, reverting it to its original default.


@adjust
=======


ADMIN COMMAND

        Syntax: @adjust|@promote  to 

Used to change a user's class from/to any of the following:
  * user
  * builder
  * programmer
  * admin
Example:

        @promote Bob to a programmer

If the user was originally a guest it will create a password and email it to
the user. It uses the email address they specified upon guest connect.


@mojo
=====


ADMIN COMMAND

        Syntax: @mojo on|off

Used by an administrator to enable full system privileges.


@new-password|@newpwd
=====================


ADMIN COMMAND

        Syntax: @new-password|@newpw?d 

Used to generate a new random password for the specified user. The password is
printed to the admin running the command, and is emailed to the user. Example:

        @newpw Billy Bob


@rehash-all
===========


ADMIN COMMAND

        Syntax: @rehash-all [-purge]

Commands are cached for fast lookup. Because of this if a command is added to
an object other than your object (such as $user), the global cache needs to be
updated. This command will clear all caches and update them as needed.
If the +purge option is specified it will purge ALL caches in the database
before rehashing. This does not happen by default.


@backup
=======


ADMIN COMMAND

        Syntax: @backup

Start an asynchronous backup of the binary database.


@shutdown
=========


ADMIN COMMAND

        Syntax: @shutdown [-t?ime=xx] [reason]

Shutdown the server, the time defaults to five minutes, if left unspecified.
The time specified is in minutes, so -time=10 would be ten minutes, not ten
seconds. Example:

        @shutdown -t=0 Upgrading Driver, Should be back online soon

Would shutdown immediately (zero minutes).


@tasks
======


ADMIN COMMAND

        Syntax: @task?s [task [task [...]]]

Briefly list all Database and Driver tasks, or list full details on the
specified tasks (as with @kill) system tasks are directly specified by
prefixing them with an asterisk). Examples:

        @tasks

        @tasks *10204

Note: does not show currently executing task.


@kill
=====


ADMIN COMMAND

        Syntax: @del-t?ask|@kill [task [task [...]]]

Kill the specified task. System tasks are directly specified by prefixing them
with an asterisk. In general you should kill the related database task and let
it kill the system task (if applicable).

        @kill *10204
        @kill 12 *1241


@add-command|@ac
================


PROGRAMMER COMMAND

        Syntax: @add-c?ommand|@ac "" [to|for] 

Used to add a command. The method called if the command matches must be
specified. The command template must be an Enhanced Command Template.
Arguments send to the method are always ordered the same, the first argument
is always the command string, followed by subsequent arguments relative to how
the command template would match using template matching (see Matching
Conventions).
For instance, the following enhanced command template:

        "@get  from "

Would evaluate to the following standard template:

        "@get * from *"

From this point, you can simply evaluate the template matching to see how its
results would be ordered:

        ;match_template("@get something from nothing", "@get * from *")
        => ["@get", "something", "from", "nothing"]

Based off these results the arg definition for your method could be:

        arg cmdstr, cmd, arg1, prep, arg2;

When a command is added it will not immediately begin working. Command caches
must be updated first. There are three different situations that will arise
when adding a command:

  Adding a local command to yourself

    This situation is the simplest to update. If you have added a command to
    yourself simply type @rehash, and your local caches will be updated.

  Adding a remote command to an object

    When adding a remote command to something you can rehash the remote
    caches by simply dropping the item and picking it back up.

  Adding a local command to another object

    If you are adding a local command to an object other than yourself, you
    will have to rehash the entire system's caches. This is done with the
    command @rehash-all, which is an administrative command.


@reap
=====


ADMIN COMMAND

        Syntax: @reap [options] []

Used in reaping users. Can have various possible behaviours. If only a user is
given (no options), @reap will enter an interactive user reaping system. At
any time during the reaping process you can use @abort to cancel any further
actions.

If no user is given, it will list all reap possibilities, where possibilities
are considered after the user has not logged in for three months. This time
can be changed with the time option, which is given as an english explanation
of the time, such as:

        > @reap +time="1 month"

In the listing the column E will have an exclamation point if the user's email
address is invalid. The column MNG represents how many objects the user
manages (always at least one). The column Notified shows if and when the last
reap notification was mailed, using the mail option. The columns Last On and
Age represent when the user was last connected, and how long it has been since
they were created.

If the mail option is given, instead of reaping it will send a message to the
user's email address, notifying them of the imminent reaping. The time option
can also be used to change the grace period, such as:

        > @reap Bob +mail +time="5 days"

A user is automatically removed from reapable status when they connect. The
grace period is enforcable only by the administrations. This command does not
make any assumptions, and an administrator will have to followup with a full
reaping at the end of the grace period.


@core
=====


ADMIN COMMAND

        Syntax: @core 

Setup the specified object as a core object. This is used primarily for core
development. It adds the 'core flag to the object, sets the object as its own
manager and writer and removes any additional ownership.


@del-command|@dc
================


PROGRAMMER COMMAND

        Syntax: @del-c?command|@dc "" [from] 

Reverses the effects of @add-command. The command template must be identical
to the one with which the command was added. The rehashing issues discussed in
@add-command apply here (in other words, you may have to do a few tricks to
update command caches).


@descendants
============


        Syntax: `@descend  [options]`

Options can be:

    +N            Descend N levels (zero or more)
    +a?ll         Descend all levels
    +o?nly        Only show objects with the specified flags
    +n?ot         Only show objects that do not have the specified flags
    +r?edundant   Redundantly show objects in the hierarchy



@describe
=========


        Syntax: @desc?ribe|@prose  [as ]

Sets the description (prose) for an object. If nothing other than the target
object is given on the command line, you will be prompted for the description.
Otherwise it will take anything after the preposition 'as' as the description.

The description is not written in plaintext, but is in CML. Because of this,
all plaintext formatting you include will be disregarded. Use CML tags for any
desired formatting.

Note: This will overwrite the current description. To edit the description on
the object, use the @edit command.


@new
====


        Syntax: @new  [named ]

Creates a new VR object with the given parent, and optionally set the name.
This command is preferred when working with VR objects, as it will correctly
handle both real and Frob instances. The alternative is @spawn which will
always create new objects. If you want to create a new non-VR object, use
@spawn or call the parent's .new() method.
See also: @destroy


wear|shed|remove
================


Syntax: wear 
OR shed|remove
Wear or remove an article of clothing. You must be holding (or wearing, as applicable) the article of clothing. The clothing must also be a $wearable_frob. You can create clothing with the @new cmd. For example: @new $wearable_frob named Trenchcoat wear trenchcoat shed trenchcoat @spawn ====== Syntax: @spawn [named ] Create a new object with the given parent, and optionally set the name. This command is generally used only by programmers, as it always creates a real object and does not create a frob instance, and it will create any type of object, not just a VR object. In general the command @new is used instead. @nh|@new-help-node ================== Syntax: `@nh [] [options]` The argument node is the parent node to descend from, or if unspecified it will default to the current node. Options can be: +i?ndex=index +o?bjname=objname +n?ame="name of node" A separate entry is made in the index for each branch in the name (separated by the | character). @rename ======= Syntax: `@rename [to] ""` Used to change the target object's name or object name. Quotes may be used, but are not required. Name templates may also be specified with the new name, by separating them from the name with commas, such as: @rename exit to Gilded Door, w?est, o?ut Keep in mind that the name is matched using the beginning of each word, where the templates are mached with Template Matching. Name templates can also be changed with the commands @add-name-template and @del-name-template. The object name can also be changed, by specifying a valid object name as the new name, such as: @rename $thing_152 to $my_lamp @ant|@add-name-template ======================= Syntax: `@ant|@add-name-template