home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / mutt / mutt.doc < prev    next >
Lisp/Scheme  |  1988-10-24  |  25KB  |  640 lines

  1. ========================================================================
  2. ==        The Mutt Programming Language       Craig Durland 9/88 ==
  3. ========================================================================
  4.  
  5. symbol    action
  6.   (    evaluate expression
  7.   )    end expression
  8.   {    start pgm
  9.   }    end pgm
  10.  
  11. SYNTAX
  12. pgm : {exp [exp ...]}, {}
  13. exp : (fcn [args]), (var [args]), var, const, ()
  14. const : number (123, 0xAbC), string ("abc", 'abc'), TRUE, FALSE
  15. arg : block
  16. block : pgm, exp or const
  17. fcn : a Mutt function (such as + or while) or defined function.
  18.  
  19. ======================================================================
  20.         Return Values
  21. ======================================================================
  22. All blocks return a value.  Pgms return the value of the last exp
  23.   executed. 
  24. The class of a return value can be one of:
  25.   BOOLEAN    TRUE or FALSE
  26.   BLOB        a pointer to a block of data
  27.   NUMBER    32 bit signed integer
  28.   STRING    a bunch of characters
  29.   VOID        a type of nothing
  30.  
  31. ======================================================================
  32.         Variables (aka vars)
  33. ======================================================================
  34. CREATION
  35.   Vars must be created (and allocated) before they can be used.
  36.   Global vars are initialized to:
  37.       bool: FALSE
  38.       INT, int, byte: 0
  39.       string: ""
  40.   Local vars are NOT initialized (ie they contain garbage when
  41.     created).
  42. EVALUATION & ASSIGNMENT
  43.   Vars behave like fcns, ie (var) evaluates the var (returns its value)
  44.     and (var val) passes val to the var for assignment.  (var val)
  45.     returns val.  If you just want to evaluate a var, you can treat it
  46.     like a const - ie var is equivalent to (var).  Note, however, doing
  47.     this may cause logic bugs if var also happens to be the name of a
  48.     const (since the const is locked out).  See GOTCHAS.  In some cases,
  49.     (var) and var don't mean the same thing - see pointer.
  50.   Cascading assignment:  you can assign multiple vars the same value.
  51.     eg (int x y z)(x (y (z 123))) assigns 123 to x, y and z.
  52.     eg (int x)(string s 20)(x (atoi (s "123"))) sets s to "123" and x
  53.       to 123.
  54. SCOPE
  55.   The scope of a variable is the same as the pgm it is allocated in.
  56.   A variable  allocated  outside of a fcn is global - ie anybody can get
  57.     at it.  Global  variables  are  local to the file (and any  included
  58.     file(s)) they are allocated in.
  59.   For example:
  60.     If foo.mut contains:
  61.       (int foo)        ; declare and allocate global var "foo"
  62.       (defun "hoho" {(int bar)(bar foo)})
  63.       (foo 123)        ; assign 123 to foo
  64.     (load "foo.mut") will create a global var foo.  (hoho)
  65.     creates bar and sets it to 123.  hoho is done and bar is deallocated.
  66.     foo remains allocated and equal to 123.
  67.  
  68. ======================================================================
  69.         Functions and Keywords
  70. ======================================================================
  71. Everything in this list is a function except those that have a return
  72.   class of zip.
  73.  
  74. KEYWORD [arg class(s) : return class] 
  75.  
  76. ; a comment that extends to the end of the line
  77. (== value value ...)    [STRINGs, NUMBERs or BOOLEANs : BOOLEAN]
  78.   Test 2 or more items for equality.  
  79.   You can only compare like types - eg (== "123" 123) is illegal.
  80.   eg (== foo 1), (== "one" "two"), (== (+ foo 3) bar 5).
  81. (!= value value)    Same as == but nonequality.  Only 2 items.
  82. (<  value value)    [NUMBER NUMBER : BOOLEAN]
  83. (<= value value)    [NUMBER NUMBER : BOOLEAN]
  84. (>  value value)    [NUMBER NUMBER : BOOLEAN]
  85. (>= value value)    [NUMBER NUMBER : BOOLEAN]
  86. (+ values)        [NUMBERs : NUMBER]
  87.   add a bunch of numbers  eg (+ 1 2 3 4) => 1+2+3+4
  88. (- values)    [NUMBERs : NUMBER]
  89.   subtract a bunch of numbers eg (- 1 2 3 4) => 1-2-3-4 = -8
  90. (* values)    multiply a bunch of numbers    [NUMBERs : NUMBER]
  91. (/ values)    divide a bunch of numbers    [NUMBERs : NUMBER]
  92. (+= var values)        [TOKEN, NUMBERs : NUMBER]
  93.   Add value(s) to var and assign it back to the var.  Returns the result.
  94.   Short hand for (var (+ var values)).
  95.   eg (+= foo 1) (+= foo fud 3) 
  96. (-= var values)        Subtract value from var. [TOKEN, NUMBERs : NUMBER]
  97. (*= var values)        Multiply var by value.    [TOKEN, NUMBERs : NUMBER]
  98. (/= var values)        Divide var by value.    [TOKEN, NUMBERs : NUMBER]
  99.  
  100. "string"
  101.   String constant.
  102.   Special characters:
  103.     \    quote the next character.  "\\" => '\'   "\^" => '^'
  104.     ^    convert the next character to a control character (make sure that
  105.       the letter is UPPERCASE!).  eg "^A"
  106.     Note: escape == ^[.
  107. 'string'
  108.   String constant.
  109.   No special characters except '' reduces to ' ie if you need a string
  110.     like "don't" use 'don''t'.
  111.   This form is handy for regular expressions.
  112.  
  113. (and values)            [BOOLEANs : BOOLEAN]
  114.   Logically and a bunch of things
  115.   The first FALSE value will terminate (ie the rest of the and will
  116.     not be evaluated).    eg (and (previous-line) (foo))
  117. (array type name dimensions)    [TOKEN TOKEN NUMBERs [TOKEN NUMBERs] : zip]
  118.   Create an array.  Types allowed: bool, int, INT, string.
  119.   (array int x 5 z 7) creates two arrays:  x with 5 ints and z with 7.
  120.   (array INT y 2 3) creates an array with 2 rows of 3 INTs each.
  121.   (array string s 5 80) creates 5 strings that can each hold up to 80
  122.     characters.
  123.   (x 3 123) sets the third element of x to 123.
  124.   (x 3) returns 123.
  125. (arg n)            [NUMBER : any class]
  126.   Get the nth argument from the parameter list.
  127.   The arguments are numbered 0,1...,(nargs)-1
  128.   eg (foo 1 "two" (three)) has 3 arguments:  numeric 1, string "two" and
  129.     whatever  fcn three  returns.  (arg 0)  returns  1, (arg 1)  returns
  130.     "two",  (arg 2) returns  result of  (three).  (arg 3), (arg -1), etc
  131.     error.
  132.   Notes:
  133.     You cannot set a arg unless it is a pointer.
  134.   See also: ask, defun, nargs.
  135. (ask prompt)        [STRING : STRING]
  136.   Get the next argument from the argument list; if the argument list is
  137.     empty, query the user.
  138.   eg if (foo (ask "foo = ")) is in fud then (fud "hoho") will pass "hoho"
  139.     to foo.  (fud) will cause the message "foo = " to appear and will wait
  140.     for a response to assign to foo.
  141.   You can force the pgm to query the user with (ask-user).  If you do
  142.     this, you will need one per ask.  The next unmodified ask will behave
  143.     as above.
  144.   See also: arg, ask-user, atoi.
  145. (ask-user)            [zip : VOID]
  146.   The next ask will query the keyboard and not the program args.
  147.   Turned off after every ask.
  148.   See also: ask.
  149. (atoi string)            [STRING : NUMBER]
  150.   Convert a string to a number.  If the string is not numeric,
  151.     atoi returns 0.
  152.   eg (foo (atoi (ask "A number please: ")))
  153.   Note: To convert a number into a string, use concat.
  154.     eg (string s 20)(s (concat 123)) will convert numeric 123 into a
  155.     string and assign it to s.
  156.   See also: ask.
  157.  
  158. (bool var [var ...])        [TOKENS : zip]
  159.   Evaluation & assignment: var, (var value) [TOKEN [BOOLEAN] : BOOLEAN]
  160.   Allocate 1 or more boolean variables.
  161.   Example: (bool foo)(foo TRUE)  ; set foo TRUE
  162.   See also: int, string.
  163. (break)                [zip : zip]
  164.   Get out of the smallest enclosing for or while loop.  The loop then
  165.     retuns the value of the last block executed.
  166.   See also: continue, for, while.
  167. (byte var [var ...])        [TOKENs : zip]
  168.   Evaluation & assignment: var, (var value) [TOKEN [NUMBER] : NUMBER]
  169.   Allocate 8 bit unsigned integers.
  170.   The range of a int is [0 : 255].
  171.   Note that a NUMBER may not fit in a byte.
  172.   See also: int, INT.
  173.  
  174. (case test body ...)
  175.   [[BOOLEAN, block, [BOOLEAN, block ...]] : last block executed]
  176.   Same as  nested  if's.  If the  test is TRUE  then the next  block  is
  177.     executed and the case is ended.  Otherwise the next block is skipped
  178.     and the cycle repeats.
  179.   eg
  180.   (string str 50)(str (ask "str = "))
  181.   (case
  182.     (== str "one")(msg "number 1")
  183.     (== str "foo")(msg "bar")
  184.     TRUE (msg str " is not something I know about.")
  185.   )
  186.   See also: switch
  187. (concat parameters)        [anything : STRING]
  188.   Concatenate parameters.
  189.   eg (concat "foo = " foo) return "foo = 123" if foo is 123 or "123".
  190. (const name value [name value ...])   [TOKEN BOOLEAN|NUMBER|STRING : zip]
  191.   Create one or more constants.  Used like other constants (such as
  192.     numbers, strings, etc).
  193.   Precedence: args, local vars, global vars, pgms, consts.
  194.   eg
  195.     (const foo 123 bar "hoho")
  196.     (msg foo bar)    ; this prints "123hoho")
  197.   Note: Do not use ()'s around constants - they are for functions only.
  198.     See GOTCHAS.
  199. (continue)            [zip : zip]
  200.   Go to the bottom of the smallest enclosing for or while loop.
  201.     If in a for loop, this means the inc part.
  202.   See also: break, for, while.
  203.  
  204. (defun name [arglist] [modifier(s)] pgm   [name ...])
  205.     [TOKEN [([type] TOKEN)...] [TOKENs] pgm : zip]
  206.   Define (ie compile) a function.  Multiple functions can be defined.
  207.   Comments and whitespace have no performance or size penalty, so use
  208.     them.
  209.   You can optionally name the arg list.  
  210.     ([type] name [dimension(s)] [name [dimension(s)]] ...) ...
  211.     INT, int and byte all mean NUMBER  (since all  numerics are promoted
  212.     to NUMBER  when  passed).  Do not  include  the length  when  naming
  213.     strings.  Array  subscripts  are used to determine the dimension the
  214.     passed in array - the first dimension  is a  placeholder  (as in C).
  215.     Arg type is  optional - if not used, no  assumations  are made about
  216.     the the arg (ie it will be type  checked at runtime if  needbe).  If
  217.     an arg is typed,  what  ever is  passed in is  assumed  to be of the
  218.     correct type - it is not checked.
  219.   Modifiers are used to put conditions on a function.
  220.     modifier : what it does    
  221.     HIDDEN     Only functions defined after this one can reference it.
  222.     MAIN       This function will be executed when it is loaded.
  223.   MAIN is a special function name.  It defines a function that is
  224.     executed at load time (the same as a function marked MAIN) and can
  225.     not be called by anyone.  Use MAINs to do things that only need to
  226.     be done once before anything else is done (for example, initializing
  227.     some variables).  Use the modifier MAIN if you also want to be able
  228.     to repeat things at other times.  There is no limit on the number of
  229.     MAIN functions or functions marked MAIN.  MAINs are called in the
  230.     order that they are defined.  Functions marked MAIN are called
  231.     alphabetically.
  232.   For example:
  233.     (defun
  234.       foo { (msg "this is foo") }    ; (foo) prints "this is foo"
  235.       bar (int x y)(string s)    ; bar has 3 args: 2 numbers and a string
  236.         {
  237.       (msg s)    ; same as (msg (arg 2))
  238.       (msg (+ x y))    ; same as (msg (+ (arg 0)(arg 1)))
  239.     }
  240.       fred (z) { (msg z (arg 1)) }    ; print the first and second args
  241.     )
  242.   Notes:
  243.     You can not assign to an arg unless it is a pointer.
  244.   See also: arg, pointer, the example pgms.
  245. (done)            [zip : zip]
  246.   Exit smallest enclosing pgm.
  247.   See also: halt.
  248.  
  249. FALSE            [zip : BOOLEAN]
  250.   The boolean constant FALSE.
  251. (floc function-name [args])
  252.   [TOKEN|STRING : BLOB] or [TOKEN|STRING any : last block executed]
  253.   Return the address of a function or call a function.
  254.   Note that the keywords and functions in this list are not "real"
  255.     functions - ie they have no address and can't be called from floc.
  256.   If given args, a function call is generated.  If you want to call a
  257.     function that has no args, use () as the args list
  258.     (eg "(floc "foobar" ())").
  259.   Example:
  260.     (defun
  261.       add (pointer defun plus) (x y)
  262.     { (msg x " + " y " = " (plus x y)) }
  263.       add-two-numbers (int a b) { (+ a b) }
  264.       silly-add (a b) { "three" }
  265.     )
  266.     (add (floc add-two-numbers) 1 2)    ; 1 + 2 = 3
  267.     (add (floc silly-add) "one" "two")    ; one + two = three
  268.   Notes:
  269.     (floc foobar) returns the address of a already defined function.  If
  270.       foobar has not been defined yet, an error is generated.
  271.     (floc "foobar"):  The location of foobar is resolved at runtime.  This
  272.       is slower and generates more code but always works (if foobar really
  273.       is a function and not a typo).
  274.   See also: loc, defun, pointer, qsort (in the EXAMPLE PGMS below)
  275. (for init test inc body)
  276.     [block, BOOLEAN, block, block : FALSE (unless break used)]
  277.   A for next loop:  perform init once.  Perform body and inc while
  278.     test is TRUE.  This is equivalent to:
  279.     init (while test { body inc })
  280.   break will terminate the loop and continue will jump to inc.
  281.   For example:
  282.     (int j)
  283.     (for (j 1) (< j 6) (+= j 1)
  284.     {
  285.       (if (== j 3)(continue))    ; skip 3
  286.       (msg j)
  287.     })
  288.     prints out: 1 2 4 5
  289.   See also: break, continue, while.
  290.  
  291. (halt)            [zip : zip]
  292.   Halt the mutt machine.
  293.   See also: done.
  294.  
  295. (goto label)        [TOKEN : zip]
  296.   Even if you dare, use this with care.
  297.   Don't cross defun boundaries.
  298.   See also: label.
  299.  
  300. (if test true [false])    [BOOLEAN, block, block : last block executed]
  301.   test and true must exist even if blank (ie "{}" or "()").
  302.   eg (if (== foo bar)(msg "foo == bar")(msg "foo != bar"))
  303.      (== foo bar)(if () (msg "foo == bar"))
  304.   The C conditional expression "condition ? true : false" can be mimiced
  305.     with (if condition true false).
  306. (include filename)        [TOKEN|STRING : zip]
  307.   Compile another file.  After filename is compiled,  compiling  resumes
  308.     at the line after the one that contained the include.
  309.     ie  "(include foo.mut)" is the same as "(include foo ; doo daa"
  310. (INT var [var ...])        [TOKENs : zip]
  311.   Evaluation & assignment: var, (var value) [TOKEN [NUMBER] : NUMBER]
  312.   Allocate 32 bit integers.
  313.   The range of a INT is [-2,147,483,648 : 2,147,483,647].
  314.   See also: bool, byte, int, string.
  315. (int var [var ...])        [TOKENs : zip]
  316.   Evaluation & assignment: var, (var value) [TOKEN [NUMBER] : NUMBER]
  317.   Allocate 16 bit integers.  The only  advantage of using int instead of
  318.     INT is that ints use less storage.
  319.   The range of a int is [-32,768 : 32,767].
  320.   Note that a NUMBER may not fit in a int.
  321.   See also: bool, byte, INT, string.
  322.  
  323. (label label-name)        [TOKEN : zip]
  324.   The target of a goto.
  325.   eg (label foo)(goto foo) creates an infinite loop.
  326.   See also: goto.
  327. (loc var)            [TOKEN : BLOB]
  328.   Return the address of a variable.  In this way you can modify the
  329.     variables you pass to functions.
  330.   Example:
  331.     (int a b c d)    ; 4 ints in row.  Same order as (array int a 4)
  332.     (defun
  333.       foo (array int x 2)  ; first element of x maps to a
  334.       {
  335.     (msg "(x 0) = " (x 0))    ; display the value of a
  336.     (x 0 456)        ; set a to 456
  337.     (x 1 111)        ; set b to 111
  338.       }
  339.       bar (pointer int x)
  340.     { (msg "x = " (x)) }    ; display the value of a
  341.     )
  342.     (a 123)(foo (loc a))(msg "a = " a "   b = " b)
  343.     (bar (loc a))
  344.     When this is run it produces:
  345.     (x 0) = 123
  346.     a = 456   b = 111
  347.     x = 456
  348.   See also: arg, defun, floc, pointer.
  349.  
  350. (msg stuff)            [any class : STRING]
  351.   Prints a message.  The list is concatenation of the arg list.
  352.   Returns the entire message.
  353.   eg (msg "foo = " foo)
  354.  
  355. (nargs)                [zip : NUMBER]
  356.   Return the number of parameters passed to the function.
  357.   eg (foo 1 "two" (three)) has 3 arguments and (nargs) returns 3.
  358.   See also: arg.
  359. (not value)            [BOOLEAN : BOOLEAN]
  360.   Negate value.  eg (not (== foo 1)).
  361. (novalue)            [zip : VOID]
  362.  
  363. (or value ...)            [BOOLEANs : BOOLEAN]
  364.   Logically or a bunch of things.
  365.   The first TRUE value will terminate (ie the rest of the or will
  366.     not be evaluated).  eg (or (beginning-of-line) foo)
  367.  
  368. (pointer type var-names)    [TOKEN TOKENs : zip]
  369.   Declare pointer vars.  You can create pointers to byte, int, INT,
  370.     bool, string, and defun (functions).
  371.   Assignment: (pv location) where location is a pointer
  372.     arg or something returned by loc or floc.
  373.   Pointers to data:
  374.     To get what a pointer points to: (pv)
  375.   Pointers to functions:
  376.     (pf) calls function pointed to by pf with no args.
  377.     (pf arg1 ... argn) calls pf with n args.
  378.   See also: defun, floc, loc.
  379. (push-args n)            [NUMBER : last arg]
  380.   Push all the args from n back on the stack.  The first arg is 0.
  381.   For example: If max is a function that takes the maximum of all its args,
  382.     and foobar is a function that takes a string and a list of numbers and
  383.     you want to find the maximum of those numbers, you could:
  384.     (defun foo (string s) { (int m) (m (max (push-args 1))) })
  385.   Notes:
  386.     push-args can only be used with defined functions plus concat and msg.
  387.       For example (+ (push-args 3)) is an error, (msg (push-args 3)) is OK.
  388.     If n is greater than the number of args, no args are pushed and no
  389.       error is generated.
  390.     You can treat push-args like a run-of-the-mill arg - eg (foo 123
  391.     (push-args 2) "hoho") and (foo (push-args 4) (push-args 2)) are OK.
  392.  
  393. (string var length [var length ...])    [TOKEN NUMBER ... : zip]
  394.   Evaluation & assignment: var, (var value) [TOKEN [STRING] : STRING]
  395.   Allocate some strings of length characters.
  396.   eg (string foo 10) foo will be able to hold up to 10 characters.
  397.   Note:  There is no length checking when assigning to strings.
  398.   See also: array, bool, int.
  399. (strlen string)            [STRING : NUMBER]
  400.   Returns the length of the string.
  401. (substr string index length)    [STRING, NUMBER, NUMBER : STRING]
  402.   Return a string of length characters starting at index (0 = first
  403.     character). 
  404.   If length or index are <0 then the length of the string is added to them.
  405.   If index > length of string, it is set after the last character of the
  406.     string.
  407.   eg (substr "foobar" 0 3) => "foo", (substr "foobar" -1 1) => "r"
  408.      (substr "foobar" 0 -1) => "fooba"
  409.      (substr "foobar" 3 100) => "bar"
  410.      (substr "foobar" 50 100) => ""
  411. (switch value  value block [value block ...] [default block])
  412.   [NUMBER|STRING|BOOLEAN, same, block, same, block ... : last block executed]
  413.   Get a value.  Scan down the list until a matching value is found and then
  414.     execute the next block and exit the switch.
  415.   If no match is found, the default block is executed (if it exists).
  416.   All values must have the same class.
  417.   eg
  418.     (switch (substr (ask "Is the moon made of green cheese? ") 0 1)
  419.       "y" (msg "Not according to current scientific thought.")
  420.       "n" (msg "Probably the case.")
  421.       default (msg "Burp.")
  422.     )
  423.   See also: case
  424.  
  425. TRUE                [zip : BOOLEAN]
  426.   The boolean constant TRUE.
  427.   Use this for the default case in case.
  428.  
  429. (while test body)    [BOOLEAN, block : FALSE (unless break used)]
  430.   Perform body while test is TRUE.
  431.   For example: (int j) (j 0) (while (< j 5) { (msg j) (+= j 1) } )
  432.     will print out: 0 1 2 3 4.
  433.   A do..while loop can be constructed like so:
  434.     (while {body test} ())
  435.   You can use break to get out of the loop or continue to move back to
  436.     test.
  437.   See also: break, continue, for.
  438.  
  439. ====================================================================
  440.         How args are passed
  441. ====================================================================
  442. All args are  evaluated  before being  passed.  bytes, ints and INTS are
  443.   converted to NUMBER.
  444. Args are passed by value and  reference.  Value  means a copy of the arg
  445.   is pushed on the stack and changes to it will not be reflected  in the
  446.   original.  When  something  is passed by  reference,  a pointer to the
  447.   original is pushed on the stack and changes will be to the original.
  448. - bools, numbers, voids:  value.
  449. - arrays, blobs, strings:  reference.
  450.  
  451. ====================================================================
  452.                      Example PGMS
  453. ====================================================================
  454.     ; Factorial the recursive way
  455. (defun
  456.   fact    ; the recursive part.  input: x  output: x!
  457.   {
  458.     (if (== (arg 0) 0) 1        ; 0! = 1
  459.       (* (arg 0) (fact (- (arg 0) 1)))    ; x! = x * (x-1)!
  460.     )
  461.   }
  462.   !    ; the main routine
  463.   {
  464.     (int x)
  465.     (x (atoi (ask "Take factorial of: ")))
  466.     (msg x "! = " (fact x))
  467.   }
  468. )
  469. (!)    ; (! 5) produces "5! = 120"
  470. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  471. (defun square        ; print a table of squares
  472. {
  473.   (int foo max)
  474.   (max (atoi(ask "Max = "))) (foo 1)
  475.   (while (<= foo max) {(msg foo "\^2 = " (* foo foo))(+= foo 1)})
  476. })
  477. ; (square 3) produces
  478. ; 1^2 = 1
  479. ; 2^2 = 4
  480. ; 3^2 = 9
  481. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  482. ; Good ol towers of hanoi
  483. ; Usage: (hanoi <n>) where n is the number of discs
  484. (defun
  485.   print-move (from to) { (msg "Move Disk From " from " To " to) }
  486.   transfer (from to via)(int n)
  487.   {
  488.     (if (== n 1)(print-move from to)
  489.     {
  490.       (transfer from via to (- n 1))
  491.       (print-move from to)
  492.       (transfer via to from (- n 1))
  493.     })
  494.   }
  495.   hanoi {(transfer "A" "B" "C" (atoi (ask "n = ")))(msg "done.")}
  496. )
  497. (hanoi)
  498. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  499. ; tobase(n,base): convert n (base 10) to base.  eg (tobase 10 16) => "A"
  500. ;    C Durland
  501.  
  502. (defun
  503.   mod (int n base)    ; n mod base = n - (n/base)*base
  504.     {(- n (* (/ n base) base))}
  505.   tobase (int n base)
  506.   {
  507.     (if (< n base) (substr "0123456789ABCDEF" n 1)
  508.       (concat
  509.         (tobase (/ n base) base)    ; tobase n/base base
  510.     (tobase (mod n base) base)    ; tobase (n mod base) base
  511.       )
  512.     )
  513.   }
  514. )
  515. (msg (tobase (atoi (ask "n = "))(atoi (ask "base = "))))
  516. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  517. (defun sort (array int list 1)(int n)    ; shell sort an array of n ints
  518. {
  519.   (int gap i j t k)
  520.   (gap (/ n 2))
  521.   (while (> gap 0)
  522.   {
  523.     (i gap)
  524.     (while (< i n)
  525.     {
  526.       (j (- i gap))
  527.       (while (and (>= j 0) (> (list j)(list (+ j gap))))
  528.       {
  529.     (k (+ j gap))(t (list j))(list j (list k))(list k t)
  530.     (-= j gap)
  531.       })
  532.       (+= i 1)
  533.     })
  534.     (/= gap 2)
  535.   })
  536. })
  537. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  538.     ; Quick sort.  From Horowitz & Sahni pg 347
  539.     ; Sort list[m..n] into assending order
  540.  
  541.     ; swap is a routine that interchanges list[a] with list[b]
  542.     ; cmp compares list[a] with list[b] and returns:
  543.     ;    negative if list[a] < list[b]
  544.     ;    positive if list[a] > list[b]
  545.     ;    zero     if list[a] = list[b]
  546. (defun
  547.   Qsort (list)(int m n)(pointer defun swap cmp)
  548.   {
  549.     (int i j)
  550.  
  551.     (if (>= m n)(done))
  552.     (i m)(j (+ n 1))
  553.     (while TRUE
  554.     {
  555.       (while { (+= i 1)(and (<= i n) (< (cmp list i m) 0)) } ())
  556.       (while { (-= j 1)(> (cmp list j m) 0) } ())
  557.       (if (< i j) (swap list i j) (break))
  558.     })
  559.     (swap list m j)
  560.     (Qsort list m (- j 1) swap cmp)
  561.     (Qsort list (+ j 1) n swap cmp)
  562.   }
  563. )
  564.     ; swap and cmp routines for arrays of ints
  565. (defun
  566.   swap (array int list 1)(int a b)    ; swap 2 elements
  567.   {
  568.     (int tmp)
  569.     (tmp (list a))(list a (list b))(list b tmp)
  570.   }
  571.   cmp (array int list 1)(int a b)    ; compare 2 elements
  572.     { (- (list a)(list b)) }
  573. )
  574.  
  575. ; (array int list 100)
  576. ; (Qsort list 0 n (floc swap) (floc cmp))
  577.  
  578. ======================================================================
  579.         Notes and Tricks
  580. ======================================================================
  581. * Lets say you have a number and wish to turn it into a string with a
  582.   leading zero if it is less than 10.
  583.     (int n)(string s 20)
  584.     (n (atoi (ask "n = ")))
  585.     (s (concat (if (< n 10) ("0")("")) n))
  586.   This trick also works in msgs, etc.
  587. * In general, only the last thing in a block matters.
  588.   So, (foo { (msg "set foo to 123") 123 }) is the same as
  589.     (msg "set foo to 123") (foo 123).
  590.  
  591. ======================================================================
  592. ======================================================================
  593.  
  594. HOW TO RUN THE COMPILER
  595.   Type "mc  filename".  filename is assumed to have a .MUT extension (ie
  596.     you don't have to type it).  The compiler produces an output file in
  597.     the current  directory with the name name.MCO where name is the same
  598.     base name as filename.
  599.   options:
  600.     -I dir: An alternate directory for include files.
  601.       For example, if foo.mut is in directory fred and contains
  602.       (include sam.mut) and sam.mut is in directory /bar then you need
  603.       mc -I/bar foo.
  604.     -l : produce a list file showing the compiler output (name.LST).
  605.     -t tname : use external token file tname.TOK.  This a code crunching
  606.      option.
  607.     -v : Display the version of the compiler
  608.  
  609. You run your compiled pgm with MM (the Mutt Machine).  Type "mm fname"
  610.   where fname is the name of the file you compiled.
  611.  
  612. For example, to compile and run the factorial pgm listed above:
  613.   mc fact    ; compile the fact pgm
  614.   Mutt compiler  11/20/87 CD
  615.   Errors: 0  Warnings: 0. Code size = 110 bytes.
  616.  
  617.   mm fact        ; run the pgm
  618.   Take factorial of: 5    ; user is prompted for value and types 5
  619.   5! = 120        ; the answer is printed out
  620.  
  621. ======================================================================
  622.             Gotchas
  623. ======================================================================
  624. * Be careful of name overlap.  Note that the following progam is legal
  625.   but may not do what you think.
  626.      (const foo 123)
  627.      (defun foo
  628.      {
  629.        (int foo)
  630.        (foo foo)    ; what does this line really do???
  631.      })
  632.  
  633. ======================================================================
  634.             Bugs
  635. ======================================================================
  636.  
  637. ======================================================================
  638. ======================================================================
  639. Copyright 1987, 1988 Craig Durland
  640.