-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathchapter5.tex
More file actions
executable file
·2066 lines (1805 loc) · 74.6 KB
/
chapter5.tex
File metadata and controls
executable file
·2066 lines (1805 loc) · 74.6 KB
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
%% Thinking Forth
%% Copyright (C) 2004 Leo Brodie
%% Initial transcription by Albert van der Horst
%%
%% Chapter: Implementation: Elements of FORTH Style
%%
%% ``%%!!!te'' marks mark typesetting errors in the original
%% We don't want to retain typesetting errors.
\chapter{Implementation: Elements~of \Forth{}~Style}\Chapmark{5}%
\index{I!Implementation|(}%
\initial Badly written \Forth{} has been accused of looking like ``code that
went through a trash compactor.'' It's true, \Forth{} affords more
freedom in the way we write applications. But that freedom also gives
us a chance to write exquisitely readable and easily maintainable
code, provided we consciously employ the elements of good \Forth{}
style.
In this chapter we'll delve into \Forth{} coding convention
including:
\begin{itemize}%%originally: no bullet points
\item listing organization
\item screen layout, spacing and indentation
\item commenting
\item choosing names
\end{itemize}
I wish I could recommend a list of hard-and-fast conventions for
everyone. Unfortunately, such a list may be inappropriate in many
situations. This chapter merges many widely-adopted conventions with
personal preferences, commented with alternate ideas and the reasons
for the preferences. In other words:
\begin{Code}
: tip value judgement ;
\end{Code}
I'd especially like to thank \person{Kim Harris},\index{H!Harris, Kim} who
proposed many of the conventions described in this chapter, for his
continuing efforts at unifying divergent views on good \Forth{} style.
\section{Listing Organization}%
\index{L!Listing organization|(}%
\index{I!Implementation!listing organization|(}
A well-organized book has clearly defined chapters, with clearly defined
sections, and a table of contents to help you see the organization at a
glance. A well-organized book is easy to read. A badly organized book
makes comprehension more difficult, and makes finding information
later on nearly impossible.
\begin{tfnote}{Bernd Paysan}
This chapter needs to focus more on files than on screens
\end{tfnote}
\wepsfigp{fig5-1}{I still don't see how these programming conventions
enhance readability.}
The necessity for good organization applies to an application listing
as well. Good organization has three aspects:
\begin{enumerate}\parsep=0pt\itemsep=0pt
\item Decomposition
\item Composition
\item Disk partitioning
\end{enumerate}
\subsection{Decomposition}%
\index{D!Decomposition|(}%
\index{L!Lexicons|(}
As we've already seen, the organization of a listing should follow the
decomposition of the application into lexicons. Generally these
lexicons should be sequenced in ``uses'' order. Lexicons being
\emph{used} should precede the lexicons which \emph{use} them.%
\index{L!Lexicons|)}
On a larger scale, elements in a listing should be organized by degree
of complexity, with the most complex variations appearing towards the
end. It's best to arrange things so that you can leave off the
lattermost screens (i.e., not load them) and still have a
self-sufficient, running application, working properly except for the
lack of the more advanced features.
We discussed the art of decomposition extensively in \Chap{3}.%
\index{D!Decomposition|)}
\subsection{Composition}%
\index{C!Composition|(}%
\index{L!Load screens|(}%
Composition is the putting together of pieces to create a whole. Good
composition requires as much artistry as good decomposition.
One of \Forth{}'s present conventions is that source code resides in
``screens,'' which are 1K units of mass storage. (The term ``screen''
refers to a block used specifically for source code.) It's possible in
\Forth{} to chain every screen of code to the next, linking the entire
listing together linearly like a lengthy parchment scroll. This is
not a useful approach. Instead:
\begin{tip}
Structure your application listing like a book: hierarchically.
\end{tip}
An application may consist of:
\begin{description}\parsep=0pt\itemsep=0pt
\item[Screens:] the smallest unit of \Forth{} source
\item[Lexicons:]\index{L!Lexicons} one to three screens, enough to
implement a component
\item[Chapters:]\index{C!Chapters} a series of related lexicons, and
\item[Load screens:] analogous to a table of contents, a screen that
loads the chapters in the proper sequence.
\end{description}
%Page 138 in first edition.
\begin{figure*}[tttt]
\caption{Example of an application-load screen.}
\labelfig{fig5-1}
\setcounter{screen}{1}
\begin{Screen}
\ QTF+ Load Screen 07/09/83
: release# ." 2.01" ;
9 load \ compiler tools, language primitives
12 load \ video primitives
21 load \ editor
39 load \ line display
48 load \ formatter
69 load \ boxes
81 load \ deferring
90 load \ framing
96 load \ labels, figures, tables
102 load \ table of contents generator
\end{Screen}
\end{figure*}%
\index{C!Composition|)}
\subsection{Application-load Screen}%
\index{L!Load screens!application|(}
\Fig{fig5-1} is an example of an application-load screen. Since it
resides in Screen 1, you can load this entire application by entering
\begin{Code}
1 load
\end{Code}
The individual load commands within this screen load the chapters of
the application. For instance, Screen 12 is the load screen for the
video primitives chapter.
As a reference tool, the application-load screen tells you where to
find all of the chapters. For instance, if you want to look at the
routines that do framing, you can see that the section starts at
Screen 90.
Each chapter-load screen in turn, loads all of the screens comprising
the chapter. We'll study some formats for chapter-load screens shortly.
The primary benefit of this hierarchical scheme is that you can load
any section, or any screen by itself, without having to load the
entire application. Modularity of the source code is one of the
reasons for \Forth{}'s quick turnaround time for editing, loading, and
testing (necessary for the iterative approach). Like pages of a book,
each screen can be accessed individually and quickly. It's a ``random
access'' approach to source-code maintenance.
You can also replace any passage of code with a new, trial version by
simply changing the screen numbers in the load screen. You don't have to
move large passages of source code around within a file.
In small applications, there may not be such things as chapters. The
application-load screen will directly load all the lexicons. In
larger applications, however, the extra level of hierarchy can improve
maintainability.
%Page 139 in first edition.
A screen should either be a load-screen or a code-screen, not a mixture.
Avoid embedding a \forthb{LOAD} or \forthb{THRU} command in the middle of a
screen containing definitions just because you ``need something'' or
because you ``ran out of room.''
\subsection{Skip Commands}%
\index{S!Skip commands}
Two commands make it easy to control what gets loaded in each screen
and what gets ignored. They are:
\medbreak
\begin{description}
\item[\emph{\forthb{\bs}}]~
\item[\emph{\forthb{\bs S}}] also called \forthb{EXIT}\index{E!EXIT}
\end{description}
\forth{\bs} is pronounced ``skip-line.'' It causes the
\Forth{} interpreter to ignore everything to the right of it on the
same line. (Since \forth{\bs} is a \Forth{} word, it must be followed
by a space.) It does not require a delimiter.
In \Fig{fig5-1}, you see \forth{\bs} used in two ways: to begin the
screen-comment line (Line 0), and to begin comments on individual
lines which have no more code to the right of the comment.
During testing, \forth{\bs} also serves to temporarily ``paren out''
lines that already contain a right parenthesis in a name or comment.
For instance, these two ``skip-line''s keep the definition of
\forth{NUTATE} from being compiled without causing problems in
encountering either right parenthesis:
\begin{Code}
\ : nutate ( x y z )
\ swap rot (nutate) ;
\end{Code}
\forthb{\bs S} is pronounced ``skip-screen.'' It causes the \Forth{}
interpreter to stop interpreting the screen entirely, as though there
were nothing else in the screen beyond \forthb{\bs S}.
In many \Forth{} systems, this function is the same as
\forthb{EXIT},\index{E!EXIT} which is the run-time routine for
semicolon. In these systems the use of \forthb{EXIT} is acceptable.
Some \Forth{} systems, however, require for internal reasons a
different routine for the ``skip-screen'' function.
Definitions for \forthb{\bs} and \forthb{\bs S} can be found in \App{C}.%
\index{L!Load screens!application|)}
\subsection{Chapter-load Screens}%
\index{L!Load screens!chapter|(}%
\index{C!Chapter-load screens|(}
\Fig{fig5-2} illustrates a typical chapter-load screen. The screens
loaded by this screen are referred to relatively, not absolutely as
they were in the application-load screen.
This is because the chapter-load screen is the first screen of the
contiguous range of screens in the chapter. You can move an entire
chapter forward or backward within the listing; the relative pointers
in the chapter-load screen are position-independent. All you have to
change is the single number in the application-load screen that points
to the beginning of the chapter.
%Page 140 in first edition.
\begin{figure*}
\caption{Example of a chapter-load screen.}
\labelfig{fig5-2}
\setcounter{screen}{100}
\begin{Screen}
\ GRAPHICS Chapter load 07/11/83
1 fh load \ dot-drawing primitive
2 fh 3 fh thru \ line-drawing primitives
4 fh 7 fh thru \ scaling, rotation
8 fh load \ box
9 fh 11 fh thru \ circle
corner \ initialize relative position to low-left corner
\end{Screen}
\end{figure*}
\index{R!Relative loading|(}%
\begin{tip}
Use absolute screen numbers in the application-load screen. Use
relative screen numbers in the chapter- or section-load screens.
\end{tip}
There are two ways to implement relative loading.
The most common is to define:
\begin{Code}
: +load ( offset -- ) blk @ + load ;
\end{Code}
and
\begin{Code}
: +thru ( lo-offset hi-offset -- )
1+ swap DO i +load LOOP ;
\end{Code}
My own way, which I submit as a more useful factoring, requires a
single word, \forthb{FH} (see \App{C} for its definition).
The phrase
\begin{Code}
1 fh load
\end{Code}
is read ``1 from here \forth{LOAD},'' and is equivalent
to \forth{1 +LOAD}.
Similarly,
\begin{Code}
2 fh 5 fh thru
\end{Code}
is read ``2 from here, 5 from here \forth{THRU}.''
Some programmers begin each chapter with a dummy word; e.g.,
\begin{Code}
: video-io ;
\end{Code}
%Page 141 in first edition.
and list its name in the comment on the line where the chapter is
loaded in the application-load screen. This permits selectively
\forth{FORGET}ting any chapter and reloading from that point on
without having to look at the chapter itself.
Within a chapter the first group of screens will usually define those
variables, constants, and other data structures needed globally within
the chapter. Following that will come the lexicons, loaded in
``uses'' order. The final lines of the chapter-load screen normally
invoke any needed initialization commands.
\index{M!Moore Products Company|(}%
Some of the more style-conscious \Forth{}wrights begin each chapter
with a ``preamble'' that discusses in general terms the theory of
operation for the components described in the chapter. \Fig{fig5-3}
is a sample preamble screen which demonstrates the format required at
Moore Products Co.
\begin{figure*}[tttt]
\caption{Moore Products Co.'s format for chapter preambles.}
\labelfig{fig5-3}
\begin{Screen}
CHAPTER 5 - ORIGIN/DESTINATION - MULTILOOP BIT ROUTINES
DOCUMENTS - CONSOLE STRUCTURE CONFIGURATION
DESIGN SPECIFICATION
SECTIONS - 3.2.7.5.4.1.2.8
3.2.7.5.4.1.2.10
ABSTRACT - File control types E M T Q and R can all
originate from a Regional Satellite or a
Data Survey Satellite. These routines allow
the operator to determine whether the control
originated from a Regional Satellite or not.
\end{Screen}
\begin{Screen}
CHAPTER NOTES - Whether or not a point originates from
a Regional Satellite is determined by
the Regional bit in BITS, as follows:
1 = Regional Satellite
2 = Data Survey Satellite
For the location of the Regional bit
in BITS, see the Design Specification
Section - 3.2.7.5.4.1.2.10
HISTORY -
\end{Screen}
\end{figure*}%
\index{M!Moore Products Company|)}
%Page 142 in first edition.
\begin{interview}
\person{Charles Moore}\index{M!Moore, Charles|(} (no relation to Moore
Products Co.) places less importance on the well-organized
hierarchical listing than I do. \person{Moore}:
\begin{tfquot}
I structure \emph{applications} hierarchically, but not necessarily
\emph{listings.} My listings are organized in a fairly sloppy way,
not at all hierarchically in the sense of primitives first.
I use \forthb{LOCATE} {[}also known as \forthb{VIEW}; see the Handy Hint
in \emph{Starting \Forth{},} Chapter Nine{]}. As a result, the
listing is much less carefully organized because I have \forthb{LOCATE}
to find things for me. I never look at listings.
\end{tfquot}\index{M!Moore, Charles|)}
\end{interview}
\subsection{--\,--> vs.\ THRU}%
\index{T!THRU|(}
\index{N!Next block|(}%
On the subject of relative loading, one popular way to load a series
of adjacent screens is with the word \forth{-{}->} (pronounced ``next
block''). This word causes the interpreter to immediately cease
interpreting the current screen and begin interpreting the next
(higher-numbered) screen.
If your system provides \forth{-{}->}, you must choose between using
the \forthb{THRU} command in your chapter-load screen to load each
series of screens, or linking each series together with the arrows and
\forth{LOAD}ing only the first in the series. (You can't do both;
you'd end up loading most of the screens more than once.)%
\index{T!THRU|)}
The nice thing about the arrows is this: suppose you change a screen
in the middle of a series, then reload the screen. The rest of the
series will automatically get loaded. You don't have to know what the
last screen is.
That's also the nasty thing about the arrows: There's no way to stop
the loading process once it starts. You may compile a lot more
screens than you need to test this one screen.%
\index{N!Next block|)}
To get analytical about it, there are three things you might want to
do after making the change just described:
\begin{enumerate}
\item load the one screen only, to test the change,
\item load the entire section in which the screen appears,
\suspend{enumerate}
or
\resume{enumerate}
\item load the entire remainder of the application.
\end{enumerate}
The use of \forthb{THRU} seems to give you the greatest control.
Some people consider the arrow to be useful for letting definitions
cross screen boundaries. In fact \forth{-{}->} is the only way to
compile a high-level (colon) definition that occupies more than one
screen, because \forth{-{}->} is ``immediate.'' But it's \emph{never}
good style to let a colon definition cross screen boundaries. (They
should never be that long!)
On the other hand, an extremely complicated and time-critical piece
of assembler coding might occupy several sequential screens. In this
case, though, normal \forthb{LOAD}ing will do just as well, since the
assembler does not use compilation mode, and therefore does not
require immediacy.
Finally, the arrow wastes an extra line of each source screen. We
don't recommend it.%
\index{R!Relative loading|)}%
\index{L!Load screens!chapter|)}%
\index{C!Chapter-load screens|)}%
\index{L!Load screens|)}%
\index{L!Listing organization|)}
%Page 143 in first edition.
\subsection{An Alternative to Screens: Source in Named Files}%
\index{N!Named files, storing source code in|(}
\index{F!File-based system|(}%
Some \Forth{} practitioners advocate storing source code in
variable-length, named text files, deliberately emulating the approach
used by traditional compilers and editors. This approach may become
more and more common, but its usefulness is still controversial.
Sure, it's nice not to have to worry about running out of room in a
screen, but the hassle of writing in a restricted area is compensated
for by retaining control of discrete chunks of code. In developing an
application, you spend a lot more time loading and reloading screens
than you do rearranging their contents.
``Infinite-length'' files allow sloppy, disorganized thinking and bad
factoring. Definitions become longer without the discipline imposed
by the 1K block boundaries. The tendency becomes to write a 20K file,
or worse: a 20K definition.
Perhaps a nice compromise would be a file-based system that allows
nested loading, and encourages the use of very small named files.
Most likely, though, the more experienced \Forth{} programmers would
not use named files longer than 5K to 10K. So what's the benefit?%
\index{F!File-based system|)}
Some might answer that rhetorical question: ``It's easier to remember
names than numbers.'' If that's so, then predefine those block numbers
as constants, e.g.:
\begin{Code}
90 Constant framing
\end{Code}
Then to load the ``framing'' section, enter
\begin{Code}
framing load
\end{Code}
Or, to list the section's load block, enter
\begin{Code}
framing list
\end{Code}
(It's a convention that names of sections end in ``ING.'')
Of course, to minimize the hassle of the screen-based approach you
need good tools, including editor commands that move lines of source
from one screen to another, and words that slide a series of screens
forward or back within the listing.%
\index{N!Named files, storing source code in|)}
\subsection{Disk Partitioning}%
\index{D!Disk partitioning|(}
The final aspect of the well-organized listing involves standardizing
an arrangement for what goes where on the disk. These standards must
be set by each shop, or department, or individual programmer,
depending on the nature of the work.
%Page 144 in first edition.
\begin{figure*}
\caption{Example of a disk-partitioning scheme within one department.}
\labelfig{fig5-4}
\begin{description}
\item[Screen 0] is the title screen, showing the name of the
application, the current release number, and primary author.
\item[Screen 1] is the application-load block.
\item[Screen 2] is reserved for possible continuation from Screen 1
\item[Screen 4 and 5] contain system messages.
\item[Screens 9 thru 29] incorporate general utilities needed
in, but not restricted to, this application.
\item[Screen 30] begins the application screens.
\end{description}
\end{figure*}
\Fig{fig5-4} shows a typical department's partitioning scheme.
In many \Forth{} shops it's considered desirable to begin sections of
code on screen numbers that are evenly divisible by three. Major
divisions on a disk should be made on boundaries evenly divisible by
thirty.%
\index{D!Disk partitioning|)}
The reason? By convention, \Forth{} screens are printed three to a
page, with the top screen always evenly divisible by three. Such a
page is called a ``triad;'' most \Forth{} systems include the word
\forth{TRIAD} to produce it, given as an argument the number of any of
the three screens in the triad. For instance, if you type
\begin{Code}
77 triad
\end{Code}
you'll get a page that includes 75, 76, and 77.
The main benefit of this convention is that if you change a single
screen, you can slip the new triad right into your binder containing
the current listing, replacing exactly one page with no overlapping
screens.
Similarly, the word \forth{INDEX} lists the first line of each screen,
60 per page, on boundaries evenly divisible by 60.\index{I!INDEX}
\index{S!Screens!numbering|(}%
\begin{tip}
Begin sections or lexicons on screen numbers evenly divisible by three.
Begin applications or chapters on screen numbers evenly divisible by
thirty.
\end{tip}%
\index{S!Screens!numbering|)}
\subsection{Electives}%
\index{E!Electives|(}
Vendors of \Forth{} systems have a problem. If they want to include
every command that the customer might expect---words to control
graphics, printers, and other niceties---they often find that the system
has swollen to more than half the memory capacity of the computer,
leaving less room for serious programmers to compile their
applications.
%Page 145 in first edition.
The solution is for the vendor to provide the bare bones as a
precompiled nucleus, with the extra goodies provided in \emph{source} form.
This approach allows the programmer to pick and choose the special
routines actually needed.
These user-loadable routines are called ``electives.'' Double-length
arithmetic, date and time support, \forth{CASE} statements and the
\forth{DOER}/\hy \forth{MAKE} construct (described later) are some of
the features that \Forth{} systems should offer as electives.%
\index{E!Electives|)}%
\index{I!Implementation!listing organization|)}
\section{Screen Layout}%
\index{S!Screens!layout|(}%
\index{I!Implementation!screen layout|(}
In this section we'll discuss the layout of each source screen.
\index{C!Comment line|(}%
\begin{tip}
Reserve Line 0 as a ``comment line.''
\end{tip}
The comment line serves both as a heading for the screen, and also as
a line in the disk \forth{INDEX}. It should describe the purpose of
the screen (not list the words defined therein).
The comment line minimally contains the name of the screen. In larger
applications, you may also include both the chapter name and screen
name. If the screen is one of a series of screens implementing a
lexicon, you should include a ``page number'' as well.
\index{S!Stamp|(}%
\index{D!Dates, representation of|(}
The upper right hand corner is reserved for the ``stamp.'' The stamp
includes the date of latest revision and, when authorship is
important, the programmer's initials (three characters to the left of
the date); e.g.:
\begin{Code}
( Chapter name Screen Name -- pg # JPJ 06/10/83)
\end{Code}
Some \Forth{} editors will enter the stamp for you at the press of a key.
A common form for representing dates is
\begin{Code}
mm-dd-yy
\end{Code}
that is, February 6, 1984 would be expressed
\begin{Code}
02-06-84
\end{Code}
An increasingly popular alternative uses
\begin{Code}
ddMmmyy
\end{Code}
where ``Mmm'' is a three-letter abbreviation of the month. For instance:
\begin{Code}
22Oct84
\end{Code}
%Page 146 in first edition.
This form requires fewer characters than
\begin{Code}
10-22-84
\end{Code}
and eliminates possible confusion between dates and months.%
\index{S!Stamp|)}%
\index{D!Dates, representation of|)}
If your system has \forth{\bs} (``skip-line''---see \App{C}), you can
write the comment line like this:
\begin{Code}
\ Chapter name Screen Name -- pg.# JPJ 06/10/83
\end{Code}
As with all comments, use lower-case or a mixture of lower- and
upper-case text in the comment line.
One way to make the index of an application reveal more about the
organization of the screens is to indent the comment line by three
spaces in screens that continue a lexicon. \Fig{fig5-5} shows a
portion of a list produced by \forthb{INDEX} in which the comment lines
for the continuing screens are indented.%
\index{C!Comment line|)}
\begin{figure*}[bbbb]
\caption{The output of \forth{INDEX} showing indented comment lines.}
\labelfig{fig5-5}
\begin{Code}
90 \ Graphics Chapter load JPJ 06/10/83
91 \ Dot-drawing primitives JPJ 06/10/83
92 \ Line-drawing primitives JPJ 06/11/83
93 \ Line-drawing primitives JPJ 06/10/83
94 \ Line-drawing primitives JPJ 09/02/83
95 \ Scaling, rotation JPJ 06/10/83
96 \ Scaling, rotation JPJ 02/19/84
97 \ Scaling, rotation JPJ 02/19/84
98 \ Scaling, rotation JPJ 02/19/84
99 \ Boxes JPJ 06/10/83
100 \ Circles JPJ 06/10/83
101 \ Circles JPJ 06/10/83
102 \ Circles JPJ 06/10/83
\end{Code}
\end{figure*}
\begin{tip}
Begin all definitions at the left edge of the screen, and define only
one word per line.
\end{tip}
%! There should be no page breaks between the text and code
\noindent \emph{Bad:}
\begin{Code}
: arriving ." Hello" ; : departing ." Goodbye" ;
\end{Code}
\noindent \emph{Good:}
\begin{Code}
: arriving ." Hello" ;
: departing ." Goodbye" ;
\end{Code}
This rule makes it easier to find a definition in the listing. (When
definitions continue for more than one line, the subsequent lines
should always be indented.)
%Page 147 in first edition.
\forthb{VARIABLE}s and \forthb{CONSTANT}s should also be defined one per
line. (See ``Samples of Good Commenting Style'' in \App{E}.) This
leaves room for an explanatory comment on the same line. The
exception is a large ``family'' of words (defined by a common
defining-word) which do not need unique comments:
\begin{Code}
0 Hue black 1 Hue blue 2 Hue green
3 Hue cyan 4 Hue red 5 Hue magenta
\end{Code}
\begin{tip}
Leave lots of room at the bottom of the screen for later additions.
\end{tip}
On your first pass, fill each screen no more than half with code. The
iterative approach demands that you sketch out the components of your
application first, then iteratively flesh them out until all the
requirements are satisfied. Usually this means adding new commands,
or adding special-case handling, to existing screens. (Not
\emph{always,} though. A new iteration may see a simplification of
the code. Or a new complexity may really belong in another component
and should be factored out, into another screen.)
Leaving plenty of room at the outset makes later additions more
pleasant. One writer recommends that on the initial pass, the screen
should contain about 20--40 percent code and 80--60 percent
whitespace \cite{stevenson81}.
Don't skip a line between each definition. You may, however, skip a
line between \emph{groups} of definitions.%
\index{D!DECIMAL|(}\index{B!BASE|(}
\begin{tip}
All screens must leave \forthb{BASE} set to \forthb{DECIMAL}.
\end{tip}
Even if you have three screens in a row in which the code is written
in \forthb{HEX} (three screens of assembler code, for instance), each
screen must set \forth{BASE} to \forthb{HEX} at the top, and restore
base to \forthb{DECIMAL} at the bottom. This rule ensures that each
screen could be loaded separately, for purposes of testing, without
mucking up the state of affairs. Also, in reading the listing you
know that values are in decimal unless the screen explicitly
says \forthb{HEX}.
Some shops take this rule even further. Rather than brashly resetting
base to \forthb{DECIMAL} at the end, they reset base to \emph{whatever
it was at the beginning.} This extra bit of insurance can be
accomplished in this fashion:
\begin{Code}
base @ hex \ save original BASE on stack
0A2 Constant bells
0A4 Constant whistles
... etc. ...
base ! \ restore it
\end{Code}
%Page 148 in first edition.
\noindent Sometimes an argument is passed on the stack from screen to
screen, such as the value returned by \forthb{BEGIN} or \forthb{IF} in a
multiscreen assembler definition, or the base address passed from one
defining word to another---see ``Compile-Time Factoring'' in \Chap{6}.
In these cases, it's best to save the value of \forth{BASE} on the
return stack like this:
\begin{Code}
base @ >r hex
... etc. ...
r> base !
\end{Code}
Some folks make it a policy to use this approach on any screen that
changes \forthb{BASE}, so they don't have to worry about it.%
\index{B!BASE|)}
\person{Moore}\index{M!Moore, Charles} prefers to define \forthb{LOAD}
to invoke \forthb{DECIMAL} after loading. This approach simplifies the
screen's contents because you don't have to worry about resetting.%
\index{D!DECIMAL|)}
\subsection{Spacing and Indentation}%
\index{S!Spacing|(}
\begin{tip}
Spacing and indentation are essential for readability.
\end{tip}
The examples in this book use widely accepted conventions of spacing
and indenting style. Whitespace, appropriately used, lends
readability. There's no penalty for leaving space in source screens
except disk memory, which is cheap.
For those who like their conventions in black and white, Table
\ref{tab-5-1} is a list of guidelines. (But remember, \Forth{}'s
interpreter couldn't care less about spacing or indentation.)
\begin{table}[bbbb]
\caption{Indentation and spacing guidelines}
\label{tab-5-1}
\medskip\blackline{0pt}\medskip
\begin{minipage}{\textwidth}
\begin{quote}
1 space between the colon and the name\\
2 spaces between the name and the comment\footnote{An often-seen
alternative calls for 1 space between the name and comment and 3
between the comment and the definition. A more liberal technique uses
3 spaces before and after the comment. Whatever you choose, be
consistent.}\\
2 spaces, or a carriage return, after the comment and
before the definition\footnotemark[1]\\
3 spaces between the name and definition if no comment is used\\
3 spaces indentation on each subsequent line (or multiples
of 3 for nested indentation)\\
1 space between words/numbers within a phrase\\
2 or 3 spaces between phrases\\
1 space between the last word and the semicolon\\
1 space between semicolon and \forthb{IMMEDIATE} (if invoked)
\end{quote}
No blank lines between definitions, except to separate distinct groups
of definitions
%% Note: AH: Again type writer style footnotes.
\end{minipage}
\medskip\blackline{0pt}
\end{table}
%Page 149 in first edition.
The last position of each line should be blank except for:
%%!!!te original used a) b) enumeration here.
\ifeightyfour
\begin{list}{\alph{enumi})}{\usecounter{enumi}}
\else
\begin{enumerate}
\fi
\item quoted strings that continue onto the next line, or
\item the end of a comment.
\ifeightyfour
\end{list}
\else
\end{enumerate}
\fi
A comment that begins with \forth{\bs} may continue right to the end
of the line. Also, a comment that begins with \forth{(} may have its
delimiting right parenthesis in the last column.
\index{I!Indentation|(}%
Here are some common errors of spacing and indentation:
\goodbreak\bigskip\noindent
\emph{Bad} (name not separated from the body of the definition):
\begin{Code}
: push heave ho ;
\end{Code}
\emph{Good:}
\begin{Code}
: push heave ho ;
\end{Code}
\emph{Bad} (subsequent lines not indented three spaces):
\begin{Code}
: riddance ( thing-never-to-darken-again -- )
darken never again ;
\end{Code}
\emph{Good:}
\begin{Code}
: riddance ( thing-never-to-darken-again -- )
darken never again ;
\end{Code}
\emph{Bad} (lack of phrasing):
\begin{Code}
: gettysburg 4 score 7 years + ago ;
\end{Code}
\goodbreak\noindent
\emph{Good:}
\begin{Code}
: gettysburg 4 score 7 years + ago ;
\end{Code}
Phrasing is a subjective art;
I've yet to see a useful set of formal rules.\\
Simply strive for readability.%
\index{S!Spacing|)}%
\index{S!Screens!layout|)}%
\index{I!Implementation!screen layout|)}%
\index{I!Indentation|)}
\section{Comment Conventions}%
\index{C!Comment conventions|(}%
\index{I!Implementation!comment conventions|(}
Appropriate commenting is essential. There are five types of comments:
stack-effect comments, data-structure comments, input-stream comments,
purpose comments and narrative comments.
%%!!!te Original didn't put this into a description
\begin{description}
\item[\emph{A} stack-effect comment]\index{S!Stack-effect comment}%
shows the arguments that the definition consumes from the stack, and
the arguments it returns to the stack, if any.
%Page 150 in first edition.
\item[\emph{A} data-structure comment]\index{D!Data-structure comment}%
indicates the position and meaning of elements in a data structure.
For instance, a text buffer might contain a count in the first byte,
and 63 free bytes for text.
\item[\emph{An} input-stream comment]\index{I!Input-stream comment}%
indicates what strings the word expects to see in the input stream.
For example, the \Forth{} word \forth{FORGET} scans for the name of a
dictionary entry in the input stream.
\item[\emph{A} purpose comment]\index{P!Purpose comment}%
describes, in as few words possible, what the definition does. How
the definition works is not the concern of the purpose comment.
\item[\emph{A} narrative comment]\index{N!Narrative comments}%
appears amidst a definition to explain what is going on, usually
line-by-line. Narrative comments are used only in the ``vertical
format,'' which we'll describe in a later section.
\end{description}
Comments are usually typed in lower-case letters to distinguish them
from source code. (Most \Forth{} words are spelled with upper-case
letters, but lower-case spellings are sometimes used in special cases.)
In the following sections we'll summarize the standardized formats
for these types of comments and give examples for each type.
\subsection{Stack Notation}%
\index{S!Stack notation|(}
\begin{tip}
Every colon or code definition that consumes and/or returns any arguments
on the stack must include a stack-effect comment.
\end{tip}
``Stack notation'' refers to conventions for representing what's on
the stack. Forms of stack notation include ``stack pictures,''
``stack effects,'' and ``stack-effect comments.''%
\index{S!Stack notation|)}%
\index{P!Purpose comment}
\subsection{Stack Picture}%
\index{S!Stack picture|(}
A stack picture depicts items understood to be on the stack at a given
time. Items are listed from left to right, with the leftmost item
representing the bottom of the stack and the rightmost item
representing the top.
For instance, the stack picture
\begin{Code}
nl n2
\end{Code}
indicates two numbers on the stack, with n2 on the top (the most
accessible position).
This is the same order that you would use to type these values in;
i.e., if n1 is 100 and n2 is 5000, then you would type
\begin{Code}
100 5000
\end{Code}
to place these values correctly on the stack.
%Page 151 in first edition.
A stack picture can include either abbreviations, such as ``n1,'' or
fully spelled-out words. Usually abbreviations are used. Some
standard abbreviations appear in Table \ref{tab-5-2}. Whether
abbreviations or fully spelled-out words are used, each stack item
should be separated by a space.
If a stack item is described with a phrase (such as
``address-of-latest-link''), the words in the phrase should be joined
by hyphens. For example, the stack picture:
\begin{Code}
address current-count max-count
\end{Code}
shows three elements on the stack.%
\index{S!Stack picture|)}
\subsection{Stack Effect}%
\index{S!Stack effect|(}
A ``stack effect'' shows two stack pictures: one picture of any items
that may be \emph{consumed} by a definition, and another picture of
any items \emph{returned} by the definition. The ``before'' picture
comes first, followed by two hyphens, then the ``after'' picture.
For instance, the stack effect for \Forth{}'s addition operator,
\forth{+} is
\begin{Code}
n n -- sum
\end{Code}
where \forth{+} consumes two numbers and returns their sum.
Remember that the stack effect describes only the \emph{net result} of
the operation on the stack. Other values that happen to reside on the
stack beneath the arguments of interest don't need to be shown. Nor
do values that may appear or disappear while the operation is
executing.
If the word returns any input arguments unchanged, they
should be repeated in the output picture; e.g.,
\begin{Code}
3rd 2nd top-input -- 3rd 2nd top-output
\end{Code}
Conversely, if the word changes any arguments, the stack comment must
use a different descriptor:
\begin{Code}
nl -- n2
n -- n'
\end{Code}
A stack effect might appear in a formatted glossary.%
\index{S!Stack effect|)}
\subsection{Stack Effect Comment}%
\index{S!Stack-effect comment|(}
A ``stack-effect comment'' is a stack effect that appears in source
code surrounded by parentheses. Here's the stack-effect comment for
the word \forth{COUNT}:
\begin{Code}
( address-of-counted-string -- address-of-text count)
\end{Code}
%Page 152 in first edition.
or:
\begin{Code}
( 'counted-string -- 'text count)
\end{Code}
(The ``count'' is on top of the stack after the word has executed.)
If a definition has no effect on the stack (that is, no effect the