Annotation of 43BSD/contrib/icon/docs/tr84-11b.roff, revision 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.