A Torture Test

for

by Donald E. Knuth Stanford University

(Version 2, January 1990)

Programs that claim to be implementations of 84 are supposed to be able to process the test routine contained in this report, producing the outputs contained in this report.

The preparation of this report was supported in part by the National Science Foundation under grants IST-8201926 and MCS-8300984, and by the System Development Foundation. is a trademark of Addison-Wesley Publishing Company.

Introduction. People often think that their programs are “debugged” when large applications have been run successfully. But system programmers know that a typical large application tends to use at most about 50 per cent of the instructions in a typical compiler. Although the other half of the code—which tends to be the “harder half”—might be riddled with errors, the system seems to be working quite impressively until an unusual case shows up on the next day. And on the following day another error manifests itself, and so on; months or years go by before certain parts of the compiler are even activated, much less tested in combination with other portions of the system, if user applications provide the only tests.

How then shall we go about testing a compiler? Ideally we would like to have a formal proof of correctness, certified by a computer. This would give us a lot of confidence, although of course the formal verification program might itself be incorrect. A more serious drawback of automatic verification is that the formal specifications of the compiler are likely to be wrong, since they aren’t much easier to write than the compiler itself. Alternatively, we can substitute an informal proof of correctness: The programmer writes his or her code in a structured manner and checks that appropriate relations remain invariant, etc. This helps greatly to reduce errors, but it cannot be expected to remove them completely; the task of checking a large system is sufficiently formidable that human beings cannot do it without making at least a few slips here and there.

Thus, we have seen that test programs are unsatisfactory if they are simply large user applications; yet some sort of test program is needed because proofs of correctness aren’t adequate either. People have proposed schemes for constructing test data automatically from a program text, but such approaches run the risk of circularity, since they cannot assume that a given program has the right structure.

I have been having good luck with a somewhat different approach, first used in 1960 to debug an ALGOL compiler. The idea is to construct a test file that is about as different from a typical user application as could be imagined. Instead of testing things that people normally want to do, the file tests complicated things that people would never dare to think of, and it embeds these complexities in still more arcane constructions. Instead of trying to make the compiler do the right thing, the goal is to make it fail (until the bugs have all been found).

To write such a fiendish test routine, one simply gets into a nasty frame of mind and tries to do everything in the unexpected way. Parameters that are normally positive are set negative or zero; borderline cases are pushed to the limit; deliberate errors are made in hopes that the compiler will not be able to recover properly from them.

A user’s application tends to exercise 50% of a compiler’s logic, but my first fiendish tests tend to improve this to about 90%. As the next step I generally make use of frequency-counting software to identify the instructions that have still not been called upon. Then I add ever more fiendishness to the test routine, until more than 99% of the code has been used at least once. (The remaining bits are things that can occur only if the source program is really huge, or if certain fatal errors are detected; or they are cases so similar to other well-tested things that there can be little doubt of their validity.)

Of course, this is not guaranteed to work. But my experience in 1960 was that only two bugs were ever found in that ALGOL compiler after it correctly translated that original fiendish test. And one of those bugs was actually present in the results of the test; I simply had failed to notice that the output was incorrect. Similar experiences occurred later during the 60s and 70s, with respect to a few assemblers, compilers, and simulators that I wrote.

This method of debugging, combined with the methodology of structured programming and informal proofs (otherwise known as careful desk checking), leads to greater reliability of production software than any other method I know. Therefore I have used it in developing 84, and the main bulk of this report is simply a presentation of the test program that was used to get the bugs out of .

Such a test file is useful also after a program has been debugged, since it can be used to give some assurance that subsequent modifications don’t mess things up.

The test file is called TRAP.MF, because of my warped sense of humor: ’s companion system, TEX, has a similar test file called TRIP, and I couldn’t help thinking about Billy Goat Gruff and the story of “trip, trap, trip, trap.”

The contents of this test file are so remote from what people actually do with , I feel apologetic if I have to explain the correct translation of TRAP.MF; nobody really cares about most of the nittygritty rules that are involved. Yet I believe TRAP exemplifies the sort of test program that has outstanding diagnostic ability, as explained above.

If somebody claims to have a correct implementation of , I will not believe it until I see that TRAP.MF is translated properly. I propose, in fact, that a program must meet two criteria before it can justifiably be called : (1) The person who wrote it must be happy with the way it works at his or her installation; and (2) the program must produce the correct results from TRAP.MF.

is in the public domain, and its algorithms are published; I’ve done this since I do not want to discourage its use by placing proprietary restrictions on the software. However, I don’t want faulty imitations to masquerade as processors, since users want to produce identical results on different machines. Hence I am planning to do whatever I can to suppress any systems that call themselves without meeting conditions (1) and (2). I have copyrighted the programs so that I have some chance to forbid unauthorized copies; I explicitly authorize copying of correct implementations, and not of incorrect ones!

The remainder of this report consists of appendices, whose contents ought to be described briefly here: Appendix A explains in detail how to carry out a test of , given a tape that contains copies

of the other appendices.

Appendix B is TRAP.MF, the fiendish test file that has already been mentioned. People who think that they understand are challenged to see if they know what is supposed to do with this file. People who know only a little about might still find it interesting to study Appendix B, just to get some insights into the methodology advocated here.

Appendix C is TRAPIN.LOG, a correct transcript file TRAP.LOG that results if INIMF is applied to TRAP.MF. (INIMF is the name of a version of that does certain initializations; this run of INIMF also creates a binary base file called TRAP.BASE.)

Appendix D is a correct transcript file TRAP.LOG that results if INIMF or any other version of is applied to TRAP.MF with base file TRAP.BASE.

Appendix E is TRAP.TYP, the symbolic version of a correct output file TRAP.72270GF that was produced at the same time as the TRAP.LOG file of Appendix D.

Appendix F is TRAP.PL, the symbolic version of a correct output file TRAP.TFM that was produced at the same time as the TRAP.LOG file of Appendix D.

Appendix G is TRAP.FOT, an abbreviated version of Appendix D that appears on the user’s terminal during the run that produces TRAP.LOG, TRAP.72270GF, and TRAP.TFM.

The debugging of and the testing of the adequacy of TRAP.MF could not have been done nearly as well as reported here except for the magnificent software support provided by my colleague David R. Fuchs. In particular, he extended our local Pascal compiler so that frequency counting and a number of other important features were added to its online debugging abilities.

The method of testing advocated here has one chief difficulty that deserves comment: I had to verify by hand that did the right things to TRAP.MF. This took many hours, and perhaps I have missed something (as I did in 1960); I must confess that I have not checked every single number in Appendices D, E, and F. However, I’m willing to pay $81.92 to the first finder of any remaining bug in , and I will be surprised if that bug doesn’t show up also in one of these appendices.

Appendix A: How to test .

0. Let’s assume that you have a tape containing TRAP.MF, TRAPIN.LOG, TRAP.LOG, TRAP.TYP, TRAP.PL, and TRAP.FOT, as in Appendices B, C, D, E, F, and G. Furthermore, let’s suppose that you have a working WEB system, and that you have working programs TFtoPL and GFtype, as described in the TEXware and ware reports.

1. Prepare a version of INIMF. (This means that your WEB change file should have init and tini defined to be null.) The debug and gubed macros should be null, in order to activate special printouts that occur when tracingedges > 1.0. The stat and tats macros should also be null, so that statistics are kept. Set mem top and mem max to 3000 (or to mem min plus 3000, if mem min isn’t zero), for purposes of this test version. Also set error line = 64, half error line = 32, max print line = 72, screen width = 100, and screen depth = 200; these parameters affect many of the lines of the test output, so your job will be much easier if you use the same settings that were used to produce Appendix E. Also (if possible) set gf buf size = 8, since this tests more parts of the program. You probably should also use the “normal” settings of other parameters found in MF.WEB (e.g., max internal = 100, buf size = 500, etc.), since these show up in a few lines of the test output. Finally, change ’s screen-display routines by putting the following simple lines in the change file:

            @x Screen routines:
            begin init_screen:=false;
            @y
            begin init_screen:=true; {screen instructions will be logged}
            @z

None of the other screen routines (update screen, blank rectangle, paint row ) should be changed in any way; the effect will be to have ’s actions recorded in the transcript files instead of on the screen, in a machine-independent way.

2. Run the INIMF prepared in step 1. In response to the first ‘**’ prompt, type carriage return (thus getting another ‘**’). Then type ‘\input trap’. You should get an output that matches the file TRAPIN.LOG (Appendix C). Don’t be alarmed by the error messages that you see, unless they are different from those in Appendix C.

3. Run INIMF again. This time type ‘␣&trap␣␣trap␣’. (The spaces in this input help to check certain parts of that aren’t otherwise used.) You should get outputs TRAP.LOG, TRAP.72270GF, and TRAP.TFM. Furthermore, your terminal should receive output that matches TRAP.FOT (Appendix G). During the middle part of this test, however, the terminal will not be getting output, because batchmode is being tested; don’t worry if nothing seems to be happening for a while—nothing is supposed to.

4. Compare the TRAP.LOG file from step 3 with the “master” TRAP.LOG file of step 0. (Let’s hope you put that master file in a safe place so that it wouldn’t be clobbered.) There should be perfect agreement between these files except in the following respects:

a) The dates and possibly the file names will naturally be different.

b) If you had different values for stack size, buf size, etc., the corresponding capacity values will be different when they are printed out at the end.

c) Help messages may be different; indeed, the author encourages non-English help messages in versions of for people who don’t understand English as well as some other language.

d) The total number and length of strings at the end and/or “still untouched” may well be different.

e) If your uses a different memory allocation or packing scheme, the memory usage statistics may change.

f) If you use a different storage allocation scheme, the capsule numbers will probably be different, but the order of variables should be unchanged when dependent variables are shown. should also choose the same variables to be dependent.

g) If your computer handles integer division of negative operands in a nonstandard way, you may get results that are rounded differently. Although TEX is careful to be machine-independent in this regard, is not, because integer divisions are present in so many places.

5. Use GFtype to convert your file TRAP.72270GF to a file TRAP.TYP. (Both of GFtype’s options, i.e., mnemonic output and image output, should be enabled so that you get the maximum amount of output.) The resulting file should agree with the master TRAP.TYP file of step 0, assuming that your GFtype has the “normal” values of compile-time constants (top pixel = 69, etc.).

6. Use TFtoPL to convert your file TRAP.TFM to a file TRAP.PL. The resulting file should agree with the master TRAP.PL file of step 0.

7. You might also wish to test TRAP with other versions of (i.e., VIRMF or a production version with another base file preloaded). It should work unless ’s primitives have been redefined in the base file. However, this step isn’t essential, since all the code of VIRMF appears in INIMF; you probably won’t catch any more errors this way, unless they would already become obvious from normal use of the system.

Appendix B: The TRAP.MF file. The contents of the test routine are prefixed here with line numbers, for ease in comparing this file with the error messages printed later; the line numbers aren’t actually present.

 1 % This is a diabolical test file for MF84. Don't get stuck.
 2 if not known inimf: .inimf.=.0. % next lines are skipped if format loaded
 3 inimf; nonstopmode; tracingtitles:=day; showstopping:=year; hppp:=1000;
 4 << == >> ::: || `` '' -- !! ?? ## && @@ $$ [[ ]] {{ }} . (( 5.5.5 )) ++ "..";
 5 begingroup save =; let=,; save,; newinternal $=,; let ):=, endgroup;
 6 let year=month; showvariable errorstopmode,readstring,2,"2",,,(,),<<,year;
 7 tracingrestores:=tracingcommands:=.00000762939453125; % that's 2^(-17)
 8 if tracingcommands>0:tracingcommands:=if not cycle "":1.1 forever;fi;
 9 tracingcommands:=2.1 exitif tracingcommands>2 endfor; showtoken |=:|>;
10 tracingedges:=1/.00001; tracingequations:=$+1; p~=tracingedges+.00001;
11 interim tracingspecs:=tracingpens:=tracingchoices:=tracingstats:=
12 warningcheck:=tracingoutput:=tracingmacros:=1; $:=ASCII""; $:=x; p~:=p~;
13 delimiters (); delimiters begintext endtext; vardef foo(text t)=t enddef;
14 def lig(text t,|)=ligtable0::for *=1step1until60:0kern boundarychar+*,endfor
15 skipto0;ligtable t:t|0,skipto255;boundarychar:=boundarychar+51.29999enddef;
16 foo begintext interim proofing:=(-.5; shipout nullpicture; special"3" endtext;
17 for n=tracingpens step 1 until proofing:fi endfor showstats; let!!=skipto;
18 path p~; p~=(0,0)..controls (15,4) and (-15,-12)..(4,0);  everyjob /*\;;
19 vardef /*\`'@#=message @ & str#@ &jobname&char ASCII'`&str@#!enddef;
20 let next=dump; vardef `'='` enddef; def '`="\*/" enddef;
21 elseif known"": `'pass[2.]; outer\; let next=\; delimiters ^~7! fi
22 next\; % the second pass will now compute silently; the first pass will halt
23 batchmode; ^~7,endgroup pausing:=1; exitif p exitif boolean pen pencircle endfor
24 scantokens begingroup message char0&"watch this"; "pair p[],';"&char-1endgroup
25 path p[][]p,w,qw; qw=(1,-2)..(2,-1)..(2.5,0.5)..(1,2)..(turningnumber',2.5);
26 numeric p[][]; p[[ [$] ]]=10000000000000000; "this string constant is incomplete
27 string foo[]p,p~if true:[];
28 boolean p[]~,boolean fi.boolean; showvariable boolean; def\\= =end enddef;
29 picture e[]e[], e[], p~[]~[][];
30 pen p~[]~,q["a",qq; p~1~=q=pencircle scaled mexp(-3016.57654);
31 transform p,pp0; if p=p:qq=makepen((1,0)..cycle) xscaled hex "1000";fi
32 qq:=makepen((0,0)..(1,0)..(0,1)..(0,0)..(1,0)..(0,1)..cycle);
33 vardef p[][]p~ begintext suffix a,b endtext())suffix@=show #@; p.a.b() enddef;
34 expandafter let\endtext\\; outer endtext,\,;;qq:=pencircle scaled 4.5 yscaled 2;
35 (6,12)-p7=(0,1)transformed p=(2/(x-x),3/0)transformed p;
36 p1\2p=p007=begintext if string p~[$]: p.1.2-p.1.199999,1 endtext transformed p;
37 showstopping:=0;showvariable p; p=p; let [[=begingroup; let ]]=endgroup;
38 (xxpart p+.002,yxpart p)=1[p1,p2]=(5,y+.00001)=(5,y)=(yypart p,xypart p);
39 reverse(p~..cycle) transformed p=p2. 3.p;
40 p[000000000001]2p~(,[2]3p~,-)=p~1~2[pausing];
41 vardef p~[]@# tertiary t:=if p@ @=@ @p fi; vardef p[][]p~[]=BAD; inner ;;
42 show p~[-2]~[3000,x]++4000>path p3; showvariable p,P;
43 numeric p[]~; p3~=2alpha; p[1/$]~=3beta;
44 begingroup save p; showvariable p; 3beta=1]]; showvariable p;
45 def//expr;=enddef;def!primary!false):!fi enddef;
46 def _aa__secondary _a_=if(true enddef; qq:=makepen(qw..(qw scaled$)..cycle);
47 primarydef _**__=[[show _*__]] enddef;
48 secondarydef _***__=expandafter __scantokens"**oct"_enddef;
49 // //pencircle slanted length p~**makepen reverse subpath p7-p2 of
50 (p7{p2}..controls _aa__not odd.1(15) and known p or !p2and-p2..{1,1}(-p2
51 {curl- +1)..tension atleast1..cycle sqrt2++sqrt2***[[]];

52 [[interim proofing:=charcode:=-20.5;chardp:=-2048;shipout nullpicture]];
53 if charexists -275.50002>known p0 0p=known p~: randomseed charcode; fi
54 randomseed:="goof"; a[($,18++1+-+18),(2,3)]=b[(3,2),(1,$);
55 show (^+1,~+2) slanted-1 yscaled-2 zscaled-(3,4), p transformed(pp xscaled 9),
56 pp shifted (1,2) transformed(p transformed p), -_[0][1,2]; show
57 floor sind mlog sqrt mexp200cosd angle(normaldeviate,uniformdeviate-chardp);
58 string s[]; s1=s2=s4; s3=s5; s1=s2; if s1<=s4<>(s1<>s3):show[[char34=s2:=s3]]fi;
59 substring penoffset point.1of.p~of[[pencircle]]rotated1080/2/1/3of decimal
60 directiontime postcontrol-1.5of(p~&cycle)-precontrol1/2of p~(p~)=s1:=s4:=s4;
61 path p~[]; p~1=p2{length"  "}&cycle; p~1=p2=p~0; p2..controls-p2..cycle=p~2;(p7
62 ..tension1.2..p~[length p~2]..p~2&{0,1}p2..tension1and atleast1..cycle)..tension
63 x..{curl1}-p7{curl hex "IsBad"}..tension.75and.74999..p2{0,1}&p2{_,'}..cycle:=p
64 ~4; subpath(-9,9)of subpath(3.5001,7.00001)of p~4=p~6;
65 show p~6, directiontime(1,2) of p~6, directiontime(1,-1.00001) of p~6;
66 p~3=(0,0)..controls (1,1) and (0,1)..(1,0); show p2..p2{p7}&{$,$}cycle,
67 (directiontime(1,1) of subpath(.314159,1) of p~3)[.314159,1];
68 p~5=(subpath(0,.25)of p~3&subpath(.25,1)of p~3)shifted begintext1,0;
69 p~3:=2/3'zscaled'{p~3}..controls(2,2/3(3))and penoffset(1/2x,y)of(0,1)(1,0);
70 show p~3 intersectiontimes reverse p~3, point.17227 of p~3, point1-.28339of p~3;
71 show point xpart(p~5 intersectiontimes p~5 shifted (.01,0))of p~5-
72 point ypart(p~5 intersectiontimes p~5 shifted (.01,0))of p~5;
73 [[interim tracingedges:=1; e[-1+-+ -1.00001]=nullpicture; addto e1 also[[
74 addto e0 doublepath p~5 scaled 3 withpen q; e0=e1=e2; cull e1 dropping (0,.1);
75 nullpicture]];show e1 shifted(4089,-4095), e2 shifted(-4095,4092)shifted (-3,0),
76 e2 shifted(4089,-4095)]];addto e1 also  e2 shifted(-2,$); e1:=e1 shifted(-4,$);
77 addto e0 also e1rotated89.999+e1scaled$; show e0 xscaled-10 yscaled2 xscaled82
78 yscaled683;addto e1 doublepath (0,9) withweight-3 withweight turningnumber p~6
79 withpen pencircle xscaled(oct"180"++1) rotated-angle(64,$) shifted (9,8)
80 withpen makepen(($,$)..(1,0)..(1,1)..($,0)..($,$)&cycle)xscaled4095.49999;
81 show e1, totalweight e1; chardp:=charcode:=5; xoffset:=-1.5; shipout e1;
82 showstats; addto e2doublepath p~ yscaled1/60; e3:=e2 yscaled 0;
83 autorounding:=2; addto e3doublepath(.5,0)..(3.5,1.5)withweight2;
84 tracingspecs:=0; q:=makepen((1,1)..cycle) yscaled 1.5;
85 p~8=(($,yy)rotated p{0,1}..{0,$}(1,0){0,$}..cycle)scaled2shifted(1000.49,9);
86 turningcheck:=1;addto e2doublepath p~8 withpen q withweight p withpen cycle p;
87 [[interim autorounding:=xx=.1; addto e2 contour p~8 withpen q withweight2]];
88 chardx:=chardp:=charext:=-14.5;shipout-(-e0-e2)+e2shifted(0,6turningnumber p~8);
89 p~9=(0,0)..(1,.5)..(5,1.5)..(7,2.5)..(12,3.5)..(13,4);addto e3 doublepath p~9;
90 smoothing:=1; addto e3 doublepath p~9; addto e3 doublepath (-4095,0)..tension
91 3/4 and 999..(0,2); show e3 rotated-90, (e0+e0) rotated90$ rotated90;
92 if "a" if "ab">"b" elseif path reverse (3,4): >="aa":foo elseif fi "bar"
93 else if '-(1,yy)<': :fi else def dup text t=[[t;save enddef;def|suffix$=,$
94 enddef; def||tertiary p=show substring p of("a" enddef;||(2,$)&"bc");
95 tertiarydef x++y=[[dup showtoken x;]];def quote x expr z of y=z enddef;
96 texts(quote x=(y+0)y+y)("xx",foo(x))=0]] enddef; def texts(text t,tt)expr?=
97 for n:=,for n"yy":n,length if false:endfor tt,t,:if string n:forsuffixes n=
98 foo1,[foo(n)],':show t,tt|(n;exitif not('<='+(?,yy)) endfor for m= :+endfor
99 for m=alpha step-1.1 3$: +m endfor fi endfor enddef; show (0,0){curl2}..
100 subpath(23.3,4.5)of p~9{curl3}..($,$){curl4}..cycle;numspecial p~++2+3;[[
101 let?=if;save if,\;def if=endinput?enddef;def texts=input enddef;texts trap ]];
102 dup[[def texts secondary x=primarydef y++y=x@y enddef; showtoken++;x enddef]]\;
103 proofing:=1;texts:="a"&"b";% strings "yy" and "ab" no longer appear in memory
104 texts-1.00001a1=-(a2+a3+a4+a5+a6);-(a3,a2)/.99999=-(a4+a5+[[showdependencies;

105 a6]],a3+a4+a5+a6)]]; 1.00001a4+1=a5+a6; alpha:=.9alpha+7; showdependencies;
106 a5=a6=2/3-a6; cull e1 dropping($,4a5)withweight1.5; charcode:=chardp:=27;
107 openwindow 3 from (0,0) to (0,0) at "whoops"; addto p; shipout p; cull p;
108 openwindow -.5 from ($,$) to ($,$) at (0,0); special p; numspecial "p";
109 openwindow 15.49999 from (0,32*1024) to (1,31*1057) at (0,0); shipout e1;
110 openwindow 5 from (0,length((0,0){0,0})) to (4,2) at ($,1);
111 openwindow 6 from (length($,0),1) to (3,10) at (-5,2);
112 display nullpicture; display p inwindow 3; display p inwindow 6;
113 display e1 inwindow 6; cull e0 dropping (0.1,4095.999999) withweight 3.5
114 withweight-3.5; display e0 inwindow 5.5; addto e0 also p; addto e0 contour 0;
115 display e0 inwindow 5.49999; addto e0 contour p~9;
116 display e1 inwindow 3+3; display e0e0 inwindow[[vardef e[]e=enddef;6]];
117 addto e0 also e1; display e0 inwindow 5; ligtable||:255|=:|>>0,skipto0;
118 display e1 inwindow 15; display e1 inwindow 6;
119 show [[interim tracingcommands:=0; lig("g")(=:|); lig("h":"i")(|=:);
120 lig("j")(|=:>);lig("k")(=:|>); lig("l")(|=:|>)]];
121 b1:=c.a[ [[let c=++;vardef b=enddef;1]] ]; ligtable"m":0=:0,skipto5;
122 !!; errhelp 0; errmessage "Be like Jane";
123 errhelp "He%%%lp%"; errmessage""; errhelp ""; errmessage "Another";
124 headerbyte 0; headerbyte(48.5)substring(-9,9)of"long"; for\=0:\
125 headerbyte 9:2a6,"q"; fontdimen 9:2a6,"q"; fontdimen 1:2048;
126 fontmaking:=1; extensible 5 5,"c"255.5,"d"; charlist 0:5:"a":"d";
127 ligtable255:255::"a"=:"b","d" kern -2048,"c":0:99.5:"e"|=:|"f",0kern';
128 ligtable 5:0; def clear(text x)=interim x:=$ enddef; clear(hppp); vppp=0;
129 [[clear(tracingmacros); clear(tracingcommands); clear(tracingoutput\;
130 clear(proofing);designsize:=.99999;charcode:=ASCII char-418.5;vppp:=designsize;
131 def dp expr d = charcode:=charcode+1; chardp:=d; shipout nullpicture enddef;
132 dp 13; dp 12; dp 0; dp 21; dp -2; dp 17; dp 11; dp 3; charic:=-1000; dp -1;
133 dp 25; dp 31; dp 19; dp 7; charwd:=256; chardy:=6; dp 23; dp 30]];
134 def f(suffix@@)(expr a,b)(text t)=numeric w; show a; % wipes out the old w
135 addto @@ contour (0,0)..(2,0)..(1,$)..(1,1)..cycle withpen qq; % strange path
136 addto @@ doublepath (0,0){1,1}..{2,1}(2,1) withpen qq; % carefully chosen
137 addto @@ doublepath(($,$){1,0}..(1,1){1,0})scaled.5 withpen nullpen;
138 cull @@ keeping (4,4) withweight1.5; enddef; def g(suffix$)=show $ enddef;
139 addto e0 contour (0,0){1,0}..{1,0}(1,0){0,$}..{0,1}cycle withpen qq;
140 f(e[3,w); g(e3,transformed p,penoffset-(1,1.3)of(pencircle scaled20 yscaled-.5),
141 directiontime (0,1) of ((0,0)..controls(1,1)and($,1)..(3,0)),
142 point 3.14159 of p~9 intersectiontimes subpath (3.14159,4) of p~9,
143 (($,1.1)..(1,$)) intersectiontimes precontrol$ of (0,0);
144 addto e3 doublepath(-4094.99998,0)..(4094.99998,-.00001) withpen penoffset 0 of
145 pencircle; addto e3 also e3 shifted (0,257); ,"flushed with pride"; numeric xx;
146 def f(expr x,y,z)=showdependencies;tracingcapsules:=1;showdependencies;show
147 1/3(3,6)*((x+y)+(y-x)), (1,1)/sqrt2 zscaled (x+1,x+2) - (x+1,x+2) rotated 45,
148 (0,1) zscaled (1,y+2)-(1,y+2) rotated 90 enddef; f((xx+1)/.3,(yy-1)/.5,(xx,0));
149 '=(1000o3-4000(o1-o2)+4000o2+9,-.01o3+3ooo+
150 [[oo=9/10(o2+o4+o5-20);o4=o5=8/9(o1+.5o2); o6=-.0001o2;showdependencies;
151 numeric o[];xpart(alfa,[[pair alfa;0]])]])=-2/3[[save p;(p$,1-p$)]];
152 xoffset:=yoffset:=4000[[oo=.5ooo=2*-1/2(ooo+[[numeric ooo;1]]);oo]];
153 for @=angle(sqrt$,mlog$):charext:=uniformdeviate$;charht:=2048;granularity:=-8;
154 addto e3 contour (0,-100)..tension 500..(100,-99)..tension 3000..cycle;
155 tracingoutput:=@; shipout e3; special "bye"; interim char 99 = "c"; true=false;
156 [[clear(tracingcommands); charcode:=ASCII char 269-13; shipout+nullpicture;
157 "careful" quote for for = @ step 200 until 2*2600: &" METAFONT" endfor;]];

158 scrollmode; "hello again"&char31; save p; fillin:=-.043;
159 def f expr x=let )=]; let [=(; show _enddef; begingroup tracingspecs:=1;
160 show nullpen, makepath.qq, makepath(q rotated1), makepath pencircle rotated $;
161 addto e0 doublepath (0,2){0,$}..{0,$}(0,1)..{1,0}(3,0)..(4,0){1,0}..cycle
162 withpen makepen((0,0)..(5,2.9)..(4,3)..cycle); tracingonline:=1; f xx[1);
163 showdependencies; qq:=q; showstats; bye endtext
164 % things not tested:
165 % interaction (error insertion/deletion, interrupts, \pausing, files not there)
166 % date, time; initialization of random number generator without randomseed
167 % system-dependent parsing of file names, areas, extensions
168 % certain error messages, especially fatal ones
169 % things that can't happen in INIMF
170 % unusual cases of fixed-point arithmetic