Annotation of 43BSD/contrib/icon/docs/tr83-10b.roff, revision 1.1.1.1

1.1       root        1: .de Ip
                      2: .IP \\$1
                      3: .br
                      4: ..
                      5: .nr $1 3
                      6: .nr $2 7
                      7: .nr $3 0
                      8: .NH 3
                      9: \*Miconx/start.s\fR
                     10: .SH
                     11: Overview
                     12: .PP
                     13: The routine \*Mmstart\fP in \*Mstart.s\fP is used to get Icon started.
                     14: When the Icon interpreter is executed,\^ the C routine \*Mmain\fP passes
                     15: control to \*Mmstart\fP,\^ and merely serves as a front-end for \*Mmstart\fP.
                     16: .SH
                     17: Generic Operation
                     18: .Ls
                     19: .Np
                     20: Call the routine \*Minit\fR with the name of the
                     21: file to interpret as its argument.
                     22: .Np
                     23: Make an Icon list out of the command line arguments using
                     24: the \*Mllist\fR function.
                     25: .Np
                     26: Invoke the main procedure of the Icon program.
                     27: .Le
                     28: .SH
                     29: \*Mstart\fP on the VAX
                     30: .PP
                     31: There is a short main program in \*Miconx/main.c\fP that calls \*Mmstart\fP
                     32: with two arguments:
                     33: .Ds
                     34: .S1
                     35:        main(argc, argv)
                     36:        int argc;
                     37:        char **argv;
                     38:        {
                     39:                mstart(argc, argv);
                     40:        }
                     41: .De
                     42: .PP
                     43: The number of command line arguments is in \*Margc\fP, and \*Margv\fP is a
                     44: pointer to an array of pointers to strings representing the arguments.
                     45: \*Margv\^[0]\fP is the command used to invoke the interpreter and \*Margv\^[1]\fP
                     46: is the name of the file being interpreted.  Additional command line arguments
                     47: are passed along to the main procedure of the Icon program.  When
                     48: \*Mmstart\fP gets control, \*M4(ap)\fP is the \*Margc\fP value and 
                     49: \*M8(ap)\fP is the argv value.
                     50: .PP
                     51: The first action taken by \*Mmstart\fP is to call \*Minit\fR to initialize the
                     52: Icon run-time system.  \*Minit\fR loads the header and code portions of
                     53: the interpretable file into memory,\^ so \*Minit\fR needs the
                     54: name of the interpretable file.  The word at \*M8(ap)\fP is loaded into
                     55: \*Mr9\fP, pointing it at \*Margv\^[0]\fP.  Then the name of the file to interpret
                     56: (\*Margv\^[1]\fP), residing at \*M4(r9)\fP, is pushed on the stack as the
                     57: argument for \*Minit\fP, which is then called.
                     58: .PP
                     59: In order to provide conformity with the usual execution environment
                     60: of Icon procedures,\^ an expression frame is created for the execution
                     61: of the main procedure.  Both the old expression frame pointer and the
                     62: old generator frame pointer are set to be 0 in the expression frame
                     63: for \*Mmain\fP.  The failure label must point to an interpreter opcode that
                     64: will terminate execution of the program.  The opcode 0 is used
                     65: for this purpose.  A word of storage,\^ \*Mflab\fR,\^ is declared and
                     66: initialized to 0.  The failure label points to \*Mflab\fR.  Thus,\^ if
                     67: \*Mmain\fP fails,\^ the interpreter executes the \*Mquit\fR opcode.
                     68: .PP
                     69: The next task is to push the descriptor for the procedure main
                     70: on the stack for later use by \*Minvoke\fR.  The variable
                     71: \*M_globals\fR contains the address of the list of global variable
                     72: descriptors.
                     73: The first global variable descriptor is always the one for the
                     74: procedure main; if no main procedure was found when the program
                     75: was linked,\^ the descriptor
                     76: will be \*M&null\fR.  The value of \*M_globals\fR is loaded into
                     77: \*Mr0\fR and the word then referenced by \*Mr0\fR is checked to see if it
                     78: is equal to \*MD_PROC\fR.  (The first word of a descriptor for a procedure
                     79: is always equal to \*MD_PROC\fR.)
                     80: .\"\^[? not sure if we really need to check for D_PROC,\^
                     81: .\"I think just checking for ~= 0 will suffice.]
                     82: If the word is not equal
                     83: to \*MD_PROC\fR,\^ a branch is made to \*Mnomain\fR which generates
                     84: the appropriate run-time error.  Otherwise,\^ the descriptor
                     85: for \*Mmain\fP is pushed onto the stack.  (The effect of the instruction
                     86: \*Mmovq\ (r0),\^\-(sp)\fR
                     87: is to move 8 bytes (the size of a quadword)
                     88: starting at the address referenced by \*Mr0\fR to the
                     89: 8 bytes referenced by the \*Msp\fR after subtracting 8 from the
                     90: \*Msp\fR.)
                     91: .PP
                     92: The main procedure is to be invoked with a list consisting of the command
                     93: line arguments (if any).  The Icon run-time routine \*Mllist\fR is used to
                     94: make the list that is passed to the main procedure.  \*Mllist\fR stores
                     95: the descriptor for the list that it creates in the descriptor above its
                     96: first argument descriptor,\^ so to accommodate the result,\^ a null descriptor
                     97: is pushed on the stack using the \*Mclrq\fR instruction.  Note that
                     98: because \*Mllist\fP calls \*Msetbound\fP and \*Mclrbound\fP,\^ it is not
                     99: possible to execute all of \*Mstart\fP until \*Mrt/setbound.s\fP has been
                    100: completed.
                    101: .PP
                    102: At the beginning of this routine,\^ \*Mr9\fR was set to point
                    103: at the first word of the argument list.
                    104: Neither the name of the Icon interpreter nor the name of the interpretable
                    105: file is desired in the argument list passed to main,\^ so \*Mr9\fR is
                    106: twice incremented by 4 (the size in bytes of a word)
                    107: to point it at the first actual program argument.
                    108: .PP
                    109: The next step is to construct the argument list for \*Mllist\fR.  For
                    110: each command line argument,\^ the address of the string and then its
                    111: length are pushed on the stack.  The length and address pairs form
                    112: descriptors that \*Mllist\fP makes an Icon list from.
                    113: \*Mr8\fR is used to count the arguments.
                    114: After the addresses and lengths of each argument have been pushed,\^ the
                    115: number of arguments is pushed on the stack.
                    116: At this point,\^ the stack looks like this:
                    117: .Ds
                    118: .ft R
                    119: .S1
                    120:        descriptor for main procedure (2 4-byte words)
                    121:        a null descriptor (2 words containing 0)
                    122:        address of first argument to Icon program
                    123:        length of first argument
                    124:        \*(El
                    125:        address of last argument to Icon program
                    126:        length of last argument
                    127: \*Msp\fR \*(ar number of arguments
                    128: .De
                    129: .LP
                    130: All addresses and lengths are one word in size.  The \*Mcalls\fR
                    131: instruction needs to be told how many words are in its argument list.
                    132: (This is necessary because when a return is made from the subroutine,\^
                    133: the specified number of words are removed from the stack.)  There
                    134: are two words for each argument and an additional word for the number
                    135: of arguments.  (Do not confuse the argument count for the \*Mllist\fR
                    136: subroutine and the argument list size.)
                    137: \*Mr8*2+1\fP is calculated in \*Mr8\fP.  This value is used
                    138: as the argument list length for the \*Mcalls\fR instruction.
                    139: When \*Mllist\fR returns,\^ the arguments are stripped from the
                    140: stack and the stack looks like this:
                    141: .Ds
                    142: .ft R
                    143: .S1
                    144:        descriptor for main procedure
                    145: \*Msp\fR \*(ar descriptor for list of command line arguments
                    146: .De
                    147: .LP
                    148: Note that the null descriptor pushed earlier received the result of
                    149: the \*Mllist\fR function.
                    150: .PP
                    151: At this point,\^ the main procedure is ready to be invoked.  The descriptor for
                    152: the main procedure is \*(a0 and the descriptor for the list of
                    153: command line arguments is \*(a1.  Before invoking the main procedure,\^
                    154: the procedure frame pointer and the generator frame pointer are cleared.
                    155: The main procedure is being invoked with one argument,\^ so a constant
                    156: 1 is pushed on the stack.  The \*Mcalls\fR instruction is given an
                    157: argument of 3 because a word is used for the number of arguments and
                    158: two additional words are used for the descriptor for the list of command
                    159: line arguments.
                    160: .PP
                    161: If the main procedure fails,\^ the interpreter will encounter the
                    162: 0 opcode discussed earlier.  If the main procedure returns (this
                    163: usually isn't done),\^ the return will manifest itself as \f3invoke\fR
                    164: returning.  If this happens,\^ \*M_c_exit\fR is called with an
                    165: argument of 0.  Incidentally,\^ this also happens when the interpreter
                    166: hits the 0 opcode.
                    167: .PP
                    168: There is a block of code labeled \*Mnomain\fR that is executed when
                    169: no main procedure is found.  This calls the routine \*Mrunerr\fR to
                    170: produce an error message.  The actual call made is \*Mrunerr(117,\^0)\fR.
                    171: The number 117 is looked up in a table of run-time errors.  If the second
                    172: argument to \*Mrunerr\fR is non-zero,\^ it is interpreted as being the
                    173: address of a descriptor and the descriptor is examined to produce
                    174: an ``offending value'' to accompany the run-time error.
                    175: .PP
                    176: The last portion of executable code in \f3start.s\fR is the subroutine
                    177: \*M_c_exit\fR.  If the variable \*M_monres\fR is non-zero,\^ it indicates
                    178: that profiling is on,\^ and it must be turned off.  This is accomplished
                    179: by calling \*M_monitor(0)\fR.  The routine \*M__cleanup\fR is then
                    180: called to shut down the i/o system.  Finally,\^ \*M_exit\fR is called
                    181: with the argument of \*M_c_exit\fR to terminate execution of the
                    182: Icon interpreter.
                    183: .PP
                    184: There are several data declarations in \*Mstart.s\fR.  The first data
                    185: declaration is a \*M.space 60\fR.  This is an accommodation for the
                    186: garbage collector.  It
                    187: insures that enough of the start of the data section
                    188: is used up to force the addresses of other data objects to be
                    189: greater than the defined constant \*MMAXTYPE\fR in \f3h/rt.h\fR.
                    190: .PP
                    191: Some assorted declarations are next. \*Mflab\fR is referenced
                    192: by the interpreter if the main procedure fails.  It must be at
                    193: least a byte long and contain a 0.  \*M_boundary\fR must be a
                    194: word long and contain a 0.  \*M_environ\fR must be a word long;
                    195: its contents are unimportant as it is written into at the beginning
                    196: of \*Mstart.s\fR.
                    197: .PP
                    198: The \*M_tended\fR array is also used in conjunction with garbage
                    199: collection.  It must declare space for five descriptors (two words
                    200: per descriptor) that are initialized to 0.
                    201: .\"\^[?]
                    202: The label \*M_etended\fR
                    203: is used to mark the end of the \*M_tended\fR array.
                    204: .ne 1i
                    205: .NH 3
                    206: \*Mrt/setbound.s\fR
                    207: .SH
                    208: Overview
                    209: .PP
                    210: \*Msetbound.s\fP contains code for \*Msetbound\fP and \*Mclrbound\fP.
                    211: \*Msetbound\fP sets \*M_boundary\fP under appropriate conditions and
                    212: \*Mclrbound\fP clears \*M_boundary\fP under appropriate conditions.
                    213: .SH
                    214: Generic Operation
                    215: .PP
                    216: When a call is made from Icon into C,\^ \*M_boundary\fP must be set to point
                    217: at the procedure frame on the top of the stack.  C routines that can
                    218: be called from Icon have a call to \*Msetbound\fP as their first
                    219: operation.  If \*Msetbound\fP is called and \*M_boundary\fP is not
                    220: set,\^ that is,\^ \*M_boundary\fP has a value of zero,\^ \*Mboundary\fP is
                    221: set to value of the \*Mfp\fP of the calling procedure.
                    222: .PP
                    223: When a C routine returns to Icon,\^ \*M_boundary\fP must be cleared.
                    224: If \*M_boundary\fP has the same value as \*Mfp\fP,\^ the routine was
                    225: called from Icon and thus when it returns,\^ it returns to Icon.
                    226: At appropriate return points in routines,\^ a call to \*Mclrbound\fP is
                    227: made.  If the return takes control back to Icon,\^ \*M_boundary\fP
                    228: is cleared.
                    229: .SH
                    230: \*Msetbound\fP on the VAX
                    231: .PP
                    232: The value of \*M_boundary\fP is tested.  If \*Mboundary\fP is not set,\^
                    233: that is,\^ if it has a value of zero,\^ it is set to the value of the
                    234: \*Mfp\fP in the calling procedure.  Because the call to
                    235: \*Msetbound\fP creates a procedure frame,\^ the \*Mfp\fP value saved in
                    236: the frame is used.  If \*M_boundary\fP is already set,\^ it is not
                    237: changed.
                    238: .SH
                    239: \*Mclrbound\fP on the VAX
                    240: .PP
                    241: The value of \*M_boundary\fP is compared to the \*Mfp\fP in the
                    242: calling procedure.  If the values are the same,\^ the calling procedure
                    243: was called from Icon and when it returns it returns to Icon.
                    244: If this is the case,\^ \*M_boundary\fP is cleared.
                    245: .SH
                    246: An Alternative Approach
                    247: .PP
                    248: If the C system on the target machine uses calls at the beginning and
                    249: end of C routines to save and restore registers,\^ it is possible to
                    250: modify these routines to set and clear the boundary.  This approach is
                    251: used on the PDP-11.
                    252: .PP
                    253: The file \*Mrt/csv.s\fP contains replacement
                    254: routines for \*Mcsv\fP and \*Mcret\fP.  When \*Mcsv\fP is called to
                    255: save registers,\^ if \*M_boundary\fP is 0,\^ \*Msp\fP is saved in
                    256: \*M_boundary\fP.  This insures that the first call from Icon into C
                    257: leaves \*M_boundary\fP at the top of the stack at that point.
                    258: When \*Mcret\fP is called to restore registers,\^ if the procedure
                    259: frame pointer is equal to \*M_boundary\fP,\^ the return is taking
                    260: control back to Icon code and \*M_boundary\fP is cleared.
                    261: .PP
                    262: Note the resemblance between calling \*Msetbound\fP at the start of a
                    263: C routine and having \*Mcsv\fP set \*M_boundary\fP whenever a C routine
                    264: is entered.  Similarly,\^ there is a resemblance between calling
                    265: \*Mclrbound\fP at appropriate points and having \*Mcret\fP clear
                    266: \*M_boundary\fP when necessary.
                    267: .PP
                    268: The initial implementation of Icon was on the PDP-11 and the modified
                    269: \*Mcsv\fP and \*Mcret\fP approach was used.  When the system was
                    270: ported to the VAX,\^ the subsumption of \*Mcsv\fP and \*Mcret\fP by the
                    271: hardware required that a software approach be taken.  The trade-offs
                    272: are marginal if the target machine uses save and restore routines.
                    273: Having a distinct \*Msetbound\fP and \*Mclrbound\fP may be easier to
                    274: implement,\^ but using modified save and restore routines is
                    275: definitely faster.
                    276: .PP
                    277: If this approach is used,\^ then \*MSetBound\fP and \*MClearBound\fP in
                    278: \*Mrt.h\fP should be defined,\^ but given no value.
                    279: .NH 3
                    280: \*Mlib/invoke.s\fR
                    281: .SH
                    282: Overview
                    283: .LP
                    284: \*Minvoke.s\fP handles four specific tasks.  These are
                    285: .Ds
                    286: .ft R
                    287: call a built-in function
                    288: call an Icon procedure
                    289: create a record
                    290: perform mutual evaluation
                    291: .De
                    292: .LP
                    293: Note that all of these operations rise from a source code
                    294: expression of the form
                    295: .Ds
                    296: \*(e0(\*(e1,\^\*(El,\^\*(en)
                    297: .De
                    298: where each \*(ai is an expression of some type.
                    299: Icon has strict left-to-right evaluation and thus,\^ for the preceding
                    300: expression,\^ \*(e0 is evaluated first,\^ then \*(e1,\^ and so forth
                    301: through \*(en.  As each expression is evaluated,\^ its result
                    302: is pushed on the stack.  After the expressions have been evaluated
                    303: (and assuming none failed),\^ the stack looks something like
                    304: .Ds
                    305: .ft R
                    306: .S1
                    307:        value from \*(e0
                    308:        value from \*(e1
                    309:        \*(El
                    310:        value from \*(ei
                    311:        \*(El
                    312: \*Msp\fR \*(ar value from \*(en
                    313: .De
                    314: Then,\^ \*(e0 is \fIinvoked\fP.
                    315: .PP
                    316: Recall that stacks are represented as growing downward.  Thus,\^
                    317: \*(en is on the ``top'' of the stack.  Also note that each
                    318: ``value'' on the stack is actually a two-word descriptor.
                    319: .\"The various \*(ei may be referred to as \fIarguments\fP.
                    320: .SH
                    321: Generic Operation
                    322: .PP
                    323: \*Minvoke\fP is an interpreter opcode that takes a single operand
                    324: specifying how many \*(ei are present (\*(e0 is not counted).
                    325: \*Minvoke\fP is also called from \*Mstart.s\fP to invoke the \*Mmain\fP
                    326: procedure.
                    327: .Ls
                    328: .Np
                    329: \*Minvoke\fP must determine whether it is to call a built-in function,\^
                    330: call an Icon procedure,\^ create a record,\^ or perform mutual evaluation.  If
                    331: \*(e0 is not something that can be invoked,\^
                    332: \*Minvoke\fP notes this as a run-time error.
                    333: .Np
                    334: If mutual evaluation is to be done,\^ \*Minvoke\fP selects the
                    335: value of \*(ei that corresponds to the value of \*(e0.  That is,\^
                    336: if \*(e0 is 2,\^ then \*(e2 is selected and returned.  If \*(e0
                    337: references a value that is out of range,\^ \*Minvoke\fP fails.
                    338: .Np
                    339: If an Icon procedure or built-in procedure
                    340: is being called,\^ the argument list is adjusted
                    341: to conform to the number of arguments that the procedure or function
                    342: is expecting.  
                    343: This may mean supplying \*M&null\fP for missing values,\^ or discarding
                    344: the last few \*(ei.  Some built-in functions take a variable number of
                    345: arguments,\^ but all Icon procedures take a fixed number of arguments.
                    346: If the desired operation is creation of a record,\^ \*Minvoke\fP treats
                    347: this just like invocation of a built-in procedure.  
                    348: .Le
                    349: .LP
                    350: Built-in functions and Icon procedures are handled in very different ways.
                    351: If a built-in function is being invoked,\^ it is simply called.  (The
                    352: calling sequence is somewhat convoluted on the VAX and is
                    353: described later.)
                    354: Calling an Icon procedure is more involved; the following actions
                    355: are taken.
                    356: .Ls
                    357: .Np
                    358: Each \*(ei in the (adjusted) argument list is dereferenced.
                    359: .Np
                    360: If \*M&trace\fP has a non-zero value,\^ the function \*Mctrace\fP is
                    361: called with appropriate arguments.  \*Mctrace\fP produces output
                    362: that includes the name of the procedure being called and the arguments
                    363: that are being passed to it.
                    364: .Np
                    365: The remainder of the procedure frame (partially constructed by the
                    366: call itself) is built.  This includes pushing values for \*M_file\fP
                    367: and \*M_line\fP on the stack.  \*M_file\fP is a pointer to a string
                    368: that names the source file from which the code currently being
                    369: executed came.  \*M_line\fP is the number of the source line
                    370: that is currently being executed.  A descriptor for
                    371: \*M&null\fP is pushed on the
                    372: stack for each dynamic local of the procedure.
                    373: .Np
                    374: The generator frame pointer is cleared (because a new expression
                    375: context is being entered).  \*Mipc\fP
                    376: is loaded with the entry point of the procedure being called.
                    377: Control is then passed back to the interpreter using a jump
                    378: instruction.
                    379: .Le
                    380: .SH
                    381: \*Minvoke\fP on the VAX
                    382: .PP
                    383: On the VAX,\^ immediately after \*Minvoke\fP has been entered,\^ the stack is
                    384: .Ds
                    385: .ft R
                    386: .St
                    387:                value from \*(e0
                    388:                value from \*(e1
                    389:                \*(El
                    390:        8       value from \*(en
                    391:        4       number of expressions \- 1 (\*Mnargs\fR)
                    392: \*Map\fR \*(ar 0       number of words in argument list (\*Mnwords\fR)
                    393:        -4      saved \*Mr11\fR
                    394:        -8      saved \*Mr10\fR
                    395:                \*(El
                    396:                saved \*Mr1\fR
                    397:                saved \*Mpc\fR
                    398:        12      saved \*Mfp\fR
                    399:        8       saved \*Map\fR
                    400:        4       program status word and register mask
                    401: \*Msp\fR,\^ \*Mfp\fR \*(ar     0       0 (condition handler address)
                    402: .De
                    403: .PP
                    404: The first action of \*Minvoke\fP is to set \*M_boundary\fP to the
                    405: value of \*Mfp\fP.  This is done because \*Minvoke\fP may be
                    406: invoking a built-in procedure.
                    407: .PP
                    408: The number of arguments with which \*(e0 is to be invoked is contained
                    409: in the \fInargs\fP word,\^ which resides at \*M4(ap)\fP.  This value
                    410: is frequently used and is put into \*Mr8\fP.
                    411: .PP
                    412: \*Minvoke\fP makes
                    413: frequent use of \*(e0,\^ but its address is not a fixed distance
                    414: from any known point.  Rather,\^ the address of \*(e0 must be calculated
                    415: using the address of \*(en and the number of arguments.  The VAX
                    416: \*Mmovaq\fP instruction makes this calculation easy.  The desired
                    417: calculation is
                    418: .Ds
                    419: r11 = 8 + ap + (r8 * 8)
                    420: .De
                    421: and is performed by
                    422: .Ds
                    423: movaq  8(ap)\^[r8],\^r11
                    424: .De
                    425: \*(e0 may be a
                    426: variable and if so,\^ it needs to be dereferenced.
                    427: \*Mr11\fP,\^ which contains the address of \*(e0 is pushed on
                    428: the stack and \*Mderef\fP is called.  The dereferencing is done
                    429: ``in place''; the previous value of \*(e0 is replaced with the
                    430: dereferenced value.  The dereferenced value is a descriptor
                    431: whose first word contains type information and whose second word
                    432: (in some cases) contains the address of a data block which holds
                    433: the actual value of the object.  Note that \*Mr11\fP points to
                    434: the first word of this descriptor.
                    435: .PP
                    436: Recall that the first task of \*Minvoke\fP is to determine what
                    437: \*(e0 is and to act accordingly.  The simplest case is when \*(e0
                    438: is a procedure.  That is checked for by comparing \*M0(r11)\fP with
                    439: \*MD_PROC\fP.  If \*(e0 is a procedure,\^ a forward jump is made to
                    440: \*Mdoinvk\fP.
                    441: .PP
                    442: It is more interesting if \*(e0 is not a procedure.  The first
                    443: alternative investigated is mutual evaluation.  mutual evaluation is similar to a procedure
                    444: call,\^ but rather than \*(e0 being a procedure,\^ it is an integer
                    445: that selects one of the \*(ei.  The selected \*(ei is the outcome of
                    446: the mutual evaluation.  The routine \*Mcvint\fP is used to
                    447: try to convert \*(e0 to an integer.  If \*(e0 cannot be converted to
                    448: an integer,\^ a forward branch is taken to \*Mtrystr\fP to explore another
                    449: possibility.
                    450: For mutual evaluation,\^ a non-positive value of \*(e0
                    451: is acceptable and is converted to a positive value using the
                    452: \*Mcvpos\fP routine.  (Expressions in the argument list are indexed
                    453: the same way that characters in a string are indexed.)  If the
                    454: position is greater than the number of expressions in the list,\^ that
                    455: is,\^ if the reference is out of range,\^ the mutual evaluation fails by calling
                    456: the routine \*Mfail\fP.  If the position is in range,\^ the selected
                    457: \*(ei must be returned as the result of the invocation (and the
                    458: result of the mutual evaluation).  The \*(ei to return is selected by multiplying
                    459: the position by 8 (each \*(ei is a descriptor) and subtracting
                    460: that from \*Mr11\fP,\^ which points at \*(e0.  The descriptor thus
                    461: referenced is copied into the location of \*(e0.  (Recall that \*(e0
                    462: is used to receive the result of an operation.)  \*M_boundary\fP
                    463: is then cleared and \*Minvoke\fP returns.
                    464: .PP
                    465: If \*(e0 is not convertible to an integer,\^ conversion to a
                    466: procedure is attempted.  (Note that this is an experimental extension
                    467: to Icon.)  \*(e0 is first converted to a string
                    468: using \*Mcvstr\fP.  If the conversion is successful,\^ the routine
                    469: \*Mstrprc\fP is called to see if the string ``names'' a procedure.
                    470: The conversion performed by \*Mstrprc\fP is ``in place'',\^ i.e.,\^
                    471: \*(e0 becomes a descriptor for a procedure.  If either the
                    472: conversion in \*Mcvstr\fP or \*Mstrprc\fP fails,\^ \*(e0 is deemed
                    473: to be uninvocable and this is noted by run-time Error 106.
                    474: .PP
                    475: At this point (the label \*Mdoinvk\fP),\^ \*(e0 is a descriptor to a procedure
                    476: to be invoked and \*Mr11\fP points to \*(e0.
                    477: .PP
                    478: The next operation is to make the number of arguments supplied
                    479: conform to the number of arguments that the procedure is expecting.
                    480: The number of arguments that a procedure expects is in the fifth
                    481: word of its procedure block.  This value for the procedure being
                    482: invoked is obtained and placed in \*Mr10\fP.
                    483: If the value is negative,\^ the number
                    484: of arguments that the procedure expects is variable.  Only built-in
                    485: procedures can have a variable number of arguments,\^ so if the
                    486: desired argument count is negative,\^ control passes to the label
                    487: \*Mbuiltin\fP.
                    488: .PP
                    489: \*Mr8\fP contains the number of arguments given and \*Mr10\fP contains
                    490: the number of arguments desired.  The value of \*Mr10\fP is subtracted
                    491: from \*Mr8\fP,\^ leaving \*Mr8\fP with the difference.  If the
                    492: number of arguments supplied is the same as the number expected,\^
                    493: no adjustment is needed and a forward jump is made to
                    494: \*Mdoderef\fP.  Otherwise,\^ the stack must be adjusted.
                    495: .PP
                    496: First,\^ \fInwords\fR and \fInargs\fR on the stack are adjusted.  Recall
                    497: that \fInargs\fR
                    498: is used by Icon and is the number of arguments for a procedure.
                    499: \fInwords\fR is used by the VAX hardware and is the number of words that
                    500: the argument list for a subroutine occupies.  \fInargs\fR resides at
                    501: \*M4(ap)\fP and is updated by storing \*Mr10\fP in \*M4(ap)\fP.
                    502: \fInwords\fR is trickier because only the low-order byte of the \fInwords\fR word
                    503: is to be used for the word count.  The low-order byte of \*Mr10\fP is
                    504: stored in \*M0(ap)\fP,\^ doubled,\^ and then incremented by one.  (The
                    505: increment by one is to allow for the \fInargs\fR word that is part of
                    506: the argument list.)
                    507: .PP
                    508: The deletion of excess arguments or addition of \*M&null\fP for
                    509: missing arguments is accomplished by moving the lower portion of
                    510: the stack up or down to overwrite excess arguments or to leave
                    511: space for missing arguments.  Consider the following:  A procedure
                    512: that expects one argument has been invoked with three arguments.
                    513: The stack is
                    514: .Ds
                    515: .ft R
                    516: .St
                    517:        128     \*(e0
                    518:        120     \*(e1
                    519:        112     \*(e2
                    520:        104     \*(e3
                    521:        100     \*Mnargs\fR (3 at call,\^ 1 after adjustment)
                    522: \*Map\fR \*(ar         96      \*Mnwords\fR (7 at call,\^ 3 after adjustment)
                    523:        92      \*Mr11\fR
                    524:                \*(El
                    525:        48      \*Mr1\fR
                    526:        44      \*Mpc\fR
                    527:        40      \*Mfp\fR
                    528:        36      \*Map\fR
                    529:        32      \*Mpsw\fR
                    530: \*Msp\fR,\^ \*Mfp\fR \*(ar     28      0
                    531: .De
                    532: The situation desired is
                    533: .Ds
                    534: .ft R
                    535:        128     \*(e0
                    536:        120     \*(e1
                    537:        116     \*Mnargs\fR (1)
                    538: \*Map\fR \*(ar         112     \*Mnwords\fR (3)
                    539:        108     \*Mr11\fR
                    540:                \*(El
                    541:        64      \*Mr1\fR
                    542:        60      \*Mpc\fR
                    543:        56      \*Mfp\fR
                    544:        52      \*Map\fR
                    545:        48      \*Mpsw\fR
                    546: \*Msp\fR,\^ \*Mfp\fR \*(ar     44      0
                    547: .De
                    548: Note the address field (which has been arbitrarily assigned).
                    549: Observe that \*(e0 and \*(e1 are in
                    550: the same place,\^ but that the lower portion of the stack has moved up.
                    551: Consider what would be desired if the
                    552: procedure being invoked requires five arguments and only three are
                    553: supplied.  The desired stack configuration is
                    554: .Ds
                    555: .ft R
                    556: .St
                    557:        128     \*(e0
                    558:        120     \*(e1
                    559:        112     \*(e2
                    560:        104     \*(e3
                    561:        96      \*M&null\fP (\*(e4)
                    562:        88      \*M&null\fP (\*(e5)
                    563:        84      \*Mnargs\fR (5)
                    564: \*Map\fR \*(ar         80      \*Mnwords\fR (11)
                    565:        76      \*Mr11\fR
                    566:                \*(El
                    567:        32      \*Mr1\fR
                    568:        28      \*Mpc\fR
                    569:        24      \*Mfp\fR
                    570:        20      \*Map\fR
                    571:        16      \*Mpsw\fR
                    572: \*Msp\fR,\^ \*Mfp\fR \*(ar     12      0
                    573: .De
                    574: As before,\^ the ``good'' arguments are in the same place,\^ but the
                    575: stack has moved down to make room for \*(e4 and \*(e5 and a value
                    576: of \*M&null\fP is supplied for them.
                    577: .PP
                    578: The VAX hardware makes these stack manipulations easy.  Recall that
                    579: \*Mr8\fP contains
                    580: .Ds
                    581: .ft R
                    582: number of arguments expected \- number of arguments supplied
                    583: .De
                    584: Thus,\^ in the first case \*Mr8\fP has a value of 2,\^ while in the second
                    585: case \*Mr8\fP is \-2.  The value of \*Mr8\fP is multiplied by
                    586: 8 to turn the argument count into a byte count.  This byte count
                    587: is added to \*Msp\fP,\^ effectively moving it to where it should
                    588: be.  Now,\^ a block of memory starting at where \*Mfp\fP points
                    589: must be moved to where \*Msp\fP points.  The size of the
                    590: block needs to be considered.  It starts at the fp and contains
                    591: the condition handler,\^ the old psw,\^ \*Map\fP,\^ \*Mfp\fP and \*Mpc\fP
                    592: \(em five words.
                    593: Eleven saved registers are included; eleven more words. (A constant,\^
                    594: \*MINVREGS\fP,\^ is used to represent the number of saved registers.)
                    595: Finally,\^ two words for \fInargs\fR and \fInwords\fR \(em a total of 18
                    596: words.  The VAX
                    597: instruction that makes the move is
                    598: .Ds
                    599: movc3  $(INVREGS+7)*4,\^(fp),\^(sp)
                    600: .De
                    601: which moves 18*4 (=72) bytes from where \*Mfp\fP is pointing to
                    602: where \*Msp\fP pointing.  The VAX allows the source and
                    603: destination fields to overlap without producing ``curious'' results.
                    604: .PP
                    605: Some housekeeping must be performed after the move is made.
                    606: \*Mfp\fP is set to point to the same word \*Msp\fP points to,\^
                    607: and the boundary is set to point to the same place.  \*Map\fP is
                    608: adjusted to point to the \fInwords\fR word.
                    609: .PP
                    610: If arguments were deleted,\^ the adjustment process is done.  If
                    611: arguments were added,\^ \*M&null\fP must be supplied as the value
                    612: for each argument that was added.  Because the descriptor for
                    613: \*M&null\fP consists of two words containing 0,\^ the task amounts to filling
                    614: in null bytes in the ``hole'' that was made.  \*Mr8\fP contains
                    615: the number of bytes in the ``hole''.  \*Mr8\fP is negative and it
                    616: is negated to obtain a positive byte count.  The instruction
                    617: .Ds
                    618: movc5  $0,\^(r0),\^$0,\^r8,\^(INVREGS+7)*4(sp)
                    619: .De
                    620: does all the work.  Specifically,\^ this instruction moves bytes of zeroes
                    621: starting at \*M(r0)\fP to a field that starts at \*M72(sp)\fP and
                    622: extends for \*Mr8\fP bytes.  The third operand of the instruction
                    623: is a ``fill character'' that is used in the event that the destination
                    624: field is longer than the source field.  In this case,\^ the source
                    625: field is 0 bytes long,\^ and a null-byte fill character is moved into
                    626: each byte of the destination field.  This is the usual way to zero
                    627: out a block of memory on the VAX.
                    628: .PP
                    629: At this point,\^ the correct number of arguments for the procedure
                    630: are on the stack.
                    631: .PP
                    632: For an Icon procedure,\^ all arguments must be dereferenced before
                    633: the procedure is called.  Procedure blocks have a field that tells
                    634: how many dynamic local variables the procedure has.  For built-in
                    635: procedures this field has a value of \-1.  If a built-in procedure
                    636: is to be invoked,\^ control jumps to the label \*Mbuiltin\fP.
                    637: If an Icon procedure is to be invoked,\^ but it has no arguments (and
                    638: thus they do not need to be dereferenced),\^ a forward jump is made
                    639: to \*Mcktrace\fP.
                    640: .PP
                    641: \*Mr11\fP points to the descriptor for \*(e0.  The address of \*(e1
                    642: is used later in \*Minvoke\fP,\^ and its address is calculated using \*Mr11\fP
                    643: because it's handy.  \*Mr10\fP contains the number of arguments and
                    644: this value is stored in \*Mr5\fP for subsequent use of \*Mr5\fP as a
                    645: counter.  The arguments must be dereferenced,\^ this is done by calling
                    646: \*Mderef\fP with the address of each argument.  The instruction
                    647: .Ds
                    648: pushaq  -(r11)
                    649: .De
                    650: is used to decrement \*Mr11\fP by 8 and then push the value of \*Mr11\fP
                    651: on the stack.  Because \*Mr11\fP initially references \*(e0,\^ the first
                    652: time through \*Mr11\fP is decremented to point at \*(e1 and
                    653: \*Mderef\fP is called with the address of \*(e1.  \*Mr11\fP is backed
                    654: down through the expression list,\^ with each \*(ei being dereferenced
                    655: in turn.  Note that the \*Msobgeq\fP instruction is used as a loop
                    656: controller,\^ decrementing \*Mr5\fP and jumping back to \*Mnxtarg\fP as
                    657: long as \*Mr5\fP is not 0.
                    658: .PP
                    659: At this point,\^ an Icon procedure is being
                    660: invoked; it has the correct number of arguments and they
                    661: have been dereferenced.
                    662: .PP
                    663: If tracing is on,\^ (indicated by a non-zero value for \*M_k_trace\fP),\^
                    664: a trace message must be produced at this point.
                    665: The routine \*Mctrace\fP does all the work.  It needs to be called
                    666: with the appropriate arguments.  \*Mctrace\fP requires three
                    667: arguments: procedure block address,\^ number of arguments,\^ and the
                    668: address of the first argument.  These are pushed on the stack and
                    669: \*Mctrace\fP is called.
                    670: .PP
                    671: The portion of the stack from \*(e0 on down constitutes a partial
                    672: procedure frame and it must be completed.  \*M_line\fP and \*M_file\fP
                    673: are pushed on the stack.  To complete the frame,\^ the local variables
                    674: must be pushed on the stack.  Local variables have an initial value
                    675: of \*M&null\fP,\^ and the \*Mmovc5\fP idiom used previously is used
                    676: again to zero out the space required for the local variables.
                    677: .PP
                    678: Because an Icon procedure is being invoked,\^ the boundary is cleared and
                    679: \*M_k_level\fP (the \*M&level\fP keyword) is incremented.  The entry
                    680: point for a procedure is stored in the third word of the procedure
                    681: block.  This value is loaded into \*Mipc\fP.
                    682: A new expression context is being entered,\^ and both
                    683: \*Mgfp\fP and \*Mefp\fP are cleared using a \*Mclrq\fP instruction.
                    684: .PP
                    685: Control is passed back to the main loop of the interpreter
                    686: by jumping to \*Minterp\fP.
                    687: The Icon procedure is now being executed.  The procedure
                    688: eventually terminates by use of \*Mpret\fP or \*Mpfail\fP.
                    689: .LP
                    690: The section of code following \*Mbuiltin:\fP
                    691: handles the case where a built-in procedure is to be invoked.
                    692: .PP
                    693: If nothing is changed,\^ when a built-in function returns,\^ it would
                    694: return to the instruction after the call to \*Minvoke\fP.  This
                    695: is unsatisfactory,\^ since the boundary needs to be cleared because
                    696: of the transition from the C environment to the Icon environment.
                    697: Rather than having a call to \*Mclrbound\fP at
                    698: the end of each built-in procedure,\^ the boundary is cleared at
                    699: a common return point.
                    700: .PP
                    701: The \*Mpc\fP value that is stored at \*M16(fp)\fP is ``hidden''
                    702: at \*M20(fp)\fP where the value of \*Mr1\fP should be saved.
                    703: \*M16(fp)\fP is replaced with the address of the forward label
                    704: \*Mbprtn\fP.  Thus,\^ when the built-in procedure returns,\^ it goes
                    705: right to \*Mbprtn\fP.  Because a C environment is being entered,\^
                    706: the boundary is set to the current value of \*Mfp\fP.  The third
                    707: word of the procedure block contains the entry point of the built-in
                    708: procedure and it is jumped to.  It is important to understand that
                    709: the procedure is not called because the call frame has already been
                    710: constructed.  Also,\^ the entry point address stored in the procedure
                    711: block \fImust\fR be past any instructions that are used to establish
                    712: the stack environment for the routine because this environment
                    713: should already be on the stack.
                    714: .PP
                    715: When the built-in procedure returns,\^ it comes to \*Mbprtn\fP.
                    716: The boundary is cleared because execution is back in an Icon
                    717: environment. The procedure return restores \*Mr1\fP,\^ which contains
                    718: the \*Mpc\fP value that \*Minvoke\fP should return to.  Because
                    719: the return has already swept off the old frame,\^ \*M0(r1)\fP is
                    720: jumped to and \*Minvoke\fP is finished.  Note that the built-in
                    721: procedure has left its result in \*(e0,\^ which is left on the
                    722: stack.  Thus,\^ the direct result of \*Minvoke\fP is an additional
                    723: value on the stack.
                    724: .SH
                    725: Some Comments on \*Minvoke\fR
                    726: .PP
                    727: It is important to understand the purpose of \*Minvoke\fP.  Unless
                    728: mutual evaluation is being performed,\^
                    729: the task of \*Minvoke\fP is to create a procedure frame for an Icon or
                    730: built-in procedure and then transfer control to the procedure.
                    731: .PP
                    732: On the VAX and the PDP-11,\^ the call to \*Minvoke\fP partially
                    733: creates the procedure frame.  \*Minvoke\fP then completes the
                    734: frame.  For Icon procedures,\^ control eventually passes out of
                    735: \*Minvoke\fP and goes back to the interpreter loop.  However,\^
                    736: for built-in procedures,\^ after the frame is built,\^ \*Minvoke\fP
                    737: \fIbranches into\fP the C code for the procedure.  Thus,\^ it appears
                    738: that the built-in procedure was called directly.  This scheme is
                    739: facilitated by the fact that entry points of C routines on the
                    740: VAX and PDP-11 are a constant distance from the start of the routine.
                    741: (The \*MEntryPoint\fP macro in \*Mrt.h\fP specifies the distance.)
                    742: On some machines this may not be practical and other schemes may need
                    743: to be developed.
                    744: .PP
                    745: Another point that needs to be addressed is that of argument removal.
                    746: When a built-in procedure,\^ Icon procedure,\^ or built-in operation is
                    747: performed,\^ the net result almost always is
                    748: simply the addition of a descriptor to the stack.  More precisely,\^
                    749: the new descriptor is actually a replacement for \*(a0,\^ which
                    750: is the descriptor for the procedure being called,\^ or in the case
                    751: of a built-in operation is \*M&null\fP.  Recall that arguments are below \*(a0
                    752: on the stack.  The \*(a0 word must be on top of the
                    753: stack when a procedure or operation is complete.  The VAX does
                    754: this via hardware,\^ which manages the stack and removes arguments when
                    755: a procedure call is complete.  The PDP-11 does not have such hardware
                    756: facilities and thus the arguments must be removed manually.  The
                    757: problem is compounded by the fact that for built-in operations,\^
                    758: \*Minvoke\fP is never called; rather,\^ the interpreter loop calls the
                    759: appropriate subroutine directly.
                    760: .PP
                    761: The method employed on the PDP-11 uses the \*Mcret\fP routine to
                    762: remove arguments.  \*Mcret\fP is called at the end of each C routine
                    763: to restore registers.  Icon has a replacement for \*Mcret\fP that
                    764: restores registers but also removes arguments when appropriate.
                    765: \*Mrt/csv.s\fP contains the replacement routine.  When \*Mcret\fP is
                    766: called,\^ if \*Mr5\fP (the \*Mpfp\fP on the PDP-11) is equal to
                    767: \*M_boundary\fP,\^ then \*Mcret\fP is returning to Icon code and any
                    768: arguments on the stack are removed,\^ leaving \*(a0 on the top of the
                    769: stack.
                    770: A similar technique may be needed on the target machine.
                    771: .PP
                    772: \*Mrt/csv.s\fP also contains a replacement for the \*Mcsv\fP routine
                    773: which saves registers upon entry to C functions
                    774: on the PDP-11.  Both \*Mcsv\fP and \*Mcret\fP also contain code that
                    775: is used to set and clear the boundary at appropriate times.  See
                    776: the description of \*Mrt/setbound.s\fP for more details.
                    777: .NH 3
                    778: \*Miconx/interp.s\fR
                    779: .SH
                    780: Overview
                    781: .PP
                    782: \*Minterp.s\fP is the main loop for the interpreter.
                    783: The execution of an Icon program is stack based.
                    784: As the interpreter executes an Icon program,\^ it
                    785: fetches instructions and accompanying operands out of the instruction
                    786: stream of the interpretable file.  Operands for
                    787: interpreter instructions are pushed on the stack and results
                    788: accumulate on the stack as operands for other instructions.
                    789: In addition to simple incremental and decremental stack changes,\^
                    790: the expression evaluation mechanism may cause portions of the
                    791: stack to be duplicated and may also cause the top portion of
                    792: the stack to be removed.
                    793: .SH
                    794: Generic Operation
                    795: .PP
                    796: An Icon program is executed by interpreting the interpretable file
                    797: produced by the linker.  The interpretation process itself is fairly
                    798: simple.  \*Mipc\fP points at the next
                    799: instruction to be executed.  (Recall that the interpretable file is
                    800: loaded into memory.)  The opcode of the instruction is fetched
                    801: and the corresponding
                    802: word in the jump table is taken as the address of a sequence of
                    803: instructions that perform the desired operations.  A branch is
                    804: taken to the referenced location and the operation is performed.
                    805: The operation may require operands; if so,\^ they appear in the
                    806: instruction stream following the opcode.  The segment of code that
                    807: performs a particular operation is responsible for fetching the
                    808: appropriate operands out of the stream.  When the
                    809: operation is complete,\^ a jump is taken to the top of the interpreter
                    810: loop and the process continues.
                    811: .PP
                    812: Interpreter operations are of two types.  Operations of the first type
                    813: call a routine to perform a task.  Operations of the second type are
                    814: executed entirely by the interpreter; no subroutine call is necessary.
                    815: .PP
                    816: Operations that require a call to be made call routines in the
                    817: \*Moperators\fP or \*Mlib\fP directories.  The routine being called
                    818: may require one or more arguments.  If arguments are required,\^ they
                    819: appear on the stack.  When the routine returns,\^ it removes
                    820: any arguments that it was called with from the stack and leaves its
                    821: result on the top of the stack.
                    822: .PP
                    823: To facilitate the calling of
                    824: routines,\^ a table known as \*Moptab\fP parallels the jump table.
                    825: An opcode \fIn\fP references the \fIn\fPth word of the jump table.
                    826: If the operation designated by the opcode requires a call,\^ the
                    827: \fIn\fPth word of \*Moptab\fP contains the address of the routine
                    828: that should be called.
                    829: .PP
                    830: The interpreter saves space in its
                    831: instruction stream by encoding operand information in some opcodes.
                    832: For example,\^ the \*Mline\fP instruction has one operand that
                    833: is used to set the value of \*M_line\fP,\^ the current source line
                    834: number.  The \*Mlinex\fP instruction is an alternate form of
                    835: \*Mline\fP which encodes the line number as the low order bits of the
                    836: opcode.  Specifically,\^ the opcodes from 192 to 256 are \*Mlinex\fP
                    837: opcodes.  For example,\^ opcode 195 is equivalent to a \*Mline\fP
                    838: opcode with an operand of 3.
                    839: .SH
                    840: Implementing the Interpreter Loop
                    841: .PP
                    842: \*Minterp.s\fP stands alone among the assembly language files as one that is
                    843: well suited to coding in a macro fashion.  Most of the interpreter loop is
                    844: written in terms of \fIcpp\fP macros and thus porting it is largely a
                    845: matter of writing the macros for the target machine.
                    846: .LP
                    847: The following \*M#define\fPs must be made.
                    848: .Ip \*MOp\ \ \ \ \ \fP
                    849: .br
                    850: The operand register.  Any general purpose register will do.  The
                    851: value of the register need not preserved between instructions; its
                    852: lifetime is only from the time that an operand is fetched until the
                    853: next opcode is fetched or a routine is called.
                    854: .Ip \*MGetOp\fP
                    855: This must expand into code that fetches the next operand out of
                    856: the instruction stream and places it in the register \*MOp\fP.
                    857: Recall that operand size is determined by
                    858: the \*M#define\fP for \*MOPNDSIZE\fP in the linker.
                    859: On the VAX,\^ \*MGetOp\fP is merely
                    860: .Ds
                    861: .ta 0.6i +0.6i +0.6i +0.6i
                    862: movl   (ipc)+,\^Op
                    863: .De
                    864: This is because operands are one word long and can begin on any byte
                    865: boundary.  If the VAX did not support word fetching from arbitrary
                    866: boundaries,\^ it would be necessary to get the bytes from the
                    867: instruction stream one at a time and make a word out of them using
                    868: boolean operations.  If such were the case,\^ a reasonable alternative
                    869: would be to make opcodes one word in size and thus all instruction
                    870: stream objects (opcodes,\^ operands,\^ and words),\^ would be of the same
                    871: size and lie on word boundaries.
                    872: .\".IP \*MGetWord\fP
                    873: .\"\*MGetWord\fP is similar to \*MGetOp\fP,\^ but rather than loading the
                    874: .\"next operand,\^ it loads the next \fIword\fP from the instruction stream into
                    875: .\"the \*MOp\fP register.  Recall that the size of a word is defined by
                    876: .\"the \*MWORDSIZE\fP in the linker.  If words are the same size as
                    877: .\"operands on the target machine,\^ \*MGetWord\fP should be identical to
                    878: .\"\*MGetOp\fP.
                    879: .Ip \*MPushOp\fP
                    880: Push the \*MOp\fP register on the stack.  The VAX uses
                    881: .ta .6i
                    882: .Ds
                    883: pushl  Op
                    884: .De
                    885: .Ip \*MPushNull\fP
                    886: Push a descriptor for \*M&null\fP on the stack.  That is,\^ push two
                    887: words of zeroes.  The VAX \*Mclrq\fP instruction does the trick:
                    888: .Ds
                    889: clrq   -(sp)
                    890: .De
                    891: .Ip \*MPush_R(x)\fP,\^\ \*MPush_S(x)\fP,\^\ \*MPush_K(x)\fP
                    892: Push the value of \*Mx\fP on the stack.  To accommodate machines with
                    893: non-orthogonal instruction sets,\^ \*MPush_R\fP is used to push a register
                    894: value,\^ and \*MPush_S\fP is used to push the contents of a storage
                    895: location.  \*MPush_K\fP is used to push a constant value.
                    896: The VAX uses
                    897: .Ds
                    898: pushl  x
                    899: .De
                    900: for both \*MPush_R(x)\fP and \*MPush_S(x)\fP,\^ while
                    901: .Ds
                    902: pushl  $x
                    903: .De
                    904: is used for \*MPush_K(x)\fP.
                    905: .Ip \*MPushOpSum_R(x)\fP,\^\ \*MPushOpSum_S(x)\fP
                    906: \*MPushOpSum_R(x)\fP adds the value
                    907: of the register \*Mx\fP to \*MOp\fP and pushes the result on the stack.
                    908: \*MPushOpSum_S(x)\fP is similar,\^ adding the value in the memory
                    909: location \*Mx\fP to \*MOp\fP and pushing the result.  On the VAX,\^
                    910: .Ds
                    911: addl3  Op,\^x,\^-(sp)
                    912: .De
                    913: is used for both.
                    914: .Ip \*MNextInst\fP
                    915: Branch to the top of the interpreter loop.  The VAX uses
                    916: .Ds
                    917: jmp    _interp
                    918: .De
                    919: .Ip \*MCallN(n)\fP
                    920: Call the routine corresponding to the current opcode with \*Mn\fP
                    921: arguments.  On the VAX,\^ the opcode fetching segment loads \*Mr0\fP
                    922: with a byte offset into the jump table.  This same byte offset
                    923: references the location in \*Moptab\fP which contains the address
                    924: of the routine which corresponds to the current opcode.
                    925: \*MCallN(n)\fP expands to
                    926: .Ds
                    927: pushl  $n
                    928: calls  $((n*2)+1),\^*optab(r0)
                    929: .De
                    930: \*Mpushl $n\fP pushes the number of arguments on the stack.  This
                    931: word becomes the \fInargs\fP word of the procedure frame.  The
                    932: first of operand of the \*Mcalls\fP instruction is the length of
                    933: words in the argument list,\^ since each argument is a two word
                    934: descriptor and the \fInargs\fP word occupies another word,\^
                    935: \*Mn*2+1\fP is used as the length of the argument list.  The
                    936: address contained in the \*Moptab\fP word referenced by \*Mr0\fP is
                    937: the routine to call.
                    938: .Ip \*MCallNameN(n,\^f)\fP
                    939: Call the routine named \*Mf\fP with \*Mn\fP arguments.  This is very
                    940: similar to \*MCallN\fP,\^ the only difference being that the routine
                    941: to call is explicitly named rather than being implicitly determined
                    942: from the opcode value.  The VAX uses
                    943: .Ds
                    944: pushl  $n
                    945: calls  $((n*2)+1),\^f
                    946: .De
                    947: .Ip \*MBitClear(m)\fP
                    948: The constant value \*Mm\fP designates bits in the \*MOp\fP register
                    949: to leave on.  All other bits in \*MOp\fP should be turned off.  That
                    950: is,\^ the complement of \*Mm\fP is \*MAND\fPed with the contents of
                    951: \*MOp\fP and the result is placed in \*MOp\fP.  This is used to
                    952: decode opcodes with encoded operands.  The VAX uses
                    953: .Ds
                    954: bicl2  $0!m,\^Op
                    955: .De
                    956: .Ip \*MJump(lab)\fP
                    957: Branch to the label \*Mlab\fP.  The destination label is close to the
                    958: jump,\^ so a short jump of some type may be used.  The VAX uses
                    959: .Ds
                    960: jbr    lab
                    961: .De
                    962: .Ip \*MLongJump(lab)\fP
                    963: \*MLongJump\fP is like \*MJump\fP with the exception that \*Mlab\fP
                    964: may be quite distant.  The VAX uses
                    965: .Ds
                    966: jmp    lab
                    967: .De
                    968: .Ip \*MLabel(lab)\fP
                    969: Generate a label declaration for \*Mlab\fP.  The VAX uses
                    970: .Ds
                    971: lab:
                    972: .De
                    973: .SH
                    974: VAX Specific Sections of \*Minterp\fR
                    975: .PP
                    976: Several sections of \*Minterp\fP are machine specific and must be
                    977: coded on a per-machine basis.  The sections in question are explained
                    978: on an individual basis:
                    979: .Ip \*M_interp\fP
                    980: The next opcode is fetched and loaded into \*Mr0\fP.  \*Mmovzbl\fP
                    981: moves a byte and zero extends it to a word value.  Because a byte was
                    982: fetched,\^ \*Mipc\fP is incremented by 1.  The opcode is saved in
                    983: \*MOp\fP in case it contains an encoded operand.  \*Mr0\fP is
                    984: multiplied by 4 to turn it into a byte offset.  A jump is made to the
                    985: address indexed by \*Mr0\fP in \*Mjumptab\fP to perform the desired
                    986: operation.  Eventually,\^ a jump returns control to the label
                    987: \*M_interp\fP to fetch and execute the next instruction.
                    988: .Ip \*Mop_bscan\fP
                    989: A descriptor for \*M_k_subject\fP is pushed on the stack.  Then
                    990: the value of \*M_k_pos\fP is pushed,\^ followed by the constant
                    991: \*MD_INTEGER\fP.  The routine corresponding to \*Mop_bscan\fP,\^
                    992: \*M_bscan\fP,\^ is called with 0 arguments.  (This causes the
                    993: descriptors for \*M_k_subject\fP and the value of \*M_k_pos\fP to be
                    994: left on the stack.)  When \*M_bscan\fP returns,\^ a branch is made to
                    995: \*M_interp\fP.
                    996: .Ip \*Mop_ccase\fP
                    997: A null descriptor is pushed on the stack.  The word immediately
                    998: above the current expression frame is then pushed on the stack.
                    999: .Ip \*Mop_chfail\fP
                   1000: The operand of \*Mchfail\fP is fetched into \*MOp\fP.  \*MOp\fP and
                   1001: \*Mipc\fP are added together and the result replaces the failure
                   1002: address in the current expression frame.
                   1003: .Ip \*Mop_dup\fP
                   1004: A null descriptor is pushed on the stack.  The value that was on top
                   1005: of the stack is now at \*M8(sp)\fP,\^ and it is copied to the top of the
                   1006: stack using a \*Mmovq\fP.
                   1007: .Ip \*Mop_eret\fP
                   1008: \*Meret\fP gets the value on top of the stack,\^ removes the current
                   1009: expression frame and puts the previous top of stack value back on the
                   1010: top of the stack.  First of all,\^
                   1011: .Ds
                   1012: movq   (sp)+,\^r0
                   1013: .De
                   1014: moves the descriptor on the top of the stack into the \*Mr0\-r1\fP
                   1015: register pair and increments the stack pointer by 8.  The \*Mgfp\fP
                   1016: is loaded with the \*Mgfp\fP value stored in the expression frame
                   1017: marker.  \*Msp\fP is loaded from \*Mefp\fP,\^ bringing the expression
                   1018: marker to the top of the stack.  The old \*Mefp\fP value from the
                   1019: marker is loaded into \*Mefp\fP.  Finally,\^ the value stored in the
                   1020: \*Mr0\-r1\fP pair is pushed on the stack.
                   1021: .Ip \*Mop_file\fP
                   1022: The operand of \*Mfile\fP is loaded into \*MOp\fP.  \*MOp\fP and the
                   1023: value of \*M_ident\fP are added and the result in placed in
                   1024: \*M_file\fP.
                   1025: .Ip \*Mop_goto\fP
                   1026: The operand is loaded into \*MOp\fP and then added to \*Mipc\fP.
                   1027: .Ip \*Mop_incres\fP
                   1028: The eighth word of the co-expression heap block for the current
                   1029: expression is incremented by one.
                   1030: .Ip \*Mop_init\fP
                   1031: This one is tricky.  The \*Minit\fP instruction arises from the
                   1032: \*Minitial\fP statement in Icon and is used to effect one-time
                   1033: execution of a segment of code.  The operand of \*Minit\fP is the
                   1034: address of the first instruction after the segment that is to be
                   1035: executed once.  The instruction
                   1036: .Ds
                   1037: movb   $59,\^-(ipc)
                   1038: .De
                   1039: decrements \*Mipc\fP by 1 and then stores the constant 59 in the byte
                   1040: that \*Mipc\fP references,\^ which is the \*Minit\fP opcode.  The magic
                   1041: number 59 is the opcode for \*Mgoto\fP,\^ so in effect,\^ the \*Minit\fP
                   1042: had been made into a goto that skips a section of code.  By adding 5
                   1043: to \*Mipc\fP,\^ it leaves \*Mipc\fP pointing at the first instruction
                   1044: of the \*Minitial\fP code.  The constant 5 is derived from the
                   1045: width of the opcode and associated operand,\^ i.e.,\^
                   1046: \*MOPSIZE+OPNDSIZE\fP.
                   1047: .Ip \*Mop_invoke\fP
                   1048: This section has two entry points: \*Mop_invoke\fP gets control if
                   1049: \*Minvoke\fP has an operand,\^ and \*Mop_invkx\fP gets control if the
                   1050: operand is encoded in the opcode.  If an operand is specified,\^ it is
                   1051: fetched into \*MOp\fP.  If the operand is encoded,\^ \*MBitClear(7)\fP is
                   1052: used to isolate the operand in \*MOp\fP.  Control converges at
                   1053: \*Mdoinvoke\fP.  The operand is the number of arguments to
                   1054: invoke the procedure with and it is pushed on the stack as
                   1055: the \fInargs\fP word.  (The arguments are already on the stack.)
                   1056: The \*Mcalls\fP instruction needs the length of the argument list,\^ so
                   1057: \*MOp\fP is multiplied by 2 and then incremented by 1.  \*Minvoke\fP
                   1058: is called.
                   1059: .Ip \*Mop_int\fP
                   1060: As in \*Mop_invoke\fP,\^ \*Mop_int\fP has a secondary entry point,\^
                   1061: \*Mop_intx\fP,\^ for operands encoded in the opcode.  At the \*Mop_int\fP
                   1062: entry point,\^ a \*MWORDSIZE\fP value is fetched out of the instruction
                   1063: stream and loaded into \*MOp\fP.  At the \*Mop_intx\fP entry point,\^
                   1064: the \*MOp\fP value is decoded from the operand.  The \*MOp\fP value is
                   1065: pushed on the stack and is followed by a \*MD_INTEGER\fP word,\^ forming
                   1066: an integer descriptor.
                   1067: .Ip \*Mop_line\fP
                   1068: Like \*Mop_invoke\fP and \*Mop_int\fP,\^ \*Mop_line\fP has a secondary
                   1069: entry point.  The operand value is obtained and then moved into \*M_line\fP.
                   1070: .Ip \*Mop_llist\fP
                   1071: \*Mllist\fP is similar to \*Minvoke\fP in that it has a number of
                   1072: arguments already on the stack and that the operand specifies the
                   1073: number.  The operand is fetched into \*MOp\fP and pushed on the
                   1074: stack to become the \fInargs\fP argument of \*Mllist\fP.  \*MOp\fP is
                   1075: then multiplied by 2 and incremented by 1 to serve as an argument
                   1076: list size for \*Mcalls\fP.
                   1077: .Ip \*Mop_mark\fP
                   1078: The operand is fetched into \*MOp\fP and \*Mipc\fP is added to it.
                   1079: \*Mefp\fP is pushed on the stack and the new \*Msp\fP value is put in
                   1080: \*Mefp\fP.  \*Mgfp\fP is pushed on the stack and cleared.  \*MOp\fP
                   1081: is pushed on the stack.
                   1082: .Ip \*Mop_mark0\fP
                   1083: Like \*Mop_mark\fP,\^ with an implicit operand value of zero.
                   1084: .Ip \*Mop_pop\fP
                   1085: The two \*Mtstl\fP instructions serve to add 8 to \*Msp\fP which
                   1086: removes the top value from the stack.
                   1087: .Ip \*Mop_sdup\fP
                   1088: The descriptor on the top of the stack is pushed on the stack,\^
                   1089: duplicating it.
                   1090: .Ip \*Mop_unmark\fP
                   1091: The operand,\^ the number of expression frames to remove from the
                   1092: stack,\^ is fetched into \*MOp\fP.  \*Mefp\fP is
                   1093: restored from the current expression frame.  The instruction
                   1094: .Ds
                   1095: sobgtr Op,\^unmkjmp
                   1096: .De
                   1097: decrements \*MOp\fP and then branches to \*Mdounmark\fP if \*MOp\fP is not
                   1098: zero.  This chains through the number of expression frames specified
                   1099: by the operand.  \*Mgfp\fP is restored from the current expression
                   1100: marker.  \*Mefp\fP is loaded into \*Msp\fP to move the expression
                   1101: marker to the top of the stack.  Finally,\^ \*Mefp\fP is restored
                   1102: from the marker and \*Msp\fP is incremented to remove the last word
                   1103: of the marker.
                   1104: .Ip \*Mop_unmk1-7\fP
                   1105: Similar to \*Munmark\fP,\^ but uses successive restorations of
                   1106: \*Mefp\fP rather than a loop.
                   1107: .Ip \*Mop_global\fP
                   1108: Dual entry points are used to deal with possible operand encoding.
                   1109: The operand,\^ which is a number of a variable in the global region,\^
                   1110: is multiplied by 8 to provide a byte offset from the start of
                   1111: the global region.  The sum of \*MOp\fP and the value of \*Mglobals\fP
                   1112: is pushed on the stack to provide a descriptor address.  The constant
                   1113: \*MD_VAR\fP is pushed on the stack to complete the descriptor for the
                   1114: global variable.
                   1115: .Ip \*Mop_static\fP
                   1116: Identical to \*Mop_global\fP except that \*Mstatics\fP is used
                   1117: instead of \*Mglobals\fP.
                   1118: .Ip \*Mop_local\fP
                   1119: The operand value is the number of a local variable for which a
                   1120: variable descriptor is to be pushed on the stack.  Recall that the
                   1121: local variables lie below the procedure frame and,\^ on the VAX,\^ the
                   1122: descriptor for the first one is at \*M\-16(fp)\fP.  \*MOp\fP is
                   1123: negated.  The instruction
                   1124: .Ds
                   1125: pushaq -16(fp)\^[Op]
                   1126: .De
                   1127: performs the calculation
                   1128: .Ds
                   1129: -16 + fp + (Op * 8)
                   1130: .De
                   1131: which computes the address of the descriptor of the desired variable
                   1132: and pushes it on the stack.  The variable descriptor is completed by
                   1133: pushing \*MD_VAR\fP on the stack.
                   1134: .Ip \*Mop_arg\fP
                   1135: Like  \*Mop_local\fP,\^ but it uses \*M8(ap)\fP as the base for the
                   1136: address calculation and the operand value is not negated.
                   1137: .Ip \*Mquit\ \ \ \ \ \fP
                   1138: Push a 0 on the stack and call the routine \*M_c_exit\fP to terminate
                   1139: execution of the Icon program.
                   1140: .Ip \*Merr\ \ \ \ \ \fP
                   1141: \*Merr\fP should never be encountered during normal execution.
                   1142: Reaching it indicates that an invalid opcode was encountered.
                   1143: It need not do anything more than abort execution.  On the VAX,\^
                   1144: it calls \*Msprintf\fP to create a string containing the invalid
                   1145: opcode and the \*Mipc\fP where it was encountered and then calls
                   1146: \*Msyserr\fP with the string as an argument.
                   1147: .NH 3
                   1148: \*Mlib/efail.s\fR
                   1149: .SH
                   1150: Overview
                   1151: .PP
                   1152: \*Mefail\fP handles the failure of an expression.  When
                   1153: Icon evaluates an expression,\^ it tries to produce a result from it.
                   1154: If at some point in the evaluation of an expression the expression
                   1155: fails,\^ Icon resumes inactive generators in the expression in
                   1156: an attempt to make the expression succeed. \*Mefail\fP is at the
                   1157: heart of this activity.
                   1158: .LP
                   1159: \*Mefail\fP has three distinct outcomes:
                   1160: .Ls
                   1161: .Np
                   1162: Resumption of the newest inactive generator in the current
                   1163: expression frame.
                   1164: .Np
                   1165: Failure of the current expression with execution continuing
                   1166: at the failure address contained in the expression marker.
                   1167: .Np
                   1168: Failure of the current expression with propagation of failure
                   1169: to the enclosing expression frame.  This is similar to (2),\^
                   1170: but occurs when the failure address is 0.  After the current
                   1171: expression fails,\^ \*Mefail\fP loops back to its entry point
                   1172: to fail again.
                   1173: .Le
                   1174: .PP
                   1175: \*Mefail\fP is branched to rather than being
                   1176: called.  This is because it
                   1177: serves as a ``back-end'' for several failure
                   1178: actions that may occur during the course of execution:
                   1179: .Ls
                   1180: .Np
                   1181: When a built-in procedure fails,\^ it calls the routine \*Mfail\fP,\^ which
                   1182: in turn branches to \*Mefail\fP.
                   1183: .Np
                   1184: When an Icon procedure fails via the \*Mpfail\fP routine,\^ \*Mpfail\fP
                   1185: terminates by branching to \*Mefail\fP.
                   1186: .Np
                   1187: When the \*Mefail\fP opcode is executed by the interpreter,\^ \*Mefail\fP
                   1188: is branched to.
                   1189: .Np
                   1190: The generator frames built by \*Mesusp\fP and \*Mlsusp\fP use \*Mefail\fP
                   1191: as a return address.  This is explained in detail later.
                   1192: .Le
                   1193: .SH
                   1194: Generic Operation
                   1195: .PP
                   1196: \*Mefail\fP is essentially a simple routine.  There are two separate
                   1197: paths of execution that \*Mefail\fP may take.  The first is to
                   1198: resume an inactive generator.  The second is to cause failure of
                   1199: the expression in lieu of an inactive generator.
                   1200: .PP
                   1201: If there is an inactive generator in the current expression frame,\^
                   1202: it must be resumed.
                   1203: If the generator is an Icon procedure and tracing is in on,\^
                   1204: \*Matrace\fP is called with appropriate arguments.  \*M_k_level\fP,\^
                   1205: \*M_line\fP,\^ and \*M_file\fP are restored from the generator frame.  A return
                   1206: is performed and the net result is that the stack is restored to
                   1207: the state that it was in before the suspension that created the
                   1208: generator.
                   1209: .PP
                   1210: If there are no inactive generators that can be resumed,\^ the
                   1211: expression being evaluated must fail.  This is done by popping
                   1212: the stack back through the current expression frame and resuming
                   1213: execution at the point indicated by the failure address in
                   1214: the expression marker.  This is a two-step process.  The first
                   1215: is to pop the frame and the second is to resume execution.
                   1216: When the frame is popped,\^ the expression has failed.  The
                   1217: failure address in the expression marker is saved before
                   1218: the frame is popped.  If this address is not zero,\^ execution
                   1219: is continued by branching to the address.  If the address is
                   1220: zero,\^ the failure is propagated to the enclosing expression by
                   1221: branching to efail.
                   1222: .PP
                   1223: Zero failure addresses are generated by the ucode instruction
                   1224: .Ds
                   1225: mark  L0
                   1226: .De
                   1227: Such instructions are used to avoid a special case during code
                   1228: generation and the only purpose they serve during program execution
                   1229: is to create an expression marker for the corresponding
                   1230: \*Munmark\fP instruction to remove.  (\*Mmark\fP and \*Munmark\fP
                   1231: instructions are paired.)
                   1232: Thus,\^ whenever \*Mefail\fP pops an expression whose marker has a
                   1233: zero failure address,\^ \*Mefail\fP causes failure in the enclosing
                   1234: expression.
                   1235: .SH
                   1236: \*Mefail\fP on the VAX
                   1237: .PP
                   1238: The first action is to determine if there is an inactive generator
                   1239: that can be reactivated.  If the generator frame pointer
                   1240: is non-zero,\^ it points to the newest inactive generator.
                   1241: Note that whenever a new expression frame is created,\^ the generator
                   1242: frame pointer is zeroed.  Thus,\^ if \*Mgfp\fP is non-zero,\^ the
                   1243: generator frame that it points to belongs to a generator in the
                   1244: current expression frame.
                   1245: .PP
                   1246: If an inactive generator is available,\^ it must be reactivated.
                   1247: First,\^ \*M_boundary\fP is restored from the generator frame.
                   1248: The stack is popped back to the generator frame by loading
                   1249: \*Mfp\fP from \*Mgfp\fP.  But,\^ before \*Mfp\fP is loaded,\^
                   1250: its value is saved in \*Mr0\fP.  \*Mfp\fP now points at
                   1251: word 0 of the generator frame,\^ but that is a word below the
                   1252: actual stack frame that it should be pointing at,\^ so \*Mfp\fP is
                   1253: incremented by 4 using a \*Mtstl\fP.
                   1254: .LP
                   1255: There are three types of generators that may be encountered
                   1256: by \*Mefail\fP.
                   1257: .Ls
                   1258: .Np
                   1259: An Icon procedure that did a \*Msuspend\fP.  In such cases,\^ the
                   1260: routine \*Mpsusp\fP handled the suspension.
                   1261: .Np
                   1262: A built-in procedure that called the C function \*Msuspend()\fP.
                   1263: .Np
                   1264: A generator created by an \*Mesusp\fP or \*Mlsusp\fP instruction.
                   1265: Such generators
                   1266: arise from source code constructs like \*M\*(x1 |\ \^\*(x2\fP,\^ \*M|\*(xx\fR,\^ and
                   1267: \*M\*(x1 \e\ \^\*(x2\fR,\^ which are referred to as \fIcontrol regimes\fP.
                   1268: .Le
                   1269: .PP
                   1270: The generators may be treated the same way as far as resumption goes.
                   1271: However,\^ if an Icon procedure is being resumed,\^ a tracing message must
                   1272: be generated if \*M_k_trace\fP is not 0.
                   1273: .PP
                   1274: If the value of \*M_boundary\fP is not the same as \*Mfp\fP,\^ the
                   1275: generator is a built-in procedure and tracing is not done.
                   1276: If the \*Mfp\fP saved in the current frame is the same as the
                   1277: \*Mfp\fP was upon entry to \*Mefail\fP (the value was saved in
                   1278: \*Mr0\fP),\^ the generator was made by an \*Mesusp\fP or an \*Mlsusp\fP
                   1279: and tracing is not done.
                   1280: .PP
                   1281: Otherwise,\^ the generator is an Icon procedure,\^ and \*Matrace\fP must
                   1282: be called.  \*Matrace\fP takes one argument,\^ the address of the
                   1283: procedure block for the procedure being resumed.  Recall that \*(e0 on the
                   1284: stack is a descriptor for the procedure block.  The address of
                   1285: \*(e0 is calculated using
                   1286: .Ds
                   1287: &\*(e0 = ap + 8 + (8 * nargs)
                   1288: .De
                   1289: The resulting address is used as the single argument for \*Matrace\fP.
                   1290: .PP
                   1291: The generator is now ready to be resumed.
                   1292: \*M_k_level\fP,\^ \*M_line\fP,\^ and \*M_file\fP are restored by popping them
                   1293: from the generator frame.  If the generator is a built-in procedure,\^
                   1294: \*M_boundary\fP is cleared.  A return is performed to activate the
                   1295: generator.
                   1296: .PP
                   1297: The return has different effects depending on the type of generator
                   1298: being resumed.
                   1299: .PP
                   1300: If the generator is a built-in procedure,\^ the return
                   1301: restores the stack to the state it was in before \*Msuspend\fP was
                   1302: called,\^ and execution proceeds at the point just after \*Msuspend()\fP.
                   1303: In this case the \*Mpc\fP value being returned to references an instruction
                   1304: in the built-in procedure.
                   1305: .PP
                   1306: If the generator is an Icon procedure,\^ the stack is restored to
                   1307: the state it was in before the \*Mpsusp\fP ucode instruction
                   1308: was executed.  The \*Mpc\fP value being returned to references an
                   1309: instruction in the interpreter loop.  Execution of the program
                   1310: continues with the interpreter instruction following the \*Mpsusp\fP.
                   1311: .PP
                   1312: If the generator is a control regime,\^ the stack is restored to
                   1313: the state it was in before the \*Mesusp\fP or \*Mlsusp\fP that
                   1314: created the generator was performed.  The
                   1315: return \*Mpc\fP points to \*Mefail\fP itself.  Thus,\^ when the
                   1316: return is done,\^ the stack is cleared,\^ and an \*Mefail\fP is performed.
                   1317: This has the effect of transferring control to the failure label
                   1318: in the expression marker of the bounding expression frame.
                   1319: .\"(The failure label lies at the start of code for the alternative.)
                   1320: .PP
                   1321: If there is no generator to reactivate,\^ the expression must fail.
                   1322: This is handled at the label \*Mnogen\fP.  \*Mefp\fP points to the
                   1323: expression frame marker.  \*Mipc\fP is loaded
                   1324: from \*M\-8(efp)\fP which contains the address to go to in the
                   1325: event that the current expression fails.  (As it has.)
                   1326: \*Mgfp\fP is restored from the expression marker.
                   1327: \*Mefp\fP is restored from the marker and the marker is popped off the stack.
                   1328: .PP
                   1329: If the failure address in \*Mipc\fP is non-zero,\^ control is passed
                   1330: back to the interpreter via a branch and execution of the ucode
                   1331: resumes at the failure address.  If \*Mipc\fP is zero,\^ the expression
                   1332: failure is transmitted to the surrounding expression frame
                   1333: by a branch to \*Mefail\fP.  (Recall that a zero failure address
                   1334: comes from a \*Mmark L0\fP instruction and that a failure that
                   1335: reaches a \*Mmark L0\fP marker must be propagated to the next
                   1336: expression marker.)
                   1337: .NH 3
                   1338: \*Mlib/pfail.s\fR
                   1339: .SH
                   1340: Overview
                   1341: .LP
                   1342: \*Mpfail\fP handles the failure of an Icon procedure.  An Icon
                   1343: procedure can fail by
                   1344: .Ds
                   1345: .ft R
                   1346: executing a \*Mfail\fP expression
                   1347: executing \*Mreturn \fIexpr\fR when \fIexpr\fR fails
                   1348: allowing the flow of control to reach the end of a procedure
                   1349: .De
                   1350: \*Mpfail\fP is entered via a branch when
                   1351: the interpreter encounters the \*Mpfail\fP instruction.
                   1352: .SH
                   1353: Generic Operation
                   1354: .PP
                   1355: The task of \*Mpfail\fP is to signal failure in the expression that
                   1356: contains the procedure call being evaluated.  This is done
                   1357: by removing the Icon procedure frame from the stack,\^ restoring
                   1358: appropriate registers and values,\^ and calling \*Mefail\fP.  The key is that
                   1359: all \*Mpfail\fP needs to do is to remove the procedure frame
                   1360: from the stack and from then on things can be handled just like expression
                   1361: failure.
                   1362: Thus,\^ \*Mefail\fP does most of the work.
                   1363: .PP
                   1364: \*Mpfail\fP calls \*Mftrace\fP to produce a trace message if
                   1365: tracing is on.  \*Mpfail\fP also decrements \*M_k_level\fP because
                   1366: a procedure is being exited.
                   1367: .PP
                   1368: Note that the procedure frame on the stack is a frame that
                   1369: was created by \*Minvoke\fP.
                   1370: .SH
                   1371: \*Mpfail\fP on the VAX
                   1372: .PP
                   1373: After \*M_k_level\fP is decremented,\^ \*M_k_trace\fP is checked to
                   1374: see if a trace message should be produced.  If tracing is on,\^
                   1375: \*Mftrace\fP must be called.  \*Mftrace\fP takes one argument,\^
                   1376: the address of the procedure block for the failing procedure.
                   1377: \*(e0 is the descriptor for the procedure block,\^ and the address
                   1378: of \*(e0 is calculated using
                   1379: .Ds
                   1380: &\*(e0 = (\fInargs\fP * 8) + 8 + ap
                   1381: .De
                   1382: The resulting address is pushed on the stack and \*Mftrace\fP is
                   1383: called.
                   1384: .PP
                   1385: Execution continues at \*Mdofail\fP to remove the procedure frame
                   1386: from the stack.  The frame cannot be merely popped because it
                   1387: contains state information that must be restored.  \*M_line\fP and
                   1388: \*M_file\fP are extracted from the frame.  \*Mefp\fP,\^ \*Mgfp\fP,\^ and
                   1389: \*Mipc\fP are restored from the frame using addresses
                   1390: relative to \*Map\fP.  Note that this works because \*Minvoke\fP saves
                   1391: these registers and their location is known.
                   1392: .PP
                   1393: \*Map\fP and \*Mfp\fP are restored from the frame.  When \*Mfp\fP is
                   1394: restored,\^ it serves to remove the procedure frame (made by
                   1395: \*Minvoke\fP) from the stack.  At this point,\^ the stack is the
                   1396: same state it was in before the interpreter performed the
                   1397: \*Minvoke\fP instruction.  A branch is made to \*Mefail\fP to
                   1398: cause failure in the enclosing expression.
                   1399: .NH 2
                   1400: Testing the Basis
                   1401: .PP
                   1402: At this point,\^ enough of the system has been written to run some
                   1403: very simple Icon
                   1404: programs.  \*Mtest/hello.icn\fP should be functional
                   1405: and more complete testing is in order.  Refer to \fITesting the
                   1406: Basis\fP in \^[5].

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.