mLisp ----- Table of Contents TABLE OF CONTENTS mlisp COMMAND LOOP BREAK COMMAND LOOP DATA TYPES THE EVALUATOR LEXICAL CONVENTIONS READTABLES SYMBOLS EVALUATION FUNCTIONS SYMBOL FUNCTIONS PROPERTY LIST FUNCTIONS ARRAY FUNCTIONS LIST FUNCTIONS DESTRUCTIVE LIST FUNCTIONS PREDICATE FUNCTIONS CONTROL CONSTRUCTS LOOPING CONSTRUCTS THE PROGRAM FEATURE DEBUGGING AND ERROR HANDLING ARITHMETIC FUNCTIONS BITWISE LOGICAL FUNCTIONS RELATIONAL FUNCTIONS STRING FUNCTIONS INPUT/OUTPUT FUNCTIONS FILE I/O FUNCTIONS SYSTEM FUNCTIONS EXAMPLES mlisp COMMAND LOOP When mlisp is started, it first tries to load "init.lsp" from the default directory. It then loads any files named as parameters on the command line (after appending ".lsp" to their names). It then issues the following prompt: > This indicates that mlisp is waiting for an expression to be typed. When an incomplete expression has been typed (one where the left and right parens don't match) mlisp changes its prompt to: n> where n is an integer indicating how many levels of left parens remain unclosed. When a complete expression has been entered, mlisp attempts to evaluate that expression. If the expression evaluates successfully, mlisp prints the result of the evaluation and then returns to the initial prompt waiting for another expression to be typed. BREAK COMMAND LOOP When mlisp encounters an error while evaluating an expression, it attempts to handle the error in the following way: If the symbol '*breakenable*' is true, the message corresponding to the error is printed. If the error is correctable, the correction message is printed. If the symbol '*tracenable*' is true, a trace back is printed. The number of entries printed depends on the value of the symbol '*tracelimit*'. If this symbol is set to something other than a number, the entire trace back stack is printed. mlisp then enters a read/eval/print loop to allow the user to examine the state of the interpreter in the context of the error. This loop differs from the normal top- level read/eval/print loop in that if the user invokes the function 'continue', mlisp will continue from a correctable error. If the user invokes the function 'clean-up', mlisp will abort the break loop and return to the top level or the next lower numbered break loop. When in a break loop, mlisp prefixes the break level to the normal prompt. If the symbol '*breakenable*' is nil, mlisp looks for a surrounding errset function. If one is found, mlisp examines the value of the print flag. If this flag is true, the error message is printed. In any case, mlisp causes the errset function call to return nil. If there is no surrounding errset function, mlisp prints the error message and returns to the top level. DATA TYPES There are several different data types available to mlisp programmers. o lists o symbols o strings o integers o floats o objects o arrays o file pointers o subrs (built-in functions) o fsubrs (special forms) Another data type is the stream. A stream is a list node whose car points to the head of a list of integers and whose cdr points to the last list node of the list. An empty stream is a list node whose car and cdr are nil. Each of the integers in the list represents a character in the stream. When a character is read from a stream, the first integer from the head of the list is removed and returned. When a character is written to a stream, the integer representing the character code of the character is appended to the end of the list. When a function indicates that it takes an input source as a parameter, this parameter can either be an input file pointer or a stream. Similarly, when a function indicates that it takes an output sink as a parameter, this parameter can either be an output file pointer or a stream. THE EVALUATOR The process of evaluation in mlisp: Integers, floats, strings, file pointers, subrs, fsubrs, objects and arrays evaluate to themselves Symbols evaluate to the value associated with their current binding Lists are evaluated by evaluating the first element of the list and then taking one of the following actions: If it is a subr, the remaining list elements are evaluated and the subr is called with these evaluated expressions as arguments. If it is an fsubr, the fsubr is called using the remaining list elements as arguments (unevaluated) If it is a list: If the list is a function closure (a list whose car is a lambda expression and whose cdr is an environment list), the car of the list is used as the function to be applied and the cdr is used as the environment to be extended with the parameter bindings. If the list is a lambda expression, the current environment is used for the function application. In either of the above two cases, the remaining list elements are evaluated and the resulting expressions are bound to the formal arguments of the lambda expression. The body of the function is executed within this new binding environment. If it is a list and the car of the list is 'macro', the remaining list elements are bound to the formal arguments of the macro expression. The body of the function is executed within this new binding environment. The result of this evaluation is considered the macro expansion. This result is then evaluated in place of the original expression. If it is an object, the second list element is evaluated and used as a message selector. The message formed by combining the selector with the values of the remaining list elements is sent to the object. LEXICAL CONVENTIONS The following conventions must be followed when entering mlisp programs: Comments in mlisp code begin with a semi-colon character and continue to the end of the line. Symbol names in mlisp can consist of any sequence of non-blank printable characters except the following: ( ) ' ` , " ; Uppercase and lowercase characters are not distinguished within symbol names. All lowercase characters are mapped to uppercase on input. Integer literals consist of a sequence of digits optionally beginning with a '+' or '-'. The range of values an integer can represent is limited by the size of a C 'long' on the machine on which mlisp is running. Floating point literals consist of a sequence of digits optionally beginning with a '+' or '-' and including an embedded decimal point. The range of values a floating point number can represent is limited by the size of a C 'float' ('double' on machines with 32 bit addresses) on the machine on which mlisp is running. Literal strings are sequences of characters surrounded by double quotes. Within quoted strings the '' character is used to allow non-printable characters to be included. The codes recognized are: \\ means the character '\' \n means newline \t means tab \r means return \f means form feed \nnn means the character whose octal code is nnn mlisp defines several useful read macros: '
== (quote ) #( ...) == an array of the specified expressions #x == a hexadecimal number #\ == the ASCII code of the character ` == (backquote ) , == (comma ) ,@ == (comma-at ) READTABLES The behaviour of the reader is controlled by a data structure called a "readtable". The reader uses the symbol *READTABLE* to locate the current readtable. This table controls the interpretation of input characters. It is an array with 128 entries, one for each of the ASCII character codes. Each entry contains one of the following things: NIL Indicating an invalid character :CONSTITUENT Indicating a symbol constituent :WHITE-SPACE Indicating a whitespace character (:TMACRO . fun) Terminating readmacro (:NMACRO . fun) Non-terminating readmacro In the case of the last two forms, the "fun" component is a function definition. This can either be a pointer to a built-in readmacro function or a lambda expression. The function should take two parameters. The first is the input stream and the second is the character that caused the invocation of the readmacro. The character is passed as an integer. The readmacro function should return NIL to indicate that the character should be treated as white space or a value consed with NIL to indicate that the readmacro should be treated as an occurance of the specified value. Of course, the readmacro code is free to read additional characters from the input stream. SYMBOLS o *obarray* - the object hash table o *standard-input* - the standard input file o *standard-output* - the standard output file o *breakenable* - flag controlling entering break loop on errors o *tracenable* - enable baktrace on errors o *tracelimit* - number of levels of trace back information o *readtable* - the current readtable o *unbound* - indicator for unbound symbols o *gc-flag* - controls the printing of gc messages EVALUATION FUNCTIONS (eval ) EVALUATE AN mlisp EXPRESSION the expression to be evaluated returns the result of evaluating the expression (apply ) APPLY A FUNCTION TO A LIST OF ARGUMENTS the function to apply (or function symbol) the argument list returns the result of applying the function to the arguments (quote ) RETURN AN EXPRESSION UNEVALUATED the expression to be quoted (quoted) returns unevaluated (backquote ) FILL IN A TEMPLATE the template returns a copy of the template with comma and comma-at expressions expanded (lambda [ ]...) MAKE A FUNCTION CLOSURE the argument list (quoted) expressions of the function body returns the function closure SYMBOL FUNCTIONS (set ) SET THE VALUE OF A SYMBOL the symbol being set the new value returns the new value (set! [ ]...) MODIFY THE VALUE OF A SYMBOL the symbol being modified the new value returns the new value (setf [ ]...) SET THE VALUE OF A FIELD the field specifier (quoted): set value of a symbol (car ) set car of a list node (cdr ) set cdr of a list node (nth ) set nth car of a list (aref ) set nth element of an array (get ) set value of a property (symbol-value ) set value of a symbol (symbol-plist ) set property list of a symbol the new value returns the new value (def [ ]...) DEFINE A FUNCTION (def-macro [ ]...) DEFINE A MACRO symbol being defined (quoted) list of formal arguments (quoted) this list is of the form: ([ ]... [&optional [ ]...] [&rest ] [&aux [ ]...]) where is a formal argument is an optional argument bound to the rest of the arguments is an auxiliary variable expressions constituting the body of the function (quoted) returns the function symbol (gensym [ ]) GENERATE A SYMBOL string or number returns the new symbol (intern ) MAKE AN INTERNED SYMBOL the symbol's print name string returns the new symbol (make-symbol ) MAKE AN UNINTERNED SYMBOL the symbol's print name string returns the new symbol (symbol-name ) GET THE PRINT NAME OF A SYMBOL the symbol returns the symbol's print name (symbol-value ) GET THE VALUE OF A SYMBOL the symbol returns the symbol's value (symbol-plist ) GET THE PROPERTY LIST OF A SYMBOL the symbol returns the symbol's property list (hash ) COMPUTE THE HASH INDEX FOR A SYMBOL the symbol or string the table size (integer) returns the hash index (integer) PROPERTY LIST FUNCTIONS (get ) GET THE VALUE OF A PROPERTY the symbol the property symbol returns the property value or nil (putprop ) PUT A PROPERTY ONTO A PROPERTY LIST the symbol the property value the property symbol returns the property value (remprop ) REMOVE A PROPERTY the symbol the property symbol returns nil VECTOR FUNCTIONS (vector [element]...) MAKE A NEW VECTOR (make-vector ) MAKE A NEW VECTOR the size of the new vector (integer) returns the new vector (vector-ref ) GET THE NTH ELEMENT OF A VECTOR the array the array index (integer) returns the value of the vector element (vector-set! ) SET THE NTH ELEMENT OF A VECTOR the array the array index (integer) the new value of the nth element returns the value of the vector element LIST FUNCTIONS (car ) RETURN THE CAR OF A LIST NODE the list node returns the car of the list node (cdr ) RETURN THE CDR OF A LIST NODE the list node returns the cdr of the list node (cxxr ) ALL CxxR COMBINATIONS (cxxxr ) ALL CxxxR COMBINATIONS (cxxxxr ) ALL CxxxxR COMBINATIONS (cons ) CONSTRUCT A NEW LIST NODE the car of the new list node the cdr of the new list node returns the new list node (list [ ]...) CREATE A LIST OF VALUES expressions to be combined into a list returns the new list (append [ ]...) APPEND LISTS lists whose elements are to be appended returns the new list (reverse ) REVERSE A LIST the list to reverse returns a new list in the reverse order (last
) RETURN THE LAST LIST NODE OF A LIST
the list returns the last list node in the list (member
]) FIND AN EXPRESSION IN A LIST the expression to find
the list to search
the keyword :test or :test-not the test function (defaults to eql) returns the remainder of the list starting with the expression (assoc [ ]) FIND AN EXPRESSION IN AN A-LIST the expression to find the association list the keyword :test or :test-not the test function (defaults to eql) returns the alist entry or nil (remove
]) REMOVE AN EXPRESSION the expression to delete
the keyword :test or :test-not the test function (defaults to eql) returns the list with the matching expressions deleted (length ) FIND THE LENGTH OF A LIST OR STRING the list or string returns the length of the list or string (nth
) RETURN THE NTH ELEMENT OF A LIST
the number of the element to return (zero origin)
the list returns the nth element or nil if the list isn't that long (nthcdr
) RETURN THE NTH CDR OF A LIST
the number of the element to return (zero origin)
the list returns the nth cdr or nil if the list isn't that long (mapc
]...) APPLY FUNCTION TO SUCCESSIVE CARS
the function or function name a list for each argument of the function returns the first list of arguments (mapcar [
]...) APPLY FUNCTION TO SUCCESSIVE CARS
the function or function name a list for each argument of the function returns a list of the values returned (mapl [
]...) APPLY FUNCTION TO SUCCESSIVE CDRS
the function or function name a list for each argument of the function returns the first list of arguments (maplist [
]...) APPLY FUNCTION TO SUCCESSIVE CDRS
the function or function name a list for each argument of the function returns a list of the values returned (subst [ ]) SUBSTITUTE EXPRESSIONS the new expression the old expression the expression in which to do the substitutions the keyword :test or :test-not the test function (defaults to eql) returns the expression with substitutions (sublis [ ]) SUBSTITUTE WITH AN A-LIST the association list the expression in which to do the substitutions the keyword :test or :test-not the test function (defaults to eql) returns the expression with substitutions DESTRUCTIVE LIST FUNCTIONS (set-car!
) REPLACE THE CAR OF A LIST NODE
the list node
the new value for the car of the list node returns the list node after updating the car (set-cdr!
) REPLACE THE CDR OF A LIST NODE
the list node
the new value for the cdr of the list node returns the list node after updating the cdr (nconc! [
]...) DESTRUCTIVELY CONCATENATE LISTS
lists to concatenate returns the result of concatenating the lists (delete!
]) DELETE AN EXPRESSION FROM A LIST the expression to delete
the keyword :test or :test-not the test function (defaults to eql) returns the list with the matching expressions deleted PREDICATE FUNCTIONS (atom ) IS THIS AN ATOM? the expression to check returns t if the value is an atom, nil otherwise (symbolp ) IS THIS A SYMBOL? the expression to check returns t if the expression is a symbol, nil otherwise (numberp ) IS THIS A NUMBER? the expression to check returns t if the expression is a number, nil otherwise (null ) IS THIS AN EMPTY LIST? the list to check returns t if the list is empty, nil otherwise (not ) IS THIS FALSE? the expression to check return t if the expression is nil, nil otherwise (listp ) IS THIS A LIST? the expression to check returns t if the value is a list node or nil, nil otherwise (consp ) IS THIS A NON-EMPTY LIST? the expression to check returns t if the value is a list node, nil otherwise (boundp ) IS THIS A BOUND SYMBOL? the symbol returns t if a value is bound to the symbol, nil otherwise (minusp ) IS THIS NUMBER NEGATIVE? the number to test returns t if the number is negative, nil otherwise (zerop ) IS THIS NUMBER ZERO? the number to test returns t if the number is zero, nil otherwise (plusp ) IS THIS NUMBER POSITIVE? the number to test returns t if the number is positive, nil otherwise (evenp ) IS THIS NUMBER EVEN? the number to test returns t if the number is even, nil otherwise (oddp ) IS THIS NUMBER ODD? the number to test returns t if the number is odd, nil otherwise (eq ) ARE THE EXPRESSIONS IDENTICAL? the first expression the second expression returns t if they are equal, nil otherwise (eql ) ARE THE EXPRESSIONS IDENTICAL? (WORKS WITH NUMBERS AND STRINGS) the first expression the second expression returns t if they are equal, nil otherwise (equal