xref: /plan9-contrib/sys/src/cmd/spin/reprosrc.c (revision de2caf28f9ba1a56e70be94a699435d36eb50311)
1312a1df1SDavid du Colombier /***** spin: reprosrc.c *****/
2312a1df1SDavid du Colombier 
3*de2caf28SDavid du Colombier /*
4*de2caf28SDavid du Colombier  * This file is part of the public release of Spin. It is subject to the
5*de2caf28SDavid du Colombier  * terms in the LICENSE file that is included in this source directory.
6*de2caf28SDavid du Colombier  * Tool documentation is available at http://spinroot.com
7*de2caf28SDavid du Colombier  */
8312a1df1SDavid du Colombier 
9312a1df1SDavid du Colombier #include <stdio.h>
10*de2caf28SDavid du Colombier #include <assert.h>
11312a1df1SDavid du Colombier #include "spin.h"
12312a1df1SDavid du Colombier #include "y.tab.h"
13312a1df1SDavid du Colombier 
14312a1df1SDavid du Colombier static int indent = 1;
15312a1df1SDavid du Colombier 
16*de2caf28SDavid du Colombier extern YYSTYPE yylval;
17*de2caf28SDavid du Colombier extern ProcList	*ready;
18*de2caf28SDavid du Colombier static void repro_seq(Sequence *);
19312a1df1SDavid du Colombier 
20312a1df1SDavid du Colombier void
doindent(void)21312a1df1SDavid du Colombier doindent(void)
22312a1df1SDavid du Colombier {	int i;
23312a1df1SDavid du Colombier 	for (i = 0; i < indent; i++)
24312a1df1SDavid du Colombier 		printf("   ");
25312a1df1SDavid du Colombier }
26312a1df1SDavid du Colombier 
27312a1df1SDavid du Colombier void
repro_sub(Element * e)28312a1df1SDavid du Colombier repro_sub(Element *e)
29312a1df1SDavid du Colombier {
30312a1df1SDavid du Colombier 	doindent();
31312a1df1SDavid du Colombier 	switch (e->n->ntyp) {
32312a1df1SDavid du Colombier 	case D_STEP:
33312a1df1SDavid du Colombier 		printf("d_step {\n");
34312a1df1SDavid du Colombier 		break;
35312a1df1SDavid du Colombier 	case ATOMIC:
36312a1df1SDavid du Colombier 		printf("atomic {\n");
37312a1df1SDavid du Colombier 		break;
38312a1df1SDavid du Colombier 	case NON_ATOMIC:
39312a1df1SDavid du Colombier 		printf(" {\n");
40312a1df1SDavid du Colombier 		break;
41312a1df1SDavid du Colombier 	}
42312a1df1SDavid du Colombier 	indent++;
43312a1df1SDavid du Colombier 	repro_seq(e->n->sl->this);
44312a1df1SDavid du Colombier 	indent--;
45312a1df1SDavid du Colombier 
46312a1df1SDavid du Colombier 	doindent();
47312a1df1SDavid du Colombier 	printf(" };\n");
48312a1df1SDavid du Colombier }
49312a1df1SDavid du Colombier 
50*de2caf28SDavid du Colombier static void
repro_seq(Sequence * s)51312a1df1SDavid du Colombier repro_seq(Sequence *s)
52312a1df1SDavid du Colombier {	Element *e;
53312a1df1SDavid du Colombier 	Symbol *v;
54312a1df1SDavid du Colombier 	SeqList *h;
55312a1df1SDavid du Colombier 
56312a1df1SDavid du Colombier 	for (e = s->frst; e; e = e->nxt)
57312a1df1SDavid du Colombier 	{
58312a1df1SDavid du Colombier 		v = has_lab(e, 0);
59312a1df1SDavid du Colombier 		if (v) printf("%s:\n", v->name);
60312a1df1SDavid du Colombier 
61312a1df1SDavid du Colombier 		if (e->n->ntyp == UNLESS)
62312a1df1SDavid du Colombier 		{	printf("/* normal */ {\n");
63312a1df1SDavid du Colombier 			repro_seq(e->n->sl->this);
64312a1df1SDavid du Colombier 			doindent();
65312a1df1SDavid du Colombier 			printf("} unless {\n");
66312a1df1SDavid du Colombier 			repro_seq(e->n->sl->nxt->this);
67312a1df1SDavid du Colombier 			doindent();
68312a1df1SDavid du Colombier 			printf("}; /* end unless */\n");
69312a1df1SDavid du Colombier 		} else if (e->sub)
70312a1df1SDavid du Colombier 		{
71312a1df1SDavid du Colombier 			switch (e->n->ntyp) {
72312a1df1SDavid du Colombier 			case DO: doindent(); printf("do\n"); indent++; break;
73312a1df1SDavid du Colombier 			case IF: doindent(); printf("if\n"); indent++; break;
74312a1df1SDavid du Colombier 			}
75312a1df1SDavid du Colombier 
76312a1df1SDavid du Colombier 			for (h = e->sub; h; h = h->nxt)
77312a1df1SDavid du Colombier 			{	indent--; doindent(); indent++; printf("::\n");
78312a1df1SDavid du Colombier 				repro_seq(h->this);
79312a1df1SDavid du Colombier 				printf("\n");
80312a1df1SDavid du Colombier 			}
81312a1df1SDavid du Colombier 
82312a1df1SDavid du Colombier 			switch (e->n->ntyp) {
83312a1df1SDavid du Colombier 			case DO: indent--; doindent(); printf("od;\n"); break;
84312a1df1SDavid du Colombier 			case IF: indent--; doindent(); printf("fi;\n"); break;
85312a1df1SDavid du Colombier 			}
86312a1df1SDavid du Colombier 		} else
87312a1df1SDavid du Colombier 		{	if (e->n->ntyp == ATOMIC
88312a1df1SDavid du Colombier 			||  e->n->ntyp == D_STEP
89312a1df1SDavid du Colombier 			||  e->n->ntyp == NON_ATOMIC)
90312a1df1SDavid du Colombier 				repro_sub(e);
91312a1df1SDavid du Colombier 			else if (e->n->ntyp != '.'
92312a1df1SDavid du Colombier 			     &&  e->n->ntyp != '@'
93312a1df1SDavid du Colombier 			     &&  e->n->ntyp != BREAK)
94312a1df1SDavid du Colombier 			{
95312a1df1SDavid du Colombier 				doindent();
96312a1df1SDavid du Colombier 				if (e->n->ntyp == C_CODE)
97312a1df1SDavid du Colombier 				{	printf("c_code ");
9800d97012SDavid du Colombier 					plunk_inline(stdout, e->n->sym->name, 1, 1);
99312a1df1SDavid du Colombier 				} else if (e->n->ntyp == 'c'
100312a1df1SDavid du Colombier 				       &&  e->n->lft->ntyp == C_EXPR)
101312a1df1SDavid du Colombier 				{	printf("c_expr { ");
102312a1df1SDavid du Colombier 					plunk_expr(stdout, e->n->lft->sym->name);
103312a1df1SDavid du Colombier 					printf("} ->\n");
104312a1df1SDavid du Colombier 				} else
105312a1df1SDavid du Colombier 				{	comment(stdout, e->n, 0);
106312a1df1SDavid du Colombier 					printf(";\n");
107312a1df1SDavid du Colombier 			}	}
108312a1df1SDavid du Colombier 		}
109312a1df1SDavid du Colombier 		if (e == s->last)
110312a1df1SDavid du Colombier 			break;
111312a1df1SDavid du Colombier 	}
112312a1df1SDavid du Colombier }
113312a1df1SDavid du Colombier 
114312a1df1SDavid du Colombier void
repro_proc(ProcList * p)115312a1df1SDavid du Colombier repro_proc(ProcList *p)
116312a1df1SDavid du Colombier {
117312a1df1SDavid du Colombier 	if (!p) return;
118312a1df1SDavid du Colombier 	if (p->nxt) repro_proc(p->nxt);
119312a1df1SDavid du Colombier 
120312a1df1SDavid du Colombier 	if (p->det) printf("D");	/* deterministic */
121312a1df1SDavid du Colombier 	printf("proctype %s()", p->n->name);
122312a1df1SDavid du Colombier 	if (p->prov)
123312a1df1SDavid du Colombier 	{	printf(" provided ");
124312a1df1SDavid du Colombier 		comment(stdout, p->prov, 0);
125312a1df1SDavid du Colombier 	}
126312a1df1SDavid du Colombier 	printf("\n{\n");
127312a1df1SDavid du Colombier 	repro_seq(p->s);
128312a1df1SDavid du Colombier 	printf("}\n");
129312a1df1SDavid du Colombier }
130312a1df1SDavid du Colombier 
131312a1df1SDavid du Colombier void
repro_src(void)132312a1df1SDavid du Colombier repro_src(void)
133312a1df1SDavid du Colombier {
134*de2caf28SDavid du Colombier 	repro_proc(ready);
135*de2caf28SDavid du Colombier }
136*de2caf28SDavid du Colombier 
137*de2caf28SDavid du Colombier static int in_decl;
138*de2caf28SDavid du Colombier static int in_c_decl;
139*de2caf28SDavid du Colombier static int in_c_code;
140*de2caf28SDavid du Colombier 
141*de2caf28SDavid du Colombier void
blip(int n,char * b)142*de2caf28SDavid du Colombier blip(int n, char *b)
143*de2caf28SDavid du Colombier {	char mtxt[1024];
144*de2caf28SDavid du Colombier 
145*de2caf28SDavid du Colombier 	strcpy(mtxt, "");
146*de2caf28SDavid du Colombier 
147*de2caf28SDavid du Colombier 	switch (n) {
148*de2caf28SDavid du Colombier 	default:	if (n > 0 && n < 256)
149*de2caf28SDavid du Colombier 				sprintf(mtxt, "%c", n);
150*de2caf28SDavid du Colombier 			else
151*de2caf28SDavid du Colombier 				sprintf(mtxt, "<%d?>", n);
152*de2caf28SDavid du Colombier 
153*de2caf28SDavid du Colombier 			break;
154*de2caf28SDavid du Colombier 	case '(':	strcpy(mtxt, "("); in_decl++; break;
155*de2caf28SDavid du Colombier 	case ')':	strcpy(mtxt, ")"); in_decl--; break;
156*de2caf28SDavid du Colombier 	case '{':	strcpy(mtxt, "{"); break;
157*de2caf28SDavid du Colombier 	case '}':	strcpy(mtxt, "}"); break;
158*de2caf28SDavid du Colombier 	case '\t':	sprintf(mtxt, "\\t"); break;
159*de2caf28SDavid du Colombier 	case '\f':	sprintf(mtxt, "\\f"); break;
160*de2caf28SDavid du Colombier 	case '\n':	sprintf(mtxt, "\\n"); break;
161*de2caf28SDavid du Colombier 	case '\r':	sprintf(mtxt, "\\r"); break;
162*de2caf28SDavid du Colombier 	case 'c':	sprintf(mtxt, "condition"); break;
163*de2caf28SDavid du Colombier 	case 's':	sprintf(mtxt, "send"); break;
164*de2caf28SDavid du Colombier 	case 'r':	sprintf(mtxt, "recv"); break;
165*de2caf28SDavid du Colombier 	case 'R':	sprintf(mtxt, "recv poll"); break;
166*de2caf28SDavid du Colombier 	case '@':	sprintf(mtxt, "@"); break;
167*de2caf28SDavid du Colombier 	case '?':	sprintf(mtxt, "(x->y:z)"); break;
168*de2caf28SDavid du Colombier 	case NEXT:	sprintf(mtxt, "X"); break;
169*de2caf28SDavid du Colombier 	case ALWAYS:	sprintf(mtxt, "[]"); break;
170*de2caf28SDavid du Colombier 	case EVENTUALLY: sprintf(mtxt, "<>"); break;
171*de2caf28SDavid du Colombier 	case IMPLIES:	sprintf(mtxt, "->"); break;
172*de2caf28SDavid du Colombier 	case EQUIV:	sprintf(mtxt, "<->"); break;
173*de2caf28SDavid du Colombier 	case UNTIL:	sprintf(mtxt, "U"); break;
174*de2caf28SDavid du Colombier 	case WEAK_UNTIL: sprintf(mtxt, "W"); break;
175*de2caf28SDavid du Colombier 	case IN: sprintf(mtxt, "in"); break;
176*de2caf28SDavid du Colombier 	case ACTIVE:	sprintf(mtxt, "active"); break;
177*de2caf28SDavid du Colombier 	case AND:	sprintf(mtxt, "&&"); break;
178*de2caf28SDavid du Colombier 	case ARROW:	sprintf(mtxt, "->"); break;
179*de2caf28SDavid du Colombier 	case ASGN:	sprintf(mtxt, "="); break;
180*de2caf28SDavid du Colombier 	case ASSERT:	sprintf(mtxt, "assert"); break;
181*de2caf28SDavid du Colombier 	case ATOMIC:	sprintf(mtxt, "atomic"); break;
182*de2caf28SDavid du Colombier 	case BREAK:	sprintf(mtxt, "break"); break;
183*de2caf28SDavid du Colombier 	case C_CODE:	sprintf(mtxt, "c_code"); in_c_code++; break;
184*de2caf28SDavid du Colombier 	case C_DECL:	sprintf(mtxt, "c_decl"); in_c_decl++; break;
185*de2caf28SDavid du Colombier 	case C_EXPR:	sprintf(mtxt, "c_expr"); break;
186*de2caf28SDavid du Colombier 	case C_STATE:	sprintf(mtxt, "c_state"); break;
187*de2caf28SDavid du Colombier 	case C_TRACK:	sprintf(mtxt, "c_track"); break;
188*de2caf28SDavid du Colombier 	case CLAIM:	sprintf(mtxt, "never"); break;
189*de2caf28SDavid du Colombier 	case CONST:	sprintf(mtxt, "%d", yylval->val); break;
190*de2caf28SDavid du Colombier 	case DECR:	sprintf(mtxt, "--"); break;
191*de2caf28SDavid du Colombier 	case D_STEP:	sprintf(mtxt, "d_step"); break;
192*de2caf28SDavid du Colombier 	case D_PROCTYPE: sprintf(mtxt, "d_proctype"); break;
193*de2caf28SDavid du Colombier 	case DO:	sprintf(mtxt, "do"); break;
194*de2caf28SDavid du Colombier 	case DOT:	sprintf(mtxt, "."); break;
195*de2caf28SDavid du Colombier 	case ELSE:	sprintf(mtxt, "else"); break;
196*de2caf28SDavid du Colombier 	case EMPTY:	sprintf(mtxt, "empty"); break;
197*de2caf28SDavid du Colombier 	case ENABLED:	sprintf(mtxt, "enabled"); break;
198*de2caf28SDavid du Colombier 	case EQ:	sprintf(mtxt, "=="); break;
199*de2caf28SDavid du Colombier 	case EVAL:	sprintf(mtxt, "eval"); break;
200*de2caf28SDavid du Colombier 	case FI:	sprintf(mtxt, "fi"); break;
201*de2caf28SDavid du Colombier 	case FOR:	sprintf(mtxt, "for"); break;
202*de2caf28SDavid du Colombier 	case FULL:	sprintf(mtxt, "full"); break;
203*de2caf28SDavid du Colombier 	case GE:	sprintf(mtxt, ">="); break;
204*de2caf28SDavid du Colombier 	case GET_P:	sprintf(mtxt, "get_priority"); break;
205*de2caf28SDavid du Colombier 	case GOTO:	sprintf(mtxt, "goto"); break;
206*de2caf28SDavid du Colombier 	case GT:	sprintf(mtxt, ">"); break;
207*de2caf28SDavid du Colombier 	case HIDDEN:	sprintf(mtxt, "hidden"); break;
208*de2caf28SDavid du Colombier 	case IF:	sprintf(mtxt, "if"); break;
209*de2caf28SDavid du Colombier 	case INCR:	sprintf(mtxt, "++"); break;
210*de2caf28SDavid du Colombier 
211*de2caf28SDavid du Colombier 	case INLINE:	sprintf(mtxt, "inline"); break;
212*de2caf28SDavid du Colombier 	case INIT:	sprintf(mtxt, "init"); break;
213*de2caf28SDavid du Colombier 	case ISLOCAL:	sprintf(mtxt, "local"); break;
214*de2caf28SDavid du Colombier 
215*de2caf28SDavid du Colombier 	case LABEL:	sprintf(mtxt, "<label-name>"); break;
216*de2caf28SDavid du Colombier 
217*de2caf28SDavid du Colombier 	case LE:	sprintf(mtxt, "<="); break;
218*de2caf28SDavid du Colombier 	case LEN:	sprintf(mtxt, "len"); break;
219*de2caf28SDavid du Colombier 	case LSHIFT:	sprintf(mtxt, "<<"); break;
220*de2caf28SDavid du Colombier 	case LT:	sprintf(mtxt, "<"); break;
221*de2caf28SDavid du Colombier 	case LTL:	sprintf(mtxt, "ltl"); break;
222*de2caf28SDavid du Colombier 
223*de2caf28SDavid du Colombier 	case NAME:	sprintf(mtxt, "%s", yylval->sym->name); break;
224*de2caf28SDavid du Colombier 
225*de2caf28SDavid du Colombier 	case XU:	switch (yylval->val) {
226*de2caf28SDavid du Colombier 			case XR:	sprintf(mtxt, "xr"); break;
227*de2caf28SDavid du Colombier 			case XS:	sprintf(mtxt, "xs"); break;
228*de2caf28SDavid du Colombier 			default:	sprintf(mtxt, "<?>"); break;
229*de2caf28SDavid du Colombier 			}
230*de2caf28SDavid du Colombier 			break;
231*de2caf28SDavid du Colombier 
232*de2caf28SDavid du Colombier 	case TYPE:	switch (yylval->val) {
233*de2caf28SDavid du Colombier 			case BIT:	sprintf(mtxt, "bit"); break;
234*de2caf28SDavid du Colombier 			case BYTE:	sprintf(mtxt, "byte"); break;
235*de2caf28SDavid du Colombier 			case CHAN:	sprintf(mtxt, "chan"); in_decl++; break;
236*de2caf28SDavid du Colombier 			case INT:	sprintf(mtxt, "int"); break;
237*de2caf28SDavid du Colombier 			case MTYPE:	sprintf(mtxt, "mtype"); break;
238*de2caf28SDavid du Colombier 			case SHORT:	sprintf(mtxt, "short"); break;
239*de2caf28SDavid du Colombier 			case UNSIGNED:	sprintf(mtxt, "unsigned"); break;
240*de2caf28SDavid du Colombier 			default:	sprintf(mtxt, "<unknown type>"); break;
241*de2caf28SDavid du Colombier 			}
242*de2caf28SDavid du Colombier 			break;
243*de2caf28SDavid du Colombier 
244*de2caf28SDavid du Colombier 	case NE:	sprintf(mtxt, "!="); break;
245*de2caf28SDavid du Colombier 	case NEG:	sprintf(mtxt, "!"); break;
246*de2caf28SDavid du Colombier 	case NEMPTY:	sprintf(mtxt, "nempty"); break;
247*de2caf28SDavid du Colombier 	case NFULL:	sprintf(mtxt, "nfull"); break;
248*de2caf28SDavid du Colombier 
249*de2caf28SDavid du Colombier 	case NON_ATOMIC: sprintf(mtxt, "<sub-sequence>"); break;
250*de2caf28SDavid du Colombier 
251*de2caf28SDavid du Colombier 	case NONPROGRESS: sprintf(mtxt, "np_"); break;
252*de2caf28SDavid du Colombier 	case OD:	sprintf(mtxt, "od"); break;
253*de2caf28SDavid du Colombier 	case OF:	sprintf(mtxt, "of"); break;
254*de2caf28SDavid du Colombier 	case OR:	sprintf(mtxt, "||"); break;
255*de2caf28SDavid du Colombier 	case O_SND:	sprintf(mtxt, "!!"); break;
256*de2caf28SDavid du Colombier 	case PC_VAL:	sprintf(mtxt, "pc_value"); break;
257*de2caf28SDavid du Colombier 	case PRINT:	sprintf(mtxt, "printf"); break;
258*de2caf28SDavid du Colombier 	case PRINTM:	sprintf(mtxt, "printm"); break;
259*de2caf28SDavid du Colombier 	case PRIORITY:	sprintf(mtxt, "priority"); break;
260*de2caf28SDavid du Colombier 	case PROCTYPE:	sprintf(mtxt, "proctype"); break;
261*de2caf28SDavid du Colombier 	case PROVIDED:	sprintf(mtxt, "provided"); break;
262*de2caf28SDavid du Colombier 	case RETURN:	sprintf(mtxt, "return"); break;
263*de2caf28SDavid du Colombier 	case RCV:	sprintf(mtxt, "?"); break;
264*de2caf28SDavid du Colombier 	case R_RCV:	sprintf(mtxt, "??"); break;
265*de2caf28SDavid du Colombier 	case RSHIFT:	sprintf(mtxt, ">>"); break;
266*de2caf28SDavid du Colombier 	case RUN:	sprintf(mtxt, "run"); break;
267*de2caf28SDavid du Colombier 	case SEP:	sprintf(mtxt, "::"); break;
268*de2caf28SDavid du Colombier 	case SEMI:	sprintf(mtxt, ";"); break;
269*de2caf28SDavid du Colombier 	case SET_P:	sprintf(mtxt, "set_priority"); break;
270*de2caf28SDavid du Colombier 	case SHOW:	sprintf(mtxt, "show"); break;
271*de2caf28SDavid du Colombier 	case SND:	sprintf(mtxt, "!"); break;
272*de2caf28SDavid du Colombier 
273*de2caf28SDavid du Colombier 	case INAME:
274*de2caf28SDavid du Colombier 	case UNAME:
275*de2caf28SDavid du Colombier 	case PNAME:
276*de2caf28SDavid du Colombier 	case STRING:	sprintf(mtxt, "%s", yylval->sym->name); break;
277*de2caf28SDavid du Colombier 
278*de2caf28SDavid du Colombier 	case TRACE:	sprintf(mtxt, "trace"); break;
279*de2caf28SDavid du Colombier 	case TIMEOUT:	sprintf(mtxt, "(timeout)"); break;
280*de2caf28SDavid du Colombier 	case TYPEDEF:	sprintf(mtxt, "typedef"); break;
281*de2caf28SDavid du Colombier 	case UMIN:	sprintf(mtxt, "-"); break;
282*de2caf28SDavid du Colombier 	case UNLESS:	sprintf(mtxt, "unless"); break;
283*de2caf28SDavid du Colombier 	}
284*de2caf28SDavid du Colombier 	strcat(b, mtxt);
285*de2caf28SDavid du Colombier }
286*de2caf28SDavid du Colombier 
287*de2caf28SDavid du Colombier void
purge(char * b)288*de2caf28SDavid du Colombier purge(char *b)
289*de2caf28SDavid du Colombier {
290*de2caf28SDavid du Colombier 	if (strlen(b) == 0) return;
291*de2caf28SDavid du Colombier 
292*de2caf28SDavid du Colombier 	if (b[strlen(b)-1] != ':')	/* label? */
293*de2caf28SDavid du Colombier 	{	if (b[0] == ':' && b[1] == ':')
294*de2caf28SDavid du Colombier 		{	indent--;
295*de2caf28SDavid du Colombier 			doindent();
296*de2caf28SDavid du Colombier 			indent++;
297*de2caf28SDavid du Colombier 		} else
298*de2caf28SDavid du Colombier 		{	doindent();
299*de2caf28SDavid du Colombier 		}
300*de2caf28SDavid du Colombier 	}
301*de2caf28SDavid du Colombier 	printf("%s\n", b);
302*de2caf28SDavid du Colombier 	strcpy(b, "");
303*de2caf28SDavid du Colombier 
304*de2caf28SDavid du Colombier 	in_decl = 0;
305*de2caf28SDavid du Colombier 	in_c_code = 0;
306*de2caf28SDavid du Colombier 	in_c_decl = 0;
307*de2caf28SDavid du Colombier }
308*de2caf28SDavid du Colombier 
309*de2caf28SDavid du Colombier int pp_mode;
310*de2caf28SDavid du Colombier extern int lex(void);
311*de2caf28SDavid du Colombier 
312*de2caf28SDavid du Colombier void
pretty_print(void)313*de2caf28SDavid du Colombier pretty_print(void)
314*de2caf28SDavid du Colombier {	int c, lastc = 0;
315*de2caf28SDavid du Colombier 	char buf[1024];
316*de2caf28SDavid du Colombier 
317*de2caf28SDavid du Colombier 	pp_mode = 1;
318*de2caf28SDavid du Colombier 	indent = 0;
319*de2caf28SDavid du Colombier 	strcpy(buf, "");
320*de2caf28SDavid du Colombier 	while ((c = lex()) != EOF)
321*de2caf28SDavid du Colombier 	{
322*de2caf28SDavid du Colombier 		if ((lastc == IF || lastc == DO) && c != SEP)
323*de2caf28SDavid du Colombier 		{	indent--;	/* c_code if */
324*de2caf28SDavid du Colombier 		}
325*de2caf28SDavid du Colombier 		if (c == C_DECL  || c == C_STATE
326*de2caf28SDavid du Colombier 		||  c == C_TRACK || c == SEP
327*de2caf28SDavid du Colombier 		||  c == DO      || c == IF
328*de2caf28SDavid du Colombier 		|| (c == TYPE && !in_decl))
329*de2caf28SDavid du Colombier 		{	purge(buf); /* start on new line */
330*de2caf28SDavid du Colombier 		}
331*de2caf28SDavid du Colombier 
332*de2caf28SDavid du Colombier 		if (c == '{'
333*de2caf28SDavid du Colombier 		&& lastc != OF && lastc != IN
334*de2caf28SDavid du Colombier 		&& lastc != ATOMIC && lastc != D_STEP
335*de2caf28SDavid du Colombier 		&& lastc != C_CODE && lastc != C_DECL && lastc != C_EXPR)
336*de2caf28SDavid du Colombier 		{	purge(buf);
337*de2caf28SDavid du Colombier 		}
338*de2caf28SDavid du Colombier 
339*de2caf28SDavid du Colombier 		if (c == PREPROC)
340*de2caf28SDavid du Colombier 		{	int oi = indent;
341*de2caf28SDavid du Colombier 			purge(buf);
342*de2caf28SDavid du Colombier 			assert(strlen(yylval->sym->name) < sizeof(buf));
343*de2caf28SDavid du Colombier 			strcpy(buf, yylval->sym->name);
344*de2caf28SDavid du Colombier 			indent = 0;
345*de2caf28SDavid du Colombier 			purge(buf);
346*de2caf28SDavid du Colombier 			indent = oi;
347*de2caf28SDavid du Colombier 			continue;
348*de2caf28SDavid du Colombier 		}
349*de2caf28SDavid du Colombier 
350*de2caf28SDavid du Colombier 		if (c != ':' && c != SEMI
351*de2caf28SDavid du Colombier 		&&  c != ',' && c != '('
352*de2caf28SDavid du Colombier 		&&  c != '#' && lastc != '#'
353*de2caf28SDavid du Colombier 		&&  c != ARROW && lastc != ARROW
354*de2caf28SDavid du Colombier 		&&  c != '.' && lastc != '.'
355*de2caf28SDavid du Colombier 		&&  c != '!' && lastc != '!'
356*de2caf28SDavid du Colombier 		&&  c != SND && lastc != SND
357*de2caf28SDavid du Colombier 		&&  c != RCV && lastc != RCV
358*de2caf28SDavid du Colombier 		&&  c != O_SND && lastc != O_SND
359*de2caf28SDavid du Colombier 		&&  c != R_RCV && lastc != R_RCV
360*de2caf28SDavid du Colombier 		&&  (c != ']' || lastc != '[')
361*de2caf28SDavid du Colombier 		&&  (c != '>' || lastc != '<')
362*de2caf28SDavid du Colombier 		&&  (c != GT || lastc != LT)
363*de2caf28SDavid du Colombier 		&&  c != '@' && lastc != '@'
364*de2caf28SDavid du Colombier 		&& (lastc != '(' || c != ')')
365*de2caf28SDavid du Colombier 		&& (lastc != '/' || c != '/')
366*de2caf28SDavid du Colombier 		&&  c != DO && c != OD && c != IF && c != FI
367*de2caf28SDavid du Colombier 		&&  c != SEP && strlen(buf) > 0)
368*de2caf28SDavid du Colombier 			strcat(buf, " ");
369*de2caf28SDavid du Colombier 
370*de2caf28SDavid du Colombier 		if (c == '}' || c == OD || c == FI)
371*de2caf28SDavid du Colombier 		{	purge(buf);
372*de2caf28SDavid du Colombier 			indent--;
373*de2caf28SDavid du Colombier 		}
374*de2caf28SDavid du Colombier 		blip(c, buf);
375*de2caf28SDavid du Colombier 
376*de2caf28SDavid du Colombier 		if (c == '{' || c == DO || c == IF)
377*de2caf28SDavid du Colombier 		{	purge(buf);
378*de2caf28SDavid du Colombier 			indent++;
379*de2caf28SDavid du Colombier 		}
380*de2caf28SDavid du Colombier 
381*de2caf28SDavid du Colombier 		if (c == '}' || c == BREAK || c == SEMI || c == ELSE
382*de2caf28SDavid du Colombier 		|| (c == ':' && lastc == NAME))
383*de2caf28SDavid du Colombier 		{	purge(buf);
384*de2caf28SDavid du Colombier 		}
385*de2caf28SDavid du Colombier 		lastc = c;
386*de2caf28SDavid du Colombier 	}
387*de2caf28SDavid du Colombier 	purge(buf);
388312a1df1SDavid du Colombier }
389