TinTin++ Mud Client Manual

         There are several different types of lists in tintin which behave in a
         fairly universal manner. To properly explain lists it's easiest to
         explain the most basic variable type first before discussing more
         complex types.

       - Basic variable: The standard key = value variable.

       - Simple list: A string that contains semicolon delimited fields.
         {a;b;c}. Can be saved as a variable.

       - Brace list: A string in which fields are delimited with braces.
         {a}{b}{c}. Brace lists cannot be stored as a variable because tables
         use braces as well, they must be stored as a simple list instead.

       - Table: Think of this as variables nested within another variable. Or
          as variables contained within another variable.

       - List: A table that uses integers for its indexes. Also known as an
         array. The #list command is a utility command for using tables as

         Simple Variables

         #variable {simple} {Hello World!}
         #show $simple

         To see if the 'simple' variable exists you can use &{simple} which
         will display 0 if the variable does not exist, or the variable's index
         if it exists.

         If you have multiple variables they are sorted alphabetically and
         numerically. While it's not all that relevant for simple variables,
         the first variable has index 1, the second variable index 2, and so

         Variable names need to start with a letter and only exist of letters,
         numbers, and underscores. If you need to use a non standard variable
         name this is possible using braces.

Example: #variable {:)} {Happy Happy!};#show ${:)}

         Variables can be accessed using their index. While primarily useful
         for tables it is possible to do this for simple variables. Use +1 for
         the first variable, +2 for the second variable, etc. Use -1 for the
         last variable, -2 for the second last variable, etc.

Example: #show The first variable is: *{+1} with value: ${+1}

         Removing Variables

         To remove a variable, use #unvariable or #unvar (every command can be
         abbreviated). It's possible to remove multiple variables at once
         using #unvar {var 1} {var 2} {etc}

         Variables are unique to each session, so if you have multiple
         sessions, removing a variable from one session won't remove it from
         other sessions.

         If you remove a table variable, all variables contained within that
         table variable are removed as well.

         Simple Lists

         A simple list is a string that contains semicolon delimited fields.
         Commands can be entered as simple lists, for example:
         #show {a};#show {b} will execute a single line as two commands.

         Several commands take a simple list as their input, these are:
         #foreach, #line substitute, #path load, #list create, and #highlight.

         Brace Lists

         A brace list is a string in which fields are delimited with braces.
         Most commands take a brace list for their arguments, for example:
         #session {x} {mud.com} {1234} {mud.tin}. The session command takes
         4 arguments, the 4th argument (command file) is optional.

         Commands that take a simple list as their input will also accept a
         brace list, keep in mind you'll have to embed the brace list in an
         extra set of braces, for example: #path load {{n}{s}{w}{w}}, which is
         identical to: #path load {n;s;w;w}.

         Brace lists cannot be stored as variables because TinTin++ will
         confuse them with tables. You can convert a brace list to a table
         variable using: #list {bracelist} {create} {{a}{b}{c}} this will look
         internally as: {{1}{a}{2}{b}{3}{c}}. You can then convert this table
         back to a simple list using: #list {bracelist} {simplify} which will
         change it to {a;b;c}.

         Braces cannot easily be escaped in TinTin++. Using \{ or \} will not
         work. The reason for this is due to several factors, but primarily
         backward compatibility. To escape braces you must define them using
         hexadecimal notation using \x7B and \x7D. See #help escape for a list
         of escape options, and the help file will also remind you of how to
         escape braces.


         Tables are key/value pairs stored within a variable. Tables are also
         known as associative arrays, dictionaries, maps, nested variables,
         structures, and probably a couple of other names. There are several
         ways to create and access tables.

Example: #variable {friendlist} {{bob}{bob@mail.com} {bubba}{sunset@gmail.com}}

         This will create a friendlist with two entries, the key is the name of
         the friend, the value is the email address of the friend. You can see
         the email address of bob using: #show {$friendlist[bob]}. You can
         also define this table as following:

         #variable {friendlist[bob]} {bob@mail.com}
         #variable {friendlist[bubba]} {sunset@gmail.com}

         This would create the exact same table as the single line declaration
         used previously. To see the first key in the table use:
         *friendlist[+1], to see the first value in the table use:
         $friendlist[+1]. To see the size of the table use &friendlist[]. To
         print a bracelist of all friends use *friendlist[], to print a
         bracelist of all friends whose name starts with the letter 'a' you
         would use: *friendlist[a%*]. Similarly to see the number of friends
         you have whose name ends with the letter 'b' you would use:

         See #help regexp for a brief overview of regular expression options.
         While TinTin++ supports PCRE (perl-compatible regular expressions), it
         embeds them within its own regular expression syntax that is simpler
         and less invasive, while still allowing the full power of PCRE for
         those who need it.

Example: #unvariable {friendlist[bubba]}

         This would remove {bubba} from the friendlist. To remove the entire
         friendlist you would use: #unvariable {friendlist}.

Example: #variable {friendlist} {{bob} {{email}{bob@ma.il} {phone}{123456789}}}

         There is no limit to the number of nests, simply add more braces. To
         see Bob's email in this example you would use:
         #show {$friendlist[bob][email]}.

         To merge two tables the #cat command can be used.
         #variable {bli} {{a}{1}{b}{2}}
         #variable {blo} {{c}{3}{d}{4}}
         #cat {blo} {$bli}


         Tables are sorted alphabetically with the exception of numbers which
         are sorted numerically. If you want to determine the sorting order
         yourself you can use use the #list command which helps you to use
         tables as arrays.

Example: #action {%1 chats %2} {#list chats add {%0}}

         Each time a chat is received it's added to the end of the 'chats' list
         variable. If you type #variable chats this might look like:

         #VARIABLE {chats}
                 {1} {Bubba chats Hi}
                 {2} {Bob chats Hi bub}
                 {3} {Bubba chats Bye}
                 {4} {Bob chats bub bye}


         There are various ways to parse lists and tables, using either #loop,
         #foreach, #while, or #<number>.

         #loop takes two numeric arguments, incrementing or decrementing the
         first number until it matches the second number. The value of the loop
         counter is stored in the provided variable.

         #foreach takes either a simple list or a brace list as its first
         argument. Foreach will go through each item in the list and store the
         value in the provided variable.

         #while will perform an if check on the first argument, if the result
         is true it will execute the commands in the second argument. Then it
         performs an if check on the first argument again. It will continue to
         repeat until the if check returns 0 or the loop is interrupted with a
         control flow command. It takes special care to avoid infinite loops.

         #<number> will execute the provided argument 'number' times. For
         example: #4 {#show beep! \a}

         Here are some examples.

Example: #list friends create {bob;bubba;zorro}

         Internally this looks like {{1}{bob}{2}{bubba}{3}{zorro}} and the
         list can be parsed in various ways.

Example: #foreach {$friends[%*]} {name} {#show $name}

Example: #foreach {*friends[%*]} {i} {#show $friends[$i]}

Example: #loop {1} {&friends[]} {i} {#show $friends[+$i]}

Example: #math i 1;#while {&friends[+$i]} {#show $friends[+$i];
         #math i $i + 1}

Example: #math i 1;#&friends[] {#show $friends[+$i];#math i $i + 1}

         Each of the five examples above performs the same task; printing the
         three names in the friends list.

         If you want to get a better look at what goes on behind the scenes
         while executing scripts you can use '#debug all on'. To stop seeing
         debug information use '#debug all off'.

         List Tables

         List tables are also known as databases and the #list command has
         several options to manipulate them.

         For these options to work properly all tables need to have identical
         keys. Here is an example list table.

         #var {friendlist}
             {1}{{name}{bob} {age}{54}}
             {2}{{name}{bubba} {age}{21}}
             {3}{{name}{pamela} {age}{36}}

         To sort the list table by age you would use:

         #list friendlist indexate age
         #list friendlist order

         To remove everyone whose name starts with a 'b' you would use:

         #list friendlist indexate name
         #list friendlist filter {} {b%*}

         The filter option only supports regular expressions. To filter
         using mathematics you would loop through the list backwards:

         #loop &friendlist[] 1 index
             #if {$friendlist[+$index][age] < 30}
                 #list friendlist delete $index

         Alternatively you can use the refine option.

         #list friendlist indexate age
         #list friendlist refine {&0 >= 30}

         To add an item to a list table there are two options:

         #list friendlist add {{{name}{hobo} {age}{42}}}
         #list friendlist insert -1 {{name}{hobo} {age}{42}}


         TinTin++ tables are exceptionally fast while they remain under 100
         items. Once a table grows beyond 10000 items there can be performance
         issues when inserting and removing items in the beginning or middle of
         the table.

         The plan is to eventually implement an indexable and flexible data
         structure for large tables.

         If you load a large table from file it's important to make sure it's
         sorted, when using #write to save a table it's automatically sorted.

         If you notice performance issues on large tables it's relatively easy
         to create a hash table.


         #alias {sethash}
             #format hash %H %1;
             #math hash1 $hash % 100;
             #math hash2 $hash / 100 % 100;
             #var hashtable[$hash1][$hash2][%1] %2

         #function {gethash}
             #format hash %H %1;
             #math hash1 $hash % 100;
             #math hash2 $hash / 100 % 100;
             #return $hashtable[$hash1][$hash2][%1]

         #alias {test}
             sethash bli hey;
             sethash bla hi;
             sethash blo hello;
             #show The value of bla is: @gethash{bla}

         The above script will rapidly store and retrieve over 1 million items.
         Looping through a hash table is relatively easy as well.


         #alias {showhash}
             #foreach {*hashtable[%*]} {hash1}
                 #foreach {*hashtable[$hash1][%*]} {hash2}
                     #echo {%-20s = %s}

Related: break, continue, foreach, loop, parse, repeat, return and while.