|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.