Annotation of 43BSD/contrib/icon/docs/tr84-11b.roff, revision 1.1.1.1

1.1       root        1: .bp
                      2: .ce 10
                      3: \f3Appendix A \(em The Parse Tree\fR
                      4: .ce 0
                      5: .sp 1
                      6: .PP
                      7: The parse tree is a collection of nodes, described below,
                      8: rooted at a
                      9: \f3proc\fR
                     10: node.
                     11: Nodes have a common format:
                     12: the first field contains the node type,
                     13: the second and third fields contain a line and column number
                     14: relating the node to the source program,
                     15: and the next zero to four fields contain node-dependent information.
                     16: The line and column numbers are usually those of the first token
                     17: or the primary token of the construct;
                     18: for example, in
                     19: \f3binop\fR
                     20: nodes, they are the location of the operator; in
                     21: \f3if\fR
                     22: nodes, they are the location of the
                     23: \fMif\fR
                     24: token.
                     25: .PP
                     26: The following list of node types
                     27: gives a brief description of the node and
                     28: a list of the node-dependent fields and their uses.
                     29: The fields are named
                     30: .I val
                     31: if they contain an integer value,
                     32: .I str
                     33: if they contain a pointer to a string, or
                     34: .I tree
                     35: if they contain a pointer to another node (a leaf or subtree).
                     36: A digit between
                     37: 0 and 3
                     38: is appended indicating its position in the node.
                     39: .PP
                     40: Seven of the nodes \(em
                     41: \f3cset\fR,
                     42: \f3id\fR,
                     43: \f3int\fR,
                     44: \f3op\fR,
                     45: \f3real\fR,
                     46: \f3res\fR,
                     47: and
                     48: \f3str\fR
                     49: \(em are leaf nodes.
                     50: These nodes, allocated and returned by the lexical analyzer,
                     51: represent source program tokens.
                     52: The remaining nodes contain one or more pointers to other nodes,
                     53: either leaves or subtrees.
                     54: .LP
                     55: .nr Z \n(PD
                     56: .nr PD \nZ
                     57: .de X
                     58: .IP \f3\\$1\fR 8n
                     59: ..
                     60: .de Y
                     61: .nr PD 0
                     62: .IP \h'10n'\fI\\$1\fR \w'\fItree1'u+12n
                     63: ..
                     64: .sp \nZu
                     65: .KS
                     66: .X activat
                     67: A transmission expression (\fIe1\fR @ \fIe2\fR).
                     68: .Y tree0
                     69: The operator (an \f3op\fR node).
                     70: .Y tree1
                     71: \fIe1\fR.
                     72: .Y tree2
                     73: \fIe2\fR.
                     74: .KE
                     75: .sp \nZu
                     76: .KS
                     77: .X alt
                     78: An alternation expression (\fIe1\fR | \fIe2\fR).
                     79: .Y tree0
                     80: \fIe1\fR.
                     81: .Y tree1
                     82: \fIe2\fR.
                     83: .KE
                     84: .sp \nZu
                     85: .KS
                     86: .X augop
                     87: An augmented assignment expression (\fIe1\fR \(ci\fM:=\fR \fIe2\fR).
                     88: .Y tree0
                     89: The operator.
                     90: .Y tree1
                     91: \fIe1\fR.
                     92: .Y tree2
                     93: \fIe1\fR.
                     94: .KE
                     95: .sp \nZu
                     96: .KS
                     97: .X bar
                     98: A repeated alternation expression (\^\^|\fIe\fR).
                     99: .Y tree0
                    100: \fIe\fR.
                    101: .KE
                    102: .sp \nZu
                    103: .KS
                    104: .X binop
                    105: A binary operation (\fIe1\fR \(ci \fIe2\fR).
                    106: .Y tree0
                    107: The operator.
                    108: .Y tree1
                    109: \fIe1\fR.
                    110: .Y tree2
                    111: \fIe2\fR.
                    112: .KE
                    113: .sp \nZu
                    114: .KS
                    115: .X break
                    116: A
                    117: \fMbreak\fR
                    118: expression (\fMbreak [\fIe\fM]\fR).
                    119: .Y tree0
                    120: \fIe\fR.
                    121: .KE
                    122: .sp \nZu
                    123: .KS
                    124: .X case
                    125: A
                    126: \fMcase\fR
                    127: expression (\fMcase \fIe\fM of { \*(El }\fR).
                    128: .Y tree0
                    129: \fIe\fR.
                    130: .Y tree1
                    131: The list of case clauses.
                    132: If there is only one case clause, this field points to the
                    133: \f3ccls\fR
                    134: node; if there are more, it points to a
                    135: \f3clist\fR
                    136: node.
                    137: .KE
                    138: .sp \nZu
                    139: .KS
                    140: .X ccls
                    141: A case clause
                    142: (\fIe1\fR : \fIe2\fR).
                    143: .Y tree0
                    144: \fIe1\fR.
                    145: For a
                    146: \fMdefault\fR
                    147: clause, this field points to a
                    148: \f3res\fR
                    149: node that contains the reserved word
                    150: \fMdefault\fR.
                    151: .Y tree1
                    152: \fIe2\fR.
                    153: .KE
                    154: .sp \nZu
                    155: .KS
                    156: .X clist
                    157: A list of case clauses.
                    158: The list is represented as a binary tree,
                    159: with left branches pointing to case clauses
                    160: and right branches pointing to a list of the remaining case clauses.
                    161: The right branch of the last
                    162: \f3clist\fR
                    163: node points directly to a
                    164: \f3ccls\fR
                    165: node.
                    166: .Y tree0
                    167: A case clause (pointer to a
                    168: \f3ccls\fR
                    169: node).
                    170: .Y tree1
                    171: Pointer to another
                    172: \f3clist\fR
                    173: node, or to the last
                    174: \f3ccls\fR
                    175: node in the list.
                    176: .KE
                    177: .sp \nZu
                    178: .KS
                    179: .X conj
                    180: A conjunction expression (\fIe1 \fM&\fI e2\fR).
                    181: .Y tree0
                    182: \fIe1\fR.
                    183: .Y tree1
                    184: \fIe2\fR.
                    185: .KE
                    186: .sp \nZu
                    187: .KS
                    188: .X create
                    189: A \fMcreate\fR expression (\fMcreate\fI e\fR).
                    190: .Y tree0
                    191: \fIe\fR.
                    192: .KE
                    193: .sp \nZu
                    194: .KS
                    195: .X cset
                    196: A leaf node representing a cset literal.
                    197: .Y str0
                    198: The string equivalent of the literal.
                    199: .Y val1
                    200: The length of the string.
                    201: .KE
                    202: .sp \nZu
                    203: .KS
                    204: .X elist
                    205: An expression list, as in a list construction
                    206: or the argument list in a procedure call.
                    207: An expression list, like a list of case clauses,
                    208: is represented as a binary tree.
                    209: .Y tree0
                    210: An expression.
                    211: .Y tree1
                    212: Pointer to another
                    213: \f3elist\fR
                    214: node, or to the last expression in the list.
                    215: .KE
                    216: .sp \nZu
                    217: .KS
                    218: .X empty
                    219: This node is used as a placeholder for missing expressions in
                    220: control structures and expression lists.
                    221: .KE
                    222: .sp \nZu
                    223: .KS
                    224: .X field
                    225: A field reference to a record (\fIe\fM . \fIident\fR).
                    226: .Y tree0
                    227: \fIe\fR.
                    228: .Y tree1
                    229: Pointer to an
                    230: \f3id\fR
                    231: node, containing the field name \fIident\fR.
                    232: .KE
                    233: .sp \nZu
                    234: .KS
                    235: .X id
                    236: A leaf node representing an identifier.
                    237: .Y str0
                    238: The name of the identifier.
                    239: .KE
                    240: .sp \nZu
                    241: .KS
                    242: .X if
                    243: An
                    244: \fMif\fR
                    245: expression (\fMif\fI e1 \fMthen\fI e2 \fM[\fMelse\fI e3\fM]\fR).
                    246: .Y tree0
                    247: \fIe1\fR.
                    248: .Y tree1
                    249: \fIe2\fR.
                    250: .Y tree2
                    251: \fIe3\fR.
                    252: .KE
                    253: .sp \nZu
                    254: .KS
                    255: .X int
                    256: A leaf node representing an integer literal.
                    257: .Y str0
                    258: The string representation of the literal.
                    259: .KE
                    260: .sp \nZu
                    261: .KS
                    262: .X invok
                    263: A procedure call or mutual evaluation expression (\fIe\fM ( \fIargs\fM )\fR).
                    264: .Y tree0
                    265: \fIe\fR.
                    266: .Y tree1
                    267: The argument list \fIargs\fR.
                    268: If there is one argument, this field points to the expression;
                    269: if there are more, it points to an
                    270: .I elist
                    271: node.
                    272: .KE
                    273: .sp \nZu
                    274: .KS
                    275: .X key
                    276: A keyword reference (\fM&\fI\^ident\fR).
                    277: .Y val0
                    278: The index of the keyword \fIident\fR, defined in the file
                    279: \fMtran/keyword.h\fR.
                    280: .KE
                    281: .sp \nZu
                    282: .KS
                    283: .X limit
                    284: A limitation expression (\fIe1\fR \e \fIe2\fR).
                    285: .Y tree0
                    286: \fIe1\fR.
                    287: .Y tree1
                    288: \fIe2\fR.
                    289: .KE
                    290: .sp \nZu
                    291: .X list
                    292: A list (\^\fM[\fIe1\fR, \fIe2\fR, \*(El \fM]\fR).
                    293: .Y tree0
                    294: The list of elements.
                    295: If there is one element, this field points to the expression;
                    296: if there are more, it points to an
                    297: \f3elist\fR
                    298: node.
                    299: .KE
                    300: .sp \nZu
                    301: .KS
                    302: .X loop
                    303: A loop expression (\fIloop\fR \fIe1\fR [\fMdo\fI e2\fR]).
                    304: .Y tree0
                    305: The style of loop.
                    306: This field points to a
                    307: \f3res\fR
                    308: node, which identifies the reserved word that introduced the loop.
                    309: .Y tree1
                    310: \fIe1\fR.
                    311: .Y tree2
                    312: \fIe2\fR.
                    313: .KE
                    314: .sp \nZu
                    315: .KS
                    316: .X next
                    317: A
                    318: \fMnext\fR
                    319: expression.
                    320: .Y
                    321: .sp -1
                    322: .KE
                    323: .sp \nZu
                    324: .KS
                    325: .in 0
                    326: .X not
                    327: A
                    328: \fMnot\fR
                    329: expression (\fNnot \fIe\fR).
                    330: .Y tree0
                    331: \fIe\fR.
                    332: .KE
                    333: .sp \nZu
                    334: .KS
                    335: .X op
                    336: A leaf node representing an operator.
                    337: .Y val0
                    338: The token type of the operator.
                    339: .KE
                    340: .sp \nZu
                    341: .KS
                    342: .X proc
                    343: A procedure.
                    344: This node is always at the root of the parse tree.
                    345: .Y tree0
                    346: The procedure name.
                    347: This field points to an
                    348: \f3id\fR
                    349: node containing the name.
                    350: .Y tree1
                    351: The
                    352: \fMinitial\fR
                    353: clause.
                    354: .Y tree2
                    355: The procedure body.
                    356: If there is one expression in the procedure body,
                    357: this field points to it;
                    358: if there are more, it points to an
                    359: \f3elist\fR
                    360: node.
                    361: .Y tree3
                    362: A node containing the
                    363: \fMend\fR
                    364: token.
                    365: This field is used to supply a line number for the implicit return
                    366: at the end of a procedure.
                    367: .KE
                    368: .sp \nZu
                    369: .KS
                    370: .X real
                    371: A leaf node representing a real number literal.
                    372: .Y str0
                    373: The string representation of the literal.
                    374: .KE
                    375: .sp \nZu
                    376: .KS
                    377: .X res
                    378: A leaf node representing a reserved word.
                    379: .Y val0
                    380: The token type of the reserved word.
                    381: .KE
                    382: .sp \nZu
                    383: .KS
                    384: .X ret
                    385: A
                    386: \fMreturn\fR
                    387: or
                    388: \fMfail\fR
                    389: expression.
                    390: .Y tree0
                    391: The type of return.
                    392: This field points to a
                    393: \f3res\fR
                    394: node, which contains the reserved word
                    395: \fMreturn\fR
                    396: or
                    397: \fMfail\fR.
                    398: .Y tree1
                    399: The expression following
                    400: \fMreturn\fR,
                    401: or a pointer to an
                    402: \f3empty\fR
                    403: node.
                    404: .KE
                    405: .sp \nZu
                    406: .KS
                    407: .X scan
                    408: A scanning expression (\fIe1\fR \fM?\fR \fIe2\fR).
                    409: .Y tree0
                    410: The operator.
                    411: .Y tree1
                    412: \fIe1\fR.
                    413: .Y tree2
                    414: \fIe2\fR.
                    415: .KE
                    416: .sp \nZu
                    417: .KS
                    418: .X sect
                    419: A section expression (\fIe1\fR [\fIe2\fR : \fIe3\fR]).
                    420: .Y tree0
                    421: \fIe1\fR.
                    422: .Y tree1
                    423: \fIe2\fR.
                    424: .Y tree2
                    425: \fIe3\fR.
                    426: .KE
                    427: .sp \nZu
                    428: .KS
                    429: .X slist
                    430: A list of expressions separated by semicolons,
                    431: as in a procedure body (a statement list).
                    432: This list, like expression lists and case lists,
                    433: is represented as a binary tree.
                    434: .Y tree0
                    435: An expression in the list.
                    436: .Y tree1
                    437: A pointer to another
                    438: \f3slist\fR
                    439: node, or to the last expression in the list.
                    440: .KE
                    441: .sp \nZu
                    442: .KS
                    443: .X str
                    444: A leaf node representing a string literal.
                    445: .Y str0
                    446: The string value of the literal.
                    447: .Y val1
                    448: The length of the string,
                    449: necessary because the string may contain the \s-2ASCII\s+2
                    450: .I null
                    451: character, which would otherwise terminate the string.
                    452: .KE
                    453: .sp \nZu
                    454: .KS
                    455: .X susp
                    456: A
                    457: \fMsuspend\fR
                    458: expression (\fMsuspend\fR [\fIe\fR]).
                    459: .Y tree0
                    460: \fIe\fR.
                    461: .KE
                    462: .sp \nZu
                    463: .KS
                    464: .X toby
                    465: A
                    466: \fMto-by\fR
                    467: expression (\fIe1\fM to \fIe2\fM by \fIe3\fR).
                    468: .Y tree0
                    469: \fIe1\fR.
                    470: .Y tree1
                    471: \fIe2\fR.
                    472: .Y tree2
                    473: \fIe3\fR.
                    474: .KE
                    475: .sp \nZu
                    476: .KS
                    477: .X to
                    478: A
                    479: \fMto\fR
                    480: expression (\fIe1\fM to \fIe2\fR).
                    481: .Y tree0
                    482: \fIe1\fR.
                    483: .Y tree1
                    484: \fIe2\fR.
                    485: .KE
                    486: .sp \nZu
                    487: .KS
                    488: .X unop
                    489: A unary operation (\(ci \fIe\fR).
                    490: .Y tree0
                    491: The operator.
                    492: .Y tree1
                    493: \fIe\fR.
                    494: .KE
                    495: .nr PD \nZ
                    496: .bp
                    497: .ce 10
                    498: \f3Appendix B \(em Icon Grammar\fR
                    499: .ce 0
                    500: .sp 1
                    501: .PP
                    502: The following grammar describes the Icon language.
                    503: Reserved words and operators
                    504: are shown in a sans-serif type face;
                    505: nonterminals are in italics.
                    506: The nonterminals
                    507: .I ident ,
                    508: .I literal ,
                    509: .I strliteral ,
                    510: and
                    511: .I empty
                    512: are left undefined in the syntax.
                    513: .sp 2
                    514: .ta 1.5iR 1.5i+1mL
                    515: .ft I
                    516: .tr |\(br
                    517: .tr -\-
                    518: .tr +\(pl
                    519: .tr /\(sl
                    520: .tr *\(**
                    521: .ss 9
                    522: .de X
                    523: \t\\$1\h'1m'\(->\t\\$2
                    524: .br
                    525: ..
                    526: .de Y
                    527: .if n .sp 1
                    528: .if t .sp .5
                    529: ..
                    530: .X    program    "decls"
                    531: .Y
                    532: .ne 2
                    533: .X      decls    "empty"
                    534: .X         ""    "decls decl"
                    535: .Y
                    536: .ne 3
                    537: .X       decl    "record"
                    538: .X         ""    "proc"
                    539: .X         ""    "global"
                    540: .X         ""    "link"
                    541: .Y
                    542: .X       link    "\fMlink\fI lnklist"
                    543: .Y
                    544: .ne 2
                    545: .X     lnklist   "lnkfile"
                    546: .X          ""   "lnklist , lnkfile"
                    547: .Y
                    548: .X     lnkfile   "ident"
                    549: .X          ""   "strliteral"
                    550: .Y
                    551: .ne 2
                    552: .X     global    "\fMglobal\fI idlist"
                    553: .Y
                    554: .X     record    "\fMrecord\fI ident \fM(\fI arglist \fM)\fI"
                    555: .Y
                    556: .X       proc    "prochead \fM;\fI locals initial procbody \fMend\fI"
                    557: .Y
                    558: .X   prochead    "\fMprocedure\fI ident \fM(\fI arglist \fM)\fI"
                    559: .Y
                    560: .ne 2
                    561: .X    arglist    "empty"
                    562: .X         ""    "idlist"
                    563: .Y
                    564: .ne 2
                    565: .X     idlist    "ident"
                    566: .X         ""    "idlist \fM,\fI ident"
                    567: .Y
                    568: .ne 2
                    569: .X     locals    "empty"
                    570: .X         ""    "locals retention idlist \fM;\fI"
                    571: .Y
                    572: .ne 2
                    573: .X  retention    "\fMlocal\fI"
                    574: .X         ""    "\fMstatic\fI"
                    575: .X         ""    "\fMdynamic\fI"
                    576: .Y
                    577: .ne 2
                    578: .X    initial    "empty"
                    579: .X         ""    "\fMinitial\fI expr \fM;\fI"
                    580: .Y
                    581: .ne 2
                    582: .X   procbody    "empty"
                    583: .X         ""    "nexpr \fM;\fI procbody"
                    584: .Y
                    585: .ne 2
                    586: .X      nexpr    "empty"
                    587: .X         ""    "expr"
                    588: .Y
                    589: .ne 2
                    590: .X       expr    "expr1a"
                    591: .X         ""    "expr \fM&\fI expr1a"
                    592: .Y
                    593: .ne 2
                    594: .X      expr1a  "expr1"
                    595: .X         ""   "expr1a \fM?\fI expr1"
                    596: .Y
                    597: .ne 5
                    598: .X      expr1    "expr2"
                    599: .X         ""    "expr2 op1 expr1"
                    600: .X         ""    "expr2 op1a expr1"
                    601: .X         ""    "expr2 \fM?:=\fI expr1"
                    602: .X         ""    "expr2 \fM&:=\fI expr1"
                    603: .X         ""    "expr2 \fM@:=\fI expr1"
                    604: .Y
                    605: .ne 6
                    606: .X        op1    "\fM:= | :=: | <- | <->\fI"
                    607: .Y
                    608: .if n .X op1a    "\fM+:= | -:= | *:= | /:= | %:= | ^:=\fI"
                    609: .if n .X   ""    "\fM++:= | --:= | **:= | \(or\(or:= | \(or\(or\(or:=\fI"
                    610: .if t .X op1a    "\fM+:= | -:= | *:= | /:= | %:= | ^:= | ++:= | \
                    611: --:= | **:= | \(or\(or:= | \(or\(or\(or:=\fI"
                    612: .X      ""       "\fM<:= | <=:= | =:= | >=:= | >:= | ~=:= \fM"
                    613: .X      ""       "\fM<<:= | <<=:= | ==:= | >>=:= | >>:= | ~==:=\fI"
                    614: .X      ""       "\fM===:= | ~===:=\fI"
                    615: .Y
                    616: .ne 3
                    617: .X      expr2    "expr3"
                    618: .X         ""    "expr2 \fMto\fI expr3"
                    619: .X         ""    "expr2 \fMto\fI expr3 \fMby\fI expr3"
                    620: .Y
                    621: .ne 2
                    622: .X      expr3    "expr4"
                    623: .X         ""    "expr4 \(or expr3"
                    624: .Y
                    625: .ne 2
                    626: .X      expr4    "expr5"
                    627: .X         ""    "expr4 op4 expr5"
                    628: .Y
                    629: .ne 3
                    630: .X        op4    "\fM< | <= | = | >= | > | ~=\fI"
                    631: .X         ""    "\fM<< | <<= | == | >>= | >> | ~==\fI"
                    632: .X         ""    "\fM=== | ~===\fI"
                    633: .Y
                    634: .ne 2
                    635: .X      expr5    "expr6"
                    636: .X         ""    "expr5 op5 expr6"
                    637: .Y
                    638: .ne 2
                    639: .X      op5     "\fM\(or\(or | \(or\(or\(or\fI"
                    640: .Y
                    641: .ne 2
                    642: .X      expr6    "expr7"
                    643: .X         ""    "expr6 op6 expr7"
                    644: .Y
                    645: .X        op6    "\fM+ | - | ++ | --\fI"
                    646: .Y
                    647: .ne 2
                    648: .X      expr7    "expr8"
                    649: .X         ""    "expr7 op7 expr8"
                    650: .Y
                    651: .X        op7    "\fM* | / | % | **\fI"
                    652: .Y
                    653: .ne 2
                    654: .X      expr8    "expr9"
                    655: .X         ""    "expr9 ^ expr8"
                    656: .Y
                    657: .ne 2
                    658: .X      expr9    "expr10"
                    659: .X         ""    "expr9 \fM\e\fI expr10"
                    660: .X         ""    "expr9 \fM @ \fIexpr10"
                    661: .Y
                    662: .ne 5
                    663: .X     expr10    "expr11"
                    664: .X         ""    "\fMnot\fI expr10"
                    665: .X         ""    "\fM@\fI expr10"
                    666: .X         ""    "\(or expr10"
                    667: .X         ""    "op10 expr10"
                    668: .Y
                    669: .X       op10    "\fM. | ! | + | - | ~ | = | * | / | \e | ? | ^\fI"
                    670: .Y
                    671: .ne 20
                    672: .X     expr11    "ident"
                    673: .X         ""    "literal"
                    674: .X         ""    "\fM&\fI ident"
                    675: .X         ""    "expr11 \fM.\fI ident"
                    676: .X         ""    "expr11 \fM[\fI nexpr \fM]\fI"
                    677: .X         ""    "expr11 \fM(\fI exprlist \fM)\fI"
                    678: .X         ""    "expr11 \fM{\fR exprlist \fM}\fI"
                    679: .X         ""    "\fM[\fI exprlist \fM]\fI"
                    680: .X         ""    "\fM(\fI exprlist \fM)\fI"
                    681: .X         ""    "{ compound }"
                    682: .X         ""    "while"
                    683: .X         ""    "until"
                    684: .X         ""    "every"
                    685: .X         ""    "repeat"
                    686: .X         ""    "\fMnext\fI"
                    687: .X         ""    "\fMbreak\fI nexpr"
                    688: .X         ""    "\fMcreate\fI expr"
                    689: .X         ""    "if"
                    690: .X         ""    "case"
                    691: .X         ""    "return"
                    692: .X         ""    "section"
                    693: .Y
                    694: .ne 2
                    695: .X      while    "\fMwhile\fI expr"
                    696: .X         ""    "\fMwhile\fI expr \fMdo\fI expr"
                    697: .Y
                    698: .ne 2
                    699: .X      until    "\fMuntil\fI expr"
                    700: .X         ""    "\fMuntil\fI expr \fMdo\fI expr"
                    701: .Y
                    702: .ne 2
                    703: .X      every    "\fMevery\fI expr"
                    704: .X         ""    "\fMevery\fI expr \fMdo\fI expr"
                    705: .Y
                    706: .X     repeat    "\fMrepeat\fI expr"
                    707: .Y
                    708: .ne 2
                    709: .X         if    "\fMif\fI expr \fMthen\fI expr"
                    710: .X         ""    "\fMif\fI expr \fMthen\fI expr \fMelse\fI expr"
                    711: .Y
                    712: .X       case    "\fMcase\fI expr \fMof\fI { caselist }"
                    713: .Y
                    714: .ne 2
                    715: .X   caselist    "cclause"
                    716: .X         ""    "caselist \fM;\fI cclause"
                    717: .Y
                    718: .ne 2
                    719: .X    cclause    "\fMdefault\fM :\fI expr"
                    720: .X         ""    "expr \fM:\fI expr"
                    721: .Y
                    722: .ne 3
                    723: .X     return    "\fMfail\fI"
                    724: .X         ""    "\fMreturn\fI nexpr"
                    725: .X         ""    "\fMsuspend\fI nexpr"
                    726: .Y
                    727: .X    section    "expr11 \fM[\fI expr sectop expr \fM]\fI"
                    728: .Y
                    729: .X     sectop    "\fM: | +: | -:\fI"
                    730: .Y
                    731: .ne 2
                    732: .X   exprlist    "nexpr"
                    733: .X         ""    "exprlist \fM,\fI nexpr"
                    734: .Y
                    735: .ne 2
                    736: .X   compound    "nexpr"
                    737: .X         ""    "nexpr \fM;\fI compound"
                    738: .ss 4
                    739: .tr ||
                    740: .tr --
                    741: .tr ++
                    742: .tr //
                    743: .tr **
                    744: .uf I
                    745: .ft R
                    746: .bp
                    747: .de Op
                    748: .if \\n(.$=2 .IP \h'3n'\f3\\$1\h'2n'\fI\\$2\fR 6n
                    749: .if \\n(.$=1 .IP \h'3n'\f3\\$1\fR 6n
                    750: .br
                    751: ..
                    752: .ce 10
                    753: \f3Appendix C \(em Ucode\fR
                    754: .ce 0
                    755: .sp 1
                    756: .PP
                    757: The intermediate ucode generated by the Icon translator
                    758: resembles a stack-oriented assembly language.
                    759: A ucode program is a sequence of labels and instructions.
                    760: A label marks a location in the program to which other instructions
                    761: may transfer control.
                    762: Labels are of the form \*(oq\f3lab L\fIn\fR\*(cq, where
                    763: .I n
                    764: is a decimal number.
                    765: A ucode instruction either describes an imperative operation
                    766: or communicates information to the Icon linker.
                    767: Instructions consist of an opcode followed by zero or more arguments.
                    768: Arguments can be decimal or octal integers,
                    769: names, or label references.
                    770: .PP
                    771: The intermediate language operates exclusively on the stack.
                    772: There are several kinds of objects that can appear on the stack:
                    773: descriptors, which represent Icon values and variables;
                    774: procedure frame markers, which mark the beginning of a new procedure frame;
                    775: expression frame markers, which delimit expression instances;
                    776: and generator frame markers, which mark inactive generators.
                    777: For more details about the stack, refer to Section 3.2.
                    778: .PP
                    779: The opcodes and their arguments are described in three groups below.
                    780: The global symbol table file has a similar format.
                    781: The opcodes used there are described in the fourth group.
                    782: .sp 1
                    783: .SH
                    784: Imperative Instructions
                    785: .PP
                    786: The instructions below,
                    787: together with the operators described in the next section,
                    788: represent run-time actions for which code is executed.
                    789: .KS
                    790: .Op bscan
                    791: Save the values of \fM&subject\fR and \fM&pos\fR on the stack
                    792: and establish values for them.
                    793: This operation is reversible.
                    794: .KE
                    795: .KS
                    796: .Op ccase
                    797: Duplicate the value on the stack
                    798: just below the current expression frame.
                    799: Used in
                    800: \fMcase\fR
                    801: expressions.
                    802: .KE
                    803: .KS
                    804: .Op chfail lab
                    805: Change the failure label for the current expression frame to
                    806: .I lab .
                    807: Used for repeated evaluation.
                    808: .KE
                    809: .KS
                    810: .Op  coact
                    811: Switch co-expression evaluation. Create a procedure frame on the current
                    812: co-expression stack. Transfer the result from old stack to new stack,
                    813: dereferencing if necessary. Set the activator field in new stack block to
                    814: point to old co-expression stack block. Return from procedure frame on
                    815: new co-expression stack.
                    816: .KE
                    817: .KS
                    818: .Op  cofail
                    819: Fail from current co-expression to activating co-expression.
                    820: Create a procedure frame on current co-expression stack. Fail from
                    821: procedure frame on activator's co-expression stack.
                    822: .KE
                    823: .KS
                    824: .Op  coret
                    825: Switch evaluation to activating co-expression.
                    826: Create a procedure frame on current co-expression stack. Transfer
                    827: the result from old stack to activator's stack, dereferencing it if the result
                    828: is on the old stack.
                    829: Return from the procedure frame on new co-expression stack.
                    830: .KE
                    831: .KS
                    832: .Op  create
                    833: Create a co-expression. Allocate
                    834: co-expression stack and heap blocks. Copy the arguments
                    835: and locals variables from the current procedure frame into the heap block.
                    836: Create a procedure frame in the new co-expression stack using the arguments
                    837: and other locals from current procedure frame. Create a procedure
                    838: frame for dummy call to \fMcoact\fR on the new co-expression stack.
                    839: Push a descriptor representing the new co-expression onto current co-expression
                    840: stack.
                    841: .KE
                    842: .KS
                    843: .Op cset n
                    844: Push a descriptor representing the cset literal at constant table location
                    845: .I n
                    846: onto the stack.
                    847: .KE
                    848: .KS
                    849: .Op dup
                    850: Push a descriptor representing the null value onto the stack, and then duplicate the value that
                    851: was the previous top of the stack.
                    852: Used in most augmented assignments.
                    853: .KE
                    854: .KS
                    855: .Op efail
                    856: Signal failure in the current expression.
                    857: If there are any inactive generators, reactivate the most recent one.
                    858: If there are none, branch to the failure label
                    859: for the current expression frame.
                    860: If the failure label is null,
                    861: exit the current expression frame,
                    862: and signal failure in the enclosing one.
                    863: .KE
                    864: .KS
                    865: .Op eret
                    866: Return a value from an expression.
                    867: Save the value on top of the stack,
                    868: exit the current expression frame,
                    869: and push the value onto the stack as part of the enclosing expression frame.
                    870: .KE
                    871: .KS
                    872: .Op escan
                    873: Restore
                    874: \fM&subject\fR
                    875: and
                    876: \fM&pos\fR
                    877: from the stack.
                    878: This operation is reversible.
                    879: .KE
                    880: .KS
                    881: .Op esusp
                    882: Suspend a value from an expression.
                    883: The value on the top of the stack is saved,
                    884: and a generator frame hiding the current expression frame is created.
                    885: The surrounding expression frame is duplicated,
                    886: and the value is pushed onto the stack as part of that expression frame.
                    887: When reactivated,
                    888: \f3esusp\fR
                    889: in turn reactivates any inactive generators in the suspended expression.
                    890: .KE
                    891: .KS
                    892: .Op field name
                    893: Access the field
                    894: .I name
                    895: of the record on the top of the stack.
                    896: .KE
                    897: .KS
                    898: .Op file name
                    899: Set the file name to
                    900: .I name
                    901: for use in error messages and tracing.
                    902: Used at the beginning of each procedure.
                    903: .KE
                    904: .KS
                    905: .Op goto lab
                    906: Transfer control to the instruction following label
                    907: .I lab .
                    908: .KE
                    909: .KS
                    910: .Op incres
                    911: Increment result count field in current co-expression stack block.
                    912: .KE
                    913: .KS
                    914: .Op init? lab
                    915: If the initialization statement for the current procedure
                    916: has already been executed once, go to
                    917: .I lab .
                    918: .KE
                    919: .KS
                    920: .Op int n
                    921: Push a descriptor representing the integer literal at constant table location
                    922: .I n
                    923: onto the stack.
                    924: .KE
                    925: .KS
                    926: .Op invoke n
                    927: Invoke a procedure or create a record.
                    928: The number of arguments or fields on the stack is given by
                    929: .I n .
                    930: The procedure (which may be a record constructor) is on the stack,
                    931: just beyond the arguments.
                    932: After invocation, the arguments are popped from the stack,
                    933: and the returned value is pushed (see
                    934: \f3pret\fR).
                    935: .KE
                    936: .KS
                    937: .Op keywd n
                    938: Push a descriptor representing a value or trapped variable representing keyword
                    939: .I n
                    940: onto the stack.
                    941: (See
                    942: \fMtran/keyword.h\fR
                    943: for keyword numbers.)
                    944: .KE
                    945: .KS
                    946: .Op limit
                    947: Check the value on the top of the stack for a legal limitation value.
                    948: If the value is zero, failure is signalled in the current expression (see
                    949: \f3efail\fR).
                    950: .KE
                    951: .KS
                    952: .Op line n
                    953: Set the line number to
                    954: .I n
                    955: for use in error messages and tracing.
                    956: .KE
                    957: .KS
                    958: .Op llist n
                    959: Create a list of
                    960: .I n
                    961: values.
                    962: The values are popped from the stack
                    963: and the created list is pushed back onto the stack.
                    964: .KE
                    965: .KS
                    966: .Op lsusp
                    967: Decrement the limitation counter for the current expression frame.
                    968: If the counter becomes zero, then return a value
                    969: from the current expression frame (see
                    970: \f3eret\fR);
                    971: otherwise, suspend a value from the current expression frame (see
                    972: \f3esusp\fR).
                    973: .KE
                    974: .KS
                    975: .Op mark lab
                    976: Save the current expression and generator frame pointers on the stack,
                    977: then create a new expression frame, with failure label
                    978: .I lab .
                    979: Control is transferred to
                    980: .I lab
                    981: if failure occurs in the expression frame and there are no suspended
                    982: generators to reactivate (see
                    983: \f3efail\fR).
                    984: The failure label \fML0\fR indicates that control is to be
                    985: transferred to the failure label in the enclosing expression.
                    986: .KE
                    987: .KS
                    988: .Op pfail
                    989: Return from the current procedure, and signal failure (see
                    990: \f3efail\fR).
                    991: .KE
                    992: .KS
                    993: .Op pnull
                    994: Push a descriptor representing the null value onto the stack.
                    995: .KE
                    996: .KS
                    997: .Op pop
                    998: Pop the top element off of the stack.
                    999: .KE
                   1000: .KS
                   1001: .Op pret
                   1002: Return from the current procedure
                   1003: with the result that is on top of the stack.
                   1004: .KE
                   1005: .KS
                   1006: .Op psusp
                   1007: Suspend from the current procedure
                   1008: with the result that is on top of the stack.
                   1009: .KE
                   1010: .KS
                   1011: .Op push1
                   1012: Push a descriptor representing the integer 1 onto the stack.
                   1013: .KE
                   1014: .KS
                   1015: .Op pushn1
                   1016: Push a descriptor representing the integer \-1 onto the stack. This is used as default in
                   1017: mutual goal-directed evaluation.
                   1018: .KE
                   1019: .KS
                   1020: .Op real n
                   1021: Push a descriptor representing the real literal at constant table location
                   1022: .I n
                   1023: onto the stack.
                   1024: .KE
                   1025: .KS
                   1026: .Op  refresh
                   1027: Allocate space for a new co-expression stack. Create a procedure frame
                   1028: in new co-expression stack using arguments and other locals from
                   1029: entry block for co-expression operand. Create a procedure frame for
                   1030: dummy call to \fMcoact\fR on new co-expression stack.
                   1031: Push a descriptor representing the new co-expression onto current co-expression
                   1032: stack.
                   1033: .KE
                   1034: .KS
                   1035: .Op sdup
                   1036: Duplicate the descriptor on the top of the stack.
                   1037: Used in assignment augmented with string scanning.
                   1038: .KE
                   1039: .KS
                   1040: .Op str n
                   1041: Push a descriptor representing the string literal at constant table location
                   1042: .I n
                   1043: onto the stack.
                   1044: .KE
                   1045: .KS
                   1046: .Op unmark n
                   1047: Exit from
                   1048: .I n
                   1049: expression frames.
                   1050: No value is pushed onto the stack in their place.
                   1051: .KE
                   1052: .KS
                   1053: .Op var n
                   1054: Push the descriptor for the variable at location
                   1055: .I n
                   1056: in the local symbol table onto the stack.
                   1057: .KE
                   1058: .sp 1
                   1059: .SH
                   1060: Operators
                   1061: .PP
                   1062: The instructions below perform the functions
                   1063: corresponding to the indicated Icon operator.
                   1064: The operands are evaluated and pushed onto the stack from left to right,
                   1065: so that the topmost element of the stack is the rightmost operand.
                   1066: The operands are popped before
                   1067: the result of the operation is pushed onto the stack.
                   1068: All operations dereference their operands as necessary,
                   1069: but only after all operands have been evaluated and pushed onto the stack.
                   1070: All operations attempt to convert their operands to an appropriate type.
                   1071: If this implicit conversion fails, an error is issued.
                   1072: Relational tests fail if the specified condition is not met;
                   1073: the result of a successful comparison is the value of the right-hand operand.
                   1074: Arithmetic operations cause an error to be issued
                   1075: if the result overflows or underflows.
                   1076: If an operation cannot be performed for some other reason,
                   1077: it fails.
                   1078: .LP
                   1079: .ta 0.5i 1.5i 3.5i 4.5i
                   1080: .de X
                   1081: \t\f3\\$1\fM\t\\$2\t\f3\\$3\fM\t\\$4\fR
                   1082: .br
                   1083: ..
                   1084: .ne 21
                   1085: .tr |\(or
                   1086: .tr +\(pl
                   1087: .tr -\-
                   1088: .tr /\(sl
                   1089: .tr *\(**
                   1090: .ss 9
                   1091: .X asgn         "x := y"      null         "/x"
                   1092: .X bang         "!x"          number       "+x"
                   1093: .X cat          "x || y"            numeq        "x = y"
                   1094: .X compl        "~x"                numge        "x >= y"
                   1095: .X diff         "x -- y"            numgt        "x > y"
                   1096: .X div          "x / y"             numle        "x <= y"
                   1097: .X eqv          "x === y"           numlt        "x < y"
                   1098: .X inter        "x ** y"            numne        "x ~= y"
                   1099: .X lconcat      "x ||| y"           plus         "x + y"
                   1100: .X lexeq        "x == y"            power        "x ^ y"
                   1101: .X lexge        "x >>= y"           random       "?x"
                   1102: .X lexgt        "x >> y"            rasgn        "x <- y"
                   1103: .X lexle        "x <<= y"           rswap        "x <-> y"
                   1104: .X lexlt        "x << y"            sect         "x\^[\^y:z]"
                   1105: .X lexne        "x ~== y"           size         "*x"
                   1106: .X minus        "x - y"             subsc        "x\^[\^y]"
                   1107: .X mod          "x % y"             swap         "x :=: y"
                   1108: .X mult         "x * y"             tabmat       "=x"
                   1109: .X neg          "-x"                toby         "x to y by z"
                   1110: .X neqv         "x ~=== y"          unioncs      "x ++ y"
                   1111: .X nonnull      "\ex"               value        ".x"
                   1112: .tr ||
                   1113: .tr ++
                   1114: .tr --
                   1115: .tr //
                   1116: .tr **
                   1117: .ss 4
                   1118: .sp 1
                   1119: .SH
                   1120: Non-Imperative Instructions
                   1121: .PP
                   1122: The following instructions generate no executable code.
                   1123: Instead, they communicate various information to the linker
                   1124: each procedure and its symbol table.
                   1125: An Icon procedure is translated into a sequence of ucode
                   1126: instructions beginning with a
                   1127: \f3proc\fR
                   1128: instruction, followed by a sequence of
                   1129: \f3local\fR
                   1130: instructions, a sequence of
                   1131: \f3con\fR
                   1132: instructions, a
                   1133: \f3declend\fR
                   1134: instruction, then the imperative instructions describing
                   1135: the procedure body.
                   1136: An
                   1137: \f3end\fR
                   1138: instruction terminates the procedure.
                   1139: .KS
                   1140: .Op proc name
                   1141: Begin a new procedure with the indicated name.
                   1142: The local and constant tables are initialized.
                   1143: The procedure block is not generated at this time,
                   1144: since the local identifiers have not yet been declared.
                   1145: .KE
                   1146: .KS
                   1147: .Op local n,flags,name
                   1148: Enter
                   1149: .I name
                   1150: into the current procedure's local symbol table at location
                   1151: .I n .
                   1152: The symbol's
                   1153: .I flags
                   1154: indicate information about the symbol, its scope, and its retention.
                   1155: All identifiers referred to in a procedure appear in the
                   1156: local symbol table.
                   1157: If an identifier is undeclared,
                   1158: its scope is determined by consulting the global symbol table
                   1159: and a list of functions.
                   1160: .KE
                   1161: .KS
                   1162: .Op con n,flags,value
                   1163: Enter
                   1164: .I value
                   1165: into the current procedure's constant table at location
                   1166: .I n
                   1167: in the table.
                   1168: The type of the constant (integer, real, or string) is indicated by
                   1169: .I flags .
                   1170: For integer and real literals,
                   1171: .I value
                   1172: is an 11-digit octal number;
                   1173: for string and cset literals,
                   1174: it is a comma-separated list of 3-digit octal numbers,
                   1175: each representing one byte in the string.
                   1176: .KE
                   1177: .KS
                   1178: .Op declend
                   1179: Signal the end of the procedure prologue.
                   1180: The procedure block is generated at this point.
                   1181: .KE
                   1182: .KS
                   1183: .Op end
                   1184: Signal the end of a procedure.
                   1185: .KE
                   1186: .sp 1
                   1187: .SH
                   1188: Global Symbol Table Instructions
                   1189: .PP
                   1190: A single global symbol table file is output during each translation.
                   1191: Record declarations appear first in the file;
                   1192: they are output as they are encountered in the Icon source program.
                   1193: The first instruction following the record declarations is
                   1194: \f3impl\fR,
                   1195: which may be followed by a
                   1196: \f3trace\fR
                   1197: instruction, then by the global declarations.
                   1198: The global declarations are output at the end of translation.
                   1199: .KS
                   1200: .Op record name,n
                   1201: Declare a record with the indicated name and
                   1202: .I n
                   1203: fields.
                   1204: One line for each field follows this line,
                   1205: each containing the field number and name.
                   1206: .KE
                   1207: .KS
                   1208: .Op impl scope
                   1209: Declare the implicit scope as indicated.
                   1210: .I Scope
                   1211: can be either
                   1212: \f3local\fR
                   1213: or
                   1214: \f3error\fR.
                   1215: If the implicit scope is
                   1216: \f3error\fR,
                   1217: undeclared identifiers are flagged as warnings during linking;
                   1218: otherwise, they are made local variables.
                   1219: The implicit scope is
                   1220: \f3error\fR
                   1221: if the
                   1222: \f3\-u\fR
                   1223: option was given on the translator command line, otherwise it is
                   1224: \f3local\fR.
                   1225: .KE
                   1226: .KS
                   1227: .Op trace
                   1228: Enable run-time tracing.
                   1229: This instruction is present if the
                   1230: \f3\-t\fR
                   1231: option was given on the translator command line,
                   1232: and causes the keyword
                   1233: \fM&trace\fR
                   1234: to be initialized to \-1.
                   1235: .KE
                   1236: .KS
                   1237: .Op global n
                   1238: Begin the global symbol table.
                   1239: There are
                   1240: .I n
                   1241: global declarations following, one per line.
                   1242: Each global declaration contains a sequence number,
                   1243: the flags, the identifier name,
                   1244: and the number of formal parameters (for procedures) or fields (for records).
                   1245: .KE
                   1246: .KS
                   1247: .Op link name
                   1248: Search each directory named in the \fIIPATH\fR environment variable
                   1249: for a file named \fIname.u1\fR. If the file is
                   1250: located, it is added to the list of files to link.
                   1251: .KE
                   1252: .bp
                   1253: .if \nv .ss 9
                   1254: .ce 10
                   1255: \f3Appendix D \(em Data Representations\fR
                   1256: .ce 0
                   1257: .sp 1
                   1258: .SH
                   1259: Descriptor Formats
                   1260: .PP
                   1261: The figures below depict each of the six descriptor types
                   1262: mentioned in Section 3.1.
                   1263: Each descriptor is two words long;
                   1264: the first word is shown on top of the second.
                   1265: .sp 1
                   1266: .TS
                   1267: center tab(:) ;
                   1268: L0w(2.2i) | L0w(2n)e S0e S0e S0e S0e S0e S0e S0e S0e S0e S0e S0e S0e S0e S0e S0e |
                   1269: LI | L S S S S S S S S S S S S S S C |
                   1270: L  | L S S S S S S S S S S S S S S S |
                   1271: L  | L S S S S S S S S S S S S S S C |
                   1272: L  | L S S S S S S S S S S S S S S S | .
                   1273: :_
                   1274: Null::0
                   1275: :_
                   1276: ::0
                   1277: :_
                   1278: .TE
                   1279: .sp 1
                   1280: .TS
                   1281: center tab(:) ;
                   1282: L0w(2.2i) | L0w(2n)e S0e S0e S0e S0e S0e S0e S0e S0e S0e S0e S0e S0e S0e S0e S0e |
                   1283: LI | C  | CI S S S S S S S S S S S S S S |
                   1284: L  | L    S  S S S S S S S S S S S S S S |
                   1285: L  | CI   S  S S S S S S S S S S S S S S |
                   1286: L  | L    S  S S S S S S S S S S S S S S | .
                   1287: :_
                   1288: String Qualifier:0:length
                   1289: :_
                   1290: :address of string
                   1291: :_
                   1292: .TE
                   1293: .sp 1
                   1294: .TS
                   1295: center tab(:) ;
                   1296: L0w(2.2i) | L0w(2n)e S0e S0e S0e S0e S0e S0e S0e S0e S0e S0e S0e S0e S0e S0e S0e |
                   1297: LI | C  | C | CI S S S S S S S | CI S S S S S |
                   1298: L  | L    S   S  S S S S S S S   S  S S S S S |
                   1299: LI | CI   S   S  S S S S S S S   S  S S S S S |
                   1300: L  | L    S   S  S S S S S S S   S  S S S S S | .
                   1301: :_
                   1302: Integer:1:0:flags:type = \fR1
                   1303: :_
                   1304: :integer
                   1305: :_
                   1306: .TE
                   1307: .sp 1
                   1308: .TS
                   1309: center tab(:) ;
                   1310: L0w(2.2i) | L0w(2n)e S0e S0e S0e S0e S0e S0e S0e S0e S0e S0e S0e S0e S0e S0e S0e |
                   1311: LI | C  | C | CI S S S S S S S | CI S S S S S |
                   1312: L  | L    S   S  S S S S S S S   S  S S S S S |
                   1313: LI | CI   S   S  S S S S S S S   S  S S S S S |
                   1314: L  | L    S   S  S S S S S S S   S  S S S S S | .
                   1315: :_
                   1316: Value:1:0:flags:type \(>= \fR2
                   1317: :_
                   1318: :address of data block
                   1319: :_
                   1320: .TE
                   1321: .sp 1
                   1322: .TS
                   1323: center tab(:) ;
                   1324: L0w(2.2i) | L0w(2n)e S0e S0e S0e S0e S0e S0e S0e S0e S0e S0e S0e S0e S0e S0e S0e |
                   1325: LI | C  | C | C | CI S S S S S S S S S S S S |
                   1326: L  | L    S   S   S  S S S S S S S S S S S S |
                   1327: LI | CI   S   S   S  S S S S S S S S S S S S |
                   1328: L  | L    S   S   S  S S S S S S S S S S S S | .
                   1329: :_
                   1330: Variable:1:1:0:offset
                   1331: :_
                   1332: :address of descriptor
                   1333: :_
                   1334: .TE
                   1335: .sp 1
                   1336: .TS
                   1337: center tab(:) ;
                   1338: L0w(2.2i) | L0w(2n)e S0e S0e S0e S0e S0e S0e S0e S0e S0e S0e S0e S0e S0e S0e S0e |
                   1339: LI | C  | C | C | CI S S S S S S | CI S S S S S |
                   1340: L  | L    S   S   S  S S S S S S   S  S S S S S |
                   1341: LI | CI   S   S   S  S S S S S S   S  S S S S S |
                   1342: L  | L    S   S   S  S S S S S S   S  S S S S S | .
                   1343: :_
                   1344: Trapped Variable:1:1:1:flags:type
                   1345: :_
                   1346: :address of data block
                   1347: :_
                   1348: .TE
                   1349: \fINotes:\fR The offset in a variable descriptor is the number of words from
                   1350: the top of the block in which the descriptor that is pointed to occurs.
                   1351: The second word in the descriptors for the trapped variables for \fM&pos\fR, \fM&random\fR,
                   1352: and \fM&trace\fR contain addresses of locations in statically allocated data.
                   1353: .bp
                   1354: .SH
                   1355: Data Block Formats
                   1356: .PP
                   1357: The data blocks used by the Icon system are pictured below.
                   1358: The data type code,
                   1359: shown as both a mnemonic and an integer,
                   1360: is always the first word of the block and has the same
                   1361: value as the type code in the
                   1362: .I value
                   1363: or
                   1364: .I "trapped variable"
                   1365: descriptor that refers to it.
                   1366: All
                   1367: .I name
                   1368: fields in the data blocks are
                   1369: .I "string qualifier"
                   1370: descriptors, and all
                   1371: .I pointers
                   1372: in the data blocks are
                   1373: .I "variable"
                   1374: descriptors.
                   1375: .sp 1
                   1376: .KS
                   1377: .TS
                   1378: center tab(:) ;
                   1379: L0w(2.2i) | L0w(2n) S0w(28n) S0w(2n) |
                   1380: LI      | C       S        S       | .
                   1381: :_
                   1382: Long Integer Block:T_LONGINT = 2
                   1383: :_
                   1384: .T&
                   1385: L       | L       CI       L       |
                   1386: L       | L       ^        L       |
                   1387: L       | L       ^        L       |
                   1388: L       | L       S        S       | .
                   1389: ::32-bit integer
                   1390: :_::_
                   1391: 
                   1392: :_
                   1393: .TE
                   1394: \fINote:\fR Long integers apply only when \fMsizeof(int) != sizeof(long)\fR
                   1395: .sp
                   1396: .KE
                   1397: .sp 1
                   1398: .KS
                   1399: .TS
                   1400: center tab(:) ;
                   1401: L0w(2.2i) | L0w(2n) S0w(28n) S0w(2n) |
                   1402: LI      | C       S        S       | .
                   1403: :_
                   1404: Real Block:T_REAL = 3
                   1405: :_
                   1406: .T&
                   1407: L       | L       CI       L       |
                   1408: L       | L       ^        L       |
                   1409: L       | L       ^        L       |
                   1410: L         L       ^        L
                   1411: L       | L       ^        L       |
                   1412: L       | L       ^        L       |
                   1413: L       | L       ^        L       |
                   1414: L       | L       S        S       | .
                   1415: ::double-precision real
                   1416: :_::_
                   1417: 
                   1418: 
                   1419: 
                   1420: :_::_
                   1421: 
                   1422: :_
                   1423: .TE
                   1424: .KE
                   1425: .sp 1
                   1426: .KS
                   1427: .TS
                   1428: center tab(:) ;
                   1429: L0w(2.2i) | L0w(2n) S0w(28n) S0w(2n) |
                   1430: LI      | C       S        S       | .
                   1431: :_
                   1432: Cset Block:T_CSET = 4
                   1433: :_
                   1434: .T&
                   1435: L       | L       CI       L       |
                   1436: L       | L       ^        L       |
                   1437: L       | L       ^        L       |
                   1438: L       | L       ^        L       |
                   1439: L       | L       ^        L       |
                   1440: L         L       ^        L
                   1441: L       | L       ^        L       |
                   1442: L       | L       ^        L       |
                   1443: L       | L       ^        L       |
                   1444: L       | L       ^        L       |
                   1445: L       | L       ^        L       |
                   1446: L       | L       S        S       | .
                   1447: ::256-bit character set
                   1448: :_::_
                   1449: 
                   1450: :_::_
                   1451: 
                   1452: 
                   1453: 
                   1454: :_::_
                   1455: 
                   1456: :_::_
                   1457: 
                   1458: :_
                   1459: .TE
                   1460: .KE
                   1461: .sp 1
                   1462: .KS
                   1463: .TS
                   1464: center tab(:) ;
                   1465: L0w(2.2i) | L0w(2n) S0w(28n) S0w(2n) |
                   1466: LI      | C       S        S       | .
                   1467: :_
                   1468: File Block:T_FILE = 5
                   1469: :_
                   1470: .T&
                   1471: L       | CI      S        S       | .
                   1472: :\s-2UNIX\s+2 file descriptor
                   1473: :_
                   1474: :file status
                   1475: :_
                   1476: .T&
                   1477: L       | L       CI       L       |
                   1478: L       | L       ^        L       |
                   1479: L       | L       ^        L       |
                   1480: L       | L       S        S       | .
                   1481: ::file name
                   1482: :_::_
                   1483: 
                   1484: :_
                   1485: .TE
                   1486: .KE
                   1487: .sp 1
                   1488: .KS
                   1489: .TS
                   1490: center tab(:) ;
                   1491: L0w(2.2i) | L0w(2n) S0w(28n) S0w(2n) |
                   1492: LI      | C       S        S       | .
                   1493: :_
                   1494: Procedure Block:T_PROCEDURE = 6
                   1495: :_
                   1496: .T&
                   1497: L       | CI      S        S       | .
                   1498: :size of this data block
                   1499: :_
                   1500: :entry point address
                   1501: :_
                   1502: :number of arguments
                   1503: :_
                   1504: :number of dynamic locals
                   1505: :_
                   1506: :number of static locals
                   1507: :_
                   1508: :index of first static local
                   1509: :_
                   1510: .T&
                   1511: L       | L       CI       L       |
                   1512: L       | L       ^        L       |
                   1513: L       | L       ^        L       |
                   1514: L       | L       S        S       | .
                   1515: ::procedure name
                   1516: :_::_
                   1517: 
                   1518: :_
                   1519: .T&
                   1520: L       | L       CI       L       |
                   1521: L       | L       ^        L       |
                   1522: L       | L       ^        L       |
                   1523: L       | L       S        S       | .
                   1524: ::name of first identifier
                   1525: :_::_
                   1526: 
                   1527: :_
                   1528: .T&
                   1529: L       | L       CB       L       |
                   1530: L         L       CB       L
                   1531: L       | L       CB       L       |
                   1532: L       | L       S        S       | .
                   1533: ::.
                   1534: ::.
                   1535: ::.
                   1536: :_
                   1537: .T&
                   1538: L       | L       CI       L       |
                   1539: L       | L       ^        L       |
                   1540: L       | L       ^        L       |
                   1541: L       | L       S        S       | .
                   1542: ::name of last identifier
                   1543: :_::_
                   1544: 
                   1545: :_
                   1546: .TE
                   1547: \fINotes:\fR Identifiers include arguments and locals.
                   1548: Similar blocks are used for built-in functions; in this
                   1549: case the word for the number of dynamic locals contains \-1.
                   1550: For functions, there are no argument names. Functions like \fMwrite\fR,
                   1551: which have an arbitrary number of argument, are indicated by
                   1552: the value \-1 in place of the number of arguments. Record constructors
                   1553: are distinguished from other functions by the value \-2
                   1554: in place of the number of dynamic locals. Each record declaration
                   1555: is distinguished by a unique record identification number, which
                   1556: appears in place of the number of static locals.
                   1557: .sp
                   1558: .KE
                   1559: .sp 1
                   1560: .KS
                   1561: .TS
                   1562: center tab(:) ;
                   1563: L0w(2.2i) | L0w(2n) S0w(28n) S0w(2n) |
                   1564: LI      | C       S        S       | .
                   1565: :_
                   1566: List Header Block:T_LIST = 7
                   1567: :_
                   1568: .T&
                   1569: L       | CI      S        S       | .
                   1570: :current size of list
                   1571: :_
                   1572: .T&
                   1573: L       | L       CI       L       |
                   1574: L       | L       ^        L       |
                   1575: L       | L       ^        L       |
                   1576: L       | L       S        S       | .
                   1577: ::pointer to first list block
                   1578: :_::_
                   1579: 
                   1580: :_
                   1581: .T&
                   1582: L       | L       CI       L       |
                   1583: L       | L       ^        L       |
                   1584: L       | L       ^        L       |
                   1585: L       | L       S        S       | .
                   1586: ::pointer to last list block
                   1587: :_::_
                   1588: 
                   1589: :_
                   1590: .TE
                   1591: .KE
                   1592: .sp 1
                   1593: .KS
                   1594: .TS
                   1595: center tab(:) ;
                   1596: L0w(2.2i) | L0w(2n) S0w(28n) S0w(2n) |
                   1597: LI      | C       S        S       | .
                   1598: :_
                   1599: List Element Block:T_LELEM = 11
                   1600: :_
                   1601: .T&
                   1602: L       | CI      S        S       | .
                   1603: :size of this data block
                   1604: :_
                   1605: :number of slots in this block
                   1606: :_
                   1607: :index of first slot used
                   1608: :_
                   1609: :number of slots used
                   1610: :_
                   1611: .T&
                   1612: L       | L       CI       L       |
                   1613: L       | L       ^        L       |
                   1614: L       | L       ^        L       |
                   1615: L       | L       S        S       | .
                   1616: ::pointer to previous list block
                   1617: :_::_
                   1618: 
                   1619: :_
                   1620: .T&
                   1621: L       | L       CI       L       |
                   1622: L       | L       ^        L       |
                   1623: L       | L       ^        L       |
                   1624: L       | L       S        S       | .
                   1625: ::pointer to next list block
                   1626: :_::_
                   1627: 
                   1628: :_
                   1629: .T&
                   1630: L       | L       CI       L       |
                   1631: L       | L       ^        L       |
                   1632: L       | L       ^        L       |
                   1633: L       | L       S        S       | .
                   1634: ::first slot
                   1635: :_::_
                   1636: 
                   1637: :_
                   1638: .T&
                   1639: L       | L       CB       L       |
                   1640: L         L       CB       L
                   1641: L       | L       CB       L       |
                   1642: L       | L       S        S       | .
                   1643: ::.
                   1644: ::.
                   1645: ::.
                   1646: :_
                   1647: .T&
                   1648: L       | L       CI       L       |
                   1649: L       | L       ^        L       |
                   1650: L       | L       ^        L       |
                   1651: L       | L       S        S       | .
                   1652: ::last slot
                   1653: :_::_
                   1654: 
                   1655: :_
                   1656: .TE
                   1657: .KE
                   1658: .sp 1
                   1659: .KS
                   1660: .TS
                   1661: center tab(:) ;
                   1662: L0w(2.2i) | L0w(2n) S0w(28n) S0w(2n) |
                   1663: LI      | C       S        S       | .
                   1664: :_
                   1665: Table Header Block:T_TABLE = 8
                   1666: :_
                   1667: .T&
                   1668: L       | CI      S        S       | .
                   1669: :current table size
                   1670: :_
                   1671: .T&
                   1672: L       | L       CI       L       |
                   1673: L       | L       ^        L       |
                   1674: L       | L       ^        L       |
                   1675: L       | L       S        S       | .
                   1676: ::default value
                   1677: :_::_
                   1678: 
                   1679: :_
                   1680: .T&
                   1681: L       | L       CI       L       |
                   1682: L       | L       ^        L       |
                   1683: L       | L       ^        L       |
                   1684: L       | L       S        S       | .
                   1685: ::first hash bucket
                   1686: :_::_
                   1687: 
                   1688: :_
                   1689: .T&
                   1690: L       | L       CB       L       |
                   1691: L         L       CB       L
                   1692: L       | L       CB       L       |
                   1693: L       | L       S        S       | .
                   1694: ::.
                   1695: ::.
                   1696: ::.
                   1697: :_
                   1698: .T&
                   1699: L       | L       CI       L       |
                   1700: L       | L       ^        L       |
                   1701: L       | L       ^        L       |
                   1702: L       | L       S        S       | .
                   1703: ::last hash bucket
                   1704: :_::_
                   1705: 
                   1706: :_
                   1707: .TE
                   1708: .KE
                   1709: .sp 1
                   1710: .KS
                   1711: .TS
                   1712: center tab(:) ;
                   1713: L0w(2.2i) | L0w(2n) S0w(28n) S0w(2n) |
                   1714: LI      | C       S        S       | .
                   1715: :_
                   1716: Table Element Block:T_TELEM = 10
                   1717: :_
                   1718: .T&
                   1719: L       | CI      S        S       | .
                   1720: :hash number
                   1721: :_
                   1722: .T&
                   1723: L       | L       CI       L       |
                   1724: L       | L       ^        L       |
                   1725: L       | L       ^        L       |
                   1726: L       | L       S        S       | .
                   1727: ::pointer to next element
                   1728: :_::_
                   1729: 
                   1730: :_
                   1731: .T&
                   1732: L       | L       CI       L       |
                   1733: L       | L       ^        L       |
                   1734: L       | L       ^        L       |
                   1735: L       | L       S        S       | .
                   1736: ::entry value
                   1737: :_::_
                   1738: 
                   1739: :_
                   1740: .T&
                   1741: L       | L       CI       L       |
                   1742: L       | L       ^        L       |
                   1743: L       | L       ^        L       |
                   1744: L       | L       S        S       | .
                   1745: ::assigned value
                   1746: :_::_
                   1747: 
                   1748: :_
                   1749: .TE
                   1750: .KE
                   1751: .sp 1
                   1752: .KS
                   1753: .TS
                   1754: center tab(:) ;
                   1755: L0w(2.2i) | L0w(2n) S0w(28n) S0w(2n) |
                   1756: LI      | C       S        S       | .
                   1757: :_
                   1758: Set Header Block:T_SET = 20
                   1759: :_
                   1760: .T&
                   1761: L       | CI      S        S       | .
                   1762: :current set size
                   1763: :_
                   1764: .T&
                   1765: L       | L       CI       L       |
                   1766: L       | L       ^        L       |
                   1767: L       | L       ^        L       |
                   1768: L       | L       S        S       | .
                   1769: ::first hash bucket
                   1770: :_::_
                   1771: 
                   1772: :_
                   1773: .T&
                   1774: L       | L       CB       L       |
                   1775: L         L       CB       L
                   1776: L       | L       CB       L       |
                   1777: L       | L       S        S       | .
                   1778: ::.
                   1779: ::.
                   1780: ::.
                   1781: :_
                   1782: .T&
                   1783: L       | L       CI       L       |
                   1784: L       | L       ^        L       |
                   1785: L       | L       ^        L       |
                   1786: L       | L       S        S       | .
                   1787: ::last hash bucket
                   1788: :_::_
                   1789: 
                   1790: :_
                   1791: .TE
                   1792: .KE
                   1793: .sp 1
                   1794: .KS
                   1795: .TS
                   1796: center tab(:) ;
                   1797: L0w(2.2i) | L0w(2n) S0w(28n) S0w(2n) |
                   1798: LI      | C       S        S       | .
                   1799: :_
                   1800: Set Element Block:T_SELEM = 21
                   1801: :_
                   1802: .T&
                   1803: L       | CI      S        S       | .
                   1804: :hash number
                   1805: :_
                   1806: .T&
                   1807: L       | L       CI       L       |
                   1808: L       | L       ^        L       |
                   1809: L       | L       ^        L       |
                   1810: L       | L       S        S       | .
                   1811: ::member value
                   1812: :_::_
                   1813: 
                   1814: :_
                   1815: .T&
                   1816: L       | L       CI       L       |
                   1817: L       | L       ^        L       |
                   1818: L       | L       ^        L       |
                   1819: L       | L       S        S       | .
                   1820: ::pointer to next member
                   1821: :_::_
                   1822: 
                   1823: :_
                   1824: .TE
                   1825: .KE
                   1826: .sp 1
                   1827: .KS
                   1828: .TS
                   1829: center tab(:) ;
                   1830: L0w(2.2i) | L0w(2n) S0w(28n) S0w(2n) |
                   1831: LI      | C       S        S       | .
                   1832: :_
                   1833: Record Block:T_RECORD = 9
                   1834: :_
                   1835: .T&
                   1836: L       | CI      S        S       | .
                   1837: :size of this data block
                   1838: :_
                   1839: :pointer to record constructor
                   1840: :_
                   1841: .T&
                   1842: L       | L       CI       L       |
                   1843: L       | L       ^        L       |
                   1844: L       | L       ^        L       |
                   1845: L       | L       S        S       | .
                   1846: ::first field of record
                   1847: :_::_
                   1848: 
                   1849: :_
                   1850: .T&
                   1851: L       | L       CB       L       |
                   1852: L         L       CB       L
                   1853: L       | L       CB       L       |
                   1854: L       | L       S        S       | .
                   1855: ::.
                   1856: ::.
                   1857: ::.
                   1858: :_
                   1859: .T&
                   1860: L       | L       CI       L       |
                   1861: L       | L       ^        L       |
                   1862: L       | L       ^        L       |
                   1863: L       | L       S        S       | .
                   1864: ::last field of record
                   1865: :_::_
                   1866: 
                   1867: :_
                   1868: .TE
                   1869: .KE
                   1870: .sp 1
                   1871: .KS
                   1872: .TS
                   1873: center tab(:) ;
                   1874: L0w(2.2i) | L0w(2n) S0w(28n) S0w(2n) |
                   1875: LI      | C       S        S       | .
                   1876: :_
                   1877: Co-Expression Stack Block:T_ESTACK = 18
                   1878: :_
                   1879: .T&
                   1880: L       | L       CI       L       |
                   1881: L       | L       ^        L       |
                   1882: L       | L       ^        L       |
                   1883: L       | L       S        S       | .
                   1884: ::most recent activator
                   1885: :_::_
                   1886: 
                   1887: :_
                   1888: .T&
                   1889: L       | CI      S        S       | .
                   1890: :stack base
                   1891: :_
                   1892: :stack pointer
                   1893: :_
                   1894: :address pointer
                   1895: :_
                   1896: :Icon/C boundary
                   1897: :_
                   1898: :number of results produced
                   1899: :_
                   1900: .T&
                   1901: L       | L       CI       L       |
                   1902: L       | L       ^        L       |
                   1903: L       | L       ^        L       |
                   1904: L       | L       S        S       | .
                   1905: ::pointer to refresh block
                   1906: :_::_
                   1907: 
                   1908: :_
                   1909: .T&
                   1910: L       | L       CB       L       |
                   1911: L         L       CB       L
                   1912: L       | L       CB       L       |
                   1913: L       | L       S        S       | .
                   1914: ::.
                   1915: ::.
                   1916: ::.
                   1917: :_
                   1918: .TE
                   1919: .KE
                   1920: .sp 1
                   1921: .KS
                   1922: .TS
                   1923: center tab(:) ;
                   1924: L0w(2.2i) | L0w(2n) S0w(28n) S0w(2n) |
                   1925: LI      | C       S        S       | .
                   1926: :_
                   1927: Co-Expression Heap Block:T_EBLOCK = 19
                   1928: :_
                   1929: .T&
                   1930: L       | CI      S        S       | .
                   1931: :size of this data block
                   1932: :_
                   1933: :entry point address
                   1934: :_
                   1935: :number of arguments
                   1936: :_
                   1937: :number of locals
                   1938: :_
                   1939: .T&
                   1940: L       | L       CI       L       |
                   1941: L       | L       ^        L       |
                   1942: L       | L       ^        L       |
                   1943: L       | L       S        S       | .
                   1944: ::procedure
                   1945: :_::_
                   1946: 
                   1947: :_
                   1948: .T&
                   1949: L       | L       CI       L       |
                   1950: L       | L       ^        L       |
                   1951: L       | L       ^        L       |
                   1952: L       | L       S        S       | .
                   1953: ::value of first identifier
                   1954: :_::_
                   1955: 
                   1956: :_
                   1957: .T&
                   1958: L       | L       CB       L       |
                   1959: L         L       CB       L
                   1960: L       | L       CB       L       |
                   1961: L       | L       S        S       | .
                   1962: ::.
                   1963: ::.
                   1964: ::.
                   1965: :_
                   1966: .T&
                   1967: L       | L       CI       L       |
                   1968: L       | L       ^        L       |
                   1969: L       | L       ^        L       |
                   1970: L       | L       S        S       | .
                   1971: ::value of last identifier
                   1972: :_::_
                   1973: 
                   1974: :_
                   1975: .TE
                   1976: \fINote:\fR Identifiers include arguments and locals.
                   1977: .sp
                   1978: .KE
                   1979: .sp 1
                   1980: .KS
                   1981: .TS
                   1982: center tab(:) ;
                   1983: L0w(2.2i) | L0w(2n) S0w(28n) S0w(2n) |
                   1984: LI      | C       S        S       | .
                   1985: :_
                   1986: Substring Trapped Variable:T_TVSUBS = 12
                   1987: :_
                   1988: .T&
                   1989: L       | CI      S        S       | .
                   1990: :length of substring
                   1991: :_
                   1992: :relative position of substring
                   1993: :_
                   1994: .T&
                   1995: L       | L       CI       L       |
                   1996: L       | L       ^        L       |
                   1997: L       | L       ^        L       |
                   1998: L       | L       S        S       | .
                   1999: ::variable containing substring
                   2000: :_::_
                   2001: 
                   2002: :_
                   2003: .TE
                   2004: .KE
                   2005: .sp 1
                   2006: .KS
                   2007: .TS
                   2008: center tab(:) ;
                   2009: L0w(2.2i) | L0w(2n) S0w(28n) S0w(2n) |
                   2010: LI      | C       S        S       | .
                   2011: :_
                   2012: Table Element Trapped Variable:T_TVTBL = 14
                   2013: :_
                   2014: .T&
                   2015: L       | CI      S        S       | .
                   2016: :hash number
                   2017: :_
                   2018: .T&
                   2019: L       | L       CI       L       |
                   2020: L       | L       ^        L       |
                   2021: L       | L       ^        L       |
                   2022: L       | L       S        S       | .
                   2023: ::pointer to table
                   2024: :_::_
                   2025: 
                   2026: :_
                   2027: .T&
                   2028: L       | L       CI       L       |
                   2029: L       | L       ^        L       |
                   2030: L       | L       ^        L       |
                   2031: L       | L       S        S       | .
                   2032: ::entry value
                   2033: :_::_
                   2034: 
                   2035: :_
                   2036: .T&
                   2037: L       | L       CI       L       |
                   2038: L       | L       ^        L       |
                   2039: L       | L       ^        L       |
                   2040: L       | L       S        S       | .
                   2041: ::
                   2042: :_::_
                   2043: 
                   2044: :_
                   2045: .TE
                   2046: \fINote\fR: The last descriptor in a table element trapped variable
                   2047: is not used until the element is inserted in the table, at which
                   2048: time the table element trapped variables is converted into a
                   2049: table element block.
                   2050: .KE
                   2051: .bp
                   2052: .ce 10
                   2053: \f3Appendix E \(em Stack Frame Formats\fR
                   2054: .ce 0
                   2055: .sp 1
                   2056: .PP
                   2057: Stack frame formats depend on computer architecture and the
                   2058: C compiler that is used. Consequently, stack frame formats are
                   2059: specific to a particular implementation. This appendix gives the
                   2060: UNIX PDP-11 and VAX-11 stack frame formats. See [3] for a detailed
                   2061: description of the design of stack frame formats.
                   2062: .PP
                   2063: On the PDP-11 and VAX-11 stacks start in high memory and grow
                   2064: downward. On these computers, a push causes the stack
                   2065: pointer to decrease and a pop causes the stack pointer to
                   2066: increase, while ``top of the stack'' refers to the
                   2067: \fIlowest\fR memory location that is logically contained in the stack.
                   2068: The diagrams that follow are arranged accordingly.
                   2069: .PP
                   2070: There are three kinds of stack frames: \fIprocedure frames\fR, \fIexpression
                   2071: frames\fR, and \fIgenerator frames\fR.
                   2072: For each kind of frame, a
                   2073: .I "frame pointer"
                   2074: points to the most recent
                   2075: .I "frame marker" ,
                   2076: which marks one end of the frame.
                   2077: These frame pointers are referred to as \fIpfp\fR, \fIefp\fR, and \fIgfp\fR,
                   2078: respectively.
                   2079: Each frame marker contains a pointer
                   2080: to the next most recent marker of the same kind.
                   2081: .sp 2
                   2082: .ce
                   2083: \f3PDP-11 Stack Frame Formats\fR
                   2084: .sp 2
                   2085: .PP
                   2086: On the PDP-11, \fIpfp\fR, \fIefp\fR, and \fIgfp\fR are in registers
                   2087: \fIr5\fR, \fIr4\fR, and \fIr3\fR, respectively,
                   2088: whenever an Icon procedure is active.
                   2089: In the interpreter implementation,
                   2090: .I r2
                   2091: contains the interpreter's program counter (\fIipc\fR),
                   2092: which points to the next icode operation to be done.
                   2093: When a C procedure is active,
                   2094: only the procedure frame pointer is kept in a register;
                   2095: registers
                   2096: .I r2\-r4
                   2097: are used for local variables by C procedures.
                   2098: .sp 1
                   2099: .SH
                   2100: Procedure Frames on the PDP-11
                   2101: .PP
                   2102: Icon procedure frames are augmented C procedure frames.
                   2103: A procedure frame contains a procedure's
                   2104: arguments, local variables,
                   2105: and temporary storage for incomplete computations.
                   2106: When an active procedure invokes another procedure,
                   2107: a new procedure frame is created for the new procedure,
                   2108: which then becomes active.
                   2109: As such, the new procedure represents an incomplete computation
                   2110: in the calling procedure,
                   2111: so the new procedure frame is
                   2112: .Q nested
                   2113: within the old one.
                   2114: The
                   2115: .I "procedure marker"
                   2116: is placed on the stack between the arguments and local variables.
                   2117: The format of the procedure frame is shown below.
                   2118: The locations are relative to \fIpfp\fR.
                   2119: .DS
                   2120: .ta 1iR 1.6i
                   2121:                arguments
                   2122:        4       number of arguments
                   2123:        2       return address
                   2124: \fIpfp\fR \(-> 0       previous \fIpfp\fR
                   2125:        \-2     previous \fIefp\fR
                   2126:        \-4     previous \fIgfp\fR
                   2127:        \-6     previous \fIipc\fR
                   2128:        \-8     previous source program line number
                   2129:        \-10    previous source program file name
                   2130: .DE
                   2131: Expression and generator frames are always
                   2132: contained wholly within a procedure frame,
                   2133: and their respective frame pointers are cleared to zero
                   2134: after being saved in the procedure marker.
                   2135: .PP
                   2136: The first argument to a procedure is located at 6(\fIpfp\fR),
                   2137: the second at 10(\fIpfp\fR), and so on.
                   2138: The first local variable is located at \-14(\fIpfp\fR),
                   2139: the second at \-18(\fIpfp\fR), and so on.
                   2140: .PP
                   2141: Procedure markers created for functions and operators
                   2142: do not contain the source program line number or file name,
                   2143: since functions and operators do not change it.
                   2144: Because they are C procedures,
                   2145: their local variables are not descriptors
                   2146: and are subject to C language conventions,
                   2147: but everything above the marker (higher addresses)
                   2148: is subject to Icon language conventions.
                   2149: The location of the procedure marker for functions and operators
                   2150: is considered the
                   2151: .I boundary ,
                   2152: mentioned in Section 3.2.
                   2153: .sp 1
                   2154: .SH
                   2155: Expression Frames on the PDP-11
                   2156: .PP
                   2157: An expression frame limits the scope of backtracking.
                   2158: No inactive generator outside the current expression frame
                   2159: may be reactivated until evaluation of the current expression is complete.
                   2160: The format of an expression marker is shown below;
                   2161: locations are relative to
                   2162: \fIefp\fR.
                   2163: .DS
                   2164: .ta 1iR 1.6i
                   2165: \fIefp\fR \(-> 0       previous \fIefp\fR
                   2166:        \-2     previous \fIgfp\fR
                   2167:        \-4     failure label for expression frame
                   2168: .DE
                   2169: When an expression frame is created,
                   2170: the generator frame pointer is cleared after being saved
                   2171: in the expression marker,
                   2172: to indicate that there are no inactive generators that may
                   2173: be reactivated while the new expression frame is current.
                   2174: An expression frame extends from its expression marker
                   2175: to the top of the stack.
                   2176: Expression frames are not disjoint;
                   2177: new frames are always nested within older ones.
                   2178: .PP
                   2179: When failure occurs within an expression and there
                   2180: are no inactive generators to reactivate,
                   2181: the expression frame is exited,
                   2182: and control is transferred to the failure label.
                   2183: If the failure label is null, however,
                   2184: another failure occurs within the new expression frame,
                   2185: and the logic is the same.
                   2186: .PP
                   2187: For limited expressions,
                   2188: the limitation counter is contained in an Icon integer
                   2189: just above the expression marker at 2(\fIefp\fR).
                   2190: This counter is decremented each time the expression suspends a result.
                   2191: .SH
                   2192: Generator Frames on the PDP-11
                   2193: .PP
                   2194: Generator frames are augmented procedure frames.
                   2195: A generator frame preserves the state of execution of a inactive generator.
                   2196: When a suspending procedure calls
                   2197: \fMpsusp\fR,
                   2198: a generator marker is placed on the stack
                   2199: to mark the point of suspension,
                   2200: and the most recent expression frame
                   2201: .I outside
                   2202: the suspending procedure frame
                   2203: (the expression frame that was current just prior to
                   2204: invocation of the suspending procedure)
                   2205: is then duplicated and pushed onto the stack.
                   2206: The suspending procedure then returns,
                   2207: so that the expression frame that was duplicated is current.
                   2208: Thus, the generator frame is contained within the expression frame, and
                   2209: .Q hides
                   2210: the inactive generator.
                   2211: The format of the generator marker is shown in the following table;
                   2212: locations are shown relative to \fIgfp\fR.
                   2213: .DS
                   2214: .ta 1iR 1.6i
                   2215:        10      reactivation address
                   2216:        8       previous \fIpfp\fR
                   2217:        6       previous \fIefp\fR
                   2218:        4       previous \fIgfp\fR
                   2219:        2       previous \fIipc\fR
                   2220: \fIgfp\fR \(-> 0       previous boundary address
                   2221:        \-2     previous value of \fM&level\fR
                   2222:        \-4     previous source program line number
                   2223:        \-6     previous source program file name
                   2224: .DE
                   2225: The last five words of the generator marker
                   2226: are actually part of a procedure marker,
                   2227: created by the call to
                   2228: \fMpsusp\fR.
                   2229: Thus, the reactivation address is just the return address for
                   2230: \fMpsusp\fR.
                   2231: .PP
                   2232: When a function or operator suspends,
                   2233: there is a boundary that becomes hidden.
                   2234: This boundary address needs to be restored upon reactivation.
                   2235: It is also important to the garbage collector,
                   2236: since the portion of a generator frame between the hidden
                   2237: boundary and the generator marker does not have
                   2238: the well-defined structure that is required.
                   2239: .sp 2
                   2240: .ce
                   2241: \f3VAX-11 Stack Frame Formats\fR
                   2242: .sp 2
                   2243: .PP
                   2244: The C frames on the VAX are variable in size and \fIap\fR is used
                   2245: to facilitate access to the arguments.
                   2246: .SH
                   2247: Procedure Frames on the VAX-11
                   2248: .PP
                   2249: On the VAX-11, there is a program counter (\fIpc\fR),
                   2250: a stack pointer (\fIsp\fR),
                   2251: a frame pointer (\fIfp\fR), and
                   2252: an argument pointer (\fIap\fR).
                   2253: These pointers are registers \fIr15\fR, \fIr14\fR, \fIr13\fR, and \fIr12\fR,
                   2254: respectively.
                   2255: Icon uses \fIfp\fR for \fIpfp\fR, \fIr11\fR for \fIefp\fR, and
                   2256: \fIr10\fR for \fIgfp\fR.
                   2257: .PP
                   2258: The procedure frame for the VAX-11 is:
                   2259: .DS
                   2260: .ta 1iR 1.6i
                   2261:                arguments
                   2262:        4       number of arguments
                   2263: \fIap\fR \(->  0       number of words in the argument list
                   2264:        \-4     previous \fIefp\fR
                   2265:        \-8     previous \fIgfp\fR
                   2266:                .\^.\^.
                   2267:        16      previous \fIpc\fR
                   2268:        12      previous \fIfp\fR
                   2269:        8       previous \fIap\fR
                   2270:        4       program status word and register mask
                   2271: \fIfp\fR \(->  0       0 (condition handler status)
                   2272:        \-4     previous source program line number
                   2273:        \-8     previous source program file name
                   2274:                local variables
                   2275: .DE
                   2276: The first argument is at 8(\fIap\fR), the second argument is at
                   2277: 16(\fIap\fR), and so on. The first local variable is at \-16(\fIfp\fR)\fR,
                   2278: the second local variable is at \-24(\fIfp\fR), and so on.
                   2279: .SH
                   2280: Expression Frames on the VAX-11
                   2281: .PP
                   2282: The expression frame marker for the VAX-11 is:
                   2283: .DS
                   2284: .ta 1iR 1.6i
                   2285: \fIefp\fR \(-> 0       previous \fIefp\fR
                   2286:        \-4     previous \fIgfp\fR
                   2287:        \-8     failure label for expression frame
                   2288: .DE
                   2289: .SH
                   2290: Generator Frames on the VAX-11
                   2291: .PP
                   2292: The generator frame marker for the VAX-11 is:
                   2293: .DS
                   2294: .ta 1iR 1.6i
                   2295:                previous \fIefp\fR
                   2296:                previous \fIgfp\fR
                   2297:                .\^.\^.
                   2298:                last saved register
                   2299:        20      reactivation address
                   2300:        16      previous \fIfp\fR
                   2301:        12      previous \fIap\fR
                   2302:        8       program status word and register mask
                   2303:        4       0 (condition handler address)
                   2304: \fIgfp\fR \(-> 0       previous boundary address
                   2305:        \-4     previous value of \fM&level\fR
                   2306:        \-8     previous source program line number
                   2307:        \-12    previous source program file name
                   2308: .DE
                   2309: .bp
                   2310: .ce 10
                   2311: \f3Appendix F \(em Sample Functions\fR
                   2312: .ce 0
                   2313: .sp 1
                   2314: .PP
                   2315: The following routines are examples of the source code
                   2316: for Icon functions.
                   2317: As indicated in the report,
                   2318: each routine consists of a C procedure that performs the indicated
                   2319: function and a procedure block linking the C procedure with
                   2320: the Icon procedure invocation mechanism.
                   2321: .PP
                   2322: The first example is the code for the routine \fMwrite\fR,
                   2323: as supplied with the Icon distribution, and is included
                   2324: to show how a routine is written to handle a variable number
                   2325: of arguments.
                   2326: .Ds
                   2327: .ta 3.5i
                   2328: #include "../h/rt.h"
                   2329: 
                   2330: /*
                   2331:  * write(a,\*bb,\*b...) - write arguments.
                   2332:  */
                   2333: 
                   2334: Xwrite(nargs)
                   2335: int nargs;
                   2336:    {
                   2337:    register int n;
                   2338:    char sbuf\^[MAXSTRING];
                   2339:    struct descrip arg;
                   2340:    FILE *f;
                   2341: 
                   2342:    f = stdout;
                   2343:    arg = nullstr;
                   2344: 
                   2345:    for (n = 1; n \*(<= nargs; n++) {
                   2346:       arg = ARG(n);
                   2347:       DeRef(arg);      /* dereference arguments */
                   2348: .De
                   2349: .Ds
                   2350: .ta 3.5i
                   2351:       if (!QUAL(arg) && TYPE(arg) == T_FILE) {
                   2352:          if (n > 1) {
                   2353:             putc('\en', f);
                   2354:             fflush(f);
                   2355:             }
                   2356:          if ((BLKLOC(arg)->file.status & FS_WRITE) == 0)
                   2357:             runerr(213, &arg);
                   2358:          f = BLKLOC(arg)->file.fd;
                   2359:          arg = nullstr;
                   2360:          }
                   2361:       else {
                   2362:          if (n == 1 && (k_output.status & FS_WRITE) == 0)
                   2363:             runerr(213, NULL);
                   2364:          defany(&arg, &nullstr);
                   2365:          if (cvstr(&arg, sbuf) == NULL)
                   2366:             runerr(109, &arg);
                   2367:          putstr(f, STRLOC(arg), STRLEN(arg));
                   2368:          }
                   2369:       }
                   2370: .De
                   2371: .Ds
                   2372: .ta 3.5i
                   2373:    putc('\en', f);
                   2374:    fflush(f);
                   2375:    if (STRLOC(arg) \*(>= sbuf && STRLOC(arg) < sbuf + MAXSTRING) {
                   2376:       sneed(STRLEN(arg));
                   2377:       STRLOC(arg) = alcstr(STRLOC(arg), STRLEN(arg));
                   2378:       }
                   2379:    ARG(0) = arg;
                   2380:    }
                   2381: 
                   2382: Procblock(write,\*b-1)
                   2383: .De
                   2384: The \-1 in the \fMProcblock\fR macro indicates that \fMwrite\fR
                   2385: takes an arbitrary number of arguments.
                   2386: .PP
                   2387: The following two routines are examples of
                   2388: typical functions that could
                   2389: be added to the run-time system using the technique described
                   2390: in Section 4.
                   2391: .PP
                   2392: The first of these routines, \fMseek\fR, interfaces to the C
                   2393: library routine \fMfseek\fR.
                   2394: .Ds
                   2395: .Ta 3.5i
                   2396: #include "../h/rt.h"
                   2397: 
                   2398: /*
                   2399:  * seek(file,\*boffset,\*bstart) - seek to offset byte from start in file.
                   2400:  */
                   2401: 
                   2402: Xseek(nargs, arg3, arg2, arg1, arg0)
                   2403: int nargs;
                   2404: struct descrip arg3, arg2, arg1, arg0;
                   2405:    {
                   2406:    long l1, l2;
                   2407:    int status;
                   2408:    FILE *fd;
                   2409:    long ftell();
                   2410: 
                   2411:    DeRef(arg1);
                   2412:    if (arg1.type != D_FILE)
                   2413:       runerr(106);
                   2414: .Dd
                   2415:    defint(&arg2, &l1, 0);
                   2416:    defshort(&arg3, 0);
                   2417: 
                   2418:    fd = BLKLOC(arg1)->file.fd;
                   2419: 
                   2420:    if ((BLKLOC(arg1)->file.status == 0) ||
                   2421:        (fseek(fd, l1, arg3.value.integer) == -1))
                   2422:       fail();
                   2423:    mkint(ftell(fd), &arg0);
                   2424:    }
                   2425: 
                   2426: Procblock(seek,\*b3)
                   2427: .De
                   2428: The argument 3 in the \fMProcblock\fR macro indicates that
                   2429: \fMseek\fR takes three arguments.
                   2430: .PP
                   2431: The routine \fMgetenv\fR provides access to
                   2432: shell environment variables through the C library procedure \fMgetenv\fR.
                   2433: .Ds
                   2434: .ta 3.5i
                   2435: #include "../h/rt.h"
                   2436: 
                   2437: /*
                   2438:  * getenv(s) - return contents of environment variable s
                   2439:  */
                   2440: 
                   2441: Xgetenv(nargs, arg1, arg0)
                   2442: int nargs;
                   2443: struct descrip arg1, arg0;
                   2444:    {
                   2445:    register char *p;
                   2446:    register int len;
                   2447:    char sbuf\^[MAXSTRING];
                   2448: 
                   2449:    DeRef(&arg1);
                   2450: .Dd
                   2451: .ta 3.5i
                   2452:    if (!QUAL(arg1))    /* check legality of argument */
                   2453:       runerr(103, &arg1);
                   2454:    if (STRLEN(arg1) \*(<= 0 || STRLEN(arg1) \*(>= MAXSTRING)
                   2455:       runerr(401, &arg1);
                   2456:    qtos(&arg1, sbuf);  /* convert argument to C-style string */
                   2457: 
                   2458:    if ((p = getenv(sbuf)) != NULL) {   /* get environment variable */
                   2459:       len = strlen(p);
                   2460:       sneed(len);
                   2461:       STRLEN(arg0) = len;
                   2462:       STRLOC(arg0) = alcstr(p, len);
                   2463:       }
                   2464:    else        /* fail if variable not in environment */
                   2465:       fail();
                   2466:    }
                   2467: 
                   2468: Procblock(getenv,\*b-1)
                   2469: .De

unix.superglobalmegacorp.com

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