diff --git a/Makefile b/Makefile index cc4cb2a6..59b2f438 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ EMULATOR ?= simh -SRC = system syseng sysen1 sysen2 sysnet kshack dragon channa midas _teco_ emacs rms klh syshst sra mrc ksc cstacy gren bawden emacs1 _mail_ l lisp liblsp +SRC = system syseng sysen1 sysen2 sysnet kshack dragon channa midas _teco_ emacs rms klh syshst sra mrc ksc cstacy gren bawden emacs1 _mail_ l lisp liblsp libdoc DOC = info _info_ sysdoc kshack _teco_ emacs emacs1 MINSYS = _ sys sys2 sys3 device emacs _teco_ sysbin inquir diff --git a/build/build.tcl b/build/build.tcl index 6bbd86d5..2bdc2442 100644 --- a/build/build.tcl +++ b/build/build.tcl @@ -498,6 +498,11 @@ respond "*" ":link sys;ts lisp,sys:purqio >\r" respond "*" ":link sys;ts q,sys;purqio >\r" respond "*" ":link sys;atsign lisp,sys;purqio >\r" +respond "*" ":link .info.;lisp step,.info.;step info\r" +respond "*" ":link libdoc;struct doc,alan;struct doc\r" +respond "*" ":link .info.;lisp struct,libdoc;struct doc\r" +respond "*" ":link l;-read- -this-,lisp;-read- -this-\r" + # ndskdmp tape respond "*" ":link kshack;good ram,.;ram ram\r" diff --git a/doc/_info_/cgol.doc b/doc/_info_/cgol.doc new file mode 100755 index 00000000..653b9803 --- /dev/null +++ b/doc/_info_/cgol.doc @@ -0,0 +1,1670 @@ + CGOL - an Algebraic Notation For MACLISP users + + V. R. Pratt + + 1/27/77 + + Common-Lisp annotations by G.J. Carrette 9/14/82 + +ABSTRACT + + MACLISP programmers who feel comfortable with ALGOL-like +notation, that is, an algebraic style in which one might write a +matrix multiply routine as + for i in 1 to n do + for k in 1 to n do + (ac := 0; + for j in 1 to n do + ac := ac + a(i,j)*b(j,k); + c(i,k) := ac) +can now write LISP programs in just such a notation. This notation is +essentially transparent to the MACLISP system, and files containing +CGOL code (possibly mixed in with standard code) can be read by the +interpreter and compiled by the compiler just as though they were +written in straight LISP notation. + +1. PHILOSOPHY + + 1.1 Representational Issues + + LISP S-expressions ("abstract" objects in a domain that +contains atoms and is closed under the pairing function CONS) require +an internal and an external representation ("concrete" objects). The +former is for the convenience of the programmer, the latter for that +of the machine. The functions (READ) and (PRINT) provide maps between +the two concrete representations. + + We use the term "LISP" principally to denote the abstract +objects; out of respect for usage, however, we shall also use it to +denote "the" standard external representation, which varies mainly in +detail from one implementation to the next. We rely on context to +disambiguate these usages. We use "INT" to denote whatever internal +representation obtains in a particular implementation; this may vary +considerably between installations. + + 1.2 CGOL as an alternative external representation. + + This document describes an alternative external +representation, CGOL, for those LISP S-expressions that encode +procedural information. The representation is modeled on McCarthy's +M-expression notation; as such it has Smith and Enea's MLISP language +as a predecessor. See section 8 for a discussion of similarities and +differences between MLISP and CGOL. + + In an environment that supports both CGOL and LISP external +representation, we envisage facilities for mapping between +representations as diagrammed below: + + + READ CGOLREAD + ------ ========> ----- <========= ------ + | LISP | | INT | | CGOL | + ------ <======== ----- =========> ------ + PRIN1 CGOLPRIN1 + + + This diagram of course generalizes to any set of external +representations. The beauty of it is that the entire system described +in this manual is no more than the implementation of CGOLREAD and +CGOLPRINT. Thus the MACLISP user wishing to experiment with CGOL can +immmediately begin by typing (CGOLREAD) to LISP and then typing in an +expression to see what it returns. The results of such an exercise +are given at the start of section 2. + + 1.3 Usage + + If LISP's top-level, a cut-down version of which might be + (PRINT (EVAL (READ))) , +is replaced by + (CGOLPRINT (EVAL (CGOLREAD))) +the top level should now expect CGOL notation, and reply in like +notation. If you prefer standard notation for output (the default if +you type (CGOL) as described below) then clearly you need + (PRINT (EVAL (CGOLREAD))) . + + In MACLISP, the function (CGOL) will set the variable READ to +CGOLREAD, achieving the above effect on MACLISP's top, break and edit +levels. Alternatively, for users who want to use only CGOL notation, +LISP can be invoked from top level via ":L CGOL;" and the LISP so +loaded will be already set up to use CGOL notation. Both (CGOLREAD) +and (CGOL) (but not CGOLPRINT) are autoloading. Thus if at any time +while talking LISP you suddenly want or need to use CGOL notation, you +need merely type (CGOL) at LISP and LISP will then expect CGOL +expressions. To revert to standard notation, type EXIT$ . (Throughout +this document we shall use $ to denote both altmode and dollar which +may be used interchangeably in CGOL, except that when typing directly +to LISP as opposed to creating a file of CGOL programs altmode should +be used to ensure immediate response of the system, which treats only +altmode as a "force-feed" character.) This implies that you may have +a mixture of CGOL and LISP programs in a single file, provided that +each block of CGOL code is preceded by (CGOL)$ (the $ is redundant but +useful if for any reason (CGOL) is taken to be in CGOL notation - it +is in fact legal CGOL notation provided the $ follows it) and is +followed by =EXIT$ (the = forces the exit to be executed even if read +but not eval'd by, say, the compiler). + + In Common-Lisp the function (CGOL) will set the readtable. +Since this needs to happen at readtime an entire file of CGOL expressions +should start with #.(CGOL) and end with =EXIT$. A more local way of +entering CGOL expressions is to use the readmacro "#$" for example: +#$ define fact(x) if x<1 then 1 else x*fact(x-1) $ + + 1.4 Design Considerations. + + The two principles that serve respectively as lower and upper +bounds on the choice of CGOL notation are: + +(i) The notation should fairly match what the non-LISP +community regards as a reasonable notation. In particular, users of +ALGOL, FORTRAN, PL/I etc, should not experience difficulty in guessing +the meanings of those constructs common to those languages, e.g. +assignment, application, arithmetic and relational operations, and the +more familiar control constructs. This requirement need not apply to +constructs peculiar to LISP, such as LIST, CONS, LAMBDA, EVAL, QUOTE +and so on. + +(ii) The notation should restrict itself to being a notation for +LISP abstract objects, and not try to be a full-blown programming +language with its own useful set of constructs. (This represents a +point of departure from the MLISP philosophy.) Useful constructs +should be added to LISP via the same channels (modulo choice of +notation) that are used regularly by all LISP users to augment LISP, +e.g. (DEFUN ...) or its CGOL equivalent. + + There is a tension between these two requirements that is at +present not appreciated by the bulk of the computer science community. +That tension is brought about by the two very different techniques for +specifying the syntax of ALGOL-like languages and the semantics of +LISP programs. The former is phrase oriented, the latter is +token oriented. ("Phrase" and "token" may be replaced respectively by +"non-terminal" and "terminal", to use the formal language +terminology.) A typical syntax specification uses BNF, i.e. a +context-free grammar, whereas LISP programs are specified in terms of +the meaning of atoms. The rich non-terminal structure of, say, the +syntax of ALGOL is replaced by a trivial non-terminal structure for +LISP, namely all non-atomic programs are of the form (FUNCTION +ARGUMENTS). + + Not all ALGOL-like languages are specified by their phrase +structure. From time to time attempts are made to use the powerful +macro facilities of assembly languages to implement "higher level" +languages. Since macros are identified by single tokens, they +constitute a token oriented specification. A limitation of the +approach is that the macro identifier must usually appear before its +arguments. Also a macro interpreter that allows nested calls must be +used. + + The CGOL notation uses a token oriented approach to fit +comfortably with constraint (ii). Unlike macro based approaches, a +given token may have either zero or one argument preceding it, in +addition to any number following it (suitably delimited). This gives +rise to the familiar association problem, which we deal with using +Floyd's notion of precedence functions. Each argument position of a +token has an associated "binding power"; association is resolved in +favor of the higher binding power. The binding power idea is due to +Floyd, who called the binding powers "operator functions"; the term we +use appears to have originated with CPL. The parsing algorithm we use +differs from Floyd's in that ours is left-corner whereas Floyd's is +pure bottom-up. The original version of the CGOL parser was +implemented at Stanford in July 1970; its use of binding powers was +copied soon after by Smith for the MLISP system. We discuss the +details of the association problem in section 3. + +2. EXAMPLES OF CGOL EXPRESSIONS + + The following examples of CGOL expressions, together with the +effect of doing (PRINT (CGOLREAD)) on them (i.e. their LISP +translations), are given below. To aid the eye we shall use upper +case for LISP and lower case for CGOL. Note that CGOLREAD demands an +ALTMODE or DOLLAR (not shown) after each CGOL expression. ALTMODE is +better for TTY input since it causes immediate response (force-feed). +In files, where force-feeding is irrelevant, DOLLAR is more convenient +to insert using TECO. + +1+1 +(PLUS 1 1) + +[1, '2+2', sin(.37*x+1)] +(LIST 1 '(PLUS 2 2) (SIN (PLUS (TIMES .37 X) 1))) + +\x,y; 1/sqrt(x**2 + y**2) +(LAMBDA (X Y) (QUOTIENT 1 (SQRT (PLUS (EXPT X 2) (EXPT Y 2))))) + +toplevel := 'print *; eval read' +(SSTATUS TOPLEVEL '(PROG2 (PRINT *) (EVAL (READ)))) + +car m & car m := cdr m +(PROG2 NIL (CAR M) (RPLACA M (CDR M))) + +'father' of x := 'brother' of relative of y +(PUTPROP X (GET (GET Y RELATIVE) 'BROTHER) 'FATHER) + +father ofq x := brother ofq relative of y % analog of SETQ % +(PUTPROP X (GET (GET Y RELATIVE) 'BROTHER) 'FATHER) + +a(i,j) := 3 +(STORE (A I J) 3) + +if numberp i and -jb then a.((a+1) to b) +(DEFUN TO (A B) (COND ((NOT (GREATERP A B)) (CONS A (TO (PLUS A 1) B))))) + +3. GRAMMAR + + A CGOL expression is a string of sub-expressions and tokens. +For example the expression "if a=b then 0 else i+1" has six +constituents corresponding to the six items in the "construct" + if a then b else c +In this example those constituents are: + the token "if" + the sub-expression "a=b" + the token "then" + the sub-expression "0" + the token "else" and + the sub-expression "i+1". +In turn, the sub-expression "a=b" has three constituents: + the sub-expression "a" + the token "=" and + the sub-expression "b". +And the sub-expression "a" has one constituent, the token "a". + + For those accustomed to BNF, the grammar of CGOL might look +like: + + ::= if then [else ] + ::= = + ::= () + ::= ; + +and so on. Since will be the only non-terminal, the left +hand side of productions may be omitted without loss of information. +Substituting variables for , we can then write CGOL rules +as: + + if a then b [else c] + a = b + (a) + a ; b + +and so on. + + As they stand, such rules are ambiguous. Does a=b;c mean +(a=b);c or a=(b;c) ? The problem is that each of "=" and ";" could take +b as its argument. We say that b associates with the one that takes +it as argument. Thus if "print a+b" means "print(a+b)", "a" has +associated with "+" in preference to "print". In CGOL, all such +disputes are resolved by binding powers, a sort of syntactic version +of atomic valences. Thus if the right binding power (rbp) of "=" is +10 and the left binding power (lbp) of ";" is 1, then a=b;c is read as +(a=b);c because the right hand argument slot of "=" pulls harder on b +than does the left hand argument slot of ";" . (Ties are broken by +associating to the left.) + + Left and right binding powers are completely independent. +Each is relevant when the expression can have a sub-expression +at the left and right hand ends respectively. Thus the left binding +power of "car" is irrelevant because "car a" does not have a +sub-expression at the left. However, it has one at the right, so its +right binding power is relevant. The opposite obtains for the suffix +operator "isatom", which has a left binding power but no right binding +power. In an expression like "if a then b else c", the right binding +power applies to all three arguments even though only the last may +actually be fought over by another operator to its right. + + In addition to the left-right association problem there is the +"dangling else" problem, named after an instance of the problem: does +"if a then if b then c else d" mean "if a then (if b then c else d)" +or "if a then (if b then c) else d" ? This problem is just a variant +of the left-right association problem; the argument "else d" could +associate with either the first or the second "if". In CGOL, all such +disputes are resolved by associating to the closer operator. (For +those who liked the atomic-valence analogy, imagine an inverse +(square?) law for distance holds.) + + The above two rules deal with most of the ambiguities that +might arise in the CGOL grammar given below. + + The following table lists the explicitly defined CGOL +constructs together with their translation into standard notation. +Except where otherwise noted, a,b,...,z denote CGOL expressions and +A,B,...,Z their corresponding standard forms. The table has three +columns, the CGOL form, the left and right binding powers when +relevant (only given once when they are the same, or when only one is +relevant), and the translation. + +---------BRACKETING OPERATORS--------- +(a) 0 A +f(a,b,...,z) 25 0 (F A B ... Z) +[a,b,...,z] 0 (LIST A B ... C) +a[b,c,...,z] 0 (MAPCAR (FUNCTION A) B C ... Z) +a{b} 0 (APPLY (FUNCTION A) B) +a[{b}] 0 (APPLY (FUNCTION MAPCAR) + (CONS (FUNCTION A) B)) + +---------QUOTING OPERATORS------- +'a' 0 'A +"a" (where a is a string) '|a| +?a (where a is a character) /a +#a (where a is any CGOL token) A +!A (where A is a LISP S-expr) A + +---------DECLARATIVE OPERATORS--------- +\ a,b,..,p; q;r;..;z 0 (LAMBDA (A B ... P) Q R ... Z) +let a=x,b=y,..,c=z;p;q;..;s 0 ((LAMBDA (A B ... C) P Q ... S) X Y ... Z) +let x,y,..,z={a}; b;c..;h 0 (APPLY '(LAMBDA (X Y .. Z) B C .. H) A) +(Think of {a} as "unpacking" a. This is consistent with its use +above as f{a}. "let x,y={a}, u=b, v,w={c};..." will do what you would +expect, translating into (APPLY '(LAMBDA (X Y U V W) ...) (APPEND A +(LIST B) C)) .) +prog a,b,..,p; q;r;..;z 0 (PROG (A B ... P) Q R ... Z) +new a,b,..,p; q;r;..;z 0 (PROG (A B ... P) Q R ... (RETURN Z)) +special a,b,...,z (DECLARE (SPECIAL A B ... Z)) + +---------CONTROL OPERATORS-------- +eval a 1 (EVAL A) +a;b;...;z 1 0 (PROGN A B ... Z) +a&b 1 0 (PROG2 NIL A B) +if a then b [else c] 2 (COND (A B) [(C)]) +return a 1 (RETURN A) +while a do b 2 (DO NIL ((NOT A)) B) +for i in l, j in m do f 2 (MAPC (FUNCTION (LAMBDA (I J) F)) L M) +for i in a to b do f 2 (DO ((I A (ADD1 I))) ((GREATERP I B)) F) +iter [for i := a step b] 2 (DO ((I A B) (J C D)) (E G) F) + [for j := c step d] + [until e] + [do f] + [return g] +(The [...] in the above all indicate optional items. Order is immaterial.) + +--------STORAGE OPERATORS------- +a of b := c 25 1 (PUTPROP B C A) +a ofq b := c 25 1 (PUTPROP B C 'A) +a:=b (a is atomic) 25 1 (SETQ A B) +x(a,b,...,z):=y 25 1 (STORE (X A B ... Z) Y) +a{b} := c 25 1 (STORE (APPLY (FUNCTION A) B) C) + (useful if a is an array whose dimensions are not fixed at compile time) +car a := b 25 1 (RPLACA A B) (similarly for cdr) +plist a := b 25 1 (SETPLIST A B) +arg a := b 25 1 (SETARG A B) +ttyread := a 25 1 (SSTATUS TTYREAD A) (etc) +a of b 25 24 (GET B A) + +---------LIST OPERATORS--------- +a.b 14 13 (CONS A B) +a@b 14 13 (APPEND A B) + +---------RELATIONAL OPERATORS-------- +a=b 10 (EQUAL A B) +a ne b 10 (NOT (EQUAL A B)) +a eq b 10 (EQ A B) +ab>...>z 10 (GREATERP A B ... Z) +a<=b 10 (NOT (GREATERP A B)) +a>=b 10 (NOT (LESSP A B)) + +(fixed point:) +a=#b 10 (= A B) +a<#b<#...<#z 10 (< A B ... Z) +a>#b>#...>#z 10 (> A B ... Z) + +(floating point:) +a=$b 10 (= A B) (just in case...) +a<$b<$...<$z 10 (<$ A B ... Z) +a>$b>$...>$z 10 (>$ A B ... Z) + +a|b 10 (ZEROP (REMAINDER A B)) +a isin b 10 (MEMBER A B) +a exists 10 (SETQ IT A) (use with caution) + +---------LOGICAL OPERATORS------- +not a 9 (NOT A) +a and b 8 (AND A B) +a or b 7 (OR A B) + +-------STRING OPERATORS---------- +a^b^...^z 18 (CAT A B ... Z) + +---------ARITHMETIC OPERATORS------- +|a| 0 (ABS A) ++a 20 A +a+b 20 (PLUS A B) +-a 20 (MINUS A) +a-b 20 (DIFFERENCE A B) +a*b 21 (TIMES A B) +a/b 21 (QUOTIENT A B) +a rem b 21 (REMAINDER A B) +a mod b 21 (MOD A B) (courtesy of CGOL) +a**b 22 (EXPT A B) + +(fixed point:) +a+#b 20 (+ A B) +a-#b 20 (- A B) +a*#b 21 (* A B) +a/#b 21 (// A B) + +(floating point:) +a+$b 20 (+$ A B) +a-$b 20 (-$ A B) +a*$b 21 (*$ A B) +a/$b 21 (//$ A B) + +---------BOOLEAN OPERATORS-------- +:n: a not 21 (BOOLE 12 0 a) +a :a: b and 21 (BOOLE 1 a b) +a :v: b or 20 (BOOLE 7 a b) +a :x: b xor 20 (BOOLE 6 a b) +a :^: b shift 22 (LSH a b) + +---------I/O OPERATORS------- +print a 2 (PRINT A) +princ a 2 (PRINC A) +write a 2 (PROG2 (TERPRI) (PRINC A)) +uread a b ... z (a-z are tokens) (UREAD A B ... Z) +uwrite a b ... z (UWRITE A B ... Z) +ufile a b ... z (UFILE A B ... Z) +load a b ... z (a-z are tokens) (FASLOAD A B ... Z) +newline (TERPRI) + +--------MISCELLANEOUS-------- +oct(a) (parens mandatory) parses a with IBASE=8 +=a 25 Translation is the value of the expression + at parse time. Useful in code that + would not otherwise be evaluated, e.g. + when compiling code. + + In addition to the above, CGOL "knows" about all the unary +functions in LISP. Thus although "car" does not appear in the above +table, CGOL knows that CAR is a LISP function with one argument. CGOL +treats all such functions f as though they were defined as + +f a 25 (F A) + + Note that f and a in the above must have some formatting +delimiter between them (space, tab or carriage return); thus car* is +not acceptable for car *, which translates as (CAR *). In general +CGOL permits atoms to have both values (i.e. to serve as variables) +and functional properties. Thus although "last [1,2,3]" will return +(3), you can set "last:=2" and find that the variable last now has +value 2. The advantage of this is that you do not have to memorize +the entire vocabulary of LISP before choosing a variable name. Make +sure you don't try to use any of the above-defined operators as +variables, or attempt to write them in the "f(x,y,z)" format; for +example, + and AND should not be used as variables, while +(x,y) and +-(a,b) will not parse because CGOL will not be able to distinguish +them from the legal +(x) and -(x) at the time it is reading the + or +-. Actually, these are about the only trouble spots, and provided you +stick to the algebraic use of + and - you won't encounter this sort of +problem. When in doubt you can always drop back into LISP by using +"!". However, that should rarely be necessary - it is intended mainly +for non-procedural items such as lists for doing MEMBER and ASSOC in. +If you can't recall the CGOL form of an expression (F A B ... Z) where +F does not itself have any special meaning to CGOL, you won't go wrong +by writing f(a,b,...,z). Thus if you forget the form "1+1", you can +write "PLUS(1,1)" and it will translate correctly. By the same token, +any LISP function not catered for in the above table can be written as +"f(a,b,...,z)", e.g. "assoc(a,b)". Care has been taken in the +definition of CGOL to avoid using LISP functions as CGOL operators +with special syntactic significance as far as possible, to permit +PLUS(1,1) and the like. However, some LISP functions remain in CGOL, +in particular +, -, * and /, along with PROG, EQ, NOT, AND and OR. +While these can to an extent be used as variables, this +is not recommended without preceding them with #, the syntax-removing +operator. However, except for + and -, all these operators can be +used without # as the function f in f{a} or f[a]. When you define +functions of your own using DEFINE, you should always invoke the +function just as you defined it. If you defined it as + define "F" a "ON" b; a+b$ then you should not call it with f(2,3) but +only with f 2 on 3 unless you precede the f with #, as in #f(2,3). +The only exception is when you define it with define "F"(a,b); a+b$ +which attaches no syntactic significance to f, but has the effect of +(DEFUN F (A B) (PLUS A B)) . + + At first sight the binding powers may seem a lot to learn. +However, they have been chosen on the basis of the data types their +operators take as arguments and return as results in order to minimize +the need for parenthesization. If you want to use CGOL notation but +don't want to have anything to do with binding powers, simply +parenthesize every CGOL expression as though you were writing in +LISP. However, if you omit all parentheses (apart from those needed +in constructs of the form f(a,b,...,z)) you will not often go wrong. +Most often you will want parentheses for grouping in arithmetic +expressions when the default priority ranking (|| + - * / mod **) +gives the wrong grouping, and when procedural expressions occur as +arguments to non-procedural expressions, e.g. "if a then (b;c)", +"(print a) + b", "a:=(b:=read)+1" and the like. + + Some operators have a right binding power one less than their +left binding power. This is to make those operators right +associative. For example, "a of b of c" is parsed as "a of (b of c)" +(since oftener than not that's what was intended), and "a@b@c" as +"a@(b@c)" (for efficiency). An interesting pair of right associative +operators is ";" and "&". These are duals of each other. They both +evaluate their arguments in the same order, but differ in the value +they return: a&b returns a, a;b returns b. By making both of them +right associative and giving them the same priority, they interact in +an elegant way. Suppose you want to evaluate a,b,...,z and to return +the value of k. Then the expression a;b;...k&...;z has the desired +effect. That is, follow every argument but the last with ";", except +for the one you want the value of, which if it is not the last should +be followed by "&". A common use for "&" is in tidying up after +computing some value, e.g. "x & x:=2" will set x to 2 and return the +old value, "a:=(b & b:=a)" will swap the contents of a and b without +using a temporary variable, and so on. Note that all this is really a +feature of LISP rather than of CGOL; however, the notation makes it +easier to see at a glance the intent of what would be relatively +difficult to follow in LISP. + +4. THE DEFINE FACILITY + + The CGOL analog of DEFUN is "define". In addition to allowing +the user to attach a lambda expression to some functional property of +an atom, it gives him some syntactic capabilities as well. + + If you don't want to take advantage of CGOL's syntactic +extensibility, just say +define "F"(x,y); x**2 + y**2 $ +or whatever it is you want to define. This is equivalent to LISP's +(DEFUN F(X Y) (PLUS (EXPT X 2) (EXPT Y 2))) +In calling F, the arguments should always be parenthesized, e.g. +f(1,2,3) . In this way CGOL can figure out that f is being applied to +(1,2,3) even though no syntax has been specified for F, because of the +way "(" is treated as an infix operator. If F is supposed to be a +fexpr, lexpr or macro then the appropriate word should follow define, +e.g. + +define lexpr "F"(x); arg(1) $ %Note that x is parenthesized, unlike in LISP% + + If you want syntax for f as well, then the basic form is + +define [fexpr|lexpr|macro] [,bp [,bp]]; body + +For example, the following could serve as a definition of "@": + +define a "@" b, 14, 13; if a then car a . (cdr a @ b) else b $ + + In this example, the pattern is a "@" b , and gives the rule +for this operator, and the two numbers give the two binding powers. +The body is what would normally appear as the body of a DEFUN. + + At present the allowable forms of patterns are few in number. +You may write a sequence of variables separated by one or more tokens +in string quotes (letters inside string quotes must be capitalized - +this is the one place where a distinction is drawn between upper and +lower case, in the sense that the reader maps all lower-case letters +not in string quotes to upper-case before thinking about what they +mean). The variables stand for CGOL expressions and the strings for +tokens (recall that a CGOL expression is a sequence of sub-expressions +and tokens). The sequence may start and end with either tokens or +variables. + + The first token in the pattern is called the operator, and the +remaining tokens are called delimiters. The operator is said to have +been defined. An operator may be defined twice only if it takes a +left argument in one case and no left argument in the other, this +being a criterion CGOL uses when deciding what a particular token in a +program means. In the above table, the operators "(", "+" and "-" all +have such dual meanings. The delimiters may appear in arbitrarily +many definitions, and arbitrarily often in each. A delimiter's +binding power is set to 0; thus in general delimiters cannot also be +used as LEDs, though they can serve as NUDs (e.g. |, which is both the +NUD for ABS and a delimiter). When you specify what delimiter is to +be used, you must stick to it; thus you cannot say +define "LOG" a "BASE" b; ...$ +and invoke it later with "log 3, 2"; you must say "log 3 base 2". + + The default binding power is 25 if none is specified, and +applies to both left and right binding powers. If one binding power +is given it is the left and right binding powers. If both are given, +they are respectively the left and right ones. + + Like LISP, CGOL is a one-pass system. This is so that a user +can type in a definition and have it take effect immediately. This +conflicts with the requirement in any system offering sophisticated +syntax that it be possible to use the syntax of an operator before it +has been defined. This requirement is nice in general, and essential +for mutually recursive function definitions. To get around this +problem, you may define the syntax of an operator at any time without +giving its semantics, simply by omitting the body of the define +command. This is not an elegant solution, and a later version of CGOL +may deal with this. (A possible solution is to keep around pieces of +unparsable text until they become parsable, and then parse them. Even +more dramatic is the solution of not parsing anything until it is to +be evaluated, i.e. dropping the unparsability condition from the +previous solution.) + +5. EXTENDING CGOL + + It is possible to add to or change the definitions of the +rules of CGOL (the ones in Section 2). To see examples of such +definitions, look under the heading BASE COMPONENT in the file +AI:PRATT;CGOL > . Given the above table, you should be able to get a +rough idea of how to write such definitions. + + The meaning of + +infix "+" 20 is "PLUS" + +is as follows. The infix operator "+" is being defined with left and +right binding power 20. (Had I said "infixr" it would make "+" right +associative by making its right binding power 19, one less than its +left.) The translation of "a+b" is then (PLUS A B) . Since the +argument positions are "standard" for infix operators, the only +information you really need to supply is what the LISP function name +is, so you say "is "PLUS"" . You don't have to use "is" - if you want +you can spell it out by saying ["PLUS", left, right] , which is a CGOL +program to build a list whose three elements are the atom "PLUS", the +left hand argument and the right hand argument. Notice the use of +this technique when defining + +infixr "&" 1 ["PROG2", nil, left, right] + +We can't say 'is "PROG2"' because that would mean '["PROG2", left, +right]'. + +6. HOW THE *FIX OPERATORS WORK + + (This treatment assumes an understanding of the basic +mechanism of the parser used for CGOL, which treats tokens as either +nuds, leds or delimiters. A nud (NUll Denotation) is a +lambda-expression of no arguments which is applied to NIL as soon as a +token denoting it is encountered by the parser without a left hand +argument. A led (LEft Denotation) is the same but with a left hand +argument. A delimiter is a token the parser does not access either +denotation of (though it may access its left binding power, lbp) +because some other denotation caused it to be skipped over (using +ADVANCE, often called by CHECK).) + + The *fix operators take three arguments with no delimiters +between them (except for nilfix which takes two and infixd which takes +four). + +arg1 is the name of the defined operator. It need not +be string-quoted, but I string-quote it anyway for visibility. It is +accessed as the value of token, which in the case of +strings is the string itself without quotes. Strings are the one +place in CGOL where lower-case is recognized, so if you do stringify +this arg, as I do, don't use lower-case. + +arg2 is the precedence, which is used for both lbp and rbp, except that in +infixr the rbp is taken to be one less than arg1. In infixd both lbp and +rbp are given. + +arg3 is the denotation, which is run at the time the parser bumps into +the operator. At that moment, token is bound to the token immediately +following that operator. Calling advance at that point will rebind +token to the next token. Advance returns the new value of token. In +the case of LEDs (LEft Denotations, namely infix, infixr, infixd, +infixm, suffix), the variable LEFT is lambda-bound (on entry to the +denotation) to the translation of the immediately preceding +expression. RIGHT is not a variable but a CGOL expression whose +translation is (PARSE r) where r is the right binding power as +determined by arg2. Thus each mention of RIGHT represents an +invocation of the parser. The parser assumes that the input pointer +is pointing to the first token of the expression to be parsed (that +token being the value of TOKEN). The parser returns the translation, +leaving the pointer at the token following the just-translated +expression. + +The IS operator is shorthand for ["FOO", left, right] (in the case of +infix) or its analogue for other *fixes, e.g. for nilfix it is +["FOO"], for prefix it is ["FOO",right], for suffix it is +["FOO",left], and for infixm it is a hairy beastie that results in 'a +foo b foo c foo d' translating as (FOO A B C D). + +To some extent you can figure some of this out by reading the +definitions of the *fix operators. Deffix takes 5 args: +the denotation type (NUD or LED, or XNUD or XLED if you are LEARNing +language X) +The appropriate IS operator +The name of the operator being defined +The left binding power +The right binding power + +The formal parameters of DEFFIX are referenced from outside DEFFIX in +a couple of cases, which makes it hard to figure out what's going on. +The comments in the list of special variables should alleviate that +somewhat. + +Incidentally, for development purposes, the LEARN-SPEAK-FORGET cluster +of functions makes definition of a new language quite painless in +CGOL. To learn definitions in language X, say LEARN "X" and +everything defined from then on using *FIX or DEFINE will be invisible +to CGOL. LEARN "" restores the standard effect of *FIX and DEFINE, +which is to specify CGOL denotations. When you say SPEAK "X" the +definitions learnt while LEARN "X" was in force take effect, +over-riding any prior CGOL definitions of the defined tokens. Both +LEARN and SPEAK work by rebinding variables. Thus the user can +achieve their effect by doing his own binding. If he uses lambda- or +prog-binding (CGOL makes lambda-binding more convenient than +prog-binding) then the effect of the binding will be undone on exit +from the expression doing the binding, whether the exit was normal or +abnormal, which has obvious advantages over the side-effect-oriented +LEARN and SPEAK functions. + + The conventions are: LEARN "X" binds CNUD to XNUD, CLED to +XLED and CLBP to XLBP. Standard CGOL takes X as the empty string. +SPEAK "X" binds NUDL, LEDL and LBPL to lists whose cdr is the previous +value before the SPEAK and whose car is XNUD, XLED or XLBP +respectively. (Hence SPEAKs may nest notations; thus if you say +SPEAK "X"; SPEAK "Y" then notation Y takes priority over notation X +which takes priority over standard CGOL notation.) FORGET undoes the +effect of the last SPEAK; it is careful not to forget CGOL itself. +If the user wishes to bind NUDL etc himself he does not have to nest +notations in the way SPEAK does; in particular, he can eliminate CGOL +notation altogether, say by binding NUDL to (XNUD), etc. However, +care should be exercised here to avoid permanently cutting off LISP +from the user in this way, e.g. by ending up with a language not +powerful enough to return to CGOL or LISP. + + These operations have several applications. One is for those +defining a whole new language. Another is for when a small and +temporary notation change is required; for example, in writing an +ALGOL parser, the infix ":" needs a different denotation inside array +declarations than elsewhere; thus just before parsing its argument, an +array declaration may say SPEAK "ARRAY" which will activate a +definition of ":" made when LEARN "ARRAY" was in force. At the end, +the array declaration should say FORGET. (Actually, in this example, +it would be more appropriate to lambda-bind LEDL and LBPL to (ARRAYLED +LED) and (ARRAYLBP LBP) respectively, so that the old bindings will be +restored automatically whether exiting normally or abnormally from the +array definition.) + + Other uses of LEARN, SPEAK and FORGET may be found in the +files TC >, EG > and MSYN >, all on the directory PRATT; at MIT-AI. + +8. LEXICAL EXTENSIONS + + The general CGOL rules for recognizing a token are that any +alphanumeric string forms a token (whence two alphanumeric strings juxtaposed +will look to CGOL like a single token), any string of digits with an optional +period forms a token, any "..." forms a token, non-printing characters (space, +tab, cr, lf) and comments (%...%) act as delimiters between consecutive tokens, +and non-alphanumeric printing symbols (glyphs) form tokens by themselves. + + It is possible to extend the class of tokens to include arbitrary +strings using the construct "newtok a,b,..." where a,b,... is a list of such +strings, inside string quotes. CGOL itself uses the following: + +newtok ":=", "<=", ">=", "=#", "=?$", "<#", ">#";, "?$", "<=", ">=", +"+#", "-#", "*#", "/#", "\\", "+?$", "-?$", "*?$", "/?$", ":N:", ":A:", ":V:", +":X:", ":^:" $ + + +7. COMPILATION + + Compilation of a CGOL file is done by invoking NCOMPL in the +same way as for a file in standard notation. That is, at DDT you say +:NCOMPL + + + The LISP compiler knows about the incantation (CGOL)$ and +evaluates it instead of outputting it. The autoload property of CGOL +means that if CGOL is not already loaded into NCOMPL it will be. When +=EXIT$ is encountered, the = forces CGOL to evaluate the EXIT +immediately, returning NCOMPL to LISP notation. The upshot of all +this is that provided each block of CGOL code in your file is preceded +with (CGOL)$ and followed by =EXIT$ , NCOMPL will have no trouble +understanding CGOL notation, even when mixed in with standard +notation. Since you need these commands in the file to interpret it +anyway, you should find that compiling a CGOL file requires no more +massaging of the file than if you had been writing in LISP notation +(e.g. declaring special variables, specifying types of variables). + +8. CGOLPRINT + + All of the above deals with CGOLREAD. CGOLPRINT is also +available, and supplies a good way to automatically convert standard +notation to CGOL notation. Thus the LISP program + (DO () (()) (CGOLPRINT (READ))) +will read a sequence of LISP expressions and print them (on whatever +output device is selected) in CGOL notation. CGOLPRINT, unlike PRINT, +makes an effort to prettyprint the output. It uses an extremely +efficient but simple-minded pretty-printing algorithm, avoiding the +overhead of the GRIND program. + +9. COMPARISON WITH MLISP + + The similarities between CGOL and Smith and Enea's MLISP are: + +(i) the use of ALGOL-like notation for LISP S-expressions + +(ii) the use of numeric operator precedence functions to resolve +association problems. + +(iii) the ability to export LISP translations of MLISP/CGOL programs +to sites supporting LISP but not MLISP/CGOL. + + The differences are: + +(i) MLISP is a sophisticated programming language offering many +facilities not appearing in LISP. These facilities are only visible +to the speaker of MLISP, and vanish if he wants to use them while +speaking LISP. (Due to the ubiquity of LISP's oblist, the user can +get at them from LISP, though they are undocumented and have names +starting with & to identify them as sytem names not for general +consumption.) Assignment to S-expressions is a particularly complex +example. In contrast, CGOL offers nothing but an alternative +notation for things already meant for consumption by LISP users. +This enables CGOL to be very small, both with respect to its +implementation and its manual. + +(ii) MLISP is a system that the user must call from the monitor, +whereas CGOL is a package that can be loaded into LISP when the +need arises. Hence a non-CGOL user can read a CGOL file without +having to commit himself to a CGOL-oriented system when he loads LISP. +In fact, when the I/O details are worked out as in Section 1.3 he may +never know that he was reading a CGOL file. + +(iii) CGOL is considerably more extensible syntactically than MLISP I +and considerably more efficient than MLISP II, which though +extensible uses backup to an excessive degree. + +10. EDITING CGOL PROGRAMS + + CGOL programs can be edited using the TECO editor just like +LISP programs. For ITS users, a recent development in LISP and TECO +has allowed LISP to have a copy of TECO as a subjob. The effect of +this is as though LISP had its own resident editor with all the power +of the TECO editor but with the added advantage that LISP can be more +selective about what it reads out of a file after the file has been +modified. In particular, TECO users with the appropriate macros +(either the EMACS macros or for non-EMACS users the LISPT MACROS file +on the .TECO.; directory of any ITS machine) can send a selected +fragment of their file to LISP by saying m,nM.ZLISP$ where m and n +specify the start and end of the buffer fragment to be sent to LISP. +CGOL users can take advantage of this scheme in exactly the same way +that LISP users can. Provided LISP's toplevel is expecting CGOL +notation at the time the user calls TECO()$ (which invokes TECO if +LISPT FASL DSK LIBLSP has been loaded), when the user returns from +TECO with a string of CGOL expressions (as determined by the m,n +argument to M.Z) LISP will correctly interpret those expressions. +(Pending repair of a bug, CGOL users must type a space when they +return to LISP, or LISP will do nothing. This should be the only +noticeable difference between LISP and CGOL for LISPT users.) + +11. MISCELLANEOUS + + Errors are dealt with exactly as in LISP, with the exception +of syntactic errors, which CGOL tries to patch, reporting on the +problem and the patch when it does so. Syntactic errors do not cause +a breakpoint to be entered, but errors that would do so in LISP do so +when using CGOL. While $P is one way (besides ^G) of exiting from a +break loop, the CGOL notation requires that the "$" be "querified", +the CGOL analog of slashifying. Also you need $ at the end rather +than space. Thus you would type +?$p$ + + +*********************************************************************** + SAMPLE PROGRAMS + + The following programs were written by the author for a +variety of purposes. Most of them deal with one or another +computational complexity problem. + + +(cgol)$ +% Sample CGOL programs for matrix multiplication % + +define a "MM" b; % Mat multiply - square matrices % +array a; array b; +let d := car dim a; +array c(d,d); + for i in 1 to d do + for k in 1 to d do + (let ac = 0; + for j in 1 to d do + ac := ac + a(i,j)*b(j,k); + c(i,k) := ac); +c +$ + +define a "MMR" b; % Mat multiply - rectangular matrices % +array a; array b; +let d1,d2 := {dim a}, d2b,d3 = {dim b}; +if d2 ne d2b then "Mismatch" else +(array c(d1,d3); + for i in 1 to d1 do + for k in 1 to d3 do + (let ac = 0; + for j in 1 to d2 do + ac := ac + a(i,j)*b(j,k); + c(i,k) := ac); +c) +$ + +=exit$ + +(cgol)$ + +% Maze-running program. Works for any number of dimensions. +Instructions for use: +Get a CGOL by saying :L CGOL; to DDT. +uread maze > ai pratt Q +init [3,3] +try source +survey + +Here is what the above commands mean. The "uread" selects the file +containing the maze program, and the control Q causes CGOL to read the +selected file. This has the effect of loading the maze program. Then +"init [3,3]" initializes the maze to a 3 by 3 maze in which ALL paths +are legal. "try source" will search for a path from source (defined +by init to be (0,0)) to destination (defined by init to be (2,2), the +opposite corner). Finally, "survey" causes a sequence of positions to +be printed out, forming a path from source to destination. To vary +this, it is possible to do, say, init [4,2,5] which will +initialize "maze" to a 4 by 2 by 5 array. After doing "init" but +before doing "try source", "maze" can be changed. To forbid a path +through, say, point (1,2), say to CGOL: +maze(1,2):="+" +If you want to set up all the elements of maze rapidly to the maze +-++ +--+ ++-- +(where + means forbidden and - means allowed), say +maze := !'(- + + - - + + - -) +where the list of +'s and -'s is what you get by reading the maze +left to right and then down. +To see what maze looks like, say +listarray 'maze' +This will print out a list of the contents of the maze array, row by +row but without delimiting one row from the next, in the same format +as was used above. If you want to save a particular +setting of the maze array for future use, just say +y := listarray 'maze' +To reset maze to that value, say +maze := y +You can also simply set y (or any other variable) to a maze by saying +y := !'(- + + - - + + - -) +A particular maze +-++- +---+ +-+-+ +-+-- +can be explored simply by saying +whynot + % + +'=array(maze,t,1)' $ + +define "TRY" here; % the maze-searching algorithm % +here = destination +or +not(or{minusp[here]}) and and{lessp[here, dims]} % outside boundary? % + and maze{here} = "-" % is this square new and legal? % and +(maze{here}:="*"; % mark square to avoid revisiting % + iter for one := stepsource step cdr one do % various directions % + (for j in [plus[here,one], difference[here,one]] do % "up" or "down" % + if try j then (maze{here}:=j; return t); % success: mark maze % + if cadr one = 1 then return nil) % failure: return nil %) $ + +define "INIT" d; % initializes maze as per dimensions d. All moves legal. % +dims := d; +array{'maze'.t.dims}; +stepsource := (\x;0)[dims]; % source of increment vector 1,0,0,... % +car stepsource := 1; cdr last stepsource := stepsource; +source := (\x;0)[dims]; destination := sub1[dims] $ + +define "SURVEY"; % prints path from source to destination % +let x = source; +while x ne destination do print x := maze{x} $ + +define "WHYNOT"; % sample non-trivial maze % +init [4,4]; +maze := !'(- + + - - - - + - + - + - + - -); +try source; +survey $ + +=exit$ + +(cgol)$ +% Program to solve a system of linear Diophantine equations. + +To use, say +solve(A,b,n) altmode +where A is an mxn matrix, b is an m-vector, and n is an integer. Here +m is the number of equations and n the number of variables. The +result will be an nxp matrix N such that Nv is a solution in x +for Ax=b for any integer v with unit first element. Morevover, all +solutions are of the form Nv. + + The basic idea is to use Gauss-Jordan elimination, but to use +Euclid's algorithm to guide the process. Euc(a) takes an integer +vector a and returns a two-list (M g) where g is the gcd of the +elements of a and a"M is a vector with g in the first coordinate and +0's elsewhere. (Here a" denotes the row vector a.) Euc is called +once per equation, and the resulting matrices from each call are more +or less multiplied together to give the final answer. + +Matrices are represented as lists of rows, rows in turn being +represented as lists of numbers. % + +define "EUC"(a); % Euclid's algorithm % +if null a then [nil,0] % should not be needed below % +else if null cdr a then [[[1]],car a] +else +let M,g = {euc(cdr a)}, h = car a; +M := (\i;0)[1 to length cdr a] . M; +let c1 = 1 . (\i;0)[1 to length cdr a], c2 = car[M]; +let ng, nc1, nc2 = {euc1(h,g,c1,c2)}; +[cons[nc1,cons[nc2,cdr[M]]],ng] $ + +define "EUC1"(a,b,u,v); +if b=0 then [a,u,v] +else +let d = a/:b; +euc1(b, a-b*d, v, difference[u,(\x;x*d)[v]]) $ + +define "SOLVE"(Av, Iv, n); +if null Av then (\x;0 . x)[Id(n)] +else + let a = car Av, i = car Iv; + let m,g = {euc(a)}; + if g = 0 then + if i = 0 then solve(cdr Av, cdr Iv, n) + else throw nil + else if not g|i then throw nil + else (m := scale1(m, i/:g); + matmul(m, (1 . (\x;0)[2 to n]) . + solve(cdr matmul(Av,cdr[m]), + cdr(difference[Iv,car[matmul(Av,list[car[m]])]]), + n-1))) $ + +define "SCALE1"(m, x); % Scale up col 1 of m by factor x % +cons[(\y;y*x)[car[m]], cdr[m]] $ + +define "SCMUL"(a,b); % multiply matrix a by scalar b % +(\q;(\p;p*b)[q])[a] $ + +define "MATMUL"(a,b); (\i;(\j;plus{times[i,j]})[list[{b}]])[a] $ + +define "ID"(n); % construct the nxn identity matrix % +(\i;(\j;if i=j then 1 else 0)[1 to n])[1 to n] $ + +=exit$ + +(cgol)$ + +%FuperFonic Tranfport algorithm - a real treafure. Does FFT +multiplication of integers. Though this algorithm is no faster than +the Strassen-Schoenhage n log n log log n FFT integer multiplication, +it is considerably simpler. % + +special n, ord, w, wi, g $ + +newtok "+:", "*:", "**:" $ +infixm "+:" 20 is "SUM" $ +infixm "*:" 21 is "BY" $ +infixr "**:" 22 is "TOTHE" $ + +define lexpr "SUM"(argno); plus{arg[1 to argno]} rem n $ + +define lexpr "BY"(argno); times{arg[1 to argno]} rem n $ + +define "TOTHE"(a,b); +if b = 0 then 1 +else if oddp b then a *: (a**:(b-1)) +else (a*:a)**:(b/:2) $ + +define "TOPOLY"(m,b,len); if len ne 0 then m mod b . topoly(m/:b, b, len-1) $ + +define "FROMPOLY"(p,b); if p then car p + b*frompoly(cdr p, b) else 0 $ + +define "EVENS" x; x and car x . evens cddr x $ % even half of vector % +define "ODDS" x; evens cdr x $ % odd half of vector % + +define "FFT"(a,pw); % FFT of vector a; pw is vector of powers of w % +if null cdr a then a +else let efft = fft(evens a, evens pw), offt = fft(odds a, evens pw); + sum[efft@efft, #mult[pw, offt@offt]] $ + +define "IFFT"(a,pwi); (\x;g*:x)[fft(a,pwi)] $ + +define a "MULT" b, 21; % n log n log log n integer multiplication % +let m := max(a, b); +if not bigp m then a*b +else +(let x = fix(log(35 * length cdr m)/log(2)); + let n = 2**2**(x-1)+1, ord = 2**x, w = 2; + let wi = w**:(ord-1), g = (n-1)/:ord*:(n-1); + let m = wi; + let pw = for i in 1 to ord collect m:=m*:w; + let pwi = car pw . reverse cdr pw, + dig = ord/:x; + frompoly(ifft(#mult[fft(topoly(a,dig,ord),pw), + fft(topoly(b,dig,ord),pw)], + pwi), + dig)) $ + +=exit$ + + +(cgol)$ +% This procedure tests the function defined as a bit string in array A +to see if it has the (PISH,TUSH) property, namely that given any +PISH variables, one can find at least TUSH functions of the remaining +variables by appropriately diddling the PISH variables.% + +special mask, llv, nb, curr, token, left, pish, tush, n, nw $ +% MASK is a 32-bit mask corresponding to a particular choice of variables +LLV is a partition of the possible functions for a given choice of + variables. Initially discrete, it is progressively refined as + evidence arises for distinguishing functions. The partition is + represented as a list of the non-singleton blocks, each of which + is represented as a list of variables, each of which is + represented as (ostensively) 1, 2, 4, 8, ... +NB The number of blocks in LLV.% + + +infix "^" 22 is "LSH" $ + + +array(mp, fixnum, 5) $ % array of 32-bit masks % +=let ibase = 2 in cgolread()$ % interprets following expr in binary % +mp(0) := 10101010101010101010101010101010; +mp(1) := 11001100110011001100110011001100; +mp(2) := 11110000111100001111000011110000; +mp(3) := 11111111000000001111111100000000; +mp(4) := 11111111111111110000000000000000$ +% Note convenience of not losing meaning of 2,3,4 in above % +% Hack: starting from right, read each column as a 5-bit number. +Recognize the sequence? These vectors are the columns arising in the +method of truth tables for testing propositional tautologies. % + +define "TEST"; enum(pish, n-1, nil, [0], (-1)^(-4)) $ + +define "ENUM" (nv, ulim, vl, sl, mask); +if nv=0 then (llv := [sl]; nb := 1; prin1(ulim+1); chek(vl, 0, 1^(n-5)); + if nb < tush then (write "No." ; tyo(7); err())) +else iter for i := ulim step i-1 until i = nv-2 do + enum(nv-1, + i-1, + if i>4 then vl @ [1^(i-5)] else vl, + sl @ mapcar('\x;x+1^i', sl), + if i>4 then mask else mp(i) :A: mask) $ + +define "PARTITION"; llv := mapcan('makeq', llv) $ + +define "CHEK"(vl, ll, ul); +if vl then + iter for i := ll step i+car vl + car vl while i
    (B -> A)) . +No promises are made about the behavior of the algorithm for +expressions without well-defined types, as in +type '\x;x(x)' . +This algorithm is believed to have a bug. However, it works pretty +well in general. % + +#prin1 := "PRINC" $ + +define "GENTYPE"; ascii(typecnt:=typecnt+1) $ + +define "PRETTY" x; +if not car x then pretty cdr x +else if not cdr x then princ(car x) +else (princ("("); pretty car x; princ("->"); pretty cadr(x); princ(")")) $ + +define "UNIFY"(ta,tb); +if null car ta then unify(cdr ta, tb) +else if null car tb then unify(ta, cdr tb) +else if cdr ta and cdr tb then ([unify(car ta, car tb), unify(cadr(ta), cadr(tb))]) +else if cdr tb then unify(tb, ta) +else (rplaca(tb, nil); rplacd(tb, ta)) $ + +define "LUNIFY"(ta,tb); +if cdr ta then unify(car ta, tb) +else (rplaca(ta, tb); rplacd(ta, [[gentype]])) $ + +define "CHAIN" tx; if car tx then tx else chain cdr tx $ + +define "RTYPE" lx; +if lx isatom then eval lx +else if car lx = "LAMBDA" then + eval [["LAMBDA", cadr(lx), ["XCONS", ["LIST", 'rtype caddr(lx)'], +chain caadr(lx)]], + ["QUOTE", [gentype]]] +else (new qq; lunify(qq := rtype car lx, rtype cadr(lx)); + chain cadr(qq)) $ + +define "TYPE" lx; +typecnt:=64; newline; pretty rtype lx; " " $ + +=exit$ + +(cgol)$ + +%Galil and Seiferas' (G&S) linear-time palstar finder. +Here a palstar is a string of palindromes of length at least two (to +avoid trivializing the problem). Thus +test "ABBACCDEFED" would return ((A B B A) (C C) (D E F E D)) +whereas +test "ABBACCDEFE" would return NIL because there is no way to parse +the input as a string of non-unit-length palindromes. % + +special n $ + +% Following takes advantage of CGOL to get around LISP's insistence +that arrays start from 0 and index by 1. In the following, A and M +start from -1 and R increments by 0.5 (the 0.5 is needed because R is +the centroid of a palindrome, and if the palindrome is of even length +the centroid will fall between two characters). All arrays can accept +real arguments, again not offered by LISP. % +prefix "A" 25 subst(right, "X", '#a(fix(x+1.1))') $ +prefix "R" 25 subst(right, "X", '#r(fix(2*x+1.01))') $ +prefix "L" 25 subst(right, "X", '#l(fix(x+.1))') $ +prefix "U" 25 subst(right, "X", '#u(fix(x+.1))') $ +prefix "V" 25 subst(right, "X", '#v(fix(x+.1))') $ +prefix "M" 25 subst(right, "X", '#m(fix(x+1.1))') $ +prefix "LINK" 25 subst(right, "X", '#link(fix(x+.1))') $ + +define "PALFIND" x, 1; % Manacher's on-line palindrome finder - used by G&S % +x:=explodec x; +array(#a, t, (n:=length x)+2); fillarray("A", nil.x@[[nil]]); +array(#r, t, 1+2*length x); +n := float n; +r(-.5):= -.5; r 0 := 0.0; +let c=.5, lt=0.0, rt=1.0; +iter( + while lt>-1 and rt 1 then + let p = i + l i -1; if p 1 and m(i-1) then + ( let x = i + l i - 1; if not m x then (m x := t; link x := fix i-1); + if u i then (x := i+2*(l i)-2; if not m x then (m x := t; link x := fix i-1)); + if v i then (x := i+2*(l i) ; if not m x then (m x := t; link x := fix i-1)))) $ + +define "PALSTAR" x, 10; % if x is palstar, returns its parse, else nil % +palfind x; setl; setuv; mark; +if m(n-1) then + let i=n-1, z=nil; + while i>=0 do (z := implode((\x;a x)[1+link i to i]) . z; i := link i); + z $ + +% Following is useful in coming up with random test inputs % +define "RANDSTR" n "ALPHABET" s, 19; % random string, length n, alphabet size s % +implode((\x;ascii(65+random s))[1 to n]) $ + +=exit$ + +(cgol)$ + +%Salamin's elliptic integral algorithm for computation of pi. +To get n digits of pi, say PI n . The answer will be an integer which +is pi times some power of ten. The last digit may be off by 1. The +algorithm is not coded for efficiency - it serves only to exhibit the +principle of Salamin's algorithm, and to churn out a few paltry digits +of pi for those who don't trust tables. As implemented below it is an +O(n**2) algorithm, and takes about a minute on the AI machine to get +400 decimal digits. % + + +%Auxiliary routine for integer square root % +define a "ISQ" b, 19; +new x; x := (b+a/b)/2; if |b-x| < 2 then x else a isq x $ + +% Integer square root of a - silly LISP's sqrt demands floating point! % +define "ISQRT" a; a isq 2**(\base;flatsize(a))(4) $ + +% Summation of 2**j * c[j+1] ; also computes agm % +define a "SIG" b, 19; +if |a-b| < 2 then (agm := a; 0) else ((a-b)/2)**2 + 2*((a+b)/2 sig isqrt(a*b)) $ + +% print pi to n significant digits % +define "PI" n, 1; +new sum, agm; sum := 10**n sig isqrt(10**(2*n)/2); + 1 + agm**2*10**(n-1)/(10**(2*n)/4-sum) $ + + +=exit$ + +(cgol)$ +% Rabin's Composite Detector. You can set k to whatever you want, +and the probability that PRIME will return T erroneously is 1/2**k. It +will never return NIL erroneously. Running time is cubic in the length +of the input. % + +special q,prod,tw,a,olda,qp,left,n,k,sw,w,hw,stopwatch $ +?*nopoint t; stopwatch:=0; qp := 821; k := 20; w := 2**35; sw:=w-1; hw := w/2 $ + +alloc(!'(list (10000 12000 0.25) + fixnum (10000 12000 0.90) + bignum (10000 12000 0.9))) $ +gc?-overflow := '\x;nil' $ + +define "TIM"; -stopwatch + stopwatch := runtime()/1000000.0 $ + +define a "BY" b, 21; a*b mod n $ + +define a "TOTHE" b, 22; % a**b mod n % + if zerop b then 1 + else if oddp b then a by (a tothe (b-1)) + else (a by a) tothe (b/2) $ + +define a "TOTHEL" b, 22; % The list [a**b, a**(b/2), ..., a**(2x+1)] % +if a=1 or b=0 then [1] +else if oddp b then [a by (a tothe (b-1))] +else new x; x := a tothel (b/2); if car x = 1 then x else car x by car x . x $ + +define "BRND" x; % Auxiliary routine for computing big random numbers% +if bigp x then random(sw) + w*brnd(x/hw) else random(x) $ + +define "BIGRANDOM" x, 25; brnd(x) mod x $ + +define "CARMICHAEL" x ,12; if x then (car(x)-1 gcd n) ne 1 or Carmichael cdr x $ + +define "PRIME" n, 12; % Returns T if n is prime % +if n<30 then n isin !'(2 3 5 7 11 13 17 19 23 29) +else +(n gcd 6469693230) = 1 and +new kk,looksprime; kk:=0; looksprime:=t; + while looksprime and kk prod of primes < x+1 % +new prod; prod := 1; +for i in 2 to x do if prime i then prod := prod*i; +new tw,q; tw:=prod+qp; q:=1; tim; +while t do + (if testwin tw then (write "Prod(" cat x cat ")*" cat q cat "+" cat qp; + if prime tw+6 then + (princ " *"; + if prime tw+8 then princ " *"); + write tim cat " secs"); + tw := tw+prod; q:=q+1) $ + +define "DOWN" n,1; % Searches down from 2**n for primes % +new nn; nn:=2**n-1; +while not prime nn do nn:=nn-2; +write nn cat " = 2**" cat n cat "-" cat 2**n-nn $ + +=exit$ + +(cgol)$ + +%Linear time Sieve of Eratosthenes program. % +% Due to Ross Gale and Vaughan Pratt. % +% The sieve is in the array sv, each word of which is 36 bits, although +only the rightmost 32 bits hold information. If 2*i+1 is composite +then a 1 appears in position (i mod 32) of sv(i/32). (Position 0 is the +least significant bit.) % + +% :A: is bitwise and, :V: is bitwise or, :^: is leftshift % + +define "PRIME" x,10; % predicate that looks up sieve % + x=2 or oddp x and sv(x:^:-6):^:(35-(x:^:-1 :A: 31)) >= 0$ + +define "SIEVE" n,1; % construct a sieve for primes < n % +array(sv,#fixnum,n/64+1); % the sieve, initially all 0's % +sv(0):=1; % 1 is composite by convention % +let s=[1]; % singleton set of numbers sieved so far % +for i in 3 to n/2 by 2 do % enumerate those i % + if prime i then % that are prime % + (let ts=nil; % temporary accumulator for new s % + for j in s do % j has been sieved, so j*i is composite for j1 % + (let k=j; % k = j*i**z for some z % + while k % + +% The following solves a problem raised by DVM shortly before I became +almost unable to type this. A man thinks of two distinct numbers +between 2 and 100. He tells the product to A and the sum to B, and +asks them to reconstruct the original numbers. (i) A says he doesn't +know. (ii) B then announces that he knew A didn't know. (iii) A +retorts that now he knows. (iv) B's comeback is that now he knows +too. What was the bus-driver's name? % + +% Here's the WWI ace practically unable to type this. What is he +thinking? % + +% Answer: what indeed % + +% (Thinks). What numbers could B have been given? At least 5. +52,3, so not (ii). 62,4 so again not (ii). 72,5 or 3,4 , but +2,5 would give it away to A straight away. Hence B seeing n=7 +couldn't be sure A didn't know. So we are looking for a number n no +binary partition of which is into two distinct primes. 8=3+5, 9=2+7, +10=3+7, 11=???, 12=5+7, 13=2+11, 14=3+11, 15=2+13, 16=3+13, 17=???... +In fact if n is odd and n-2 is not prime, we are clearly have such a +number. Conversely, if n is odd and n-2 is prime we have failed. Now +consider just even n. 18=5+13, 20=3+17, 22=3+19, 24=5+19, 26=3+23, +28=5+23, 30=7+23, 32=3+29,... We observe that 3-5-7 form a solid +block, the only way to beat which is to find three consecutive odd +non-primes. Weelll,... 91 115 117 119 121 141 143 183 185 are all +that are in this category. But 94=11+83, 118=11+107, 120=11+109, +122=13+109, 124=17+107, 144=13+131, 146=19+127, 186=13+173, 188=31+157 +(a sort of local success for Goldbach's conjecture). So this rules out +the possibility of even n. Hence B must have seen odd n such that n-2 +is not prime, or equivalently n such that n-2 is an odd composite. +Thus n is one of 11 17 23 27 29 35 37 41 47 53 ... + +Now if A now knows the answer, it could have been (2,9), (3,8), +(4,7),... which we note have the property that their products are +each associated only with one n in the above list. (E.g., (5,6) is +excluded because its product 30 is associated with not only 11=5+6 but +17=2+15.) But now B knows the answer, which would be impossible if it +were any of (2,9), (3,8) or (4,7), since B's knowing the sum is 11 +doesn't help here. More generally, we are looking for an n with +exactly one binary partition whose product is not the product of the +binary partition of some other n (always n is 11 17 23 27 ... as +above.) So the following should work: + +for each n such that n-2 is odd composite do + if there exist none or more than one partition of n such that no + other factorizations of product of this partition have their sum-2 + odd composite then reject n. + +Checking this for the first few values of n, we find: +n=11: eliminated by argument above about (2,9), (3,8) and (4,7). +n=17: 2*15=5*6, 3*14=2*21, 5*12=3*20, 6*11=2*33, 7*10=2*35, 8*9=3*24. +This leaves only (4,13) for n=17, so (4,13) has to be one answer. We +now check that there are no further answers as follows. % + +fasload:=nil $ + +load rab$ % prime number package % + +delim "BY" $ + +array(g,t,200); array(awful,fixnum,9901) $ + +define "SEARCH"; +for n in 11 to 199 by 2 do if not prime(n-2) then + (g(n) := nil; + for j in 2 to n/2 do + (jtnmj := j*(n-j); g(n) := jtnmj . g(n); + awful(jtnmj):=awful(jtnmj)+1)); +for n in 11 to 199 by 2 do if not prime(n-2) then + (p := 0; + for j in 2 to n/2 do if awful(j*(n-j))=1 then (p:=p+1; x:=j); + if p=1 then (print n; princ x)) $ + +% Running this program yielded only n=17, x=4, so the pair of numbers +had to be (4,13) % + +=exit$ + + +(cgol)$ + +% Repetition finding algorithm; Pratt's variant of Weiner's algorithm % + +% The following paragraph defines some slick syntax which allows this +code to be read in conjunction with my paper on this variant of +Weiner's algorithm, available from the author at the MIT AI Lab. % + +"TAILS" of ":" := nil; newtok ":=" $ % so w:a is not confused with :a: % +infixr "." 26 [["GET", left, ["QUOTE", "ONE"]], right] $ % the w.a property % +infixr ":" 26 [["GET", left, ["QUOTE", "TWO"]], right] $ % the w:a property % +prefix "*" 26 [["GET", xx:=right; check ":";right, ["QUOTE", "ABOVE"]], xx] $ + % the *a:w property % +literal suc, loc, len $ % Avoids having to write "SUC" etc % + +define "GENERATE"; %creates a new node in the graph% +let x=ncons nil; +"ONE" of x := array(nil,t,6); % the w.a property % +"TWO" of x := array(nil,t,6); % the w:a property % +"ABOVE" of x := array(nil,t,6); % the *a:w property % +x $ + +define "CREATEVERTEX"; % what to do when a node to be visited isn't there % +wa := generate; len of wa := 1 + len of w; loc of wa := w.a; +w:a := wa; % connect w to wa via w's :a link % +u := if w = eps then eps % u is to be wa's longest proper suffix in the graph % + else (tt := suc of w; + while null tt:a and tt ne eps do tt := suc of tt; + tt:a or eps); +c := a(loc of wa - len of u - 1); x := *c:u; +suc of wa := u; % link wa to u % +*c:u := wa; % link u to wa % +if x then (suc of x := wa; % if x exists link it to wa % + d := a(loc of x - len of wa - 1); *d:wa := x); +if null x then wa.a(w.a) := w.a + 1 +else for b in 0 to 5 do wa.b := x.b $ + +define "SCAN" x; % Main routine. X is a list of numbers in range [0,5] % +n := length x; array(a,t,1+n); fillarray("A", cons(0, x)); % input % +eps := generate; len of eps := 0; loc of eps := 1; suc of eps := eps; +w := eps; i := 1; % initialization % +while i <= n do % scan whole string % + (a := a(i); % a abbreviates a(i) % + if null w.a then % seen wa before? % + (w.a := i+1; % no, record its position % + if w ne eps then w := suc of w % then push [ pointer % + else i := i+1) % or push both [ and ] % + else (if null w:a then createvertex; % new node if only 2nd wa % + w := w:a; i := i+1); % push ] pointer % + print i; princ len of wi cat " " cat loc of w) $ % trace i,w % + +=exit$ + + +(((((((((((((((((((((((((((((((((FIN))))))))))))))))))))))))))))))))) + diff --git a/doc/_info_/fasbin.format b/doc/_info_/fasbin.format new file mode 100755 index 00000000..1ea955d7 --- /dev/null +++ b/doc/_info_/fasbin.format @@ -0,0 +1,233 @@ + +THE "NEW" FASLOAD SCHEME (AS OF 1/31/73) USES A NEW FORMAT +FOR ITS FILES. A FASL FILE CONSISTS OF TWO HEADER WORDS, +FOLLOWED BY A SERIES OF FASL BLOCKS; THE TWO HEADER WORDS +ARE BOTH SIXBIT, THE FIRST BEING "*FASL*" AND THE SECOND +THE CONTENTS OF LOCATION LDFNM2 IN THE LISP WHICH ASSEMBLED +THE FILE (A VERSION NUMBER IN SIXBIT). +EACH FASL BLOCK CONSISTS OF A WORD OF NINE FOUR-BIT +RELOCATION BYTES, FOLLOWED BY NINE PIECES OF FASL DATA. +THE LENGTH OF EACH DATA ITEM IS DEPENDENT ON THE +RELOCATION TYPE; THUS FASLBLOCKS ARE OF VARYING LENGTH. +THE LAST BLOCK MAY HAVE FEWER THAN NINE DATA ITEMS. +THE RELOCATION TYPES AND THE FORMATS OF THE ASSOCIATED +DATA ITEMS ARE AS FOLLOWS: + +TYPE NAME DATA FORMAT + +0 ABSOLUTE ONE ABSOLUTE WORD TO BE LOADED. +1 RELOCATABLE ONE WORD, THE RIGHT HALF OF WHICH + IS RELOCATABLE; I.E. AT LOAD TIME + THE LOAD OFFSET IS TO BE ADDED TO + THE RIGHT HALF. +2 SPECIAL A WORD TO BE LOADED, WHOSE RIGHT + HALF CONTAINS THE INDEX OF AN ATOM + (HOPEFULLY OF TYPE PNAME) THE ADDRESS + OF THE VALUE CELL OF WHICH IS TO + REPLACE THE RIGHT HALF OF THE LOADED + WORD. (IF NO VALUE CELL EXISTS, ONE + IS TO BE CREATED.) +3 SMASHABLE CALL SIMILAR TO TYPE 4 (Q.V.) EXCEPT THAT + THE INSTRUCTION IS ONE OF THE SERIES + OF CALL UUOS WHICH MAY BE "SMASHED" + FOR PURIFICATION PURPOSES. AT PRESENT + THESE UUOS ARE: CALL, JCALL, NCALL, + NJCALL. +4 QUOTE ATOM ONE WORD TO BE LOADED WHOSE RIGHT HALF + CONTAINS THE INDEX OF AN ATOM WHOSE + ADDRESS IS TO REPLACE THE RIGHT HALF + OF THE WORD LOADED. +5 QUOTE LIST A SERIES OF WORDS REPRESENTING AN + S-EXPRESSION TO BE CONSTRUCTED BY THE + LOADER. THE FORMAT OF THESE WORDS IS + BEST EXPLAINED BY THE ALGORITHM USED + TO CONTRUCT THE S-EXPRESSION: THE + LOADER EXAMINES BITS 4.7-4.9 OF EACH + WORD. IF 0, THEN THE ATOM WHOSE INDEX + IS IN THE RIGHT HALF OF THE WORD IS + PUSHED ONTO A STACK. IF 1, THEN THE + LOADER POPS AS MANY ITEMS OFF THE STACK + AS SPECIFIED BY THE NUMBER IN THE RIGHT HALF + OF THE WORD AND MAKES A LIST OF THEM, SO THAT + THE LAST ITEM POPPED BECOMES THE FIRST + ITEM OF THE LIST; THIS LIST IS THEN + PUSHED ONTO THE STACK. IF 2, THEN THE + LOADER POPS ONE ITEM OFF THE STACK AND + PROCEEDS AS FOR 1, EXCEPT THAT THE ITEM + FIRST POPPED IS USED TO END THE LIST + INSTEAD IF NIL. (THIS ALLOWS FOR DOTTED + PAIRS.) IF 3, THEN THE TOP ITEM ON THE STACK + IS EVALUATED AND RESTORED BACK ON THE TOP OF + THE STACK. IF 7, THEN THE LEFT HALF OF THE + WORD SHOULD BE -1 OR -2, INDICATING THE + SECOND LAST WORD OF THE DATA; IF -1, + THE RIGHT HALF OF THIS WORD AND THE + ADDRESS OF (WHAT SHOULD BE) THE SINGLE + ITEM ON THE STACK (WHICH IS POPPED OFF) + ARE MADE RESPECTIVELY INTO THE LEFT AND + RIGHT HALVES OF A WORD TO BE LOADED INTO + BINARY PROGRAM SPACE; IF -2, THE + S-EXPRESSION IS PLACED INTO THE NEXT + SLOT OF THE ATOMTABLE (SEE TYPE 12). + THE ONE WORD REMAINING IS THE HASH KEY + OF THE S-EXPRESSION AS COMPUTED BY + SXHASH; THIS IS USED BY THE LOADER + TO SAVE GCPRO SOME WORK. +6 GLOBALSYM ONE WORD; THE RIGHT HALF IS AN INDEX + INTO THE TABLE LSYMS IN LISP. THE + INDICATED VALUE IS RETRIEVED, NEGATED + IF BIT 4.9 OF THE DATA WORD IS 1, AND + ADDED TO THE RIGHT HALF OF THE LAST + WORD LOADED INTO BINARY PROGRAM SPACE. + THIS ALLOWS LAP CODE TO REFER TO + SELECTED LOCATIONS INTERNAL TO LISP + WITHOUT GETTING SYMBOLS FROM DDT. +7 GETDDTSYM IF THE FIRST WORD IS -1, THEN THE LOAD + OFFSET IF ADDED INTO THE LEFT HALF + OF THE WORD MOST RECENTLY LOADED INTO + BINARY PROGRAM SPACE (THIS IS HOW LEFT + HALF RELOCATION IS ACCOMPLISHED). + OTHERWISE, THE FIRST WORD + CONTAINS IN BITS 1.1-4.5 A SYMBOL + IN SQUOZE CODE. THE LOADER GETS + THE VALUE OF THIS SYMBOL FROM DDT + IF POSSIBLE, NEGATES IT IF BIT 4.9 + IS 1, THEN ADDS THE RESULT TO THE + FIELD OF THE LAST WORD LOADED AS + SPECIFIED BY BITS 4.6-4.7: + 3=ENTIRE WORD + 2=AC FIELD ONLY + 1=RIGHT HALF ONLY + 0=ENTIRE WORD, BUT SWAP HALVES OF + VALUE BEFORE ADDING. + THESE FOUR FIELDS CORRESPOND TO + OPCODE, AC, ADDRESS, AND INDEX FIELDS + RESPECTIVELY IN A LAP INSTRUCTION. + IF BIT 4.8 IS A 1, THEN ANOTHER WORD + FOLLOWS, CONTAINING THE VALUE OF THE + SYMBOL AS OBTAINED FROM DDT AT + ASSEMBLE TIME. IF THE VERSION NUMBER + OF THAT LISP (AS DETERMINED FROM THE + SECOND FILE HEADER WORD) IS THE SAME + AS THAT OF THE LISP BEING LOADED INTO, + THEN THIS VALUE IS USED AND DDT IS NOT + CONSULTED AT LOAD TIME; THIS IS FOR + SPEED. IF THE VERSION NUMBERS ARE + DIFFERENT, THEN DDT IS CONSULTED. +10 ARRAY REF ONE WORD TO BE LOADED, WHOSE RIGHT HALF + CONTAINS THE ATOMINDEX OF AN ATOMIC + SYMBOL. IF THE SYMBOL HAS AN ARRAY + PROPERTY, IT IS FETCHED; OTHERWISE + ONE IS CREATED. THE RIGHT HALF OF THE + WORD TO BE LOADED IS REPLACED WITH + THE ADDRESS OF THE SECOND WORD OF THE + ARRAY POINTER (I.E. OF THE TTSAR). + IN THIS WAY ACCESSES TO ARRAYS CAN BE + OPEN-CODED. +11 UNUSED [ERROR IN FILE] +12 ATOMTABLE INFO A HEADER WORD, POSSIBLY FOLLOWED BY + OTHERS, DEPENDING ON BITS 4.7-4.8: + IF 0, THE RIGHT HALF IS THE NUMBER + OF WORDS FOLLOWING, WHICH CONSTITUTE + THE PNAME OF A PNAME-TYPE ATOM, IN THE + ORDER OF THEIR APPEARANCE ON A + PROPERTY LIST. THE ATOM IS INTERNED. + IF 1, THE ONE WORD FOLLOWING IS + THE VALUE OF A FIXNUM TO BE CREATED. + IF 2, THE FOLLOWING WORD IS THE VALUE + OF A FLONUM. IF 3, THE RIGHT HALF IS + THE NUMBER OF FIXNUM COMPONENTS OF A + BIGNUM FOLLOWING, MOST SIGNIFICANT + WORD FIRST. THE HEADER WORD CONTAINS + THREE BITS OF THE SIGN OF THE BIGNUM + IN BITS 3.1-3.3. + THE ATOM THUS CREATED IS ASSIGNED A + PLACE IN THE ATOMTABLE MAINTAINED BY + THE LOADER (AS AN ARRAY) USING + CONSECUTIVE LOCATIONS; FROM THAT POINT + ON OTHER DATA ITEMS REFERRING TO THAT + ITEM CAN DO SO BY THE INDEX OF THE + ATOM IN THIS TABLE. + SEE ALSO TYPES 5 AND 16, WHICH ALSO + MAKE ENTRIES IN THE ATOMTABLE. +13 ENTRY INFO TWO WORDS. THE LEFT HALF OF THE FIRST + WORD IS THE ATOMINDEX OF THE NAME OF + THE FUNCTION BEING DEFINED; THE RIGHT + HALF THAT OF THE SUBR TYPE (THE + PROPERTY UNDER WHICH TO CREATE THE + ENTRY POINT, E.G. SUBR OR FSUBR). + THE RIGHT HALF OF THE SECOND WORD IS + THE LOCATION OF THE ENTRY POINT AS A + RELOCATABLE POINTER: THE LOAD OFFSET + MUST BE ADDED TO IT. THE LEFT HALF OF + THE SECOND WORD CONTAINS INFORMATION + USED TO CREATE AN ARGS PROPERTY FOR + THE FUNCTION AS SPECIFIED IN THE + ORIGINAL LAP CODE. IF THIS HALFWORD + IS ZERO, NO ARGS PROPERTY IS CREATED + AND ANY ALREADY PRESENT IS REMOVED. + OTHERWISE THE HALFWORD IS DIVIDED INTO + TWO NINE-BIT BYTES, EACH OF WHICH IS + CONVERTED AS FOLLOWS: + BYTE RESULT + 0 NIL + 777 777 + N N-1, WHERE N IS NOT 0 OR 777 + THESE TWO ITEMS ARE THEN CONSED AND + FOR THE ARGS PROPERTY. +14 LOC THE WORD IS A RELOCATABLE QUANTITY + SPECIFYING WHERE TO CONTINUE LOADING. + IT IS NOT PERMITTED TO LOC BELOW THE + ORIGIN OF THE ASSEMBLY. IF THE LOC + IS TO A LOCATION HIGHER THAN ANY YET + LOADED INTO, THEN FASLOAD ZEROS OUT + ALL WORDS ABOVE THAT HIGHEST LOCATION + UP TO THE LOCATION SPECIFIED. + FASLOAD KEEPS TRACK OF THE HIGHEST + LOCATION EVER LOADED INTO; THIS VALUE + PLUS ONE BECOMES THE VALUE OF BPORG + AT THE END OF ASSEMBLY, REGARDLESS + OF THE STATE OF THE LOCATION POINTER + WHEN LOADING TERMINATES. +15 PUTDDTSYM FIRST WORD, THE SYMBOL IN SQUOZE CODE. + IF BIT 4.9=0, THE SYMBOL IS DEFINED TO + DDT IF POSSIBLE WITH THE ADDRESS OF THE + WORD OF BINARY PROGRAM SPACE ABOUT + TO BE LOADED INTO AS ITS VALUE. + IF BIT 4.9=1, THE VALUE IS GOBBLED FROM + THE FOLLOWING WORD. BIT 4.8 (OF THE WORD + CONTAINING THE SQUOZE) MEANS RELOCATE + THE LEFT HALF OF THE VALUE BY THE LOAD + OFFSET, AND BIT 4.7 LIKEWISE FOR THE + RIGHT HALF. + WHETHER OR NOT THE SYMBOL ACTUALLY GETS + PUT IN DDT'S SYMBOL TABLE IS A FUNCTION + OF THREE CONDITIONS: FIRST, THAT THERE + IS A DDT WITH A SYMBOL TABLE; SECOND, + THE VALUE OF THE VARIABLE SYMBOLS; + THIRD, BIT 4.6 OF THE FIRST PUTDDTSYM + WORD. THE FIRST CONDITION OF COURSE MUST + BE SATISFIED. IF SO, THEN THE SYMBOL IS + PUT IN THE SYMBOL TABLE ONLY IF SYMBOLS + HAS A NON-NIL VALUE. FURTHERMORE, IF + THAT VALUE IS THE ATOM SYMBOLS ITSELF, + THEN THE SYMBOL IS PUT ONLY IF BIT 4.6 + IS ON (INDICATING A "GLOBAL" SYMBOL). +16 EVAL MUNGEABLE A SERIES OF WORDS SIMILAR TO THOSE + FOR TYPE 5, BUT WITH NO FOLLOWING + HASH KEY. AN S-EXPRESSION IS + CONSTRUCTED AND EVALUATED. THIS IS + USED FOR THE SO-CALLED "MUNGEABLES" + IN A FILE OF LAP CODE. + IF THE LEFT HALF OF THE LAST WORD IS + -1, THE VALUE IS THROWN AWAY. IF IT + IS -2, THE VALUE IS ENTERED IN THE + ATOMTABLE. +17 END OF BINARY ONE WORD, WHICH MUST BE "*FASL*" IN + SIXBIT. THIS SHOULD BE THE LAST DATA + WORD IN THE FILE. ANY RELOCATION + BYTES LEFT OVER AFTER A TYPE 17 ARE + IGNORED. +THIS SHOULD BE FOLLOWED EITHER BY END OF FILE OR A WORD +FULL OF ^C'S. + \ No newline at end of file diff --git a/doc/_info_/fasl.format b/doc/_info_/fasl.format new file mode 100755 index 00000000..1bd626b2 --- /dev/null +++ b/doc/_info_/fasl.format @@ -0,0 +1,425 @@ +;;; FORMAT OF FASL FILES: + + THE "NEW" FASLOAD SCHEME (AS OF 1/31/73) USES A NEW FORMAT FOR + ITS FILES. A FASL FILE CONSISTS OF TWO HEADER WORDS, FOLLOWED BY + A SERIES OF FASL BLOCKS; THE TWO HEADER WORDS ARE BOTH SIXBIT, + THE FIRST BEING "*FASL+" (FOR HISTORICAL REASONS, "*FASL* IS + ALSO ACCEPTED) AND THE SECOND THE CONTENTS OF LOCATION LDFNM2 IN + THE LISP WHICH ASSEMBLED THE FILE (A VERSION NUMBER IN SIXBIT). + EACH FASL BLOCK CONSISTS OF A WORD OF NINE FOUR-BIT RELOCATION + BYTES, FOLLOWED BY NINE PIECES OF FASL DATA. THE LENGTH OF EACH + DATA ITEM IS DEPENDENT ON THE RELOCATION TYPE; THUS FASLBLOCKS + ARE OF VARYING LENGTH. THE LAST BLOCK MAY HAVE FEWER THAN NINE + DATA ITEMS. THE RELOCATION TYPES AND THE FORMATS OF THE + ASSOCIATED DATA ITEMS ARE AS FOLLOWS: + + TYPE 0 ABSOLUTE + ONE ABSOLUTE WORD TO BE LOADED. + + TYPE 1 RELOCATABLE + ONE WORD, THE RIGHT HALF OF WHICH IS RELOCATABLE; I.E. AT LOAD + TIME THE LOAD OFFSET IS TO BE ADDED TO THE RIGHT HALF. + + TYPE 2 SPECIAL + A WORD TO BE LOADED, WHOSE RIGHT HALF CONTAINS THE INDEX OF AN + ATOM (HOPEFULLY OF TYPE PNAME) THE ADDRESS OF THE VALUE CELL OF + WHICH IS TO REPLACE THE RIGHT HALF OF THE LOADED WORD. (IF NO + VALUE CELL EXISTS, ONE IS TO BE CREATED.) + + TYPE 3 SMASHABLE CALL + SIMILAR TO TYPE 4 (Q.V.) EXCEPT THAT THE INSTRUCTION IS ONE OF + THE SERIES OF CALL UUOS WHICH MAY BE "SMASHED" FOR PURIFICATION + PURPOSES. AT PRESENT THESE UUOS ARE: CALL, JCALL, NCALL, NJCALL. + + TYPE 4 QUOTED ATOM + ONE WORD TO BE LOADED WHOSE RIGHT HALF CONTAINS THE INDEX OF AN + ATOM WHOSE ADDRESS IS TO REPLACE THE RIGHT HALF OF THE WORD + LOADED. + + TYPE 5 QUOTED LIST + A SERIES OF WORDS REPRESENTING AN S-EXPRESSION TO BE CONSTRUCTED + BY THE LOADER. THE FORMAT OF THESE WORDS IS BEST EXPLAINED BY + THE ALGORITHM USED TO CONTRUCT THE S-EXPRESSION: THE LOADER + EXAMINES BITS 4.7-4.9 OF SUCCESSIVELY READ WORDS, AND DISPATCHES + ON THEM: + 0 THE ATOM WHOSE INDEX IS IN THE RIGHT HALF OF THE WORD + IS PUSHED ONTO A STACK. + 1 THE LOADER POPS AS MANY ITEMS OFF THE STACK AS + SPECIFIED BY THE NUMBER IN THE RIGHT HALF OF THE WORD + AND MAKES A LIST OF THEM, SO THAT THE LAST ITEM POPPED + BECOMES THE FIRST ITEM OF THE LIST; THIS LIST IS THEN + PUSHED ONTO THE STACK. + 2 THE LOADER POPS ONE ITEM OFF THE STACK AND PROCEEDS AS + FOR 1, EXCEPT THAT THE ITEM FIRST POPPED IS USED TO + END THE LIST INSTEAD IF NIL. (THIS ALLOWS FOR DOTTED + PAIRS.) + 3 THE TOP ITEM ON THE STACK IS EVALUATED AND STORED BACK + ON THE TOP OF THE STACK. + 4 THE RIGHT HALF OR THE WORD SPECIFIES THE LENGTH OF A + HUNK TO BE MADE BY TAKING THAT MANY ITEMS FROM THE TOP + OF THE STACK; THIS HUNK IS THEN PUSHED BACK. + 5 UNUSED. + 6 UNUSED. + 7 THE LEFT HALF OF THE WORD SHOULD BE -1 OR -2, + INDICATING THE SECOND LAST WORD OF THE DATA; IF -1, + THE RIGHT HALF OF THIS WORD AND THE ADDRESS OF (WHAT + SHOULD BE) THE SINGLE ITEM ON THE STACK (WHICH IS + POPPED OFF) ARE MADE RESPECTIVELY INTO THE LEFT AND + RIGHT HALVES OF A WORD TO BE LOADED INTO BINARY + PROGRAM SPACE; IF -2, THE S-EXPRESSION IS PLACED INTO + THE NEXT SLOT OF THE ATOMTABLE (SEE TYPE 12). THE ONE + WORD REMAINING IS THE HASH KEY OF THE S-EXPRESSION AS + COMPUTED BY SXHASH; THIS IS USED BY THE LOADER TO SAVE + GCPRO SOME WORK. + + TYPE 6 GLOBALSYM + ONE WORD; THE RIGHT HALF IS AN INDEX INTO THE TABLE LSYMS IN + LISP. THE INDICATED VALUE IS RETRIEVED, NEGATED IF BIT 4.9 OF + THE DATA WORD IS 1, AND ADDED TO THE RIGHT HALF OF THE LAST + WORD LOADED INTO BINARY PROGRAM SPACE. THIS ALLOWS LAP CODE + TO REFER TO SELECTED LOCATIONS INTERNAL TO LISP WITHOUT + GETTING SYMBOLS FROM DDT. + + TYPE 7 GETDDTSYM + IF THE FIRST WORD IS -1, THEN THE LOAD OFFSET IS ADDED INTO + THE LEFT HALF OF THE WORD MOST RECENTLY LOADED INTO BINARY + PROGRAM SPACE (THIS IS HOW LEFT HALF RELOCATION IS + ACCOMPLISHED). OTHERWISE, THE FIRST WORD CONTAINS IN BITS + 1.1-4.5 A SYMBOL IN SQUOZE CODE. THE LOADER GETS THE VALUE OF + THIS SYMBOL FROM DDT IF POSSIBLE, NEGATES IT IF BIT 4.9 IS 1, + THEN ADDS THE RESULT TO THE FIELD OF THE LAST WORD LOADED AS + SPECIFIED BY BITS 4.6-4.7: + 3 = ENTIRE WORD + 2 = AC FIELD ONLY + 1 = RIGHT HALF ONLY + 0 = ENTIRE WORD, BUT SWAP HALVES OF VALUE BEFORE ADDING. + THESE FOUR FIELDS CORRESPOND TO OPCODE, AC, ADDRESS, AND INDEX + FIELDS RESPECTIVELY IN A LAP INSTRUCTION. IF BIT 4.8 IS A 1, + THEN ANOTHER WORD FOLLOWS, CONTAINING THE VALUE OF THE SYMBOL + AS OBTAINED FROM DDT AT ASSEMBLE TIME. IF THE VERSION NUMBER + OF THAT LISP (AS DETERMINED FROM THE SECOND FILE HEADER WORD) + IS THE SAME AS THAT OF THE LISP BEING LOADED INTO, THEN THIS + VALUE IS USED AND DDT IS NOT CONSULTED AT LOAD TIME; THIS IS + FOR SPEED. IF THE VERSION NUMBERS ARE DIFFERENT, THEN DDT IS + CONSULTED. + + TYPE 10 ARRAY REFERENCE + ONE WORD TO BE LOADED, WHOSE RIGHT HALF CONTAINS THE ATOMINDEX + OF AN ATOMIC SYMBOL. IF THE SYMBOL HAS AN ARRAY PROPERTY, IT + IS FETCHED; OTHERWISE ONE IS CREATED. THE RIGHT HALF OF THE + WORD TO BE LOADED IS REPLACED WITH THE ADDRESS OF THE SECOND + WORD OF THE ARRAY POINTER (I.E. OF THE TTSAR). IN THIS WAY + ACCESSES TO ARRAYS CAN BE OPEN-CODED. + + TYPE 11 UNUSED + + TYPE 12 ATOMTABLE INFO + A HEADER WORD, POSSIBLY FOLLOWED BY OTHERS, DEPENDING ON BITS + 4.7-4.9: + 0 THE RIGHT HALF IS THE NUMBER OF WORDS FOLLOWING, WHICH + CONSTITUTE THE PNAME OF A PNAME-TYPE ATOM, IN THE + ORDER OF THEIR APPEARANCE ON A PROPERTY LIST. THE ATOM + IS INTERNED. + 1 THE ONE WORD FOLLOWING IS THE VALUE OF A FIXNUM TO BE + CREATED. + 2 THE FOLLOWING WORD IS THE VALUE OF A FLONUM. + 3 THE RIGHT HALF IS THE NUMBER OF FIXNUM COMPONENTS OF A + BIGNUM FOLLOWING, MOST SIGNIFICANT WORD FIRST. BIT 3.1 + IS THE SIGN OF THE BIGNUM. + 4 THE FOLLOWING TWO WORDS ARE A DOUBLE-PRECISION NUMBER. + 5 THE FOLLOWING TWO WORDS ARE A COMPLEX NUMBER. + 6 THE FOLLOWING FOUR WORDS ARE A DUPLEX NUMBER. + 7 UNUSED. + THE ATOM THUS CREATED IS ASSIGNED A PLACE IN THE ATOMTABLE + MAINTAINED BY THE LOADER (AS AN ARRAY) USING CONSECUTIVE + LOCATIONS; FROM THAT POINT ON OTHER DATA ITEMS REFERRING TO + THAT ITEM CAN DO SO BY THE INDEX OF THE ATOM IN THIS TABLE. + SEE ALSO TYPES 5 AND 16, WHICH ALSO MAKE ENTRIES IN THE + ATOMTABLE. + + TYPE 13 ENTRY INFO + TWO WORDS. THE LEFT HALF OF THE FIRST WORD IS THE ATOMINDEX + OF THE NAME OF THE FUNCTION BEING DEFINED; THE RIGHT HALF + THAT OF THE SUBR TYPE (THE PROPERTY UNDER WHICH TO CREATE THE + ENTRY POINT, E.G. SUBR OR FSUBR). THE RIGHT HALF OF THE + SECOND WORD IS THE LOCATION OF THE ENTRY POINT AS A + RELOCATABLE POINTER: THE LOAD OFFSET MUST BE ADDED TO IT. THE + LEFT HALF OF THE SECOND WORD CONTAINS THE ARGS PROPERTY, IN + INTERNAL ARGS PROPERTY FORMAT, AS SPECIFIED IN THE ORIGINAL + LAP CODE BY THE ARGS CONSTRUCT. + + TYPE 14 LOC + THE WORD IS A RELOCATABLE QUANTITY SPECIFYING WHERE TO + CONTINUE LOADING. IT IS NOT PERMITTED TO LOC BELOW THE + ORIGIN OF THE ASSEMBLY. IF THE LOC IS TO A LOCATION HIGHER + THAN ANY YET LOADED INTO, THEN FASLOAD ZEROS OUT ALL WORDS + ABOVE THAT HIGHEST LOCATION UP TO THE LOCATION SPECIFIED. + FASLOAD KEEPS TRACK OF THE HIGHEST LOCATION EVER LOADED INTO; + THIS VALUE PLUS ONE BECOMES THE VALUE OF BPORG AT THE END OF + ASSEMBLY, REGARDLESS OF THE STATE OF THE LOCATION POINTER + WHEN LOADING TERMINATES. THIS TYPE IS NEVER USED BY LAP + CODE, BUT ONLY BY MIDAS .FASL CODE. + + TYPE 15 PUTDDTSYM + FIRST WORD, THE SYMBOL IN SQUOZE CODE. IF BIT 4.9=0, THE + SYMBOL IS DEFINED TO DDT IF POSSIBLE WITH THE ADDRESS OF THE + WORD OF BINARY PROGRAM SPACE ABOUT TO BE LOADED INTO AS ITS + VALUE. IF BIT 4.9=1, THE VALUE IS GOBBLED FROM THE FOLLOWING + WORD. BIT 4.8 (OF THE WORD CONTAINING THE SQUOZE) MEANS + RELOCATE THE LEFT HALF OF THE VALUE BY THE LOAD OFFSET, AND + BIT 4.7 LIKEWISE FOR THE RIGHT HALF. WHETHER OR NOT THE + SYMBOL ACTUALLY GETS PUT IN DDT'S SYMBOL TABLE IS A FUNCTION + OF THREE CONDITIONS: FIRST, THAT THERE IS A DDT WITH A SYMBOL + TABLE; SECOND, THE VALUE OF THE LISP VARIABLE "SYMBOLS"; + THIRD, BIT 4.6 OF THE FIRST PUTDDTSYM WORD. THE FIRST + CONDITION OF COURSE MUST BE SATISFIED. IF SO, THEN THE SYMBOL + IS PUT IN THE SYMBOL TABLE ONLY IF SYMBOLS HAS A NON-NIL + VALUE. FURTHERMORE, IF THAT VALUE IS THE ATOM SYMBOLS ITSELF, + THEN THE SYMBOL IS PUT ONLY IF BIT 4.6 IS ON (INDICATING A + "GLOBAL" SYMBOL). + + TYPE 16 EVAL MUNGEABLE + A SERIES OF WORDS SIMILAR TO THOSE FOR TYPE 5, BUT WITH NO + FOLLOWING HASH KEY. AN S-EXPRESSION IS CONSTRUCTED AND + EVALUATED. THIS IS USED FOR THE SO-CALLED "MUNGEABLES" IN A + FILE OF LAP CODE. IF THE LEFT HALF OF THE LAST WORD IS -1, + THE VALUE IS THROWN AWAY. IF IT IS -2, THE VALUE IS ENTERED + IN THE ATOMTABLE. + + TYPE 17 END OF BINARY + ONE WORD, WHICH MUST BE "*FASL+" (OR "*FASL*") IN SIXBIT. + THIS SHOULD BE THE LAST DATA WORD IN THE FILE. ANY RELOCATION + BYTES LEFT OVER AFTER A TYPE 17 ARE IGNORED. THIS SHOULD BE + FOLLOWED EITHER BY END OF FILE OR A WORD FULL OF ^C'S. + +THE "NEW" FASLOAD SCHEME (AS OF 1/31/73) USES A NEW FORMAT +FOR ITS FILES. A FASL FILE CONSISTS OF TWO HEADER WORDS, +FOLLOWED BY A SERIES OF FASL BLOCKS; THE TWO HEADER WORDS +ARE BOTH SIXBIT, THE FIRST BEING "*FASL*" AND THE SECOND +THE CONTENTS OF LOCATION LDFNM2 IN THE LISP WHICH ASSEMBLED +THE FILE (A VERSION NUMBER IN SIXBIT). +EACH FASL BLOCK CONSISTS OF A WORD OF NINE FOUR-BIT +RELOCATION BYTES, FOLLOWED BY NINE PIECES OF FASL DATA. +THE LENGTH OF EACH DATA ITEM IS DEPENDENT ON THE +RELOCATION TYPE; THUS FASLBLOCKS ARE OF VARYING LENGTH. +THE LAST BLOCK MAY HAVE FEWER THAN NINE DATA ITEMS. +THE RELOCATION TYPES AND THE FORMATS OF THE ASSOCIATED +DATA ITEMS ARE AS FOLLOWS: + +TYPE NAME DATA FORMAT + +0 ABSOLUTE ONE ABSOLUTE WORD TO BE LOADED. +1 RELOCATABLE ONE WORD, THE RIGHT HALF OF WHICH + IS RELOCATABLE; I.E. AT LOAD TIME + THE LOAD OFFSET IS TO BE ADDED TO + THE RIGHT HALF. +2 SPECIAL A WORD TO BE LOADED, WHOSE RIGHT + HALF CONTAINS THE INDEX OF AN ATOM + (HOPEFULLY OF TYPE PNAME) THE ADDRESS + OF THE VALUE CELL OF WHICH IS TO + REPLACE THE RIGHT HALF OF THE LOADED + WORD. (IF NO VALUE CELL EXISTS, ONE + IS TO BE CREATED.) +3 SMASHABLE CALL SIMILAR TO TYPE 4 (Q.V.) EXCEPT THAT + THE INSTRUCTION IS ONE OF THE SERIES + OF CALL UUOS WHICH MAY BE "SMASHED" + FOR PURIFICATION PURPOSES. AT PRESENT + THESE UUOS ARE: CALL, JCALL, NCALL, + NJCALL. +4 QUOTE ATOM ONE WORD TO BE LOADED WHOSE RIGHT HALF + CONTAINS THE INDEX OF AN ATOM WHOSE + ADDRESS IS TO REPLACE THE RIGHT HALF + OF THE WORD LOADED. +5 QUOTE LIST A SERIES OF WORDS REPRESENTING AN + S-EXPRESSION TO BE CONSTRUCTED BY THE + LOADER. THE FORMAT OF THESE WORDS IS + BEST EXPLAINED BY THE ALGORITHM USED + TO CONTRUCT THE S-EXPRESSION: THE + LOADER EXAMINES BITS 4.7-4.9 OF EACH + WORD. IF 0, THEN THE ATOM WHOSE INDEX + IS IN THE RIGHT HALF OF THE WORD IS + PUSHED ONTO A STACK. IF 1, THEN THE + LOADER POPS AS MANY ITEMS OFF THE STACK + AS SPECIFIED BY THE NUMBER IN THE RIGHT HALF + OF THE WORD AND MAKES A LIST OF THEM, SO THAT + THE LAST ITEM POPPED BECOMES THE FIRST + ITEM OF THE LIST; THIS LIST IS THEN + PUSHED ONTO THE STACK. IF 2, THEN THE + LOADER POPS ONE ITEM OFF THE STACK AND + PROCEEDS AS FOR 1, EXCEPT THAT THE ITEM + FIRST POPPED IS USED TO END THE LIST + INSTEAD IF NIL. (THIS ALLOWS FOR DOTTED + PAIRS.) IF 3, THEN THE TOP ITEM ON THE STACK + IS EVALUATED AND RESTORED BACK ON THE TOP OF + THE STACK. IF 7, THEN THE LEFT HALF OF THE + WORD SHOULD BE -1 OR -2, INDICATING THE + SECOND LAST WORD OF THE DATA; IF -1, + THE RIGHT HALF OF THIS WORD AND THE + ADDRESS OF (WHAT SHOULD BE) THE SINGLE + ITEM ON THE STACK (WHICH IS POPPED OFF) + ARE MADE RESPECTIVELY INTO THE LEFT AND + RIGHT HALVES OF A WORD TO BE LOADED INTO + BINARY PROGRAM SPACE; IF -2, THE + S-EXPRESSION IS PLACED INTO THE NEXT + SLOT OF THE ATOMTABLE (SEE TYPE 12). + THE ONE WORD REMAINING IS THE HASH KEY + OF THE S-EXPRESSION AS COMPUTED BY + SXHASH; THIS IS USED BY THE LOADER + TO SAVE GCPRO SOME WORK. +6 GLOBALSYM ONE WORD; THE RIGHT HALF IS AN INDEX + INTO THE TABLE LSYMS IN LISP. THE + INDICATED VALUE IS RETRIEVED, NEGATED + IF BIT 4.9 OF THE DATA WORD IS 1, AND + ADDED TO THE RIGHT HALF OF THE LAST + WORD LOADED INTO BINARY PROGRAM SPACE. + THIS ALLOWS LAP CODE TO REFER TO + SELECTED LOCATIONS INTERNAL TO LISP + WITHOUT GETTING SYMBOLS FROM DDT. +7 GETDDTSYM IF THE FIRST WORD IS -1, THEN THE LOAD + OFFSET IF ADDED INTO THE LEFT HALF + OF THE WORD MOST RECENTLY LOADED INTO + BINARY PROGRAM SPACE (THIS IS HOW LEFT + HALF RELOCATION IS ACCOMPLISHED). + OTHERWISE, THE FIRST WORD + CONTAINS IN BITS 1.1-4.5 A SYMBOL + IN SQUOZE CODE. THE LOADER GETS + THE VALUE OF THIS SYMBOL FROM DDT + IF POSSIBLE, NEGATES IT IF BIT 4.9 + IS 1, THEN ADDS THE RESULT TO THE + FIELD OF THE LAST WORD LOADED AS + SPECIFIED BY BITS 4.6-4.7: + 3=ENTIRE WORD + 2=AC FIELD ONLY + 1=RIGHT HALF ONLY + 0=ENTIRE WORD, BUT SWAP HALVES OF + VALUE BEFORE ADDING. + THESE FOUR FIELDS CORRESPOND TO + OPCODE, AC, ADDRESS, AND INDEX FIELDS + RESPECTIVELY IN A LAP INSTRUCTION. + IF BIT 4.8 IS A 1, THEN ANOTHER WORD + FOLLOWS, CONTAINING THE VALUE OF THE + SYMBOL AS OBTAINED FROM DDT AT + ASSEMBLE TIME. IF THE VERSION NUMBER + OF THAT LISP (AS DETERMINED FROM THE + SECOND FILE HEADER WORD) IS THE SAME + AS THAT OF THE LISP BEING LOADED INTO, + THEN THIS VALUE IS USED AND DDT IS NOT + CONSULTED AT LOAD TIME; THIS IS FOR + SPEED. IF THE VERSION NUMBERS ARE + DIFFERENT, THEN DDT IS CONSULTED. +10 ARRAY REF ONE WORD TO BE LOADED, WHOSE RIGHT HALF + CONTAINS THE ATOMINDEX OF AN ATOMIC + SYMBOL. IF THE SYMBOL HAS AN ARRAY + PROPERTY, IT IS FETCHED; OTHERWISE + ONE IS CREATED. THE RIGHT HALF OF THE + WORD TO BE LOADED IS REPLACED WITH + THE ADDRESS OF THE SECOND WORD OF THE + ARRAY POINTER (I.E. OF THE TTSAR). + IN THIS WAY ACCESSES TO ARRAYS CAN BE + OPEN-CODED. +11 UNUSED [ERROR IN FILE] +12 ATOMTABLE INFO A HEADER WORD, POSSIBLY FOLLOWED BY + OTHERS, DEPENDING ON BITS 4.7-4.8: + IF 0, THE RIGHT HALF IS THE NUMBER + OF WORDS FOLLOWING, WHICH CONSTITUTE + THE PNAME OF A PNAME-TYPE ATOM, IN THE + ORDER OF THEIR APPEARANCE ON A + PROPERTY LIST. THE ATOM IS INTERNED. + IF 1, THE ONE WORD FOLLOWING IS + THE VALUE OF A FIXNUM TO BE CREATED. + IF 2, THE FOLLOWING WORD IS THE VALUE + OF A FLONUM. IF 3, THE RIGHT HALF IS + THE NUMBER OF FIXNUM COMPONENTS OF A + BIGNUM FOLLOWING, MOST SIGNIFICANT + WORD FIRST. THE HEADER WORD CONTAINS + THREE BITS OF THE SIGN OF THE BIGNUM + IN BITS 3.1-3.3. + THE ATOM THUS CREATED IS ASSIGNED A + PLACE IN THE ATOMTABLE MAINTAINED BY + THE LOADER (AS AN ARRAY) USING + CONSECUTIVE LOCATIONS; FROM THAT POINT + ON OTHER DATA ITEMS REFERRING TO THAT + ITEM CAN DO SO BY THE INDEX OF THE + ATOM IN THIS TABLE. + SEE ALSO TYPES 5 AND 16, WHICH ALSO + MAKE ENTRIES IN THE ATOMTABLE. +13 ENTRY INFO TWO WORDS. THE LEFT HALF OF THE FIRST + WORD IS THE ATOMINDEX OF THE NAME OF + THE FUNCTION BEING DEFINED; THE RIGHT + HALF THAT OF THE SUBR TYPE (THE + PROPERTY UNDER WHICH TO CREATE THE + ENTRY POINT, E.G. SUBR OR FSUBR). + THE RIGHT HALF OF THE SECOND WORD IS + THE LOCATION OF THE ENTRY POINT AS A + RELOCATABLE POINTER: THE LOAD OFFSET + MUST BE ADDED TO IT. THE LEFT HALF OF + THE SECOND WORD CONTAINS INFORMATION + USED TO CREATE AN ARGS PROPERTY FOR + THE FUNCTION AS SPECIFIED IN THE + ORIGINAL LAP CODE. IF THIS HALFWORD + IS ZERO, NO ARGS PROPERTY IS CREATED + AND ANY ALREADY PRESENT IS REMOVED. + OTHERWISE THE HALFWORD IS DIVIDED INTO + TWO NINE-BIT BYTES, EACH OF WHICH IS + CONVERTED AS FOLLOWS: + BYTE RESULT + 0 NIL + 777 777 + N N-1, WHERE N IS NOT 0 OR 777 + THESE TWO ITEMS ARE THEN CONSED AND + FOR THE ARGS PROPERTY. +14 LOC THE WORD IS A RELOCATABLE QUANTITY + SPECIFYING WHERE TO CONTINUE LOADING. + IT IS NOT PERMITTED TO LOC BELOW THE + ORIGIN OF THE ASSEMBLY. IF THE LOC + IS TO A LOCATION HIGHER THAN ANY YET + LOADED INTO, THEN FASLOAD ZEROS OUT + ALL WORDS ABOVE THAT HIGHEST LOCATION + UP TO THE LOCATION SPECIFIED. + FASLOAD KEEPS TRACK OF THE HIGHEST + LOCATION EVER LOADED INTO; THIS VALUE + PLUS ONE BECOMES THE VALUE OF BPORG + AT THE END OF ASSEMBLY, REGARDLESS + OF THE STATE OF THE LOCATION POINTER + WHEN LOADING TERMINATES. +15 PUTDDTSYM FIRST WORD, THE SYMBOL IN SQUOZE CODE. + IF BIT 4.9=0, THE SYMBOL IS DEFINED TO + DDT IF POSSIBLE WITH THE ADDRESS OF THE + WORD OF BINARY PROGRAM SPACE ABOUT + TO BE LOADED INTO AS ITS VALUE. + IF BIT 4.9=1, THE VALUE IS GOBBLED FROM + THE FOLLOWING WORD. BIT 4.8 (OF THE WORD + CONTAINING THE SQUOZE) MEANS RELOCATE + THE LEFT HALF OF THE VALUE BY THE LOAD + OFFSET, AND BIT 4.7 LIKEWISE FOR THE + RIGHT HALF. + WHETHER OR NOT THE SYMBOL ACTUALLY GETS + PUT IN DDT'S SYMBOL TABLE IS A FUNCTION + OF THREE CONDITIONS: FIRST, THAT THERE + IS A DDT WITH A SYMBOL TABLE; SECOND, + THE VALUE OF THE VARIABLE SYMBOLS; + THIRD, BIT 4.6 OF THE FIRST PUTDDTSYM + WORD. THE FIRST CONDITION OF COURSE MUST + BE SATISFIED. IF SO, THEN THE SYMBOL IS + PUT IN THE SYMBOL TABLE ONLY IF SYMBOLS + HAS A NON-NIL VALUE. FURTHERMORE, IF + THAT VALUE IS THE ATOM SYMBOLS ITSELF, + THEN THE SYMBOL IS PUT ONLY IF BIT 4.6 + IS ON (INDICATING A "GLOBAL" SYMBOL). +16 EVAL MUNGEABLE A SERIES OF WORDS SIMILAR TO THOSE + FOR TYPE 5, BUT WITH NO FOLLOWING + HASH KEY. AN S-EXPRESSION IS + CONSTRUCTED AND EVALUATED. THIS IS + USED FOR THE SO-CALLED "MUNGEABLES" + IN A FILE OF LAP CODE. + IF THE LEFT HALF OF THE LAST WORD IS + -1, THE VALUE IS THROWN AWAY. IF IT + IS -2, THE VALUE IS ENTERED IN THE + ATOMTABLE. +17 END OF BINARY ONE WORD, WHICH MUST BE "*FASL*" IN + SIXBIT. THIS SHOULD BE THE LAST DATA + WORD IN THE FILE. ANY RELOCATION + BYTES LEFT OVER AFTER A TYPE 17 ARE + IGNORED. +THIS SHOULD BE FOLLOWED EITHER BY END OF FILE OR A WORD +FULL OF ^C'S. diff --git a/doc/_info_/lisp.cursor b/doc/_info_/lisp.cursor new file mode 100755 index 00000000..17b3fc3a --- /dev/null +++ b/doc/_info_/lisp.cursor @@ -0,0 +1,86 @@ +Cursorpos in Lisp: + +CURSORPOS is an LSUBR of 0-3 evaluated arguments. If no arguments are +given, then the cursor coordinates of the default output TTY are returned +as a dotted pair in the form (line# . column#). If args are specified, +then the result is determined as shown below (returns "T" on success, "NIL" +on failure) and if the last arg is a TTY output file then it is used +instead of the default. Note that the "T" option alone will return the +coordinates of TTY "T" rather than homing the cursor; see "T" below. With +two numeric args given, the cursor is moved to the ARG1th line and ARG2th +column. + +These are the special codes used for (CURSORPOS []): + +A Advance to a fresh line. If at beginning of line do nothing, + else act like a CRLF. +B move Backward. Decrements the horizontal position. + If the horizontal position is 0, it is set to the horizontal + screen size (wraparound from left margin to right margin). +C Clear screen. The cursor goes to the upper left corner and + the whole screen is cleared. On a printing tty (%TOMVU is 0) + a CRLF is output, since "clearing the screen" is undefined. + If "C" is output to the echo area, only the echo area is + cleared, and only the echo area cursor is moved. +D move Down. The vertical position is incremented. If it becomes + equal to the vertical screen size, it is set to 0. +E clear to Eof. The remainder of the current line, and all lower + lines, are erased. The cursor doesn't move. +F move Forward. The horizontal position is incremented. At the + end of the line it wraps around to the beginning of the + same line. +H set Horizontal position. Takes one extra argument: it + should be the desired horizontal position setting. + The vertical position is not changed. An attempt to + set the position beyond a margin will position it at the + margin. +I Outputs a one-position printing character. Takes an extra + argument: the numeric ASCII code of the desired character. +K Kill (erase) the character the cursor points at. The cursor + does not move. The position erased is the one that would be + written in next by ordinary output. +L clear Line. The current line, starting with the position that + the cursor points at, is erased. The cursor does not move. +M (More) hang up until a character is read in then home-up. +N (No home-up) similar, but don't home up after the character is + read. +P output a . +Q output a . +R Restore cursor position. The cursor is set to the most + recently saved value. +S Save cursor position. Remembers the current cursor position + for use with "R". There is no stack for saved cursor + positions; only the most recent saved position is remembered. +T go to Top of screen (home up). The cursor is positioned at the + upper left corner of the screen. Note: since "T" will be + taken to mean output TTY "T" an alternate form must be used. + (CURSORPOS 'top), (CURSORPOS 84.), and (CURSORPOS 'T 'T) will + all work. +U move Up. The vertical position is decremented. If it was 0, + it becomes equal to the vertical size minus one. +V set Vertical position. Takes an argument--the desired vertical + position. An attempt to set the cursor beyond the top or bottom + margin will position it as far as allowed in the desired direction. + Similarly, "V" will not move the echo area cursor outside the echo + area. Note that vertical positions in the echo area are to be + specified relative to the top of the echo area. +X backspace and erase one character ("B" followed by "K"). +Z home down. The cursor is positioned at the lower left corner. +] obsolete - same as "L". +[ insert line. The current line and all lines below it are + pushed down one slot. A blank line appears at the current + position. The cursor does not move. Works only on terminals + which have %TOLID set ("\" also). See :TTYVAR TTYOPT + for information on %TOLID. +\ delete line. The current line disappears, and all the lines + below it move up by one position. The bottom line becomes + blank. The cursor does not move. +^ insert character. All the characters after the cursor move + right one position. The last one moves off the right margin + and disappears. A space appears at the cursor, which does not + move. Works only on terminals which have %TOCID set ("_" also). + See :TTYVAR TTYOPT for information on %TOCID. +_ delete character. The character at the cursor disappears, and + all the rest of the characters on the line move left one + position. A space appears at the end of the line. The cursor + does not move. Note: it's an underscore, not hyphen. diff --git a/doc/_info_/lisp.defvst b/doc/_info_/lisp.defvst new file mode 100755 index 00000000..7d933ec2 --- /dev/null +++ b/doc/_info_/lisp.defvst @@ -0,0 +1,248 @@ + + DEFVST is an acronym for "DEFine a Vector-like STructure" + All entries in a Vector-like structure are "pointers" (FIXNUMs, LISTs, etc) + Future plans call for + DEFBST - "DEFine a Bitstring-like STructure", useful where + the structure is an interface to some memory + block required to be sequential by, say, operating + system conventions, or hardware needs. + DEFSTRUCT - "DEFine a general STRUCTure" + which will be done by composing DEFVST and DEFBST. + Vector-like structures are implemented as EXTENDs, which are emulated in + maclisp by HUNKs, and on the LISPMachine by 1-dimensional + ART-Q arrays; EXTENDs interface to a CLASS system, which in MacLISP + interface will be activated at any time when the CLASS system is loaded -- + only a skeletal amount of information is necessary in each class + of vector-like structures in order to prepare for the link-up. + + Free (global) variables controlling actions: + CONSTRUCTOR-NAMESTRING-PREFIX - constructor name is obtained by + concatenating this string with the + structure name. + SELECTOR-NAMESTRING-STYLE - () ==> selector macro name is same + as keyword (variable name). + - "xxx" ==> selector macro name gotten + by concatenating structure + name, "xxx", and keyword. + + Basic macros: DEFVST for defining a structure + SETVST for updating a selected component + (and SETF) + Also, an interface from DEFSTRUCT has been defined (see its documentation). + + Additional functions: + STRUCT-TYPEP for "structures", returns the given name, + and for non-structures, returns (). + |defvst-construction/||, |defvst-initialize/||, |defvst-typchk/||, + |defvst-construction-1/||, |defvst-selection/||, and |defvst-xref/|| + are internal helper functions. + + Usage is like: + (DEFVST SHIP + (X-POSITION /: FIXNUM) + Y-POSITION + (MASS = 1000.) + (COST (DAY-HIGH-PRICE)) + COLOR ) + (SETVST (SHIP-X-POSITION QE2) 109.) + or alternatively, + (SETF (SHIP-X-POSITION QE2) 109.) + since SETF will macroexpand out the component selector, and thus turn + into SETVST, on structures references. Also, a set of "options" may + be specified by including the structure name in a list: + (DEFVST (SHIP ...) ...) + currently, only :CONSTRUCTOR and :NO-SELECTOR-MACROS are valid options. + + Note that "=" is used as a keyword in the component part to mean + an initialization form follows; and that a component specification + which is just a 2-list is expanded like + (
    ) ==> ( = ) + This is done for compatibility of style with the LISPM defstructure. + See further notes below for the meaning of the ":" in the default form. + + + + The SETVST macro (and SETF) is used in conjunction with DEFVST. The + example use of DEFVST "defines" a vector-like structure of 4 components; + the generic name of this structure is "SHIP", and the components are + identified by the ordering of what are called keywords - X-POSITION, + Y-POSITION, MASS, and COLOR. Each "definition" causes the creation of + 1) A constructor macro, whose name (normally) is obtained by prefixing + the string "CONS-A-" onto the generic name of the structure. + (Actually, it gets this prefix string from the variable + CONSTRUCTOR-NAMESTRING-PREFIX, so that it can be modified) + In the example, this becomes CONS-A-SHIP. The constructor + permits installing values into the component slots at instantiation + time, which are evaluated from either the (default) forms supplied + by the invocation of DEFVST, or from the forms obtained by keyword + parameters in the instantiating form. E.g. + (CONS-A-BANK DOLLARS (PLUS 300. WALLET) MANAGER '|Jones, J.|) + would put the numerical value of 300.+WALLET in the DOLLARS + component of a newly-created bank, and install |Jones, J.| as + its MANAGER. When the CONSTRUCTOR option is given, the user + supplies a specific name for this macro. + 2) N selector macros, one for each keyword (which denotes one + component slot), which are obtained (normally) by concatenating + the generic name, a "-", and the keyword name. (Actually, + the middle string is obtained from the value of the variable + SELECTOR-NAMESTRING-STYLE, so that it can be modified) + In the example, we have SHIP-X-POSITION, SHIP-Y-POSITION, + SHIP-MASS, and SHIP-COLOR. + 2a: (SHIP-X-POSITION QE2) + to obtain the x-coordinate of QE2 + 2b: (SETVST (SHIP-X-POSITION QE2) 109.) + to change the x-coordinate to of QE2 to 109. + One interesting facet of the selector macroexpansions is that + when done for compilation, the turn into the MacLISP CXR, + which can generally be open-coded in one or two instructions. + But when expanded during interpretation, the go thru a + safety checking function, which assures that a selector + created for a SHIP structure is only applied to SHIP structures, + and not to other kinds of data, or other structures. + When the NO-SELECTOR-MACROS option is given, then these macros, + like SHIP-X-POSITION, are not created; this is intended to + delete the spurious creation of macros, when another macro + package is using DEFVST like a subroutine. + 3) An information structure, stored as the STRUCT=INFO property + of the generic name symbol. This information has the shape + (DEFVST STRUCT=INFO + VERSION-NUMBER + GENERIC-NAME + CONSTRUCTOR-NAME + NUMBER-OF-NAMED-COMPONENTS + COMPONENT-DEFAULT-INITIALIZATION-LISTS + CLASS-SKELETON) + The generic name corresponds to the "name" of the structure + being defined; in the example, it is BANK. The version number + corresponds to a version of "implementation status" for DEFVST -- + thus it should be possible to make rather radical changes in + the future implementation, while maintain compatibility with + previously compiled structures (that means that existing FASL + files won't have to be recompiled whenever some change to + DEFVST is made). + The zero'th element of the initializations is either (), or a + 3-list of the key-name, selector-name, and default size for the + &REST component - the "block" of unnamed components in the + structure. The remaining elements of the initializations are + the "initialization lists" for each named component: + ( ) + ;() initial value, no restrictions + ( ) + ;no restrictions + ( + . ) + + + CONSTRAINTS, and INITIAL VALUES + Each of the components may be constrained to be a particular + type datum, and may be initialized according to the form supplied + as default by the call to DEFVST. + The syntax for a non-simple component specification is a list with + the first element being the key name, the item following the first + "=" in the list being a form which is the default form to be evaluated + for that component in any creations of instances of that structure, + and the element following the first ":" is either a type name or list + of type names that restricts any creating instance from supplying an + initial value of the wrong type. If a key has a restriction + associated with it, but no default initial-value form, then DEFVST + picks some default value consistent with the restriction. + + Consider the example + + (DEFVST BANK + (DOLLARS : (FIXNUM FLONUM MUMBLE)) + MANAGER + (LIMIT : (FIXNUM FLONUM) = 1000000.0) + &REST + VAULTS + 30.) + + First, the macro invocation of DEFVST would expand into + + (EVAL-WHEN (EVAL COMPILE LOAD) + (AND (STATUS FEATURE COMPLR) (SPECIAL BANK-CLASS)) + (DEFPROP BANK BANK-CLASS CLASS-VAR) + (|defvst-initialize/|| + 'BANK ;structure name + 'CONS-A-BANK ;constructor name + 3 ;number of components in each structure + '#((VAULTS BANK-VAULTS 36) ;vector of slot information + (DOLLARS BANK-DOLLARS 0 FIXNUM FLONUM MUMBLE) + (MANAGER BANK-MANAGER) + (LIMIT BANK-LIMIT 1000000.0 FIXNUM FLONUM)) + 2 ;"generation" number of DEFVST + '((DSK JONL) TEST EXAMPL)) ;file being processed when DEFVST expanded + (DEFPROP BANK-VAULTS (BANK 4 &REST) SELECTOR) + 'BANK) + + The internal function |defvst-initialize/|| creates the STRUCT=INFO + property for BANK, and sets up macro definitions for all the selector + names, and for the constructor name; also, a "skeleton" is framed + so that all instances may be grouped into a CLASS of such structures. + (This information is kept in in the STRUCT=INFO property.) When the + CLASS system is actually loaded, the skeletons will be fleshed out + to the full degree [ see the documentation on the MacLISP SEND + facility, and on the EXTENDed CLASS system]. + After that, then, a "simple" creation instance will take default values + for all components with either initial value or restriction + specifications, and null in the unspecified components; for example + (CONS-A-BANK) + then yields an instance, which when printed as a VECTOR, is like + #( 0 () 1.0E6 () . . . () ) + namely, a bank with three named components, and with 30. unnamed + components which are accessed as if VAULTS were a vector name. + Note that the the function CLASS-OF (and also SI:EXTEND-CLASS-OF) + gets the class descriptor for this class of structures, which + may be only a "skeleton" when the CLASS system isn't loaded. + + A more complex example of construction, such as, + + (CONS-A-BANK DOLLARS (CASEQ VIP + (FEDERAL 15.0E9) + (SAVINGS-&-LOAN 10.0E6) + (MICKEY-MOUSE 1)) + MANAGER '|Jones, J.| + LIMIT (BANK-DOLLARS CURRENT-CONSTRUCTION) + VAULTS 12.) + + illustrates four points of a creating instance - - + (1) keywords paired with initial values are just alternating + pairs in the list, and + (2) the forms for initial values are substituted into a piece of + code output by the macro, so that they are evaluated at + instantiation time, and + (3) the variable CURRENT-CONSTRUCTION is temporarily bound to the + structure being created so that it may be referenced; the + installing of initial values happens last. + (4) components which are under a restriction, and are not constant + (at compile time) must be submitted to dynamic type checking. + Notice how this macro-expands -- + + (LET ((CURRENT-CONSTRUCTION (SI:MAKE-EXTEND 33. BANK-CLASS))) + (SETVST (BANK-DOLLARS CURRENT-CONSTRUCTION) + (|defvst-typchk/|| (CASEQ VIP + (FEDERAL 1.5E+10) + (SAVINGS-&-LOAN 10000000.0) + (MICKEY-MOUSE 1)) + '(FIXNUM FLONUM MUMBLE) + 'BANK-DOLLARS)) + (SETVST (BANK-LIMIT CURRENT-CONSTRUCTION) + (|defvst-typchk/|| (BANK-DOLLARS CURRENT-CONSTRUCTION) + '(FIXNUM FLONUM) + 'BANK-LIMIT)) + CURRENT-CONSTRUCTION) + + This code might actually not run, since it could stop on a Restriction + Violation if the variable VIP does not have a value among + FEDERAL, SAVINGS-&-LOAN, MICKEY-MOUSE + for then it would turn up a () for the DOLLARS component, which + was specified to be restricted to fixnums. + + Further macro-expansion causes the "SETVST"s to become "SI:XSET"s. + In maclisp, SI:XREF becomes CXR, SI:XSET becomes RPLACX, and + SI:MAKE-EXTEND becomes MAKHUNK (that is how EXTEND's are emulated + there). Neither the EXTEND package nor any runtime CLASS facilities + need be loaded in the runtime environment of code which uses structures, + since dynamic tests are made before any of these facilites are are used + (that is, any facility beyond the MacLISP native HUNK capability). + diff --git a/doc/_info_/lisp.edit b/doc/_info_/lisp.edit new file mode 100755 index 00000000..96b3f6bb --- /dev/null +++ b/doc/_info_/lisp.edit @@ -0,0 +1,239 @@ + +The following excerpts from the historical maclisp update files +may help the luser of the Kludgy Binford Editor + + +5/15/71 -JONL- +. . . +8) THE BINFORD EDITOR HAS BEEN IN LISP FOR SOME TIME, BUT WAS +UNDOCUMENTED [EXCEPT BY WORD OF MOUTH.] FOR THOSE WHO HAVE ALREADY +USED IT, NOTE THAT IT HAS BEEN CHANGED EVER SO SLIGHTLY IN LISP 190] +EVAL'ING (EDIT) ENTERS EDIT MODE, WHEREIN COMMANDS ARE GIVEN SIMILAR +TO TECO COMMANDS, ACTION IS TAKEN ON SOME EXPRESSION CURRENTLY IN THE +WORKING SPACE, AND A WINDOW AROUND THE POINTER IS PRINTED OUT AFTER +EVERY COMMAND EXECUTION. (EDIT T) ENTERS EDIT MODE BUT DOES NOT +TYPE OUT THE WINDOW AFTER EVERY COMMAND. [THE P COMMAND WILL CAUSE +PRINTING OF THE WINDOW - USEFUL WHEN AT A TELETYPE]. COMMANDS ARE: + Q EXIT FROM THE EDITOR BACK TO LISP. + YATOM CAUSES THE FUNCTION PROPERTY OF ATOM TO + BE BROUGHT IN FOR EDITING. + YPATOMPROP YANK IN THE PROP PROPERTY OF + THE ATOM ATOM. + YPATOM YANKS THE WHOLE PROPERTY LIST OF ATOM. + J CAUSES THE POINTER [WHICH IS PRINTED OUT AS ] TO + JUMP TO THE TOP OF THE WORKING EXPRESSION. + SE1 . . . EN SEARCHES FOR AN OCCURENCE + OF THE SEQUENCE OF S-EXPRESSIONS E1 . . . EN AND + MOVES THE POINTER JUST TO THE RIGHT IF SUCCESSFUL. + NOTE THAT THE LISP READER IS USED FOR READ-IN BY THE + EDITOR, SO THAT THE ATOM MUST BE + FOLLOWED BY SOME ATOM TERMINATING CHARACTER + [SUCH AS ]. + IE1 . . . EN INSERTS AT THE CURRENT + POINTER POSITION THE SEQUENCE E1 . . . EN + K KILLS THE S-EXPRESSION JUST TO THE RIGHT OF THE + POINTER, AND SAVES IT AS THE VALUE OF THE ATOM . + IVEXP INSERTS THE VALUE OF THE S-EXPRESSION EXP. + ESPECIALLY USEFUL WHEN INSERTING STUFF DELETED FROM + SOME PRIOR POINT. + EVEXP MERELY EVALUATES EXP. +HENCEFORWARD, WILL NOT BE EXPLICITLY WRITTEN OUT, BUT WILL BE +UNDERSTOOD TO BE THE COMMAND TERMINATION CHARACTER. THE NEXT GROUP +OF COMMANDS ADMIT AN OPTIONAL NUMERIC ARGUMENT [BASE 10.], PRECEEDING +THE COMMAND, TO BE INTERPRETED AS A REPLICATION NUMBER: + F MOVE FORWARD [RIGHTWARDS] PAST ONE TOKEN. A TOKEN IS + EITHER A PARENTHESIS OR AN ATOM. + C SAME AS F + -B SAME AS F + B MOVE BACK [LEFTWARDS] OVER ONE TOKEN. + -C SAME AS B + -F SAME AS B + R MOVE RIGHTWARDS PAST THE NEXT S-EXPRESSION. + L MOVE LEFT OVER ONE S-EXPRESSION. + D MOVE "DOWN" INTO THE FIRST NON-ATOMIC S-EXPRESSION TO THE + RIGHT OF THE POINTER. + U MOVE "UP" OUT OF THE S-EXPRESSION CONTAINING THE POINTER. + K KILL ALSO ADMITS A REPLICATION NUMBER. + PW ARG IS NOT REALLY A REPLICATION NUMBER, + BUT RATHER THE "WINDOW WIDTH" IN NUMBER OF TOKENS. +THE FOLLOWING LITTLE USED COMMANDS MAY POSSIBLY BE OF SOME INTEREST: + ( INSERT A VIRTUAL OPEN PARENTHESIS. + ) INSERT A VIRTUAL CLOSE PARENTHESIS. + D( VIRTUALLY DELETE AN OPEN PARENS + D) VIRTUALLY DELETE A CLOSE PARENS + () RESTRUCTURE THE WORKING S-EXPRESSION ACCORDING TO THE + VIRTUAL PARENTHESES AND DELETIONS. +[[Note: the "virtual parens" stuff probably doesn't work right -- JONL]] + + +7/8/73 - JONL - +. . . +THE VALUE OF THE VARIABLE EDIT IS NOW (AS OF LISP 486) A LIST OF FLAGS +THAT THE IN-CORE EDITOR WILL USE WHEN SEARCHING FOR A FUNCTION +DEFINITION. THUS TO EDIT CNVR FUNCTIONS, ONE MAY WANT TO DO + (SETQ EDIT (CONS 'CEXPR EDIT)) +THE VALUE OF THE VARIABLE  IS THE BACK-UP CHAIN FOR THE EDITOR, +THE CAR OF WHICH WILL BE POINTING TO THE PLACE IN YOUR FUNCTION WHERE +THE CURRENT EDIT CURSOR IS. THUS, ONE MAY USE THE EDITOR TO POSITION +THE EDIT-CURSOR, AND THEN RUN OTHER PROGRAMS THAT "TAKE IT FROM THERE" + + +AUG 17, 1974 LISP 893 - GLS AND JONL - +. . . +[3] NEW COMMANDS FOR THE BINFORD EDITOR: + SS (SAVE SPOT) GOBBLES THE NAME OF AN ATOMIC + SYMBOL, AND SETQ'S IT TO THE CURRENT EDITOR + CONTEXT. + RS (RESTORE SPOT) GOBBLES SUCH A SETQ'D ATOMIC SYMBOL + AND MAGICALLY MOVES THE EDITOR'S CURSOR TO THE + SAVED SPOT. + PC (PRINT CONTEXT) GOBBLES UP TO TWO FLONUMS (TERMINATE + WITH $$) AND, USING THEM FOR THE PRINLEVEL AND + PRINLENGTH, PRINTS THE CURRENT LEVEL OF LIST + STRUCTURE. IF YOU DON'T SUPPLY TWO ARGS, + DEFAULTS OF 4 ARE USED. + + +TUESDAY SEPT 14,1976 FM+6D.1H.33M.7S. LISP 1211 -GLS,JONL- +. . . +[7] CHANGES TO THE "BINFORD EDITOR" (EDIT FUNCTION): + [7.1] THE COMMANDS "C" AND "-C" HAVE DISAPPEARED. + THEY WERE EQUIVALENT TO THE STILL-EXISTING + "F" AND "-F" COMMANDS. + [7.2] "SS" = "SAVE SPOT", "RS" = "RESTORE SPOT" + BOTH TAKE AN ATOMIC SYMBOL AS AN ARGUMENT. + SS SAVES THE CURRENT "SPOT" (WHERE THE $$ APPEARS) + AS THE VALUE OF THE SPECIFIED VARIABLE, AND RS + RETURNS TO THAT SPOT. THUS: + SS FOO + ... LOTSA EDITING ... + RS FOO + + [7.3] AN ARGUMENT TO EDIT NO LONGER CONTROLS THE AUTO-PRINT + FEATURE (SEE [7.4] BELOW); INSTEAD, IT SHOULD BE AN + ATOMIC SYMBOL, THE NAME OF A FUNCTION. AS THE EDITOR + IS ENTERED, THAT FUNCTION IS "YANKED" SO THAT EDITING + MAY BEGIN ON ITS CODE WITHOUT EXPLICITLY USING THE + "Y" COMMAND. THE VALUE OF THE VARIABLE "EDIT" + CONTROLS WHICH PROPERTIES WILL BE HUNTED FOR BY THE + "Y" OPERATION [INITIAL VALUE IS (EXPR FEXPR MACRO)]. + [7.4] "SP" = "START/STOP PRINTING" TOGGLES THE STATE OF + THE AUTOMATIC PRINTOUT AFTER EACH COMMAND. + [7.5] "-KI" IS LIKE "L KI"; THAT IS, IT REPLACES THE + PRECEDING S-EXPRESSION WITH ITS ARGUMENT. + [7.6] AN "S" COMMAND IMMEDIATELY FOLLOWED BY "$$" + (I.E. A NULL SEARCH STRING" WILL REPEAT THE PREVIOUS + SEARCH, AS IN TECO. + [7.7] YANKING IN A VALUE PROPERTY NOW WINS. THUS: + YP FOO VALUE $$ + ALLOWS YOU TO EDIT THE VALUE PROPERTY OF FOO. + + +WEDNESDAY DEC 29,1976 FQ+1D.9H.29M.54S. LISP 1251 -JONL- +. . . +8) EDIT ALLOWS THE USER TO DEFINE NEW EDITING FUNCTIONS. PUTTING AN + "EDIT" PROPERTY ON AN ATOM MAKES IT AN EDITOR COMMAND, AND WHEN + INVOKED, THAT FUNCTIONS IS CALLED WITH THREE ARGUMENTS: + I) REPEAT COUNT + II) THE CURRENT "LEFT-LIST" (VALUE OF THE ATOM ) + III) THE CURRENT "UP-LIST" + FOR MORE DETAILS, SEE THE FILE MC:LISP;EDITOR > + + +THURSDAY JAN 06,1977 FM+1D.23H.52M.11S. LISP 1252 - GLS - +. . . +[4] IF EDIT READS A COMMAND WHOSE NAME IS NOT RECOGNIZED, THEN IF THE + ATOM OF THAT NAME HAS AN EDIT PROPERTY, THEN THAT PROPERTY SHOULD + BE A FUNCTION. IT WILL BE CALLED WITH THE REPEAT COUNT AS AN ARGUMENT + (0 IS SUPPLIED IF NO ARGUMENT IS GIVEN). THE FUNCTION MAY + DO ANYTHING IT LIKES, BUT WILL PROBABLY WANT TO OPERATE ON THE + FUNCTION BEING EDITED. THE EDITOR'S CURSOR IS REPRESENTED BY + TWO DATA STRUCTURES, THE "LEFT-LIST" AND THE "UP-LIST". + THE FORMER SAYS HOW TO BACK UP AT THE CURRENT LEVEL OF LIST; + THE LATTER SAYS HOW TO BACK UP A LEVEL OF LIST STRUCTURE. + THE LEFT-LIST IS THE VALUE OF THE ATOM  (THREE ALTMODES), + AND THE UP-LIST IS THE VALUE OF THE ATOM ^^^ (THREE UPARROWS OR + CIRCUMFLEXES, ASCII 136). + THE CAR OF THE LEFT-LIST IS THE LEVEL OF LIST STRUCTURE BEING + EDITED; THE CURSOR IS CONSIDERED TO BE BEFORE THE CAAR + OF THE LEFT-LIST. THE CDR OF THE LEFT-LIST IS THE LEFT-LIST + FOR THE PREVIOUS POINT IN THIS LEVEL OF LIST. THE UP-LIST + IS A STACK OF OLD LEFT-LISTS. + THE FOLLOWING FUNCTIONS ARE USEFUL UTILITIES FOR BUILDING + NEW EDITOR FUNCTIONS, AND ILLUSTRATE THE CORRECT WAY TO MANIPULATE + THE LEFT-LIST AND UP-LIST. + (DEFUN RIGHT () (AND (EDCAR) (SETQ  (CONS (CDAR ) )))) + (DEFUN LEFT () (AND  (CDR ) (SETQ  (CDR )))) + (DEFUN DOWN () (AND (EDCAAR) + (SETQ ^^^ (CONS  ^^^)  (NCONS (CAAR ))))) + (DEFUN UP () (AND ^^^ (CAR ^^^) (CDR ^^^) + (SETQ  (CAR ^^^) ^^^ (CDR ^^^)))) + (DEFUN YANK (FN) + ((LAMBDA (PL) + (COND (PL (SETQ ^^^ NIL) + (SETQ  (NCONS PL))) + (T (PRINC '|??|)))) + (GETL FN EDIT))) + (DEFUN SPLICE (IT) + (COND ((AND (LEFT) (EDCAR)) + (RPLACD (CAR ) IT) + (RIGHT)) + ((AND (UP) (EDCAR)) + (RPLACA (CAR ) IT) + (DOWN)))) + (DEFUN KILL () + (PROG2 NIL (CAAR ) + (SPLICE (COND ((EDCAR) (CDAR )) (T (CAR )))))) + (DEFUN INSERT (IT) + (SPLICE (CONS IT (AND  (CAR )))) + (RIGHT)) + + (DEFUN EDCAR () (AND  (NOT (ATOM (CAR ))))) + (DEFUN EDCAAR () (AND (EDCAR) (NOT (ATOM (CAAR ))))) + + NOTICE THAT LEFT AND RIGHT AND UP AND DOWN RETURN NIL + IF THEY FAIL. KILL RETURNS THE THING KILLED (THE STANDARD + EDITOR COMMAND "K" PUTS THIS THING INTO THE VALUE CELL OF "".) + AS TWO EXAMPLES OF NEW EDITOR COMMANDS, CONSIDER + "XCH" (NOTE THAT NAMES OF EDITOR COMMANDS MUST BE THREE CHARACTERS OR + FEWER), WHICH TRANSPOSES THE NEXT TWO ITEMS AFTER THE CURSOR, + AND "BRY", WHICH BURIES THE NEXT THING IN LEVELS + OF LIST STRUCTURE. + + (DEFPROP XCH ED-EXCHANGE EDIT) + (DEFUN ED-EXCHANGE (N) ;ARGUMENT IS IGNORED + (INSERT (PROG2 NIL (KILL) (RIGHT)))) + + (DEFPROP BRY ED-BURY EDIT) + (DEFUN ED-BURY (N) + (AND (EDCAR) + (DO ((I (MAX N 1) (- I 1))) + ((ZEROP I)) + (SPLICE (RPLACA (CAR ) (NCONS (CAAR ))))))) + + I HAVE TESTED THESE DEFINITIONS AND THEY SEEM TO WORK. + + +1/13/78 LISP 1383 +. . . +[3] THE EDITOR COMMAND YV FOO IS THE SAME AS YP FOO VALUE . + IT IS USEFUL FOR EDITING THE VALUE OF A SYMBOL. + + +Thursday June 07,1979 FQ+5D.11H.58M.56S. - Jonl - +. . . +5) The famous but Kludgy Binford Editor is now autoloadable. + Thus it is no longer part of the initial ITS maclisp environment. + REMEMBER:  holds the last thing killed +  holds the "back-upwards" list + ^^^ holds the "back-leftwards" list + EDIT hold a list of the names for "editible" properties + "S", that is the search command, with no trailing arguments, + means to search again for the same thing as before. + Both "S" and "I" take arbitrarily many trailing arguments, + terminated by + Also, any symbol with an EDIT property may be an edit command, + wherein the function stored under the EDIT property is applied + to a number: 0 means no numeric arg to function + n > 0 is the numeric argument given to the command + diff --git a/doc/_info_/lisp.extend b/doc/_info_/lisp.extend new file mode 100755 index 00000000..1122f134 --- /dev/null +++ b/doc/_info_/lisp.extend @@ -0,0 +1,175 @@ +Functions: + PTR-TYPEP Primitive TYPE name for a datum -- see MC:NIL;NEWFUN > + for specifics. + EXTENDP + SI:EXTENDP A basic primitive type is the EXTEND, which is just a chunk + of index-access components, and a link to a descriptor object + which is itself another EXTEND. In fact, these "descriptor + objects" are essentially CLASSes in the LISPM and SMALLTALK + sense. In MacLISP, they are emulated with hunks. + EXTEND-LENGTH + SI:EXTEND-LENGTH The argument is an "instance" and this function just + counts the number of components in that instance. + SI:MAKE-EXTEND Takes two arguments -- first is number of "slots" + to be allocated in the instance, 2nd is CLASS object for which + an instance is being created, + + SI:MAKE-RANDOM-EXTEND Basically, like SI:MAKE-EXTEND, except that + the 2nd arg is optional, and it is not required to be a + CLASS object (but will be put into the class-link slot). + This is primarily for bootstrapping class-like systems. + + SI:EXTEND First arg must be a CLASS -- remaining args are constructed + into an object of that CLASS; (SI:EXTEND SOME-CLASS 'T () ) + would cons up a "SOME", and (SI:XREF frob 0) would get the 'T. + SI:XREF basic accessor for EXTENDs, e.g. (SI:XREF ) + SI:XSET basic updator, e.g. (SI:XSET ) + CLASSP A predicate which is "true" iff its arg is not only an EXTEND, + but a class descriptor for some class of objects; such an + object, a CLASS object, will henceforth just be called a CLASS. + CLASS-OF For any argument, will return the CLASS for which that argument + is an instance; arguments of "primitive" type (i.e., not a + EXTEND) will be classified according to a systemic table, + whereas an EXTEND itself will have a direct link to its CLASS. + SEND Takes two or more arguments; the first is an object to + be acted upon, the second is a "keyword" which will be used + to select a method from among those accessible in the CLASS + of the first argument, and the remaining arguments are + just additional arguments to the method function. + SEND-AS Takes three or more arguments. Second arg is some object + to be acted upon (third is "keyword") just as with SEND, but + first argument is a CLASS which is to be the root for method + searching rather than the the class of the active object. + ADD-METHOD Takes args -- ( ) -- and stores the + function as a method in the CLASS . + Thus if SEND sends a message with the key to an + object in the CLASS (or to any object whose CLASS has + as a superior class), then will be invoked. + There is an as-yet undocumented means for specifying the + method-searching function on a class by class basis. + FIND-METHOD (FIND-METHOD ) Returns the function + which will handle message for the CLASS . + DESCRIBE Prints a brief description of the object; for EXTENDed + objects, retrieves some information from the corresponding + CLASS; for CLASS's themselves, will also do the DESCRIBE + operation for all its superiors. + WHICH-OPERATIONS For any object as argument, will print out a sequence + of lines with the (1) name of each "operation" (or message) + which is applicable to this object (as well as any object in + the same CLASS), (2) the name of the function which will handle + that operation, and (3) the name of the CLASS from which that + method was "inherited." See also SI:OPERATIONS-LIST below. + TYPE-OF Retrieves the TYPE name as stored in the CLASS for the datum + given as argument. For all MacLISP primitive datatypes (like, + SYMBOLs, BIGNUMS, etc), this will be the same as the TYPEP of + the datum. + EQ-FOR-EQUAL? Takes two args -- returns "true" only if EQ is + satisfactory for the EQUAL test (e.g., as on SYMBOLs). + + SI:DEFCLASS*-1 Argspectrum is like ( + &optional ( )) + Normally, called by using the DEFCLASS* macro; + is a symbol to be used to describe the "type" of + objects and is stored in a slot of the CLASS retrieveable + by SI:CLASS-TYPEP and TYPE-OF (see below). + is a symbol which will be set to the CLASS about + to be created; conventionally, if FOO is chosen as the + type name, then FOO-CLASS is the class variable. + a list of CLASSes which are to be considered superiors + of this class (for the purposes of inheritance of + properties, such as "methods"). + SI:HAS-SUPERIOR A predicate, "true" iff the second arg is some super- + class of the first arg. Both arguments must be classs. + SI:WHERE-IS-METHOD As above with SI:FIND-METHOD, but returns the actual + CLASS under which that function was stored as a method. + SI:OPERATIONS-LIST Argument must be a CLASS; returns a list of items + like `(, , ,), where is a method + name (or message key word), is the function which + handles that method, and is the CLASS in which it was + found. will either be the same as the argument, or + one of the superiors of the argument. + + +The following functions (which are SUBR's) also have macro definitions +which are "enabled" when compiling, to produce more efficient compiled code: + EXTEND-LENGTH, EXTENDP (merely produces call to the "SI:"-named versions) + SI:MAKE-EXTEND, SI:EXTEND, SI:XREF, and SI:XSET +Macros (only): + DEFCLASS* (DEFCLASS* . ) creates + a new CLASS named , and putting it in the variable named + ; the superior class may not be ommited. Typical + use might be + (DEFCLASS* MUMBLENUM MUMBLENUM-CLASS (NUMBER-CLASS)) + [Note that the value of OBJECT-CLASS is the CLASS which is the + root of the CLASS hierarchy]. + DEFMETHOD* Defines a method for a particular class, to be used when a + specified message is sent. For example, + (DEFMETHOD* (KEY FOO-CLASS) (OBJ . ) + . ) + defines a KEY method for instances of class FOO. Then when + (SEND 'KEY ) is executed, OBJ is bound to , + the are bound (or "spread-out") to and , + and is executed. KEY can be a list of keys instead of + a single key. + TYPECASEQ Like CASEQ, but dispatches on the "primitive" type of the + datum. E.g., (TYPECASEQ X ((SYMBOL STRING) 5) (T 6)) + could be emulated by (CASEQ (PTR-TYPEP X) + ((SYMBOL STRING) 5) + (T 6)) + In some implementations, however, this will be done by a + fast dispatch through a table, rather than by sequence of + EQ comparisons. + MAPF A generalized Mapper, usable on VECTORs, FIXNUMs, as well as + lists. See MC:NIL;NEWFUN > for more details. + **SELF-EVAL** Most EXTENDed data will have this symbol stored in + the (CXR 1 ) slot. The macro-expansion of + (**SELF-EVAL** ...) yields (QUOTE (**SELF-EVAL** ...)) + **CLASS-SELF-EVAL** Same as for **SELF-EVAL**, but used only in CLASS's -- + this provides a simple heuristic to distinguish them quickly + from other hunks, and other EXTENDs + SI:EXTEND-CLASS-OF 1 arg. If object is know to be an EXTEND, this will + produce much faster code than calling CLASS-OF. + SI:CLASS-VAR + SI:CLASS-NAME + SI:CLASS-TYPEP + SI:CLASS-SUPERIORS Each CLASS (an EXTENDED data object which serves as + a descriptor for a whole class of objects) has about 17. + slots of data, the 5 more important of which are listed here + by the accessor macro names. Typically, each class has some + symbolic name, and some global variable whose value is that + class object; e.g. let be the CLASS for VECTORs, then + (SI:CLASS-NAME ) ==> VECTOR, and + (SI:CLASS-VAR ) ==> VECTOR-CLASS + As a general convention, any class named FOO has the + class variable FOO-CLASS. The SI:CLASS-TYPEP component + is the value to be returned by TYPE-OF. SI:CLASS-SUPERIORS + is a list of CLASS's of which this one is a subclass; + primarily, the superiors are of interest when searching + for applicable methods, and the search goes "upwards" in + order to "inherit" properties from the superiors. + +Variables: + NULL-CLASS CLASS for () + PAIR-CLASS CLASS for non-null lists + and CLASS's for standard MacLISP data types: + FIXNUM-CLASS, FLONUM-CLASS, BIGNUM-CLASS, SYMBOL-CLASS, ARRAY-CLASS + HUNK-CLASS, SFA-CLASS, FILE-CLASS, JOB-CLASS, RANDOM-CLASS + *:TRUTH In MacLISP world, this is just "T", but in a real + NIL, it will be a new, unique constant to mean + "true"; "false" will still be represented by (). + SI:INITIAL-CLASSES Holds a list of lists -- total of 22. -- each list + of which holds a little information about the initial + set up of the CLASS system; (mapcar 'CAR SI:INITIAL-CLASSES) + returns a list of the names of all initial CLASSes. + +Error facilities: + Because the EXTEND facilities are designed to provide the MacLISP +user with some of the amenities of NIL or the LISPM, some extension +to the error system was needed, and it comes from the system file +LISP:CERROR -- CERROR and FERROR are supported, as on the LISPMachine, +but FORMAT is not forcibly loaded (it is called only when already loaded +so that one may use EXTENDs without having to load the humungous FORMAT file). +A few global variables are set up: + STANDARD-OUTPUT is set to T, and + ERROR-OUTPUT is set to a SFA which directs output to MSGFILES + diff --git a/doc/_info_/lisp.format b/doc/_info_/lisp.format new file mode 100755 index 00000000..234afd82 --- /dev/null +++ b/doc/_info_/lisp.format @@ -0,0 +1,119 @@ + + This is an abbreviated version of FORMAT documentation, intended +for on-line use. It is intended as a quick reference only, and does +not contain detailed semantics. + + FORMAT destination control-string &rest args + If DESTINATION is NIL, the formatted output is collected in a +"string"; if it is T, then the "standard default output stream" is +used, which the same as the NIL output filespec in Maclisp. + CONTROL-STRING may be a "string" (symbol), or a list. If it is a +list, then the elements are processed sequentially; if an element is +a "string" it is FORMATted; otherwise, the element should be a list, +and if the car of it is a recognized FORMAT directive, the +corresponding action is taken, and the cdr of that element is taken to +be the list of parameters to that directive. If it isn't a recognized +directive, then it is simply EVALed, and anything it writes to the +stream STANDARD-OUTPUT will appear in the result of FORMAT. + + ?FORMAT destination control-string &rest args + This is identical to FORMAT except in the interpretation of +DESTINATION, which is interpreted as a Maclisp style filespec. That +is, NIL means output to the standard default output stream, T means +the tty, etc. + + + FERROR condition control-string &rest args + This SIGNALs CONDITION with arguments of CONTROL-STRING, NIL, NIL, +and (spread) ARGS. In Maclisp, if CONDITION is NIL, then +CONTROL-STRING and ARGS are given to FORMAT to get a string argument +to give as a sole argument to ERROR. Otherwise, the SIGNAL function +is called, as it is on the Lisp Machine. SIGNAL is not defined here. + + + The Operators +Character args used parameters +---------------------------------------------------------------- +~D One column-width, pad-char, comma-char + Output arg as a decimal integer, right justified. If the : + modifier is given, 3-digit groups will be separated by + comma-char. If the @ modifier is given, then the sign will be + output unconditionally. +~O Same as ~D, but outputs the number in octal. +~A One mincol, colinc, minpad, padchar + The argument is PRINCed, left-justified in a field mincol + wide. See ~< for interpretation of the other params. +~S Same as ~A, only uses PRIN1 (recognizes the PRIN1 hook, too). +~C One + In Maclisp only: this operator should not be considered to be + properly defined yet, except insofar as ~C (no modifiers) will + try to output the character as it is (TYO plus "C-" and/or + "M-" for supra-ascii control and meta), and ~:@C will give a + long-winded fully spelled out naming of the character. +~P Hairy + With no modifiers, this takes one arg, and if it is not 1, + prints a lower-case "s". The following is tentative, based on + feedback: If the : modifier is given, the previous arg is + used instead (ie, it sort of does a ~-1* first). If the @ + modifier is given, then if the arg is 1 a "y" is printed, + otherwise "ies". +~* Hairy count + This ignores count (default 1) arguments. Count may be + negative. +~% None count + Outputs count (default 1) newlines. +~& None count + Performs the FRESH-LINE operation, and then outputs count-1 + newlines. Count defaults to 1. +~| none count + Outputs count (default 1) formfeeds. This will do a + (CURSORPOS 'C) on TTYs. +~X none count + Outputs count (default 1) spaces. +~T none destination, increment + Spaces to column (plus destination (times n increment)) for + the smallest value of N needed to pass the current column. + Destination and increment default to 1. This may use absolute + cursor positioning on TTYs. +~~ none count + Outputs count (default 1) tildes. +~G hairy n + "Goes to" the Nth argument (zero origined). The : modifier + makes this relative, ie identical to ~*. +~[ One none + This formats the ARGth alternative of the portion of the + control string terminated by a matching ~] (ie they may be + nested) and separated by ~;, as in + "~[Siamese ~;Persian ~;Yu-shiang ~:;Unknown ~]Kitty". + The alternatives are zero origined. The : modifier given to + ~; causes the following alternative to be treated as an "else" + clause; eg, an argument of 1 will give "Persian Kitty", and + an arg of anything but 0, 1, or 2 will give "Unknown Kitty". +~:[ one none + This is an "if" rather than a selection. The first + alternative string will be used if the arg is false, otherwise + the second will be. +~; This is the canonical control-string separater. It is not + itself defined, and any arguments, parameters, or modifiers it + uses are interpreted by whoever is using it as a delimiter. +~] Terminates ~[ or ~:[. +~< none mincol, colinc, minpad, padchar + The text between the ~< and the balancing ~> is "broken into + chunks" by delimiting ~;s, and justified in a field MINCOL + wide. With no modifiers, the leftmost segment will be left + justified, and the rightmost right justified. The : modifier + causes spacing to be put before the leftmost segment, and the + @ modifier after the rightmost. If there is only one segment + and no modifiers, then the segment will be right justified. + MINCOL is adjusted upwards in COLINC (default 1) increments so + that there will be at least MINPAD (default 0) pad characters + in each of the spacing breaks. Thus, + "~10" => "foo bar", and + "~10" => " foobar", and + "~10:" => " foo bar" +~> Terminates a ~> construct. +~R one none + ~R prints its arg as a cardinal English number, eg "four"; + ~:R prints it as ordinal, eg "fourth"; + ~@R prints it as a Roman numeral, eg "IV"; + ~:@R prints it as an ole Roman numeral, eg "IIII". diff --git a/doc/_info_/lisp.loop b/doc/_info_/lisp.loop new file mode 100755 index 00000000..c89a8476 --- /dev/null +++ b/doc/_info_/lisp.loop @@ -0,0 +1,973 @@ +.c Thursday July 10,1980 3:59 LQ+5D.3H.56M.26S. -*- Text -*- + +.chapter "Introduction" + LOOP is a Lisp macro which provides a programmable iteration +facility. The same LOOP module operates compatibly in both Lisp +Machine Lisp and Maclisp (PDP-10 and Multics). LOOP was inspired by +the "FOR" facility of CLISP in InterLisp; however, it is not +compatible and differs in several details. + + The general approach is that a form introduced by the word +3loop* generates a single program loop, into which a large variety +of features can be incorporated. The loop consists of some +initialization (2prologue*) code, a body which may be executed +several times, and some exit (2epilogue*) code. Variables may be +declared local to the loop. The +features are concerned with loop variables, deciding when to end the +iteration, putting user-written code into the loop, returning a value +from the construct, and iterating a variable through various real or +virtual sets of values. + The 3loop* form consists of a series of clauses, each +introduced by a keyword symbol. Forms appearing in or implied by the +clauses of a 3loop* form are classed as those to be executed as +initialization code, body code, and/or exit code, but aside from that +they are executed strictly in the order implied by the original +composition. Thus, just as in ordinary Lisp code, side-effects may +be used, and one piece of code may depend on following another for +its proper operation. This is the principal philosophy difference +from InterLisp's "FOR" facility. + Note that 3loop* forms are intended to look like stylized English +rather than Lisp code. There is a notably low density of parentheses, +and many of the keywords are accepted in several synonymous forms to +allow writing of more euphonious and grammatical English. Some +find this notation verbose and distasteful, while others find it +flexible and convenient. The former are invited to stick to 3do*. +.space 1 +.group +.lisp +(defun print-elements-of-list (list-of-elements) + (loop for element in list-of-elements + do (print element))) +.end_lisp + The above function prints each element in its argument, which +should be a list. It returns 3nil*. +.end_group +.space 1 +.group +.lisp +(defun extract-interesting-numbers (start-value end-value) + (loop for number from start-value to end-value + when (interesting-p number) collect number)) +.end_lisp + The above function takes two arguments, which should be +fixnums, and returns a list of all the numbers in that range +(inclusive) which satisfy the predicate 3interesting-p*. +.end_group +.space 1 +.group +.lisp +(defun find-maximum-element (array) + (loop for i from 0 below (cadr (arraydims array)) + maximize (funcall array i))) +.end_lisp + 3Find-maximum-element* returns the maximum of the elements +of its argument, a one-dimensional array. +.end_group +.group +.space 1 +.lisp +(defun remove (object list) + (loop for element in list + unless (equal object element) collect element)) +.end_lisp + 3Remove* is like the Lisp function 3delete*, except +that it copies the list rather than destructively splicing out +elements. +.end_group +.space 1 +.group +.lisp +(defun find-frob (list) + (loop for element in list + when (frobp element) return element + finally (error '|Frob not found in list| list))) +.end_lisp + This returns the first element of its list argument which +satisfies the predicate 3frobp*. If none is found, an error is +generated. +.end_group + +.chapter "Clauses" + + Internally, LOOP constructs a 3prog* which includes +variable bindings, pre-iteration (initialization) code, +post-iteration (exit) code, the body of the iteration, and stepping +of variables of iteration to their next values (which happens on +every iteration after executing the body). + A 2clause* consists of the keyword symbol and any other +Lisp forms and keywords which it deals with. For example, +.lisp +(loop for x in l do (print x)), +.end_lisp +contains two clauses, "7for x in l*" and "7do (print x)*". +Certain of the +parts of the clause will be described as being 2expressions*, e.g. +"(print x)" in the above. +An expression can be a single Lisp form, or a series of forms +implicitly collected with 3progn*. An expression is terminated by +the next following atom, which is taken to be a keyword. Thus, syntax +allows only the first form in an expression to be atomic, but makes +misspelled keywords more easily detectable. + + Bindings and iteration variable steppings may be performed +either sequentially or in +'cindex sequential vs parallel binding and initialization +parallel, which affects how the stepping of one iteration +variable may depend on the value of another. The syntax for +distinguishing the two will be described with the corresponding clauses. +When a set of things is "in parallel", all of the bindings produced +will be performed in parallel by a single lambda binding. +Subsequent bindings will be performed inside of that binding environment. + +.section "Iteration-Producing Clauses" + + These clauses all create a 2variable of iteration*, which +is bound locally to the loop and takes on a new value on each +successive iteration. Note that if more than one iteration-producing +clause is used in the same loop, several variables are created which +all step together through their values; when any of the iterations +terminates, the entire loop terminates. Nested iterations are not +generated; for those, you need a second 3loop* form in the body of +the loop. + + All of the iteration-producing clauses initially defined are +introduced with the keyword 3for* (or 3as*, which is +synonomous). +'cindex parallel vs. sequential iteration stepping +3For* clauses may be clustered into groups, the variables of +iteration of which are to be stepped in +parallel, by introducing the additional clauses with 3and* instead +of 3for* or 3as*. For example, the following iterates over the +elements in a list, and also has a variable for the element from the +previous iteration: +.lisp +(loop for item in list and previous-item = 'foo then item + do ...) +.end_lisp +During the first iteration, 3previous-item* has the value +3foo*; in subsequent iterations, it has the value of 3item* +from the previous iteration. Note that this would not work if the +stepping were not performed in parallel. + + The order of evaluation in iteration-producing clauses is that +'cindex order of evaluation in iteration clauses +those expressions which are only evaluated once are evaluated in order +at the beginning of the form, during the variable-binding phase, while +those expressions which are evaluated each time around the loop are +evaluated in order in the body. + + These are the iteration-producing clauses. Optional parts are +enclosed in curly brackets. + +.table 3 250 500 + +.item for 2var* {2data-type*} in 2expr1* {by 2expr2*} +.kindex for +This iterates over each of the elements in the list 2expr1*. If +the 3by* subclause is present, 2expr2* is evaluated once +on entry to the loop +to supply the function to be used to fetch successive sublists, +instead of 3cdr*. + +.item for 2var* on 2expr1* {by 2expr2*} +.kindex for +This is like the previous 3for* format, except that 2var* is +set to successive tails of the list instead of successive elements. + +.item for 2var* {2data-type*} = 2expr* +.kindex for +On each iteration, 2expr* is evaluated and 2var* is set to the result. + +.item for 2var* {2data-type*} = 2expr1* then 2expr2* +.kindex for +2Var* is bound to 2expr1* when the loop is entered, and set to +2expr2* on all succeeding iterations. + +.item for 2var* {2data-type*} from 2expr1* {to 2expr2*} {by 2expr3*} +.kindex for +'c i can't read moon's handwriting! +This performs numeric iteration. 2Var* is initialized to +2expr1*, and on each succeeding iteration is incremented by +2expr3* (default 31*). If the 3to* phrase is given, the +iteration terminates when 2var* becomes greater than 2expr2*. +Each of the +expressions is evaluated only once, and the 3to* and 3by* +phrases may be written in either order. 3Downto* may be used instead +of 3to*, in which case 2var* is decremented by the step value, +and the endtest is adjusted accordingly. If 3below* is used +instead of 3to*, or 3above* instead of 3downto*, the +iteration will be terminated before 2expr2* is reached, rather +than after. Note that the 3to* variant appropriate for the +direction of stepping must be used for the endtest to be formed +correctly, i.e. the code will not work if 2expr3* is negative or +zero. If no limit specifying clause is given, then the direction of +the stepping may be specified as being decreasing by using +3downfrom* instead of 3from*. 3Upfrom* may also be used +instead of 3from*; it forces the stepping direction to be +increasing. +The 2data-type* defaults to 3fixnum*. + +.item for 2var* {2data-type*} being 2expr* and its 2path* ... +.item1 for 2var* {2data-type*} being {each} 2path* ... +.kindex for +This provides a user-definable iteration facility. 2Path* names +the manner in which the iteration is to be performed. The ellipsis +indicates where various path dependent preposition/expression pairs +may appear. See the section on Iteration Paths +((iteration-path-page)) for complete documentation. +.end_table + +.section "Bindings" +.setq with-clause page +.kindex with +'cindex variable bindings + The 3with* keyword may be used to establish initial +bindings, that is, variables which are local to the loop but are only +set once, rather than on each iteration. The 3with* clause looks like: +.lisp +3with 2var1* {2data-type*} {= 2expr1*} + {and 2var2* {2data-type*} {= 2expr2*}}...* +.end_lisp +If no 2expr* is given, the variable is initialized to the +appropriate value for its data type, usually 3nil*. + 3With* bindings linked by 3and* are performed in +parallel; those not linked are performed sequentially. That is, +.lisp +(loop with a = (foo) and b = (bar) ...) +.end_lisp +binds the variables like +.lisp +((lambda (a b) ...) + (foo) (bar)) +.end_lisp +whereas +.lisp +(loop with a = (foo) with b = (barprime a) ...) +.end_lisp +binds the variables like +.lisp +((lambda (a) + ((lambda (b) ...) + (barprime a))) + (foo)) +.end_lisp +All 2expr*'s in 3with* clauses are evaluated in the order they +are written, upon entrance to the loop rather than where they appear +in the body. Thus good style suggests that 3with* clauses be +placed first in the loop. + + For binding more than one variable with no particular +initialization, one may use the construct +.lisp +3with 2variable-list* {2data-type-list*} {and ...}* +.end_lisp +as in +.lisp +with (i j k t1 t2) (fixnum fixnum fixnum) ... +.end_lisp +which is a useful special case of 2destructuring* +((destructuring-section)). + + +.section "Entrance and Exit" + +.table 3 250 500 +.item initially 2expression* +.kindex initially +This puts 2expression* into the 2prologue* of the iteration. It +will be evaluated before any other initialization code other than the +initial bindings. For the sake of good style, the 3initially* +clause should therefore be placed after any 3with* clauses but +before the main body of the loop. + +.item finally 2expression* +.kindex finally +This puts 2expression* into the 2epilogue* of the loop, which is +evaluated when the iteration terminates (other than by an explicit +3return*). For stylistic reasons, then, this clause should appear +last in the loop body. Note that certain clauses may generate code +which terminates the iteration without running the epilogue code; +this behaviour is noted with those clauses. + +.end_table + +.section "Side Effects" +.setq side-effects-section css-number +.table 3 250 500 +.item do 2expression* +.item1 doing 2expression* +.kindex do doing +2Expression* is evaluated each time through the loop. +.end_table + +.section "Values" +.setq values-section css-number + The following clauses accumulate a return value for the +iteration in some manner. The general form is +.lisp +32type-of-collection expr* {2data-type*} {into 2var*}* +.end_lisp +where 2type-of-collection* is a 3loop* keyword, and 2expr* +is the thing being "accumulated" somehow. If no 3into* is +specified, then the accumulation will be returned when the 3loop* +terminates. If there is an 3into*, then when the epilogue of the +3loop* is reached, 2var* (a variable automatically bound +locally in the loop) will have been set to the accumulated +result and may be used by the epilogue code. In this way, a user may +accumulate and somehow pass back multiple values from a single +3loop*, or use them during the loop. It is safe to reference +these variables during the loop, but they should not be modified +until the epilogue code of the loop is reached. +For example, +.lisp +(loop for x in list + collect (foo x) into foo-list + collect (bar x) into bar-list + collect (baz x) into baz-list + finally (return (list foo-list bar-list baz-list))) +.end_lisp +which has the same effect as +.lisp +(do ((g0001 l (cdr g0001)) (x) (foo-list) (bar-list) (baz-list)) + ((null g0001) + (list (nreverse foo-list) + (nreverse bar-list) + (nreverse baz-list))) + (setq x (car g0001)) + (setq foo-list (cons (foo x) foo-list)) + (setq bar-list (cons (bar x) bar-list)) + (setq baz-list (cons (baz x) baz-list))) +.end_lisp + +.table 3 250 500 + +.item collect 2expr* {into 2var*} +.item1 collecting ... +.kindex collect collecting +.setq collect-clause page +This causes the values of 2expr* on each iteration to be collected +into a list. + +.item nconc 2expr* {into 2var*} +.item1 nconcing ... +.item1 append ... +.item1 appending ... +.kindex nconc nconcing append appending +These are like 3collect*, but the results are 3nconc*ed or +3append*ed together as appropriate. +3collecting*:3mapcar*::3nconcing*:3mapcan*. + +.item count 2expr* {into 2var*} +.item1 counting ... +.kindex count counting +If 2expr* evaluates non-3nil*, a counter is incremented. +The 2data-type* is always 3fixnum*. + +.item sum 2expr* {2data-type*} {into 2var*} +.item1 summing ... +.kindex sum summing +Evaluates 2expr* on each iteration, and accumulates the sum of all +the values. 2Data-type* defaults to +3number*, which for all practical purposes is 3notype*. + +.item maximize 2expr* {2data-type*} {into 2var*} +.item1 minimize ... +.kindex maximize minimize +Computes the maximum (or minimum) of 2expr* over all +iterations. 2Data-type* defaults to 3number*. +.end_table + + Not only may there be multiple 2accumulations* in a +'cindex multiple accumulations +3loop*, but a single 2accumulation* may come from multiple +places 2within the same 3loop* form*. Obviously, the types of +the collection must be compatible. 3Collect*, 3nconc*, and +3append* may all be mixed, as may 3sum* and 3count*, and +3maximize* and 3minimize*. For example, +.lisp +(loop for x in '(a b c) for y in '((1 2) (3 4) (5 6)) + collect x + append y) + => (a 1 2 b 3 4 c 5 6) +.end_lisp +.group +The following computes the average of the entries in the list +2list-of-frobs*: +.lisp +(loop for x in list-of-frobs + count t into count-var + sum x into sum-var + finally (return (quotient sum-var count-var))) +.end_lisp +.end_group + +.section "Endtests" +.cindex terminating the iteration + The following clauses may be used to provide additional +control over when the iteration gets terminated, possibly causing +exit code (due to 3finally*) to be performed and possibly returning +a value (e.g., from 3collect*). + +.table 3 250 500 +.item while 2expr* +.kindex while +If 2expr* evaluates to 3nil*, the loop is exited, performing +exit code (if any), and returning any accumulated value. The +test is placed in the body of the loop where it is written. It may +appear between sequential 3for* clauses. + +.item until 2expr* +.kindex until +Identical to 3while (not 2expr*)*. +.end_table + + This may be needed, for example, to step through a strange +data structure, as in +.lisp +(loop for concept = 2expr* then (superior-concept concept) + until (eq concept [summum-genus]) + ...) +.end_lisp + +.section "Aggregated Boolean Tests" + +.table 3 250 500 +.item always 2expr* +.kindex always +If 2expr* evaluates to 3nil*, the iteration is terminated and +3nil* returned; otherwise, 3t* will be returned when the loop +finishes, after the epilogue code (if any, as specified with the +3finally* clause) has been run. + +.item never 2expr* +.kindex never +This is like 3always (not 2expr*)*. + +.item thereis 2expr* +.kindex thereis +If 2expr* evaluates non-3nil*, then the iteration is +terminated and that value is returned, without running the epilogue +code. +.end_table + +.section "Conditionalization" +.cindex conditionalizing clause(s) + These clauses may be used to "conditionalize" the following +clause. They may precede any of the side-effecting or value-producing +clauses, such as 3do*, 3collect*, or 3always*. + +.table 3 250 500 +.item when 2expr* +.item1 if 2expr* +.kindex when if +.space 0 +.c Make sure this starts it on a new line.... +.c .break doesn't do it. +.c Will a ".space 0" do it? +If 2expr* evaluates to 3nil*, the following clause will be +skipped, otherwise not. + +.item unless 2expr* +.kindex unless +This is equivalent to 3when (not 2expr*))*. +.end_table + + Multiple conditionalization clauses may appear in sequence. +If one test fails, then any following tests in the immediate sequence, +and the clause being conditionalized, are skipped. + + Multiple clauses may be conditionalized under the same test by +joining them with 3and*, as in +.lisp +(loop for i from a to b + when (zerop (remainder i 3)) + collect i and do (print i)) +.end_lisp +which returns a list of all multiples of 33* from 2a* to +2b* (inclusive) and prints them as they are being collected. + Conditionals may be nested. For example, +.lisp +(loop for i from a to b + when (zerop (remainder i 3)) + do (print i) + and when (zerop (remainder i 2)) + collect i) +.end_lisp +returns a list of all multiples of 36* from 2a* to 2b*, +and prints all multiples of 33* from 2a* to 2b*. + + Useful with the conditionalization clauses is the 3return* +clause, which causes an explicit return of its "argument" as +the value of the iteration, bypassing any epilogue code. That is, +.lisp +3when 2expr1* return 2expr2** +.end_lisp +is equivalent to +.lisp +3when 2expr1* do (return 2expr2*)* +.end_lisp + Conditionalization of one of the "aggregated boolean value" +clauses simply causes the test which would cause the iteration to +terminate early not to be performed unless the condition succeeds. +For example, +.lisp +(loop for x in l + when (significant-p x) + do (print x) (princ "is significant.") + and thereis (extra-special-significant-p x)) +.end_lisp + +.group + The format of a conditionalization and following clause is +typically something like +.lisp +3when 2expr1* 2keyword* 2expr2** +.end_lisp +If 2expr2* is the keyword 3it*, then a variable is generated to +hold the value of 2expr1*, and that variable gets substituted for +2expr2*. Thus, the composition +.lisp +3when 2expr* return it* +.end_lisp +is equivalent to the clause +.lisp +3thereis 2expr** +.end_lisp +and one may collect all non-null values in an iteration by saying +.lisp +3when 2expression* collect it* +.end_lisp +If multiple clauses are joined with 3and*, the 3it* keyword +may only be used in the first. If multiple 3when*s, +3unless*es, and/or 3if*s occur in sequence, the value +substituted for 3it* will be that of the last test performed. +.end_group + +.chapter "LOOP Synonyms" + +.defmac define-loop-macro +.lisp +(define-loop-macro 2keyword*) +.end_lisp +may be used to make 2keyword*, a 3loop* keyword (such as +3for*), into a LISP macro which may introduce a 3loop* form. +For example, after evaluating +.lisp +(define-loop-macro for), +.end_lisp +one may now write an iteration as +.lisp +(for i from 1 below n do ...) +.end_lisp +.end_defmac + +.chapter "Data Types" +.setq data-type-section page +.cindex data type keywords + In many of the clause descriptions, an optional 2data-type* +is shown. A 2data-type* in this sense is an atomic symbol, and is +recognizable as such by LOOP. LOOP interfaces to a module which +defines how declarations and initializations are to be performed for +various data types. However, it recognizes several types specially so +that that module need not be present in order for them to be used: +.table 3 250 500 +.item fixnum +An implementation-dependent limited range integer. +.item flonum +An implementation-dependent limited precision floating point number. +.item integer +Any integer (no range restriction). +.item number +Any number. +.item notype +Unspecified type (i.e., anything else). +.end_table + +.chapter "Destructuring" +.setq destructuring-section page + 2Destructuring* provides one with the ability to +"simultaneously" assign or bind multiple variables to components of +some data structure. Typically this is used with list structure +(which is the only mode currently supported). For example, +.lisp +(desetq (foo . bar) '(a b c)) +.end_lisp +has the effect of setting 3foo* to 3a* and 3bar* to 3(b +c)*. +LOOP only requires destructuring support when one of these patterns is +supplied in place of a variable. +In addition, the "binding" of a pattern to a constant 3nil* is so +treated that it requires no special support code; this allows the +case +.lisp +with (a b c) +.end_lisp +to work without destructuring support code. + + One may specify the data types of the components of a pattern +by using a corresponding pattern of the data type keywords in place of +a single data type keyword. This syntax remains unambiguous because +wherever a data type keyword is possible, a 3loop* keyword is +the only other possibility. Thus, if one wants to do +.lisp +(loop for x in l + as i fixnum = (car x) + and j fixnum = (cadr x) + and k fixnum = (cddr x) + ...) +.end_lisp +and no reference to 3x* is needed, one may instead write +.lisp +(loop for (i j . k) (fixnum fixnum . fixnum) in l ...) +.end_lisp +To allow some abbreviation of the data type pattern, an atomic data +type component of the pattern is considered to state that all +components of the corresponding part of the variable pattern are of +that type. That is, the previous form could be written as +.lisp +(loop for (i j . k) fixnum in l ...) +.end_lisp +This generality allows binding of multiple typed variables in a +reasonably concise manner, as in +.lisp +(loop with (a b c) and (i j k) fixnum ...) +.end_lisp +which binds 3a*, 3b*, and 3c* to 3nil* and 3i*, +3j*, and 3k* to 30* for use as temporaries during the +iteration, and declares 3i*, 3j*, and 3k* to be fixnums +for the benefit of the compiler. +.lisp +.space 1 +(defun map-over-properties (fn symbol) + (loop for (propname propval) on (plist symbol) by 'cddr + do (funcall fn symbol propname propval))) +.end_lisp +.space 1 + See also section (dependencies-section), +(dependencies-section-page), which discusses support code needed in +various implementations. + +.chapter "Iteration Paths" +.setq iteration-path-page page + Iteration paths provide a mechanism for user extension of +iteration-producing clauses. The interface is constrained so that the +definition of a path +need not depend on much of the internals of LOOP. In general, a path +iteration has one of the forms +.lisp +for 2var* {2data-type*} being 2expr0* and its 2pathname* + {2preposition1* 2expr1*}... +for 2var* {2data-type*} being {each} 2pathname* of 2expr0* + {2preposition1* 2expr1*} +.end_lisp +The difference between the two is this: in the first, 2var* will +take on the value of 2expr0* the first time through the loop; but +in the second, it will be the "first step along the path". +2Pathname* is an atomic symbol which is defined as a 3loop* path +function. The usage and defaulting of 2data-type* is up to the +path function. Any number of preposition/expression pairs may be +present; the prepositions allowable for any particular path are +defined by that path. The 3of* preposition has special +meaning in that it specifies the starting point of the path; thus, +the first variation shown implicitly uses an 3of* 2expr0* +"prepositional phrase". To enhance readability, pathnames are usually +defined in both the singular and plural forms. To satisfy the +anthropomorphic among you, 3his*, 3her*, or 3their* may be +substituted for the 3its* keyword. Egocentricity is not condoned. + One pre-defined path is 3cars*; it simply iterates over +successive 3car*s of its starting argument, terminating after an +atom is reached. For example, +.lisp +(loop for x being cars of '((a b) c) collect x) + => ((a b) a) +(loop for x being '((a b) c) and its cars collect x) + => (((a b) c) (a b) a) +.end_lisp +The above forms are equivalent to +.lisp +(loop for x = (car '((a b) c)) then (car x) + collect x + until (atom x)) +.end_lisp +and +.lisp +(loop for x = '((a b) c) then (car x) + collect x + until (atom x)) +.end_lisp +respectively. (Note that the 3atom* check following the +body of this loop is part of the +definition of the 3cars* path, and is not a property of +paths in general.) +.group + By special dispensation, if a 2pathname* is not +recognized, then the 3attachments* path will be invoked upon a +syntactic transformation of the original input. This name derives +historically from its original usage in XLMS. +Essentially, the 3loop* fragment +.lisp +for 2var* being 2a-r* of 2expr* ... +.end_lisp +is taken as if it were +.lisp +for 2var* being attachments in 2a-r-** of 2expr* ... +.end_lisp +and +.lisp +for 2var* being 2expr* and its 2a-r* ... +.end_lisp +is taken as if it were +.lisp +for 2var* being 2expr* and its attachments in 2a-r-** +.end_lisp +Thus, this "undefined pathname hook" only works if the +3attachments* path is defined. Note also: +.defvar loop-attachment-transformer +The value of this is a function of one argument which will be called +on 2a-r* to transform it into 2a-r-**. If it is +3nil*, then a 3quote* is listed around the expression, +effectively causing the special 3attachments* syntax to be an +unevaluated form of the 3attachments* path. This +is initially 3nil* except in an LMS environment, in which case it +is a function which simply returns 2a-r*. +.end_defvar +.end_group + +.need 6000 +.c 6 inches -- don't want the section header to come out all alone. +.section "Defining Paths" + + This section will probably be of interest only to those +interested in defining their own paths. + For the purposes of discussion, the general template form of +an iteration may be assumed to be +.lisp +(let 2variable-bindings* + (prog () + 2prologue-code* + next-loop + 2pre-body-endtests-1* + 2pre-body-steps-1* + 2pre-body-endtests-2* + 2pre-body-steps-2* + ... + 2body* + 2post-body-endtests-1* + 2post-body-steps-1* + 2post-body-endtests-2* + 2post-body-steps-2* + ... + (go next-loop) + end-loop + 2epilogue-code* + )) +.end_lisp +When more than one 3for* clause is grouped together with 3and*, +the endtests and steps are arranged to occur together in parallel. +Sequentially arranged 3for* clauses cause multiple endtests and +steps to occur one after another, as shown in the above template. + A function to generate code for a path may be declared to +3loop* with the 3define-loop-path* function: +.defun define-loop-path pathname-or-names path-function list-of-allowable-prepositions (1any-number-of*data) +This defines 2path-function* to be the handler for the path(s) +2pathname-or-names*, which may be either a symbol or a list of +symbols. Such a handler should follow the conventions described +below. +.end_defun + +The handler will be called with the following arguments: +.table 2 250 500 +.item path-name +The name of the path which caused the path function to be invoked. +.item variable +The "iteration variable". +.item data-type +The data type supplied with the iteration variable, or 3nil* if +none was supplied. +.item prepositional-phrases +This is a list with entries of the form 2(preposition +expression)*, in the order in which they were collected. This may +also include some supplied implicitly (e.g. 3of* phrases, and +3in* phrases for +attachment relations); the ordering will show the order of evaluation +which should be followed for the expressions. +.item inclusive? +This is 3t* if 2variable* should have the starting point of +the path as its value on the first iteration, 3nil* otherwise. +.item allowed-prepositions +This is the list of allowable prepositions declared for the pathname +that caused the path function to be invoked. It and 2data* +(immediately below) may be used by the path function such that a +single function may handle similar paths. +.item data +This is the list of "data" declared for the pathname that caused the +path function to be invoked. It may, for instance, contain a +canonicalized pathname, or a set of functions or flags to aid the +path function in determining what to do. In this way, the same +path function may be able to handle different paths. +.end_table + The handler should return a list with the following elements: +.table 2 250 500 +.item variable-bindings +This is a list of variables which need to be bound. The entries in it +may be of the form 2variable*, (2variable* 2expression*), +or (2variable* 2expression* 2data-type*). Note that it is +the responsibility of the handler to make sure the iteration variable +gets bound. All of these variables will be bound in parallel; thus, +if initialization of one depends on others, it should be done with a +3setq* in the 2prologue-forms*. +.item prologue-forms +This is a list of forms which should be included in the loop prologue. + +.item pre-body-endtest +This is a single form. +.item pre-body-steps +This should be an alternating list of variables and expressions to +step them. They will be stepped in parallel. (This is like the +arguments to 3setq*; in fact, it will be used as the arguments to +3psetq*.) + +.item post-body-endtest +Like 2pre-body-endtest*, but done after the 2body*, just +before starting the next iteration. +.item post-body-steps +Like 2pre-body-steps*. +.end_table +If anyone finds that they need to modify the 2main* body or the +epilogue code, we would like to hear about it. + A qualification is in order with respect to stepping. In +order to make parallel stepping work properly, 3loop* must be able +to coerce the stepping code for different 3for* clauses to act in +parallel. Thus, the canonical place for stepping to occur is in the +2post-body-steps*; the 2pre-body-steps* is mainly useful when +the iteration variable needs to be set to some function of whatever is +actually being iterated over. For example, the LOOP clause +.lisp +3for 2var* in 2list** +.end_lisp +effectively returns the following elements for the template (where +2tem* is really a gensymed variable name): +.table 2 250 500 +.item variable-bindings +3(2var* (2tem* 2list*))* +.item prologue-forms +3nil* +.item pre-body-endtest +3(null 2tem*)* +.item pre-body-steps +3(2var* (car 2tem*))* +.item post-body-endtest +3nil* +.item post-body-steps +3(2tem* (cdr 2tem*))* +.end_table + +.defun loop-tequal token symbol-or-string +This is the LOOP token comparison function. 2Token* is any Lisp +object; 2symbol-or-string* is the keyword it is to be compared +against. It returns 3t* if they represent the same token, +comparing in a manner appropriate for the implementation. In certain +implementations 3loop-tequal* may be a macro. +.end_defun + +.chapter "Compatibility with FOR" + LOOP is not truly compatible with FOR (a similar Maclisp +iteration package). The reason for this is +that LOOP has certain "ideas" about how it should handle such things +as order of evaluation and repeated evaluation, which are quite +different from FOR's simpler template approach. Many of the keywords, +and hopefully all of the functionality, have been preserved. In many +cases, code written with FOR will work with LOOP, although it +sometimes may not behave identically. For convenience, here is a +(non-exhaustive) summary of the major differences. + One major difference is that LOOP is more fastidious about how +it orders the assignments and endtests. Take, for example +.lisp +(loop for n in list as z = (* n n) collect z) +.end_lisp +In FOR, 3n* would be assigned to the 3car* of the list, then +3z* would be stepped, and then the 3null* check would be made +on the iteration list. This means that on the last iteration 3z* +will be assigned to 3(* nil nil)*, which might cause some +consternation to the Lisp interpreter. In LOOP, first a 3null* +check is made on the list, then 3n* is set to the 3car* of the +list, then 3z* is stepped. + Explicit endtests (3while* and 3until*) are placed +"where they appear" in the iteration sequence. This obviates the +3repeat-while* and 3repeat-until* keywords of FOR. For +example, the FOR construct +.lisp +(for x in l collect x repeat-while (< x 259.)) +.end_lisp +may be replaced by the LOOP construct +.lisp +(loop for x in l collect x while (< x 259.)) +.end_lisp +Note that in the FOR case, the ordering of the clauses typically does +not matter, but in the LOOP case it typically does. Thus, the +ordering in +.lisp +(loop for data = (generate-some-data) + collect (f data) + while (test data)) +.end_lisp +causes the result to be a list with at least one element. + + LOOP attempts to suppress repeated evaluation where possible. +Which expressions get repeatedly evaluated is documented with the +corresponding clauses. One significant example where LOOP and FOR +differ is in the case +.lisp +(loop for i from 0 to 2expression* ...) +.end_lisp +in which FOR evaluates 2expression* at every iteration, whereas +LOOP saves the value at the start of the iteration. + It should be noted that the conditionalization clauses +(3when*, 3until*, and 3if*) affect only the following +clause rather than the whole of the "body" of the iteration, as would +be the case in FOR. + Because it is difficult for it to work in all cases, the +3trailing* clause has been eliminated. Its effect may be achieved, +however, by tacking +.lisp +and 2var* = 2initial-value* then 2var-to-be-trailed* +.end_lisp +after the 3for* clause which steps 2var-to-be-trailed*. + +.chapter "Dependencies" +.setq dependencies-section css-number +.setq dependencies-section-page page + The LOOP package may require the existence of other routines +in some implementations. For efficiency reasons, LOOP avoids +producing 3let* in the code it generates unless it is necessary +for destructuring bindings. + In the PDP-10 Maclisp implementation, LOOP uses 3ferror* +to generate error messages; 3ferror* is part of the FORMAT +package, and is assumed to be autoloadable from there. 3Let*, +which is used to produce destructuring bindings, and the destructuring +version of 3setq* called 3desetq*, which is used only when +destructuring is used, are both autoloadable. The "parallel setq" +mechanism is simulated so that 3psetq* is not needed. Macro +memoizing is performed using the same facilities which 3defmacro* +uses, and are autoloadable (and typically present in most +environments). + In Multics Maclisp, LOOP does not presently call 3ferror*, +which does not exist. +There is a 3let* macro available with +destructuring capability; it is non-standard (not part of the Multics +Lisp system) -- for further information contact the authors. Currently, +macro memoizing is performed by 3rplaca*/3rplacd* splicing, +unconditionally. + In Lisp Machine lisp, 3ferror* is used to generate errors. +This is part of the basic Lisp Machine environment. At this time, +destructuring support is not part of the basic environment, although +it is available; contact either the authors or the Lisp Machine group +if you need this. Macro memoizing is performed using 3displace*, +with the same effect as in Multics Maclisp. + +.c Local Modes: +.c Auto Fill Mode:1 +.c Comment Start:.c +.c Comment Begin:.c +.c Comment End: +.eof diff --git a/doc/_info_/lisp.newio b/doc/_info_/lisp.newio new file mode 100755 index 00000000..0a655bc7 --- /dev/null +++ b/doc/_info_/lisp.newio @@ -0,0 +1,215 @@ +MacLISP NewIO Functions Kent M. Pitman, 21 Feb 1980 + + +Opening/Closing and using file objects in New-I/O. + +New I/O has the notion of a data object called a file. Files are actually +implemented as arrays, so if you get ahold of a file object and type +(TYPEP ) it will answer "ARRAY", but there is another predicate +(FILEP ) that should return T in the case of files and not for other +arrays. + +File objects are created by the open command. The open command takes +the following syntax (both arguments optional). + + (OPEN [ [ ]]) + + must evaluate to either a NAMESTRING or a NAMELIST. + The default file is the value of the variable DEFAULTF. + + must evaluate to a list of atoms specifying the modes to open + the file in. The default is '(IN ASCII DSK BLOCK). + + Possible options are: + Direction - either IN (or READ), OUT (or PRINT), APPEND + + Data mode - either ASCII, FIXNUM (bastard image mode), + or IMAGE (really super-image). + Device type - TTY or DSK + Buffering mode - BLOCK or SINGLE + Echo mode - Open in echo area of tty only (this works only + in ITS MACLISP) + +This operation opens a file and creates an object which knows what is +going on with respect to the file. Each time you open a file, a new +file object is created (except under certain conditions to be detailed +later). Multiple file objects may be open to a file by the same name. +If they are reading the file, they will all have pointers to the same file. +If they are writing to the file, they will all have pointers to different +files, and the file object which is closed last will be the one which +becomes the file named. A file opened for write cannot be opened by +anyone else (including DDT's print). It MUST be closed first. + +To close a file, the syntax is merely (CLOSE ) where +must be a form that evaluates to a file object (the thing returned by +the OPEN request). Note that the thing returned from the open request +does not get stored anywhere automatically so make sure you setq some +variable to it or you will not be able to do anything with it! File +objects with no pointers to them are closed and recycled the next time +a garbage collection is done. + +Most input/output commands default to the tty and accept optional file +objects as a last arg. Examples are: + +(TYO [ ]) ; Output ascii char corresponding to + ; on if given, else tty. + +(TYI [ ]) ; Return the fixnum value of next character seen + ; on if given, else tty. + +(PRINT [ ]) ; Use lisp normal printer to display + ; on if given, else tty. + +READ, READLINE, IN, OUT, PRINC, PRIN1, and so on all work in analagous ways. + +Most commands that are for inputing from a file also allow an optional +arg following the file object which is the value to be returned if there +is an end of file. + +Thus you can also say: + +(SETQ UNIQUE (GENSYM)) +(READ UNIQUE) + +and if an end of file condition occurs during the real (ie, the read fails), +then the last arg (UNIQUE in above example) will be returned. If the read +happens to touch the end of the buffer but is still successful, the end +of file value will not be returned. TYI and TYIPEEK require that the +end-of-file value be a fixnum (-1. is a good choice - especially since +TYIPEEK is broken at the time I am writing this and it will return -1. +regardless of what you say if an end of file is hit.) + +Note: The end of file condition on the tty cannot happen in tyi/tyipeek + but can happen in READ and READLINE and is defined to happen + if there is an over-rubout. + +If an end-of-file is reached and there is no form to return (ie, the +optional arg was omitted) an error results if there is also not an +EOF function... (What's an EOF function?) + +The function (EOFFN [ ]) is a +function that reads or sets the eoffn (End Of File FuNction) for a +file-object. If the EOFFN is null (default) then an error will happen +if there is an eof condition is reached. + +(EOFFN ) tells you what 's related End of file + function is. + +(EOFFN ) sets 's + eoffn. + +The EOFFN must be a function of two args: + arg1= the stream on which the end-of-file has happened. + arg2= the value that the user expected returned (optional last value + or default last value (NIL for READ and READLINE, -1 for TYI + and TYIPEEK, etc.)) + +The file will be closed automatically by lisp when an end-of-file + is read and before the eof function has been called (if any) or the + eof value returned. A common kind of EOF function is one which re-opens + the file object. A file object may be re-opened in the identical modes + it was opened the first time by just saying (OPEN ). + +File specifications may take on the following formats: + +((device directory) filename1 filename2) ; Namelist + +|device: directory; filename1 filename2| ; Namestring + +with * being used as a wildcard (means use the default, NOT match all files). +The default file is stored in DEFAULTF. It should never be altered by +(SETQ DEFAULTF ...) but rather the function DEFAULTF of one arg should be +used. It will ensure that the right syntax is used. + +Eg, if DEFAULTF evals to ((DSK FOO) BAZ >) and the user does: + (DEFAULTF '(FOO BAR)) +DEFAULTF is now => ((DSK FOO) FOO BAR) + (DEFAULTF 'BOX) +DEFAULTF => ((DSK FOO) BOX BAR) + (DEFAULTF '((BAZ))) +DEFAULTF => ((DSK BAZ) BOX BAR) + (DEFAULTF '((AI))) +DEFAULTF => ((AI BAZ) BOX BAR) ; DEFAULTF is smart about devices + (DEFAULTF '((FOO) * BAX)) +DEFAULTF => ((AI FOO) BOX BAX) + +and so on... + +There is a general command that you can call to merge to filenames. +It is called MERGEF and is what is used by DEFAULTF. Thus saying +(MERGEF '|HI THERE| '((FOO BAR) BAZ GUNK)) will return +((FOO BAR) HI THERE). + +Other useful commands are which work on all of [namelists, namestrings, +file-objects] are: + +(NAMELIST ) ; give namelist form of file + +(NAMESTRING ) ; give namestring form of file + +(SHORTNAMESTRING ) ; give only filename1 and filename2 + ; parts of namestring + +NOTE: The namestring format on non-ITS sites allows the appropriate + filenaming conventions for the operating system being run under. + eg, for Twenex, |BAR.BAZ.3| would be an appropriate + namestring. + +(PROBEF ) ; returns NIL if file doesn't exist, and the true name + ; of the file as a namelist if it does exist. + +(DELETEF ) ; deletes the file + +(RENAMEF ) ; renames the to + +The following are kind of special purpose things: + +(CNAMEF ) + This command will take a file object which must be closed, and + rename it so that when you call OPEN on it, you'll be opening + a different file. This helps cope with the problem that you can + only create some fixed number of open streams (like 13 or so) + on ITS, and if you have used all the file streams but have one + you want to recycle, you can do a CNAMEF. + +(ENDPAGEFN [ ]) + When a page-end occurs on a stream it is non-fatal and will + just be ignored unless an endpage handler has been specified. + There is a default ENDPAGEFN for TYO (the default tty output + stream) which causes the ##MORE## at the bottom of a page. + This is similar in use to EOFFN. + +Notes on variables: + + TYO - Should always have the tty output object in it. + TYI - Should always have the tty input object in it. + + +(CURSORPOS [ ] [ ]) + +If is omitted, the cursorposition on (or the +default output file if this is missing) is returned as +( . ) -- 0-indexed. + +If is given it is of one of the following forms: + + - send a  to the tty - see .INFO.;LISP CURSOR + for full description of what options there are. + - same as - some chars need extra data. + - move to position ( . ) + NIL - move to on current line - same as 'H + NIL - move to (same ) - same as 'V + NIL NIL - stay where you are (?) + + +------------------------------------------------------------------------------ + +There is also a function called LOAD which will read and execute a file +as a unit. If the file is a FASL file, it will be fasloaded, else it will +forms will be read and eval'd from it sequentially as if it had been typed +at the terminal. (Default input is bound during such a read so that commands +like (TYI) ore (READ) at toplevel with no file-spec argument will be read +from the file rather than from the terminal.) The syntax for the command +is just (LOAD ) where should evaluate to a namelist, +namestring, or file object. + diff --git a/doc/_info_/lisp.news b/doc/_info_/lisp.news new file mode 100755 index 00000000..d0a0ee8f --- /dev/null +++ b/doc/_info_/lisp.news @@ -0,0 +1,8508 @@ +Wednesday February 17,1982 LQ+2D.4H.21M.13S. -- JonL -- + +1) In SHARPM 82, #| now works as on the LISPM, namely #|...cruft...|# + "disappears" like a balanced comment; note that termination is |# + Also, #R now works; e.g. #3R21 is 7 (21 in base 3). +2) Two new functions in auxillary files, but not autoloading + DEFCONST is in the MLMAC file; it is like DEFVAR, but always SETQs. + ARRAYP is in the MLSUB file; returns true for non-funny arrays. +3) GENTEMP, an LSUBR, generates truly uninterned symbols. Should be + used in preference to GENSYM by macros which generate temporary + local variables. +4) The TTYNOTES-FUNCTION facility for COMPLR has been emended + +_______________________________________________________________________ + + +2) Two new functions in auxillary files, but not autoloading + DEFCONST is in the MLMAC file; it is like DEFVAR, but always SETQs. + ARRAYP is in the MLSUB file; returns true for non-funny arrays. + (defun ARRAYP (x) + (and (eq (typep x) 'ARRAY) + (memq (array-type x) '(NIL T FIXNUM FLONUM)) + 'T)) + +3) GENTEMP, an LSUBR, generates truly uninterned symbols. Should be + used in preference to GENSYM by macros which generate temporary + local variables. + + GENTEMP permits one optional argument, a prefix for the symbol to be + created (defaults to T), and creates a symbol like + (maknam (append (explode ) + (explode '|..|) + (explode ()))) + E.g., (GENTEMP) => |T..1| + (GENTEMP '|Foo|) => |Foo..1| + A basic problem with GENSYM is that even though the symbol is uninterned + when created, it may be written out to a FASL during compilation, and + upon loading it will then be interned; separate such compilations + can thus have unfortunate co-incidences between variables which were + thought to be unique. Any symbol with a +INTERNAL-TEMP-MARKER + property on its property list will be treated during compilation in + such a way that it won't be interned when the FASL file is loaded. + +4) The TTYNOTES-FUNCTION facility for COMPLR has been emended + + If a symbol has a TTYNOTES-FUNCTION property, then that is assumed to + be some function which when applied to the symbol will either return a + re-nameing of it for the unfasl and ttynotes purposes, or will return () + meaning "I've alredy outputted all the msgs I care to see". Currently it + doesn't support the re-naming for break-point error msgs. + + +Tuesday April 28,1981 LQ+2D.2H.11M.23S. LISP 2100 / COMPLR 1111 -- JonL -- + +1) It now works to place a SFA into the variables TYI and TYO. + [more exposition below] +2) YES-OR-NO-P and Y-OR-N-P are two LISPM-compatible LSUBRs, which have been + [more exposition below] +3) BUT-TAIL, a new SUBR of 2 arguments, is autoloadable from the file MACAID. + [more exposition below] +4) +TYI is a new SUBR of 1 argument, for a super-fast version of TYI. + [more exposition below] +5) The feature "BIBOP" has gone away. It is an archaic distinction. +6) (STATUS TTYIFA) and (STATUS TTYOFA) return pointers to the initial, + built-in, TTY input file array, and respectively TTY output file array. +7) (INCLUDEF) and (INCLUDE () ) are now no-ops, rather than errors. +8) HERALD, from the MLMAC file, uses the FILE-EXIT-FUNCTIONS facility +9) DEFVST admits two more "options", :CONSTRUCTOR and :NO-SELECTOR-MACROS, + and the option-list is parsed the same way as on the LISPM -- + [more exposition below] + + +Items affecting only COMPLR + +C1) A method for individually controlling TTYNOTES information. + [more exposition below] +C2) New command line switch -- "R" which controls the variable RUNTIME-LIMITP, + [more exposition below] +C3) Interaction between the switches MACROS and DEFMACRO-FOR-COMPILING: + [more exposition below] + + +_______________________________________________________________________ + +1) It now works to place a SFA into the variables TYI and TYO. + The file QUERIO, when loaded, sets up the variable QUERY-IO to be a + "Bi-directional" SFA which can be used as a TTY -- it is normally used + by YES-OR-NO-P etc (see note 2 below). Users may use the source code + of QUERIO as a guide in writing other SFA's which want to act as filters + for the TTY (source on ITS machines is MC:LSPSRC;QUERIO >). +2) YES-OR-NO-P and Y-OR-N-P are two LISPM-compatible LSUBRs, which have been + autoloadable for some time now, but which never got documented. + See page 163 of the LISPMachine manual. Briefly, they take two + optional arguments which are a "stream" onto which to print a "message", + and return either T or () depending on whether the user typed the + appropriate affirmative response ("Y" in the case of Y-OR-N-P, and + "YES" in the case of YES-OR-NO-P); they insist on either the + required affirmative or negative response, and will try again if you + type something else. The MacLISP version of these functions permit the + "stream" and "message" arguments to be in either order, and YES-OR-NO-P + ignores any 's typed. +3) BUT-TAIL, a new SUBR of 2 arguments, is autoloadable from the file MACAID. + (BUT-TAIL ) assumes that is some nthcdr of , + and copys the top level of up to the point of . + It is like the LISPM "LDIFF"; +4) +TYI is a new SUBR of 1 argument, for a super-fast version of TYI. + Like its counterpart, +TYO, the single argument must be a file-array, + a SFA, or the symbol T (which is converted to the value of TYI). + Upon reaching End-of-File, +TYI will return -1, but will not close + the file, nor run any EOFFN function; if complete EOF action is + desired, then one could just use +TYI until it returns -1, and then + make one final call with TYI. +8) HERALD, from the MLMAC file, uses the FILE-EXIT-FUNCTIONS facility + (see LISP NEWS note of Feb 7,1981) in order to cause + the putprop of the VERSION property only when everything is + completely and successfully loaded. +9) DEFVST admits two more "options", :CONSTRUCTOR and :NO-SELECTOR-MACROS, + and the option-list is parsed the same way as on the LISPM -- + Thus, (DEFVST (FOO (:CONSTRUCTOR FLOAT-A-FOO)) ... ) + causes FLOAT-A-FOO to be the name of the constructor macro, rather + than CONS-A-FOO (or MAKE-FOO). The :NO-SELECTOR-MACROS option + causes no macro properties to be output for the selector names; + this is preparatory for an interface between DEFSTRUCT and DEFVST. + + +Items affecting only COMPLR + +C1) A method for individually controlling TTYNOTES information. + When compiling using COMPLR, if a symbol has a TTYNOTES-FUNCTION property, + then the compiler will call that function, with that symbol as its one + argument, instead of printing out on the TTY its usual message + "FOO compiled, and assembler" +C2) New command line switch -- "R" which controls the variable RUNTIME-LIMITP, + initially set to (). If RUNTIME-LIMITP is non-(), then a compilation + which "gives up its TTY" (such as by the "D" switch meaning "DISOWN", or + such as by having been started from a JCL with no request for TTYNOTEDS) + will use the ALARMCLOCK feature to cause a break-loop to occur after + RUNTIME-LIMIT microseconds of runtime have elapsed (default initial value + of RUNTIME-LIMIT is 6.0e+8, or 10. minutes). As of March 1981, the + ALARMCLOCK feature does not work on the TOPS-10/20 versions of MacLISP, + but it may soon be implmented for the TOPS-20 one. +C3) Interaction between the switches MACROS and DEFMACRO-FOR-COMPILING: + Carl Hoffman wants to get the functionaliy of the MacLISP/NIL + DEFMACRO into Multics, without having to add any new switches + (such as DEFMACRO-FOR-COMPILING etc) to the Multics MacLISP + compiler -- as an accommodation to a style of compiler usage + whereby the user "pretends" that the switch MACROS is to take + over the functionality of DEFMACRO-FOR-COMPILING, I've changed + the two occurrences of this latter switch in the DEFMACRO source + file into + (cond ((boundp 'DEFMACRO-FOR-COMPILING) + DEFMACRO-FOR-COMPILING) + ((status FEATURE COMPLR) + MACROS) + ('T)) + The normal state in the PDP10 MacLISP world is that + DEFMACRO-FOR-COMPILING is set to 'T (even in non-COMPLR lisps), and + MACROS is defaultly (); just the opposite case would apparently obtain + under Multics, that is DEFMACRO-FOR-COMPILING would be unbound, and + MACROS would be T. So, this way, in the PDP10 MacLISP world, if a user + has a files of code which don't actually SETQ the switch + DEFMACRO-FOR-COMPILING, then he do (MAKUNBOUND 'DEFMACRO-FOR-COMPILING) + [possibly in a COMPLR INIT file] and let this switch meaning operate the + way CWH will have it do under Multics. + +Saturday Feb 07,1981 NM+3D.15H.34M.49S. LISP 2071 / COMPLR 1094 -- JonL -- + + +1) Multiple-value capability implemented thru some autoloadable things: + New AUTOLOADable macros and capabilities from MLMAC: + MULTIPLE-VALUE, VALUES, MULTIPLE-VALUE-BIND + Autoloading SUBRs from file MLSUB: + MULTIPLE-VALUE-LIST, VALUES-LIST, and SI:CHECK-MULTIPLICITIES + Non-autoloading macros available in MLMAC: + MULTIPLE-VALUE-RETURN and RETURN-LIST + Reminder: MULTIPLE-VALUE is essentially the same as MSETQ-CALL of + previous notes. The names MSETQ-CALL and MSETQ-RETURN will be + superseded by the LISPM names; however macros to convert them will + be provided in the UMLMAC file (Utility MacLisp MACros). + [more exposition below] +2) Additional, new "out-of-core" SUBRs and MACROs: + Two LSUBRs "<=" and ">=", of 2 or more args are autoloadable from MLSUB file + SOURCE-TRANS properties are set up, in the MLMAC file, for + LOGAND, LOGIOR, LOGXOR, LOGNOT, FIXNUMP, FLONUMP, EVENP, <=, >=, <, and >. + (see item 4 below for "SOURCE-TRANS"), and these are used to + generate some other SUBRs in the MLSUB file: + LOGAND, LOGIOR, LOGXOR, LOGNOT, + LISTP, FIXNUMP, FLONUMP, and EVENP. + Non-autoloading macro available in DEFMAC: DEFUNP + Non-autoload versions of FMAKUNBOUND, FSYMEVAL, and FSET are in FUNCEL file. + [more exposition below] +3) Default value for DEFUN&-CHECK-ARGS is now (), and whenever &OPTIONAL or + &REST args are specified, the "args property" of the symbol will be set. + [more exposition below] + DEFUN&-CHECK-ARGS is the variable which says whether or not there should + be code in the function itself to do number-of-args checking. + The interpreter, and "UUO" handler, when in *RSET mode, will check the + number of arguments passed to a LSUBR/SUBR against the "args property", + which is retrieved and set by the ARGS function. +4) SOURCE-TRANS properties for COMPLR act almost like LISPM "optimizers". + [more exposition below] +5) FILE-EXIT-FUNCTIONS is a new global variable which is lambda-bound to + the value of FILE-EXIT-FUNCTIONS-DEFAULT by LOAD and FASLOAD. + It holds a list of functions of 1 arg to be run at end of loading. + [more exposition below] +6) DEFSFA, a macro for defining macros to make SFA usage easier, is now + defined in the EXTMAC file (along with DEFCLASS* and DEFMETHOD*) + see the documentation file SFA.DOC (on ITS system -- .INFO.;LISP SFA) + for full information. + +_______________________________________________________________________ + +1) Multiple-value capability implemented thru some autoloadable things: + New AUTOLOADable macros and capabilities from MLMAC: + MULTIPLE-VALUE, VALUES, MULTIPLE-VALUE-BIND + Autoloading SUBRs from file MLSUB: + MULTIPLE-VALUE-LIST, VALUES-LIST, and SI:CHECK-MULTIPLICITIES + Non-autoloading macros available in MLMAC: + MULTIPLE-VALUE-RETURN and RETURN-LIST + Reminder: MULTIPLE-VALUE is essentially the same as MSETQ-CALL of + previous notes. The names MSETQ-CALL and MSETQ-RETURN will be + supersede by the LISPM names; however macros to convert them will + be provided in the UMLMAC file (Utility MacLisp MACros). + + Frequently, it is convenient to think of a function as returning + several values; in LISP, one often just constructed a list of the + several item, and the calling function would "destructure" that list. + The basic special forms MULTIPLE-VALUE and VALUES are provided to + indicate respectively a function call which is expected to return + (possibly) multiple values, and a function exit which does provide + (possibly) multiple values. Cooperation is achieved through a + "return-values vector", which in MacLISP is just a collection of + several special variables. MULTIPLE-VALUE is somewhat like SETQ + in that the multiple-values returned by the call will be set into + some variables; e.g., + (MULTIPLE-VALUE (AVERAGE MAX STANDARD-DEVIATION) + (STATISTICS-GATHERER x1 y1 ...)) + might set up three values in the variables AVERAGE, MAX, and + STANDARD-DEVIATION, but without requiring an intermediate list of + results. Similarly, + (MULTIPLE-VALUE-BIND (AVERAGE MAX STANDARD-DEVIATION) + (STATISTICS-GATHERER x1 y1 ...) + (do-something ...) + ... + (do-last-thing ...)) + provides a lambda-binding, rather than a setting, of the variables, + over the enclosed scope. Also, for example, the routine + STATISTICS-GATHERER might look like + (DEFUN STATISTICS-GATHERER (a1 a2 ...) + ... ;lotta work here! + (VALUES (//$ SUM N) HIGHEST (COMPUTE-SD))) + The value of the form (MULTIPLE-VALUE (X ...) ...) is the thing + which got set to X; since destructuring works with MULTIPLE-VALUE, + then (MULTIPLE-VALUE (() Y ...) ...) returns the thing which would + have been set to the first variable, had it not been (). + + MSETQ-CALL and MSETQ-RETURN are being superseded by the LISPM names, + which are now essentially equivalent; minor differences are noted by + an occurrence of **** in the documentation here below. + 1a) MULTIPLE-VALUE, in MacLISP, macroexpands into code to setq the requested + variables to the multiple values returned by a function call. E.g. + (MULTIPLE-VALUE (FORM EX?) (MACROEXPAND-1*M FORM)) + calls a macroexpander which returns two values -- the first is the + possibly expanded form, and the second is a flag saying whether or + not any expansion really happened. If there aren't enough returned + values to set all the indicated variables, the default action of the + MacLISP facility is to pad out with ()'s (same as on LISPM); + however, **** if the global variable SI:CHECK-MULTIPLICITIES is + set to CERROR, an error will be signalled instead. See the + discussion under item 4 below. + 1b) VALUES is a new LISPM special form, and in NIL/MacLISP it is + essentially the same thing as MSETQ-RETURN was; its basic action is + to set up a "return-values vector"; typical usage would be to + call VALUES as the last form in a lambda-expression. Example: + (DEFUN TWIST (X Y) + (COND ((AND (NUMBERP X) (NUMBERP Y)) + (VALUES 'T (LESSP X Y))) + ('T (SETQ X (TO-STRING X) Y (TO-STRING Y)) + (VALUES () (ALPHALESSP X Y))))) + 1c) MULTIPLE-VALUE-LIST constructs a list of all the (possibly multiple) + values returned by the evaluated sub-form. Format of usage is like + (MULTIPLE-VALUE-LIST ( ...)) + where should return some (possibly multiple) values. + 1d) RETURN in MacLISP still admits only one argument **** -- in order to do + a RETURN with multiple arguments, do (RETURN (VALUES first second ...)) + MULTIPLE-VALUE-RETURN is primitive on the LISPM, but is macro expanded + in MacLISP to use merely RETURN. Currently, RETURN (but not + MULTIPLE-VALUE-RETURN) is primitive in MacLISP, and this causes one + incompatibility -- (RETURN (VALUES ...)) on the LISPM might return + only one value, but in MacLISP it will return as many values as are + provided by the VALUES; also, if FOO is a function returning + multiple values, then (RETURN (FOO)) will "pass them all thru" doing + essentially what MULTIPLE-VALUE-RETURN does on the LISPM. + 1e) VALUES-LIST is a SUBR of one argument, a list, which it "spreads out" + into the "return-values vector"; Thus (VALUES-LIST '(1 B 3)) + is the same as (VALUES 1 'B 3). + RETURN-LIST macroexpands into something like + (MULTIPLE-VALUE-RETURN (VALUES-LIST ...)) + As mentioned above for MULTIPLE-VALUE-RETURN, there is the implicit + LISPM/MacLISP incompatibility about RETURN. + 1f) MULTIPLE-VALUE-BIND -- a form is to be evaluated, returning several + values, and *then* a lambda-binding contour is created, with + the values bound to some variables; following that, the body of + and implicit PROGN is executed. Example: + (MULTIPLE-VALUE-BIND (A B C) (GET-THREE-VALS ...) + (COGITATE-UPON A) + (LIST B C)) + 1G) SI:CHECK-MULTIPLICITIES **** is called whenever MULTIPLE-VALUE or + MULTIPLE-BIND have more variables than there are returned values; + the value of SI:CHECK-MULTIPLICITIES, as a variable, then determines + what to do (default setting is null): + () -- means pad out unsupplied multiple-return-values with nulls; + CERROR -- means run an error if not enough values supplied; + any thing else should be a function to funcall with an argument which + is the number of variables minus one (*:ARn contains the + actual number of returned values). + Remember also that MULTIPLE-VALUE depends upon a "return-values vector" being + set up by the function called, and thus constructs like + (MULTIPLE-VALUE (v1 v2) (PROG1 (MANY-VALUED-FUN a1 a3) (SOMETHING-ELSE))) + will not work in general; a correct way to do this particular example is + (LET (unique-var-1 unique-var-2) + (MULTIPLE-VALUE (unique-var-1 unique-var-2) (MANY-VALUED-FUN a1 a3)) + (SOMETHING-ELSE) + (SETQ v1 unique-var-1 v2 unique-var-2) + v1) + This "fault" of side-effecting also applies to MULTIPLE-VALUE-LIST. + + The multiple-value functions operate quite efficiently for 8 or fewer + return values -- many of them are "open-coded" by virtue of the code + produced by the macroexpansions. Any returned values more than 8 are + passed via a cons'ing mechanism. Degenerate forms will generally + work OK, provided they make sense; e.g. (VALUES FOOBAZ) is just the + same as FOOBAZ, except the internal "number-of-extra-return-values" + variable is set up; (MULTIPLE-VALUE (X) ...) again will turn out + pretty much like an ordinary SETQ, and (MULTIPLE-VALUE () (FOO)) + will turn out pretty much like (FOO), except that the internal + count variable is set up. + +2) Additional, new "out-of-core" SUBRs and MACROs: + Two LSUBRs "<=" and ">=", of 2 or more args are autoloadable from MLSUB file + SOURCE-TRANS properties are set up, in the MLMAC file, for + LOGAND, LOGIOR, LOGXOR, LOGNOT, FIXNUMP, FLONUMP, EVENP, <=, >=, <, and >. + (see item 4 below for "SOURCE-TRANS"), and these are used to + generate some other SUBRs in the MLSUB file: + LOGAND, LOGIOR, LOGXOR, LOGNOT, + LISTP, FIXNUMP, FLONUMP, and EVENP. + Non-autoloading macro available in DEFMAC: DEFUNP + Non-autoload versions of FMAKUNBOUND, FSYMEVAL, and FSET are in FUNCEL file. + + Each of <= and >= take two or more arguments; in addition, SOURCE-TRANS + properties are set up for <=, >=, < ,and > so that the case of three + or more arguments are "wrapped up in a LAMBDA" and the basic open-coding + action of the COMPLR on the binary version can be used. + NILAID permits usage of any of <, <=, >=, >, <$, <=$, >=$, and >$ with + two or more arguments; the "$" versions are for floating-point. + In conjunction with the functions which get SOURCE-TRANS properties + from the MLMAC file, there are SUBR definitions of them in this + file (MLSUB, which is acronymic for "MacLisp SUBrs"): + LOGAND, LOGIOR, LOGXOR, LOGNOT, FIXNUMP, FLONUMP, and EVENP. + For example, the definition of EVENP can be + (DEFUN EVENP (X) (EVENP X)) + because the SOURCE-TRANS's cause "(EVENP X)" to expand into + "(NOT (ODDP X))"; similar tactics are used for multiple-argumented + funtions like LOGXOR etc. + Non-autoloading macro available in DEFMAC: DEFUNP + As on the LISPM, (DEFUNP FOO () e1 e2 ... en) macroexpands + into (DEFUN FOO () + (PROG () + e1 + e2 + (RETURN en))) + Non-autoload versions of FMAKUNBOUND, FSYMEVAL, and FSET are in FUNCEL file. + By loading in the EXTEND feature, a pseudo SUBR object can be created + and manipulated; thus reasonable versions of the LISPM/NIL functions + FMAKUNBOUND, FSYMEVAL, and FSET are implemented. + This facility is pre-loaded into NILAID. + + +3) Default value for DEFUN&-CHECK-ARGS is now (), and whenever &OPTIONAL or + &REST args are specified, the "args property" of the symbol will be set. + + DEFUN&-CHECK-ARGS is the variable which says whether or not there should + be code in the function itself to do number-of-args checking. + The interpreter, and "UUO" handler, when in *RSET mode, will check the + number of arguments passed to a LSUBR/SUBR against the "args property", + which is retrieved and set by the ARGS function. + + +4) SOURCE-TRANS properties for COMPLR act almost like LISPM "optimizers". + + It is now possible to carry out "code-transformations" in COMPLR + by means of the SOURCE-TRANS mechanism. When compiling a form whose + CAR is a symbol, the compiler will check for a SOURCE-TRANS property + on the symbol. The value of this propery should be a list of + transformation routines, each of which must be a function of one + argument. Furthermore, each transformation routine must return two + values (e.g., via VALUES), the first being the transformed form and + the second being a flag which, when non-null, indicates that the + transformation routine has "done something". The compiler applies + each transformation routine in turn, passing the form to be + transformed as the sole argument. If the transformation routine + returns a second value of () then it is considered to have + "done nothing" and the next transformation routine is tried; otherwise + the routine is considered to have "done something" and the entire + process begins anew with the first transformation routine. + The transformation of the original form is complete only after all + transformation routines have been tried and "done nothing". This + transformation procedure is carried out fully before any macro + expansion is attempted. + Note well, that this differs from the LISPM facility in that the + translating functions *must* return at least two values. + + +5) FILE-EXIT-FUNCTIONS is a new global variable which is lambda-bound to + the value of FILE-EXIT-FUNCTIONS-DEFAULT by LOAD and FASLOAD. + It holds a list of functions of 1 arg to be run at end of loading. + + The argument supplied to each function is null if loading completed + successfully; otherwise it is the file-array of the file being + aborted. This provision uses the UNWIND-PROTECT mechanism, so these + functions will be called even if the file is aborted by ^G or *THROW. + The initial setting of FILE-EXIT-FUNCTIONS-DEFAULT is null, so if you + set it to something else, those functions will be run at the end of + every file loading; typically, a file itself may push forms onto + FILE-EXIT-FUNCTIONS to provide for individual "cleanup". + + + +Friday, Dec 5,1980 LQ+5D.18H.52M.7S. LISP 2057 - JonL - + + +1) Seven items of previous LISP RECENT (dated Oct 28,1980) have been emended: + 1a) Documentation available for (STATUS USRHUNK) etc. + 1b) Both " and # are set up in the initial environment as readmacros. + 1c) CATCH and THROW are now autoloading macros from LISP:MLMAC. + 1d) Warnings about MacLISP incompatibilites with NIL, and how to + overcome the most common ones. + 1e) +INTERNAL-PERMUTIBLE-P is an autoloading subr from LISP:MACAID. + 1f) PAIRP and FBOUNDP are now initial system subrs; (PAIRP x) is the + same as (EQ (TYPEP x) 'LIST), and (FBOUNDP x) is non-null iff + x is a symbol with a functional "property". + 1g) Several "internal" subrs exist to augment compiled code: + *LDB, *DPB, *LOAD-BYTE, and *DEPOSIT-BYTE + 1h) At user level, the function's name is FIND-METHOD (rather than SI:...) + Also the names now are SI:MAKE-EXTEND, SI:EXTEND, SI:EXTEND-LENGTH, + SI:XREF, and SI:XSET rather than the *:<...> versions. + [more exposition below] +2) ** Incompatible change**" ARRAYDIMS called on a "NIL" type array will + return (NIL ...) instead of (T ...) as formerly. + New Functions, as on the LISPMachine: + (ARRAY-DIMENSION-N ) gets i'th dimension number of + (ARRAY-/#-DIMS ) gets the number of dimensions + (ARRAY-TYPE ) is the same as (CAR (ARRAYDIMS )) +3) DEFVST "macros" now all share code to minimize space. + Interpretive access to structure components checks the type of the struct. + New macros STRUCT-LET and STRUCT-SETF have featureful convience. + [more exposition below] +4) Three new functions autoloadable from DEFMAX file: + MACROEXPAND-1*M is a multiple-value returning subr of 1 arg + called like (MSETQ-CALL (X ?) (MACROEXPAND-1*M Y)) + +INTERNAL-TRY-AUTOLOADP a subr of 1 argument autoloadable from DEFMAX, + tries to autoload a function's autoload file, if it has one. + FLUSH-MACROMEMOS -- to flush the macromemo "cache"; and some new + settings for the switch DEFMACRO-DISPLACE-CALL + [more exposition below] +5) Some more LISPM-compatible autoloadable facilities, and error facilities. + CERROR, FERROR, and ERROR-RESTART as on LISPM, from LISP:CERROR file. + also a new subr +INTERNAL-LOSSAGE of three args, for use when an + "unreasonable" point is reached. + Y-OR-N-P from LISP:YESNOP file, for interactive querying. + New "error-checking" routines from LISP:ERRCK file + Documentation below for CHECK-TYPE and CHECK-SUBSEQUENCE. + [more exposition below] +6) SXHASH may dynamically be adjusted to be more anti-symmetric + [more exposition below] +7) LOOP and DEFINE-LOOP-PATH are now autoloading + See the documentation file .INFO.;LISP LOOP, or the LCS Technical Report + "LOOP Iteration Macro" MIT/LCS/TM-169. +8) DELASSQ, a new LSUBR of 2 or three args, is a cross between DELQ and ASSQ + (DELASSQ 'A '((A . 1) (B . 2) (A . 3))) ==> ( (B . 2) ) + but remember, that like DELQ, rplacds are being done. +9) #(...) notation is usable now whenever the VECTOR package is loaded; the + print method for vectors generatates this syntax, and # will read it. + #B is usabe when the BITS package is loaded; + #T is usable when the EXTEND packages is loaded (any new NIL data type + usage will load EXTEND). In MacLISP, #T is synonymous with T. + #*400000000* now reads in correctly. +10) Four new internal subrs, to help with various STRING packages: + +INTERNAL-CHAR-N +INTERNAL-RPLACHAR-N + +INTERNAL-STRING-WORD-N +INTERNAL-SET-STRING-WORD-N + [more exposition below] +11) Value of the variable PURCOPY is a list of things which the + PURCOPY function should not actually copy. For example, CLASS objects + should never be moved, and hence can't be PURCOPYied. +12) The function SQOZ/| is no longer part of the basic system -- it is + defined in the GETMIDASOP file. + +For TWENEX users: +X1) Twenex MacLISP offers a parsable "init file" facility now + CURSORPOS and "rubout" of TTY input now work on systems with VTS + [more exposition below] + +____________________________________________________________________________ + +1) Six items of previous LISP recent have been emmended significantly: + 1a) Documentation available for (STATUS USRHUNK) etc. + 1b) Both " and # are set up in the initial environment as readmacros. + 1c) CATCH and THROW are now autoloading macros from LISP:MLMAC. + 1d) Warnings about MacLISP incompatibilites with NIL, and how to + overcome the most common ones. + 1e) +INTERNAL-PERMUTIBLE-P is an autoloading subr from LISP:MACAID. + 1f) PAIRP and FBOUNDP are now initial system subrs; (PAIRP x) is the + same as (EQ (TYPEP x) 'LIST), and (FBOUNDP x) is non-null iff + x is a symbol with a functional "property". + 1g) Several "internal" subrs exist to augment compiled code: + *LDB, *DPB, *LOAD-BYTE, and *DEPOSIT-BYTE + 1h) At user level, the function's name is FIND-METHOD (rather than SI:...) + Also the names now are SI:MAKE-EXTEND, SI:EXTEND, SI:EXTEND-LENGTH, + SI:XREF, and SI:XSET rather than the *:<...> versions. + + 1a) Four new STATUS calls permit hooks into system functions, when given + hunks as arguments -- used as the basis of the EXTEND system, as + the LISP RECENT note of Oct 28,1980, item 3. See the documentation + file ".INFO.;LISP SEND" on ITS systems and "LISP:SEND.DOC" on + TOPS-10/20 systems. See also ".INFO.;LISP EXTEND" on ITS systems and + "LISP:EXTEND.DOC" TOPS-10/20 systems. + (SSTATUS USRHUNK ) specifies the "user hunk" predicate, which + determines whether to "hook into" a user-provided definition for + some system facility, or to treat the data strictly as a hunk. + (SSTATUS SENDI ) specifies a "SEND" interpreter -- + is invoked in order to send a "message" to a "user hunk", when a + hunk which passes the "usrhunk" test is given as argument to any of + EQUAL SUBST PURCOPY EVAL PRINT EXPLODE FLATSIZE + ALPHALESSP SAMEPNAMEP NAMESTRING SXHASH + or to any of the following out-of-core facilities + GFLATSIZE SPRINT USERATOMS-HOOK DESCRIBE WHICH-OPERATIONS + See the file LISP:SEND.DOC (or .INFO.;LISP SEND on ITS systems) + (SSTATUS CALLI ) specifies a "transfer function" to be + used when when a "user hunk" is FUNCALL'd. This is a hand-coded + substitute for the IAPPLY internal LISP routine. + See the file LISP:SEND.DOC (or .INFO.;LISP SEND on ITS systems) + (SSTATUS VECTOR `( )) specifies the functions + for LEXPR-FUNCALL to use for determining if the argument to be spread + is a vector, determining its length, and accessing its elements. + This allows one to do (LEXPR-FUNCALL #'LIST 'A 'B #(C D E)), for + example, yielding (A B C D E). + + 1b) Both " and # are set up in the initial environment as readmacros. + # still requires the file LISP:SHARPM.FASL, but the default function + for " will still create a pseudo-string (un-intern'd symbol) rather than + requiring the full STRING support package; loading in the file + LISP:STRING.FASL will do a SETSYNTAX on " to get real STRINGs. + + 1c) CATCH and THROW will expand according to the old syntax, but someday + this may change; currently (CATCH exp tag) ==> (*CATCH 'tag exp) + and similarly for THROW. + + + 1d) A MacLISP pre-loaded with most of the NIL facilities, is obtained by + running the subsystem NILAID (NILAID^K on ITS systems); this is more- + or-less a union of the MacLISP and NIL facilities, but one must remember + the following incompatibilities: + (1) The nullist is identified with the symbol |NIL| in MacLISP, but + has a unique new data type in NIL, so NIL code which depends on + the non-symbolness of the nullist wil lose -- check your usages + of SYMBOLP. + (2) The function atom is "false" for hunks in MacLISP, and thus is + "false" for STRINGs, VECTORs and all other data embedded into the + USRHUNK feature, so it would be more compatible to use (PAIRP X) + rather than (NOT (ATOM X)), if you want to distinguish cons cells. + The function LISTP is equivalent to (OR (NULL X) (PAIRP X)). + (3) FBOUNDP in NIL will only return "true" or "false" -- namely #T + or () -- but in MacLISP, it returns the information from the GETL + function, when "true"; thus there is more information in the + MacLISP result. + Since there are no real SUBR objects in MacLISP, the result of + FSYMEVAL will not be compatible; but used in limited ways, it will + work, e.g. (FSET 'MUMBLE (FSYMEVAL x)). + (4) CATCH (and THROW) in MacLISP still has the old semantics, but in NIL + and NILAID it has the new, namely the same as *CATCH (and *THROW); + use the * versions and be safe. + (5) CASEQ will not work on CHARACTER objects in MacLISP + (6) DEFUN will not keep track of the "documentation" string. + (7) No real package system is set up -- so GET-PNAME merely returns + the portion of a pname-string following the first ":" (if any). + + 1e) +INTERNAL-PERMUTIBLE-P is an autoloading subr from LISP:MACAID. + (+INTERNAL-PERMUTIBLE-P l) is non-() iff the forms on the list 'l' + may be EVAL'd in any order, and get the same results/effects. For + example (5 (MUMBLE X)) is permutible, since nothing which happens + inside MUMLBE can affect the value of 5; but (X (RPLACA Y)) is not + permutible, since X may point to a list which is updated by the RPLACA. + + 1g) Currently, the compiler may turn LDB into a call to the internal + subr *LDB, which has args the same as LDB except the "ppss" arg has + been lsh'd by 30. places (also, no type-checking is done on the args). + Similar remarks apply for *DPB, *LOAD-BYTE, and *DEPOSIT-BYTE. + Another alternative is that it may turn LDB into a LSH followed by + a LOGIOR. Someday, it may open-code these into an actual pdp10 LDB. + + 1h) For a certain amount of time, the EXTEND file will probably also put + macro definitions on *: to become SI:, the names + EXTEND, EXTEND-LENGTH, MAKE-EXTEND, XREF, and XSET. + +3) DEFVST "macros" now all share code to minimize space. + Interpretive access to structure components checks the type of the struct. + New macros STRUCT-LET and STRUCT-SETF have featureful convience. + + Accessor macros for a structure generally gave rise to a modest + amount of code, but a new scheme has just been implemented in which + all such macros use precisely one function; each accessor macro, or + constructor macro, needs only two properties on its property list -- + a MACRO property pointing the the single expander function, and a + small SELECTOR or CONSTRUCTOR property. Similarly, the output of + the DEFVST macro is significantly smaller, due to calling an + initialization function which will be autoloaded when needed, + rather than expanding out lots of lisp code. In interpreter usages + of selector "macros" (in *RSET mode) the code will certify that a + selector macro is being applied to a structure of the correct type; + if not, a proceedable error will be performed. + STRUCT-LET and STRUCT-SETF have been devised to facilitate + multiple settings, or gettings, of structure components. For example, + suppose DESK is a strucure with four components, defined like + (DEFVST DESK A B C D), and suppose that is a DESK possibly + created by (SETQ (CONS-A-DESK C 'FULL)). Then + (STRUCT-SETF (DESK ) (A 'PAPER) (B 25.) (D (folders))) + expands into a short program to fill in the DESK-A, DESK-B, and DESK-D + components of . Also + (STRUCT-LET (DESK ) (A (D) (MIDDLE-DRAWER B)) + ... do-some-work ... ) + would lambda-bind the variables A, D, and MIDDLE-DRAWER respectively to + the DESK-A, DESK-D and DESK-B components of and then do further + work, indicated like the implicit progn of a LET. + The code for DEFVST has been split up into three files. The new + file DEFVSX (and auxillary file for structure usage) contains various + common selector-macro expansion functions, constructor functions, etc; + the file DEFVST now contains only the DEFVST macro itself, and all the + various "methods" applicable to objects in the class STRUCT-CLASS. It + should be possible to have a file of code which defines and uses + structures, but which when compiled needs neither file loaded; the + DEFVSX file would be loaded if in the resultant object environment + it becomes necessary to expand any accessor/constructor macros at runtime. + One needn't have DEFVST loaded except when compiling, or when wanting the + more refined methods available through the EXTEND class hierarchy (as + opposed to treating structures merely as hunks). + The third file is DEFVSY, and is loaded whenever the output of + DEFVST, in the runtime environment, actually is constructing up new + instances of a defined structure. DEFVSY takes about 250. words of + binary program space, and thus will probably "pay for itself" in + terms of the code saved in the CONS-A-foo expansions. DEFVSX takes + about 590.; and DEFVST takes about 1040. + DEFVST created structures interface into the MacLISP (and NIL) + CLASS system, but they do not load it if not already loaded. Structure + instances created before the CLASS system is loaded will leave around + a "skeleton" class, which the cooperating EXTEND file will "flesh out" + when it is loaded. Typical usage of structures should cause no + overhead in the run-time environment except possibly the DEFVSY file + and a few "skeletal" classes. + +4) Three new functions autoloadable from DEFMAX file: + MACROEXPAND-1*M is a multiple-value returning subr of 1 arg + called like (MSETQ-CALL (X ?) (MACROEXPAND-1*M Y)) + +INTERNAL-TRY-AUTOLOADP a subr of 1 argument autoloadable from DEFMAX, + tries to autoload a function's autoload file, if it has one. + FLUSH-MACROMEMOS -- to flush the macromemo "cache"; and some new + settings for the switch DEFMACRO-DISPLACE-CALL + + MACROEXPAND-1*M does one step in the macroexpansion of its argument, + and returns that expansion (or the original form if it didn't represent + a macro call, and also returns a flag, T or (), telling whether or not + any expansion was done. + + The argument to +INTERNAL-TRY-AUTOLOADP should be a symbol; it tries to + load in the file from the autoload property of its argument, if there is + one. Non-null return value iff it did the loading. + + + A user may request flushing all the "cacheings" for expansions + of a macro FOO by doing (FLUSH-MACROMEMOS 'FOO () ), and may flush + all "cacheings" by (FLUSH-MACROMEMOS () () ). Here, the word "flush" + really means "invalidate", and generally nothing is done during + "flushing" except updating some validation counter. + This problem may be more thoroughly described by the following + explanation. When DEFMACRO is used to define a macro, the value of + thes witch DEFMACRO-DISPLACE-CALL determines whether the original + cell which started out with a macro call will be displaced, either by + the result of the macro expansion directly, or by an "expanded" marker + which acts like a "cache" for the expansion; a third alternative + is not to displace, but to enter into a hash table. A problem arises + in trying to determine when to invalidate such "cache" or hash-table + entries; clearly, such an invalidating must be done when the particular + macro is redefined, but many macros call the function MACROEXPAND, + and hence the value of their expansion would likely be changed by + redefining some other (totally random?) macro. As a step in solving + this problem, the durrent DEFMAX code recognized four conditions -- + A "cached" or hash-tabled expansion which becomes invalid: + 1) Only when the particular macro which gave rise to it is redefined. + 2) When any macro is re-defined (including the one for which the + expansions itself was done). All formerly compiled DEFMACROs + will currently fall into this category. + 3) When a new structure is defined (by means of DEFVST); this would + be the case for a generalized structure-hacking macro such + as STRUCT-LET, which utilizes information about a structure + being decomposed, as well as any sub-macroexpansions. + 4) When the user requests that all "cacheings" for this particular + macro, say FOO, be flushed -- this can now be done by + (FLUSH-MACROMEMOS 'FOO () ) -- or when the user requests that all + "cacheings" or hash-tableings be invalidated; this can now be done + by (FLUSH-MACROMEMOS () () ). + Currently, a test of the switch DEFMACRO-DISPLACE-CALL at performed at + macro-definition time to determine which one of 1-3 will be the case: + (EQ DEFMACRO-DISPLACE-CALL MACROEXPAND) -- case 1 + (EQ DEFMACRO-DISPLACE-CALL '|defvst-construction/||) -- case 3 + (NULL DEFMACRO-DISPLACE-CALL) -- no "cacheing" + (EQ DEFMACRO-DISPLACE-CALL 'DEFMACRO-DISPLACE) -- direct displace + any other value for DEFMACRO-DISPLACE-CALL -- case 2 + Note that the value which selects case 1 is not the (interned) symbol + MACROEXPANDED, but its value as a global variable; this is a "safety" + feature so that one will be less likely to get case 1 accidentally. + Also note that the second argument to FLUSH-MACROMEMOS, if not null, + is a signal to set up the right kind of flusher: + case 1 -- 'FLUSH-MACROMEMOS + case 2 -- value of MACROEXPEND + case 3 -- '|defvst-construction/|| + +5) Some more LISPM-compatible autoloadable facilities, and error facilities. + CERROR, FERROR, and ERROR-RESTART as on LISPM, from LISP:CERROR file. + also a new subr +INTERNAL-LOSSAGE of three args, for use when an + "unreasonable" point is reached. + Y-OR-N-P from LISP:YESNOP file, for interactive querying. + New "error-checking" routines from LISP:ERRCK file + Documentation below for CHECK-TYPE and CHECK-SUBSEQUENCE. + + Only CHECK-TYPE, CHECK-SUBSEQUENCE and +INTERNAL-LOSSAGE aren't documented + in the LISPM manual. The first two are macros which produce code calling + some internal subrs. + CHECK-TYPE takes a variable name (which it "quotes"), a function + usable as a type-testing predicate, and a symbol naming the routine which + wants the test done. CHECK-SUBSEQUENCE sets up a multiple return + value call and thus wants a list of variable names (again "unquoted"), + the name of a sequence type such as LIST, VECTOR, STRING or BITS (or null + which means any "sequence" is acceptable), and the name of the routine + which wants the test done. In each case, the macro produces code to + pass the "variables" to the internal checker, and to setq them to + the possibly-corrected return values; if the type of the main argument + isn't correct, a :WRONG-TYPE-ARGUMENT condition is signalled to CERROR, + and the corresponding variable is set to the returned value; similarly, + if the subsequence designated by the two more variables for "start + index" and "number of items" doesn't lie within the main argument, + then a :INCONSISTENT-ARGUMENTS condition is signalled. Examples: + (CHECK-TYPE X #'FLONUMP 'Hooperbylic-SIN) + (CHECK-SUBSEQUENCE (IN-STRING 1ST-CHAR-INDEX NCHARS) 'STRING 'MY-DOIT) + The "number of items" variable may be written as (), in which case the + check is merely that the index is valid for the sequence; also, it may + be calculated up by the internal routine to coincide with the end of the + sequence, by passing an optional 5th arg of (). E.g. + (CHECK-SUBSEQUENCE (IN-STRING 1ST-CHAR-INDEX HAUMANY) + 'STRING + 'MY-DOIT + () + () ) + would have one effect like + (SETQ HAUMANY (- (STRING-LENGTH IN-STRING) 1ST-CHAR-INDEX)) + + +INTERNAL-LOSSAGE is for use when system code is admittedly + incomplete, or some unfathomable point has been reached. + (+INTERNAL-LOSSAGE ) will print a message identifying + this point, and run a FAIL-ACT error. should be an identifier, and + should be the name of the function which is complaining; if + non-() may be an associated piece of data. + + +6) SXHASH may dynamically be adjusted to be more anti-symmetric + It seems that most persons are in favor of a change in the SXHASH + algorithm which would break its current symmetric behaviour on lists; + as the consequences of making this change are rather light, we offer + a status call which will dynamically do it; but the initial setting + is still the old way. Someday soon, we may set the default state + to be this new anti-symmetric version. The consequences of having two + different sxhash'ers for lists are primarily that extra space may be + taken when loading in previously compiled files, or when using the + EXPR-HASH feature; thus the change-over will likely be co-ordinated + with a massive re-compilation of all system FASL files, and probably + all MACSYMA files. + (SSTATUS SXHASH 'T), the current default, causes SXHASH to maintain + compatibility with the algorithm prior to the date Nov 3, 1980; + (SSTATUS SXHASH () ) activates the new alogrithm + (defun SXHASH-FOR-LIST (x) + (+ (rot (sxhash (car x)) 11.) (rot (sxhash (cdr x)) 7))) + Note that the use of an output from sxhash should be such that + "all bits are considered". For example, if you want to reduce the range + further to something less than the 36-bit 2's complement number that comes + out, don't just take the low 18. bits or something like that, but take + the remainder upon division by a suitable prime. + + +10) Four new internal subrs, to help with various STRING packages: + +INTERNAL-CHAR-N +INTERNAL-RPLACHAR-N + +INTERNAL-STRING-WORD-N +INTERNAL-SET-STRING-WORD-N + + The first two are interrupt-protected, non-checking versions of + CHAR-N and RPLACHAR-N; the second two are similar, but deal + with PDP10 words rather than characters. STRAUX (the STRing + AUXillary file) will guarantee that these functions exist, either + by noting their presence in the lisp system, or by supplying + a somewhat-less-than-perfect version itself. + + +X1) Twenex MacLISP offers a parsable "init file" facility now + CURSORPOS and "rubout" of TTY input now work on systems with VTS + As with MacLISP other on operating-systems, a space right after + the subsystem name causes supression of the init facility. Thus, + @MACLISP ;gets the default, LISP.INI, if it exists + @MACLISP ;stops the search for an init file. + @MACLISP FOO.BAR ;gets FOO.BAR as a LISP.INI file + TOPS-20 systems may soon get the Virtual Terminal Service developed + by Mike Travers at MIT-XX (now with Foonly); MacLISP uses it to + achieve CURSORPOS and a "rubout" facililty for type-in + + +Tuesday Oct 28,1980 FM+4D.17H.18M.10S. LISP 2033 - Jonl - + +1) Some new functions: + ASH is a SUBR of two (fixnum) arguments, and is open-coded by the compiler. + MAKE-LIST is a SUBR of one (fixnum) argument. + LOAD-BYTE, DEPOSIT-BYTE, LDB, and DPB are now installed as SUBR's. + LEXPR-FUNCALL, an LSUBR, follows the LISPMachine definition + [more exposition below] +2) Many new autoloadable functions and macros: + Macros from LISP:MLMAC -- + HERALD SELECTQ IF DEFVAR CATCH THROW + PSETQ SETQ-IF-UNBOUND MSETQ-CALL MSETQ-RETURN + WITHOUT-INTERRUPTS WITH-INTERRUPTS WITHOUT-TTY-INTERRUPTS + Macros from LISP:MACAID -- + DEFSIMPLEMAC DEFBOTHMACRO + Functions from LISP:MACAID -- + +INTERNAL-DUP-P +INTERNAL-PERMUTIBLE-P + |constant-p/|| |carcdrp/|| |no-funp/|| |side-effectsp/|| + SYMBOLCONC FLATTEN-SYMS + [more exposition below] +3) A user-extensible data-type scheme, using NIL's EXTEND data type, and + with a hierarchical CLASS system. See also the documentation file + ".INFO.;LISP EXTEND" on ITS systems and "LISP:EXTEND.DOC" on TOPS-10/20 + systems. (The "USRHUNK" facility is required, and is take over by this + CLASS system -- see 5 below). The autoloadable parts are: + Functions from LISP:EXTEND -- + PTR-TYPEP EQ-FOR-EQUAL? SI:DEFCLASS*-1 + ADD-METHOD FIND-METHOD WHICH-OPERATIONS DESCRIBE + Functions (with compile-time macro definitions) from LISP:EXTBAS ("basic") + EXTENDP SI:MAKE-EXTEND SI:XREF SI:XSET SI:EXTEND-LENGTH + SI:EXTEND (no macro definition) + Macros from LISP:EXTMAC -- + DEFCLASS* DEFMETHOD* MAKE-A-METHOD TYPECASEQ + plus all accessor macros for CLASS objects + Functions from LISP:SUBSEQ -- + SUBSEQ REPLACE TO-LIST TO-VECTOR TO-STRING TO-BITS + Functions and macros from LISP:EXTSTR ("structures") + SI:DEFCLASS*-2 **SELF-EVAL** **CLASS-SELF-EVAL** + [more exposition below] +4) Non-autoloadable Macros and Functions of general utility, from LISP:UMLMAC + FIXNUMP FLONUMP LISTP EVENP + LOGAND LOGIOR LOGXOR LOGNOT BIT-TEST BIT-SET BIT-CLEAR + WHEN UNLESS DOLIST DOTIMES <= >= + [more exposition below] +5) [delete -- discussed under item (1a) in note of Dec 04,1980] +6) A few piddling minor changes: + 6a) There is now a PDP10 on the (STATUS FEATURES) list. + 6b) Both " and # are set up in the initial environment as readmacros. + # still requires the file LISP:SHARPM.FASL, but the default function + for " will still create a pseudo-string (un-intern'd symbol) rather + than requiring the full STRING support package; loading in the file + LISP:STRING.FASL will do a SETSYNTAX on " to get real STRINGs. + 6c) SETF is gone as an FSUBR -- the macro definitions is now autoloading. + 6d) (STATUS NOINTERRUPT) returns the current state of the NOINTERRUPT flag. + (SSTATUS NOINTERRUPT ) is like (NOINTERRUPT ), but slower. +7) New variable GRLINEL controls GRINDEF -- formerly the linewidth to be used + while grinding was computed from (LINEL (OR (CAR OUTFILES) T)) + As this is only a heuristic, the variable GRLINEL (default UNBOUND) will + have priority if it is bound to a value. + +____________________________________________________________________________ + + +1) Some new functions: + ASH is a SUBR of two (fixnum) arguments, and is open-coded by the compiler. + MAKE-LIST is a SUBR of one (fixnum) argument. + LOAD-BYTE, DEPOSIT-BYTE, LDB, and DPB are now installed as SUBR's. + LEXPR-FUNCALL, an LSUBR, follows the LISPMachine definition + ASH is the "harmful operation" of arithmetic shifting. Many computer + people have been led into thinking that ASH can substitute for multiply + (or divide) when the multiplier (divisor) is a power of two; this is + a "harmful thought", as the following analysis shows. + (ASH ) is like *2^ for non-negative , and + almost like /2^<-n> for negative -- if is also negative then + it is like [+2^<-n>-1]/2^<-n>. + Many out-of-core functions need a function which generates a list + of nulls; hence: + (MAKE-LIST 0) ==> () + (MAKE-LIST ) ==> `( () ,.(make-list )) + LOAD-BYTE etc have been described in previous notes, but now + LOAD-BYTE, DEPOSIT-BYTE, LDB, and DPB are now installed as SUBR's. + The COMPLR open-codes some cases as BOOLE's [e.g., (LDB 0203 X) ==> + (BOOLE 1 (LSH X -2) 7), and (DPB 0 #o0304 X) ==> (BOOLE 4 X #o170) ] + From the LISPMachine manual, page 14, + "LEXPR-FUNCALL is like a cross between APPLY and FUNCALL. + (LEXPR-FUNCALL ... ) applies the + function to the arguments through followed + by the elements of ." + +2) Many new autoloadable functions and macros: + Macros from LISP:MLMAC -- + HERALD SELECTQ IF DEFVAR + PSETQ SETQ-IF-UNBOUND MSETQ-CALL MSETQ-RETURN + WITHOUT-INTERRUPTS WITH-INTERRUPTS WITHOUT-TTY-INTERRUPTS + Macros from LISP:MACAID -- + DEFSIMPLEMAC DEFBOTHMACRO + Functions from LISP:MACAID -- + +INTERNAL-DUP-P +INTERNAL-PERMUTIBLE-P + |constant-p/|| |carcdrp/|| |no-funp/|| |side-effectsp/|| + SYMBOLCONC FLATTEN-SYMS + + The file MC:LSPSRC;MLMAC > contains some "MacLisp MACros" which + are being standardized for compatibility with LISPM and NIL + All of these have AUTOLOAD properties in the latest LISPs (version + numbers 1997 and greater, except PSETQ, MSETQ-CALL, and MSETQ-RETURN + aren't in 1997). They are generally quite simple, and the most detailed + explanation of each one can be gained merely by inspecting the source file. + HERALD is used to print a loading message, subject to (STATUS NOLDMSG), + and to put a VERSION property on the name of the package being loaded. + SELECTQ, DEFVAR, SETQ-IF-UNBOUND, and PSETQ ("parallel setq") are + for compatibility with the LISPMachine; MSETQ-CALL, and MSETQ-RETURN + are essentially the same as the LISPM's MULTIPLE-VALUE and + MULTIPLE-VALUE-RETURN but are limited to 8 args). + (IF

    ... ) is like (COND (

    ) ('T ... )) + The "WITH...INTERRUPTS" series bind NOINTERRUPT to T, (), and TTY + respectively, and currently achieve their effect by a kludge which is + likely to be unworkable on TOPS-10 systems [an internal "write only" + variable, +INTERNAL-WITHOUT-INTERRUPTS, is used to get a memory trap upon + binding or unbinding]. Someday this kludgy hack may yield to a + potentially slower, but more robust, implementation. + + The file MC:NILCOM;MACAID > contains some macros and functions which + are of aid in writing lisp MACROS. All of these have AUTOLOAD properties + in the latest LISPs (version numbers 1997 and greater). + DEFSIMPLEMAC -- this is like DEFMACRO restricted to one "argument"; + if need be, a LAMBDA is "wrapped" around the macro product to + prevent duplication of code. E.g., let SQUARE be defined as + (DEFSIMPLEMAC SQUARE (X) `(TIMES ,X ,X)) + then (SQUARE (CAR X)) ==> (TIMES (CAR X) (CAR X)), but + (SQUARE (HUNOZ X)) ==> ((LAMBDA (G0031) (TIMES G0031 G0031)) + (HUNOZ X)) + DEFBOTHMACRO -- used just like DEFMACRO, except that a SUBR definition + is also produced by macroexpanding a prototypical call, and the + macro definition is conditionalized upon loading into a COMPLR. + E.g., (DEFBOTHMACRO MAKE-FROBL (X Y Z) `(LIST ,X (LIST ,Y ,Z))) + produces the equivalent DEFMACRO defintion which is loaded only + when (STATUS FEATURE COMPLR) is true, and also produces a DEFUN + like (DEFUN MAKE-FROBL (X Y Z) (LIST X (LIST Y Z))). + + [Note: Both DEFSIMPLEMAC and DEFBOTHMACRO are limited approximations + to what will someday be called "DEFOPEN" -- a complete solution to + the DEFSUBST attempt of the LISPM. KMP and I (JONL) have some ideas + about doing this, but currently do not have the time to finish it; + when completed, this feature will also make available to the user + certain very general code-analysis and code-expander modules.] + + DEFCOMPLRMAC -- used to make the COMPLR part of a DEFBOTHMACRO. + Syntax is just like DEFMACRO, and a conditional test for + (STATUS FEATURE COMPLR) is "wrapped" around the defmacro. + + SYMBOLCONC (x1 ... xn) + Basically, a form of STRING-APPEND, but result is returned as + an INTERNed symbol. + FLATTEN-SYMS (x l) + Appends a list of all symbols on "x" to the list "l". + |constant-p/|| (x) + Non-() only if x is a "constant" with respect to EVAL. + |carcdrp/|| (x) + Non-() iff x is a symbol for a "carcdr" function (like "CADAR"). + |no-funp/|| (x) + Non-() iff x is a form consisting only of variables, constants, + and primitive data access operations (like "CDDAR" and "+" etc). + |side-effectsp/|| (x) + Non-() iff x is a form whose EVALuation has no ordinary lisp + side-effects (like SETQ, RPLACA, or calling unknown functions) + +INTERNAL-DUP-P (x) + Non-() iff (1) the arg is a piece of lisp code representing a fairly + trivial computation, (2) it may be eval'd multiple times without + side-effects, and (3) it is "cheaper" to duplicate the permissibly + duplicatable code rather than do a lambda-binding. + +INTERNAL-PERMUTIBLE-P (l) + Non-() iff the forms on the list 'l' may be EVAL'd in any order, + and get the same results/effects. For example (5 (MUMBLE X)) + is permutible, since nothing which happens inside MUMLBE can + affect the value of 5; but (X (RPLACA Y)) is not permutible, + since X may point to a list which is updated by the RPLACA. + +3) A user-extensible data-type scheme, using NIL's EXTEND data type, and + with a hierarchical CLASS system. See also the documentation file + ".INFO.;LISP EXTEND" on ITS systems and "LISP:EXTEND.DOC" on TOPS-10/20 + systems. (The "USRHUNK" facility is required, and is take over by this + CLASS system -- see 5 below). The autoloadable parts are: + Functions from LISP:EXTEND -- + PTR-TYPEP EQ-FOR-EQUAL? SI:DEFCLASS*-1 + ADD-METHOD FIND-METHOD WHICH-OPERATIONS DESCRIBE + Functions (with compile-time macro definitions) from LISP:EXTBAS ("basic") + EXTENDP SI:MAKE-EXTEND SI:XREF SI:XSET SI:EXTEND-LENGTH + SI:EXTEND (no macro definition) + Macros from LISP:EXTMAC -- + DEFCLASS* DEFMETHOD* MAKE-A-METHOD TYPECASEQ + plus all accessor macros for CLASS objects + Functions from LISP:SUBSEQ -- + SUBSEQ REPLACE TO-LIST TO-VECTOR TO-STRING TO-BITS + Functions and macros from LISP:EXTSTR ("structures") + SI:DEFCLASS*-2 **SELF-EVAL** **CLASS-SELF-EVAL** + + A CLASS system, and all the new NIL data types, have been embedded + into MacLISP, primarily using certain hooks into MacLISP's hunks. See + the documentation file LISP:EXTEND.DOC (or .INFO.;LISP EXTEND on ITS + systems, or also LISP;EXTEND DOC). In general, see the file NIL;NEWFUN > + on the MIT-MC machine for a description of "new" functions added to NIL + (acronymic for "NewImplementationofLisp", or if you like "NilIsLisp"). + All of the LISPM string functions mentioned on pages 79.-83. of the + manual are implemented, except NSUBSTRING. Also, many more functions are + available, including those supporting a new primitive data type called + CHARACTER, and for which the user is directed to the first page of the + source file LISP:STRING.LSP (or on ITS systems, NILCOM;STRING >). + For VECTOR's, whose support is in the file LISP:VECTOR, the functions + available are VECTORP, VECTOR-LENGTH, SET-VECTOR-LENGTH (downwards only), + VREF, VSET, MAKE-VECTOR and VECTOR. (MAKE-VECTOR ) makes vector full + of nulls of size ; (VECTOR e0 e1 ... en) makes a vector of size n+1, + with components e0 e1 ... en, and (VREF i) on such a vector would get + the i'th zero-origined component; (VSET i ) would set it to the + value . + For BITS's (bit strings, or sequences of 0's and 1's), the functions, + completely analogous with VECTORs, are BITSP, BITS-LENGTH, SET-BITS-LENGTH + (downwards only), BIT, RPLACBIT, and MAKE-BITS. In addition, there are + NIBBLE and SET-NIBBLE: (NIBBLE ) gets bits out of the + bitstring , beginning at index , and makes them into a FIXNUM + with bit being numerically the least significant. + From the file LISP:SUBSEQ are several generic functions; + (SUBSEQ ) constructs a new sequence of the same type as , + beginning with element for a total new length of ; the second + are third arguments are optional, with reasonable defaults. Thus, for + example, (SUBSEQ "abcdefg" 2) would give out "cdefg". The functions + TO-xxx are like SUBSEQ, except that they force the type of sequence output + to be "xxx"; e.g. (TO-BITS '(1 0 1 1 0 0 1)) gives out #B"1011001", + and (TO-VECTOR "AbC") gives #(~A ~/b ~C). REPLACE is for destructively + clobbering a subpart of one sequence with that of another: + (REPLACE ) starts at index of the sequence + and replaces it with elements of the sequence beginning from , + for a total of elements; the third, fourth, and fifth arguments are + optional, with reasonable defaults. + +4) Non-autoloadable Macros and Functions of general utility, from LISP:UMLMAC + FIXNUMP FLONUMP LISTP EVENP + LOGAND LOGIOR LOGXOR LOGNOT BIT-TEST BIT-SET BIT-CLEAR + WHEN UNLESS DOLIST DOTIMES <= >= + The definitions for most of these macros should be obvious, but a few need + some more explanation: + FIXNUMP is *not* the same as FIXP (which admits bignums); both + FIXNUMP and FLONUMP merely check the TYPEP of their arg. + LISTP admits the nullist as well as cons cells. + EVENP is just not ODDP; + "<=" is just "not >", but calls with 2 or 3 arguments are permitted. + LOGxxx are the bitwise boolean operators defined on FIXNUMs, and + may be given arbitrarily many arguments (except LOGNOT) + BIT-xxx takes exactly two arguments; BIT-TEST is "true" if and only + if the LOGAND is non-zero; BIT-SET is just LOGIOR; and BIT-CLEAR + is non-commutative for (BIT-CLEAR ) acts like + (LOGAND (LOGNOT ) ). + (WHEN p e1 e2 ... en) is like (COND (p e1 e2 ... en)) + (UNLESS p e1 e2 ... en) is like (COND ((NOT p) e1 e2 ... en)) + (DOTIMES (i n) ......) expands into a DO loop which "does" + the body n times, with "i" set to the loop counter each time + (DOLIST (x y) ......) is much like + (PROGN (MAPC '(LAMBDA (x) ......) y) + ()) + (DOLIST (x y i) ......) is similar, but "i" is set to a + counter which is incremented each time down the list "y". + + +Thursday FEB 07,1980 FM+6D.18H.36M.35S. LISP 1922 - JONL - + +1) MACRO-EXPANSION-USE is a user-extensible feature - you may supply + a function to do the macro "memoizing" or "displaceing". +2) FBOUNDP and SELECTQ defined as macros in MACAID, have autoload properties. +3) (STATUS FASLNAMELIST) gets the namelist of the file being FASLOAD'd + or returns null if not in FASLOAD. +4) LOAD-BYTE (and DEPOSIT-BYTE) had their sense reversed - bit numbering + is now low-order to high ("right-to-left") as in VAX-like computers. + LDB and DPB remain the same. +____________________________________________________________________________ + +1) MACRO-EXPANSION-USE is a user-extensible feature - you may supply + a function to do the macro "memoizing" or "displaceing". + The run-time global-variable MACRO-EXPANSION-USE, if not null, holds + a "memoizing hook" function for macroexpansions (that is, for those + defined by DEFMACRO with the DEFMACRO-DISPLACE-CALL option). This + function takes two arguments, the original form and the expansion, + and handles any displaceing, memoizing or whatever. The available + built-in options are: + () - No memoizing or displaceing, but just use the expansion. + MACROEXPANDED - A system-supplied memoized-displace feature, which + pays attention to changes of MACRO-EXPANSION-USE, and + to any redefinition of the macro. + MACROMEMO - A system-supplied hash-array scheme, for memoizing without + displace the original form, but which does "pay attention" + as above. (data on the hash-array are in MACROMEMO). + Or, you may use any appropriate two-argument function, such as + DISPLACE - Replace CAR and CDR of first arg with those from second. + Previous usages of DEFMACRO and MACRO-EXPANSION-USE are fully compatible. + + Note: macros defined by MACRO or DEFUN, rather than by DEFMACRO will not + interface to the generalized memoizing feature. Additionally, + one should take care not to clobber the three system functions + mentioned above, since other parts of the system depend upon them. + +2) FBOUNDP and SELECTQ defined as macros in MACAID, have autoload properties. + (FBOUNDP x) ==> (GETL x '(SUBR FSUBR LSUBR EXPR FEXPR MACRO)) + SELECTQ just turns into CASEQ, but if the last clause was an "OTHERWISE", + then it becomes "T" (so that CASEQ will stop on it) + + +Sunday December 9,1979 FM+5D.18H.52M.12S. LISP 1914/COMPLR 904 - JONL, RWK - + +WARNING! The two new macro-characters, items 1 and 2 below, may become + standard someday (set up as macros in the initial lisp environment); + anyone who will have trouble accommodating should send mail to BUG-LISP. + +1) +INTERNAL-#-MACRO is autoloadable, for use as a reader-macro-character + function for "#"; fully compatible with NIL/LISPM usage. +2) +INTERNAL-/"-MACRO is defined for use in making " a string macro character. + TTYSCAN-STRINGERS| helps TTY-rubout processing in string-like sequences. +3) Two **INCOMPATIBILITIES**: + Carriage-Return, no longer invisible, is now a "white-space" character. + TERPRI is initially non-null, meaning no automatic insertion of 's. +4) PROG1 -- Like PROG2 but return first argument instead of second. +5) SETF is an FSUBR like the LISPM's general update operator + DEFSETF is an autoloadable macro to help one extend the SETF range. +6) As on LISPM, PUSH and POP have been extended to use SETF instead of SETQ. +7) INCLUDEF is a subr version of INCLUDE, for the sake of transportable code. +8) A new "Software device" convention for NAMELIST-series functions. + Namelists of the form ((LISP) * *) refer to the maclisp system area. +9) LDB and DPB and other new AUTOLOADable software as fasl file on LISP: + files ((LISP) DEFVST FASL), ((LISP) MACAID FASL), ((LISP) LODBYT FASL) +10) VSAID - VECTOR support package; STRING - support and NILAID on LISP: +11) (STATUS FILESYSTEM-TYPE), (STATUS OPSYSTEM-TYPE), and (STATUS SITE) + Warning! (LAST (STATUS FEATURES)) for non-ITS systems will be different. +12) Some things that failed to be documented previously about DEFUN/DEFUN& + &WHOLE - DEFMACRO now permits a keyword &WHOLE, to get at whole call form + DEFUN reverts to DEFUN& "if necessary"; e.g. for keywords and destructuring +13) FRETRY, a new function which is in many ways like FRETURN. +14) The setting of "+" in the toplevel and break loops modified. +15) SPRIN1, a Pretty-printing version of PRIN1 autoloadable from GRINDEF +16) CLEAR-INPUT and CLEAR-OUTPUT on SFA's now works + +17) USERATOMS-HOOKS, for compiling user-defined "SQUIDified" datatypes +18) EOF-COMPILE-QUEUE, for queueing forms to be "done" at the end of file. + +____________________________________________________________________________ + +** NOTE ** In the commentary which follows, this marker marks sections +** NOTE ** explaining features not yet present on the LISP machine. +** NOTE ** At some point in the future it is expected they will be added, +** NOTE ** but in the interim, people writing code for both systems should +** NOTE ** be careful. + +1) +INTERNAL-#-MACRO is autoloadable, for use as a reader-macro-character + function for "#"; fully compatible with NIL/LISPM usage. + +INTERNAL-#-MACRO is provided with an autoload property such that + if the user does (SETSYNTAX '/# 'SPLICING '|+INTERNAL-#-MACRO|) he will + get a MACLISP/LISPM/NIL compatible version of the read macro character + for #. Lately, this "generalized" macro character has been especially + useful for conditionalizing out lines of code based on which dialect of + lisp the code is being read into. Needless to say, it would be nice + if users could begin to accommodate this macro-character definition, + so that it can turned initailly on some day - it currently is + set on by LISPM and NIL. + The read-time meaning of a "#" instance is determined by a "dispatch" + character, which immediately follows the "#" (except when there is a + numeric "argument", in which case the base-10. digits occur between the + "#" and the dispatch character, or if there is a "control,meta" argument + in which case the argument is between the "#" and the dispatch). + The dispatch character is completely programmable (by the user too) in + essentially the same way that macro characters in general are programmable. + The function SETSYNTAX-SHARP-MACRO is like SETSYNTAX, but is for the + meanings of the character following a #. However, the associated function + must take one argument, which will be bound to any "argument" as indicated + above - null for no argument, a fixnum if the argument is a digit string, + and a symbol if the argument is one of ^B ("CONTROL"), ^C ("META"), + or ^F ("CONTROL-META"). DEFSHARP, an autoloadable macro, provides an + easy way to set up "macro character functions", to which the general # + macro character function will dispatch, depending on the character + immediately following the #. + (DEFSHARP /% (() ) (MACROEXPAND (/#SUB-READ () READ-STREAM))) + defines (and activates using SETSYNTAX-SHARP-MACRO) a function to be run + when #% occurs. There are several more options, for which the interested + party is referred to the commentary in the source code near the definition + of DEFSHARP. + + Currently, the following characters are set up as "SHARP-MACRO"s: + / - Input the following character, and give out its ascii value - + thus #/A yields 65. (101 octal). A "cntrl,meta" argument will + add in amount to make a 9-bit ascii code, with "cntrol" adding 2^7, + and "meta" adding 2^8; thus #/A yields 449. (701 octal). + ^ - Input the following character, and XOR 2^6 into its ascii value - + this generally has an effect similar to holding the control key + down while typing that character. Any argument is ignored. + . - Read-time ealuation of the next form. Any argument is ignored. + Thus, (A #.(1+ BPORG) B) might read in like (A 125755 B). + , - Load time evaluation of the next form. "#," is the same is "#." + except when compiling, in which case a "SQUID" is returned. + Any argument is ignored. + % - Read-time macro expansion; thus #%(FOO 3) will be read in + like #.(MACROEXPAND '(FOO 3)) + ' - #' reads in like (FUNCTION ). Any argument is ignored. + * - Numeric read in the "natural base" or your machine - thus for + the PDP10 and LISPM, #*xxxx* will read the digits "xxxx" in + octal; likely some other machines will use hexadecimal. + Any argument is ignored. [This is intended for use by machine + dependent code.] + \ - Following this is an alphabetic name of a character, and its + ascii value is returned; as with "#/", a "cntrl,meta" argument + will potentially convert to a 9-bit code. The correspondence + between names and values is as follows: + NULL - 0, BS - 8, BACKSPACE - 8., TAB - 9, + LF - 10., LINEFEED - 10., VT - 11., FF - 12., FORMFEED - 12., + CR - 13., RETURN - 13., NL - 13., NEWLINE - 13., ALTMODE - 27., + SP - 32., SPACE - 32., RUBOUT - 127., DELETE - 127., + ALPHA - 2, BETA - 3, EPSILON - 6, HELP - 2110. BELL - 7., + FORM - 12., BACK-NEXT - 31. + + - Next form should be a feature name, or boolean combination of + feature names, and the form after that will be read in and flushed + unless the specified featues are on the (STATUS FEATURES) list. + E.g. (A #+SAIL B C) + Will be "(A B C)" on the SAIL system but "(A C)" elsewhere. + (A #+(and (or VSAID STRINGS) (not EXPERIMENTAL)) B C) + As above, but the "B" is present only for non-experimental + systems which have either a VSAID or STRINGS feature. + - - Just like "+" above, but with the sense reversed. Thus + #-{...} is equivalent to #+(not {...}) + M - Equivalent to #+MACLISP + N - Equivalent to #+NIL, except that additional NIL syntax is + permitted in the forms to be passed over. For example, + #B"10110" and #T and #(...) would normally be illegal for + maclisp, but within the scope of a #N they are readable + (for the primary purpose of correct parsing, since they would + normally be thrown away; but if the NILAID pacakge is present, + supporting a sort of NIL-in-maclisp, then a cooperative answer + is returned). + O - Octal reading - a number should follow + Q - Equivalent to #+LISPM + R - Temporary radix change for reading a number; e.g. #3R2010 + reads in base 3 and returns 57. The "base" must be a + number between (not inclusive) 1 and 37., expressed as digits + in base ten; thus #16R... would indicate a hexadecimal notation. + Due to a shortcoming of maclisp, if you want to use digits greater + than 9, as in #16R-1A9 (= -425.), you must preceed the number with + an algebraic sign. + X - Hexadecimal reading - a number should follow + + On the ITS systems, the source code (or a link to it) will be in the file + LIBDOC;SHARPM NIL + +2) +INTERNAL-/"-MACRO is defined for use in making " a string macro character. + TTYSCAN-STRINGERS| helps TTY-rubout processing in string-like sequences. + The function defined for +INTERNAL-/"-MACRO returns an uninterned + symbol which has been set to itself; as with "#", it is up to the + user to do (SETSYNTAX '/" 'MACRO '+INTERNAL-/"-MACRO) if he wants. + TTYSCAN-STRINGERS| is a variable set up to an a-list of start + and stop (ascii values of) characters so that the system-supplied + tty prescan function can know about which (read macro) characters are + string-like delimiters. + Of course, you may supply your own macro function for doublequote if + you don't like the style of +INTERNAL-/"-MACRO. The compiler version of + this function - +INTERNAL-/"-MACRO - in addition to the abovementioned + action, puts a "+INTERNAL-STRING-MARKER" property on the symbol as well, + so that it may output + `(PROGN (SETQ ,symbol ',symbol) + (PUTPROP ,symbol T '+INTERNAL-STRING-MARKER)) + This allows a macro to use a string compiled into it in producing code + which gets output to yet another FASL file, and have that final one still + have the same characteristics of the original. Code which produces symbols + for strings can put this property on when in the compiler, to cause this + processing to happen for his strings as well. This saves the user from + having to write his own USERATOMS-HOOK (see below). + +3) Two **INCOMPATIBILITIES**: + Carriage-Return, no longer invisible, is now a "white-space" character. + TERPRI is initially non-null, meaning no automatic insertion of 's. + This means that will terminate an atom, just like space does, + and also that it is not necessary to "slashify" 's occurring within + a vertical-bar or double-quote string. Actually, many persons may prefer + to reset TERPRI to (), so that symbols will not appear to "wrap-around" + at the end of a line; the only danger is that atoms (symbols or bignums) + which are longer than the line-length will have a carriage-return inserted + "in the middle" of them, thereby destroying read-back capability. + +4) PROG1 -- Like PROG2 but return first argument instead of second. + (PROG1 e1 e2 ... en) is like (PROG2 () e1 e2 ... en) + So if you had this defined as macro in your files, you can relax now. + +5) SETF is an FSUBR like the LISPM's general update operator. + DEFSETF is an autoloadable macro to help one extend the SETF range. + SETF is particularly useful with structure accessing macros, such + as DEFVST (or other packages) would define. It's syntax is like a + generalized SETQ. For example, assume there is a macro defined by + (DEFMACRO SHIP-LABEL (X) `(CXR 6 ,x)) + then + (SETF (CADDAR A) 'BAR + (CDR B) (LIST 4) + Y 'BUZZ + (SHIP-LABEL MYSHIP) 'JOLLY-ROGER) + is equivalent to + (PROGN (RPLACA (CDDAR A) 'BAR) + (RPLACD B (LIST 4)) + (SETQ Y 'BUZZ) + (RPLACX 6 MYSHIP 'JOLLY-ROGER)) + Five standard cases are "built-in" in the interpreter, but are + redefinable with the generalized SETF expander package which will be + autoloaded when used. + a) symbols, in which case SETF acts just like SETQ; + b) car/cdr operations up to depth 4, inversion is either + a RPLACA or RPLACD; e.g. (SETF (CADR X) Y) operates + like (RPLACA (CDR X) Y); + c) GET, is inverted by PUTPROP; e.g. (SETF (GET (MUMBLE) BAR) 'LO) + works like (PUTPROP (MUMBLE) 'LO BAR) , however, correct + order of evaluation is obeyed, namely strict left-to-right + from the original form; [as of 12/10/79, the order-of-evaluation + specification has a bug in it, but this may be corrected - JONL ] + d) PLIST, inverted by SETPLIST, and + e) ARRAYCALL inverted by STORE; + Macros are expanded 1 step at a time, and a SETF-X property is + checked for, in case the user has an overriding expander. + If the access is not a SETF-X expansion, or one of the 5 recognized + cases, (or a macro or "autoload" which expands into such), then the + function +INTERNAL-SETF-X is called on the list of remaining + access/value pairs and the result is EVAL'd. + The return value is the result of the last form; *note* that the + last form is not evaluated twice unless it is safe and cheap to do so. + ** NOTE ** On the LISP Machine, only one access/value pair is allowed + ** NOTE ** and the return value is not defined. This is a superset of + ** NOTE ** the LISP Machine definition. If you wish your code to run + ** NOTE ** on the LISP Machine, you will have to limit your usage to + ** NOTE ** these constraints, and the similar constrains it places on + ** NOTE ** PUSH and POP. + In compiled code, no extra overhead is associated with the return value + being defined, unless you actually make use of it; the form is analyzed + (possibly) differently depending on whether the resultant value is needed. + + DEFSETF, an autoloadable macro, allows telling SETF, PUSH, and + POP how to invert an access; for simple cases, DEFSETF makes accessor + inversion definition very easy. + (DEFSETF (( () ) ) + ) + where is the name of the function to invert, + is a series of symbols to be bound to arguments to the function to be + inverted. is the symbol to be bound to the value to be stored. + is T or (), according to whether the return value from the + inverted form is the same as . is a form to CONS up + the apropriate code to store into the slot specified. + For example, the DEFSETF for CXR: + (DEFSETF CXR (( () INDEX HUNK) VALUE) + () ;RPLACX returns HUNK, not VALUE + `(RPLACX ,INDEX ,HUNK ,VALUE)) + Handling LSUBRs and FSUBRs and macros with variable numbers of arguments + is not quite as simple. Those interested should see MC:NILCOM;SETF > + It is also possible to write other macros which make use of this + information in such a way to avoid duplicating forms in the macro in the + code, etc. A mechanism to make this easy to use will be provided. + +6) As on LISPM, PUSH and POP have been extended to use SETF instead of SETQ. + Thus (PUSH 'BAR (CAR (FOO))) is like + (SETF (CAR (FOO)) (CONS 'BAR (CAR (FOO))) + ** EXCEPT: ** + ** NOTE ** Unlike on the LISP Machine, the return value of PUSH is + ** NOTE ** defined to be the new value of the list ("stack"). Also, + ** NOTE ** there will be no multiple evaluation of the function FOO, + ** NOTE ** as would occur on the LISP machine, and the order of evaluation + ** NOTE ** is guarenteed to be left-to-right + Also, you can do + (POP (SAVED-LOCS (GET-FROB)) (CURRENT-LOC (GET-NEW-FROB))) where SAVED-LOCS + and CURRENT-LOC are suitable accessor macros to a stack of "LOC"s in a + "FROB" and a single "LOC" in a "FROB", respectively. The second argument is + optional, and in all cases, the return value is the CAR of the list accessed + ** NOTE ** The LISP Machine supports only the 1 argument case, and does + ** NOTE ** NOT guarentee single-evaluation of the accessor nor left-right + ** NOTE ** order. + +7) INCLUDEF is a subr version of INCLUDE, for the sake of transportable code. + (INCLUDEF '((NILSRC) DRAMMP >)) is like (INCLUDE ((NILSRC) DRAMMP >)) + This allows conditional inclusion, such as according to site or filesystem. + +8) A new "Software device" convention for NAMELIST-series functions. + Namelists of the form ((LISP) * *) refer to the maclisp system area. + + I/O functions which accept namelists will look for a PPN property + on a symbol before deciding that it is not a device; if found, then + that property is substituted for the device-directory field, and + the "namelist" tries again. In particular, the symbol LISP, on + non-ITS systems, will have an initial PPN property (if in fact there + is no "LISP" device), which will link to the directory with the autoload + files on it. On the ITS systems, "LISP" has a PPN property of NIL, + but the NAMELIST functions have always converted an unknown device + name into a directory name. + +9) LDB and DPB and other new AUTOLOADable software as fasl file on LISP: + files ((LISP) DEFVST FASL), ((LISP) MACAID FASL), ((LISP) LODBYT FASL) + + DEFVST - a structure-defining package for MACLISP/LISPM/NIL + documentation is on LISP;DEFVST DOC + MACAID - many "aids" to macro usage. "(HERALD /30)" produces a + form which will print out the version number of the when + it is being loaded - a number obtained from the second file name + of the source when it is being compiled. The reader is referred to + commentary in the source file of MACAID for further information. + LODBYT - LDB and DPB are LISPM-compatible macros (which in some cases + will call the small subroutines *LDB and *DPB). "LOAD-BYTE", a + macro with args ( ) assumes that + "" is a 36-bit word, "" is the low-order bit + of a byte of length "" bits (0-origin indexing). + Bits are numbered from low-order high-order ("right-to-left") with + the lowest-order bit being 0. + "(DEPOSIT-BYTE )" is + similar, but the is inserted into the return copy of + the . Although LDB and DPB are documented in the LISP Machine + Manual, there is a definition here below for benefit of those who + couldn't get a LISPM manual. + For LDB and DPB - + The representation "" assumes that in base 8, this argument + is expressing two octal digits "pp" followed by another two octal + digits "ss". Then "(LDB )" selects a byte of + (\ 64.) bits in length, which is positioned in with + (\ (// 64.) 64.) bits to the right of the byte; in other + words, is a PDP10 byte-pointer right-shifted by 24. bits. + For "(DPB )", note that DPB is a non-destructive + operation which returns a new value. Some cases of the + macro-expansions of LDB and DPB (and LOAD-BYTE and DEPOSITE-BYTE) + produce LSH and BOOLE, but others produce calls to the functions + *LDB and *DPB; thus, until the compiler begins to open-code *LDB + and *DPB, you will need this "macros" file loaded into your run-time + environment also. + +10) VSAID - VECTOR support package; STRING - support, and NILAID on LISP: + + NILAID is a NIL-compatibility support package for maclisp. + VSAID is a limited support package for using VECTORs and EXTENDs, which + is required by DEFVST, STRING and NILAID. + STRING has the NIL and LISPM string handling primitives in it, with a + few basic ones coded "by hand" for speed. Garbage-collection + strategy requires the use of the GC-DAEMON. See the first + page of the source file for more information. + +11) (STATUS FILESYSTEM-TYPE), (STATUS OPSYSTEM-TYPE), and (STATUS SITE) + Warning! (LAST (STATUS FEATURES)) for non-ITS systems will be different. + The last item in the "features" list will be (STATUS FILESYSTEM-TYPE) + and the next-to-last will be (STATUS SITE); this will mean no + change for ITS-supported systems, but will be different on the other + kinds of systems. + The FILESYSTEM-TYPE is either "ITS", "DEC20", or "DEC10" and is a + kind of general "operating-system type". The OPSYSTEM-TYPE is either + "TOPS-20" or "TENEX", when the file-system type is DEC20; or, if the + file-system type is DEC10, it is among "TOPS-10" (for vanilla-flavoured + TOPS-10), "CMU" (for CMU-hacked-up TOPS-10), or "SAIL" (for a + SAIL-perverted-WAITS TOPS-10. The SITE name was originally meant to + distinguish running on the MIT-AI machine from the MIT-ML machine (but + nowadays, the same maclisp system runs unmodified on all ITS machines); + nevertheless, the SITE name is among "AI", "ML", "MC", or "DM" for ITS + systems, "TOPS-20" or "TENEX" for DEC20 style systems, "SAIL" for (r.i.p) + the SU-AI system, and "TOPS-10" or "CMU" for non-SAIL DEC10 style systems. + Someday, the DEC10/DEC20 site names may be more informative, + e.g. "CMU-10A", "XX", "BBN-D" or whatever. + +12) Some things that failed to be documented previously about DEFUN/DEFUN& + &WHOLE - DEFMACRO now permits a keyword &WHOLE, to get at whole call form + by specifying a variable to be bound to the whole call form. + (DEFMACRO FOOM (&WHOLE X) ) would bind X just like + (MACRO FOOM (X) ) + DEFUN reverts to DEFUN& "if necessary"; e.g. for keywords and destructuring + Thus in MACLISP, you can use the & keywords, and argument + destructuring without expliciting using DEFUN&. + For example, (DEFUN FOO ((A . B) &REST W) (LIST A B W)) + becomes essentially + (DEFUN FOO G0005 + (LET ((W (AND (> G0005 1) (LISTIFY (- 1 G0005)))) + ((A . B) (ARG 1))) + (LIST A B W))) + Any required, optional, or rest variable may be null, meaning "ignore". + DEFUN& with "&optional" and/or "&rest" keywords (and DEFUNs that are + turned into DEFUN& with these keywords) cause the function to become + an LEXPR type - (compiled into LSUBR instead of SUBR). Thus, in order + to compile other functions calling these functions, you will likely + have to give *LEXPR declarations for these functions, even though they + are not explicitly of the maclisp LEXPR format. + ** DEFUN&-CHECK-ARGS controls whether or not there is run-time + checking to see if a DEFUN& with &OPTIONAL or &REST arguments + has too many or two few arguments passed. + +13) FRETRY, a new function which is in many ways like FRETURN. + FRETRY "unwinds" the stack to the point indicated by the first + argument, which should be a PDL pointer such as would be in the list + returned by EVALFRAME, and it then evaluates the form extracted from + its second argument, which should be a list such as would be returned + by EVALFRAME. It was intended primarily to be used to "re-try" something + that appears to be losing, but which has been corrected (say, in an error + break loop). E.g. + (SETQ EF (EVALFRAME ...)) + (FRETRY (CADR EF) EF) + But it could be used more generally, e.g. + (SETQ PP (GET-PDL-PTR )) + (FRETRY PP `(EVAL ,pp (BREAK STOP-AND-LOOK))) + In fact, one could define + (DEFUN FRETURN (PP X) + (SETQ PP (EVALFRAME (1+ PP))) + (FRETRY (CADR PP) + (CASEQ (CAR PP) + (EVAL `(EVAL ,(cadr pp) (QUOTE ,x))) + (APPLY `(APPLY ,(cadr pp) (QUOTE (,x))))))) + +14) The setting of "+" in the toplevel and break loops modified. + If "+" is input to the toplevel or break loops, then the value of + "+" will not be set for that time around, thus leaving "+" with + a value corresping to the previous input to toplevel or break. + +15) SPRIN1, a Pretty-printing version of PRIN1 autoloadable from GRINDEF + SPRIN1 is an autoloadable function suitable for assigning to + PRIN1, so that the general top-level printer becomes a "SPRINTER". + Try, for example, (SETQ PRIN1 'SPRIN1) + +16) CLEAR-INPUT and CLEAR-OUTPUT on SFA's now works + Hurray! They give it the CLEAR-INPUT and CLEAR-OUTPUT operation, + if defined. The argument is always (). + +17) USERATOMS-HOOKS, for compiling user-defined "SQUIDified" datatypes + This hook provides a means for the user to manipulate user-defined + "atomic" datatypes in the compiler, and then substitute a SQUIDform-like + piece of code to construct such an object when the form is output + to the FASL file. For example, if the user has macros which manipulate + strings represented as (STRING-MARKER . ), he would be + unable to include any of these strings as literal data in the FASL + file, since there is no representation for arrays in FASL files. + However, with this hook it would be possible to achieve the effects + of outputing these strings directly. The alternative until now has + been to use "SQUID" forms, but this has the disadvantage that you cannot + then manipualate these things in the same manner as in the interpreter. + If the symbol USERATOMS-HOOKS is non-nil, it should be a list of + functions of one argument, which will be called on every piece (atomic + or not) of any literal object being output to the FASL file. If the object + does not need special handling, the function should return (). Otherwise + it should return the NCONS of an s-expression to evaluate at load time + to create the object. + The hook will not be called on an object more than once. EQness is + preserved, if two strings or whatever are EQ in the compiler, they + will be made EQ in the interpreter (using the atom-table, for you + low-level hackers). + + (eval-when (COMPILE) + (defun MYSTRINGHOOK (form) + (cond ((atom form) ()) ;If we don't recognize it, return () + ((eq (car form) 'STRING-MARKER) ;One of ourse + `((CONS 'STRING-MARKER + (fillarray (array () ,(arraysize (cdr form))) + ',(listarray (cdr form)))))) + (t ()))) ;Not one of ours, return (). + + (push 'MYSTRINGHOOK USERATOMS-HOOKS)) + + This is not implemented as efficiently as it might be. If it is too slow, + it can be speeded up. + + [Note: the resulting FASL file may not work in LISP 1861 or before, due to + a but in FASLOAD] + +18) EOF-COMPILE-QUEUE, for queueing forms to be "done" at the end of file. + EOF-COMPILE-QUEUE provides a means to "add forms to the end of the file" + in the compiler. Thus if you need certain cleanup actions performed + at the end of the file, you can push forms onto this queue, which will + be compiled in the order they were pushed when the end of the file + is reached. It is OK for forms on this queue to push new forms onto the + queue. + + +Thursday August 16,1979 LQ+1D.1H.28M.3S. LISP 1860 / COMPLR 895 -JONL- + +1) DEFMACRO usages no longer cause automatic loading of DEFMAX file. +2) DEFUN& and DEFMACRO admits a "supplied-p" variable for &OPTIONAL variables. +3) DEFAULTF no longer manipulated by LOAD or FASLOAD, and new initial value. +4) ERROR-BREAK-ENVIRONMENT - sets OBARRAY/READTABLE for ^B and error loops. +5) Splicing macros which return a singleton list may now appear at top level.î + +The following three items apply to compiler usage: +6) New COMPLR switch "~", controlling the variable QUIT-ON-ERROR +7) New UUO "STRT7" for typing out ascii strings. Works similar to "STRT". +8) Two numerical No-Op subrs FIXNUM-IDENTITY and FLONUM-IDENTITY open-compile + +____________________________________________________________________________ + +1) DEFMACRO usages no longer cause automatic loading of DEFMAX file. + As of version 80, DEFMACRO will stop outputting, along with each + macro definition compiled, the form + (AND (NOT (GET '|forget-macromemos/|| 'SUBR)) + (LOAD `(,(car (get 'defmacro 'autoload)) DEFMAX FASL))) + Since LISPs prior to about version 1832 did not have autoload properties + for the auxillary functions needed by DEFMACRO-defined macros, then + each such macro explicitly tried to load the DEFMAX file if not already + loaded. If you see a message about + "|forget-macromemos/|| Undefined Function" + it is probably because you are using DEFMACRO output in an old LISP + (and some of the system code does depend upon DEFMACRO, e.g. LET) so + you should simply load the DEFMAX file by hand. + +2) DEFUN& and DEFMACRO admits a "supplied-p" variable for &OPTIONAL variables. + The format "(binding default-value flag-variable)" used in a place where a + &OPTIONAL variable would be used, causes the symbol "flag-variable" to be + bound to T if that optional argument is actually supplied, and to null + otherwise. Example: + (DEFUN FOO (&OPTIONAL (Z () ZP?)) ... ) + causes "ZP?" to be non-null for those calls to FOO with an argument. + +3) DEFAULTF no longer manipulated by LOAD or FASLOAD, and new initial value. + This has the consequence that only the "oldio" compatibility functions + change DEFAULTF (namely, UREAD, UWRITE, UFILE, UKILL). Furthermore, its + initial setting will be + `((DSK ,(status udir)) * >) ;ITS + `((DSK ,(status udir)) * LSP) ;TOPS-10/CMU + `((PS ,(status udir)) * LSP) ;TOPS-20/TENEX + `((DSK ,(status udir)) * ___) ;SAIL (kludge, meaning no extension) + +4) ERROR-BREAK-ENVIRONMENT - sets OBARRAY/READTABLE for ^B and error loops. + As a special variable, ERROR-BREAK-ENVIRONMENT holds a pair (cons pair) + of an obarray and readtable to use during the system-supplied ^B break and + error handlers. Its initial setting is + `(,(get 'OBARRAY 'ARRAY) . ,(get 'READTABLE 'ARRAY)) + This may be especially useful to the person who is debugging his macros + during the compilation of some file, and wants a different debugging + environment than the compiler's OBARRAY/READTABLE. + +5) Splicing macros which return a singleton list may now appear at top level. + also may appear just after a "dot" for a dotted pair or hunk. + At top level, if a splicing macro returns a list of one element, + then READ returns that element just as if it were read primitively; + the same holds true for splicing macros just after a dotted-pair dot. + E.g., if "~" is defined as (SETSYNTAX '/~ 'SPLICING '(LAMBDA () (READ))) + then (A . ~(B)) reads in the same as (A . B) + + An error (ILLEGAL RETURN VALUE FROM SPLICING MACRO --READ) is given if + something other than () or a singleton LIST is returned in this context. + (Longer lists are of course legal in other circumstances). + Multiple splicing macro calls can be placed after a dot, but only one + of them can return non-NIL, or it is an error. + +6) New COMPLR switch "~", controlling the variable QUIT-ON-ERROR + Generally, if an *error* (as opposed to a warning condition) + is discovered, the COMPLR will go into a BREAK loop, awaiting + further intervention by the user. But if the value of the + variable QUIT-ON-ERROR is non-null, it will merely do a (QUIT); + The initial value of this variable is (). + +7) New COMPLR switch "7", controlling the variable USE-STRT7 + LISP 1858 has a new UUO, "STRT7", for typing out ascii strings, which + works similarly to "STRT". The compiler will generally turn PRINC + of a quoted thing into a STRT (which is for sixbit formats), but + now "STRT7" can be used, resulting in shorter lengths for lower-case + strings. Initially USE-STRT7 is off, since older LISPs don't + support STRT7. + +8) Two numerical No-Op subrs FIXNUM-IDENTITY and FLONUM-IDENTITY open-compile + Along with the numerical subrs "+", "+$", etc. are added two identity + functions: (FIXNUM-IDENTITY x) requires that x evaluate to something + of type FIXNUM, and (FLONUM-IDENTITY x) similarly requires FLONUM; + both merely return their argument. In the past, users have been + checking the type of certain arguments by code like "(+ )" and + "(+$ )"; these forms will still achieve the desired effect, + but "FIXNUM-IDENTITY" and "FLONUM-IDENTITY" can be used to distinguish + this case from accidental 1-argument uses of the fixnum PLUS function. + These functions are not part of a type-assertion scheme, but merely take + advantage of the compiler's open-coding schemes. + +Thursday June 07,1979 FQ+5D.11H.58M.56S. - Jonl - + +1) Value of "MAKHUNK" permits use of a new HUNK2 space. +2) HUNKs now have a PRINT syntax, and can be FASLOADed +3) Added comma syntax for backquote selects NCONC rather than APPEND +4) Backquote macro permits "grindef"ing in format exactly as read in. +5) The famous but Kludgy Binford Editor is now autoloadable. +6) Remaining hooks into TOPLEVEL/BREAK loop +7) LAST-MACROEXPANDED-LOSER is gone. + +8) RPLACX now is open-coded by COMPLR (in the same way that CXR is) +9) New compiler switch: HUNK2-TO-LIST, with switch letter "2". + +_______________________________________________________________________ + + +1) Value of "MAKHUNK" permits use of a new HUNK2 space. + The value of the special variable MAKHUNK controls whether hunks + of size 1 and 2 are stored in LIST space, or in a HUNK2 space. + MAKHUNK = T says use HUNK2; initial setting is MAKHUNK = T. + The compiler will rewrite forms like "(HUNK x)" and "(HUNK x y)" + into appropiate calls to NCONS or CONS, depending on the value of + the new compiler switch "HUNK2-TO-LIST" - see the comment below. + +2) HUNKs now have a PRINT syntax, and can be FASLOADed + When "MAKHUNK" is non-null, certain formats will be recognized by + the reader as presenting HUNKs; when "MAKHUNK" is null, these formats + will be treated as previously, namely erroneous. Any "S-expression" + presented like a list, but with more than one dot, or with a dot + immediately before the final parens, will be read-in as a HUNK. E.g. + (A . B . C), (A . B .) as well as (A .) + PRINT will always put the dot before the final parens. + FASLAP can output hunks, in case any should be incorporated into your + expr code; and FASLOAD can load them back in. + +3) Added comma syntax for backquote selects NCONC rather than APPEND + The form ",." in addition to ",@" is recognized by the backquote + feature. ",." selects NCONC instead of APPEND, and thus we have + `(,@B C) generates (APPEND B '(C)) + `(,.B C) generates (NCONC B '(C)) + [This idea, for ",." comes from RBR] + +4) Backquote macro permits "grindef"ing in format exactly as read in. + The "backquote" macro now has the option of generating + "macroified" code, with the name |`-expander/|| as a primary + eval-time macro. This option will be exercised if + BACKQUOTE-EXPAND-WHEN is "EVAL" (or in general anything except + "READ"), and otherwise the expansion will occur at read-in time + just as at present. Three other internal markers are added: + |`,/|| |`,@/|| and |`,./||. + GRINDEF would print out a form just like it was read-in, using + the READMACROINVERSE feature; however, there is a flaw in this + feature in that readmacros won't appear in the CDR part of + a list; thus you never see '(A . 'B) grindef'd out that way. + For the same reason, it would be somewhat of a pain to get + `(A . ,B) to grindef out that way, but `(A ,@B) and `(A ,.B) + both win. Note the weird commutation: `(A . ,B) works the + same as `(A ,. B) ?? + All the aforesaid "markers" and macros are on the obarray, so that + any PRINTing or GRINDEFing (regardless of the success of the + READMACROINVERSE attempts) would be readable back in with no loss + of functionality. All such markers (and other parts of this feature) + are automatically autoloaded. + +5) The famous but Kludgy Binford Editor is now autoloadable. + Thus it is no longer part of the initial ITS maclisp environment. + REMEMBER:  holds the last thing killed +  holds the "back-upwards" list + ^^^ holds the "back-leftwards" list + EDIT hold a list of the names for "editible" properties + "S", that is the search command, with no trailing arguments, + means to search again for the same thing as before. + Both "S" and "I" take arbitrarily many trailing arguments, + terminated by + Also, any symbol with an EDIT property may be an edit command, + wherein the function stored under the EDIT property is applied + to a number: 0 means no numeric arg to function + n > 0 is the numeric argument given to the command + +6) Remaining hooks into TOPLEVEL/BREAK loop + The following special global variables are now in the system, and + they also have respectively a SUBR property corresponding to the + system-supplied code for the parallel top-level operations: + READ-EVAL-*-PRINT for "prin1" part of the loop, subr of 1 arg + READ-EVAL-PRINT-* for "terpri" part of the loop, subr of 0 args + *-READ-EVAL-PRINT for "read" part of the loop, subr of 0 args + READ-*-EVAL-PRINT for "eval" part of the loop, subr of 1 arg + The "LISP RECENT" note of May 15,1978 mentioned two of these as + "hooks" into the TOPLEVEL/BREAK loop; the number of these hooks is + thus now extended to include the full set possible. Recall that each + such function "intercepts" the TOPLEVEL/BREAK loop at the point of the + "*" in its PNAME. Thus one pass through the loop would look essentially + like: + (AND *-READ-EVAL-PRINT (FUNCALL *-READ-EVAL-PRINT)) ;"intercept" + (SETQ * (*-READ-EVAL-PRINT) ;TOP-LEVEL-READ + (AND READ-*-EVAL-PRINT (FUNCALL READ-*-EVAL-PRINT *)) ;"intercept" + (SETQ * (READ-*-EVAL-PRINT *)) ;TOP-LEVEL-EVAL + (AND READ-EVAL-*-PRINT (FUNCALL READ-EVAL-*-PRINT *)) ;"intercept" + (READ-EVAL-*-PRINT *) ;TOP-LEVEL-PRINT + (AND READ-EVAL-PRINT-* (FUNCALL READ-EVAL-PRINT-*)) ;"intercept" + (READ-EVAL-PRINT-*) ;TOP-LEVEL-TERPRI + + +7) LAST-MACROEXPANDED-LOSER is gone. + It used to do something in macros defined by DEFMACRO. + +8) RPLACX now is open-coded by COMPLR (in the same way that CXR is) + +9) New compiler switch: HUNK2-TO-LIST, with switch letter "2". + causes "(HUNK x)" to compile like "(NCONS x)", and "(HUNK x y)" + to compile like "(CONS x y)". Initial setting is (), so that + hunk calls are output; in the object environment, a hunk call may + actually produce a list cell if MAKHUNK is null. + + + +Wednesday April 11,1979 FQ+7D.0H.20M.8S. - JONL - + +1) New features for DEFMACRO: MACRO-EXPANSION-USE and temporary + switch overrides for the free-variable type switches. +2) OWN-SYMBOL - a declaration for disassociating any systemic properties + from a symbol when compiling a file. +3) MACRO-EXPAND in the compiler - a macro-expander for all levels. + +____________________________________________________________________________ + +1) New features for DEFMACRO: MACRO-EXPANSION-USE and temporary + switch overrides for the free-variable type switches. + + MACRO-EXPANSION-USE for "memorizing" macro expansions + in a hash-array and for displace'ing macros in which the + call is displaced in an "back-up'able" manner. + Temporary overrides for the three macro-definition switches + (namely DEFMACRO-DISPLACE-CALL, DEFMACRO-FOR-COMPILING, and + DEFMACRO-CHECK-ARGS). This feature is available for + DEFMACRO and DEFUN/& and MACRO. + + 1a) Chuck Rich's macro annotation package (MACROD) and Ken Kahn's + macro expansion package have been added to MACLISP's DEFMACRO + facility. A new runtime switch (as opposed to macro definition + time switch) has been added, MACRO-EXPANSION-USE: + If MACRO-EXPANSION-USE is set to MACROMEMO, then Rich's hash- + array "memoizer" will remember previously-expanded macro calls, + and not re-expand unless the macro is redefined (via DEFMACRO); + If MACRO-EXPANSION-USE is set to MACROEXPANDED, then Kahn's + style "displacer" will displace the original call with a form + which remembers both the old original, and the expansion, and + not re-expand unless the macro is redefined (via DEFMACRO); + GRINDEF is smart about these "displaced" forms. + + In the runtime environment, macros produced while + DEFMACRO-DISPLACE-CALL is non-null will pay attention to the global + variable MACRO-EXPANSION-USE (default = () ). + MACRO-EXPANSION-USE: + = MACROEXPANDED - Displace the original cell with a form like + (MACROEXPANDED + + + ) + Thereafter, the macro named MACROEXPANDED will + return the until either the value of + MACRO-EXPANSION-USE changes, or the + of the original macro changes (such as by loading + in a new definition of the macro). + = MACROEXPAND - Same as above; for those who can't spell. + = DISPLACE - Displace the original cell with the expansion of the + macro-form. There is no general way to un-do, or + "go back" after this kind of displacement. + = MACROMEMO - Remember the expansions is a hasharray, where the + global variable MACROMEMO is a dotted pair of the + number-of-buckets and the array pointer itself. + All "memorized" expansions can be forgotten merely + by doing (RPLACD MACROMEMO () ). + = () - None of the above, i.e. merely expand the macro + and return that value. + Pretty-printing of forms displaced with MACROEXPANDED is controlled by + the global variable GRIND-MACROEXPANDED: if T, then only the + expanded form will be printed; if (), then only the original form + will be printed. (Default = () ) + + As an aid in debugging, the global variable LAST-MACROEXPANDED-LOSER + holds a ptr to the last cell visited by MACROEXPANDED + + + 1b) The three switches relevant to macro defining time (as opposed + macro expansion time) may be temporarily overridden. These + switches are DEFMACRO-DISPLACE-CALL, DEFMACRO-FOR-COMPILING, and + DEFMACRO-CHECK-ARGS. If the "name" part of a DEFMACRO usage is a + list (instead of a symbol), then the first element is taken as the + "name", and the rest of the list is treated like a form to SETQ, + that is, alternating items in the list are names for the switches + and a form that is evaluated to get the switch value. For example: + (DEFMACRO (RLIST DEFMACRO-DISPLACE-CALL 'T DEFMACRO-CHECK-ARGS ()) (X Y) + `(LIST ,y ,x)) + will make a macro for RLIST which will be of the run-time + displacing type as explained above, regardless of the global setting + of the switch DEFMACRO-DISPLACE-CALL; also it will not insert any + code into RLIST to check for proper number of args being passed. + This capability, for DEFMACRO-DISPLACE-CALL, rather outdates the + function DEFMACRO-DISPLACE, for any call to it could merely be + replaced by a call to DEFMACRO with a temporary override of the + switch DEFMACRO-DISPLACE-CALL. + + As a reminder, the meaning of these three switches is reproduced here: + DEFMACRO-DISPLACE-CALL if non-null, the resultant macros do a runtime + (default = T) test of MACRO-EXPANSION-USE for possible + displacement and/or "memoizing" in a hasharray. + DEFMACRO-FOR-COMPILING determines whether the macros produced will be + (default = T) of the form that gets compiled by COMPLR + (in either case, COMPLR "remembers" them). + DEFMACRO-CHECK-ARGS determines whether there should be code to carry + (default = T) out number-of-args checking at runtime. + + +2) OWN-SYMBOL - a declaration for disassociating any systemic properties + from a symbol when compiling a file. + E.g. (DECLARE (OWN-SYMBOL PUSH UNWIND-PROTECT)) + will REMOB the two symbols PUSH and UNWIND-PROTECT, and thus + subsequent usages of them in the file will appear to be "fresh" + atoms. This is the surest way to disconnect all special knowledge + that COMPLR has about a particular symbol, so that it can be used + by the user in some peculiar way. + +3) MACRO-EXPAND in the compiler - a macro-expander for all levels. + Item 6 of the LISP RECENT note dated Jan 27, 1979, spoke about + a switch EXPAND-OUT-MACROS, which affects the treatment of + top-level forms which are sent out to the FASL file. The + function MACRO-EXPAND is called, which performs a sort of + "meta" compilation on the form, but actually only expanding out + any macro usages (which would later be expanded and run during + load-in time). This saves the load/run-time environment the + burden of needing the whole macro-environment. This function, + MACRO-EXPAND, is available to the user for his various wants, + as it is on both obarrays. + +Saturday Jan 27,1979 LQ+7D.1H.40M.31S. LISP 1785 / COMPLR 867 -JONL- + + +1) EVAL-WHEN - - a new fsubr, like DECLARE but much more general +2) DEFUN permits LISP-Machine like syntax, and LET-destructuring of arguments. +3) New AUTOLOADable MACROs: LET, LET*, DESETQ; and DEFMACRO, MACRO, DEFUN& + Functions MACROEXPAND and MACROEXPAND-1, defined as on LISPM, are available +4) Better error checking in *RSET mode for functions that cdr down lists: + LAST now gets the last node of a non-atomic s-expression, or () for (). +5) "MACLISP" is now on the feature list, to help distinguish from LISPM. +6) COMPLR has some new switches and global variables - EXPAND-OUT-MACROS etc. +7) SUSPEND - review of meanings of arguments +8) Under the ITS operating system, a JCL line with only a means don't + use any INIT file, even if the connected directory has one. This may + be extended to the TOPS versions also. + +____________________________________________________________________________ + +1) EVAL-WHEN - - a new fsubr, like DECLARE but much more general + (EVAL-WHEN ( ... ) . . . ) + will cause the evaluation of the various only if the "evaluator" + matches one of the indicators in the first list; these indicators + may be among EVAL, COMPILE, or LOAD, which respectively trigger + EVAL - a normal, read-eval-print loop + COMPILE - the "maklap" processor, which compiles files + LOAD - "fasload" (which only processes compiler output) + (EVAL-WHEN (COMPILE) (SAY THIS)) is entirely equivalent to + (DECLARE (SAY THIS)) + (EVAL-WHEN (EVAL LOAD) (RUN THAT)) is generally equivalent to + (RUN THAT) + (EVAL-WHEN (LOAD) (PRINT '|Loading Compiled version of Foo|)) + will cause the print request to appear only in the compiled FASL + file, and be run at load time. (or LAP file if you don't assemble). + (EVAL-WHEN (EVAL COMPILE LOAD) (SETSYNTAX '/% 'MACRO 'FUNNY-FUN)) + causes evaluation in all environments, which is often what one wants + with macro characters. + +2) DEFUN permits LISP-Machine like syntax, and LET-destructuring of arguments. + DEFUN automatically becomes DEFUN& if "&" keywords occur in the dummy + argument list, or any dummy argument is not a symbol; see 3b below. + +3) New AUTOLOADable MACROs: LET, LET*, DESETQ; and DEFMACRO, MACRO, DEFUN& + Functions MACROEXPAND and MACROEXPAND-1, defined as on LISPM, are available + from the file supporting DEFUN&, but they do not have autoload properties. + LET, LET*, and DESETQ are on the same file LISP;LET FASL + DEFMACRO, MACRO, and DEFUN& are on the file LISP;DEFMAC FASL + In the BNF descriptions below, "{...|...}" denotes precisely one of + the alternatives between the brackets and separated by vertical-bars; + "{...}*" means zero or more occurances of the alternatives, "{...}+" + means one or more occurances. + 3a) LET, LET*, and DESETQ + Following the many user definitions of a macro LET, we now + have an autoload property for LET, and a definitions of it + which is fairly intuitive: + (LET ((A ) (B ) ... (C )) + ) + macro-expands into + ((LAMBDA (A B ... C) ) + ... ) + In certain arcane instances, one wants a sequential binding, rather + than the parallel binding that occurs for a multiple-variable LAMBDA; + thus, LET* may be used: + (LET* ((A ) (B ) ... (C )) + ) + macro-expands into + ((LAMBDA (A) + ((LAMBDA (B) + ... + ((LAMBDA (C) + ) + ) + ... ) + ) + ) + In all other respect, however, LET* is similar to LET. One + especially useful feature which the MACLISP macro for LET has is + that of "pattern decomposition": a general data pattern may be used + in each place where a variable is expected; and for each combination + of data-accessing functions which access a non-null symbol in the data + pattern, there is set up a binding between that symbol and the same + data-accessing path applied to the "argument" expression (that is, + one of the ). Thus nullist in a pattern means "ignore". A simple + example should suffice, but also a BNF description is given. + (LET ( ((A . B) ) + ((() C () D) ) + (TEMP1) + TEMP2 ) + ) + expands into something that operates like + ((LAMBDA (G0001 G0002 A B C D TEMP1 TEMP2) + (SETQ A (CAR G0001)) + (SETQ B (CDR G0001)) + (SETQ C (CADR G0002)) + (SETQ D (CADDDR G0002)) + ) + () () () () () () ) + Just exactly what code comes out of the LET macro depends on many + things, but the intent is to "decompose" the argument, according + to the structure of the pattern of variables, and bind the variables + correspondingly. + DESETQ is similar, but there is no "binding" involved - only + "set"ing. For example, + (DESETQ (A . B) (MUMBLIFY)) + might become + ((LAMBDA (G0001) (SETQ A (CAR G0001) B (CDR G0001))) (MUMBLIFY)) + When compiled, the extra variable G0001 may not cause any noticeable + slowdown in the running of such code, but if the item being + destructured is denoted by a variable, then there is no new LAMBDA: + (DESETQ (() C () D) XVAR) + might expand into + (SETQ C (CADR XVAR) D (CADDDR XVAR)) + A given instance of LET or DESETQ usage will be "DISPLACED" or + not depending on the value of the variable DEFMACRO-DISPLACE-CALL; + See 3c below for more information about the use of this flag. + In point of fact, LET is continually being extended to know + about structures other than lists; thus in NIL, one may destructure + thru VECTORs also, and thru a "record" created by the structure + package DEFVST (currently on LIBDOC and LIBLSP). But leaving + aside these more arcane data structure for now, a BNF description + would be + ( LET ( { | ( ) }* ) + { }* ) + where a "" may be a symbol, or the nullist, or any list + (or "vector", or "defvst") structure. Also: + ( DESETQ ) + + 3b) DEFUN&, for maclisp compatibility with the extended DEFUN syntax + of the LISPMachine, using "&OPTIONAL" and "&REST" + Also, note that if DEFUN notices the occurance of any of the + keywords &OPTIONAL, &REST, or &AUX in the defining arglist, the + the form is automatically turned into a DEFUN& (which may have + to be autoloaded). This way, it will appear that MACLISP + supports the extended syntax. Let an "" be defined + by BNF as follows: + ( {}* { &OPTIONAL { | ( ) }* } + { &REST } + { &AUX { | ( ) }* } ) + Then the extended DEFUN syntax is defined by + ( DEFUN { | ( ) | ( ) }+ + { EXPR | FEXPR | MACRO | | } + { | () | } + { ( DECLARE { }* ) | | } + { }* ) + + Note that this allow pattern decomposition at each argument + position of a function definition; if a single symbol, say + occurs in the optional list, it is treated as if it were of the + form "( () )" - this way there is no ambiguity caused by + the permission of s in the optional list, for the use + of such must be in the default-value-supplied form. Also, the + order of evaluation of the default values for optional arguments, + and of the values for the auxillary variables, is strictly + left-to-right, **after** all the non-optional argument bindings + have been made. Here is an example with a lot of "bells-and-whistles" + just for illustrative purposes: + (DEFUN FOO ( (() NAME VARLIST . BODY) + KIND + &OPTIONAL (PS-FLAG (AND (EQ (CAAR BODY) 'DECLARE))) + ((DNAM . DLST) (AND PS-FLAG (CADAR BODY))) + &REST W + &AUX (N (COND (PS-FLAG 5) (6))) + ) + (WORK-IT-OUT ...)) + Thus FOO requires at least two arguments; and two more will be further + bound, one into PS-FLAG, and the other destructured into (DNAM . DLST) + + 3c) DEFMACRO, MACRO -- macro-producing macros, compatible with LISPM. + Three flags are noticed during instances of the macro expansions: + DEFMACRO-CHECK-ARGS (default = T) + DEFMACRO-DISPLACE-CALL (default = T) + DEFMACRO-FOR-COMPILING (default = T) + The first flag if non-null, produces a macro which checks each + instance of usage for compatible numbers of "arguments"; since this + checking takes time, it may not be desirable in all circumstances. + The second if non-null, produces a macro which calls + DISPLACE in order to displace out the original macro call. + The macros MACRO-DISPLACE and DEFMACRO-DISPLACE exist, just + as in the LISPM, which do not pay attention to this flag, but + rather always yield a product which uses DISPLACE. + The third determines which of the two macro-defining forms + will be used: (DEFUN foo MACRO ...) or (DEFUN (foo MACRO) ...) + If non-null, the latter will be used so that the macro will be + compiled by the compiler (whereas the former format is intended + primarily for macros used interpretively, or as compilation aids; + see 5b below. + DEFMACRO admits a "bound-variable-list" that is reminiscent of + the standard argument-list processing: + ( {}* + {&OPTIONAL { | ( ) }+ } + {&REST } ) + As with DEFUN&, a single symbol, say , in the &optional list + is treated as if it were of the form "( () )", for purposes + of default initializations. + Examples: + (MACRO ERRBRK (X) (COND ((EQ (CADR X) 'BARF) '(ERR)) + (`(PROG2 (PRINC ',(cadr x)) (BREAK ERROR))))) + (DEFMACRO ERRBRK (MSG &OPTIONAL (BKTYPE 'ERROR)) + (COND ((EQ (CADR X) 'BARF) '(ERR)) + (`(PROG2 (PRINC ',msg) (BREAK ,bktype))))) + +4) Better error checking in *RSET mode for functions that cdr down lists: + LAST now gets the last node of a non-atomic s-expression, or () for (). + In *RSET mode, the time is taken to check that no attempt is made + to take the cdr of a non-null atom in the functions + NTH, NTHCDR, APPEND, NCONC, REVERSE, NREVERSE, NRECONC, ASSQ, MEMQ, DELQ + Regardless of the setting of *RSET, the following functions will + not cdr through a non-null atom: + LAST, MEMBER, ASSOC, DELETE, all MAP series. + [In LISP versions prior to about 1783, LAST had the bug that it would + begin cdr'ing down the plist of any symbol at the termination of a + non-standard list - try (LAST '(A . CAR))]. Note however, if any of the + MAP series gets expanded into a DO loop by the compiler, the endtest will + be replaced by NULL rather than ATOM. + + +5) "MACLISP" is now on the feature list, to help distinguish from LISPM. + (STATUS FEATURE LISPM) is non-null for the LISP machine + (STATUS FEATURE MACLISP) is non-null for all PDP10 and MULTICS MACLISPs + (STATUS FEATURE NIL) is non-null for any real or simulated NIL. + +6) COMPLR has some new switches and global variables - EXPAND-OUT-MACROS etc. + 6a) new switch - H for variable EXPAND-OUT-MACROS + Toplevel forms which are not functions to be compiled (or other + wise specially treated by MAKLAP) could be fully macro-expanded + before being output to the FASL file. Normal setting is non-null + meaning to do this expansion. + 6b) repeat of meaning of the M switch - variable MACROS + MAKLAP will not cause the compilation of a form like + (DEFUN MACRO () ...) when it is processing a file, + for it assumes that this macro is only for aid during compilation. + If MACROS is non-null, it will also output an expr form for such + a macro into the FASL file. Remember that if the definition is like + (DEFUN ( MACRO) () ...), then the compiled version of the + macro will always be output. In either case, COMPLR remembers the + expr definition for use during the subsequent parts of the file. + 6c) new variable - MAKLAP-DEFAULTF-STYLE + The command line read maklap usually consists of two file specs + separater by a left-arrow (underscore in new ascii); the filling + in of the unspecified components of a file spec can be done either + from the accumulated left-to-right mergeing, or begin separately + for input and output file specs. MIDAS style is the former, and + the value of this new variable either is MIDAS or (). + 6d) when making up, can set feature NO-EXTRA-OBARRAY + (SSTATUS FEATURE NO-EXTRA-OBARRAY) will permit CCLOAD to make + up a compiler without the COBARRAY/CREADTABLE which separates + user environment from compiler environment. If saving about 1.5K + or so words means that much to you, and taking a chance means + very little . . . + +7) SUSPEND - review of meanings of arguments + [Original information in the LISP NEWS file, under dates + 5/22/74 JAN 13,1978 June 14,1978 ] + If no arguments are given, then a return to monitor is preceeded by + the message ";$Suspended$" (in ITS, it is ":Suspended", and those + are alt-modes rather than dollar-signs). + First arg - string for printing to exec; null; or (on ITS) small fixnum. + Ordinarily, when the suspended LISP returns to the monitor, it + will print the message ";$Suspended$", but a non-null symbol will + be printed instead; null means continue immediately, possibly after + dumping out into the file specified by the second argument. + For ITS system, the message printed out will be executed by DDT, just + like a string to VALRET; if the argument is a fixnum, it will be + taken as the value to put in the right half of a .BREAK 16,. + Second arg - file name in which to dump the pure parts of the system + For ITS system, the job is PDUMPd, with an "indirect" symbol table; + the pages shared with the system-dumped TS LISP are not dumped + if (STATUS FLUSH) is non-null. Since a LISP tries to share its + read-only pages with the system-dumped TS LISP, the only reason + for allowing them to be copied out into the dump'd file when + SUSPENDing is the fear that the system-dumped TS LISP may + inadvertently disappear off the file system. + For TOPS-10 systems (and SAIL), the high segment of a two-segment + job is dumped into this file; one must still type a SSAVE (or + or SAVE) at the monitor in order to dump the low segment. But + if (STATUS FLUSH) is non-null, then no dumping of the high + segment occurs, and it is flushed before returning to the monitor, + so that when the dumped low segment is re-activated, it will try + to retrieve the high segment associated with the original + LISP.SHR file. Caution! As of Jan 1979, there may still be + bugs in the non-its version of SUSPEND. + +8) Under the ITS operating system, a JCL line with only a means don't + use any INIT file, even if the connected directory has one. This may + be extended to the TOPS versions also. + +Thursday Oct 12,1978 FQ+3D.8H.53M.53S. COMPLR 834 - JONL - + + +[1] New command line switch "Y", causes all warning and error + messages to appear on the TTY. A summary of conditions for + compiler messages appears below. +[2] OBARRAYs revisited: SOBARRAY and COBARRAY, also SREADTABLE + and CREADTABLE. +[3] Functional variables are no longer supported. "V" switch is gone. + You will have to use FUNCALL if that's what you want. Beware. + + +_________________________________________________________________________ + + +[1] New command line switch "Y", causes all warning and error + messages to appear on the TTY. A summary of conditions for + compiler messages appears below. + The "Y" switch controls the variable YESWARNTTY; if the "T" + switch has been specified, it too will set YESWARNTTY on. Default + setting for all switches is "off", except "F", "K", "O", and "U". + The "U" switch primarily controls the printing of the assembler's + commentary into the unfasl file; warning messages and error messages + from either the compiler or assembler will be put into the unfasl file + (as well as into any file on the list CMSGFILES, which is initially null), + and will also be printed on the TTY if YESWARNTTY is non-null. If nothing + other than the header gets put into the unfasl file, it will be deleted. + If no fasl file is being produced (only the lap file is being generated), + then the warning and error messages will be put into the lap file. + The format of commentary in the UNFASL file is: + 1) A header of three lines with source file name, assembler version + number, and compiler version number, and (optionally if available) + a line with the date and time of compilation. + "'(THIS IS THE UNFASL FOR (fn1 fn2 dev usr))" + "'(ASSEMBLED BY FASLAP /nnn)" + "'(COMPILED BY LISP COMPILER /nnn)" + ";COMPILED ON WEDNESDAY, OCTOBER 11, 1978, AT 12:49 PM" + 2) "(COMMENT **** " begins a warning message + 3) "(COMMENT **ERROR** " begins an error message + 4) " (COMMENT **FASL** " begins a comment from the assembler + 5) "(COMMENT " begins users COMMENTs, which are added + to the unfasl file + + + + switches | warnings | errors | run break-loop | notifications + T Y G | to TTY | to TTY | if find errors | to TTY + ________________|__________|________|________________|______________ + off off off | no | no | yes | no + off off on | no | no | no | no + off on off | yes | yes | yes | no + off on on | yes | yes | no | no + on off off | yes | yes | yes | yes + on off on | yes | yes | no | yes + on on off | yes | yes | yes | yes + on on on | yes | yes | no | yes + + + + + +[2] OBARRAYs revisited: SOBARRAY and COBARRAY, also SREADTABLE + and CREADTABLE. + SOBARRAY is a global variable which holds the + obarray containing the compiler functions; COBARRAY holds the + user's functions. It is possible to create a COMPLR that has + only one obarray (normally there are two - one for the compiler's + functions, and one for the users') if at creation time before + fasloading the COMPLR, one does (SSTATUS FEATURE NO-EXTRA-OBARRAY). + Both obarray names - COBARRAY and SOBARRAY - are on both obarrays; + so it is an easy matter to switch obarrays - just do + (SETQ OBARRAY SOBARRAY) or (SETQ OBARRAY COBARRAY) + COBARRAY is made current after quitting to LISP toplevel (such as + by typing ^G), so that complr functions will not interfere with use + of CHOMP. Also CREADTABLE is allied with COBARRAY in the attempt + to separate user-specific syntax from the standard LISP syntax. + Both names CREADTABLE and SREADTABLE are on both obarrays. + + +Friday Oct 6,1978 NM+4D.11H.46M.53S. LISP 1747/1750 -HIC, JONL- + +Changes affecting all LISPs: +[1] COMPLR now supports the new CATCH-like functions, + and in-core compilation with the function CHOMP +[2] New OPEN option: NODEFAULT + + +Changes affecting ITS LISP: +[A] New INIT file scheme supported + +---------------------------------------------------------------------- + +Changes affecting all LISPs: + +[1] Compiler support for the new catch-style functions (UNWIND-PROTECT, + *CATCH, *THROW, CATCHALL, and CATCH-BARRIER) is in compiler version 828 + which is being released synchronously with LISP 1747. + A new function in the COMPLR, "CHOMP", is from LIBLSP;CHOMP FASL. + (CHOMP FUN1 FUN2 . . . FUN-M) + will compile and asemble, in-core, all the m functions named, making the + SUBR [or FSUBR] property to preceed the old EXPR [or FEXPR] property on + the property list. Thus the compiled version will be current, but the + EXPR version may be restored by REMPROPing the compiled marker. + (CHOMP (FN1 FN2 DEV USR) FUN1 FUN2 . . . FUN-M) + will do the same as above, but will also produce a file of FASL code named + DEV:USR;FN1 FN2 + +[2] New OPEN option: NODEFAULT + Normally, OPEN merges the user given filespec with the default filespec. + Since * means omitted component, a file with a * in its name could not + be looked up. To prevent merging with defaultf, and thereby allowing + filenames with *'s to be looked up, use the NODEFAULT flag in the options + list. + + +Changes affecting ITS LISP: +[A] New INIT file scheme supported by LISP. The new release of DDT (currently + on MC, soon to be on all machines) supports a new style of INIT file + as well as sophisticated HSNAME hackery. LISP now has support for both + of these features. + (STATUS HSNAME) returns your current HSNAME (home directory, where all + init files and your mail live) + This is the same as (STATUS HOMEDIR) + (STATUS HSNAME foo) returns foo's home directory ("foo" is evaled) + (STATUS HSNAME foo its) returns foo's home directory on the specified + ITS ("foo" and "its" are evaled) + (STATUS XUNAME) returns your XUNAME (his "real" name, possibly with + trailing digits removed). This is the same + as (STATUS USERID), but is included for + compatibility with ITS names for things. + + The algorithm for interpreting the JCL line and for finding init files for + LISP jobs is as follows: + A) No JCL, look for ; LISP, if not found try + ;* LISP + B) JCL of the form: + foo; look for foo; LISP, if not found try + foo;* LISP + fn1 look for ;fn1 > + fn1 fn2 look for ;fn1 fn2 + foo;fn1 look for foo;fn1 > + for COMPLRs, it is similar: + look for ; COMPLR, if not found try + ;* COMPLR + + + +Sunday Sept 17,1978 FM+11H.57M.58S. LISP 1742 -HIC, JONL- + +Changes affecting all LISPs: +[1] New autoloadable interpreter macros: backquote ("`") and LET. +[2] New functions: NTH, NTHCDR, and LIST* +[3] *THROW, *CATCH, CATCHALL, CATCH-BARRIER, and UNWIND-PROTECT. +[4] SFA's (Software File Arrays) are implemented; see below. +[5] DISPLACE now treats atomic arguments differently. +[6] Minor changes to treatment of bound-variable lists. + NIL is now ignored if used as a variable in bound-variable-lists. + PROGV with more variables than values will make the extras "unbound" +[7] OPEN now complains about illegal keywords +[8] The null pname now prints as || +[9] New features: SFA, EXPERIMENTAL + +Changes affecting ITS LISPs: +[A] Planned move of autoloadable system files from COMMON; to LISP; +[B] PURE now defaultly 1 +[C] Arg to TTY-RETURN function is now meaningful + +Changes of interest to LISP internals hackers: +[{] There is now a way, using some LAP or MIDAS code, to handle IOC errors + +Compiler changes: +[i] The name "QCOMPLR" replaced by "COMPLR" +[ii] COMPLR will now try to fully macro-expand any toplevel form. +[iii] More on COMPLR command line switch settings, and on error messages. +[iv] New names used for temporary files usage during compilation. + You may find FOO _FASL_ and FOO _UNFA_ while producing FOO FASL. + + +---------------------------------------------------------------------- + +Changes affecting all LISPs: + +[1] New autoloadable interpreter macros: backquote ("`") and LET. + The "backquote" macro and the LET macro will be autoloaded when used. + The backquote macro allows generation of quoted structure with + evaluated inserts, and is compatible with the LISP Machine's version. + A "," within a backquote indicates evaluation of the next s-expression, + and ",@" indicates not only evaluation but also that the resultant form is + "spliced" into the surrounding list. + For example: + `(A B ,(+ 1 2)) reads in like (CONS 'A (CONS 'B (CONS (+ 1 2) 'NIL))) + which when evaluated generates (A B 3) + `(A B ,@(LIST 1 2)) read in like + (CONS 'A (CONS 'B (APPEND (LIST 1 2) 'NIL))) + which when evaluated generates (A B 1 2) + One can imagine how especially helpful this will be in writing definitions + of MACROs. + The LET macro provides a convenient way to lambda-bind variables to + values. Its usages is as follows: + (LET ((var1 val1) (var2 val2) . . . (varn valn)) + + . . . + ) + One may substitute merely "var" in place of "(var NIL)" + For example: + (LET ((A 1) (B 2) C) + ) + Binds A to 1, B to 2, and C to NIL and then evaluates . + An extension to the binding of one variable, is a "pattern" of + variables, which are bound to the corresponding subparts of the + "val"; e.g., (LET ( ((A . B) '(CONS 1 2)) ((C () D) (LIST 1 2 3))) + ) + would bind A to "CONS", B to "(1 2)", C to "1", and D to "3". + There is an attempt by the LET macro code to optimize the destructuring + operations of CAR and CDR over the original value. + +[2] New functions: NTH, NTHCDR, and LIST* + For cdr'ing down a list, using 0-origin indexing, use NTHCDR and NTH: + (NTHCDR 0 x) is just x, and (NTHCDR n+1 x) is (CDR (NTHCDR n x)) + (NTH n x) is the same as (CAR (NTHCDR n x)) + For compound constructions using CONS, use LIST* as if it were an + LSUBR version of CONS. For example, + (LIST* . . . ) evals like + (CONS (CONS . . . (CONS ) . . . )) + + +[3] *THROW, *CATCH, CATCHALL, CATCH-BARRIER, and UNWIND-PROTECT. + For compatibility with the new format of CATCH and THROW in the + LISP Machine, and in NIL, we are introducing *THROW and *CATCH. + Please use these, and sometime in the future, CATCH and THROW in + PDP10 MACLISP may be changed also. It is recommended that old code be + converted to *CATCH and *THROW. + (*CATCH e1 e2 ... e) + Forms e1 through e are evaluated, returning the last as the + value of the CATCH, unless a THROW (or *THROW) occurs whose tag matches + the value of during the sub-evaluations; then the value of + the catch is the value from the THROW. Note that is evaluated + first. + (*THROW ) + Both and are evaluated as in normal SUBR control, + and a control-chain break-up is initiated, passing along both + values; at some higher level, the break-up will be "caught". + If the "catching" is by CATCH, then the value of is + passed to CATCH; if by CATCHALL, the both values are passed (q.v.). + (CATCHALL e1 e2 ... e) + Has same semantics as CATCH, except that if **any** THROW occurs + during the sub-evaluations, then the value of the CATCH is obtained + by applying the value of to the throw value and throw + tag. E.g. + (CATCHALL '(LAMBDA (TG VAL) + ;Note that for some tags, the throw is + ; repeated, so that the CATCHALL acts as + ; if it in fact ignores that THROW. + (COND ((MEMQ TG '(TOPLEVEL BREAK)) (THROW VAL TG)) + ((OR STOPP (EQ TG 'FOO)) (THROW VAL 'FOO)) + (#T VAL))) + (SETUP 25) + (RUNLIKE ABAT)) + (CATCH-BARRIER e1 e2 ... e) + Has the same syntax as CATCH, and more or less the same semantics, but + if a thrown tag is not in the tag-list, then the THROW that threw it + goes into an unseen-throw-tag error. The idea is that searching does + not proceed back up the stack beyond this point; whereas if a THROW of + a tag is not caught by a particular CATCH, then tag searching continues + back up to the stack above the CATCH. + + (UNWIND-PROTECT u1 u2 ... u) + The form will be evaluated, but if the stack is "unwound" past + the point of the UNWIND-PROTECT for ANY REASON, + then the unwinder must cause the evaluation, in order, + of u1 through u in the environment that obtains by first + unwinding to the stack point of the UNWIND-PROTECT; then the + unwinding may continue. If terminates normally, then + the value will be that obtained from , but the forms u1 + through u will be evaluated also. The intent is + that the operation of will do some things that need to be + undone after sucessful completion, but which can not be undone + merely by lambda-binding (eg, closing an opened file). Thus any + aborting of the evaluation of will not leave undesired states + hanging around. Before the u's are run, NOINTERRUPT is set to + T, so that asynchronous conditions cannot cause premature termination + of the handlers. It is restored to its previous value upon + completion of the u's. If a THROW is done, the user must reset + NOINTERRUPT to the value he wishes it to be! The UNWIND-PROTECT + frame is removed from the stack BEFORE the u's are run so that + they may freely do THROWS (et al.). + +[4] SFA's (Software File Arrays) are implemented. As the documentation on + these are lengthy and is subject to change, please check the file + LISP;SFA > for the latest information. + +[5] DISPLACE now treats atomic arguments differently. + Its definition is now like: + (DEFUN DISPLACE (X Y) + (AND (ATOM X) (ERROR '|-- not a list. (DISPLACE)| X)) + (COND ((ATOM Y) + (RPLACA X 'PROGN) + (RPLACD X (NCONS Y))) + (T (RPLACA X (CAR Y)) + (RPLACD X (CDR Y))))) + +[6] Minor changes to treatment of bound-variable lists. + NIL is now ignored if used as a variable in bound-variable-lists. + PROGV with more variables than values will make the extras "unbound" + For example ((LAMBDA (A () B) (LIST A B)) '1 '2 '3) ==> (1 3) + All of "'1", "'2", "'3" are evaluated, but there is no binding to NIL. + And (PROGV '(A B C) '(1 2) (LIST A C)) will generate an UNBND-VRBL error. + A binding is actually provided for "C", but it is the internal + "UNBOUND" marker which the interpreter catches. + +[7] OPEN now complains about illegal keywords in the modelist. + Thus, (OPEN '(FOO BAR) '(OUT MUMBLE)) will cause an error, of the + WRNG-TYPE-ARG variety. + +[8] The null pname now prints as ||, rather than not printing at all. + GRINDEF has been changed to return an asterisk. + +[9] Two new possible feature names have been added. SFA is in the feature list + if the LISP contains SFA's, and EXPERIMENTAL is in the feature list if the + LISP is considered experimental. + + +Changes affecting ITS LISPs: + +[A] There is a planned move of autoloadable system files from COMMON; to LISP;. + Links will be left from COMMON; to LISP; for some period of time and then + those links will be flushed. All new autoloadable files will go on LISP;. + Please modify any programs that explicitly look on COMMON; for autoload + files to look on LISP; + +[B] The value of PURE now defaults to 1. Since with the new UUOLINKS scheme, + uuolinks segments are added dynamically, there is only a minor loss of core + when PURE is non-NIL. It is still possible to set PURE to NIL before + FASLOADING any files thus not using any extra core at all. + +[C] The arg given by LISP to the TTY-RETURN function is now meaningful. + If it is the atom IN, then LISP is hanging in one of the canonical input + waits. If the LISP was not in one of the input waits, then a value of + NIL is supplied as the argument. + + +Changes of interest to LISP internals hackers: + +[{] There is now a way, using some LAP or MIDAS code, to handle IOC errors. + The user must put an instruction to XCT in IOCINS. If LISP does not + know about the PC of the IOC error (it currently does not know about + any IOC errors), then the user's instruction gets XCT'ed with the PC + of the error in AC R, and the error code in AC D. The user's routine + must not change any AC's other than R and D, though the stacks may be + used. If the XCT'ed instruction skips, the right half of R must have + been set up by the user to be the PC to dispatch to after leaving interrupt + level, and the left half of R to 400000+. + + +Compiler changes: + +[i] The name "QCOMPLR" replaced by "COMPLR" + The names "QCOMPLR", "QC", "NCOMPLR" and "N" (as well as all + the "old" versions like "OQCOMPL") have been superseded + by "COMPLR" and "CL" (and "OCOMPL" and "OC"). There will no + longer be provided support for oldio compilers. + +[ii] COMPLR will now try to fully macro-expand any toplevel form. + Any form in a file that the compiler would normally just pass on + through to the FASL file will now be fully macro expanded, in that + a "pseudo-compilation" phase is done on it to expand macros. + +[iii] More on COMPLR command line switch settings, and on error messages. + A review of the current command line switches, and their meanings: + + letter | variable name | meaning + ---------------------------------------------------------------------- + A ASSEMBLE Source is to be assembled only (generally used + on a file of LAP code - see "K" switch below) + C CLOSED Generic arithmetic functions are not open-coded + D DISOWNED Run the compilation disowned + E EXPR-HASH Output the EXPR-HASH properties in the FASL + F FASL Compile and produce FASL file (normal mode) + G GAG-ERRBREAKS Don't go into break loop when finding bad data + K NOLAP Don't write a LAP file, or if "A" switch is on + kill the "LAP" file (which may be source file) + M MACROS Output MACRO defunitions to FASL file + O ARRAYOPEN Open-code the array-accessing (no error + checking in the open-coded variety) + S SPECIALS Treat all variables as if declared SPECIAL + T TTYNOTES Prompt notes and warning msgs go to TTY + U UNFASLCOMMENTS A file (second name UNFASL) of messages will be + produced; warnings, errors, comments, etc. + W MUZZLED Don't inform about failure to open-code generic + arithmetic functions + X MAPEX Open-code all MAP type functions + Z SYMBOLS Assembler symbol definitions go out to FASL + + FIXSW All generic arithmetic is FIXNUM only. + $ FLOSW All generic arithmetic is FLONUM only. + + In an initialized COMPLR, only the F, K, O, U, and V switches are "on", + and all others are "off". They may be set by explicit lisp code in which + a non-null value for the "variable-name" means "on", or by the appearance + of the "switch-letter" between parens in the command line. + + More of an attempt is being made not to let error msgs clog up the TTY. + Warning msgs will be printed on the TTY only if TTYNOTES is non-null, + and error breaks on erroneous-looking input data will be run only if not + disowned and GAG-ERRBREAKS is null (default state of each variable is null) + + +Wednesday June 14,1978 FQ+1D.8H.19M.18S. LISP 1633 -HIC- + + +Changes that affect ITS NEWIO: +[A] SUSPEND's second arg is now meaningful on ITS +[B] CURSORPOS' returned value is now meaningful +[C] SACONS added to XTRSYMS for graphics hackers +[D] Fixnum has meaning as first arg to VALRET/SUSPEND +[E] (STATUS CLI) and (SSTATUS CLI) added to enable/disable CLI interrupts + +Changes that affect all LISPs: +[1] PUSH, POP, and DISPLACE FEXPR's in interpreter +[2] SETPLIST returns its second arg +[3] (STATUS FASLOAD) returns the file-object of the file currently being loaded +[4] One final word on hairy defun +[5] New meaningful value of *PURE: SYMBOL (doesn't cons pure SY2) + +Changes of interest to LISP internals hackers: +[!] Internals hackers take note: XPURIFY +------------------------------------------------------------------------------ +Changes that affect ITS NEWIO: +[A] SUSPEND's second arg is now meaningful on ITS. If the second argument to + SUSPEND is given, it is interpreted as a filename in which to pdump the + LISP. An indirect symbol-table pointer is dumped (thus saving disk space) + and the setting of (SSTATUS FLUSH x) is obeyed. + +[B] CURSORPOS' returned value is now meaningful. If the value is T, then the + operation was sent to the terminal and had some affect (the appropriate + ^P code is sent, though ^PC on a printing terminal does not actually + clear the 'screen'.). If the value is NIL, then the ^P code was not sent + and therefore nothing was done. The current setting of the TTY is looked + at and a table internal to LISP is used to determine applicability. + +[C] The symbol SACONShas been added to XTRSYMS for use by graphics hackers. + This change, along with the previous change in GETDDTSYM, obviates the + need for graphics users to load symbols. + +[D] A fixnum as the first argument to VALRET/SUSPEND is interpreted as the + value to put in the right half of a .BREAK 16,. + +[E] (STATUS CLI) and (SSTATUS CLI) have been added to enable/disable CLI + interrupts. Unlike before, CLI interrupts are defaultly OFF [(SSTATUS + CLI NIL)]. Therefore, people setting CLI-MESSAGE must do an (SSTATUS + CLI T) in order to actually recieve the interrupts. + + +Changes that affect all LISPs: +[1] PUSH, POP, and DISPLACE in interpreter: + FSUBR: (PUSH X L) ==> (SETQ L (CONS X L)) + FSUBR: (POP L) ==> (PROG2 () (CAR L) (SETQ L (CDR L))) + FSUBR: (POP L X) ==> (PROG2 () (SETQ X (CAR L)) (SETQ L (CDR L))) + SUBR: (DISPLACE X Y) ==> (PROGN (RPLACA X (CAR Y)) (RPLACD X (CDR Y)) X) + +[2] SETPLIST returns its second argument. + +[3] (STATUS FASLOAD) returns the file-object of the file currently being + loaded. + +[4] The one final word on hairy defun is that the first atom in a DEFUN is + ALWAYS interpreted as the function name. Therefore: + (DEFUN MACRO FEXPR ...) + defines a FEXPR called MACRO, and not vice-versa. + +[5] New meaningful value of *PURE: SYMBOL. If *PURE contains SYMBOL then + everything EXCEPT symbols will be pure-consed. THis was added for + use in a new Macsyma loader, and may not be of general use. + + +Changes of interest to LISP internals hackers: +[!] Internals hackers take note: XPURIFY has been added as an alternaate entry + to the PURIFY routine. If you XPURIFY$G, then the LISP will expect itself + to be :PDUMP'ed to LISP;PURQIX nnnn instead of SYS;PURQIO nnnn. This is + usefull for creating experimental LISP versions. + +THURSDAY MAY 25,1978 FM+3D.8H.53M.31S. NCOMPLR 769 -JONL- + +Finally! A new QCOMPLR is out, which corrects many bugs noted during +the past year, and implements several new features. + +[1] Many calls to CONS, LIST, NCONS, XCONS, etc are now coded as fast + JSP-type subroutine calls. These calls cannot be linked-up in + LISPs prior to version number 1493. +[2] The version number of the compiler is kept in the global variable + COMPLRVERNO; this used to be "INIT1". Recall that the FASLAP version + number is in FASLVERNO. +[3] There is no longer any NOARGS feature, nor ARGSP functional; if you + don't know what this means, don't worry about it. +[4] A list of all the compiler-command-line switches is kept in the global + variable SWITCHTABLE along with standard settings, which have been + changed to (FKOUV). This means that normal operation is to compile a + file, producing a FASL output and UNFASL comments file, but no LAP. + The "I" switch now permits specifying a file to be loaded just after + the normal compiler initialization routine is done +[5] Several standard macro definitions have been added, as well as a + macro expander for CASEQ. (See the LISP RECENT note of Jan 26, 1978, + for syntax of CASEQ. Also, see below.) The new macros are + PUSH, POP, LET, and DISPLACE. +[6] A new feature has been added for load-time evaluations (that is, + at fasload time), dubbed SQUID for "Self-QUoting Internal Datum". + The value of the symbol SQUID, in the compiler, is an atom specially + reserved for this purpose, which is used much like the atom QUOTE. +[7] Many old bugs have been fixed, probably too many to enumerate + individually; but we could mention specifically + [7a] (DEFUN (FOO MUMBLE) . . .) + (DEFUN (FOO GHAST) . . .) will now correctly define + these two pseudo functions. + [7b] CGOL files should compile ok now. + [7c] Error messages come out on the TTY if so requested. + [7d] The error signalled by "NO FREE REGACS" should go away. + [7e] Some cases of incorrect code output have been fixed. +[8] A top level call to LAP-A-LIST with a quoted argument is specially + recognized and treated as if it were a standard LAP call. + +____________________________________________________________________________ + + + +[4] A list of all the compiler-command-line switches is kept in the global + variable SWITCHTABLE along with standard settings; The format is + ((A ASSEMBLE NIL) ... (Z SYMBOLS NIL)) + Each item in the list is a 3-list: a letter used as the switch request + in the command parser, a variable name used as the global variable + holding the value of the switch, and an initial setting. Only about + 15. letters are currently in use, so the user could add to this table + if he would like to set up some switches of his own. SWITCHTABLE starts + out sorted alphabetically by switch-letter, and if you want to see a list + of all letters currently in use, do (MAPCAR 'CAR SWITCHTABLE). Note well, + that the INITIALIZE function resets the switches to their initial values. + The standard switch settings have been changed to (FKOUV), which + is to say that normal operation is to compile a file, producing + a FASL output and UNFASL comments file, but no LAP. Furthermore, + annotations to the TTY are not requested, and the V switch is in + cooperation with the recently announced non-feature, the dropping of a + certain evaluator anomaly destribed under (STATUS PUNT). + If the "I" switch is specified, it means "do a standard initialization + before compiling another file"; this is often helpful when several files + are being used as sources for the compiler. A problem arises however + because this initialization will remove MACRO properties, and other + properties put on symbols by DECLARE; thus if a user has a file with + all the necessary actions in it, he may specify that that file be + LOADed just after the initialization by placing the file namestring + between square brackets, just after the "I". E.g., + FOO FASL_FOO >(TWI[usr;CMPSET >]) + +[5] Briefly, CASEQ looks like + a kind of cond, in which one item is evaluated, and the remaining + items are like COND clauses; the predicate test at each clause is + essentially MEMQ of evaluated item and list at first of clause. + The item must be either a SYMBOL or a (non-BIGNUM) number; the + various keys in the clause-lists must be then either all symbols, + or all fixnums, or all flonums. Two exceptions are added for + convenience: If a clause has an atom as its first element, then + it is interpreted as if it were a singleton list of that atom, + except that if such atom is the symbol T, then that clause + unconditionally succeeds. Example: + (CASEQ (COMPUTATE-VAL) + ((3 5 7 11. 13. 17. 19.) 'PRIME) + (1 'UNITY) + ((2 4 8 16.) 'TWO-POWER) + (T 'RANDOM)) + + The others expand as follows: + (PUSH X L) ==> (SETQ L (CONS X L)) + (POP L) ==> (SETQ L (CDR L)) + (POP L X) ==> (SETQ X (PROG2 NIL (CAR L) (SETQ L (CDR L)))) + (LET ((V1 E1) (V2 E2) . . . (VN EN)) F1 F2 . . . FK) + ==> + ((LAMBDA (V1 V2 . . . VN) + F1 F2 . . . FK) + E1 E2 . . . EN) + DISPLACE is intended for use as a macro-displacing function; + thus if (DEFUN FOO MACRO (X) (MUMBLE X)) is a macro definition, + then (DEFUN FOO MACRO (X) (DISPLACE X (MUMBLE X))) will cause + the macro call to be displaced by its code after the first + expansion. + +[6] SQUID Feature Test Module + + (DECLARE (SETSYNTAX '/% 'MACRO '(LAMBDA () (LIST SQUID (READ)))) + (SPECIAL FIRSTVAR SECONDVAR)) + %(+ 1 2) + (SETQ FIRSTVAR %(+ 1 2)) + '(A %(+ 1 2) B) + (SETQ SECONDVAR '(A %(+ 1 2) B)) + (DEFUN MACFUN MACRO (FORM) %(+ 3 4)) + (DEFUN TESTFUN () (LIST (MACFUN) %(+ 5 6) '(A %(+ 7 8)))) + + Notice how the read-macro gives the impression of designating a + subexpression, even of a quoted form, to be evaluated at load time. + Note also, how SQUID at top level acts like QUOTE. + + +Monday, May 15,1978 FQ+18H.41M.47S. LISP 1578 --GLS, HIC, JONL-- + +Changes that affect all LISP's: +[A] The result of (STATUS SYSTEM foo) contains SYMBOL if foo is a system symbol +[B] FLONUM's are allowed in the ALLOC function but not in the INIT file +[C] Changes to purification in general (**PURE SYSTEMS BUILDERS TAKE NOTE**) +[D] New version of the TRACE package +[E] GETDDTSYM checks LISP's built-in table before looking at the symbol table +[F] Two hooks into toplevel/break READ-EVAL-PRINT loop +[G] More information on the LENGTHF function (NEWIO only) +[H] CNAMEF: semi-new undocumented function now being documented + +Changes that affect ITS LISP's: +[1] FLUSH status option allows removal of LISP's pure pages on a suspend +[2] Changes to UUOLINKS segments allows them to be extendable +[3] .XUNAME now used to find INIT file + +An inquiry: +[!] Which is more useful: (STATUS SEGLOG) or (STATUS SEGSIZE) + +Items of interest to LISP internals hackers: +[{] More symbolic definitions +[|] New SY.OTC bit in SY2 +[}] Internal purification changes + +------------------------------------------------------------------------- +Changes affecting all LISP's: + +[A] The result of (STATUS SYSTEM foo) contains SYMBOL if foo is a system + symbol. Previously, (STATUS SYSTEM 'LAMBDA) would return nil, and this + was clearly wrong. Therefore, in addition to anything else that was + previously returned by this STATUS function, SYMBOL will be returned for + all symbols in the initial system. + +[B] FLONUM's are allowed in the ALLOC function but not in the INIT file. + Previously FLONUM's were allowed only as the last of the set of three args + for each space. The restriction of not allowing flonums in the INIT + file is that at the time the INIT file is read, no FLONUM consing is + allowed. If you do use FLONUM's in the INIT file comment, you will find + that the LISP will get a fatal error. + +[C] Changes to purification in general (**PURE SYSTEMS BUILDERS TAKE NOTE**): + There have been several changes to the purification scheme that make it + more consistent, and apparently more correct. Previously, COPYSYMBOL would + return a pure symbol if *PURE was non-nil, now COPYSYMBOL always returns + an impure symbol. In earlier LISP's, all symbols consed while *PURE was + non-nil would go into pure space. This included things like GENSYM's. + Now, only INTERN'ed symbols (such as produced by READ) will be purified. + PURCOPY on a symbol now purifies as much of the symbol as possible, whereas + previously only the PNAME was purified. These changes, along with the + corresponding internal changes, seem to be effective in producing more + correct purification actions. For example, MACSYMA and NCOMPLR have been + observed to get smaller due to less garbage collectable stuff being consed + in pure space. + +[D] A new version of the TRACE package has been installed. The fasl for old + Trace is Comlap;Trace Ofasl. In new Trace, there is a way to trace a + macro as if it were a function: + + (Trace (Macr Macroval)) will give the same Entry print, but on Exit prints + the final result (after Eval) of the Macro-call. You can also trace the + old way with a regular Trace call without interfering with this + (misfeature?). Currently, Macroval doesn't do error-checking, so + (Trace (Cons Macroval)) will screw up. + +[E] GETDDTSYM checks LISP's built-in table before looking at the symbol table. + This should allow people building systems that GETDDTSYM common symbols + to not have to load all the symbols into their DDT, and should also allow + Tops-10 GETDDTSYM to win in more cases. + +[F] Two hooks into toplevel/break READ-EVAL-PRINT loop: + The two symbols READ-*-EVAL-PRINT and READ-EVAL-*-PRINT allow intercepting + the read-eval-print loop in the position indicated by the *. The symbols + should be bound to the name of the function to be invoked. Each is a + function of one argument, and the value returned is used in lieu of the + function's argument (which would normally be passed on to the next + function in the loop). The functions are run both at top level and at + break level. + +[G] More information on the LENGTHF function (NEWIO only) + It has been brought to our attention that the description of the LENGTHF + function was lacking. The value returned by the LENGTHF function applied + to a file-object is the length in 'bytes' of the file. The byte size + is determined by the mode the file was opened in. For ASCII mode, the + byte size is 7, and for FIXNUM mode the byte size is 36. Therefore, for + FIXNUM files, the value returned is the size of the file in words, which is + 5 times less then the size of the file in characters. Note that this value + is also the highest value that may be used as an argument to FILEPOS for an + input file. + +[H] CNAMEF: semi-new undocumented function now being documented + (CNAMEF ) replaces the filename in the + closed file-object by the filename specified in the second argument. This + is useful if the creation of extra file arrays is either not desirable or + possible. + + +Changes that affect ITS LISP's: + +[1] The FLUSH status option allows removal of LISP's pure pages on a suspend. + If a (SSTATUS FLUSH T) is done before a SUSPEND, LISP will flush its pure + pages from its page map before returning to DDT. This saves about 28 pages + in a PDUMP'ed file. NOTE THAT USING THIS OPTION REMOVES SOME ROBUSTNESS + FROM YOUR SAVED SYSTEM!!! + +[2] Internal changes to the UUOLINKS segments allow them to be extendable. + In older LISP's, the value of PURE was taken to be the number of pages to + be allocated to the UUOLINKS area. Now, the value of PURE is ignored and + as long as it is a FIXNUM, UUOLINKS are allocated segment by segment when + new segments are required. Note that UUOLINKS segments may now be added + even after a system has been purified thus allowing multi-level pure + systems to be built up. + +[3] The XUNAME is now used to find the default INIT file. Formerly, the SNAME + was used, but this was inconsistent with the function of other programs. + Now, $$^S will affect the place that files are defaultly read from, but + NOT from where INIT files are read from, whereas $^S can be used to change + the source of INIT files, but not the default directory. + + +An inquiry: + +[!] Which is more useful: (STATUS SEGLOG) or (STATUS SEGSIZE)? + Currently, (STATUS SEGLOG) returns the log base 2 of the segment size. + We postulate that the actual segment size is more useful, and therefore + are considering removing SEGLOG in favor of SEGSIZE. Are there any + opinions on this matter? + + +Items of interest to LISP internals hackers: + +[{] More symbolic definitions have been introduced. + There are now symbolic definitions for the bits in the first word of an + SY2 block. To use '?' typeout mode use the prefix 'SY.'. + The ST (segment) table bits have also been defined under the prefix of + 'ST.'. + +[|] There is a new bit in the first word of SY2. The SY.OTC bit is set when + SY.CCN (compiled code needs me) is on and the referencer is other then a + CALL uuo (hence the name, Other Then Call, or OTC). + +[}] In order to impliment the new purification scheme, there have been some + changes to the internal purification routines. The symbol conser (SYCONS) + has been split into two consers: SYCONS for impure symbols and PSYCONS + for pure symbols. Note that this is consistent with the other pure/impure + consers. + +Thursday March 23,1978 FQ+7D.3H.39M.38S. LISP 1513 --HIC, GLS, JONL-- + +Changes that affect ITS NEWIO only: +[1] New SCROLL option for TTY's +[2] New STATUS option: OSPEED +[3] Change in CURSORPOSable terminal definition +[4] New symbols with AUTOLOAD property: CREATE-JOB, LEDIT + +Changes that affect all NEWIO's: +[a] New function: LENGTHF + +Changes that affect all LISP's: +[A] New functions: *READCH, *TYI, *READ + +General announcement: +[!] TOPS-10 NEWIO is here! + +Changes of interest only to LISP internals pathologists: +[@] DBGMSK now has %PIATY off + +---------------------------------------------------------------------- +Changes that affect ITS NEWIO only: +[1] There is now a new OPEN option for TTY's. If SCROLL mode is specified in + the option list, or if it has been set in the TTY status variable, LISP + will handle the scrolling correctly. Before this option, scrolling could + lose on MOREing. If the terminal is not in scroll mode, ITS will be + informed of the fact that scrolling is requested so that normal output will + cause the display to scroll. + +[2] New STATUS option: OSPEED. + (STATUS OSPEED ) returns the speed in BAUD of the TTY + open on . To obtain the speed of the controlling + terminal, (STATUS OSPEED TYO) may be used. + +[3] There has been a slight change in the definition of a terminal to which + LISP will output ITS display (control-P) codes. If the %TOMVB (move + back) bit is set, LISP will treat the terminal as a display. Previously, + the %TOMVU (move up) bit was checked, and would cause misfunction on + GLASS TTY's. We are contemplating making LISP smarter about terminal + types so that the value returned from CURSORPOS (T for succesful operation, + NIL for failure) will actually reflect whether the operation was + performed on the terminal. Comments about the display handling scheme + are solicited. + +[4] CREATE-JOB has autoload property of COM:HUMBLE FASL + LEDIT has autoload property of COM:LEDIT FASL + +Changes that affect all NEWIO's: +[a] A new function has been added which returns the length of an input file. + (LENGTHF ) returns the length of the input file open + on . + +Changes that affect all LISP's: +[A] *READCH, *READ, *TYI are new functions added mainly for the benefit of the + compiler. They are SUBRs of zero arguments and function the same as + their counterparts (READCH, READ, TYI) with no arguments given. + +General announcement: +[!] TOPS-10 NEWIO is now alive. It has been running on some DECsystem-20's + under the TOPS-10 simulator and has run fine on standalone TOPS-10's. + Unfourtunatly, it has not had widespread distribution. Any TOPS-10 site + interested in obtaining a copy of NEWIO should send a note to BUG-LISP + and we will try to accomodate you. We need it to be used in the field if + we are to have any hopes of making it solid. + +Changes of interest only to LISP internals pathologists: +[@] Of interest to LISP internals pathologists is the fact that DBGMSK + now has the %PIATY bit off. If you are debugging a LISP in which the + program enables TTY-RETURN interrupts, you would lose badly. Now, + setting IMASK and .MASK to DBGMSK will turn off TTY-RETURN interrupts and + allow simpler debugging. + +SUNDAY FEB 26,1978 FM+4D.3H.23M.22S. LISP 499 --HIC, GLS, JONL--- + +NOTICE: +AS THIS "LISP RECENT" COMES SHORTLY AFTER THE PREVIOUS "LISP RECENT", IT +WILL BE APPENDED TO THE FRONT OF RATHER THAN SUPERCEDING THE PREVIOUS ONE. + +CHANGES THAT AFFECT ALL USERS: +[1] YOUR DEFAULT INIT FILE IS NOW AUTOMATICALLY READ BY LISP +[2] REMINDER: LSUBR CONS HAS BEEN REMOVED + +CHANGES THAT AFFECT ITS NEWIO: +[A] ARGUMENT OF T TO DIRECTORY FUNTION IS NOW MEANINGFUL +---------------------------------------------------------------------- +[1] WHEN LISP IS STARTED UP YOUR DEFAULT INIT FILE WILL BE READ IN + WITHOUT INTERVENTION. TO PREVENT READING IN THE INIT FILE, IT IS + NECESSARY TO GIVE A JCL CONTAINING ONLY SPACES SO: + :LISP + READS YOUR INIT FILE WHEREAS: + :LISP + DOES NOT. NOTE THAT A DIFFERENT INIT FILE MAY BE SPECIFIED IN THE JCL + AS BEFORE. + +[2] LSUBR CONS, WHICH WAS ADDED A FEW RELEASES AGO, HAS BEEN REMOVED. IT + HAS ACTUALLY BEEN REMOVED FOR A WHILE, BUT IT IS BEING DOCUMENTED IN + LISP RECENT FOR THE FIRST TIME. AS THERE WERE SOME PROBLEMS WITH + THE NEW FORM OF CONS, AND THERE WAS NO COMPILER SUPPORT FOR IT, WE DECIDED + TO REMOVE THE NEW CONS UNTIL THINGS COULD BE BETTER WORKED OUT. + AN ANNOUNCEMENT WILL BE MADE WHEN LSUBR CONS RETURNS. + +[A] AN ARGUMENT OF T TO THE DIRECTORY AND MAPDIRECTORY FUNCTIONS IS NOW + MEANINGFUL. A CALL IS OF THE FORM: + (DIRECTORY []) + IF PROPS-TO-RETURN IS OMITTED, THEN A SELECTED SUBSET OF THE + FILE PROPERTIES IS RETURNED. IF PROPS-TO-RETURN IS T, ALL OF THE + AVAILABLE PROPERTIES WILL BE RETURNED. IF PROPS-TO-RETURN IS NIL, NO + PROPERTIES ARE RETURNED. PROPS-TO-RETURN MAY BE A LIST IN WHICH CASE + IT EXPLICITLY STATES THE PROPERTIES TO BE RETURNED. + +SUNDAY FEB 19,1978 FQ+4D.11H.48M.14S. LISP 493 -GLS, HIC, JONL- + +IMPORTANT NOTIFICATION REGARDING UPCOMING CHANGE: +[!] IN THE NEXT VERSION OF LISP, INIT FILES WILL ALWAYS BE READ UPON STARTUP + +CHANGES THAT AFFECT NEWIO ONLY: +[A] UREAD NOW RETURNS TRUENAME OF FILE RATHER THAN FILE NAME AS GIVEN +[B] THERE IS NOW AN AUTOLOAD PROPERTY ON THE INF-EDIT FUNCTION FOR LISPT USERS +[C] THERE IS NOW AN AUTOLOAD PROPERTY ON THE LAP-A-LIST FUNCTION +[D] FUNCTIONAL VARIABLES ARE NOW UNDER A STATUS/SSTATUS SWITCH + +CHANGES THAT AFFECT ALL VERSIONS: +[1] EXP NOW ACCEPTS ARGUMENTS UP TO 88.0 +---------------------------------------------------------------------- +[!] IN THE NEXT RELEASE OF LISP YOUR DEFAULT INIT FILE (THE ONE YOU WOULD + GET IF YOU TYPED ^Q TO ALLOC QUESTION) WILL DE LOADED WHEN LISP IS + STARTED FOR THE FIRST TIME. THE FILE THAT IS READ CAN BE MODIFIED + BY GIVING LISP A JCL LINE (AS ALWAYS). THERE WILL BE NO WAY, WITHIN + LISP, TO TURN THIS FEATURE OFF. WHAT THIS MEANS IS THAT LISP WILL NOW + HANDLE INIT FILES IN THE WAY THAT MOST OTHER SYSTEM PROGRAMS, SUCH AS + EMACS, HANDLE THEM. + +[A] UREAD NOW RETURNS THE VALUE OF THE FUNCTION TRUENAME APPLIED TO THE + FILE OPENED BY UREAD. YOU CAN THEREFORE SEE EXACTLY WHAT FILE IS BEING + PROCESSED. + +[B] THE INF-EDIT FUNCTION, WHICH IS THE WAY IN WHICH THE EDITING PACKAGE LISPT + IS INVOKED, NOW HAS A SYSTEM AUTOLOAD PROPERTY. + +[C] THE FUNCTION LAP-A-LIST NOW HAS AN AUTOLOAD PROPERTY. LAP-A-LIST IS + A FUNCTION WHICH IS USED BY LAP AFTER IT BUILDS A LIST OF THE USERS + INPUT. IT IS FELT THAT USERS WANTING TO GENERATE LAP CODE VIA PROGRAMS + AND PASS IT TO LAP TO BE PROCESSED CAN MORE EASILY GENERATE A LIST OF + LAP EXPRESSIONS RATHER THAN PUTTING UP WITH THE FUNNY INTERFACE TO + LAP AS IS CURRENTLY REQUIRED. LAP-A-LIST TAKES AS ITS ARGUMENT A LIST + WHICH IS SIMPLY A LIST OF THE INDIVIDUAL LINES THAT WOULD NORMALLY BE + FED TO THE LAP PROGRAM. + +[D] WE PLAN TO FLUSH FUNCTIONAL VARIABLES IN THE NEAR FUTURE. AS AN INTERIM + MEASURE, WHETHER OR NOT AN ATOM IN A FUNCTIONAL POSITION IS EVALUATED + IS DETERMINED BY THE SETTING OF THE 'PUNT' STATUS FLAG. WHEN (STATUS PUNT) + IS T, EVALUATION OF FUNCTIONAL VARIABLES WILL BE SKIPPED (PUNTED?). + THE FLAG IS DEFAULTLY T, AND SHOULD BE SET TO NIL BY THE USER IF UNDEFINED + FUNCTION OBJECT ERRORS ARISE IN PREVIOUSLY FUNCTIONING PROGRAMS. + NOTE THAT SINCE FUNCTIONAL VARIABLES ARE GOING TO BE FLUSHED ALL TOGETHER + AT SOME FUTURE DATE, IT IS BEST LEAVE THE FLAG ON IN ORDER TO INSURE THAT + YOUR PROGRAMS WILL FUNCTION CORRECTLY WHEN FUNCTIONAL VARIABLES ARE + COMPLETELY REMOVED. + +[!] AS E^88.0 IS INDEED REPRESENTABLE, IT HAS BEEN DECIDED TO EXTEND THE + LEGAL INPUT VALUES FOR THE EXP FUNCTION. NOTE THAT THE ACCURACY OF THIS + FUNCTION AT THE HIGHER VALUES MIGHT BE REDUCED. + +THURSDAY JAN 26,1978 FM+2D.9H.23M.18S. LISP 472 -GLS, HIC, JONL- + +THINGS WE WOULD LIKE TO KNOW: +[A] INPUT/OUTPUT BASES DEFAULTING TO DECIMAL +[B] FUNCTION CELLS +[C] ERROR HANDLING +[D] DOTS IN DOTTED PAIRS REQUIRING A SPACE ON BOTH SIDES + +CHANGES THAT AFFECT ALL VERSIONS: +[1] NEW SYNTACTIC CONSTRUCT: CASEQ +[2] *RSET DEFAULT IS NOW T +[3] CONS IS NOW AN LSUBR (!) +[4] LIMITATION ON LENGTH OF VALRET STRINGS HAS BEEN REMOVED + +CHANGES THAT AFFECT SAIL VERSION: +[!] VALRET WILL NOW DO A PTLOAD, TO LOAD ARGUMENT INTO LINE EDITOR +-------------------------------------------------------------------- +PLEASE ANSWER THE FOLLOWING QUESTIONS IF YOU FEEL THEY HAVE A +BEARING ON YOUR ACTIVTIES BY SENDING MAIL TO BUG-LISP: +[A] SHOULD THE DEFAULT BASE FOR INPUT AND OUTPUT BE DECIMAL? + IF SO, WHAT SHOULD BE USED FOR AN OCTAL 'POINT'? + +[B] WE ARE CONSIDERING IMPLEMENTING 'FUNCTION CELLS'. THESE WOULD + HOLD THE FUNCTIONAL PROPERTIES OF AN SYMBOL. THIS CHANGE WOULD + REMOVE THE ABILITY TO USE PUTPROP/DEFPROP/GET TO HACK FUNCTIONAL + PROPERTIES. SUGGESTIONS ARE SOLICITED. + +[C] WE ARE ALSO CONSIDERING IMPROVING THE ERROR HANDLING FACILITIES + AND WOULD APPRECIATE INPUT ON THE TYPES OF THINGS THAT ARE + DESIRED. + +[D] SHOULD THE DOT IN DOTTED PAIRS *REQUIRE* A SPACE ON EACH SIDE? + IF NO SPACE WAS PRESENT THE DOT WOULD BE CONSIDERED EITHER A + DECIMAL POINT OR PART OF A SYMBOL. + +THE FOLLOWING APPLY TO ALL SYSTEMS: +[1] THERE IS A NEW TYPE OF CONDITIONAL NAMED 'CASEQ'. + + (CASEQ + ( E1 E2 ... EN) ;CLAUSE 1 + ( E1 E2 ... EN) ;CLAUSE 2 + ... + ( E1 E2 ... EN)) ;CLAUSE M + + MUST EVALUATE TO EITHER A SYMBOL OR A FIXNUM. + ALL OF THE KEYS IN THE KEY-SETS MUST BE OF THE SAME TYPE, + EITHER SYMBOL OR FIXNUM, AND MUST BE OF THIS SAME TYPE + ALSO. + IS EITHER THE ATOM T, A RANDOM ATOM (SYMBOL OR FIXNUM), + OR A LIST OF ATOMS (SYMBOLS OR FIXNUMS). IF IT IS THE ATOM T, + THE EXPRESSIONS FOLLOWNG IT ARE EVALUATED UNCONDITIONALLY. + THIS SHOULD OCCUR ONLY IN THE LAST CLAUSE, IF AT ALL. + IF IS A SINGLE ATOM (OTHER THAN T), THEN IF IT MATCHES + THE FOLLOWING EXPRESSIONS ARE EVALUATED. IF A LIST OF ATOMS + IS PRESENT, THEN EACH ATOM IS MATCHED AGAINST AND THE + EXPRESSIONS ARE EVALUATED IF ANY ATOM MATCHES. THE ATOMS IN THE + ARE NEVER EVALUATED. "MATCHING" MEANS EQ FOR SYMBOLS + AND = FOR FIXNUMS. + THE VALUE OF CASEQ IS THE VALUE OF THE LAST EXPRESSION EVALUATED + IF A MATCH IS FOUND, ELSE NIL. + IT IS NOT USEFUL FOR A GIVEN KEY TO APPEAR MORE THAN ONCE AMONG + ALL THE KEY-SETS OF A SINGLE CASEQ. THE IDEA OF CASEQ IS TO + PROVIDE A DISPATCHING CONSTRUCT. A "T-CLAUSE" PROVIDES AN + "ELSE" CASE FOR WHEN NO EXPLICITLY GIVEN KEYS MATCH. + EVENTUALLY WE HOPE THAT CASEQ ON FIXNUMS, AT LEAST, WILL COMPILE + ESPECIALLY WELL, INTO A KIND OF FORTRAN-STYLE COMPUTED GOTO. + +[2] THE DEFAULT VALUE OF *RSET IS NOW T. + +[3] CONS IS NOW AN LSUBR. + (CONS A B C D) <==> (CONS A (CONS B (CONS C D))) + (CONS A) <==> A + IN OTHER WORDS, IT RIGHT-ASSOCIATES. + (CONS A B C D NIL) = (LIST A B C D), BUT ON THE LISP MACHINE + THEY MAY HAVE DIFFERENT CONNOTATIONS WITH RESPECT TO STORAGE + ALLOCATION. + +[4] THE LIMITATION ON THE LENGTH OF VALRET STRINGS HAS BEEN REMOVED + FOR ALL PRACTICAL PURPOSES. + +[!] IN SAIL VERSION, VALRETTING A STRING NOW LOADS THE STRING INTO + THE LINE EDITOR VIA PTLOAD. + +FRIDAY JAN 13,1978 NM+4D.23H.1M.55S. LISP 383 -GLS, HIC- + +[@] SOME CHANGES IN NOMENCLATURE FOR VARIOUS VERSIONS + +[1] LAST MOST FINAL DOCUMENTATION OF THE HAIRY DEFUN FEATURE +[2] (STATUS JNUMBER) RETURNS A JOB NUMBER +[3] NEW EDIT COMMAND: YV FOO YANKS VALUE OF FOO + +[A] FILEPOS CAN TAKE T AND NIL AS POSITION SPECIFIERS +[B] MEANINGS OF T AND NIL WHERE A FILE OBJECT IS REQUIRED +[C] NEW IO-LOSSAGE ERROR FOR AN INVALID VALUE OF MSGFILES +[D] SLIGHT INCOMPATIBILITY: UREAD AND UFILE NOW RETURN A FULL NAMELIST +[E] UAPPEND NO LONGER RENAMES THE FILE ON OPENING IT +[F] FOR THE RECORD, COMPLETE DEFINITIONS OF OLDIO IN TERMS OF NEWIO +[G] RENAMEF AND DELETEF OF A FILE OBJECT NOW CLOSE THE FILE OBJECT +[H] ALL ITS NEWIO I/O IS NOW DONE WITH SIOT + +SOME FEATURES PRESENTLY IMPLEMENTED ONLY FOR THE SAIL VERSION: +[!] SAIL VERSION NOW USES TWO SEPARATE DISK FILES FOR SAVED LISPS +["] INITIALIZATION AUTOMATICALLY SAVES A HIGH SEGMENT +[#] FASLOAD CAN LOAD INTO THE HIGH SEGMENT +[$] HIGH-SEGMENT PURE FREE STORAGE +[%] SUSPEND NOW TAKES ONE OR TWO ARGUMENTS + +SOME THINGS PROBABLY OF INTEREST ONLY TO LISP SYSTEM HACKERS: +[{] NEW INTERNAL ROUTINES %CONS, %HUNK, ETC. SOLVE A PDLNMK PROBLEM +[|] INITG IS NOW INITIALIZEG, TO PREVENT CONFLICT WITH DEC-10 INIT UUO +[}] NEW MACROS PUSHN AND POPI ARE USED IN THE SOURCE +[~] THE FORMAT OF FILE OBJECTS HAS CHANGED SOME - REASSEMBLE CODE IF NECESSARY +---------------------------------------------------------------- +[@] THERE ARE MANY, MANY VERSIONS OF MACLISP FLOATING AROUND. + EVEN JUST ON THE PDP-10, THERE ARE MANY BECAUSE OF THE + POSSIBILITIES OF CONDITIONAL ASSEMBLY. WORK IS PROCEEDING + APACE ON VERSIONS FOR THE TENEX AND TOPS-20 OPERATING SYSTEMS, + AND ON NEWIO VERSIONS FOR SAIL AND TOPS-10. HERE WE LAY OUT + SOME STANDARD NOMENCLATURE FOR THE VARIOUS VERSIONS. + THE VARIOUS NAMES FALL INTO SETS WHICH REPRESENT ORTHOGONAL + CHOICES. + OPERATING SYSTEM: + / ITS + | / TOPS-10 + | DEC-10 | SAIL + PDP-10 | \ CMU + | / + | DEC-20 | TENEX + \ \ TOPS-20 (AKA "TWENEX") + MULTICS + THE PDP-10 VERSION WILL EVENTUALLY RUN ON SIX DIFFERENT + OPERATING SYSTEMS. TOPS-10, SAIL, AND CMU ARE SUFFICIENTLY + SIMILAR TO WARRANT LUMPING THEM TOGETHER AS "DEC-10"; SIMILARLY + TENEX AND TOPS-20 ARE LUMPED TOGETHER AS "DEC-20". + MULTICS, OF COURSE, IS NOT A PDP-10 VERSION. + PROCESSOR: + KA10 + KI10 + KL10 + THE KA10 VERSION WILL RUN ON ALL PROCESSORS; THE KI10 VERSION WILL + RUN ONLY ON KI10 AND KL10 PROCESSORS; AND THE KL10 ONLY ON KL10'S. + SO FAR WE HAVE BEEN GENERATING ONLY KA10 VERSIONS; WHEN THE NEW + NUMBER STUFF IS IMPLEMENTED, THIS CHOICE WILL BECOME MORE IMPORTANT. + I/O IMPLEMENTATION: + OLDIO (UREAD, UWRITE, ETC. *ONLY*) + NEWIO (MULTIPLE I/O CHANNELS; ALSO SUPPORTS UREAD) + MINIMALITY: + MINIMAL (FANCY FRILLS NOT INCLUDED) + USELESS (FANCY "USELESS" FRILLS ARE INCLUDED) + THE FRILLS INCLUDE THE GCD FUNCTION, PURIFY AND FRIENDS, AND LOTS + OF LITTLE I/O HACKS LIKE ROMAN NUMERALS AND PRINLEVEL/PRINLENGTH. + THE MINIMAL VERSION IS USUALLY USED ONLY FOR DEC-10 VERSIONS + WHICH MUST RUN ON MACHINES WITH LITTLE PHYSICAL MEMORY; HOWEVER, + IT IS AN OPTION INDEPENDENT OF OPERATING SYSTEM. + ARITHMETIC: + BIGNUMS + DOUBLE-PRECISION FLONUMS + COMPLEX NUMBERS + THESE THREE ARE INDEPENDENT CHOICES WHICH MAY BE PRESENT OR ABSENT. + + THUS, TO IDENTIFY THE VERSION PRESENTLY RUNNING AT MIT-AI, WE + MIGHT SAY "THE ITS KA10 NEWIO USELESS BIGNUM VERSION". + + +[1] THE FOLLOWING ARE THE OFFICIAL SPECS FOR THE "HAIRY DEFUN" + FEATURE, WHEREIN THE NAME OF THE FUNCTION IS ACTUALLY + A LIST OF GOODIES. IF THE INTERPRETER OR COMPILER DOESN'T + ACTUALLY DO WHAT FOLLOWS, IT'S A BUG. (UP TO NOW WE HAVEN'T + BEEN ABLE TO DISTINGUISH BUGS AND MISFEATURES BECAUSE WE + WEREN'T SURE PRECISELY WHAT THE FEATURE SHOULD DO IN ALL CASES.) + + THE GENERAL FORM OF A CALL TO DEFUN IS: + (DEFUN . ) + AND MAY BE INTERCHANGED. + MAY BE OMITTED, OR MAY BE "EXPR", "FEXPR", OR "MACRO". + MAY BE A SYMBOL (THE NAME OF THE FUNCTION), OR + A LIST OF TWO TO FOUR SYMBOLS (IN WHICH CASE THE FLAG "MACRO" + IS ILLEGAL). IS A NON-NIL SYMBOL OR A LIST OF SYMBOLS; + THE FORMER INDICATES AN LEXPR (INCOMPATIBLE WITH THE "MACRO" + AND "FEXPR" FLAGS). + IF THE VALUE OF THE SWITCH DEFUN IS T, THEN THE EXPR-HASH HACK + IS ENABLED. IN THIS CASE, DEFUN AVOIDS MAKING THE INTERPRETIVE + DEFINITION IF HASHING THE DEFINITION INDICATES THAT IT IS + THE SAME AS THE CURRENT, PRESUMABLY COMPILED, DEFINITION. + THE VARIOUS CASES ARE: + FORM OF : + FOO (FOO BAR) (FOO BAR BAZ) (FOO BAR BAZ QUUX) + EXPR-HASH PROPERTY IS ON THE ATOM: + FOO THE RESULT OF - NONE - FOO + (GET 'FOO 'BAR) + IF THIS IS A SYMBOL + EXPR-HASH PROPERTY INDICATOR IS: + EXPR-HASH EXPR-HASH - NONE - QUUX + DEFUN PUTS THE FUNCTION DEFINITION ON FOO UNDER THE PROPERTY: + EXPR/FEXPR/MACRO BAR BAR BAR + COMPILER PUTS THE FUNCTION DEFINITION ON FOO UNDER THE PROPERTY: + SUBR/FSUBR/LSUBR BAR * BAZ BAZ + * THE PROPERTY WILL BE A SYMBOL |FOO BAR| WHICH IN TURN + WILL HAVE THE APPROPRIATE SUBR/FSUBR/LSUBR PROPERTY. + +[2] (STATUS JNUMBER) RETURNS THE NUMBER OF THE LISP JOB (AS DEFINED + BY THE HOST OPERATING SYSTEM). + +[3] THE EDITOR COMMAND YV FOO IS THE SAME AS YP FOO VALUE . + IT IS USEFUL FOR EDITING THE VALUE OF A SYMBOL. + +[A] T AND NIL AS THE SECOND ARGUMENT TO FILEPOS HAVE SPECIAL + MEANINGS. T MEANS THE END OF THE FILE, AND NIL MEANS + THE ACTUAL BEGINNING OF THE FILE. THE DIFFERENCE BETWEEN + NIL AND 0 IS THAT 0 MEANS THE LOGICAL BEGINNING OF THE FILE, + WHILE NIL MEANS THE PHYSICAL BEGINNING. THIS MAKES NO + DIFFERENCE IN ANY CURRENT IMPLEMENTATION, BUT WILL MAKE + A DIFFERENCE WHEN SAIL NEWIO EXISTS. FILEPOS WILL KNOW + ABOUT THE SAIL RECORD OFFSET FEATURE, AND NIL WILL MEAN + THE APPROPRIATE NEGATIVE RECORD NUMBER. + +[B] THERE ARE THREE KINDS OF CONTEXTS IN WHICH A FILE OBJECT + CAN BE USED: + (1) AN INPUT FILE IS NEEDED, E.G. FOR READ AND TYI. + (2) AN OUTPUT FILE IS NEEDED, E.G. FOR PRINT AND TYO. + (3) EITHER DIRECTION IS ACCEPTABLE, E.G. FOR LINEL AND (STATUS TTYCONS). + IN THE PAST T HAS MEANT THE TTY (THE TERMINAL). UNFORTUNATELY, + THERE IS AN AMBIGUITY IN CONTEXT (3). TO ALLEVIATE THIS, WE + ARRANGED FOR THE VARIABLES TYI AND TYO TO CONTAIN THE FILES + USED FOR THE TTY (AS ALREADY DOCUMENTED), SO THAT THE USER + CAN REFER TO THESE VARIABLES IN CONTEXT (3). MOREOVER, + IN CONTEXTS (1) AND (2) T IS TAKEN TO MEAN "THE FILE IN + THE VARIABLE TYI OR TYO (RESPECTIVELY)". + A PREVIOUSLY UNDOCUMENTED FEATURE OF THIS IS THAT MSGFILES, + FOR EXAMPLE, CAN BE '(T) (WHICH IS IN FACT THE DEFAULT VALUE), + WHICH CAUSES MESSAGES TO GO TO WHATEVER FILE IS IN TYO. + IN THIS WAY ONE NEED NOT CHANGE MSGFILES JUST BECAUSE THE VALUE + OF TYO IS CHANGED. + WE NOW ALSO MAKE THE FURTHER EXTENSION THAT IN CONTEXT (2), + WHERE ^W WOULD BE HEEDED IF A FILE ARGUMENT WERE OMITTED, + THAT SPECIFYING THE FILE EXPLICITLY (BY REFERRING TO THE VALUE + OF TYO) WILL NOT HEED ^W, BUT SPECIFYING T WILL ALLOW ^W TO + FORCE THE FILE IN TYO TO BE IGNORED. THIS, FOR EXAMPLE, + ALLOWS ^W TO SUPPRESS MSGFILES ACTIVITY TO THE TTY AND WELL AS + ORDINARY ACTIVITY. + NIL AS A FILE MEANS DIFFERENT THINGS IN DIFFERENT CONTEXTS. + IN CONTEXTS (1) AND (2) IT MEANS THE SAME AS SPECIFYING + NO FILE ARGUMENT AT ALL, AND SO USES THE DEFAULT (INFILE FOR + CONTEXT (1), OUTFILES AND TYO AS CONTROLLED BY ^R AND ^W FOR + CONTEXT (2)). FOR CONTEXT (3) IT MEANS "SET A DEFAULT VALUE" + IF THAT IS APPROPRIATE (E.G. FOR LINEL), AND IS ILLEGAL IF NOT + APPROPRIATE. + +[C] IF MSGFILES IS EVER FOUND TO HAVE A BAD VALUE, AND IO-LOSSAGE + ERROR OCCURS, SIMILAR TO THE FAIL-ACT ERRORS FOR BAD VALUES + OF BASE, IBASE, ETC. BEFORE THE ERROR OCCURS, MSGFILES IS + SET TO '(T). + +[D] UREAD AND UFILE NOW HAVE AS THEIR VALUE A FULL NAMELIST, NOT + JUST THE SIMPLE FILE NAMES. THUS UREAD MIGHT RETURN + ((DSK LOSER) FOO BAR) WHERE FORMERLY IT WOULD HAVE RETURNED + (FOO BAR). + +[E] UAPPEND NO LONGER RENAMES THE OPENED FILE TO ".LISP. APPEND"; + THE FILE RETAINS ITS OWN NAME. (THIS IS PRIMARILY BECAUSE + IT IS SO DIFFICULT TO RENAME AN OPEN FILE ON TOPS-10 - GRR!). + +[F] HERE ARE THE OFFICIAL DEFINITIONS OF THE OLDIO FUNCTIONS + IN TERMS OF NEWIO FUNCTIONS: + + (DEFUN UREAD FEXPR (FILENAME) + (UCLOSE) + ((LAMBDA (FILE) + (EOFFN UREAD + (FUNCTION + (LAMBDA (EOFFILE EOFVAL) + (UCLOSE) + EOFVAL))) + (INPUSH (SETQ UREAD FILE)) + (DEFAULTF FILE)) + (OPEN (*UGREAT FILENAME) 'IN))) + + (DEFUN UCLOSE FEXPR (X) + (COND (UREAD + ((LAMBDA (OUREAD) + (AND (EQ OUREAD INFILE) (INPUSH -1)) + (SETQ UREAD NIL) + (CLOSE OUREAD)) + UREAD)) + (T NIL))) + + (DEFUN UWRITE FEXPR (DEVDIR) + (OR DEVDIR (SETQ DEVDIR (CAR (DEFAULTF NIL)))) + (*UWRITE (CONS DEVDIR + (COND ((STATUS FEATURE DEC10) + (CONS (STATUS JNAME) '(OUT))) + ((STATUS FEATURE DEC20) + '(MACLISP OUTPUT)) + ((STATUS FEATURE ITS) + '(.LISP. OUTPUT)))) + 'OUT + (LIST DEVDIR))) + + (DEFUN UAPPEND FEXPR (FILENAME) + (SETQ FILENAME (*UGREAT FILENAME)) + (*UWRITE FILENAME 'APPEND FILENAME)) + + (DEFUN *UWRITE (NAME MODE NEWDEFAULT) ;INTERNAL ROUTINE + (COND (UWRITE + (SETQ OUTFILES (DELQ UWRITE OUTFILES)) + (CLOSE UWRITE) + (SETQ UWRITE NIL))) + ((LAMBDA (FILE) + (SETQ OUTFILES + (CONS (SETQ UWRITE FILE) + OUTFILES)) + (CAR (DEFAULTF NEWDEFAULT))) + (OPEN NAME MODE))) + + (DEFUN UFILE FEXPR (SHORTNAME) + (COND ((NULL UWRITE) + (ERROR 'NO/ UWRITE/ FILE + (CONS 'UFILE SHORTNAME) + 'IO-LOSSAGE)) + (T (PROG2 NIL + (DEFAULTF (RENAMEF UWRITE (*UGREAT SHORTNAME))) + (SETQ OUTFILES (DELQ UWRITE OUTFILES)) + (SETQ UWRITE NIL) + (OR OUTFILES (SETQ ^R NIL)))))) + + (DEFUN *UGREAT (NAME) ;INTERNAL ROUTINE + (MERGEF NAME + (COND ((STATUS FEATURE DEC10) '(* . LSP)) + ((STATUS FEATURE DEC20) '(* MACLISP *)) + ((STATUS FEATURE ITS) '(* . >))))) + + (DEFUN UPROBE FEXPR (FILENAME) + (SETQ FILENAME (MERGEF (*UGREAT FILENAME) NIL)) + (PROBEF FILENAME)) + + (DEFUN UKILL FEXPR (FILENAME) + (DEFAULTF (DELETEF FILENAME)))) + + +[G] FOR CONSISTENCY WITH TOPS-10 (SIGH), THE NEWIO FUNCTIONS + DELETEF AND RENAMEF WHEN APPLIED TO A FILE OBJECT WILL + ALSO CLOSE THE FILE OBJECT. + +[H] IN CASE ANYONE CARES, ALL ITS NEWIO I/O TRANSACTIONS ARE + NOW DONE WITH SIOT, NOT WITH BLOCK IOT. THIS MAY AFFECT + INTERACTIONS WITH FILES WRITTEN BY PROGRAMS WHICH STILL + USE BLOCK IOT (E.G. ^C PADDING AT ENDS OF FILES). + +THE FOLLOWING FEATURES EXIST ONLY IN THE SAIL VERSION. +EVENTUALLY THEY WILL BE IMPLEMENTED IN ALL DEC-10 VERSIONS. +SOME OF THESE PROVIDE ABILITIES ANALOGOUS TO, BUT NOT +IDENTICAL WITH, FEATURES ALREADY PROVIDED ON ITS FOR HACKING +SHARABLE CODE AND DATA. SYSTEMS PROGRAMMERS SHOULD EXAMINE +THE FOLLOWING DESCRIPTIONS TO SEE HOW TO HANDLE THESE +FEATURES IN A MANNER COMPATIBLE WITH ALL VERSIONS. +AT THE END IS AN EXAMPLE OF HOW TO CREATE A SHARED SYSTEM +IN A WAY THAT WILL WORK IN ALL EXISTING PDP-10 VERSIONS. + +[!] THE SAIL (SU-AI) TIME-SHARING SYSTEM ORDINARY SAVES + TWO-SEGMENT PROGRAMS AS A SINGLE FILE, UNLIKE TOPS-10, + WHICH USES TWO DISTINCT DISK FILES (ONE FOR EACH + SEGMENT). MACLISP NOW GOES TO SOME TROUBLE TO USE TWO + DISTINCT FILES ON SAIL ALSO. THE HIGH-SEGMENT FILE + NORMALLY HAS THE EXTENSION ".SHR". THIS IS USED TO + SUPPORT THE OTHER FEATURES BELOW. + +["] WHEN A NEW MACLISP HAS BEEN ASSEMBLED, LOADED, AND + STARTED BY THE SU-AI MAINTAINER, IT WILL AUTOMATICALLY + TRY TO DUMP OUT THE HIGH SEGMENT AS A DISK FILE, + AND WILL PRINT A MESSAGE REGARDING SUCCESS OR FAILURE. + IT THEN LOADS THE LINE EDITOR WITH AN APPROPRIATE + SAVE COMMAND (NOT SSAVE, BECAUSE ONLY THE LOW SEGMENT + SHOULD BE SAVED) FOR THE USER TO APPROVE WITH "RETURN" + IF DESIRED. (IF THE MAINTAINER WANTS TO USE NON-STANDARD + FILE NAMES, HE CAN DEPOSIT THE NAMES IN LOCATIONS + SGADEV, SGANAM, SGAEXT, AND SGAPPN.) + +[#] FASLOAD CAN NOW LOAD CODE INTO THE HIGH SEGMENT. + RECALL THAT IN THE ITS VERSION, THE VARIABLE "PURE" + CONTROLS THE LOADING OF PURIFIABLE (SHARABLE) CODE. + THE MEANING OF THIS VARIABLE HAS BEEN EXTENDED. + IF PURE IS A FIXNUM, THEN FASLOAD WILL SET UP FOR + THE UUOLINKS HACK. THE EXTENSION IS TWOFOLD: + (1) IF THE ABSOLUTE VALUE OF PURE IS LESS THAN 10, + IT IS MULTIPLIED BY 1024. (1K). (2) THE ABSOLUTE + VALUE OF THE RESULT IS AN ESTIMATE OF THE NUMBER + OF *WORDS* DESIRED FOR THE UUOLINKS HACK. THIS SHOULD + BE ABOUT 15% MORE THAN THE TOTAL NUMBER OF DIFFERENT + COMPILED FUNCTIONS TO BE LOADED. (STEP 1 IS FOR + COMPATIBILITY WITH THE OLD MEANING OF PURE, AS THE + NUMBER OF 1K BLOCKS TO RESERVE.) + IN THE ITS (AND DEC-20) VERSIONS, THE SIGN OF THE + FIXNUM IS IRRELEVANT. FOR SAIL (AND EVENTUALLY TOPS-10 + AND CMU), THE SIGN CONTROLS WHICH SEGMENT TO LOAD INTO. + A POSITIVE VALUE LOADS INTO THE LOW SEGMENT, AS BEFORE. + A NEGATIVE VALUE CAUSES THE HIGH SEGMENT TO BE + DEPURIFIED (A WRITABLE COPY MADE) IF NECESSARY; + THE CODE IS THEN LOADED INTO THE HIGH SEGMENT. + ALSO, ONLY ONE OF THE UUOLINKS AREAS IS MADE IN THE + LOW SEGMENT; THE OTHER IS PUT IN THE HIGH SEGMENT. + (THUS THE HIGH-SEGMENT LOADING FEATURE IS TIED TO THE + UUOLINKS FEATURE - SORRY ABOUT THAT.) + +[$] RECALL THAT *PURE CONTROLS WHETHER CERTAIN KINDS OF + S-EXPRESSIONS ARE TO BE AUTOMATICALLY PURCOPY'D. + FOR ITS (AND DEC-20) ALL THAT MATTERS IS WHETHER IT IS + NIL OR NON-NIL. FOR SAIL (AND EVENTUALLY TOPS-10 AND CMU), + IT MUST BE A FIXNUM TO CAUSE PURCOPY TO USE THE HIGH + SEGMENT. THIS IN TURN WORKS ONLY IF PURE IS A NEGATIVE + FIXNUM. + THE VALUE OF *PURE SHOULD BE AN ESTIMATE OF THE TOTAL + NUMBER OF WORDS OF PURE FREE STORAGE NEEDED, INCLUDING ALL + THAT LOADED BY PREVIOUS FILES AND ALL THAT INCLUDED IN + THE INITIAL LISP SYSTEM (PRESENTLY ABOUT 6000. WORDS). + THIS CAUSES FASLOAD TO PREALLOCATE ENOUGH ADDITIONAL ROOM + IN THE HIGH SEGMENT TO ACCOMODATE THE ESTIMATED TOTAL AMOUNT + OF PURE STORAGE. (THE PREALLOCATION IS NECESSARY BECAUSE + IT ISN'T POSSIBLE TO ALLOCATE LIST STORAGE IN THE HIGH + SEGMENT ONCE THE LOADING OF CODE HAS BEGUN.) MAKING THE + ESTIMATE IN *PURE TOO BIG MERELY WASTES SPACE IN THE + HIGH SEGMENT; MAKING IT TOO SMALL CAUSES PURCOPY TO MAKE + ITS COPIES IN THE LOW SEGMENT. + +[%] ONCE CODE AND DATA HAS BEEN LOADED INTO THE HIGH SEGMENT, + ONE CAN USE SUSPEND TO REPURIFY AND DUMP IT. IF SUSPEND + IS GIVEN TWO ARGUMENTS, IT WILL TAKE THE SECOND AS A FILE + NAME, DUMP THE HIGH SEGMENT TO THAT FILE, AND EXPUNGE THE + HIGH SEGMENT. IT THEN RETURNS TO MONITOR LEVEL. (THE SAIL + VERSION ALSO LOADS THE FIRST ARGUMENT INTO THE LINE + EDITOR; THIS WILL NORMALLY BE A SAVE (NOT SSAVE) COMMAND.) + WHEN THE LOW SEGMENT IS SUBSEQUENTLY CONTINUED OR RUN + FROM THE SAVE FILE, IT WILL ATTACH TO A HIGH SEGMENT + MADE FROM THE SAVED HIGH-SEGMENT FILE. IN SO DOING IT + WILL ARRANGE TO SHARE THAT HIGH SEGMENT WITH OTHER LISPS + USING THAT SAME HIGH SEGMENT. + +CHANGES OF INTEREST TO LISP SYSTEM HACKERS: +[{] THERE WAS A BUG WHICH OCCURRED BECAUSE CONS (AND HUNK) DID NOT + PDLNMK ITS ARGUMENTS. THIS WAS CONSIDERED OKAY BECAUSE NCOMPLR + KNOWS ABOUT THESE SPECIALLY, AND KNOWS THAT THEY MUST NOT BE + GIVEN UNSAFE ARGUMENTS. HOWEVER, IT WAS POSSIBLE TO USE FUNCALL + (OR SUBRCALL!) TO GIVE THEM UNSAFE ARGUMENTS. THE SOLUTION + WAS TO MAKE CONS AND HUNK ALWAYS PDLNMK, AND TO HAVE SPECIAL + ROUTINES %CONS, %NCONS, %XCONS, %HUNK3, AND %HUNK4, WHICH ARE + CALLED BY JSP T, AND WHICH NCOMPLR KNOWS ABOUT. THESE EXPECT + SAFE ARGUMENTS AND DO NOT PDLNMK. + +[|] INITG IS NOW INITIALIZEG, TO PREVENT CONFLICT WITH DEC-10 INIT UUO. + +[}] THE MACRO PUSHN PDL,N PUSHES N WORDS OF ZEROS ONTO PDL. THIS WORKS + FOR ANY N; THE MACRO KNOWS ABOUT THE ROUTINES NPUSH, 0PUSH, AND + 0.0PUSH AND GENERATES THE APPROPRIATE CALLS. THE MACRO IMPLICITLY + DESTROYS T. + THE MACRO POPI PDL,N POPS N WORDS FROM PDL BY SUBTRACTING AN + APPROPRIATE LITERAL. THE MACRO KNOWS ABOUT LOCATION R70. + +[~] THE FORMAT OF FILE OBJECTS HAS BEEN CHANGED TO ACCOMODATE NEW INFORMATION. + SOME EXTRA RESERVED SLOTS HAVE BEEN CREATED FOR FUTURE EXPANSION. + IN PARTICULAR, NOTICE J.UIND (USER INDEX) FOR JOB ARRAYS, AND + FB.BVC (VALID CHARACTER COUNT) FOR FILE OBJECTS. + +THURSDAY JUNE 09,1977 LQ+1D.1H.47M.35S. LISP 293 - GLS - + +[1] EVALHOOK NEVER SEES THE ARRAY REFERENCE OF A STORE + +[A] THE DEFAULT ##MORE## PROCESSOR NOW DOES (NOINTERRUPT NIL) +[B] CHANGES TO ALLFILES: + [B1] NAMESTRINGS ARE NOW ILLEGAL - USE NAMELISTS OR FILES + [B2] NEW OPTIONS: BITS, CHARACTERS, BYTES, BYTESIZE +---------------------------------------------------------------- +[1] TO PREVENT A PECULIAR SCREW INVOLVING THE PARTICULARLY KLUDGY + IMPLEMENTATION OF STORE, THE EVALHOOK FUNCTION (IF ANY) WILL + NEVER SEE THE ARRAY REFERENCE ITSELF AS A HOOKED FORM. INSTEAD, + IT WILL SEE ONLY SUBFORMS OF THE ARRAY REFERENCE. + +[A] MY FACE IS RED. TIME AND AGAIN I HAVE WARNED THAT ASYNCHRONOUS + INTERRUPTS ARE ALWAYS RUN BY THE SYSTEM IN (NOINTERRUPT T) MODE + TO PREVENT TIMING BUGS. IT IS UP TO THE INTERRUPT FUNCTION TO + RE-ENABLE INTERRUPTS BY SAYING (NOINTERRUPT NIL) IF DESIRED. + THE SYSTEM-SUPPLIED ##MORE## PROCESSOR NOW DOES (NOINTERRUPT NIL) + SO THAT IF YOU TYPE ^G (QUIT) OR ANY OTHER INTERRUPT CHARACTER AT + IT THE INTERRUPT WILL GO THROUGH IMMEDIATELY. + +[B] CHANGES TO THE ALLFILES PACKAGE, WHICH INCLUDES THE FUNCTIONS + ALLFILES, MAPALLFILES, DIRECTORY, AND MAPDIRECTORY: + [B1] TO PREVENT A REOCCURRENCE OF THE RECENT DISASTER IN + WHICH SOMEONE DID + (MAPALLFILES 'DELETEF '((DSK LOSER) * *)) + AND DELETED 1/3 OF ALL OF MC'S FILES BEFORE IT WAS STOPPED, + ALLFILES AND RELATED FUNCTIONS WILL NOT ACCEPT NAMESTRINGS + ANY MORE. (RRECALL THAT THE FILESPEC ARGUMENT IS A + LIST OF FILESPECS; THE TRAP IS THAT ERRONEOUSLY FEEDING + IT A SINGLE NAMELIST WILL MAKE IT THINK IT IS GETTING A + LIST OF NAMESTRINGS.) NAMELISTS AND FILE OBJECTS ARE STILL + ACCEPTABLE. IF YOU REALLY WANT TO ALLOW NAMESTRINGS, YOU + CAN ALWAYS SAY + (ALLFILES (MAPCAR 'NAMELIST FOO) ...) + AND BE VERY, VERY, VERY, VERY, VERY, VERY CAREFUL! + [B2] NEW OPTIONS ACCEPTED BY THE DIRECTORY AND MAPDIRECTORY FUNCTIONS: + BITS THE NUMBER OF BITS IN THE FILE + BYTES THE NUMBER OF BYTES IN THE FILE + BYTESIZE THE SIZE OF THE BYTES + CHARACTERS THE NUMBER OF CHARACTERS IN THE FILE + (THIS IS AN OLD OPTION, BUT NOW IT + YIELDS THE CORRECT CHARACTER COUNT RATHER + THAN ROUNDING UP TO A MULTIPLE OF FIVE) + +MONDAY MAY 16,1977 LQ+6D.8H.0M.26S. LISP 1272 - GLS - + +I BELIEVE THAT I HAVE FINALLY KILLED THE GC BUG THAT WAS +CAUSING THE TOPS-10 IMPLEMENTATION TO GET MPV ON STARTUP. +NUMEROUS OTHER BUGS HAVE BEEN KILLED ALSO. + +AS ALWAYS, NUMBERED ITEMS ARE FOR ALL LISPS, AND LETTERED +ONES FOR NEWIO ONLY. THE OTHERS ARE IN NON-STANDARD CATEGORIES. + +[1] THE VALUE OF HUNKP CONTROLS PRINT, PURCOPY, AND EQUAL +[2] PURE HUNKS EXIST (PURCOPY WILL WIN ON HUNKS) +[3] NEW PREDICATE: SYMBOLP +[4] CHANGES TO RANDOM; ALSO ([S]STATUS RANDOM). +[5] WARNING ABOUT MOST NEGATIVE NUMBER (THE "SETZ" PROBLEM) +[6] +, +$, AND THE LIKE NEVER DETECT OVERFLOW OR UNDERFLOW +[7] FLONUM OUTPUT HAS BEEN IMPROVED +[8] SQRT HAS BEEN IMPROVED +[9] VALUE OF FASLOAD IS NOW THE FUNCTION PROPERTIES TO CHECK + +[A] NEW FUNCTION: FILEP +[B] FOR INFERIOR JOB HACKERS: JOBS CAN HAVE "PROPERTY LISTS" +[C] ASCII MODE I/O TO AND FROM INFERIORS IS PRESENTLY BROKEN + +[&] THE NEW FUNCTION LH| PERFORMS A COMPLETELY WEIRD CROCK FOR LH + +[;] THE SEGMENT TABLE BITS $FXP AND $FLP HAVE BEEN CHANGED +---------------------------------------------------------------- +[1] THE VARIABLE HUNKP (INITIALLY T), IF NIL, CAUSES THE FUNCTIONS + PRINT, EQUAL, AND PURCOPY TO TREAT HUNKS AS LISTS (AS MOST + OTHER SYSTEM FUNCTIONS DO). IF NON-NIL, THEN THESE THREE + FUNCTIONS WILL TREAT THE HUNNKS AS HUNKS; IN PARTICULAR, + EQUAL WILL COMPARE THE HUNKS ELEMENT-BY-ELEMENT. + +[2] PURE HUNKS EXIST (PURCOPY WILL WIN ON HUNKS). THIS JUST FILLS + IN A TRIVIAL HOLE THAT I DIDN'T GET AROUND TO IMPLEMENTING + EARLIER. (STATUS PURSPCNAMES) WILL REFLECT THE PRESENCE + OF THIS FEATURE. + +[3] (SYMBOLP X) IS NON-NIL IFF X IS AN ATOMIC SYMBOL. + THIS CATEGORY INCLUDES NIL; THAT IS, (SYMBOLP 'NIL) => T. + +[4] THE RANDOM FUNCTION NOW HAS BETTER BEHAVIOR. THE TWO-ARGUMENT + FORM HAS BEEN ELIMINATED (WHICH USED TO INITIALIZE THE GENERATOR), + SINCE THE STATE CANNOT BE CONTAINED IN TWO FIXNUMS ANY MORE. + A NEW STATUS FUNCTION EXISTS FOR THIS PURPOSE. + (STATUS RANDOM) RETURNS A LIST WHICH SUMMARIZES THE STATE + OF THE RANDOM NUMBER GENERATOR. NO GUARANTEES ARE MADE AS TO + ITS FORMAT, EXCEPT THAT IT MAY BE FED AS AN ARGUMENT X TO + (SSTATUS RANDOM X), WHICH WILL RESTORE THE GENERATOR TO THAT + FROZEN STATE. (SSTATUS RANDOM N) FOR ANY FIXNUM N IS ALSO + PERMISSIBLE; THIS WILL INITIALIZE THE GENERATOR IN A WAY THAT + DEPENDS IN AN UNSPECIFIED WAY ON N. (THIS IS SO THAT PEOPLE + CAN DO, FOR EXAMPLE, (SSTATUS RANDOM (TIME)) OR SOMETHING.) + +[5] THE PDP-10 HARDWARE (BOTH KA10 AND KL10) HAS A WEIRD GLITCH TO + THE EFFECT THAT IT FAILS TO DIVIDE THE MOST NEGATIVE FIXNUM + (-400000000000) BY 1 CORRECTLY, EVEN THOUGH THE RESULTS ARE + WELL-DEFINED AND REPRESENTABLE. THE GENERIC FUNCTIONS + (QUOTIENT, *QUO, REMAINDER) HAVE BEEN FIXED TO COMPENSATE FOR + THIS PROBLEM; THEY ARE CONCEPTUALLY "GUARANTEED" TO RETURN + CORRECT ANSWERS INDEPENDENT OF SUCH HARDWARE LOSSES. HOWEVER, + THERE IS NO EFFECTIVE WAY TO FIX THE FIXNUM-ONLY FUNCTIONS + (//, \); SUCH FUNCTIONS ARE PERMITTED TO HAVE THE CHARACTERISTICS + IMPOSED BY THE HOST HARDWARE (THUS ON MULTICS // MAY HAVE + OTHER PECULIARITIES, FOR ALL I KNOW). THIS IS BECAUSE THESE + FUNCTIONS ARE INTENDED TO BE OPEN-CODED AS SINGLE HOST HARDWARE + INSTRUCTIONS. BEWARE! + +[6] THE FIXNUM- AND FLONUM-ONLY ARITHMETIC FUNCTIONS ARE NOW + *DEFINED* TO DO "WHAT THE HARDWARE DOES". THE INTERPRETED + VERSIONS USED TO DETECT OVERFLOW AND UNDERFLOW, BUT NO MORE. + THUS YOU CAN USE + TO COMPUTE STRANGE CHECKSUMS, ETC. + IN ANY CASE, COMPILED AND INTERPRETED CODE SHOULD BE COMPATIBLE + WITH RESPECT TO THESE FUNCTIONS. ANY PECULIAR SCREWS IN THE + HARDWARE ARE NOT COMPENSATED FOR (SEE [5] ABOVE). THE GENERIC + ARITHMETIC FUNCTIONS ARE "GUARANTEED" TO BEHAVE "MATHEMATICALLY" + AND TO COMPENSATE AS NECESSARY FOR SUCH SCREWS. + +[7] AN IMPROVED FLONUM PRINT ALGORITHM HAS BEEN INSTALLED. + I (GLS) HAVE "PROVED" THAT IT HAS THESE PROPERTIES: + (1) IT OUTPUTS ENOUGH DIGITS THAT NO INFORMATION IS LOST + (A PERFECT READER, WHICH I DO NOT YET CLAIM LISP HAS, + CAN ALWAYS RECOVER THE ORIGINAL FLONUM BY ROUNDING). + (2) IT OUTPUTS NO MORE DIGITS THAN NECESSARY TO ACHIEVE (1). + (3) IT OUTPUTS THE BEST POSSIBLE DECIMAL FLONUM OF THE + NUMBER OF DIGITS IN (2). + +[8] THANKS TO AN ALGORITHM FROM KAHAN AND HELP FROM RJF (FATEMAN), + THE SQRT ROUTINE HAS BEEN IMPROVED. IT IS CONSIDERABLY FASTER. + +[9] THE VALUE OF FASLOAD IS NOW THE LIST OF PROPERTIES FASLOAD SHOULD + CHECK FOR TO DECIDE WHETHER TO PRINT A WARNING MESSAGE. ITS + INITIAL VALUE IS (SUBR FSUBR LSUBR), AND SO WILL HAVE THE SAME EFFECT + AS BEFORE, WHEN THE INITIAL VALUE WAS T. ALSO AS BEFORE, SETTING FASLOAD + TO NIL WILL SUPPRESS ALL SUCH ERROR MESSAGES. ONE CAN BE VERY PARANOID, + FOR EXAMPLE, AND SET IT TO (EXPR SUBR LSRUB FEXPR FSUBR ARRAY MACRO). + +[A] THE PREDICATE FILEP RETURNS T IFF ITS ARGUMENT IS A FILE OBJECT. + IT WILL RETURN T EVEN IF IT IS A CLOSED FILE; TO DETECT AN OPEN + FILE, USE (AND (FILEP X) (STATUS FILEMODE X)). + +[B] INFERIOR JOB OBJECTS NOW HAVE AN EXTRA SLOT J.CRUFT + WHICH IS GC-PROTECTED. SEE SYS:.FASL DEFS FOR THE + JOB OBJECT DEFINITIONS. BY CONVENTION, THIS NEW SLOT + IS USED TO HOLD A PROPERTY LIST FOR VARIOUS DATA ABOUT + THE JOB. + +[C] BECAUSE OF AN ITS DEFICIENCY, THE NEW CODE THAT ALLOWS FILEPOS + TO WORK ON OUTPUT FILES AND SIOT TO BE USED FOR ALL ASCII I/O + DOESN'T WORK ON THE USR DEVICE (INFERIOR JOBS). THE BASIC + PROBLEM IS THAT SIOT DOESN'T WORK ON THE USR DEVICE IN ITS. + ONE CONSEQUENCE IS THAT LISPT WILL NOT WORK ON ITS 1051 AND ABOVE + (FOR WHICH THE NEW SIOT I/O CODE WILL BE PROVIDED IN LISP). + +[&] THE FUNCTION LH| IS A HACK FOR THE BENEFIT OF THIRD-FLOOR + HACKERS. IT NORMALLY EXISTS ONLY IN THE ITS VERSION. + THIS FEATURE IS ONLY SEMI-OFFICIAL, AND I WON'T GUARANTEE + IT TO WORK FOR ANYONE BUT LH AND FRIENDS. + (LH| ) ALLOCATES A CHUNK OF MEMORY + WORDS BIG OF DATA TYPE . (ACTUALLY, IS + ROUNDED UP TO BE AN INTEGRAL NUMBER OF PAGES.) + THE RETURNED VALUE IS A FIXNUM WHICH IS THE ADDRESS OF + THE FIRST WORD OF THE CHUNK OF MEMORY. IF ZERO IS RETURNED, + IT WAS NOT POSSIBLE TO OBTAIN THE MEMORY. (THIS SHOULD + BE FAMILIAR TO GETCOR HACKERS!) ONE SHOULD **NOT** USE + (DECLARE (FIXNUM (LH/|))); IT IS NOT A NUMBER FUNCTION + JUST BECAUSE IT RETURNS A FIXNUM! NOTICE THAT ONE MUST USE + A "/" TO GET THE "|" IN THE NAME OF THE FUNCTION. + THE CHUNK OF MEMORY WILL BE MADE TO HAVE THE DATA TYPE + INDICATED BY ; ONE CAN ALLOCATE THE MEMORY AT WILL + AND CREATE POINTERS INTO IT. GC WILL MARK FROM ALL WORDS + IN THE SPACE IF IS LIST, BIGNUM, OR ANY KIND OF HUNK. + HOWEVER, THE DATA IN THE MEMORY ITSELF IS NOT MARKED OR SWEPT. + NO GUARANTEES ARE MADE IF IS "SYMBOL" OR "ARRAY"; + ALL OTHER DATA TYPES SHOULD WORK, HOWEVER. + +[;] FOR ANY .FASL CODE HACKERS WHO MAY CARE: THE BITS $FXP AND + $FLP IN SEGMENT TABLE ENRTIES HAVE DISAPPEARED. THE BIT + THAT USED TO BE $FXP IS NOW CALLED $PDLNM, AND $FLP IS NO + LONGER USED. PDL NUMBER SEGMENTS NOW HAVE FX+$PDLNM OR + FL+$PDLNM SET INSTEAD OF $FXP OR $FLP. (THIS IS TO ALLOW + INTRODUCTION OF OTHER NUMBER PDLS IN THE FUTURE IF DESIRED.) + THIS CHANGE IS UPWARD-COMPATIBLE FOR COMPILED CODE WHICH + OPEN-CODES TYPE TESTS; EVENTUALLY THE COMPILER WILL BE + CHANGED TO REFLECT THE NEW BITS. + +THURSDAY MARCH 03,1977 FQ+6D.12H.27M.23S. LISP 1258 - GLS - + +WELL, WE ARE WORKING AWAY ON THE NEW LISP MANUAL! +ELLEN IS DOING MOST OF THE WORK, WITH OTHERS PITCHING +IN WRITING NEW TEXT (THE CONFLICTS BETWEEN WHICH ELLEN +GETS TO RESOLVE). CURRENTLY CHAPTERS 3 AND 4 ARE IN +PROGRESS. +THE FILES ".INFO.;OLDIO ORDER" AND ".INFO.;NEWIO ORDER" +CONTAIN A SUMMARY OF THE FUNCTIONS AND VARIABLES AVAILABLE +IN LISP. I WILL TRY TO KEEP THESE UP-TO-DATE (THEY ARE +MECHANICALLY GENERATED). +THE FOLLOWING NAMING SCHEME TAKES EFFECT ON ITS AS OF THIS VERSION. +-> MEANS "IS LINKED TO" (DISK-TYPE FILE NAME LINKS). + + L -> LISP -> NEWIO + Q -> NEWIO -> SYS:PURQIO > + O -> OLDIO -> SYS:PURBIB > + OL -> OLISP -> ONEWIO + OQ -> ONEWIO -> SYS:PURQIO NNN (FOR SOME NNN) + OO -> OOLDIO -> SYS:PURBIB NNN (FOR SOME NNN) + OOL -> OOLISP -> OONEWIO + OOQ -> OONEWIO -> SYS:PURQIO < + OOO -> OOOLDIO -> SYS:PURBIB < + +THAT IS, L^K AND LISP^K NOW ALWAYS GET YOU A NEWIO. +SO DO Q^K AND NEWIO^K. TO GET AN OLDIO, USE O^K OR OLDIO^K. +THE "O" AND "OO" VERSIONS GET OLD AND VERY OLD VERSIONS. +THIS WAS ALREADY IN EFFECT ON AI, BUT IS NOW ON ALL ITS +MACHINES. +MANY BUGS HAVE BEEN FIXED IN THIS VERSION, INCLUDING +THE ONE ABOUT GC-OVERFLOW (I HOPE!). MANY NEW FEATURES +AS FOLLOWS. AS ALWAYS, NUMBERED ITEMS ARE FOR ALL LISPS, +AND LETTERED ITEMS FOR NEWIO ONLY. + +[1] NEW FUNCTION: QUIT (COMPATIBLE WITH MULTICS VERSION) +[2] CHANGES TO GC-RELATED USER INTERRUPTS: + [2A] GC-OVERFLOW WORKS BETTER - CAN GET SEVERAL PER GC + [2B] GC-DAEMON GETS MORE INFORMATION NOWADAYS +[3] CHANGES TO STATUS FUNCTIONS: + [3A] (STATUS PURSPCNAMES) YIELDS NAMES OF ALL PURE SPACES + [3B] (STATUS HACTRN) YIELDS T FOR UNKNOWN SUPERIOR + [3C] (STATUS XJNAME) HAS BEEN RENAMED (STATUS SUBSYSTEM) + [3D] (STATUS XUNAME) HAS BEEN RENAMED (STATUS USERID) + [3E] (STATUS FEATURE TOPS-10) IS BEST WAY TO CHECK FOR TOPS-10 + [3F] WE ARE PHASING OUT (STATUS TERPRI) - USE TERPRI VARIABLE + +[A] FILEPOS WORKS ON OUTPUT FILES - ALL ITS I/O USES SIOT NOW +[B] INCLUDE PROVIDES AN EOFFN TO MAKE EOF TRANSPARENT +[C] AUTOLOAD NOW USES LOAD INSTEAD OF FASLOAD (LIKE MULTICS) +[D] DELETEF OF AN OPEN FILE NOW USES DELEWO (IT USED TO JUST LOSE) +[E] THE RENAME FUNCTION HAS BEEN RENAMED TO RENAMEF +[F] (STATUS TTYREAD) IS NOW IN THE READTABLE AGAIN IN NEWIO +[G] NUMERIC (STATUS TTYINT) VALUES CAN NOW FILTER ALL SUPRA-ASCII BITS +---------------------------------------------------------------- +[1] (QUIT), AS ON MULTICS, CAUSES THE LISP JOB TO COMMIT SUICIDE. + (IT DOES NOT PRODUCE A ^G OR ^X QUIT - FOR THOSE, USE THE + ^G FUNCTION OR (ERROR 'QUIT)!) + QUIT IS ACTUALLY AN LSUBR OF 0 TO 1 ARGUMENTS. POSSIBLE + VALUES FOR THE ARGUMENT: + NIL SAME AS NO ARGUMENT - DO A NORMAL QUIT + T QUIT AS NOISELESSLY AS POSSIBLE (DON'T PRINT :KILL, ETC.) + ERROR ERROR QUIT. FLUSH TYPEAHEAD, AND GENERALLY CLEAN UP. + A FIXNUM ARGUMENT IS MACHINE-DEPENDENT. ON ITS, IT IS + FED AS THE EFFECTIVE ADDRESS FOR .BREAK 16,. + +[2] CHANGES TO GC-RELATED USER INTERRUPTS: + [2A] IT USED TO BE THAT IF SEVERAL SPACES GOT A GC-OVERFLOW + CONDITION DURING A SINGLE GC, ONLY ONE INTERRUPT WOULD + BE SIGNALED. NOW ALL OF THEM SHOULD BE SIGNALLED, AS + SEPARATE INTERRUPTS. + [2B] THE ARGUMENT RECEIVED BY GC-DAEMON HAS BEEN CHANGED + IN AN INCOMPATIBLE MANNER. THE OLD FORMAT WAS: + ( ( . ) ...) + THE NEW FORMAT IS: + ( ( + ) + ...) + THE TWO NEW QUANTITIES ARE THE SIZE OF THE SPACE AT + THE BEGINNING AND END OF THE GC. THE DIFFERENCE OF + THESE TWO QUANTITIES GIVES THE AMOUNT OF SPACE + ADDED DURING THE GC, WHILE THE DIFFERENCE BETWEEN + AND THE FROM THE PREVIOUS + GC GIVES THE AMOUNT ADDED BETWEEN GC'S. NOTE ALSO + THAT THE NEW FORMAT DOESN'T HAVE THAT CRETINOUS + DOTTED PAIR, SO LATER MORE INFORMATION CAN BE ADDED + COMPATIBLY. + +[3] CHANGES TO STATUS FUNCTIONS: + [3A] (STATUS PURSPCNAMES) YIELDS NAMES OF ALL PURE SPACES. + PRESENTLY THIS IS (LIST FIXNUM FLONUM BIGNUM), + BUT IN CASE THIS EVER CHANGES, THIS STATUS CALL IS + THE RIGHT WAY TO FIND THEM ALL. RECALL THAT + (STATUS SPCNAMES) GIVES THE NAMES OF NON-PURE SPACES. + [3B] (STATUS HACTRN) YIELDS T FOR UNKNOWN SUPERIOR. + AS BEFORE, IT CAN ALSO YIELD "DDT" FOR A DDT SUPERIOR, + "LISP" FOR A LISP SUPERIOR (THIS IS DETERMINED BY + BITS IN THE .OPTION USER VARIABLE), OR NIL FOR NO + SUPERIOR. + [3C] (STATUS XJNAME) HAS BEEN RENAMED (STATUS SUBSYSTEM). + EVENTUALLY THIS WILL BE MADE MEANINGFUL ON TOPS-10 + AND MULTICS IMPLEMENTATIONS. THE INTENDED INTERPRETATION + IS "THE GENERIC NAME OF THIS PROGRAM". + (STATUS JNAME) IS TO BE INTERPRETED AS "THE UNIQUE + IDENTIFIER OF THIS JOB WITHIN THE TIME-SHARING SYSTEM". + [3D] (STATUS XUNAME) HAS BEEN RENAMED (STATUS USERID). + EVENTUALLY THIS WILL BE MADE MEANINGFUL ON TOPS-10 + AND MULTICS IMPLEMENTATIONS. THE INTENDED INTERPRETATION + IS "THE GENERIC NAME OF THIS USER (E.G. "FRED"). + (STATUS UNAME) IS TO BE INTERPRETED AS "THE UNIQUE + IDENTIFIER OF THIS LOGGED-IN INSTANCE OF THE USER + WITHIN THE TIME-SHARING SYSTEM". + [3E] (STATUS FEATURE TOPS-10) IS BEST WAY TO CHECK FOR + RUNNING UNDER A REAL TOPS-10 SYSTEM. WE MAY PHASE OUT + (STATUS FEATURE DEC10), OR LET IT MEAN ANY TOPS-10-LIKE + SYSTEM, SUCH AS SAIL. WE ALSO ANTICIPATE HAVING TO + INTRODUCE (STATUS FEATURE TOPS-20) SOMEDAY. + [3F] WE ARE PHASING OUT (STATUS TERPRI). PLEASE ELIMINATE + FROM YOUR PROGRAMS IF POSSIBLE. IN NEWIO YOU CAN SET + THE LINEL OF A FILE TO 0 INSTEAD, OR YOU CAN BIND + THE TERPRI VARIABLE. + +[A] FILEPOS NOW WORKS ON OUTPUT FILES, THANKS TO IMPROVEMENTS + TO ITS. THIS ONLY WORKS IN ITS VERSION 1048 OR GREATER, + AND SO WILL NOT APPEAR ON A GIVEN MACHINE UNTIL A VERSION + OF ITS APPEARS WHICH CAN SUPPORT THE FEATURE. + AS A COROLLARY, ALL LISP BUFFERED I/O IS DONE WITH SIOT. + IN THIS WAY EXACT CHARACTER COUNTS ARE USED, ELIMINATING + THE TRAILING CONTROL-C PROBLEM. + +[B] INCLUDE PROVIDES AN EOFFN TO MAKE EOF TRANSPARENT. + WHEN READING OFF THE END OF AN INCLUDED FILE, NO EOF + SHOULD BE DETECTED (UNLESS READ WAS IN THE MIDDLE OF AN + OBJECT, WHICH CAUSES A FAIL-ACT); READING SHOULD JUST + CONTINUE IN THE FILE POPPED OFF THE INSTACK. THIS MEANS + THAT AN INCLUDED FILE IS JUST LIKE STICKING THE INCLUDED + FILE IN THE MIDDLE OF THE INCLUDING I/O STREAM. + +[C] AUTOLOAD NOW USES LOAD INSTEAD OF FASLOAD (LIKE MULTICS). + +[D] DELETEF OF AN OPEN FILE NOW USES DELEWO (IT USED TO JUST LOSE). + THIS TOO DEPENDS ON ITS VERSION 1048 OR GREATER. + +[E] THE RENAME FUNCTION HAS BEEN RENAMED TO RENAMEF. + THIS IS FOR COMPATIBILITY WITH DELETEF, MERGEF, PROBEF, ETC., + AND TO AVOID USING UP A GOOD WORD. + +[F] (STATUS TTYREAD) IS NOW IN THE READTABLE AGAIN IN NEWIO. + THIS IS COMPATIBLE WITH OLDIO, AND ALSO MAKES MORE SENSE + SINCE IT IS RELATED TO THE FORCE-FEED BITS WHICH ARE ALSO + IN THE READTABLE. SINCE IT NEVER WORKED BEFORE IN NEWIO + ANYWAY, THIS SHOULD NOT BREAK ANY PROGRAMS! + +[G] RECALL THE FORMER OBSCURE FEATURE THAT IF AN "INTERRUPT + FUNCTION" FOR THE KEYBOARD SET VIA (SSTATUS TTYINT) IS A + FIXNUM, THEN IT SPECIFIES THE DEFAULT LISP ACTION FOR + AN INTERRUPT CHARACTER OF THAT ASCII VALUE; AND THAT FURTHERMORE + SUPRA-ASCII BITS COULD BE USED TO FILTER THE CONTROL AND + META BITS, NAMELY 400 REQUIRED THE META BIT TO BE PRESENT + FOR THE ACTION TO OCCUR, AND 400_22 FORBADE THE PRESENCE + OF THE META BIT, AND SIMILARLY FOR 200 AND THE CONTROL BIT. + THIS HAS BEEN EXTENDED TO THE TOP BIT (4000), THE SHIFT-LOCK + BIT (2000), AND THE SHIFT BIT (1000). IF YOU REALLY WANT + TO HACK AROUND WITH 12-BIT KEYBOARD INPUT, THIS IS YOUR + CUP OF T. + +THURSDAY JAN 06,1977 FM+1D.23H.52M.11S. LISP 1252 - GLS - + +WELL, FOLKS, JONL HAS GONE TO IBM FOR SEVERAL MOONS, AND I AM WORKING +ON MY THESIS THIS SEMESTER (DUE IN MAY), SO DON'T EXPECT TO GET +NEW FEATURES IMPLEMENTED WITH BLINDING SPEED. I WILL DO MY BEST TO +FIX ANY BUGS THAT CROP UP (IN PARTICULAR, I BELIEVE I HAVE FIXED +THE NEFARIOUS FASLOAD BUG OF VERSION 1251). MOST OF THE ITEMS +BELOW ARE NOT BRAND NEW, BUT JUST THINGS THAT DIDN'T WORK UNTIL NOW +OR WERE NEVER DOCUMENTED PROPERLY. + +AS USUAL, NUMBERS=ALL LISPS, LETTERS=NEWIO ONLY. + +[1] PRINC NOW NO LONGER AUTO-TERPRI'S BEFORE ATOMS. +[2] NEW "EVALSHUNT" HACK FOR PECULIAR FORMS. +[3] GC NOW MARKS HUNKS MORE SPACE-EFFICIENTLY. +[4] HOW TO DEFINE NEW EDITOR COMMANDS. + +[A] NEW FUNCTION: +TYO +[B] SEEING GC STATISTICS IN THE WHO-LINE. +---------------------------------------------------------------- +[1] PRINC NOW NO LONGER ATTEMPTS TO GET IN A TERPRI BEFORE AN + ATOM IF NECESSARY. (IT DOES, HOWEVER, PROVIDE A TERPRI ON + REACHING THE LINEL UNLESS OTHERWISE OVERRIDDEN BY THE VALUE OF + TERPRI OR BY (SSTATUS TERPRI ...).) PRIN1 CONTINUES TO PUT + IN AUTO-TERPRI'S BEFORE ATOMS. + +[2] WHEN EVAL COMES UPON A FORM WHOSE CAR IS NON-ATOMIC AND + WHOSE CAAR IS NOT LAMBDA, FUNARG, OR LABEL, AND IF THE + VALUE OF THE ATOM EVAL IS NON-NIL, THEN THIS VALUE + SHOULD BE A FUNCTION OF ONE ARGUMENT, AND IT IS CALLED ON THE + FORM. IT IS THE RESPONSIBILITY OF THE FUNCTION TO EVALUATE THE + FORM AND DELIVER AN APPROPRIATE VALUE. THIS IS KNOWN AS THE + "EVALSHUNT" KLUDGE. + +[3] GC NOW TAKES MUCH LESS PDL TO MARK HUNKS. IF YOU HAVE GOTTEN + PDL OVERFLOW DURING GC WHILE USING HUNKS, THIS SHOULD ALLEVIATE + YOUR PROBLEM. + +[4] IF EDIT READS A COMMAND WHOSE NAME IS NOT RECOGNIZED, THEN IF THE + ATOM OF THAT NAME HAS AN EDIT PROPERTY, THEN THAT PROPERTY SHOULD + BE A FUNCTION. IT WILL BE CALLED WITH THE REPEAT COUNT AS AN ARGUMENT + (0 IS SUPPLIED IF NO ARGUMENT IS GIVEN). THE FUNCTION MAY + DO ANYTHING IT LIKES, BUT WILL PROBABLY WANT TO OPERATE ON THE + FUNCTION BEING EDITED. THE EDITOR'S CURSOR IS REPRESENTED BY + TWO DATA STRUCTURES, THE "LEFT-LIST" AND THE "UP-LIST". + THE FORMER SAYS HOW TO BACK UP AT THE CURRENT LEVEL OF LIST; + THE LATTER SAYS HOW TO BACK UP A LEVEL OF LIST STRUCTURE. + THE LEFT-LIST IS THE VALUE OF THE ATOM  (THREE ALTMODES), + AND THE UP-LIST IS THE VALUE OF THE ATOM ^^^ (THREE UPARROWS OR + CIRCUMFLEXES, ASCII 136). + THE CAR OF THE LEFT-LIST IS THE LEVEL OF LIST STRUCTURE BEING + EDITED; THE CURSOR IS CONSIDERED TO BE BEFORE THE CAAR + OF THE LEFT-LIST. THE CDR OF THE LEFT-LIST IS THE LEFT-LIST + FOR THE PREVIOUS POINT IN THIS LEVEL OF LIST. THE UP-LIST + IS A STACK OF OLD LEFT-LISTS. + THE FOLLOWING FUNCTIONS ARE USEFUL UTILITIES FOR BUILDING + NEW EDITOR FUNCTIONS, AND ILLUSTRATE THE CORRECT WAY TO MANIPULATE + THE LEFT-LIST AND UP-LIST. + (DEFUN RIGHT () (AND (EDCAR) (SETQ  (CONS (CDAR ) )))) + (DEFUN LEFT () (AND  (CDR ) (SETQ  (CDR )))) + (DEFUN DOWN () (AND (EDCAAR) + (SETQ ^^^ (CONS  ^^^)  (NCONS (CAAR ))))) + (DEFUN UP () (AND ^^^ (CAR ^^^) (CDR ^^^) + (SETQ  (CAR ^^^) ^^^ (CDR ^^^)))) + (DEFUN YANK (FN) + ((LAMBDA (PL) + (COND (PL (SETQ ^^^ NIL) + (SETQ  (NCONS PL))) + (T (PRINC '|??|)))) + (GETL FN EDIT))) + (DEFUN SPLICE (IT) + (COND ((AND (LEFT) (EDCAR)) + (RPLACD (CAR ) IT) + (RIGHT)) + ((AND (UP) (EDCAR)) + (RPLACA (CAR ) IT) + (DOWN)))) + (DEFUN KILL () + (PROG2 NIL (CAAR ) + (SPLICE (COND ((EDCAR) (CDAR )) (T (CAR )))))) + (DEFUN INSERT (IT) + (SPLICE (CONS IT (AND  (CAR )))) + (RIGHT)) + + (DEFUN EDCAR () (AND  (NOT (ATOM (CAR ))))) + (DEFUN EDCAAR () (AND (EDCAR) (NOT (ATOM (CAAR ))))) + + NOTICE THAT LEFT AND RIGHT AND UP AND DOWN RETURN NIL + IF THEY FAIL. KILL RETURNS THE THING KILLED (THE STANDARD + EDITOR COMMAND "K" PUTS THIS THING INTO THE VALUE CELL OF "".) + AS TWO EXAMPLES OF NEW EDITOR COMMANDS, CONSIDER + "XCH" (NOTE THAT NAMES OF EDITOR COMMANDS MUST BE THREE CHARACTERS OR + FEWER), WHICH TRANSPOSES THE NEXT TWO ITEMS AFTER THE CURSOR, + AND "BRY", WHICH BURIES THE NEXT THING IN LEVELS + OF LIST STRUCTURE. + + (DEFPROP XCH ED-EXCHANGE EDIT) + (DEFUN ED-EXCHANGE (N) ;ARGUMENT IS IGNORED + (INSERT (PROG2 NIL (KILL) (RIGHT)))) + + (DEFPROP BRY ED-BURY EDIT) + (DEFUN ED-BURY (N) + (AND (EDCAR) + (DO ((I (MAX N 1) (- I 1))) + ((ZEROP I)) + (SPLICE (RPLACA (CAR ) (NCONS (CAAR ))))))) + + I HAVE TESTED THESE DEFINITIONS AND THEY SEEM TO WORK. + +[A] THE NEW FUNCTION +TYO OF TWO ARGUMENTS IS A SUPER-FAST TYO. + THE FIRST ARGUMENT IS THE ASCII VALUE TO OUTPUT AND THE + SECOND IS THE FILE TO OUTPUT IT ON. THE ATOM "T" MAY NOT + BE USED AS A SECOND ARGUMENT; INSTEAD OF (+TYO 43 T), SAY + (+TYO 43 TYO) OR THE EQUIVALENT. ALSO, THE SECOND ARGUMENT + MUST BE A SINGLE FILE, NOT A LIST OF FILES. THE +TYO FUNCTION + DOES NO ARGUMENT CHECKING IF NOT IN *RSET MODE. + IT DOES NOT ATTEMPT TO UPDATE THE CHARPOS OF THE FILE, OR + SUPPLY AN AUTO-TERPRI FOR EXCEEDING THE LINEL. IT DOES CHECK + FOR NON-IMAGE-MODE TTY FILES AND IN THAT CASE CONVERT ^P AND ^C + TO ^P P AND ^P Q. IT ALSO UPDATES THE FILEPOS CORRECTLY. + +[B] NEWIO HAS HAD FOR SOME TIME STATUS CALLS FOR MANIPULATING THE + WHO-LINE; THESE WERE DESCRIBED PREVIOUSLY IN LISP ARCHIV. + NOW A NEW STATUS CALL CONTROLS THE DISPLAY OF GC STATISTICS IN + THE WHO-LINE. + (STATUS GCWHO) RETURNS THE CURRENT GCWHO STATUS AS A FIXNUM. + (SSTATUS GCWHO ) SETS THE STATUS TO THE FIXNUM . + RIGHT NOW ONLY THE 1 AND 2 BITS OF THE STATUS ARE SIGNIFICANT. + 1 MEANS THAT DURING A GC, THE WHO-LINE SHOULD BE ALTERED TO + READ "GC:XXXXX" WHERE XXXXX IS THE REASON FOR THE GC. + AT THE END OF THE GARBAGE COLLECTION THE WHO-LINE IS RESTORED. + 2 MEANS THAT AT THE END OF THE GC THE .WHO2 WORD SHOULD + BE CLOBBERED WITH GC RUN TIME INFORMATION. SPECIFICALLY, + THE LEFT HALF GETS THE PERCENTAGE OF RUN TIME WHICH HAS BEEN + SPENT IN GC, AND THE RIGHT HALF GETS THE GC RUN TIME IN FORTIETHS + OF A SECOND. IF THE FIRST TWO ARGUMENTS TO (SSTATUS WHO1 ...) + ARE 52 OCTAL AND '%, THEN THESE STATISTICS WILL BE PRINTED + IN THE FORM "NNN% HH:MM:DD.T", JUST LIKE THE STANDARD SYSTEM + RUNTIME PERCENTAGE AND VALUE. IN THIS WAY ONE CAN CONTINUOUSLY + MONITOR GC RUN TIME STATISTICS. THE 1 AND 2 BITS MAY BE USED + TOGETHER (3) OR INDEPENDENTLY. NOTE THAT WHILE USING THE 2 BIT + THE .WHO3 VARIABLE IS STILL LEFT OVER FOR USE BY THE USER. + THUS ONE MIGHT SAY: + (SSTATUS WHO1 52 '% 166 0) + (SSTATUS GCWHO 3) + (SSTATUS WHO3 'QUUX) + AND ONE WOULD NORMALLY SEE "43% 00:15:07.8 QUUX", BUT DURING + A GC ONE WOULD SEE "GC:FIXNUM" OR WHATEVER. + A NOTE FOR THOSE WHO USE SUSPEND: IF THE SUSPENDED JOB IS DUMPED + OUT AND LATER RELOADED, THE RUNTIME (MAINTAINED BY THE TIME-SHARING + SYSTEM) WILL HAVE BEEN RESET, BUT NOT THE GCTIME, WHICH IS MAINTAINED + BY LISP. THEREFORE A ROUTINE WHICH DOES A SUSPEND SHOULD PERFORM + (SSTATUS GCTIME 0) ON RETURN FROM THE SUSPEND IN ORDER TO MAKE + THE WHO-LINE AND OTHER GC STATISTICS ACCURATE. + + +WEDNESDAY DEC 29,1976 FQ+1D.9H.29M.54S. LISP 1251 -JONL- + + +AS USUAL, NUMBERED ITEMS APPLY BOTH TO OLDIO AND NEWIO LISPS; +LETTERED ITEMS APPLY ONLY TO NEWIO. + +1) THE FUNCTION "RANDOM" HAS BEEN SLIGHTLY IMPROVED +2) NUMBERS GIVEN AS FILE-NAME ARGUMENTS ARE NOW CONVERTED TO + SYMBOLIC STRINGS ACCORDING TO A RIGID ALGORITHM. +3) ALLOC NO LONGER ASKS FOR "CORE?". +4) ALL VERSIONS ARE NOW BIBOP. TOPS-10 VERSION IS FULLY BIBOPIFIED. +5) MACDMP HAS BEEN FLUSHED. USE SUSPEND. +6) THE VALUE OF THE ATOM "TERPRI" NOW CONTROLS THE AUTOMATIC + INSERTION OF NEWLINE CHARACTERS IN THE CHARACTER OUTPUT STREAMS. +7) MORE THINGS OPEN-CODED BY NCOMPLR, AND OTHER UPDATES +8) EDIT ALLOWS THE USER TO DEFINE NEW EDITING FUNCTIONS: + + +[A] HOW TO USE DEFAULT LINEL AND PAGEL FOR FILES. +[B] NCOMPLR THINKS IT KNOWS ABOUT INCLUDE NOW +[C] WHO-LINES ON AI TV-TERMINALS ARE NOW USABLE. + +---------------------------------------------------------------- + +1) "RANDOM" CHANGED SLIGHTLY. NEW ALGORITHM FROM KNUTH IS MUCH + BETTER - NO LONGER HAS THE CORRELATED-TRIPLES PROPERTY. + (RANDOM NIL) AS WELL AS ANY TWO-ARGUMENT CALL TO RANDOM RESTARTS + THE GENERATOR OVER AT ITS BEGINNING. TIMING IS THE SAME. +2) FIXNUMS GIVEN AS FILE NAMES: PREVIOUSLY, THESE WERE CONVERTED + TO CHARACTER STRINGS MERELY BY PRINTING IN THE CURRENT BASE. + NOW, THE BASE IS TEMPORARILY LAMBDA-BOUND TO TEN, AND *NOPOINT + TO NIL, DURING THE CONVERSION. FOR EXAMPLE, IF BASE=IBASE=8, + THEN TYPING IN AND EVALING THE FORM + (UREAD TEST 131 DSK LOSER) + WILL RESULT IN SELECTING THE FILE DSK:LOSER;TEST 89 +3) ALLOC NO LONGER ASKS FOR "CORE". A # WILL PROMP THE ENTRIES THAT + CANNOT BE EXPANDED AFTER ALLOCATION. FOR ITS VERSIONS ONLY THE + PDLS CANNOT BE EXPANDED, BUT IN THE TOPS-10 VERSION, + BINARY-PROGRAM-SPACE MAY NOT BE FURTHER EXPANDED. + +4) AND 5) HOORAY, HOORAY! + +6) THE VALUE OF THE ATOM "TERPRI" NOW CONTROLS THE AUTOMATIC + INSERTION OF NEWLINE CHARACTERS IN THE CHARACTER OUTPUT STREAMS. + IF NON-NIL, THEN ALL SUCH AUTOMATIC INSERTION IS SUPPRESSED FOR + ALL OUTPUT FILES AND DEVICES, REGARDLESS OF THEIR PARTICULAR + LINELS. IN NEWIO, IF THE LINEL FOR A PARTICULAR OUTPUT FILE IS 0, + THEN THE AUTOMATIC INSERTION IS SUPPRESSED FOR THAT FILE. + +7) NCOMPLR NOW OPEN-CODES TYPEP, ATOM, NUMBERP, FIXP, FLOATP, BIGP, + ZEROP, MINUSP, PLUSP, AND HUNKP USING THE SEGMENT TABLE. + FOR TOPS-10 LUSERS: THE MAKLAP PARSER ACCEPTS PPN DESIGNATIONS + IN SQUARE BRACKETS. + FOR ITS LUSERS: @DEFINE HAS BEEN DEFINED. SEE DOCUMENTATION + FOR THE @ CROSS-REFERENCING PROGRAM. + THE VALUE OF THE ATOM "GCPROTECT" NOW CONTROLS HOW LAP AND FASLOAD + USE THAT FUNCTION. THIS IS A SPECIAL HAC FOR OWL SYSTEM, AND + NO ONE ELSE SHOULD EVER SET "GCPROTECT" TO NON-NIL. + +8) EDIT ALLOWS THE USER TO DEFINE NEW EDITING FUNCTIONS. PUTTING AN + "EDIT" PROPERTY ON AN ATOM MAKES IT AN EDITOR COMMAND, AND WHEN + INVOKED, THAT FUNCTIONS IS CALLED WITH THREE ARGUMENTS: + I) REPEAT COUNT + II) THE CURRENT "LEFT-LIST" (VALUE OF THE ATOM ) + III) THE CURRENT "UP-LIST" + FOR MORE DETAILS, SEE THE FILE MC:LISP;EDITOR > + + +[A] WHENEVER A FILE-OBJECT IS CREATED, SUCH AS BY "OPEN", THE LINEL AND + PAGEL ARE SET FROM AN INTERNAL DEFAULT VALUE. THESE VALUES ARE + ACCESSED BY (LINEL NIL) (PAGEL NIL), AND SET TO NEW VALUES BY + (LINEL NIL ) (PAGEL NIL ) + +[B] QCOMPLR THINKS IT KNOWS ABOUT INCLUDE. WHAT MORE CAN WE SAY? + +[C] THERE ARE THREE WHO-LINES USABLE FROM LISP ON THE AI MACHINE, + AND THE GARBAGE-COLLECTOR CAN DISPLAY ITS OPERATIONS ON A WHO-LINE + QUUX WILL DOCUMENT THIS STUFF AS AND WHEN IT IS OPERATIONAL. + + + TUESDAY SEPT 14,1976 FM+6D.1H.33M.7S. LISP 1211 -GLS,JONL- + +OLDIO AND NEWIO LISPS NOW BOTH ANNOUNCE THEMSELVES AS SUCH. +YOU CAN GET AN OLDIO BY TYPING OLDIO^K OR O^K; AS BEFORE, +NEWIO^K OR Q^K GETS A NEWIO. IN THE NEAR FUTURE, LISP^K +AND L^K WILL START PROVIDING A NEWIO INSTEAD OF AN OLDIO. +OLDIO WILL STILL BE AVAILABLE AS OLDIO^K OR O^K FOR SEVERAL +MONTHS AFTER THAT. + +NUMBERED ITEMS BELOW APPLY TO ALL LISPS; LETTERED ONES TO NEWIO ONLY. + +[1] WHAT ARE PEOPLE USING HUNKS FOR? +[2] NEW ARITHMETIC FUNCTION: IFIX +[3] "AUTOLOAD" HAS LOWER PRIORITY THAN OTHER FUNCTIONAL PROPERTIES +[4] ALLOC FUNCTION AND GC PRINTOUT SUPPRESS ZERO-SIZE SPACES +[5] EVALHOOK NOW HOOKS BOTH A MACRO CALL AND ITS EXPANSION +[6] NEW .FASL MACRO PRINTS SUPPRESSABLE LOAD MESSAGE +[7] CHANGES TO EDIT FUNCTION AND NEW COMMANDS + +[A] NEWIO NOW PROVIDES A ##MORE## PROCESSOR +[B] NEW NVID, SLAVE, MPX PACKAGES FOR NEWIO +[C] PROBLEM WITH INIT FILES IN NEWIO: UREAD DOESN'T CLOSE THEM +[D] UNTRAPPED MEMORY AND MACHINE ERRORS NOW GO TO DDT +[E] CHANGES TO HANDLING OF TTY BLOCK OUTPUT +[F] BUG OF FASLOAD FROM WITHIN FASLOAD-FILE-NOT-FOUND BREAK FIXED +[G] STUPID SPACE-SWALLOWING THING ONLY HAPPENS IF READ IS NIL +[H] NEW CURSORPOS FEATURES: A, H, I, V +[I] THE ACTION AT END-OF-FILE HAS BEEN CHANGED +---------------------------------------------------------------- +[1] IF YOU USE HUNKS, SEND SOME MAIL TO GLS SAYING FOR WHAT. + (JUST NOSY, I GUESS.) NCOMPLR NOW OPEN-CODES CXR. + +[2] (IFIX X) IS JUST LIKE (FIX X), EXCEPT THAT X IS CONSTRAINED TO BE + WITHIN THE RANGE OF FIXNUMS. WHILE "FIX" MAY RETURN A BIGNUM, + "IFIX" WILL NOT, AND THIS ALLOWS EFFICIENT OPEN-CODING OF "IFIX". + CAVEAT EMPTOR! THIS IS NOT THE SAME FUNCTION AS FORTRAN'S "IFIX": + THIS ONE IS THE SAME AS THE "ENTIER" FUNCTION, AS IN ALGOL. + +[3] WHENEVER LISP LOOKS UP A FUNCTION ON A PROPERTY LIST, IT + WILL NOW PREFER A SUBR, EXPR, ETC. TO AN AUTOLOAD PROPERTY + EVEN IF THE SUBR (OR WHATEVER) OCCURS AFTER THE AUTOLOAD + PROPERTY ON THE PROPERTY LIST. THAT IS, IT EFFECTIVELY + LOOKS FOR OTHER FUNCTIONAL PROPERTIES FIRST, AND ONLY ON + FAILURE DOES LISP CHECK FOR AN AUTOLOAD PROPERTY. + THIS FIXES THE SCREW WHERE ONE PACKAGE DEFINES THE SUBR + FOO AND THEN ANOTHER DOES (DEFPROP FOO ... AUTOLOAD). + +[4] IF A SPACE HAS ZERO SIZE (OFTEN TRUE OF HUNK SPACES!), + THEN THE ALLOC FUNCTION WILL NOT INCLUDE THE SPACE IN + THE RETURNED DATA, AND GC STATISTICS PRINTOUT WILL NOT + MENTION THE SPACE. (STATUS SPCNAMES) WILL, HOWEVER, + MENTION ALL SPACES, EVEN THOSE OF ZERO SIZE. + +[5] EVALHOOK NOW HOOKS BOTH A MACRO CALL AND ITS EXPANSION. + FORMERLY THE HOOK FUNCTION SAW THE MACRO CALL, AND THEN + THE FIRST FORM WITHIN THE EXPANSION, BUT NOT THE EXPANSION + ITSELF. + +[6] MANY AUXILLIARY FILES, SUCH AS "GRIND", "LAP", "ALLFILES", ETC. + WHICH ARE AUTOLOADABLE, OR FASLOADED BY THE USER, PRINT A MESSAGE + ANNOUNCING THEIR VERSION NUMBER AND THE FACT THAT THEY ARE BEING + LOADED. FOR EXAMPLE, WHEN ALLFILES IS LOADED, IT PRINTS + ;LOADING ALLFILES 43 + BY CONVENTION, ALL SUCH LOADING MESSAGES ARE SUPPRESSED IF THE + USER HAS DONE (SSTATUS FEATURE NOLDMSG). ALL SUCH FILES WRITTEN + IN LISP HAVE EXPR CODE WHICH CHECKS THE FEATURE LIST FOR + "NOLDMSG", AND IF ABSENT, PRINTS THE LOADING MESSAGE. + TO FACILITATE SUCH A MESSAGE PRINTING FEATURE FOR PACKAGES WRITTEN + IN MIDAS, THE STANDARD FILE "SYS:.FASL DEFS", TO BE INSERTED BY + .FASL FILES, NOW HAS A MACRO "VERPRT". ITS ARGUMENT SHOULD BE + THE NAME OF THE PACKAGE; IT GENERATES A .SXEVAL FORM WHICH + WILL PRINT A MESSAGE WHEN THE FILE IS LOADED. FOR EXAMPLE, + THE ALLFILES PACKAGE EFFECTIVELY BEGINS: + TITLE ALLFILES + .FASL + .INSRT SYS:.FASL DEFS + VERPRT ALLFILES + + THE GENERATED FORM WORKS IN EITHER OLDIO OR NEWIO; + IN NEWIO, THE MESSAGE IS PRINTED ON THE FILES SPECIFIED + BY THE VARIABLE "MSGFILES" (WHICH IS ALSO USED BY ALL LISP + SYSTEM MESSAGES). + +[7] CHANGES TO THE "BINFORD EDITOR" (EDIT FUNCTION): + [7.1] THE COMMANDS "C" AND "-C" HAVE DISAPPEARED. + THEY WERE EQUIVALENT TO THE STILL-EXISTING + "F" AND "-F" COMMANDS. + [7.2] "SS" = "SAVE SPOT", "RS" = "RESTORE SPOT" + BOTH TAKE AN ATOMIC SYMBOL AS AN ARGUMENT. + SS SAVES THE CURRENT "SPOT" (WHERE THE $$ APPEARS) + AS THE VALUE OF THE SPECIFIED VARIABLE, AND RS + RETURNS TO THAT SPOT. THUS: + SS FOO + ... LOTSA EDITING ... + RS FOO + + [7.3] AN ARGUMENT TO EDIT NO LONGER CONTROLS THE AUTO-PRINT + FEATURE (SEE [7.4] BELOW); INSTEAD, IT SHOULD BE AN + ATOMIC SYMBOL, THE NAME OF A FUNCTION. AS THE EDITOR + IS ENTERED, THAT FUNCTION IS "YANKED" SO THAT EDITING + MAY BEGIN ON ITS CODE WITHOUT EXPLICITLY USING THE + "Y" COMMAND. THE VALUE OF THE VARIABLE "EDIT" + CONTROLS WHICH PROPERTIES WILL BE HUNTED FOR BY THE + "Y" OPERATION [INITIAL VALUE IS (EXPR FEXPR MACRO)]. + [7.4] "SP" = "START/STOP PRINTING" TOGGLES THE STATE OF + THE AUTOMATIC PRINTOUT AFTER EACH COMMAND. + [7.5] "-KI" IS LIKE "L KI"; THAT IS, IT REPLACES THE + PRECEDING S-EXPRESSION WITH ITS ARGUMENT. + [7.6] AN "S" COMMAND IMMEDIATELY FOLLOWED BY "$$" + (I.E. A NULL SEARCH STRING" WILL REPEAT THE PREVIOUS + SEARCH, AS IN TECO. + [7.7] YANKING IN A VALUE PROPERTY NOW WINS. THUS: + YP FOO VALUE $$ + ALLOWS YOU TO EDIT THE VALUE PROPERTY OF FOO. +---------------------------------------------------------------- +[A] NEWIO NOW PROVIDES A ##MORE## PROCESSOR, IF YOU ARE IN + ":TCTYP MORE" MODE WHEN LISP STARTS UP. WHEN THE END OF + THE SCREEN IS REACHED, "##MORE##" IS PRINTED, AND LISP + WAITS FOR A CHARACTER. SPACE OR RUBOUT IS SWALLOWED, + AND ANYTHING ELSE IS LEFT TO BE SEEN BY LATER ##MORE##'S + (AND EVENTUALLY BY READ). THE STATE OF THE ##MORE## INTERRUPT + MAY STILL BE TOGGLED BY TYPING M AT LISP, + AS WITH ANY OTHER ITS JOB. + +[B] THE VARIOUS MOBYIO FEATURES IMPLEMETED ONLY ON THE AI MACHINE + (SUCH AS REAL AND FAKE TV'S, 340 STUFF, PLOTLIST AND MULTIPLEXOR + ROUTINES) HAVE BEEN CODED AS AUTOLOAD PACKAGES FOR NEWIO. THEY + ARE VIRTUALLY UNTESTED, AND WE WOULD APPRECIATE IT IF TV AND 340 + HACKERS WOULD GIVE THEM A TRY AND HELP FIND THE BUGS. + +[C] .LISP. (INIT) FILES ARE NOT HANDLED VIA THE UREAD MECHANISM + IN NEWIO. A STANDARD TRICK IN OLDIO, NOT USABLE IN NEWIO, IS TO + CALL UREAD IN THE LAST FORM IN AN INIT FILE, AND DEPEND ON IT TO + CLOSE THE INIT FILE BEFORE OPENING THE NEW ONE. SINCE THIS + DOESN'T WORK IN NEWIO, IT MAY HAPPEN THAT AN .INIT. FILE IS NEVER + CLOSED. THERE ARE TWO SOLUTIONS: + (1) LET THE .INIT. FILE EXPLICITLY CLOSE ITSELF, AND POP THE + INPUT STACK, DURING THE EVALUATION OF THE LAST FORM. E.G. + (COMMENT CORE 120 . . .) ;RELIC FOR ALLOC + (DO SOME STUFF) + . . . ;MORE STUFF + (PROGN (CLOSE INFILE) (INPUSH -1)) + (2) ARRANGE NOT TO RESET ^Q TO NIL IN THE INIT FILE, SO THAT + THE TOP-LEVEL READ-EVAL-PRINT LOOP WILL ENCOUNTER + END-OF-FILE AND CLOSE IT FOR YOU. + +[D] THE OLD MESSAGE ABOUT + ;REFERENCE TO NON-EXISTENT MEMORY FROM LOCATION 314159 + ;PROGRAM TRAPPED WHILE IN COMPLETELY-CRETINOUS-ROUTINE + HAS BEEN FLUSHED IN NEWIO. NOW, WHEN A MEMORY PROTECT VIOLATION, + WRITE INTO READ-ONLY MEMORY, ILLEGAL OPERATION, OR PARITY ERROR + OCCURS, NEWIO CHECKS THE VALUE OF THE ATOM "MACHINE-ERROR", + AS PREVIOUSLY DOCUMENTED. IF NON-NIL, IT IS THE USER HANDLER + FOR THE ERROR. IF NIL, LISP REFLECTS THE INTERRUPT BACK OUT, + AND DDT HANDLES IT, PRINTING THE FAMILAR MESSAGE: + MPV; 314159>>MOVE 1,(2) 1/ 43 271828/ ?? + WHICH MAY SEEM SOMEWHAT MORE CRYPTIC, BUT WILL MAKE IT MUCH EASIER + FOR KNOWLEDGEABLE LISP HACKERS TO DEBUG THE ERROR. TO GET THE + EFFECT OF THE OLD HANDLER (RETURN TO TOP LEVEL), TYPE $G TO DDT. + SYSTEMS SUCH AS MACSYMA WHICH REQUIRE A BETTER USER INTERFACE SHOULD + PROVIDE A MACHINE-ERROR USER INTERRUPT HANDLER. + +[E] ALL TTY BLOCK OUTPUT IN NEWIO IS NOW DONE WITH SIOT. + AS A COROLLARY, A FILE WRITTEN IN TTY BLOCK IMAGE OUTPUT MODE + WILL WRITE 8-BIT CHARACTERS, AND TTY BLOCK FIXNUM OUTPUT + WILL WRITE 12.-BIT CHARACTERS. SUPER SYSTEMS HACKERS TAKE NOTE! + +[F] BUG OF FASLOAD FROM WITHIN FASLOAD-FILE-NOT-FOUND BREAK FIXED. + WHEN YOU GET A FILE-NOT-FOUND ERROR FROM FASLOAD, IT NOW WORKS + TO REPEAT THE FASLOAD WITHOUT EXITING FROM THE BREAK. + +[G] THE KLUDGE WHERE LISP'S TOP-LEVEL AND BREAK-LEVEL SWALLOW A + SPACE AFTER AN ATOM DOES NOT HAPPEN IF THE USER SUPPLIED A + READ FUNCTION BY SETQ'ING THE VARIABLE "READ". + +[H] NEW CURSORPOS FEATURES: A, H, I, V + (CURSORPOS 'A) ADVANCES TO A FRESH LINE; THAT IS, + IT DOES A TERPRI UNLESS THE TTY IS ALREADY + AT THE BEGINNING OF A LINE. + (CURSORPOS 'P) (OUTPUT A ^P) HAS BEEN FLUSHED. + (TYO 20) NOW DOES THE RIGHT THING IN NEWIO. + (CURSORPOS 'H ) SETS JUST THE HORIZONTAL POSITION + TO WITHOUT AFFECTING THE VERTICAL POSITION. + (CURSORPOS 'V ) SIMILARLY SETS THE VERTICAL POSITION. + (CURSORPOS 'I ) OUTPUTS ASCII CODE AS A ONE-POSITION + PRINTING CHARACTER (WILL NOT WORK UNTIL IMPLEMENTED + IN ITS, WHICH ISN'T YET!). + +[I] THE ACTION AT END-OF-FILE, CONTRARY TO THE MOONUAL, IS NOW: + IF WITHIN READ IN THE MIDDLE OF AN OBJECT (TYI CANNOT BE + "IN THE MIDDLE OF AN OBJECT") SIGNAL A READ-EOF ERROR. + OTHERWISE, IF NO USER EOF HANDLER BELONGS TO THE FILE, + THEN CLOSE THE FILE UNLESS IT IS A TTY + (EOF ON A TTY MERELY MEANS OVER-RUBOUT), + POP THE INPUT STACK (BY DOING (INPUSH -1)), + THEN IF WITHIN A READ THAT HAD ARGUMENTS + RETURN THE EOF VALUE, AND OTHERWISE REPEAT + THE READ FROM THE NOW CURRENT FILE POPPED. + IF THERE WAS A USER EOF HANDLER, + THEN CALL IT WITH THE FILE AND EOF VALUE AS + ARGUMENTS. WHEN IT RETURNS, THEN + IF IT RETURNED NIL, CLOSE THE FILE (UNLESS + IT IS A TTY) AND POP THE INPUT STACK, + THEN REPEAT THE READ FROM THE NEW CURRENT + INPUT FILE. + IF IT RETURNED T, REPEAT THE READ USING WHATEVER + SOURCE THE EOF HANDLER MADE CURRENT. + IF IT RETURNED ANY OTHER VALUE, THEN + IF NOT WITHIN A READ WITH ARGUMENTS, + PRETEND IT RETURNED NIL. + OTHERWISE, EXIT THE READ WITH THE VALUE + RETURNED BY THE EOF HANDLER. + IN THE ABOVE, "READ" REFERS TO WHATEVER INPUT FUNCTION WAS + CALLED, SUCH AS READ, READLINE, TYI, ETC. + + THURSDAY JULY 01,1976 NM+4D.11H.48M.23S. LISP 1168 - GLS - + +[1] HUNK STUFF HAS CHANGED; HUNK,HUNKIFY => MAKHUNK,HUNK +[2] TOPLEVEL AND BREAKLEVEL FLUSH SPACES AFTER ATOMS +[3] PRINT IS MORE CLEVER ABOUT AUTO-TERPRI AND PRINLEVEL +[4] NEW FUNCTION "SUBR" FINDS ROUTINE A PC IS IN +FOR NEWIO ONLY: +[A] MAR-BREAK INTERRUPT TURNS OFF MAR +[B] ALL THE NEW INTERRUPTS RUN IN (NOINTERRUPT T) STATE +[C] THE VARIABLE DEFAULTF IS THE DEFAULT FILE NAMES +[D] MACHINE-ERROR INTERRUPT NOW GETS MORE ARGUMENTS +---------------------------------------------------------------- +[1] THE HUNK STUFF HAS BEEN REVISED AS FOLLOWS: + (CXR 0 X) = (CDR X), (CXR 1 X) = (CAR X) + THIS IS THE REVERSE OF WHAT IT INITIALLY WAS. THE OTHER + COMPONENTS ARE STILL COMPONENTS 2 THROUGH N-1. + THE OLD "HUNKIFY" FUNCTION HAS BEEN RENAMED "HUNK". + IT TAKES ITS ARGUMENTS IN THE ORDER 1, 2, 3, ..., N-1, 0. + THIS IS THE ORDER THEY ARE PRINTED IN. THUS: + (SETQ FOO (HUNK 1 2 3 4 5)) + (1 . 2 . 3 . 4 . 5) + (CXR 1 FOO) + 1 + (CXR 2 FOO) + 2 + (CXR 0 FOO) + 5 + THE OLD "HUNK" FUNCTION HAS BEEN RENAMED "MAKHUNK". + IT ALSO HAS AN EXTENDED DEFINITION: IF THE ARGUMENT TO + MAKHUNK IS A FIXNUM, IT CREATES A HUNK THAT BIG FILLED + WITH NILS. IF THE ARGUMENT IS A LIST, IT CREATES A HUNK + FILLED WITH THE ELEMENTS OF THE LIST. THUS + (MAKHUNK (LIST A B C D)) = (HUNK A B C D) +[2] IN THE SYSTEM-SUPPLIED TOPLEVEL AND BREAKLEVEL + READ-EVAL-PRINT LOOPS, JUST AFTER AN ITEM IS READ THE + FOLLOWING OCCURS: + (AND (ATOM THE-ITEM) + (NOT (ZEROP (BOOLE 1 100000 + (STATUS SYNTAX (TYIPEEK))))) + (TYI)) + IN THIS WAY THE SPACE THAT TERMINATED THE ATOM (IF IT WAS + IN FACT A SPACE) IS FLUSHED. THIS IS SO THAT THE SPACE + WILL NOT HANG AROUND AND CONFUSE, E.G., **MORE** + PROCESSING. USER TOPLEVELS AND BREAKLEVELS SHOULD DO + A SIMILAR THING. + I WOULD APPRECIATE GETTING COMMENTS ABOUT THIS GENERAL + PROBLEM ABOUT SPACES AFTER ATOMS. SHOULD THERE BE TWO + READ FUNCTIONS, ONE WHICH FLUSHES SPACES AND ONE WHICH + DOES NOT? OR WHAT? -- GLS +[3] A NEW USELESS FEATURE OF PRINT IS THAT THE AUTO-TERPRI + HACK IS MORE CLEVER. UP TO NOW PRINT HAS CALCULATED + THE SIZE OF EACH ATOMIC SYMBOL AND PUT A TERPRI (CARRIAGE + RETURN) BEFORE THE SYMBOL IF IT WON'T FIT ON THE CURRENT OUTPUT + LINE. NOW IT CALCULATES OR ESTIMATES THE LENGTH OF EACH ATOM + (NUMBERS, ETC., AS WELL AS SYMBOLS), AND ALLOWS FOR ANY + PARENTHESES WHICH MUST PRECEDE OR FOLLOW THE ATOM. THUS, + IF THE NEXT FRAGMENT TO PRINT IS "((FOOBAR)))", PRINT + WILL TERPRI IF THERE ARE NOT AT LEAST ELEVEN CHARACTERS + LEFT IN THE OUTPUT LINE. THIS MEANS THAT YOU DON'T GET + ISOLATED LEFT PARENS AT THE END OF A LINE, OR RIGHT PARENS + AT THE BEGINNING OF A LINE. +[4] THE NEW FUNCTION "SUBR" (ONLY IN BIBOP LISPS, FOR OBSCURE + TECHNICAL REASONS), TAKES ONE ARGUMENT, A FIXNUM, AND TRIES + TO DETERMINE WHAT FUNCTION THAT NUMBER WOULD BE A PC IN. + THIS HACK IS ONLY APPROXIMATE, AND DEPENDS ON LOOKING AT ALL + THE PROPERTY LISTS OF ATOMS IN THE CURRENT OBARRAY. + THE ATOM WITH THE CLOSEST REASONABLE SUBR, FSUBR, LSUBR, + OR ARRAY PROPERTY IS RETURNED AS THE RESULT. + IF NO REASONABLE RESULT IS FOUND, THE ATOM "?" IS RETURNED. + (WHAT THIS DOES IS PROVIDE A HANDLE ON AN INTERNAL ROUTINE + LISP HAS HAD FOR A LONG TIME ANYWAY. SEE ITEM [D] BELOW.) + +FOR NEWIO ONLY: + +[A] WHEN THE MAR-BREAK USER INTERRUPT GOES OFF, AN IMPLICIT + (SSTATUS MAR 0 NIL) HAS BEEN PERFORMED. IT IS UP TO + THE MAR-BREAK FUNCTION TO RE-ENABLE THE MAR IF DESIRED. + THIS IS SIMILAR TO THE OPERATION OF THE ALARMCLOCK + FUNCTION. THE INTENTION IS TO HELP PREVENT INFINITE LOOPS. +[B] ALL THE NEW ASYNCHRONOUS INTERRUPTS ANNOUNCED LAST TIME, NAMELY + MAR-BREAK, SYS-DEATH, AND TTY-RETURN, ARE RUN IN (NOINTERRUPT T) + MODE JUST LIKE TTY CHARACTER INTERRUPTS. (I FORGOT TO DOCUMENT + THIS LAST TIME.) +[C] THE VARIABLE DEFAULTF NOW CONTAINS NEWIO'S DEFAULT FILE NAMES, + IN THE FORM OF A NAMELIST. THIS IS SO YOU CAN LAMBDA-BIND + THEM. THE FUNCTION DEFAULTF STILL EXISTS AND IS EQUIVALENT + TO: + (DEFUN DEFAULTF (X) + (SETQ DEFAULTF + (MERGEF (OR X DEFAULTF) DEFAULTF))) +[D] THE MACHINE-ERROR INTERRUPT HAS BEEN CHANGED TO TAKE FOUR + ARGUMENTS. THEY ARE A SYMBOL AND THREE FIXNUMS, IN THAT ORDER + (THIS INVOLVES A REVERSAL OF ITS FORMAR ARGUMENTS.) THE SYMBOL + STILL INDICATES THE ERROR TYPE. THE THREE FIXNUMS ARE, + IN ORDER, THE LOCATION OF THE ERROR, THE PC AS OF THE ERROR, + AND THE JPC AS OF THE ERROR. FOR THE NONCE, THE FIRST AND THIRD + FIXNUMS ARE ALWAYS ZERO, BUT EVENTUALLY WILL CONTAIN INFORMATION + AS CORRECT AS ITS CAN SUPPLY. + AS AN EXAMPLE OF A MACHINE-ERROR FUNCTION, THIS ONE DOES + APPROXIMATELY WHAT THE SYSTEM DEFAULT HANDLER DOES: + (DEFUN MACHINE-ERROR-HANDLER (TYPE LOC PC JPC) + (TERPRI) + (PRINC (COND ((EQ TYPE 'EXAMINE) + '|;REFERENCE TO NON-EXISTENT MEMORY|) + ((EQ TYPE 'DEPOSIT) + '|;WRITE INTO READ-ONLY MEMORY|) + ((EQ TYPE 'EVAL) + '|;ILLEGAL MACHINE OPERATION|) + ((EQ TYPE 'ODDP) + '|;PARITY ERROR|))) + (PRINC '| FROM LOCATION |) + (PRIN1 PC) + (TERPRI) + (PRINC '|;PROGRAM TRAPPED WHILE IN |) + (PRIN1 (SUBR PC)) ;SEE ITEM [4] ABOVE FOR SUBR + (ERROR)) + ANOTHER ONE TO USE IS: + (DEFUN MACHINE-ERROR-HANDLER (TYPE LOC PC JPC) + ((LAMBDA (ARGS) + (BREAK MACHINE-ERROR)) + (LIST (COND ((EQ TYPE 'EXAMINE) + 'REFERENCE-TO-NON-EXISTENT-MEMORY) + ((EQ TYPE 'DEPOSIT) + 'WRITE-INTO-READ-ONLY-MEMORY) + ((EQ TYPE 'EVAL) + 'ILLEGAL-MACHINE-OPERATION) + ((EQ TYPE 'ODDP) + 'PARITY-ERROR)) + 'AT + 'LOCATION + LOC + 'FROM + 'WITHIN + (SUBR PC)))) + WHEN THE BREAK OCCURS, THE VARIABLE ARGS, FOLLOWING CONVENTION, + HAS THE USEFUL DATA. + + TUESDAY JUNE 15,1976 FM+3D.2H.27M.33S. LISP 1160 - GLS - + +NOTE THAT NUMBERED ITEMS ARE FOR BOTH NEWIO AND OLDIO, +WHILE LETTERED ITEMS ARE FOR NEWIO ONLY. NOTE ALSO THAT +NUMBERED AND LETTERED ITEMS ARE INTERMIXED SLIGHTLY. + +[0] NEW COMPILER FEATURES + [0A] (PROGN 'COMPILE A1 ... AN) AT TOP LEVEL COMPILES A1 ... AN + [0B] (DEFUN (FOO BAR) ...) PULLS A SPECIAL GENSYM HACK + [0C] (RECOMPL '(A B C ...)) IS USED TO RECOMPILE A FILE + [0D] THE COMPILER NOW RECOGNIZES (CGOL) SPECIALLY +[1] THE VARIABLE ZFUZZ CONTROLS PRECISION OF PLUS AND DIFFERENCE +[2] DEFPROP AND DEFUN DO A REMPROP LOOP, NOT JUST A SINGLE REMPROP +[3] P% IS "LISP TYPEOUT MODE", AND GETS SET UP IN & IF POSSIBLE +[A] TYI ARRANGES TO READ NON-ACTIVATION CHARACTERS +[B] TYI ON TTY DOESN'T CONFUSE CURSORPOS ANY MORE +[C] THE VARIABLES TYI AND TYO CONTAIN THE INITIAL TTY FILE OBJECTS +[D] SETQ OF READ NOW WORKS IN NEWIO; "LOAD" USES IT TOO +[E] RECALL THAT HH$X IS BB$X IN NEWIO +[F] SPECIAL TREATMENT OF CTRL AND META CHARACTERS IN NEWIO +[G] MAR INTERRUPT FEATURE + [F1] THE MAR-BREAK USER INTERRUPT + [F2] (STATUS MAR) AND (SSTATUS MAR) + [F3] SUSPEND SAVES AND RESTORES THE MAR + [F4] ^G CIRCUMVENTS THE MAR ON RESTORED VARIABLES +[H] OTHER NEW USER INTERRUPTS + [G1] TTY-RETURN (TTY JUST RETURNED TO THE JOB) + [G2] SYS-DEATH AND (STATUS ITS) + [G3] MACHINE-ERROR (MEMORY ERRORS, ILLEGAL OPERS, PARITY ERRORS) +[4] HUNKS PACKAGE + [5A] NEW DATA TYPES + [5B] NEW PRIMITIVES: CXR, RPLACX, HUNK, HUNKIFY, HUNKSIZE + [5C] EQUAL AND SXHASH TREAT HUNKS SPECIALLY + [5D] PRINT TREATS HUNKS SPECIALLY + [5E] TREATMENT OF HUNKS AS LIST STRUCTURE + [5F] (STATUS FEATURE HUNK) + [5G] (STATUS SPCNAMES) + [5H] (STATUS GCSIZE), ETC., AND (ALLOC X) +[I] HUMBLE PACKAGE FOR HACKING INFERIOR JOBS ON ITS + [I1] SPECIAL VARIABLES AND THE JOB TABLE + [I2] CREATE-JOB + [I3] SELECT-JOB + [I4] KILL-JOB + [I5] LOAD-JOB + [I6] JOB-USET-READ AND JOB-USET-WRITE + [I7] EXAMINE-JOB AND DEPOSIT-JOB + [I8] *ATTY AND *DTTY + [I9] AUXILIARY PACKAGES +---------------------------------------------------------------- +[0] NEW COMPILER FEATURES + [0A] IF THE FORM (PROGN 'COMPILE A1 ... AN) IS SEEN + AT THE TOP LEVEL OF A FILE, THE COMPILER COMPILES + THE FORMS A1 ... AN AS IF THEY ALL WERE SEEN AT TOP LEVEL. + IN THIS WAY A MACRO CAN "RETURN MULTIPLE FORMS" TO BE + COMPILED (AFTER ALL, THE CONSTRUCT ALSO WORKS IN THE + INTERPRETER). + [0B] (DEFUN (FOO BAR) ...) IN THE INTERPRETER DEFINES FOO + TO HAVE A BAR PROPERTY WHICH IS A LAMBDA EXPRESSION. + THE COMPILER CREATES A GENSYM G0034, OUTPUTS THE FORM + (DEFPROP FOO G0034 BAR), + AND THEN COMPILES THE FUNCTION UNDER THE NAME G0034. + IN THIS WAY (FUNCALL (GET 'FOO 'BAR) ...) WILL ALWAYS + WORK, FOR EXAMPLE. + CONTRAST THIS WITH (DEFUN (FOO BAR BAZ) ...), WHICH + IN THE INTERPRETER GIVES FOO A BAR PROPERTY, AND WHEN + COMPILED GIVES FOO A BAZ PROPERTY. + [0C] THE VARIABLE RECOMPL, IF NON-NIL, CAUSES THE COMPILER + TO IGNORE ALL FORMS IN A FILE EXCEPT DECLARATIONS + AND FUNCTIONS WHOSE NAMES APPEAR IN THE LIST WHICH + IS THE VALUE OF RECOMPL. THE FUNCTION RECOMPL + APPENDS ITS ARGUMENT TO THE RECOMPL LIST. THE IDEA + IS THAT ONE CAN SPECIFY TO THE COMPILER WHICH FUNCTIONS + IN A FILE HAVE CHANGED, AND PRODUCE AN "UPDATE" FASL + FILE CONTAINING ONLY THE DIFFERENCES. + [0D] THE COMPILER NOW RECOGNIZES THE FORM (CGOL), AND + TREATS IT SOMEWHAT LIKE (DECLARE (EVAL (READ))) (CGOL). +[1] IF THE VARIABLE ZFUZZ IS NON-NIL, THEN PLUS AND DIFFERENCE + PERFORM A SPECIAL FUZZ CHECK ON FLOATING POINT NUMBERS. + IF A AND B ARE THE NUMBERS TO BE ADDED (POSSIBLY AFTER CONTAGIOUS + CONVERSION TO FLOATING POINT), THEN IF + A + B < B * ZFUZZ + THEN THE RESULT IS FORCED TO ZERO. + THIS HACK WAS INVENTED FOR BMT; IT MAY CHANGE IF HE DECIDES IT + ISN'T THE RIGHT THING. +[2] BEFORE PUTTING THE NEW PROPERTY ON AN ATOM, DEFPROP AND DEFUN + USED TO PERFORM A SINGLE REMPROP OF THE PROPERTY. NOW THEY LOOP, + REMOVING ALL INSTANCES OF THE PROPERTY FROM THE ATOM. THIS IS + TO ALLOW FOR TRACE, WHICH CREATES ATOMS WITH MULTIPLE OCCURRENCES + OF A GIVEN PROPERTY NAME. +[3] FOR THOSE WHO HACK LISP FROM DDT: + THE SYMBOL P% IS A PUSHJ INSTRUCTION SUITABLE FOR USE AS A DDT + USER TYPEOUT MODE (BY DEPOSITING IT INTO ..TAMPER OR SOME SIMILAR + LOCATION). IF WHEN THE LISP IS STARTED UP DDT HAS A SYMBOL TABLE + LOADED FOR THE LISP, LISP MOVES THE TYPEOUT MODE IN ..TAMPER + TO ..TPERCE, AND DEPOSITS P% IN ..TAMPER. IN THIS WAY THE DDT + COMMAND & MEANS LISP TYPEOUT MODE, AND SQUOZE TYPEOUT MAY BE DONE + VIA $%;. + THIS FORM OF LISP TYPEOUT MODE TYPES OUT $Q, NOT THE CONTENTS + OF . AS P.$X AND PL.$X DO. IF $Q HAS A NON-ZERO LEFT HALF, + THEN BOTH THE LEFT AND RIGHT HALVES ARE PRINTED AS S-EXPRESSIONS, + SEPARATED BY ",,". THIS TYPEOUT MODE IS USEFUL IN CONJUNCTION + WITH THE "RAID REGISTER" FEATURE OF DDT ($V). + +REMEMBER, LETTERED ITEMS ARE FOR NEWIO ONLY! + +[A] WHEN INPUTTING FROM A TTY USING THE TYI FUNCTION (AS OPPOSED TO + READ OR READLINE), NEWIO ARRANGES TO SET THE %TIACT BIT. + THE EFFECT OF THIS IS TO READ ANY CHARACTER IMMEDIATELY, EVEN + IF NO ACTIVATION CHARACTER HAS BEEN TYPED YET. THIS WILL + ALLEVIATE THE SCREW INVOLVING (STATUS TTY) FOR MOST PEOPLE. +[B] MANY PLACES IN NEWIO ARE NOW MUCH MORE CLEVER ABOUT UPDATING + THE CHARPOS AND LINENUM OF A TTY OUTPUT FILE WHEN INPUT HAS + BEEN DONE ON THE ASSOCIATED TTY. IN PARTICULAR, THE TYI + FUNCTION AND THE PRE-SCAN FUNCTION FOR READ BOTH UPDATE THINGS + CORRECTLY. THE VARIOUS DDT TYPEOUT HACKS ALSO ARRANGE TO + UPDATE THINGS CORRECTLY. +[C] THE VARIABLES TYI AND TYO NOW COME INITIALIZED RESPECTIVELY TO + THE INITIAL TTY INPUT AND OUTPUT FILE OBJECTS. T STILL WORKS + AS AN ARGUMENT TO MOST I/O FUNCTIONS, BUT TO AVOID AMBIGUITIES + USE THE OBJECTS IN TYI AND TYO. ALSO, SEVERAL PLACES IN NEWIO + WHICH USED TO SUPPLY A T FOR A FILE OBJECT NOW SUPPLY THE TTY + FILE OBJECT ITSELF, PARTICULARLY THE PLACE THAT SUPPLIES ARGUMENTS + TO INTERRUPT FUNCTION. +[D] NEWIO NOW UNDERSTANDS THAT IF THE VARIABLE READ IS NON-NIL IT IS + A USER READ FUNCTION. THE LOAD FUNCTION, WHEN LOADING AN EXPR FILE, + USES THIS USER READ FUNCTION ALSO. +[E] MORE FOR DDT HACKERS: SINCE THE ^H BREAK WAS RENAMED THE ^B BREAK + IN NEWIO, THE HH$X HACK IS CALLED BB$X IN NEWIO. +[F] IF AN INPUT TTY IS OPEN IN 12-BIT MODE, THE DEFAULT READ PRE-SCAN + FUNCTION TRIES TO THROW AWAY INTERRUPT CHARACTERS. THIS IS SO + THAT TOP CHARACTERS CAN GO THROUGH AS ALPHABETICS, WITHOUT LETTING + CONTROL CHARACTERS CONFUSE THE READER. + IT HAS ALWAYS BEEN TRUE THAT IF A TTY INPUT INTERRUPT FUNCTION WAS + REALLY A NUMBER, THEN IT MEANT THAT THE "INTERNAL" INTERRUPT + ACTION SPECIFIED BY THAT NUMBER WAS TO BE TAKEN; FURTHERMORE, + IF THE 200 OR 400 BIT WAS SET IN THE NUMBER, THE CTRL OR META + BIT WAS REQUIRED TO BE PRESENT IN THE TYPED CHARACTER (THIS + WAS SO THAT CTRL/G WOULD QUIT BUT "PI" WOULD NOT, FOR INSTANCE). + A NEW TWIST IS THAT THE 200000000 AND 400000000 (200 AND 400 IN THE + LEFT HALF) BITS REQUIRE THE ABSENCE OF THE CTRL AND META BITS + IN THE TYPED CHARACTER FOR THE INTERRUPT ACTION TO TAKE PLACE. + THUS, FOR EXAMPLE: + (SSTATUS TTYINT 7 207) ;CTRL/G AND META/CTRL/G QUIT + (SSTATUS TTYINT 7 607) ;ONLY META/CTRL/G QUITS + (SSTATUS TTYINT 7 400000207) ;CTRL/G QUITS, BUT NOT META/CTRL/G + (SSTATUS TTYINT 600000007) ;"PI" QUITS, BUT NOT CTRL/G OR META/CTRL/G +[G] MAR INTERRUPT FEATURE + AT LONG LAST, THE MAR BREAK IS AVAILABLE TO THE LISP USER! + THIS IS A FEATURE WHICH DETECTS WHEN A GIVEN MEMORY LOCATION IS + REFERENCED AND GIVES AN INTERRUPT. + [F1] THE VARIABLE MAR-BREAK, IF NON-NIL, IS A USER INTERRUPT + FUNCTION WHICH IS CALLED WHEN THE MAR BREAK IS FIRED. + IT TAKES ONE ARGUMENT WHICH PRESENTLY IS ALWAYS NIL. + [F2] (STATUS MAR) AND (SSTATUS MAR) + TO "ARM" THE MAR BREAK, IT IS NECESSARY TO SAY + (SSTATUS MAR N LOC) + WHERE N CONTROLS WHEN THE MAR IS FIRED, AND LOC IS + THE PLACE TO MONITOR. N MAY TAKE ON THE FOLLOWING VALUES: + 0 TURN OFF THE MAR FEATURE + 1 BREAK ON INSTRUCTION FETCH + 2 BREAK ON WRITE + 3 BREAK ON ALL REFERENCES + ON THE KL-10, THESE ADDITIONAL VALUES ARE REPUTED TO WORK: + 10 BREAK ON DATA READ + 11 BREAK ON READ AND FETCH + 12 BREAK ON READ AND WRITE, BUT NOT FETCH + 13 BREAK ON FETCH AND WRITE, BUT NOT READ + THE 4 BIT (EXEC VS. USER MODE) IS IGNORED (USER IS FORCED). + LOC IS ANY S-EXPRESSION; THAT CELL IS THE ONE MONITORED. + THUS (SETQ FOO (LIST 'A 'B)) (SSTATUS MAR 2 FOO) + WILL TRIP THE MAR BREAK IF THE LIST CELL IN FOO IS EVER + RPLACA'D OR RPLACD'D. AS AN EXAMPLE: + (DEFUN MAR-TRACER (X) + (TERPRI) + (PRINC '|NOW THE VARIABLE |) + (PRIN1 THE-MAR-VARIABLE) + (PRINC '| HAS THE VALUE |) + (PRIN1 (SYMEVAL THE-MAR-VARIABLE)) + (SSTATUS MAR 2 (GET THE-MAR-VARIABLE 'VALUE))) + (SETQ MAR-BREAK 'MAR-TRACER) + (DEFUN MAR FEXPR (X) + (SETQ THE-MAR-VARIABLE (CAR X)) + ;; MAKE SURE THE VARIABLE HAS A VALUE CELL + (COND ((NOT (BOUNDP THE-MAR-VARIABLE)) + (SET THE-MAR-VARIABLE NIL))) + (SSTATUS MAR 2 (GET THE-MAR-VARIABLE 'VALUE))) + (DEFUN UNMAR () (SSTATUS MAR 0 NIL)) + (MAR QUUX) + (SETQ QUUX 5) + NOW QUUX HAS THE VALUE 5 + (DO ((QUUX 0 (+ QUUX 1))) ((= QUUX 2)) (HACK QUUX)) + NOW QUUX HAS THE VALUE 0 + NOW QUUX HAS THE VALUE 1 + NOW QUUX HAS THE VALUE 2 + NOW QUUX HAS THE VALUE 5 + NIL + (STATUS MAR) RETURNS A 2-LIST DESCRIBING THE CURRENT STATE + OF THE MAR, OR NIL IF THE MAR IS NOT IN USE. NOTE THAT + USING THE MAR FROM DDT WILL NOT CONFUSE LISP, AND LISP + TRIES NOT TO CONFUSE DDT. IF LISP IS NOT USING THE MAR, + THEN IT DOESN'T EVEN TAKE THE MAR INTERRUPT FROM ITS, + AND SO DDT CAN TRAP IT. + [F3] THE SUSPEND FUNCTION DOES ITS BEST TO SAVE AND RESTORE + THE STATE OF THE MAR. + [F4] WHEN A ^G FORCES A QUIT BACK TO TOP LEVEL, THE MAR BREAK + IS DISABLED DURING THE UNBINDING OF VARIABLES, AND + RE-ENABLED AFTERWARDS. THIS IS BECAUSE DURING A QUIT + LISP IS NOT IN A GOOD STATE FOR RUNNING USER INTERRUPTS. +[H] OTHER NEW USER INTERRUPTS + [G1] TTY-RETURN, IF NON-NIL, IS A USER INTERRUPT FUNCTION + WHICH IS RUN WHENEVER THE TTY IS GIVEN TO THE LISP JOB. + (THIS IS DRIVEN BY THE %PIATY BIT IN ITS.) + THIS IS USEFUL FOR TELLING LISP THAT SOME OTHER JOB + MAY HAVE MESSED UP THE SCREEN DISPLAY. + THE ARGUMENT TO THE FUNCTION IS PRESENTLY ALWAYS NIL. + [G2] SYS-DEATH, IF NON-NIL, IS A USER INTERRUPT FUNCTION + WHICH IS RUN WHENEVER THE STATE OF THE SYSTEM IS GOING + DOWN, BEING REVIVED, OR BEGIN DEBUGGED. + (THIS IS DRIVEN BY THE %PIDWN AND %PIDBG BITS IN ITS.) + THE ARGUMENT TO THE FUNCTION IS PRESENTLY ALWAYS NIL. + USEFUL IN CONJUNCTION WITH THIS INTERRUPT IS (STATUS ITS). + THIS RETURNS A LIST OF FIVE NUMBERS: + (1) THE TIME, IN SECONDS, UNTIL THE SYSTEM GOES DOWN, + AS A FLONUM, -1.0 IF THE SYSTEM DOES NOT PLAN + TO GO DOWN, OR -2.0 IF THE SYSTEM IS ALREADY DOWN. + (2) A FIXNUM, NON-ZERO IF THE SYSTEM IS BEING DEBUGGED. + (3) THE NUMBER OF USERS ON THE SYSTEM, AS A FIXNUM. + (4) THE NUMBER OF MEMORY ERRORS THE SYSTEM HAS SURVIVED. + (5) THE TIME IN SECONDS THE SYSTEM HAS BEEN UP, + AS A FLONUM. + THIS INFORMATION COMES FROM THE ITS "SSTATU" SYSTEM CALL. + [G3] MACHINE-ERROR, IF NON-NIL, IS A USER INTERRUPT FUNCTION + WHICH IS RUN WHENEVER A MEMORY PROTECTION VIOLATION, + WRITE INTO READ-ONLY MEMORY, ILLEGAL OPERATION, OR + PARITY ERROR OCCURS. THE FUNCTION RECEIVES TWO ARGUMENTS: + THE FIRST IS THE PROGRAM COUNTER WHEN THE ERROR OCCURRED + (NOT THE MEMORY LOCATION OF THE ERROR!), AND THE SECOND + IS A SYMBOL DESCRIBING THE TYPE OF ERROR: + EXAMINE ATTEMPT TO REFERENCE NON-EXISTENT MEMORY + DEPOSIT WRITE INTO READ-ONLY MEMORY + EVAL ILLEGAL OPERATION + ODDP PARITY ERROR + NOTE THAT THE LISP SYSTEM MAY INTERCEPT SOME OCCURRENCES + OF THESE ERRORS, SINCE THEY CAN BE USED FOR VARIOUS + SHARED-MEMORY HACKS. + IF THE USER INTERRUPT FUNCTION EVER RETURNS, THE PROGRAM + IS RESUMED AT THE PROGRAM COUNTER AS OF THE ERROR; + THAT IS, THE ERRONEOUS OPERATION IS RETRIED. BEWARE + OF LOOPS! IT IS EXPECTED THAT THE INTERRUPT FUNCTION WILL + NORMALLY ERROR OUT. + IF NO USER INTERRUPT FUNCTION IS SUPPLIED, LISP WILL + BEHAVE AS IT ALWAYS HAS, AND ERROR OUT TO TOP LEVEL. + +THE NEXT FEATURE IS AVAILABLE IN ALL BIBOP LISPS, WHETHER OLDIO OR NEWIO. + +[4] HUNKS PACKAGE + THE HUNKS PACKAGE PROVIDES LISP WITH A KIND OF "RECORD" OR + "SMALL VECTOR" FEATURE. THE HUNK DATA TYPE INTERACTS SMOOTHLY + WITH THE LIST DATA TYPE TO PROVIDE SOME INTERESTING CAPABILITIES. + [5A] A NEW DATA TYPE IS INTRODUCED INTO LISP, THE "HUNK". + HUNKS ARE SHORT VECTORS OF S-EXPRESSIONS. IN THE CURRENT + IMPLEMENTATION THERE ARE ACTUALLY SEVERAL SPACES OF + FOR HUNKS, VARIOUSLY CALLED HUNK4, HUNK8, HUNK16, ETC. + THESE WILL BE EXPLAINED IN DETAIL BELOW. IN SOME + CONTEXTS ORDINARY LIST CELLS ARE CONSIDERED TO BE HUNKS + OF LENGTH 2. HUNKS ARE NOT CONSIDERED TO BE ATOMS; + (ATOM H) RETURNS NIL FOR ANY HUNK H. + [5B] (HUNKP X) IS A PREDICATE WHICH RETURNS T IFF X IS A HUNK. + IN THIS CONTEXT A LIST CELL IS NOT CONSIDERED TO BE A HUNK. + (CXR N H) RETURNS THE N'TH ELEMENT OF THE HUNK H. + (CXR 0 H) IS EQUIVALENT TO (CAR H), AND (CXR 1 H) + IS EQUIVALENT TO (CDR H); IN FACT, THE CAR AND CDR + FUNCTIONS MAY BE USED ON HUNKS AS WELL AS ON LISTS. + (RPLACX N H Z) REPLACES THE N'TH COMPONENT OF H WITH Z. + THE VALUE OF RPLACX IS ITS (MODIFIED) SECOND ARGUMENT. + THUS (RPLACX 0 H Z) IS EQUIVALENT TO (RPLACA H Z), + AND (RPLACX 1 H Z) IS EQUIVALENT TO (RPLACD H Z). + (HUNK N) CREATES A HUNK OF SIZE N AND RETURNS IT. + (HUNK 0) RETURNS NIL, AND (HUNK 1) OR (HUNK 2) + RETURNS A LIST CELL. ALL COMPONENTS ARE INITIALIZED + TO NIL. THE COMPONENTS ARE NUMBERED FROM 0 TO N-1. + (HUNKIFY A0 A2 ... AN-1) IS EQUIVALENT TO + ((LAMBDA (H) + (RPLACX 0 A0) + ... + (RPLACX N-1 AN-1)) + (HUNK N)) + THAT IS, IT CREATES A HUNK WHOSE COMPONENTS ARE THE + ARGUMENTS TO HUNKIFY. NOTE THAT, AS FUNNY BOUNDARY + CASES, (HUNKIFY) RETURNS NIL, AND (HUNKIFY X) + IS THE SAME AS (NCONS X). + (HUNKSIZE H) RETURNS THE NUMBER OF COMPONENTS IN + THE HUNK H. HUNKSIZE OF A LIST CELL IS 2; HUNKSIZE + OF NIL IS 0. + [5C] EQUAL WILL COMPARE HUNKS BY DOING A RECURSIVE + COMPONENT BY COMPONENT COMPARISON. SXHASH WILL + COMPUTE THE HASH ON THE BASIS OF ALL COMPONENTS. + [5D] HUNKS ARE PRINTED USING AN EXTENSION TO DOT NOTATION + SUGGESTED BY RMS. SINCE LIST CELLS ARE CONSIDERED TO + BE 2-HUNKS, AND ARE PRINTED AS (CAR . CDR), THE RESULT + OF (HUNKIFY A0 A1 A2 +++ AN-2 AN-1) IS PRINTED AS + (A0 . A2 . A3 . +++ . AN-2 . AN-1 . A1), WHERE "+++" + IS USED AS AN ELLIPSIS TO AVOID CONFUSION WITH THE + DOT NOTATION. THUS WE HAVE: + (HUNKIFY 0) => (0) + (HUNKIFY 0 1) => (0 . 1) + (HUNKIFY 0 1 2) => (0 . 2 . 1) + (HUNKIFY 0 1 2 3) => (0 . 2 . 3 . 1) + THE REASON FOR THE STRANGE PLACEMENT OF A1 IS SO THAT + THE CDR WILL BE LAST. THIS MAY SEEM RATHER KLUDGY, BUT + ACTUALLY LENDS ITSELF TO CERTAIN ELEGANT EXTENSIONS. + ONE IS A GENERAL EXTENSION OF THIS DOT NOTATION TO LIST + NOTATION. AS AN EXAMPLE, CONSIDER: + (A B . C . D E . F G H I . J . K) + THIS IS HOW PRINT WOULD REPRESENT THE RESULT OF: + (HUNKIFY 'A + (HUNKIFY 'B + (HUNKIFY 'E + (HUNKIFY 'G + (HUNKIFY 'H + (HUNKIFY 'I + 'K + 'J))) + 'F) + 'C + 'D)) + THE BASIC IDEA IS THAT CONSECUTIVE ITEMS SEPARATED BY DOTS + ALL BELONG TO THE SAME HUNK; ITEMS SEPARATED ONLY BY SPACES + BELONG TO DIFFERENT HUNKS, AND THE SECOND HUNK IS THE CDR + (I.E. THE (CXR 1)) OF THE FIRST HUNK. ANOTHER WAY TO THINK + ABOUT IT IS TO REPLACE THE TWO PARENS BY SUPER-BRACKETS, + AND THEN BETWEEN TWO ITEMS SEPARATED BY SPACE BUT NOT DOT + INSERT ".(". NOTE THAT THE DEFINITION OF (HUNKIFY X) + AS (NCONS X) CAUSES THE BOUNDARY CONDITION AT THE END OF + THE LIST TO WIN. + AS A SPECIAL CASE, IF THE CDR OF A HUNK (OTHER THAN A LIST + CELL) IS NIL, THAT NIL MAY BE ELIDED (BUT THE PRECEDING DOT + MAY NOT BE ELIDED!). THUS: + (HUNKIFY 1 (HUNKIFY 2 NIL 3 4) 5) => (1 . 5 2 . 3 . 4 .) + (HUNKIFY 'A + (HUNKIFY 'B + (HUNKIFY 'C + NIL + 'D) + 'E) + 'F) => (A . F B . E C . D .) + MAYBE EVENTUALLY READ WILL KNOW HOW TO READ THESE IN. + [5E] MOST OTHER FUNCTIONS WHICH OPERATE ON LIST STRUCTURE + WILL TREAT HUNKS AS LIST CELLS, USING ONLY THE FIRST + TWO POINTERS. (IN PARTICULAR, SUBST AND SUBLIS DO + NOT PRESENTLY KNOW ANYTHING SPECIAL ABOUT HUNKS; + HENCE (SUBST NIL NIL H) WILL NOT COPY A HUNK!) + EVAL ALSO TREATS HUNKS AS LIST CELLS; THUS THE EXPRESSION + (PLUS . FIXNUM . SIMP 1 2 3) + EVALUATES TO 6, IGNORING "FIXNUM" AND "SIMP". + IMAGINE THE POSSIBILITIES FOR HACKING! + [5F] (STATUS FEATURE HUNK) IS NON-NIL IFF LISP HAS THE HUNK STUFF. + [5G] (STATUS SPCNAMES) WILL INCLUDE THE NAMES OF ALL THE ACTUAL + SPACES. IN THE CURRENT IMPLEMENTATION HUNKS HAVE SPACES + FOR HUNKS OF VARIOUS POWERS OF TWO IN SIZE, NAMELY 4., 8., + 16., ... UP TO SOME LIMIT (PROBABLY 16., THOUGH IT IS AN + ASSEMBLY PARAMETER I CAN CHANGE IF ANYONE NEEDS IT). + A HUNK OF 11. POINTERS IS MADE USING ONE OF 16. POINTERS + AND MARKING 5. OF THEM AS UNUSED. IT IS PROBABLY NOT + A GOOD IDEA TO DEPEND ON THIS IMPLEMENTATION, AS ONE CAN + IMAGINE MORE HACKISH IMPLEMENTATIONS (BUDDY BLOCK, ETC.). + [5H] (STATUS GCSIZE), (STATUS GCMAX), (ALLOC T), AND SIMILAR + HACKS ALL KNOW ABOUT THE SPACE NAMES FOR HUNKS AS + RETURNED BY (STATUS SPCNAMES). + +THIS LAST MESS IS IN NEWIO ONLY! + +[I] HUMBLE PACKAGE FOR HACKING INFERIOR JOBS ON ITS + LIBLSP;HUMBLE FASL CONTAINS A COLLECTION OF PRIMITIVES FOR + HACKING INFERIOR JOBS FROM LISP. SOME LESS PRIMITIVE PACKAGES + WHICH USE HUMBLE ALSO EXIST; JLK IS A GOOD PERSON TO ASK. + [I1] THE FOLLOWING SPECIAL VARIABLES ARE SACRED TO HUMBLE: + CURRENT-JOB + THE-JOB-INPUT-CHANNEL + THE-JOB-OUTPUT-CHANNEL + THE-JOB-INPUT-CHANNEL-FILE-OBJECT + THE-JOB-OUTPUT-CHANNEL-FILE-OBJECT + THE USER OF HUMBLE NEED CONCERN HIMSELF ONLY WITH + CURRENT-JOB. IF NON-NIL, THIS IS THE JOB OBJECT FOR + THE CURRENT JOB. HUMBLE USES TWO I/O CHANNELS, WHICH + ARE USED TO SERVE THE CURRENT JOB. + JOB OBJECTS ARE SIMILAR TO NEWIO FILE OBJECTS. THEIR + FORMAT IS DOCUMENTED (AND SYMBOLS DEFINED) IN LISP;DEFNS >. + HUMBLE AND LISP MAINTAIN INTERNALLY A TABLE OF JOB OBJECTS + (KEPT AT LOCATION JOBTB). IF A JOB OBJECT IS EVER GARBAGE + COLLECTED, GC PRINTS A MESSAGE AND .UCLOSE'S THE JOB. + [I2] (CREATE-JOB ) + CREATES A JOB OBJECT, AND MAKES IT CURRENT. + AND ARE THE INTERRUPT FUNCTIONS + TO BE USED IF AN INTERRUPT IS RECEIVED ON THE INFERIOR + OR ON THE I/O CHANNELS USED TO SERVICE INFERIORS, + RESPECTIVELY. THEY RECEIVE ONE ARGUMENT, THE JOB + OBJECT OR FILE OBJECT ASSOCIATED WITH THE INTERRUPT. + AND ARE OPTIONAL ARGUMENTS. + = NIL (DEFAULT) MEANS YOUR UNAME. + = T (NON-DEFAULT) MEANS REQUIRE FOREIGN JOB. + CREATE-JOB RETURNS A LIST OF TWO THINGS: + (1) ONE OF THE FOLLOWING ATOMS: + INFERIOR, REOWNED, FOREIGN + (2) THE NEWLY CREATED JOB OBJECT + IF WAS NON-NIL AND THE JOB WAS NOT FOUND, + NIL IS RETURNED. + [I3] (SELECT-JOB ) MAKES THE SPECIFIED JOB CURRENT IN THE + EXPECTED MODE (FOREIGN OR NOT), RETURNING VALUES AS FOR + CREATE-JOB. + [I4] (KILL-JOB) KILLS THE CURRENT JOB. + [I5] (LOAD-JOB ) OPENS UP FILE (SPECIFIED + AS A NEWIO NAMELIST OR NAMESTRING) AND LOADS IT INTO TH + CURRENT JOB AS A BINARY PROGRAM (USES THE LOAD SYSTEM CALL). + RETURNS: + NIL WON! + BIN? FILE NOT BIN + FILE? FILE NOT FOUND + [I6] (JOB-USET-READ ) RETURNS VALUE OF USET VAR , + OR NIL IF NO CURRENT JOB. + (JOB-USET-WRITE ) WRITES USET VAR , + THEN RETURNS T FOR SUCCESS OR NIL IF NO CURRENT JOB OR THE + CURRENT JOB IS FOREIGN. SHOULD HAVE THE 400000 BIT SET. + [I7] (EXAMINE-JOB ) EXAMINES LOCATION OF CURRENT JOB. + RETURNS NIL ON FAILURE (INDICATES BAD ERROR). + (DEPOSIT-JOB ) DEPOSITS IN OF CURRENT JOB. + RETURNS NIL ON FAILURE (INDICATES BAD ERROR). + [I8] (*ATTY) DOES A .ATTY TO THE CURRENT JOB; (*DTTY) DOES A .DTTY. + BOTH RETURN T FOR SUCCESS AND NIL FOR FAILURE. + [I9] THERE EXIST PACKAGES OF MACROS AND HIGHER-LEVEL FUNCTIONS + FOR HACKING INFERIOR JOBS. SEE JLK OR RZ FOR IDEAS. + +MONDAY, MARCH 22,1976 FM+6D.22H.2M.17S. LISP 1130 - GLS & JONL - + +[1] (STATUS XUNAME) AND (STATUS XJNAME) NOW EXIST. +[2] FUNNY FORMAT DEFUN ALLOWS ARBITRARY PROPERTY NAMES +[3] PRIN1 DOES VERTICAL BAR AND LOOKAHEAD CLEVERNESS +[4] BREAK MAY TAKE ONE ARGUMENT, DEFAULTING THE SECOND TO T +[5] VALUE OF $P IS THE $P ATOM (NIL => NONE) +[6] *NOPOINT CONTROLS OUTPUT OF LEADING SUPRA-DECIMAL + +THE FOLLOWING CHANGES APPLY TO NEWIO ONLY: +[A] OPENI, OPENO, OPENA HAVE GONE AWAY +[B] (STATUS FILEMODE) RETURNS NIL IF GIVEN A CLOSED FILE. +[C] CLI-MESSAGE INTERRUPT HANDLER +[D] NEW FUNCTIONS: ALLFILES AND FRIENDS +[E] WHO-LINE STATUS CALLS +[F] (STATUS TTYTYPE ) RETURNS TCTYP +[G] EXAMPLES OF KEYBOARD PRE-SCAN FUNCTIONS +---------------------------------------------------------------- +[1] (STATUS XUNAME) AND (STATUS XJNAME) WERE ADDED AS AN + AUGMENTATION TO (STATUS UNAME) AND (STATUS JNAME). +[2] THE "FUNCTION NAME" IN A DEFUN FORM MAY BE A 3-LIST; + THE FIRST ELEMENT IS THE NAME, THE SECOND THE "EXPR" + PROPERTY NAME, AND THE THIRD THE "SUBR" PROPERTY NAME. + THAT IS, INSTEAD OF USING THE PROPERTY NAME "EXPR" + (OR "FEXPR"), THE INTERPRETER WILL USE THE PROPERTY NAME + WHICH IS THE SECOND ELEMENT, AND THE COMPILER WILL USE + THAT WHICH IS THE THIRD NAME. THE TYPE OF THE FUNCTION + IS STILL DETERMINED BY THE OPTIONAL FLAG "FEXPR" + AND WHETHER THE LAMBDA VARIABLE LIST IS ATOMIC. + EXAMPLE: + (DEFUN (FOO QEXPR QSUBR) (A B) ...) + IN THE INTERPRETER PUTS A LAMBDA EXPRESSION UNDER + THE "QEXPR" PROPERTY OF "FOO", AND IN THE COMPILER + COMPILES A SUBR OF TWO ARGUMENTS HEADED BY THE + LAP STATEMENT (LAP FOO QSUBR) INSTEAD OF + (LAP FOO SUBR). +[3] MOSTLY FOR AESTHETIC REASONS, PRIN1 IS NOW MORE CLEVER + ABOUT PRINTING ATOMS: + (A) IF PRIN1 THINKS VERTICAL BARS WILL LOOK NICER + THAN SLASHES, IT WILL USE THEM. + (B) IF IT LOOKS LIKE THE NEXT ATOM TO PRINT WILL + NOT FIT ON THE LINE, PRIN1 TRIES TO GET + A TERPRI IN BEFORE THE ATOM, THUS AVOIDING + SPLITTING AN ATOM ACROSS A NEWLINE. + THESE HEURISTICS MAY BECOME EVEN MORE CLEVER IN THE FUTURE. + PRINC DOES NOT USE ANY OF THESE HACKS. FLATSIZE USES + THE FIRST, BUT NOT THE SECOND. +[4] THE FORM (BREAK FOO) IS NOW THE SAME AS (BREAK FOO T). +[5] THE BREAK LOOP NO LONGER LOOKS FOR THE ATOM P. + INSTEAD, IT LOOKS FOR THE ATOM WHICH IS THE VALUE + OF THE ATOM P, WHICH IS INITIALLY SET TO 'P, SO IT + WORKS AS BEFORE BHY DEFAULT. IF P IS NIL, THEN NO + ATOM WILL SERVE THE P FUNCTION. +[6] IF BASE IS GREATER THAN 10., *NOPOINT IF NON-NIL + WILL SUPPRESS THE + WHICH NORMALLY PRECEDES POSITIVE + SUPRA-DECIMAL NUMBERS. FOR BASE = 10., *NOPOINT + STILL SUPPRESSES THE TRAILING DECIMALLL POINT. + +THE FOLLOWING CHANGES APPLY TO NEWIO ONLY: + +[A] OPENI, OPENO, OPENA HAVE GONE AWAY. USE OPEN + WITH THE "IN", "OUT", OR "APPEND" OPTION IN THE + SECOND ARGUMENT. +[B] (STATUS FILEMODE ) RETURNS NIL FOR A CLOSED FILE. + FOR OPEN FILES, IT OPERATES AS IT ALWAYS HAS. + FOR A NON-FILE, IT GIVES A WRNG-TYPE-ARG ERROR. +[C] THE ATOM "CLI-MESSAGE" HAS AS ITS VALUE THE USER + INTERRUPT FUNCTION FOR THE CLI DEVICE INTERRUPT. + THE FUNCTION GETS A SINGLE ARGUMENT OF NIL. + IT SHOULD OPEN THE "CLA:" DEVICE IN RESPONSE TO + THE INTERRUPT IN ORDER TOP READ THE MESSAGE. + ONE OF THE OPTIONS IN OPEN'S SECOND ARGUMENT SHOULD + BE "CLA" (AS OPPOSED TO "DSK" OR "TTY"); THIS CAUSES + OPEN TO READ THE FIRST TWO WORDS OF THE FILE AND USE + THEM AS THE FILE NAMES FOR THE TRUENAME FUNCTION. THE + CLA: FILE SHOULD BE OPENED IN BLOCK MODE FOR THIS PURPOSE. + THE DEFAULT CLI-MESSAGE FUNCTION IS NIL, I.E. IGNORE + THE INTERRUPTS. +[D] FOUR NEW FUNCTIONS (AUTOLOADABLE) NOW EXIST FOR LOOKING + AT FILE DIRECTORIES: ALLFILES, DIRECTORY, MAPALLFILES, + AND MAPDIRECTORY. + + (ALLFILES X) TAKES A LIST OF NAMELISTS (AND NAMESTRINGS) X AND RETURNS A LIST + OF NAMELISTS IN THE FILE SYSTEM WHICH MATCH ELEMENTS OF X. + THERE IS NO GUARANTEE AS TO THE ORDERING OF THE FILES IN + THE RETURNED LIST. IF A SORTED LIST IS DESIRED, THE SORTCAR + FUNCTION SHOULD BE USED WITH AN APPROPRIATE PREDICATE. + NOTE WELL THAT X IS A *LIST* OF NAMELISTS, AND NOT JUST + A SINGLE NAMELIST; THIS IS AN INCOMPATIBILITY WITH THE ALLFILES + FUNCTION DESCRIBED IN THE MOONUAL. + + EXAMPLE: (ALLFILES '(|GLS;ALLFIL| ((DSK TGQ) * SONG) |* BIN|)) + RETURNS DESCRIPTORS FOR ALL FILES ON GLS'S DIRECTORY WITH + FIRST NAME "ALLFIL", ALL SONGS ON TGQ, AND ALL DSK FILES IN + ANY DIRECTORY WITH SECOND NAME "BIN". + + (DIRECTORY X) IS LIKE (ALLFILES X), BUT INSTEAD OF + NAMELISTS IT RETURNS A LIST OF FILE DESCRIPTORS, WHERE + EACH DESCRIPTOR HAS A NAMELIST IN THE CAR AND A + PROPERTY LIST IN THE CDR. TYPICAL PROPERTIES ARE: + WORDS SIZE OF FILE IN PDP-10 WORDS + CHARACTERS SIZE OF FILE IN ASCII CHARACTERS + BITS SIZE IN BITS (TO BE IMPLEMENTED WHEN ITS SUPPORTS IT) + CREDATE DATE OF CREATION + CRETIME TIME OF CREATION + REFDATE DATE OF MOST RECENT REFERENCE + LINK NAME LINKED TO + PACK PACK NUMBER + UNDUMPED T IF FILE NOT YET BACKED UP ON MAGTAPE + NOREAP T IF NO REAP BIT IS SET + + (DIRECTORY X PROPS) IS SIMILAR, BUT INCLUDES ONLY + THE PROPERTIES MENTIONED IN "PROPS" FOR EFFICIENCY. + AS A SPECIAL CASE, OMITTING "LINK" CAUSES LINKS NOT + TO BE INCLUDED AT ALL. + + (MAPALLFILES FN X) IS LIKE (MAPC FN (ALLFILES X)) + BUT DOESN'T HAVE TO CONS UP THE WHOLE LIST AT ONCE. + + (MAPDIRECTORY FN X) AND (MAPDIRECTORY FN X PROPS) + ARE SIMILAR. + + MATCHING: + AT PRESENT, THE ONLY MATCHING CAPABILITIES IN ALLFILES + ARE DIRECT NAME EQUALITY AND *, WHICH MATCHES ANYTHING. + * AS A DEVICE NAME IMPLIES DSK. + * AS A DIRECTORY NAME USES ALL DIRECTORIES FOR DSK, + AND THE DEFAULT DIRECTORY FOR ALL OTHER DEVICES. + IN THIS CONTEXT, AI, ML, MC, AND DM ARE *NOT* CONSIDERED + TO BE DSK DEVICES; BUT IN OTHER CONTEXTS THEY ARE. + +[E] (SSTATUS WHO1 A B C D) SETS THE .WHO1 USER VARIABLE TO + <.BYTE 8 ? A ? B ? C ? D> + IN MIDAS TERMINOLOGY. A AND C MUST BE FIXNUMS; B AND D + MUST BE FIXNUMS WITH ASCII VALUES, OR CHARACTER OBJECTS. + (SSTATUS WHO2 X) AND (SSTATUS WHO3 X) SET THE .WHO2 AND + .WHO3 USER VARIABLES. X MAY BE A FIXNUM OR A SYMBOL; + IN THE LATTER CASE THE FIRST SIX CHARACTERS ARE USED TO + FORM A SIXBIT WORD. + THE .WHON USER VARIABLES CAUSE INFORMATION TO BE DISPLAYED + IN THE TERMINAL'S WHO-LINE. + THE MEANING OF A, B, C, AND D IS AS FOLLOWS: + VAR BITS MEANING + A 200 IF 1, SUPPRESS ENTIRE WHO-LINE + 100 SUPPRESS SPACE BETWEEN HALVES OF .WHO2 + 70 MODE FOR PRINTING LEFT HALF OF .WHO2 + 0 DO NOT PRINT + 1 DATE IN PACKED FORM: + 774000 YEAR MOD 100. + 3600 MONTH (1=JANUARY) + 174 DAY OF MONTH + 2 TIME IN FORTIETHS OF A SECOND, + PRINTED AS HH:MM:SS.T + 3 TIME IN HALF-SECONDS, + PRINTED AS HH:MM:SS + 4 OCTAL HALFWORD + 5 DECIMAL HALFWORD (NO . SUPPLIED) + 6 THREE SIXBIT CHARACTERS + 7 UNUSED + 7 MODE FOR RIGHT HALF OF .WHO2 + B 177 IF NON-ZERO, PRINT BETWEEN HALVES OF + .WHO2 AS AN ASCII CHARACTER + 200 IF 1, PRINT CHAR TWICE + C 200 IF 1, SUPPRESS SPACE BETWEEN .WHO2 + PRINTOUT AND .WHO3 PRINTOUT + OTHERWISE LIKE A, BUT FOR .WHO3. + D LIKE B, BUT FOR .WHO3. + THAT IS, IF THE WHO-LINE IS PRINTED AT ALL, WHAT APPEARS + AT THE END IS THE CHARACTERS: + IIIIXX-JJJJ=KKKKYY+LLLL + WHERE: + IIII IS THE RESULT OF PRINTING THE LEFT HALF + OF .WHO2 AS SPECIFIED BY A'S 70 BITS. + JJJJ RIGHT HALF OF .WHO2, BY A'S 7 BITS. + KKKK LEFT HALF OF .WHO3, BY C'S 70 BITS. + LLLL RIGHT HALF OF .WHO3, BY C'S 7 BITS. + XX ZERO TO TWO CHARACTERS, SPECIFIED BY B. + YY ZERO TO TWO CHARACTERS, SPECIFIED BY D. + - SPACE, UNLESS A'S 100 BIT IS 1. + = SPACE, UNLESS C'S 200 BIT IS 1. + + SPACE, UNLESS C'S 100 BIT IS 1. + EXAMPLE: + (SSTATUS WHO1 166 0 144 '/!) + (SSTATUS WHO2 'FOOBAR) + (SSTATUS WHO3 (+ (LSH 1234 22) 3456)) + CAUSES "FOOBAR 1234!5678" TO APPEAR IN THE WHO-LINE. + + THE STATUS FORMS ARE AS FOLLOWS: + (STATUS WHO1) RETURNS A LIST OF FOUR FIXNUMS. + (STATUS WHO2) AND (STATUS WHO3) RETURN FIXNUMS. + +[F] (STATUS TTYTYPE ) RETURNS THE TCTYP VARIABLE + FOR THE SPECIFIED OUTPUT TTY (IF OMITTED, THIS DEFAULTS + TO T, THE STANDARD OUTPUT TTY). THIS IS THE EXTENSION + IN NEWIO TO OLDIO'S SETTING OF THE VARIABLE "TTY". + FOR COMPATIBILITY, WHEN IT STARTS UP, NEWIO LISP DOES + (SETQ TTY (STATUS TTYTYPE T)). + POSSIBLE VALUES ARE: + 0 PRINTING CONSOLE + 1 GOOD DATAPOINT + 2 "LOSER" DATAPOINT + 3 IMLAC + 4 TEKTRONIX 4000 SERIES (FORMERLY ARDS) + 5 PDP-11 (KNIGHT) TV DISPLAY + 6 MEMOREX (FORMERLY HORIZONTAL ARDS) + 7 SOFTWARE TTY + 10 TERMINET + 11 TTY USING ASCII STANDARD DISPLAY SEQUENCES + IN GENERAL, IT IS BETTER NOT TO USE THIS STATUS FUNCTION, + BUT RATHER TO SAY (STATUS FILEMODE ) AND + LOOK FOR FLAGS SUCH AS "RUBOUT" AND "CURSORPOS". + +[G] EXAMPLES OF KEYBOARD PRE-SCAN FUNCTIONS. + +(1) THE KEYBOARD PRE-SCAN FUNCTION IS THE ONE SET BY + (SSTATUS TTYSCAN ...). IT IS THE FUNCTION WHICH HANDLES + RUBOUT AND ^L PROCESSING. AS AN EXAMPLE, THE FUNCTION + GIVEN HERE IS A VERY CLOSE APPROXIMATION TO THE DEFAULT + PROVIDED BY LISP. + +------------------------------------------------------------ +SAMPLE TTY PRESCAN FUNCTION -- APPROXIMATELY THE ONE IN LISP +------------------------------------------------------------ +(DECLARE (MAPEX)) + +(DEFUN CONSTANT MACRO (X) + (LIST 'DEFUN (CADR X) 'MACRO '(X) (LIST 'QUOTE (CADDR X)))) + +(DEFUN LOGAND MACRO (X) (CONS 'BOOLE (CONS '1 (CDR X)))) +(DEFUN LOGOR MACRO (X) (CONS 'BOOLE (CONS '7 (CDR X)))) +(DEFUN LOGCLR MACRO (X) (CONS 'BOOLE (CONS '4 (CDR X)))) + +(DEFUN PUSH MACRO (X) (LIST 'SETQ (CADDR X) (LIST 'CONS (CADR X) (CADDR X)))) +(DEFUN POP MACRO (X) + (LIST 'PROG2 NIL + (LIST 'CAR (CADR X)) + (LIST 'SETQ (CADR X) (LIST 'CDR (CADR X))))) + +(CONSTANT TOP 4000) ;NAMES OF BITS FOR KNIGHT KEYBOARDS +(CONSTANT SHIFTLOCK 2000) +(CONSTANT SHIFT 1000) +(CONSTANT META 400) +(CONSTANT CTRL 200) +(CONSTANT ASCII-BITS 177) + +(CONSTANT ^K 13) ;VARIOUS ASCII CHARACTERS +(CONSTANT ^L 14) +(CONSTANT ^M 15) +(CONSTANT SPACE 40) +(CONSTANT OPEN-PAREN 50) +(CONSTANT VERTICAL-BAR 174) +(CONSTANT PSEUDOSPACE 203) ;A FAKE SPACE (INTERNAL TO LISP) + +(CONSTANT SLASH-SYNTAX 2000) ;BITS IN READER SYNTAX TABLE +(CONSTANT ALTERNATE-SYNTAX 40) +(CONSTANT OPEN-SYNTAX 40000) +(CONSTANT CLOSE-SYNTAX 10000) +(CONSTANT RUBOUT-SYNTAX 1000) +(CONSTANT FORCE-FEED 1000) ;WITH ALTERNATE-SYNTAX +(CONSTANT SPACE-SYNTAX 100000) +(CONSTANT SINGLE-SYNTAX 200000) +(CONSTANT MACRO-SYNTAX 4000) +(CONSTANT WORTHY-SYNTAX 277237) ;"WORTHY" CHARACTERS + +(CONSTANT SLASH-FLAG 400000) +(CONSTANT STRING-BEGIN-FLAG 200000) +(CONSTANT STRING-END-FLAG 100000) + +(DEFUN TYI7 (IFILE) + ((LAMBDA (CH) + (COND ((ZEROP (LOGAND (CTRL) CH)) CH) + ((= CH (+ (CTRL) 177)) 177) + (T (LOGAND CH 37)))) + (LOGCLR (TYI IFILE) (LOGOR (TOP) (SHIFTLOCK) (SHIFT) (META))))) + +(DEFUN REPRINT (CHARS COUNT POS OFILE) + (DECLARE (FIXNUM COUNT)) + (COND (OFILE + (AND POS (CURSORPOS (CAR POS) (CDR POS) OFILE)) + (AND (PLUSP COUNT) + (DO ((I 0 (1+ I))) + ((= I COUNT) (TYO (SPACE) OFILE)) + (DECLARE (FIXNUM I)) + (TYO (OPEN-PAREN) OFILE))) + (MAPCAR '(LAMBDA (CH) (TYO (LOGAND CH (ASCII-BITS)) OFILE)) CHARS)))) + +(DEFUN TTY-PRESCAN (IFILE FN PARENSCOUNT) + (DECLARE (FIXNUM PARENSCOUNT)) + (PROG (USEFUL STARTPOS OFILE STRING-END BUFFER CH SYNTAX LINMODE TTYREAD COUNT) + (DECLARE (FIXNUM STRING-END CH SYNTAX COUNT)) + (AND (SETQ OFILE (STATUS TTYCONS IFILE)) + (SETQ STARTPOS (CURSORPOS OFILE))) + (SETQ LINMODE (STATUS LINMODE IFILE)) + (SETQ TTYREAD (STATUS TTYREAD IFILE)) + (SETQ COUNT PARENSCOUNT) + (SETQ STRING-END -1) + LOOP (SETQ SYNTAX (STATUS SYNTAX (SETQ CH (TYI7 IFILE)))) + (COND ((= CH (^M)) + (COND ((EQ FN 'READLINE) (GO DONE)) + (LINMODE + (OR (MINUSP STRING-END) (PUSH (PSEUDOSPACE) BUFFER)) + (GO DONE))))) + (COND ((OR (= CH (^K)) (= CH (^L))) + (COND ((NULL OFILE) (GO LOOP)) + (T (COND ((AND (= CH (^L)) STARTPOS) + (CURSORPOS 'C OFILE)) + (T (TERPRI OFILE))) + (SETQ STARTPOS (CURSORPOS OFILE)) + (REPRINT (REVERSE BUFFER) PARENSCOUNT NIL OFILE) + (GO LOOP)))) + ((AND (NOT (EQ FN 'READLINE)) + (PLUSP (LOGAND SYNTAX (SLASH-SYNTAX)))) + (PUSH CH BUFFER) + (PUSH (LOGOR (SLASH-FLAG) (TYI7)) BUFFER) + (SETQ USEFUL T) + (GO LOOP)) + ((AND (PLUSP (LOGAND SYNTAX (RUBOUT-SYNTAX))) + (ZEROP (LOGAND SYNTAX (ALTERNATE-SYNTAX)))) + (COND (BUFFER + (AND OFILE + (OR (RUBOUT (LOGCLR (SETQ CH (POP BUFFER)) + (LOGOR (SLASH-FLAG) + (STRING-BEGIN-FLAG) + (STRING-END-FLAG))) + OFILE) + (REPRINT (REVERSE BUFFER) PARENSCOUNT STARTPOS OFILE))) + (COND ((PLUSP (LOGAND CH (SLASH-FLAG))) + (AND OFILE + (OR (RUBOUT (POP BUFFER) OFILE) + (REPRINT (REVERSE BUFFER) PARENSCOUNT STARTPOS OFILE)))) + ((NOT (MINUSP STRING-END)) + (AND (PLUSP (LOGAND CH (STRING-BEGIN-FLAG))) + (SETQ STRING-END -1))) + ((PLUSP (LOGAND CH (STRING-END-FLAG))) + (SETQ STRING-END (LOGAND CH (ASCII-BITS)))) + ((PLUSP (LOGAND (SETQ SYNTAX + (STATUS SYNTAX + (LOGCLR CH + (LOGOR (SLASH-FLAG) + (STRING-BEGIN-FLAG) + (STRING-END-FLAG))))) + (OPEN-SYNTAX))) + (SETQ COUNT (- COUNT 1))) + ((PLUSP (LOGAND SYNTAX (CLOSE-SYNTAX))) + (SETQ COUNT (+ COUNT 1))))) + (T (AND OFILE (TERPRI OFILE)))) + (GO LOOP)) + ((EQ FN 'READLINE) + (PUSH CH BUFFER) + (GO LOOP)) + ((NOT (MINUSP STRING-END)) + (COND ((= CH STRING-END) + (PUSH (LOGOR CH (STRING-END-FLAG)) BUFFER) + (SETQ STRING-END -1)) + (T (PUSH CH BUFFER))) + (GO LOOP)) + ((AND (PLUSP (LOGAND SYNTAX (FORCE-FEED))) + (PLUSP (LOGAND SYNTAX (ALTERNATE-SYNTAX)))) + (GO DONE)) + ((PLUSP (LOGAND SYNTAX (SPACE-SYNTAX))) + (COND ((OR (PLUSP COUNT) (NOT USEFUL) LINMODE (NOT TTYREAD)) + (PUSH CH BUFFER) + (GO LOOP)) + (T (GO DONE)))) + ((PLUSP (LOGAND SYNTAX (SINGLE-SYNTAX))) + (COND ((OR (PLUSP COUNT) LINMODE (NOT TTYREAD)) + (SETQ USEFUL T) + (PUSH CH BUFFER) + (GO LOOP)) + (T (GO DONE)))) + ((PLUSP (LOGAND SYNTAX (MACRO-SYNTAX))) + ((LAMBDA (MAC) + (COND ((EQ MAC '+INTERNAL-/;-MACRO) + (PUSH (LOGOR CH (STRING-BEGIN-FLAG)) BUFFER) + (SETQ STRING-END (^M))) + ((EQ MAC '+INTERNAL-/|-MACRO) + (PUSH (LOGOR CH (STRING-BEGIN-FLAG)) BUFFER) + (SETQ STRING-END (VERTICAL-BAR))) + (T (PUSH CH BUFFER)))) + (CAR (STATUS MACRO (+ CH 0)))) + (SETQ USEFUL T) + (GO LOOP)) + ((PLUSP (LOGAND SYNTAX (OPEN-SYNTAX))) + (SETQ COUNT (+ COUNT 1)) + (SETQ USEFUL T) + (PUSH CH BUFFER) + (GO LOOP)) + ((PLUSP (LOGAND SYNTAX (CLOSE-SYNTAX))) + (COND ((OR (PLUSP COUNT) (NOT USEFUL) LINMODE (NOT TTYREAD)) + (COND ((PLUSP (SETQ COUNT (- COUNT 1))) + (PUSH CH BUFFER) + (GO LOOP)) + (T (GO DONE)))) + (T (GO DONE)))) + ((PLUSP (LOGAND SYNTAX (WORTHY-SYNTAX))) + (PUSH CH BUFFER) + (SETQ USEFUL T) + (GO LOOP)) + (T (PUSH CH BUFFER) (GO LOOP))) + DONE (AND OFILE + ((LAMBDA (POS) + (LINENUM OFILE (CAR POS)) + (CHARPOS OFILE (CDR POS))) + (CURSORPOS OFILE))) + (PUSH CH BUFFER) + (SETQ BUFFER (NREVERSE BUFFER)) + (MAP '(LAMBDA (X) + (AND (PLUSP (LOGAND (CAR X) (LOGOR (SLASH-FLAG) + (STRING-BEGIN-FLAG) + (STRING-END-FLAG)))) + (RPLACA X (LOGCLR (CAR X) (LOGOR (SLASH-FLAG) + (STRING-BEGIN-FLAG) + (STRING-END-FLAG)))))) + BUFFER) + (RETURN BUFFER))) + +AS AN EXAMPLE OF HOW YOU MIGHT CHANGE THIS, HERE IS A SLIGHT +MODIFICATION TO GIVE ONE THE "PARENS BALANCE WINDOW" PROPOSED +BY GREENBLATT: + +------------------------------------------------- +TTY PRESCAN FUNCTION WITH PARENS BALANCING WINDOW +------------------------------------------------- +(DECLARE (ARGS 'CURSORPOS '(0 . 3)) + (SPECIAL IFILE OFILE) + (DEFPROP TTYRE A STATUS) + (DEFPROP TTYSI A STATUS) + (DEFPROP TTYCO A STATUS) + (DEFPROP LINMO A STATUS)) ;FIX NCOMPL BUGS + +(DECLARE (MAPEX T) (NEWIO T)) + +(DEFUN CONSTANT MACRO (X) + (LIST 'DEFUN (CADR X) 'MACRO '(X) (LIST 'QUOTE (CADDR X)))) + +(DEFUN LOGAND MACRO (X) (CONS 'BOOLE (CONS '1 (CDR X)))) +(DEFUN LOGOR MACRO (X) (CONS 'BOOLE (CONS '7 (CDR X)))) +(DEFUN LOGCLR MACRO (X) (CONS 'BOOLE (CONS '4 (CDR X)))) + +(DEFUN PUSH MACRO (X) (LIST 'SETQ (CADDR X) (LIST 'CONS (CADR X) (CADDR X)))) +(DEFUN POP MACRO (X) + (LIST 'PROG2 NIL + (LIST 'CAR (CADR X)) + (LIST 'SETQ (CADR X) (LIST 'CDR (CADR X))))) + +(CONSTANT TOP 4000) ;NAMES OF BITS FOR KNIGHT KEYBOARDS +(CONSTANT SHIFTLOCK 2000) +(CONSTANT SHIFT 1000) +(CONSTANT META 400) +(CONSTANT CTRL 200) +(CONSTANT ASCII-BITS 177) + +(CONSTANT ^K 13) ;VARIOUS ASCII CHARACTERS +(CONSTANT ^L 14) +(CONSTANT ^M 15) +(CONSTANT SPACE 40) +(CONSTANT OPEN-PAREN 50) +(CONSTANT VERTICAL-BAR 174) +(CONSTANT PSEUDOSPACE 203) ;A FAKE SPACE (INTERNAL TO LISP) + +(CONSTANT SLASH-SYNTAX 2000) ;BITS IN READER SYNTAX TABLE +(CONSTANT ALTERNATE-SYNTAX 40) +(CONSTANT OPEN-SYNTAX 40000) +(CONSTANT CLOSE-SYNTAX 10000) +(CONSTANT RUBOUT-SYNTAX 1000) +(CONSTANT FORCE-FEED 1000) ;WITH ALTERNATE-SYNTAX +(CONSTANT SPACE-SYNTAX 100000) +(CONSTANT SINGLE-SYNTAX 200000) +(CONSTANT MACRO-SYNTAX 4000) +(CONSTANT WORTHY-SYNTAX 277237) ;"WORTHY" CHARACTERS + +(CONSTANT SLASH-FLAG 400000) +(CONSTANT STRING-BEGIN-FLAG 200000) +(CONSTANT STRING-END-FLAG 100000) + +(DECLARE (FIXNUM (TYI7 NIL))) + +(DEFUN TYI7 (IFILE) + ((LAMBDA (CH) + (COND ((ZEROP (LOGAND (CTRL) CH)) CH) + ((= CH (+ (CTRL) 177)) 177) + (T (LOGAND CH 37)))) + (LOGCLR (TYI IFILE) (LOGOR (TOP) (SHIFTLOCK) (SHIFT) (META))))) + +(DEFUN REPRINT (CHARS COUNT POS OFILE) + (DECLARE (FIXNUM COUNT)) + (COND (OFILE + (AND POS (CURSORPOS (CAR POS) (CDR POS) OFILE)) + (AND (PLUSP COUNT) + (DO ((I 0 (1+ I))) + ((= I COUNT) (TYO (SPACE) OFILE)) + (DECLARE (FIXNUM I)) + (TYO (OPEN-PAREN) OFILE))) + (MAPCAR '(LAMBDA (CH) (TYO (LOGAND CH (ASCII-BITS)) OFILE)) CHARS)))) + +(DEFUN PROMPTER (BUFFER SIZE OFILE) + (AND OFILE + ((LAMBDA (CHARS POS HAUMANY) + (CURSORPOS 0 (- (CDR SIZE) HAUMANY 5) OFILE) + (CURSORPOS 'L OFILE) + (DO ((I 0 (1+ I)) + (L CHARS (CDR L))) + ((OR (NULL L) + (= (CAR L) (^M)) + (= I HAUMANY))) + (DECLARE (FIXNUM I)) + (TYO (LOGAND (CAR L) (ASCII-BITS)))) + (CURSORPOS (CAR POS) (CDR POS) OFILE)) + (DO ((X BUFFER (CDR X)) + (N 0 ((LAMBDA (SYNTAX) + (COND (STRING N) + ((PLUSP (LOGAND SYNTAX (OPEN-SYNTAX))) + (- N 1)) + ((PLUSP (LOGAND SYNTAX (CLOSE-SYNTAX))) + (+ N 1)) + (T N))) + (STATUS SYNTAX (LOGAND (CAR X) (ASCII-BITS))))) + (STRING NIL (COND ((PLUSP (LOGAND (CAR X) (STRING-BEGIN-FLAG))) NIL) + ((PLUSP (LOGAND (CAR X) (STRING-END-FLAG))) T) + (T STRING))) + (CHARS NIL (CONS (CAR X) CHARS))) + ((OR (MINUSP N) (NULL X)) CHARS) + (DECLARE (FIXNUM N))) + (CURSORPOS OFILE) + (// (CDR SIZE) 2)))) + +(DEFUN TTY-PRESCAN (IFILE FN PARENSCOUNT) + (DECLARE (FIXNUM PARENSCOUNT)) + (PROG (USEFUL STARTPOS OFILE STRING-END BUFFER CH SYNTAX LINMODE TTYREAD COUNT SIZE) + (DECLARE (FIXNUM STRING-END CH SYNTAX COUNT)) + (COND ((SETQ OFILE (STATUS TTYCONS IFILE)) + (SETQ STARTPOS (CURSORPOS OFILE)) + (SETQ SIZE (STATUS TTYSIZE OFILE)))) + (SETQ LINMODE (STATUS LINMODE IFILE)) + (SETQ TTYREAD (STATUS TTYREAD IFILE)) + (SETQ COUNT PARENSCOUNT) + (SETQ STRING-END -1) + LOOP (SETQ SYNTAX (STATUS SYNTAX (SETQ CH (TYI7 IFILE)))) + (COND ((= CH (^M)) + (COND ((EQ FN 'READLINE) (GO DONE)) + (LINMODE + (OR (MINUSP STRING-END) (PUSH (PSEUDOSPACE) BUFFER)) + (GO DONE))))) + (COND ((OR (= CH (^K)) (= CH (^L))) + (COND ((NULL OFILE) (GO LOOP)) + (T (COND ((AND (= CH (^L)) STARTPOS) + (CURSORPOS 'C OFILE)) + (T (TERPRI OFILE))) + (SETQ STARTPOS (CURSORPOS OFILE)) + (REPRINT (REVERSE BUFFER) PARENSCOUNT NIL OFILE) + (PROMPTER BUFFER SIZE OFILE) + (GO LOOP)))) + ((AND (NOT (EQ FN 'READLINE)) + (PLUSP (LOGAND SYNTAX (SLASH-SYNTAX)))) + (PUSH CH BUFFER) + (PUSH (LOGOR (SLASH-FLAG) (TYI7 IFILE)) BUFFER) + (SETQ USEFUL T) + (GO LOOP)) + ((AND (PLUSP (LOGAND SYNTAX (RUBOUT-SYNTAX))) + (ZEROP (LOGAND SYNTAX (ALTERNATE-SYNTAX)))) + (COND (BUFFER + (AND OFILE + (OR (RUBOUT (LOGCLR (SETQ CH (POP BUFFER)) + (LOGOR (SLASH-FLAG) + (STRING-BEGIN-FLAG) + (STRING-END-FLAG))) + OFILE) + (REPRINT (REVERSE BUFFER) PARENSCOUNT STARTPOS OFILE))) + (COND ((PLUSP (LOGAND CH (SLASH-FLAG))) + (AND OFILE + (OR (RUBOUT (POP BUFFER) OFILE) + (REPRINT (REVERSE BUFFER) PARENSCOUNT STARTPOS OFILE)))) + ((NOT (MINUSP STRING-END)) + (AND (PLUSP (LOGAND CH (STRING-BEGIN-FLAG))) + (SETQ STRING-END -1))) + ((PLUSP (LOGAND CH (STRING-END-FLAG))) + (SETQ STRING-END (LOGAND CH (ASCII-BITS)))) + ((PLUSP (LOGAND (SETQ SYNTAX + (STATUS SYNTAX + (LOGCLR CH + (LOGOR (SLASH-FLAG) + (STRING-BEGIN-FLAG) + (STRING-END-FLAG))))) + (OPEN-SYNTAX))) + (PROMPTER BUFFER SIZE OFILE) + (SETQ COUNT (- COUNT 1))) + ((PLUSP (LOGAND SYNTAX (CLOSE-SYNTAX))) + (PROMPTER BUFFER SIZE OFILE) + (SETQ COUNT (+ COUNT 1))))) + (T (AND OFILE (TERPRI OFILE)))) + (GO LOOP)) + ((EQ FN 'READLINE) + (PUSH CH BUFFER) + (GO LOOP)) + ((NOT (MINUSP STRING-END)) + (COND ((= CH STRING-END) + (PUSH (LOGOR CH (STRING-END-FLAG)) BUFFER) + (SETQ STRING-END -1)) + (T (PUSH CH BUFFER))) + (GO LOOP)) + ((AND (PLUSP (LOGAND SYNTAX (FORCE-FEED))) + (PLUSP (LOGAND SYNTAX (ALTERNATE-SYNTAX)))) + (GO DONE)) + ((PLUSP (LOGAND SYNTAX (SPACE-SYNTAX))) + (COND ((OR (PLUSP COUNT) (NOT USEFUL) LINMODE (NOT TTYREAD)) + (PUSH CH BUFFER) + (PROMPTER BUFFER SIZE OFILE) + (GO LOOP)) + (T (GO DONE)))) + ((PLUSP (LOGAND SYNTAX (SINGLE-SYNTAX))) + (COND ((OR (PLUSP COUNT) LINMODE (NOT TTYREAD)) + (SETQ USEFUL T) + (PUSH CH BUFFER) + (GO LOOP)) + (T (GO DONE)))) + ((PLUSP (LOGAND SYNTAX (MACRO-SYNTAX))) + ((LAMBDA (MAC) + (COND ((EQ MAC '+INTERNAL-/;-MACRO) + (PUSH (LOGOR CH (STRING-BEGIN-FLAG)) BUFFER) + (SETQ STRING-END (^M))) + ((EQ MAC '+INTERNAL-/|-MACRO) + (PUSH (LOGOR CH (STRING-BEGIN-FLAG)) BUFFER) + (SETQ STRING-END (VERTICAL-BAR))) + (T (PUSH CH BUFFER)))) + (CAR (STATUS MACRO (+ CH 0)))) + (SETQ USEFUL T) + (GO LOOP)) + ((PLUSP (LOGAND SYNTAX (OPEN-SYNTAX))) + (SETQ COUNT (+ COUNT 1)) + (SETQ USEFUL T) + (PUSH CH BUFFER) + (PROMPTER BUFFER SIZE OFILE) + (GO LOOP)) + ((PLUSP (LOGAND SYNTAX (CLOSE-SYNTAX))) + (COND ((OR (PLUSP COUNT) (NOT USEFUL) LINMODE (NOT TTYREAD)) + (COND ((PLUSP (SETQ COUNT (- COUNT 1))) + (PUSH CH BUFFER) + (PROMPTER BUFFER SIZE OFILE) + (GO LOOP)) + (T (GO DONE)))) + (T (GO DONE)))) + ((PLUSP (LOGAND SYNTAX (WORTHY-SYNTAX))) + (PUSH CH BUFFER) + (SETQ USEFUL T) + (GO LOOP)) + (T (PUSH CH BUFFER) (GO LOOP))) + DONE (AND OFILE + ((LAMBDA (POS) + (LINENUM OFILE (CAR POS)) + (CHARPOS OFILE (CDR POS))) + (CURSORPOS OFILE))) + (PUSH CH BUFFER) + (SETQ BUFFER (NREVERSE BUFFER)) + (MAP '(LAMBDA (X) + (AND (PLUSP (LOGAND (CAR X) (LOGOR (SLASH-FLAG) + (STRING-BEGIN-FLAG) + (STRING-END-FLAG)))) + (RPLACA X (LOGCLR (CAR X) (LOGOR (SLASH-FLAG) + (STRING-BEGIN-FLAG) + (STRING-END-FLAG)))))) + BUFFER) + (PROMPTER NIL SIZE OFILE) + (RETURN BUFFER))) + +(SSTATUS TTYSCAN 'TTY-PRESCAN) + +WEDNESDAY JUNE 11,1975 NM+2D.17H.37M.36S. LISP 1076 - GLS - + + TRY NEWIO! + +BRIEF SYNOPSIS: + FOR ALL LISPS: +[1] PRIN1, PRINC, AND PRINT NOW ALWAYS RETURN T +[2] NEW FUNCTION: PROGV DOES DYNAMIC VARIABLE BINDING +[3] NEW FUNCTION: MAPATOMS MAPS OVER ALL ATOMS IN AN OBARRAY +[4] FLATC HAS BEEN SPEEDED UP FOR SYMBOLS + FOR NEWIO: +[A] EDIT NOW WORKS +[B] NEW FUNCTION: LOAD LOADS UP BOTH EXPR AND FASL FILES +[C] NEW FUNCTION: INCLUDE IS LIKE A MIDAS .INSRT +[D] UREAD'S EOF HANDLER HAS CHANGED +[E] NEW FUNCTION: FILEPOS IS FINALLY IMPLEMENTED +[F] (STATUS FILEMODE) RETURNS FILEPOS INDICATOR IF APPROPRIATE +---------------------------------------------------------------- +[1] PRIN1, PRINC, AND PRINT NOW ALL RETURN T INSTEAD OF + THEIR ARGUMENTS. THIS IS A BELATED FAST ARITHMETIC MOD. + +[2] (PROGV ... ) + EVALUATES ... AS A PROGN IN AN ENVIRONMENT + CREATED BY BINDING THE SYMBOLS IN TO THE + RESPECTIVE VALUES IN . THAT IS, THE FIRST + TWO ARGUMENTS TO PROGV ARE EVALUATED; THE FIRST MUST + PRODUCE A LIST OF SPECIAL VARIABLES, AND THE SECOND + A LIST OF VALUES. THE VARIABLES ARE THEN BOUND TO THE + VALUES. IF TOO FEW VALUES ARE SUPPLIED, THE REST OF + THE VARIABLES ARE BOUND TO NIL. IF TOO MANY VALUES + ARE SUPPLIED, THE EXCESS VALUES ARE IGNORED. + THE BODY OF THE PROGV IS THEN EVALUATED AS A PROGN, + THE VARIABLES UNBOUND TO THEIR OLD VALUES, AND THE + VALUE OF THE LAST FORM IS RETURNED. + EXAMPLE: + (SETQ A 'FOO) + (SETQ B 'BAR) + (PROGV (LIST A B 'B) (LIST B) (LIST A B FOO BAR)) + ==> (FOO NIL BAR NIL) + +[3] (MAPATOMS ) MAPS THE FUNCTION OF ONE ARGUMENT + OVER ALL SYMBOLS IN THE CURRENT OBARRAY, AND THEN + RETURNS NIL. EXAMPLE: + (MAPATOMS (FUNCTION (LAMBDA (X) + (AND (= (FLATC X) 11.) + (PRINT X))))) + WOULD PRINT: + NOINTERRUPT + GC-OVERFLOW + AND RETURN NIL. + A SECOND ARGUMENT MAY BE SUPPLIED, WHICH MUST BE AN + OBARRAY (*NOT* AN ATOM WITH AN OBARRAY AS AN ARRAY + PROPERTY!!!). THE FUNCTION IS THEN MAPPED OVER THE + SPECIFIED OBARRAY. + +[4] FLATC HAS SPECIAL SPEED-OF-LIGHT CODE FOR SYMBOLS, + IN CASE ANYONE WANTS TO KNOW... +---------------------------------------------------------------- +[A] THE EDIT PACKAGE NOW WORKS CORRECTLY IN NEWIO. + +[B] THE LOAD FUNCTION TAKES A NEWIO FILE NAME AS ITS ARGUMENT, + AND ATTEMPTS TO LOAD IT UP. IF NO SECOND FILE NAME IS + GIVEN, IT FIRST TRIES USING "FASL", AND THEN ">". + AFTER FINDING THE FILE, IT DETERMINES WHETHER IT IS A FASL + FILE OR NOT (BY LOOKING AT THE FIRST WORD). IF A FASL FILE, + IT CALLS FASLOAD TO LOAD THE FILE. OTHERWISE, IT OPENS + THE FILE AS AN ASCII FILE, PUSHES IT ON THE INSTACK, + AND PERFORMS A READ-EVAL LOOP UNTIL END OF FILE. + BECAUSE OF THIS MODE OF OPERATION, INCLUDE'S (SEE [C]) + WILL WORK IN LOADED FILES. + THE IDEA IS THAT YOU SAY (LOAD 'FOO) AND IT LOADS FOO. + +[C] INCLUDE IS A FEXPR WHICH TAKES A FILE NAME. + (DEFUN INCLUDE FEXPR (X) (INPUSH (OPEN (CAR X)))) + THAT IS, ONE TYPICALLY WOULD WRITE: + (INCLUDE |DSK:GLS;FOO >|) + OR WHATEVER. + IF THIS IS EVALUATED IN THE COURSE OF UREAD'ING OR + LOAD'ING A FILE, THE EFFECT IS TO INCLUDE THE TEXT OF + THE INSERTED FILE IN PLACE OF THE INCLUDE. (OF COURSE, + USER-SUPPLIED EOF HANDLERS MAY ALTER THIS SOMEWHAT.) + EVENTUALLY THE @ PROGRAM WILL UNDERSTAND INCLUDE'S. + +[D] UREAD'S EOF HANDLER WAS FORMERLY DEFINED TO BE: + (LAMBDA (FILE EOFVAL) (SETQ UREAD NIL)) + IT IS NOW DEFINED TO BE: + (LAMBDA (FILE EOFVAL) (SETQ UREAD NIL) EOFVAL) + SO THAT READ OF ONE ARGUMENT WILL WORK CORRECTLY + ON A UREAD FILE. + +[E] FILEPOS IS NOW IMPLEMENTED, EXCEPT THAT IT DOES NOT + WORK YET TO TRY TO SET THE FILEPOS ON AN OUTPUT FILE. + (ONE MAY READ THE CURRENT FILEPOS WHILE WRITING, + HOWEVER.) FILEPOS MEASURES POSITION IN TERMS OF + CHARACTERS FOR ASCII FILES, AND FIXNUMS (WORDS) + FOR FIXNUM FILES. + +[F] (STATUS FILEMODE FOO) WILL RETURN THE FLAG "FILEPOS" + IN THE CDR OF ITS RESULT IFF THE FILE FOO WILL WORK + FOR BOTH READING AND SETTING THE FILEPOS. + +TUESDAY MAY 27,1975 FM+2D.18H.3M.18S. NEWIO 1061 - GLS - + +Note that ONEWIO^K or OQ^K gets an old version of NEWIO (Q). + +Brief synopsis: +[1] MSGFILES controls output of "messages" from LISP. +[2] File arrays as arguments to SYSCALL supply channel number. +[3] ERRPRINT may take a second arg (output files). +[4] (CLOSE foo) does (SSTATUS TTYCONS foo NIL) if foo is a tty. +[5] OPEN tends to reset file array attributes. +[6] A sample program to do rubout processing. +[7] A sample program to use 12-bit chars on Knight keyboards. +[8] A sample program to use the echo area. +[9] A sample program to hack the line printer. +[10] A sample program to create "dribble files" using ECHOFILES. +---------------------------------------------------------------- +[1] The variable MSGFILES is like the variable OUTFILES, + except that "messages" like GC messages, error messages, + ";BKPT barf", etc. are output to MSGFILES files and not + to OUTFILES files. (Recall that OUTFILES is the list of + default user output files, controlled by ^R. There is no + switch equivalent to ^R for MSGFILES.) Initially the value + of MSGFILES is (T), i.e. messages go only to the tty. + +[2] If a file array is given as an input argument to SYSCALL + in newio, the system actually gives the .CALL the channel + number of the file array. If T is given, the channel number + of the input tty file T is supplied. Thus: + (SYSCALL 0 'SCML T 7) + sets the number of command lines (size of echo area) to 7 + for the standard input tty. + By the way, if you ever use SYSCALL for something you think + LISP might want to provide as a separate function (for ease of + use, compatibility with other systems, etc.) please send + mail to GLS describing the usage. + +[3] The ERRPRINT function now takes an optional second argument + like PRINT to specify the output files to print the message + on. Thus, for example, + (ERRPRINT NIL MSGFILES) + prints the most recent error message onto the message files. + +[4] Closing a tty file will undo any (SSTATUS TTYCONS) pair + that that file may be engaged in. Since OPEN uses CLOSE + if given an actual file as first argument, note that it + may be necessary to re-TTYCONS two tty files after + re-opening one or both of them. + +[5] In general, re-opening a file (especially a tty) resets + the file array for that tty. LISP makes an effort to + save some important attributes about the input and output + T files (standard tty) when starting up and re-opening the + T tty files, but this is not a general attribute of the OPEN + function. Thus, after re-opening a file array, the attributes + of that file array (such as (SSTATUS TTYCONS), (SSTATUS TTY), + (SSTATUS TTYINT), (EOFFN) or (ENDPAGEFN), etc.) should be + set up all over again. + +[6] Sometimes a user may want to do his own rubout processing + without having to hack the ultimately hairy (SSTATUS TTYSCAN) + feature. Here is a function showing the correct way to + do rubout processing for simple applications. + +;;; This function takes two arguments. +;;; The first is the character (a fixnum) which terminates input. +;;; The second is the file to read from (T for tty input). +;;; It works to use this function on a non-tty. +;;; The result returned is a list of fixnums representing the +;;; characters read and not rubbed out. The termination character +;;; is not included in this list, but thrown away. +;;; Over-rubout does not do anything at all. +;;; Example: (SNARF-CHARS-UNTIL 3 t) +;;; reads characters from T (the tty) until a ^C (ascii code 3) +;;; is typed. If the user types "FOOBERAR^C", +;;; then the result will be (106 117 117 102 101 122). +;;; +;;; Note the use of the newio function RUBOUT to rub characters out. +;;; If RUBOUT returns NIL, then it could not rub the character out +;;; (e.g. it was tab or cr); it is necessary then to re-print the +;;; list of buffered characters. +;;; TTYP is non-NIL iff the input file is a tty. +;;; ECHO-FILE is the associated output file of the input tty, +;;; or NIL if the input file has none or isn't a tty. +;;; START-POS is the original cursor position in ECHO-FILE, or NIL. +;;; BUFFER is a list of characters read in reverse order. + +(DEFUN SNARF-CHARS-UNTIL (ENDCHAR INPUT-FILE) + ((LAMBDA (TTYP) + ((LAMBDA (ECHO-FILE) + (DO ((START-POS (AND ECHO-FILE (CURSORPOS ECHO-FILE))) + (BUFFER) + (CHAR (TYI INPUT-FILE) (TYI INPUT-FILE))) + ((= CHAR ENDCHAR) (NREVERSE BUFFER)) + (COND ((= CHAR 177) + (AND BUFFER + ECHO-FILE + (OR (RUBOUT (CAR BUFFER) ECHO-FILE) + (PROGN (CURSORPOS (CAR START-POS) + (CDR START-POS) + ECHO-FILE) + (CURSORPOS 'E ECHO-FILE) + (MAPC (FUNCTION (LAMBDA (CH) + (TYO CH ECHO-FILE))) + (REVERSE (CDR BUFFER)))))) + (AND BUFFER (SETQ BUFFER (CDR BUFFER)))) + (T (SETQ BUFFER (CONS CHAR BUFFER)))))) + (AND TTYP (STATUS TTYCONS INPUT-FILE)))) + (MEMQ 'TTY (CAR (STATUS FILEMODE INPUT-FILE))))) + +[7] This function shows the correct way to re-open the tty + in 12-bit mode on a Knight keyboard. Note that the LISP + system normally folds 12-bit characters down to 7 bits + always, except for the TYI function. Thus the READTABLE + still only has 200 entries, etc. + +;;; Open the tty in 12-bit mode. After (12-BIT-OPEN) is done, +;;; (TYI) from the tty will return 12-bit characters. The characters +;;; are as supplied by ITS: +;;; bit value ITS name correspondence +;;; 2.3 4000 %TXTOP TOP +;;; 2.2 2000 %TXSFL SHIFT LOCK +;;; 2.1 1000 %TXSFT SHIFT +;;; 1.9 400 %TXMTA META +;;; 1.8 200 %TXCTL CONTROL +;;; 1.7-1.1 177 %TXASC ascii code +;;; After re-opening the input tty in 12-bit mode, it is necessary +;;; to restore the attributes of the file array. +;;; In this mode, the LISP system control characters are set up +;;; to ignore control characters which do not actually have the +;;; CONTROL bit set. Thus typing TOP-X to get "beta" will not +;;; invoke the system ^C interrupt. User interrupt character +;;; functions must decide for themselves whether to do such +;;; filtering (they receive the full 12-bit character as an +;;; argument, and so may do this if desired). + +(DEFUN 12-BIT-OPEN NIL + ((LAMBDA (SCAN-FUNCTION) + (OPEN T '(TTY IN SINGLE FIXNUM)) ;OPEN IN 12-BIT MODE + (SSTATUS TTYCONS T T) ;TIE TO OUTPUT TTY + (SSTATUS TTYSCAN SCAN-FUNCTION) ;SET UP RUBOUT HANDLER + (MAPC (FUNCTION (LAMBDA (CH INT) ;SET UP STANDARD + (SSTATUS TTYINT ; CONTROL CHARACTERS, + CH ; REQUIRING "CONTROL" + (+ INT 200)))) ; KEY FOR ANY EFFECT + '(3 4 7 22 23 24 26 27 30 32) + '(3 4 7 22 30 24 26 27 30 32))) + (STATUS TTYSCAN))) ;OLD RUBOUT HANDLER + +[8] Here is a function which opens up and manipulates tty files + such that input is typed in the echo area and output appears + above. Rubout processing happens correctly in the echo area. + Note that it uses TTY-ENDPAGEFN, the **MORE** processor + defined in the previous LISP RECENT. + +(DEFUN SPLITSCREEN (ECHOAREASIZE) + ((LAMBDA (ECHOTTY VERTICAL) + (SSTATUS TTYCONS T ECHOTTY) ;cons echo area tty to input tty + (PAGEL T (- VERTICAL ECHOAREASIZE)) ;set pagel for main area tty + (ENDPAGEFN T 'TTY-ENDPAGEFN) ;set endpagefn + (SYSCALL 0 'SCML T ECHOAREASIZE) ;set size of echo area + (CURSORPOS 'C T) ;clear screen (why not?) + 'DONE) + (OPEN '((TTY)) '(TTY OUT ECHO)) ;file array for echo area tty output + (CAR (STATUS TTYSIZE T)))) + + Here is a version which causes ALL input and output to happen + in the echo area, leaving the main program area free for graphics + or whatever else. + +(DEFUN SMALLSCREEN (ECHOAREASIZE) + (OPEN T '(TTY OUT ECHO)) + (SSTATUS TTYCONS T T) + (SYSCALL 0 'SCML T ECHOAREASIZE) + 'DONE) + +[9] Here are some routines which simulate the old ^B-^E feature + of oldio. Since ^B is a break in newio, ^A and ^E are used. + The functions WALBEG and WALEND are as in DDT, and are used + to open and close the wallpaper file. If ^A discovers that + WALBEG has not been called, the TPL device is used. + +;;; WALLPAPER ROUTINES +;;; VALUE OF WALLPAPERFILE, IF NON-NIL, IS FILE ARRAY FOR +;;; WALLPAPER. +;;; ^A-HANDLER IS INVOKED BY TYPING ^A. TURNS ON OUTPUT +;;; TO WALLPAPER FILE. +;;; ^E-HANDLER IS INVOKED BY ^E. TURNS OFF WALLPAPER OUTPUT. +;;; WALBEG INITIALIZES SETUP TO SPECIFIED FILE. +;;; WALEND TERMINATES THE CURRENT WALLPAPER FILE, +;;; AND NAMES IT IF DESIRED (DEFAULT IS "WPAPER >"). + +(DECLARE (SPECIAL WALLPAPERFILE OLD^R)) + +(SETQ WALLPAPERFILE NIL) + +(DEFUN ^A-HANDLER (F CH) + (OR WALLPAPERFILE (WALBEG TPL)) + (OR ^A (SETQ OLD^R ^R)) + (SETQ ^A T) + (SETQ ^R T) + (OR (MEMQ WALLPAPERFILE OUTFILES) + (SETQ OUTFILES (CONS WALLPAPERFILE OUTFILES)))) + +(DEFUN ^E-HANDLER (F CH) + (SETQ ^R OLD^R) + (SETQ ^A NIL) + (SETQ OUTFILES (DELQ WALLPAPERFILE OUTFILES))) + +(DEFUN WALBEG FEXPR (DEVDIR) + (WALEND) + (SETQ WALLPAPERFILE + (OPEN (LIST (OR DEVDIR (CAR (DEFAULTF NIL))) + '_WALL_ + 'PAPER) + 'OUT)) + T) + +(DEFUN WALEND FEXPR (NAME) + (COND (WALLPAPERFILE + (^E-HANDLER NIL NIL) + (AND NAME (RENAME WALLPAPERFILE NAME)) + (CLOSE WALLPAPERFILE) + (SETQ WALLPAPERFILE NIL)))) + +(SSTATUS TTYINT 1 '^A-HANDLER) +(SSTATUS TTYINT 5 '^E-HANDLER) + +[10] Here are some functions to create "dribble files", + i.e. files contains both input and output. + +;;; (DRIBBLE) opens a dribble output file. +;;; DRIBBLE, if non-nil, is the dribble output file array. +;;; (WIPE FOO BAR) wipes up the current dribble, closing +;;; the file and naming it FOO BAR. + +(DECLARE (SPECIAL DRIBBLE)) + +(DEFUN DRIBBLE NIL + (WIPE /.DRIB/. OUTPUT) + (SETQ DRIBBLE (OPEN '|.DRIB. OUTPUT| 'OUT))) + (SETQ OUTFILES (CONS DRIBBLE OUTFILES)) + (SETQ ECHOFILES (CONS DRIBBLE ECHOFILES)) + (SETQ MSGFILES (CONS DRIBBLE MSGFILES)) + (SETQ ^R T)) + +(DEFUN WIPE FEXPR (NAME) + (COND (DRIBBLE + (OR (SETQ OUTFILES (DELQ DRIBBLE OUTFILES)) + (SETQ ^R NIL)) + (SETQ ECHOFILES (DELQ DRIBBLE ECHOFILES)) + (SETQ MSGFILES (DELQ DRIBBLE MSGFILES)) + (CLOSE (RENAME (PROG2 NIL DRIBBLE + (SETQ DRIBBLE NIL)) + NAME))))) + +FRIDAY APRIL 18,1975 FQ+9H.34M.47S. LISP 1049 - GLS - + +A NEW VERSION OF NEWIO IS UP! TRY IT, AND REPORT ANY +LOSSES TO GLS, OR SAY :BUG NEWIO ... ^C TO DDT. + +BRIEF SYNOPSIS: +[0] INCOMPATIBLE CHANGE!!! PRINT, PRIN1, AND PRINC TO GIVE OUT T +[1] COMPILER RESETS GENSYM COUNTER +[2] DEFUN MAY REMOVE THE EXPR-HASH PROPERTY +[3] VERTICAL BAR AND EXCLAMATION POINT AS SYMBOL QUOTERS +[4] NEW PECULIAR FUNCTION: SYSCALL +[5] COMPILER ALLOWS DECLARES IN DO LOOPS +[6] TECHNIQUE: AVOIDING NUMBER CONSING +[7] EVALHOOK +[8] NEW VERSION OF NEWIO OUT + [A] TYIPEEK NOW IMPLEMENTED + [B] ^Q TO ALLOC AND JCL WORK + [C] (STATUS FILEMODE) + [D] (STATUS TTYINT) + [E] (STATUS TTYCONS) + [F] (STATUS TTYSCAN) + [G] RUBOUT + [H] NEW INTERRUPT SYSTEM + [I] VALUE OF AUTOLOAD IS THE AUTOLOAD FUNCTION + [J] **MORE** INTERRUPTS + [K] FASLOAD WITHIN FASLOAD + [L] ^X FUNCTION FLUSHED - ^G REMAINS + [M] FORCE IS FORCE-OUTPUT AGAIN + [N] CLEAR-INPUT AND CLEAR-OUTPUT +---------------------------------------------------------------- +[0] A GHOST OF THE PAST LOOMS UP. WHEN NCOMPLR WAS CREATED, WE MADE + SOME DECISIONS THAT, FOR EFFICIENCY REASONS, REQUIRED TYO, PRINT, + PRIN1, AND PRINC TO RETURN SOME PROVABLY NON-NUMERIC VALUE. + GENERALLY, THIS MEANS SOME CONSTANT LIKE T OR NIL. TYO WAS + CHANGED LONG AGO, BUT WE HAVE BEEN WAITING UNTIL THE LAST POSSIBLE + MINUTE TO MAKE THE REQUISITE CHANGE TO THE PRINT SERIES. THE TIME + HAS COME (AND WE HEAR VOICES OF WALRUSES); OUR SYMPATHIES GO OUT + TO THOSE, WHO LIKE US, WILL HAVE TO EXPLORE THEIR CODE TO + ACCOMODATE THIS INCOMPATIBLE CHANGE. HOWEVER, THIS CHANGE WILL + NOT ACTUALLY TAKE EFFECT UNTIL AFTER MAY 19, 1975. IF THE ONLY + USE YOUR EVER MADE OF THE VALUE OR PRINT WAS TO CONTINUE AN "AND", + YOU NEED NOT WORRY. E.G. + (AND (PRED X) (PRINC 'HERE/ WE/ ARE/ ) (PRINT X) (PRINT Y)) + WILL STILL WORK ESSENTIALLY THE SAME. + BE WARNED ALSO! THE OLD COMPLR IS ESSENTIALLY DEAD; THERE + WILL BE A FUNERAL FOR IT SOON. NCOMPLR IS NOW QUITE A BIT MORE + BUG-FREE THAN THE OLD COMPLR, AND AFTER COMPLR'S DEMISE, + SYS:TS COMPLR WILL LINK TO SYS:TS NCOMPLR. + +[1] NOTE THAT THE COMPILER USES THE GENSYM FUNCTION FOR + GENERATING LAP TAGS, AND RESETS THE GENSYM COUNTER AT + THE BEGINNING OF EACH FUNCTION. THEREFORE GENSYM IS NOT + A RELIABLE WAY TO GENERATE UNIQUE ATOMS FOR USE BY MACROS + IF YOU PLAN TO INTERN THEM (UNINTERNED, THE NAME DOESN'T + MATTER, OF COURSE). SORRY ABOUT THAT. + +[2] DEFUN WILL REMOVE THE EXPR-HASH PROPERTY FROM AN ATOM + IF IN EXPR-HASH MODE (DEFUN = T) AND IT INSTALLS A NEW + PROPERTY. THIS IS TO PREVENT LOSSES SUCH AS RE-INSTALLING + THE OLD DEFINITION NOT WORKING. + +[3] VERTICAL BAR (ASCII CODE 174) NOW INITIALLY HAS A READ-MACRO + PROPERTY WHICH CAUSES IT TO GOBBLE UP CHARACTERS UNTIL + THE NEXT VERTICAL BAR, AND MAKE AN INTERNED ATOMIC SYMBOL + OUT OF IT. IT IS THUS ANOTHER WAY TO QUOTE CHARACTERS + IN ATOMIC SYMBOLS. TO GET A VERTICAL BAR OR CARRIAGE RETURN + OR SLASH INTO SUCH A CONSTRUCT, USE SLASH. EXAMPLE: + |A /| WILL GOBBLE CHARS UNTIL +THE NEXT /| NOT PRECEDED BY //| + IS THE ATOMIC SYMBOL WITH THE PRINT NAME: + "A | WILL GOBBLE CHARS UNTIL THE NEXT | NOT PRECEDED BY /" + THE CARRIAGE RETURN ISN(T PART OF THE PRINT NAME BECAUSE IT + HAD NO / IN FRONT OF IT. THIS IS SO AN AUTOMATIC TERPRI + FORCED BY THE LINEL WON'T SCREW THINGS UP. + AS A CONCESSION TO DATAPOINT LOSERS, EXCLAMATION POINT + PRESENTLY HAS A SIMLAR PROPERTY. HOWEVER, LOSERS ARE + ADVISED NOT TO PUT ! IN THEIR FILES, AS VERTICAL BAR IS + THE "OFFICIAL" ONE. USERS OF CONNIVER ON DATAPOINTS + HAVE A PROBLEM -- TOUGH NOOGIES. + EVENTUALLY PRIN1 WILL HAVE SOME SMARTS ABOUT OUTPUTTING + VERTICAL BARS. IN NEWIO, THE RUBOUT PROCESSOR IS CLEVER + ABOUT VERTICAL BARS, BUT NOT IN OLDIO -- BEWARE. + +[4] THE FUNCTION SYSCALL TAKES FROM TWO TO TEN ARGUMENTS. + THEY ARE: + (1) N, THE NUMBER OF OUTPUT RESULTS DESIRED (A FIXNUM + FROM 0 TO 8); THE RETURN VALUE OF SYSCALL WILL THUS + BE A LIST OF N FIXNUMS. OPTIONALLY, THE "CONTROL" + BITS "C" MAY BE SPECIFIED BY GIVING AS FIRST ARG + N + LSH[C;18.] + (2) NAME OF SYSTEM CALL (ATOMIC SYMBOL). + (3-10) INPUT ARGUMENTS (FIXNUMS). + THE SPECIFIED ITS SYSTEM CALL IS PERFORMED AND A LIST + OF THE RESULTS ARE RETURNED AS FIXNUMS. IF AN ERROR + OCCURS, A FIXNUM (THE ERROR CODE) IS RETURNED INSTEAD + OF THE LIST OF RESULTS. + NO COMPENSATION IS MADE FOR SYSTEM CALLS THAT TAKE + CHANNEL NUMEBSR, AOBJN POINTERS, CLOBBER THEIR + INPUT ARGS, ETC. BEWARE! + EXAMPLE: + (SYSCALL 6 'CNSGET 2) + WILL RETURN A LIST OF SIX FIXNUMS DESCRIBING THE + TTY (OLDIO OPENS THE TTY ON CHANNEL 2 -- NEWIO + USERS, BEWARE!!!). + +[5] THE COMPILER NOW ALLOWS LOCAL DECLARATIONS TO BE PUT IN DO + LOOPS IN THE SAME WAY THEY MAY BE IN LAMBDAS AND PROGS. + EXAMPLE, TO FIND THE INDEX OF THE FIRST "FOO" IN THE LIST X: + (DO ((N 0 (1+ N)) (L X (CDR L))) + ((NULL L) -1) + (DECLARE (FIXNUM N)) + (AND (EQ (CAR L) 'FOO) (RETURN N))) + +[6] PROGRAMMING TECHNIQUE: + YOU MAY FIND YOUR FUNCTIONS DOING AN INORDINATE AMOUNT + OF NUMBER CONSING EVEN AFTER USING NCOMPLR. IF SO, + CONSIDER WHETHER ANY OF YOUR FUNCTIONS, WHICH ARE NOT DECLARED + TO BE FIXNUM OR FLONUM FUNCTIONS ARE NEEDLESSLY RETURNING + NUMERICAL RESULTS. E.G., + (DEFUN BAR (X Y N M) + (COND ((MUMBLE X Y) + (PRINC '/ANSWERS/ ARE:) + (PRIN1 N) (PRINC '/ ) (PRIN1 M) (TERPRI))) + N) ;RANDOM RETURN VALUE + IF BAR IS INDEED USED PRIMARILY FOR EFFECT, THERE IS NO REASON + TO RETURN A NUMERICAL VALUE, WHICH WILL USUALLY CAUSE NCOMPLR + TO OUTPUT A NUMBER-CONS CALL. SOMETIMES, RETURNING A NUMERICAL + RESULT MAY BE PARTIALLY HIDDEN FROM YOUR EYE, AS IN THE CASE OF + FEEDING AN ARG TO A FUNCTION SUCH AS STORE, WHICH RETURNS ONE OF + ITS INPUT ARGS AS RESULTANT VALUE E.G., + (DEFUN FOO (J N) (STORE (MY-FIXNUM-ARRAY N) J)) + THIS WILL STORE THE FIXNUM J INTO SLOT N, AND IT WILL ALSO + RETURN J. UNLESS YOU REALLY NEED FOO TO RETURN J, YOU SHOULD + WRITE + (DEFUN FOO (J N) (STORE (MY-FIXNUM-ARRAY N) J) NIL) + AND LET NIL BE RETURNED. THIS APPLIES TO ANY FUNCTION + WHOSE LAST ACTION WILL PRODUCE A NUMERICAL VALUE, AND WHOSE + PURPOSE IS PRIMARILY TO PERFORM SOME SIDE-EFFECT. + +[7] AT LONG LAST, HERE IS SOME (MINIMAL) DOCUMENTATION + ON THE INFAMOUS EVALHOOK FEATURE! + THE EVALHOOK FEATURE WAS INVENTED SO THAT A DYNAMIC + SINGLE-STEP TRACER COULD BE WRITTEN. USING THE + EVALHOOK FEATURE IS A BLACK ART, SO READ ON, BUT + CAREFULLY. + THERE EXIST BOTH A FUNCTION AND A VARIABLE CALLED + "EVALHOOK". THERE IS ALSO A (SSTATUS EVALHOOK). + ((STATUS EVALHOOK) EXISTS BUT DOES NOT RETURN ANYTHING + MEANINGFUL AT ALL.) + THE SEMANTICS OF THE VARIABLE EVALHOOK ARE AS FOLLOWS: + WHENEVER THE FUNCTION EVAL IS ENTERED, WHETHER FROM + WITHIN THE SYSTEM OR BY EXPLICIT INVOCATION BY THE USER, + THEN IF THE VALUE OF THE VARIABLE EVALHOOK IS NON-NIL, + AND *RSET IS NON-NIL, AND (SSTATUS EVALHOOK T) HAS BEEN + DONE, THEN EVAL DOES NOT EVALUATE ITS ARGUMENT. + INSTEAD IT ASSUMES THAT THE VALUE OF THE VARIABLE + EVALHOOK IS A FUNCTION OF ONE ARGUMENT. IT FETCHES + THIS FUNCTION, LAMBDA-BINDS EVALHOOK TO NIL, AND + CALLS THE FUNCTION WITH THE ARGUMENT TO EVAL. + THIS FUNCTION THEN HAS THE RESPONSIBILITY FOR EVALUATING + THE FORM AND RETURNING A RESULT. THIS RESULT BECOMES + THE RESULT OF THE ORIGINAL CALL TO EVAL. + IT IS EVIDENT THAT SUCH A FUNCTION CAN DO OTHER THINGS + BESIDES EVALUATE THE FORM; E.G. IT CAN PRINT TRACE + INFORMATION. + THE REASON THAT EVALHOOK IS BOUND BACK TO NIL BEFORE + CALLING THE HOOK FUNCTION IS BECAUSE THE HOOK FUNCTION + MAY BE INTERPRETED, AND WE WANT TO AVOID INFINITE + RECURSION. THERE IS A PROBLEM, THOUGH: HOW CAN THE + HOOK FUNCTION EVALUATE ITS ARGUMENT ONCE IT HAS + PRINTED STUFF OUT? IF IT JUST CALLS EVAL BACK AGAIN, + THEN THE VARIABLE EVALHOOK WILL BE NIL, AND THE + HOOK FUNCTION WILL NOT GET CALLED FOR THE RECURSIVE + CALLS ON EVAL. IF IT SETQ'S EVALHOOK TO THE HOOK + FUNCTION AND THEN CALLS EVAL, THE HOOK FUNCTION WILL + GET CALLED BACK WITH THE SAME THING. + FOR THIS REASON THERE IS AN EVALHOOK FUNCTION. + THE EVALHOOK FUNCTION CALLS EVAL WITH ITS FIRST + ARGUMENT, AFTER BINDING THE VARIABLE EVALHOOK TO + ITS LAST ARGUMENT, AND BYPASSING THE HOOK FUNCTION + CHECK IN EVAL. + IF THAT ALL WENT BY TOO FAST, TAKE A LOOK AT THESE + DEFINITIONS IN LISP: + + (DECLARE (SPECIAL *RSET EVALHOOK)) + + (DEFUN EVAL N + (OR (= N 1) (= N 2) + (ERROR '|WRONG NUMBER OF ARGS TO LSUBR| + (CONS 'EVAL (LISTIFY N)) + 'WRNG-NO-ARGS)) + (AND (= N 2) + (HACK-FAKE-ALIST (ARG 2))) + (COND ((AND EVALHOOK + *RSET + (SSTATUS-EVALHOOK-T-WAS-DONE-P)) + ((LAMBDA (EVALHOOK) + (FUNCALL EVALHOOK (ARG 1))) + NIL)) + (T (+INTERNAL-EVAL (ARG 1))))) + + (DEFUN EVALHOOK N + (OR (= N 2) (= N 3) + (ERROR '|WRONG NUMBER OF ARGS TO LSUBR| + (CONS 'EVALHOOK (LISTIFY N)) + 'WRNG-NO-ARGS)) + (AND (= N 3) ;SECOND ARG OF 3 IS ALIST + (HACK-FAKE-ALIST (ARG 2))) + ((LAMBDA (EVALHOOK) + (+INTERNAL-EVAL (ARG 1))) + (ARG N))) + + THE REASON THAT BOTH (*RSET T) AND (SSTATUS EVALHOOK T) + MUST BE DONE IS FOR REASONS OF EFFICIENCY (SIGH). + + HERE IS AN EXAMPLE OF THE USAGE OF EVALHOOK: + +(DEFUN HOOK FEXPR (X) ;CALLED AS (HOOK ) + ((LAMBDA (*RSET EVALHOOK) + (PROG2 (SSTATUS EVALHOOK T) ;MAGIC SSTATUS + (EVAL (CAR X)) ;EVALUATE FORM + (SSTATUS EVALHOOK NIL))) ;MORE MAGIC + T + 'HOOK-FUNCTION)) ;THE HOOK FUNCTION + +(DEFUN HOOK-FUNCTION (F) + (TERPRI) ;PRINT PRETTY MESSAGE FOR INPUT + (PRINC '|FORM: |) + (PRIN1 F) + ((LAMBDA (V) ;V GETS VALUE OF FORM + (TERPRI) ;PRETTY OUTPUT MESSAGE + (PRINC '|VALUE: |) + (PRIN1 V)) + (EVALHOOK F 'HOOK-FUNCTION))) ;THIS IS HOW TO EVAL THE FORM + ; SO AS TO HOOK SUB-FORMS + + THUS FOR SOMETHING LIKE (HOOK (CONS (CAR '(A . B)) 'C)) + THE FOLLOWING OUTPUT MIGHT BE SEEN: + + FORM: (CONS (CAR (QUOTE (A . B))) (QUOTE C)) + FORM: (CAR (QUOTE (A . B))) + FORM: (QUOTE (A . B)) + VALUE: (A . B) + FORM: (QUOTE C) + VALUE: C + VALUE: ((A . B) . C) + ((A . B) . C) + + NATURALLY, ONE CAN DREAM UP INFINITELY HAIRY THINGS + TO DO WITH THIS, SUCH AS INTERACTIVE TRACING AND BREAKING, + INDENTED OUTPUT, ETC. + + +[8] A NEW VERSION OF NEWIO IS OUT! + HERE FOLLOWS A COPY OF .INFO.;NEWIO STUFF, WHICH HAS + BEEN UPDATED TO ACCOUNT FOR ALL THE CHANGES MENTIONED + IN THE SYNOPSIS. + +NEWIO NEWIO NEWIO NEWIO NEWIO NEWIO NEWIO NEWIO NEWIO NEWIO +---------------------------------------------------------------- +THINGS OF NOTE NOT YET IMPLEMENTED: +---------------------------------------------------------------- +[1] FILEPOS NOT YET IMPLEMENTED. +[2] ALLFILES NOT YET IMPLEMENTED. +[3] MOBY I/O DOES NOT YET WORK UNDER NEW I/O. + +---------------------------------------------------------------- +NEW FUNCTIONS: +---------------------------------------------------------------- +(^G) SIGNALS A ^G QUIT; IT REPLACES (IOC G). + +(IN ) READS IN A FIXNUM FROM A BINARY INPUT FILE AND + RETURNS IT. TO GET A BINARY FILE, SEE THE NEW + OPEN FUNCTION. + +(OUT ) OUTPUTS THE FIXNUM TO THE BINARY + FILE AND RETURNS T. + +(TRUENAME ) GIVES THE "TRUE NAME" OF THE FILE, + AS OPPOSED TO THE FILE NAMES USED TO OPEN IT. + THIS IS THE NAME FOUND AFTER TRANSLATIONS AND + LINKS, ETC. (IT IS THE NAME RETURNED BY A .RCHST + ON THE FILE'S CHANNEL.) + +ECHOFILES IS A VARIABLE WHICH, IF NON-NIL, SHOULD BE A + LIST OF OUTPUT FILES. THESE OUTPUT FILES + RECEIVE EVERY CHARACTER SEEN AS INPUT BY TYI + (AND FUNCTIONS WHICH USE TYI, SUCH AS READ). + IF A FILE IS A MEMBER OF BOTH THE ECHOFILES + AND OUTFILES LISTS, IT WILL BE A "DRIBBLE + FILE", RECORDING BOTH INPUT AND OUTPUT. + NOTE THAT THE FUNCTION WHICH PRE-SCANS TTY INPUT + AND PERFORMS RUBOUT PROCESSING LAMBDA-BINDS + ECHOFILES TO NIL, SO YOU WON'T SEE RUBBED-OUT + CHARACTERS. + +(OPEN ) OPENS A FILE AND RETURNS A + CORRESPONDING FILE OBJECT. IT IS ACTUALLY AN LSUBR + OF ZERO TO TWO ARGUMENTS. THE DEFAULTS TO THE + CURRENT DEFAULT FILE NAMES. THE DEFAULTS + TO NIL. +IF IS A NAMELIST OR NAMESTRING, A NEW FILE ARRAY + IS CREATED. IF IS A FILE ARRAY ALREADY, IT IS + CLOSED AND RE-OPENED IN THE SPECIFIED MODE; ITS FORMER + MODES SERVE AS THE DEFAULTS FOR THE . + THE DETERMINES A LARGE NUMBER OF ATTRIBUTES + FOR OPENING THE FILE. FOR EACH ATTRIBUTE THERE ARE + TWO OR MORE MUTUALLY EXCLUSIVE VALUES WHICH MAY BE + SPECIFIED AS FOLLOWS. VALUES MARKED BY A * ARE THOSE + USED AS DEFAULTS WHEN THE IS A NAMELIST OR + NAMESTRING. IF THE IS AN ATOM, IT IS THE + SAME AS SPECIFYING THE LIST OF THAT ONE ATOM. +DIRECTION: + * IN INPUT FILE + * READ SAME AS "IN" + OUT OUTPUT FILE + PRINT SAME AS "OUT" + APPEND OUTPUT, APPENDED TO EXISTING FILE +DATA MODE: + * ASCII FILE IS A STREAM OF ASCII CHARACTERS. + SYSTEM-DEPENDENT TRANSFORMATIONS MAY + OCCUR, SUCH AS SUPPLYING LF AFTER CR, + OR BEING CAREFUL WITH OUTPUT OF ^P, + OR MULTICS ESCAPE CONVENTIONS. + FIXNUM FILE IS A STREAM OF FIXNUMS. THIS + IS FOR DEALING WITH FILES THOUGHT OF + AS "BINARY" RATHER THAN "CHARACTER". + IMAGE FILE IS A STREAM OF ASCII CHARACTERS. + ABSOLUTELY NO TRANSFORMATIONS ARE MADE. +DEVICE TYPE: + * DSK STANDARD KIND OF FILE. + TTY CONSOLE. IN PARTICULAR, ONLY TTY INPUT + FILES HAVE INTERRUPT CHARACTER FUNCTIONS + ASSOCIATED WITH THEM. +BUFFERING MODE: + * BLOCK DATA IS BUFFERED. + SINGLE DATA IS UNBUFFERED. + IF THE DEVICE TYPE IS TTY, THE DEFAULT IS + SINGLE INSTEAD OF BLOCK ON ITS. +ECHO MODE: + ECHO OPENS OUTPUT TTY IN ECHO AREA (ITS ONLY). +SOME OF THESE VALUES ARE OF COURSE SYSTEM-DEPENDENT. + YOUR LOCAL LISP SYSTEM WILL ATTEMPT TO DO THE RIGHT + THING, HOWEVER, IN ANY CASE. +IF THE OPTIONS LIST IS INVALID IN ANY WAY, OPEN MAY EITHER + GIVE A WRNG-TYPE-ARGS ERROR, OR BLITHELY ASSUME A + CORRECTED VALUE FOR AN ATTRIBUTE. IN GENERAL, ERRORS + SHOULD OCCUR ONLY FOR TRULY CONFLICTING SPECIFICATIONS. + ON THE OTHER HAND, SPECIFYING BLOCK MODE FOR A DEVICE + THAT THE SYSTEM WANTS TO HANDLE ONLY IN CHARACTER MODE + MAY JUST GO AHEAD AND USE CHARACTER MODE. +(OPENI X) == (OPEN X 'READ) +(OPENO X) == (OPEN X 'PRINT) +(OPENA X) == (OPEN X 'APPEND) + +(RUBOUT ) ATTEMPTS TO RUB OUT ONE CHARACTER. + SHOULD BE A FIXNUM BETWEEN 0 AND 177 (AN ASCII VALUE). + SHOULD BE A TTY OUTPUT FILE; IF OMITTED, T IS ASSUMED. +IF IT IS NOT POSSIBLE TO RUB OUT THE CHARACTER CORRECTLY, +RUBOUT WILL RETURN NIL INSTEAD OF T; IT IS UP TO THE CALLER +TO DO SOMETHING ABOUT THIS CASE. CHARACTERS WHICH CANNOT +CORRECTLY BE RUBBED OUT INCLUDE TAB AND CARRIAGE RETURN. +IF THE OUTPUT TTY CAN DO CURSOR POSITIONING AND SELECTIVE +RASURE, THEN THE CHARACTER IS RUBBED OUT BY ERASING IT +FROM THE SCREEN AND BACKING UP THE CURSOR; OTHERWISE, THE +CHARACTER IS PRINTED ON THE TTY (RUBOUT ECHO). + +(SSTATUS TTYSCAN ) SETS UP A TTY PRE-SCAN +FUNCTION FOR , WHICH MUST BE A TTY INPUT FILE. +IF IS OMITTED, T IS ASSUMED. +THE SHOULD ACCEPT THREE ARGUMENTS: + (1) THE FILE TO DO PRE-SCANNING FOR. + (2) THE INPUT FUNCTION TO PRE-SCAN FOR. + POSSIBILITIES ARE READ, TYI, READLINE, + EDIT, AND PERHAPS OTHERS. + (3) THE NUMBER OF HANGING LEFT PARENTHESES, AS + A FIXNUM (MEANINGFUL ONLY IF ARGUMENT 2 + IS 'READ). +IT IS THE RESPONSIBILITY OF THE PRE-SCAN FUNCTION TO +READ IN SOME CHARACTERS FROM THE FILE HANDED TO IT AS +ITS FIRST ARGUMENT, AND TO RETURN A LIST OF FIXNUMS +BETWEEN 0 AND 177 OCTAL. TYPICALLY THE PRE-SCAN FUNCTION +WILL PROVIDE FOR RUBOUT PROCESSING, ETC. +IF THE PRE-SCAN FUNCTION RETURNS NIL, AN END-OF-FILE +WILL BE SIGNALED FOR THE TTY INPUT FILE. THIS IS A WAY +TO SIGNAL OVER-RUBOUT. +(THE INITIAL LISP SYSTEM PROVIDES FOR THE INITIAL TTY INPUT +FILE A PRE-SCAN FUNCTION WHICH DOES STANDARD RUBOUT PROCESSING.) +(STATUS TTYSCAN ) NATURALLY RETURNS THE PRE-SCAN +FUNCTION FOR (T IF IS OMITTED). + + +---------------------------------------------------------------- +THINGS WHICH HAVE CHANGED FROM OLD I/O AND NOT IN THE MANUAL: +---------------------------------------------------------------- + +IN NEW I/O FILES ARE SPECIFIED BY MEANS OF NAMESTRINGS AND +NAMELISTS AS DOCUMENTED IN THE MANUAL. +THERE IS FURTHERMORE A COMPATIBILITY FEATURE WHICH ALLOWS +OLD I/O 4-LISTS TO BE USED INTERCHANGEABLY WITH NEW I/O +NAMELISTS. IF THE CAR OF A PUTATIVE NAMELIST IS ATOMIC, +THEN IT IS ASSUMED TO BE AN OLD I/O 4-LIST. +FINALLY, NEW I/O ON THE PDP-10 KNOWS MOST STANDARD DEVICE +NAMES; IF IT SEES A NAME WHERE A DEVICE BELONGS, AND IT IS +NOT ONE OF THE STANDARD DEVICE NAMES, AND NO SNAME WAS +SUPPLIED, THEN THE NAME IS TAKEN TO BE THE SNAME, AND * +IS SUPPLIED FOR THE DEVICE. +ALL THESE COMPATIBILITY FEATURES ARE FOR THE PDP-10 ONLY! +EXAMPLES: + THESE ARE ALL EQUIVALENT AS FILE NAMES: + (FOO BAR * GLS) + (FOO BAR GLS) + ((GLS) FOO BAR) + ((* GLS) FOO BAR) +THE ARGUMENT TO AN OLD I/O FUNCTION IS ONE OF THESE LISTS; +THUS ONE MAY SAY EQUIVALENTLY: + (UREAD FOO > * GLS) + (UREAD FOO > DSK GLS) ;IF YOUR DEFAULT DEV IS DSK: + (UREAD FOO) ;IF YOUR DEFAULT IS DSK:GLS; + ; BECAUSE UREAD SUPPLIES > + (UREAD (GLS) FOO) ;IF YOUR DEFAULT DEV IS DSK: + (UREAD (DSK GLS) FOO) + (UREAD (DSK GLS) FOO >) + +HERE ARE DEFINITIONS OF THE OLD I/O FUNCTIONS IN TERMS OF THE +NEW ONES. THEY MAY BE TAKEN QUITE LITERALLY. +(DEFUN UREAD FEXPR (FILENAME) + (UCLOSE) + ((LAMBDA (FILE) + (EOFFN FILE + (FUNCTION + (LAMBDA (EOFFILE EOFVAL) + (SETQ UREAD NIL)))) + (INPUSH (SETQ UREAD FILE)) + (CAR (DEFAULTF FILE))) + (OPEN (*UGREAT FILENAME) 'IN))) + +(DEFUN UCLOSE FEXPR (X) + (COND (UREAD + (AND (EQ UREAD INFILE) (INPUSH -1)) + (CLOSE (PROG2 NIL UREAD (SETQ UREAD NIL)))) + (T NIL))) + +(DEFUN UWRITE FEXPR (DEVDIR) + (OR DEVDIR (SETQ DEVDIR (CAR (DEFAULTF NIL)))) + (*UWRITE (CONS DEVDIR (COND ((STATUS FEATURE DEC10) + (CONS (STATUS JNAME) '(OUT))) + ((STATUS FEATURE ITS) + '(.LISP. OUTPUT)))) + 'OUT + (LIST DEVDIR))) + +(DEFUN UAPPEND FEXPR (FILENAME) + (PROG2 (SETQ FILENAME (*UGREAT FILENAME)) + (*UWRITE FILENAME 'APPEND FILENAME) + (RENAME UWRITE + (COND ((STATUS FEATURE DEC10) + (CONS (STATUS JNAME) '(OUT))) + ((STATUS FEATURE ITS) + '(/.LISP/. APPEND)))))) + +(DEFUN *UWRITE (NAME MODE NEWDEFAULT) ;INTERNAL ROUTINE + (COND (UWRITE + (SETQ OUTFILES (DELQ UWRITE OUTFILES)) + (CLOSE UWRITE) + (SETQ UWRITE NIL))) + ((LAMBDA (FILE) + (SETQ OUTFILES + (CONS (SETQ UWRITE FILE) + OUTFILES)) + (CAR (DEFAULTF NEWDEFAULT))) + (OPEN NAME MODE))) + +(DEFUN UFILE FEXPR (SHORTNAME) + (COND ((NULL UWRITE) + (ERROR 'NO/ UWRITE/ FILE + (CONS 'UFILE SHORTNAME) + 'IO-LOSSAGE)) + (T (PROG2 NIL + (CAR (DEFAULTF (RENAME UWRITE + (*UGREAT SHORTNAME)))) + (SETQ OUTFILES (DELQ UWRITE OUTFILES)) + (CLOSE UWRITE) + (SETQ UWRITE NIL))))) + +(DEFUN CRUNIT FEXPR (DEVDIR) + (CAR (DEFAULTF (AND DEVDIR (LIST DEVDIR))))) + +(DEFUN *UGREAT (NAME) ;INTERNAL ROUTINE + (MERGEF (MERGEF NAME + (COND ((STATUS FEATURE DEC10) + '(* . LSP)) + ((STATUS FEATURE ITS) + '(* . >)))) + NIL)) + +(DEFUN UPROBE FEXPR (FILENAME) + (SETQ FILENAME (MERGEF (*UGREAT FILENAME) NIL)) + (AND (PROBEF FILENAME) FILENAME)) + +(DEFUN UKILL FEXPR (FILENAME) + (DEFAULTF (DELETEF FILENAME)))) + + + +CURSORPOS MAY TAKE AN EXTRA ARGUMENT TO DETERMINE WHICH OUTPUT +TTY TO DO THE CURSOR POSITIONING ON. IF THE LAST ARGUMENT CAN +BE TAKEN TO BE A TTY, IT IS. +ONE INCOMPATIBILITY IS THAT (CURSORPOS 'T) NOW MEANS GET THE +COORDINATES OF TTY "T" RATHER THAN GO TO THE TOP OF THE SCREEN. +TO GO TO THE TOP OF THE SCREEN FOR THE DEFAULT TTY, USE +(CURSORPOS 'TOP) OR (CURSORPOS 124) OR (CURSORPOS 'T T). + +LISTEN SIMILARLY TAKES AN OPTIONAL ARGUMENT TELLING WHICH INPUT +TTY TO LISTEN TO. NOTE THAT (LISTEN T) IS NOT QUITE THE SAME +AS (LISTEN); THE LATTER MERELY RETURNS THE RESULT OF A .LISTEN, +WHILE THE FORMER ACCOUNTS FOR BUFFERED-UP CHARACTERS WITHIN LISP. + +TYIPEEK NOW TAKES UP TO THREE ARGUMENTS. +THE FIRST ARGUMENT IS AS IN OLD I/O; IT SPECIFIES THE KIND +OF PEEKING. A FIRST ARGUMENT OF NIL IS THE SAME AS NO ARGUMENT +AT ALL, EXCEPT THAT YOU NEED IT TO GET IN THE OTHER TWO +ARGUMENTS. THESE EXTRA ARGUMENTS ARE AS FOR READ, NAMELY +A FILE AND/OR EOF VALUE (WHICH SHOULD BE A FIXNUM). +AN INCOMPATIBLE CHANGE IS THAT TYIPEEK BY DEFAULT RETURNS +-1 INSTEAD OF 3 AT END OF FILE AND NEWIO. + +(STATUS FILEMODE ) RETURNS A DOTTED PAIR WHOSE CAR +IS A LIST OF VALID OPTIONS TO THE OPEN FUNCTION, DESCRIBING +THE ATTRIBUTES OF THE FILE, AND WHOSE CDR IS A LIST OF +SEMI-SYSTEM-DEPENDENT SYMBOLS DESCRIBING ATTRIBUTES WHICH CANNOT +BE FED TO OPEN. AMONG THESE ATTRIBUTES ARE: + RUBOUT THIS TTY CAN SELECTIVELY ERASE. + SAIL THIS TTY HAS THE SAIL CHARACTER SET. + CURSORPOS THIS TTY CAN DO CURSOR POSITIONING. + +(SSTATUS TTYCONS ) EFFECTIVELY BINDS TWO TTY +FILES INTO A SINGLE CONSOLE. ONE OF THE TTY'S SHOULD BE AN +INPUT TTY, AND THE OTHER AN OUTPUT TTY. INITIALLY THE +SYSTEM PERFORMS (SSTATUS TTYCONS T T) FOR YOU. +(STATUS TTYCONS ) RETURNS THE TTY WHICH THE ONE YOU +SPECIFIED IS LINKED TO, OR NIL IF IT ISN'T LINKED. +THIS IS USEFUL, FOR EXAMPLE, IN A **MORE** INTERRUPT, +TO DETERMINE WHICH INPUT TTY TO READ THE CHARACTER FROM. + +(STATUS TTYINT ) +(SSTATUS TTYINT ) +THESE STATUS FUNCTION ARE USED TO SET UP AND EXAMINE +INTERRUPT CHARACTER FUNCTIONS FOR TTY INPUT FILES. +IF IS OMITTED, T (THE STANDARD TTY) IS ASSUMED. + SHOULD BE EITHER A NUMERIC ASCII VALUE, OR +A SINGLE CHARACTER OBJECT. NOTE THAT IS ALWAYS +EVALUATED, UNLIKE (STATUS CHTRAN), FOR EXAMPLE. + SHOULD BE EITHER A FUNCTION OF TWO ARGUMENTS +OR A FIXNUM. IF IT IS A FUNCTION, THEN WHEN THE INTERRUPT +OCCURS IT RECEIVES AS ARGUMENTS THE FILE ON WHICH THE +INTERRUPT OCCURRED, AND THE CHARACTER TYPED, AS A FIXNUM. +IF THE FUNCTION IS A FIXNUM, IT REPRESENTS THE INTERNAL +SYSTEMIC INTERRUPT INITIALLY ASSOCIATED WITH THAT CHARACTER. +THUS, FOR EXAMPLE: + (SSTATUS TTYINT 7 + '(LAMBDA (F CH) (PRINC '|WHY DID YOU TYPE ^G? |))) + (SSTATUS TTYINT 6 7) +WILL CAUSE ^F T DO A "^G QUIT", AND ^G MERELY TO PRINT THE +MESSAGE "WHY DID YOU TYPE ^G? ". +NOTE THAT AN INTERRUPT CAN BE ASSOCIATED WITH ANY ASCII +CHARACTER, NOT JUST CONTROL CHARACTERS. (FOR A FRUSTRATING +EXPERIENCE, SET ")" TO BE A "^G QUIT".) ON ITS, HOWEVER, +ONE MUST USE (SSTATUS TTY) TO TELL ITS THAT THINGS LIKE +"?" OR "#" ARE TO BE CONSIDERED INTERRUPT CHARACTERS +(THIS IS SIMILAR TO THE ACTIVATION CHARACTER PROBLEM). +THE MEANINGFUL SYSTEMIC INTERRUPT VALUES ARE: + OCTAL VALUE CHAR WHAT IT DOES + 3 ^C (SETQ ^D NIL) + 4 ^D (SETQ ^D T) + 7 ^G ^G QUIT + 22 ^R (SETQ ^R T) + 24 ^T (SETQ ^R NIL) + 26 ^V (SETQ ^W NIL) + 27 ^W (SETQ ^W T) + 30 ^X ^X QUIT + 32 ^Z RETURN TO DDT +THE DIFFERENCE BETWEEN (SSTATUS TTYINT 1 4) AND +(SSTATUS TTYINT 1 '(LAMBDA (F CH) (SETQ ^D T))) +IS THAT THE FORMER WILL LET THE INTERRUPT HAPPEN AND +TAKE EFFECT EVEN IF IN A PLACE WHERE A GENERAL USER +FUNCTION MAY NOT BE RUN, E.G. IN THE MIDDLE OF A GARBAGE +COLLECTION. +NOTE THAT INITIALLY ^S IS SET TO BE LIKE ^W AS AN +INTERRUPT CHARACTER (SEE BELOW). + +^Q IS NO LONGER INITIALLY AN INTERRUPT CHARACTER, +BUT A SPLICING MACRO AND FORCE-FEED WHOSE DEFINITION +IS (LAMBDA NIL (SETQ ^Q T) NIL). THIS HAS THE SAME +EFFECT WHEN TYPED AT THE KEYBOARD AS BEFORE, BUT +PREVENTS CERTAIN TIMING SCREWS. + +^S NO LONGER DOES (SETQ ^Q NIL). INSTEAD, IT IS THE +SAME AS ^W AS AN INTERRUPT CHARACTER. UNLIKE ^W, +IT IS ALSO A SPLICING MACRO AND FORCE-FEED, WITH THE +DEFINITION (LAMBDA NIL (SETQ ^W NIL) (TERPRI) NIL). +THUS IF A LONG PRINTOUT IS COMING AT YOU, JUST TYPE +^S AND YOU WILL SEE A TERPRI WHEN CONTROL RETURNS TO +THE KEYBOARD. THIS IS LIKE ^S IN DDT, AND REPLACES +THE OLD TRICK OF TYPING ^W AND THEN (IOC V). + +^Z NO LONGER DOES A :VK TO DDT. + +^U NO LONGER RELEASES THE PAGEPAUSE (WHICH IS ALSO GONE). + +^B AND ^E DO NOT TOGGLE LPT OUTPUT. +LOSERS CAN PROGRAM THIS FOR THEMSELVES. +SEE ML:GLS;NIFTY QIO. + +^H IS ALPHABETIC IN NEW I/O, FOR COMPATIBILITY WITH +MULTICS, AND SO YOU CAN UNDERLINE NAMES. BEWARE! +A_ IS NOT THE SAME ATOM AS _A. +(THERE WILL EVENTUALLY BE A USER-PROGRAMMABLE +SOLUTION TO THIS "BUG" - A LINE CANONICALIZER.) + +^B IN NEW I/O GIVES A "^B BREAK", WHICH IS THE SAME AS +THE "^H BREAK" OF OLD I/O. + +FOR TTY OUTPUT FILES ON ITS, THE ENDPAGEFN IS NOT TRIPPED WHEN +THE LINENUM EXCEEDS PAGEL. RATHER, THE **MORE** INTERRUPT +IS USED, WHICH IS MORE ACCURATE FOR DETECING THE BOTTOM OF +THE SCREEN. WHEN THE TTY REACHES THE BOTTOM OF THE SCREEN, +THE ENDPAGEFN FOR THE TTY IS INVOKED; IT RECEIVES AS ARGUMENT +THE FILE ON WHICH THE INTERRUPT OCCURRED. + +HERE ARE SOME NEAT FUNCTIONS FOR USING THE **MORE** FEATURE +(THEY LIVE IN ML:GLS;NIFTY QIO): + +(DECLARE (SPECIAL **MORE** MORE-FLUSH)) +(SETQ **MORE** '##MORE##) +(SETQ MORE-FLUSH NIL) + +;;; TTY-ENDPAGEFN IS AN ENDPAGEFN FOR THE TTY FOR PROCESSING +;;; **MORE** INTERRUPTS. WHAT IT DOES DEPENDS ON TWO +;;; GLOBAL VARIABLES (BOUND BY THE CATCHMORE MACRO): +;;; **MORE** MORE-FLUSH ACTION +;;; NIL NIL NOTHING +;;; NON-NIL NIL "DUMB" MORE PROCESSING; +;;; I.E. PRINT THE VALUE +;;; OF **MORE** AND WAIT FOR +;;; THE LOSER TO TYPE SOMETHING, +;;; BUT NO PROVISION FOR FLUSHING +;;; NIL NON-NIL FLUSH IMMEDIATELY BY DOING +;;; (THROW NIL CLEVER-MORE). +;;; THIS IS GOOD FOR PRINTING +;;; EXACTLY ENOUGH TO FILL A SCREEN. +;;; NON-NIL NON-NIL "SMART" MORE PROCESSING; +;;; I.E. PRINC THE VALUE OF +;;; **MORE** AND WAIT FOR A +;;; CHARACTER. IF SPACE OR +;;; RUBOUT, GOBBLE IT. IF IT +;;; WAS SPACE, JUST RETURN; +;;; OTHERWISE FLUSH BY PRINC'ING +;;; MORE-FLUSH AND DOING +;;; (THROW NIL CLEVER-MORE). + +(DEFUN TTY-ENDPAGEFN (FILE) + (COND (**MORE** (PRINC **MORE**) + ((LAMBDA (IFILE) + ((LAMBDA (CH) + (AND (OR (= CH 40) + (= CH 177)) + (TYI IFILE)) + (COND ((AND MORE-FLUSH + (NOT (= CH 40))) + (PRINC MORE-FLUSH) + (THROW NIL CLEVER-MORE)) + (T (CURSORPOS NIL 0 FILE) + (CURSORPOS 'L FILE) + (CURSORPOS 'T FILE)))) + (TYIPEEK NIL IFILE))) + (OR (STATUS TTYCONS FILE) T))) + (MORE-FLUSH (THROW NIL CLEVER-MORE)))) + +(ENDPAGEFN T 'TTY-ENDPAGEFN) + +;;; (CATCHMORE X Y Z) EVALUATES Z WITH A **MORE** CATCH +;;; AROUND IT. THIS COOPERATES WITH TTY-ENDPAGEFN +;;; TO DO **MORE** PROCESSING. +;;; THUS, FOR EXAMPLE, (CATCHMORE '**MORE** 'FLUSHED ) +;;; WHERE DOES SOME PRINTING WILL PERFORM THE +;;; STANDARD KIND OF **MORE** PROCESSING, FLUSHING +;;; IF A NON-SPACE IS TYPED. +;;; THE MACRODEF MACRO-DEFINER LIVES IN ML:GLS;MACROS >. + +(MACRODEF CATCHMORE (MOREMSG FLUSHMSG . BODY) + (CATCH ((LAMBDA (**MORE** MORE-FLUSH) . BODY) + MOREMSG FLUSHMSG) + CLEVER-MORE)) + +(DEFUN DIR FEXPR (X) ;LIST AN ITS FILE DIRECTORY + (TERPRI) + (CURSORPOS 'C) + ((LAMBDA (FILE) + (CATCHMORE '|---TYPE SPACE FOR MORE---| + '|OH, WELL, SO MUCH FOR THAT...| + (DO ((CH (TYI FILE) (TYI FILE))) + ((= CH 14)) + (TYO CH))) + (CLOSE FILE)) + (OPEN (CONS (CONS 'DSK X) '(/.FILE/. /(DIR/))))) + (ASCII 0)) + +FASLOADING WITHIN A FASLOAD WORKS PRETTY WELL. +NATURALLY, YOU CAN ONLY FASLOAD *BETWEEN* FUNCTION; +"EVALUATED CONSTANTS" WITHIN A FUNCTION MAY NOT +DO FASLOADS. (IF YOU DON'T UNDERSTAND THIS LAST ITEM, +DON'T WORRY.) + +FORCE-OUTPUT IS AS IN THE MANUAL; IT FORCES AN BUFFER OUT. +CLEAR-INPUT AND CLEAR-OUTPUT BOTH EXIST. ON ITS THEY ARE +MEANINGFUL ONLY FOR TTY FILES, THOUGH THEY DON'T HURT ON +ANY OTHER FILES. + +THE STATUS CALLS BELOW ARE EQUIVALENT TO THE +EXPRESSIONS TO THE RIGHT, AND ARE INCLUDED ONLY +FOR COMPATIBILITY WITH OLD I/O. AVOID USING THESE +STATUS CALLS IN NEW CODE. +NOTE THAT (STATUS UREAD) ETC. RETURNS A NEW I/O NAMELIST, +WHICH IS NOT QUITE OF THE SAME FORM AS AN OLD I/O 4-LIST. + +(STATUS UREAD) <=> (TRUENAME UREAD) +(SSTATUS UREAD ...) <=> (UREAD ...) +(STATUS UWRITE) <=> (CAR (TRUENAME UWRITE)) +(SSTATUS UWRITE ...) <=> (UWRITE ...) +(STATUS CRFILE) <=> (CDR (DEFAULTF NIL)) +(SSTATUS CRFILE ...) <=> (DEFAULTF '(...)) +(STATUS CRUNIT) <=> (CRUNIT NIL) +(SSTATUS CRUNIT ...) <=> (CRUNIT ...) + +FOR COMPATIBILITY WITH OLD I/O, IF THE FILE IS OMITTED +IN THE STATUS CALLS BELOW, THE VALUE T (THE STANDARD +INITIAL TTY) IS ASSUMED. + +(STATUS TTY X) HANDS BACK THE TTYST1, TTYST2, AND TTYSTS + VARIABLES FOR THE TTY INPUT FILE X AS A LIST + OF THREE FIXNUMS. + +(SSTATUS TTY M N X) SETS THE TTYST1 AND TTYST2 VARIABLES + FOR THE TTY INPUT FILE X TO THE FIXNUMS M AND N. + +(STATUS TTYREAD X) HANDS BACK THE TTYREAD SWITCH FOR THE + TTY INPUT FILE X. IF NIL, THEN ONLY FORCE-FEED + CHARACTERS CAUSE THE TTY PRE-SCAN FUNCTION TO + RETURN WITH ITS BUFFERED LIST OF CHARACTERS. + +(SSTATUS TTYREAD VAL X) SETS THE SWITCH TO T OR NIL + ACCORDING TO VAL. + +(STATUS LINMODE X) HANDS BACK THE LINMODE SWITCH FOR THE + TTY INPUT FILE X. IF T, THEN ONLY CARRIAGE + RETURNS CAUSE THE TTY PRE-SCAN FUNCTION TO + RETURN WITH ITS BUFFERED LIST OF CHARACTERS. + +(SSTATUS LINMODE VAL X) SETS THE LINMODE SWITCH. + IT ALSO AFFECTS THE ACTIVATION BITS IN + THE TTYST1 AND TTYST2 VARIABLES. + +---------------------------------------------------------------- +THINGS WHICH HAVE DISAPPEARED IN NEW I/O, NOT TO BE IMPLEMENTED +---------------------------------------------------------------- +(STATUS INTERRUPT) AND (SSTATUS INTERRUPT) DO NOT EXIST +IN NEWIO. (ENDPAGEFN ) IS USED TO SET UP +**MORE** INTERRUPTS; (SSTATUS TTYINT) IS USED TO SET FUNCTIONS +FOR INTERRUPT CHARACTERS. ALL OTHER INTERRUPT FUNCTIONS +ARE THE VALUES OF ATOMIC SYMBOLS, AND SO CAN BE SET UP +WITH SETQ. THE NAMES OF THESE VARIABLES ARE: + +ALARMCLOCK UNDF-FNCTN +AUTOLOAD UNBND-VRBL +ERRSET WRNG-TYPE-ARG +*RSET-TRAP UNSEEN-GO-TAG +GC-DAEMON WRNG-NO-ARGS +GC-OVERFLOW GC-LOSSAGE +PDL-OVERFLOW FAIL-ACT + IO-LOSSAGE + +THE ONLY ONE OF THESE WHICH IS NEW IN NEWIO IS AUTOLOAD, +WHICH HOLDS THE AUTOLOAD INTERRUPT HANDLER. + +LOADARRAYS AND DUMPARRAYS NO LONGER EXIST. A MORE GENERAL +NEW I/O PRIMITIVE WILL EVENTUALLY ENABLE THE USER TO WRITE +THESE FUNCTIONS FOR HIMSELF (A STANDARD PACKAGE EQUIVALENT +TO THE OLD ONES WILL BE PROVIDED). + +IOC NO LONGER EXISTS IN NEW I/O. USE THE FOLLOWING + TABLE OF EQUIVALENCES: +(IOC C) <=> (SETQ ^D NIL) +(IOC D) <=> (SETQ ^D T) +(IOC G) <=> (^G) +(IOC Q) <=> (SETQ ^Q T) +(IOC R) <=> (SETQ ^R T) +(IOC S) <=> (SETQ ^Q NIL) +(IOC T) <=> (SETQ ^R NIL) +(IOC V) <=> (SETQ ^W NIL) +(IOC W) <=> (CLEAR-OUTPUT (SETQ ^W T)) +(IOC X) <=> (^X) +(IOC Z) <=> (VALRET ':VK/ ) +TO INVOKE USER INTERRUPT FUNCTIONS, JUST FUNCALL THEM. + +IOG NO LONGER EXISTS. INSTEAD OF (IOG NIL ...) SAY INSTEAD + ((LAMBDA (^Q ^R ^W) ...) NIL NIL NIL). + +(STATUS IOC), (SSTATUS IOC) NO LONGER EXIST. + THEIR EFFECT CAN BE DUPLICATED BY USING + SETQ, FUNCALL, OR THE NEW ^X AND ^G + FUNCTIONS. + +(STATUS TERPRI), (SSTATUS TERPRI) NO LONGER EXIST. + TO GET THEIR EFFECT, USE THE LINEL FUNCTION + TO SET THE LINEL FOR EACH OUTPUT FILE TO 0. + (A LINEL OF ZERO MEANS INFINITY.) + +(STATUS PAGEPAUSE), (SSTATUS PAGEPAUSE) NO LONGER EXIST. + THEY HAVE BEEN SUPERSEDED BY THE **MORE** + INTERRUPT FEATURE. + +2/7/75 - JONL AND GLS - + +BRIEF SYNOPSIS: +[1] THE VALUE OF PRIN1 CONTROLS USE OF PRIN1 BY LISP. +[2] NEW COMPLR SWITCHES, AND DECLARATIONS, AND THINGS: + [2A] ^^ NOW ENTERS MAKLAP. + [2B] COMPILER-STATE TO DETERMINE STATE OF COMPILER. + [2C] EXPR-HASH (E SWITCH) FOR FUNCTION HASHING. + [2D] THE GLOBAL VARIABLE "SOBARRAY" HOLDS THE ARRAY POINTER + TO THE STANDARD LISP OBARRAY. + [2E] EOC-EVAL TO EVAL THINGS AFTER COMPILATION IS COMPLETED. + [2F] COUTPUT TO OUTPUT THINGS TO THE LAP FILE. + [2G] DONT EVER, BUT EVER, USER "QUOTE" AS A LAMBDA OR + PROG VARIABLE. +[3] VALUE OF DEFUN CONTROLS EXPR-HASH CROCK IN INTERPRETER. +[4] USE PLIST AND SETPLIST TO ACCESS AND STORE PROPERTY LISTS +[5] "ROMAN" APPEARS ON THE FEATURE LIST [GOTTEN BY (STATUS FEATURES), + OR TESTED BY (STATUS FEATURE ROMAN)] IF THAT HACK IS ASSEMBLED IN. +[6] ON A DEC-10 MONITOR, (STATUS JNAME) RETURNS "NNNLSP". +[7] _ FIXNUM OUTPUT FORMAT EXTENDED TO _22, _11. +[8] (STATUS FREE ...), (SSTATUS FREE ...) FLUSHED. +[9] MANY CHANGES TO THE BREAK AND *BREAK FUNCTIONS: + [4A] BREAK OF THREE ARGUMENTS NO LONGER EXISTS. + [4B] BREAK/*BREAK LAMBDA-BIND *, +, -. + [4C] ([S]STATUS BREAKLEVEL) IS LIKE ([S]STATUS TOPLEVEL). + [4D] BREAK USES A CATCH; (THROW BREAK) EXITS. + ALSO, AN ATTEMPT TO EXPLAIN BREAK AND TOPLEVEL IN EXPR CODE + +---------------------------------------------------------------- + +[1] THE VALUE OF THE ATOM "PRIN1" NOW CONTROLS THE ACTION OF + PRINTING BY THE TOP-LEVEL AND BREAK ROUTINES. IN SHORT, AN + ITEM X RESULTING FROM THE EVALUATION IN THESE LOOPS IS + PRINTED LIKE + (COND (PRIN1 (FUNCALL PRIN1 X)) + (T (PRIN1 X))) + THIS FEATURE EXISTS PRIMARILY FOR THE OWL SYSTEM, WHICH HAS + CIRCULAR LIST STRUCTURE ABUNDANT, AND DOESN'T NEED TO + REWRITE THE ENTIRE TOP-LEVEL ROUTINE MERELY TO ACCOUNT FOR + THE PRINTING OF CIRCULAR STRUCTURE. + +[2] SOME NEW SWITCHES AND DECLARATIONS FOR THE COMPILER: + [2A] TYPING ^^ NOW ENTERS MAKLAP [JUST AS IN MACSYMA, WHERE ^^ + DOES A (CONTINUE)]. + [2B] COMPILER-STATE + THIS VARIABLE REVEALS TO THE USER ONE OF THREE STATES + THAT THE COMPILER MAY BE IN, AND IS OF INTEREST TO + SOMEONE WHO WANTS TO WRITE SOPHISTICATED MACROS WHICH + EXPAND IN DIFFERENT WAYS DEPENDING ON THE REASON FOR + THE EXPANSION. POSSIBLE VALUES FOR COMPILER-STATE: + [2B1] "TOPLEVEL" + THE COMPILER IS AT THE TOP LEVEL OF LISP. + [2B2] "MAKLAP" + THE COMPILER IS SCANNING AN INPUT FILE LOOKING + FOR FUNCTION DEFINITIONS TO COMPILE. IN THIS + STATE THE COMPILER WILL EXPAND ANY TOP-LEVEL + FORM (FOO ...) FOR WHICH FOO HAS A MACRO + PROPERTY TO SEE IF A FUNCTION DEFINITION IS + PRODUCED [WHICH WOULD THEN BE COMPILED]. + [2B3] "COMPILE" + THE COMPILER IS ACTUALLY COMPILING A FORM + WHICH IS A FUNCTION DEFINITION, PRODUCING + LAP CODE. IN THIS STATE ANY SUB-FORM + (FOO ...) WHICH IS TO BE COMPILED IS EXPANDED + IF FOO HAS A MACRO PROPERTY. + RANDOM EXAMPLE: + WHEN A FUNCTION IS DEFINED YOU WANT THE FLATSIZE OF + THE DEFINITION TO BE PUT ON THE PROPERTY LIST OF + THE FUNCTION. IF THE FUNCTION IS COMPILED, YOU WANT + TO ARRANGE TO OUTPUT AN APPROPRIATE DEFPROP INTO + THE LAP FILE. + (DEFUN STRANGE-DEFUN MACRO (FORM) + ;DO THE MACRO THING (NOT HAIRY) + (RPLACA FORM 'DEFUN) + ;NOW HACK THE FLATSIZE THING + (COND ((OR (NULL (BOUNDP COMPILER-STATE)) + (EQ COMPILER-STATE 'TOPLEVEL)) + ;IF INTERPRETING, OR AT COMPILER TOPLEVEL, + ; JUST GO AHEAD AND DO THE PUTPROP + (PUTPROP (CADR FORM) + (FLATSIZE FORM) + 'STRANGE-FLATSIZE)) + + ((EQ COMPILER-STATE 'MAKLAP) + ;IF COMPILING A TOP-LEVEL FORM FROM A FILE, + ; ARRANGE FOR A DEFPROP IN THE LAP FILE + (COUTPUT (LIST 'DEFPROP + (CADR FORM) + (FLATSIZE FORM) + 'STRANGE-FLATSIZE))) + ((EQ COMPILER-STATE 'COMPILE) + ;WE DON'T WANT A DEFPROP IN THE + ; MIDDLE OF ANY LAP CODE! + (ERROR 'STRANGE-DEFUN/ IN/ SUBFORM + FORM + 'FAIL-ACT)))) + [2C] EXPR-HASH + THIS FEATURE CONTROLS THE AUTOMATIC OUTPUTTING BY THE + COMPILER OF A DEFPROP FOR EACH FUNCTION COMPILED WHICH + DEFINES AN "EXPR-HASH" PROPERTY FOR THAT FUNCTION. THIS + PROPERTY IS A NUMBER, WHICH IS THE SXHASH OF THE + LAMBDA-FORM STORED AS THE EXPR PROPERTY OF THE FUNCTION + WHEN USED IN EXPRFORM. THE INTENDED USE OF THIS IS TO + HAVE A QUICK, AUTOMATIC SCHEME TO DECIDE WHICH FUNCTIONS + HAVE BEEN EDITED SINCE COMPILATION, AND TO READ IN THE + EXPR VERSIONS OF THOSE CHANGED FUNCTIONS. STORING THE + SXHASH OF THE LAMBDA DEFINITION OF THE FUNCTION LENDS + ITSELF TO SIMPLE, QUICK, AND NON-SPACE-CONSUMING (IF NOT + COMPLETELY FOOLPROOF) METHODS. IT IS SET EITHER BY + A DECLARATION + (DECLARE (EXPR-HASH )) + OR BY USING THE "E" SWITCH IN THE MAKLAP COMMAND LINE. + [SEE ITEM [3] BELOW FOR AN ASSOCIATED CHANGE IN DEFUN.] + [2D] SOBARRAY + THIS VARIABLE HOLDS A POINTER TO THE STANDARD LISP OBARRAY, + IN WHICH THE COMPILER ITSELF IS RESIDENT. "COBARRAY" HOLDS + THE ARRAY POINTER TO THE COMPILER'S OBARRAY USED WHILE + COMPILING FILES. THESE TWO VARIABLES FACILITATE WRITING + OBARRAY-SWITCHING FUNCTIONS. + [2E] EOC-EVAL + THIS VARIABLE HOLDS A LIST OF FORMS TO BE EVALUATED + AFTER COMPILATION OF A FILE HAS BEEN COMPLETED. ONE CAN + SET IT FROM A DECLARE, OR USE THE FUNCTION "EOC-EVAL" + WHICH CONSES THE ITEMS OF THE CALLING FORM ONTO THE LIST + STORED IN EOC-EVAL. AT THE TIME OF COMPLETION OF + COMPILATION, (MAPC 'EVAL EOC-EVAL) IS DONE. + EOC-EVAL IS RESET BY INITIALIZATION, OR BY THE WHIM + OF THE USER. + [2F] COUTPUT + THIS FUNCTION SHOULD BE USED TO OUTPUT RANDOM FORMS + TO THE LAP FILE. THIS IS CURRENTLY DONE BY USING + PRINT; THUS ONE USED TO SAY, FOR EXAMPLE + (DECLARE (PRINT (LIST 'SETQ + 'VERSION + (CADR (STATUS UREAD))))) + IT IS ANTICIPATED, HOWEVER, THAT EVENTUALLY THE COMPILER + MAY NOT WRITE A LAP FILE, BUT WILL BUFFER UP FORMS + FOR THE ASSEMBLY PASS. THEREFORE THE FUNCTION + COUTPUT SHOULD BE USED INSTEAD: + (DECLARE (COUTPUT (LIST 'SETQ + 'VERSION + (CADR (STATUS UREAD))))) + WHICH WILL DO THE CORRECT THING IN THE FUTURE + WHEN THE BUFFERING MODE MATERIALIZES. + +[3] THE VALUE OF THE VARIABLE DEFUN CONTROLS A CROCK IN THE + WORKINGS OF THE FUNCTION DEFUN. IF THE VALUE OF DEFUN + IS NON-NIL, THEN EVALUATING (DEFUN FOO ...) WILL SUCCEED + IN CREATING THE NEW DEFINITION ONLY IF EITHER: + [A] FOO HAS NO EXPR-HASH PROPERTY. + [B] FOO HAS AN EXPR-HASH PROPERTY, BUT IT IS NOT + THE SAME AS SXHASH OF THE LAMBDA FORM FOR THE + NEW DEFINITION. + THUS A POOR MAN'S WAY TO USE THE COMPILER'S EXPR-HASH + FEATURE IS TO COMPILE A FILE WITH THE (E) SWITCH, + LOAD IT INTO A LISP, EDIT THE FILE SOME, DO (SETQ DEFUN T), + THEN JUST READ IN THE UPDATED SOURCE, AND THE EXPR-HASH + SCHEME WILL (PROBABLY) REDEFINE ONLY THOSE FUNCTIONS + WHICH HAVE CHANGED, AND LEAVE THE SUBR VERSIONS IN FORCE + FOR UNCHANGED FUNCTIONS, PROBABLY. + +[4] THE NEW SUBR OF ONE ARGUMENT, PLIST, IS USED TO RETRIEVE THE + PROPERTY LIST OF A SYMBOL; THIS FUNCTION WORKS ON ALL SYMBOLS + INCLUDING NIL, WHEREAS CDR WILL WORK ONLY FOR NON-NULL SYMBOLS + IN NON-*RSET MODE. SIMILAR REMARKS HOLD FOR THE NEW SUBR OF TWO + ARGUMENTS, SETPLIST. (SETPLIST X (PLIST X)) SHOULD BE A NOOP. + +[5] IF "ROMAN" IS A FEATURE OF THE LISP YOU ARE USEING, THEN + YOU CAN TRY (SETQ IBASE 'ROMAN) OR (SETQ BASE 'ROMAN) FOR + FUN AND GAMES; OTHERWISE, NO. + +[6] IN THE DEC-10 VERSION OF MACLISP, (STATUS JNAME) RETURNS + THE ATOMIC SYMBOL "NNNLSP", WHERE NNN IS THE JOB NUMBER + IN DECIMAL. THIS IS A STANDARD FIRST FILE NAME FOR + TEMPORARY FILES, ETC. + +[7] TO MAKE THE _ FORMAT OF FIXNUM OUTPUT MORE USEFUL, + THE FOLLOWING FORMATS ARE NOW USED [WHEN IBASE IS 8 + AND (STATUS _) IS T]: + IF THE NUMBER IS SMALLER THAN 2**18., + OR IF THE LOW NINE BITS IN THE BINARY REPRESENTATION + ARE NOT ALL ZERO, + THEN THE _ FORMAT IS NOT USED. + IF THE LOW 41 BITS ARE ALL ZERO, THEN N_41 IS USED. + IF THE LOW 33 BITS ARE ALL ZERO, THEN N_33 IS USED. + IF THE LOW 22 BITS ARE ALL ZERO, THEN N_22 IS USED. + OTHERWISE, N_11 IS USED. + NOTE THAT THESE CORRESPOND TO QUARTER-WORD BOUNDARIES + (EXCEPT N_41); BUT N_11 IS NOT USED IF 6 OR FEWER + DIGITS WOULD SUFFICE. + +[8] (STATUS FREE ...) AND (SSTATUS FREE ...) HAVE BEEN, OR + SOON WILL BE, FLUSHED, SINCE THEY ARE OBSOLETE AND + MAINLY A PAIN TO MAINTAIN. + +[9] MANY CHANGES TO THE BREAK FUNCTION: + [9A] BREAK OF THREE ARGUMENTS HAS BEEN FLUSHED. + (THE THIRD ARGUMENT USED TO BE A FORM TO BE + EVALUATED IF P WERE TYPED.) + [9B] *BREAK (ERGO ALSO BREAK) NOW LAMBDA-BINDS + *, +, AND - TO THEIR OWN CURRENT VALUES SO THAT + THEY WILL BE RESTORED ON EXIT FROM THE BREAK. + [9C] (STATUS BREAKLEVEL) AND (SSTATUS BREAKLEVEL ) + ARE ANALOGOUS TO (STATUS TOPLEVEL) AND + (SSTATUS TOPLEVEL ). THE DEFAULT BREAKLEVEL, + LIKE THE DEFAULT TOPLEVEL, IS A READ-EVAL-PRINT + LOOP WHICH UPDATES *, +, AND - PROPERLY. + [9D] BREAK HAS BEEN REDEFINED USING CATCH, WITH A + CATCH-TAG OF "BREAK". IF AT ANY TIME WITHIN A + BREAK THE FORM (THROW BREAK) IS EXECUTED, + THE BREAK (OR *BREAK) FUNCTION WILL BE EXITED, + RETURNING . THUS, FOR EXAMPLE, IF ONE + TIRES OF TYPING (RETURN '(FOO)) TO UNBND-VRBL + BREAKS OR WHATEVER, ONE MIGHT DEFINE A MACRO- + CHARACTER + (SETSYNTAX '/: 'MACRO + '(LAMBDA NIL + (THROW (LIST (READ)) BREAK))) + AND SIMPLY TYPE :FOO AT THE UNBND-VRBL BREAK + TO USE THE VARIABLE FOO INSTEAD. + + BELOW IS A NEW DEFINITION OF THE BREAK AND *BREAK FUNCTIONS W + WRITTEN IN LISP, AS WELL AS A HALF-HEARTED ATTEMPT AT + EXPLAINING THE TOP LEVEL LOOP. + +(DEFUN BREAK FEXPR (X) + (*BREAK (EVAL (CADR X)) (CAR X)) ;NOTE ARGUMENT REVERSAL + +;;; THE FIRST ARGUMENT TO BREAK IS A SWITCH, WHICH IF NIL CAUSES +;;; IMMEDIATE EXIT WITH NOTHING BEING DONE; +;;; OTHERWISE, THE VARIABLES ^Q, ^W, AND EVALHOOK ARE BOUND +;;; TO NIL, AND THE VARIABLES *, +, AND - ARE BOUND TO THEIR +;;; CURRENT VALUES, AND THE MESSAGE ";BKPT " IS PRINTED. +;;; A READ-EVAL-PRINT LOOP SIMILAR TO THE TOP LEVEL LOOP +;;; IS THEN ENTERED. THIS BREAK LOOP IS SURROUNDED BY AN +;;; ERRSET AND A CATCH. ERRORS MERELY CAUSE THE BREAK +;;; LOOP TO BE RE-ENTERED. +;;; THE VALUE OF (STATUS BREAKLEVEL) SERVES A FUNCTION +;;; SIMILAR TO THAT OF (STATUS TOPLEVEL) IN THE TOP LEVEL +;;; LOOP. +;;; AS EACH FORM IS READ IN THE DEFAULT BREAK LOOP, THERE ARE +;;; FOUR CASES: +;;; [1] END OF FILE. THIS INDICATES OVER-RUBOUT AND +;;; SIMPLY CAUSES A TERPRI. +;;; [2] THE FORM IS THE ATOM P. *BREAK RETURNS NIL. +;;; [3] THE FORM IS (RETURN ). THE FORM +;;; IS EVALUATED AND RETURNED. +;;; [4] OTHERWISE, THE FORM IS EVALUATED AND THE RESULT +;;; PRINTED OUT IN A MANNER ANALOGOUS TO THE TOP +;;; LEVEL READ-EVAL-PRINT LOOP. THE VARIABLES +, -, +;;; AND * ARE UPDATED APPROPRIATELY. (RECALL, HOWEVER, +;;; THAT THEY WERE BOUND ON ENTRY TO *BREAK, AND SO +;;; WILL BE RESTORED EVENTUALLY.) +;;; THE WAY TO RETURN FROM A BREAK IS TO DO A THROW WITH +;;; A TAG OF "BREAK"; THIS WILL RETURN FROM THE CATCH WHICH +;;; SURROUNDS THE BREAK LOOP. THIS IS HOW CASES [2] AND [3] +;;; RETURN THEIR VALUES; CASE [4] MAY ALSO CAUSE A RETURN FROM +;;; THE BREAK. + +(DECLARE (SPECIAL Q ^W EVALHOOK * + -)) + +(DEFUN *BREAK (BREAKP BREAKID) + (AND BREAKP + ((LAMBDA (^Q ^W EVALHOOK * + -) + (TERPRI) + (PRINC '/;BKPT/ ) + (PRINC BREAKID) + (SETQ + -) + (CATCH (DO NIL + (NIL) + (ERRSET (DO ((EOF (LIST NIL)) (FORM)) + (NIL) + (COND ((STATUS BREAKLEVEL) + (EVAL (STATUS BREAKLEVEL))) + (T (SETQ FORM (READ EOF)) + (COND ((EQ FORM EOF) (TERPRI)) + ((EQ FORM 'P) + (THROW NIL BREAK)) + ((EQ (CAR FORM) 'RETURN) + (THROW (EVAL (CADR FORM)) + BREAK)) + (T (SETQ - FORM) + (SYSPRINT (SETQ * + ((LAMBDA (+) + (EVAL FORM)) + (PROG2 NIL + + (SETQ + -))))) + (TERPRI)))))))) + BREAK) + (OR (STATUS LINMODE) (TERPRI))) + NIL + NIL + NIL + * + + + -))) + +(DEFUN SYSPRINT (X) ;INTERNAL PRINTING FUNCTION + (OR (STATUS LINMODE) (TERPRI)) + (COND (PRIN1 (FUNCALL PRIN1 X)) + (T (PRIN1 X))) + (TYO 40)) + +(DEFUN STANDARD-TOP-LEVEL NIL + (PROG (^Q ^W ^R EVALHOOK BASE IBASE ...) + ERRS ;ERRORS, UNCAUGHT THROWS, ETC. COME HERE + (RESET-BOUND-VARS) + ^G ;^G QUITS COME HERE + (RESET-INTERNAL-TOP-LEVEL-VARS) + (RESTORE-THE-WORLD) + (DO-DELAYED-INTERRUPTS) +;RECALL THAT ERRORS DO (SETQ // ERRLIST) SO LAMBDA-BINDING ERRLIST WORKS + (MAPC (FUNCTION EVAL) //) + (AND (STATUS LINMODE) (TERPRI)) + (SETQ * '*) + (DO ((EOF (LIST NIL))) (NIL) + (RESET-INTERNAL-TOP-LEVEL-VARS) + (SETQ * (COND ((STATUS TOPLEVEL) + (EVAL (STATUS TOPLEVEL))) + (T (SYSPRINT *) + (TERPRI) + (DO ((FORM (READ EOF) (READ EOF))) + ((NOT (EQ FORM EOF)) + (SETQ - FORM)) + (TERPRI)) + ((LAMBDA (+) (EVAL -)) + (PROG2 NIL + (SETQ + -))))))))) + +(DEFUN RESTORE-THE-WORLD NIL + (RESET-THE-PDLS) + (SETQ ^Q NIL) + (SETQ EVALHOOK NIL) + (RESTORE-THE-IO-SYSTEM) + (ENABLE-SYSTEM-INTERRUPTS) + (RESET-INTERNAL-GC-MARK-BITS)) + +(DEFUN DO-DELAYED-INTERRUPTS NIL + (OR INTERNAL-NOINTERRUPT-SWITCH + (PROCESS-PENDING-ALARMCLOCK-AND-TTY-INTERRUPTS))) + 12/8/74 JONL & GLS + +Remember, BIBOP LISP is now the standard system LISP! + [As of version number 958]. + +LISTARRAY has been extended to be an LSUBR. an optional second + argument puts a bound on the number of elements to LISTIFY. + For example, (LISTARRAY ary 5) lists only the first five elements + of ary; while (LISTARRAY ary), as before, lists all elements. + note that (LISTARRAY ary (APPLY 'TIMES (CDR (ARRAYDIMS ary)))) + also lists all elements. + +MAKOBLIST, MAKREADTABLE, and BLTARRAY have been flushed. If you + used them before, you can substitute calls as in the table below: + + FOR THIS CODE USE THIS INSTEAD + + (BLTARRAY x y) (FILLARRAY Y X) + ;note reversal of args + (MAKREADTABLE x) (*ARRAY x 'READTABLE) + x not T or NIL + (MAKREADTABLE t-or-nil) (*ARRAY (GENSYM) 'READTABLE t-or-nil) + + (MAKOBLIST x) (*ARRAY x 'OBARRAY) + x not NIL + (MAKOBLIST NIL) (LISTARRAY + OBARRAY + (- (CADR (ARRAYDIMS 'OBARRAY)) 129.)) + +Note that FILLARRAY is consistent in that it always transfers + the contents of its second arg into the first, and returns + the first (an array). Note too that this means that when + replacing a BLTARRAY by a FILLARRAY, you must reverse the args. + + +SYMEVAL lives! If you know that you are evaluating an atomic symbol, + it will be faster to use SYMEVAL rather than the general-purpose + EVAL. In particular, as soon as BIBOP LISP becomes the settled + standard, SYMEVAL will compile optimally into two instructions. + +In *RSET mode, all car-cdr calls are checked at each level to see + that CAR or CDR is applied only to proper data. This checking is + not done by compiled code [which usually open-codes car-cdr ings] + [this is not really true, because compiled code calls functions + like CDDDDR, even if the user does not explicitly use them], + nor when *RSET = NIL. CAR and CDR are variables which control + the checking as follows: + LIST can hack only lists + NIL can hack lists and NIL + SYMBOL can hack lists, NIL, and symbols + T can hack anything. + When in *RSET mode, the value of CDR controls the permissible + operations for the function CDR, and the value of CAR controls + the permissible operations for the function CAR. + FRIDAY SEPT 13,1974 LQ+4D.19H.41M.28S. LISP 909 - GLS - + +BRIEF SYNOPSIS: + +[1] NEW FUNCTION: FSC. SIMILAR TO LSH AND ROT. +[2] NEW STATUS OPTION: (STATUS TTYSIZE). +[3] REMPROP CHANGED TO RETURN USEFUL QUANTITY. +[4] ISQRT HAS BEEN FLUSHED. CODE BELOW SUPERSEDES IT. +[5] (EXPT X .5) IS INHERENTLY LESS ACCURATE THAN (SQRT X). +[6] FASLOAD FILES CAN BE CONCATENATED. +[7] (IOC W) PROBLEM EXTENDS TO IOG. GRUMBLE. BEWARE! +---------------------------------------------------------------- +[1] NEW FUNCTION: FSC IS ANALOGOUS TO ROT AND LSH. + IT ACCEPTS EITHER FIXNUMS OR FLONUMS, AND ACTS UPON + THE BITS GIVEN IT; I.E. LIKE ROT AND LSH IT DOES NOT + DO THE FLOAT OR FIX FUNCTION. UNLIKE ROT AND LSH, HOWEVER, + FSC RETURNS A FLONUM. NOTE THAT THE FSC PDP-10 INSTRUCTION + NORMALIZES THE RESULT. THIS IS A PDP-10 DEPENDENT FUNCTION! + (FSC N 0) IN PARTICULAR IS INTENDED TO BE THE INVERSE + OF (LSH N 0); NAMELY, IT TAKES A FIXNUM AND MAKES THE + BITS OF THAT FIXNUM INTO A FLONUM (THAT IS, IT USES THE + FIXNUM AS THE MACHINE REPRESENTATION OF THE FLONUM). + IN GENERAL, (= F (FSC (LSH F 0) 0)) FOR ANY FLONUM F, + BUT (= X (LSH (FSC X 0) 0)) FOR FIXNUM X IFF X IS + THE REPRESENTATION OF A *NORMALIZED* PDP-10 FLONUM. + +[2] (STATUS TTYSIZE) RETURNS A DOTTED PAIR OF THE TTY'S CURRENT + HEIGHT AND WIDTH (ANALOGOUS TO CURSORPOS OF NO ARGS). + THESE ARE THE PARAMETERS AS RETURNED BY THE SYSTEM, WHICH + PRESUMABLY ARE SETTABLE VIA :TCTYP. + +[3] REMPROP, IF IT FINDS THE PROPERTY TO REMOVE, INSTEAD OF + RETURNING T, RETURNS THE CELL OF THE PROPERTY LIST WHOSE + CAR IS THE PROPERTY (THIS CELL WAS SPLICED OUT FROM THE + PROPERTY LIST). + +[4] ISQRT HAS BEEN FLUSHED FROM THE LISP SYSTEM. THE LISP + CODE BELOW IS MORE ACCURATE AND WORKS ON BIGNUMS. + + (DEFUN BSQRT (N) + (BSQRT1 (ABS N) + (EXPT 2 (// (1+ (HAULONG N)) 2)))) + + (DEFUN BSQRT1 (N GUESS) + ((LAMBDA (NEXT) + (COND ((LESSP NEXT GUESS) + (BSQRT1 N NEXT)) + (T GUESS))) + (*QUO (*PLUS GUESS (*QUO N GUESS)) 2))) + + THIS IS ESSENTIALLY A NEWTON ITERATION (DUE TO GOSPER) + WITH APPROPRIATE PRECAUTIONS FOR INTEGER TRUNCATION. + +[5] (EXPT X .5) IS INHERENTLY LESS ACCURATE THAN (SQRT X). + USE THE LATTER WHEN YOU KNOW IT'S SQRT. + +[6] IF YOU CONCATENATE SEVERAL FASLOAD FILES SO THAT THE + BEGINNING *FASL* OF THE NEXT FOLLOWS THE TERMINATING *FASL* + OF THE PREVIOUS ONE, THEN FASLOAD WILL GO 'ROUND THE + FASLOAD CYCLE AGAIN AND LOAD IT UP TOO. CURRENTLY + THERE IS NO CONVENIENT WAY TO CONCATENATE FASLOAD FILES, + BUT I NEVER PROMISED YOU A ROSE GARDEN. + +[7] REMEMBER THE (IOC W) BUG, GANG? IT STILL HAUNTS US! + NAMELY, (IOC W) RESETS THE TTY OUTPUT BUFFER, THUS POSSIBLY + LOSING CHARACTERS FROM THE PREVIOUS OUTPUT FUNCTION. + THE RIGHT WAY TO DO IT IS (SETQ ^W T). WELL, IT FOLLOWS + THAT (IOG W ) ISN'T THE RIGHT THING EITHER. + THE RIGHT THING IS (IOG NIL (SETQ ^W T) ). + I DON'T LIKE IT EITHER. + +[8] POOR SIGNP! + + AUG 17, 1974 LISP 893 - GLS AND JONL - + +[1] A NEW LAP, INCOMPATIBLE WITH OLDER LISPS, IS STANDARD +[2] NEW FUNCTIONS: ^, ^$. EXPT EXTENDED. +[3] NEW EDITOR COMMANDS: SS, RS, PC. +[4] BOUNDP HAS BEEN CHANGED TO SAVE CONSING. +[5] ERRFRAME HAS BEEN CHANGED TO GIVE OUT MORE INFO. +[6] THROWING OUT OF A TTY INTERRUPT CAN LEAD TO LOSSAGE. +[7] DONT USE (IOC W) IF YOU REALLY WANT (SETQ ^W T). +[8] NCOMPLR RECOGNIZES "COMPLR (INIT)" FILES. +[9] IN LISP, YOU CAN NOW (SETQ IBASE 'ROMAN). DITTO FOR BASE. + +---------------------------------------------------------------- +[1] LAP 81 IS THE STANDARD LAP NOW, AND IS WHAT YOU GET BY + AUTOLOAD. SINCE IT WILL NOT WORK IN LISPS WITH VERSION + NUMBERS LESS THAN 892, YOU WILL HAVE TO RETRIEVE THE OLDER + LAP EXPLICITLY IF YOU NEED IT. DO (FASLOAD LAP OFASL COM) + BEFORE TRYING TO USE LAP IN AN OLDER LISP. + LAP NOW USES THE VALUE OF THE VARIABLE FASLOAD IN THE + SAME WAY FASLOAD ITSELF DOES: IF IT IS NIL, THEN MESSAGES + ABOUT FUNCTIONS REDEFINITIONS ARE SUPPRESSED. ALSO, LAP + NOW TRIES TO DO PURE LOADINGS WHEN THE VALUE OF "PURE" IS + NON-NIL. + +[2] NEW FUNCTIONS: + ^ TAKES TWO FIXNUMS A AND B, AND RETURNS A TO THE B'TH + POWER AS A FIXNUM (MODULO 2^35.). WILL NOT DO BIGNUM + ARITHMETIC. + ^$ TAKES A FLONUM AND A FIXNUM, RETURNING A FLONUM. + EXPT HAS BEEN EXTENDED. IF THE EXPONENT IS A FLONUM, + THEN THE BASE IS CONVERTED TO A FLONUM, AND THEN + THE FORMULA B (B LOG A) + A = E + IS USED, USING THE LOG AND EXP FUNCTIONS. + +[3] NEW COMMANDS FOR THE BINFORD EDITOR: + SS (SAVE SPOT) GOBBLES THE NAME OF AN ATOMIC + SYMBOL, AND SETQ'S IT TO THE CURRENT EDITOR + CONTEXT. + RS (RESTORE SPOT) GOBBLES SUCH A SETQ'D ATOMIC SYMBOL + AND MAGICALLY MOVES THE EDITOR'S CURSOR TO THE + SAVED SPOT. + PC (PRINT CONTEXT) GOBBLES UP TO TWO FLONUMS (TERMINATE + WITH $$) AND, USING THEM FOR THE PRINLEVEL AND + PRINLENGTH, PRINTS THE CURRENT LEVEL OF LIST + STRUCTURE. IF YOU DON'T SUPPLY TWO ARGS, + DEFAULTS OF 4 ARE USED. + +[4] BOUNDP IS NOW A PURE PREDICATE; IT RETURNS T OR NIL. + ONE CAN GET THE OLD EFFECT OF BOUNDP BY SAYING + (AND (BOUNDP X) (CONS NIL (EVAL X))). + THERE WILL SOOON BE A SPECIAL FUNCTION FOR OBTAINING THE + VALUE OF A SYMBOL, WHICH WILL RUN A LITTLE FASTER THAN + "EVAL", AND WHICH WILL COMPILE QUITE OPTIMALLY. THUS, + (AND (BOUNDP X) (SYMEVAL X)) WILL COMPILE INTO MUCH + FASTER CODE THAN THE WILL THE CURRENT FORM: + (AND (SETQ FOO (BOUNDP X)) (CDR FOO)) + +[5] ERRFRAME HAS BEEN CHANGED TO GIVE YOU MORE INFORMATION. + FORMERLY THE THIRD ITEM OF THE RETURNED LIST WAS THE + ERROR MESSAGE ONLY. NOW IT IS A LIST OF FROM ONE TO + THREE THINGS. IF IT IS ONE THING, IT IS THE ERROR MESSAGE. + YOU CAN PRINC THIS TO RE-CREATE THE ERROR PRINTOUT. + IF THERE ARE TWO THINGS, THE FIRST IS THE MESSAGE AND THE + SECOND IS THE LOSING ITEM. IF THERE ARE THREE THINGS, + THEY ARE THE ERROR MESSAGE, THE LOSING ITEM, AND THE + TYPE OF ERROR (E.G. FAIL-ACT OR UNBND-VRBL). + IN SHORT, YOU GET A LIST OF THINGS SUCH THAT + (APPLY 'ERROR (CADDR (ERRFRAME NIL))) + WILL RE-CREATE THE SAME ERROR! + +[6] PEOPLE HAVE BEEN WRITING TTY INTERRUPT FUNCTION LIKE + (SSTATUS INTERRUPT 15. + '(LAMBDA NIL (THROW NIL TO-TOP-LEVEL))). + THERE IS A DANGER IN THIS: RECALL THAT WHEN A TTY USER + INTERRUPT IS RUN, THE SYSTEM DOES AN IMPLICIT + (NOINTERRUPT 'TTY) + FOR YOU TO PREVENT TIMING ERRORS. IF YOU EXIT THE USER + INTERRUPT ABNORMALLY, YOU MUST RESET NOINTERRUPT YOURSELF. + (SSTATUS INTERRUPT 15. + '(LAMBDA NIL (NOINTERRUPT NIL) + (THROW NIL TO-TOP-LEVEL))) + ALTERNATIVELY, THE TOP LEVEL COULD SAY + (NOINTERRUPT NIL) + AFTER CATCHING THE THROW, POSSIBLY A SAFER ALTERNATIVE + IN SOME CASES. + +[7] LOSERS NOTE: (IOC W) IS NOT THE SAME AS (SETQ ^W T). + IN GENERAL, WHEN YOU JUST WANT TO SET AN I/O SWITCH, + USE SETQ UNLESS YOU ARE AWARE OF THE SIDE EFFECTS INVOLVED. + (IOC W) IN PARTICULAR PERFORMS A SYSTEM (= ITS) I/O + RESET, CLEARING THE TTY OUTPUT BUFFER. IF ANY CHARS + ARE PENDING IN THE BUFFER FOR OUTPUT FROM THE PREVIOUS + PRINT, THEY WILL BE FLUSHED. THUS + (PROG2 (PRINC 'FOOBAR) (IOC W)) + IS VERY LIKELY NOT TO PRINT ANYTHING AT ALL! OR MAYBE + JUST THE "F" IF YOU ARE LUCKY. (PROG2 (PRINC 'FOOBAR) + (SETQ ^W T)) DOES WHAT YOU WANT AND LETS THE "FOOBAR" + PRINT OUT. + +[8] NCOMPLR WILL LOOK FOR A "COMPLR (INIT)" FILE WHEN IT IS + STARTED UP, AND IF FOUND, WILL UREAD AND READ-EVAL IT IN. + YOU CAN FASLOAD OTHER FILES FROM THIS INIT FILE, BUT + CURRENTLY CANNOT UREAD OTHER FILES. THE INIT FILE MAY + BE EITHER ON YOUR DIRECTORY, OR ON THE "(INIT)" DIRECTORY. + +MONDAY JULY 29,1974 FQ+3D.1H.24M.28S. LISP 873 - GLS - + + +THIS LISP RECENT IS SHORT, BUT ITEM [2] IS OF GREAT IMPORTANCE. +THE PREVIOUS LISP RECENT APPEARS AT THE END OF THIS ONE SINCE +IT HASN'T BEEN AROUND FOR VERY LONG. + +BRIEF SYNOPSIS: + +[1] *RSET-TRAP FUNCTION IS ALWAYS RUN AND MUST CHECK *RSET ITSELF +[2] (CAR NIL) AND (CDR NIL) ARE ALWAYS NIL +[3] DUMPARRAYS/LOADARRAYS NOW KNOW ABOUT FIXNUM AND FLONUM ARRAYS +---------------------------------------------------------------- +[1] THE *RSET-TRAP USER INTERRUPT IS ALWAYS RUN WHEN AN + UNCORRECTABLE ERROR IS ABOUT TO POP BACK TO TOP LEVEL + OR TO AN ERRSET. IT IS UP TO THE *RSET-TRAP FUNCTION + TO CHECK THE *RSET SWITCH FOR ITSELF (THE SYSTEM-SUPPLIED + *RSET-TRAP FUNCTION INDEED DOES THIS). + +[2] FOR COMPATIBILITY WITH INTERLISP (FOO), THE CAR AND CDR + OF NIL ARE ALWAYS BUT ALWAYS NIL. NIL STILL HAS A + PROPERTY LIST, AND GET AND PUTPROP STILL WORK ON IT, + BUT NIL'S PROPERTY LIST IS NOT ITS CDR (CROCK, CROCK). + THE CLAIM IS THAT ONE CAN WRITE CODE SUCH AS + (CADDR X) + INSTEAD OF THE MORE TIME- AND SPACE-CONSUMING + (AND (CDR X) (CDDR X) (CADDR X)) + AND SO ON. SEND COMPLAINTS TO GLS, BUT I DOUBT IT WILL + DO YOU ANY GOOD. + +[3] DUMPARRAYS AND LOADARRAYS WILL NOW DO THE CORRECT THING + WITH FIXNUM AND FLONUM ARRAYS. OLD DUMPARRAYS FILES ARE + STILL GOOD - THE HACK IS UPWARD COMPATIBLE. + FRIDAY JULY 19,1974 NM+8H.29M.40S. LISP 861 - GLS - + +BRIEF SYNOPSIS: + +[1] NEW FUNCTIONS: UPROBE, UCLOSE, UAPPEND +[2] DEFPROP NOW DOES REMPROP FIRST, AS DEFUN ALWAYS HAS +[3] (NOINTERRUPT 'TTY) - NEW NOINTERUPT OPTION +[4] PDLFRAME HAS DISAPPEARED - USE EVALFRAME +[5] (SSTATUS CRFILE ...) SETS UREAD FILE NAME DEFAULTS +[6] VALUE OF // INTERACTS WITH ERRLIST; *, +, - MENTIONED +[7] ONE MAY THROW OUT OF A USER INTERRUPT NOW +[8] APPLYFRAMES WIN BETTER - FEAR NOT +[9] UNPURIFY$G DEPURIFIES ALL PAGES - PURIFY$G WILL REPURIFY THEM +[:] COMPLR/NCOMPLR HAVE PRIVATE OBARRAY AS WELL AS READTABLE +[;] MIDAS AND FASLOAD COOPERATE +---------------------------------------------------------------- +[1] THREE NEW FUNCTIONS FOR OLD I/O: + [1A] UPROBE TAKES ARGUMENTS LIKE UREAD, AND TRIES TO FIND + THE FILE SPECIFIED. IF IT EXISTS, UPROBE RETURNS THE + ACTUAL FILE NAMES; IF NOT, IT RETURNS NIL. + [1B] UCLOSE (OF NO ARGUMENTS) CLOSES THE UREAD INPUT + CHANNEL. THIS IS PRIMARILY OF USE BEFORE CALLING THE + SUSPEND FUNCTION. + [1C] UAPPEND (ARGUMENTS LIKE UREAD) OPENS THE SPECIFIED + FILE, WHICH MUST ALREADY EXIST, FOR WRITING. + THE FILE IS RENAMED TO BE ".LISP. APPEND", AND BECOMES + NON-ACCESSIBLE (YOU SEE A * NEXT TO IT IN THE + DIRECTORY). ANY OUTPUT DIRECTED TO THE UWRITE OUTPUT + CHANNEL (THE ^R SWITCH) IS THEN OUTPUT TO THIS FILE, + APPENDED TO THE PREVIOUS CONTENTS. WHEN THE FILE + IS EVENTUALLY CLOSED WITH UFILE, IT WILL TAKE ON THE + FILE NAMES SPECIFIED BY UFILE, AND WILL CONTAIN ITS + OLD CONTENTS WITH THE NEW MATERIAL TACKED ONTO THE + END. NOTE THAT UAPPEND IS REALLY MORE LIKE NCONC + THAN APPEND! I.E. IT DOES NOT COPY THE FILE, BUT + ADDS ONTO THE EXISTING ONE, CLOBBERING IN NEW DATA. + +[2] DEFPROP USED TO BE DESCRIBED AS + (DEFUN DEFPROP FEXPR (X) + (PUTPROP (CAR X) (CADR X) (CADDR X))) + THANKS TO AGITATION BY CERTAIN PARTIES, IT IS NOW + (DEFUN DEFPROP FEXPR (X) + (REMPROP (CAR X) (CADDR X)) + (PUTPROP (CAR X) (CADR X) (CADDR X))) + THAT IS, DEFPROP IS GUARANTEED TO PUT THE NEW PROPERTY + AT THE HEAD OF THE PROPERTY LIST. NOTE THAT DEFUN HAS DONE + SUCH REMPROPING IN THE PAST ALREADY. + +[3] NOINTERRUPT HAS BEEN EXTENDED TO HAVE THREE STATES: + (NOINTERRUPT T) CAUSES ALL ASYNCHRONOUS USER + INTERRUPTS TO BE DELAYED (AS BEFORE; + "ASYNCHRONOUS" INTERRUPTS ARE PRESENTLY + TTY CONTROL CHARS AND THE ALARMCLOCK) + (NOINTERRUPT NIL) LETS SUCH INTERRUPTS GO THROUGH + IMMEDIATELY (THE INITIAL STATE); ANY + DELAYED INTERRUPTS ARE RUN DURING THIS CALL. + *** (NOINTERRUPT 'TTY) CAUSES ONLY TTY INTERRUPTS TO + BE DELAYED, AND LETS OTHERS GO THROUGH. + IN THIS WAY ONE CAN SUPPRESS ^G QUITS, ETC., + BUT STILL ALLOW CLOCK INTERRUPTS. + +[4] PDLFRAME, A SYNONYM FOR EVALFRAME, HAS DISAPPEARED. + USE EVALFRAME FROM NOW ON. + +[5] (SSTATUS CRFILE FOO BAR) WILL SET THE UREAD FILE NAME + DEFAULTS TO "FOO BAR". (STATUS CRFILE) READS THEM, + AS BEFORE. + +[6] THE ATOM // IS NOW A VARIABLE, USED IN CONJUNCTION + WITH ERRLIST. WHEN AN ERROR PROPAGATES BACK TO TOP LEVEL, + THEN WHERE THE TOP LEVEL FORMERLY DID + (MAPC (FUNCTION EVAL) ERRLIST) + IT NOW DOES INSTEAD + (MAPC (FUNCTION EVAL) //) + AND WHEN AN ERROR OCCURS, THEN (SETQ // ERRLIST) + IS PERFORMED. THUS THIS NEW MECHANISM WORKS ALMOST LIKE + THE OLD, WITH ONE IMPROVEMENT (SUGGESTED MY MACRAKIS): + ONE CAN LAMBDA-BIND ERRLIST OVER A COMPUTATION, AND IF + AN ERROR OCCURS THE CURRENT ERRLIST WILL BE USED AND NOT + THE TOP-LEVEL ERRLIST. THIS MAY SOMETIMES BE A DESIRABLE + ALTERNATIVE TO ERRSET. + RECALL AGAIN THAT *, +, AND - ALSO HAVE MEANINGFUL VALUES: + * CONTAINS THE LAST THING TYPED OUT BY LISP'S TOP + LEVEL. THUS IF YOU FORGOT TO TYPE A SETQ AROUND + THE PREVIOUS FORM, YOU CAN STILL RETRIEVE THE + RESULTANT VALUE. + + CONTAINS THE LAST THING READ BY LISP'S TOP LEVEL. + THIS IS USEFUL IN CASE OF A TYPING ERROR; YOU CAN + SAVE THE FORM AND MAYBE EDIT IT. + - CONTAINS THE CURRENT THING READ BY THE TOP LEVEL + (WHEN EVALUATION OF THE THING IS COMPLETED, THEN + SOMETHING LIKE (SETQ + -) HAPPENS). + NOTE THAT ERROR BREAKS SAVE +, SO THAT IF YOU SAY: + (PLUS 3 'A) ;LOSEY LOSEY + A NON-NUMERIC VALUE ;LISP COMPLAINS + ;BKPT WRNG-TYPE-ARG + (PLUS 3 5) ;DO SOME STUFF IN THE BREAK + 10 + $P ;RETURN FROM BREAK + A NON-NUMERIC VALUE ;LISP GRIPES AGAIN + (SETQ FOO +) ;NOW SAVE VALUE OF + + (PLUS 3 'A) ;IT IS FORM THAT LOST + +[7] FORMERLY USER INTERRUPTS WERE AN IMMOVABLE WALL WITH + RESPECT TO THROWS; NOW THEY ARE TRANSPARENT. THIS + MEANS THAT YOU CAN THROW OUT OF A USER INTERRUPT IN + THE OBVIOUS MANNER. EXAMPLE: + + (SSTATUS INTERRUPT 0 '(LAMBDA (X) (THROW NIL ABORT)) + (CATCH (HAIRY-COMPUTATION) ABORT) ;HAIRY MESS + + IN THIS WAY ONE CAN ABORT THE HAIRY MESS BY TYPING ^@. + +[8] SOME PEOPLE HAVE COMPLAINED OF SUPER-SLOWNESS WHEN RUNNING + IN *RSET MODE. THIS WAS DUE TO FAULTY DESIGN IN THE + APPLYFRAME ROUTINES, WHCIH CAUSED CONSING ON EVERY + FUNCTION CALL. THIS HAS BEEN CORRECTED, SO DON'T FEAR + TO USE *RSET MODE NOW. + +[9] UNPURIFY$G TO A LISP OR BLISP WILL UNPURIFY ALL PURE + PAGES IN THE LISP BY COPYING THEM. THIS IS PRIMARILY + SO THAT JPG CAN WIN WHEN DUMPING MACSYMA. PURIFY$G + WILL THEN REPURIFY THE (COPIED) PAGES. + +[:] NCOMPLR WINS WITH ARRAYCALL NOW, BUT COMPLR DOES NOT. + ALSO, BOTH COMPLR AND NCOMPLR HAVE A PRIVATE OBARRAY + AS WELL AS READTABLE (CALLED COBARRAY AND CREADTABLE). + +[;] GREENBLATT (RG) HAS HACKED MIDAS SO THAT IT CAN PRODUCE + FASL FORMAT OUTPUT; THUS ONE CAN USE ALL THE MACRO + FEATURES TO PRODUCE CODE TO LOAD INTO LISP. + THE FOLLOWING IS A COPY OF AI:MIDAS;FASL > WRITTEN BY RG. + + +FASL Feature In Midas. + + Midas can now assemble FASL files that can be loaded +by LISP in the same manner as LAP FASL output. This mode is +entered by the .FASL pseudo op, which must appear at the +beginning of the file before any storage words. + After .FASL has been seen, the assembly becomes a +two pass relocatable assembly. However, certain +restrictions and "changes of interpretation" apply. + Global symbols (declared as usual with " or .GLOBAL) +are persmissible. However, since the output is to be loaded +with FASLOAD using DDT's symbol table instead of STINK, +there are quite a few differences in detail. + For symbols defined within the current assembly, the +only effect of being declared GLOBAL is that the GLOBAL +information is passed on to FASL when the symbol table is +written at the end of pass 2. This in combination with the +SYMBOLS switch in FASLOAD determines whether the symbol gets +loaded into DDT's symbol table. If SYMBOLS is NIL, no +symbols will be loaded; if SYMBOLS is EQ to SYMBOLS, only +globals will be loaded; and if SYMBOLS is T, all symbols +(local and global) will be loaded. Once the symbol is +loaded (or not), the information as to its GLOBALness is +lost and, of course, makes no further difference. The +initial state when LISP is loaded is NIL. + GLOBAL symbols not defined in the current assembly +are also legal, but there are additional restrictions as to +where in a storage word they may appear and what masking may +be specified (as compared to a normal relocatable assembly). +Briefly, they may appear as in a storage word as a full +word, a right half, a left half, or an accumulator. They may +be negated, but can not be operated on with any other +operator. Error printouts will be produced if they appear +elsewhere. When the symbol is encountered by FASLOAD, DDT's +symbol table is consulted. If it is defined at that time, +OK, otherwise FASLOAD will generate an error. + Any sort of global parameter assignment or location +assignment is Forbidden. .LOP, .LVAL1, .LVAL2, etc are not +available. + + +New Pseudo OPs Available only in FASL assemblies. + + The following pseudos are available to facilitate +the communication between MIDAS assembled programs and LISP +(particularily with regard to list structure). + +.ENTRY function type args + + Function is an atom and is taken as the name of + a function beginning at the current location. Type + should be one of SUBR, FSUBR or LSUBR, and has the + obvious interpretation. Args is a numeric-valued field + which is passed thru to FASLOAD and used to construct + the args property of the function. If it is zero, no + args property is created. Otherwise it is considered to + be a halfword divided into two 9 bit bytes, each of + which is converted as follows: + byte result + 0 nil + 777 777 + otherwise n n-1 + These two items are then CONSed and from the + args property. + +The following pseudos may appear in constants!! + +.ATOM atom + + followed by a LISP atom in "MIDAS" format (see below). + May only appear in right half (or entire word) of a + storage word. Assembles into a pointer to the atom + header of the specified atom. + +.SPECI atom + + similar to .ATOM but assembles into a pointer to the + SPECIAL value cell of the specified atom. + +.FUNCT atom + + similar to .ATOM, but invokes special action by FASLOAD + in case the PURESW is on. Normally used in function + calls. Briefly, if FASLOAD is going to purify the + function it is loading, it must "snap the links" first. + If .FUNCT is used, the location will be examined by + FASLOAD and the link snapped if possible before + purification. + Typical usage: + CALL 2,.FUNCT EQUAL ;calls equal as a function of 2 args + ; note: the CALL is not defined + ; or treated specially by MIDAS. + +.ARRAY atom + + similar to .ATOM, but assembles into a pointer to the + Array SAR. + +.SX S-expression + + similar to .ATOM, but handles a LISP S-expression. + (See below). + +.SXEVA S-expression + + reads S expression. This S expression is EVALed (for + effect presumably) at FASLOAD time. The resulting + value is thrown away. Does not form part of storage + word. + +.SXE S-expression + + Similar to .SX but list is EVALed at FASLOAD time. The + resulting value is assembled into storage word. + + +The MIDAS "LISP READER" + + By a conspiracy between MIDAS and FASLOAD, a version +of the LISP reader is available. However, due to historical +reasons (mostly, i.e. the FASLOAD format was originally +intended only to deal with COMPLR type output), there are a +number of "glitches" (see below for list). These will +probably tend to go away in the fullness of time. + +a) numeric ATOM + + The first character of a LISP atom is examined +specially. If it is a # or &, the atom is declared to be +numeric and either fixed (#) or floating (&). Midas then +proceeds to input a normal numberic field (terminated, note, +by either space or comma). This value is then "stored" in +the appropriate "space" (fixnum space or flonum space). + +b) other ATOMs (also known as PNAME atoms or (LISP) SYMBOLS) + + If the first character of the atom is not # or &, +the atom is a "PNAME" atom. / becomes a single character +quote character as in LISP. The atom may be indefinitely +long. The atom will be terminated by an unquoted space, +carrige return, tab, (, ), or semicolon. Unquoted linefeeds +are ignored and do not become part of the atom. The +character that terminates the atom is "used up" unless it is +a ( or ). Note that period is a legal constituent of a atom +and does not terminate it or act specially. + +c) lists. + + Work normally, but note following caution relative +to dot notation: . does not terminate atoms. Thus, to +invoke dot notation, the dot must be left delimited by a +space, tab, parenthesis, or other character that does +terminate atoms. + +Glitches: + + 1) Restriction on pass dependant list + structure -- In any list reading operation, no new + atoms not previously encountered may be + encountered for the first time on pass 2. + However, this restriction does not apply to + atom-only reading operations (.ATOM, .SPECI, + .FUNCT etc). + 2) Single quote for quoting does not exist (no + other macro characters exist either.) + 3) Numbers must be flagged as above always. + MOVEI A,.ATOM 123 ;LOSES - gives pointer + ; to PNAME type atom + ; with PNAME 123. it is + ; not numeric. + use: + MOVEI A,.ATOM #123 ;WINS + 4) No provision exists to reference "GLOBALSYMS" + in FASLOAD. This mostly means only that DDT must + be present to load a MIDAS assembled FASL file. + (some simple COMPLR and LAP FASL files can + successfully be FASLOADed by, for example, a + disowned LISP running without a DDT. + 5) LOC is illegal in a FASL assembly. BLOCK of a + non-relocatable quantity is ok. + 6) Currently, symbol loading is VERY slow. Thus + use SYMBOLS nil, (the initial state) unless + symbols are necessary. + 7) Midas does not know about any LISP symbols or + UUOs specially. Use them as globals until someone + gets around to fixing up a .INSRT file with the + appropriate defs. + 8) .ATOM "should" be a special case of .SX . + However, it is handled separately because of the + following "reasons": + a) The previously noted restriction on pass + dependent LISTS. + b) Midas can do constants optimization on + atoms ppearing in constants (on both pass one + and pass two) but not on LISTS. Therefore, + each list is guaranteed to take a separate + word in the constants area even if it is + identical to some other list which also + appears in a constant. + c) Each list takes an additional entry in + FASLOAD's "atom" table. This is a temporary + table that is flushed after the FASLOADing is + complete. Of course, .SX still works for + atoms modulo the above noted restrictions and + inefficencies. + +5/22/74 JONL + +Brief Synopsis: for LISP 838 and greater + +1) SUSPEND - new function, LSUBR of 0 or 1 arguments, like MACDMP, + but can continue where the computation left off, rather than + restarting at top level. +2) MUNKAM is the inverse of MAKNUM. On the PDP10 system, is pretty + much the same as CDR, except that the argument is required to be + a fixnum, and the COMPLRs will open-code MUNKAM. +3) RANDOM will accept two arguments, as a means of "seeding" it. + Also, a slight deficiency has been noted. +4) A programmable features list for (STATUS FEATURE foo), and an aid, + (SSTATUS LINMODE T), for systems with line rather than character + oriented TTY input. +5) ARRAYCALL, SUBRCALL, AND LSUBRCALL are now all FSUBRs, and + take an extra argument to aid NCOMPLR in open-coding these + applications. Disregard any previous notes on these functions, + and note well below. +6) Examples of some particularly useful lisp macros, especially for + users of ARRAYCALL, SUBRCALL, and LSUBRCALL. +7) The compiler declaration ARRAY* has been extended to allow + information about the ranges of indices. Also, NCOMPLR now uses + its own private obarray when compiling a file, in addition to its + own private readtable. + +-------------------------------------------------------------------- + +1) (SUSPEND) may be executed at any point in a computation, and + control will be returned to the LISP's superior [DDT or monitor]. + Accumulators, push-down stacks, and other variables will be saved, + and its starting address will be set so that if the job be dumped + on dsk, and reloaded at some future time, starting it again will + cause it to resume where the computation and continue just after + the call to SUSPEND. One limitation: if any input-output devices + are in use other than the TTY, SUSPEND will error with a fail-act. + (SUSPEND s), like (MACDMP s), passes the characters of the symbol + s to the superior job as a valret string. + +2) By "inverse of MAKNUM", the following is meant: + (EQ X (MUNKAM (MAKNUM X))) evaluates to T for all X. Shortly, + the MULTICS implementation will have a reasonable version of + MAKNUM and MUNKAM implemented, so that one may write a + hash-coder-on-EQ for s-expressions. Previous notes in LISP ARCHIV + have given examples on how to hash an s-expression on EQUAL. By + replacing "(\ (SXHASH X) 777))" with "(\ (MAKNUM X) 777)" one + will have a hasher on EQ. + +3) By "seeding" RANDOM, one may obtain a variety of starting points, + corresponding to the various internal states of the two-word state + register. Any two successive outputs of RANDOM will do as the + two words for a seed; for example, (SETQ X (RANDOM) Y (RANDOM)) + will preserve the current state of the random number generator + in the variables X and Y, and the state may be restored to that + state [after, possibly, further usage of RANDOM] by (RANDOM X Y). + Users of RANDOM should take note of a fact which Bill Gosper + ferreted out of Knuth - this random number genertor flunks the + 3-way serial test. That is, if triplets of "random" numbers + are generated by clumping together the + 3n, 3n+1, and 3n+2 outputs of RANDOM, then there will be an + interdependency among the triples such that half of all triples + will be missed - not particularly good for picking "random" + points in 3-space. One way out of this bind is simply + to use only every other output of RANDOM in generting the triples. + +4) As described in previous notes, there is an internal list of + "features" describing which of the various MACLISP options are + actually available in the LISP being used, and which time-sharing + system it is running under. Now the user can create his own + feature names and add, or delete, from this list at will. + (STATUS FEATURE FOO) + is non-NIL if and only if FOO is on the features list; + (SSTATUS FEATURE FOO) + will add FOO to the features list, and + (SSTATUS NOFEATURE FOO) + will delete it. + (SSTATUS LINMODE T) + tells the time-sharing system not to activate your job while + waiting for TTY input until a carriage-return is typed. For the + TOPS-10 system, it means the basic input instruction is INCHRW + instead of INCHR, and that the time-sharing system will handle + rubouts until the carriage-return is typed. Since the ITS system + does not handle rubouts under any circumstances, many users want + a mode under which the rubout handler of the MACLISP reader will + be effective on a line-by-line basis, and under which no read + reading is done until a carriage-return is typed. This can be + achieved as follows: + (SSTATUS SYNTAX 13. 501540) + ;makes an invisible force-feed char + (SSTATUS LINMODE T) + ;tells ITS to sleep until or + (SSTATUS TTYREAD T) + ;tells LISP's reader to forget about looking for + ;"balanced" s-expressions before actually gobbling + ;up characters from the TTY + It is worthwile to note here that the "force-feed" option on , + and the TTYREAD option are properties of LISP's readtable, while + the LINMODE option is a property of the LISP's relation with the + time-sharing system. + + +5) There has long been a certain ambiguity in LISP with respect to + the meaning of an atomic function. For (FOO X Y), most LISP + systems will scan the property list of FOO to see if there are + any functional properties [such as SUBR, EXPR, etc], and if so, + use the first one found as the functional-interpretation of FOO; + if none are found, then the value of FOO as a variable is picked up, + and the function-hunting process continues recursively. Some other + systems always pick up the variable value, and never resort to + storing subroutine addresses, or LAMBDA forms, as "properties" on + a property list. The function FUNCALL was implemented as a means + of directing the MACLISP evaluator first to the variable + value as function rather than starting out on the functional + properties. Thus, (FUNCALL FOO X Y) is equivalent to + (APPLY FOO (LIST X Y)). However, FUNCALL is essentially an + interpretation, and the COMPLR can not open-code the dispatch to + the function of interest unless more is known about its calling + conventions. For this reason, ARRAYCALL, LSUBRCALL, and SUBRCALL + have been implemented as FSUBRs. The general forms are + (ARRAYCALL type ap i1 . . . in) + (LSUBRCALL type lfun arg1 . . . argn) + (SUBRCALL type fun arg1 . . . argn) + type should be either "FIXNUM", "FLONUM", "T", or "NIL", depending + on the resulting type of value returned by the function [or on the + array type, in the case of ARRAYCALL. Both T-type and NIL-type + arrays may be specified by NIL here, which simply means + "s-expression" array rather than "numeric" array.]. ap should + evaluate to an array pointer such as created by *ARRAY + [(1) returned by *ARRAY if its first argument is NIL, or (2) put + on the property list of the given non-NIL symbol]. lfun should + evaluate to an LSUBR pointer, which on the PDP10 systems is obtained + only by doing (GET 'FOO 'LSUBR) for some LSUBR FOO; similarly, fun + should evaluate to a SUBR pointer. The reason the type argument is + required is that NCOMPLR can generate optimal code for these + applications. Versions of NCOMPLR greater than 454 will code these three + functions open [COMPLR will not be nearly so optimal in its codings of these + three. Neither will COMPLR actually open-code array references.]. + in the case of SUBRCALL and LSUBRCALL, the type info is mainly + an aid to NCOMPLR, and type NIL could always be used as default; + however, using type FIXNUM or FLONUM where NIL is required + will result in wrong code. For ARRAYCALL, it will be necessary + always to have the correct type info since wrong code would result + from any kind of type mismatch. + + + + EXAMPLE: suppose you have done + (SETQ BARODD (ARRAY NIL FIXNUM N) BAREVEN (ARRAY NIL FIXNUM N)) + Now at this point, both BARODD and BAREVEN hold as value an array + pointer. They would have ARRAY properties on their property list + if, for example, (ARRAY BARODD FIXNUM N) had been done instead. + Then the following will fill BARODD with the first N odd integers, + and BAREVEN with the first N even integers: + (DO I 1 (1+ I) (> I (* 2 N)) + (STORE (ARRAYCALL FIXNUM + (COND ((ODDP I) BARODD) (BAREVEN)) + (/ (1- I) 2)) + I)) + + +6) EXAMPLE USING MACROS FOR SIMPLIFIED SYNTAX: + Assuming BARODD and BAREVEN as above [that is, variables that + have been set to some array pointer], let us define two macros + (DEFUN MACRO BO (X) + (SUBST (CADR X) 'INDEX '(ARRAYCALL FIXNUM BARODD INDEX))) + (DEFUN MACRO BE (X) + (SUBST (CADR X) 'INDEX '(ARRAYCALL FIXNUM BAREVEN INDEX))) + Then we could fill BARODD and BAREVEN as follows: + (DO J 1 (1+ J) (> J N) (STORE (BE (1- J)) (* 2 J))) + (DO J 0 (1+ J) (NOT (< J N)) (STORE (BO J) (1+ (* 2 J)))) + Admittedly, this saves a lot of typing. But suppose you have a + host of such array variables that you would like to abbreviate + with such a MACRO. Typing in all the macro definitions could be + tediously repetitive. Consider the following macro-defining macro, + and some of its uses: + (DEFUN MACRO ABBA (Y) + (SUBLIS (LIST (CONS 'SHORT (CADR Y)) + (CONS 'LONG (CADDR Y)) + (CONS 'TYPE (CADDR Y))) + '(DEFUN MACRO SHORT (X) + (SUBST (CDR X) + 'INDEXLIST + '(ARRAYCALL TYPE LONG . INDEXLIST))))) + Now we might use ABBA to produce the macro for BE, but note that + the form of the macro is slightly different - the main body of the + macro output appears to be a dotted-list rather than a standard + list. This is so that arrays of varying numbers of dimensions may + have their abbreviations defined by the same super-macro. + (ABBA BO BARODD FIXNUM) + expands into + (DEFUN MACRO BO (X) + (SUBST (CDR X) + 'INDEXLIST + '(ARRAYCALL FIXNUM BARODD . INDEXLIST))) + which then causes the appropriate macro definition for BO. As + you would expect, then, (BO J) expands into + (ARRYACALL FIXNUM BARODD J) + But consider the two-dimensional hash array HASH defined as + (SETQ HASH (ARRAY NIL T 37 37)) + Then (ABBA HA HASH T) defines HA so that (HA 3 (+ N 2)) expands + into (ARRAYCALL T HASH 3 (+ N 2)) + + + Guy Steele has accumulated a file of sophisticated macros and + macro-defining macros, and the interested may consult with him + about them. + + +7) In order to get maximal speed from open-compiled array references, + you may inform NCOMPLR of the actual ranges of the array + indices. Thus a two-dimensional array of FIXNUMS, size 3 by 4, + could be declared by: + (ARRAY* (FIXNUM (CIR 3 4))) + Even partial information will be useful; a NIL or ? in index + positions will indicate that no information is available about that + particular dimension. For example, to add to the above declaration + that for a two-dimensional array in which only the column dimension + is known in advance, one could say: + (ARRAY* (FIXNUM (CORL ? 4) (CIR 3 4))) + The previous syntax for ARRAY* is still available, and one + should note that the following two forms both convey the same + information: + (ARRAY* (NOTYPE DXA 1 CIR 2)) + (ARRAY* (NOTYPE (DXA NIL) (CIR ? ?))) + + Also, NCOMPLR now uses its own private obarray when compiling a + file, in addition to its own private readtable; they are contained, + respectively, in the two global variables COBARRAY and CREADTABLE. + If you have the practice of escaping to top-level LISP, and + loading in some of your own functions, be sure to do this stuff + under the correct obarray and readtable. E.G., you might do + ((LAMBDA (OBARRAY READTABLE) + (FASLOAD MY FUNS DSK LOSER)) + COBARRAY CREADTABLE) + TUESDAY APRIL 23,1974 NM+2D.8H.36M.6S. LISP 810 - GLS - + +BRIEF SYNOPSIS: +[1] NEW FUNCTION: GETCHARN +[2] ALARMCLOCK AND TTY INTERRUPTS ARE RUN WITH (NOINTERRUPT T) +[3] NEW ARRAY SCHEME +[4] NEW FUNCTIONS: SUBRCALL, LSUBRCALL, ARRAYCALL +[5] UUO'S CHANGED: LER2,LER4 GONE; LER3 MOVED; ACALL,AJCALL NEW +[6] HH$X SLIGHTLY IMPROVED +---------------------------------------------------------------- +[1] NEW FUNCTION: GETCHARN IS LIKE GETCHAR, BUT RETURNS A + NUMBER INSTEAD OF A SINGLE CHARACTER OBJECT. IT IS + TO GETCHAR AS EXPLODEN IS TO EXPLODEC, AND IS SIMILAR IN ACTION + TO (LAMBDA (X) (CAR (EXPLODEN X))). EXAMPLES: + (GETCHARN 'FOOBAR 1) => 106 ;OCTAL + (GETCHARN 'FOOBAR 4) => 102 + (GETCHARN 'FOOBAR -1) => 0 + (GETCHARN 'FOOBAR 77) => 0 + +[2] WHEN AN ALARMCLOCK OR TTY INTERRUPT HAPPENS, THE NOINTERRUPT + FLAG IS SAVED, (NOINTERRUPT T) IS PERFORMED, THE USER'S SERVICE + FUNCTION IS EXECUTED, AND THE NOINTERRUPT FLAG IS RESTORED AFTER + EXECUTION. [THE FLAG MIGHT CONCEIVABLY BE ON IF (IOC ) WERE + USED TO INITIATE THE INTERRUPT - NOINTERRUPT ONLY LOCKS OUT + REAL-TIME EVENTS.] THUS, AN ALARMCLOCK HANDLER, FOR EXAMPLE, + WONT BE ABORTED BY A RANDOM ^G BEFORE IT HAS HAD A CHANCE TO + RESTART THE CLOCK. + +[3] THE NEW ARRAY SCHEME IS WORKING WELL NOW FROM THE INTERPRETER + SIDE; THE NCOMPLR WILL KNOW ABOUT IT WHEN THE NEXT VERSION + IS AVAILABLE, AND COMPLR WILL FOLLOW SUIT SHORTLY THEREAFTER. + THE LISP NEW-ARRAY SCHEME COMPRISES MANY CHANGES TO THE + ARRAY PACKAGE, MOST OF WHICH ARE EXTENSIONS; THERE + ARE FEW INCOMPATIBILITIES. THE MOST IMPORTANT EXTENSION IS + THE ADDITION OF TWO NEW TYPES OF ARRAYS: FIXNUM AND FLONUM. + THESE TYPES OF ARRAYS STORE THEIR ELEMENTS AS 36-BIT WORDS + RATHER THAN AS 18-BIT POINTERS, THUS SAVING SPACE AND TIME. + SHORTLY, BOTH COMPLR AND NCOMPLR WILL PRODUCE CODE FOR ARRAYS + THAT WILL OPEN-ACCESS BOTH STANDARD AND FULLWORD ARRAYS ALMOST + AS FAST AS FORTRAN-COMPILED CODE DOES. + ONE SOMEWHAT DRASTIC CHANGE: NSTORE WILL GO AWAY, SINCE + FIXNUM ARRAYS CAN BE USED WHERE AN ARRAY OF NUMBERS IS DESIRED. + FUNCTIONS SUCH AS LOADARRAYS AND DISGORGE WILL BE MODIFIED TO + USE FIXNUM ARRAYS RATHER THAN S-EXPRESSION-WITHOUT-GC-PROTECTION + ARRAYS. IT IS POSSIBLE THAT SOMETIME IN THE FUTURE THERE MAY BE + OTHER VERSIONS OF THE FIXNUM-ARRAY IDEA, IN WHICH THE USER + SPECIFIES THE NUMBER OF BITS FOR EACH ENTRY; THUS AN ARRAY + OF 1-BIT BYTES COULD EFFECT A SAVINGS OF A FACTOR OF 36. BUT + THIS IS ONLY A POSSIBILITY FOR THE FUTURE. OTHER CHANGES AND + EXTENSIONS ARE DESCRIBED BELOW ON A FUNCTION-BY-FUNCTION BASIS: + +(*ARRAY ... ) ;LSUBR (2 . 7) + + CREATES AN N-DIMENSIONAL ARRAY. SPECIFIES THE TYPE + OF THE ARRAY TO BE CREATED: + + T S-EXPRESSION (AS BEFORE) + NIL S-EXPRESSION (BUT NO GC PROTECTION) + FIXNUM CONTAINS FIXNUMS AS 36-BIT WORDS + FLONUM CONTAINS FLONUMS AS 36-BIT WORDS + OBARRAY OBARRAY + READTABLE READTABLE + + IF IS NIL, THEN AN ARRAY OF THE SPECIFIED TYPE, + DIMENSIONALITY, AND SIZE IS CREATED, AND A FRESH ARRAY + POINTER IS CONSED UP AND RETURNED; THE LATTER IS AN + OBJECT WHICH POINTS TO THE BODY OF THE ARRAY. + TYPEP OF SUCH AN OBJECT RETURNS "ARRAY". SUCH OBJECTS + ARE ALSO THE RESULT OF SAYING (GET 'FOO 'ARRAY), AND + ARE THE VALUE OF ATOMIC SYMBOLS LIKE OBARRAY AND READTABLE. + ARRAY POINTERS MAY BE GIVEN TO APPLY AND FUNCALL; THUS + (READTABLE 10) IS THE 10'TH ENTRY OF THE INITIAL READTABLE, + THAT IS, OF THE ARRAY UNDER READTABLE'S ARRAY PROPERTY; BUT + (FUNCALL READTABLE 10) IS THE 10'TH ENTRY OF THE CURRENT + READTABLE, THAT IS, THE ARRAY POINTER WHICH IS THE VALUE + OF THE VARIABLE "READTABLE". IN GENERAL, ARRAY POINTERS + MAY BE USED IN ALMOST ANY PLACE (ALMOST!) THAT AN ATOMIC + SYMBOL WITH AN ARRAY PROPERTY MAY BE USED. THERE IS A PLACE + WHERE ARRAY POINTERS MUST BE USED IN PREFERENCE TO ATOMIC + SYMBOLS WITH ARRAY PROPERTIES: SEE THE NEW "ARRAYCALL" + FUNCTION BELOW. IN GENERAL, THE USER CANNOT MANIPULATE + ARRAYS DIRECTLY, BUT ONLY THROUGH ARRAY POINTERS; THIS + IS BECAUSE ARRAYS MAY BE RELOCATED WITHOUT WARNING BY + THE GARBAGE COLLECTOR. FURTHERMORE, NO TWO NON-EQ ARRAY + POINTERS CAN EVER POINT TO THE SAME ARRAY. + IF IS NON-NIL, THEN IT MUST BE EITHER AN ARRAY + POINTER OR AN ATOMIC SYMBOL. IF IT IS A SYMBOL, AND THE + SYMBOL HAS NO ARRAY PROPERTY, IT IS GIVEN ONE (A FRESH + ARRAY POINTER IS CONSED UP FOR THIS PURPOSE). IF + IS AN ARRAY POINTER, OR A SYMBOL WITH AN ARRAY PROPERTY, + THEN ANY ARRAY CURRENTLY POINTED TO BY THAT POINTER IS + KILLED. IN ANY CASE THE ARRAY POINTER IS THEN MADE TO + POINT TO THE NEWLY CREATED ARRAY. + AN ARRAY MAY BE UP TO FIVE-DIMENSIONAL (FORMERLY ONLY FOUR + DIMENSIONS WERE ALLOWED). IF IS SPECIFIED AS JX, + THEN THE X'TH SUBSCRIPT VARIES FROM 0 TO JX-1, AS BEFORE. + AN ARRAY IS EFFECTIVELY A FUNCTION; THUS IF FOO HAS AN + ARRAY PROPERTY, THEN (FOO 1 3) RETURNS ELEMENT [1,3] OF THE + ARRAY FOO (WHICH BETTER BE TWO-DIMENSIONAL!) + WHEN A NEW ARRAY IS CREATED, ITS ENTRIES ARE INITIALIZED TO + NIL FOR ARRAYS OF TYPE "T" OR "NIL", TO 0 FOR FIXNUM ARRAYS, + OR TO 0.0 FOR FLONUM ARRAYS. TO INITIALIZE AN ARRAY TO OTHER + VALUES, SEE THE FUNCTIONS *REARRAY, BLTARRAY, AND FILLARRAY + BELOW. + IF IS OBARRAY OR READTABLE, THEN THE EXTRA ARGUMENTS + HAVE A SLIGHTLY DIFFERENT SIGNIFICANCE. ONLY TWO OR THREE + ARGUMENTS IN ALL MAY BE GIVEN; THE THIRD, IF PRESENT, TELLS + HOW TO INITIALIZE THE OBARRAY OR READTABLE. + FOR AN OBARRAY, A THIRD ARGUMENT OF NIL MEANS THAT THE NEW + OBARRAY SHOULD BE LEFT COMPLETELY EMPTY. A THIRD ARGUMENT + OF T MEANS THAT THE NEW ARGUMENT SHOULD BE INITIALIZED FROM + THE CURRENT OBARRAY (THAT IS, FROM WHATEVER ARRAY POINTER IS + THE CURRENT VALUE OF THE VARIABLE "OBARRAY"). ANY OTHER + THIRD ARGUMENT MUST BE AN ARRAY OF TYPE OBARRAY FROM WHICH + TO INITIALIZE THE NEW OBARRAY. OMITTING THE THIRD ARGUMENT + IS THE SAME AS SAYING T. NOTE THAT WHEN ONE OBARRAY IS + INITIALIZED FROM ANOTHER, THE BUCKETS ARE COPIED, BUT + THE ATOMIC SYMBOLS ARE NOT COPIED. + FOR A READTABLE, A THIRD ARGUMENT OF NIL MEANS THAT THE NEW + READTABLE SHOULD BE INITIALIZED FROM THE CURRENT READTABLE. + A THIRD ARGUMENT OF T MEANS TO INITIALIZE FROM THE SYSTEM'S + INITIAL READTABLE. ANY OTHER THIRD ARGUMENT MUST BE A + READTABLE TO INITIALIZE FROM. (IT MAKES NO SENSE TO HAVE AN + "EMPTY" READTABLE AS IT DOES FOR AN OBARRAY). OMITTING THE + THIRD ARGUMENT IS THE SAME AS SAYING NIL. + + EXAMPLES: + (*ARRAY 'FOO 'FIXNUM 3 4 5) ;FOO GETS AN ARRAY + ; PROPERTY FOR A + ; 3X4X5 ARRAY OF FIXNUMS + (*ARRAY NIL T 4 4) ;RETURNS ARRAY POINTER + ; FOR A 4X4 ARRAY OF + ; ARBITRARY S-EXPRESSIONS + (*ARRAY 'QUUX 'READTABLE) ;QUUX IS GIVEN AN ARRAY + ; PROPERTY FOR A + ; READTABLE, INITIALIZED + ; FROM CURRENT ONE + +(ARRAY < ... ) ;FSUBR + + ARRAY IS THE SAME AS *ARRAY, EXCEPT THAT THE FIRST TWO + ARGUMENTS ARE NOT EVALUATED. THUS THE EXAMPLES ABOVE COULD + HAVE BEEN WRITTEN: + (ARRAY FOO FIXNUM 3 4 5) + (ARRAY NIL T 4 4) + (ARRAY QUUX READTABLE) + +(STORE ) ;FSUBR + + THIS WORKS AS BEFORE: IT STORES THE GIVEN VALUE IN THE + SPECIFIED ARRAY ELEMENT. IF IS A CALL TO + A FIXNUM OR FLONUM ARRAY, THEN SHOULD BE A FIXNUM + OR FLONUM, RESPECTIVELY. RECALL THAT STORE EVALUATES ITS + SECOND ARGUMENT BEFORE THE FIRST ARGUMENT; THUS + (SETQ J 3) + (STORE (FOOARRAY (SETQ J 5)) J) + WILL STORE 3, NOT 5, IN ELEMENT 5 OF FOOARRAY. ONE SHOULD AVOID + DEPENDING ON THIS FACT, HOWEVER, IN THE INTERESTS OF CLARITY. + SEE ALSO THE DESCRIPTION OF THE NEW "ARRAYCALL" FUNCTION BELOW. + +(ARRAYDIMS ) ;SUBR 1 + + THIS FUNCTION WORKS AS BEFORE, BUT CAN RETURN A BROADER + RANGE OF VALUES. IT RETURNS A LIST, SUCH THAT THE CAR + OF THE LIST IS THE TYPE OF THE ARRAY (I.E., T, NIL, + FIXNUM, FLONUM, OBARRAY, OR READTABLE), AND THE CDR IS + A LIST OF ARRAY DIMENSIONS. THUS: + (ARRAY QUUX FIXNUM 3 4 5) + (ARRAYDIMS 'QUUX) => (FIXNUM 3 4 5) + (ARRAYDIMS (GET 'QUUX 'ARRAY)) => (FIXNUM 3 4 5) + (ARRAY ZORCH OBARRAY) + (ARRAYDIMS 'ZORCH) => (OBARRAY 777) + WHERE 777 HAPPENS TO BE THE SIZE OF AN OBARRAY ON THIS + GIVEN LISP SYSTEM (THIS VARIES FROM ONE LISP TO ANOTHER). + NOTE THAT ARRAYDIMS RETURNS SLIGHTLY DIFFERENT VALUES FOR + READTABLES AND OBARRAYS THAN IT USED TO. + +(*REARRAY ... ) ;LSUBR (1 . 7) + + THIS FUNCTION WORKS PRETTY MUCH AS BEFORE. + IF IT IS GIVEN ONLY ONE ARGUMENT (*REARRAY FOO), THEN FOO + MAY BE AN ARRAY POINTER OR AN ATOMIC SYMBOL. IF IT IS AN + ATOMIC SYMBOL WITH NO ARRAY PROPERTY, IT MERELY RETURNS. + OTHERWISE IT KILLS THE ARRAY POINTED TO BY THE ARRAY POINTER + (THE ONE GIVEN, OR THE ONE OBTAINED FROM THE SYMBOL'S + PROPERTY LIST). THE ARRAY POINTER IS NOW "DEAD", AND CANNOT + BE USED AS A FUNCTION UNLESS AND UNTIL IT IS GIVEN A NEW + ARRAY TO POINT TO. + IF MORE THAN ONE ARGUMENT IS GIVEN TO *REARRAY, THEN THEY + SHOULD BE ARGUMENTS SIMILAR TO THOSE FOR *ARRAY, EXCEPT THAT + THE FIRST ARGUMENT MUST ALREADY BE A LIVE ARRAY, EITHER AS + AN ARRAY POINTER OR AS A SYMBOL WITH A LIVE ARRAY PROPERTY. + *REARRAY EFFECTIVELY CREATES A NEW ARRAY OF THE SPECIFIED + DIMENSIONS AND BLTARRAY'S DATA FROM THE GIVEN ARRAY INTO THE + NEW, THEN ALTERS THE ARRAY POINTER TO POINT TO THE NEW ARRAY. + *REARRAY WILL NOT PERMIT YOU TO ALTER THE TYPE OF THE ARRAY + AT PRESENT - YOU MUST SPECIFY THE CORRECT TYPE. IT IS RATHER + MEANINGLESS TO USE *REARRAY OF MORE THAN ONE ARGUMENT ON A + READTABLE OR OBARRAY. + +(BLTARRAY ) ;SUBR 2 + + BLTARRAY, AS BEFORE, COPIES THE DATA IN INTO + . IF IS SHORTER, THEN EXTRA DATA IN + IS UNHARMED, MORE OR LESS. IF IS + SHORTER, THEN AS MUCH DATA AS WILL FIT IS COPIED. + BLTARRAY INSISTS ON GETTING TWO ARRAYS OF THE SAME TYPE; + IT WILL NOT COPY A FIXNUM ARRAY INTO A FLONUM ARRAY, AN + S-EXPRESSION ARRAY, OR A READTABLE. + IF ONE OBARRAY IS COPIED INTO ANOTHER, THE BUCKETS ARE + COPIED AS WELL, AS IF FOR *ARRAY. + +(LISTARRAY ) ;SUBR 1 + + LISTARRAY NOW WORKS ON ARRAYS OF ALL TYPES AND ALL + DIMENSIONS. IT RETURNS A LIST OF ALL THE DATA IN THE + GIVEN ARRAY. IF A MULTI-DIMENSIONAL ARRAY IS GIVEN, + THE DATA IS TAKEN IN ROW-MAJOR ORDER; FOR EXAMPLE: + (ARRAY FOO FIXNUM 2 2) + (LISTARRAY 'FOO) + RETURNS FOO[0,0] FOO[0,1] FOO[1,0] FOO[1,1] AS A LIST + IN THAT ORDER. + +(FILLARRAY ) ;SUBR 2 + + FILLARRAY IS AN INVERSE TO LISTARRAY, EXCEPT THAT IT + IS NOT PERMITTED TO USE FILLARRAY ON READTABLES OR + OBARRAYS. IT DISTRIBUTES THE GIVEN LIST OF ITEMS + INTO THE GIVEN ARRAY IN ROW-MAJOR ORDER. IF A FIXNUM + OR FLONUM ARRAY IS SUPPLIED, THEN THE ELEMENTS OF THE + LIST MUST ALL BE FIXNUMS OR FLONUMS, RESPECTIVELY. + IF THERE ARE TOO MANY ITEMS IN THE LIST, THE EXTRA ONES + ARE IGNORED; IF THERE ARE NOT ENOUGH, THEN THE LAST ONE + IS USED TO FILL OUT THE ARRAY. THUS + (FILLARRAY 'FOO '(43 11 27)) ;RANDOM NUMBERS + FILLS FOO, AS DEFINED ABOVE, SUCH THAT + FOO[0,0] = 43 + FOO[0,1] = 11 + FOO[1,0] = 27 + FOO[1,1] = 27 + +(MAKOBLIST ) ;SUBR 1 + + THIS FUNCTION WORKS AS BEFORE. NOTE THE FOLLOWING + EQUIVALENCES IN THE NEW ARRAY SCHEME: + (MAKOBLIST NIL) <=> (LISTARRAY OBARRAY) + (MAKOBLIST X) <=> (*ARRAY X 'OBARRAY) + FOR X NOT NIL. + +(MAKREADTABLE ) ;SUBR 1 + + THIS FUNCTION WORKS AS BEFORE. NOTE THE FOLLOWING + EQUIVALENCES IN THE NEW ARRAY SCHEME: + (MAKREADTABLE NIL) <=> (*ARRAY (GENSYM) 'READTABLE) + (MAKREADTABLE T) <=> (*ARRAY (GENSYM) 'READTABLE T) + (MAKREADTABLE X) <=> (*ARRAY X 'READTABLE) + FOR X NOT NIL OR T. + +(ARRAYCALL ... ) ;LSUBR (2 . 6) + + [SEE ALSO ITEM [4] BELOW.] + ARRAYCALL IS SIMILAR TO FUNCALL, BUT INSISTS THAT ITS SECOND + ARGUMENT BE AN ARRAY POINTER (AN ATOMIC SYMBOL WITH AN ARRAY + PROPERTY IS NOT ACCEPTABLE IN THIS CONTEXT!) ITS FIRST ARGUMENT + SHOULD MATCH THE TYPE INFORMATION OF THE ARRAY - EITHER FIXNUM, + FLONUM, NIL, OR T. + + ITS PRIME VIRTUE IS THAT IT PERMITS THE COMPILER TO OPEN-CODE + ACCESS TO VARIABLE ARRAYS. ONE MAY ALSO WRITE + (STORE (ARRAYCALL TYPE VAR X1 ... XN) VAL) + AND HAVE IT COMPILE EFFICIENTLY. EXAMPLE OF USE: + (DEFUN TRANSPOSE (A) + (PROG (ARY TYP) + (COND ((EQ (SETQ TYP (TYPEP A)) 'ARRAY) + (SETQ ARY A)) + ((AND (EQ TYP 'SYMBOL) + (SETQ ARY (GET A 'ARRAY)))) + (T (RETURN + (TRANSPOSE + (ERROR 'NON-ARRAY/ -/ TRANSPOSE + A 'WRNG-TYPE-ARG))))) + (OR (AND (= (LENGTH (SETQ TYP + (ARRAYDIMS ARY))) + 3) + (= (CADR TYP) (CADDR TYP))) + (RETURN + (TRANSPOSE + (ERROR 'NOT/ 2-DIM/ SQUARE/ -/ TRANSPOSE + A 'WRNG-TYPE-ARG)))) + (DO ((N) (I 1 (1+ I))) + ((= I (CADR TYP))) + (DO ((J 1 (1+ J))) + ((= J I)) + (SETQ N (ARRAYCALL (CAR TYP) ARY I J)) + (STORE (ARRAYCALL (CAR TYP) ARY I J) + (ARRAYCALL (CAR TYP) ARY J I)) + (STORE (ARRAYCALL (CAR TYP) ARY J I) N))) + (RETURN A))) + ANOTHER VARIATION WOULD BE TO LIMIT TRANSPOSE TO FIXNUM ARRAYS. + THE EACH OF THE FOUR USAGES OF ARRAYCALL WOULD BE LIKE + (ARRAYCALL 'FIXNUM ARY . . .), AND THE NCOMPLR WOULD BE ABLE + TO MAKE OPEN-CODED REFERENCES TO THE ARRAY. + +PRIN1, PRINC, EXPLODEC, ETC. + + THE PRINT FUNCTIONS AND OTHER RELATED FUNCTIONS PRINT ARRAY + POINTERS IN THE FOLLOWING MANNER: IF THE ARRAY POINTER IS + DEAD (POINTS TO NO LIVE ARRAY), IT PRINTS AS "#DEAD-ARRAY". + OTHERWISE IT PRINTS AS "#", THE TYPE OF ARRAY, "-", THE + DIMENSIONS OF THE ARRAY SEPARATED BY ":" IN THE CURRENT + RADIX, "-", AND THE ADDRESS OF THE ARRAY POINTER IN OCTAL. + THUS PRINTING AN ARRAY POINTER LETS YOU SEE THE SAME + INFORMATION RETURNED BY ARRAYDIMS. EXAMPLES: +USER: (ARRAY NIL OBARRAY) +LISP: #OBARRAY-777-103426 +U: (ARRAY NIL FIXNUM 4 5 6) +L: #FIXNUM-4:5:6-103424 +U: (ARRAY FOO T 3 5 2 4 3) +L: FOO +U: (GET 'FOO 'ARRAY) +L: #T-3:5:2:4:3-102362 + +[4] THREE NEW FUNCTIONS: SUBRCALL, LSUBRCALL, ARRAYCALL. + (ARRAYCALL IS ALSO THORUGHLY DESCRIBED IN ITEM [3].) + THESE ARE ANALOGOUS TO FUNCALL, IN THAT THEY TAKE + A "FUNCTION" SPECIFICATION AS THE FIRST ARGUMENT AND + AND ARGUMENTS FOR THAT FUNCTION AS THE REST OF THE + ARGUMENTS. THE DIFFERENCE IS THAT THE SECOND ARGUMENT + TO CALL (FOR AMONG [SUBR, LSUBR, ARRAY]) + SHOULD BE THE KIND OF ITEM YOU WOULD OBTAIN BY SAYING + (GET 'QUUX ') FOR SOME ATOMIC SYMBOL QUUX. + THUS: + (SUBRCALL NIL (GET 'CAR 'SUBR) '(A . B)) => A + YOU USE THESE AT YOUR OWN RISK, OF COURSE; THE INTERPRETER + CAN'T CHECK EVERYTHING. SOON THE COMPILER WILL OPEN-CODE + THESE GUYS SUPER-EFFICIENTLY. + HERE IS AN INTERESTING HACK: + + (SETQ SUBRDISPATCH (ARRAY NIL T 40)) ;40=RANDOM SIZE + + (DO ((I 0 (1+ I)) + (X '(CAR CDR CADR REVERSE EXPLODE ...) (CDR X))) + ((NULL X)) + (STORE (ARRAYCALL T SUBRDISPATCH I) + (GET (CAR X) 'SUBR))) + + (SUBRCALL NIL (ARRAYCALL T SUBRDISPATCH 3) '(A B C)) => (C B A) + + (SUBRCALL NIL (ARRAYCALL T SUBRDISPATCH 1) '(A B C)) => B + + AND SO FORTH AND SO ON. THAT IS, YOU CAN HAVE AN ARRAY + OF DISPATCH ADDRESSES. AGAIN, BE CAREFUL! + +[5] FOR MACHINE LANGUAGE HACKERS ONLY: + PDP-10 LISP'S UUO'S HAVE BEEN REARRANGED. LER2 AND LER4 + HAVE BEEN FLUSHED. LER3'S OPCODE HAS BEEN ALTERED. + TWO NEW UUO'S: ACALL AND AJCALL. THE EFFECTIVE ADDRESS + OF ACALL MUST AN ARRAY POINTER, WHICH SHOULD HAVE ITS + COMPILED-CODE-NEEDS-ME BIT TURNED ON. ACALL SERVES + AS AN NCALL TO AN ARRAY (ONE CAN'T INCREMENT THE + EFFECTIVE ADDRESS OF AN NCALL TO AN ARRAY BECAUSE IT + IS INDIRECT). THE UUO HANDLER THUS SMASHES NCALL'S TO + ARRAYS TO BE ACALL'S INSTEAD OF PUSHJ'S, AND SIMILARLY + NJCALL'S TO BE AJCALL'S. IN MOST PRACTICAL CASES THIS + WILL NOT BE NECESSARY, SINCE THE COMPILER HOPEFULLY + CAN OPEN-CODE MOST ARRAY ACCESSES ANYWAY. + THE GETMIDASOP FUNCTION HAS BEEN UPDATED TO REFLECT + THESE ALTERED OP-CODES. + +[6] HH$X TRIES NOT TO SIGNAL A ^H INTERRUPT IF IT THINKS THAT THE + INTERRUPT WILL BE STACKED IN THE INTERRUPT QUEUE RATHER THAN + RUN IMMEDIATELY. IT WILL SIMPLY RETURN TO DDT IN THIS CASE. + FRIDAY MARCH 01,1974 FQ+18H.38M.31S. LISP 767 - GLS - + +[1] NEGATIVE RUNTIMES +[2] ERRFRAME CHANGE +[3] FUNCALL PUSHES APPLY FRAMES +[4] NEW FUNCTION: NRECONC +[5] PRINT, PRIN1, PRINC CHECK I/O FLAGS - AFFECTS ABBREVIATION +[6] (STATUS UREAD) IS NOW CONSISTENT ABOUT LINKS +[7] SOME CHANGES TO ARRAY STUFF (PREPARING FOR NEW ARRAYS) + [7A] TYPEP MAY RETURN ARRAY + [7B] BIBOP SAR SPACE NOW CALLED ARRAY SPACE + [7C] IN BOTH LISPS, ALLOC SAYS "ARRAY=" +[8] REVIEW OF P.$X AND FRIENDS +---------------------------------------------------------------- +[1] IT HAS BEEN OBSERVED THAT OCCASIONALLY RUNTIMES WILL BE + MEASURED AS BEING NEGATIVE. THIS IS APPARENTLY AN ITS BUG + HAVING SOMETHING TO DO WITH REQUESTING CORE MANAGEMENT, + SO IT HAPPENS MORE IN BIBOP LISP THAN IN NON-BIBOP. I'VE + TAKEN SOME COMPENSATIVE ACTIONS, BUT BE FOREWARNED AND BEWARE. + +[2] CHANGE TO ERRFRAMES: FOR COMPATIBILITY WITH EVALFRAMES, + ERRFRAMES ARE NOW OF THE FORM + + (ERR ) + + I.E. THE ATOM "ERR" IS NOW CONSED ON THE FRONT, JUST + AS "EVAL" OR "APPLY" IS CONSED ONTO AN EVALFRAME. + +[3] SPEAKING OF EVALFRAMES: FUNCALL CREATES SUCH A FRAME + OF THE APPLY VARIETY THESE DAYS. + +[4] (NRECONC X Y) <=> (NCONC (NREVERSE X) Y) + BUT IS FASTER, BECAUSE IT DOESN'T HAVE TO SCAN BACK + DOWN THE LIST JUST NREVERSED TO DO THE NCONC. + +[5] PRINT, PRIN1, AND PRINC CHECK ALL THEOUTPUT FLAGS + (^W, ^R, ^B, ^N) BEFORE COMMENCING PRINTOUT. + IF THE FLAGS ALL INDICATE NO OUTPUT, THEY RETURN + IMMEDIATELY, THUS SAVING MUCH TIME. + FURTHERMORE, IF OUTPUT IS GOING TO THE TTY AND + NOWHERE ELSE, AND YOU ARE USING PRINLEVEL AND PRINLENGTH + TO GET ABBREVIATED FORMS OUTPUT, THEN ONLY THE + ABBREVIATED FORMS ARE GENERATED. THIS MEANS THAT + TYPING ^R IN THE MIDDLE OF SUCH A PRINTOUT MAY + CAUSE A FILE TO RECEIVE (THE TAIL END OF) AN + ABBREVIATED FORM, EVEN IF (STATUS ABBREVIATE) + REQUESTS OTHERWISE. ON THE OTHER HAND, THIS HACK + PREVENTS CERTAIN SCREWS INVOLVING CIRCULAR LISTS. + +[6] IF DSK:LOSER;FOO BAR IS A LINK TO DSK:CLOD;ZORCH QUUX + AND YOU DO (UREAD FOO BAR DSK LOSER), THEN (STATUS UREAD) + WILL RETURN (ZORCH QUUX DSK CLOD) AND NOT + (ZORCH QUUX DSK LOSER) AS IT USED TO. + +[7] SOME NEW STUFF HAS BEEN INSTALLED IN THIS LISP + IN ANTICIPATION OF THE NEW FAST ARRAY SCHEME. + A NEW KIND OF SPACE HAS BEEN IMPLEMENTED IN + NON-BIBOP LISP, ANALOGOUS TO BIBOP LISP'S + FORMER "SAR" SPACE, WHICH HOLDS OBJECTS CALLED + ARRAY POINTERS. + + [7A] SUCH OBJECTS ARE OF TYPE "ARRAY". TYPEP + WILL RETURN "ARRAY" FOR SUCH AN OBJECT. + + [7B] BIBOP'S SAR SPACE IS NOW CALLED ARRAY SPACE, + FOR INDEED THEY ARE THE SAME OBJECTS. + THUS YOU MUST NOW SAY (ALLOC '(ARRAY 300)) + INSTEAD OF (ALLOC '(SAR 300)), ETC. + + [7C] THE INITIAL ALLOC WILL ASK YOU "ARRAY=". + ARRAY POINTERS ARE TWO WORDS, SO IF YOU SAY + 100., YOU HAVE ALLOCATED ROOM FOR 50. ARRAY + POINTERS. + + OTHERWISE ALL THE ARRAY STUFF SHOULD WORK THE SAME AS + BEFORE; BUT WATCH FOR THE NEW ARRAY SCHEME! + +[8] FOR PEOPLE WHO USE DDT TO DEBUG LISP CODE (I.E. + SUPER-HACKERS), HERE IS A REVIEW OF P.$X AND FRIENDS: + + P.$X AND RELATED GOODIES ARE NAMED INSTRUCTIONS WHICH + YOU CAN EXECUTE FROM DDT WITH THE $X COMMAND WHICH DO + ALL KINDS OF NICE THINGS FOR YOU. THEY AVOID CLOBBERING + ANYTHING WITHIN THE LISP, E.G. THEY SAVE AND RESTORE + ANY ACCUMULATORS AND/OR TEMPORARIES THEY USE, + AND ARE CIRCUMSPECT ABOUT I/O SWITCHES. + + REFERENCES TO "THE LEFT HALF OF ." OR "THE RIGHT HALF + OF ." MEANS THAT THE LEFT OR RIGHT HALF OF DDT'S + CURRENTLY OPEN LOCATION IS UNDER CONSIDERATION. $=ALTMODE. + + P.$X ASSUMES THE RIGHT HALF OF . TO BE AN + S-EXPRESION, AND PRINTS IT. + PL.$X PRINTS THE LEFT HALF OF . AS AN S-EXPRESSION. + PP Z$X WHERE Z IS SOME QUANTITY, PRINTS THAT QUANTITY + AS IF IT WERE A POINTER, AS AN S-EXPRESSION. + (PP IS A UUO, AND Z IS ITS EFFECTIVE ADDRESS. + SINCE PP IS A UUO, A FEW TEMPORARIES USED BY THE + UUO HANDLER GET CLOBBERED; THUS BEWARE OF USING + IT IF YOU MAY HAVE BROKEN OUT OF THE UUO + HANDLER TO DDT.) + VC.$X ASSUMES THAT THE RIGHT HALF OF . POINTS TO + A VALUE CELL, AND RUNS OVER THE OBARRAY TRYING + TO FIND AN ATOM WITH THAT VALUE CELL. PRINTS + THE ATOM IF IT FINDS ONE, OTHERWISE PRINTS ?. + VCL.$X ASSUMES LEFT HALF OF . POINTS TO A VALUE CELL, + AND BEHAVES LIKE VC.$X. NOTE THAT THIS IS + PARTICULARLY GOOD FOR EXAMINING SPECIAL PDL + ENTRIES, WHICH HAVE VALUE CELL POINTERS IN THE + LEFT HALF, AND OLD VALUES ON THE RIGHT HALF. + SB.$X ASSUMES THAT THE RIGHT HALF OF . POINTS + SOMEWHERE INTO THE MIDDLE OF A SUBR, AND RUNS + OVER THE OBARRAY TRYING TO FIND THE NAME OF THE + SUBR. IF THE NAME CAN BE FOUND, IT IS PRINTED. + THIS IS ESPECIALLY GOOD FOR REGULAR PDL ENTRIES + CREATED BY PUSHJ, BECAUSE THEY CONTAIN A SUBR + RETURN ADDRESS IN THE RIGHT HALF. + HH$X CREATE A FAKE ^H BREAKPOINT IN LISP. + THIS SAVES THE ENVIRONMENT THE WAY ANY USER + INTERRUPT DOES AND LETS YOU INVESTIGATE A + LITTLE. THIS IS GOOD WHEN YOU CAN'T AFFORD + TO PROCEED THE LISP EVEN LONG ENOUGH TO TYPE + ^H AT IT. WHEN YOU TYPE $P AT LISP, YOU WILL + SEE A *. YOU ARE IN DDT! (YES, $P GETS YOU BACK + TO DDT, NOT BACK FROM IT, HERE!) + NOTE THAT IF YOU WENT BACK TO DDT WHILE LISP + HAD USER INTERRUPTS LOCKED OUT (E.G. IN THE + MIDDLE OF A GARBAGE COLLECTION), THEN THE + ^H BREAK CAN'T BE RUN; YOU WILL RETURN TO DDT + IMMEDIATELY. + DP$X DEPURIFIES THE PAGE CONTAINING .. THIS WAS + INVENTED BEFORE DDT DID IT FOR YOU. + RP$X REPURIFIES THE PAGE CONTAINING .. THIS IS + SOMEWHAT MORE USEFUL, E.G. TO REPURIFY A PAGE + AFTER PATCHING IT. + PURIFY$G THIS PURIFIES THE SYSTEM PAGES OF LISP + WHICH MAY BE PURE. FOR BIBOP LISP, IT ALSO + PURIFIES THOSE PAGES OF USER CODE WHICH HAVE + BEEN MARKED AS PURIFIABLE. IT TENDS TO + DESTROY ACCUMULATORS; YOU CAN'T PROCEED AFTER + DOING IT. (IT IS GENERALLY PERFORMED PRIOR + TO DUMPING OUT A LISP, E.G. JUST AFTER A + CALL TO THE FUNCTION MACDMP.) + + THE REST OF THESE ARE AVAILABLE ONLY IN BIBOP LISP. + + T.$X IS LIKE P.$X, BUT INSTEAD OF PRINTING THE + RIGHT HALF OF . AS AN S-EXPRESSION, IT GETS + TYPEP INFORMATION FOR IT FROM THE BIBOP + TYPE TABLE, AND PRINTS THE TYPE INFORMATION. + TL.$X LIKE T.$X, BUT LOOKS AT THE LEFT HALF OF .. + TP Z$X LIKE PP Z$X, ONLY DOES T. INSTEAD OF P.. + TBLPUR$X PRINTS OUT BIBOP'S PURTBL DATA BASE, + ONE DIGIT FOR EVERY PAGE IN THE 256K ADDRESS + SPACE. THE DIGITS ARE 0 = NONEXISTENT MEMORY, + 1 = IMPURE MEMORY, 2 = PURE MEMORY, + 3 = MEMORY IN AN UNCERTAIN STATE, E.G. PDL + AREAS AND THE END OF BINARY PROGRAM SPACE. + AT THE END SUMMARIES ARE PRINTED. + THIS IS NOT THE ACTUAL STATE OF MEMORY, BUT + ONLY WHAT BIBOP WOULD LIKE IT TO BE, + E.G. A PAGE MARKED 2 MAY NOT REALLY BE PURE. + PURIFY$X IN BIBOP EFFECTIVELY FORCES THE ACTUAL + STATE OF THE WORLD TO CONFORM TO THE PURTBL. + PAGPUR$X PRINTS OUT A TABLE LIKE TBLPUR, BUT + DISPLAYS THE ACTUAL STATE OF EACH PAGE, + NONEXISTENT, IMPURE, OR PURE. + \ No newline at end of file diff --git a/doc/_info_/lisp.recent b/doc/_info_/lisp.recent new file mode 100755 index 00000000..9702571d --- /dev/null +++ b/doc/_info_/lisp.recent @@ -0,0 +1,51 @@ +Wednesday February 17,1982 LQ+2D.4H.21M.13S. -- JonL -- + +1) In SHARPM 82, #| now works as on the LISPM, namely #|...cruft...|# + "disappears" like a balanced comment; note that termination is |# + Also, #R now works; e.g. #3R21 is 7 (21 in base 3). +2) Two new functions in auxillary files, but not autoloading + DEFCONST is in the MLMAC file; it is like DEFVAR, but always SETQs. + ARRAYP is in the MLSUB file; returns true for non-funny arrays. +3) GENTEMP, an LSUBR, generates truly uninterned symbols. Should be + used in preference to GENSYM by macros which generate temporary + local variables. +4) The TTYNOTES-FUNCTION facility for COMPLR has been emended + +_______________________________________________________________________ + + +2) Two new functions in auxillary files, but not autoloading + DEFCONST is in the MLMAC file; it is like DEFVAR, but always SETQs. + ARRAYP is in the MLSUB file; returns true for non-funny arrays. + (defun ARRAYP (x) + (and (eq (typep x) 'ARRAY) + (memq (array-type x) '(NIL T FIXNUM FLONUM)) + 'T)) + +3) GENTEMP, an LSUBR, generates truly uninterned symbols. Should be + used in preference to GENSYM by macros which generate temporary + local variables. + + GENTEMP permits one optional argument, a prefix for the symbol to be + created (defaults to T), and creates a symbol like + (maknam (append (explode ) + (explode '|..|) + (explode ()))) + E.g., (GENTEMP) => |T..1| + (GENTEMP '|Foo|) => |Foo..1| + A basic problem with GENSYM is that even though the symbol is uninterned + when created, it may be written out to a FASL during compilation, and + upon loading it will then be interned; separate such compilations + can thus have unfortunate co-incidences between variables which were + thought to be unique. Any symbol with a +INTERNAL-TEMP-MARKER + property on its property list will be treated during compilation in + such a way that it won't be interned when the FASL file is loaded. + +4) The TTYNOTES-FUNCTION facility for COMPLR has been emended + + If a symbol has a TTYNOTES-FUNCTION property, then that is assumed to + be some function which when applied to the symbol will either return a + re-nameing of it for the unfasl and ttynotes purposes, or will return () + meaning "I've alredy outputted all the msgs I care to see". Currently it + doesn't support the re-naming for break-point error msgs. + diff --git a/doc/_info_/lisp.send b/doc/_info_/lisp.send new file mode 100755 index 00000000..8ba0cfd5 --- /dev/null +++ b/doc/_info_/lisp.send @@ -0,0 +1,164 @@ + +Documentation of the "usrhunk" apparatus for SENDing messages. + + (SSTATUS USRHUNK ) specifies the "user hunk" predicate, which + determines whether to "hook into" a user-provided definition for + some system facility, or to treat the data strictly as a hunk. + (SSTATUS SENDI ) specifies a "SEND" interpreter -- + is invoked in order to send a "message" to a "user hunk", when a + hunk which passes the "usrhunk" test is given as argument to any of + EQUAL SUBST PURCOPY EVAL SXHASH PRINT EXPLODE + FLATSIZE ALPHALESSP SAMEPNAMEP NAMESTRING + or to any of the following out-of-core facilities + GFLATSIZE SPRINT USERATOMS-HOOK DESCRIBE WHICH-OPERATIONS + (SSTATUS CALLI ) + + The usrhunk takes one argument, and should return + non-null for objects that LISP should send messages to. It is invoked + via (CALL 1,) so this link gets snapped, which means that if you redefine + the predicate then the new definition may not take effect unless you + un-snap by doing (SSTATUS USRHUNK (STATUS USRHNK)). + The usrhunk SEND interpreter, , is invoked via (JCALL 16,) + so its link too may be snapped. This function is responsible for + delivering the message to the apropriate code for handling it; return + values are sometimes significant. See below for documentation on specific + messages which will be sent by LISP. Note that an lsubr "SEND" is assumed; + this function could be the function that is given to (SSTATUS SENDI ...). + + For the dozen or so system functions which will send a message to + a usrhunk, the action is as follows. Suppose the message is, say, DOIT; + then (DOIT ) will be interpreted by doing a send like + (SEND 'DOIT ), and this will cause the send interpreter + function to select some specialized function, say, FROBULATE, which will + then be applied to the arguments in the same order as given to SEND. E.g., + (DEFUN FROBULATE (actor msg-key other-arg) + (caseq msg-key + (DOIT ) + (DONT ) + (T ))) + Actually, the "msg-key" argument could be ignored, but this example shows + how several different messages could be dispatched to the same function. + The argument spectrum of the frobulator should match that of the original + function; thus for the SXHASH message it might be + (DEFUN HASH-IT-ALL (ob () ) ...) + where the "()" means to ignore the message key (which should be sent as + SXHASH). On the other hand, there may be some importance to the order + of arguments, as this example for the SUBST message shows: + (DEFUN SUBST-FOR-TRICKY-HUNK (hunk () old new) + (hunkify (subst old new (extract-data hunk)))) + Here is a table of the actions taken by the system functions which + resort to SENDing, and of the meanings of the arguments being "sent": + EQUAL -- (send obj1 'EQUAL obj2) -- "obj1" and "obj2" are two objects + to be compared, and of course "equal" is commutative. + SUBST -- (send object 'SUBST a b) -- Substitute a for b in object. + PURCOPY -- (send object 'SUBST a b) -- Substitute a for b in object, + using static (potentially read-only) consing areas. + EVAL -- (send object 'EVAL) -- Return the value of this object. + Typically, just returns itself for "implicit quoting". + FLATSIZE -- (send object 'FLATSIZE printp level slashifyp) + "printp" -- non-null if called from inside print as part of the + autoterpri hackery; in this case it should return + characters before next legal place to break. This doesn't + matter if you're not doing autoterpri hacking. + "level" -- fixnum level of recursion of PRINT/FLATSIZE; can + be passed on to PRINT-OBJECT or FLATSIZE-OBJECT (see + below for their definitions). This is used to limit + recursion with PRINLEVEL set non-null. + "slashifyp" -- If non-null, include slashes where print would. + PRINT -- First, there will be done + (send object 'FLATSIZE 'T -1 slashifyp) + and then + (send object 'PRINT stream level slashifyp) + "stream" -- SFA, file, T, or () to print to + "level" -- recursion level of PRINT calling print or print + methods recursively. If you do printing that may wish + to be limited in depth by PRINLEVEL, you should do your + output with PRINT-OBJECT, which takes the current nesting + level as one of it's arguments. ; + "slashify-p" -- if non-null, this is PRIN1, not PRINC + EXPLODE -- As with PRINT, there will first be done + (send object 'FLATSIZE 'T -1 slashifyp) + and then + (send object 'EXPLODE slashify-p number-p) + "slashify-p" -- non-null if slashes should be output where + print would put them. + "number-p" -- non-null if characters should be returned as + fixnums; otherwise, they are single-character symbols. + ALPHALESSP -- Will send either a LESSP or GREATERP message, + with one argument, which is the 'other' object for comparison. + SAMEPNAMEP -- Sends a SAMEPNAMEP message, with one argument which is + the 'other' object for comparison. + SXHASH -- Sends a SXHASH message, which should return a FIXNUM to + be the SXHASH of the object. + NAMESTRING -- Sends a NAMESTRING message, which should return a SYMBOL + whose pname characters are a 'namestring' for the object. + + Two new functions have been added to the initial MacLISP for the sake + of recursive calls to PRINT and FLATSIZE by various PRINT and FLATSIZE + methods, and they have arguments similarly. + PRINT-OBJECT (object level slashifyp stream &optional ignored) + FLATSIZE-OBJECT (object printp level slashifyp &optional ignored) + "object" -- object to be printed or to have it's FLATSIZE computed. + "level" -- recursive printing level, for PRINLEVEL detection. You should + pass in the current LEVEL, zero-origen. + "slashifyp" -- non-null indicates slashification should be done + "stream" -- file or SFA + "printp" -- non-null if FLATSIZE is being called originally from PRINT + This will be passed in to any FLATSIZE methods called + recursively and means "This is a FLATSIZE up to first place + OK to break", for print's TERPRI hacking. If you see this + and want to punt, return zero. + "ignored" -- for compatability with an irrelevant LISPM feature. + + + + *** CALLI processing *** + + CALLI interpreters must be hand coded; they cannot be coded in LISP. + This is because of the way they are invoked: They get invoked with + the stack in the format for IAPPLY. IAPPLY is LISP's Internal APPLY. + The arguments are on the stack, like for an LSUBR call, and T contains + the negative of the number of args, just like for an LSUBR call. However, + where the return address would be is found the object to be applied. What + LISP does is to take that object, figure out how to apply it, replace it's + slot on the stack with ,,CPOPJ . CPOPJ is the address of a POPJ P, + thus returning to it returns to the caller of the IAPPLY, who's return + address is just below that. + |arg n + |arg n-1 + .. + .. + .. + |arg 1 + |arg 0 + object-to-be-applied + return-address + Register T (accumulator 6) contains -n, and the slot containing + object-to-be-applied is clobbered to ,,CPOPJ + and the function is invoked. + + The user CALLI handler can act in several ways. You can figure out the + function you wish to invoke, clobber the slot to + contain a CPOPJ (or whatever routine you want executed later) and do + a JCALLF 16,(routine) or you can replace the with + another object to be used instead, and JRST off to IAPPLY. IAPPLY will + then recompute what to do (possibly invoking the user CALLI handler if + it answers true to the USRHUNK test), apply the function and return. + + Since the CALLI handler is not a function, it does not live in a SUBR + or LSUBR property, but instead in a CALLI property. (SSTATUS CALLI 'FOO) + looks for a CALLI property on FOO. If it finds it, it stores a JRST to + that routine internally, and saves the symbol FOO to be returned by + (STATUS CALLI). + + +____________________________________________________________________________ + +2/19/80 -- RWK +1) **SELF-EVAL** hook + PRINC/PRIN1 now send a FLATC/FLATSIZE message first. This should be + improved some more but it really does work. PRINLEVEL info needs to be + passed back and forth between MACLISP and user printers, and FLATC/FLATSIZE + should be told whether or not it is for PRINT so they can give the FLATC + before the first break. + diff --git a/doc/_info_/lisp.sfa b/doc/_info_/lisp.sfa new file mode 100755 index 00000000..c3fc5209 --- /dev/null +++ b/doc/_info_/lisp.sfa @@ -0,0 +1,342 @@ +I) Introduction. + + There are many instances when a MacLISP programmer wishes to +simulate an arbitrary I/O device. That is, he wishes to use the primitives +provided in LISP for doing I/O (such as READ and PRINT) yet wishes the +target/source of the characters to be completely arbitrary. I propose a +mechanism called an "SFA" (Software File Array) to handle this situation. + + An SFA consists of a function and some associated local storage +bound up in an "SFA-object". In order to satisfy the above goals, an +SFA-object may be used in almost all places that a file-object can be used. +Note that the existence of SFAs will not obviate the need for the current +NEWIO implementation of files. SFAs are strictly a user entity, and the +files are still needed in order to communicate with the operating system. + + The SFA-function is a user-defined EXPR/SUBR which accepts 3 +arguments. Its first argument is the SFA-object on which it is to act, and +the second argument is a symbol indicating the operation to be performed. +The third argument is operation specific. The SFA-object needs to be +supplied to the function because one SFA-function may be associated with +many different SFA-objects. There are some operations used by the system +(TYI, TYO, etc...). The user is free to define new operations and to use +them by calling the SFA directly. + + As there are predefined uses for many of the system I/O functions +that currently exist, when these functions are translated to SFA operations +they must retain the semantics they have when applied to file-objects. +Since this is the case, any SFA that expects to interface directly to the +standard I/O routines must know about the difference between binary and +character-oriented operations. Generally, an SFA will only handle one type +of I/O (i.e. most SFAs will not handle both the IN and TYI operation), yet +the structure of SFAs will not preclude them handling both. + + +II) System defined operations + +1) Operations applicable to both input and output SFAs + +A) WHICH-OPERATIONS + + The SFA must return a list of operations which it can perform. +Every SFA *must* handle the WHICH-OPERATIONS operation. + +B) OPEN + + This operation is invoked if an OPEN is done with a SFA as its first +argument. The SFA should return either a file-object or a +SFA-object. The third argument to the SFA is the second argument to +the OPEN, and it defaults to NIL. + + +C) CLOSE + + This operation is invoked when a CLOSE is done with a SFA as its +argument. There is never a third arg, and the SFA should return either +T if the close was successful and NIL if not (e.g. if the SFA was already +"closed".) + + +D) DELETEF + + No arguments will be passed to the SFA. There is no clear global +semantic meaning of this. + + +E) FILEPOS + + If an argument is given to FILEPOS, it is NCONS'ed and handed to the +SFA, else the SFA is given NIL. For a NIL argument, a fixnum should be +returned. For one argument, the SFA should interpret the argument as a +"position" to set the "file" to, and perform appropriate actions. + + +F) (STATUS FILEMODE) [operation: FILEMODE] + + The SFA should return a list of adjectives describing itself. If the +SFA cannot support the FILEMODE operation (as determined by a +system-performed WHICH-OPERATIONS check), then a list of the form: + + ((SFA) {results of a WHICH-OPERATIONS call}) + +is returned. + +2) Functions applicable to SFAs which can do input + + If the SFA is to support normal LISP reading other than TYI, it must +support at least TYI and UNTYI, and preferably TYIPEEK also. + +A) TYI + + The SFA should return a fixnum representing a character. This operation +may be called from a READ, READLINE, or a straight TYI (the SFA cannot +depend upon being able to determine the context). The argument is the +value to return when EOF is reached (this is true for all input functions +including IN). + + +B) UNTYI + + The SFA should put the argument into its input stream and on the next +TYI should spew forth the saved character rather than the next one in the +"stream". Note that an arbitrary number of UNTYI's may be done in a row. + + +C) TYIPEEK + + The SFA should return a fixnum (as in TYI) but should not remove the +character from the input flow. Therefore, subsequent TYIPEEK's will read +the same character. If the SFA cannot handle TYIPEEK, it will be simulated +by a TYI/UNTYI pair of operations. + + +D) IN + + The value returned should be a fixnum that is the next binary value in +the input stream. The argument is the EOF value. + + +E) READLINE + + The value returned should be a symbol that represents one "line" of the +input stream. If the SFA cannot handle this operation, it is simulated in +terms of TYI. The argument is the value to return upon EOF. + + +F) READ + + The value returned should be the next "object" in the input stream If +the SFA cannot handle this operation, it is simulated in terms of +TYI/UNTYI. The argument is the value to return upon EOF. + + +G) LISTEN + CLEAR-INPUT + + For LISTEN, the total number of items (or "characters") currently +held in the input buffer is returned; for CLEAR-INPUT, the input buffer +is just thrown away. + +3) Functions applicable to SFAs which can do output + +A) TYO + + The argument is a fixnum representing a character. The value returned +should be T if the SFA succeeds, and NIL if the output was unsuccessful. + + +B) OUT + + The argument is a fixnum and is output as such. The TYO/OUT pair of +functions is the analog to the TYI/IN pair. + + +C) FORCE-OUTPUT + CLEAR-OUTPUT + + For FORCE-OUTPUT, the SFA should empty its output buffer to the logical +"device" to which it is connected; for CLEAR-OUTPUT, any buffer is just +thrown away. + +D) PRIN1 + + The SFA should print the arg in its slashified form. If the SFA +cannot perform this operation, it is simulated in terms of TYO. + + +E) PRINT + + The SFA should print the arg in its slashified form preceeded by a + and terminated by a . If the SFA cannot perform this +operation, it is simulated in terms of TYO. + + +F) PRINC + + The SFA should print the arg in its unslashified form. If the SFA +cannot perform this operation, it is simulated in terms of TYO. + + +G) CURSORPOS + + The SFA will receive a list of the data args given to CURSORPOS. There +may be 0, 1 or 2 of these. If given the horizontal and vertical position, +there will be two elements in the list ( ) which are +zero-indexed fixnums (or NIL for either/both meaning use the current value). +If given a single ascii character object, a relative cursor movement will +be expected (eg, C=Clear Screen, U=Move Up, ... [See .INFO.;LISP CURSOR]) +If an empty data list is received, the SFA-handler should return the current +cursor position as a dotted pair ( . ). There is +no clear global semantic meaning of this operations when +performed on non-tty's. + + +H) RUBOUT + + The sfa should try to delete the last character output (either +by main output, or by echo output). See documentation on the MacLISP +RUBOUT function. + + +III) System functions for manipulating SFAs + +A) (SFA-CREATE + + ) + + SFA-CREATE returns an SFA-object which represents a function and +associated local storage. If the first arg is a SYMBOL, then that symbol +is taken as the SFA-function; if the first arg is an SFA-object, then the +function associated with it is used as the SFA-function, and the local +storage is possibly reclaimed (the first arg being an SFA is not yet +implemented). The second arg to this function should be the number of user +locations to allocate in the SFA-object. + + When the SFA-CREATE is done, the SFA is immediatly invoked with a +WHICH-OPERATIONS call. A mask is then created corresponding to the +internal functions that the SFA knows how to do. This mask is used for +fast error-checking when a predefined operation is handed an SFA (e.g. +TYO). + + +B) (SFA-CALL []) + + SFA-CALL is used to perform an arbitrary operation on an arbitrary +SFA-object. For example, (TYO 1 ) is equivalent to +(SFA-CALL 'TYO 1). + + +C) (SFAP ) + + Returns T iff is a SFA-object else returns NIL. + + +D) (SFA-GET ) + + SFA-GET reads the local storage of . If the second +arg is a fixnum, then location of the user's local storage is +accessed. This number may range from 0 to the maximum as specified when +the SFA-object is created {see SFA-CREATE}. If the second arg is a +symbol, then one of the "named" locations is accessed. The names are as +follows: + + FUNCTION The SFA-function + WHICH-OPERATIONS A list of operations of interest to the + system that the SFA can perform. This is a + subset of the SFAs WHICH-OPERATIONS list. + PNAME The object to print as the "name" of an SFA + PLIST A general property list, for use by the user. + XCONS A "correspondent" for a bi-directional SFA; + akin to the TTYCONS concept for TTY's. + +E) (SFA-STORE ) + + is stored in the location specified by the second arg to +SFA-STORE. Locations are as for SFA-GET. It is strongly recommended that +the SFA-function NEVER be changed. + + + + +IV) Higher level tools. + +A) DEFSFA -- Define a SFA + + [requires some runtime support, which will be autoloaded in] + +(DEFSFA ( ) + &rest ) + + -- The name of this type of SFA. + + -- a variable to be bound to the SFA itself when it is sent a +message + + -- a variable to be bound to the name of the message. + + -- a list of slot names, or ( ) +each slot will have an accessor macro defined for it, with a name formed by +(SYMBOLCONC '- ) + + -- a list of option specs. An option spec is either a bare +symbol, denoting that the specified option is TRUE, or a list of an option +name and a value. The only option defined currently is :INIT, which +suppresses newly consed SFA's of this type getting a :INIT message if no +initial values are supplied. (If initial values are supplied, the :INIT +message must be sent in order to store them). + + -- a list of clauses. Each clause has the form + ( . ) + -- the ops are message keys, ala the second argument + to SEND or SFA-CALL. + -- This is either a symbol, in which case it is bound to the + 3rd argument, or a list of two or more symbols, in which + case it is bound to the 3rd-th arguments. No error + checking on number of arguments will be done. If the symbol + is atomic, it will be reachable via either SFA-CALL or SEND, + otherwise it will be reachable only by SEND. This is + because SFA-CALL does not allow other than 3 arguments to be + passed. + -- list of forms to be evaluated. The last one's value will be + returned. + +This defines accessor macros for each slot in the SFA, plus a macro for +creating the SFA, named by prepending CONS-A- to the sfa-name. The +CONS-A-mumble macro does the SFA-CREATE, and immediately sends it a :INIT +message with a list of alternating slot-names and values. + +All this works via the following lower-level mechanisms: + +B) (SFA-UNCLAIMED-MESSAGE ) Basically, this reports +the error. But first, it handles several special cases. The first is +turning a SEND into an SFA-CALL. When a SEND is performed on a SFA, it is +simulated by doing an SFA-CALL with an operation of :SEND, and a 3rd +argument of (LIST <3rd argument> ... ). If +:SEND is the operation to SFA-UNCLAIMED-MESSAGE, AND the SFA claims to +implement the (in response to a WHICH-OPERATIONS-INTERNAL +query), it will turn it back into an SFA-CALL of the , with +any extra arguments being thrown away. If it DOESN'T claim to handle it +the message is passed off to the superclass via SEND-AS + +A subcase of the :SEND case is when the is +WHICH-OPERATIONS. This implies a (SEND 'WHICH-OPERATIONS) was done. +So this is simulated by mergeing any operations obtainable from the +superclass of SFA-CLASS. (If the EXTEND package isn't loaded, it doesn't +try to get them though.) + +If the message is WHICH-OPERATIONS-INTERNAL, then the handler did not +implement WHICH-OPERATIONS-INTERNAL. We assume WHICH-OPERATIONS will +do the job and SFA-CALL that. + +If the message is something other than :SEND, it just passes the message on +up to the superclass with SEND-AS. + +It is recommended that any SFA's which for one reason or another do not use +DEFSFA should use SFA-UNCLAIMED-MESSAGE. Essentially the correct behaviour +with respect to SEND should result. + +;;; Local modes: ! +;;; Mode: Text ! +;;; Auto fill mode:1 ! +;;; Fill column:75 ! +;;; End: ! diff --git a/doc/_info_/lisp.sharpc b/doc/_info_/lisp.sharpc new file mode 100755 index 00000000..f99fd171 --- /dev/null +++ b/doc/_info_/lisp.sharpc @@ -0,0 +1,127 @@ +Date: 25 November 1980 12:52-EST +From: Robert W. Kerns +Subject: Feature double creature +To: KMP at MIT-MC +cc: LISP-FORUM at MIT-MC, "(FILE [LISP;SHARPC DOC])" at MIT-MC + +Well, I suppose I should at this time (I've been postponing it) propose my +FEATURE-SET proposal. + +First off, a couple notes about KMP's proposal: + +1) I think the need for a canonical way of determining which dialect the code +is running under is clear. + +2) I don't see any reason for it to be a STATUS mumble rather than a variable. + +3) The issue is separate from issues of sharp-sign conditionalization and +feature-testing. Sharp-sign conditionalization does not want to depend on what +features are PRESENT AT READ TIME, but rather WHAT FEATURES ARE PRESENT AT +TIME-OF-USE. This last is the motivation for my proposal. + +Some of you have seen this before. I've long intended to bring this out as +an alternate mode for the existing MACLISP SHARPM package, but haven't had the +time for integrating my code into the current version. But since it turns out +I need it for cross-compilation in NIL, I've just fixed it up. + +1) A single LISP environment often has need of reading forms intended for +different LISP environments. For example, a compiler may be doing READ for +forms which may be EVAL'ed in its environment, or which may be EVAL'd in some +other LISP with possibly different features (probably not the COMPLR feature!) +with or without compilation. I.e. the line #-FOO in a source file usually +refers to a feature FOO in the LISP that the compiled file will run in. (I'll +get into exceptions to this later). The LISP where it will eventually matter +whether the FOO feature exists I will call the TARGET LISP. The target LISP +may or may not be the same LISP that is doing the READ that see's the #+FOO. + +2) It is not really enough to say that because a feature is not on a list of +features somewhere that a feature is not present. Sometimes this is because +whoever told the compiler what features exist simply did not know all about the +target environment (I.e. I'm compiling this file for use with the RWK-HACKS +feature). Sometimes you know that a feature is NOT present, like FRANZ in the +MACLISP compiler. The obvious solution is to maintain TWO LISTS, of KNOWN +FEATURES and NON-FEATURES. What do you do if a feature is not known? Two +options are to signal an error, and to ask the user. I prefer the later. + +3) It is not enough to have simply ONE set of features. When doing a LOAD in +a COMPLR, for example, one generally intends for that code to be evaluated in +the compiler, so the LOCAL LISP is the target, and the LOCAL FEATURES should be +brought to bear. When reading for compilation, COMPILATION-TARGET-FEATURES +should be what is used (by default) for FEATUREP. + +So! I define the following goodies: + +[This stuff is available by loading ((LISP) SHARPCONDITIONALS) either on top of + or instead of ((LISP) SHARPM)] + +defun DEF-FEATURE-SET target features &optional nofeatures (query-mode ':QUERY) + Defines a feature-set for a target environment named , with + the supplied features and non-features. If is :QUERY, the + user will be asked each time. If is :ERROR, an error is + signaled. If is T, FEATUREP of things unknown returns T, while + if it is (), it returns (). + +[This query-mode stuff is merely to satisfy any namby-pambies out there who + don't like this winning stuff for one reason or another. If nobody dislikes + this stuff, maybe it should be flushed as being excess hair.] + +defvar TARGET-FEATURES default LOCAL-FEATURES + The default feature-set for FEATUREP and the sharp-sign macro. This should + be bound around calls to READ when the result of the READ will be understood + in some other environment, such as compilers. + +defun FEATUREP feature &optional (feature-set TARGET-FEATURES) (featurep T) + Returns T if is known to be a feature in . + is a symbol which has been defined to be a feature-set by + DEF-FEATURE-SET. If it the feature is not known to be either a feature or + not a feature, action is taken according to the query-mode of the feature + set. (see DEF-FEATURE-SET) + + featurep is a purely internal flag which if () turns FEATURP into NOFEATUREP. + +defun NOFEATUREP feature &optional (feature-set TARGET-FEATURES) + like FEATUREP, except returns T if known NOT to be a feature. + +FEATUREP will take not only a feature name, but a generalized FEATURE-SPEC. A +feature-spec is a feature name, or (OR f1 f2 ... fn), meaning T iff f1, f2, ... +OR fn satisfy the FEATUREP test, (NOT f) [meaning the same as (nofeature f)], +(AND f1 f2 ... fn) meaning T iff f1, f2, ... AND fn satisfy the featurep test. +In addition to these familiar operators can be used any name of a FEATURE-SET. +I.e. (FEATUREP (AND (LOCAL-FEATURES F1) F2)) returns T iff F1 is a feature in +LOCAL-FEATURES and F2 is a feature in whatever feature set is the value of +TARGET-FEATURES. This may have some limited application in conjunction with #+ +and #-, but should not be used wantonly. + +#+ and #- are followed by a feature-spec and another form. #+ calls FEATUREP, +and #- calls NOFEATUREP on the feature-spec, and if () is returned, the next +form is gobbled and thrown away. Note that it is gobbled via a recursive READ, +so if it contains illegal syntax or #.'s, an error may result. Note that +using #- and #+ inside forms conditionalized with #- and #+ can quickly result +in unreadable and unmaintainable code. + +A few functions for manipulating FEATURE-SETs: + +defun COPY-FEATURE-SET old new + This function makes a new feature-set having the same known features, + non-features, and query mode as the old. It is probably the right way + to create new feature sets for related environments. + +defun SET-FEATURE feature &optional (feature-set-name TARGET-FEATURES) + This function makes be a feature in the feature-set named by + . (FEATUREP ) will thereafter + return T. + +defun SET-NOFEATURE feature &optional (feature-set-name TARGET-FEATURES) + This function makes be a non-feature in the feature-set named by + . (NOFEATUREP ) will + thereafter return T. + +defun SET-FEATURE-UNKNOWN feature &optional (feature-set-name TARGET-FEATURES) + This function makes be unknown in the feature set. Depending on + the query-mode, FEATUREP and NOFEATUREP may query, give an error, or assume + the default values thereafter. + +defun SET-FEATURE-SET-QUERY-MODE feature-set-name mode + sets the feature-set query-mode to . can be one of :QUERY, + :ERROR, T, or (), as described above. + diff --git a/doc/_info_/lisp.sharpm b/doc/_info_/lisp.sharpm new file mode 100755 index 00000000..688a5742 --- /dev/null +++ b/doc/_info_/lisp.sharpm @@ -0,0 +1,82 @@ +The extended syntax of #, as indicated by the subsequent character, with +questionable or not-yet-fully worked-out cases indicated by "???", and * +in column 1 meaning NIL/NIL-compatibility only + +* " BITS expressed as 4 bits per hexadecimal digit + % MACROEXPAND following form at read time. + ' Like single-quote macro. #'foo ==> (FUNCTION foo) +* ( S-expression VECTOR, elements inside list + * Unsigned-integer, or Machine-word + + Conditional read, for next expression. A feature name, or + list with "OR" or "AND" as first element and remaining elements + as feature names, must immediately follow. Next form is + skipped unless this system has one of the requested features + (for "OR") or unless it has all the requested features (for + "AND". + , Load-time evaluation + - Conditional read, like "#+", but next form is skipped if the + conditions indicated are satisfied. + . Read-time evaluation + 0 ... 9 decimal representation for a radix denotation +??? : Flush a package prefix, e.g. #:SI:FOO is the same as FOO +* B Binary notation for a bitstring follows + M Next form is flushed unless this is a MACLISP system + N Next form is flushed unless this is a NIL system + O Octal notation follows, either for a number or for a bitstring + Q Next form is flushed unless this is a LISPM system + R Radix change -- #16R reads in base 16. +* T Truthity, a specific non-null, not false, constant + X Hexadecimal notation for a number or for a bitstring + ^ A FIXNUM, obtained by "controlifying" the next character. + (e.g. #^B is 2, the ascii value of control-B) + / A FIXNUM, denoted by the next character (e.g. #/A is 65.). + \ A FIXNUM, denoted by the following standard symbolic names: + Name Value Name Value + NULL 0 RETURN 13 + ALPHA 2 NEWLINE 13 + BETA 3 CR 13 + EPSILON 6 NL 13 + BELL 7 ALTMODE 27 + BACKSPACE 8 ALT 27 + BS 8 BACK-NEXT 31 + TAB 9 SPACE 32 + LINEFEED 10 SP 32 + LF 10 DELETE 127 + VT 11 RUBOUT 127 + FORM 12 HELP 2120 + FORMFEED 12 + FF 12 + + +The user may add to this list using the function SETSYNTAX-SHARP-MACRO, +whose argument list is + ( &OPTIONAL (rt READTABLE)) +The general # macro character function will dispatch to +when is the character immediately following the #; the +dispatch table is kept on a per Readtable basis. Or he may use the +autoloadable macro DEFSHARP which provides an easy way to set up "macro +character functions". For example + (defsharp /% (() ) + (macroexpand (/#sub-read () READ-STREAM))) +defines (and activates using SETSYNTAX-SHARP-MACRO) a function to be run +when #% occurs. An alternative form is + (defsharp /: SPLICING (() ) + (/#-flush-chars-not-set #/: 'T) () ) +where the word SPLICING indicates that the result is to be like a +SPLICING readmacro character -- the default is like an elemental +readmacro character. + +The # macro works by keying off a second character, with possibly an +argument in between. Currently, the permissible arguments are + (1) digits, for a numeric argument, e.g. #3R201 reads 201 in base 3. + (2) ^B, ^C, or ^F to signify respectively "add control bit", "add meta + bit", and "add control-meta bits". The "control" bit has value + 128. and the "meta" bit has value 256. +The alist from /#-MACRO-DATALIST holds, for each valid "second" character, +a 4-list: ( ) +where Takes one argument, as described above in (1) and (2). If + there is no "argument" then () is passed to the function. + Is either MACRO or SPLICING + A flag which, if non-null, means don't flush the "second" + character from the input stream before running . + Is the numeric encoding of the character diff --git a/doc/_info_/lisp.stepmm b/doc/_info_/lisp.stepmm new file mode 100755 index 00000000..3649d790 --- /dev/null +++ b/doc/_info_/lisp.stepmm @@ -0,0 +1,697 @@ + + + --- THE LISP STEPPER --- + + (FOR MORE INFORMATION THAN PROVIDED HERE CONTACT THE AUTHOR: + MATTHEW MORGENSTERN M.I.T. NE43-317 253-3546 + OR :MAIL TO MM; @ML:) + +TO LOAD: FROM LISP EXECUTE (FASLOAD STEPMM FASL COM). + + +NOTE: THE STEPPER HAS BEEN MODIFIED TO WORK IN BOTH OLDIO AND + NEWIO LISP ENVIRONMENTS. AN ENDPAGEFN IS PROVIDED + WITHIN THE STEPPER FOR NEWIO AND IT MAY BE CHANGED BY + GIVING A DIFFERENT VALUE TO THE ATOM MMSTEP-ENDPAGEFN . + THIS IS ALSO THE NAME OF THE INITIAL ENDPAGEFN, AND IT + CAN BE USED OUTSIDE THE STEPPER TOO BY DOING + (ENDPAGEFN T 'MMSTEP-ENDPAGEFN). + + +TO CURRENT USERS: + A NEW INTERESTING DISPLAY MODE IS NOW AVAILABLE, SEE THE +S COMMAND. OTHER NEW COMMANDS INCLUDE (U -), PATTERN MATCHING +FOR AN S-EXPRESSION IN A (COND ...), E(VAL), WTALL (WAIT-ALL), +WTIF (WAIT-IF), AND VARIABLE LENGTH PAUSING WHILE IN A AND C +MODES. + + +I CAPABILITIES + + THE LISP STEPPER PACKAGE PROVIDES DEBUGGING CAPABILITIES +FOR INTERPRETED LISP PROGRAMS THAT ARE COMPARABLE TO THE CAPABILITIES +PROVIDED BY DDT FOR ASSEMBLER CODE. THESE CAPABILITIES INCLUDE: + + 1) SINGLE STEPPING THROUGH THE EVALUATION OF A FUNCTION AND +OVER OR INTO OTHER INTERPRETED FUNCTIONS, WHEN CALLED, ON A +SELECTIVE BASIS AS DETERMINED BY THE USER. EACH SUCH FORM +AND ITS RESULTING VALUE MAY BE DISPLAYED. + + 2) DYNAMIC BREAKPOINTING ON ONE OR MORE OF THE FOLLOWING +CONDITIONS: THE S-EXPRESSION OR ATOM ABOUT TO BE EVALUATED +MATCHES A PATTERN YOU PROVIDE; A SPECIFIC FUNCTION IS EXPLICITLY +EVAL'D; A GIVEN ATOM EVALUATES TO A GIVEN VALUE; A GIVEN ATOM +IS TO BE BOUND IN A PROG, EITHER TYPE OF DO, OR AN EVAL'D +LAMBDA; OR UPON AN ARBITRARY USER-SPECIFIED CONDITION. + + 3) RETURNING A DIFFERENT VALUE FOR A GIVEN S-EXPRESSION -- +THIS ALLOWS FOR CHANGING THE ACTION THAT WOULD BE INITIATED BY +CONDITIONALS IN THE PROGRAM AND/OR BY GO'S IN A PROG OR DO. +YOU CAN ALSO "GO" TO ANY INSIDE THE CURRENT PROG. + + 4) THESE CAPABILITIES MAY BE REQUESTED WHEN THE INITIAL +FUNCTION IS STARTED, OR THEY MAY BE INITIATED AT ANY +OTHER POINT IN THE COURSE OF EXECUTION -- EITHER FROM THE +CONSOLE WHILE IN A BREAKPOINT, OR DIRECTLY FROM THE PROGRAM. + + +II HOW TO USE + + THE STEPPER MAY BE INVOKED INITIALLY BY USING THE +FUNCTION MEV AS ONE WOULD USE EVAL OF ONE ARGUMENT; EG. +(MEV '(FCN ARG1 ARG2)). FROM A BREAKPOINT OR IN A PROGRAM, +THE STEPPER MAY BE TURNED ON BY INVOKING (HKSTART) WITH NO +ARGUMENTS. IT MAY BE TURNED OFF BY THE Q COMMAND DESCRIBED +BELOW, OR OF COURSE BY CONTROL-G. AFTER MEV EVALUATES ITS +ARGUMENT, IT RETURNS THE VALUE AND TURNS OFF THE STEPPER. +NOTE THAT IN THE ABOVE EXAMPLE THE FORM TO MEV WAS QUOTED. +IF, SAY, THE VALUE OF F WAS THE S-EXPRESSION (FCN ARG1 ARG2), +THEN ONE COULD USE (MEV F) INSTEAD. + + AT ANY POINT DURING THE STEPPING, ONE MAY INSPECT THE +VALUES OF OTHER VARIABLES, AND EVEN REAPPLY MEV TO ANY FORM. +THIS MAY BE DONE IN EITHER OF THREE WAYS. EACH COMMAND WILL BE +PROMPTED FOR BY // , USUALLY FOLLOWING THE LAST FORM PRINTED +OUT. ANY S-EXPRESSION THAT YOU TYPE WHICH IS NOT RECOGNIZED AS +A COMMAND WILL BE EVAL'D (WITHIN AN ERRSET TO CATCH ERRORS). +ALTERNATIVELY, YOU CAN USE THE E COMMAND TO EVAL ANY EXPRESSION, +OR THE H COMMAND TO GET A NICE TYPE OF CONTROL-H BREAK. + + EACH COMMAND MUST BE FOLLOWED BY A SPACE (UNLESS THE +COMMAND IS A LIST). EACH FORM AND RESULT WHICH IS +PRINTED OUT WILL BE FOLLOWED BY # INDICATING THE +RELATIVE LEVEL OF EVALUATION (IE. STACK DEPTH SINCE INVOCATION). + + +THE PRIMARY COMMANDS ARE: + +D (MNEMONIC FOR DOWN) GO DOWN TO THE NEXT DEEPER LEVEL OF + EVALUATION AND DISPLAY THE FIRST FORM THERE BEFORE EVALUATING + IT. EG. IF THE FORM IS A FUNCTION CALL, WILL DISPLAY THE FIRST + ARGUMENT OF THE FUNCTION IF IT HAS ARGUMENTS IN THE CALL; + ELSE WILL DISPLAY THE FIRST S-EXP OF THE FUNCTION. + THEN PROMPTS FOR THE NEXT COMMAND. + +E (EVAL) CAN BE USED TO EVAL AN ARBITRARY EXPRESSION. IT + STARTS A NEW LINE, WAITS FOR YOU TO TYPE THE EXPRESSION, + THEN EVAL'S IT WITHIN AN ERRSET, AND PRINTS THE RESULT. + COMPARABLE TO JUST TYPING THE EXPRESSION OR ATOM AFTER + THE //, BUT CANNOT BE CONFUSED WITH A COMMAND, AND THE + FORMAT IS NICER. + +H (CONTROL-H) EXECUTES A CONTROL-H BREAK, AND WHEN $P'ED + DISPLAYS THE CURRENT FORM. WITHIN THE BREAK, ONE CAN + INSPECT THE VALUES OF VARIABLES, ETC., AND EVEN REAPPLY MEV + TO ANY FORM. + +N (NEXT) DISPLAY THE NEXT FORM (IE. S-EXP) AT THIS LEVEL, + WITHOUT SHOWING OR INSPECTING THE EVALUATION OF THE LOWER + LEVELS OF THE CURRENT FORM. THE VALUE OF THE CURRENT FORM + IS DISPLAYED FIRST. IF YOU WISH A CONDITION TO BE TESTED FOR + AT LOWER LEVELS, USE NN INSTEAD. + +NN LIKE N BUT SLOWER SINCE IT INSPECTS THE LOWER LEVELS. + USE INSTEAD OF N WHEN TESTING FOR A CONDITION. + +U (UP) GO UP TO THE NEXT HIGHER LEVEL OF EVALUATION AND SHOW + THE NEXT FORM AT THAT LEVEL. THE FORM(S) AT THE CURRENT AND + LOWER LEVELS ARE EVALUATED WITHOUT DISPLAY. AS AN EXAMPLE + OF ITS USE, AFTER YOU HAVE SEEN THE EVALUATION OF THE + ARGUMENTS TO A FUNCTION, THE NEXT FORM TO BE EVALUATED, IF + THE FUNCTION IS BEING INTERPRETED, WILL BE THE FIRST + S-EXPRESSION OF THE FUNCTION; TO AVOID SEEING HOW THE + FUNCTION IS EVALUATED INTERNALLY, YOU CAN TYPE U . + NOTE THAT THE LOWER LEVELS ARE NOT INSPECTED -- THUS + IF A CONDITION IS TO BE TESTED FOR AT THESE LEVELS, USE UU. + +(U ) IF IS POSITIVE (INCL. 0), FORMS ARE NOT + INSPECTED NOR DISPLAYED UNTIL THAT LEVEL NUMBER IS RETURNED + TO. IF NEGATIVE, GOES UP THIS NUMBER (ABSOLUTE VALUE) OF + LEVELS RELATIVE TO THE CURRENT LEVEL. THUS (U -1) IS + EQUIVALENT TO U . + +UU LIKE U BUT SLOWER. USE IF TESTING FOR A CONDITION. + +(UU ) LIKE (U ) BUT SLOWER. USE IF TESTING FOR A + CONDITION. + +Q (QUIT) EXIT FROM THE STEPPER. + +S (SHOW OR DISPLAY MODE) FOR DATAPOINTS AND OTHER DISPLAY + CONSOLES, THIS GIVES A NICE EASY READING OUTPUT + OF SELECTED LEVELS THAT CONSTITUTE THE CONTEXT OF THE + CURRENT EVALUATION. SPECIFICALLY, IT SELECTS THE CURRENT + LEVEL FOR SPRINTING AS A "HEADER", AND AS YOU GO DEEPER, THE + LOCAL CONTEXT IS ABBREVIATE-PRINTED UNDER THIS HEADER, AND + THE CURRENT OUTPUT WILL BE SPRINTED. S MAY BE USED AS OFTEN + AS YOU LIKE. HEADERS WILL AUTOMATICALLY BE POPPED WHEN YOU + RETURN . THE COMMAND (S ) SELECTS A PARTICULAR LEVEL + AS A HEADER. IT AND THE COMMAND SN AND SEVERAL USER + SETTABLE PARAMETERS ARE DESCRIBED IN THE MORE DETAILED + SECTION BELOW. + +(= ) THE S-EXPRESSION IS SUBSTITUTED FOR THE CURRENT + FORM AND ANOTHER COMMAND IS PROMPTED FOR (IE. YOU CAN STEP + INTO OR OVER THE NEW FORM IF YOU WANT TO). WHEN THE + RESULTING VALUE IS RETURNED IT WILL BE AS IF THE + ORIGINAL FORM HAD YIELDED THAT VALUE. FOR + EXAMPLE YOU CAN CHANGE THE APPARENT TRUTH OR FALSITY OF + PREDICATES OR BYPASS A (GO