xref: /plan9-contrib/sys/src/cmd/spin/pangen4.c (revision de2caf28f9ba1a56e70be94a699435d36eb50311)
1219b2ee8SDavid du Colombier /***** spin: pangen4.c *****/
2219b2ee8SDavid 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  */
8219b2ee8SDavid du Colombier 
9219b2ee8SDavid du Colombier #include "spin.h"
10219b2ee8SDavid du Colombier #include "y.tab.h"
11219b2ee8SDavid du Colombier 
12*de2caf28SDavid du Colombier extern FILE	*fd_tc, *fd_tb;
13219b2ee8SDavid du Colombier extern Queue	*qtab;
14219b2ee8SDavid du Colombier extern Symbol	*Fname;
15*de2caf28SDavid du Colombier extern int	lineno, m_loss, Pid_nr, eventmapnr, multi_oval;
16312a1df1SDavid du Colombier extern short	nocast, has_provided, has_sorted;
17*de2caf28SDavid du Colombier extern const char *R13_[], *R14_[], *R15_[];
18219b2ee8SDavid du Colombier 
197dd7cddfSDavid du Colombier static void	check_proc(Lextok *, int);
207dd7cddfSDavid du Colombier 
21219b2ee8SDavid du Colombier void
undostmnt(Lextok * now,int m)22219b2ee8SDavid du Colombier undostmnt(Lextok *now, int m)
23219b2ee8SDavid du Colombier {	Lextok *v;
247dd7cddfSDavid du Colombier 	int i, j;
25219b2ee8SDavid du Colombier 
26219b2ee8SDavid du Colombier 	if (!now)
27*de2caf28SDavid du Colombier 	{	fprintf(fd_tb, "0");
28219b2ee8SDavid du Colombier 		return;
29219b2ee8SDavid du Colombier 	}
30219b2ee8SDavid du Colombier 	lineno = now->ln;
31219b2ee8SDavid du Colombier 	Fname  = now->fn;
32219b2ee8SDavid du Colombier 	switch (now->ntyp) {
33219b2ee8SDavid du Colombier 	case CONST:	case '!':	case UMIN:
34219b2ee8SDavid du Colombier 	case '~':	case '/':	case '*':
35219b2ee8SDavid du Colombier 	case '-':	case '+':	case '%':
36219b2ee8SDavid du Colombier 	case LT:	case GT:	case '&':
37219b2ee8SDavid du Colombier 	case '|':	case LE:	case GE:
38219b2ee8SDavid du Colombier 	case NE:	case EQ:	case OR:
39219b2ee8SDavid du Colombier 	case AND:	case LSHIFT:	case RSHIFT:
40219b2ee8SDavid du Colombier 	case TIMEOUT:	case LEN:	case NAME:
41219b2ee8SDavid du Colombier 	case FULL:	case EMPTY:	case 'R':
42219b2ee8SDavid du Colombier 	case NFULL:	case NEMPTY:	case ENABLED:
437dd7cddfSDavid du Colombier 	case '?':	case PC_VAL:	case '^':
44*de2caf28SDavid du Colombier 	case C_EXPR:	case GET_P:
457dd7cddfSDavid du Colombier 	case NONPROGRESS:
46*de2caf28SDavid du Colombier 		putstmnt(fd_tb, now, m);
47219b2ee8SDavid du Colombier 		break;
487dd7cddfSDavid du Colombier 
497dd7cddfSDavid du Colombier 	case RUN:
50*de2caf28SDavid du Colombier 		fprintf(fd_tb, "delproc(0, now._nr_pr-1)");
51219b2ee8SDavid du Colombier 		break;
527dd7cddfSDavid du Colombier 
537dd7cddfSDavid du Colombier 	case 's':
54*de2caf28SDavid du Colombier 		if (Pid_nr == eventmapnr) break;
557dd7cddfSDavid du Colombier 
567dd7cddfSDavid du Colombier 		if (m_loss)
57*de2caf28SDavid du Colombier 			fprintf(fd_tb, "if (_m == 2) ");
58*de2caf28SDavid du Colombier 		putname(fd_tb, "_m = unsend(", now->lft, m, ")");
59219b2ee8SDavid du Colombier 		break;
607dd7cddfSDavid du Colombier 
617dd7cddfSDavid du Colombier 	case 'r':
62*de2caf28SDavid du Colombier 		if (Pid_nr == eventmapnr) break;
637dd7cddfSDavid du Colombier 
647dd7cddfSDavid du Colombier 		for (v = now->rgt, i=j=0; v; v = v->rgt, i++)
657dd7cddfSDavid du Colombier 			if (v->lft->ntyp != CONST
667dd7cddfSDavid du Colombier 			&&  v->lft->ntyp != EVAL)
67219b2ee8SDavid du Colombier 				j++;
687dd7cddfSDavid du Colombier 		if (j == 0 && now->val >= 2)
697dd7cddfSDavid du Colombier 			break;	/* poll without side-effect */
707dd7cddfSDavid du Colombier 
717dd7cddfSDavid du Colombier 		{	int ii = 0, jj;
727dd7cddfSDavid du Colombier 
737dd7cddfSDavid du Colombier 			for (v = now->rgt; v; v = v->rgt)
747dd7cddfSDavid du Colombier 				if ((v->lft->ntyp != CONST
757dd7cddfSDavid du Colombier 				&&   v->lft->ntyp != EVAL))
767dd7cddfSDavid du Colombier 					ii++;	/* nr of things bupped */
777dd7cddfSDavid du Colombier 			if (now->val == 1)
787dd7cddfSDavid du Colombier 			{	ii++;
797dd7cddfSDavid du Colombier 				jj = multi_oval - ii - 1;
80*de2caf28SDavid du Colombier 				fprintf(fd_tb, "XX = trpt->bup.oval");
817dd7cddfSDavid du Colombier 				if (multi_oval > 0)
82*de2caf28SDavid du Colombier 				{	fprintf(fd_tb, "s[%d]", jj);
837dd7cddfSDavid du Colombier 					jj++;
847dd7cddfSDavid du Colombier 				}
85*de2caf28SDavid du Colombier 				fprintf(fd_tb, ";\n\t\t");
86219b2ee8SDavid du Colombier 			} else
87*de2caf28SDavid du Colombier 			{	fprintf(fd_tb, "XX = 1;\n\t\t");
887dd7cddfSDavid du Colombier 				jj = multi_oval - ii - 1;
897dd7cddfSDavid du Colombier 			}
907dd7cddfSDavid du Colombier 
917dd7cddfSDavid du Colombier 			if (now->val < 2)	/* not for channel poll */
92219b2ee8SDavid du Colombier 			for (v = now->rgt, i = 0; v; v = v->rgt, i++)
937dd7cddfSDavid du Colombier 			{	switch(v->lft->ntyp) {
947dd7cddfSDavid du Colombier 				case CONST:
957dd7cddfSDavid du Colombier 				case EVAL:
96*de2caf28SDavid du Colombier 					fprintf(fd_tb, "unrecv");
97*de2caf28SDavid du Colombier 					putname(fd_tb, "(", now->lft, m, ", XX-1, ");
98*de2caf28SDavid du Colombier 					fprintf(fd_tb, "%d, ", i);
997dd7cddfSDavid du Colombier 					if (v->lft->ntyp == EVAL)
100*de2caf28SDavid du Colombier 					{	if (v->lft->lft->ntyp == ',')
101*de2caf28SDavid du Colombier 						{	undostmnt(v->lft->lft->lft, m);
102*de2caf28SDavid du Colombier 						} else
103*de2caf28SDavid du Colombier 						{	undostmnt(v->lft->lft, m);
104*de2caf28SDavid du Colombier 						}
105*de2caf28SDavid du Colombier 					} else
106*de2caf28SDavid du Colombier 					{	undostmnt(v->lft, m);
107*de2caf28SDavid du Colombier 					}
108*de2caf28SDavid du Colombier 					fprintf(fd_tb, ", %d);\n\t\t", (i==0)?1:0);
1097dd7cddfSDavid du Colombier 					break;
1107dd7cddfSDavid du Colombier 				default:
111*de2caf28SDavid du Colombier 					fprintf(fd_tb, "unrecv");
112*de2caf28SDavid du Colombier 					putname(fd_tb, "(", now->lft, m, ", XX-1, ");
113*de2caf28SDavid du Colombier 					fprintf(fd_tb, "%d, ", i);
1147dd7cddfSDavid du Colombier 					if (v->lft->sym
1157dd7cddfSDavid du Colombier 					&& !strcmp(v->lft->sym->name, "_"))
116*de2caf28SDavid du Colombier 					{	fprintf(fd_tb, "trpt->bup.oval");
1177dd7cddfSDavid du Colombier 						if (multi_oval > 0)
118*de2caf28SDavid du Colombier 							fprintf(fd_tb, "s[%d]", jj);
1197dd7cddfSDavid du Colombier 					} else
120*de2caf28SDavid du Colombier 						putstmnt(fd_tb, v->lft, m);
1217dd7cddfSDavid du Colombier 
122*de2caf28SDavid du Colombier 					fprintf(fd_tb, ", %d);\n\t\t", (i==0)?1:0);
1237dd7cddfSDavid du Colombier 					if (multi_oval > 0)
1247dd7cddfSDavid du Colombier 						jj++;
1257dd7cddfSDavid du Colombier 					break;
1267dd7cddfSDavid du Colombier 			}	}
1277dd7cddfSDavid du Colombier 			jj = multi_oval - ii - 1;
128312a1df1SDavid du Colombier 
129312a1df1SDavid du Colombier 			if (now->val == 1 && multi_oval > 0)
130312a1df1SDavid du Colombier 				jj++;	/* new 3.4.0 */
131312a1df1SDavid du Colombier 
1327dd7cddfSDavid du Colombier 			for (v = now->rgt, i = 0; v; v = v->rgt, i++)
1337dd7cddfSDavid du Colombier 			{	switch(v->lft->ntyp) {
1347dd7cddfSDavid du Colombier 				case CONST:
1357dd7cddfSDavid du Colombier 				case EVAL:
1367dd7cddfSDavid du Colombier 					break;
1377dd7cddfSDavid du Colombier 				default:
1387dd7cddfSDavid du Colombier 					if (!v->lft->sym
1397dd7cddfSDavid du Colombier 					||  strcmp(v->lft->sym->name, "_") != 0)
140*de2caf28SDavid du Colombier 					{	nocast=1; putstmnt(fd_tb, v->lft, m);
141*de2caf28SDavid du Colombier 						nocast=0; fprintf(fd_tb, " = trpt->bup.oval");
1427dd7cddfSDavid du Colombier 						if (multi_oval > 0)
143*de2caf28SDavid du Colombier 							fprintf(fd_tb, "s[%d]", jj);
144*de2caf28SDavid du Colombier 						fprintf(fd_tb, ";\n\t\t");
145219b2ee8SDavid du Colombier 					}
1467dd7cddfSDavid du Colombier 					if (multi_oval > 0)
1477dd7cddfSDavid du Colombier 						jj++;
1487dd7cddfSDavid du Colombier 					break;
1497dd7cddfSDavid du Colombier 			}	}
1507dd7cddfSDavid du Colombier 			multi_oval -= ii;
151219b2ee8SDavid du Colombier 		}
152219b2ee8SDavid du Colombier 		break;
1537dd7cddfSDavid du Colombier 
1547dd7cddfSDavid du Colombier 	case '@':
155*de2caf28SDavid du Colombier 		fprintf(fd_tb, "p_restor(II);\n\t\t");
156*de2caf28SDavid du Colombier 		break;
157*de2caf28SDavid du Colombier 
158*de2caf28SDavid du Colombier 	case SET_P:
159*de2caf28SDavid du Colombier 		fprintf(fd_tb, "((P0 *)pptr((trpt->o_priority >> 8)))");
160*de2caf28SDavid du Colombier 		fprintf(fd_tb, "->_priority = trpt->o_priority & 255");
161219b2ee8SDavid du Colombier 		break;
1627dd7cddfSDavid du Colombier 
1637dd7cddfSDavid du Colombier 	case ASGN:
164*de2caf28SDavid du Colombier 		if (check_track(now) == STRUCT) { break; }
165*de2caf28SDavid du Colombier 
166*de2caf28SDavid du Colombier 		nocast=1; putstmnt(fd_tb, now->lft, m);
167*de2caf28SDavid du Colombier 		nocast=0; fprintf(fd_tb, " = trpt->bup.oval");
1687dd7cddfSDavid du Colombier 		if (multi_oval > 0)
1697dd7cddfSDavid du Colombier 		{	multi_oval--;
170*de2caf28SDavid du Colombier 			fprintf(fd_tb, "s[%d]", multi_oval-1);
1717dd7cddfSDavid du Colombier 		}
172219b2ee8SDavid du Colombier 		check_proc(now->rgt, m);
173219b2ee8SDavid du Colombier 		break;
1747dd7cddfSDavid du Colombier 
1757dd7cddfSDavid du Colombier 	case 'c':
1767dd7cddfSDavid du Colombier 		check_proc(now->lft, m);
177219b2ee8SDavid du Colombier 		break;
1787dd7cddfSDavid du Colombier 
179219b2ee8SDavid du Colombier 	case '.':
180219b2ee8SDavid du Colombier 	case GOTO:
181219b2ee8SDavid du Colombier 	case ELSE:
1827dd7cddfSDavid du Colombier 	case BREAK:
183219b2ee8SDavid du Colombier 		break;
1847dd7cddfSDavid du Colombier 
185312a1df1SDavid du Colombier 	case C_CODE:
186*de2caf28SDavid du Colombier 		fprintf(fd_tb, "sv_restor();\n");
187312a1df1SDavid du Colombier 		break;
188312a1df1SDavid du Colombier 
1897dd7cddfSDavid du Colombier 	case ASSERT:
1907dd7cddfSDavid du Colombier 	case PRINT:
1917dd7cddfSDavid du Colombier 		check_proc(now, m);
1927dd7cddfSDavid du Colombier 		break;
193312a1df1SDavid du Colombier 	case PRINTM:
194312a1df1SDavid du Colombier 		break;
1957dd7cddfSDavid du Colombier 
196*de2caf28SDavid du Colombier 	case ',':
197*de2caf28SDavid du Colombier 		if (now->lft)	/* eval usertype5 */
198*de2caf28SDavid du Colombier 		{	undostmnt(now->lft, m);
199*de2caf28SDavid du Colombier 			break;
200*de2caf28SDavid du Colombier 		} /* else fall thru */
2017dd7cddfSDavid du Colombier 	default:
2027dd7cddfSDavid du Colombier 		printf("spin: bad node type %d (.b)\n", now->ntyp);
2037dd7cddfSDavid du Colombier 		alldone(1);
204219b2ee8SDavid du Colombier 	}
205219b2ee8SDavid du Colombier }
206219b2ee8SDavid du Colombier 
207219b2ee8SDavid du Colombier int
any_undo(Lextok * now)208219b2ee8SDavid du Colombier any_undo(Lextok *now)
209219b2ee8SDavid du Colombier {	/* is there anything to undo on a return move? */
210219b2ee8SDavid du Colombier 	if (!now) return 1;
211219b2ee8SDavid du Colombier 	switch (now->ntyp) {
212219b2ee8SDavid du Colombier 	case 'c':	return any_oper(now->lft, RUN);
213219b2ee8SDavid du Colombier 	case ASSERT:
214219b2ee8SDavid du Colombier 	case PRINT:	return any_oper(now, RUN);
215219b2ee8SDavid du Colombier 
216312a1df1SDavid du Colombier 	case PRINTM:
217219b2ee8SDavid du Colombier 	case   '.':
218219b2ee8SDavid du Colombier 	case  GOTO:
219219b2ee8SDavid du Colombier 	case  ELSE:
220219b2ee8SDavid du Colombier 	case BREAK:	return 0;
221219b2ee8SDavid du Colombier 	default:	return 1;
222219b2ee8SDavid du Colombier 	}
223219b2ee8SDavid du Colombier }
224219b2ee8SDavid du Colombier 
225219b2ee8SDavid du Colombier int
any_oper(Lextok * now,int oper)226219b2ee8SDavid du Colombier any_oper(Lextok *now, int oper)
227219b2ee8SDavid du Colombier {	/* check if an expression contains oper operator */
228219b2ee8SDavid du Colombier 	if (!now) return 0;
229219b2ee8SDavid du Colombier 	if (now->ntyp == oper)
230219b2ee8SDavid du Colombier 		return 1;
231219b2ee8SDavid du Colombier 	return (any_oper(now->lft, oper) || any_oper(now->rgt, oper));
232219b2ee8SDavid du Colombier }
233219b2ee8SDavid du Colombier 
2347dd7cddfSDavid du Colombier static void
check_proc(Lextok * now,int m)235219b2ee8SDavid du Colombier check_proc(Lextok *now, int m)
236219b2ee8SDavid du Colombier {
237219b2ee8SDavid du Colombier 	if (!now)
238219b2ee8SDavid du Colombier 		return;
239219b2ee8SDavid du Colombier 	if (now->ntyp == '@' || now->ntyp == RUN)
240*de2caf28SDavid du Colombier 	{	fprintf(fd_tb, ";\n\t\t");
241219b2ee8SDavid du Colombier 		undostmnt(now, m);
242219b2ee8SDavid du Colombier 	}
243219b2ee8SDavid du Colombier 	check_proc(now->lft, m);
244219b2ee8SDavid du Colombier 	check_proc(now->rgt, m);
245219b2ee8SDavid du Colombier }
246219b2ee8SDavid du Colombier 
247219b2ee8SDavid du Colombier void
genunio(void)248219b2ee8SDavid du Colombier genunio(void)
2497dd7cddfSDavid du Colombier {	char buf1[256];
2507dd7cddfSDavid du Colombier 	Queue *q; int i;
251219b2ee8SDavid du Colombier 
252*de2caf28SDavid du Colombier 	ntimes(fd_tc, 0, 1, R13_);
253219b2ee8SDavid du Colombier 	for (q = qtab; q; q = q->nxt)
254*de2caf28SDavid du Colombier 	{	fprintf(fd_tc, "\tcase %d:\n", q->qid);
255219b2ee8SDavid du Colombier 
256219b2ee8SDavid du Colombier 		if (has_sorted)
257219b2ee8SDavid du Colombier 		{	sprintf(buf1, "((Q%d *)z)->contents", q->qid);
258*de2caf28SDavid du Colombier 			fprintf(fd_tc, "#ifdef HAS_SORTED\n");
259*de2caf28SDavid du Colombier 			fprintf(fd_tc, "\t\tj = trpt->ipt;\n");	/* ipt was bup.oval */
260*de2caf28SDavid du Colombier 			fprintf(fd_tc, "#endif\n");
261*de2caf28SDavid du Colombier 			fprintf(fd_tc, "\t\tfor (k = j; k < ((Q%d *)z)->Qlen; k++)\n",
2627dd7cddfSDavid du Colombier 				q->qid);
263*de2caf28SDavid du Colombier 			fprintf(fd_tc, "\t\t{\n");
264219b2ee8SDavid du Colombier 			for (i = 0; i < q->nflds; i++)
265*de2caf28SDavid du Colombier 			fprintf(fd_tc, "\t\t\t%s[k].fld%d = %s[k+1].fld%d;\n",
266219b2ee8SDavid du Colombier 				buf1, i, buf1, i);
267*de2caf28SDavid du Colombier 			fprintf(fd_tc, "\t\t}\n");
268*de2caf28SDavid du Colombier 			fprintf(fd_tc, "\t\tj = ((Q0 *)z)->Qlen;\n");
269219b2ee8SDavid du Colombier 		}
270219b2ee8SDavid du Colombier 
271219b2ee8SDavid du Colombier 		sprintf(buf1, "((Q%d *)z)->contents[j].fld", q->qid);
272219b2ee8SDavid du Colombier 		for (i = 0; i < q->nflds; i++)
273*de2caf28SDavid du Colombier 			fprintf(fd_tc, "\t\t%s%d = 0;\n", buf1, i);
274219b2ee8SDavid du Colombier 		if (q->nslots==0)
275219b2ee8SDavid du Colombier 		{	/* check if rendezvous succeeded, 1 level down */
276*de2caf28SDavid du Colombier 			fprintf(fd_tc, "\t\t_m = (trpt+1)->o_m;\n");
277*de2caf28SDavid du Colombier 			fprintf(fd_tc, "\t\tif (_m) (trpt-1)->o_pm |= 1;\n");
278*de2caf28SDavid du Colombier 			fprintf(fd_tc, "\t\tUnBlock;\n");
279219b2ee8SDavid du Colombier 		} else
280*de2caf28SDavid du Colombier 			fprintf(fd_tc, "\t\t_m = trpt->o_m;\n");
2817dd7cddfSDavid du Colombier 
282*de2caf28SDavid du Colombier 		fprintf(fd_tc, "\t\tbreak;\n");
283219b2ee8SDavid du Colombier 	}
284*de2caf28SDavid du Colombier 	ntimes(fd_tc, 0, 1, R14_);
285219b2ee8SDavid du Colombier 	for (q = qtab; q; q = q->nxt)
286219b2ee8SDavid du Colombier 	{	sprintf(buf1, "((Q%d *)z)->contents", q->qid);
287*de2caf28SDavid du Colombier 		fprintf(fd_tc, "	case %d:\n", q->qid);
288219b2ee8SDavid du Colombier 		if (q->nslots == 0)
289*de2caf28SDavid du Colombier 			fprintf(fd_tc, "\t\tif (strt) boq = from+1;\n");
290219b2ee8SDavid du Colombier 		else if (q->nslots > 1)	/* shift */
291*de2caf28SDavid du Colombier 		{	fprintf(fd_tc, "\t\tif (strt && slot<%d)\n",
292219b2ee8SDavid du Colombier 							q->nslots-1);
293*de2caf28SDavid du Colombier 			fprintf(fd_tc, "\t\t{\tfor (j--; j>=slot; j--)\n");
294*de2caf28SDavid du Colombier 			fprintf(fd_tc, "\t\t\t{");
295219b2ee8SDavid du Colombier 			for (i = 0; i < q->nflds; i++)
296*de2caf28SDavid du Colombier 			{	fprintf(fd_tc, "\t%s[j+1].fld%d =\n\t\t\t",
297219b2ee8SDavid du Colombier 							buf1, i);
298*de2caf28SDavid du Colombier 				fprintf(fd_tc, "\t%s[j].fld%d;\n\t\t\t",
299219b2ee8SDavid du Colombier 							buf1, i);
300219b2ee8SDavid du Colombier 			}
301*de2caf28SDavid du Colombier 			fprintf(fd_tc, "}\n\t\t}\n");
302219b2ee8SDavid du Colombier 		}
303219b2ee8SDavid du Colombier 		strcat(buf1, "[slot].fld");
304*de2caf28SDavid du Colombier 		fprintf(fd_tc, "\t\tif (strt) {\n");
305219b2ee8SDavid du Colombier 		for (i = 0; i < q->nflds; i++)
306*de2caf28SDavid du Colombier 			fprintf(fd_tc, "\t\t\t%s%d = 0;\n", buf1, i);
307*de2caf28SDavid du Colombier 		fprintf(fd_tc, "\t\t}\n");
308219b2ee8SDavid du Colombier 		if (q->nflds == 1)	/* set */
309*de2caf28SDavid du Colombier 			fprintf(fd_tc, "\t\tif (fld == 0) %s0 = fldvar;\n",
310219b2ee8SDavid du Colombier 							buf1);
311219b2ee8SDavid du Colombier 		else
312*de2caf28SDavid du Colombier 		{	fprintf(fd_tc, "\t\tswitch (fld) {\n");
313219b2ee8SDavid du Colombier 			for (i = 0; i < q->nflds; i++)
314*de2caf28SDavid du Colombier 			{	fprintf(fd_tc, "\t\tcase %d:\t%s", i, buf1);
315*de2caf28SDavid du Colombier 				fprintf(fd_tc, "%d = fldvar; break;\n", i);
316219b2ee8SDavid du Colombier 			}
317*de2caf28SDavid du Colombier 			fprintf(fd_tc, "\t\t}\n");
318219b2ee8SDavid du Colombier 		}
319*de2caf28SDavid du Colombier 		fprintf(fd_tc, "\t\tbreak;\n");
320219b2ee8SDavid du Colombier 	}
321*de2caf28SDavid du Colombier 	ntimes(fd_tc, 0, 1, R15_);
322219b2ee8SDavid du Colombier }
3237dd7cddfSDavid du Colombier 
32400d97012SDavid du Colombier extern void explain(int);
32500d97012SDavid du Colombier 
3267dd7cddfSDavid du Colombier int
proper_enabler(Lextok * n)3277dd7cddfSDavid du Colombier proper_enabler(Lextok *n)
3287dd7cddfSDavid du Colombier {
3297dd7cddfSDavid du Colombier 	if (!n) return 1;
3307dd7cddfSDavid du Colombier 	switch (n->ntyp) {
3317dd7cddfSDavid du Colombier 	case NEMPTY:	case FULL:
3327dd7cddfSDavid du Colombier 	case NFULL:	case EMPTY:
3337dd7cddfSDavid du Colombier 	case LEN:	case 'R':
3347dd7cddfSDavid du Colombier 	case NAME:
3357dd7cddfSDavid du Colombier 		has_provided = 1;
336*de2caf28SDavid du Colombier 		if (strcmp(n->sym->name, "_pid") == 0
337*de2caf28SDavid du Colombier 		||  strcmp(n->sym->name, "_priority") == 0)
3387dd7cddfSDavid du Colombier 			return 1;
3397dd7cddfSDavid du Colombier 		return (!(n->sym->context));
3407dd7cddfSDavid du Colombier 
34100d97012SDavid du Colombier 	case C_EXPR:
34200d97012SDavid du Colombier 	case CONST:
34300d97012SDavid du Colombier 	case TIMEOUT:
3447dd7cddfSDavid du Colombier 		has_provided = 1;
3457dd7cddfSDavid du Colombier 		return 1;
3467dd7cddfSDavid du Colombier 
3477dd7cddfSDavid du Colombier 	case ENABLED:	case PC_VAL:
348*de2caf28SDavid du Colombier 	case GET_P:	/* not SET_P */
3497dd7cddfSDavid du Colombier 		return proper_enabler(n->lft);
3507dd7cddfSDavid du Colombier 
3517dd7cddfSDavid du Colombier 	case '!': case UMIN: case '~':
3527dd7cddfSDavid du Colombier 		return proper_enabler(n->lft);
3537dd7cddfSDavid du Colombier 
3547dd7cddfSDavid du Colombier 	case '/': case '*': case '-': case '+':
3557dd7cddfSDavid du Colombier 	case '%': case LT:  case GT: case '&': case '^':
3567dd7cddfSDavid du Colombier 	case '|': case LE:  case GE:  case NE: case '?':
3577dd7cddfSDavid du Colombier 	case EQ:  case OR:  case AND: case LSHIFT:
358*de2caf28SDavid du Colombier 	case RSHIFT: case 'c': /* case ',': */
3597dd7cddfSDavid du Colombier 		return proper_enabler(n->lft) && proper_enabler(n->rgt);
360*de2caf28SDavid du Colombier 
3617dd7cddfSDavid du Colombier 	default:
3627dd7cddfSDavid du Colombier 		break;
3637dd7cddfSDavid du Colombier 	}
36400d97012SDavid du Colombier 	printf("spin: saw ");
36500d97012SDavid du Colombier 	explain(n->ntyp);
36600d97012SDavid du Colombier 	printf("\n");
3677dd7cddfSDavid du Colombier 	return 0;
3687dd7cddfSDavid du Colombier }
369