xref: /plan9/sys/src/cmd/spin/spinlex.c (revision 00d970127b9d44d2b22f4f656717a212dec1f1d2)
1219b2ee8SDavid du Colombier /***** spin: spinlex.c *****/
2219b2ee8SDavid du Colombier 
3312a1df1SDavid du Colombier /* Copyright (c) 1989-2003 by Lucent Technologies, Bell Laboratories.     */
47dd7cddfSDavid du Colombier /* All Rights Reserved.  This software is for educational purposes only.  */
5312a1df1SDavid du Colombier /* No guarantee whatsoever is expressed or implied by the distribution of */
6312a1df1SDavid du Colombier /* this code.  Permission is given to distribute this code provided that  */
7312a1df1SDavid du Colombier /* this introductory message is not removed and no monies are exchanged.  */
8312a1df1SDavid du Colombier /* Software written by Gerard J. Holzmann.  For tool documentation see:   */
9312a1df1SDavid du Colombier /*             http://spinroot.com/                                       */
10312a1df1SDavid du Colombier /* Send all bug-reports and/or questions to: bugs@spinroot.com            */
11219b2ee8SDavid du Colombier 
127dd7cddfSDavid du Colombier #include <stdlib.h>
13219b2ee8SDavid du Colombier #include "spin.h"
14219b2ee8SDavid du Colombier #include "y.tab.h"
15219b2ee8SDavid du Colombier 
167dd7cddfSDavid du Colombier #define MAXINL	16	/* max recursion depth inline fcts */
177dd7cddfSDavid du Colombier #define MAXPAR	32	/* max params to an inline call */
187dd7cddfSDavid du Colombier #define MAXLEN	512	/* max len of an actual parameter text */
197dd7cddfSDavid du Colombier 
207dd7cddfSDavid du Colombier typedef struct IType {
217dd7cddfSDavid du Colombier 	Symbol *nm;		/* name of the type */
227dd7cddfSDavid du Colombier 	Lextok *cn;		/* contents */
237dd7cddfSDavid du Colombier 	Lextok *params;		/* formal pars if any */
247dd7cddfSDavid du Colombier 	char   **anms;		/* literal text for actual pars */
25312a1df1SDavid du Colombier 	char   *prec;		/* precondition for c_code or c_expr */
26*00d97012SDavid du Colombier 	int    uiid;		/* unique inline id */
277dd7cddfSDavid du Colombier 	int    dln, cln;	/* def and call linenr */
287dd7cddfSDavid du Colombier 	Symbol *dfn, *cfn;	/* def and call filename */
297dd7cddfSDavid du Colombier 	struct IType *nxt;	/* linked list */
307dd7cddfSDavid du Colombier } IType;
31219b2ee8SDavid du Colombier 
32312a1df1SDavid du Colombier typedef struct C_Added {
33312a1df1SDavid du Colombier 	Symbol *s;
34312a1df1SDavid du Colombier 	Symbol *t;
35312a1df1SDavid du Colombier 	Symbol *ival;
36312a1df1SDavid du Colombier 	struct C_Added *nxt;
37312a1df1SDavid du Colombier } C_Added;
38219b2ee8SDavid du Colombier 
39312a1df1SDavid du Colombier extern RunList	*X;
40312a1df1SDavid du Colombier extern ProcList	*rdy;
41*00d97012SDavid du Colombier extern Symbol	*Fname, *oFname;
42312a1df1SDavid du Colombier extern Symbol	*context, *owner;
43312a1df1SDavid du Colombier extern YYSTYPE	yylval;
44312a1df1SDavid du Colombier extern short	has_last, has_code;
45*00d97012SDavid du Colombier extern int	verbose, IArgs, hastrack, separate, ltl_mode;
46312a1df1SDavid du Colombier 
47312a1df1SDavid du Colombier short	has_stack = 0;
48312a1df1SDavid du Colombier int	lineno  = 1;
49*00d97012SDavid du Colombier int	scope_seq[128], scope_level = 0;
50*00d97012SDavid du Colombier char	CurScope[MAXSCOPESZ];
517dd7cddfSDavid du Colombier char	yytext[2048];
527dd7cddfSDavid du Colombier FILE	*yyin, *yyout;
53219b2ee8SDavid du Colombier 
54312a1df1SDavid du Colombier static C_Added	*c_added, *c_tracked;
55312a1df1SDavid du Colombier static IType	*Inline_stub[MAXINL];
567dd7cddfSDavid du Colombier static char	*ReDiRect;
57312a1df1SDavid du Colombier static char	*Inliner[MAXINL], IArg_cont[MAXPAR][MAXLEN];
58312a1df1SDavid du Colombier static unsigned char	in_comment=0;
59312a1df1SDavid du Colombier static int	IArgno = 0, Inlining = -1;
607dd7cddfSDavid du Colombier static int	check_name(char *);
617dd7cddfSDavid du Colombier 
627dd7cddfSDavid du Colombier #if 1
637dd7cddfSDavid du Colombier #define Token(y)	{ if (in_comment) goto again; \
647dd7cddfSDavid du Colombier 			yylval = nn(ZN,0,ZN,ZN); return y; }
657dd7cddfSDavid du Colombier 
667dd7cddfSDavid du Colombier #define ValToken(x, y)	{ if (in_comment) goto again; \
677dd7cddfSDavid du Colombier 			yylval = nn(ZN,0,ZN,ZN); yylval->val = x; return y; }
687dd7cddfSDavid du Colombier 
697dd7cddfSDavid du Colombier #define SymToken(x, y)	{ if (in_comment) goto again; \
707dd7cddfSDavid du Colombier 			yylval = nn(ZN,0,ZN,ZN); yylval->sym = x; return y; }
717dd7cddfSDavid du Colombier #else
72219b2ee8SDavid du Colombier #define Token(y)	{ yylval = nn(ZN,0,ZN,ZN); \
73219b2ee8SDavid du Colombier 			if (!in_comment) return y; else goto again; }
74219b2ee8SDavid du Colombier 
75219b2ee8SDavid du Colombier #define ValToken(x, y)	{ yylval = nn(ZN,0,ZN,ZN); yylval->val = x; \
76219b2ee8SDavid du Colombier 			if (!in_comment) return y; else goto again; }
77219b2ee8SDavid du Colombier 
78219b2ee8SDavid du Colombier #define SymToken(x, y)	{ yylval = nn(ZN,0,ZN,ZN); yylval->sym = x; \
79219b2ee8SDavid du Colombier 			if (!in_comment) return y; else goto again; }
807dd7cddfSDavid du Colombier #endif
81219b2ee8SDavid du Colombier 
82312a1df1SDavid du Colombier static int	getinline(void);
83312a1df1SDavid du Colombier static void	uninline(void);
84312a1df1SDavid du Colombier 
85312a1df1SDavid du Colombier #if 1
867dd7cddfSDavid du Colombier #define Getchar()	((Inlining<0)?getc(yyin):getinline())
877dd7cddfSDavid du Colombier #define Ungetch(c)	{if (Inlining<0) ungetc(c,yyin); else uninline();}
88219b2ee8SDavid du Colombier 
89312a1df1SDavid du Colombier #else
90312a1df1SDavid du Colombier 
91312a1df1SDavid du Colombier static int
Getchar(void)92312a1df1SDavid du Colombier Getchar(void)
93312a1df1SDavid du Colombier {	int c;
94*00d97012SDavid du Colombier 
95312a1df1SDavid du Colombier 	if (Inlining<0)
96312a1df1SDavid du Colombier 		c = getc(yyin);
97312a1df1SDavid du Colombier 	else
98312a1df1SDavid du Colombier 		c = getinline();
99*00d97012SDavid du Colombier 	if (0)
100*00d97012SDavid du Colombier 	{	printf("<%c:%d>[%d] ", c, c, Inlining);
101*00d97012SDavid du Colombier 	} else
102*00d97012SDavid du Colombier 	{	printf("%c", c);
103*00d97012SDavid du Colombier 	}
104312a1df1SDavid du Colombier 	return c;
105312a1df1SDavid du Colombier }
106312a1df1SDavid du Colombier 
107312a1df1SDavid du Colombier static void
Ungetch(int c)108312a1df1SDavid du Colombier Ungetch(int c)
109312a1df1SDavid du Colombier {
110312a1df1SDavid du Colombier 	if (Inlining<0)
111312a1df1SDavid du Colombier 		ungetc(c,yyin);
112312a1df1SDavid du Colombier 	else
113312a1df1SDavid du Colombier 		uninline();
114*00d97012SDavid du Colombier 	if (0)
115*00d97012SDavid du Colombier 	{	printf("<bs>");
116*00d97012SDavid du Colombier 	}
117312a1df1SDavid du Colombier }
118312a1df1SDavid du Colombier #endif
1197dd7cddfSDavid du Colombier 
1207dd7cddfSDavid du Colombier static int
notdollar(int c)121*00d97012SDavid du Colombier notdollar(int c)
122*00d97012SDavid du Colombier {	return (c != '$' && c != '\n');
123*00d97012SDavid du Colombier }
124*00d97012SDavid du Colombier 
125*00d97012SDavid du Colombier static int
notquote(int c)126219b2ee8SDavid du Colombier notquote(int c)
127219b2ee8SDavid du Colombier {	return (c != '\"' && c != '\n');
128219b2ee8SDavid du Colombier }
129219b2ee8SDavid du Colombier 
130219b2ee8SDavid du Colombier int
isalnum_(int c)131219b2ee8SDavid du Colombier isalnum_(int c)
132219b2ee8SDavid du Colombier {	return (isalnum(c) || c == '_');
133219b2ee8SDavid du Colombier }
134219b2ee8SDavid du Colombier 
1357dd7cddfSDavid du Colombier static int
isalpha_(int c)1367dd7cddfSDavid du Colombier isalpha_(int c)
1377dd7cddfSDavid du Colombier {	return isalpha(c);	/* could be macro */
1387dd7cddfSDavid du Colombier }
1397dd7cddfSDavid du Colombier 
1407dd7cddfSDavid du Colombier static int
isdigit_(int c)1417dd7cddfSDavid du Colombier isdigit_(int c)
1427dd7cddfSDavid du Colombier {	return isdigit(c);	/* could be macro */
1437dd7cddfSDavid du Colombier }
1447dd7cddfSDavid du Colombier 
1457dd7cddfSDavid du Colombier static void
getword(int first,int (* tst)(int))146219b2ee8SDavid du Colombier getword(int first, int (*tst)(int))
147*00d97012SDavid du Colombier {	int i=0, c;
148219b2ee8SDavid du Colombier 
1497dd7cddfSDavid du Colombier 	yytext[i++]= (char) first;
150219b2ee8SDavid du Colombier 	while (tst(c = Getchar()))
151*00d97012SDavid du Colombier 	{	yytext[i++] = (char) c;
152312a1df1SDavid du Colombier 		if (c == '\\')
153*00d97012SDavid du Colombier 		{	c = Getchar();
154*00d97012SDavid du Colombier 			yytext[i++] = (char) c;	/* no tst */
155*00d97012SDavid du Colombier 	}	}
156219b2ee8SDavid du Colombier 	yytext[i] = '\0';
157219b2ee8SDavid du Colombier 	Ungetch(c);
158219b2ee8SDavid du Colombier }
159219b2ee8SDavid du Colombier 
1607dd7cddfSDavid du Colombier static int
follow(int tok,int ifyes,int ifno)161219b2ee8SDavid du Colombier follow(int tok, int ifyes, int ifno)
162219b2ee8SDavid du Colombier {	int c;
163219b2ee8SDavid du Colombier 
164219b2ee8SDavid du Colombier 	if ((c = Getchar()) == tok)
165219b2ee8SDavid du Colombier 		return ifyes;
166219b2ee8SDavid du Colombier 	Ungetch(c);
167219b2ee8SDavid du Colombier 
168219b2ee8SDavid du Colombier 	return ifno;
169219b2ee8SDavid du Colombier }
170219b2ee8SDavid du Colombier 
1717dd7cddfSDavid du Colombier static IType *seqnames;
1727dd7cddfSDavid du Colombier 
1737dd7cddfSDavid du Colombier static void
def_inline(Symbol * s,int ln,char * ptr,char * prc,Lextok * nms)174312a1df1SDavid du Colombier def_inline(Symbol *s, int ln, char *ptr, char *prc, Lextok *nms)
1757dd7cddfSDavid du Colombier {	IType *tmp;
176*00d97012SDavid du Colombier 	int  cnt = 0;
177*00d97012SDavid du Colombier 	char *nw = (char *) emalloc(strlen(ptr)+1);
1787dd7cddfSDavid du Colombier 	strcpy(nw, ptr);
1797dd7cddfSDavid du Colombier 
180*00d97012SDavid du Colombier 	for (tmp = seqnames; tmp; cnt++, tmp = tmp->nxt)
1817dd7cddfSDavid du Colombier 		if (!strcmp(s->name, tmp->nm->name))
1827dd7cddfSDavid du Colombier 		{	non_fatal("procedure name %s redefined",
1837dd7cddfSDavid du Colombier 				tmp->nm->name);
1847dd7cddfSDavid du Colombier 			tmp->cn = (Lextok *) nw;
1857dd7cddfSDavid du Colombier 			tmp->params = nms;
1867dd7cddfSDavid du Colombier 			tmp->dln = ln;
1877dd7cddfSDavid du Colombier 			tmp->dfn = Fname;
1887dd7cddfSDavid du Colombier 			return;
1897dd7cddfSDavid du Colombier 		}
1907dd7cddfSDavid du Colombier 	tmp = (IType *) emalloc(sizeof(IType));
1917dd7cddfSDavid du Colombier 	tmp->nm = s;
1927dd7cddfSDavid du Colombier 	tmp->cn = (Lextok *) nw;
1937dd7cddfSDavid du Colombier 	tmp->params = nms;
194312a1df1SDavid du Colombier 	if (strlen(prc) > 0)
195*00d97012SDavid du Colombier 	{	tmp->prec = (char *) emalloc(strlen(prc)+1);
196312a1df1SDavid du Colombier 		strcpy(tmp->prec, prc);
197312a1df1SDavid du Colombier 	}
1987dd7cddfSDavid du Colombier 	tmp->dln = ln;
1997dd7cddfSDavid du Colombier 	tmp->dfn = Fname;
200*00d97012SDavid du Colombier 	tmp->uiid = cnt+1;	/* so that 0 means: not an inline */
2017dd7cddfSDavid du Colombier 	tmp->nxt = seqnames;
2027dd7cddfSDavid du Colombier 	seqnames = tmp;
2037dd7cddfSDavid du Colombier }
2047dd7cddfSDavid du Colombier 
205312a1df1SDavid du Colombier void
gencodetable(FILE * fd)206312a1df1SDavid du Colombier gencodetable(FILE *fd)
207312a1df1SDavid du Colombier {	IType *tmp;
208312a1df1SDavid du Colombier 	char *q;
209312a1df1SDavid du Colombier 	int cnt;
210312a1df1SDavid du Colombier 
211312a1df1SDavid du Colombier 	if (separate == 2) return;
212312a1df1SDavid du Colombier 
213312a1df1SDavid du Colombier 	fprintf(fd, "struct {\n");
214312a1df1SDavid du Colombier 	fprintf(fd, "	char *c; char *t;\n");
215312a1df1SDavid du Colombier 	fprintf(fd, "} code_lookup[] = {\n");
216312a1df1SDavid du Colombier 
217312a1df1SDavid du Colombier 	if (has_code)
218312a1df1SDavid du Colombier 	for (tmp = seqnames; tmp; tmp = tmp->nxt)
219312a1df1SDavid du Colombier 		if (tmp->nm->type == CODE_FRAG
220312a1df1SDavid du Colombier 		||  tmp->nm->type == CODE_DECL)
221312a1df1SDavid du Colombier 		{	fprintf(fd, "\t{ \"%s\", ",
222312a1df1SDavid du Colombier 				tmp->nm->name);
223312a1df1SDavid du Colombier 			q = (char *) tmp->cn;
224312a1df1SDavid du Colombier 
225312a1df1SDavid du Colombier 			while (*q == '\n' || *q == '\r' || *q == '\\')
226312a1df1SDavid du Colombier 				q++;
227312a1df1SDavid du Colombier 
228312a1df1SDavid du Colombier 			fprintf(fd, "\"");
229312a1df1SDavid du Colombier 			cnt = 0;
230312a1df1SDavid du Colombier 			while (*q && cnt < 1024) /* pangen1.h allows 2048 */
231312a1df1SDavid du Colombier 			{	switch (*q) {
232312a1df1SDavid du Colombier 				case '"':
233312a1df1SDavid du Colombier 					fprintf(fd, "\\\"");
234312a1df1SDavid du Colombier 					break;
235312a1df1SDavid du Colombier 				case '%':
236312a1df1SDavid du Colombier 					fprintf(fd, "%%");
237312a1df1SDavid du Colombier 					break;
238312a1df1SDavid du Colombier 				case '\n':
239312a1df1SDavid du Colombier 					fprintf(fd, "\\n");
240312a1df1SDavid du Colombier 					break;
241312a1df1SDavid du Colombier 				default:
242312a1df1SDavid du Colombier 					putc(*q, fd);
243312a1df1SDavid du Colombier 					break;
244312a1df1SDavid du Colombier 				}
245312a1df1SDavid du Colombier 				q++; cnt++;
246312a1df1SDavid du Colombier 			}
247312a1df1SDavid du Colombier 			if (*q) fprintf(fd, "...");
248312a1df1SDavid du Colombier 			fprintf(fd, "\"");
249312a1df1SDavid du Colombier 			fprintf(fd, " },\n");
250312a1df1SDavid du Colombier 		}
251312a1df1SDavid du Colombier 
252312a1df1SDavid du Colombier 	fprintf(fd, "	{ (char *) 0, \"\" }\n");
253312a1df1SDavid du Colombier 	fprintf(fd, "};\n");
254312a1df1SDavid du Colombier }
255312a1df1SDavid du Colombier 
2567dd7cddfSDavid du Colombier static int
iseqname(char * t)2577dd7cddfSDavid du Colombier iseqname(char *t)
2587dd7cddfSDavid du Colombier {	IType *tmp;
2597dd7cddfSDavid du Colombier 
2607dd7cddfSDavid du Colombier 	for (tmp = seqnames; tmp; tmp = tmp->nxt)
2617dd7cddfSDavid du Colombier 	{	if (!strcmp(t, tmp->nm->name))
2627dd7cddfSDavid du Colombier 			return 1;
2637dd7cddfSDavid du Colombier 	}
2647dd7cddfSDavid du Colombier 	return 0;
2657dd7cddfSDavid du Colombier }
2667dd7cddfSDavid du Colombier 
2677dd7cddfSDavid du Colombier static int
getinline(void)2687dd7cddfSDavid du Colombier getinline(void)
2697dd7cddfSDavid du Colombier {	int c;
2707dd7cddfSDavid du Colombier 
2717dd7cddfSDavid du Colombier 	if (ReDiRect)
2727dd7cddfSDavid du Colombier 	{	c = *ReDiRect++;
2737dd7cddfSDavid du Colombier 		if (c == '\0')
2747dd7cddfSDavid du Colombier 		{	ReDiRect = (char *) 0;
2757dd7cddfSDavid du Colombier 			c = *Inliner[Inlining]++;
2767dd7cddfSDavid du Colombier 		}
2777dd7cddfSDavid du Colombier 	} else
2787dd7cddfSDavid du Colombier 		c = *Inliner[Inlining]++;
2797dd7cddfSDavid du Colombier 
2807dd7cddfSDavid du Colombier 	if (c == '\0')
2817dd7cddfSDavid du Colombier 	{	lineno = Inline_stub[Inlining]->cln;
2827dd7cddfSDavid du Colombier 		Fname  = Inline_stub[Inlining]->cfn;
2837dd7cddfSDavid du Colombier 		Inlining--;
2847dd7cddfSDavid du Colombier #if 0
2857dd7cddfSDavid du Colombier 		if (verbose&32)
286*00d97012SDavid du Colombier 		printf("spin: %s:%d, done inlining %s\n",
287*00d97012SDavid du Colombier 			Fname, lineno, Inline_stub[Inlining+1]->nm->name);
2887dd7cddfSDavid du Colombier #endif
2897dd7cddfSDavid du Colombier 		return Getchar();
2907dd7cddfSDavid du Colombier 	}
2917dd7cddfSDavid du Colombier 	return c;
2927dd7cddfSDavid du Colombier }
2937dd7cddfSDavid du Colombier 
2947dd7cddfSDavid du Colombier static void
uninline(void)2957dd7cddfSDavid du Colombier uninline(void)
2967dd7cddfSDavid du Colombier {
2977dd7cddfSDavid du Colombier 	if (ReDiRect)
2987dd7cddfSDavid du Colombier 		ReDiRect--;
2997dd7cddfSDavid du Colombier 	else
3007dd7cddfSDavid du Colombier 		Inliner[Inlining]--;
3017dd7cddfSDavid du Colombier }
3027dd7cddfSDavid du Colombier 
303*00d97012SDavid du Colombier int
is_inline(void)304*00d97012SDavid du Colombier is_inline(void)
305*00d97012SDavid du Colombier {
306*00d97012SDavid du Colombier 	if (Inlining < 0)
307*00d97012SDavid du Colombier 		return 0;	/* i.e., not an inline */
308*00d97012SDavid du Colombier 	if (Inline_stub[Inlining] == NULL)
309*00d97012SDavid du Colombier 		fatal("unexpected, inline_stub not set", 0);
310*00d97012SDavid du Colombier 	return Inline_stub[Inlining]->uiid;
311*00d97012SDavid du Colombier }
312*00d97012SDavid du Colombier 
313312a1df1SDavid du Colombier IType *
find_inline(char * s)314312a1df1SDavid du Colombier find_inline(char *s)
315312a1df1SDavid du Colombier {	IType *tmp;
316312a1df1SDavid du Colombier 
317312a1df1SDavid du Colombier 	for (tmp = seqnames; tmp; tmp = tmp->nxt)
318312a1df1SDavid du Colombier 		if (!strcmp(s, tmp->nm->name))
319312a1df1SDavid du Colombier 			break;
320312a1df1SDavid du Colombier 	if (!tmp)
321312a1df1SDavid du Colombier 		fatal("cannot happen, missing inline def %s", s);
322*00d97012SDavid du Colombier 
323312a1df1SDavid du Colombier 	return tmp;
324312a1df1SDavid du Colombier }
325312a1df1SDavid du Colombier 
326312a1df1SDavid du Colombier void
c_state(Symbol * s,Symbol * t,Symbol * ival)327312a1df1SDavid du Colombier c_state(Symbol *s, Symbol *t, Symbol *ival)	/* name, scope, ival */
328312a1df1SDavid du Colombier {	C_Added *r;
329312a1df1SDavid du Colombier 
330312a1df1SDavid du Colombier 	r = (C_Added *) emalloc(sizeof(C_Added));
331312a1df1SDavid du Colombier 	r->s = s;	/* pointer to a data object */
332312a1df1SDavid du Colombier 	r->t = t;	/* size of object, or "global", or "local proctype_name"  */
333312a1df1SDavid du Colombier 	r->ival = ival;
334312a1df1SDavid du Colombier 	r->nxt = c_added;
335312a1df1SDavid du Colombier 	c_added = r;
336312a1df1SDavid du Colombier }
337312a1df1SDavid du Colombier 
338312a1df1SDavid du Colombier void
c_track(Symbol * s,Symbol * t,Symbol * stackonly)339312a1df1SDavid du Colombier c_track(Symbol *s, Symbol *t, Symbol *stackonly)	/* name, size */
340312a1df1SDavid du Colombier {	C_Added *r;
341312a1df1SDavid du Colombier 
342312a1df1SDavid du Colombier 	r = (C_Added *) emalloc(sizeof(C_Added));
343312a1df1SDavid du Colombier 	r->s = s;
344312a1df1SDavid du Colombier 	r->t = t;
345312a1df1SDavid du Colombier 	r->ival = stackonly;	/* abuse of name */
346312a1df1SDavid du Colombier 	r->nxt = c_tracked;
347312a1df1SDavid du Colombier 	c_tracked = r;
348312a1df1SDavid du Colombier 
349312a1df1SDavid du Colombier 	if (stackonly != ZS)
350312a1df1SDavid du Colombier 	{	if (strcmp(stackonly->name, "\"Matched\"") == 0)
351312a1df1SDavid du Colombier 			r->ival = ZS;	/* the default */
352312a1df1SDavid du Colombier 		else if (strcmp(stackonly->name, "\"UnMatched\"") != 0
353312a1df1SDavid du Colombier 		     &&  strcmp(stackonly->name, "\"unMatched\"") != 0
354312a1df1SDavid du Colombier 		     &&  strcmp(stackonly->name, "\"StackOnly\"") != 0)
355312a1df1SDavid du Colombier 			non_fatal("expecting '[Un]Matched', saw %s", stackonly->name);
356312a1df1SDavid du Colombier 		else
357*00d97012SDavid du Colombier 			has_stack = 1;	/* unmatched stack */
358312a1df1SDavid du Colombier 	}
359312a1df1SDavid du Colombier }
360312a1df1SDavid du Colombier 
361312a1df1SDavid du Colombier char *
jump_etc(char * op)362312a1df1SDavid du Colombier jump_etc(char *op)
363312a1df1SDavid du Colombier {	char *p = op;
364312a1df1SDavid du Colombier 
365312a1df1SDavid du Colombier 	/* kludgy - try to get the type separated from the name */
366312a1df1SDavid du Colombier 
367312a1df1SDavid du Colombier 	while (*p == ' ' || *p == '\t')
368312a1df1SDavid du Colombier 		p++;	/* initial white space */
369312a1df1SDavid du Colombier 	while (*p != ' ' && *p != '\t')
370312a1df1SDavid du Colombier 		p++;	/* type name */
371312a1df1SDavid du Colombier 	while (*p == ' ' || *p == '\t')
372312a1df1SDavid du Colombier 		p++;	/* white space */
373312a1df1SDavid du Colombier 	while (*p == '*')
374312a1df1SDavid du Colombier 		p++;	/* decorations */
375312a1df1SDavid du Colombier 	while (*p == ' ' || *p == '\t')
376312a1df1SDavid du Colombier 		p++;	/* white space */
377312a1df1SDavid du Colombier 
378312a1df1SDavid du Colombier 	if (*p == '\0')
379312a1df1SDavid du Colombier 		fatal("c_state format (%s)", op);
380312a1df1SDavid du Colombier 
381312a1df1SDavid du Colombier 	if (strchr(p, '[')
382312a1df1SDavid du Colombier 	&&  !strchr(p, '{'))
383312a1df1SDavid du Colombier 	{	non_fatal("array initialization error, c_state (%s)", p);
384312a1df1SDavid du Colombier 		return (char *) 0;
385312a1df1SDavid du Colombier 	}
386312a1df1SDavid du Colombier 
387312a1df1SDavid du Colombier 	return p;
388312a1df1SDavid du Colombier }
389312a1df1SDavid du Colombier 
390312a1df1SDavid du Colombier void
c_add_globinit(FILE * fd)391312a1df1SDavid du Colombier c_add_globinit(FILE *fd)
392312a1df1SDavid du Colombier {	C_Added *r;
393312a1df1SDavid du Colombier 	char *p, *q;
394312a1df1SDavid du Colombier 
395312a1df1SDavid du Colombier 	fprintf(fd, "void\nglobinit(void)\n{\n");
396312a1df1SDavid du Colombier 	for (r = c_added; r; r = r->nxt)
397312a1df1SDavid du Colombier 	{	if (r->ival == ZS)
398312a1df1SDavid du Colombier 			continue;
399312a1df1SDavid du Colombier 
400312a1df1SDavid du Colombier 		if (strncmp(r->t->name, " Global ", strlen(" Global ")) == 0)
401312a1df1SDavid du Colombier 		{	for (q = r->ival->name; *q; q++)
402312a1df1SDavid du Colombier 			{	if (*q == '\"')
403312a1df1SDavid du Colombier 					*q = ' ';
404312a1df1SDavid du Colombier 				if (*q == '\\')
405312a1df1SDavid du Colombier 					*q++ = ' '; /* skip over the next */
406312a1df1SDavid du Colombier 			}
407312a1df1SDavid du Colombier 			p = jump_etc(r->s->name);	/* e.g., "int **q" */
408312a1df1SDavid du Colombier 			if (p)
409312a1df1SDavid du Colombier 			fprintf(fd, "	now.%s = %s;\n", p, r->ival->name);
410312a1df1SDavid du Colombier 
411312a1df1SDavid du Colombier 		} else
412312a1df1SDavid du Colombier 		if (strncmp(r->t->name, " Hidden ", strlen(" Hidden ")) == 0)
413312a1df1SDavid du Colombier 		{	for (q = r->ival->name; *q; q++)
414312a1df1SDavid du Colombier 			{	if (*q == '\"')
415312a1df1SDavid du Colombier 					*q = ' ';
416312a1df1SDavid du Colombier 				if (*q == '\\')
417312a1df1SDavid du Colombier 					*q++ = ' '; /* skip over the next */
418312a1df1SDavid du Colombier 			}
419312a1df1SDavid du Colombier 			p = jump_etc(r->s->name);	/* e.g., "int **q" */
420312a1df1SDavid du Colombier 			if (p)
421312a1df1SDavid du Colombier 			fprintf(fd, "	%s = %s;\n", p, r->ival->name);	/* no now. prefix */
422312a1df1SDavid du Colombier 
423312a1df1SDavid du Colombier 	}	}
424312a1df1SDavid du Colombier 	fprintf(fd, "}\n");
425312a1df1SDavid du Colombier }
426312a1df1SDavid du Colombier 
427312a1df1SDavid du Colombier void
c_add_locinit(FILE * fd,int tpnr,char * pnm)428312a1df1SDavid du Colombier c_add_locinit(FILE *fd, int tpnr, char *pnm)
429312a1df1SDavid du Colombier {	C_Added *r;
430312a1df1SDavid du Colombier 	char *p, *q, *s;
431312a1df1SDavid du Colombier 	int frst = 1;
432312a1df1SDavid du Colombier 
433312a1df1SDavid du Colombier 	fprintf(fd, "void\nlocinit%d(int h)\n{\n", tpnr);
434312a1df1SDavid du Colombier 	for (r = c_added; r; r = r->nxt)
435312a1df1SDavid du Colombier 		if (r->ival != ZS
436312a1df1SDavid du Colombier 		&&  strncmp(r->t->name, " Local", strlen(" Local")) == 0)
437312a1df1SDavid du Colombier 		{	for (q = r->ival->name; *q; q++)
438312a1df1SDavid du Colombier 				if (*q == '\"')
439312a1df1SDavid du Colombier 					*q = ' ';
440312a1df1SDavid du Colombier 
441312a1df1SDavid du Colombier 			p = jump_etc(r->s->name);	/* e.g., "int **q" */
442312a1df1SDavid du Colombier 
443312a1df1SDavid du Colombier 			q = r->t->name + strlen(" Local");
444312a1df1SDavid du Colombier 			while (*q == ' ' || *q == '\t')
445312a1df1SDavid du Colombier 				q++;			/* process name */
446312a1df1SDavid du Colombier 
447312a1df1SDavid du Colombier 			s = (char *) emalloc(strlen(q)+1);
448312a1df1SDavid du Colombier 			strcpy(s, q);
449312a1df1SDavid du Colombier 
450312a1df1SDavid du Colombier 			q = &s[strlen(s)-1];
451312a1df1SDavid du Colombier 			while (*q == ' ' || *q == '\t')
452312a1df1SDavid du Colombier 				*q-- = '\0';
453312a1df1SDavid du Colombier 
454312a1df1SDavid du Colombier 			if (strcmp(pnm, s) != 0)
455312a1df1SDavid du Colombier 				continue;
456312a1df1SDavid du Colombier 
457312a1df1SDavid du Colombier 			if (frst)
458312a1df1SDavid du Colombier 			{	fprintf(fd, "\tuchar *this = pptr(h);\n");
459312a1df1SDavid du Colombier 				frst = 0;
460312a1df1SDavid du Colombier 			}
461312a1df1SDavid du Colombier 
462312a1df1SDavid du Colombier 			if (p)
463312a1df1SDavid du Colombier 			fprintf(fd, "		((P%d *)this)->%s = %s;\n",
464312a1df1SDavid du Colombier 				tpnr, p, r->ival->name);
465312a1df1SDavid du Colombier 
466312a1df1SDavid du Colombier 		}
467312a1df1SDavid du Colombier 	fprintf(fd, "}\n");
468312a1df1SDavid du Colombier }
469312a1df1SDavid du Colombier 
470312a1df1SDavid du Colombier /* tracking:
471312a1df1SDavid du Colombier 	1. for non-global and non-local c_state decls: add up all the sizes in c_added
472312a1df1SDavid du Colombier 	2. add a global char array of that size into now
473312a1df1SDavid du Colombier 	3. generate a routine that memcpy's the required values into that array
474312a1df1SDavid du Colombier 	4. generate a call to that routine
475312a1df1SDavid du Colombier  */
476312a1df1SDavid du Colombier 
477312a1df1SDavid du Colombier void
c_preview(void)478312a1df1SDavid du Colombier c_preview(void)
479312a1df1SDavid du Colombier {	C_Added *r;
480312a1df1SDavid du Colombier 
481312a1df1SDavid du Colombier 	hastrack = 0;
482312a1df1SDavid du Colombier 	if (c_tracked)
483312a1df1SDavid du Colombier 		hastrack = 1;
484312a1df1SDavid du Colombier 	else
485312a1df1SDavid du Colombier 	for (r = c_added; r; r = r->nxt)
486312a1df1SDavid du Colombier 		if (strncmp(r->t->name, " Global ", strlen(" Global ")) != 0
487312a1df1SDavid du Colombier 		&&  strncmp(r->t->name, " Hidden ", strlen(" Hidden ")) != 0
488312a1df1SDavid du Colombier 		&&  strncmp(r->t->name, " Local",  strlen(" Local"))  != 0)
489312a1df1SDavid du Colombier 		{	hastrack = 1;	/* c_state variant now obsolete */
490312a1df1SDavid du Colombier 			break;
491312a1df1SDavid du Colombier 		}
492312a1df1SDavid du Colombier }
493312a1df1SDavid du Colombier 
494312a1df1SDavid du Colombier int
c_add_sv(FILE * fd)495312a1df1SDavid du Colombier c_add_sv(FILE *fd)	/* 1+2 -- called in pangen1.c */
496312a1df1SDavid du Colombier {	C_Added *r;
497312a1df1SDavid du Colombier 	int cnt = 0;
498312a1df1SDavid du Colombier 
499312a1df1SDavid du Colombier 	if (!c_added && !c_tracked) return 0;
500312a1df1SDavid du Colombier 
501312a1df1SDavid du Colombier 	for (r = c_added; r; r = r->nxt)	/* pickup global decls */
502312a1df1SDavid du Colombier 		if (strncmp(r->t->name, " Global ", strlen(" Global ")) == 0)
503312a1df1SDavid du Colombier 			fprintf(fd, "	%s;\n", r->s->name);
504312a1df1SDavid du Colombier 
505312a1df1SDavid du Colombier 	for (r = c_added; r; r = r->nxt)
506312a1df1SDavid du Colombier 		if (strncmp(r->t->name, " Global ", strlen(" Global ")) != 0
507312a1df1SDavid du Colombier 		&&  strncmp(r->t->name, " Hidden ", strlen(" Hidden ")) != 0
508312a1df1SDavid du Colombier 		&&  strncmp(r->t->name, " Local",  strlen(" Local"))  != 0)
509312a1df1SDavid du Colombier 		{	cnt++;	/* obsolete use */
510312a1df1SDavid du Colombier 		}
511312a1df1SDavid du Colombier 
512312a1df1SDavid du Colombier 	for (r = c_tracked; r; r = r->nxt)
513312a1df1SDavid du Colombier 		cnt++;		/* preferred use */
514312a1df1SDavid du Colombier 
515312a1df1SDavid du Colombier 	if (cnt == 0) return 0;
516312a1df1SDavid du Colombier 
517312a1df1SDavid du Colombier 	cnt = 0;
518312a1df1SDavid du Colombier 	fprintf(fd, "	uchar c_state[");
519312a1df1SDavid du Colombier 	for (r = c_added; r; r = r->nxt)
520312a1df1SDavid du Colombier 		if (strncmp(r->t->name, " Global ", strlen(" Global ")) != 0
521312a1df1SDavid du Colombier 		&&  strncmp(r->t->name, " Hidden ", strlen(" Hidden ")) != 0
522312a1df1SDavid du Colombier 		&&  strncmp(r->t->name, " Local",  strlen(" Local"))  != 0)
523312a1df1SDavid du Colombier 		{	fprintf(fd, "%ssizeof(%s)",
524312a1df1SDavid du Colombier 				(cnt==0)?"":"+", r->t->name);
525312a1df1SDavid du Colombier 			cnt++;
526312a1df1SDavid du Colombier 		}
527312a1df1SDavid du Colombier 
528312a1df1SDavid du Colombier 	for (r = c_tracked; r; r = r->nxt)
529312a1df1SDavid du Colombier 	{	if (r->ival != ZS) continue;
530312a1df1SDavid du Colombier 
531312a1df1SDavid du Colombier 		fprintf(fd, "%s%s",
532312a1df1SDavid du Colombier 			(cnt==0)?"":"+", r->t->name);
533312a1df1SDavid du Colombier 		cnt++;
534312a1df1SDavid du Colombier 	}
535312a1df1SDavid du Colombier 
536312a1df1SDavid du Colombier 	if (cnt == 0) fprintf(fd, "4");	/* now redundant */
537312a1df1SDavid du Colombier 	fprintf(fd, "];\n");
538312a1df1SDavid du Colombier 	return 1;
539312a1df1SDavid du Colombier }
540312a1df1SDavid du Colombier 
541312a1df1SDavid du Colombier void
c_stack_size(FILE * fd)542*00d97012SDavid du Colombier c_stack_size(FILE *fd)
543*00d97012SDavid du Colombier {	C_Added *r;
544*00d97012SDavid du Colombier 	int cnt = 0;
545*00d97012SDavid du Colombier 
546*00d97012SDavid du Colombier 	for (r = c_tracked; r; r = r->nxt)
547*00d97012SDavid du Colombier 		if (r->ival != ZS)
548*00d97012SDavid du Colombier 		{	fprintf(fd, "%s%s",
549*00d97012SDavid du Colombier 				(cnt==0)?"":"+", r->t->name);
550*00d97012SDavid du Colombier 			cnt++;
551*00d97012SDavid du Colombier 		}
552*00d97012SDavid du Colombier 	if (cnt == 0)
553*00d97012SDavid du Colombier 	{	fprintf(fd, "WS");
554*00d97012SDavid du Colombier 	}
555*00d97012SDavid du Colombier }
556*00d97012SDavid du Colombier 
557*00d97012SDavid du Colombier void
c_add_stack(FILE * fd)558312a1df1SDavid du Colombier c_add_stack(FILE *fd)
559312a1df1SDavid du Colombier {	C_Added *r;
560312a1df1SDavid du Colombier 	int cnt = 0;
561312a1df1SDavid du Colombier 
562*00d97012SDavid du Colombier 	if ((!c_added && !c_tracked) || !has_stack)
563*00d97012SDavid du Colombier 	{	return;
564*00d97012SDavid du Colombier 	}
565312a1df1SDavid du Colombier 
566312a1df1SDavid du Colombier 	for (r = c_tracked; r; r = r->nxt)
567312a1df1SDavid du Colombier 		if (r->ival != ZS)
568*00d97012SDavid du Colombier 		{	cnt++;
569312a1df1SDavid du Colombier 		}
570312a1df1SDavid du Colombier 
571*00d97012SDavid du Colombier 	if (cnt > 0)
572*00d97012SDavid du Colombier 	{	fprintf(fd, "	uchar c_stack[StackSize];\n");
573*00d97012SDavid du Colombier 	}
574312a1df1SDavid du Colombier }
575312a1df1SDavid du Colombier 
576312a1df1SDavid du Colombier void
c_add_hidden(FILE * fd)577312a1df1SDavid du Colombier c_add_hidden(FILE *fd)
578312a1df1SDavid du Colombier {	C_Added *r;
579312a1df1SDavid du Colombier 
580312a1df1SDavid du Colombier 	for (r = c_added; r; r = r->nxt)	/* pickup hidden decls */
581312a1df1SDavid du Colombier 		if (strncmp(r->t->name, "\"Hidden\"", strlen("\"Hidden\"")) == 0)
582312a1df1SDavid du Colombier 		{	r->s->name[strlen(r->s->name)-1] = ' ';
583312a1df1SDavid du Colombier 			fprintf(fd, "%s;	/* Hidden */\n", &r->s->name[1]);
584312a1df1SDavid du Colombier 			r->s->name[strlen(r->s->name)-1] = '"';
585312a1df1SDavid du Colombier 		}
586312a1df1SDavid du Colombier 	/* called before c_add_def - quotes are still there */
587312a1df1SDavid du Colombier }
588312a1df1SDavid du Colombier 
589312a1df1SDavid du Colombier void
c_add_loc(FILE * fd,char * s)590312a1df1SDavid du Colombier c_add_loc(FILE *fd, char *s)	/* state vector entries for proctype s */
591312a1df1SDavid du Colombier {	C_Added *r;
592312a1df1SDavid du Colombier 	static char buf[1024];
593312a1df1SDavid du Colombier 	char *p;
594312a1df1SDavid du Colombier 
595312a1df1SDavid du Colombier 	if (!c_added) return;
596312a1df1SDavid du Colombier 
597312a1df1SDavid du Colombier 	strcpy(buf, s);
598312a1df1SDavid du Colombier 	strcat(buf, " ");
599312a1df1SDavid du Colombier 	for (r = c_added; r; r = r->nxt)	/* pickup local decls */
600312a1df1SDavid du Colombier 		if (strncmp(r->t->name, " Local", strlen(" Local")) == 0)
601312a1df1SDavid du Colombier 		{	p = r->t->name + strlen(" Local");
602312a1df1SDavid du Colombier 			while (*p == ' ' || *p == '\t')
603312a1df1SDavid du Colombier 				p++;
604312a1df1SDavid du Colombier 			if (strcmp(p, buf) == 0)
605312a1df1SDavid du Colombier 				fprintf(fd, "	%s;\n", r->s->name);
606312a1df1SDavid du Colombier 		}
607312a1df1SDavid du Colombier }
608312a1df1SDavid du Colombier void
c_add_def(FILE * fd)609312a1df1SDavid du Colombier c_add_def(FILE *fd)	/* 3 - called in plunk_c_fcts() */
610312a1df1SDavid du Colombier {	C_Added *r;
611312a1df1SDavid du Colombier 
612312a1df1SDavid du Colombier 	fprintf(fd, "#if defined(C_States) && defined(HAS_TRACK)\n");
613312a1df1SDavid du Colombier 	for (r = c_added; r; r = r->nxt)
614312a1df1SDavid du Colombier 	{	r->s->name[strlen(r->s->name)-1] = ' ';
615312a1df1SDavid du Colombier 		r->s->name[0] = ' '; /* remove the "s */
616312a1df1SDavid du Colombier 
617312a1df1SDavid du Colombier 		r->t->name[strlen(r->t->name)-1] = ' ';
618312a1df1SDavid du Colombier 		r->t->name[0] = ' ';
619312a1df1SDavid du Colombier 
620312a1df1SDavid du Colombier 		if (strncmp(r->t->name, " Global ", strlen(" Global ")) == 0
621312a1df1SDavid du Colombier 		||  strncmp(r->t->name, " Hidden ", strlen(" Hidden ")) == 0
622312a1df1SDavid du Colombier 		||  strncmp(r->t->name, " Local",  strlen(" Local"))  == 0)
623312a1df1SDavid du Colombier 			continue;
624312a1df1SDavid du Colombier 
625312a1df1SDavid du Colombier 		if (strchr(r->s->name, '&'))
626312a1df1SDavid du Colombier 			fatal("dereferencing state object: %s", r->s->name);
627312a1df1SDavid du Colombier 
628312a1df1SDavid du Colombier 		fprintf(fd, "extern %s %s;\n", r->t->name, r->s->name);
629312a1df1SDavid du Colombier 	}
630312a1df1SDavid du Colombier 	for (r = c_tracked; r; r = r->nxt)
631312a1df1SDavid du Colombier 	{	r->s->name[strlen(r->s->name)-1] = ' ';
632312a1df1SDavid du Colombier 		r->s->name[0] = ' '; /* remove " */
633312a1df1SDavid du Colombier 
634312a1df1SDavid du Colombier 		r->t->name[strlen(r->t->name)-1] = ' ';
635312a1df1SDavid du Colombier 		r->t->name[0] = ' ';
636312a1df1SDavid du Colombier 	}
637312a1df1SDavid du Colombier 
638312a1df1SDavid du Colombier 	if (separate == 2)
639312a1df1SDavid du Colombier 	{	fprintf(fd, "#endif\n");
640312a1df1SDavid du Colombier 		return;
641312a1df1SDavid du Colombier 	}
642312a1df1SDavid du Colombier 
643312a1df1SDavid du Colombier 	if (has_stack)
644*00d97012SDavid du Colombier 	{	fprintf(fd, "int cpu_printf(const char *, ...);\n");
645*00d97012SDavid du Colombier 		fprintf(fd, "void\nc_stack(uchar *p_t_r)\n{\n");
646312a1df1SDavid du Colombier 		fprintf(fd, "#ifdef VERBOSE\n");
647*00d97012SDavid du Colombier 		fprintf(fd, "	cpu_printf(\"c_stack %%u\\n\", p_t_r);\n");
648312a1df1SDavid du Colombier 		fprintf(fd, "#endif\n");
649312a1df1SDavid du Colombier 		for (r = c_tracked; r; r = r->nxt)
650312a1df1SDavid du Colombier 		{	if (r->ival == ZS) continue;
651312a1df1SDavid du Colombier 
652312a1df1SDavid du Colombier 			fprintf(fd, "\tif(%s)\n", r->s->name);
653312a1df1SDavid du Colombier 			fprintf(fd, "\t\tmemcpy(p_t_r, %s, %s);\n",
654312a1df1SDavid du Colombier 				r->s->name, r->t->name);
655312a1df1SDavid du Colombier 			fprintf(fd, "\telse\n");
656312a1df1SDavid du Colombier 			fprintf(fd, "\t\tmemset(p_t_r, 0, %s);\n",
657312a1df1SDavid du Colombier 				r->t->name);
658312a1df1SDavid du Colombier 			fprintf(fd, "\tp_t_r += %s;\n", r->t->name);
659312a1df1SDavid du Colombier 		}
660312a1df1SDavid du Colombier 		fprintf(fd, "}\n\n");
661312a1df1SDavid du Colombier 	}
662312a1df1SDavid du Colombier 
663f3793cddSDavid du Colombier 	fprintf(fd, "void\nc_update(uchar *p_t_r)\n{\n");
664312a1df1SDavid du Colombier 	fprintf(fd, "#ifdef VERBOSE\n");
665312a1df1SDavid du Colombier 	fprintf(fd, "	printf(\"c_update %%u\\n\", p_t_r);\n");
666312a1df1SDavid du Colombier 	fprintf(fd, "#endif\n");
667312a1df1SDavid du Colombier 	for (r = c_added; r; r = r->nxt)
668312a1df1SDavid du Colombier 	{	if (strncmp(r->t->name, " Global ", strlen(" Global ")) == 0
669312a1df1SDavid du Colombier 		||  strncmp(r->t->name, " Hidden ", strlen(" Hidden ")) == 0
670312a1df1SDavid du Colombier 		||  strncmp(r->t->name, " Local",  strlen(" Local"))  == 0)
671312a1df1SDavid du Colombier 			continue;
672312a1df1SDavid du Colombier 
673312a1df1SDavid du Colombier 		fprintf(fd, "\tmemcpy(p_t_r, &%s, sizeof(%s));\n",
674312a1df1SDavid du Colombier 			r->s->name, r->t->name);
675312a1df1SDavid du Colombier 		fprintf(fd, "\tp_t_r += sizeof(%s);\n", r->t->name);
676312a1df1SDavid du Colombier 	}
677312a1df1SDavid du Colombier 
678312a1df1SDavid du Colombier 	for (r = c_tracked; r; r = r->nxt)
679312a1df1SDavid du Colombier 	{	if (r->ival) continue;
680312a1df1SDavid du Colombier 
681312a1df1SDavid du Colombier 		fprintf(fd, "\tif(%s)\n", r->s->name);
682312a1df1SDavid du Colombier 		fprintf(fd, "\t\tmemcpy(p_t_r, %s, %s);\n",
683312a1df1SDavid du Colombier 			r->s->name, r->t->name);
684312a1df1SDavid du Colombier 		fprintf(fd, "\telse\n");
685312a1df1SDavid du Colombier 		fprintf(fd, "\t\tmemset(p_t_r, 0, %s);\n",
686312a1df1SDavid du Colombier 			r->t->name);
687312a1df1SDavid du Colombier 		fprintf(fd, "\tp_t_r += %s;\n", r->t->name);
688312a1df1SDavid du Colombier 	}
689312a1df1SDavid du Colombier 
690312a1df1SDavid du Colombier 	fprintf(fd, "}\n");
691312a1df1SDavid du Colombier 
692312a1df1SDavid du Colombier 	if (has_stack)
693f3793cddSDavid du Colombier 	{	fprintf(fd, "void\nc_unstack(uchar *p_t_r)\n{\n");
694312a1df1SDavid du Colombier 		fprintf(fd, "#ifdef VERBOSE\n");
695*00d97012SDavid du Colombier 		fprintf(fd, "	cpu_printf(\"c_unstack %%u\\n\", p_t_r);\n");
696312a1df1SDavid du Colombier 		fprintf(fd, "#endif\n");
697312a1df1SDavid du Colombier 		for (r = c_tracked; r; r = r->nxt)
698312a1df1SDavid du Colombier 		{	if (r->ival == ZS) continue;
699312a1df1SDavid du Colombier 
700312a1df1SDavid du Colombier 			fprintf(fd, "\tif(%s)\n", r->s->name);
701312a1df1SDavid du Colombier 			fprintf(fd, "\t\tmemcpy(%s, p_t_r, %s);\n",
702312a1df1SDavid du Colombier 				r->s->name, r->t->name);
703312a1df1SDavid du Colombier 			fprintf(fd, "\tp_t_r += %s;\n", r->t->name);
704312a1df1SDavid du Colombier 		}
705312a1df1SDavid du Colombier 		fprintf(fd, "}\n");
706312a1df1SDavid du Colombier 	}
707312a1df1SDavid du Colombier 
708f3793cddSDavid du Colombier 	fprintf(fd, "void\nc_revert(uchar *p_t_r)\n{\n");
709312a1df1SDavid du Colombier 	fprintf(fd, "#ifdef VERBOSE\n");
710312a1df1SDavid du Colombier 	fprintf(fd, "	printf(\"c_revert %%u\\n\", p_t_r);\n");
711312a1df1SDavid du Colombier 	fprintf(fd, "#endif\n");
712312a1df1SDavid du Colombier 	for (r = c_added; r; r = r->nxt)
713312a1df1SDavid du Colombier 	{	if (strncmp(r->t->name, " Global ", strlen(" Global ")) == 0
714312a1df1SDavid du Colombier 		||  strncmp(r->t->name, " Hidden ", strlen(" Hidden ")) == 0
715312a1df1SDavid du Colombier 		||  strncmp(r->t->name, " Local",  strlen(" Local"))  == 0)
716312a1df1SDavid du Colombier 			continue;
717312a1df1SDavid du Colombier 
718312a1df1SDavid du Colombier 		fprintf(fd, "\tmemcpy(&%s, p_t_r, sizeof(%s));\n",
719312a1df1SDavid du Colombier 			r->s->name, r->t->name);
720312a1df1SDavid du Colombier 		fprintf(fd, "\tp_t_r += sizeof(%s);\n", r->t->name);
721312a1df1SDavid du Colombier 	}
722312a1df1SDavid du Colombier 	for (r = c_tracked; r; r = r->nxt)
723312a1df1SDavid du Colombier 	{	if (r->ival != ZS) continue;
724312a1df1SDavid du Colombier 
725312a1df1SDavid du Colombier 		fprintf(fd, "\tif(%s)\n", r->s->name);
726312a1df1SDavid du Colombier 		fprintf(fd, "\t\tmemcpy(%s, p_t_r, %s);\n",
727312a1df1SDavid du Colombier 			r->s->name, r->t->name);
728312a1df1SDavid du Colombier 		fprintf(fd, "\tp_t_r += %s;\n", r->t->name);
729312a1df1SDavid du Colombier 	}
730312a1df1SDavid du Colombier 
731312a1df1SDavid du Colombier 	fprintf(fd, "}\n");
732312a1df1SDavid du Colombier 	fprintf(fd, "#endif\n");
733312a1df1SDavid du Colombier }
734312a1df1SDavid du Colombier 
735312a1df1SDavid du Colombier void
plunk_reverse(FILE * fd,IType * p,int matchthis)736312a1df1SDavid du Colombier plunk_reverse(FILE *fd, IType *p, int matchthis)
737312a1df1SDavid du Colombier {	char *y, *z;
738312a1df1SDavid du Colombier 
739312a1df1SDavid du Colombier 	if (!p) return;
740312a1df1SDavid du Colombier 	plunk_reverse(fd, p->nxt, matchthis);
741312a1df1SDavid du Colombier 
742312a1df1SDavid du Colombier 	if (!p->nm->context
743312a1df1SDavid du Colombier 	&&   p->nm->type == matchthis)
744312a1df1SDavid du Colombier 	{	fprintf(fd, "\n/* start of %s */\n", p->nm->name);
745312a1df1SDavid du Colombier 		z = (char *) p->cn;
746312a1df1SDavid du Colombier 		while (*z == '\n' || *z == '\r' || *z == '\\')
747312a1df1SDavid du Colombier 			z++;
748312a1df1SDavid du Colombier 		/* e.g.: \#include "..." */
749312a1df1SDavid du Colombier 
750312a1df1SDavid du Colombier 		y = z;
751312a1df1SDavid du Colombier 		while ((y = strstr(y, "\\#")) != NULL)
752312a1df1SDavid du Colombier 		{	*y = '\n'; y++;
753312a1df1SDavid du Colombier 		}
754312a1df1SDavid du Colombier 
755312a1df1SDavid du Colombier 		fprintf(fd, "%s\n", z);
756312a1df1SDavid du Colombier 		fprintf(fd, "\n/* end of %s */\n", p->nm->name);
757312a1df1SDavid du Colombier 	}
758312a1df1SDavid du Colombier }
759312a1df1SDavid du Colombier 
760312a1df1SDavid du Colombier void
plunk_c_decls(FILE * fd)761312a1df1SDavid du Colombier plunk_c_decls(FILE *fd)
762312a1df1SDavid du Colombier {
763312a1df1SDavid du Colombier 	plunk_reverse(fd, seqnames, CODE_DECL);
764312a1df1SDavid du Colombier }
765312a1df1SDavid du Colombier 
766312a1df1SDavid du Colombier void
plunk_c_fcts(FILE * fd)767312a1df1SDavid du Colombier plunk_c_fcts(FILE *fd)
768312a1df1SDavid du Colombier {
769312a1df1SDavid du Colombier 	if (separate == 2 && hastrack)
770312a1df1SDavid du Colombier 	{	c_add_def(fd);
771312a1df1SDavid du Colombier 		return;
772312a1df1SDavid du Colombier 	}
773312a1df1SDavid du Colombier 
774312a1df1SDavid du Colombier 	c_add_hidden(fd);
775312a1df1SDavid du Colombier 	plunk_reverse(fd, seqnames, CODE_FRAG);
776312a1df1SDavid du Colombier 
777312a1df1SDavid du Colombier 	if (c_added || c_tracked)	/* enables calls to c_revert and c_update */
778312a1df1SDavid du Colombier 		fprintf(fd, "#define C_States	1\n");
779312a1df1SDavid du Colombier 	else
780312a1df1SDavid du Colombier 		fprintf(fd, "#undef C_States\n");
781312a1df1SDavid du Colombier 
782312a1df1SDavid du Colombier 	if (hastrack)
783312a1df1SDavid du Colombier 		c_add_def(fd);
784312a1df1SDavid du Colombier 
785312a1df1SDavid du Colombier 	c_add_globinit(fd);
786312a1df1SDavid du Colombier 	do_locinits(fd);
787312a1df1SDavid du Colombier }
788312a1df1SDavid du Colombier 
789312a1df1SDavid du Colombier static void
check_inline(IType * tmp)790312a1df1SDavid du Colombier check_inline(IType *tmp)
791312a1df1SDavid du Colombier {	char buf[128];
792312a1df1SDavid du Colombier 	ProcList *p;
793312a1df1SDavid du Colombier 
794312a1df1SDavid du Colombier 	if (!X) return;
795312a1df1SDavid du Colombier 
796312a1df1SDavid du Colombier 	for (p = rdy; p; p = p->nxt)
797312a1df1SDavid du Colombier 	{	if (strcmp(p->n->name, X->n->name) == 0)
798312a1df1SDavid du Colombier 			continue;
799312a1df1SDavid du Colombier 		sprintf(buf, "P%s->", p->n->name);
800312a1df1SDavid du Colombier 		if (strstr((char *)tmp->cn, buf))
801312a1df1SDavid du Colombier 		{	printf("spin: in proctype %s, ref to object in proctype %s\n",
802312a1df1SDavid du Colombier 				X->n->name, p->n->name);
803312a1df1SDavid du Colombier 			fatal("invalid variable ref in '%s'", tmp->nm->name);
804312a1df1SDavid du Colombier 	}	}
805312a1df1SDavid du Colombier }
806312a1df1SDavid du Colombier 
807312a1df1SDavid du Colombier void
plunk_expr(FILE * fd,char * s)808312a1df1SDavid du Colombier plunk_expr(FILE *fd, char *s)
809312a1df1SDavid du Colombier {	IType *tmp;
810312a1df1SDavid du Colombier 
811312a1df1SDavid du Colombier 	tmp = find_inline(s);
812312a1df1SDavid du Colombier 	check_inline(tmp);
813312a1df1SDavid du Colombier 
814312a1df1SDavid du Colombier 	fprintf(fd, "%s", (char *) tmp->cn);
815312a1df1SDavid du Colombier }
816312a1df1SDavid du Colombier 
817312a1df1SDavid du Colombier void
preruse(FILE * fd,Lextok * n)818312a1df1SDavid du Colombier preruse(FILE *fd, Lextok *n)	/* check a condition for c_expr with preconditions */
819312a1df1SDavid du Colombier {	IType *tmp;
820312a1df1SDavid du Colombier 
821312a1df1SDavid du Colombier 	if (!n) return;
822312a1df1SDavid du Colombier 	if (n->ntyp == C_EXPR)
823312a1df1SDavid du Colombier 	{	tmp = find_inline(n->sym->name);
824312a1df1SDavid du Colombier 		if (tmp->prec)
825312a1df1SDavid du Colombier 		{	fprintf(fd, "if (!(%s)) { if (!readtrail) { depth++; ", tmp->prec);
826312a1df1SDavid du Colombier 			fprintf(fd, "trpt++; trpt->pr = II; trpt->o_t = t;");
827*00d97012SDavid du Colombier 			fprintf(fd, "trpt->st = tt; uerror(\"%s\"); continue; } ", tmp->prec);
828312a1df1SDavid du Colombier 			fprintf(fd, "else { printf(\"pan: precondition false: %s\\n\"); ", tmp->prec);
829312a1df1SDavid du Colombier 			fprintf(fd, "_m = 3; goto P999; } } \n\t\t");
830312a1df1SDavid du Colombier 		}
831312a1df1SDavid du Colombier 	} else
832312a1df1SDavid du Colombier 	{	preruse(fd, n->rgt);
833312a1df1SDavid du Colombier 		preruse(fd, n->lft);
834312a1df1SDavid du Colombier 	}
835312a1df1SDavid du Colombier }
836312a1df1SDavid du Colombier 
837312a1df1SDavid du Colombier int
glob_inline(char * s)838312a1df1SDavid du Colombier glob_inline(char *s)
839312a1df1SDavid du Colombier {	IType *tmp;
840312a1df1SDavid du Colombier 	char *bdy;
841312a1df1SDavid du Colombier 
842312a1df1SDavid du Colombier 	tmp = find_inline(s);
843312a1df1SDavid du Colombier 	bdy = (char *) tmp->cn;
844312a1df1SDavid du Colombier 	return (strstr(bdy, "now.")		/* global ref or   */
845312a1df1SDavid du Colombier 	||      strchr(bdy, '(') > bdy);	/* possible C-function call */
846312a1df1SDavid du Colombier }
847312a1df1SDavid du Colombier 
848312a1df1SDavid du Colombier void
plunk_inline(FILE * fd,char * s,int how,int gencode)849*00d97012SDavid du Colombier plunk_inline(FILE *fd, char *s, int how, int gencode)	/* c_code with precondition */
850312a1df1SDavid du Colombier {	IType *tmp;
851312a1df1SDavid du Colombier 
852312a1df1SDavid du Colombier 	tmp = find_inline(s);
853312a1df1SDavid du Colombier 	check_inline(tmp);
854312a1df1SDavid du Colombier 
855312a1df1SDavid du Colombier 	fprintf(fd, "{ ");
856312a1df1SDavid du Colombier 	if (how && tmp->prec)
857*00d97012SDavid du Colombier 	{	fprintf(fd, "if (!(%s)) { if (!readtrail) {",
858*00d97012SDavid du Colombier 			tmp->prec);
859*00d97012SDavid du Colombier 		fprintf(fd, " uerror(\"%s\"); continue; ",
860*00d97012SDavid du Colombier 			tmp->prec);
861*00d97012SDavid du Colombier 		fprintf(fd, "} else { ");
862*00d97012SDavid du Colombier 		fprintf(fd, "printf(\"pan: precondition false: %s\\n\"); _m = 3; goto P999; } } ",
863*00d97012SDavid du Colombier 			tmp->prec);
864312a1df1SDavid du Colombier 	}
865*00d97012SDavid du Colombier 
866*00d97012SDavid du Colombier 	if (!gencode)	/* not in d_step */
867*00d97012SDavid du Colombier 	{	fprintf(fd, "\n\t\tsv_save();");
868*00d97012SDavid du Colombier 	}
869*00d97012SDavid du Colombier 
870312a1df1SDavid du Colombier 	fprintf(fd, "%s", (char *) tmp->cn);
871312a1df1SDavid du Colombier 	fprintf(fd, " }\n");
872312a1df1SDavid du Colombier }
873312a1df1SDavid du Colombier 
874312a1df1SDavid du Colombier void
no_side_effects(char * s)875312a1df1SDavid du Colombier no_side_effects(char *s)
876312a1df1SDavid du Colombier {	IType *tmp;
877312a1df1SDavid du Colombier 	char *t;
878312a1df1SDavid du Colombier 
879312a1df1SDavid du Colombier 	/* could still defeat this check via hidden
880312a1df1SDavid du Colombier 	 * side effects in function calls,
881312a1df1SDavid du Colombier 	 * but this will catch at least some cases
882312a1df1SDavid du Colombier 	 */
883312a1df1SDavid du Colombier 
884312a1df1SDavid du Colombier 	tmp = find_inline(s);
885312a1df1SDavid du Colombier 	t = (char *) tmp->cn;
886312a1df1SDavid du Colombier 
887312a1df1SDavid du Colombier 	if (strchr(t, ';')
888312a1df1SDavid du Colombier 	||  strstr(t, "++")
889312a1df1SDavid du Colombier 	||  strstr(t, "--"))
890312a1df1SDavid du Colombier 	{
891312a1df1SDavid du Colombier bad:		lineno = tmp->dln;
892312a1df1SDavid du Colombier 		Fname = tmp->dfn;
893312a1df1SDavid du Colombier 		non_fatal("c_expr %s has side-effects", s);
894312a1df1SDavid du Colombier 		return;
895312a1df1SDavid du Colombier 	}
896312a1df1SDavid du Colombier 	while ((t = strchr(t, '=')) != NULL)
897312a1df1SDavid du Colombier 	{	if (*(t-1) == '!'
898312a1df1SDavid du Colombier 		||  *(t-1) == '>'
899312a1df1SDavid du Colombier 		||  *(t-1) == '<')
900312a1df1SDavid du Colombier 		{	t++;
901312a1df1SDavid du Colombier 			continue;
902312a1df1SDavid du Colombier 		}
903312a1df1SDavid du Colombier 		t++;
904312a1df1SDavid du Colombier 		if (*t != '=')
905312a1df1SDavid du Colombier 			goto bad;
906312a1df1SDavid du Colombier 		t++;
907312a1df1SDavid du Colombier 	}
908312a1df1SDavid du Colombier }
909312a1df1SDavid du Colombier 
9107dd7cddfSDavid du Colombier void
pickup_inline(Symbol * t,Lextok * apars)9117dd7cddfSDavid du Colombier pickup_inline(Symbol *t, Lextok *apars)
9127dd7cddfSDavid du Colombier {	IType *tmp; Lextok *p, *q; int j;
9137dd7cddfSDavid du Colombier 
914312a1df1SDavid du Colombier 	tmp = find_inline(t->name);
9157dd7cddfSDavid du Colombier 
9167dd7cddfSDavid du Colombier 	if (++Inlining >= MAXINL)
917*00d97012SDavid du Colombier 		fatal("inlines nested too deeply", 0);
9187dd7cddfSDavid du Colombier 	tmp->cln = lineno;	/* remember calling point */
9197dd7cddfSDavid du Colombier 	tmp->cfn = Fname;	/* and filename */
9207dd7cddfSDavid du Colombier 
9217dd7cddfSDavid du Colombier 	for (p = apars, q = tmp->params, j = 0; p && q; p = p->rgt, q = q->rgt)
9227dd7cddfSDavid du Colombier 		j++; /* count them */
9237dd7cddfSDavid du Colombier 	if (p || q)
9247dd7cddfSDavid du Colombier 		fatal("wrong nr of params on call of '%s'", t->name);
9257dd7cddfSDavid du Colombier 
9267dd7cddfSDavid du Colombier 	tmp->anms  = (char **) emalloc(j * sizeof(char *));
9277dd7cddfSDavid du Colombier 	for (p = apars, j = 0; p; p = p->rgt, j++)
928*00d97012SDavid du Colombier 	{	tmp->anms[j] = (char *) emalloc(strlen(IArg_cont[j])+1);
9297dd7cddfSDavid du Colombier 		strcpy(tmp->anms[j], IArg_cont[j]);
9307dd7cddfSDavid du Colombier 	}
9317dd7cddfSDavid du Colombier 
9327dd7cddfSDavid du Colombier 	lineno = tmp->dln;	/* linenr of def */
9337dd7cddfSDavid du Colombier 	Fname = tmp->dfn;	/* filename of same */
9347dd7cddfSDavid du Colombier 	Inliner[Inlining] = (char *)tmp->cn;
9357dd7cddfSDavid du Colombier 	Inline_stub[Inlining] = tmp;
9367dd7cddfSDavid du Colombier #if 0
9377dd7cddfSDavid du Colombier 	if (verbose&32)
938*00d97012SDavid du Colombier 	printf("spin: %s:%d, inlining '%s' (from %s:%d)\n",
939*00d97012SDavid du Colombier 		tmp->cfn->name, tmp->cln, t->name, tmp->dfn->name, tmp->dln);
9407dd7cddfSDavid du Colombier #endif
9417dd7cddfSDavid du Colombier 	for (j = 0; j < Inlining; j++)
9427dd7cddfSDavid du Colombier 		if (Inline_stub[j] == Inline_stub[Inlining])
9437dd7cddfSDavid du Colombier 		fatal("cyclic inline attempt on: %s", t->name);
9447dd7cddfSDavid du Colombier }
9457dd7cddfSDavid du Colombier 
9467dd7cddfSDavid du Colombier static void
do_directive(int first)947312a1df1SDavid du Colombier do_directive(int first)
9487dd7cddfSDavid du Colombier {	int c = first;	/* handles lines starting with pound */
9497dd7cddfSDavid du Colombier 
9507dd7cddfSDavid du Colombier 	getword(c, isalpha_);
9517dd7cddfSDavid du Colombier 
952312a1df1SDavid du Colombier 	if (strcmp(yytext, "#ident") == 0)
953312a1df1SDavid du Colombier 		goto done;
954312a1df1SDavid du Colombier 
9557dd7cddfSDavid du Colombier 	if ((c = Getchar()) != ' ')
9567dd7cddfSDavid du Colombier 		fatal("malformed preprocessor directive - # .", 0);
9577dd7cddfSDavid du Colombier 
9587dd7cddfSDavid du Colombier 	if (!isdigit_(c = Getchar()))
9597dd7cddfSDavid du Colombier 		fatal("malformed preprocessor directive - # .lineno", 0);
9607dd7cddfSDavid du Colombier 
9617dd7cddfSDavid du Colombier 	getword(c, isdigit_);
9627dd7cddfSDavid du Colombier 	lineno = atoi(yytext);	/* pickup the line number */
9637dd7cddfSDavid du Colombier 
9647dd7cddfSDavid du Colombier 	if ((c = Getchar()) == '\n')
9657dd7cddfSDavid du Colombier 		return;	/* no filename */
9667dd7cddfSDavid du Colombier 
9677dd7cddfSDavid du Colombier 	if (c != ' ')
9687dd7cddfSDavid du Colombier 		fatal("malformed preprocessor directive - .fname", 0);
9697dd7cddfSDavid du Colombier 
9707dd7cddfSDavid du Colombier 	if ((c = Getchar()) != '\"')
971*00d97012SDavid du Colombier 	{	printf("got %c, expected \" -- lineno %d\n", c, lineno);
972*00d97012SDavid du Colombier 		fatal("malformed preprocessor directive - .fname (%s)", yytext);
973*00d97012SDavid du Colombier 	}
9747dd7cddfSDavid du Colombier 
975*00d97012SDavid du Colombier 	getword(Getchar(), notquote);	/* was getword(c, notquote); */
9767dd7cddfSDavid du Colombier 	if (Getchar() != '\"')
9777dd7cddfSDavid du Colombier 		fatal("malformed preprocessor directive - fname.", 0);
9787dd7cddfSDavid du Colombier 
979*00d97012SDavid du Colombier 	/* strcat(yytext, "\""); */
9807dd7cddfSDavid du Colombier 	Fname = lookup(yytext);
981312a1df1SDavid du Colombier done:
9827dd7cddfSDavid du Colombier 	while (Getchar() != '\n')
9837dd7cddfSDavid du Colombier 		;
9847dd7cddfSDavid du Colombier }
9857dd7cddfSDavid du Colombier 
9867dd7cddfSDavid du Colombier void
precondition(char * q)987312a1df1SDavid du Colombier precondition(char *q)
988312a1df1SDavid du Colombier {	int c, nest = 1;
989312a1df1SDavid du Colombier 
990312a1df1SDavid du Colombier 	for (;;)
991312a1df1SDavid du Colombier 	{	c = Getchar();
992312a1df1SDavid du Colombier 		*q++ = c;
993312a1df1SDavid du Colombier 		switch (c) {
994312a1df1SDavid du Colombier 		case '\n':
995312a1df1SDavid du Colombier 			lineno++;
996312a1df1SDavid du Colombier 			break;
997312a1df1SDavid du Colombier 		case '[':
998312a1df1SDavid du Colombier 			nest++;
999312a1df1SDavid du Colombier 			break;
1000312a1df1SDavid du Colombier 		case ']':
1001312a1df1SDavid du Colombier 			if (--nest <= 0)
1002312a1df1SDavid du Colombier 			{	*--q = '\0';
1003312a1df1SDavid du Colombier 				return;
1004312a1df1SDavid du Colombier 			}
1005312a1df1SDavid du Colombier 			break;
1006312a1df1SDavid du Colombier 		}
1007312a1df1SDavid du Colombier 	}
1008*00d97012SDavid du Colombier 	fatal("cannot happen", (char *) 0); /* unreachable */
1009312a1df1SDavid du Colombier }
1010312a1df1SDavid du Colombier 
1011*00d97012SDavid du Colombier 
1012312a1df1SDavid du Colombier Symbol *
prep_inline(Symbol * s,Lextok * nms)10137dd7cddfSDavid du Colombier prep_inline(Symbol *s, Lextok *nms)
10147dd7cddfSDavid du Colombier {	int c, nest = 1, dln, firstchar, cnr;
1015*00d97012SDavid du Colombier 	char *p;
10167dd7cddfSDavid du Colombier 	Lextok *t;
1017*00d97012SDavid du Colombier 	static char Buf1[SOMETHINGBIG], Buf2[RATHERSMALL];
1018312a1df1SDavid du Colombier 	static int c_code = 1;
10197dd7cddfSDavid du Colombier 
10207dd7cddfSDavid du Colombier 	for (t = nms; t; t = t->rgt)
10217dd7cddfSDavid du Colombier 		if (t->lft)
10227dd7cddfSDavid du Colombier 		{	if (t->lft->ntyp != NAME)
1023*00d97012SDavid du Colombier 			fatal("bad param to inline %s", s?s->name:"--");
10247dd7cddfSDavid du Colombier 			t->lft->sym->hidden |= 32;
10257dd7cddfSDavid du Colombier 		}
10267dd7cddfSDavid du Colombier 
1027312a1df1SDavid du Colombier 	if (!s)	/* C_Code fragment */
1028312a1df1SDavid du Colombier 	{	s = (Symbol *) emalloc(sizeof(Symbol));
1029*00d97012SDavid du Colombier 		s->name = (char *) emalloc(strlen("c_code")+26);
1030312a1df1SDavid du Colombier 		sprintf(s->name, "c_code%d", c_code++);
1031312a1df1SDavid du Colombier 		s->context = context;
1032312a1df1SDavid du Colombier 		s->type = CODE_FRAG;
1033312a1df1SDavid du Colombier 	} else
10347dd7cddfSDavid du Colombier 		s->type = PREDEF;
1035312a1df1SDavid du Colombier 
1036*00d97012SDavid du Colombier 	p = &Buf1[0];
1037*00d97012SDavid du Colombier 	Buf2[0] = '\0';
10387dd7cddfSDavid du Colombier 	for (;;)
10397dd7cddfSDavid du Colombier 	{	c = Getchar();
10407dd7cddfSDavid du Colombier 		switch (c) {
1041312a1df1SDavid du Colombier 		case '[':
1042312a1df1SDavid du Colombier 			if (s->type != CODE_FRAG)
1043312a1df1SDavid du Colombier 				goto bad;
1044*00d97012SDavid du Colombier 			precondition(&Buf2[0]);	/* e.g., c_code [p] { r = p-r; } */
1045312a1df1SDavid du Colombier 			continue;
10467dd7cddfSDavid du Colombier 		case '{':
10477dd7cddfSDavid du Colombier 			break;
10487dd7cddfSDavid du Colombier 		case '\n':
10497dd7cddfSDavid du Colombier 			lineno++;
10507dd7cddfSDavid du Colombier 			/* fall through */
10517dd7cddfSDavid du Colombier 		case ' ': case '\t': case '\f': case '\r':
10527dd7cddfSDavid du Colombier 			continue;
1053312a1df1SDavid du Colombier 		default :
1054312a1df1SDavid du Colombier 			 printf("spin: saw char '%c'\n", c);
1055312a1df1SDavid du Colombier bad:			 fatal("bad inline: %s", s->name);
10567dd7cddfSDavid du Colombier 		}
10577dd7cddfSDavid du Colombier 		break;
10587dd7cddfSDavid du Colombier 	}
10597dd7cddfSDavid du Colombier 	dln = lineno;
1060312a1df1SDavid du Colombier 	if (s->type == CODE_FRAG)
1061312a1df1SDavid du Colombier 	{	if (verbose&32)
1062*00d97012SDavid du Colombier 			sprintf(Buf1, "\t/* line %d %s */\n\t\t",
1063312a1df1SDavid du Colombier 				lineno, Fname->name);
1064312a1df1SDavid du Colombier 		else
1065*00d97012SDavid du Colombier 			strcpy(Buf1, "");
1066312a1df1SDavid du Colombier 	} else
1067*00d97012SDavid du Colombier 		sprintf(Buf1, "\n#line %d \"%s\"\n{", lineno, Fname->name);
1068*00d97012SDavid du Colombier 	p += strlen(Buf1);
10697dd7cddfSDavid du Colombier 	firstchar = 1;
10707dd7cddfSDavid du Colombier 
10717dd7cddfSDavid du Colombier 	cnr = 1; /* not zero */
10727dd7cddfSDavid du Colombier more:
1073*00d97012SDavid du Colombier 	c = Getchar();
1074*00d97012SDavid du Colombier 	*p++ = (char) c;
1075*00d97012SDavid du Colombier 	if (p - Buf1 >= SOMETHINGBIG)
10767dd7cddfSDavid du Colombier 		fatal("inline text too long", 0);
10777dd7cddfSDavid du Colombier 	switch (c) {
10787dd7cddfSDavid du Colombier 	case '\n':
10797dd7cddfSDavid du Colombier 		lineno++;
10807dd7cddfSDavid du Colombier 		cnr = 0;
10817dd7cddfSDavid du Colombier 		break;
10827dd7cddfSDavid du Colombier 	case '{':
10837dd7cddfSDavid du Colombier 		cnr++;
10847dd7cddfSDavid du Colombier 		nest++;
10857dd7cddfSDavid du Colombier 		break;
10867dd7cddfSDavid du Colombier 	case '}':
10877dd7cddfSDavid du Colombier 		cnr++;
10887dd7cddfSDavid du Colombier 		if (--nest <= 0)
10897dd7cddfSDavid du Colombier 		{	*p = '\0';
1090312a1df1SDavid du Colombier 			if (s->type == CODE_FRAG)
1091312a1df1SDavid du Colombier 				*--p = '\0';	/* remove trailing '}' */
1092*00d97012SDavid du Colombier 			def_inline(s, dln, &Buf1[0], &Buf2[0], nms);
1093*00d97012SDavid du Colombier 			if (firstchar)
1094312a1df1SDavid du Colombier 				printf("%3d: %s, warning: empty inline definition (%s)\n",
1095312a1df1SDavid du Colombier 					dln, Fname->name, s->name);
1096312a1df1SDavid du Colombier 			return s;	/* normal return */
10977dd7cddfSDavid du Colombier 		}
10987dd7cddfSDavid du Colombier 		break;
10997dd7cddfSDavid du Colombier 	case '#':
11007dd7cddfSDavid du Colombier 		if (cnr == 0)
11017dd7cddfSDavid du Colombier 		{	p--;
1102312a1df1SDavid du Colombier 			do_directive(c); /* reads to newline */
1103*00d97012SDavid du Colombier 		} else
1104*00d97012SDavid du Colombier 		{	firstchar = 0;
1105*00d97012SDavid du Colombier 			cnr++;
1106*00d97012SDavid du Colombier 		}
11077dd7cddfSDavid du Colombier 		break;
11087dd7cddfSDavid du Colombier 	case '\t':
11097dd7cddfSDavid du Colombier 	case ' ':
11107dd7cddfSDavid du Colombier 	case '\f':
11117dd7cddfSDavid du Colombier 		cnr++;
11127dd7cddfSDavid du Colombier 		break;
1113*00d97012SDavid du Colombier 	default:
1114*00d97012SDavid du Colombier 		firstchar = 0;
1115*00d97012SDavid du Colombier 		cnr++;
1116*00d97012SDavid du Colombier 		break;
11177dd7cddfSDavid du Colombier 	}
11187dd7cddfSDavid du Colombier 	goto more;
11197dd7cddfSDavid du Colombier }
11207dd7cddfSDavid du Colombier 
1121*00d97012SDavid du Colombier static void
set_cur_scope(void)1122*00d97012SDavid du Colombier set_cur_scope(void)
1123*00d97012SDavid du Colombier {	int i;
1124*00d97012SDavid du Colombier 	char tmpbuf[256];
1125*00d97012SDavid du Colombier 
1126*00d97012SDavid du Colombier 	strcpy(CurScope, "_");
1127*00d97012SDavid du Colombier 
1128*00d97012SDavid du Colombier 	if (context)
1129*00d97012SDavid du Colombier 	for (i = 0; i < scope_level; i++)
1130*00d97012SDavid du Colombier 	{	sprintf(tmpbuf, "%d_", scope_seq[i]);
1131*00d97012SDavid du Colombier 		strcat(CurScope, tmpbuf);
1132*00d97012SDavid du Colombier 	}
1133*00d97012SDavid du Colombier }
1134*00d97012SDavid du Colombier 
11357dd7cddfSDavid du Colombier static int
lex(void)1136219b2ee8SDavid du Colombier lex(void)
1137219b2ee8SDavid du Colombier {	int c;
1138219b2ee8SDavid du Colombier 
1139219b2ee8SDavid du Colombier again:
1140219b2ee8SDavid du Colombier 	c = Getchar();
11417dd7cddfSDavid du Colombier 	yytext[0] = (char) c;
1142219b2ee8SDavid du Colombier 	yytext[1] = '\0';
1143219b2ee8SDavid du Colombier 	switch (c) {
1144*00d97012SDavid du Colombier 	case EOF:
1145*00d97012SDavid du Colombier 		return c;
1146219b2ee8SDavid du Colombier 	case '\n':		/* newline */
1147219b2ee8SDavid du Colombier 		lineno++;
11487dd7cddfSDavid du Colombier 	case '\r':		/* carriage return */
1149219b2ee8SDavid du Colombier 		goto again;
1150219b2ee8SDavid du Colombier 
11517dd7cddfSDavid du Colombier 	case  ' ': case '\t': case '\f':	/* white space */
1152219b2ee8SDavid du Colombier 		goto again;
1153219b2ee8SDavid du Colombier 
1154219b2ee8SDavid du Colombier 	case '#':		/* preprocessor directive */
11557dd7cddfSDavid du Colombier 		if (in_comment) goto again;
1156312a1df1SDavid du Colombier 		do_directive(c);
1157219b2ee8SDavid du Colombier 		goto again;
1158219b2ee8SDavid du Colombier 
1159219b2ee8SDavid du Colombier 	case '\"':
1160219b2ee8SDavid du Colombier 		getword(c, notquote);
1161219b2ee8SDavid du Colombier 		if (Getchar() != '\"')
1162219b2ee8SDavid du Colombier 			fatal("string not terminated", yytext);
1163219b2ee8SDavid du Colombier 		strcat(yytext, "\"");
11647dd7cddfSDavid du Colombier 		SymToken(lookup(yytext), STRING)
11657dd7cddfSDavid du Colombier 
1166*00d97012SDavid du Colombier 	case '$':
1167*00d97012SDavid du Colombier 		getword('\"', notdollar);
1168*00d97012SDavid du Colombier 		if (Getchar() != '$')
1169*00d97012SDavid du Colombier 			fatal("ltl definition not terminated", yytext);
1170*00d97012SDavid du Colombier 		strcat(yytext, "\"");
1171*00d97012SDavid du Colombier 		SymToken(lookup(yytext), STRING)
1172*00d97012SDavid du Colombier 
11737dd7cddfSDavid du Colombier 	case '\'':	/* new 3.0.9 */
11747dd7cddfSDavid du Colombier 		c = Getchar();
11757dd7cddfSDavid du Colombier 		if (c == '\\')
11767dd7cddfSDavid du Colombier 		{	c = Getchar();
11777dd7cddfSDavid du Colombier 			if (c == 'n') c = '\n';
11787dd7cddfSDavid du Colombier 			else if (c == 'r') c = '\r';
11797dd7cddfSDavid du Colombier 			else if (c == 't') c = '\t';
11807dd7cddfSDavid du Colombier 			else if (c == 'f') c = '\f';
11817dd7cddfSDavid du Colombier 		}
1182312a1df1SDavid du Colombier 		if (Getchar() != '\'' && !in_comment)
1183312a1df1SDavid du Colombier 			fatal("character quote missing: %s", yytext);
11847dd7cddfSDavid du Colombier 		ValToken(c, CONST)
1185219b2ee8SDavid du Colombier 
1186219b2ee8SDavid du Colombier 	default:
1187219b2ee8SDavid du Colombier 		break;
1188219b2ee8SDavid du Colombier 	}
1189219b2ee8SDavid du Colombier 
11907dd7cddfSDavid du Colombier 	if (isdigit_(c))
11917dd7cddfSDavid du Colombier 	{	getword(c, isdigit_);
11927dd7cddfSDavid du Colombier 		ValToken(atoi(yytext), CONST)
1193219b2ee8SDavid du Colombier 	}
1194219b2ee8SDavid du Colombier 
11957dd7cddfSDavid du Colombier 	if (isalpha_(c) || c == '_')
1196219b2ee8SDavid du Colombier 	{	getword(c, isalnum_);
1197219b2ee8SDavid du Colombier 		if (!in_comment)
11987dd7cddfSDavid du Colombier 		{	c = check_name(yytext);
11997dd7cddfSDavid du Colombier 			if (c) return c;
12007dd7cddfSDavid du Colombier 			/* else fall through */
12017dd7cddfSDavid du Colombier 		}
12027dd7cddfSDavid du Colombier 		goto again;
1203219b2ee8SDavid du Colombier 	}
1204219b2ee8SDavid du Colombier 
1205*00d97012SDavid du Colombier 	if (ltl_mode)
1206*00d97012SDavid du Colombier 	{	switch (c) {
1207*00d97012SDavid du Colombier 		case '-': c = follow('>', IMPLIES,    '-'); break;
1208*00d97012SDavid du Colombier 		case '[': c = follow(']', ALWAYS,     '['); break;
1209*00d97012SDavid du Colombier 		case '<': c = follow('>', EVENTUALLY, '<');
1210*00d97012SDavid du Colombier 			  if (c == '<')
1211*00d97012SDavid du Colombier 			  {	c = Getchar();
1212*00d97012SDavid du Colombier 				if (c == '-')
1213*00d97012SDavid du Colombier 				{	c = follow('>', EQUIV, '-');
1214*00d97012SDavid du Colombier 					if (c == '-')
1215*00d97012SDavid du Colombier 					{	Ungetch(c);
1216*00d97012SDavid du Colombier 						c = '<';
1217*00d97012SDavid du Colombier 					}
1218*00d97012SDavid du Colombier 				} else
1219*00d97012SDavid du Colombier 				{	Ungetch(c);
1220*00d97012SDavid du Colombier 					c = '<';
1221*00d97012SDavid du Colombier 			  }	}
1222*00d97012SDavid du Colombier 		default:  break;
1223*00d97012SDavid du Colombier 	}	}
1224*00d97012SDavid du Colombier 
1225219b2ee8SDavid du Colombier 	switch (c) {
1226219b2ee8SDavid du Colombier 	case '/': c = follow('*', 0, '/');
1227219b2ee8SDavid du Colombier 		  if (!c) { in_comment = 1; goto again; }
1228219b2ee8SDavid du Colombier 		  break;
1229219b2ee8SDavid du Colombier 	case '*': c = follow('/', 0, '*');
1230219b2ee8SDavid du Colombier 		  if (!c) { in_comment = 0; goto again; }
1231219b2ee8SDavid du Colombier 		  break;
1232219b2ee8SDavid du Colombier 	case ':': c = follow(':', SEP, ':'); break;
1233219b2ee8SDavid du Colombier 	case '-': c = follow('>', SEMI, follow('-', DECR, '-')); break;
1234219b2ee8SDavid du Colombier 	case '+': c = follow('+', INCR, '+'); break;
1235219b2ee8SDavid du Colombier 	case '<': c = follow('<', LSHIFT, follow('=', LE, LT)); break;
1236219b2ee8SDavid du Colombier 	case '>': c = follow('>', RSHIFT, follow('=', GE, GT)); break;
1237219b2ee8SDavid du Colombier 	case '=': c = follow('=', EQ, ASGN); break;
1238219b2ee8SDavid du Colombier 	case '!': c = follow('=', NE, follow('!', O_SND, SND)); break;
1239219b2ee8SDavid du Colombier 	case '?': c = follow('?', R_RCV, RCV); break;
1240219b2ee8SDavid du Colombier 	case '&': c = follow('&', AND, '&'); break;
1241219b2ee8SDavid du Colombier 	case '|': c = follow('|', OR, '|'); break;
1242219b2ee8SDavid du Colombier 	case ';': c = SEMI; break;
1243*00d97012SDavid du Colombier 	case '.': c = follow('.', DOTDOT, '.'); break;
1244*00d97012SDavid du Colombier 	case '{': scope_seq[scope_level++]++; set_cur_scope(); break;
1245*00d97012SDavid du Colombier 	case '}': scope_level--; set_cur_scope(); break;
1246219b2ee8SDavid du Colombier 	default : break;
1247219b2ee8SDavid du Colombier 	}
12487dd7cddfSDavid du Colombier 	Token(c)
1249219b2ee8SDavid du Colombier }
1250219b2ee8SDavid du Colombier 
1251219b2ee8SDavid du Colombier static struct {
1252*00d97012SDavid du Colombier 	char *s;	int tok;
1253*00d97012SDavid du Colombier } LTL_syms[] = {
1254*00d97012SDavid du Colombier 	/* [], <>, ->, and <-> are intercepted in lex() */
1255*00d97012SDavid du Colombier 	{ "U",		UNTIL   },
1256*00d97012SDavid du Colombier 	{ "V",		RELEASE },
1257*00d97012SDavid du Colombier 	{ "W",		WEAK_UNTIL },
1258*00d97012SDavid du Colombier 	{ "X",		NEXT    },
1259*00d97012SDavid du Colombier 	{ "always",	ALWAYS  },
1260*00d97012SDavid du Colombier 	{ "eventually",	EVENTUALLY },
1261*00d97012SDavid du Colombier 	{ "until",	UNTIL   },
1262*00d97012SDavid du Colombier 	{ "stronguntil",UNTIL   },
1263*00d97012SDavid du Colombier 	{ "weakuntil",	WEAK_UNTIL   },
1264*00d97012SDavid du Colombier 	{ "release",	RELEASE },
1265*00d97012SDavid du Colombier 	{ "next",	NEXT    },
1266*00d97012SDavid du Colombier 	{ "implies",	IMPLIES },
1267*00d97012SDavid du Colombier 	{ "equivalent",	EQUIV   },
1268*00d97012SDavid du Colombier 	{ 0, 		0       },
1269*00d97012SDavid du Colombier };
1270*00d97012SDavid du Colombier 
1271*00d97012SDavid du Colombier static struct {
1272219b2ee8SDavid du Colombier 	char *s;	int tok;	int val;	char *sym;
1273219b2ee8SDavid du Colombier } Names[] = {
12747dd7cddfSDavid du Colombier 	{"active",	ACTIVE,		0,		0},
12757dd7cddfSDavid du Colombier 	{"assert",	ASSERT,		0,		0},
12767dd7cddfSDavid du Colombier 	{"atomic",	ATOMIC,		0,		0},
12777dd7cddfSDavid du Colombier 	{"bit",		TYPE,		BIT,		0},
12787dd7cddfSDavid du Colombier 	{"bool",	TYPE,		BIT,		0},
12797dd7cddfSDavid du Colombier 	{"break",	BREAK,		0,		0},
12807dd7cddfSDavid du Colombier 	{"byte",	TYPE,		BYTE,		0},
1281312a1df1SDavid du Colombier 	{"c_code",	C_CODE,		0,		0},
1282312a1df1SDavid du Colombier 	{"c_decl",	C_DECL,		0,		0},
1283312a1df1SDavid du Colombier 	{"c_expr",	C_EXPR,		0,		0},
1284312a1df1SDavid du Colombier 	{"c_state",	C_STATE,	0,		0},
1285312a1df1SDavid du Colombier 	{"c_track",	C_TRACK,	0,		0},
12867dd7cddfSDavid du Colombier 	{"D_proctype",	D_PROCTYPE,	0,		0},
12877dd7cddfSDavid du Colombier 	{"do",		DO,		0,		0},
12887dd7cddfSDavid du Colombier 	{"chan",	TYPE,		CHAN,		0},
12897dd7cddfSDavid du Colombier 	{"else", 	ELSE,		0,		0},
12907dd7cddfSDavid du Colombier 	{"empty",	EMPTY,		0,		0},
12917dd7cddfSDavid du Colombier 	{"enabled",	ENABLED,	0,		0},
12927dd7cddfSDavid du Colombier 	{"eval",	EVAL,		0,		0},
12937dd7cddfSDavid du Colombier 	{"false",	CONST,		0,		0},
12947dd7cddfSDavid du Colombier 	{"fi",		FI,		0,		0},
1295*00d97012SDavid du Colombier 	{"for",		FOR,		0,		0},
12967dd7cddfSDavid du Colombier 	{"full",	FULL,		0,		0},
12977dd7cddfSDavid du Colombier 	{"goto",	GOTO,		0,		0},
12987dd7cddfSDavid du Colombier 	{"hidden",	HIDDEN,		0,		":hide:"},
12997dd7cddfSDavid du Colombier 	{"if",		IF,		0,		0},
1300*00d97012SDavid du Colombier 	{"in",		IN,		0,		0},
13017dd7cddfSDavid du Colombier 	{"init",	INIT,		0,		":init:"},
1302*00d97012SDavid du Colombier 	{"inline",	INLINE,		0,		0},
13037dd7cddfSDavid du Colombier 	{"int",		TYPE,		INT,		0},
13047dd7cddfSDavid du Colombier 	{"len",		LEN,		0,		0},
1305312a1df1SDavid du Colombier 	{"local",	ISLOCAL,	0,		":local:"},
1306*00d97012SDavid du Colombier 	{"ltl",		LTL,		0,		":ltl:"},
13077dd7cddfSDavid du Colombier 	{"mtype",	TYPE,		MTYPE,		0},
13087dd7cddfSDavid du Colombier 	{"nempty",	NEMPTY,		0,		0},
13097dd7cddfSDavid du Colombier 	{"never",	CLAIM,		0,		":never:"},
13107dd7cddfSDavid du Colombier 	{"nfull",	NFULL,		0,		0},
13117dd7cddfSDavid du Colombier 	{"notrace",	TRACE,		0,		":notrace:"},
13127dd7cddfSDavid du Colombier 	{"np_",		NONPROGRESS,	0,		0},
13137dd7cddfSDavid du Colombier 	{"od",		OD,		0,		0},
13147dd7cddfSDavid du Colombier 	{"of",		OF,		0,		0},
13157dd7cddfSDavid du Colombier 	{"pc_value",	PC_VAL,		0,		0},
1316312a1df1SDavid du Colombier 	{"pid",		TYPE,		BYTE,		0},
13177dd7cddfSDavid du Colombier 	{"printf",	PRINT,		0,		0},
1318312a1df1SDavid du Colombier 	{"printm",	PRINTM,		0,		0},
13197dd7cddfSDavid du Colombier 	{"priority",	PRIORITY,	0,		0},
13207dd7cddfSDavid du Colombier 	{"proctype",	PROCTYPE,	0,		0},
13217dd7cddfSDavid du Colombier 	{"provided",	PROVIDED,	0,		0},
13227dd7cddfSDavid du Colombier 	{"run",		RUN,		0,		0},
13237dd7cddfSDavid du Colombier 	{"d_step",	D_STEP,		0,		0},
1324*00d97012SDavid du Colombier 	{"select",	SELECT,		0,	0},
13257dd7cddfSDavid du Colombier 	{"short",	TYPE,		SHORT,		0},
13267dd7cddfSDavid du Colombier 	{"skip",	CONST,		1,		0},
13277dd7cddfSDavid du Colombier 	{"timeout",	TIMEOUT,	0,		0},
13287dd7cddfSDavid du Colombier 	{"trace",	TRACE,		0,		":trace:"},
13297dd7cddfSDavid du Colombier 	{"true",	CONST,		1,		0},
13307dd7cddfSDavid du Colombier 	{"show",	SHOW,		0,		":show:"},
13317dd7cddfSDavid du Colombier 	{"typedef",	TYPEDEF,	0,		0},
13327dd7cddfSDavid du Colombier 	{"unless",	UNLESS,		0,		0},
13337dd7cddfSDavid du Colombier 	{"unsigned",	TYPE,		UNSIGNED,	0},
13347dd7cddfSDavid du Colombier 	{"xr",		XU,		XR,		0},
13357dd7cddfSDavid du Colombier 	{"xs",		XU,		XS,		0},
13367dd7cddfSDavid du Colombier 	{0, 		0,		0,		0},
1337219b2ee8SDavid du Colombier };
1338219b2ee8SDavid du Colombier 
13397dd7cddfSDavid du Colombier static int
check_name(char * s)1340219b2ee8SDavid du Colombier check_name(char *s)
1341312a1df1SDavid du Colombier {	int i;
1342219b2ee8SDavid du Colombier 
1343219b2ee8SDavid du Colombier 	yylval = nn(ZN, 0, ZN, ZN);
1344*00d97012SDavid du Colombier 
1345*00d97012SDavid du Colombier 	if (ltl_mode)
1346*00d97012SDavid du Colombier 	{	for (i = 0; LTL_syms[i].s; i++)
1347*00d97012SDavid du Colombier 		{	if (strcmp(s, LTL_syms[i].s) == 0)
1348*00d97012SDavid du Colombier 			{	return LTL_syms[i].tok;
1349*00d97012SDavid du Colombier 	}	}	}
1350*00d97012SDavid du Colombier 
1351219b2ee8SDavid du Colombier 	for (i = 0; Names[i].s; i++)
1352*00d97012SDavid du Colombier 	{	if (strcmp(s, Names[i].s) == 0)
1353219b2ee8SDavid du Colombier 		{	yylval->val = Names[i].val;
1354219b2ee8SDavid du Colombier 			if (Names[i].sym)
1355219b2ee8SDavid du Colombier 				yylval->sym = lookup(Names[i].sym);
1356219b2ee8SDavid du Colombier 			return Names[i].tok;
1357*00d97012SDavid du Colombier 	}	}
1358219b2ee8SDavid du Colombier 
1359312a1df1SDavid du Colombier 	if ((yylval->val = ismtype(s)) != 0)
1360219b2ee8SDavid du Colombier 	{	yylval->ismtyp = 1;
1361219b2ee8SDavid du Colombier 		return CONST;
1362219b2ee8SDavid du Colombier 	}
1363219b2ee8SDavid du Colombier 
1364219b2ee8SDavid du Colombier 	if (strcmp(s, "_last") == 0)
1365219b2ee8SDavid du Colombier 		has_last++;
1366219b2ee8SDavid du Colombier 
13677dd7cddfSDavid du Colombier 	if (Inlining >= 0 && !ReDiRect)
13687dd7cddfSDavid du Colombier 	{	Lextok *tt, *t = Inline_stub[Inlining]->params;
1369312a1df1SDavid du Colombier 
1370312a1df1SDavid du Colombier 		for (i = 0; t; t = t->rgt, i++)				/* formal pars */
1371312a1df1SDavid du Colombier 		 if (!strcmp(s, t->lft->sym->name)			/* varname matches formal */
1372312a1df1SDavid du Colombier 		 &&   strcmp(s, Inline_stub[Inlining]->anms[i]) != 0)	/* actual pars */
13737dd7cddfSDavid du Colombier 		 {
13747dd7cddfSDavid du Colombier #if 0
13757dd7cddfSDavid du Colombier 			if (verbose&32)
13767dd7cddfSDavid du Colombier 			printf("\tline %d, replace %s in call of '%s' with %s\n",
13777dd7cddfSDavid du Colombier 				lineno, s,
13787dd7cddfSDavid du Colombier 				Inline_stub[Inlining]->nm->name,
13797dd7cddfSDavid du Colombier 				Inline_stub[Inlining]->anms[i]);
13807dd7cddfSDavid du Colombier #endif
1381312a1df1SDavid du Colombier 			for (tt = Inline_stub[Inlining]->params; tt; tt = tt->rgt)
13827dd7cddfSDavid du Colombier 				if (!strcmp(Inline_stub[Inlining]->anms[i],
13837dd7cddfSDavid du Colombier 					tt->lft->sym->name))
13847dd7cddfSDavid du Colombier 				{	/* would be cyclic if not caught */
1385*00d97012SDavid du Colombier 					printf("spin: %s:%d replacement value: %s\n",
1386*00d97012SDavid du Colombier 						oFname->name?oFname->name:"--", lineno, tt->lft->sym->name);
1387*00d97012SDavid du Colombier 					fatal("formal par of %s contains replacement value",
1388312a1df1SDavid du Colombier 						Inline_stub[Inlining]->nm->name);
13897dd7cddfSDavid du Colombier 					yylval->ntyp = tt->lft->ntyp;
13907dd7cddfSDavid du Colombier 					yylval->sym = lookup(tt->lft->sym->name);
13917dd7cddfSDavid du Colombier 					return NAME;
13927dd7cddfSDavid du Colombier 				}
1393*00d97012SDavid du Colombier 
1394*00d97012SDavid du Colombier 			/* check for occurrence of param as field of struct */
1395*00d97012SDavid du Colombier 			{ char *ptr = Inline_stub[Inlining]->anms[i];
1396*00d97012SDavid du Colombier 				while ((ptr = strstr(ptr, s)) != NULL)
1397*00d97012SDavid du Colombier 				{	if (*(ptr-1) == '.'
1398*00d97012SDavid du Colombier 					||  *(ptr+strlen(s)) == '.')
1399*00d97012SDavid du Colombier 					{	fatal("formal par of %s used in structure name",
1400*00d97012SDavid du Colombier 						Inline_stub[Inlining]->nm->name);
1401*00d97012SDavid du Colombier 					}
1402*00d97012SDavid du Colombier 					ptr++;
1403*00d97012SDavid du Colombier 			}	}
14047dd7cddfSDavid du Colombier 			ReDiRect = Inline_stub[Inlining]->anms[i];
14057dd7cddfSDavid du Colombier 			return 0;
14067dd7cddfSDavid du Colombier 	}	 }
1407219b2ee8SDavid du Colombier 
14087dd7cddfSDavid du Colombier 	yylval->sym = lookup(s);	/* symbol table */
1409219b2ee8SDavid du Colombier 	if (isutype(s))
1410219b2ee8SDavid du Colombier 		return UNAME;
1411219b2ee8SDavid du Colombier 	if (isproctype(s))
1412219b2ee8SDavid du Colombier 		return PNAME;
14137dd7cddfSDavid du Colombier 	if (iseqname(s))
14147dd7cddfSDavid du Colombier 		return INAME;
1415219b2ee8SDavid du Colombier 
1416219b2ee8SDavid du Colombier 	return NAME;
1417219b2ee8SDavid du Colombier }
1418219b2ee8SDavid du Colombier 
1419219b2ee8SDavid du Colombier int
yylex(void)1420219b2ee8SDavid du Colombier yylex(void)
1421219b2ee8SDavid du Colombier {	static int last = 0;
1422219b2ee8SDavid du Colombier 	static int hold = 0;
1423219b2ee8SDavid du Colombier 	int c;
1424219b2ee8SDavid du Colombier 	/*
1425219b2ee8SDavid du Colombier 	 * repair two common syntax mistakes with
1426219b2ee8SDavid du Colombier 	 * semi-colons before or after a '}'
1427219b2ee8SDavid du Colombier 	 */
1428219b2ee8SDavid du Colombier 	if (hold)
1429219b2ee8SDavid du Colombier 	{	c = hold;
1430219b2ee8SDavid du Colombier 		hold = 0;
1431219b2ee8SDavid du Colombier 	} else
1432219b2ee8SDavid du Colombier 	{	c = lex();
1433219b2ee8SDavid du Colombier 		if (last == ELSE
1434219b2ee8SDavid du Colombier 		&&  c != SEMI
1435219b2ee8SDavid du Colombier 		&&  c != FI)
1436219b2ee8SDavid du Colombier 		{	hold = c;
1437219b2ee8SDavid du Colombier 			last = 0;
1438219b2ee8SDavid du Colombier 			return SEMI;
1439219b2ee8SDavid du Colombier 		}
1440219b2ee8SDavid du Colombier 		if (last == '}'
1441219b2ee8SDavid du Colombier 		&&  c != PROCTYPE
1442219b2ee8SDavid du Colombier 		&&  c != INIT
1443219b2ee8SDavid du Colombier 		&&  c != CLAIM
1444219b2ee8SDavid du Colombier 		&&  c != SEP
1445219b2ee8SDavid du Colombier 		&&  c != FI
1446219b2ee8SDavid du Colombier 		&&  c != OD
1447219b2ee8SDavid du Colombier 		&&  c != '}'
1448219b2ee8SDavid du Colombier 		&&  c != UNLESS
1449219b2ee8SDavid du Colombier 		&&  c != SEMI
1450219b2ee8SDavid du Colombier 		&&  c != EOF)
1451219b2ee8SDavid du Colombier 		{	hold = c;
1452219b2ee8SDavid du Colombier 			last = 0;
1453219b2ee8SDavid du Colombier 			return SEMI;	/* insert ';' */
1454219b2ee8SDavid du Colombier 		}
1455219b2ee8SDavid du Colombier 		if (c == SEMI)
1456312a1df1SDavid du Colombier 		{	/* if context, we're not in a typedef
1457219b2ee8SDavid du Colombier 			 * because they're global.
1458219b2ee8SDavid du Colombier 			 * if owner, we're at the end of a ref
1459219b2ee8SDavid du Colombier 			 * to a struct field -- prevent that the
1460219b2ee8SDavid du Colombier 			 * lookahead is interpreted as a field of
1461219b2ee8SDavid du Colombier 			 * the same struct...
1462219b2ee8SDavid du Colombier 			 */
1463219b2ee8SDavid du Colombier 			if (context) owner = ZS;
1464219b2ee8SDavid du Colombier 			hold = lex();	/* look ahead */
1465219b2ee8SDavid du Colombier 			if (hold == '}'
1466219b2ee8SDavid du Colombier 			||  hold == SEMI)
1467219b2ee8SDavid du Colombier 			{	c = hold; /* omit ';' */
1468219b2ee8SDavid du Colombier 				hold = 0;
1469219b2ee8SDavid du Colombier 			}
1470219b2ee8SDavid du Colombier 		}
1471219b2ee8SDavid du Colombier 	}
1472219b2ee8SDavid du Colombier 	last = c;
14737dd7cddfSDavid du Colombier 
14747dd7cddfSDavid du Colombier 	if (IArgs)
14757dd7cddfSDavid du Colombier 	{	static int IArg_nst = 0;
1476312a1df1SDavid du Colombier 
14777dd7cddfSDavid du Colombier 		if (strcmp(yytext, ",") == 0)
14787dd7cddfSDavid du Colombier 		{	IArg_cont[++IArgno][0] = '\0';
14797dd7cddfSDavid du Colombier 		} else if (strcmp(yytext, "(") == 0)
14807dd7cddfSDavid du Colombier 		{	if (IArg_nst++ == 0)
14817dd7cddfSDavid du Colombier 			{	IArgno = 0;
14827dd7cddfSDavid du Colombier 				IArg_cont[0][0] = '\0';
14837dd7cddfSDavid du Colombier 			} else
14847dd7cddfSDavid du Colombier 				strcat(IArg_cont[IArgno], yytext);
1485312a1df1SDavid du Colombier 		} else if (strcmp(yytext, ")") == 0)
1486312a1df1SDavid du Colombier 		{	if (--IArg_nst > 0)
1487312a1df1SDavid du Colombier 				strcat(IArg_cont[IArgno], yytext);
1488312a1df1SDavid du Colombier 		} else if (c == CONST && yytext[0] == '\'')
1489312a1df1SDavid du Colombier 		{	sprintf(yytext, "'%c'", yylval->val);
1490312a1df1SDavid du Colombier 			strcat(IArg_cont[IArgno], yytext);
1491*00d97012SDavid du Colombier 		} else if (c == CONST)
1492*00d97012SDavid du Colombier 		{	sprintf(yytext, "%d", yylval->val);
1493*00d97012SDavid du Colombier 			strcat(IArg_cont[IArgno], yytext);
1494312a1df1SDavid du Colombier 		} else
1495f3793cddSDavid du Colombier 		{
1496f3793cddSDavid du Colombier 			switch (c) {
1497f3793cddSDavid du Colombier 			case SEP:	strcpy(yytext, "::"); break;
1498f3793cddSDavid du Colombier 			case SEMI:	strcpy(yytext, ";"); break;
1499f3793cddSDavid du Colombier 			case DECR:	strcpy(yytext, "--"); break;
1500f3793cddSDavid du Colombier 			case INCR: 	strcpy(yytext, "++"); break;
1501f3793cddSDavid du Colombier 			case LSHIFT:	strcpy(yytext, "<<"); break;
1502f3793cddSDavid du Colombier 			case RSHIFT:	strcpy(yytext, ">>"); break;
1503f3793cddSDavid du Colombier 			case LE:	strcpy(yytext, "<="); break;
1504f3793cddSDavid du Colombier 			case LT:	strcpy(yytext, "<"); break;
1505f3793cddSDavid du Colombier 			case GE:	strcpy(yytext, ">="); break;
1506f3793cddSDavid du Colombier 			case GT:	strcpy(yytext, ">"); break;
1507f3793cddSDavid du Colombier 			case EQ:	strcpy(yytext, "=="); break;
1508f3793cddSDavid du Colombier 			case ASGN:	strcpy(yytext, "="); break;
1509f3793cddSDavid du Colombier 			case NE:	strcpy(yytext, "!="); break;
1510f3793cddSDavid du Colombier 			case R_RCV:	strcpy(yytext, "??"); break;
1511f3793cddSDavid du Colombier 			case RCV:	strcpy(yytext, "?"); break;
1512f3793cddSDavid du Colombier 			case O_SND:	strcpy(yytext, "!!"); break;
1513f3793cddSDavid du Colombier 			case SND:	strcpy(yytext, "!"); break;
1514f3793cddSDavid du Colombier 			case AND: 	strcpy(yytext, "&&"); break;
1515f3793cddSDavid du Colombier 			case OR:	strcpy(yytext, "||"); break;
1516f3793cddSDavid du Colombier 			}
1517f3793cddSDavid du Colombier 			strcat(IArg_cont[IArgno], yytext);
1518312a1df1SDavid du Colombier 		}
15197dd7cddfSDavid du Colombier 	}
1520219b2ee8SDavid du Colombier 	return c;
1521219b2ee8SDavid du Colombier }
1522