home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / me34src.zip / me3 / doc / mutt2.doc < prev    next >
Text File  |  1995-01-14  |  39KB  |  963 lines

  1. ========================================================================
  2. ==     The Mutt2 Programming Language         Craig Durland 9/89 10/91 ==
  3. ========================================================================
  4.  
  5. Here is the documentation for the core Mutt2 programming language.
  6. There are probably many extensions, depending on what application Mutt
  7. is embedded in.  See the documentation for the application for more info.
  8.  
  9.  
  10.              Copyright 1991 Craig Durland
  11.     Distributed under the terms of the GNU General Public License.
  12.   Distributed "as is", without warranties of any kind, but comments,
  13.            suggestions and bug reports are welcome.
  14.  
  15. ======================================================================
  16. ==            Syntax                        ==
  17. ======================================================================
  18.  
  19. symbol    action
  20.   (    evaluate expression
  21.   )    end expression
  22.   {    start block
  23.   }    end block
  24.  
  25. SYNTAX
  26.   pgm   : {exp [exp ...]}, {}
  27.   exp   : (fcn [args]), (var [args]), var, const, ()
  28.   const : number (123, 0xAbC), string ("abc", 'abc'), TRUE, FALSE
  29.   arg   : block
  30.   block : pgm, exp or const
  31.   fcn   : a Mutt function (such as + or while) or defined function.
  32.  
  33. ======================================================================
  34. ==            Data Types                    ==
  35. ======================================================================
  36.  
  37. Mutt is a typed language.
  38. (data-types):
  39.   Type        id    What it is
  40.   ----        --    ---- --    --
  41.   BOOLEAN    0x05    TRUE or FALSE.
  42.   BLOB        0x06    A pointer to a block of data.
  43.   NUMBER    0x03    32 bit signed integer.
  44.   STRING    0x08    A bunch of characters.
  45.   LIST        0x09    A list of things.
  46.   VOID        0x01    A type of nothing.
  47.   FCNPTR    0x07    A pointer to a function.
  48.   CHARACTER    0x0A    This is not a real data type.  It is a helper
  49.             type.
  50.   REAL        0x04    Not implemented.
  51.  
  52. Id is a numeric constant that is used to identify a data type.  They are
  53.   used in Mutt programs when you need to talk about types (see
  54.   convert-to).
  55.  
  56. List Syntax
  57.   Sometimes I'll need to refer to the contents of a list.  To do that,
  58.     I'll use [<first element> <next element> ...].  Everything in "[]"
  59.     are the contents of the list.  "[]" by itself means the empty list.
  60.  
  61. ======================================================================
  62. ==                Return Values                ==
  63. ======================================================================
  64.  
  65. All blocks "return" a value.  Pgms return the value of the last exp
  66.   executed.  Note that a pgm can return values of different types.
  67. The class of a return value can be one of:
  68.   BOOLEAN, BLOB, NUMBER, STRING, LIST, VOID, FCNPTR.
  69.  
  70. ======================================================================
  71. ==             Variables (aka vars)                ==
  72. ======================================================================
  73. CREATION
  74.   Vars must be created before they can be used.
  75.   Global vars are initialized to:
  76.       bool            : FALSE
  77.       int, small-int, byte    : 0
  78.       string            : ""
  79.       list            : empty
  80.   Most Local vars are NOT initialized (ie they contain garbage when
  81.     created).  Local strings and lists are initialized the same as
  82.     globals.
  83. EVALUATION & ASSIGNMENT
  84.   Vars behave like fcns, ie (var) evaluates the var (returns its value)
  85.     and (var val) passes val to the var for assignment.  (var val)
  86.     returns val.  If you just want to evaluate a var, you can treat it
  87.     like a const - ie "var" is equivalent to "(var)".  Note, however,
  88.     doing this may cause logic bugs if var also happens to be the name
  89.     of a const (since the const is locked out).  See GOTCHAS.  In some
  90.     cases, (var) and var don't mean the same thing - see pointer.
  91.   Cascading assignment:  you can assign multiple vars the same value.
  92.     eg (int x y z)(x (y (z 123))) assigns 123 to x, y and z.
  93.     eg (int x)(string s 20)(x (convert-to NUMBER (s "123"))) sets s to
  94.       "123" and x to 123.
  95. SCOPE
  96.   The scope of a variable is the same as the pgm it is created in.
  97.   A variable created outside of a fcn (defun) is global - ie anybody
  98.     can get at it.  Global variables are local to the file (and any
  99.     included file(s)) they are created in.
  100.   For example:
  101.     If foo.mut contains:
  102.       (int foo)        ; declare and create global var "foo"
  103.       (defun "hoho" { (int bar) (bar foo) })
  104.       (foo 123)        ; assign 123 to foo
  105.     (load "foo.mut") will create a global var foo.  (hoho)
  106.     creates bar and sets it to 123.  hoho is done and bar is freed.
  107.     foo is still alive and equal to 123.
  108.  
  109. ======================================================================
  110. ==            Functions and Keywords                ==
  111. ======================================================================
  112. Everything in this list is a function (except those that have a return
  113.   class of zip).
  114.  
  115. A TOKEN is a bunch of letters, eg foo.
  116.  
  117. Keyword Args        [arg class(s) : return class]
  118. ------- ----        ---- -------- -    ------ ------
  119.  
  120. ; (semi-colon)    A comment that extends to the end of the line
  121.  
  122. (== value value ...)          [STRINGs, NUMBERs or BOOLEANs : BOOLEAN]
  123.   Test 2 or more items for equality.  
  124.   You can only compare like types - eg (== "123" 123) is illegal.
  125.   eg (== foo 1), (== "one" "two"), (== (+ foo 3) bar 5).
  126. (!= value value)                 [NUMBER NUMBER : BOOLEAN]
  127.     Same as == but nonequality.  Only 2 items.
  128. (<  value1 value2) TRUE if value1 <  value2.     [NUMBER NUMBER : BOOLEAN]
  129. (<= value1 value2) TRUE if value1 <= value2.     [NUMBER NUMBER : BOOLEAN]
  130. (>  value1 value2) TRUE if value1 >  value2.     [NUMBER NUMBER : BOOLEAN]
  131. (>= value1 value2) TRUE if value1 >= value2.     [NUMBER NUMBER : BOOLEAN]
  132. (+  values)                        [NUMBERs : NUMBER]
  133.     Add a bunch of numbers  eg (+ 1 2 3 4) => 1+2+3+4
  134. (-  values)                        [NUMBERs : NUMBER]
  135.     Subtract a bunch of numbers eg (- 1 2 3 4) => 1-2-3-4 = -8
  136. (*  values)    multiply a bunch of numbers        [NUMBERs : NUMBER]
  137. (/  values)    divide a bunch of numbers        [NUMBERs : NUMBER]
  138. (+= var values)                      [TOKEN NUMBERs : NUMBER]
  139.     Add value(s) to var and assign it back to the var.  Returns the result.
  140.     Short hand for (var (+ var values)).
  141.     eg (+= foo 1) (+= foo fud 3) 
  142. (-= var values)      Subtract value from var.      [TOKEN NUMBERs : NUMBER]
  143. (*= var values)      Multiply var by value.      [TOKEN NUMBERs : NUMBER]
  144. (/= var values)      Divide var by value.          [TOKEN NUMBERs : NUMBER]
  145.  
  146. "string"
  147.   String constant.
  148.   Special characters:
  149.     \    quote the next character.  "\\" => '\'   "\^" => '^'
  150.     ^    convert the next character to a control character (make sure that
  151.       the letter is UPPERCASE!).  eg "^A"
  152.     Note: escape == ^[.
  153. 'string'
  154.   String constant.
  155.   No special characters except '' reduces to ' ie if you need a string
  156.     like "don't", you can use 'don''t'.
  157.   This form is handy for regular expressions.
  158.  
  159. (and values)                 [BOOLEAN [BOOLEAN ...] : BOOLEAN]
  160.   Logically and a bunch of things
  161.   The first FALSE value will terminate (ie the rest of the and will
  162.     not be evaluated).
  163.   Example:
  164.     (and (previous-line) (foo)):  If previous-line returns TRUE, foo is
  165.       called and that will be the result of the and.  If previous-line
  166.       returns FALSE, the and returns FALSE and foo is not called.
  167.   See also: or.                                  
  168. (arg n)                              [NUMBER : any class]
  169.   Get the nth argument from the parameter list.
  170.   The arguments are numbered 0,1...,(nargs)-1
  171.   eg (fcn 1 "two" (three)) has 3 arguments:  numeric 1, string "two" and
  172.     whatever fcn three returns.  (arg 0) returns 1, (arg 1) returns
  173.     "two", (arg 2) returns result of (three).  (arg 3), (arg -1), etc
  174.     error.
  175.   Notes:
  176.     You cannot set a arg unless it is a pointer.
  177.     See defun for how you can name the args.
  178.   See also: ask, defun, nargs.
  179. (array type name dimensions)   [TOKEN TOKEN NUMBERs [TOKEN NUMBERs] : zip]
  180.   Create an array.  Types allowed: bool, int, small-int.
  181.   (array int x 5 z 7) creates two arrays:  x with 5 ints and z with 7.
  182.   (array int y 2 3) creates an array with 2 rows of 3 ints each.
  183.   (x 3 123) sets the third element of x to 123.
  184.   (x 3) returns 123.
  185. (ask prompt(s))                       [any class(s) ... : STRING]
  186.   Get the next argument from the argument list; if the argument list is
  187.     empty, query the user.  Aways returns a string - if the arg is not a
  188.     string, it is converted to one.
  189.   eg if (foo (ask "foo = ")) is in fud then (fud "hoho") will pass "hoho"
  190.     to foo.  (fud) will cause the message "foo = " to appear and will wait
  191.     for a response to assign to foo.
  192.   You can force the pgm to query the user with (ask-user).  If you do
  193.     this, you will need one per ask.  The next unmodified (ask) will
  194.     behave as above.
  195.   (ask) can take more than one argument.  For example, if foo is 123 then
  196.     (ask "foo is currently " foo ".  Change it to: ") might prompt:
  197.     "foo is currently 123.  Change it to: ".
  198.   Notes:
  199.     Be careful if you mix arg lists and asks.  It can be confusing (to
  200.       the programmer) if you try to get some args via (arg n) and others
  201.       via (ask).  In this case, you should use interactive asks to keep
  202.       ask out of the arg list.  Use nargs and arg if you must mix (to
  203.       implement your own ask like functionality) and will be asking for
  204.       an arg starting after the first one.
  205.     If not interactive, each ask will get the next arg from the arg
  206.       list.  The first ask gets a copy of the first arg, the second ask
  207.       gets the a copy of the second arg, etc.  until there are no more
  208.       args.  After that, next ask will abort the program.  There is no
  209.       way to restart ask.
  210.     Ask doesn't change the arg list - you can ask away and still get at
  211.       any arg with (arg).
  212.   See also: arg, ask-user, convert-to, arg, nargs.
  213. (ask-user)                              [zip : VOID]
  214.   The next ask will query the keyboard and not the program args.
  215.   Turned off after every ask.
  216.   See also: ask.
  217.  
  218. (bool var [var ...])                 [TOKEN [TOKEN ...] : zip]
  219.   Create one or more boolean variables.  If in a defun, the variable is
  220.     local to that defun, otherwise it is global.
  221.   Evaluation: var                     [TOKEN : BOOLEAN]
  222.   Assignment: (var value)             [TOKEN BOOLEAN : BOOLEAN]
  223.   Example: (bool foo)(foo TRUE)  ;; create and set "foo" TRUE
  224.   See also: int, string, list, array.
  225. (break)                                   [zip : zip]
  226.   Get out of the smallest enclosing for or while loop.  The loop then
  227.     retuns the value of the last block executed.
  228.   See also: continue, for, while.
  229. (byte var [var ...])                 [TOKEN [TOKEN ...] : zip]
  230.   Evaluation: var                      [TOKEN : NUMBER]
  231.   Assignment: (var value)               [TOKEN NUMBER : NUMBER]
  232.   Allocate 8 bit unsigned integers.
  233.   The range of a byte is [0 : 255].
  234.   Note that a NUMBER may not fit in a byte.  If not, the number will be
  235.     truncated to fit.
  236.   See also: int, small-int, array, bool.
  237.  
  238. (cond test body ...)
  239.         [[BOOLEAN, block, [BOOLEAN, block ...]] : last block executed]
  240.   Same as  nested  if's.  If the  test is TRUE  then the next  block  is
  241.     executed and the cond is ended.  Otherwise the next block is skipped
  242.     and the cycle repeats.
  243.   eg
  244.   (string str)(str (ask "str = "))
  245.   (cond
  246.     (== str "one") (msg "number 1")
  247.     (== str "foo") (msg "bar")
  248.     TRUE (msg str " is not something I know about.")
  249.   )
  250.   See also: switch.
  251. (concat parameters)                   [anything ... : STRING]
  252.   Concatenate parameters.
  253.   eg (concat "foo = " foo) returns "foo = 123" if foo is 123 or "123".
  254. (const name value [name value ...])    [TOKEN BOOLEAN|NUMBER|STRING : zip]
  255.   Create one or more constants.  Used like other constants (such as
  256.     numbers, strings, etc).
  257.   Precedence: args, local vars, global vars, pgms, consts.
  258.   eg
  259.     (const foo 123 bar "hoho")
  260.     (msg foo bar)    ;; this prints "123hoho")
  261.   Notes:
  262.     Do not use ()'s around constants - they are for functions only.
  263.     See GOTCHAS.
  264. (continue)                               [zip : zip]
  265.   Go to the bottom of the smallest enclosing for or while loop.
  266.     If in a for loop, this means the inc part.
  267.   See also: break, for, while.
  268. (convert-to type value)                       [NUMBER any : type]
  269.   Convert a value of one data type to another type.
  270.   Valid conversions:
  271.     BLOB to:
  272.       No valid conversions.
  273.     BOOLEAN to:
  274.       NUMBER:      TRUE -> 1 and FALSE -> 0
  275.     FCNPTR to:
  276.       No valid conversions.
  277.     LIST to:
  278.       No valid conversions.
  279.     NUMBER to:
  280.       STRING:     same as (concat).  eg 123 -> "123"
  281.       CHARACTER: 0x33 -> "3"
  282.       BOOLEAN:     0 -> FALSE and everything else -> TRUE
  283.     STRING to:
  284.       NUMBER:     "123" -> 123
  285.       CHARACTER: "3" -> 0x33
  286.     VOID to:
  287.       No valid conversions.
  288.    The numeric constants for the data types are in the data types
  289.      section (see data-types).
  290.  
  291.   eg (foo (convert-to NUMBER (ask "A number please: ")))
  292.   Note:
  293.     To convert a number into a string, you can also use concat.  eg
  294.       (string s 20)(s (concat 123)) will convert numeric 123 into a
  295.       string and assign it to s.  This is the same as (s (convert-to
  296.       STRING 123))
  297.     To convert to a list, use: (insert-object L 0 val1 val2 ...).  
  298.       If (convert-to LIST val1 val2 ...)  is ever implemented, it would
  299.       be the same as:
  300.         (defun convert-to-list (int type)(val1 val2) ;; ...
  301.       { (list L) (insert-object L 0 (push-args 1)) L })
  302.   See also: ask.
  303.  
  304. (defun name [arglist] [modifier(s)] pgm   [name ...])
  305.                 [TOKEN [([type] TOKEN)...] [TOKENs] pgm : zip]
  306.   Define a function.  Multiple functions can be defined.
  307.   Comments and whitespace have no performance or size penalty, so use
  308.     them.
  309.   You can optionally name the arg list.  
  310.     ([type] name [dimension(s)] [name [dimension(s)]] ...) ...
  311.     int, small-int and byte all mean NUMBER (since all numerics are
  312.     promoted to NUMBER when passed).  Array subscripts are used to
  313.     determine the dimension the passed in array - the first dimension is
  314.     a placeholder (as in C).  Arg type is optional - if not used, no
  315.     assumptions are made about the the arg (ie it will be type checked
  316.     at runtime if needbe).  If an arg is typed, what ever is passed in
  317.     is assumed to be of the correct type - it is not checked.
  318.   Modifiers are used to put conditions on a function.
  319.     Modifier : What It Does
  320.     -------- - ---- -- ----
  321.     HIDDEN     Only functions defined after this one can reference it.
  322.     MAIN       This function will be executed when it is loaded.
  323.   MAIN is a special function name.  It defines a function that is
  324.     executed at load time (the same as a function marked MAIN) and can
  325.     not be called by anyone.  Use MAINs to do things that only need to
  326.     be done once before anything else is done (for example, initializing
  327.     some variables).  Use the modifier MAIN if you also want to be able
  328.     to repeat things at other times.  There is no limit on the number of
  329.     MAIN functions or functions marked MAIN.  MAINs are called in the
  330.     order that they are defined.  Functions marked MAIN are called
  331.     alphabetically (for the purposes of the sort, functions named MAIN
  332.     are treated as if their name really was MAIN and are sorted by
  333.     address (ie first defined, first called)).
  334.   For example:
  335.     (defun
  336.       foo { (msg "this is foo") }    ; (foo) prints "this is foo"
  337.       bar (int x y)(string s)    ; bar has 3 args: 2 numbers and a string
  338.         {
  339.       (msg s)    ; same as (msg (arg 2))
  340.       (msg (+ x y))    ; same as (msg (+ (arg 0)(arg 1)))
  341.     }
  342.       fred (z) { (msg z (arg 1)) }    ; print the first and second args
  343.       sam MAIN { (msg "sam") }        ; sam is run at load time
  344.       MAIN { (msg "MAIN is run only at load time") }
  345.     )
  346.   Notes:
  347.     You can not assign to an arg unless it is a pointer.
  348.  
  349.   There is a special case of defun that generates code and returns a
  350.     pointer to that code.  These "anon" defuns are for passing code
  351.     fragments to routines without having to go to the effort of thinking
  352.     up a name for a routine.  {{ and }} are the symbols that delimit the
  353.     code and can be used just about anywhere but are only useful as part
  354.     of a function call.
  355.     For example:
  356.       1> (defun example (pointer defun code) { (code) })
  357.       2> (example {{ (msg "example") }})
  358.     Line 1 defuns a routine that takes a pointer to code and runs the
  359.     code.  Line 2 shows how to use an anon defun in a call.  When line 2
  360.     is run, "example" is printed out.
  361.   Anon defuns can do anything defuns can (declare variables, make calls,
  362.     etc) except name the arg list.  This means that you have to use the
  363.     (arg n) notation when dealing with passed in args.  Also, a anon
  364.     defun can NOT access variables declared in the defun it is in.  It
  365.     can access global variables.
  366.     For example:
  367.       (defun
  368.         foo
  369.     {
  370.       (int x)
  371.       {{ (msg x) }}
  372.     })
  373.       is an error.
  374.  
  375.   See also: arg, pointer, the example pgms.
  376. (done)                                   [zip : zip]
  377.   Exit smallest enclosing pgm.
  378.   See also: halt.
  379.  
  380. (extract-element object-name n)
  381.                             [LIST NUMBER : object]
  382.                           [STRING NUMBER : STRING]
  383.   Make a copy of the nth element of a list or string.
  384.   This is the same as (atomize (extract-elements object-name n 1))
  385.     except there is no atomize function.  For example, extracting a
  386.     number from a list results in a number.  If you had used
  387.     extract-elements, it would have returned a list with number in it.
  388.   See extract-elements for how n can modified by the function.
  389.   In the STRING case, this function is the same as
  390.     (extract-elements string n 1).
  391.   Examples:
  392.     (extract-element "123" 1) => "2"
  393.     (extract-element ["123" 4 5] 1) => 4
  394.     (extract-element  [] n) => []
  395.   See also:  extract-elements, insert-object, remove-elements,
  396.     length-of, list.
  397. (extract-elements object-name n z)
  398.                            [LIST NUMBER NUMBER : LIST]
  399.                        [STRING NUMBER NUMBER : STRING]
  400.   Starting at element n, copy of z elements of a list or string to a new
  401.     list or string (0 == first element)
  402.   If (z <= 0) or (n > (length-of object)) or (object == []), returns [].
  403.   If n or z is < 0 then the length of the object is added to them.
  404.   If n > (length-of object), it is set after the last element of the
  405.     object.
  406.   If ask for more elements than are available, returns as many as can.
  407.   Examples:
  408.     (extract-elements "123" 1 1) => "2"
  409.     (extract-elements ["123" 4 5] 0 2) => ["123" 4]
  410.     (extract-elements ["123" 4 5] 1 1) => [4]
  411.     (extract-elements [] n z) => []
  412.   extract-elements also acts like Mock Lisp's substr:
  413.     (extract-elements "foobar" 0 3) => "foo"
  414.     (extract-elements "foobar" -1 1) => "r"
  415.     (extract-elements "foobar" 0 -1) => "fooba"
  416.     (extract-elements "foobar" 3 100) => "bar"
  417.     (extract-elements "foobar" 50 100) => ""
  418.   See also:  extract-element, insert-object, remove-elements, length-of,
  419.     list.
  420.  
  421. (FALSE)                               [zip : BOOLEAN]
  422.   The boolean constant FALSE.
  423.  
  424. (floc function-name)                [TOKEN|STRING : BLOB]
  425. (floc function-name ())        [TOKEN|STRING     : (function-name)]
  426. (floc function-name arg1)        [TOKEN|STRING any : (function-name arg1)]
  427. (floc function-name arg1 arg2 ...)
  428.          [TOKEN|STRING any any ... : (function-name arg1 arg2 ...)]
  429.   Return the address of or call a function.
  430.   (floc function-name) returns the address of function-name.
  431.   (floc function-name ()) calls function-name with no args.
  432.   (floc function-name arg) calls function-name with one arg.
  433.   (floc function-name arg1 ... argN) calls function-name with N args.
  434.  
  435.   A function is:
  436.     An internal-function - one of:
  437.       ask, concat, extract-element, extract-elements, insert-object,
  438.       msg, remove-elements
  439.     A program (something created with (defun)).
  440.     The name of an external token (see the compiler "-t" option).
  441.  
  442.   The format of function-name is:
  443.     A token (such as foobar).
  444.     A string (such as "foobar").
  445.     A function that returns a string (such as (foobar)).
  446.     A string variable (such as (foostring)).
  447.  
  448.   Note that most of the keywords and functions in this list are not
  449.     "real" functions - ie they have no address and can't be used in floc
  450.     (the exceptions are the internal functions mentioned above).
  451.   If using strings (variable or constant), you can only reference
  452.     programs or tokens (ie no internal-functions).
  453.   If given args, a function call is generated.  If you want to call a
  454.     function that has no args, use () as the args list
  455.     (eg "(floc "foobar" ())").
  456.   If you want to use a string variable, the format is:
  457.     (floc (string-var)) or (floc (string-var)([args]))
  458.     The thing to note is that the string var has to be in parentheses
  459.     (this is probably a bug).  At run time, the string is deferenced and
  460.     its contents is used to identify the function.
  461.  
  462.   Example:
  463.     (defun
  464.       add (pointer defun plus) (x y)
  465.     { (msg x " + " y " = " (plus x y)) }
  466.       add-two-numbers (int a b) { (+ a b) }
  467.       silly-add (a b) { "three" }
  468.     )
  469.     (add (floc add-two-numbers) 1 2)    ; 1 + 2 = 3
  470.     (add (floc silly-add) "one" "two")    ; one + two = three
  471.   Example:
  472.     (string name-of-two)
  473.     (defun
  474.       one { "two" }
  475.       two { "this is a test" }
  476.     )
  477.     (msg (floc (one)()))        ;; this prints: this is a test
  478.     (name-of-two "two")
  479.     (msg (floc (name-of-two)()))    ;; this also prints: this is a test
  480.  
  481.   Notes:
  482.     (floc foobar) returns the address of a already defined function.
  483.       Its an error if foobar is not defined in the same file (or any
  484.       included files) as the floc.
  485.     The order in which the address is resolved (at compile time) is:
  486.     Internal-functions (see above).
  487.     An already defined program.
  488.     An external token or a pgm defined after the floc.
  489.     String (constant or variable).  Resolved at run time.
  490.       Given these rules, you should be careful about name overloading.
  491.     (floc "foobar"):  The location of foobar is resolved at runtime.
  492.       This is slower and generates more code but always works (if foobar
  493.       really is a function and not a typo).  Note that this method does
  494.       not work for internal-functions or external tokens that don't also
  495.       have a name list for the tokens.
  496.   See also: loc, defun, pointer, qsort (in the Example Programs below)
  497.  
  498. (for init test inc body)
  499.         [block, BOOLEAN, block, block : FALSE (unless break used)]
  500.   A for next loop:  perform init once.  Perform body and inc while
  501.     test is TRUE.  This is equivalent to:
  502.     init (while test { body inc })
  503.   break will terminate the loop and continue will jump to inc.
  504.   For example:
  505.     (int j)
  506.     (for (j 1) (< j 6) (+= j 1)
  507.     {
  508.       (if (== j 3)(continue))    ; skip 3
  509.       (msg j)
  510.     })
  511.     prints out: 1 2 4 5
  512.   See also: break, continue, while.
  513.  
  514. (goto label)                             [TOKEN : zip]
  515.   Even if you dare, use this with care.
  516.   Don't cross defun boundaries.
  517.   See also: label.
  518.  
  519. (halt)                                   [zip : zip]
  520.   Halt the Mutt machine.  This stops any program that is running and
  521.     returns control to the application.
  522.   See also: done.
  523.  
  524. (if test true [false])         [BOOLEAN, block, block : last block executed]
  525.   test and true must exist even if blank (ie "{}" or "()").
  526.   eg (if (== foo bar) (msg "foo == bar") (msg "foo != bar") )
  527.      (== foo bar)(if () (msg "foo == bar"))
  528.   The C conditional expression "condition ? true : false" can be mimiced
  529.     with (if condition true false).
  530. (include filename)                      [TOKEN|STRING : zip]
  531.   Compile another file.  After filename is compiled,  compiling  resumes
  532.     at the line after the one that contained the include.
  533.     ie  "(include foo.mut)" is the same as "(include foo ; doo daa"
  534. (insert-object object-name n new-object ...)
  535.                     [LIST NUMBER any [any ...] : LIST]
  536.                   [STRING NUMBER STRING [STRING ...] : STRING]
  537.   Insert an object into another object after the nth element.
  538.   To prepend an object, use n == -1.
  539.   You can put the following types into a list: STRING, NUMBER, LIST.
  540.     Mix and match as much as you like.
  541.   Example:
  542.     (list L)
  543.     (insert-object L 0 "123" 5 6) => ["123" 5 6]
  544.     (insert-object L 0 4)         => ["123" 4 5 6]
  545.     (insert-object L 555 7)      => ["123" 4 5 6 7]
  546.   See also:  extract-element, remove-elements, length-of, list, string.
  547. (int name [name ...])                 [TOKEN [TOKEN ...] : zip]
  548.   Evaluation: var                      [TOKEN : NUMBER]
  549.   Assignment: (var value)               [TOKEN NUMBER : NUMBER]
  550.   Create 32 bit integer variables.
  551.   The range of a int is [-2,147,483,648 : 2,147,483,647].
  552.   See also: bool, byte, small-int, string, array.
  553. (small-int name [name ...])             [TOKEN [TOKEN ...] : zip]
  554.   Evaluation: var                      [TOKEN : NUMBER]
  555.   Assignment: (var value)               [TOKEN NUMBER : NUMBER]
  556.   Create 16 bit integer variables.  The only advantage of using small-int
  557.     instead of int is that small-ints require less memory to store (and
  558.     it might take less time to store and retrieve them).
  559.   The range of a small-int is [-32,768 : 32,767].
  560.   Note that a NUMBER may not fit in a small-int.  If not, the number
  561.     will be truncated to fit.
  562.   See also: bool, byte, int, string, array.
  563.  
  564. (label label-name)                         [TOKEN : zip]
  565.   The target of a goto.
  566.   eg (label foo)(goto foo) creates an infinite loop.
  567.   See also: goto.
  568. (length-of name)                        [any : NUMBER]
  569.   Return the length of a object.
  570.   Type        Length
  571.   ----        ------
  572.   STRING    Number of characters in the string.  eg "foo" => 3.
  573.   LIST        Number of elements in the list.
  574.         eg ["one" 2 "three"] => 3.
  575.   See also: list, insert-object.
  576. (list name [name ...])                 [TOKEN [TOKEN ...] : zip]
  577.   Create one or more list variables.  If in a defun, the variable is
  578.     local to that defun, otherwise it is global.
  579.   Example:
  580.     (list L) creates a list named L.
  581.     (insert-object L 0 "123" 5 6) puts 3 elements in to L:  ["123" 5 6]
  582.   See also:  string, extract-element, insert-object, length-of,
  583.     remove-elements.
  584. (loc var)                            [TOKEN : BLOB]
  585.   Return the address of a variable.  In this way you can modify the
  586.     variables you pass to functions.
  587.   loc works on the following types:  byte, int, small-int, bool and arrays.
  588.     Strings and lists not supported (yet).
  589.   Example:
  590.     (int a b c d)    ; 4 ints in row.  Same order as (array int a 4)
  591.     (defun
  592.       MAIN
  593.       {
  594.     (a 123)(foo (loc a))(msg "a = " a "   b = " b)
  595.     (bar (loc a))
  596.       }
  597.       foo (array int x 2)  ; first element of x maps to a
  598.       {
  599.     (msg "(x 0) = " (x 0))    ; display the value of a
  600.     (x 0 456)        ; set a to 456
  601.     (x 1 111)        ; set b to 111
  602.       }
  603.       bar (pointer int x)
  604.     { (msg "x = " (x)) }    ; display the value of a
  605.     )
  606.     When this is run it produces:
  607.     (x 0) = 123
  608.     a = 456   b = 111
  609.     x = 456
  610.   See also: arg, defun, floc, pointer.
  611.  
  612. (msg stuff)                      [any class ... : STRING]
  613.   Prints a message.  The list is concatenation of the arg list.
  614.   Returns the entire message.
  615.   eg (msg "foo = " foo)
  616.   Note: (msg) is the same as (msg "").
  617.  
  618. (nargs)                                [zip : NUMBER]
  619.   Return the number of parameters passed to the function.
  620.   eg (foo 1 "two" (three)) has 3 arguments and (nargs) returns 3.
  621.   See also: arg.
  622. (not value)                           [BOOLEAN : BOOLEAN]
  623.   Negate value.
  624.   For example: (not (== foo 1)) returns TRUE if foo not equal to 1.
  625. (novalue)                              [zip : VOID]
  626.   A way to make sure a function returns VOID.
  627.  
  628. (or value ...)                 [BOOLEAN [BOOLEAN ...] : BOOLEAN]
  629.   Logically or a bunch of things.
  630.   The first TRUE value will terminate (ie the rest of the or will
  631.     not be evaluated).  eg (or (beginning-of-line) foo)
  632.   For example:
  633.     (or (foo) TRUE (bar)):  If (foo) returns TRUE, the or returns TRUE
  634.     and nothing else is done.  If (foo) return FALSE, the or returns
  635.     TRUE anyway (because of the TRUE).  In all cases, bar is never
  636.     called.
  637.   See also: and.
  638.  
  639. (pointer type var-names)           [TOKEN TOKEN [TOKEN ...] : zip]
  640.   Declare pointer vars.  You can create pointers to byte, small-int,
  641.     int, bool, and defun (functions).
  642.   Pointers to data:
  643.     To get what a pointer points to: (pd)
  644.     Assignment: (pd location) where location is a pointer
  645.       arg or something returned by loc or floc.
  646.   Pointers to functions:
  647.     (pf) calls function pointed to by pf with no args.
  648.     (pf arg1 ... argn) calls pf with n args.
  649.   See also: defun, floc, loc.
  650. (push-arg exp)                         [anything : anything]
  651.   Push a arg onto the function call list.  Useful when you need to call
  652.     a function and you don't what args you need to call it with at
  653.     compile time.
  654.   Example:
  655.     (int j)
  656.     (foo "arg 1"
  657.       (for (j 0) (< j some-num) (+= j 1) (push-arg (peek j)))
  658.     )
  659.     This will call foo with one or more args:  "arg 1" and some-num of
  660.       whatever peek returns.
  661.   See also: push-args.
  662. (push-args n)                           [NUMBER : last arg]
  663.   Push all the args from n back on the stack.  The first arg is 0.
  664.   For example: If max is a function that takes the maximum of all its args,
  665.     and foobar is a function that takes a string and a list of numbers and
  666.     you want to find the maximum of those numbers, you could:
  667.     (defun foo (string s) { (int m) (m (max (push-args 1))) })
  668.   Notes:
  669.     push-args can only be used with defined functions plus concat and msg.
  670.       For example (+ (push-args 3)) is an error, (msg (push-args 3)) is OK.
  671.     If n is greater than the number of args, no args are pushed and no
  672.       error is generated.
  673.     You can treat push-args like a run-of-the-mill arg - eg (foo 123
  674.       (push-args 2) "hoho") and (foo (push-args 4) (push-args 2)) are
  675.       OK.
  676.   See also: push-arg.
  677.  
  678. (remove-elements object n z)        [LIST|STRING NUMBER NUMBER : VOID]
  679.   Remove z elements of a object starting at the nth element.
  680.   If (n >= (length object)), nothing happens.
  681.   (remove-elements [] n z):  [].
  682. !!!??? other magic done to n and z?
  683.   Examples:
  684.     (remove-elements [1 2 3] 0 1)     => [2 3]
  685.     (remove-elements [1 2 3] 1 100)   => [1]
  686.     (remove-elements [1 2 3] 100 100) => [1 2 3]
  687.   Notes:
  688.     This doesn't work on string constants (doesn't make sense either).
  689.       ie (remove-elements "123" 1 1) doesn't work.
  690.       (text "123")(remove-elements text 1 1) does.
  691.  
  692. (string name ...)                 [TOKEN [TOKEN ...] : zip]
  693.   Evaluation: var                      [TOKEN : STRING]
  694.   Assignment: (var value)               [TOKEN STRING : STRING]
  695.   Create some strings.  String length is variable ie the string will
  696.     resize it self to hold whatever you want to put in it.
  697.   Example:
  698.     (string foo)
  699.     (foo "this is a test")
  700.     (msg foo)        ;; this will print "this is a test"
  701.   See also:  list, extract-elements, insert-object, length-of,
  702.     remove-elements.
  703. (switch value  value block [value block ...] [default block])
  704. [NUMBER|STRING|BOOLEAN, same, block, same, block ... : last block executed]
  705.   Get a value.  Scan down the list until a matching value is found and then
  706.     execute the next block and exit the switch.
  707.   If no match is found, the default block is executed (if it exists).
  708.   All values must have the same class.
  709.   eg
  710.     (switch (extract-elements (ask "Is the moon made of green cheese? ") 0 1)
  711.       "y" (msg "Not according to current scientific thought.")
  712.       "n" (msg "Probably the case.")
  713.       default (msg "Burp.")
  714.     )
  715.   See also: cond
  716.  
  717. (TRUE)                               [zip : BOOLEAN]
  718.   The boolean constant TRUE.
  719.   Use this for the default case in cond.
  720.  
  721. (while test body)          [BOOLEAN, block : FALSE (unless break used)]
  722.   Perform body while test is TRUE.
  723.   For example: (int j) (j 0) (while (< j 5) { (msg j) (+= j 1) } )
  724.     will print out: 0 1 2 3 4.
  725.   A do..while loop can be constructed like so:
  726.     (while {body test} ())
  727.   You can use break to get out of the loop or continue to move back to
  728.     test.
  729.   See also: break, continue, for.
  730.  
  731. ====================================================================
  732.              How args are passed
  733. ====================================================================
  734. All args are evaluated before being passed.  bytes, small-ints and ints
  735.   are converted to NUMBER.
  736. Args are passed by value and  reference.  Value  means a copy of the arg
  737.   is pushed on the stack and changes to it will not be reflected  in the
  738.   original.  When  something  is passed by  reference,  a pointer to the
  739.   original is pushed on the stack and changes will be to the original.
  740. - bools, numbers, voids:  value.
  741. - arrays, blobs, strings, lists:  reference.
  742.  
  743. ====================================================================
  744.                Example Programs
  745. ====================================================================
  746.     ; Factorial the recursive way
  747. (const NUMBER    0x03)
  748. (defun
  749.   fact    ;; the recursive part.  input: x  output: x!
  750.   {
  751.     (if (== (arg 0) 0) 1        ; 0! = 1
  752.       (* (arg 0) (fact (- (arg 0) 1))))    ; x! = x * (x-1)!
  753.   }
  754.   fact1 (int x)        ;; same as fact but with named args
  755.   {
  756.     (if (== x 0) 1        ; 0! = 1
  757.       (* x (fact (- x 1))))    ; x! = x * (x-1)!
  758.   }
  759.   !    ;; the main routine
  760.   {
  761.     (int x)
  762.     (x (convert-to NUMBER (ask "Take factorial of: ")))
  763.     (msg x "! = " (fact x))
  764.   }
  765.   MAIN { (!) }        ;; (! 5) produces "5! = 120" 
  766. )
  767.  
  768. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  769. (const NUMBER    0x03)
  770. (defun square MAIN        ; print a table of squares
  771. {
  772.   (int foo max)
  773.   (max (convert-to NUMBER (ask "Max = ")))
  774.   (foo 1)
  775.   (while (<= foo max) { (msg foo "\^2 = " (* foo foo)) (+= foo 1) })
  776. })
  777. ; (square 3) produces
  778. ; 1^2 = 1
  779. ; 2^2 = 4
  780. ; 3^2 = 9
  781. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  782. ; Good ol towers of hanoi
  783. ; Usage: (hanoi <n>) where n is the number of discs
  784. (const NUMBER    0x03)
  785. (defun
  786.   print-move (from to) { (msg "Move Disk From " from " To " to) }
  787.   transfer (from to via)(int n)
  788.   {
  789.     (if (== n 1)(print-move from to)
  790.     {
  791.       (transfer from via to (- n 1))
  792.       (print-move from to)
  793.       (transfer via to from (- n 1))
  794.     })
  795.   }
  796.   hanoi MAIN
  797.     { (transfer "A" "B" "C" (convert-to NUMBER  (ask "n = ")))(msg "done.") }
  798. )
  799. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  800. ; tobase(n,base): convert n (base 10) to base.  eg (tobase 10 16) => "A"
  801. ;    C Durland
  802.  
  803. (defun
  804.   mod (int n base)    ; n mod base = n - (n/base)*base
  805.     { (- n (* (/ n base) base)) }
  806.   tobase (int n base)
  807.   {
  808.     (if (< n base) (extract-elements "0123456789ABCDEF" n 1)
  809.       (concat
  810.         (tobase (/ n base) base)    ; tobase n/base base
  811.     (tobase (mod n base) base)    ; tobase (n mod base) base
  812.       )
  813.     )
  814.   }
  815. )
  816. (const NUMBER    0x03)
  817. (defun
  818.   MAIN
  819.   {
  820.     (msg (tobase
  821.     (convert-to NUMBER (ask "n = "))
  822.     (convert-to NUMBER (ask "base = "))))
  823.   })
  824. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  825. (defun 
  826.   sort (array int list-to-sort 1)(int n)    ; shell sort an array of n ints
  827.   {
  828.     (int gap i j t k)
  829.  
  830.     (gap (/ n 2))
  831.     (while (> gap 0)
  832.     {
  833.       (i gap)
  834.       (while (< i n)
  835.       {
  836.     (j (- i gap))
  837.     (while (and (>= j 0) (> (list-to-sort j)(list-to-sort (+ j gap))))
  838.     {
  839.       (k (+ j gap))(t (list-to-sort j))
  840.       (list-to-sort j (list-to-sort k))(list-to-sort k t)
  841.       (-= j gap)
  842.     })
  843.         (+= i 1)
  844.       })
  845.       (/= gap 2)
  846.     })
  847.   }
  848. )
  849. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  850.     ; Quick sort.  From Horowitz & Sahni pg 347
  851.     ; Sort list[m..n] into ascending order
  852.  
  853.     ; swap is a routine that interchanges list[a] with list[b]
  854.     ; cmp compares list[a] with list[b] and returns:
  855.     ;    negative if list[a] < list[b]
  856.     ;    positive if list[a] > list[b]
  857.     ;    zero     if list[a] = list[b]
  858. (defun
  859.   Qsort (list-to-sort)(int m n)(pointer defun swap cmp)
  860.   {
  861.     (int i j)
  862.  
  863.     (if (>= m n) (done))    ;; end the recursion
  864.     (i m) (j (+ n 1))
  865.     (while TRUE
  866.     {
  867.       (while { (+= i 1)(and (<= i n) (< (cmp list-to-sort i m) 0)) } ())
  868.       (while { (-= j 1)(> (cmp list-to-sort j m) 0) } ())
  869.       (if (< i j) (swap list-to-sort i j) (break))
  870.     })
  871.     (swap list-to-sort m j)
  872.     (Qsort list-to-sort m (- j 1) swap cmp)
  873.     (Qsort list-to-sort (+ j 1) n swap cmp)
  874.   }
  875. )
  876.  
  877.     ; swap and cmp routines for arrays of ints
  878. (defun
  879.   swap (array int list-to-sort 1)(int a b)    ; swap 2 elements
  880.   {
  881.     (int tmp)
  882.     (tmp (list-to-sort a)) (list-to-sort a (list-to-sort b))
  883.     (list-to-sort b tmp)
  884.   }
  885.   cmp (array int list-to-sort 1)(int a b)    ; compare 2 elements
  886.     { (- (list-to-sort a) (list-to-sort b)) }
  887. )
  888.  
  889. ; (array int list-to-sort 100)
  890. ; (Qsort list-to-sort 0 n (floc swap) (floc cmp))
  891.  
  892. ======================================================================
  893.                Notes and Tricks
  894. ======================================================================
  895. * Lets say you have a number and wish to turn it into a string with a
  896.   leading zero if it is less than 10.
  897.     (int n)(string s 20)
  898.     (n (convert-to NUMBER (ask "n = ")))
  899.     (s (concat (if (< n 10) ("0")("")) n))
  900.   This trick also works in msgs, etc.
  901. * In general, only the last thing in a block matters.
  902.   So, (foo { (msg "set foo to 123") 123 }) is the same as
  903.     (msg "set foo to 123") (foo 123).
  904.  
  905. ======================================================================
  906.               The Mutt Compiler
  907. ======================================================================
  908.    Since Mutt is a compiled language, you'll need to compile the
  909. programs you've written before you can run them.  To do this use MC2,
  910. the Mutt2 Compiler.  Type "mc2 filename".  filename is assumed to have a
  911. .MUT extension (ie you don't have to type it).  The compiler produces an
  912. output file in the current directory with the name name.MCO (where name
  913. is the same base name as filename).
  914.   MC2 options:
  915.     -I directory-name
  916.        An alternate directory for include files.  For example, if
  917.      foo.mut is in directory fred and contains (include sam.mut) and
  918.      sam.mut is in directory /bar then you need mc -I/bar foo.
  919.     -l
  920.        Produce a list file showing the compiler output (name.LST).
  921.     -t tname
  922.        Use external token file tname.TOK.  This a code crunching
  923.      option.  Useful when Mutt is used as an embedded language.
  924.      Normally, when MC can't resolve a function call (to an external
  925.      function), the name is looked up at runtime.  This has two
  926.      disadvantages - the name takes up space and it takes time to
  927.      look up the name.  The token file tells MC where the external
  928.      functions are located and avoids these problems.  It is only
  929.      used at compile time.
  930.     -v
  931.        Display the version of the compiler.
  932.  
  933.    You can run your compiled program in one of two ways:  If Mutt is
  934. embedded in another program, read the documentation on that program to
  935. find out how to load and run Mutt programs.  If you are using Mutt
  936. standalone (using just the functions contained in this documentation)
  937. then use MM2 (the Mutt2 Machine).  Type "mm2 fname" where fname is the
  938. name of the file you compiled.
  939.  
  940. For example, to compile and run the factorial program listed above:
  941.   mc2 fact            ; type this to compile the fact program
  942.   Mutt2 compiler 10/16/91
  943.   Errors: 0  Warnings: 0. Code size = 99 bytes.
  944.  
  945.   mm2 fact            ; type this to run the fact program
  946.   Take factorial of: 5        ; user is prompted for a value and types 5
  947.   5! = 120            ; the answer is printed out
  948.  
  949. ======================================================================
  950.                    Gotchas
  951. ======================================================================
  952. * Be careful of name overlap.  Note that the following program is legal
  953.   but may not do what you think.
  954.      (const foo 123)
  955.      (defun foo
  956.      {
  957.        (int foo)
  958.        (foo foo)    ; what does this line really do???
  959.      })
  960.  
  961. ======================================================================
  962. ======================================================================
  963.