-
Notifications
You must be signed in to change notification settings - Fork 0
/
bmanual.html
1228 lines (1190 loc) · 42.2 KB
/
bmanual.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!-- saved from url=(0048)https://www.bell-labs.com/usr/dmr/www/kbman.html -->
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>
B2020 Manual (based on Thompson's B Manual)
</title></head>
<body bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#330088" alink="#FF0044">
<center><h2>Users' Reference to B2020
</h2><br>
<i>Ken Thompson
</i><br>
edited for B2020 by
<i>John Cowan
<br>
</i>
<h4>ABSTRACT</h4></center>
B2020 is a computer language intended for
recursive, primarily non-numeric applications
typified by system programming. B has a
small, unrestrictive syntax that is easy to compile.
Because of the unusual freedom of expression and
a rich set of operators, B
programs are often quite compact.
<br> <br>
This manual contains a concise definition of the language and sample
programs.
<br> <br>
<hr>
[ <i>This is a rendition, after scanning, OCR, and editing,
of an internal Bell Labs Technical Memorandum dated
January 7, 1972. It is Ken's original manual for the B
language on the PDP-11. An
<a href="https://www.bell-labs.com/usr/dmr/www/kbman.pdf">image</a> of the
original document is available in PDF, but it is big:
just under 1MB.
<p>
Nearby is <a href="https://www.bell-labs.com/usr/dmr/www/bintro.html">CSTR #8</a>,
which is a report by Steve Johnson and Brian Kernighan describing
the B implementation on Honeywell
equipment.
</p><p>
The language being described was really the same, but it's interesting
to look at the differences in description and environment.
To describe the BNF syntax, Ken used a variant that depends
on super- and subscripts to say "how many", which in the original
were stacked above each other when they occurred simultaneously.
This doesn't look too awful in the HTML rendering, but was probably
better in the original.
</p><p>
The other thing that is observable is the degree to which the GCOS
version had to struggle to work in that environment.
Its library description is full of odd concepts like "the AFT"
the *SRC file, and other peculiarities.
</p></i><p><i>
--DMR, July 1997</i> ]
<p>
[
<i>Why is B still interesting in 2020?
Because it is a good medium-level language
for use on word-oriented machines
such as the older DEC PDP systems
(excluding the PDP-11).
On such equipment, the typeless nature of B
was an advantage,
whereas on the PDP-11
and other byte-oriented CPUs,
it was nothing but an annoyance.
That was the primary reason
for evolving B into C.
<p>B2020 includes many C convenience features
but retains the typelessness of original B.
If B had not been abandoned,
it would probably have evolved
in something like this way.
<p>--JC, September 2020
</i>
]
</p><hr>
</i>
<h4>Introduction
</h4>
<br> <br>
B2020 is a computer language directly descended from B,
which is a computer language directly descendant from BCPL [1,2].
B2020 is good for recursive,
non-numeric, machine independent applications, such as system and
language work.
<br> <br>
B2020, compared to BCPL, is syntactically rich in expressions and
syntactically poor in statements (though not as poor as B).
A look at the examples in
section 9 of this document will give a flavor of the language.
<br> <br>
B was designed and implemented by D. M. Ritchie and Ken Thompson.
The B2020 modifications that do not come from C
(most of them do)
were designed by John Cowan.
<h4>Syntax
</h4>
<br> <br>
The syntactic notation in this manual is basically BNF with the
following exceptions:
<ol>
<li><p>
The metacharacters <tt><</tt> and <tt>></tt> are removed. Syntactic variables are
in italics to differentiate them from literals and metacharacters.
</p></li><p><li>
The metacharacter <tt>|</tt> is removed. Each syntactic alternative
is placed on a separate line.
</p></li><p><li>
The metacharacters <tt>{</tt> and <tt>}</tt> denote syntactic grouping.
</p></li><p><li>
A syntactic group followed by numerical sub- and superscripts
denote repetition of the group as follows:
</p></li></ol>
<pre> {..}<sub>m</sub> m,m+1,...
{..}<sub>m</sub><sup>n</sup> m,m+1,...,n
</pre>
<h4>Canonical Syntax
</h4>
<br> <br>
The syntax given in this section defines all the legal constructions
in B2020 without specifying the association rules. These are
given later along with the semantic description of each construction.
<br> <br> <blockquote> <pre>
<i>program</i> ::=
{<i>definition</i>}<sub>0</sub>
<i>definition</i> ::=
<b>FIXME</b>
<i>ival</i> ::=
<i>constant</i>
<i>name</i>
<i>statement</i> ::=
auto <i>name</i> = {<i>constant</i>}<sub>0</sub><sup>1</sup> {, <i>name</i> = {<i>constant</i>}<sub>0</sub><sup>1</sup>}<sub>0</sub> ; <i>statement</i>
extern <i>name</i> {, <i>name</i>}<sub>0</sub> ; <i>statement</i>
<i>name</i> : <i>statement</i>
case <i>constant</i> : <i>statement</i>
{ {<i>statement</i>}<sub>0</sub> }
if ( <i>rvalue</i> ) <i>statement</i> {else <i>statement</i>}<sub>0</sub><sup>1</sup>
while ( <i>rvalue</i> ) <i>statement</i>
do <i>statement</i> until ( <i>rvalue</i> )
for ( <i>rvalue</i>1 ; <i>rvalue</i>2 ; <i>rvalue</i>3) <i>statement</i>
switch <i>rvalue</i> <i>statement</i>
goto <i>rvalue</i> ;
break ;
continue ;
return {( <i>rvalue</i> )}<sub>0</sub><sup>1</sup> ;
{<i>rvalue</i>}<sub>0</sub><sup>1</sup> ;
<i>rvalue</i> ::=
( <i>rvalue</i> )
<i>lvalue</i>
<i>constant</i>
<i>lvalue</i> <i>assign</i> <i>rvalue</i>
<i>inc-dec</i> <i>lvalue</i>
<i>lvalue</i> <i>inc-dec</i>
<i>unary</i> <i>rvalue</i>
& <i>lvalue</i>
<i>rvalue</i> <i>binary</i> <i>rvalue</i>
<i>rvalue</i> <i>relop</i> <i>rvalue</i>
<i>rvalue</i> ? <i>rvalue</i> : <i>rvalue</i>
<i>rvalue</i> ( {<i>rvalue</i> {, <i>rvalue</i>}<sub>0</sub> }<sub>0</sub><sup>1</sup> )
<i>assign</i> ::=
= {<i>binary</i>}<sub>0</sub><sup>1</sup>
<i>inc-dec</i> ::=
++
--
<i>unary</i> ::=
-
!
~
<i>binary</i> ::=
|
||
&
&&
<<
>>
-
+
%
*
/
<i>relop</i> :=
==
!=
<
<=
>
>=
<i>lvalue</i> ::=
<i>name</i>
* <i>rvalue</i>
<i>rvalue</i> [ <i>rvalue</i> ]
<i>constant</i> ::=
{digit}<sub>1</sub>
' {char}<sub>1</sub> '
" {char}<sub>0</sub> "
<i>name</i> ::=
alpha {<i>alpha-digit</i>}<sub>0</sub>
<i>alpha-digit</i> ::=
alpha
digit
</pre>
</blockquote>
<h4>Comments and Character Sets
</h4>
<br> <br>
Comments are delimited as in PL/I by /* and */.
In addition, // indicates a comment
that is delimited by the end of the line.
<br> <br>
In general, B2020 requires tokens to be separated by blanks, comments
or newlines, however the compiler infers separators surrounding
any of the characters <tt>(){}[],;?:</tt> or surrounding any
maximal sequence of the characters <tt>+-*/<>&|!</tt>.
<br> <br>
The character set used in B2020 is Unicode.
<br> <br>
The syntactic variable 'alpha' is not defined. It represents any
Unicode character with a General Category
of Ll, Lm, Lt, Lu, or Lo, as well as <tt>_</tt>.
<br> <br>
The syntactic variable 'digit' is not defined. It represents the
characters <tt>0</tt>, <tt>1</tt>, <tt>2</tt>, ... <tt>9</tt>.
Other Unicode digits are not included.
<br> <br>
The syntactic variable 'char' is not defined. It is essentially
any Unicode character plus the escape character <tt>\</tt> followed
by another character to represent characters not easily
represented. The following escape sequences are
currently defined:
<dl><dt></dt><dd><tt><pre> <tt>\0</tt><i> null
</i><tt>\(</tt><i> </i><tt>{</tt>
<tt>\)</tt><i> </i><tt>}</tt>
<tt>\t</tt><i> tab
</i><tt>\\</tt><i> </i><tt>\</tt>
<tt>\'</tt><i> </i><tt>'</tt>
<tt>\"</tt><i> </i><tt>"</tt>
<tt>\n</tt><i> new line
</i></pre></tt></dd></dl>
In addition, the escape sequence \u followed by four hex digits,
or \U followed by eight hex digits, represents a Unicode character.
All keywords in the language are only recognized in lower case.
Keywords are reserved.
</i><h4>3.0 Rvalues and Lvalues
</h4>
<br> <br>
An rvalue is a binary bit pattern of a fixed length
such as 16, 32, or 64 bits.
Objects are rvalues of different kinds
such as integers, labels, vectors and functions. The actual kind
of object represented is called the type of the rvalue.
<br> <br>
A B2020 expression can be evaluated to yield an rvalue, but its type
is undefined until the rvalue is used in some context. It is
then assumed to represent an object of the required type. For
example, in the following function call
<dl><dt></dt><dd><tt><pre> (b? f:g[i] )(1, x>1)
</pre></tt></dd></dl>
The expression <code>(b?f:g[i])</code> is evaluated to yield an rvalue which
is interpreted to be of type function. Whether <code>f</code> and <code>g[i]</code> are in
fact functions is not checked. Similarly, <code>b</code> is assumed to be of
type truth value, <code>x</code> to be type integer etc.
<br> <br>
There is no check to insure that here are no type mismatches.
Similarly, there are no wanted, or unwanted, type conversions.
<br> <br>
An lvalue is a bit pattern representing a storage location
containing an rvalue. An lvalue is a type in B2020. The unary operator
* can be used to interpret an rvalue as an lvalue. Thus
<dl><dt></dt><dd><tt><pre> *X
</pre></tt></dd></dl>
evaluates the
expression x to yield an rvalue, which is then
interpreted as an lvalue. If it is then used in an rvalue context,
the application of <tt>*</tt> yields the rvalue therein stored. The
operator <tt>*</tt> can be thought of as indirection.
<br> <br>
The unary operator <tt>&</tt> can be used to interpret an lvalue as an
rvalue. Thus
<dl><dt></dt><dd><tt><pre> &x
</pre></tt></dd></dl>
evaluates the expression x as an lvalue. The application of <tt>&</tt>
then yields the lvalue as an rvalue. The operator <tt>&</tt> can therefore
be thought of as the address function.
<br> <br>
The names lvalue and rvalue come from the assignment statement
which requires an lvalue on the left and an rvalue on the right.
<h4>4.0 Expression Evaluation
</h4>
<br> <br>
Binding of expressions (lvalues and rvalues) is in the same order
as the sub-sections of this section except as noted.
Thus expressions referred to as operands of <tt>+</tt> (section 4.4)
are expressions defined in sections 4.1 to 4.3.
The binding of operators at the same level
(left to right, right to left) is specified in each sub-section.
<h4>4.1 Primary Expressions
</h4>
<ol>
<li><p>
A name is an lvalue of one of three storage classes (automatic, external and internal).
</p></li><li><p>
A decimal constant is an rvalue.
It consists of a digit
between 1 and 9 followed
by any number of digits between 0
and 9. The value of the
constant should not exceed the
maximum value that can be stored in an object.
</p></li><li><p>
A decimal constant is an rvalue.
It consists of a digit
between 1 and 9 followed
by any number of digits between 0
and 9. The value of the
constant should not exceed the
maximum value that can be stored in an object.
</p></li><li><p>
An octal constant is the same as a decimal constant except
that it begins with a zero and cannot contain 8 or 9.
It is then interpreted in base 8.
A hexadecimal constant is the same as an octal constant
except that it begins with a zero followed by an x or X,
and can contain the hexadecimal digits a-f or A-F.
It is then interpreted in base 16.
</p></li><li><p>
A character constant is represented by <tt>'</tt> followed by
as many characters as will fit into a rvalue
when encoded in UTF-8
(possibly escaped) followed by another <tt>'</tt>.
It has an rvalue equal to the value of the bytes
packed and right adjusted.
</p></li><li><p>
A string is any number of characters between <tt>"</tt> characters.
The characters are packed into adjacent objects (lvalues
sequential) and terminated with the character '<code><code>x</code></code>'. The
rvalue of the string is the lvalue of the object containing
the first character. See section 8.0 for library functions
used to manipulate strings in a machine independent
fashion.
</p></li><li><p>
Any expression in () parentheses is a primary expression.
Parentheses are used to alter order of binding.
</p></li><li><p>
A vector is a primary expression followed by any expression
in [] brackets. The two expressions are evaluated to
rvalues, added and the result is used as an lvalue. The
primary expression can be thought of as a pointer to the
base of a vector, while the bracketed expression can be
thought of as the offset in the vector. Since <code>E1[E2</code>] is
identical to <code>*(E1+E2)</code>, and addition is commutative, the
base of the vector and the offset in the vector can swap
positions.
</p></li><li><p>
A function is a primary expression followed by any number
of expressions in <tt>()</tt> parentheses separated by commas. The
expressions In parentheses are evaluated (in an unspecified
order) to rvalues and assigned to the function's parameters.
The primary expression is evaluated to an rvalue
(assumed to be type function). The function is then
called. Each call is recursive at little cost in time or
space.
</p></li><li><p>
A float constant is an rvalue.
It is written in decimal in the usual notation,
and represents an IEEE binary32 number.
The notations +0.inf, -0.inf, and +0.nan
represent positive and negative infinity and NaN respectively.
Note that the B2020 operators will not work correctly
on floating-point values.
</p></li></ol>
Primary expressions are bound left to right.
</p></li></ol>
<h4>4.2 Unary Operators
</h4>
<br> <br>
<ol>
</p></li><li><p>
The rvalue (or indirection) prefix unary operator <tt>*</tt> is
described in section 3.0. Its operand is evaluated to
rvalue, and then used as an lvalue.
In this manner, address arithmetic may be performed.
</p></li><li><p>
The lvalue (or address) prefix unary operator & is also
described in section 3.0. Note that
&*x is identically x,
but *&x is only x if x is an lvalue.
</p></li><li><p>
The operand of the negate prefix unary operator - is interpreted
as an integer rvalue. The result is an rvalue with
opposite sign.
</p></li><li><p>
The NOT prefix unary operator ! takes an integer rvalue
operand. The result is zero if the operand is non-zero.
The result is one if the operand is zero.
</p></li><li><p>
The complement <tt>~</tt> operator takes an integer rvalue operand.
The result is the value interpreted
in two's complement with all bits flipped.
</p></li><li><p>
The increment <tt>++</tt> and decrement <tt>--</tt> unary operators may be
used either in prefix or postfix form.
Either form requires an lvalue operand. The rvalue stored in the lvalue
is either incremented or decremented by one. The result is
the rvalue either before or after the operation depending
on postfix or prefix notation respectively. Thus if x
currently contains the rvalue 5, then ++x and x++ both
change x to 6. The value of ++x is 6 while x++ is 5.
Similarly, --x and x-- store 4 in X. The former has rvalue
result 4, the latter 5.
</p></li></ol>
Unary operators are bound right to left. Thus -!x++ is bound
-(!(x++)).
<h4>4.3 Multiplicative Operators
</h4>
<br> <br>
The multiplicative binary operators <tt>*</tt>, <tt>/</tt>, and <tt>%</tt>, expect rvalue
integer operands. The result is also an integer.
<ol>
<li><p>
The operator * denotes multiplication.
</p></li><li><p>
The operator <tt>/</tt> denotes division. The result is correct if
the first operand is divisible by the second.
If both operands are positive, the result is truncated
toward zero.
Otherwise the rounding is undefined, but never
greater than one.
</p></li><li><p>
The operator <tt>%</tt> denotes modulo. If both operands are positive,
the result is correct. It is undefined otherwise.
</p></li></ol>
The multiplicative operators bind left to right.
<h4>4.4 Additive Operators
</h4>
<br> <br>
The binary operators <tt>+</tt> and <tt>-</tt> are add and subtract.
The additive
operators bind left to right.
<h4>Shift Operators
</h4>
<br> <br>
The binary operators
<tt><<</tt> and <tt>>></tt> are left and right shift respectively.
The left rvalue operand is taken as a bit pattern.
The right operand is taken as an integer shift count.
The result is the bit pattern shifted by the shift count.
Vacated bits are
filled with zeros. The result is undefined if the shift count
negative or larger than an object length. The shift operators
bind left to right.
<h4>4.6 Relational Operators
</h4>
<br> <br>
The relational operators <tt><</tt> (less than), <tt><=</tt> (less than or equal
to), <tt>></tt> (greater than), and <tt>>=</tt> ( greater than or equal to) take
integer rvalue operands. The result is one if the operands are
in the given relation to one another. The result is zero otherwise.
<h4>4.7 Equality Operators
</h4>
<br> <br>
The equality operators <tt>==</tt> (equal to) and <tt>!=</tt> (not equal to)
perform similarly to the relation operators.
<h4>4.8 The AND operators
</h4>
<br> <br>
The AND operator <tt>&</tt> takes operands as bit patterns. The result is
the bit pattern that is the bit-wise AND of the operands.
<br> <br>
The logical AND operator <tt>&&</tt> takes operands as
boolean values, where 0 means false. If the left operand is 0,
it will be returned and the right operand will not be evaluated.
Otherwise the right operand is returned.
<h4>The OR operators
</h4>
<br> <br>
The OR operator <tt></tt>| performs exactly as AND, but the result is the
bit-wise inclusive OR of the operands.
<br> <br>
The logical OR operator <tt>||</tt> takes operands as
boolean values, where 0 means false. If the left operand is not 0,
it will be returned and the right operand will not be evaluated.
Otherwise the right operand is returned.
<h4>4.10 Conditional Expression
</h4>
<br> <br>
Three rvalue expressions separated by <tt>?</tt> and <tt>:</tt> form a conditional
expression. The first expression (to the left of the ?) is
evaluated. If the result is non-zero, the second expression is
evaluated and the third ignored. If the value is zero, the
second expression is ignored and the third is evaluated. The
result is either the evaluation of the second or third expression.
<br> <br>
Binding is right to left. Thus <code>a?b:c?d:e</code> is <code>a?b:(c?d:e)</code>.
<h4>4.11 Assignment Operators
</h4>
<br> <br>
There are 12 assignment operators in B2020. All have the form
<dl><dt></dt><dd><tt><pre> lvalue op rvalue
</pre></tt></dd></dl>
The assignment operator
= merely evaluates the rvalue and stores
the result in the lvalue. The assignment operators <tt>|=</tt>, <tt>&=</tt>, <tt>=</tt>,
<tt>|=</tt>, <tt><<=</tt>, <tt>>>=</tt>, <tt>+=</tt>, <tt>-=</tt>, <tt>%=</tt>, <tt>*=</tt>, and <tt>/=</tt> perform a
binary operation (see sections 4.3 to 4.9) between the rvalue
stored in the assignment's lvalue and the assignment's rvalue.
The result is then stored in the lvalue. The expression x*=10 is
identical to x=x*10. The result
of an assignment is the rvalue. Assignments bind right to left,
thus x=y=0 assigns zero to y, then x, and returns the rvalue
zero.
<h4>5.0 Statements
</h4>
<br> <br>
Statements define program execution. Each statement is executed
by the computer in sequence. There are, of course, statements to
conditionally or unconditionally alter normal sequencing.
<h4>5.1 Compound Statement
</h4>
<br> <br>
A sequence of statements in <tt>{}</tt> braces is syntactically a single
statement. This mechanism is provided so that where a single
statement is expected, any number of statements can be placed.
<h4>5.1 Conditional Statement
</h4>
<br> <br>
A conditional statement has two forms. The first:
<dl><dt></dt><dd><tt><pre> if(rvalue) statement<sub>1</sub>
</pre></tt></dd></dl>
evaluates the rvalue and executes statement<sub>1</sub>, if the rvalue is
non-zero. If the rvalue is zero, statement<sub>1</sub> is skipped. The
second form:
<dl><dt></dt><dd><tt><pre> if(rvalue) statement<sub>1</sub> else statement<sub>2</sub>
</pre></tt></dd></dl>
is defined as follows in terms of the first form:
<dl><dt></dt><dd><tt><pre> if(x=(rvalue)) statement<sub>1</sub> if(!x) statement<sub>2</sub>
</pre></tt></dd></dl>
Thus, only one of the two statements is executed, depending on
the value of rvalue. In the above example,
x is not a real variable, but just a demonstration aid.
<h4>5.3 Loop Statements
</h4>
<br> <br>
The while statement has the form:
<dl><dt></dt><dd><tt><pre> while(rvalue) statement
</pre></tt></dd></dl>
The execution is described in terms of the conditional and goto
statements as follows:
<dl><dt></dt><dd><tt><pre> x: if(rvalue) { statement goto x; ]
</pre></tt></dd></dl>
Thus the statement is executed repeatedly while the rvalue is
non-zero. Again, x is a demonstration aid.
<br> <br>
The do-until statement has the form:
<dl><dt></dt><dd><tt><pre> do statement until (rvalue)
</pre></tt></dd></dl>
The execution is described in terms of the conditional and goto
statements as follows:
<dl><dt></dt><dd><tt><pre> x: { statement; if (!rvalue) goto x; }
</pre></tt></dd></dl>
Thus the statement is executed at least once, and then repeatedly
while the rvalue is not 0.
<br> <br>
The for statement has the form:
<dl><dt></dt><dd><tt><pre> for(rvalue1; rvalue2; rvalue3) statement
</pre></tt></dd></dl>
The execution is described in terms of the while
statement as follows:
<dl><dt></dt><dd><tt><pre> { rvalue1; while(rvalue2) { statement; rvalue3 } }
</pre></tt></dd></dl>
Thus rvalue1 is evaluated,
and then the statement is executed and rvalue3 is evaluated repeatedly
while rvalue2 is non-zero.
<h4>5.4 Switch Statement
</h4>
<br> <br>
The switch statement is the most complicated
statement in B2020. The
switch has the form:
<dl><dt></dt><dd><tt><pre> switch rvalue statement<sub>1</sub>
</pre></tt></dd></dl>
Virtually always, statement<sub>1</sub> above is a compound statement. Each
statement in statement<sub>1</sub> may be preceded by a case as follows:
<dl><dt></dt><dd><tt><pre> case constant:
</pre></tt></dd></dl>
During execution, the rvalue is evaluated and compared to each
case constant in undefined order. If a case constant is equal to
the evaluated rvalue, control is passed to the statement following
the case. If the rvalue matches none of the cases, statement<sub>1</sub>
is skipped.
<h4>5.5 Jump Statements
</h4>
<br> <br>
The goto statement is as follows:
<dl><dt></dt><dd><tt><pre> goto rvalue ;
</pre></tt></dd></dl>
The rvalue is expected to be of type label. Control is then
passed to the corresponding label. Goto's cannot be executed to
labels outside the currently executing function level.
<br> <br>
The break statement is as follows:
<dl><dt></dt><dd><tt><pre> break ;
</pre></tt></dd></dl>
Control is passed to the statement
following the innermost enclosing
loop or break statement.
<br> <br>
The continue statement is as follows:
<dl><dt></dt><dd><tt><pre> continue ;
</pre></tt></dd></dl>
Control is passed to the statement
the first statement
of the innermost enclosing loop statement.
However, if the loop statement is a for statement,
its rvalue3 is re-evaluated first.
<h4>5.6 Return Statement
</h4>
<br> <br>
The return statement is used in a function to return control to
the caller of a function. The first form simply returns control.
<dl><dt></dt><dd><tt><pre> return ;
</pre></tt></dd></dl>
The second form returns an rvalue for the execution of the function.
<dl><dt></dt><dd><tt><pre> return ( rvalue ) ;
</pre></tt></dd></dl>
The caller of the function need not use the returned rvalue.
<h4>3.7 Rvalue Statement
</h4>
<br> <br>
Any rvalue followed by a semicolon is a statement. The two most
common rvalue statements are assignment and function call.
<h4>5.8 Null Statement
</h4>
<br> <br>
A semicolon is a null statement causing no execution. It is used
mainly to carry a label after the last executable statement in a
compound statement. It sometimes has use to supply a null body
to a while statement.
<br> <br> <b>No updates past this point.</b> <br> <br>
<h4>6.0 Declarations
</h4>
<br> <br>
Declarations in B2020 specify storage class
of variables. Such declarations also, in some circumstances,
specify initialization.
<br> <br>
There are
three storage
classes in B2020. Automatic storage is allocated for
each function
invocation. External storage is allocated before
execution and
is available to any and all functions.
Internal storage is local to a function and is available only to
that function, but is available to all invocations of that function.
<h4>6.1 External Declaration
</h4>
<br> <br>
The external declaration has the form:
<dl><dt></dt><dd><tt><pre> extern name<sub>1</sub> , name<sub>2</sub> ... ;
</pre></tt></dd></dl>
The external declaration specifies that each of
the named variables is of the external storage class.
The declaration must
occur before the first use of each of the variables. Each of the
variables must also be externally defined.
<h4>6/2 Automatic Declaration
</h4>
<br> <br>
The automatic declaration also constitutes a definition:
<dl><dt></dt><dd><tt><pre> auto name<sub>1</sub> {constant}<sub>0</sub><sup>1</sup> , name<sub>2</sub> {constant]<sub>0</sub><sup>1</sup> ... ;
</pre></tt></dd></dl>
In absence of the constant, the automatic declaration defines the
variable to be of class automatic. At the same time, storage is
allocated for the variable. When an automatic declaration is
followed by a constant, the automatic variable is
also initialized to the base of an automatic vector
of the size of the constant.
The actual subscripts used to reference the vector range
from zero to the value of the constant less one.
<h4>6.3 Internal Declaration
</h4>
<br> <br>
The first reference to a variable not declared as external or
automatic constitutes an internal declaration, All internal
variables not defined as labels are flagged as undefined within a
function. Labels are defined and initialized as follows:
<dl><dt></dt><dd><tt><pre> name :
</pre></tt></dd></dl>
<h4>7.0 External Definitions
</h4>
<br> <br>
A complete B2020 program consists of a series of external definitions.
Execution is started by the hidden sequence
<dl><dt></dt><dd><tt><pre> main(); exit();
</pre></tt></dd></dl>
Thus, it is expected that one of the external definitions is a
function definition of main. (Exit is a predefined library function.
See section 8.0)
<h4>7.1 Simple Definition
</h4>
<br> <br>
The simple external definition allocates an external object and
optionally initializes it:
<dl><dt></dt><dd><tt><pre> name {ival , ival ...}<sub>0</sub> ;
</pre></tt></dd></dl>
If the external object is defined with no initialization, it is
initialized with zero. A single initialization with a constant
initializes the external with the value of the constant.
Initialization with a name initializes the external to the address of
that name. Many such initializations may be accessed as a vector
based at &name.
<h4>7.2 Vector Definitions
</h4>
<br> <br>
An external vector definition has the following form:
<dl><dt></dt><dd><tt><pre> name [ {constant}<sub>0</sub><sup>1</sup> ] {ival , ival ...}<sub>0</sub> ;
</pre></tt></dd></dl>
The name is initialized with the lvalue of the base of
an external vector. If the vector size is missing, zero is assumed. In
either case, the vector is initialized with the list of initial
values. Each initial value is either a constant or a name. A
constant initial value initializes the vector element to the
value of the constant. The name initializes the element to the
address of the name. The actual size
is the maximum of the given size and the number of initial values.
<h4>7.3 Function Definitions
</h4>
<br> <br>
Function definitions have the following form:
<dl><dt></dt><dd><tt><pre> name ( arguments ) statement
</pre></tt></dd></dl>
The name is initialized to the rvalue of the function.
The arguments consist of a list of names separated by commas.
Each name defines an automatic lvalue that is assigned the rvalue of the
corresponding function call actual parameters. The statement
(often compound) defines the execution of the function when invoked.
<h4>8.0 Library Functions
</h4>
<br> <br>
There is a standard library of B2020 functions.
The following is a list of those functions:
<dl compact="">
<dt>c = char(string, i);</dt><dd>
<br>
The i-th character of the string is returned.
</dd><dt>error = chdir(string) ;</dt><dd>
<br>
The path name represented by the string becomes
the current directory.
A negative number returned indicates an error.
</dd><dt>error = chmod(string, mode);</dt><dd>
<br>
The file specified by the string has its mode changed to
the mode argument. A negative number returned indicates an
error. (*)
</dd><dt>error = chown(string, owner);</dt><dd>
<br>
The file specified by the string has its owner changed to
the owner argument. A negative number returned indicates
an error. (*)
</dd><dt>error = close(file) ;</dt><dd>
<br>
The open file specified by the file argument is closed. A
negative number returned indicates an error. (*)
</dd><dt>file = creat(string, mode);</dt><dd>
<br>
The file specified by the string is either truncated or
created in the mode specified depending on its prior existence.
In both cases, the file is opened for writing and a
file descriptor is returned. A negative number returned
indicates an error. (*)
</dd><dt>ctime(time, date);</dt><dd>
<br>
The system time (60-ths of a second) represented in the
two-word vector time is converted to a 16-character date in
the 8-word vector date. The converted date has the following format:
"Mmm dd hh:mm:ss".
</dd><dt>execl(string, arg0, arg1, ..., 0);</dt><dd>
<br>
The current process is replaced by the execution of the
file specified by string. The arg-i strings are passed as
arguments. A return indicates an error. (*)
</dd><dt>execv(string, argv, count);</dt><dd>
<br>
The current process is replaced by the execution of the
file specified by string. The vector of strings of length
count are passed as arguments. A return indicates an error. (*)
</dd><dt>exit( ) ;</dt><dd>
<br>
The current process is terminated. (*)
</dd><dt>error = fork( ) ;</dt><dd>
<br>
The current process splits into two. The child process is
returned a zero. The parent process is returned the process ID of
the child. A negative number returned indicates
an error. (*)
</dd><dt>error = fstat(file, status);</dt><dd>
<br>
The i-node of the open file designated by file is put in
the 20-word vector status. A negative number returned
indicates an error. (*)
</dd><dt>char = getchar( ) ;</dt><dd>
The next character form the standard input file is returned.
The character `*e' is returned for an end-of-file.
</dd><dt>id = getuid();</dt><dd>
<br>
The user-ID of the current process is returned. (*)
</dd><dt>error = gtty(file, ttystat);</dt><dd>
<br>
The teletype modes of the open file designated by file is
returned in the 3-word vector ttstat. A negative number
returned indicates an error. (*)
</dd><dt>lchar(string, i, char);</dt><dd>
<br>
The character char is stored in the i-th character of the
string.
</dd><dt>error = link(string1, string2);</dt><dd>
<br>
The pathname specified by string2 is created such that it
is a link to the existing file specified by string1. A
negative number returned indicates an error. (*)
</dd><dt>error = mkdir(string, mode);</dt><dd>
<br>
The directory specified by the string is made to exist with
the specified access mode. A negative number returned
indicates an error. (*)
</dd><dt>file = open(string, mode);</dt><dd>
<br>
The file specified by the string is opened for reading if
mode is zero, for writing if mode is not zero. The open
file designator is returned. A negative number returned
indicates an error. (*)
</dd><dt>printf(format, argl, ...);</dt><dd>
<br>
See section 9.3 below.
</dd><dt>printn(number, base);</dt><dd>
<br>
See section 9.1 below.
</dd><dt>putchar(char) ;</dt><dd>
<br>
The character char is written on the standard output file.
</dd><dt>nread = read(file, buffer, count);</dt><dd>
<br>
Count bytes are read into the vector buffer from the open
file designated by file. The actual number of bytes read
are returned. A negative number returned indicates an
error. (*)
</dd><dt>error = seek(filet offset, pointer);</dt><dd>
<br>
The I/O pointer on the open file designated by file is set
to the value of the designated pointer plus the offset. A
pointer of zero designates the beginning of the file. A
pointer of one designates the current I/O pointer. A
pointer of two designates the end of the file. A negative
number returned indicates an error. (*)
</dd><dt>error = setuid(id);</dt><dd>
<br>
The user-ID of the current process is set to id.
A negative number returned indicates an error. (*)
</dd><dt>error = stat(string, status);</dt><dd>
<br>
The i-node of the file specified by the string is put in
the 20-word vector status. A negative number returned
indicates an error. (*)
</dd><dt>error = stty(file, ttystat);</dt><dd>
<br>
The teletype modes of the open file designated by file is
set from the 3-word vector ttystat. A negative number
returned indicates an error. (*)
</dd><dt>time(timev);</dt><dd>
<br>
The current system time is returned in the 2-word vector
timev. (*)
</dd><dt>error = unlink(string);</dt><dd>
<br>
The link specified by the string is removed. A negative
number returned indicates an error. (*)
</dd><dt>error = wait( );</dt><dd>
<br>
The current process is suspended until one of its child
processes terminates. At that time, the child's process-ID
is returned. A negative number returned indicates an error. (*)
</dd><dt>nwrite = write(file, buffer, count);</dt><dd>
<br>
Count bytes are written out of the vector buffer on the
open file designated by file. The actual number of bytes
written are returned. A negative number returned indicates
an error. (*)
</dd></dl>
<br> <br>
Besides the functions available from the library, there is a
predefined external vector named argv included with every program.
The size of argv is argv[0]+1.
The elements
argv[1]...argv[argv[0]] are the parameter strings as passed by
the system in the execution of the current process. (See shell
in II of [4])
<h4>9.0 Examples
</h4>
<br> <br>
The examples appear exactly as given to B.
<h4>9.1
</h4>
<br> <br>
<dl><dt></dt><dd><tt><pre>/* The following function will print a non-negative number, n, to
the base b, where 2<=b<=10, This routine uses the fact that
in the Unicode character set, the digits O to 9 have sequential
code values. */
printn(n,b) {
extern putchar;
auto a;
if(a=n/b) /* assignment, not test for equality */
printn(a, b); /* recursive */
putchar(n%b + '0');
}
</pre></tt></dd></dl>
<h4>9.2
</h4>
<br> <br>
<dl><dt></dt><dd><tt><pre>/* The following program will calculate the constant e-2 to about
4000 decimal digits, and print it 50 characters to the line in
groups of 5 characters. The method is simple output conversion
of the expansion
1/2! + 1/3! + ... = .111....
where the bases of the digits are 2, 3, 4, . . . */
main() {
extern putchar, n, v;
auto i, c, col, a;
i = col = 0;
while(i<n)
v[i++] = 1;
while(col<2*n) {
a = n+1 ;
c = i = 0;
while (i<n) {
c =+ v[i] *10;
v[i++] = c%a;
c =/ a--;
}
putchar(c+'0');
if(!(++col%5))
putchar(col%50?' ': '*n');
}
putchar('*n*n');
}
v[2000];
n 2000;
</pre></tt></dd></dl>
<h4>9.3
</h4>
<br> <br>
<dl><dt></dt><dd><tt><pre>/* The following function is a general formatting, printing, and
conversion subroutine. The first argument is a format string.
Character sequences of the form `%x' are interpreted and cause
conversion of type 'x' of the next argument, other character
sequences are printed verbatim. Thus
printf("delta is %d*n", delta);
will convert the variable delta to decimal (%d) and print the
string with the converted form of delta in place of %d. The
conversions %d-decimal, %o-octal, *s-string and %c-character
are allowed.
This program calls upon the function `printn'. (see section
9.1) */
printf(fmt, x1,x2,x3,x4,x5,x6,x7,x8,x9) {
extern printn, char, putchar;
auto adx, x, c, i, j;
i= 0; /* fmt index */
adx = &x1; /* argument pointer */
loop :