-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathforth.tex
1562 lines (1345 loc) · 43.8 KB
/
forth.tex
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
\documentclass[10pt,letterpaper]{book}
%\setlength\overfullrule{5pt} % Draft
%\usepackage{a4wide}
%\includeonly{titlepage,foreword,foreword-ans,process,members-2x}
%\includeonly{intro,notation,usage,doc,label}
%\includeonly{core}%,block,double,exception,facility,file,float}
%\includeonly{locals,memory,tools,search,string,xchar}
%\includeonly{rationale,bib,history,diff,port,implement,testsuite}
%\includeonly{process2018}
% ========== Page Size ==========
% (taken from a4wide.sty, but now applied to US Letter Paper)
\oddsidemargin 0.15 in % Left margin on odd-numbered pages.
\evensidemargin 0.35 in % Left margin on even-numbered pages.
\marginparwidth 1 in % Width of marginal notes.
\oddsidemargin 0.25 in % Note that \oddsidemargin = \evensidemargin
\evensidemargin 0.25 in
\marginparwidth 0.75 in
\textwidth 5.875 in % Width of text line.
% ========== Document Organisation Flags ==========
\newif\ifinline % Inline Rationale glossary matter
\newif\ifshowref % Display Cross Reference labels
\newif\ifrelease % Draft/Release version
\input{config}
% =================================================
% Tell LaTeX to record a list of all the files
%\listfiles
% To Do
%
% Get rid of labels
% code environment
% auto xref ambiguous conditions
% add \log to History / Change Log
%\usepackage{supertabular}
\usepackage{graphicx}
\usepackage{randtext} % Randamize text (for email addresses)
% ========== Subtables ==========
%\usepackage{float}
%\floatstyle{plaintop}
%\newfloat{subtable}{hbtp}{lot}[table]
%\floatname{subtable}{Table}
%\renewcommand{\thesubtable}{\thetable \alph{subtable}}
% ====================
% ========== Remember Include Filename ==========
% Patch the \include command to remember the current include
% filename.
\makeatletter
% Define a blank file name to start with
\def\includefile{}
% Make a note of the original version of \include
\let\forth@include=\include
% Define a our new version
\renewcommand{\include}[1]{%
\IfFileExists{#1.tex}{%
\gdef\includefile{#1}% Remember the filename
\forth@include{#1}% Include it
}{%
\@latex@error{File "#1.tex" Not Found!}\@ehc
}
}
% ========== Page Header / Footer ==========
\usepackage{fancyhdr}
\pagestyle{fancy}
\makeatletter
\newcommand{\docversion}{%
\revision
\ifinline
\textit{r}% word Rationale only
\fi%
\ifshowref
\textit{x}
\fi
}
\makeatother
\ifrelease
\lhead[\leftmark]{Forth \snapshot{} \release}
\rhead[Forth \snapshot{} \release]{\leftmark}
\else
\lhead[\leftmark]{Forth 200\emph{x} / \docversion}
\rhead[Forth 200\emph{x} / \docversion]{\leftmark}
\fi
\ifrelease
\lfoot[\rm\thepage]{}
\rfoot[]{\rm\thepage}
\else
\lfoot[\rm\thepage]{\sf\small\includefile}
\rfoot[\sf\small\includefile]{\rm\thepage}
\fi
\cfoot{}
\renewcommand{\footrulewidth}{0.4pt}
\newcommand{\collate}{%
! `` \# \$ \% \& ' ( ) * + , - . / digits : ; $<$ = $>$
? @ ALPHA [ \bs{} ] \^{} \_ ` alpha \{ | \} \tilde}
% ==========================================
% ========== Deferred Placement ==========
\usepackage{answers}
% The answerfile switch controls the use of deferred text.
% Turning it on will allow text to be exported to a "solution"
% file, while turning it off will simply place the text in line.
\ifinline
\answerfilesfalse
\else
\answerfilestrue
\fi
% =======================================
% ========== Change Log / History =========
\usepackage{history}
%\openhistory
% =========================================
% ========== PostScript Fonts ==========
\usepackage[T1]{fontenc}
\usepackage[safe,warn]{textcomp}
\usepackage{mathptmx} % Times for roman and formula
%\usepackage{avant} % Avant Guard for sans-serif
\usepackage[scaled=.88]{helvet} % Helvetica for sans-serif
\usepackage{courier} % Courier for teletype
% ======================================
\usepackage{xcolor}
\usepackage[colorlinks,
linkcolor = red,
urlcolor = red,
citecolor = blue,
anchorcolor = blue,
% linkbordercolor=blue,
% pdfborderstyle={/S/U/W 1},
pageanchor=false,
pdfpagelabels=false,
breaklinks=true]{hyperref}
% ========== Block Paragraphs ==========
\usepackage{parskip}
% ======================================
\makeatletter
% ========== Word Glossary ==========
% .wrd the list of raw (unsorted) word entries
% .wds the sorted list of word entries.
%
% Note that this requires an external program (sort.pl) to sort
% the entries.
\newwrite\wordfile
\immediate\openout\wordfile=\jobname.wrd
% Note the "core" wordlist chapter so we can handle this as a
% special case. Of particular interest to worddef and wref.
\newcounter{word@core}
\setcounter{word@core}{6}
% "Normal" or "Extended" wordset
\newif\if@ext
\newcommand{\extended}{%
\@exttrue
\label{wordlist:\word@list-ext}
}
\newcommand{\setwordlist}[1]{%
\gdef\word@list{#1}
}
\setwordlist{core}
\newcommand{\wordlist}[1]{%
\gdef\word@list{#1} % Set the current wordlist
\@extfalse % Core wordset, non-extended wordlist
\label{wordlist:#1} % Label the wordlist, just in case
\chaptermark{\MakeUppercase{#1} Word Set} % Set the page heading
%
% Set up a file ready for the deferred text
%
\ifanswerfiles
\Closesolutionfile{rationale}
\Closesolutionfile{testing}
\Closesolutionfile{implementation}
\Opensolutionfile{rationale}[r-#1]
\Opensolutionfile{testing}[t-#1]
\Opensolutionfile{implementation}[i-#1]
\fi
}
% ===================================
% The following environment define a glossary entry of a word.
% It has two mandatory arguments and three optional ones.
%
% \begin{worddef*}[<label>]{<number>}[<sub-number>]{<name>}[<english>][<proposal>]
%
% <label> Is the LaTeX label given to the word. It is used when
% processing links, and should not include any non alphanumeric
% characters. This is the label by which the word in known to the
% LaTeX system, and the name which should should be used in
% the \word{<label>} and \wref{<label>} commands.
% Default: <name> is assumed to be the label.
%
% <number> The word's number in the alphabetical listing of words.
% This should be the full four digit number.
%
% <sub-number>
% The Forth200x standard requires we add new words between
% existing words. I.e., a new word between 0124 and 0125,
% we can only archive this by further dividing the number
% with a two digit sub-number.
% Default: None.
%
% <name> This is the display name of the word. It is typeset in
% standard LaTeX.
%
% <english> Is the english pronunciation of the word.
% Default: None.
%
% <proposal>
% The name of the proposal which introduced this word. All
% words introduced by Forth 200x should have a proposal.
% Default: None.
%
% The stared version of worddef, adds change bars to the output. This
% is used to introduce a new word into the standard for the first time.
%
% The worddef environment will automatically generate an index entry
% for the word.
%
% The following commands are provided to aid the word definition:
%
% \compile Compilation time semantics
% \execute[<type>] Execution semantics, with a given <type>
% \init Initiation
% \interpret Interpretation semantics
% \note[<number>] Note with an optional <number>
% \runtime[<type>] Run-time semantics, with a given <type>
% \see Reference to other words (See)
%
% \item[<name>] None standard section "<name>:"
%
% \param{<stack item>}
% Type set <stack item> according to the notation rule.
% See the definition of \param for the rules.
%
% \stack[<stack>]{<before>}{<after>}
% Type set a stack picture according to the same notation
% rules as used form \param.
%
% All text which should appear in one of the appendices in the
% final document must appear within the associated environment.
% This allows the text to be shipped out to a separate .sub support
% file, when inlineing is disabled (\ifinline is false).
%
% \begin{rationale} ... \end{rationale}
% \begin{testing} ... \end{testing}
% \test[<format>]{<pre>}{<post>} A test case
% \begin{implement} ... \end{implement}
% ==== worddef ====
% Unfortunately, LaTeX does not provide an easy way of identifying
% more than one optional arguments. The worddef environment, calls
% on a chain of intermediate macros (word@def@a, word@def@b, and
% so on) to extract each of the optional parameters, one at a time.
% They define a number of macros:
%
% \if@star True if the change bar is required (worddef*)
% \word@label LaTeX label for the word, for use in \word{} or \wref{}
% \word@num the four digit number
% \word@sub the two digit sub-division number
% \word@name the name of the word being defined
% \word@read the english pronunciation / reading of the word name
% \word@prop Proposal which introduced the new definition
%
% In addition to these macros we also have two global macros:
%
% \word@list name of the current word list
% \if@ext true if in extended word list
% Before we start, we define a error reporting macro which identifies
% both the word and the word list in which the error was found
\newcommand{\word@error}[1]{%
\@latex@error{%
In \ifnum\value{word@core}=\value{chapter}\thesection\else\thesubsection\fi
\ifx\word@num\empty .----\else.\word@num\fi
\ifx\word@sub\empty\else .\word@sub\fi
\space
"\word@name" of wordset "\word@list" \MessageBreak
#1}\@ehc
}
\newif\if@star
\newenvironment{worddef}{\@starfalse\word@def@a}{\word@def@end}
\newenvironment{worddef*}{\@startrue\word@def@a}{\word@def@end}
% So we must start by processing the first two parameters:
% <label> and <number>. Defines the macros:
% \word@label \empty or the text label
% \word@num \empty or the four digit number
\newcommand{\word@def@a}[2][\empty]{% [<label>]{<number>}...
\ifx#1\empty\let\word@label=\empty\else\def\word@label{#1}\fi
\def\word@num{#2}
\word@def@b
}
% Now we process the second pair of parameters: <sub-number> and
% <name>. So we define (or redefine) the macros:
% \word@label if \word@label is \empty this is redefined to <name>
% \word@sub the two digit sub-division number
% \word@name the name of the word being defined
% For some reason I have yet to work out, this treats numbers with
% duplicate digits (such as 11, 22, 33, and so on) an empty. Thus
% the use of a magic number (100) to signify an empty sub-number,
% as the maximum sub-number should only be 99, this should be sufficient.
\newcommand{\word@def@b}[2][100]{% ...[<sub-number>]{<name>}...
\ifnum#1<100\def\word@sub{#1}\else\let\word@sub=\empty\fi
\ifx\word@label\empty\def\word@label{#2}\fi
\def\word@name{#2}
\word@def@c
}
% Now we can process the next optional parameter: <english>
% Note that if the word has a <proposal> parameter, the
% <english> parameter is required.
% Rather surprisingly this defines a new macro:
% \word@read the english pronunciation / reading of the word name
\newcommand{\word@def@c}[1][\empty]{% ...[<english>]...
\ifx#1\empty\let\word@read=\empty\else\def\word@read{#1}\fi
\word@def@d
}
% Finally we can process the final optional parameter: <proposal>
% Note that all additions to the ANS Forth standard require the
% <proposal> parameter. Thus a new word which has a <proposal> but
% not a separate english pronunciation, MUST provide an empty
% pronunciation parameter. This macro defines the new macro:
% \word@prop Proposal which introduced the new definition
\newcommand{\word@def@d}[1][\empty]{% ...[<proposal>]
\ifx#1\empty\let\word@prop=\empty\else\def\word@prop{#1}\fi
% \word@def@test
\word@def@begin
}
% Now we have collected all of the parameters we can start the word
% definition. We break this into separate sections, first we generate
% the word index entry (\word@def@index) then the word's banner in the
% glossary (\word@def@head), and finally we set up the environment for
% the text of the definition itself (\word@def@body).
% However, before we do any of this, we ensure that all new words have
% a proposal attached.
\newcommand{\word@def@begin}{%
\typeout{%
\ifx\empty\word@num----\else\word@num\fi
\ifx\empty\word@sub\space\space\space\else.\word@sub\fi
\space\includefile:\word@label}
\ifx\empty\word@prop
% No proposal - word must be from ANS Forth '94
\if@star
% We have a new word without a proposal?
\word@error{New words MUST have a proposal}
\fi
\fi
\word@def@index
\word@def@head
\word@def@body
}
% Write the index entry for the word, based on our collected macros
\newcommand{\word@def@index}{%
\immediate\write\wordfile{\string\indexentry%
\if@star*\fi% * = Changebar
\ifnum\value{word@core}=\value{chapter}{\thesection}\else{\thesubsection}\fi% 1: <section>
{\word@num}% 2: <number>
{\word@sub}% 3: <sub number>
{\word@name}% 4: <name>
{\word@list}% 5: <wordlist>
{\if@ext\space EXT\fi}% 6: <ext>
{\word@prop}% 7: <proposal>
{\word@label}% 8: <label>
{\word@read}% 9: <english>
}
}
% Show the macros, used for debugging
\newcommand{\word@def@test}{%
\begin{tabular}{rl}
Change bar: & \if@star On\else Off\fi \\
Section: & \ifnum\value{word@core}=\valign{chapter}\thesection\else\thesubsection\fi \\
Number: & \word@num \\
Sub Number: & \word@sub \\
Name: & \word@name \\
Wordlist: & \word@list~\if@ext EXT\fi \\
Proposal: & \word@prop \\
Label: & \word@label \\
English: & \word@read \\
\end{tabular}\par
}
% ==== Word Header ====
%
% Generate the word header based on the macros collected
\newcommand{\word@def@head}{%
\ifx\word@prop\empty\else
\fi
%
% This is a good place to start a new page
%
\pagebreak[3]
%
% Define the hyper target before the glossary entry
% So that a hyperlink will show the glossary line
%
\hyperdef{\word@list}{\word@label}{}
%
% Word number and name
%
%\@tempswbfalse
%\ifrelease\else
% \ifx\empty\word@prop\else
% \cbstart\marginpar{\tiny{\color{white}c:b}}
% \@tempswbtrue
% \fi
%\fi
\makebox[0.5\textwidth][l]{%
\makebox[6.0em][l]{% <== Magic Number, width of section number
% Switch to a bold font
\bfseries\sffamily
%
% Current section or subsection
%
\ifnum\value{word@core}=\value{chapter}
% In the core wordset
\thesection
\else
% In all other word sets
\thesubsection
\fi
%
% Word number
%
\ifx\empty\word@num
% No word number given
.\rule[.8ex]{2em}{.5pt}
\else%
%\if@tempswb%
% \uline{.\word@num}%
%\else%
.\word@num%
%\fi%
\fi%
%
% Sub division
%
\ifx\word@sub\empty
~% No sub division
\else
%\if@tempswb
% \uline{.\word@sub}
%\else
.\word@sub
%\fi
\fi
}
%
% Word Name
%
%\mdseries % Back to a medium weight (normal) font
\texttt{\textbf{\word@name}}
}
%\if@tempswb
% \cbend
%\fi
%
% English pronunciation (if given)
%
\ifx\word@read\empty
% No english pronunciation given
\else
``\word@read''
\fi
%
% Wordlist
%
\hfill
\MakeUppercase{\word@list}
\if@ext EXT\fi
%
% Cross Reference
%
\ifshowref%
\ifx\word@label\word@name
% Word label is the word name
\else
% Label is different to name
\hbox to 0pt{\textsf{\small ~~\word@label}}
\fi
\fi%
%
% Start change bar
%
\if@star%
\cbstart\patch{\word@prop}%
\fi%
%
% Proposal
%
\\*[-0.6ex]
\ifx\word@prop\empty
% No proposal - word must be from ANS Forth '94
\else
\ifrelease\else
\mbox{} \hfill % flush right (under the wordset name)
\textsf{\small \word@prop}
\fi
\fi
%
% Define the label for this word
%
\def\@currentlabel{%
\ifnum\value{word@core}=\value{chapter}\thesection\else\thesubsection\fi%
\ifx\empty\word@num .0\else.\word@num\fi%
\ifx\empty\word@sub\else .\word@sub\fi
}%
\edef\@currentlabelname{\word@name}%
\def\@currentHref{\word@list.\word@label}%
\label{\word@list:\word@label}%
%
% End the header
%
\if@star\else
\ifx\word@prop\empty\else\cbend\fi % Draft
\fi
\\*[-1.5\baselineskip]
%
% This is a very bad place for a page break
%
\pagebreak[0]
}
% ==== Word Body ====
%
% Define the macro which will be used to format items within the word
% definition. We right align the text which is output with a trailing
% colon.
\newcommand{\word@item}[1]{%
\hfil
\ifx#1\else #1:\fi
}
% For the main body of the definition we use a "simple" list
% environment. We need only set up the margins for environment.
\newcommand{\word@def@body}{
\begin{list}{}{
\setlength{\labelwidth}{6.8em} % <== Magic number, width of indent
\setlength{\leftmargin}{\labelwidth}
\addtolength{\leftmargin}{\labelsep}
\renewcommand{\makelabel}{\word@item}
}
}
% ==== Word Footer ====
%
% This cleans up after the header and body
\newcommand{\word@def@end}{%
%
% Extend the normal "missing \item" error message to
% tell us which word is in error.
%
\def\@noitemerr{\word@error{Something wrong here --- perhaps a
missing \string\item}}
%
% End the list started by \word@def@body
%
\end{list}
%
% End the change bar, if it was enabled
%
\if@star\cbend\fi%
%
% Leave some extra space after the list
%
\vspace{3ex}
%
% This would be a fairly good place for a page break
%
\par\pagebreak[3]
}
% ==== Word Sections ====
% Define the sections found within a glossary entry.
\newcommand{\compile}{\samepage\item[Compilation]}
\newcommand{\execute}[1][\empty]{%
\pagebreak[3]
\ifx#1\empty
\item[Execution]
\else
\item[\emph{#1} Execution]
\fi
}
\newcommand{\init}{\samepage\item[Initiation]}
\newcommand{\interpret}{\samepage\item[Interpretation]}
\newcommand{\note}[1][\empty]{\item[Note\ifx#1\empty\else\ #1\fi]}
\newcommand{\runtime}[1][]{\pagebreak[3]\item[#1 Run-time]}
\newcommand{\see}{\samepage\item[See]}
% ==== Stack Descriptions ====
% Okay, we are going for some very nasty low level TeX here.
% Check out the actionarg entry of the TeX FAQ for full details.
%
% First we define the functions which are going to be called by our
% special characters
\newcommand{\stack@sub}[1]{\raisebox{-0.4ex}{\scriptsize #1}} % _
\newcommand{\stack@sup}[1]{\raisebox{0.8ex}{\scriptsize #1}} % ^
%\newcommand{\stack@mul}{\ensuremath{\mathbin\times}} % *
\newcommand{\stack@mul}{\,*\,} % *
\newcommand{\stack@bar}{~\textbar~} % |
\newcommand{\stack@opa}{\ensuremath{\langle}} % <
\newcommand{\stack@cla}{\ensuremath{\rangle}} % >
\newif\if@stack@quote\@stack@quotetrue
\newcommand{\stack@qot}{% % "
\if@stack@quote``\@stack@quotefalse\else''\@stack@quotetrue\fi}
% Now we have to activate the special characters we are going to
% define, so that we can define them! We do this inside a simple
% group so we don't screw up the rest of the system.
\begingroup
\catcode`\_=\active % Subscript: _1 or _{12}
\catcode`\*=\active % Multiply: 1*2
\catcode`\|=\active % Alternative: u|n
\catcode`\<=\active % Start text: <ccc>
\catcode`\>=\active % End text: <ccc>
\catcode`\"=\active % Syntax element: "name"
% Because we are inside a simple group, we have to use \gdef rather
% than \newcommand. The \stack@set command installs the new specials
% for the next function call.
\gdef\stack@set{%
\catcode`\_=\active \let_=\stack@sub%
\catcode`\*=\active \let*=\stack@mul%
\catcode`\|=\active \let|=\stack@bar%
\catcode`\<=\active \let<=\stack@opa%
\catcode`\>=\active \let>=\stack@cla%
\catcode`\"=\active \let"=\stack@qot%
}
\endgroup
% Now we can define the \stack command:
%
% \stack[<stack>}{<before>}{<after>}
%
% Where the <before> and <after> parameters are interpreted with the
% new specials. To do this we have to enable the new specials before
% processing the arguments with the support function \stack@sig. We
% do this inside a new group so we don't bugger up text outside of
% the parameter.
%
% The <before> and <after> parameters define a number of additional
% special characters as follows:
% _x or _{xx} x or xx is a subscript
% x*y becomes x multiplied by y ($x\times y$)
% x|y becomes x or y ( x \textbar y )
% <xxx> becomes an argument <xxx>
% " becomes open or close double quote
%
% All other characters are typeset in italic.
\newcommand{\stack}[1][\empty]{% [<stack>]...
( % Mark the start of the signature
\ifx#1\empty\else #1: \fi % The stack name (if given)
\begingroup % Open a new restricted scope for new specials
\itshape % The signature is in italic
\stack@set % Enable the specials
\stack@sig % Parse the signature parameters
% We have to do this in a separate macro as
% the specials are not active when this macro
% is executed
}
\newcommand{\stack@sig}[2]{% ...{<before>}{<after>}
#1\ % Pre-condition (before)
--{\,}-- % Mark the "execution point"
\ #2 % Post-condition (after)
\endgroup % Close restricted scope
% Disable new specials and \itshape
) % Close stack signature
}
% The \param{} command allows us to process its argument in exactly
% the same way as the <before> and <after> parameters. Thus we have
% to use the same trick of enabling the our specials inside of a new
% group before calling a helper word \param@arg which actually
% processes the argument.
\newcommand{\param}{% ...
\begingroup % Open a restricted scope for our specials
\itshape % A stack parameter is always given in italic
\stack@set % Enable the specials
\param@arg % Parse the parameter
}
\newcommand{\param@arg}[1]{% ...{<param>}
#1% % Parse the parameter with our specials enabled
\endgroup % Close restricted scope, we don't want our
% specials buggering up anything else now do we,
% this also cancels the \itshape command
}
% As part of the testing environment we also provide the \test
% macro to typeset the text of a test case.
% \test[<format>]{<pre>}{<post>}
\newcommand{\test}{\frenchspacing\obeyspaces\test@arg}
\newcommand{\test@arg}[3][]{%
\texttt{T\{ #2 -> #3 #1\}T}%
\nonfrenchspacing\catcode`\ =10}
% ==== Deferred Text ====
%
% \begin{rationale} ... \end{rationale}
% \begin{testing} ... \end{testing}
% \test{<pre>}{<post>} A test case
% \begin{implement} ... \end{implement}
%
% Deferred text refers to those parts of a words definition that
% do not appear in the main normative definition. Such informative
% text appears in a separate appendix. Be in the Rationale, Test
% cases, or a reference implementation.
%
% Rather than defining sections as we have done for the different
% semantic descriptions, we have to define environments so that we
% can either include the text in with the normative definition as
% it is much easer to review the text in this way, or export the
% text to another file, which can then be included into the
% appropriate section of the appendix.
%
% We have to provide two separate versions of these environments.
% One is used when we are inlining (\inlinetrue) and the other when
% we are exporting (\inlinefalse).
\ifinline
% We have to define the "inline" version of these environments.
% These will simply show the text inline with the normative
% description.
% We define two helper macros. The first of which will output
% the section <title> and define a hyper target for the <title>
% based on the current name <space>.
\newcommand{\inline@section}[2]{% {<space>}{<title>}
% In the review version of the document we change the font
% for the informative text to help distinguish it from the normative
% text. In the final version it will appear in a separate appendix.
\sffamily
%
% Output the section <title> and define an associated
% hyper target in the given name <space>.
\item[\hyperdef{#1.\word@list}{\word@label}{#2}]
}
% We need to fake a latex label for this section of the words
% definition. This macro will fake a label for the given
% <annex> within a given name <space>.
\newcommand{\inline@label}[2]{% {<space>}{<annex>}
% We start by fakeing the current label value
\def\@currentlabel{%
#2.%
\ifnum\value{word@core}=\value{chapter}\thesection\else\thesubsection\fi%
\ifx\word@num\empty.0\else.\word@num\fi%
\ifx\word@sub\empty\else.\word@sub\fi%
}
% The text of the label
\edef\@currentlabelname{\word@name}
% The hyper target for this label
\def\@currentHref{#1.\word@list.\word@label}
% Finally, the label itself
\label{#1:\word@list:\word@label}
}
% \begin{rationale} ... \end{rationale}
% The rationale environment must define a cross reference label
% (and hyper link target) for use by \rref.
\newenvironment{rationale}{%
\inline@section{rat}{Rationale}
\inline@label{rat}{\ref{annex:rationale}}
}{
% Switch back to the normal font
\rmfamily
}
% \begin{testing} ... \end{testing}
% Now we need to do something similar for the testing environment.
\newenvironment{testing}{
\inline@section{test}{Testing}
\inline@label{test}{\ref{annex:test}}
}{
\rmfamily
}
% \begin{implment} ... \end{implment}
% And the same again for the reference implementation.
\newenvironment{implement}{%
\inline@section{imp}{Implementation}
\inline@label{imp}{\ref{annex:implement}}
\ttfamily
}{%
\rmfamily
}
% Sometime we want "normal" text in the implementation and
% testing sections. We define a "Deferred Font" to hide the
% sf/rm font switch.
\newcommand{\textdf}[1]{\textsf{#1}}
\newcommand{\dffamily}{\sffamily}
\else
% We are not "inline," so we have to ship the informative text
% out to their respective appendices.
%
% For this some knowledge of the answers package is required.
% This package allows us to define an association between two
% environments and a "solution" file:
%
% \Newassociation{defertext}{deferredtext}{deferred}
%
% When a <defertext> environment is encountered the text will
% be written out to the associated solution file (<deferred> in
% this case). The text is placed in the <deferredtext>
% environment, so that it may be processed correctly.
%
% The <deferredtext> environment is executed with a number of
% parameters. These are defined by the \deferredtextparams
% macro. This allows us to capture the environment in which the
% defertext environment was found, and pass on any relevant
% information to the deferred text environment.
%
% The command:
%
% \Opensolutionfile{deferred}[filename]
%
% associates an actual file name (in this case <filename>) with
% the solution file handle <deferred>. This allows a single
% solution file handle to be associated with multiple physical
% files, one per wordlist.
%
% So that's the background, no on to the deferred environments!
% Override the default file extension (.tex) for these support
% files. Making it something else (.sub) will make it easy to
% delete them after a run.
\renewcommand{\solutionextension}{sub}
% Define a new solution handle for each of the informative
% environments:
\Newassociation{rationale}{worddefer}{rationale}
\Newassociation{testing}{worddefer}{testing}
\Newassociation{implement}{worddefer}{implementation}
% The pre<x> macros are invoked before the text is shipped out to
% the auxiliary file. We use them to redirect the reader to the
% appropriate appendix.
% \newcommand{\prerationale}{%
% \item[Rationale] See \rref{\word@list:\word@label}{\word@name}.
% }
% \newcommand{\pretesting}{%
% \item[Testing] See \tref{\word@list:\word@label}{\word@name}.
% }
% \newcommand{\preimplement}{%
% \item[Implementation] See \iref{\word@list:\word@label}{\word@name}.
% }
% The text for all three environments will be processed by
% the worddefer environment. This will be given a number
% of paramaters, which must capture the current environment
% when the source environment was used.
\renewcommand{\worddeferparams}{%
{\ifnum\value{word@core}=\value{chapter}\thesection\else\thesubsection\fi}% Section (or sub-section) number
{\ifx\empty\word@num0\else\word@num\fi}% 2 Word number or \empty
{\ifx\empty\word@sub0\else\word@sub\fi}% 3 Word sub-number
{\word@list}% 4 The current word list
{\word@label}% 5 The label for the word
{\word@name}% 6 The LaTeX name for the word
{\if@star\word@prop\fi}% 7 Proposal
}
% The exported text has to interact with the appendix which
% includes the text. It does this though the following
% interface:
% The appendix must define a namespace for itself. This tells
% worddefer which label to generate (rat, test or imp).
\def\defer@space{%
\@latex@error{No name space defined - Use the
\protect\namespace command to define a namespace}\@ehc
}
\newcommand{\namespace}[1]{%
\gdef\defer@space{#1}
}
% If the appendix generates a header for each section, there is
% the potential for a header to appear with no body if there is
% no exported text for the appendix in a given wordlist. To
% prevent this rather unsightly situation the appendix uses the
% \defersection command to define the current section heading.
\newcommand{\defersection}[1]{\gdef\defer@title{#1}}
% deferword will output an appropriate section heading, and then
% resets \defer@title to \empty so that it is only output once.
% However, as we do not output a section header, we still need to
% be able to increment the section number, so that the numbering
% keeps in step with the wordlist definitions. Thus we provide
% a macro to increment the section number if the header was not
% output. This should be called after the support file has been
% input into the document.
\newcommand{\stepsection}{%
\ifx\defer@title\empty\else
\stepcounter{section}
\fi
}
% Now we have set up the environment we can finally override the
% default worddefer environment. This takes seven parameters which
% where defined by \deferwordparams to be:
%
% #1 Section (or sub-section) number
% #2 Word number or 0
% #3 Word sub-number or 0
% #4 The current word list
% #5 The label for the word
% #6 The LaTeX name for the word
% #7 The proposal for the word
% We redefine the standard worddefer environment to take account