{note The Interlisp-10 compiler itself, i.e., the part that actually generates code, was written and documented by, and is the responsibility of A.K. Hartley. The user interfaces, i.e., {fn TCOMPL}, {fn RECOMPILE}, {fn BCOMPL}, and {fn BRECOMPILE}, were written by W. Teitelman.} {index *PRIMARY* compiler} The compiler is contained in the standard Interlisp system. It may be used to compile functions defined in the user's Interlisp system, or to compile definitions stored in a file. The resulting compiled code may be stored as it is compiled, so as to be available for immediate use, or it may be written onto a file for subsequent loading. The most common way to use the compiler is to use one of the file package functions, such as {fn MAKEFILE} ({PageRef Fn MAKEFILE}), which automatically updates source files, and produces compiled versions. However, it is also possible to compile individual functions defined in the user's Interlisp system, by directly calling the compiler using functions such as {fn COMPILE} ({PageRef Fn COMPILE}). No matter how the compiler is called, the function {index *PRIMARY* COMPSET FN}{fn COMPSET} is called which asks the user certain questions concerning the compilation. ({fn COMPSET} sets the free variables {index LAPFLG Var}{var LAPFLG}, {index *PRIMARY* STRF Var}{var STRF}, {index SVFLG Var}{var SVFLG}, {index LCFIL Var}{var LCFIL} and {index LSTFIL Var}{var LSTFIL} which determine various modes of operation.) Those that can be answered "yes" or "no" can be answered with {lisp YES}, {lisp Y}, or {lisp T} for "yes"; and {lisp NO}, {lisp N}, or {lisp NIL} for "no". The questions are: {Tag CompilerQuestions} {index *BEGIN* compiler questions} {Begin LabeledList compiler questions} {Label {lisp LISTING?}{index LISTING? (Compiler Question)}} {Text This asks whether to generate a listing of the compiled code. The LAP and machine code are usually not of interest but can be helpful in debugging macros. Possible answers are: {Begin LabeledList Possible answers} {Indent 15percent} {Label {lisp 1}} {Item Prints output of pass 1, the {index LAP}{lisp LAP} macro code. } {Label {lisp 2}} {Item Prints output of pass 2, the machine code.} {Label {lisp YES}} {Item Prints output of both passes.} {Label {lisp NO}} {Item Prints no listings.} {End LabeledList Possible answers} The variable {index LAPFLG Var}{var LAPFLG} is set to the answer. } {Label {lisp FILE:}{index FILE: (Compiler Question)}} {Text This question (which only appears if the answer to {lisp LISTING?} is affirmative) ask where the compiled code listing(s) should be written. Answering {lisp T} will print the listings at the terminal. The variable {index LSTFIL Var}{var LSTFIL} is set to the answer. {note will "T" or "TTY:" print to the terminal ?? T --> print to terminal; TTY: --> print to file TTY: This should be made consistant} } {Label {lisp REDEFINE?}{index REDEFINE? (Compiler Question)}} {Text This question asks whether the functions compiled should be redefined to their compiled definitions. If this is answered {lisp YES}, the compiled code is stored and the function definition changed, otherwise the function definition remains unchanged. The variable {index STRF Var}{var STRF} is set to {lisp T} (if this is answered {lisp YES}) or {lisp NIL}. } {Label {lisp SAVE EXPRS?}{index SAVE EXPRS? (Compiler Question)}} {Text This question asks whether the original defining {lisp EXPR}s of functions should be saved. If answered {lisp YES}, then before redefining a function to its compiled definition, the {lisp EXPR} definition is saved on the property list of the function name. Otherwise they are discarded. It is very useful to save the {lisp EXPR} definitions, just in case the compiled function needs to be changed. The editing functions will retrieve this saved definition if it exists, rather than reading from a source file. The variable {index SVFLG Var}{var SVFLG} is set to {lisp T} (if this is answered {lisp YES}) or {lisp NIL}. {note EXPR def is always saved under prop EXPR, right?? doc here??} {note this is only asked when REDEFINE? is true. right?? (seems to make sense, tho I haven't checked it)} } {Label {lisp OUTPUT FILE?}{index OUTPUT FILE? (Compiler Question)}} {Text This question asks whether (and where) the compiled definitions should be written into a file for later loading. If you answer with the name of a file, that file will be used. If you answer {lisp Y} or {lisp YES}, you will be asked the name of the file. If the file named is already open, it will continue to be used. If you answer {lisp T} or {lisp TTY:}, the output will be typed on the teletype (not particularly useful). If you answer {lisp N}, {lisp NO}, or {lisp NIL}, output will {it not} be done. The variable {index LCFIL Var}{var LCFIL} is set to the name of the file. {note what is LCFIL set to if no file? NIL??} {note won't whatever you type be used as a file name if you don't answer Y, YES, N, NO, NIL, T, TTY: ??} } {End LabeledList compiler questions} In order to make answering these questions easier, there are four other possible answers to the {lisp LISTING?} question, which specify common compiling modes: {Begin LabeledList other possible answers} {Label {lisp S}{index S (Response to Compiler Question)}} {Item {lisp S}ame as last setting. Uses the same answers to compiler questions as given for the last compilation. {note always asks OUTPUT FILE} } {Label {lisp F}{index F (Response to Compiler Question)}} {Item Compile to {lisp F}ile, without redefining functions. } {Label {lisp ST}{index ST (Response to Compiler Question)}} {Item {lisp ST}ore new definitions, saving {lisp EXPR} definitions. } {Label {lisp STF}{index STF (Response to Compiler Question)}} {Item {lisp ST}ore new definitions; {lisp F}orget {lisp EXPR} definitions. } {End LabeledList other possible answers} Implicit in these answers are the answers to the questions on disposition of compiled code and {lisp EXPR} definitions, so the questions {lisp REDEFINE?} and {lisp SAVE EXPRS?} would not be asked if these answers were given. {lisp OUTPUT FILE?} would still be asked, however. For example: {lispcode _COMPILE((FACT FACT1 FACT2)) LISTING? ST OUTPUT FILE? FACT.DCOM (FACT COMPILING) . . (FACT REDEFINED) . . (FACT2 REDEFINED) (FACT FACT1 FACT2) _} This process caused the functions {lisp FACT}, {lisp FACT1}, and {lisp FACT2} to be compiled, redefined, and the compiled definitions also written on the file {lisp FACT.DCOM} for subsequent loading. {index *END* compiler questions} {Begin SubSec Compiler Printout} {Title Compiler Printout} {Text {index *BEGIN* compiler printout} In Interlisp-D, for each function {arg FN} compiled, whether by {fn TCOMPL}, {fn RECOMPILE}, or {fn COMPILE}, the compiler prints: {lisp ({arg FN} ({arg ARG{sub 1}} {ellipsis} {arg ARG{sub N}}) (uses: {arg VAR{sub 1}} {ellipsis} {arg VAR{sub N}}) (calls: {arg FN{sub 1}} {ellipsis} {arg FN{sub N}}))} The message is printed at the beginning of the second pass of the compilation of {arg FN}. {lisp ({arg ARG{sub 1}} {ellipsis} {arg ARG{sub N}})} is the list of arguments to {arg FN}; following "{lisp uses:}" are the free variables referenced or set in {arg FN} (not including global variables); following "{lisp calls:}" are the undefined functions called within {arg FN}. In Interlisp-10, for every function compiled, the compiler prints {lisp ({arg FN} ({arg ARG{sub 1}} {ellipsis} {arg ARG{sub N}}) ({arg FREE{sub 1}} {ellipsis} {arg FREE{sub N}}))}, where {arg FREE{sub 1}} {ellipsis} {arg FREE{sub N}} are the free variables referenced or set in {arg FN}. If the compilation of {arg FN} causes the generation of one or more auxilary functions (see {PageRef Tag CompilingFUNCTION}), a compiler message will be printed for these functions before the message for {arg FN}, e.g., {lispcode (FOOA0027 (X) (uses: XX)) (FOO (A B))} When compiling a block, the compiler first prints {lisp ({arg BLKNAME} {arg BLKFN{sub 1}} {arg BLKFN{sub 2}} {ellipsis})}. Then the normal message is printed for the entire block. The names of the arguments to the block are generated by suffixing "{lisp #}" and a number to the block name, e.g., {lisp (FOOBLOCK (FOOBLOCK#0 FOOBLOCK#1) {arg FREE-VARIABLES})}. Then a message is printed for each {it entry} to the block. In addition to the above output, both {fn RECOMPILE} and {fn BRECOMPILE} print the name of each function that is being copied from the old compiled file to the new compiled file. The normal compiler message is printed for each function that is actually compiled. The compiler prints out error messages when it encounters problems compiling a function. For example: {lispcode ----- In BAZ: ***** (BAZ - illegal RETURN) -----} The above error message indicates that an "{lisp illegal RETURN}" compiler error occurred while trying to compile the function {lisp BAZ}. Some compiler errors cause the compilation to terminate, producing nothing; however, there are other compiler errors which do not stop compilation. The compiler error messages are described on {PageRef Tag CompilerErrors}. Compiler printout and error messages go to the file {var COUTFILE}, initially {lisp T}. {var COUTFILE} can also be set to the name of a file opened for output, in which case all compiler printout will go to {var COUTFILE}, i.e. the compiler will compile "silently." However, any error messages will be printed to both {index COUTFILE Var}{var COUTFILE} as well as {lisp T}. {index *END* compiler printout} }{End SubSec Compiler Printout}