xref: /plan9/sys/src/games/festoon.c (revision 27d75179f48b32c8ae0ccd9970d644855c29d5e0)
1 #include <u.h>
2 #include <libc.h>
3 
4 #define R rand()&32767
5 #define T 0.125
6 #define CHOOSE(x) (x[(R)%(sizeof x / sizeof x[0])])
7 #define EQ(a,b) (strcmp(a,b)==0)
8 #define LAST(x) (x[strlen(x)-1])
9 #define VOWEL(x) (x=='a'||x=='e'||x=='i'||x=='o'||x=='u')
10 #define N 8
11 
12 typedef struct xyz {
13 	char           *type;
14 	union {
15 		struct xyz     *x[N];
16 		char           *s[N];
17 	}               list;
18 }              *X, XX;
19 typedef struct {
20 	char           *number, *ending, *tense, *an, *unspec, *passive;
21 }              *E, EE;
22 
23 char           *tense(), *number();
24 char            buff[1000];
25 int             io;
26 int             flag;
27 int		eqn=0, tbl=0, pic=0;
28 double          makeup = -1.;
29 
30 X np(E);
31 X aux(E);
32 X passive(E);
33 X passprep(void);
34 X vp(E);
35 X art(E);
36 X modal(E);
37 X perf(E);
38 X prog(E);
39 X verb(E);
40 X noun(E);
41 X nounal(E);
42 char *prefix(void);
43 char *root(void);
44 int prob(double);
45 char *tense(void);
46 char *number(void);
47 X getxx(void);
48 X verbal(E);
49 X adverb(void);
50 X adjective(void);
51 X adjph(E);
52 X prep(void);
53 X comp(E);
54 X advp(E);
55 X vprep(void);
56 E getenvq(void);
57 X comma(E);
58 X conjadv(void);
59 X lconjadv(void);
60 X conjsub(void);
61 X lconjsub(void);
62 X conj(void);
63 X nomz(void);
64 X equation();
65 X turgid(E);
66 void pr(X);
67 void out(char *);
68 void caps(void);
69 void abo(void);
70 char *splitup(char *);
71 
72 X
nomq(E env)73 nomq(E env) {
74 	X               v = getxx();
75 	v->type = "-nomq";
76 	if (EQ(env->number, "sing")) {
77 		if (EQ(tense(), "past"))
78 			v->list.s[0] = "there was";
79 		else
80 			v->list.s[0] = "there is";
81 	} else {
82 		if (EQ(tense(), "past"))
83 			v->list.s[0] = "there were";
84 		else
85 			v->list.s[0] = "there are";
86 	}
87 	if (prob(0.2))
88 		v->list.s[1] = " not";
89 	return v;
90 }
91 
92 X
rel(void)93 rel(void) {
94 	static char    *c[] = {"that", "which"};
95 	X               v = getxx();
96 	v->type = "-rel";
97 	v->list.s[0] = CHOOSE(c);
98 	return v;
99 }
100 
101 X
sent(E env)102 sent(E env) {
103 	X               sentv = getxx();
104 	sentv->type = "sent";
105 	if (prob(0.09)) {
106 		env->unspec = "";
107 		sentv->list.x[1] = np(env);
108 		sentv->list.x[3] = aux(env);
109 		sentv->list.x[4] = vp(env);
110 		sentv->list.x[0] = nomq(env);
111 		sentv->list.x[2] = rel();
112 		return sentv;
113 	}
114 	sentv->list.x[0] = np(env);
115 	sentv->list.x[1] = aux(env);
116 	sentv->list.x[2] = vp(env);
117 	return sentv;
118 }
119 
120 X
nomy(void)121 nomy(void) {
122 	X               v = getxx();
123 	v->type = "-nomq";
124 	v->list.s[0] = "the fact that";
125 	return v;
126 }
127 
128 X
np(env)129 np(env)
130 	E               env;
131 {
132 	X               npv = getxx();
133 	EE              nenv;
134 	static EE       empty;
135 	npv->type = "np";
136 	if (prob(0.025)) {
137 		nenv = empty;
138 		npv->list.x[0] = nomy();
139 		npv->list.x[1] = sent(&nenv);
140 		if (env->number == 0)
141 			env->number = "sing";
142 		return npv;
143 	}
144 	npv->list.x[1] = nounal(env);
145 	npv->list.x[0] = art(env);
146 	return npv;
147 }
148 
149 X
aux(E env)150 aux(E env) {
151 	X               auxv = getxx();
152 	int             i = 0;
153 	auxv->type = "aux";
154 	if (env->tense == 0)
155 		env->tense = env->ending = tense();
156 	if (prob(0.25))
157 		auxv->list.x[i++] = modal(env);
158 	if (prob(0.25))
159 		auxv->list.x[i++] = perf(env);
160 	if (prob(0.25))
161 		auxv->list.x[i++] = prog(env);
162 	USED(i);
163 	return auxv;
164 }
165 
166 X
passive(env)167 passive(env)
168 	E               env;
169 {
170 	X               v = getxx();
171 	v->type = "-passive";
172 	if (env->tense == 0)
173 		env->tense = env->ending = tense();
174 	if (env->number == 0)
175 		env->number = number();
176 	if (EQ(env->ending, "modal"))
177 		v->list.s[0] = "be";
178 	else if (EQ(env->ending, "-en"))
179 		v->list.s[0] = "been";
180 	else if (EQ(env->ending, "-ing"))
181 		v->list.s[0] = "being";
182 	else {
183 		if (EQ(env->tense, "past"))
184 			v->list.s[0] = EQ(env->number, "sing") ? "was" : "were";
185 		else
186 			v->list.s[0] = EQ(env->number, "sing") ? "is" : "are";
187 	}
188 	env->passive = env->ending = "pass";
189 	return v;
190 }
191 
192 X
passprep(void)193 passprep(void) {
194 	X               v = getxx();
195 	v->type = "-passprep";
196 	v->list.s[0] = "by";
197 	return v;
198 }
199 
200 X
vp(env)201 vp(env)
202 	E               env;
203 {
204 	X               vpv = getxx();
205 	int             i = 0;
206 	vpv->type = "vp";
207 	if (prob(0.5))
208 		vpv->list.x[i++] = passive(env);
209 	vpv->list.x[i++] = verbal(env);
210 	vpv->list.x[i++] = comp(env);
211 	if (prob(0.10))
212 		vpv->list.x[i++] = advp(env);
213 	USED(i);
214 	return vpv;
215 }
216 
217 X
art(env)218 art(env)
219 	E               env;
220 {
221 	static char    *aspecsg[] = {"the", "the", "the", "the", "the", "this", "this", "that"};
222 	static char    *aspecpl[] = {"the", "the", "the", "the", "the", "these", "those"};
223 	static char    *aunssg[] = {"a", "a", "a", "a", "a", "a", "a", "much", "each", "any"};
224 	static char    *aunspl[] = {"some", "a few", "a couple", "several", "many", "all",
225 		"no",
226 		"an undue number of",
227 	"a number of"};
228 	X               artv = getxx();
229 	artv->type = "-art";
230 	if (env->number == 0)
231 		env->number = number();
232 	if (env->unspec == 0 && prob(0.33)) {
233 		if (EQ(env->number, "sing"))
234 			artv->list.s[0] = CHOOSE(aspecsg);
235 		else
236 			artv->list.s[0] = CHOOSE(aspecpl);
237 	} else if (prob(0.50) || env->an && EQ(env->number, "sing")) {
238 		if (EQ(env->number, "sing"))
239 			artv->list.s[0] = env->an ? "a" : CHOOSE(aunssg);
240 		else
241 			artv->list.s[0] = CHOOSE(aunspl);
242 		if (env->an && EQ(artv->list.s[0], "all"))
243 			artv->list.s[0] = "";
244 	} else
245 		artv->list.s[0] = "";
246 	env->unspec = 0;
247 	if (env->an && EQ(env->an, "an") && EQ(artv->list.s[0], "a"))
248 		artv->list.s[0] = "an";
249 	env->an = 0;
250 	return artv;
251 }
252 
253 X
modal(env)254 modal(env)
255 	E               env;
256 {
257 	static char    *pres[] = {"can", "may", "must", "shall", "will"};
258 	static char    *past[] = {"could", "might", "should", "would"};
259 	X               modalv = getxx();
260 	modalv->type = "-modal";
261 	if (env->tense == 0)
262 		env->tense = env->ending = tense();
263 	if (EQ(env->ending, "pres"))
264 		modalv->list.s[0] = CHOOSE(pres);
265 	else
266 		modalv->list.s[0] = CHOOSE(past);
267 	env->ending = "modal";
268 	return modalv;
269 }
270 
271 X
perf(env)272 perf(env)
273 	E               env;
274 {
275 	X               perfv = getxx();
276 	perfv->type = "-perf";
277 	if (env->tense == 0)
278 		env->tense = env->ending = tense();
279 	if (env->number == 0)
280 		env->number = number();
281 	if (EQ(env->ending, "past")) {
282 		perfv->list.s[0] = "had";
283 	} else if (EQ(env->ending, "pres")) {
284 		if (EQ(env->number, "sing"))
285 			perfv->list.s[0] = "had";
286 		else
287 			perfv->list.s[0] = "have";
288 	} else
289 		perfv->list.s[0] = "have";
290 	env->ending = "-en";
291 	return perfv;
292 }
293 
294 X
prog(env)295 prog(env)
296 	E               env;
297 {
298 	X               progv = getxx();
299 	progv->type = "-prog";
300 	if (env->tense == 0)
301 		env->tense = env->ending = tense();
302 	if (env->number == 0)
303 		env->number = number();
304 	if (EQ(env->ending, "pres")) {
305 		if (EQ(env->number, "sing"))
306 			progv->list.s[0] = "is";
307 		else
308 			progv->list.s[0] = "are";
309 	} else if (EQ(env->ending, "past")) {
310 		if (EQ(env->number, "sing"))
311 			progv->list.s[0] = "was";
312 		else
313 			progv->list.s[0] = "were";
314 	} else if (EQ(env->ending, "-en")) {
315 		progv->list.s[0] = "been";
316 	} else if (EQ(env->ending, "modal")) {
317 		progv->list.s[0] = "be";
318 	}
319 	env->ending = "-ing";
320 	return progv;
321 }
322 
323 X
verb(env)324 verb(env)
325 	E               env;
326 {
327 	/* they pres, he pres, they past, they perf, they prog, they pass */
328 	static char    *ends[][6] = {{"ate", "ates", "ated", "ated", "ating", "ated"},
329 	{"en", "ens", "ened", "ened", "ening", "ened"},
330 	{"esce", "esces", "esced", "esced", "escing", "esced"},
331 	{"fy", "fies", "fied", "fied", "fying", "fied"},
332 	{"ize", "izes", "ized", "ized", "izing", "ized"}};
333 	X               verbv = getxx();
334 	int             i;
335 	verbv->type = "-verb";
336 	if (env->tense == 0)
337 		env->tense = env->ending = tense();
338 	if (env->number == 0)
339 		env->number = number();
340 	if (0 && prob(0.1) && EQ(env->tense, env->ending)) {
341 		if (EQ(env->number, "sing")) {
342 			if (EQ(env->tense, "pres"))
343 				verbv->list.s[0] = "is";
344 			else
345 				verbv->list.s[0] = "was";
346 		} else {
347 			if (EQ(env->tense, "pres"))
348 				verbv->list.s[0] = "are";
349 			else
350 				verbv->list.s[0] = "were";
351 		}
352 	} else {
353 		verbv->list.s[0] = prefix();
354 		verbv->list.s[1] = root();
355 		if (EQ(env->ending, "pres") && EQ(env->number, "sing"))
356 			i = 1;
357 		else if (EQ(env->ending, "pres") || EQ(env->ending, "modal"))
358 			i = 0;
359 		else if (EQ(env->ending, "past"))
360 			i = 2;
361 		else if (EQ(env->ending, "-en"))
362 			i = 3;
363 		else if (EQ(env->ending, "-ing"))
364 			i = 4;
365 		else if (EQ(env->ending, "pass"))
366 			i = 5;
367 		else
368 			i = 0;
369 		verbv->list.s[2] = ends[R % (sizeof ends / sizeof *ends)][i];
370 	}
371 	env->ending = 0;
372 	return verbv;
373 }
374 
375 static char    *nounlist[] = {"final completion",
376 	"final ending", "final outcome",
377 	"adaptation", "appearance", "argument", "circumstance",
378 	"confession", "confidence", "delimitation", "dilution",
379 	"dissertation", "distribution", "duplication",
380 	"entertainment", "equipment", "evolution",
381 	"existence", "expression", "generation", "impression",
382 	"integration", "interaction", "investment", "judgment",
383 	"population", "provision", "solution", "statement",
384 	"tradition", "transmission",
385 	"final result", "added increment", "assistance",
386 	"beneficial assistance", "mutual cooperation",
387 	"projection", "future projection",
388 	"capability", "conjecture", "consensus of opinion",
389 	"general consensus", "absence", "deficiency",
390 	"inadequacy", "insufficience", "insufficiency",
391 	"growing importance", "renewed emphasis",
392 	"renewed interest", "changing behavior",
393 	"critical thinking", "careful thinking",
394 	"comprehensive survey", "high standard",
395 	"basic foundation", "system testing",
396 	"serious discussion", "serious concern",
397 	"organizational framework", "prototype model",
398 	"uniform nomenclature", "greater cooperation",
399 	"uniform consistency", "early expectation",
400 	"standardization", "great similarity",
401 	"shortage", "presence", "sufficiency",
402 	"consequent result", "construct", "disutility",
403 	"early beginning", "emotional feeling", "endeavor",
404 	"authorization", "order of magnitude", "preference",
405 	"impact", "joint cooperation", "joint partnership",
406 	"main essential", "methodology", "modification",
407 	"necessary requisite", "past history", "situation",
408 	"effectuation", "clarification", "new doubt",
409 	"policy", "encouragement", "preparation",
410 	"criterion", "material", "interest", "acceptance",
411 	"rejection", "publication", "circulation",
412 	"protection", "insurance",
413 	"assignment", "identification",
414 	"submission", "request",
415 	"guidance", "correspondence", "inclusion",
416 	"attachment", "assumption",
417 	"recommendation", "prescription", "approval",
418 	"discretion", "responsibility", "relevance",
419 	"issuance", "termination", "total effect",
420 	"deleterious effect", "consolidation",
421 	"aggregation", "definiteness", "commencement",
422 	"actual experience", "experience",
423 	"combination", "accord", "filing",
424 	"idea", "abstraction", "method", "procedure",
425 	"complaint", "maintenance", "finance", "travel",
426 	"purchase", "repair", "routine",
427 	"development", "cancellation",
428 	"partitioning", "development effort",
429 	"project", "automation", "multilevel architecture",
430 	"multilevel heirarchy", "data stream",
431 	"objective",
432 	"individual assignment", "mode of operation",
433 	"clear community", "attendant interest",
434 	"task division", "well defined interfacing",
435 	"team report", "meeting time", "effective use",
436 	"friction",
437 	"major objective", "ownership",
438 	"overall project time constraint",
439 	"functional division", "requirements analysis",
440 	"code development", "charter",
441 	"requirements definition", "vertical division",
442 	"broad range", "strong feeling",
443 	"considerable latitude", "overall project constraint",
444 	"sufficient resource", "assigned task", "expectation",
445 	"critical aspect", "clear understanding",
446 	"computing load", "clean interfacing", "natural basis",
447 	"team activity", "team responsibility",
448 	"main function", "predominant portion",
449 	"work plan", "major breakpoint", "work module",
450 	"achievable accuracy", "supplementary work",
451 	"field version", "internal establishment",
452 	"internal communication", "development progress",
453 	"internal meeting", "experience level",
454 	"high level autonomy", "adherence",
455 	"feasibility demonstration", "persistent problem",
456 	"internal objective", "idea sharing",
457 	"improved performance", "unfamiliar methodology",
458 	"new methodology", "development experience",
459 	"module specification", "good progress",
460 	"optimal number", "natural division",
461 	"good relationship", "cross attendance",
462 	"attendance", "necessary communication",
463 	"evolving organization", "basic principle",
464 	"complete revision", "general information",
465 	"primary objective", "load-carrying capacity",
466 	"necessary revision", "major change",
467 	"clarified interpretation", "subsequent attempt",
468 	"basic objective", "full utilization",
469 	"practical consideration",
470 	"proportionate quantity", "substantial change",
471 	"database design", "unified framework",
472 	"customer service", "strong interest",
473 	"unified description", "necessary background information",
474 	"provisioning", "physical coverage", "general observation",
475 	"new technology", "validity determination",
476 	"relation", "regulation", "verification",
477 	"impediment", "portal", "practice", "premise",
478 	"basis", "movement", "question",
479 	"issue", "input", "output", "observation",
480 	"input", "output", "input", "output",
481 	"mechanization", "function", "evaluation",
482 	"result", "further consideration", "category",
483 	"performance indicator", "early warning",
484 	"analysis purpose", "measurement", "replacement",
485 	"utilitarian purpose",
486 	"quota", "proposed enhancement", "enhancement",
487 	"interfacing", "team organization", "module",
488 	"guideline", "continuing study",
489 	"required assistance", "major advance",
490 	"proposal", "hierarchy",
491 	"current view", "refinement", "activity",
492 	"external description", "tight schedule pressure",
493 	"internal conflict", "internal issue",
494 	"reasonable compromise", "next phase",
495 	"goal", "time constraint", "constraint",
496 	"outcome", "important outcome",
497 	"considerable experience", "intelligent choice",
498 	"deliverable documentation", "discussion",
499 	"timely delivery", "design issue", "large quantity",
500 	"general environment", "protocol",
501 	"transitioning", "modeling",
502 	"considerable difficulty", "abstract interfacing",
503 	"data structure", "consideration", "difficulty",
504 	"statistical accuracy",
505 	"agenda", "technique", "reordering",
506 	"reauthorization", "current proposal",
507 	"significant change", "criteria", "validation",
508 	"validity",
509 	"terminology", "current understanding",
510 	"incorporation", "staffing impact",
511 	"schedule impact", "cost tradeoff",
512 	"system architecture",
513 	"adequate capacity", "centralization",
514 	"current task", "system deployment",
515 	"attendant uncertainty", "process",
516 	"potential usefulness", "proposed method",
517 	"basic assumption", "anomaly",
518 	"available data", "potential improvement",
519 	"registration", "exemption", "exception",
520 	"follow-up", "service",
521 	"installation", "construction", "necessity",
522 	"occasion", "instrumentation", "disposal",
523 	"attractiveness",
524 	"convenience", "sponsoring",
525 	"signification", "meaningfulness",
526 	"significantness", "individuality",
527 	"specification", "determination", "affirmation",
528 	"recruitment", "supervision", "management",
529 	"oversight", "overview", "environment",
530 	"effectation", "circumvention", "location",
531 	"execution", "effectiveness", "consciousness",
532 	"notation", "confirmation", "restriction",
533 	"organization", "realization", "actification",
534 	"activation", "reification", "beginning", "conclusion",
535 	"ending", "finishing", "teamwork", "motivation",
536 	"attitude", "good attitude",
537 	"progress", "milestone", "deadline", "schedule",
538 	"allocation", "resource", "command", "concern",
539 	"time", "time frame", "reality",
540 	"behaviour", "ability", "advent", "increment",
541 	"opportunity", "accomplishment", "aggregate",
542 	"analysis", "totality", "matter",
543 	"date", "duration", "centrality",
544 	"proximity", "collection", "elimination",
545 	"investigation", "opinion", "debate",
546 	"decision", "benefit", "difference", "discontinuity",
547 	"fabrication", "plan", "chart", "forecast",
548 	"simplicity", "simplification", "maximization",
549 	"minimization", "direction",
550 	"agreement",
551 	"amount", "quantity", "quality", "essence",
552 	"description", "violation", "purpose",
553 	"primary purpose", "automatic control", "redefinition",
554 	"uniform emphasis", "study activity", "work activity",
555 	"concept stage", "concept activity",
556 	"possible potential", "summarization", "system function",
557 	"rationale", "significant enhancement", "diverse need",
558 	"diverse organization", "comprehensive plan", "interim",
559 	"functional overview", "system configuration",
560 	"configuration", "failure", "quantitative result",
561 	"major obstacle", "conception",
562 	"effectiveness", "final evaluation",
563 	"interrelationship", "functional requirement",
564 	"system philosophy", "verbal interchange",
565 	"perceived inadequacy", "primary emphasis",
566 	"intermingling", "cooperation", "partnership",
567 	"adjustment", "application", "implementation",
568 	"contact", "mention", "power",
569 	"nature", "invention", "importance",
570 	"ground", "reason", "permission", "size",
571 	"report", "documentation", "priority",
572 	"pursuance", "recurrance", "resumption",
573 	"presupposition", "continuance",
574 	"substantiation", "success", "action", "truth",
575 	"past experience", "greater acceptability",
576 	"organizational structure", "clear distinction",
577 	"clear definition",
578 	"significant use", "unmet need", "centralized organization",
579 	"vague concept", "negative impact", "detrimental effect",
580 	"modularization", "submodularization",
581 	"effect", "consistancy",
582 	"inconsistancy", "completion", "utilization",
583 	"reference", "doubt", "evidence",
584 	"viewpoint",
585 	"actual fact",
586 	"true fact", "underlying purpose", "viable alternative"};
587 
588 static char    *adjlist[] = {"concrete", "abstract", "procedural",
589 	"real", "ideal", "functional", "prototype",
590 	"effective", "capable", "incremental",
591 	"perceived", "associated", "interdepartmental",
592 	"diverse", "characteristic", "worst-case",
593 	"qualitative", "fully automatic", "candidate",
594 	"consensual", "consequential", "conjectural",
595 	"constructive", "initial", "cooperative",
596 	"essential", "methodological", "requisite",
597 	"historical", "situational", "political",
598 	"prepared", "material", "defined", "well defined",
599 	"organizational", "projected", "overall",
600 	"accepted", "rejected", "corresponding",
601 	"committed", "environmental", "typical", "working", "timely",
602 	"growing", "unprecedented", "new", "renewed", "fresh",
603 	"rapid", "changing", "careful", "comprehensive", "broad",
604 	"massive", "huge", "enormous",
605 	"evaluated", "discresionary",
606 	"durable", "beneficial",
607 	"maximal", "tremendous", "minimal",
608 	"on-site", "standardized", "standard",
609 	"powerful", "natural", "necessary",
610 	"reasonable", "successful",
611 	"doubtful", "dubious", "certain",
612 	"unified", "different", "similar", "utilitarian",
613 	"realizable", "organizable", "motivated",
614 	"topical", "valuable", "feasible",
615 	"intelligent", "deliverable", "nontrivial",
616 	"worthwhile", "complicated",
617 	"organized", "organizing", "progressing",
618 	"schedulable", "resourceful", "commanding",
619 	"important", "allocatable", "temporal",
620 	"ponderable", "understandable", "comprehendable",
621 	"past", "present", "future",
622 	"obvious", "considerable", "finished", "completed",
623 	"unique", "abovementioned",
624 	"major", "minor", "tendentious", "activating",
625 	"actual", "added", "adequate", "affordable",
626 	"analyzable", "additional", "intuitive",
627 	"artificial", "good", "better",
628 	"worse", "bad", "basic", "fundamental", "brief",
629 	"general", "very unique", "extreme", "most unique",
630 	"central", "proximate", "approximate", "collected",
631 	"conductable", "comtemplatable",
632 	"continuing", "demonstrable", "desirable",
633 	"correctable", "foreseeable",
634 	"discontinued", "early", "beginning",
635 	"effectuated", "elucidated", "emotional",
636 	"enclosed", "enthused", "entire", "exact",
637 	"experimental", "fearful", "final",
638 	"following", "informative",
639 	"full", "complete", "indicated", "authorized",
640 	"modularized", "submodularized",
641 	"particular", "preferred", "satisfactory",
642 	"measurable", "referenced", "literal",
643 	"modified",
644 	"correct", "prioritized", "prolonged",
645 	"regrettable", "apparent",
646 	"continued", "subsequent", "sufficient",
647 	"suggestive", "true", "ultimate", "separate",
648 	"purposeful", "regarded", "resulting",
649 	"doubtful", "evident", "interesting", "worthy",
650 	"uniform", "vital", "viable",
651 	"worthwhile", "alternative",
652 	"sophisticated", "employed",
653 	"clear", "lucid", "simple", "perspicuous",
654 	"incomplete", "concerned"};
655 
656 X
noun(env)657 noun(env)
658 	E               env;
659 {
660 	static char    *suff[] = {"ion", "sion", "tion", "age",
661 		"ness", "ment", "ure",
662 		"ity", "iety", "ty", "ence", "ency", "ance",
663 		"ancy", "tude", "hood", "ture", "ate", "art", "ard",
664 		"ism", "ine", "stress", "trix", "ess",
665 		"dom", "ship", "eer", "ster", "ant", "ent", "ary",
666 		"ery", "ory", "ette", "let", "ling", "ule", "kin",
667 		"ar", "or", "ist", "fulness",
668 		"kin", "cule", "icle", "y", "ability", "iosos"};
669 	X               nounv = getxx();
670 	int             i = 0;
671 	nounv->type = "-noun";
672 	if (env->number == 0)
673 		env->number = number();
674 	if (prob(makeup)) {
675 		if (prob(0.05)) {
676 			nounv->list.s[i++] = CHOOSE(adjlist);
677 			nounv->list.s[i++] = "ness";
678 		} else
679 			nounv->list.s[i++] = CHOOSE(nounlist);
680 	} else {
681 		nounv->list.s[i++] = prefix();
682 		nounv->list.s[i++] = root();
683 		nounv->list.s[i++] = CHOOSE(suff);
684 	}
685 	if (EQ(env->number, "plural")) {
686 		if (LAST(nounv->list.s[i - 1]) == 's')
687 			nounv->list.s[i] = "es";
688 		else if (LAST(nounv->list.s[i - 1]) == 'y')
689 			nounv->list.s[i] = "ies";
690 		else
691 			nounv->list.s[i] = "s";
692 	}
693 	return nounv;
694 }
695 
696 X
adjval(void)697 adjval(void) {
698 	X               adjvalv = getxx();
699 	int             i = 0;
700 	adjvalv->type = "adjval";
701 	if (prob(0.25)) {
702 		adjvalv->list.x[i++] = adverb();
703 	}
704 	do {
705 		adjvalv->list.x[i++] = adjective();
706 	} while (i < N - 1 && prob(0.25));
707 	return adjvalv;
708 }
709 
710 X
nounal(env)711 nounal(env)
712 	E               env;
713 {
714 	X               nounalv = getxx();
715 	int             i = 0;
716 	X               p;
717 	nounalv->type = "nounal";
718 	if (prob(0.15)) {
719 		nounalv->list.x[i++] = adjval();
720 	}
721 	nounalv->list.x[i++] = noun(env);
722 	if (prob(0.15)) {
723 		nounalv->list.x[i] = adjph(env);
724 	}
725 	env->an = "a";
726 	for (p = nounalv; p->type[0] != '-'; p = p->list.x[0]);
727 	for (i = 0; p->list.s[i]; i++) {
728 		if (p->list.s[i][0] == 0)
729 			continue;
730 		if (VOWEL(p->list.s[i][0])) {
731 			env->an = "an";
732 		}
733 		break;
734 	}
735 	return nounalv;
736 }
737 
738 char           *
prefix(void)739 prefix(void) {
740 	static char    *pref[] = {
741 		"amb", "ambi", "super", "hyper", "an", "tra", "trans", "post", "palim",
742 		"omni", "pan", "circ", "circum", "peri", "a", "ab", "abs", "de", "apo",
743 		"re", "ana", "mal", "ante", "pre", "fore", "pro", "infra", "para",
744 		"inter", "ultra", "extra", "trans", "cata", "de", "oct", "octa",
745 		"octo", "equi", "pseudo", "prim", "prot", "proto", "pent", "penta",
746 		"quin", "quint", "quinque", "pro", "tetr", "tetra", "quad", "quadr",
747 		"quadri", "quartet", "off", "bene", "hemi", "demi", "semi", "crypto",
748 		"cent", "centi", "hecto", "en", "em", "in", "im", "intro", "be",
749 		"macro", "poly", "mult", "multi", "neo", "nona", "novem", "ennea",
750 		"in", "un", "im", "il", "ir", "non", "a", "nil", "paleo", "mon", "mono",
751 		"uni", "e", "ex", "ec", "ef", "super", "supr", "sur", "hyper", "vic",
752 		"vice", "hept", "hepta", "sept", "septe", "septem", "septi", "hex",
753 		"hexa", "sex", "dis", "deca", "deka", "deci", "kilo", "mill", "milli",
754 		"tri", "per", "dia", "ad", "com", "di", "amphi", "bi", "bin", "bis",
755 	"sub", "hypo", "epi", "eu", "holo"};
756 	if (prob(0.65))
757 		return "";
758 	return CHOOSE(pref);
759 }
760 
761 char           *
root(void)762 root(void) {
763 	static char    *root[] = {
764 		"pan", "omni", "arch", "zo", "rog", "rogat", "cred", "flect", "flex",
765 		"test", "hem", "hemato", "nasc", "nat", "bibl", "fer", "voc", "port", "lat",
766 		"fortuna", "ped", "chrom", "vinc", "vict", "crea", "cise", "mort", "mors",
767 		"necr", "claim", "clam", "hetero", "pel", "puls", "vac", "iso", "phobe",
768 		"phobia", "prim", "prime", "flu", "flux", "sequ", "liber", "liver", "theo",
769 		"magna", "medi", "man", "manu", "pen", "pend", "pens", "eu", "capit",
770 		"iatr", "aud", "aus", "cor", "cord", "cour", "grav", "ten", "tain",
771 		"tent", "sacr", "sacer", "heiro", "sanct", "cide", "mega", "ultima",
772 		"ridi", "risi", "leg", "jus", "jur", "nom", "duc", "duct", "duce",
773 		"bio", "viv", "vivi", "vita", "lus", "lum", "luc", "photo",
774 		"min", "philo", "phile", "phila", "amic", "anthrop", "poly", "multi",
775 		"fac", "fact", "fic", "fect", "meter", "psych", "mod", "mot", "mov",
776 		"nov", "neo", "neg", "uni", "alter", "ali", "idio", "pop", "dem",
777 		"demo", "lic", "licit", "poten", "posse", "potes", "mem", "simul",
778 		"arch", "homo", "mar", "mer", "vis", "vid", "scope", "auto", "mitt",
779 		"miss", "ac", "acr", "brev", "clud", "clus", "dorm", "micro", "aster",
780 		"astro", "rect", "recti", "forc", "fort", "path", "cap", "cep", "cept",
781 		"put", "tempo", "tempor", "dent", "dont", "ver", "veri",
782 		"feder", "fide", "feal", "fid", "cosm", "migra", "hydro", "aqu",
783 		"endo", "gyn", "logo", "opus", "oper", "graph", "scrib", "scrip",
784 	"mis", "miso", "anni", "annu", "enni", "ced", "cede", "ceed", "cess"};
785 	return CHOOSE(root);
786 }
787 
prob(f)788 prob(f)
789 	double          f;
790 {
791 	return (R) < (f * 32767.0);
792 }
793 
794 char           *
tense()795 tense()
796 {
797 	return prob(0.5) ? "pres" : "past";
798 }
799 
800 char           *
number()801 number()
802 {
803 	return prob(0.25) ? "plural" : "sing";
804 }
805 
806 X
getxx()807 getxx()
808 {
809 	X               rv;
810 	static XX       empty;
811 
812 	rv = (X) malloc(sizeof *rv);
813 	if (rv == 0) {
814 		fprint(2, "festoon: outa space\n");
815 		exits("space");
816 	}
817 	*rv = empty;
818 	return rv;
819 }
820 
821 X
verbal(env)822 verbal(env)
823 	E               env;
824 {
825 	X               verbalv = getxx();
826 	int             i = 0;
827 	verbalv->type = "verbal";
828 	if (prob(0.25))
829 		verbalv->list.x[i++] = adverb();
830 	verbalv->list.x[i] = verb(env);
831 	return verbalv;
832 }
833 
834 static char    *advlist[] = {"absolutely", "functionally",
835 	"accordingly", "broadly", "actionably", "actually",
836 	"additionally",
837 	"ambiguously", "amply",
838 	"analogously",
839 	"aperiodically",
840 	"apparently", "appreciably",
841 	"appropriately", "approximately",
842 	"arbitrarily",
843 	"associatively",
844 	"automatically",
845 	"awfully",
846 	"axiomatically",
847 	"badly", "barely", "basically",
848 	"beneficially",
849 	"blatantly",
850 	"capably", "carefully", "carelessly",
851 	"casually", "causally", "cautiously",
852 	"centrally", "certainly",
853 	"cheaply", "cleanly",
854 	"closely", "coarsely", "cognizantly",
855 	"coincidentally", "collectively", "collaterally",
856 	"comparably",
857 	"competently", "completely", "comprehensibly",
858 	"concededly", "conceivably",
859 	"concisely", "conclusively", "concretely",
860 	"concurrently", "conjecturally",
861 	"currently",
862 	"conscientously", "consequently", "consequentially",
863 	"consistently", "constantly",
864 	"contemporaneuosly", "constructively",
865 	"continually", "continuously", "contractually",
866 	"contrarily", "contributatively", "conveniently",
867 	"conventionally",
868 	"correctively",
869 	"correctly",
870 	"crudely",
871 	"curiously",
872 	"decidedly",
873 	"deeply",
874 	"deficiently", "demandingly",
875 	"dependably", "desireably",
876 	"determinately", "diagnostically",
877 	"differentially", "differently",
878 	"directly", "discernibly",
879 	"distinctly", "doubtfully", "dramatically",
880 	"dynamically",
881 	"economically",
882 	"effecaciously", "efficiently",
883 	"elegantly",
884 	"emphatically", "encouragingly",
885 	"endlessly", "endurably",
886 	"entirely", "epistomologically",
887 	"functionally", "immediately",
888 	"equably", "equally", "equitably", "erroneously",
889 	"esoterically", "eternally", "evenly", "eventfully",
890 	"eventually", "evidently",
891 	"exceedingly", "exactly", "excellently",
892 	"exceptionally", "excessively", "exclusively",
893 	"experimentally",
894 	"explicitly", "extremely",
895 	"factually", "faithfully",
896 	"faultlessly", "feasibly",
897 	"finitely", "firmly", "forcefully",
898 	"formally", "formerly", "frankly", "freely",
899 	"frugally", "fully", "generally",
900 	"globally", "gradually",
901 	"harmlessly",
902 	"helpfully",
903 	"highly", "homogeneously",
904 	"hopefully",
905 	"ideally", "identically", "ideologically",
906 	"idiomatically", "idiosyncratically", "idly",
907 	"imaginably", "immaterially", "immensely",
908 	"impartially", "imperceptably", "imperfectly", "importantly",
909 	"improperly", "imprudently", "inaccurately", "inappropriately",
910 	"accurately",
911 	"inclusively", "incompletely", "incorrectly",
912 	"increasingly", "independently",
913 	"indirectly", "ineffectively", "ineffectually", "inefficiently",
914 	"infallibly", "instantaneously", "instantly",
915 	"insufficiently", "internally", "likely", "only",
916 	"invaluably", "inversely", "irrelevantly", "irrespectively",
917 	"largely", "lastly", "legitimately", "literally",
918 	"locally", "loosely", "manageably", "markedly",
919 	"memorably", "mildly", "mindfully", "moderately",
920 	"momentarily", "naturally", "needfully", "needlessly",
921 	"nominally", "normally", "objectively", "occasionally",
922 	"temporarily",
923 	"officially", "oppositely", "ordinarily", "ostensibly",
924 	"partially", "permissibly",
925 	"personally", "pertinently",
926 	"physically", "plainly", "plainly",
927 	"pleasingly", "politically",
928 	"potentially", "predictively",
929 	"predominantly", "prematurely", "preparedly", "presently",
930 	"previously", "primarily",
931 	"primely", "principally", "problematically",
932 	"productively", "promptly", "proportionately",
933 	"provably", "purely", "quickly", "radically", "randomly", "recently",
934 	"repeatedly", "secondarily", "separately",
935 	"usually", "specifically",
936 	"redundantly", "regardlessly", "reliably",
937 	"remarkably", "remotely", "respectively",
938 	"probably",
939 	"robustly", "seemingly",
940 	"sensibly", "singularly", "steadily",
941 	"strikingly", "substantially", "successfully",
942 	"supposedly", "systematically", "understandably",
943 	"necessarily", "unfortunately",
944 	"unnecessarily", "unmistakably", "usefully", "weakly"};
945 
946 X
adverb(void)947 adverb(void) {
948 	static char    *wordy[] = {"very ", "extremely ", "generally ",
949 		"reasonably ", "fundamentally ", "essentially ", "particularly ",
950 		"very ",
951 		"very ", "very ",
952 		"very ", "very ",
953 		"very ", "very ",
954 		"very ", "very ",
955 		"very ", "very ",
956 		"very ", "very ",
957 		"very ", "very ",
958 		"entirely ",
959 		"rather ", "fairly ", "relatively ", "comparatively ",
960 		"moderately ",
961 		"totally ", "very ", "quite "};
962 	static char    *suff[] = {"wardly", "ably", "wisely",
963 		"ably", "ily", "ly", "ly", "ly"};
964 
965 	X               adverbv = getxx();
966 	int             i = 0;
967 
968 	adverbv->type = "-adverb";
969 	if (prob(0.150)) {
970 		adverbv->list.s[i] = prob(.5) ? "simply" : "easily";
971 		return adverbv;
972 	}
973 	if (prob(0.4))
974 		adverbv->list.s[i++] = CHOOSE(wordy);
975 	if (prob(makeup))
976 		adverbv->list.s[i] = CHOOSE(advlist);
977 	else {
978 		adverbv->list.s[i++] = prefix();
979 		adverbv->list.s[i++] = root();
980 		adverbv->list.s[i] = CHOOSE(suff);
981 	}
982 	return adverbv;
983 }
984 
985 X
adjective(void)986 adjective(void) {
987 	static char    *suff[] = {"ive", "ful", "ous", "some", "oid",
988 	"ine", "esque", "en", "an",
989 	"ile", "able", "ible", "istic", "ic",
990 	"an", "ian", "ish", "ite", "al", "less"};
991 	X               adjv = getxx();
992 	int             i = 0;
993 
994 	adjv->type = "-adjective";
995 	if (prob(0.2)) {
996 		adjv->list.s[i++] = "not ";
997 		adjv->list.s[i++] = "un";
998 	}
999 	if (prob(makeup)) {
1000 		adjv->list.s[i] = CHOOSE(adjlist);
1001 		return adjv;
1002 	}
1003 	adjv->list.s[i++] = prefix();
1004 	adjv->list.s[i++] = root();
1005 	adjv->list.s[i] = CHOOSE(suff);
1006 	return adjv;
1007 }
1008 
1009 X
adjph(env)1010 adjph(env)
1011 	E               env;
1012 {
1013 	X               adjv = getxx();
1014 	EE              nenv;
1015 	static EE       empty;
1016 	int             i = 0;
1017 	adjv->type = "adjph";
1018 	if (prob(0.25)) {
1019 		nenv = *env;
1020 		nenv.tense = 0;
1021 		adjv->list.x[i++] = rel();
1022 		adjv->list.x[i++] = aux(&nenv);
1023 		adjv->list.x[i] = vp(&nenv);
1024 		return adjv;
1025 	}
1026 	nenv = empty;
1027 	adjv->list.x[i++] = prep();
1028 	adjv->list.x[i] = np(&nenv);
1029 	return adjv;
1030 }
1031 
1032 static char    *preplist[] = {"across", "by", "in", "of",
1033 	"near", "under", "over",
1034 	"in back of", "below", "behind", "of", "of", "of", "of",
1035 	"centered around", "centered about",
1036 	"in close proximity to", "following after",
1037 	"in between", "in conflict with", "in conjunction with",
1038 	"in the area of", "in the neighborhood of", "in the proximity of",
1039 	"in the field of", "for the purpose of",
1040 	"giving rise to", "based upon", "being caused by",
1041 	"of", "of", "of", "of",
1042 	"being effectuated by", "being aggrevated by",
1043 	"being used with",
1044 	"being collected together with", "being combined together with",
1045 	"connected up to", "exhibiting a tendency towards",
1046 	"being facilitated by",
1047 	"being employed with",
1048 	"having a deleterious effect upon", "impacting",
1049 	"being joined together with", "being merged together with",
1050 	"in the vicinity of"};
1051 
1052 X
prep(void)1053 prep(void) {
1054 	X               pv = getxx();
1055 	pv->type = "-prep";
1056 	pv->list.s[0] = CHOOSE(preplist);
1057 	return pv;
1058 }
1059 
1060 X
comp(env)1061 comp(env)
1062 	E               env;
1063 {
1064 	X               v = getxx();
1065 	EE              nenv;
1066 	static EE       empty;
1067 	int             i = 0;
1068 	nenv = empty;
1069 	v->type = "comp";
1070 	if (0 && prob(0.001))
1071 		v->list.x[i++] = adjective();
1072 	else if (prob(0.1))
1073 		v->list.x[i++] = advp(&nenv);
1074 	else {
1075 		if (env->passive)
1076 			v->list.x[i++] = passprep();
1077 		v->list.x[i++] = np(&nenv);
1078 		env->passive = 0;
1079 	}
1080 	if (0 && prob(0.05))
1081 		v->list.x[i++] = adverb();
1082 	USED(i);
1083 	return v;
1084 }
1085 
1086 X
advp(env)1087 advp(env)
1088 	E               env;
1089 {
1090 	X               v = getxx();
1091 	v->type = "advp";
1092 	v->list.x[0] = vprep();
1093 	v->list.x[1] = np(env);
1094 	return v;
1095 }
1096 
1097 static char    *vpreplist[] = {"to", "at", "by", "from", "with", "for"};
1098 
1099 X
vprep(void)1100 vprep(void) {
1101 	X               v = getxx();
1102 	v->type = "-vprep";
1103 	v->list.s[0] = CHOOSE(vpreplist);
1104 	return v;
1105 }
1106 
1107 E
getenvq()1108 getenvq()
1109 {
1110 	static EE       empty;
1111 	E               v;
1112 	v = (E) malloc(sizeof *v);
1113 	if (v == 0) {
1114 		print("outa room\n");
1115 		exits("room");
1116 	}
1117 	*v = empty;
1118 	return v;
1119 }
1120 
1121 X
comma(env)1122 comma(env)
1123 	E               env;
1124 {
1125 	X               v = getxx();
1126 	static EE       empty;
1127 
1128 	v->type = "-comma";
1129 	v->list.s[0] = ",";
1130 	*env = empty;
1131 	return v;
1132 }
1133 
1134 static char    *conjadvlist[] = {"we believe", "naturally", "therefore",
1135 	"moreover", "obviously"};
1136 
1137 X
conjadv(void)1138 conjadv(void) {
1139 	X               v = getxx();
1140 
1141 	v->type = "-conjadv";
1142 	v->list.s[0] = CHOOSE(conjadvlist);
1143 	return v;
1144 }
1145 
1146 static char    *lconjlist[] = {"therefore", "however", "nevertheless",
1147 	"consequently", "also", "in addition", "moreover",
1148 	"accordingly", "essentially", "presumably", "actually",
1149 	"basically", "importantly", "clearly", "obviously",
1150 	"needless to say", "as already stated",
1151 	"generally", "approximately", "presently",
1152 	"hopefully", "usually", "in the great majority of cases",
1153 	"seen in the above light", "most significantly",
1154 	"when the need arises",
1155 	"in a large number of cases", "after this is accomplished",
1156 	"in all cases",
1157 	"having been made aware concerning these matters",
1158 	"as an example of this", "as a consequence of this",
1159 	"as a matter of fact", "as is often the case",
1160 	"as of this date", "assuming that this is the case",
1161 	"at the present moment in time", "at this time",
1162 	"as a consequent result of this", "as a desireable benefit of this",
1163 	"if at all possible", "similarly", "in the same connection",
1164 	"in large measure", "in many cases", "in rare cases",
1165 	"in some cases", "in the interim", "in the last analysis",
1166 	"in light of these facts", "in the majority of instances",
1167 	"in the not too distant future", "in the same way as described above",
1168 	"in this case", "for all intents and purposes",
1169 	"to arrive at an approximation", "for this reason",
1170 	"for many reasons, then",
1171 	"as is often the case", "last but not least",
1172 	"later on", "on a few occasions", "on this occasion",
1173 	"in summary", "taking this into consideration",
1174 	"with this in mind",
1175 	"substantially", "ultimately"};
1176 
1177 X
lconjadv(void)1178 lconjadv(void) {
1179 
1180 	X               v = getxx();
1181 	v->type = "-lconjadv";
1182 	v->list.s[0] = CHOOSE(lconjlist);
1183 	return v;
1184 }
1185 
1186 X
conjsub(void)1187 conjsub(void) {
1188 	static char    *conjsublist[] = {"although", "even though",
1189 		"despite the fact that",
1190 		"for the simple reason that",
1191 		"because", "due to the fact that", "since",
1192 		"whether or not",
1193 		"inasmuch as",
1194 	"as"};
1195 	X               v = getxx();
1196 	v->type = "-conjsub";
1197 	v->list.s[0] = CHOOSE(conjsublist);
1198 	return v;
1199 }
1200 
1201 static char    *lconjsublist[] = {"although", "even though",
1202 	"despite the fact that",
1203 	"because", "due to the fact that", "since",
1204 	"if", "anytime that", "in the case that",
1205 	"as a consequence of the fact that",
1206 	"as regards the fact that",
1207 	"as a desireable benefit of the fact that",
1208 	"with reference to the fact that",
1209 	"as long as",
1210 	"as an important essential of the fact that",
1211 	"in conjunction with the fact that",
1212 	"in the light of the fact that",
1213 	"if", "if", "if", "if",
1214 	"leaving out of consideration the fact that",
1215 	"just as",
1216 	"inasmuch as", "until such time as",
1217 	"as soon as", "being as", "in the same way as",
1218 	"with the exception of the fact that",
1219 	"notwithstanding the fact that",
1220 	"on the grounds that",
1221 	"on the basis of the fact that",
1222 	"persuant to the fact that",
1223 	"although it seems apparent that",
1224 	"with regard to the fact that",
1225 	"as can be seen from the fact that",
1226 	"as"};
1227 
1228 X
lconjsub(void)1229 lconjsub(void) {
1230 	X               v = getxx();
1231 	v->type = "-lconjsub";
1232 	v->list.s[0] = CHOOSE(lconjsublist);
1233 	return v;
1234 }
1235 
1236 static char    *conjlist[] = {"and", "but", "yet", "and", "and"};
1237 
1238 X
conj(void)1239 conj(void) {
1240 	X               v = getxx();
1241 	v->type = "-conj";
1242 	v->list.s[0] = CHOOSE(conjlist);
1243 	return v;
1244 }
1245 static char    *nomzlist[] = {"it is easy to see that",
1246 	"it is a basic fact that",
1247 	"it is obvious that", "it is not unimportant that",
1248 	"it is easy to overlook the fact that",
1249 	"it is within the realm of possibility that",
1250 	"it is apparent that",
1251 	"this is indicitive of the fact that",
1252 	"this is in substantial agreement with the fact that",
1253 	"this demonstrates the fact that",
1254 	"this leaves out of consideration the fact that",
1255 	"it is of the utmost importance that",
1256 	"the truth is that",
1257 	"the fact is that",
1258 	"it turns out that", "it will turn out to be true that",
1259 	"it should be noted that",
1260 	"it stands to reason that",
1261 	"it would not be unreasonable to assume that",
1262 	"it is interesting to note that",
1263 	"this can be proved by:",
1264 	"this is a trivial consequence of",
1265 	"it is assumed that",
1266 	"it remains to be shown that",
1267 	"it is left to the reader to prove"
1268 };
1269 
1270 X
nomz(void)1271 nomz(void) {
1272 	X               v = getxx();
1273 	v->type = "-nomz";
1274 	v->list.s[0] = CHOOSE(nomzlist);
1275 	return v;
1276 }
1277 
1278 X
equation(void)1279 equation(void) {
1280 	X		v = getxx();
1281 	static char eqnbuff[100], x;
1282 	static char *eqnelem[] = {"int", "sum", "prod", "union", "inter"};
1283 	static char *eqnfn[] = { "sin", "cos", "tan", "arc", "det",
1284 		"log", "exp", "f", "g", "sinh", "O", "J sub 0", "J sub 1",
1285 		"P sub i", "gamma", "zeta" };
1286 	static char *eqnval[] = { "0", "DELTA", "GAMMA", "LAMBDA",
1287 		"OMEGA", "PHI", "PSI", "SIGMA", "THETA", "UPSILON",
1288 		"XI", "alpha", "beta", "gamma", "delta", "epsilon",
1289 		"eta", "kappa","lambda", "mu", "omega", "x", "zeta", "inf"};
1290 	static char *eqnrel[] = {"=", "<=", ">=", "==", "!=", "approx"};
1291 
1292 	x = 'a' + (R)%26;
1293 	v->type = "-eqn";
1294 	sprint(eqnbuff,"$%s from %c=%d to %s %s ( %c ) d%c %s %s$",
1295 		CHOOSE(eqnelem), x, (R)&077, CHOOSE(eqnval), CHOOSE(eqnfn),
1296 		x, x, CHOOSE(eqnrel), CHOOSE(eqnval));
1297 	v->list.s[0] = eqnbuff;
1298 	return v;
1299 }
1300 
1301 X
turgid(env)1302 turgid(env)
1303 	E               env;
1304 {
1305 	X               v = getxx();
1306 	int             i = 0;
1307 
1308 	v->type = "turgid";
1309 	if (prob(T * 1.5)) {
1310 		v->list.x[i++] = lconjadv();
1311 		v->list.x[i++] = comma(env);
1312 		v->list.x[i++] = sent(env);
1313 	} else if (prob(2 * T)) {
1314 		v->list.x[i++] = turgid(env);
1315 		v->list.x[i++] = comma(env);
1316 		v->list.x[i++] = conj();
1317 		v->list.x[i++] = sent(env);
1318 	} else if (prob(1.5 * T)) {
1319 		v->list.x[i++] = lconjsub();
1320 		v->list.x[i++] = sent(env);
1321 		v->list.x[i++] = comma(env);
1322 		v->list.x[i++] = sent(env);
1323 	} else if (prob(T * .5)) {
1324 		v->list.x[i++] = sent(env);
1325 		v->list.x[i++] = comma(env);
1326 		v->list.x[i++] = conjadv();
1327 	} else if (prob(T)) {
1328 		v->list.x[i++] = turgid(env);
1329 		v->list.x[i++] = comma(env);
1330 		v->list.x[i++] = conjsub();
1331 		v->list.x[i++] = sent(env);
1332 	} else if (prob(.5 * T)) {
1333 		v->list.x[i++] = nomz();
1334 		if (eqn && prob(.5)) {
1335 			v->list.x[i++] = equation();
1336 			v->list.x[i++] = comma(env);
1337 			v->list.x[i++] = conj();
1338 		}
1339 		v->list.x[i++] = sent(env);
1340 	} else
1341 		v->list.x[i++] = sent(env);
1342 	USED(i);
1343 	return v;
1344 }
1345 
1346 char *
splitup(char * strlab)1347 splitup(char *strlab)  {
1348 	static char label[64];
1349 	int j, c;
1350 
1351 	label[0]='"';
1352 	for (j=1; j<60 &&
1353 		(c = *strlab++) != '\0'; j++)
1354 		if (c == ' ') {
1355 			label[j++]='"';
1356 			label[j++]=' ';
1357 			label[j]='"';
1358 		}
1359 		else
1360 			label[j] = c;
1361 	label[j++] = '"'; label[j] = '\0';
1362 	return(label);
1363 }
1364 
1365 void
abo(void)1366 abo(void) {
1367 	fprint(2, "usage: festoon [-pet] [-sSEED] [SENTENCES] [%%-invented-nouns]\n");
1368 	exits("usage");
1369 }
1370 
1371 void
caps(void)1372 caps(void) {
1373 	int             i;
1374 	for (i = 1; i < io; i++)
1375 		if (buff[i - 1] == ' ' && buff[i] <= 'z' && buff[i] >= 'a')
1376 			buff[i] += 'A' - 'a';
1377 }
1378 
1379 void
main(int argc,char * argv[])1380 main(int argc, char *argv[]) {
1381 	static char    *furniture[] = {"WASTEBASKET", "ASHTRAY", "TABLE",
1382 	"DESK DRAWER", "COAT LOCKER", "BOOKSHELF"};
1383 
1384 	static char    *ccto[] = {
1385 		"J. N. Akkerhuis",
1386 		"J. J. Argosy",
1387 		"M. D. Banal",
1388 		"H. V. Bandersnatch",
1389 		"L. Bimmler",
1390 		"F. W. Blivet",
1391 		"Z. Brazen",
1392 		"M. Bushido",
1393 		"J. D. Carbuncle",
1394 		"N. Crab",
1395 		"R. H. deTruckle",
1396 		"R. L. Drechsler",
1397 		"C. B. Dudgeon",
1398 		"R. T. Dun",
1399 		"G. R. Emlin",
1400 		"W. G. Fallow",
1401 		"R. S. Flummox",
1402 		"R. N. Fribble",
1403 		"C. R. Glitch",
1404 		"R. H. Hardin",
1405 		"S. A. Hobble",
1406 		"B. W. Kernighan",
1407 		"D. B. Knudsen",
1408 		"C. L'Hommedieu",
1409 		"R. S. Limn",
1410 		"S. T. Livid",
1411 		"Mrs. B. R. Mauve",
1412 		"C. Mee",
1413 		"N-P. Nelson",
1414 		"C. H. Russet",
1415 		"M. Shayegan",
1416 		"M. H. Simper",
1417 		"B. R. Sorrel",
1418 		"G. Swale",
1419 		"R. R. Swarthy",
1420 		"P. Terra-Cotta",
1421 		"U. G. Winnow"};
1422 
1423 	static char	*picelem[] = { "box", "ellipse", "box", "box"};
1424 	static char	*piccon[] = { "arrow", "line", "line <-", "line <->",
1425 	"spline", "spline <-", "spline <->"};
1426 	static char	*picdir[] = { "right", "down right", "down",
1427 	"left", "up left", "left", "down", "down right", nil};
1428 	E               env;
1429 	X               tree;
1430 	int             i, j = 0, k = 0;
1431 	int             lim = 0;
1432 	long            t = 0;
1433 	char            c, **str;
1434 	int		junk, junk2;
1435 
1436 	for (i = 1, ++argv; i < argc; i++, argv++)
1437 		if (*argv[0] == '-')	/* -pet -snnn */
1438 			while (c = *++argv[0])
1439 				switch (c) {
1440 				case 'z':
1441 					flag = 1;
1442 					continue;
1443 				case 'p':
1444 					pic = 1;
1445 					continue;
1446 				case 't':
1447 					tbl = 1;
1448 					continue;
1449 				case 'e':
1450 					eqn = 1;
1451 					continue;
1452 				case 's':
1453 				t = atoi(argv[0]+1); argv[0][1] = '\0';
1454 					continue;
1455 				default:
1456 					abo();	/* illegal option */
1457 				}
1458 		else if (lim == 0)
1459 			lim = atoi(argv[0]);
1460 		else
1461 			makeup = 1.0 - (float) atoi(argv[0]) / 100.0;
1462 	USED(i);
1463 	if (t == 0)
1464 		time(&t);
1465 	if (makeup < 0. || makeup > 1.0)
1466 		makeup = 1.0;
1467 	if (lim <= 0)
1468 		lim = 25;
1469 	srand((int) t);
1470 
1471 	print(".TL\n");
1472 	env = getenvq();
1473 	tree = np(env);
1474 	io = 0;
1475 	pr(tree);
1476 	buff[io] = 0;
1477 	caps();
1478 	print("%s\n", buff);
1479 	print(".AU \"C. C. Festoon\" CCF Headquarters %ld\n", t);
1480 	if (eqn)
1481 		print(".EQ\ndelim $$\n.EN\n");
1482 	print(".AS\n");
1483 	free(env);
1484 	do {
1485 		env = getenvq();
1486 		tree = turgid(env);
1487 		io = 0;
1488 		pr(tree);
1489 		buff[io] = 0;
1490 		print("%s.\n", buff);
1491 		free(env);
1492 	} while (prob(0.75));
1493 	print(".AE\n");
1494 	print(".MT \"MEMORANDUM FOR %s\"\n.hy 1\n",
1495 	       CHOOSE(furniture));
1496 	while (i++ < lim) {
1497 		if (i % 23 == 0) {	/* Time for a section header */
1498 			env = getenvq();
1499 			tree = np(env);
1500 			io = 0;
1501 			print(".H 1 \"");
1502 			pr(tree);
1503 			buff[io] = 0;
1504 			caps();
1505 			print("%s\"\n", buff);
1506 			free(env);
1507 		}
1508 		if (i % 27 == 0 && pic) {	/* Time for a picture */
1509 			print(".DS CB\n.ps -1\n.PS\n");
1510 			str = &(CHOOSE(picdir));
1511 			if (*str == nil) str = &picdir[0];
1512  			junk2 = (R&07) + 3;
1513 			for(junk = 1; junk < junk2; junk++) {
1514 				print("%s; ", *str);
1515 				if (str == &picdir[0]) {
1516 					pic = 2; print("A: ");
1517 				}
1518 				print("%s %s ht %3.1f wid %3.1f\n",
1519 				CHOOSE(picelem), splitup(CHOOSE(nounlist)),
1520 				0.4+0.5/junk2, 0.8+0.6/junk2);
1521 				print("%s %s %3.1f ",
1522 				CHOOSE(piccon), *str, 0.2+.3/junk2);
1523 				if (*++str == nil) str = &picdir[0];
1524 				print("then %s %3.1f %s\n",
1525 				*str, 0.3+.2/junk2,
1526 				splitup(CHOOSE(adjlist)));
1527 			}
1528 			print("circle rad .3 \"process\" \"completion\"\n");
1529 			if (pic == 2) {
1530 				pic =1;
1531 				print("line <- dashed up .25 from A.n\n");
1532 				print("circle rad .3 \"process\" \"start\"\n");
1533 			}
1534 			print(".PE\n.ps +1\n.DE\n");
1535 			print(".ce\n\\fBFigure %d\\fP\n", i/27);
1536 		}
1537 		if (i % 41 == 0 && tbl) {	/* Time for a table */
1538 			print(".TS\n");
1539 			print("box, center;\nc\ts\ts\n");
1540 			print("n | l | lw(%3.1fi).\n", 2.0+(41.0+(t&07))/i);
1541 			print("Action Plan %d\n=\n", i);
1542 			print("Item\tWho\tAction\n");
1543 			for (junk = 1; junk < (i&17)+4; junk++) {
1544 				print("_\n%ld\t", t/i+junk);
1545 				print("%s\tT{\n", CHOOSE(ccto));
1546 				env = getenvq();
1547 				io = 0;
1548 				tree = sent(env);
1549 				pr(tree);
1550 				buff[io] = 0;
1551 				print("%s.\nT}\n", buff);
1552 				free(env);
1553 			}
1554 			print(".TE\n");
1555 			print(".ce\n\\fBTable %d\\fP\n", i/41);
1556 		}
1557 		env = getenvq();
1558 		tree = turgid(env);
1559 		io = 0;
1560 		pr(tree);
1561 		buff[io] = 0;
1562 		if (++k % 13 == 0 && prob(0.35)) {	/* Bullet list */
1563 			print("%s:\n", buff);
1564 			print(".BL\n");
1565 			do {
1566 				print(".LI\n");
1567 				free(env);
1568 				env = getenvq();
1569 				io = 0;
1570 				tree = sent(env);
1571 				pr(tree);
1572 				buff[io] = 0;
1573 				print("%s.\n", buff);
1574 			} while (prob(.83));
1575 			print(".LE\n");
1576 			print(".P\n");
1577 		} else {
1578 			if (k % 11 == 0 && prob(.21)) {	/* do as footnote */
1579 				print("%s\\*F.\n", buff);
1580 				free(env);
1581 				env = getenvq();
1582 				io = 0;
1583 				tree = sent(env);
1584 				pr(tree);
1585 				buff[io] = 0;
1586 				print(".FS\n%s.\n.FE\n", buff);
1587 			}
1588 			else print("%s.\n", buff);	/* normal flush */
1589 		}
1590 		if (++j > 2 && prob(0.4))
1591 			print(".P\n"), j = 0;
1592 		free(env);
1593 	}
1594 	USED(i);
1595 	print(".SG\n");
1596 	print(".NS 0\n");
1597 	for (j = 0; j == 0;) {
1598 		for (i = 0; i < sizeof ccto / sizeof *ccto; i++) {
1599 			if (prob(.10))
1600 				j = 1, print("%s\n", ccto[i]);
1601 		}
1602 	}
1603 	print(".NE\n");
1604 	USED(i);
1605 	exits("");
1606 }
1607 
1608 void
pr(tree)1609 pr(tree)
1610 	X               tree;
1611 {
1612 	int             i;
1613 	if (flag ) {
1614 		out("<");
1615 		out(tree->type);
1616 		out(">");
1617 	}
1618 	if (tree->type[0] == '-') {
1619 		out(" ");
1620 		for (i = 0; tree->list.s[i]; i++) {
1621 			out(tree->list.s[i]);
1622 		}
1623 	} else
1624 		for (i = 0; tree->list.x[i]; i++) {
1625 			pr(tree->list.x[i]);
1626 		}
1627 	free(tree);
1628 	USED(i);
1629 	return;
1630 }
1631 
1632 void
out(s)1633 out(s)
1634 	char           *s;
1635 {
1636 	if (io == 0 && *s == ' ')
1637 		return;
1638 	if (io == 0) {
1639 		for (; s[io]; io++)
1640 			buff[io] = s[io];
1641 		buff[0] += 'A' - 'a';
1642 		return;
1643 	}
1644 	if ((buff[io - 1] == ' ' || buff[io - 1] == '\n' ) && *s == ' ')
1645 		return;
1646 	if (buff[io - 1] == ' ' && *s == ',') {
1647 		buff[io - 1] = ',';
1648 		buff[io++] = '\n';
1649 		return;
1650 	}
1651 	if (buff[io - 1] == 'y' && *s == 'i' && s[1] == 'e')
1652 		io--;
1653 	else if (*s == buff[io - 1] && *s != 's' && *s != 'n')
1654 		io--;
1655 	else if (*s == 'e' && buff[io - 1] == 'a')
1656 		io--;
1657 	for (; *s;)
1658 		buff[io++] = *s++;
1659 	return;
1660 }
1661