|
|
1.1 ! root 1: .\" Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. ! 2: .Du START ! 3: .sp 1 ! 4: .in 0 ! 5: .ce 99 ! 6: DESCRIPTION OF B ! 7: ! 8: Lambert Meertens ! 9: Steven Pemberton ! 10: ! 11: CWI ! 12: Amsterdam ! 13: ! 14: April 1984 ! 15: .ce 0 ! 16: .Co ! 17: .ds Sn Contents ! 18: .bp ! 19: .in 15 ! 20: .nf ! 21: .ps 8 ! 22: .vs 10 ! 23: CONTENTS ! 24: ! 25: 0.\0INTRODUCTION ! 26: 1.\0VALUES IN B ! 27: 2.\0SYNTAX DESCRIPTION METHOD ! 28: 3.\0REPRESENTATIONS ! 29: 4.\0UNITS ! 30: 4.1.\0HOW-TO-UNITS ! 31: 4.2.\0YIELD-UNITS ! 32: 4.3.\0TEST-UNITS ! 33: 4.4.\0REFINEMENTS ! 34: 4.5.\0COMMAND-SUITES ! 35: 5.\0COMMANDS ! 36: 5.1.\0\0SIMPLE-COMMANDS ! 37: 5.1.1.\0\0CHECK-COMMANDS ! 38: 5.1.2.\0\0WRITE-COMMANDS ! 39: 5.1.3.\0\0READ-COMMANDS ! 40: 5.1.4.\0\0PUT-COMMANDS ! 41: 5.1.5.\0\0DRAW-COMMANDS ! 42: 5.1.6.\0\0CHOOSE-COMMANDS ! 43: 5.1.7.\0\0SET-RANDOM-COMMANDS ! 44: 5.1.8.\0\0REMOVE-COMMANDS ! 45: 5.1.9.\0\0INSERT-COMMANDS ! 46: 5.1.10.\0DELETE-COMMANDS ! 47: 5.1.11.\0QUIT-COMMAND ! 48: 5.1.12.\0RETURN-COMMANDS ! 49: 5.1.13.\0SUCCEED-COMMAND ! 50: 5.1.14.\0FAIL-COMMAND ! 51: 5.1.15.\0USER-DEFINED-COMMANDS ! 52: 5.1.16.\0REFINED-COMMANDS ! 53: 5.2.\0CONTROL-COMMANDS ! 54: 5.2.1.\0IF-COMMANDS ! 55: 5.2.2.\0SELECT-COMMANDS ! 56: 5.2.3.\0WHILE-COMMANDS ! 57: 5.2.4.\0FOR-COMMANDS ! 58: 6.\0EXPRESSIONS, TARGETS AND TESTS ! 59: 6.1.\0EXPRESSIONS ! 60: 6.1.1.\0NUMERIC-CONSTANTS ! 61: 6.1.2.\0TARGET-CONTENTS ! 62: 6.1.3.\0TRIMMED-TEXTS ! 63: 6.1.4.\0TABLE-SELECTIONS ! 64: 6.1.5.\0DISPLAYS ! 65: 6.1.6.\0FORMULAS ! 66: Formulas with user-defined functions ! 67: Formulas with predefined functions ! 68: 6.1.7.\0REFINED-EXPRESSIONS ! 69: 6.2.\0TARGETS ! 70: 6.2.1.\0IDENTIFIERS ! 71: 6.2.2.\0TRIMMED-TEXT-TARGETS ! 72: 6.2.3.\0TABLE-SELECTION-TARGETS ! 73: 6.3.\0TESTS ! 74: 6.3.1.\0ORDER-TESTS ! 75: 6.3.2.\0PROPOSITIONS ! 76: Propositions with user-defined predicates ! 77: Propositions with predefined predicates ! 78: 6.3.3.\0REFINED-TESTS ! 79: 6.3.4.\0CONJUNCTIONS ! 80: 6.3.5.\0DISJUNCTIONS ! 81: 6.3.6.\0NEGATIONS ! 82: 6.3.7.\0QUANTIFICATIONS ! 83: INDEX ! 84: .ps 10 ! 85: .vs 12 ! 86: .in 0 ! 87: .ds Sn Introduction ! 88: .bp ! 89: .St 0 INTRODUCTION ! 90: .fi ! 91: .Tx ! 92: \*B is a simple but powerful new programming language, designed for use in ! 93: personal computing. ! 94: (Note: the name ``\*B'' is only a temporary working title, ! 95: and the new language bears no relation to the predecessor of ! 96: C.)\ ! 97: The foremost aim in the design of \*B has been the ease of use for ! 98: programmers who want to produce working programs without having ! 99: to master a complex tool. ! 100: An implementation of \*B is available from the \*B group at ! 101: the CWI, currently only under UNIX* or its look-alikes, but soon ! 102: (scheduled early 1985) also for the IBM-PC under MS-DOS. ! 103: Remarks concerning the implementation appear in this description ! 104: between double braces {{ and }}. ! 105: .sp 0.6v ! 106: This description of \*B originated from a text, prepared by ! 107: the first author, for use in teaching \*B during the Fall ! 108: term of 1982 at New York University. ! 109: The aim is to provide a reference book for the users of \*B that is more ! 110: accessible than the somewhat formal ``Draft Proposal'' [2]. ! 111: While it is not a text book, it should also be useful ! 112: to people who already have ample programming ! 113: experience and want to learn \*B. ! 114: A text book for beginners is also available from the CWI [1]. ! 115: .sp 0.6v ! 116: In this description we have tried to remain close to the Draft Proposal ! 117: in order to facilitate cross-referencing. To this end, all section numbers ! 118: from section 4 onwards are the same as in the Draft Proposal. ! 119: However there are some changes in terminology. ! 120: Some minor differences are ! 121: .sp 0.6v ! 122: .ta 2m \w'mmTYPE-TYPES-expressionmm'u \w'mmTYPE-TYPES-expressionmm'u+\w'multiple-expressionmm'u ! 123: .nf ! 124: \& Draft Proposal: This description: ! 125: .sp 0.4v ! 126: \& textual-display text-display ! 127: \& textual-body text-body ! 128: \& LIST-body optional-list-body ! 129: \& TABLE-body optional-table-filler-series ! 130: .fi ! 131: .sp 0.6v ! 132: But the main difference is perhaps in the treatment of ``collateral'': ! 133: .sp 0.6v ! 134: .nf ! 135: \& Draft Proposal: This description: Examples ! 136: .sp 0.4v ! 137: \& collateral-expression expression \*(<:a (a, b) a, b\*(:> ! 138: \& TYPE-expression single-expression \*(<:a (a, b)\*(:> ! 139: \& TYPE-TYPES-expression multiple-expression \*(<: a, b\*(:> ! 140: .fi ! 141: .sp 0.6v ! 142: Whereas these are purely descriptional differences, ! 143: there are also a few differences in content. ! 144: Where the Draft Proposal has the keyword \*(<:ALLOW\*(:>, ! 145: \*B now has the keyword \*(<:SHARE\*(:>; ! 146: a command \*(<:READ\*(:>\ ...\ \*(<:RAW\*(:> has been added; ! 147: and approximate-constants may no longer consist of just an exponent-part: ! 148: \*(<:E-1\*(:> must now be written \*(<:1E-1\*(:>. ! 149: .sp 0.6v ! 150: References ! 151: .sp 0.5v ! 152: .in +\w'[1]\ 'u ! 153: .ti 0 ! 154: [1]\ \fIComputer Programming for Beginners, Introducing the B Language, ! 155: Part 1\fP, ! 156: .br ! 157: Leo Geurts, CWI, Amsterdam, 1984 ! 158: .sp 0.5v ! 159: .ti 0 ! 160: [2]\ \fIDraft Proposal for the B Programming Language\fP, ! 161: .br ! 162: Lambert Meertens, CWI, Amsterdam, 1981 ! 163: .sp 0.6v ! 164: .in 0 ! 165: *\ \s-2Unix is a trademark of Bell Laboratories.\s0 ! 166: .fi ! 167: .SN 1 ! 168: .bp ! 169: .St 1 "VALUES IN \*B" ! 170: .de tY ! 171: .sp 1 ! 172: .ne 5 ! 173: .in \w'Compounds\0\0'u ! 174: .ta \w'Compounds\0\0'u ! 175: .ti 0 ! 176: \\$1\t\c ! 177: .. ! 178: .Xx number ! 179: .Xx exact number ! 180: .Xx approximate number ! 181: .Xx text ! 182: .Xx character ! 183: .Xx order ! 184: .Xx compound ! 185: .Xx field ! 186: .Xx list ! 187: .Xx entry ! 188: .Xx list entry ! 189: .Xx table ! 190: .Xx table entry ! 191: .Xx key ! 192: .Xx associate ! 193: .Tx ! 194: \*B has two basic types of values: numbers and texts, and three ways of making ! 195: new types of values from existing ones: compounds, lists and tables. ! 196: The built-in functions for operating on these values are described ! 197: in section 6.1.6 entitled ``Formulas with predefined functions''. ! 198: .tY Numbers ! 199: Numbers come in two kinds: exact and approximate. ! 200: Exact numbers are rational numbers. ! 201: For example, \*(<:1.25\*(:> = \*(<:5/4\*(:>, and \*(<:(1/3)*3\*(:> = \*(<:1\*(:>. ! 202: There is no restriction on the size of numerator and denominator. ! 203: Approximate numbers are implemented by whatever the hardware has to offer ! 204: for fast but approximate arithmetic (floating point). ! 205: .br ! 206: The arithmetic operations and many other functions give an exact result ! 207: when their operands are exact, ! 208: and an approximate result otherwise, ! 209: but the function \*(<:sin\*(:>, for example, always returns an approximate number. ! 210: .br ! 211: An exact number can be made approximate with the \*(<:~\*(:> function ! 212: (e.g. \*(<:~1.25\*(:>); ! 213: the functions \*(<:round\*(:>, \*(<:floor\*(:> and \*(<:ceiling\*(:> can be used to convert ! 214: an approximate number to an exact one. ! 215: .br ! 216: Exact and approximate numbers may be mixed in arithmetic, as in \*(<:4 * atan 1\*(:>. ! 217: .tY Texts ! 218: Texts (strings) are composed of printable ASCII characters. ! 219: They are variable length, and are ordered in the usual lexicographic way: ! 220: \&\*(<:'a' < 'aa' < 'b'\*(:>. ! 221: There is no type ``character'': a text of length one will do. ! 222: .br ! 223: The printable characters ! 224: are the 95 characters represented on the lines below, ! 225: where the blank space preceding `\*(<:!\*(:>' stands for the ! 226: (otherwise invisible) space character: ! 227: .Di 5 ! 228: \*(<: !"#$%&'()*+,-./0123456789:;<=>? ! 229: @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_ ! 230: `abcdefghijklmnopqrstuvwxyz{|}~\*(:> ! 231: .br ! 232: .Ed ! 233: The ordering ! 234: on the characters is the ASCII collating order, which is the order ! 235: in which the characters are displayed above. ! 236: .tY Compounds ! 237: A compound consists of a sequence of other values, its ``fields''. ! 238: For example, ! 239: the number \*(<:3\*(:> and the text \*(<:'xyz'\*(:> may be combined to give the ! 240: compound \*(<:3, 'xyz'\*(:>. ! 241: Compounds are also ordered lexicographically. ! 242: .br ! 243: For example, \*(<:(3, 'xyz') < (3, 'yz') < (pi, 'aaa')\*(:>. ! 244: For this to be meaningful, the compounds that are compared must ! 245: be of the same type. ! 246: This means that they have the ! 247: same number of fields, and that corresponding fields are of the same type. ! 248: .br ! 249: The only way to obtain the individual fields of a compound is to put it ! 250: in a multiple-target with the right number of components, as in ! 251: .Di 1 ! 252: \*(<:PUT name IN last'name, first'name, middle'name\*(:>. ! 253: .Ed ! 254: .tY Lists ! 255: A list is a \fIsorted\fP sequence of values, its ``entries''. ! 256: All entries of a list must be of the same type, and this determines ! 257: the type of the list. ! 258: The length of a list may vary without influencing its type. ! 259: When an entry is inserted in a list (with an \*(<:INSERT\*(:> command), it is automatically ! 260: inserted in the list in the proper position in the sorting order. ! 261: A list may contain duplicates of the same entry. ! 262: Entries may be removed with the \*(<:REMOVE\*(:> command. ! 263: Again, lists themselves are ordered lexicographically. ! 264: .tY Tables ! 265: A table consists of a (sorted) sequence of ``table entries''. ! 266: Each table entry is a pair of two values: a \fIkey\fP and an \fIassociate\fP. ! 267: All keys of a table must be of the same type; similarly, all associates must ! 268: also be of the same type (but that type may be different to ! 269: that of the keys). ! 270: A table may not contain duplicate keys. ! 271: If \*(<:k\*(:> is a key of the table \*(<:t\*(:>, then \*(<:t[k]\*(:> ! 272: gives the associate corresponding to \*(<:k\*(:>. ! 273: New entries can be made, or existing entries modified, by putting the ! 274: associate value in the table after selecting with the key value, as ! 275: in \*(<:PUT a IN t[k]\*(:>. ! 276: Entries can be deleted with the \*(<:DELETE\*(:> command, as in \*(<:DELETE t[k]\*(:>. ! 277: The ordering is again lexicographic. ! 278: .St 2 "SYNTAX DESCRIPTION METHOD" ! 279: .Tx ! 280: The syntax of \*B is given in the following form: ! 281: each rule starts with the name of the thing being defined followed by a colon; ! 282: following this are one or more alternatives, ! 283: each marked with a \(bu in front. ! 284: Each alternative is composed of symbols that stand for ! 285: themselves, or the names of other rules. ! 286: These other rules are then defined elsewhere in the grammar, ! 287: or possibly in the same rule. ! 288: As an example, here is a simple grammar for a small part of English: ! 289: .Sy 4 ! 290: .Pn sentence 3 ! 291: .Al ! 292: declarative ! 293: .Al ! 294: declarative \*(<:,\*(:> connective\0sentence ! 295: .Pn declarative 3 ! 296: .Al ! 297: collective-noun\0verb\0collective-noun ! 298: .Al ! 299: collective-noun \*(<:do not\*(:> verb\0collective-noun ! 300: .Pn collective-noun 2 ! 301: .Al ! 302: \*(<:cats\*(:> ! 303: .Al ! 304: \*(<:dogs\*(:> ! 305: .Al ! 306: \*(<:people\*(:> ! 307: .Al ! 308: \*(<:the police\*(:> ! 309: .Pn verb 2 ! 310: .Al ! 311: \*(<:love\*(:> ! 312: .Al ! 313: \*(<:hate\*(:> ! 314: .Al ! 315: \*(<:eat\*(:> ! 316: .Al ! 317: \*(<:hassle\*(:> ! 318: .Pn connective 2 ! 319: .Al ! 320: \*(<:and\*(:> ! 321: .Al ! 322: \*(<:but\*(:> ! 323: .Al ! 324: \*(<:although\*(:> ! 325: .Al ! 326: \*(<:because\*(:> ! 327: .Al ! 328: \*(<:yet\*(:> ! 329: .Tx ! 330: This produces sentences like: ! 331: .Di 4 ! 332: .in -6 ! 333: \*(<:dogs do not love the police\*(:> ! 334: \*(<:the police hassle dogs\*(:> ! 335: \*(<:cats do not hate cats , but cats hate dogs , because dogs hate cats\*(:> ! 336: \*(<:people eat dogs , yet dogs love people\*(:> ! 337: .in +6 ! 338: .Ed ! 339: .in 0 ! 340: You will notice that the names of rules are in a different ! 341: typeface to words that stand for themselves. ! 342: In the grammar of \*B that follows, furthermore, rule names ! 343: are all in lower-case letters, while words that stand for themselves are all ! 344: in upper-case letters, so they are easily distinguished. ! 345: .sp ! 346: It often happens that a part of an alternative is optional. ! 347: There is a special rule for this: ! 348: .Sy 4 ! 349: .Pr empty 2 ! 350: .Al ! 351: .br ! 352: .Pr optional-ANYTHING 3 ! 353: .Al ! 354: empty ! 355: .Al ! 356: ANYTHING ! 357: .Tx ! 358: The ``optional'' rule is included to save many rules in the definition. ! 359: For example, it stands for a rule ! 360: .Pn optional-comment 3 ! 361: .Al ! 362: empty ! 363: .Al ! 364: comment ! 365: .Tx ! 366: and similar rules. ! 367: (Empty produces an empty result.) ! 368: .St 3 REPRESENTATIONS ! 369: .Xx indentation ! 370: .Xx increase-indentation ! 371: .Xx decrease-indentation ! 372: .Xx new-line-proper ! 373: .Xx keyword ! 374: .Xx tag ! 375: .Pr new-line 2 ! 376: .Sl ! 377: optional-comment\0new-line-proper\0indent ! 378: .Ps ! 379: A \*B program consists of indented lines. ! 380: A new-line-proper marks a transition to a new line. ! 381: An indent stands for the left margin blank offset. ! 382: Initially, the left margin has zero width. ! 383: The indentation is increased by an increase-indentation ! 384: and decreased again by a decrease-indentation. ! 385: These always come in pairs and serve for grouping, just as BEGIN-END pairs ! 386: do in other programming languages. ! 387: An increase-indentation is always preceded by a line ending with a colon ! 388: (possibly followed by comment). ! 389: .Pr comment 3 ! 390: .Al ! 391: optional-new-line-proper\0optional-spaces ! 392: \*(<:\\\*(:> comment-body\0optional-further-comment ! 393: .Pr further-comment 3 ! 394: .Al ! 395: new-line-proper\0optional-spaces ! 396: \*(<:\\\*(:> comment-body\0optional-further-comment ! 397: .Pr spaces 2 ! 398: .Sl ! 399: space\0optional-spaces ! 400: .Ps ! 401: Comments may be placed at the end of a line or may stand alone ! 402: on a line. ! 403: No comment may precede the first line of a unit (see section 4). ! 404: .br ! 405: A comment-body may be any sequence of printable characters. ! 406: .Sx 2 comment: ! 407: \*(<:\\modified 6/4/84 to reject passwords of length < 6\*(:> ! 408: .Tx ! 409: Keywords are composed of CAPITAL letters (\*(<:A\*(:> to \*(<:Z\*(:>), digits, ! 410: and quotes (\*(<:'\*(:> and \*(<:"\*(:>). ! 411: A keyword must start with a letter. ! 412: For example, \*(<:A3'B"\*(:> is a keyword. ! 413: .Tx ! 414: Tags are composed of lower-case letters (\*(<:a\*(:> to \*(<:z\*(:>), digits, ! 415: and quotes (\*(<:'\*(:> and \*(<:"\*(:>). ! 416: A tag must start with a letter. ! 417: For example, \*(<:a3'b"\*(:> is a tag. ! 418: .Tx ! 419: Some other signs are composite: \*(<:..\*(:>, \*(<:**\*(:>, \*(<:*/\*(:>, \*(<:/*\*(:>, \*(<:^^\*(:>, ! 420: \*(<:<<\*(:>, \*(<:><\*(:>, \*(<:>>\*(:>, \*(<:<=\*(:>, \*(<:<>\*(:> and \*(<:>=\*(:>. ! 421: Spaces are freely allowed between symbols, but not ! 422: within keywords, tags, numeric-constants and composite signs. ! 423: Sometimes spaces are required to separate keywords and tags from following ! 424: symbols. ! 425: For example, \*(<:cos y\*(:> is not the same as \*(<:cosy\*(:>: the latter is ! 426: taken to be one tag. ! 427: .St 4 UNITS ! 428: .Xx work-space ! 429: .Sy 4 ! 430: .Pr unit 4 ! 431: .Al ! 432: how-to-unit ! 433: .Al ! 434: yield-unit ! 435: .Al ! 436: test-unit ! 437: .Ps ! 438: Units are the building blocks of a \*B ``program''. ! 439: Users can define new commands, functions and predicates by writing a unit. ! 440: These units reside in a work-space. ! 441: .Pr refinement-suite 2 ! 442: .Al ! 443: new-line\0refinement\0optional-refinement-suite ! 444: .Ps ! 445: When writing a unit, the specification of some parts ! 446: (commands, expressions and tests) may be deferred by ! 447: using a ``refinement''. ! 448: These refinements are then specified at the end of the unit. ! 449: .Se 3 4.1 HOW-TO-UNITS ! 450: .Xx keyword ! 451: .Xx user-defined-command ! 452: .Sy 3 ! 453: .Pr how-to-unit 3 ! 454: .Al ! 455: \*(<:HOW'TO\*(:> formal-user-defined-command\*(<::\*(:> ! 456: .br ! 457: command-suite ! 458: .br ! 459: optional-refinement-suite ! 460: .Pr formal-user-defined-command 2 ! 461: .Sl ! 462: keyword\0optional-formal-tail ! 463: .Ps ! 464: The first keyword of a formal-user-defined-command must be unique, i.e., ! 465: different from the first keywords of all predefined and other ! 466: user-defined commands. ! 467: So it is impossible to redefine the built-in commands of \*B. ! 468: It may also not be \*(<:HOW'TO\*(:>, \*(<:YIELD\*(:>, \*(<:TEST\*(:>, \*(<:SHARE\*(:> or \*(<:ELSE\*(:>. ! 469: Otherwise, it may be chosen freely. ! 470: There are no restrictions on the second and further keywords. ! 471: .Pr formal-tail 3 ! 472: .Al ! 473: formal-parameter\0optional-formal-trailer ! 474: .Al ! 475: formal-trailer ! 476: .Pr formal-trailer 2 ! 477: .Sl ! 478: keyword\0optional-formal-tail ! 479: .Pr formal-parameter 1 ! 480: .Sl ! 481: tag ! 482: .Ps ! 483: Note that, although actual-parameters (section 5.1.16) ! 484: and formal-operands (section 4.2) may be composite, ! 485: formal-parameters must be simple tags. ! 486: .Sx 5 \k1how-to-unit: ! 487: \*(<:HOW'TO PUSH value ON stack: ! 488: PUT value IN stack[#stack+1]\*(:> ! 489: .Tx ! 490: A how-to-unit defines the meaning of a new command ! 491: (see ``user-defined-commands'', section 5.1.16). ! 492: The above unit defines a \*(<:PUSH\*(:>\ ...\ \*(<:ON\*(:>\ ... command. ! 493: Once the command has been defined, it may be used in the ! 494: same way as the built-in commands. ! 495: Other user-defined commands may be used in the body of a unit ! 496: even if they have not yet been defined, ! 497: though they must be defined by the time the unit is invoked. ! 498: .Xe ! 499: .Sa ! 500: quit-command (5.1.11), ! 501: share-heading (4.5), ! 502: user-defined-commands (5.1.16). ! 503: .Se 3 4.2 YIELD-UNITS ! 504: .Xx "overloading of functions and predicates" ! 505: .Xx user-defined functions ! 506: .Xx formula ! 507: .Xx function ! 508: .Xx predicate ! 509: .Xx zeroadic ! 510: .Xx monadic ! 511: .Xx dyadic ! 512: .Sy 3 ! 513: .Pr yield-unit 3 ! 514: .Al ! 515: \*(<:YIELD\*(:> formal-formula\*(<::\*(:> ! 516: .br ! 517: command-suite ! 518: .br ! 519: optional-refinement-suite ! 520: .Pr formal-formula 4 ! 521: .Al ! 522: formal-zeroadic-formula ! 523: .Al ! 524: formal-monadic-formula ! 525: .Al ! 526: formal-dyadic-formula ! 527: .Pr formal-zeroadic-formula 2 ! 528: .Sl ! 529: zeroadic-function ! 530: .Pr formal-monadic-formula 2 ! 531: .Sl ! 532: monadic-function\0formal-operand ! 533: .Pr formal-dyadic-formula 2 ! 534: .Al ! 535: formal-operand\0dyadic-function\0formal-operand ! 536: .Ps ! 537: Functions must not be ``overloaded'' (multiply defined), ! 538: and a user-defined function must be represented by a tag. ! 539: However, a given tag may be used, at the same time, for ! 540: a dyadic-function and either a zeroadic- or a monadic-function or -predicate. ! 541: (In other words, you may not have a function that is both monadic ! 542: and zeroadic, for otherwise it would be impossible to decide what was meant ! 543: in cases such as \*(<:f + 1\*(:>, ! 544: where \*(<:f\*(:> could be either zeroadic or monadic, and the restrictions ! 545: also apply to combinations of functions and predicates.) ! 546: .Pr formal-operand 2 ! 547: .Sl ! 548: single-identifier ! 549: .Sx 5 \k1yield-unit: ! 550: \*(<:YIELD (a, b) over (c, d): ! 551: PUT c*c+d*d IN rr ! 552: RETURN (a*c+b*d)/rr, (-a*d+b*c)/rr\*(:> ! 553: .Xe ! 554: .Tx ! 555: A yield-unit defines the meaning of a new function ! 556: (see ``Formulas with user-defined functions'', section 6.1.6). ! 557: The example given above defines complex division. ! 558: (Complex numbers are not a built-in type of \*B.) ! 559: .br ! 560: Functions may be zeroadic (no operands), monadic (one trailing operand) ! 561: or dyadic (two operands, one at the left and one at the right). ! 562: .Sa ! 563: return-commands (5.1.12), ! 564: share-headings (4.5), ! 565: formulas with user-defined functions (6.1.6). ! 566: .Se 3 4.3 TEST-UNITS ! 567: .Xx "overloading of functions and predicates" ! 568: .Xx user-defined-predicates ! 569: .Xx test ! 570: .Xx formula ! 571: .Xx function ! 572: .Xx predicate ! 573: .Xx proposition ! 574: .Xx zeroadic ! 575: .Xx monadic ! 576: .Xx dyadic ! 577: .Sy 3 ! 578: .Pr test-unit 3 ! 579: .Al ! 580: \*(<:TEST\*(:> formal-proposition\*(<::\*(:> ! 581: .br ! 582: command-suite ! 583: .br ! 584: optional-refinement-suite ! 585: .Pr formal-proposition 4 ! 586: .Al ! 587: formal-zeroadic-proposition ! 588: .Al ! 589: formal-monadic-proposition ! 590: .Al ! 591: formal-dyadic-proposition ! 592: .Pr formal-zeroadic-proposition 2 ! 593: .Sl ! 594: zeroadic-predicate ! 595: .Pr formal-monadic-proposition 2 ! 596: .Al ! 597: monadic-predicate\0formal-operand ! 598: .Pr formal-dyadic-proposition 2 ! 599: .Al ! 600: formal-operand\0dyadic-predicate\0formal-operand ! 601: .Ps ! 602: Like functions, predicates must not be ``overloaded'', ! 603: though a given tag may be used, at the same time, for ! 604: a dyadic-predicate and either a zeroadic- or a monadic-function or -predicate. ! 605: .Sx 5 \k1test-unit: ! 606: \*(<:TEST a subset b: ! 607: REPORT EACH x IN a HAS x in b\*(:> ! 608: .Xe ! 609: .Tx ! 610: A test-unit defines the meaning of a new predicate ! 611: (see ``Propositions with user-defined predicates'', section 6.3.2). ! 612: Like functions, predicates may be zeroadic, monadic or dyadic. ! 613: .br ! 614: Tests do not return a value, but succeed or fail via the \*(<:REPORT\*(:>, ! 615: \*(<:SUCCEED\*(:> and \*(<:FAIL\*(:> commands. ! 616: .Sa ! 617: report-commands (5.1.13), ! 618: succeed-command (5.1.14), ! 619: fail-command (5.1.15), ! 620: share-headings (4.5), ! 621: propositions with user-defined predicates (6.3.2). ! 622: .Se 4 4.4 REFINEMENTS ! 623: .Xx keyword ! 624: .Sy 4 ! 625: .Pr refinement 4 ! 626: .Al ! 627: command-refinement ! 628: .Al ! 629: expression-refinement ! 630: .Al ! 631: test-refinement ! 632: .Pr command-refinement 2 ! 633: .Sl ! 634: keyword\*(<::\*(:> command-suite ! 635: .Ps ! 636: The keyword of a command-refinement must be different from the first keywords ! 637: of all predefined commands, ! 638: and it may also not be \*(<:HOW'TO\*(:>, \*(<:YIELD\*(:>, \*(<:TEST\*(:>, \*(<:SHARE\*(:> or \*(<:ELSE\*(:>. ! 639: It may, however, be the same as the first keyword of a user-defined-command. ! 640: .Sx 4 \k1command-refinement: ! 641: \*(<:SELECT'TASK: ! 642: PUT min tasks IN task ! 643: REMOVE task FROM tasks\*(:> ! 644: .Pr expression-refinement 2 ! 645: .Sl ! 646: tag\*(<::\*(:> command-suite ! 647: .Sx 4 expression-refinement: ! 648: \*(<:stack'pointer: ! 649: IF stack = {}: RETURN 0 ! 650: RETURN max keys stack\*(:> ! 651: .Pr test-refinement 2 ! 652: .Sl ! 653: tag\*(<::\*(:> command-suite ! 654: .Sx 4 test-refinement: ! 655: \*(<:special'case: ! 656: REPORT position+d = line'length\*(:> ! 657: .Xe ! 658: .Tx ! 659: Refinements support the method of ``top-down'' programming, also ! 660: known as programming by ``stepwise refinement''. ! 661: The body of a unit may be written using refined-commands, -expressions ! 662: and -tests that reflect the appropriate, coarse-grained, level of ! 663: abstraction for expressing the algorithmic intention. ! 664: In subsequent refinements, these may be refined to ! 665: the necessary detail, possibly in several steps. ! 666: As with units, there are three kinds of refinements. ! 667: The differences with units are: ! 668: .in (\w'\(em\ 'u+3m)u ! 669: .ti 3m ! 670: \(em\ refinements are bound to a unit and may not be invoked ! 671: from other units; ! 672: .ti 3m ! 673: \(em\ all tags known inside the unit are also known inside the ! 674: refinement; ! 675: .ti 3m ! 676: \(em\ no parameters or operands can be passed when the ! 677: refinement is invoked. ! 678: .in 0 ! 679: {{Currently, refinements may only occur within unit bodies, and not ! 680: in ``immediate commands''.}} ! 681: .Sa ! 682: refined-commands (5.1.17), ! 683: refined-expressions (6.1.7), ! 684: refined-tests (6.3.3). ! 685: .Se 4 4.5 COMMAND-SUITES ! 686: .Xx target ! 687: .Xx local ! 688: .Xx global ! 689: .Xx work-space ! 690: .Xx permanent environment ! 691: .Xx yield-unit ! 692: .Xx expression-refinement ! 693: .Xx return-command ! 694: .Xx test-unit ! 695: .Xx test-refinement ! 696: .Xx report-command ! 697: .Xx succeed-command ! 698: .Xx fail-command ! 699: .Sy 4 ! 700: .Pr command-suite 4 ! 701: .Al ! 702: simple-command ! 703: .Al ! 704: increase-indentation\0optional-share-heading ! 705: optional-command-sequence\0decrease-indentation ! 706: .Ps ! 707: A command-suite may only follow the preceding colon on the same line ! 708: if it is a simple-command. ! 709: Otherwise, it starts on a new line, with ! 710: all lines of the command-suite indented. ! 711: .Sx 4 command-suite ! 712: \*(<:SHARE name'list, abbreviation'table ! 713: IF name in keys abbreviation'table: ! 714: PUT abbreviation'table[name] IN name ! 715: IF name not'in name'list: ! 716: INSERT name IN name'list\*(:> ! 717: .Xe ! 718: .Pr share-heading 3 ! 719: .Al ! 720: new-line \*(<:SHARE\*(:> identifier\0optional-share-heading ! 721: .Ps ! 722: Tags used as targets (variables) in a unit ! 723: (except those that are formal-parameters) ! 724: are by default local to the unit. ! 725: If a target should be shared between several units, ! 726: this can be indicated by listing the tag ! 727: in a share-heading at the start of the unit body. ! 728: It stands then for a global target of the work-space. ! 729: The global targets together with their contents are also called the ``permanent ! 730: environment'', because they survive on logging out. ! 731: .br ! 732: A share-heading may only occur in the command-suite of a unit (and not ! 733: of a refinement or compound-command). ! 734: .Sx 2 share-heading ! 735: \*(<:SHARE name'list, abbreviation'table\*(:> ! 736: .Xe ! 737: .Pr command-sequence 2 ! 738: .Al ! 739: new-line\0command\0optional-command-sequence ! 740: .Ps ! 741: The execution of the command-suite of a yield-unit or ! 742: expression-refinement must end in a return-command, and return-commands ! 743: may only occur within such command-suites. ! 744: .Ps ! 745: The execution of the command-suite of a test-unit or ! 746: test-refinement must end in a report-, succeed- or fail-command, and these ! 747: may only occur within such command-suites. ! 748: .Sx 3 command-sequence ! 749: \*(<:IF name in keys abbreviation'table: ! 750: PUT abbreviation'table[name] IN name ! 751: IF name not'in name'list: ! 752: INSERT name IN name'list\*(:> ! 753: .Xe ! 754: .St 5 COMMANDS ! 755: .Xx immediate command ! 756: .Xx global ! 757: .Xx interrupt key ! 758: .Tx ! 759: Commands may be given as ``immediate commands'', directly from ! 760: the terminal, or may be part of a unit. ! 761: If commands are given as immediate commands, they are obeyed ! 762: directly. ! 763: Any targets in the command are then interpreted as global targets ! 764: from the permanent environment. ! 765: Within a unit, targets are local, unless they have been listed ! 766: in a share-heading (see above). ! 767: .br ! 768: If the user presses the interrupt key while a command is executing, ! 769: execution is aborted, and the user is prompted for another immediate command. ! 770: .Sy 3 ! 771: .Pr command 3 ! 772: .Al ! 773: simple-command ! 774: .Al ! 775: control-command ! 776: .Se 3 5.1 SIMPLE-COMMANDS ! 777: .Sy 3 ! 778: .Pr simple-command 3 ! 779: .Al ! 780: check-command ! 781: .Al ! 782: write-command ! 783: .Al ! 784: read-command ! 785: .Al ! 786: put-command ! 787: .Al ! 788: draw-command ! 789: .Al ! 790: choose-command ! 791: .Al ! 792: set-random-command ! 793: .Al ! 794: remove-command ! 795: .Al ! 796: insert-command ! 797: .Al ! 798: delete-command ! 799: .Al ! 800: terminating-command ! 801: .Al ! 802: user-defined-command ! 803: .Al ! 804: refined-command ! 805: .Pr terminating-command 3 ! 806: .Al ! 807: quit-command ! 808: .Al ! 809: return-command ! 810: .Al ! 811: report-command ! 812: .Al ! 813: succeed-command ! 814: .Al ! 815: fail-command ! 816: .Se 2 5.1.1 CHECK-COMMANDS ! 817: .Sy 2 ! 818: .Pr check-command 2 ! 819: .Sl ! 820: \*(<:CHECK\*(:> test ! 821: .Sx 3 \k1check-command: ! 822: \*(<:CHECK i >= 0 AND j >= 0 AND i+j <= n\*(:> ! 823: .Xe ! 824: .Tx ! 825: When a check-command is executed, its test is tested. ! 826: If the test fails, an error is reported and execution halts. ! 827: Otherwise, no message is given and execution continues. ! 828: Check-commands may be used, for example, to check the requirements of ! 829: parameters or operands on entry to a unit. ! 830: The liberal use of check-commands helps to get programs correct quickly. ! 831: .Se 3 5.1.2 WRITE-COMMANDS ! 832: .Xx convert to a text ! 833: .Xx permanent environment ! 834: .Xx interrupt key ! 835: .Sy 3 ! 836: .Pr write-command 3 ! 837: .Al ! 838: \*(<:WRITE\*(:> new-liners ! 839: .Al ! 840: \*(<:WRITE\*(:> optional-new-liners\0expression\0optional-new-liners ! 841: .Pr new-liners 2 ! 842: .Sl ! 843: \*(<:/\*(:> optional-new-liners ! 844: .Ex 3 ! 845: \k1write-commands: ! 846: \h'|\n1u'\*(<:WRITE //\*(:> ! 847: \h'|\n1u'\*(<:WRITE // 'Give a value in the range 1 through `n`: '\*(:> ! 848: .Tx ! 849: The expression is converted to a text and written to the screen. ! 850: Each \*(<:/\*(:> gives a transition to a new line. ! 851: Note that you write no comma before or after the \*(<:/\*(:>s. ! 852: .br ! 853: With the exception of adjacent texts, ! 854: values that are adjacent are written separated by a space. ! 855: Compounds within other values (within lists, tables or other compounds) ! 856: are written with commas between their fields, ! 857: and where necessary, the whole surrounded by brackets. ! 858: Similarly, inner texts are written enclosed by quotes. ! 859: Compounds and texts not within other values are output without commas, ! 860: brackets and quotes. ! 861: Thus, ! 862: .Di 2 ! 863: \*(<:WRITE 0, 1, ',', 2, '!', '!', 3 ! 864: WRITE {1; 2}, {['a','b']:('b','a'); ['b','a']:('a','b')} /\*(:> ! 865: .Ed ! 866: gives ! 867: .Di 1 ! 868: \*(<:0 1 , 2 !! 3 {1; 2} {['a', 'b']: ('b', 'a'); ['b', 'a']: ('a', 'b')}\*(:> ! 869: .Ed ! 870: For formatting purposes, see the operators \*(<:>>\*(:>, \*(<:<<\*(:>, and \*(<:><\*(:> ! 871: in section 6.1.6, ``Functions on Texts'', ! 872: and the conversions in text-displays in section 6.1.5, ``Displays''. ! 873: .Se 3 5.1.3 READ-COMMANDS ! 874: .Sy 3 ! 875: .Pr read-command 4 ! 876: .Al ! 877: \*(<:READ\*(:> target \*(<:EG\*(:> expression ! 878: .Al ! 879: \*(<:READ\*(:> target \*(<:RAW\*(:> ! 880: .Ex 3 ! 881: read-commands: ! 882: \*(<:READ n, s EG 0, '' ! 883: READ line RAW\*(:> ! 884: .Xe ! 885: .Tx ! 886: The execution of a read-command prompts the user ! 887: to supply one input line. ! 888: .br ! 889: If an \*(<:EG\*(:> part is present, the input is interpreted as an ! 890: \fIexpression\fP of the same type as the expression following \*(<:EG\*(:>. ! 891: (Usually, the example expression will consist of constants, ! 892: but other expressions are also allowed.) ! 893: The input expression is evaluated in the permanent environment ! 894: (so local tags of units cannot be used) and put in the target. ! 895: To input a text-display (literal), text quotes are required. ! 896: .br ! 897: If \*(<:RAW\*(:> is specified, the target must be a text target. ! 898: The input line is put in the target literally. ! 899: No text quotes are needed. ! 900: .br ! 901: If the user presses the interrupt key instead of supplying a value, ! 902: the read-command, and in fact the whole program, is aborted. ! 903: This is useful for entering a sequence of data of unspecified length. ! 904: .Se 3 5.1.4 PUT-COMMANDS ! 905: .Xx target ! 906: .Xx location ! 907: .Xx type ! 908: .Sy 3 ! 909: .Pr put-command 3 ! 910: .Sl ! 911: \*(<:PUT\*(:> expression \*(<:IN\*(:> target ! 912: .Sx 3 \k1put-command: ! 913: \*(<:PUT a+1, ({}, {1..a}) IN a, b\*(:> ! 914: .Xe ! 915: .Tx ! 916: The value of the expression is put in the target. ! 917: This means that the value will be held in a location ! 918: for the target, until a different value is put in the target, ! 919: or the target is deleted. ! 920: If no such location exists already, it is created on ! 921: the spot. ! 922: Here, as in other cases, the types must agree. ! 923: {{This is currently not checked in general.}} ! 924: See also the sections on various kinds of targets below (section 6.2). ! 925: .Se 2 5.1.5 DRAW-COMMANDS ! 926: .Xx random ! 927: .Xx number ! 928: .Sy 2 ! 929: .Pr draw-command 2 ! 930: .Sl ! 931: \*(<:DRAW\*(:> target ! 932: .Sx 3 \k1draw-command: ! 933: \*(<:DRAW r\*(:> ! 934: .Xe ! 935: .Tx ! 936: A random approximate number ! 937: (from \*(<:~0\*(:> up to, but not including, \*(<:~1\*(:>) ! 938: is drawn and put in the target. ! 939: .Se 4 5.1.6 CHOOSE-COMMANDS ! 940: .Xx text, list or table ! 941: .Xx random ! 942: .Xx character ! 943: .Xx list entry ! 944: .Xx associate ! 945: .Sy 4 ! 946: .Pr choose-command 4 ! 947: .Sl ! 948: \*(<:CHOOSE\*(:> target \*(<:FROM\*(:> expression ! 949: .Sx 3 \k1choose-command: ! 950: \*(<:CHOOSE exit FROM exits[current'room]\*(:> ! 951: .Xe ! 952: .Tx ! 953: The expression must have a text, list or table as value. ! 954: This value must not be empty. ! 955: An item is drawn at random from the value ! 956: (characters from a text, entries from a list and associates ! 957: from a table) ! 958: and put in the target. ! 959: The item is not removed from the value. ! 960: .Se 2 5.1.7 SET-RANDOM-COMMANDS ! 961: .Xx random ! 962: .Sy 2 ! 963: .Pr set-random-command 2 ! 964: .Sl ! 965: \*(<:SET'RANDOM\*(:> expression ! 966: .Sx 3 \k1set-random-command: ! 967: \*(<:SET'RANDOM 'Monte Carlo', run\*(:> ! 968: .Xe ! 969: .Tx ! 970: The (pseudo-)random sequence ! 971: used for draw- and choose-commands ! 972: is reset to a point, depending on the ! 973: value of the expression. ! 974: .Se 3 5.1.8 REMOVE-COMMANDS ! 975: .Xx list entry ! 976: .Sy 3 ! 977: .Pr remove-command 3 ! 978: .Sl ! 979: \*(<:REMOVE\*(:> expression \*(<:FROM\*(:> target ! 980: .Sx 3 \k1remove-command: ! 981: \*(<:REMOVE task FROM tasks\*(:> ! 982: .Xe ! 983: .Tx ! 984: The target must hold a list, and the value of the expression must be ! 985: an entry of that list. ! 986: The entry is removed. ! 987: If it was present more than once, only one instance is removed. ! 988: .Se 3 5.1.9 INSERT-COMMANDS ! 989: .Xx list entry ! 990: .Sy 3 ! 991: .Pr insert-command 3 ! 992: .Sl ! 993: \*(<:INSERT\*(:> expression \*(<:IN\*(:> target ! 994: .Sx 3 \k1insert-command: ! 995: \*(<:INSERT new'task IN tasks\*(:> ! 996: .Xe ! 997: .Tx ! 998: The target must hold a list. ! 999: The value of the expression is inserted as a list entry. ! 1000: If that entry was already present, one more instance will be present. ! 1001: .Se 2 5.1.10 DELETE-COMMANDS ! 1002: .Xx location ! 1003: .Xx table entry ! 1004: .Xx table-selection-target ! 1005: .Sy 2 ! 1006: .Pr delete-command 2 ! 1007: .Sl ! 1008: \*(<:DELETE\*(:> target ! 1009: .Sx 3 \k1delete-command: ! 1010: \*(<:DELETE t[i], u[i, j]\*(:> ! 1011: .Xe ! 1012: .Tx ! 1013: The location for the target ceases to exist. ! 1014: If a multiple-target is given, all its single-targets are deleted. ! 1015: If a table-selection-target is given, the table must contain the key ! 1016: that is used as selector. ! 1017: The table entry with that key is then deleted from the table. ! 1018: It is an error to delete a trimmed-text-target (e.g., \*(<:t@2\*(:>). ! 1019: .Se 2 5.1.11 QUIT-COMMAND ! 1020: .Xx how-to-unit ! 1021: .Xx command-refinement ! 1022: .Xx immediate-command ! 1023: .Xx permanent environment ! 1024: .Sy 2 ! 1025: .Pr quit-command 2 ! 1026: .Sl ! 1027: \*(<:QUIT\*(:> ! 1028: .Ps ! 1029: A quit-command may only occur in the command-suite of a ! 1030: how-to-unit or command-refinement, or as an immediate command. ! 1031: .Sx 3 \k1quit-command: ! 1032: \*(<:QUIT\*(:> ! 1033: .Xe ! 1034: .Tx ! 1035: The execution of a quit-command causes the termination of the execution ! 1036: of the how-to-unit or command-refinement in whose command-suite ! 1037: it occurs. ! 1038: If it occurs in a command-refinement, the execution of ! 1039: the invoking refined-command is thereby terminated and the further ! 1040: execution continues as if the refined-command had terminated normally. ! 1041: Otherwise, the execution of ! 1042: the invoking user-defined-command is terminated and the further ! 1043: execution continues similarly. ! 1044: .br ! 1045: Given as an immediate command, \*(<:QUIT\*(:> terminates the current ! 1046: session. ! 1047: All units and targets in the permanent environment ! 1048: survive and can be used again at the next session. ! 1049: .Se 2 5.1.12 RETURN-COMMANDS ! 1050: .Xx expression-refinement ! 1051: .Xx user-defined-function ! 1052: .Xx refined-expression ! 1053: .Xx yield-unit ! 1054: .Sy 2 ! 1055: .Pr return-command 2 ! 1056: .Sl ! 1057: \*(<:RETURN\*(:> expression ! 1058: .Sx 3 \k1return-command: ! 1059: \*(<:RETURN (a*c+b*d)/rr, (-a*d+b*c)/rr\*(:> ! 1060: .Xe ! 1061: .Tx ! 1062: The execution of a return-command causes the termination of the execution ! 1063: of the yield-unit or expression-refinement in whose command-suite ! 1064: it occurs. ! 1065: The value of the expression is returned as the value of the invoking ! 1066: user-defined function or refined-expression. ! 1067: Return-commands may only occur within the command-suite of a ! 1068: yield-unit or expression-refinement. ! 1069: .Se 2 5.1.13 REPORT-COMMANDS ! 1070: .Xx test-unit ! 1071: .Xx test-refinement ! 1072: .Xx user-defined-predicate ! 1073: .Xx refined-test ! 1074: .Xx bound tags ! 1075: .Pr report-command 2 ! 1076: .Sl ! 1077: \*(<:REPORT\*(:> test ! 1078: .Sx 3 \k1report-command: ! 1079: \*(<:REPORT i in keys t\*(:> ! 1080: .Xe ! 1081: .Tx ! 1082: The execution of a report-command causes the termination of the execution ! 1083: of the test-unit or test-refinement in whose command-suite ! 1084: it occurs. ! 1085: The invoking user-defined predicate or refined-test ! 1086: succeeds/fails if the test of the report-command succeeds/fails. ! 1087: If the invoker is a test-refinement, ! 1088: any bound tags set by a for-command (see section 5.2.4) or ! 1089: a quantification (section 6.3.7) will temporarily survive, ! 1090: as described under REFINED-TESTS (section 6.3.3). ! 1091: .br ! 1092: Report-commands may only occur within the command-suite of a ! 1093: test-unit or test-refinement. ! 1094: .br ! 1095: The command ``\*(<:REPORT\*(:> test'' is equivalent to ! 1096: .Di 3 ! 1097: \*(<:SELECT: ! 1098: \*(:>test\*(<:: SUCCEED ! 1099: ELSE: FAIL\*(:> ! 1100: .Ed ! 1101: .Se 2 5.1.14 SUCCEED-COMMAND ! 1102: .Xx test-unit ! 1103: .Xx test-refinement ! 1104: .Xx user-defined-predicate ! 1105: .Xx refined-test ! 1106: .Xx bound tags ! 1107: .Sy 2 ! 1108: .Pr succeed-command 2 ! 1109: .Sl ! 1110: \*(<:SUCCEED\*(:> ! 1111: .Sx 3 \k1succeed-command: ! 1112: \*(<:SUCCEED\*(:> ! 1113: .Xe ! 1114: .Tx ! 1115: The execution of a succeed-command causes the termination of the execution ! 1116: of the test-unit or test-refinement in whose command-suite ! 1117: it occurs. ! 1118: The invoking user-defined predicate or refined-test succeeds. ! 1119: As with report-commands, bound tags temporarily survive. ! 1120: .br ! 1121: Succeed-commands may only occur within the command-suite of a ! 1122: test-unit or test-refinement. ! 1123: .br ! 1124: The command \*(<:SUCCEED\*(:> is equivalent to \*(<:REPORT 0 = 0\*(:>. ! 1125: .Se 2 5.1.15 FAIL-COMMAND ! 1126: .Xx test-unit ! 1127: .Xx test-refinement ! 1128: .Xx user-defined-predicate ! 1129: .Xx refined-test ! 1130: .Xx bound tags ! 1131: .Sy 2 ! 1132: .Pr fail-command 2 ! 1133: .Sl ! 1134: \*(<:FAIL\*(:> ! 1135: .Sx 3 \k1fail-command: ! 1136: \*(<:FAIL\*(:> ! 1137: .Xe ! 1138: .Tx ! 1139: The execution of a fail-command causes the termination of the execution ! 1140: of the test-unit or test-refinement in whose command-suite ! 1141: it occurs. ! 1142: The invoking user-defined predicate or refined-test fails. ! 1143: As with report-commands, bound tags temporarily survive. ! 1144: .br ! 1145: Fail-commands may only occur within the command-suite of a ! 1146: test-unit or test-refinement. ! 1147: .br ! 1148: The command \*(<:FAIL\*(:> is equivalent to \*(<:REPORT 0 = 1\*(:>. ! 1149: .Se 2 5.1.16 USER-DEFINED-COMMANDS ! 1150: .Xx keyword ! 1151: .Xx how-to-unit ! 1152: .Xx quit-command ! 1153: .Sy 2 ! 1154: .Pr user-defined-command 2 ! 1155: .Sl ! 1156: keyword\0optional-actual-parameter\0optional-trailer ! 1157: .Pr trailer 2 ! 1158: .Sl ! 1159: keyword\0optional-actual-parameter\0optional-trailer ! 1160: .Pr actual-parameter 2 ! 1161: .Al ! 1162: identifier ! 1163: .Al ! 1164: target ! 1165: .Al ! 1166: expression ! 1167: .Ps ! 1168: The keywords and actual-parameters must correspond one to one to those ! 1169: of the formal-user-defined-command of one unique how-to-unit. ! 1170: .Ex 6 ! 1171: \k1user-defined-commands: ! 1172: \h'|\n1u'\*(<:CLEAN'UP\*(:> ! 1173: \h'|\n1u'\*(<:DRINK me\*(:> ! 1174: \h'|\n1u'\*(<:TURN a UPSIDE DOWN\*(:> ! 1175: \h'|\n1u'\*(<:PUSH v ON operand'stack\*(:> ! 1176: .Xe ! 1177: .Tx ! 1178: A user-defined-command is executed in the following steps: ! 1179: .in \w'2.\ 'u ! 1180: .ti 0 ! 1181: 1.\ Any local tags in the how-to-unit that might clash with tags currently ! 1182: in use are systematically replaced by other tags that do not cause conflict. ! 1183: .ti 0 ! 1184: 2.\ Each actual-parameter is placed between parentheses \*(<:(\*(:> and \*(<:)\*(:> ! 1185: and then ! 1186: substituted throughout the unit for the corresponding formal-parameter. ! 1187: .ti 0 ! 1188: 3.\ The command-suite of the unit, thus modified, is executed. ! 1189: .in 0 ! 1190: The execution of the user-defined-command is complete when the execution ! 1191: of this command-suite terminates (normally, or because of the execution ! 1192: of a quit-command). ! 1193: After the execution is complete, ! 1194: the local tags of the unit are no longer accessible. ! 1195: .Se 2 5.1.17 REFINED-COMMANDS ! 1196: .Xx keyword ! 1197: .Xx command-refinement ! 1198: .Xx quit-command ! 1199: .Sy 2 ! 1200: .Pr refined-command 2 ! 1201: .Sl ! 1202: keyword ! 1203: .Ps ! 1204: The keyword of a refined-command must occur as the keyword of one ! 1205: command-refinement in the unit ! 1206: in which it occurs. ! 1207: That command-refinement specifies the meaning of the refined-command. ! 1208: .Sx 3 \k1refined-command: ! 1209: \*(<:REMOVE'MULTIPLES\*(:> ! 1210: .Xe ! 1211: .Tx ! 1212: A refined-command is executed by executing ! 1213: the command-suite of the corresponding command-refinement. ! 1214: The execution of the refined-command is complete when the execution ! 1215: of this command-suite terminates ! 1216: (normally, or because of the execution of a quit-command). ! 1217: .Se 5 5.2 CONTROL-COMMANDS ! 1218: .Sy 5 ! 1219: .Pr control-command 5 ! 1220: .Al ! 1221: if-command ! 1222: .Al ! 1223: select-command ! 1224: .Al ! 1225: while-command ! 1226: .Al ! 1227: for-command ! 1228: .Se 2 5.2.1 IF-COMMANDS ! 1229: .Sy 2 ! 1230: .Pr if-command 2 ! 1231: .Sl ! 1232: \*(<:IF\*(:> test\*(<::\*(:> command-suite ! 1233: .Sx 3 \k1if-command: ! 1234: \*(<:IF i < 0: PUT -i, -j IN i, j\*(:> ! 1235: .Xe ! 1236: .Tx ! 1237: The test is tested. ! 1238: If it succeeds, the command-suite is executed; ! 1239: if it fails, the command-suite is not executed. ! 1240: .br ! 1241: (If something should be executed on failure too, or there are ! 1242: more alternatives, you should use a select-command instead.) ! 1243: .br ! 1244: The command ! 1245: ``\*(<:IF\*(:> test\*(<::\*(:> command-suite'' ! 1246: is equivalent to: ! 1247: .Di 3 ! 1248: \*(<:SELECT: ! 1249: \*(:>test\*(<:: \*(:>command-suite\*(<: ! 1250: ELSE: \\do nothing.\*(:> ! 1251: .Ed ! 1252: .Se 2 5.2.2 SELECT-COMMANDS ! 1253: .Sy 2 ! 1254: .Pr select-command 2 ! 1255: .Sl ! 1256: \*(<:SELECT:\*(:> alternative-suite ! 1257: .Pr alternative-suite 3 ! 1258: .Al ! 1259: increase-indentation\0new-line\0alternative-sequence\0decrease-indentation ! 1260: .Pr alternative-sequence 4 ! 1261: .Al ! 1262: single-alternative ! 1263: .Al ! 1264: else-alternative ! 1265: .Al ! 1266: single-alternative\0new-line\0alternative-sequence ! 1267: .Pr single-alternative 2 ! 1268: .Sl ! 1269: test\*(<::\*(:> command-suite ! 1270: .Pr else-alternative 2 ! 1271: .Sl ! 1272: \*(<:ELSE:\*(:> command-suite ! 1273: .Eo 5 select-commands:\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\k2\": ! 1274: \h'|\n1u'\*(<:SELECT:\*(:> \h'|\n2u'\*(<:SELECT:\*(:> ! 1275: \h'|\n1u'\*(<: a < 0: RETURN -a\*(:> \h'|\n2u'\*(<: a < 0: RETURN -a\*(:> ! 1276: \h'|\n1u'\*(<: a >= 0: RETURN a\*(:> \h'|\n2u'\*(<: ELSE: RETURN a\*(:> ! 1277: .Xe ! 1278: .Tx ! 1279: The tests of the alternatives are tested one by one, ! 1280: starting with the first and proceeding downwards, until one ! 1281: is found that succeeds. ! 1282: The corresponding command-suite is then executed. ! 1283: \*(<:ELSE\*(:> may be used in the final alternative as a test that always succeeds. ! 1284: If all the tests fail, an error is reported. ! 1285: .Se 2 5.2.3 WHILE-COMMANDS ! 1286: .Xx terminating command ! 1287: .Sy 2 ! 1288: .Pr while-command 2 ! 1289: .Sl ! 1290: \*(<:WHILE\*(:> test\*(<::\*(:> command-suite ! 1291: .Sx 3 \k1while-command: ! 1292: \*(<:WHILE x > 1: PUT x/10, c+1 IN x, c\*(:> ! 1293: .Xe ! 1294: .Tx ! 1295: If the test succeeds, the command-suite is executed, and the ! 1296: while-command is repeated, and so on, until the test fails, ! 1297: or until an escape is forced by a terminating command. ! 1298: If the test fails the very first time, the command-suite is ! 1299: not executed at all. ! 1300: .Se 3 5.2.4 FOR-COMMANDS ! 1301: .Xx text, list or table ! 1302: .Xx character ! 1303: .Xx list entry ! 1304: .Xx associate ! 1305: .Xx target ! 1306: .Xx bound tags ! 1307: .Sy 3 ! 1308: .Pr for-command 3 ! 1309: .Sl ! 1310: \*(<:FOR\*(:> in-ranger\*(<::\*(:> command-suite ! 1311: .Pr in-ranger 2 ! 1312: .Sl ! 1313: identifier \*(<:IN\*(:> expression ! 1314: .Sx 3 \k1for-command: ! 1315: \*(<:FOR i, j IN keys t: PUT t[i, j] IN t'[j, i]\*(:> ! 1316: .Xe ! 1317: .Tx ! 1318: The value of the expression must be a text, list or table. ! 1319: One by one, each item of that value ! 1320: (characters for a text, list entries for a list and associates for a table) ! 1321: is put in the identifier, and the command-suite executed. ! 1322: For example, ! 1323: .Di 1 ! 1324: \*(<:FOR c IN 'ABC': WRITE 'letter is', c /\*(:> ! 1325: .Ed ! 1326: is equivalent to ! 1327: .Di 3 ! 1328: \*(<:WRITE 'letter is', 'A' / ! 1329: WRITE 'letter is', 'B' / ! 1330: WRITE 'letter is', 'C' /\*(:> ! 1331: .Ed ! 1332: If \*(<:t\*(:> is a table, then ! 1333: ``\*(<:FOR a IN t: TREAT a\*(:>'' ! 1334: treats the associates of \*(<:t\*(:> in the same way as ! 1335: .Di 3 ! 1336: \*(<:FOR k IN keys t: ! 1337: PUT t[k] IN a ! 1338: TREAT a\*(:> ! 1339: .Ed ! 1340: The tags of the identifier of a for-command may not be used as targets ! 1341: or target-contents ! 1342: outside such a for-command. ! 1343: They are ``bound tags'', and lose their meaning outside the ! 1344: for-command. ! 1345: There is one exception to this rule: ! 1346: if a for-command is used in a test-refinement, and within ! 1347: the for-command a report-, succeed- or fail-command is ! 1348: executed, the currently bound tags will temporarily survive ! 1349: as described under REFINED-TESTS (section 6.3.3). ! 1350: .Sa ! 1351: quantifications (6.3.7).
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.