1219b2ee8SDavid du Colombier /***** spin: spinlex.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
97dd7cddfSDavid du Colombier #include <stdlib.h>
10*de2caf28SDavid du Colombier #include <assert.h>
11*de2caf28SDavid du Colombier #include <errno.h>
12*de2caf28SDavid du Colombier #include <ctype.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 */
24*de2caf28SDavid du Colombier Lextok *rval; /* variable to assign return value, if any */
257dd7cddfSDavid du Colombier char **anms; /* literal text for actual pars */
26312a1df1SDavid du Colombier char *prec; /* precondition for c_code or c_expr */
2700d97012SDavid du Colombier int uiid; /* unique inline id */
28*de2caf28SDavid du Colombier int is_expr; /* c_expr in an ltl formula */
297dd7cddfSDavid du Colombier int dln, cln; /* def and call linenr */
307dd7cddfSDavid du Colombier Symbol *dfn, *cfn; /* def and call filename */
317dd7cddfSDavid du Colombier struct IType *nxt; /* linked list */
327dd7cddfSDavid du Colombier } IType;
33219b2ee8SDavid du Colombier
34312a1df1SDavid du Colombier typedef struct C_Added {
35312a1df1SDavid du Colombier Symbol *s;
36312a1df1SDavid du Colombier Symbol *t;
37312a1df1SDavid du Colombier Symbol *ival;
38*de2caf28SDavid du Colombier Symbol *fnm;
39*de2caf28SDavid du Colombier int lno;
40312a1df1SDavid du Colombier struct C_Added *nxt;
41312a1df1SDavid du Colombier } C_Added;
42219b2ee8SDavid du Colombier
43*de2caf28SDavid du Colombier extern RunList *X_lst;
44*de2caf28SDavid du Colombier extern ProcList *ready;
4500d97012SDavid du Colombier extern Symbol *Fname, *oFname;
46312a1df1SDavid du Colombier extern Symbol *context, *owner;
47312a1df1SDavid du Colombier extern YYSTYPE yylval;
48*de2caf28SDavid du Colombier extern short has_last, has_code, has_priority;
49*de2caf28SDavid du Colombier extern int verbose, IArgs, hastrack, separate, in_for;
50*de2caf28SDavid du Colombier extern int implied_semis, ltl_mode, in_seq, par_cnt;
51312a1df1SDavid du Colombier
52312a1df1SDavid du Colombier short has_stack = 0;
53312a1df1SDavid du Colombier int lineno = 1;
5400d97012SDavid du Colombier int scope_seq[128], scope_level = 0;
5500d97012SDavid du Colombier char CurScope[MAXSCOPESZ];
567dd7cddfSDavid du Colombier char yytext[2048];
577dd7cddfSDavid du Colombier FILE *yyin, *yyout;
58219b2ee8SDavid du Colombier
59312a1df1SDavid du Colombier static C_Added *c_added, *c_tracked;
60312a1df1SDavid du Colombier static IType *Inline_stub[MAXINL];
617dd7cddfSDavid du Colombier static char *ReDiRect;
62312a1df1SDavid du Colombier static char *Inliner[MAXINL], IArg_cont[MAXPAR][MAXLEN];
63312a1df1SDavid du Colombier static unsigned char in_comment=0;
64312a1df1SDavid du Colombier static int IArgno = 0, Inlining = -1;
657dd7cddfSDavid du Colombier static int check_name(char *);
66*de2caf28SDavid du Colombier static int last_token = 0;
677dd7cddfSDavid du Colombier
687dd7cddfSDavid du Colombier #define ValToken(x, y) { if (in_comment) goto again; \
69*de2caf28SDavid du Colombier yylval = nn(ZN,0,ZN,ZN); \
70*de2caf28SDavid du Colombier yylval->val = x; \
71*de2caf28SDavid du Colombier last_token = y; \
72*de2caf28SDavid du Colombier return y; \
73*de2caf28SDavid du Colombier }
747dd7cddfSDavid du Colombier
757dd7cddfSDavid du Colombier #define SymToken(x, y) { if (in_comment) goto again; \
76*de2caf28SDavid du Colombier yylval = nn(ZN,0,ZN,ZN); \
77*de2caf28SDavid du Colombier yylval->sym = x; \
78*de2caf28SDavid du Colombier last_token = y; \
79*de2caf28SDavid du Colombier return y; \
80*de2caf28SDavid du Colombier }
81219b2ee8SDavid du Colombier
82312a1df1SDavid du Colombier static int getinline(void);
83312a1df1SDavid du Colombier static void uninline(void);
84312a1df1SDavid du Colombier
85*de2caf28SDavid du Colombier static int PushBack;
86*de2caf28SDavid du Colombier static int PushedBack;
87*de2caf28SDavid du Colombier static char pushedback[4096];
88219b2ee8SDavid du Colombier
89*de2caf28SDavid du Colombier static void
push_back(char * s)90*de2caf28SDavid du Colombier push_back(char *s)
91*de2caf28SDavid du Colombier {
92*de2caf28SDavid du Colombier if (PushedBack + strlen(s) > 4094)
93*de2caf28SDavid du Colombier { fatal("select statement too large", 0);
94*de2caf28SDavid du Colombier }
95*de2caf28SDavid du Colombier strcat(pushedback, s);
96*de2caf28SDavid du Colombier PushedBack += strlen(s);
97*de2caf28SDavid du Colombier }
98312a1df1SDavid du Colombier
99312a1df1SDavid du Colombier static int
Getchar(void)100312a1df1SDavid du Colombier Getchar(void)
101312a1df1SDavid du Colombier { int c;
10200d97012SDavid du Colombier
103*de2caf28SDavid du Colombier if (PushedBack > 0 && PushBack < PushedBack)
104*de2caf28SDavid du Colombier { c = pushedback[PushBack++];
105*de2caf28SDavid du Colombier if (PushBack == PushedBack)
106*de2caf28SDavid du Colombier { pushedback[0] = '\0';
107*de2caf28SDavid du Colombier PushBack = PushedBack = 0;
108*de2caf28SDavid du Colombier }
109*de2caf28SDavid du Colombier return c; /* expanded select statement */
110*de2caf28SDavid du Colombier }
111312a1df1SDavid du Colombier if (Inlining<0)
112*de2caf28SDavid du Colombier { do { c = getc(yyin);
113*de2caf28SDavid du Colombier } while (c == 0); // ignore null chars
114*de2caf28SDavid du Colombier // eventually there will always be an EOF
115*de2caf28SDavid du Colombier } else
116*de2caf28SDavid du Colombier { c = getinline();
117*de2caf28SDavid du Colombier }
118*de2caf28SDavid du Colombier #if 0
11900d97012SDavid du Colombier if (0)
12000d97012SDavid du Colombier { printf("<%c:%d>[%d] ", c, c, Inlining);
12100d97012SDavid du Colombier } else
12200d97012SDavid du Colombier { printf("%c", c);
12300d97012SDavid du Colombier }
124*de2caf28SDavid du Colombier #endif
125312a1df1SDavid du Colombier return c;
126312a1df1SDavid du Colombier }
127312a1df1SDavid du Colombier
128312a1df1SDavid du Colombier static void
Ungetch(int c)129312a1df1SDavid du Colombier Ungetch(int c)
130312a1df1SDavid du Colombier {
131*de2caf28SDavid du Colombier if (PushedBack > 0 && PushBack > 0)
132*de2caf28SDavid du Colombier { PushBack--;
133*de2caf28SDavid du Colombier return;
134*de2caf28SDavid du Colombier }
135*de2caf28SDavid du Colombier
136312a1df1SDavid du Colombier if (Inlining<0)
137*de2caf28SDavid du Colombier { ungetc(c,yyin);
138*de2caf28SDavid du Colombier } else
139*de2caf28SDavid du Colombier { uninline();
140*de2caf28SDavid du Colombier }
14100d97012SDavid du Colombier if (0)
142*de2caf28SDavid du Colombier { printf("\n<bs{%d}bs>\n", c);
14300d97012SDavid du Colombier }
144312a1df1SDavid du Colombier }
1457dd7cddfSDavid du Colombier
1467dd7cddfSDavid du Colombier static int
notdollar(int c)14700d97012SDavid du Colombier notdollar(int c)
14800d97012SDavid du Colombier { return (c != '$' && c != '\n');
14900d97012SDavid du Colombier }
15000d97012SDavid du Colombier
15100d97012SDavid du Colombier static int
notquote(int c)152219b2ee8SDavid du Colombier notquote(int c)
153219b2ee8SDavid du Colombier { return (c != '\"' && c != '\n');
154219b2ee8SDavid du Colombier }
155219b2ee8SDavid du Colombier
156219b2ee8SDavid du Colombier int
isalnum_(int c)157219b2ee8SDavid du Colombier isalnum_(int c)
158219b2ee8SDavid du Colombier { return (isalnum(c) || c == '_');
159219b2ee8SDavid du Colombier }
160219b2ee8SDavid du Colombier
1617dd7cddfSDavid du Colombier static int
isalpha_(int c)1627dd7cddfSDavid du Colombier isalpha_(int c)
1637dd7cddfSDavid du Colombier { return isalpha(c); /* could be macro */
1647dd7cddfSDavid du Colombier }
1657dd7cddfSDavid du Colombier
1667dd7cddfSDavid du Colombier static int
isdigit_(int c)1677dd7cddfSDavid du Colombier isdigit_(int c)
1687dd7cddfSDavid du Colombier { return isdigit(c); /* could be macro */
1697dd7cddfSDavid du Colombier }
1707dd7cddfSDavid du Colombier
1717dd7cddfSDavid du Colombier static void
getword(int first,int (* tst)(int))172219b2ee8SDavid du Colombier getword(int first, int (*tst)(int))
17300d97012SDavid du Colombier { int i=0, c;
174219b2ee8SDavid du Colombier
1757dd7cddfSDavid du Colombier yytext[i++]= (char) first;
176219b2ee8SDavid du Colombier while (tst(c = Getchar()))
177*de2caf28SDavid du Colombier { if (c == EOF)
178*de2caf28SDavid du Colombier { break;
179*de2caf28SDavid du Colombier }
180*de2caf28SDavid du Colombier yytext[i++] = (char) c;
181312a1df1SDavid du Colombier if (c == '\\')
18200d97012SDavid du Colombier { c = Getchar();
18300d97012SDavid du Colombier yytext[i++] = (char) c; /* no tst */
18400d97012SDavid du Colombier } }
185219b2ee8SDavid du Colombier yytext[i] = '\0';
186*de2caf28SDavid du Colombier
187219b2ee8SDavid du Colombier Ungetch(c);
188219b2ee8SDavid du Colombier }
189219b2ee8SDavid du Colombier
1907dd7cddfSDavid du Colombier static int
follow(int tok,int ifyes,int ifno)191219b2ee8SDavid du Colombier follow(int tok, int ifyes, int ifno)
192219b2ee8SDavid du Colombier { int c;
193219b2ee8SDavid du Colombier
194219b2ee8SDavid du Colombier if ((c = Getchar()) == tok)
195*de2caf28SDavid du Colombier { return ifyes;
196*de2caf28SDavid du Colombier }
197219b2ee8SDavid du Colombier Ungetch(c);
198219b2ee8SDavid du Colombier
199219b2ee8SDavid du Colombier return ifno;
200219b2ee8SDavid du Colombier }
201219b2ee8SDavid du Colombier
2027dd7cddfSDavid du Colombier static IType *seqnames;
2037dd7cddfSDavid du Colombier
2047dd7cddfSDavid du Colombier static void
def_inline(Symbol * s,int ln,char * ptr,char * prc,Lextok * nms)205312a1df1SDavid du Colombier def_inline(Symbol *s, int ln, char *ptr, char *prc, Lextok *nms)
2067dd7cddfSDavid du Colombier { IType *tmp;
20700d97012SDavid du Colombier int cnt = 0;
20800d97012SDavid du Colombier char *nw = (char *) emalloc(strlen(ptr)+1);
2097dd7cddfSDavid du Colombier strcpy(nw, ptr);
2107dd7cddfSDavid du Colombier
21100d97012SDavid du Colombier for (tmp = seqnames; tmp; cnt++, tmp = tmp->nxt)
2127dd7cddfSDavid du Colombier if (!strcmp(s->name, tmp->nm->name))
2137dd7cddfSDavid du Colombier { non_fatal("procedure name %s redefined",
2147dd7cddfSDavid du Colombier tmp->nm->name);
2157dd7cddfSDavid du Colombier tmp->cn = (Lextok *) nw;
2167dd7cddfSDavid du Colombier tmp->params = nms;
2177dd7cddfSDavid du Colombier tmp->dln = ln;
2187dd7cddfSDavid du Colombier tmp->dfn = Fname;
2197dd7cddfSDavid du Colombier return;
2207dd7cddfSDavid du Colombier }
2217dd7cddfSDavid du Colombier tmp = (IType *) emalloc(sizeof(IType));
2227dd7cddfSDavid du Colombier tmp->nm = s;
2237dd7cddfSDavid du Colombier tmp->cn = (Lextok *) nw;
2247dd7cddfSDavid du Colombier tmp->params = nms;
225312a1df1SDavid du Colombier if (strlen(prc) > 0)
22600d97012SDavid du Colombier { tmp->prec = (char *) emalloc(strlen(prc)+1);
227312a1df1SDavid du Colombier strcpy(tmp->prec, prc);
228312a1df1SDavid du Colombier }
2297dd7cddfSDavid du Colombier tmp->dln = ln;
2307dd7cddfSDavid du Colombier tmp->dfn = Fname;
23100d97012SDavid du Colombier tmp->uiid = cnt+1; /* so that 0 means: not an inline */
2327dd7cddfSDavid du Colombier tmp->nxt = seqnames;
2337dd7cddfSDavid du Colombier seqnames = tmp;
2347dd7cddfSDavid du Colombier }
2357dd7cddfSDavid du Colombier
236312a1df1SDavid du Colombier void
gencodetable(FILE * fd)237312a1df1SDavid du Colombier gencodetable(FILE *fd)
238312a1df1SDavid du Colombier { IType *tmp;
239312a1df1SDavid du Colombier char *q;
240312a1df1SDavid du Colombier int cnt;
241312a1df1SDavid du Colombier
242312a1df1SDavid du Colombier if (separate == 2) return;
243312a1df1SDavid du Colombier
244312a1df1SDavid du Colombier fprintf(fd, "struct {\n");
245312a1df1SDavid du Colombier fprintf(fd, " char *c; char *t;\n");
246312a1df1SDavid du Colombier fprintf(fd, "} code_lookup[] = {\n");
247312a1df1SDavid du Colombier
248312a1df1SDavid du Colombier if (has_code)
249312a1df1SDavid du Colombier for (tmp = seqnames; tmp; tmp = tmp->nxt)
250312a1df1SDavid du Colombier if (tmp->nm->type == CODE_FRAG
251312a1df1SDavid du Colombier || tmp->nm->type == CODE_DECL)
252312a1df1SDavid du Colombier { fprintf(fd, "\t{ \"%s\", ",
253312a1df1SDavid du Colombier tmp->nm->name);
254312a1df1SDavid du Colombier q = (char *) tmp->cn;
255312a1df1SDavid du Colombier
256312a1df1SDavid du Colombier while (*q == '\n' || *q == '\r' || *q == '\\')
257312a1df1SDavid du Colombier q++;
258312a1df1SDavid du Colombier
259312a1df1SDavid du Colombier fprintf(fd, "\"");
260312a1df1SDavid du Colombier cnt = 0;
261312a1df1SDavid du Colombier while (*q && cnt < 1024) /* pangen1.h allows 2048 */
262312a1df1SDavid du Colombier { switch (*q) {
263312a1df1SDavid du Colombier case '"':
264312a1df1SDavid du Colombier fprintf(fd, "\\\"");
265312a1df1SDavid du Colombier break;
266312a1df1SDavid du Colombier case '%':
267312a1df1SDavid du Colombier fprintf(fd, "%%");
268312a1df1SDavid du Colombier break;
269312a1df1SDavid du Colombier case '\n':
270312a1df1SDavid du Colombier fprintf(fd, "\\n");
271312a1df1SDavid du Colombier break;
272312a1df1SDavid du Colombier default:
273312a1df1SDavid du Colombier putc(*q, fd);
274312a1df1SDavid du Colombier break;
275312a1df1SDavid du Colombier }
276312a1df1SDavid du Colombier q++; cnt++;
277312a1df1SDavid du Colombier }
278312a1df1SDavid du Colombier if (*q) fprintf(fd, "...");
279312a1df1SDavid du Colombier fprintf(fd, "\"");
280312a1df1SDavid du Colombier fprintf(fd, " },\n");
281312a1df1SDavid du Colombier }
282312a1df1SDavid du Colombier
283312a1df1SDavid du Colombier fprintf(fd, " { (char *) 0, \"\" }\n");
284312a1df1SDavid du Colombier fprintf(fd, "};\n");
285312a1df1SDavid du Colombier }
286312a1df1SDavid du Colombier
2877dd7cddfSDavid du Colombier static int
iseqname(char * t)2887dd7cddfSDavid du Colombier iseqname(char *t)
2897dd7cddfSDavid du Colombier { IType *tmp;
2907dd7cddfSDavid du Colombier
2917dd7cddfSDavid du Colombier for (tmp = seqnames; tmp; tmp = tmp->nxt)
2927dd7cddfSDavid du Colombier { if (!strcmp(t, tmp->nm->name))
2937dd7cddfSDavid du Colombier return 1;
2947dd7cddfSDavid du Colombier }
2957dd7cddfSDavid du Colombier return 0;
2967dd7cddfSDavid du Colombier }
2977dd7cddfSDavid du Colombier
298*de2caf28SDavid du Colombier Lextok *
return_statement(Lextok * n)299*de2caf28SDavid du Colombier return_statement(Lextok *n)
300*de2caf28SDavid du Colombier {
301*de2caf28SDavid du Colombier if (Inline_stub[Inlining]->rval)
302*de2caf28SDavid du Colombier { Lextok *g = nn(ZN, NAME, ZN, ZN);
303*de2caf28SDavid du Colombier Lextok *h = Inline_stub[Inlining]->rval;
304*de2caf28SDavid du Colombier g->sym = lookup("rv_");
305*de2caf28SDavid du Colombier return nn(h, ASGN, h, n);
306*de2caf28SDavid du Colombier } else
307*de2caf28SDavid du Colombier { fatal("return statement outside inline", (char *) 0);
308*de2caf28SDavid du Colombier }
309*de2caf28SDavid du Colombier return ZN;
310*de2caf28SDavid du Colombier }
311*de2caf28SDavid du Colombier
3127dd7cddfSDavid du Colombier static int
getinline(void)3137dd7cddfSDavid du Colombier getinline(void)
3147dd7cddfSDavid du Colombier { int c;
3157dd7cddfSDavid du Colombier
3167dd7cddfSDavid du Colombier if (ReDiRect)
3177dd7cddfSDavid du Colombier { c = *ReDiRect++;
3187dd7cddfSDavid du Colombier if (c == '\0')
3197dd7cddfSDavid du Colombier { ReDiRect = (char *) 0;
3207dd7cddfSDavid du Colombier c = *Inliner[Inlining]++;
3217dd7cddfSDavid du Colombier }
3227dd7cddfSDavid du Colombier } else
323*de2caf28SDavid du Colombier {
3247dd7cddfSDavid du Colombier c = *Inliner[Inlining]++;
325*de2caf28SDavid du Colombier }
3267dd7cddfSDavid du Colombier
3277dd7cddfSDavid du Colombier if (c == '\0')
328*de2caf28SDavid du Colombier {
329*de2caf28SDavid du Colombier lineno = Inline_stub[Inlining]->cln;
3307dd7cddfSDavid du Colombier Fname = Inline_stub[Inlining]->cfn;
3317dd7cddfSDavid du Colombier Inlining--;
332*de2caf28SDavid du Colombier
3337dd7cddfSDavid du Colombier #if 0
3347dd7cddfSDavid du Colombier if (verbose&32)
33500d97012SDavid du Colombier printf("spin: %s:%d, done inlining %s\n",
33600d97012SDavid du Colombier Fname, lineno, Inline_stub[Inlining+1]->nm->name);
3377dd7cddfSDavid du Colombier #endif
3387dd7cddfSDavid du Colombier return Getchar();
3397dd7cddfSDavid du Colombier }
3407dd7cddfSDavid du Colombier return c;
3417dd7cddfSDavid du Colombier }
3427dd7cddfSDavid du Colombier
3437dd7cddfSDavid du Colombier static void
uninline(void)3447dd7cddfSDavid du Colombier uninline(void)
3457dd7cddfSDavid du Colombier {
3467dd7cddfSDavid du Colombier if (ReDiRect)
3477dd7cddfSDavid du Colombier ReDiRect--;
3487dd7cddfSDavid du Colombier else
3497dd7cddfSDavid du Colombier Inliner[Inlining]--;
3507dd7cddfSDavid du Colombier }
3517dd7cddfSDavid du Colombier
35200d97012SDavid du Colombier int
is_inline(void)35300d97012SDavid du Colombier is_inline(void)
35400d97012SDavid du Colombier {
35500d97012SDavid du Colombier if (Inlining < 0)
35600d97012SDavid du Colombier return 0; /* i.e., not an inline */
35700d97012SDavid du Colombier if (Inline_stub[Inlining] == NULL)
35800d97012SDavid du Colombier fatal("unexpected, inline_stub not set", 0);
35900d97012SDavid du Colombier return Inline_stub[Inlining]->uiid;
36000d97012SDavid du Colombier }
36100d97012SDavid du Colombier
362312a1df1SDavid du Colombier IType *
find_inline(char * s)363312a1df1SDavid du Colombier find_inline(char *s)
364312a1df1SDavid du Colombier { IType *tmp;
365312a1df1SDavid du Colombier
366312a1df1SDavid du Colombier for (tmp = seqnames; tmp; tmp = tmp->nxt)
367312a1df1SDavid du Colombier if (!strcmp(s, tmp->nm->name))
368312a1df1SDavid du Colombier break;
369312a1df1SDavid du Colombier if (!tmp)
370312a1df1SDavid du Colombier fatal("cannot happen, missing inline def %s", s);
37100d97012SDavid du Colombier
372312a1df1SDavid du Colombier return tmp;
373312a1df1SDavid du Colombier }
374312a1df1SDavid du Colombier
375312a1df1SDavid du Colombier void
c_state(Symbol * s,Symbol * t,Symbol * ival)376312a1df1SDavid du Colombier c_state(Symbol *s, Symbol *t, Symbol *ival) /* name, scope, ival */
377312a1df1SDavid du Colombier { C_Added *r;
378312a1df1SDavid du Colombier
379312a1df1SDavid du Colombier r = (C_Added *) emalloc(sizeof(C_Added));
380312a1df1SDavid du Colombier r->s = s; /* pointer to a data object */
381312a1df1SDavid du Colombier r->t = t; /* size of object, or "global", or "local proctype_name" */
382312a1df1SDavid du Colombier r->ival = ival;
383*de2caf28SDavid du Colombier r->lno = lineno;
384*de2caf28SDavid du Colombier r->fnm = Fname;
385312a1df1SDavid du Colombier r->nxt = c_added;
386*de2caf28SDavid du Colombier
387*de2caf28SDavid du Colombier if(strncmp(r->s->name, "\"unsigned unsigned", 18) == 0)
388*de2caf28SDavid du Colombier { int i;
389*de2caf28SDavid du Colombier for (i = 10; i < 18; i++)
390*de2caf28SDavid du Colombier { r->s->name[i] = ' ';
391*de2caf28SDavid du Colombier }
392*de2caf28SDavid du Colombier /* printf("corrected <%s>\n", r->s->name); */
393*de2caf28SDavid du Colombier }
394312a1df1SDavid du Colombier c_added = r;
395312a1df1SDavid du Colombier }
396312a1df1SDavid du Colombier
397312a1df1SDavid du Colombier void
c_track(Symbol * s,Symbol * t,Symbol * stackonly)398312a1df1SDavid du Colombier c_track(Symbol *s, Symbol *t, Symbol *stackonly) /* name, size */
399312a1df1SDavid du Colombier { C_Added *r;
400312a1df1SDavid du Colombier
401312a1df1SDavid du Colombier r = (C_Added *) emalloc(sizeof(C_Added));
402312a1df1SDavid du Colombier r->s = s;
403312a1df1SDavid du Colombier r->t = t;
404312a1df1SDavid du Colombier r->ival = stackonly; /* abuse of name */
405312a1df1SDavid du Colombier r->nxt = c_tracked;
406*de2caf28SDavid du Colombier r->fnm = Fname;
407*de2caf28SDavid du Colombier r->lno = lineno;
408312a1df1SDavid du Colombier c_tracked = r;
409312a1df1SDavid du Colombier
410312a1df1SDavid du Colombier if (stackonly != ZS)
411312a1df1SDavid du Colombier { if (strcmp(stackonly->name, "\"Matched\"") == 0)
412312a1df1SDavid du Colombier r->ival = ZS; /* the default */
413312a1df1SDavid du Colombier else if (strcmp(stackonly->name, "\"UnMatched\"") != 0
414312a1df1SDavid du Colombier && strcmp(stackonly->name, "\"unMatched\"") != 0
415312a1df1SDavid du Colombier && strcmp(stackonly->name, "\"StackOnly\"") != 0)
416312a1df1SDavid du Colombier non_fatal("expecting '[Un]Matched', saw %s", stackonly->name);
417312a1df1SDavid du Colombier else
41800d97012SDavid du Colombier has_stack = 1; /* unmatched stack */
419312a1df1SDavid du Colombier }
420312a1df1SDavid du Colombier }
421312a1df1SDavid du Colombier
422312a1df1SDavid du Colombier char *
skip_white(char * p)423*de2caf28SDavid du Colombier skip_white(char *p)
424*de2caf28SDavid du Colombier {
425*de2caf28SDavid du Colombier if (p != NULL)
426*de2caf28SDavid du Colombier { while (*p == ' ' || *p == '\t')
427*de2caf28SDavid du Colombier p++;
428*de2caf28SDavid du Colombier } else
429*de2caf28SDavid du Colombier { fatal("bad format - 1", (char *) 0);
430*de2caf28SDavid du Colombier }
431*de2caf28SDavid du Colombier return p;
432*de2caf28SDavid du Colombier }
433312a1df1SDavid du Colombier
434*de2caf28SDavid du Colombier char *
skip_nonwhite(char * p)435*de2caf28SDavid du Colombier skip_nonwhite(char *p)
436*de2caf28SDavid du Colombier {
437*de2caf28SDavid du Colombier if (p != NULL)
438*de2caf28SDavid du Colombier { while (*p != ' ' && *p != '\t')
439*de2caf28SDavid du Colombier p++;
440*de2caf28SDavid du Colombier } else
441*de2caf28SDavid du Colombier { fatal("bad format - 2", (char *) 0);
442*de2caf28SDavid du Colombier }
443*de2caf28SDavid du Colombier return p;
444*de2caf28SDavid du Colombier }
445312a1df1SDavid du Colombier
446*de2caf28SDavid du Colombier static char *
jump_etc(C_Added * r)447*de2caf28SDavid du Colombier jump_etc(C_Added *r)
448*de2caf28SDavid du Colombier { char *op = r->s->name;
449*de2caf28SDavid du Colombier char *p = op;
450*de2caf28SDavid du Colombier char *q = (char *) 0;
451*de2caf28SDavid du Colombier int oln = lineno;
452*de2caf28SDavid du Colombier Symbol *ofnm = Fname;
453*de2caf28SDavid du Colombier
454*de2caf28SDavid du Colombier /* try to get the type separated from the name */
455*de2caf28SDavid du Colombier lineno = r->lno;
456*de2caf28SDavid du Colombier Fname = r->fnm;
457*de2caf28SDavid du Colombier
458*de2caf28SDavid du Colombier p = skip_white(p); /* initial white space */
459*de2caf28SDavid du Colombier
460*de2caf28SDavid du Colombier if (strncmp(p, "enum", strlen("enum")) == 0) /* special case: a two-part typename */
461*de2caf28SDavid du Colombier { p += strlen("enum")+1;
462*de2caf28SDavid du Colombier p = skip_white(p);
463*de2caf28SDavid du Colombier }
464*de2caf28SDavid du Colombier if (strncmp(p, "unsigned", strlen("unsigned")) == 0) /* possibly a two-part typename */
465*de2caf28SDavid du Colombier { p += strlen("unsigned")+1;
466*de2caf28SDavid du Colombier q = p = skip_white(p);
467*de2caf28SDavid du Colombier }
468*de2caf28SDavid du Colombier p = skip_nonwhite(p); /* type name */
469*de2caf28SDavid du Colombier p = skip_white(p); /* white space */
470*de2caf28SDavid du Colombier while (*p == '*') p++; /* decorations */
471*de2caf28SDavid du Colombier p = skip_white(p); /* white space */
472312a1df1SDavid du Colombier
473312a1df1SDavid du Colombier if (*p == '\0')
474*de2caf28SDavid du Colombier { if (q)
475*de2caf28SDavid du Colombier { p = q; /* unsigned with implied 'int' */
476*de2caf28SDavid du Colombier } else
477*de2caf28SDavid du Colombier { fatal("c_state format (%s)", op);
478*de2caf28SDavid du Colombier } }
479312a1df1SDavid du Colombier
480312a1df1SDavid du Colombier if (strchr(p, '[')
481*de2caf28SDavid du Colombier && (!r->ival
482*de2caf28SDavid du Colombier || !r->ival->name
483*de2caf28SDavid du Colombier || !strchr(r->ival->name, '{'))) /* was !strchr(p, '{')) */
484312a1df1SDavid du Colombier { non_fatal("array initialization error, c_state (%s)", p);
485*de2caf28SDavid du Colombier p = (char *) 0;
486312a1df1SDavid du Colombier }
487312a1df1SDavid du Colombier
488*de2caf28SDavid du Colombier lineno = oln;
489*de2caf28SDavid du Colombier Fname = ofnm;
490*de2caf28SDavid du Colombier
491312a1df1SDavid du Colombier return p;
492312a1df1SDavid du Colombier }
493312a1df1SDavid du Colombier
494312a1df1SDavid du Colombier void
c_add_globinit(FILE * fd)495312a1df1SDavid du Colombier c_add_globinit(FILE *fd)
496312a1df1SDavid du Colombier { C_Added *r;
497312a1df1SDavid du Colombier char *p, *q;
498312a1df1SDavid du Colombier
499312a1df1SDavid du Colombier fprintf(fd, "void\nglobinit(void)\n{\n");
500312a1df1SDavid du Colombier for (r = c_added; r; r = r->nxt)
501312a1df1SDavid du Colombier { if (r->ival == ZS)
502312a1df1SDavid du Colombier continue;
503312a1df1SDavid du Colombier
504312a1df1SDavid du Colombier if (strncmp(r->t->name, " Global ", strlen(" Global ")) == 0)
505312a1df1SDavid du Colombier { for (q = r->ival->name; *q; q++)
506312a1df1SDavid du Colombier { if (*q == '\"')
507312a1df1SDavid du Colombier *q = ' ';
508312a1df1SDavid du Colombier if (*q == '\\')
509312a1df1SDavid du Colombier *q++ = ' '; /* skip over the next */
510312a1df1SDavid du Colombier }
511*de2caf28SDavid du Colombier p = jump_etc(r); /* e.g., "int **q" */
512312a1df1SDavid du Colombier if (p)
513312a1df1SDavid du Colombier fprintf(fd, " now.%s = %s;\n", p, r->ival->name);
514312a1df1SDavid du Colombier
515312a1df1SDavid du Colombier } else
516312a1df1SDavid du Colombier if (strncmp(r->t->name, " Hidden ", strlen(" Hidden ")) == 0)
517312a1df1SDavid du Colombier { for (q = r->ival->name; *q; q++)
518312a1df1SDavid du Colombier { if (*q == '\"')
519312a1df1SDavid du Colombier *q = ' ';
520312a1df1SDavid du Colombier if (*q == '\\')
521312a1df1SDavid du Colombier *q++ = ' '; /* skip over the next */
522312a1df1SDavid du Colombier }
523*de2caf28SDavid du Colombier p = jump_etc(r); /* e.g., "int **q" */
524312a1df1SDavid du Colombier if (p)
525312a1df1SDavid du Colombier fprintf(fd, " %s = %s;\n", p, r->ival->name); /* no now. prefix */
526312a1df1SDavid du Colombier
527312a1df1SDavid du Colombier } }
528312a1df1SDavid du Colombier fprintf(fd, "}\n");
529312a1df1SDavid du Colombier }
530312a1df1SDavid du Colombier
531312a1df1SDavid du Colombier void
c_add_locinit(FILE * fd,int tpnr,char * pnm)532312a1df1SDavid du Colombier c_add_locinit(FILE *fd, int tpnr, char *pnm)
533312a1df1SDavid du Colombier { C_Added *r;
534312a1df1SDavid du Colombier char *p, *q, *s;
535312a1df1SDavid du Colombier int frst = 1;
536312a1df1SDavid du Colombier
537312a1df1SDavid du Colombier fprintf(fd, "void\nlocinit%d(int h)\n{\n", tpnr);
538312a1df1SDavid du Colombier for (r = c_added; r; r = r->nxt)
539312a1df1SDavid du Colombier if (r->ival != ZS
540312a1df1SDavid du Colombier && strncmp(r->t->name, " Local", strlen(" Local")) == 0)
541312a1df1SDavid du Colombier { for (q = r->ival->name; *q; q++)
542312a1df1SDavid du Colombier if (*q == '\"')
543312a1df1SDavid du Colombier *q = ' ';
544*de2caf28SDavid du Colombier p = jump_etc(r); /* e.g., "int **q" */
545312a1df1SDavid du Colombier
546312a1df1SDavid du Colombier q = r->t->name + strlen(" Local");
547312a1df1SDavid du Colombier while (*q == ' ' || *q == '\t')
548312a1df1SDavid du Colombier q++; /* process name */
549312a1df1SDavid du Colombier
550312a1df1SDavid du Colombier s = (char *) emalloc(strlen(q)+1);
551312a1df1SDavid du Colombier strcpy(s, q);
552312a1df1SDavid du Colombier
553312a1df1SDavid du Colombier q = &s[strlen(s)-1];
554312a1df1SDavid du Colombier while (*q == ' ' || *q == '\t')
555312a1df1SDavid du Colombier *q-- = '\0';
556312a1df1SDavid du Colombier
557312a1df1SDavid du Colombier if (strcmp(pnm, s) != 0)
558312a1df1SDavid du Colombier continue;
559312a1df1SDavid du Colombier
560312a1df1SDavid du Colombier if (frst)
561*de2caf28SDavid du Colombier { fprintf(fd, "\tuchar *_this = pptr(h);\n");
562312a1df1SDavid du Colombier frst = 0;
563312a1df1SDavid du Colombier }
564312a1df1SDavid du Colombier
565312a1df1SDavid du Colombier if (p)
566*de2caf28SDavid du Colombier { fprintf(fd, "\t\t((P%d *)_this)->%s = %s;\n",
567312a1df1SDavid du Colombier tpnr, p, r->ival->name);
568*de2caf28SDavid du Colombier }
569312a1df1SDavid du Colombier }
570312a1df1SDavid du Colombier fprintf(fd, "}\n");
571312a1df1SDavid du Colombier }
572312a1df1SDavid du Colombier
573312a1df1SDavid du Colombier /* tracking:
574312a1df1SDavid du Colombier 1. for non-global and non-local c_state decls: add up all the sizes in c_added
575312a1df1SDavid du Colombier 2. add a global char array of that size into now
576312a1df1SDavid du Colombier 3. generate a routine that memcpy's the required values into that array
577312a1df1SDavid du Colombier 4. generate a call to that routine
578312a1df1SDavid du Colombier */
579312a1df1SDavid du Colombier
580312a1df1SDavid du Colombier void
c_preview(void)581312a1df1SDavid du Colombier c_preview(void)
582312a1df1SDavid du Colombier { C_Added *r;
583312a1df1SDavid du Colombier
584312a1df1SDavid du Colombier hastrack = 0;
585312a1df1SDavid du Colombier if (c_tracked)
586312a1df1SDavid du Colombier hastrack = 1;
587312a1df1SDavid du Colombier else
588312a1df1SDavid du Colombier for (r = c_added; r; r = r->nxt)
589312a1df1SDavid du Colombier if (strncmp(r->t->name, " Global ", strlen(" Global ")) != 0
590312a1df1SDavid du Colombier && strncmp(r->t->name, " Hidden ", strlen(" Hidden ")) != 0
591312a1df1SDavid du Colombier && strncmp(r->t->name, " Local", strlen(" Local")) != 0)
592312a1df1SDavid du Colombier { hastrack = 1; /* c_state variant now obsolete */
593312a1df1SDavid du Colombier break;
594312a1df1SDavid du Colombier }
595312a1df1SDavid du Colombier }
596312a1df1SDavid du Colombier
597312a1df1SDavid du Colombier int
c_add_sv(FILE * fd)598312a1df1SDavid du Colombier c_add_sv(FILE *fd) /* 1+2 -- called in pangen1.c */
599312a1df1SDavid du Colombier { C_Added *r;
600312a1df1SDavid du Colombier int cnt = 0;
601312a1df1SDavid du Colombier
602312a1df1SDavid du Colombier if (!c_added && !c_tracked) return 0;
603312a1df1SDavid du Colombier
604312a1df1SDavid du Colombier for (r = c_added; r; r = r->nxt) /* pickup global decls */
605312a1df1SDavid du Colombier if (strncmp(r->t->name, " Global ", strlen(" Global ")) == 0)
606312a1df1SDavid du Colombier fprintf(fd, " %s;\n", r->s->name);
607312a1df1SDavid du Colombier
608312a1df1SDavid du Colombier for (r = c_added; r; r = r->nxt)
609312a1df1SDavid du Colombier if (strncmp(r->t->name, " Global ", strlen(" Global ")) != 0
610312a1df1SDavid du Colombier && strncmp(r->t->name, " Hidden ", strlen(" Hidden ")) != 0
611312a1df1SDavid du Colombier && strncmp(r->t->name, " Local", strlen(" Local")) != 0)
612312a1df1SDavid du Colombier { cnt++; /* obsolete use */
613312a1df1SDavid du Colombier }
614312a1df1SDavid du Colombier
615312a1df1SDavid du Colombier for (r = c_tracked; r; r = r->nxt)
616312a1df1SDavid du Colombier cnt++; /* preferred use */
617312a1df1SDavid du Colombier
618312a1df1SDavid du Colombier if (cnt == 0) return 0;
619312a1df1SDavid du Colombier
620312a1df1SDavid du Colombier cnt = 0;
621312a1df1SDavid du Colombier fprintf(fd, " uchar c_state[");
622312a1df1SDavid du Colombier for (r = c_added; r; r = r->nxt)
623312a1df1SDavid du Colombier if (strncmp(r->t->name, " Global ", strlen(" Global ")) != 0
624312a1df1SDavid du Colombier && strncmp(r->t->name, " Hidden ", strlen(" Hidden ")) != 0
625312a1df1SDavid du Colombier && strncmp(r->t->name, " Local", strlen(" Local")) != 0)
626312a1df1SDavid du Colombier { fprintf(fd, "%ssizeof(%s)",
627312a1df1SDavid du Colombier (cnt==0)?"":"+", r->t->name);
628312a1df1SDavid du Colombier cnt++;
629312a1df1SDavid du Colombier }
630312a1df1SDavid du Colombier
631312a1df1SDavid du Colombier for (r = c_tracked; r; r = r->nxt)
632312a1df1SDavid du Colombier { if (r->ival != ZS) continue;
633312a1df1SDavid du Colombier
634312a1df1SDavid du Colombier fprintf(fd, "%s%s",
635312a1df1SDavid du Colombier (cnt==0)?"":"+", r->t->name);
636312a1df1SDavid du Colombier cnt++;
637312a1df1SDavid du Colombier }
638312a1df1SDavid du Colombier
639312a1df1SDavid du Colombier if (cnt == 0) fprintf(fd, "4"); /* now redundant */
640312a1df1SDavid du Colombier fprintf(fd, "];\n");
641312a1df1SDavid du Colombier return 1;
642312a1df1SDavid du Colombier }
643312a1df1SDavid du Colombier
644312a1df1SDavid du Colombier void
c_stack_size(FILE * fd)64500d97012SDavid du Colombier c_stack_size(FILE *fd)
64600d97012SDavid du Colombier { C_Added *r;
64700d97012SDavid du Colombier int cnt = 0;
64800d97012SDavid du Colombier
64900d97012SDavid du Colombier for (r = c_tracked; r; r = r->nxt)
65000d97012SDavid du Colombier if (r->ival != ZS)
65100d97012SDavid du Colombier { fprintf(fd, "%s%s",
65200d97012SDavid du Colombier (cnt==0)?"":"+", r->t->name);
65300d97012SDavid du Colombier cnt++;
65400d97012SDavid du Colombier }
65500d97012SDavid du Colombier if (cnt == 0)
65600d97012SDavid du Colombier { fprintf(fd, "WS");
65700d97012SDavid du Colombier }
65800d97012SDavid du Colombier }
65900d97012SDavid du Colombier
66000d97012SDavid du Colombier void
c_add_stack(FILE * fd)661312a1df1SDavid du Colombier c_add_stack(FILE *fd)
662312a1df1SDavid du Colombier { C_Added *r;
663312a1df1SDavid du Colombier int cnt = 0;
664312a1df1SDavid du Colombier
66500d97012SDavid du Colombier if ((!c_added && !c_tracked) || !has_stack)
66600d97012SDavid du Colombier { return;
66700d97012SDavid du Colombier }
668312a1df1SDavid du Colombier
669312a1df1SDavid du Colombier for (r = c_tracked; r; r = r->nxt)
670312a1df1SDavid du Colombier if (r->ival != ZS)
67100d97012SDavid du Colombier { cnt++;
672312a1df1SDavid du Colombier }
673312a1df1SDavid du Colombier
67400d97012SDavid du Colombier if (cnt > 0)
67500d97012SDavid du Colombier { fprintf(fd, " uchar c_stack[StackSize];\n");
67600d97012SDavid du Colombier }
677312a1df1SDavid du Colombier }
678312a1df1SDavid du Colombier
679312a1df1SDavid du Colombier void
c_add_hidden(FILE * fd)680312a1df1SDavid du Colombier c_add_hidden(FILE *fd)
681312a1df1SDavid du Colombier { C_Added *r;
682312a1df1SDavid du Colombier
683312a1df1SDavid du Colombier for (r = c_added; r; r = r->nxt) /* pickup hidden decls */
684312a1df1SDavid du Colombier if (strncmp(r->t->name, "\"Hidden\"", strlen("\"Hidden\"")) == 0)
685312a1df1SDavid du Colombier { r->s->name[strlen(r->s->name)-1] = ' ';
686312a1df1SDavid du Colombier fprintf(fd, "%s; /* Hidden */\n", &r->s->name[1]);
687312a1df1SDavid du Colombier r->s->name[strlen(r->s->name)-1] = '"';
688312a1df1SDavid du Colombier }
689312a1df1SDavid du Colombier /* called before c_add_def - quotes are still there */
690312a1df1SDavid du Colombier }
691312a1df1SDavid du Colombier
692312a1df1SDavid du Colombier void
c_add_loc(FILE * fd,char * s)693312a1df1SDavid du Colombier c_add_loc(FILE *fd, char *s) /* state vector entries for proctype s */
694312a1df1SDavid du Colombier { C_Added *r;
695312a1df1SDavid du Colombier static char buf[1024];
696312a1df1SDavid du Colombier char *p;
697312a1df1SDavid du Colombier
698312a1df1SDavid du Colombier if (!c_added) return;
699312a1df1SDavid du Colombier
700312a1df1SDavid du Colombier strcpy(buf, s);
701312a1df1SDavid du Colombier strcat(buf, " ");
702312a1df1SDavid du Colombier for (r = c_added; r; r = r->nxt) /* pickup local decls */
703*de2caf28SDavid du Colombier { if (strncmp(r->t->name, " Local", strlen(" Local")) == 0)
704312a1df1SDavid du Colombier { p = r->t->name + strlen(" Local");
705*de2caf28SDavid du Colombier fprintf(fd, "/* XXX p=<%s>, s=<%s>, buf=<%s> r->s->name=<%s>XXX */\n", p, s, buf, r->s->name);
706312a1df1SDavid du Colombier while (*p == ' ' || *p == '\t')
707*de2caf28SDavid du Colombier { p++;
708312a1df1SDavid du Colombier }
709*de2caf28SDavid du Colombier if (strcmp(p, buf) == 0
710*de2caf28SDavid du Colombier || (strncmp(p, "init", 4) == 0 && strncmp(buf, ":init:", 6) == 0))
711*de2caf28SDavid du Colombier { fprintf(fd, " %s;\n", r->s->name);
712*de2caf28SDavid du Colombier } } }
713312a1df1SDavid du Colombier }
714312a1df1SDavid du Colombier void
c_add_def(FILE * fd)715312a1df1SDavid du Colombier c_add_def(FILE *fd) /* 3 - called in plunk_c_fcts() */
716312a1df1SDavid du Colombier { C_Added *r;
717312a1df1SDavid du Colombier
718*de2caf28SDavid du Colombier fprintf(fd, "#if defined(C_States) && (HAS_TRACK==1)\n");
719312a1df1SDavid du Colombier for (r = c_added; r; r = r->nxt)
720312a1df1SDavid du Colombier { r->s->name[strlen(r->s->name)-1] = ' ';
721312a1df1SDavid du Colombier r->s->name[0] = ' '; /* remove the "s */
722312a1df1SDavid du Colombier
723312a1df1SDavid du Colombier r->t->name[strlen(r->t->name)-1] = ' ';
724312a1df1SDavid du Colombier r->t->name[0] = ' ';
725312a1df1SDavid du Colombier
726312a1df1SDavid du Colombier if (strncmp(r->t->name, " Global ", strlen(" Global ")) == 0
727312a1df1SDavid du Colombier || strncmp(r->t->name, " Hidden ", strlen(" Hidden ")) == 0
728312a1df1SDavid du Colombier || strncmp(r->t->name, " Local", strlen(" Local")) == 0)
729312a1df1SDavid du Colombier continue;
730312a1df1SDavid du Colombier
731312a1df1SDavid du Colombier if (strchr(r->s->name, '&'))
732312a1df1SDavid du Colombier fatal("dereferencing state object: %s", r->s->name);
733312a1df1SDavid du Colombier
734312a1df1SDavid du Colombier fprintf(fd, "extern %s %s;\n", r->t->name, r->s->name);
735312a1df1SDavid du Colombier }
736312a1df1SDavid du Colombier for (r = c_tracked; r; r = r->nxt)
737312a1df1SDavid du Colombier { r->s->name[strlen(r->s->name)-1] = ' ';
738312a1df1SDavid du Colombier r->s->name[0] = ' '; /* remove " */
739312a1df1SDavid du Colombier
740312a1df1SDavid du Colombier r->t->name[strlen(r->t->name)-1] = ' ';
741312a1df1SDavid du Colombier r->t->name[0] = ' ';
742312a1df1SDavid du Colombier }
743312a1df1SDavid du Colombier
744312a1df1SDavid du Colombier if (separate == 2)
745312a1df1SDavid du Colombier { fprintf(fd, "#endif\n");
746312a1df1SDavid du Colombier return;
747312a1df1SDavid du Colombier }
748312a1df1SDavid du Colombier
749312a1df1SDavid du Colombier if (has_stack)
75000d97012SDavid du Colombier { fprintf(fd, "int cpu_printf(const char *, ...);\n");
75100d97012SDavid du Colombier fprintf(fd, "void\nc_stack(uchar *p_t_r)\n{\n");
752312a1df1SDavid du Colombier fprintf(fd, "#ifdef VERBOSE\n");
75300d97012SDavid du Colombier fprintf(fd, " cpu_printf(\"c_stack %%u\\n\", p_t_r);\n");
754312a1df1SDavid du Colombier fprintf(fd, "#endif\n");
755312a1df1SDavid du Colombier for (r = c_tracked; r; r = r->nxt)
756312a1df1SDavid du Colombier { if (r->ival == ZS) continue;
757312a1df1SDavid du Colombier
758312a1df1SDavid du Colombier fprintf(fd, "\tif(%s)\n", r->s->name);
759312a1df1SDavid du Colombier fprintf(fd, "\t\tmemcpy(p_t_r, %s, %s);\n",
760312a1df1SDavid du Colombier r->s->name, r->t->name);
761312a1df1SDavid du Colombier fprintf(fd, "\telse\n");
762312a1df1SDavid du Colombier fprintf(fd, "\t\tmemset(p_t_r, 0, %s);\n",
763312a1df1SDavid du Colombier r->t->name);
764312a1df1SDavid du Colombier fprintf(fd, "\tp_t_r += %s;\n", r->t->name);
765312a1df1SDavid du Colombier }
766312a1df1SDavid du Colombier fprintf(fd, "}\n\n");
767312a1df1SDavid du Colombier }
768312a1df1SDavid du Colombier
769f3793cddSDavid du Colombier fprintf(fd, "void\nc_update(uchar *p_t_r)\n{\n");
770312a1df1SDavid du Colombier fprintf(fd, "#ifdef VERBOSE\n");
771*de2caf28SDavid du Colombier fprintf(fd, " printf(\"c_update %%p\\n\", p_t_r);\n");
772312a1df1SDavid du Colombier fprintf(fd, "#endif\n");
773312a1df1SDavid du Colombier for (r = c_added; r; r = r->nxt)
774312a1df1SDavid du Colombier { if (strncmp(r->t->name, " Global ", strlen(" Global ")) == 0
775312a1df1SDavid du Colombier || strncmp(r->t->name, " Hidden ", strlen(" Hidden ")) == 0
776312a1df1SDavid du Colombier || strncmp(r->t->name, " Local", strlen(" Local")) == 0)
777312a1df1SDavid du Colombier continue;
778312a1df1SDavid du Colombier
779312a1df1SDavid du Colombier fprintf(fd, "\tmemcpy(p_t_r, &%s, sizeof(%s));\n",
780312a1df1SDavid du Colombier r->s->name, r->t->name);
781312a1df1SDavid du Colombier fprintf(fd, "\tp_t_r += sizeof(%s);\n", r->t->name);
782312a1df1SDavid du Colombier }
783312a1df1SDavid du Colombier
784312a1df1SDavid du Colombier for (r = c_tracked; r; r = r->nxt)
785312a1df1SDavid du Colombier { if (r->ival) continue;
786312a1df1SDavid du Colombier
787312a1df1SDavid du Colombier fprintf(fd, "\tif(%s)\n", r->s->name);
788312a1df1SDavid du Colombier fprintf(fd, "\t\tmemcpy(p_t_r, %s, %s);\n",
789312a1df1SDavid du Colombier r->s->name, r->t->name);
790312a1df1SDavid du Colombier fprintf(fd, "\telse\n");
791312a1df1SDavid du Colombier fprintf(fd, "\t\tmemset(p_t_r, 0, %s);\n",
792312a1df1SDavid du Colombier r->t->name);
793312a1df1SDavid du Colombier fprintf(fd, "\tp_t_r += %s;\n", r->t->name);
794312a1df1SDavid du Colombier }
795312a1df1SDavid du Colombier
796312a1df1SDavid du Colombier fprintf(fd, "}\n");
797312a1df1SDavid du Colombier
798312a1df1SDavid du Colombier if (has_stack)
799f3793cddSDavid du Colombier { fprintf(fd, "void\nc_unstack(uchar *p_t_r)\n{\n");
800312a1df1SDavid du Colombier fprintf(fd, "#ifdef VERBOSE\n");
80100d97012SDavid du Colombier fprintf(fd, " cpu_printf(\"c_unstack %%u\\n\", p_t_r);\n");
802312a1df1SDavid du Colombier fprintf(fd, "#endif\n");
803312a1df1SDavid du Colombier for (r = c_tracked; r; r = r->nxt)
804312a1df1SDavid du Colombier { if (r->ival == ZS) continue;
805312a1df1SDavid du Colombier
806312a1df1SDavid du Colombier fprintf(fd, "\tif(%s)\n", r->s->name);
807312a1df1SDavid du Colombier fprintf(fd, "\t\tmemcpy(%s, p_t_r, %s);\n",
808312a1df1SDavid du Colombier r->s->name, r->t->name);
809312a1df1SDavid du Colombier fprintf(fd, "\tp_t_r += %s;\n", r->t->name);
810312a1df1SDavid du Colombier }
811312a1df1SDavid du Colombier fprintf(fd, "}\n");
812312a1df1SDavid du Colombier }
813312a1df1SDavid du Colombier
814f3793cddSDavid du Colombier fprintf(fd, "void\nc_revert(uchar *p_t_r)\n{\n");
815312a1df1SDavid du Colombier fprintf(fd, "#ifdef VERBOSE\n");
816*de2caf28SDavid du Colombier fprintf(fd, " printf(\"c_revert %%p\\n\", p_t_r);\n");
817312a1df1SDavid du Colombier fprintf(fd, "#endif\n");
818312a1df1SDavid du Colombier for (r = c_added; r; r = r->nxt)
819312a1df1SDavid du Colombier { if (strncmp(r->t->name, " Global ", strlen(" Global ")) == 0
820312a1df1SDavid du Colombier || strncmp(r->t->name, " Hidden ", strlen(" Hidden ")) == 0
821312a1df1SDavid du Colombier || strncmp(r->t->name, " Local", strlen(" Local")) == 0)
822312a1df1SDavid du Colombier continue;
823312a1df1SDavid du Colombier
824312a1df1SDavid du Colombier fprintf(fd, "\tmemcpy(&%s, p_t_r, sizeof(%s));\n",
825312a1df1SDavid du Colombier r->s->name, r->t->name);
826312a1df1SDavid du Colombier fprintf(fd, "\tp_t_r += sizeof(%s);\n", r->t->name);
827312a1df1SDavid du Colombier }
828312a1df1SDavid du Colombier for (r = c_tracked; r; r = r->nxt)
829312a1df1SDavid du Colombier { if (r->ival != ZS) continue;
830312a1df1SDavid du Colombier
831312a1df1SDavid du Colombier fprintf(fd, "\tif(%s)\n", r->s->name);
832312a1df1SDavid du Colombier fprintf(fd, "\t\tmemcpy(%s, p_t_r, %s);\n",
833312a1df1SDavid du Colombier r->s->name, r->t->name);
834312a1df1SDavid du Colombier fprintf(fd, "\tp_t_r += %s;\n", r->t->name);
835312a1df1SDavid du Colombier }
836312a1df1SDavid du Colombier
837312a1df1SDavid du Colombier fprintf(fd, "}\n");
838312a1df1SDavid du Colombier fprintf(fd, "#endif\n");
839312a1df1SDavid du Colombier }
840312a1df1SDavid du Colombier
841312a1df1SDavid du Colombier void
plunk_reverse(FILE * fd,IType * p,int matchthis)842312a1df1SDavid du Colombier plunk_reverse(FILE *fd, IType *p, int matchthis)
843312a1df1SDavid du Colombier { char *y, *z;
844312a1df1SDavid du Colombier
845312a1df1SDavid du Colombier if (!p) return;
846312a1df1SDavid du Colombier plunk_reverse(fd, p->nxt, matchthis);
847312a1df1SDavid du Colombier
848312a1df1SDavid du Colombier if (!p->nm->context
849*de2caf28SDavid du Colombier && p->nm->type == matchthis
850*de2caf28SDavid du Colombier && p->is_expr == 0)
851312a1df1SDavid du Colombier { fprintf(fd, "\n/* start of %s */\n", p->nm->name);
852312a1df1SDavid du Colombier z = (char *) p->cn;
853312a1df1SDavid du Colombier while (*z == '\n' || *z == '\r' || *z == '\\')
854*de2caf28SDavid du Colombier { z++;
855*de2caf28SDavid du Colombier }
856312a1df1SDavid du Colombier /* e.g.: \#include "..." */
857312a1df1SDavid du Colombier
858312a1df1SDavid du Colombier y = z;
859312a1df1SDavid du Colombier while ((y = strstr(y, "\\#")) != NULL)
860312a1df1SDavid du Colombier { *y = '\n'; y++;
861312a1df1SDavid du Colombier }
862312a1df1SDavid du Colombier
863312a1df1SDavid du Colombier fprintf(fd, "%s\n", z);
864312a1df1SDavid du Colombier fprintf(fd, "\n/* end of %s */\n", p->nm->name);
865312a1df1SDavid du Colombier }
866312a1df1SDavid du Colombier }
867312a1df1SDavid du Colombier
868312a1df1SDavid du Colombier void
plunk_c_decls(FILE * fd)869312a1df1SDavid du Colombier plunk_c_decls(FILE *fd)
870312a1df1SDavid du Colombier {
871312a1df1SDavid du Colombier plunk_reverse(fd, seqnames, CODE_DECL);
872312a1df1SDavid du Colombier }
873312a1df1SDavid du Colombier
874312a1df1SDavid du Colombier void
plunk_c_fcts(FILE * fd)875312a1df1SDavid du Colombier plunk_c_fcts(FILE *fd)
876312a1df1SDavid du Colombier {
877312a1df1SDavid du Colombier if (separate == 2 && hastrack)
878312a1df1SDavid du Colombier { c_add_def(fd);
879312a1df1SDavid du Colombier return;
880312a1df1SDavid du Colombier }
881312a1df1SDavid du Colombier
882312a1df1SDavid du Colombier c_add_hidden(fd);
883312a1df1SDavid du Colombier plunk_reverse(fd, seqnames, CODE_FRAG);
884312a1df1SDavid du Colombier
885312a1df1SDavid du Colombier if (c_added || c_tracked) /* enables calls to c_revert and c_update */
886312a1df1SDavid du Colombier fprintf(fd, "#define C_States 1\n");
887312a1df1SDavid du Colombier else
888312a1df1SDavid du Colombier fprintf(fd, "#undef C_States\n");
889312a1df1SDavid du Colombier
890312a1df1SDavid du Colombier if (hastrack)
891312a1df1SDavid du Colombier c_add_def(fd);
892312a1df1SDavid du Colombier
893312a1df1SDavid du Colombier c_add_globinit(fd);
894312a1df1SDavid du Colombier do_locinits(fd);
895312a1df1SDavid du Colombier }
896312a1df1SDavid du Colombier
897312a1df1SDavid du Colombier static void
check_inline(IType * tmp)898312a1df1SDavid du Colombier check_inline(IType *tmp)
899312a1df1SDavid du Colombier { char buf[128];
900312a1df1SDavid du Colombier ProcList *p;
901312a1df1SDavid du Colombier
902*de2caf28SDavid du Colombier if (!X_lst) return;
903312a1df1SDavid du Colombier
904*de2caf28SDavid du Colombier for (p = ready; p; p = p->nxt)
905*de2caf28SDavid du Colombier { if (strcmp(p->n->name, X_lst->n->name) == 0)
906312a1df1SDavid du Colombier continue;
907312a1df1SDavid du Colombier sprintf(buf, "P%s->", p->n->name);
908312a1df1SDavid du Colombier if (strstr((char *)tmp->cn, buf))
909312a1df1SDavid du Colombier { printf("spin: in proctype %s, ref to object in proctype %s\n",
910*de2caf28SDavid du Colombier X_lst->n->name, p->n->name);
911312a1df1SDavid du Colombier fatal("invalid variable ref in '%s'", tmp->nm->name);
912312a1df1SDavid du Colombier } }
913312a1df1SDavid du Colombier }
914312a1df1SDavid du Colombier
915*de2caf28SDavid du Colombier extern short terse;
916*de2caf28SDavid du Colombier extern short nocast;
917*de2caf28SDavid du Colombier
918312a1df1SDavid du Colombier void
plunk_expr(FILE * fd,char * s)919312a1df1SDavid du Colombier plunk_expr(FILE *fd, char *s)
920312a1df1SDavid du Colombier { IType *tmp;
921*de2caf28SDavid du Colombier char *q;
922312a1df1SDavid du Colombier
923312a1df1SDavid du Colombier tmp = find_inline(s);
924312a1df1SDavid du Colombier check_inline(tmp);
925312a1df1SDavid du Colombier
926*de2caf28SDavid du Colombier if (terse && nocast)
927*de2caf28SDavid du Colombier { for (q = (char *) tmp->cn; q && *q != '\0'; q++)
928*de2caf28SDavid du Colombier { fflush(fd);
929*de2caf28SDavid du Colombier if (*q == '"')
930*de2caf28SDavid du Colombier { fprintf(fd, "\\");
931*de2caf28SDavid du Colombier }
932*de2caf28SDavid du Colombier fprintf(fd, "%c", *q);
933*de2caf28SDavid du Colombier }
934*de2caf28SDavid du Colombier } else
935*de2caf28SDavid du Colombier { fprintf(fd, "%s", (char *) tmp->cn);
936*de2caf28SDavid du Colombier }
937312a1df1SDavid du Colombier }
938312a1df1SDavid du Colombier
939312a1df1SDavid du Colombier void
preruse(FILE * fd,Lextok * n)940312a1df1SDavid du Colombier preruse(FILE *fd, Lextok *n) /* check a condition for c_expr with preconditions */
941312a1df1SDavid du Colombier { IType *tmp;
942312a1df1SDavid du Colombier
943312a1df1SDavid du Colombier if (!n) return;
944312a1df1SDavid du Colombier if (n->ntyp == C_EXPR)
945312a1df1SDavid du Colombier { tmp = find_inline(n->sym->name);
946312a1df1SDavid du Colombier if (tmp->prec)
947312a1df1SDavid du Colombier { fprintf(fd, "if (!(%s)) { if (!readtrail) { depth++; ", tmp->prec);
948*de2caf28SDavid du Colombier fprintf(fd, "trpt++; trpt->pr = II; trpt->o_t = t; trpt->st = tt; ");
949*de2caf28SDavid du Colombier fprintf(fd, "uerror(\"c_expr line %d precondition false: %s\"); continue;",
950*de2caf28SDavid du Colombier tmp->dln, tmp->prec);
951*de2caf28SDavid du Colombier fprintf(fd, " } else { printf(\"pan: precondition false: %s\\n\"); ",
952*de2caf28SDavid du Colombier tmp->prec);
953312a1df1SDavid du Colombier fprintf(fd, "_m = 3; goto P999; } } \n\t\t");
954312a1df1SDavid du Colombier }
955312a1df1SDavid du Colombier } else
956312a1df1SDavid du Colombier { preruse(fd, n->rgt);
957312a1df1SDavid du Colombier preruse(fd, n->lft);
958312a1df1SDavid du Colombier }
959312a1df1SDavid du Colombier }
960312a1df1SDavid du Colombier
961312a1df1SDavid du Colombier int
glob_inline(char * s)962312a1df1SDavid du Colombier glob_inline(char *s)
963312a1df1SDavid du Colombier { IType *tmp;
964312a1df1SDavid du Colombier char *bdy;
965312a1df1SDavid du Colombier
966312a1df1SDavid du Colombier tmp = find_inline(s);
967312a1df1SDavid du Colombier bdy = (char *) tmp->cn;
968312a1df1SDavid du Colombier return (strstr(bdy, "now.") /* global ref or */
969312a1df1SDavid du Colombier || strchr(bdy, '(') > bdy); /* possible C-function call */
970312a1df1SDavid du Colombier }
971312a1df1SDavid du Colombier
972*de2caf28SDavid du Colombier char *
put_inline(FILE * fd,char * s)973*de2caf28SDavid du Colombier put_inline(FILE *fd, char *s)
974*de2caf28SDavid du Colombier { IType *tmp;
975*de2caf28SDavid du Colombier
976*de2caf28SDavid du Colombier tmp = find_inline(s);
977*de2caf28SDavid du Colombier check_inline(tmp);
978*de2caf28SDavid du Colombier return (char *) tmp->cn;
979*de2caf28SDavid du Colombier }
980*de2caf28SDavid du Colombier
981*de2caf28SDavid du Colombier void
mark_last(void)982*de2caf28SDavid du Colombier mark_last(void)
983*de2caf28SDavid du Colombier {
984*de2caf28SDavid du Colombier if (seqnames)
985*de2caf28SDavid du Colombier { seqnames->is_expr = 1;
986*de2caf28SDavid du Colombier }
987*de2caf28SDavid du Colombier }
988*de2caf28SDavid du Colombier
989312a1df1SDavid du Colombier void
plunk_inline(FILE * fd,char * s,int how,int gencode)99000d97012SDavid du Colombier plunk_inline(FILE *fd, char *s, int how, int gencode) /* c_code with precondition */
991312a1df1SDavid du Colombier { IType *tmp;
992312a1df1SDavid du Colombier
993312a1df1SDavid du Colombier tmp = find_inline(s);
994312a1df1SDavid du Colombier check_inline(tmp);
995312a1df1SDavid du Colombier
996312a1df1SDavid du Colombier fprintf(fd, "{ ");
997312a1df1SDavid du Colombier if (how && tmp->prec)
99800d97012SDavid du Colombier { fprintf(fd, "if (!(%s)) { if (!readtrail) {",
99900d97012SDavid du Colombier tmp->prec);
1000*de2caf28SDavid du Colombier fprintf(fd, " uerror(\"c_code line %d precondition false: %s\"); continue; ",
1001*de2caf28SDavid du Colombier tmp->dln,
100200d97012SDavid du Colombier tmp->prec);
100300d97012SDavid du Colombier fprintf(fd, "} else { ");
100400d97012SDavid du Colombier fprintf(fd, "printf(\"pan: precondition false: %s\\n\"); _m = 3; goto P999; } } ",
100500d97012SDavid du Colombier tmp->prec);
1006312a1df1SDavid du Colombier }
100700d97012SDavid du Colombier
100800d97012SDavid du Colombier if (!gencode) /* not in d_step */
100900d97012SDavid du Colombier { fprintf(fd, "\n\t\tsv_save();");
101000d97012SDavid du Colombier }
101100d97012SDavid du Colombier
1012312a1df1SDavid du Colombier fprintf(fd, "%s", (char *) tmp->cn);
1013312a1df1SDavid du Colombier fprintf(fd, " }\n");
1014312a1df1SDavid du Colombier }
1015312a1df1SDavid du Colombier
1016*de2caf28SDavid du Colombier int
side_scan(char * t,char * pat)1017*de2caf28SDavid du Colombier side_scan(char *t, char *pat)
1018*de2caf28SDavid du Colombier { char *r = strstr(t, pat);
1019*de2caf28SDavid du Colombier return (r
1020*de2caf28SDavid du Colombier && *(r-1) != '"'
1021*de2caf28SDavid du Colombier && *(r-1) != '\'');
1022*de2caf28SDavid du Colombier }
1023*de2caf28SDavid du Colombier
1024312a1df1SDavid du Colombier void
no_side_effects(char * s)1025312a1df1SDavid du Colombier no_side_effects(char *s)
1026312a1df1SDavid du Colombier { IType *tmp;
1027312a1df1SDavid du Colombier char *t;
1028*de2caf28SDavid du Colombier char *z;
1029312a1df1SDavid du Colombier
1030312a1df1SDavid du Colombier /* could still defeat this check via hidden
1031312a1df1SDavid du Colombier * side effects in function calls,
1032312a1df1SDavid du Colombier * but this will catch at least some cases
1033312a1df1SDavid du Colombier */
1034312a1df1SDavid du Colombier
1035312a1df1SDavid du Colombier tmp = find_inline(s);
1036312a1df1SDavid du Colombier t = (char *) tmp->cn;
1037*de2caf28SDavid du Colombier while (t && *t == ' ')
1038*de2caf28SDavid du Colombier { t++;
1039*de2caf28SDavid du Colombier }
1040312a1df1SDavid du Colombier
1041*de2caf28SDavid du Colombier z = strchr(t, '(');
1042*de2caf28SDavid du Colombier if (z
1043*de2caf28SDavid du Colombier && z > t
1044*de2caf28SDavid du Colombier && isalnum((int) *(z-1))
1045*de2caf28SDavid du Colombier && strncmp(t, "spin_mutex_free(", strlen("spin_mutex_free(")) != 0)
1046*de2caf28SDavid du Colombier { goto bad; /* fct call */
1047*de2caf28SDavid du Colombier }
1048*de2caf28SDavid du Colombier
1049*de2caf28SDavid du Colombier if (side_scan(t, ";")
1050*de2caf28SDavid du Colombier || side_scan(t, "++")
1051*de2caf28SDavid du Colombier || side_scan(t, "--"))
1052312a1df1SDavid du Colombier {
1053312a1df1SDavid du Colombier bad: lineno = tmp->dln;
1054312a1df1SDavid du Colombier Fname = tmp->dfn;
1055312a1df1SDavid du Colombier non_fatal("c_expr %s has side-effects", s);
1056312a1df1SDavid du Colombier return;
1057312a1df1SDavid du Colombier }
1058312a1df1SDavid du Colombier while ((t = strchr(t, '=')) != NULL)
1059312a1df1SDavid du Colombier { if (*(t-1) == '!'
1060312a1df1SDavid du Colombier || *(t-1) == '>'
1061*de2caf28SDavid du Colombier || *(t-1) == '<'
1062*de2caf28SDavid du Colombier || *(t-1) == '"'
1063*de2caf28SDavid du Colombier || *(t-1) == '\'')
1064*de2caf28SDavid du Colombier { t += 2;
1065312a1df1SDavid du Colombier continue;
1066312a1df1SDavid du Colombier }
1067312a1df1SDavid du Colombier t++;
1068312a1df1SDavid du Colombier if (*t != '=')
1069312a1df1SDavid du Colombier goto bad;
1070312a1df1SDavid du Colombier t++;
1071312a1df1SDavid du Colombier }
1072312a1df1SDavid du Colombier }
1073312a1df1SDavid du Colombier
10747dd7cddfSDavid du Colombier void
pickup_inline(Symbol * t,Lextok * apars,Lextok * rval)1075*de2caf28SDavid du Colombier pickup_inline(Symbol *t, Lextok *apars, Lextok *rval)
10767dd7cddfSDavid du Colombier { IType *tmp; Lextok *p, *q; int j;
10777dd7cddfSDavid du Colombier
1078312a1df1SDavid du Colombier tmp = find_inline(t->name);
10797dd7cddfSDavid du Colombier
10807dd7cddfSDavid du Colombier if (++Inlining >= MAXINL)
108100d97012SDavid du Colombier fatal("inlines nested too deeply", 0);
10827dd7cddfSDavid du Colombier tmp->cln = lineno; /* remember calling point */
10837dd7cddfSDavid du Colombier tmp->cfn = Fname; /* and filename */
1084*de2caf28SDavid du Colombier tmp->rval = rval;
10857dd7cddfSDavid du Colombier
10867dd7cddfSDavid du Colombier for (p = apars, q = tmp->params, j = 0; p && q; p = p->rgt, q = q->rgt)
10877dd7cddfSDavid du Colombier j++; /* count them */
10887dd7cddfSDavid du Colombier if (p || q)
10897dd7cddfSDavid du Colombier fatal("wrong nr of params on call of '%s'", t->name);
10907dd7cddfSDavid du Colombier
10917dd7cddfSDavid du Colombier tmp->anms = (char **) emalloc(j * sizeof(char *));
10927dd7cddfSDavid du Colombier for (p = apars, j = 0; p; p = p->rgt, j++)
109300d97012SDavid du Colombier { tmp->anms[j] = (char *) emalloc(strlen(IArg_cont[j])+1);
10947dd7cddfSDavid du Colombier strcpy(tmp->anms[j], IArg_cont[j]);
10957dd7cddfSDavid du Colombier }
10967dd7cddfSDavid du Colombier
10977dd7cddfSDavid du Colombier lineno = tmp->dln; /* linenr of def */
10987dd7cddfSDavid du Colombier Fname = tmp->dfn; /* filename of same */
10997dd7cddfSDavid du Colombier Inliner[Inlining] = (char *)tmp->cn;
11007dd7cddfSDavid du Colombier Inline_stub[Inlining] = tmp;
11017dd7cddfSDavid du Colombier #if 0
11027dd7cddfSDavid du Colombier if (verbose&32)
110300d97012SDavid du Colombier printf("spin: %s:%d, inlining '%s' (from %s:%d)\n",
110400d97012SDavid du Colombier tmp->cfn->name, tmp->cln, t->name, tmp->dfn->name, tmp->dln);
11057dd7cddfSDavid du Colombier #endif
11067dd7cddfSDavid du Colombier for (j = 0; j < Inlining; j++)
1107*de2caf28SDavid du Colombier { if (Inline_stub[j] == Inline_stub[Inlining])
1108*de2caf28SDavid du Colombier { fatal("cyclic inline attempt on: %s", t->name);
1109*de2caf28SDavid du Colombier } }
1110*de2caf28SDavid du Colombier last_token = SEMI; /* avoid insertion of extra semi */
11117dd7cddfSDavid du Colombier }
11127dd7cddfSDavid du Colombier
1113*de2caf28SDavid du Colombier extern int pp_mode;
1114*de2caf28SDavid du Colombier
11157dd7cddfSDavid du Colombier static void
do_directive(int first)1116312a1df1SDavid du Colombier do_directive(int first)
11177dd7cddfSDavid du Colombier { int c = first; /* handles lines starting with pound */
11187dd7cddfSDavid du Colombier
11197dd7cddfSDavid du Colombier getword(c, isalpha_);
11207dd7cddfSDavid du Colombier
1121312a1df1SDavid du Colombier if (strcmp(yytext, "#ident") == 0)
1122312a1df1SDavid du Colombier goto done;
1123312a1df1SDavid du Colombier
11247dd7cddfSDavid du Colombier if ((c = Getchar()) != ' ')
11257dd7cddfSDavid du Colombier fatal("malformed preprocessor directive - # .", 0);
11267dd7cddfSDavid du Colombier
11277dd7cddfSDavid du Colombier if (!isdigit_(c = Getchar()))
11287dd7cddfSDavid du Colombier fatal("malformed preprocessor directive - # .lineno", 0);
11297dd7cddfSDavid du Colombier
11307dd7cddfSDavid du Colombier getword(c, isdigit_);
11317dd7cddfSDavid du Colombier lineno = atoi(yytext); /* pickup the line number */
11327dd7cddfSDavid du Colombier
11337dd7cddfSDavid du Colombier if ((c = Getchar()) == '\n')
11347dd7cddfSDavid du Colombier return; /* no filename */
11357dd7cddfSDavid du Colombier
11367dd7cddfSDavid du Colombier if (c != ' ')
11377dd7cddfSDavid du Colombier fatal("malformed preprocessor directive - .fname", 0);
11387dd7cddfSDavid du Colombier
11397dd7cddfSDavid du Colombier if ((c = Getchar()) != '\"')
114000d97012SDavid du Colombier { printf("got %c, expected \" -- lineno %d\n", c, lineno);
114100d97012SDavid du Colombier fatal("malformed preprocessor directive - .fname (%s)", yytext);
114200d97012SDavid du Colombier }
11437dd7cddfSDavid du Colombier
114400d97012SDavid du Colombier getword(Getchar(), notquote); /* was getword(c, notquote); */
11457dd7cddfSDavid du Colombier if (Getchar() != '\"')
11467dd7cddfSDavid du Colombier fatal("malformed preprocessor directive - fname.", 0);
11477dd7cddfSDavid du Colombier
114800d97012SDavid du Colombier /* strcat(yytext, "\""); */
11497dd7cddfSDavid du Colombier Fname = lookup(yytext);
1150312a1df1SDavid du Colombier done:
11517dd7cddfSDavid du Colombier while (Getchar() != '\n')
11527dd7cddfSDavid du Colombier ;
11537dd7cddfSDavid du Colombier }
11547dd7cddfSDavid du Colombier
11557dd7cddfSDavid du Colombier void
precondition(char * q)1156312a1df1SDavid du Colombier precondition(char *q)
1157312a1df1SDavid du Colombier { int c, nest = 1;
1158312a1df1SDavid du Colombier
1159312a1df1SDavid du Colombier for (;;)
1160312a1df1SDavid du Colombier { c = Getchar();
1161312a1df1SDavid du Colombier *q++ = c;
1162312a1df1SDavid du Colombier switch (c) {
1163312a1df1SDavid du Colombier case '\n':
1164312a1df1SDavid du Colombier lineno++;
1165312a1df1SDavid du Colombier break;
1166312a1df1SDavid du Colombier case '[':
1167312a1df1SDavid du Colombier nest++;
1168312a1df1SDavid du Colombier break;
1169312a1df1SDavid du Colombier case ']':
1170312a1df1SDavid du Colombier if (--nest <= 0)
1171312a1df1SDavid du Colombier { *--q = '\0';
1172312a1df1SDavid du Colombier return;
1173312a1df1SDavid du Colombier }
1174312a1df1SDavid du Colombier break;
1175312a1df1SDavid du Colombier }
1176312a1df1SDavid du Colombier }
117700d97012SDavid du Colombier fatal("cannot happen", (char *) 0); /* unreachable */
1178312a1df1SDavid du Colombier }
1179312a1df1SDavid du Colombier
118000d97012SDavid du Colombier
1181312a1df1SDavid du Colombier Symbol *
prep_inline(Symbol * s,Lextok * nms)11827dd7cddfSDavid du Colombier prep_inline(Symbol *s, Lextok *nms)
11837dd7cddfSDavid du Colombier { int c, nest = 1, dln, firstchar, cnr;
118400d97012SDavid du Colombier char *p;
11857dd7cddfSDavid du Colombier Lextok *t;
118600d97012SDavid du Colombier static char Buf1[SOMETHINGBIG], Buf2[RATHERSMALL];
1187312a1df1SDavid du Colombier static int c_code = 1;
11887dd7cddfSDavid du Colombier
11897dd7cddfSDavid du Colombier for (t = nms; t; t = t->rgt)
11907dd7cddfSDavid du Colombier if (t->lft)
11917dd7cddfSDavid du Colombier { if (t->lft->ntyp != NAME)
119200d97012SDavid du Colombier fatal("bad param to inline %s", s?s->name:"--");
11937dd7cddfSDavid du Colombier t->lft->sym->hidden |= 32;
11947dd7cddfSDavid du Colombier }
11957dd7cddfSDavid du Colombier
1196312a1df1SDavid du Colombier if (!s) /* C_Code fragment */
1197312a1df1SDavid du Colombier { s = (Symbol *) emalloc(sizeof(Symbol));
119800d97012SDavid du Colombier s->name = (char *) emalloc(strlen("c_code")+26);
1199312a1df1SDavid du Colombier sprintf(s->name, "c_code%d", c_code++);
1200312a1df1SDavid du Colombier s->context = context;
1201312a1df1SDavid du Colombier s->type = CODE_FRAG;
1202312a1df1SDavid du Colombier } else
1203*de2caf28SDavid du Colombier { s->type = PREDEF;
1204*de2caf28SDavid du Colombier }
1205312a1df1SDavid du Colombier
120600d97012SDavid du Colombier p = &Buf1[0];
120700d97012SDavid du Colombier Buf2[0] = '\0';
12087dd7cddfSDavid du Colombier for (;;)
12097dd7cddfSDavid du Colombier { c = Getchar();
12107dd7cddfSDavid du Colombier switch (c) {
1211312a1df1SDavid du Colombier case '[':
1212312a1df1SDavid du Colombier if (s->type != CODE_FRAG)
1213312a1df1SDavid du Colombier goto bad;
121400d97012SDavid du Colombier precondition(&Buf2[0]); /* e.g., c_code [p] { r = p-r; } */
1215312a1df1SDavid du Colombier continue;
12167dd7cddfSDavid du Colombier case '{':
12177dd7cddfSDavid du Colombier break;
12187dd7cddfSDavid du Colombier case '\n':
12197dd7cddfSDavid du Colombier lineno++;
12207dd7cddfSDavid du Colombier /* fall through */
12217dd7cddfSDavid du Colombier case ' ': case '\t': case '\f': case '\r':
12227dd7cddfSDavid du Colombier continue;
1223312a1df1SDavid du Colombier default :
1224312a1df1SDavid du Colombier printf("spin: saw char '%c'\n", c);
1225312a1df1SDavid du Colombier bad: fatal("bad inline: %s", s->name);
12267dd7cddfSDavid du Colombier }
12277dd7cddfSDavid du Colombier break;
12287dd7cddfSDavid du Colombier }
12297dd7cddfSDavid du Colombier dln = lineno;
1230312a1df1SDavid du Colombier if (s->type == CODE_FRAG)
1231312a1df1SDavid du Colombier { if (verbose&32)
1232*de2caf28SDavid du Colombier { sprintf(Buf1, "\t/* line %d %s */\n\t\t",
1233312a1df1SDavid du Colombier lineno, Fname->name);
1234312a1df1SDavid du Colombier } else
1235*de2caf28SDavid du Colombier { strcpy(Buf1, "");
1236*de2caf28SDavid du Colombier }
1237*de2caf28SDavid du Colombier } else
1238*de2caf28SDavid du Colombier { sprintf(Buf1, "\n#line %d \"%s\"\n{", lineno, Fname->name);
1239*de2caf28SDavid du Colombier }
124000d97012SDavid du Colombier p += strlen(Buf1);
12417dd7cddfSDavid du Colombier firstchar = 1;
12427dd7cddfSDavid du Colombier
12437dd7cddfSDavid du Colombier cnr = 1; /* not zero */
12447dd7cddfSDavid du Colombier more:
124500d97012SDavid du Colombier c = Getchar();
124600d97012SDavid du Colombier *p++ = (char) c;
124700d97012SDavid du Colombier if (p - Buf1 >= SOMETHINGBIG)
12487dd7cddfSDavid du Colombier fatal("inline text too long", 0);
12497dd7cddfSDavid du Colombier switch (c) {
12507dd7cddfSDavid du Colombier case '\n':
12517dd7cddfSDavid du Colombier lineno++;
12527dd7cddfSDavid du Colombier cnr = 0;
12537dd7cddfSDavid du Colombier break;
12547dd7cddfSDavid du Colombier case '{':
12557dd7cddfSDavid du Colombier cnr++;
12567dd7cddfSDavid du Colombier nest++;
12577dd7cddfSDavid du Colombier break;
12587dd7cddfSDavid du Colombier case '}':
12597dd7cddfSDavid du Colombier cnr++;
12607dd7cddfSDavid du Colombier if (--nest <= 0)
12617dd7cddfSDavid du Colombier { *p = '\0';
1262312a1df1SDavid du Colombier if (s->type == CODE_FRAG)
1263*de2caf28SDavid du Colombier { *--p = '\0'; /* remove trailing '}' */
1264*de2caf28SDavid du Colombier }
126500d97012SDavid du Colombier def_inline(s, dln, &Buf1[0], &Buf2[0], nms);
126600d97012SDavid du Colombier if (firstchar)
1267*de2caf28SDavid du Colombier { printf("%3d: %s, warning: empty inline definition (%s)\n",
1268312a1df1SDavid du Colombier dln, Fname->name, s->name);
1269*de2caf28SDavid du Colombier }
1270312a1df1SDavid du Colombier return s; /* normal return */
12717dd7cddfSDavid du Colombier }
12727dd7cddfSDavid du Colombier break;
12737dd7cddfSDavid du Colombier case '#':
12747dd7cddfSDavid du Colombier if (cnr == 0)
12757dd7cddfSDavid du Colombier { p--;
1276312a1df1SDavid du Colombier do_directive(c); /* reads to newline */
127700d97012SDavid du Colombier } else
127800d97012SDavid du Colombier { firstchar = 0;
127900d97012SDavid du Colombier cnr++;
128000d97012SDavid du Colombier }
12817dd7cddfSDavid du Colombier break;
12827dd7cddfSDavid du Colombier case '\t':
12837dd7cddfSDavid du Colombier case ' ':
12847dd7cddfSDavid du Colombier case '\f':
12857dd7cddfSDavid du Colombier cnr++;
12867dd7cddfSDavid du Colombier break;
1287*de2caf28SDavid du Colombier case '"':
1288*de2caf28SDavid du Colombier do {
1289*de2caf28SDavid du Colombier c = Getchar();
1290*de2caf28SDavid du Colombier *p++ = (char) c;
1291*de2caf28SDavid du Colombier if (c == '\\')
1292*de2caf28SDavid du Colombier { *p++ = (char) Getchar();
1293*de2caf28SDavid du Colombier }
1294*de2caf28SDavid du Colombier if (p - Buf1 >= SOMETHINGBIG)
1295*de2caf28SDavid du Colombier { fatal("inline text too long", 0);
1296*de2caf28SDavid du Colombier }
1297*de2caf28SDavid du Colombier } while (c != '"'); /* end of string */
1298*de2caf28SDavid du Colombier /* *p = '\0'; */
1299*de2caf28SDavid du Colombier break;
1300*de2caf28SDavid du Colombier case '\'':
1301*de2caf28SDavid du Colombier c = Getchar();
1302*de2caf28SDavid du Colombier *p++ = (char) c;
1303*de2caf28SDavid du Colombier if (c == '\\')
1304*de2caf28SDavid du Colombier { *p++ = (char) Getchar();
1305*de2caf28SDavid du Colombier }
1306*de2caf28SDavid du Colombier c = Getchar();
1307*de2caf28SDavid du Colombier *p++ = (char) c;
1308*de2caf28SDavid du Colombier assert(c == '\'');
1309*de2caf28SDavid du Colombier break;
131000d97012SDavid du Colombier default:
131100d97012SDavid du Colombier firstchar = 0;
131200d97012SDavid du Colombier cnr++;
131300d97012SDavid du Colombier break;
13147dd7cddfSDavid du Colombier }
13157dd7cddfSDavid du Colombier goto more;
13167dd7cddfSDavid du Colombier }
13177dd7cddfSDavid du Colombier
131800d97012SDavid du Colombier static void
set_cur_scope(void)131900d97012SDavid du Colombier set_cur_scope(void)
132000d97012SDavid du Colombier { int i;
132100d97012SDavid du Colombier char tmpbuf[256];
132200d97012SDavid du Colombier
132300d97012SDavid du Colombier strcpy(CurScope, "_");
132400d97012SDavid du Colombier
132500d97012SDavid du Colombier if (context)
132600d97012SDavid du Colombier for (i = 0; i < scope_level; i++)
132700d97012SDavid du Colombier { sprintf(tmpbuf, "%d_", scope_seq[i]);
132800d97012SDavid du Colombier strcat(CurScope, tmpbuf);
132900d97012SDavid du Colombier }
133000d97012SDavid du Colombier }
133100d97012SDavid du Colombier
13327dd7cddfSDavid du Colombier static int
pre_proc(void)1333*de2caf28SDavid du Colombier pre_proc(void)
1334*de2caf28SDavid du Colombier { char b[512];
1335*de2caf28SDavid du Colombier int c, i = 0;
1336*de2caf28SDavid du Colombier
1337*de2caf28SDavid du Colombier b[i++] = '#';
1338*de2caf28SDavid du Colombier while ((c = Getchar()) != '\n' && c != EOF)
1339*de2caf28SDavid du Colombier { b[i++] = (char) c;
1340*de2caf28SDavid du Colombier }
1341*de2caf28SDavid du Colombier b[i] = '\0';
1342*de2caf28SDavid du Colombier yylval = nn(ZN, 0, ZN, ZN);
1343*de2caf28SDavid du Colombier yylval->sym = lookup(b);
1344*de2caf28SDavid du Colombier return PREPROC;
1345*de2caf28SDavid du Colombier }
1346*de2caf28SDavid du Colombier
1347*de2caf28SDavid du Colombier static int specials[] = {
1348*de2caf28SDavid du Colombier '}', ')', ']',
1349*de2caf28SDavid du Colombier OD, FI, ELSE, BREAK,
1350*de2caf28SDavid du Colombier C_CODE, C_EXPR, C_DECL,
1351*de2caf28SDavid du Colombier NAME, CONST, INCR, DECR, 0
1352*de2caf28SDavid du Colombier };
1353*de2caf28SDavid du Colombier
1354*de2caf28SDavid du Colombier int
follows_token(int c)1355*de2caf28SDavid du Colombier follows_token(int c)
1356*de2caf28SDavid du Colombier { int i;
1357*de2caf28SDavid du Colombier
1358*de2caf28SDavid du Colombier for (i = 0; specials[i]; i++)
1359*de2caf28SDavid du Colombier { if (c == specials[i])
1360*de2caf28SDavid du Colombier { return 1;
1361*de2caf28SDavid du Colombier } }
1362*de2caf28SDavid du Colombier return 0;
1363*de2caf28SDavid du Colombier }
1364*de2caf28SDavid du Colombier #define DEFER_LTL
1365*de2caf28SDavid du Colombier #ifdef DEFER_LTL
1366*de2caf28SDavid du Colombier /* defer ltl formula to the end of the spec
1367*de2caf28SDavid du Colombier * no matter where they appear in the original
1368*de2caf28SDavid du Colombier */
1369*de2caf28SDavid du Colombier
1370*de2caf28SDavid du Colombier static int deferred = 0;
1371*de2caf28SDavid du Colombier static FILE *defer_fd;
1372*de2caf28SDavid du Colombier
1373*de2caf28SDavid du Colombier int
get_deferred(void)1374*de2caf28SDavid du Colombier get_deferred(void)
1375*de2caf28SDavid du Colombier {
1376*de2caf28SDavid du Colombier if (!defer_fd)
1377*de2caf28SDavid du Colombier { return 0; /* nothing was deferred */
1378*de2caf28SDavid du Colombier }
1379*de2caf28SDavid du Colombier fclose(defer_fd);
1380*de2caf28SDavid du Colombier
1381*de2caf28SDavid du Colombier defer_fd = fopen(TMP_FILE2, "r");
1382*de2caf28SDavid du Colombier if (!defer_fd)
1383*de2caf28SDavid du Colombier { non_fatal("cannot retrieve deferred ltl formula", (char *) 0);
1384*de2caf28SDavid du Colombier return 0;
1385*de2caf28SDavid du Colombier }
1386*de2caf28SDavid du Colombier fclose(yyin);
1387*de2caf28SDavid du Colombier yyin = defer_fd;
1388*de2caf28SDavid du Colombier return 1;
1389*de2caf28SDavid du Colombier }
1390*de2caf28SDavid du Colombier
1391*de2caf28SDavid du Colombier void
zap_deferred(void)1392*de2caf28SDavid du Colombier zap_deferred(void)
1393*de2caf28SDavid du Colombier {
1394*de2caf28SDavid du Colombier (void) unlink(TMP_FILE2);
1395*de2caf28SDavid du Colombier }
1396*de2caf28SDavid du Colombier
1397*de2caf28SDavid du Colombier int
put_deferred(void)1398*de2caf28SDavid du Colombier put_deferred(void)
1399*de2caf28SDavid du Colombier { int c, cnt;
1400*de2caf28SDavid du Colombier if (!defer_fd)
1401*de2caf28SDavid du Colombier { defer_fd = fopen(TMP_FILE2, "w+");
1402*de2caf28SDavid du Colombier if (!defer_fd)
1403*de2caf28SDavid du Colombier { non_fatal("cannot defer ltl expansion", (char *) 0);
1404*de2caf28SDavid du Colombier return 0;
1405*de2caf28SDavid du Colombier } }
1406*de2caf28SDavid du Colombier fprintf(defer_fd, "ltl ");
1407*de2caf28SDavid du Colombier cnt = 0;
1408*de2caf28SDavid du Colombier while ((c = getc(yyin)) != EOF)
1409*de2caf28SDavid du Colombier { if (c == '{')
1410*de2caf28SDavid du Colombier { cnt++;
1411*de2caf28SDavid du Colombier }
1412*de2caf28SDavid du Colombier if (c == '}')
1413*de2caf28SDavid du Colombier { cnt--;
1414*de2caf28SDavid du Colombier if (cnt == 0)
1415*de2caf28SDavid du Colombier { break;
1416*de2caf28SDavid du Colombier } }
1417*de2caf28SDavid du Colombier fprintf(defer_fd, "%c", c);
1418*de2caf28SDavid du Colombier }
1419*de2caf28SDavid du Colombier fprintf(defer_fd, "}\n");
1420*de2caf28SDavid du Colombier fflush(defer_fd);
1421*de2caf28SDavid du Colombier return 1;
1422*de2caf28SDavid du Colombier }
1423*de2caf28SDavid du Colombier #endif
1424*de2caf28SDavid du Colombier
1425*de2caf28SDavid du Colombier #define EXPAND_SELECT
1426*de2caf28SDavid du Colombier #ifdef EXPAND_SELECT
1427*de2caf28SDavid du Colombier static char tmp_hold[256];
1428*de2caf28SDavid du Colombier static int tmp_has;
1429*de2caf28SDavid du Colombier
1430*de2caf28SDavid du Colombier void
new_select(void)1431*de2caf28SDavid du Colombier new_select(void)
1432*de2caf28SDavid du Colombier { tmp_hold[0] = '\0';
1433*de2caf28SDavid du Colombier tmp_has = 0;
1434*de2caf28SDavid du Colombier }
1435*de2caf28SDavid du Colombier
1436*de2caf28SDavid du Colombier static int
scan_to(int stop,int (* tst)(int),char * buf,int bufsz)1437*de2caf28SDavid du Colombier scan_to(int stop, int (*tst)(int), char *buf, int bufsz)
1438*de2caf28SDavid du Colombier { int c, i = 0;
1439*de2caf28SDavid du Colombier
1440*de2caf28SDavid du Colombier do { c = Getchar();
1441*de2caf28SDavid du Colombier if (tmp_has < sizeof(tmp_hold))
1442*de2caf28SDavid du Colombier { tmp_hold[tmp_has++] = c;
1443*de2caf28SDavid du Colombier }
1444*de2caf28SDavid du Colombier if (c == '\n')
1445*de2caf28SDavid du Colombier { lineno++;
1446*de2caf28SDavid du Colombier } else if (buf && i < bufsz-1)
1447*de2caf28SDavid du Colombier { buf[i++] = c;
1448*de2caf28SDavid du Colombier } else if (buf && i >= bufsz-1)
1449*de2caf28SDavid du Colombier { buf[bufsz-1] = '\0';
1450*de2caf28SDavid du Colombier fatal("name too long", buf);
1451*de2caf28SDavid du Colombier }
1452*de2caf28SDavid du Colombier if (tst && !tst(c) && c != ' ' && c != '\t')
1453*de2caf28SDavid du Colombier { break;
1454*de2caf28SDavid du Colombier }
1455*de2caf28SDavid du Colombier } while (c != stop && c != EOF);
1456*de2caf28SDavid du Colombier
1457*de2caf28SDavid du Colombier if (buf)
1458*de2caf28SDavid du Colombier { if (i <= 0)
1459*de2caf28SDavid du Colombier { fatal("input error", (char *) 0);
1460*de2caf28SDavid du Colombier }
1461*de2caf28SDavid du Colombier buf[i-1] = '\0';
1462*de2caf28SDavid du Colombier }
1463*de2caf28SDavid du Colombier
1464*de2caf28SDavid du Colombier if (c != stop)
1465*de2caf28SDavid du Colombier { if (0)
1466*de2caf28SDavid du Colombier { printf("saw: '%c', expected '%c'\n", c, stop);
1467*de2caf28SDavid du Colombier }
1468*de2caf28SDavid du Colombier if (tmp_has < sizeof(tmp_hold))
1469*de2caf28SDavid du Colombier { tmp_hold[tmp_has] = '\0';
1470*de2caf28SDavid du Colombier push_back(tmp_hold);
1471*de2caf28SDavid du Colombier if (0)
1472*de2caf28SDavid du Colombier { printf("pushed back: <'%s'>\n", tmp_hold);
1473*de2caf28SDavid du Colombier }
1474*de2caf28SDavid du Colombier return 0; /* internal expansion fails */
1475*de2caf28SDavid du Colombier } else
1476*de2caf28SDavid du Colombier { fatal("expecting select ( name : constant .. constant )", 0);
1477*de2caf28SDavid du Colombier } }
1478*de2caf28SDavid du Colombier return 1; /* success */
1479*de2caf28SDavid du Colombier }
1480*de2caf28SDavid du Colombier #endif
1481*de2caf28SDavid du Colombier
1482*de2caf28SDavid du Colombier int
lex(void)1483219b2ee8SDavid du Colombier lex(void)
1484219b2ee8SDavid du Colombier { int c;
1485219b2ee8SDavid du Colombier again:
1486219b2ee8SDavid du Colombier c = Getchar();
1487*de2caf28SDavid du Colombier /* more: */
14887dd7cddfSDavid du Colombier yytext[0] = (char) c;
1489219b2ee8SDavid du Colombier yytext[1] = '\0';
1490219b2ee8SDavid du Colombier switch (c) {
149100d97012SDavid du Colombier case EOF:
1492*de2caf28SDavid du Colombier #ifdef DEFER_LTL
1493*de2caf28SDavid du Colombier if (!deferred)
1494*de2caf28SDavid du Colombier { deferred = 1;
1495*de2caf28SDavid du Colombier if (get_deferred())
1496*de2caf28SDavid du Colombier { goto again;
1497*de2caf28SDavid du Colombier }
1498*de2caf28SDavid du Colombier } else
1499*de2caf28SDavid du Colombier { zap_deferred();
1500*de2caf28SDavid du Colombier }
1501*de2caf28SDavid du Colombier #endif
150200d97012SDavid du Colombier return c;
1503219b2ee8SDavid du Colombier case '\n': /* newline */
1504219b2ee8SDavid du Colombier lineno++;
1505*de2caf28SDavid du Colombier /* make most semi-colons optional */
1506*de2caf28SDavid du Colombier if (implied_semis
1507*de2caf28SDavid du Colombier /* && context */
1508*de2caf28SDavid du Colombier && in_seq
1509*de2caf28SDavid du Colombier && par_cnt == 0
1510*de2caf28SDavid du Colombier && follows_token(last_token))
1511*de2caf28SDavid du Colombier { if (last_token == '}')
1512*de2caf28SDavid du Colombier { do { c = Getchar();
1513*de2caf28SDavid du Colombier if (c == '\n')
1514*de2caf28SDavid du Colombier { lineno++;
1515*de2caf28SDavid du Colombier }
1516*de2caf28SDavid du Colombier } while (c == ' ' || c == '\t' ||
1517*de2caf28SDavid du Colombier c == '\f' || c == '\n' ||
1518*de2caf28SDavid du Colombier c == '\r');
1519*de2caf28SDavid du Colombier Ungetch(c);
1520*de2caf28SDavid du Colombier if (0) printf("%d: saw %d\n", lineno, c);
1521*de2caf28SDavid du Colombier if (c == 'u') /* first letter of UNLESS */
1522*de2caf28SDavid du Colombier { goto again;
1523*de2caf28SDavid du Colombier } }
1524*de2caf28SDavid du Colombier if (0)
1525*de2caf28SDavid du Colombier { printf("insert ; line %d, last_token %d in_seq %d\n",
1526*de2caf28SDavid du Colombier lineno-1, last_token, in_seq);
1527*de2caf28SDavid du Colombier }
1528*de2caf28SDavid du Colombier ValToken(1, SEMI);
1529*de2caf28SDavid du Colombier }
1530*de2caf28SDavid du Colombier /* else fall thru */
15317dd7cddfSDavid du Colombier case '\r': /* carriage return */
1532219b2ee8SDavid du Colombier goto again;
1533219b2ee8SDavid du Colombier
15347dd7cddfSDavid du Colombier case ' ': case '\t': case '\f': /* white space */
1535219b2ee8SDavid du Colombier goto again;
1536219b2ee8SDavid du Colombier
1537219b2ee8SDavid du Colombier case '#': /* preprocessor directive */
15387dd7cddfSDavid du Colombier if (in_comment) goto again;
1539*de2caf28SDavid du Colombier if (pp_mode)
1540*de2caf28SDavid du Colombier { last_token = PREPROC;
1541*de2caf28SDavid du Colombier return pre_proc();
1542*de2caf28SDavid du Colombier }
1543312a1df1SDavid du Colombier do_directive(c);
1544219b2ee8SDavid du Colombier goto again;
1545219b2ee8SDavid du Colombier
1546219b2ee8SDavid du Colombier case '\"':
1547219b2ee8SDavid du Colombier getword(c, notquote);
1548219b2ee8SDavid du Colombier if (Getchar() != '\"')
1549219b2ee8SDavid du Colombier fatal("string not terminated", yytext);
1550219b2ee8SDavid du Colombier strcat(yytext, "\"");
15517dd7cddfSDavid du Colombier SymToken(lookup(yytext), STRING)
15527dd7cddfSDavid du Colombier
155300d97012SDavid du Colombier case '$':
155400d97012SDavid du Colombier getword('\"', notdollar);
155500d97012SDavid du Colombier if (Getchar() != '$')
155600d97012SDavid du Colombier fatal("ltl definition not terminated", yytext);
155700d97012SDavid du Colombier strcat(yytext, "\"");
155800d97012SDavid du Colombier SymToken(lookup(yytext), STRING)
155900d97012SDavid du Colombier
15607dd7cddfSDavid du Colombier case '\'': /* new 3.0.9 */
15617dd7cddfSDavid du Colombier c = Getchar();
15627dd7cddfSDavid du Colombier if (c == '\\')
15637dd7cddfSDavid du Colombier { c = Getchar();
15647dd7cddfSDavid du Colombier if (c == 'n') c = '\n';
15657dd7cddfSDavid du Colombier else if (c == 'r') c = '\r';
15667dd7cddfSDavid du Colombier else if (c == 't') c = '\t';
15677dd7cddfSDavid du Colombier else if (c == 'f') c = '\f';
15687dd7cddfSDavid du Colombier }
1569312a1df1SDavid du Colombier if (Getchar() != '\'' && !in_comment)
1570312a1df1SDavid du Colombier fatal("character quote missing: %s", yytext);
15717dd7cddfSDavid du Colombier ValToken(c, CONST)
1572219b2ee8SDavid du Colombier
1573219b2ee8SDavid du Colombier default:
1574219b2ee8SDavid du Colombier break;
1575219b2ee8SDavid du Colombier }
1576219b2ee8SDavid du Colombier
15777dd7cddfSDavid du Colombier if (isdigit_(c))
1578*de2caf28SDavid du Colombier { long int nr;
1579*de2caf28SDavid du Colombier getword(c, isdigit_);
1580*de2caf28SDavid du Colombier errno = 0;
1581*de2caf28SDavid du Colombier nr = strtol(yytext, NULL, 10);
1582*de2caf28SDavid du Colombier if (errno != 0)
1583*de2caf28SDavid du Colombier { fprintf(stderr, "spin: value out of range: '%s' read as '%d'\n",
1584*de2caf28SDavid du Colombier yytext, (int) nr);
1585*de2caf28SDavid du Colombier }
1586*de2caf28SDavid du Colombier ValToken((int)nr, CONST)
1587219b2ee8SDavid du Colombier }
1588219b2ee8SDavid du Colombier
15897dd7cddfSDavid du Colombier if (isalpha_(c) || c == '_')
1590219b2ee8SDavid du Colombier { getword(c, isalnum_);
1591219b2ee8SDavid du Colombier if (!in_comment)
15927dd7cddfSDavid du Colombier { c = check_name(yytext);
1593*de2caf28SDavid du Colombier
1594*de2caf28SDavid du Colombier /* replace timeout with (timeout) */
1595*de2caf28SDavid du Colombier if (c == TIMEOUT
1596*de2caf28SDavid du Colombier && Inlining < 0
1597*de2caf28SDavid du Colombier && last_token != '(')
1598*de2caf28SDavid du Colombier { push_back("timeout)");
1599*de2caf28SDavid du Colombier last_token = '(';
1600*de2caf28SDavid du Colombier return '(';
1601*de2caf28SDavid du Colombier }
1602*de2caf28SDavid du Colombier /* end */
1603*de2caf28SDavid du Colombier
1604*de2caf28SDavid du Colombier #ifdef EXPAND_SELECT
1605*de2caf28SDavid du Colombier if (c == SELECT && Inlining < 0)
1606*de2caf28SDavid du Colombier { char name[64], from[32], upto[32];
1607*de2caf28SDavid du Colombier int i, a, b;
1608*de2caf28SDavid du Colombier new_select();
1609*de2caf28SDavid du Colombier if (!scan_to('(', 0, 0, 0)
1610*de2caf28SDavid du Colombier || !scan_to(':', isalnum, name, sizeof(name))
1611*de2caf28SDavid du Colombier || !scan_to('.', isdigit, from, sizeof(from))
1612*de2caf28SDavid du Colombier || !scan_to('.', 0, 0, 0)
1613*de2caf28SDavid du Colombier || !scan_to(')', isdigit, upto, sizeof(upto)))
1614*de2caf28SDavid du Colombier { goto not_expanded;
1615*de2caf28SDavid du Colombier }
1616*de2caf28SDavid du Colombier a = atoi(from);
1617*de2caf28SDavid du Colombier b = atoi(upto);
1618*de2caf28SDavid du Colombier if (0)
1619*de2caf28SDavid du Colombier { printf("Select %s from %d to %d\n",
1620*de2caf28SDavid du Colombier name, a, b);
1621*de2caf28SDavid du Colombier }
1622*de2caf28SDavid du Colombier if (a > b)
1623*de2caf28SDavid du Colombier { non_fatal("bad range in select statement", 0);
1624*de2caf28SDavid du Colombier goto again;
1625*de2caf28SDavid du Colombier }
1626*de2caf28SDavid du Colombier if (b - a <= 32)
1627*de2caf28SDavid du Colombier { push_back("if ");
1628*de2caf28SDavid du Colombier for (i = a; i <= b; i++)
1629*de2caf28SDavid du Colombier { char buf[256];
1630*de2caf28SDavid du Colombier push_back(":: ");
1631*de2caf28SDavid du Colombier sprintf(buf, "%s = %d ",
1632*de2caf28SDavid du Colombier name, i);
1633*de2caf28SDavid du Colombier push_back(buf);
1634*de2caf28SDavid du Colombier }
1635*de2caf28SDavid du Colombier push_back("fi ");
1636*de2caf28SDavid du Colombier } else
1637*de2caf28SDavid du Colombier { char buf[256];
1638*de2caf28SDavid du Colombier sprintf(buf, "%s = %d; do ",
1639*de2caf28SDavid du Colombier name, a);
1640*de2caf28SDavid du Colombier push_back(buf);
1641*de2caf28SDavid du Colombier sprintf(buf, ":: (%s < %d) -> %s++ ",
1642*de2caf28SDavid du Colombier name, b, name);
1643*de2caf28SDavid du Colombier push_back(buf);
1644*de2caf28SDavid du Colombier push_back(":: break od; ");
1645*de2caf28SDavid du Colombier }
1646*de2caf28SDavid du Colombier goto again;
1647*de2caf28SDavid du Colombier }
1648*de2caf28SDavid du Colombier not_expanded:
1649*de2caf28SDavid du Colombier #endif
1650*de2caf28SDavid du Colombier
1651*de2caf28SDavid du Colombier #ifdef DEFER_LTL
1652*de2caf28SDavid du Colombier if (c == LTL && !deferred)
1653*de2caf28SDavid du Colombier { if (put_deferred())
1654*de2caf28SDavid du Colombier { goto again;
1655*de2caf28SDavid du Colombier } }
1656*de2caf28SDavid du Colombier #endif
1657*de2caf28SDavid du Colombier if (c)
1658*de2caf28SDavid du Colombier { last_token = c;
1659*de2caf28SDavid du Colombier return c;
1660*de2caf28SDavid du Colombier }
16617dd7cddfSDavid du Colombier /* else fall through */
16627dd7cddfSDavid du Colombier }
16637dd7cddfSDavid du Colombier goto again;
1664219b2ee8SDavid du Colombier }
1665219b2ee8SDavid du Colombier
166600d97012SDavid du Colombier if (ltl_mode)
166700d97012SDavid du Colombier { switch (c) {
166800d97012SDavid du Colombier case '-': c = follow('>', IMPLIES, '-'); break;
166900d97012SDavid du Colombier case '[': c = follow(']', ALWAYS, '['); break;
167000d97012SDavid du Colombier case '<': c = follow('>', EVENTUALLY, '<');
167100d97012SDavid du Colombier if (c == '<')
167200d97012SDavid du Colombier { c = Getchar();
167300d97012SDavid du Colombier if (c == '-')
167400d97012SDavid du Colombier { c = follow('>', EQUIV, '-');
167500d97012SDavid du Colombier if (c == '-')
167600d97012SDavid du Colombier { Ungetch(c);
167700d97012SDavid du Colombier c = '<';
167800d97012SDavid du Colombier }
167900d97012SDavid du Colombier } else
168000d97012SDavid du Colombier { Ungetch(c);
168100d97012SDavid du Colombier c = '<';
168200d97012SDavid du Colombier } }
168300d97012SDavid du Colombier default: break;
168400d97012SDavid du Colombier } }
168500d97012SDavid du Colombier
1686219b2ee8SDavid du Colombier switch (c) {
1687219b2ee8SDavid du Colombier case '/': c = follow('*', 0, '/');
1688219b2ee8SDavid du Colombier if (!c) { in_comment = 1; goto again; }
1689219b2ee8SDavid du Colombier break;
1690219b2ee8SDavid du Colombier case '*': c = follow('/', 0, '*');
1691219b2ee8SDavid du Colombier if (!c) { in_comment = 0; goto again; }
1692219b2ee8SDavid du Colombier break;
1693219b2ee8SDavid du Colombier case ':': c = follow(':', SEP, ':'); break;
1694*de2caf28SDavid du Colombier case '-': c = follow('>', ARROW, follow('-', DECR, '-')); break;
1695219b2ee8SDavid du Colombier case '+': c = follow('+', INCR, '+'); break;
1696219b2ee8SDavid du Colombier case '<': c = follow('<', LSHIFT, follow('=', LE, LT)); break;
1697219b2ee8SDavid du Colombier case '>': c = follow('>', RSHIFT, follow('=', GE, GT)); break;
1698219b2ee8SDavid du Colombier case '=': c = follow('=', EQ, ASGN); break;
1699219b2ee8SDavid du Colombier case '!': c = follow('=', NE, follow('!', O_SND, SND)); break;
1700219b2ee8SDavid du Colombier case '?': c = follow('?', R_RCV, RCV); break;
1701219b2ee8SDavid du Colombier case '&': c = follow('&', AND, '&'); break;
1702219b2ee8SDavid du Colombier case '|': c = follow('|', OR, '|'); break;
1703219b2ee8SDavid du Colombier case ';': c = SEMI; break;
170400d97012SDavid du Colombier case '.': c = follow('.', DOTDOT, '.'); break;
170500d97012SDavid du Colombier case '{': scope_seq[scope_level++]++; set_cur_scope(); break;
170600d97012SDavid du Colombier case '}': scope_level--; set_cur_scope(); break;
1707219b2ee8SDavid du Colombier default : break;
1708219b2ee8SDavid du Colombier }
1709*de2caf28SDavid du Colombier ValToken(0, c)
1710219b2ee8SDavid du Colombier }
1711219b2ee8SDavid du Colombier
1712219b2ee8SDavid du Colombier static struct {
171300d97012SDavid du Colombier char *s; int tok;
171400d97012SDavid du Colombier } LTL_syms[] = {
171500d97012SDavid du Colombier /* [], <>, ->, and <-> are intercepted in lex() */
171600d97012SDavid du Colombier { "U", UNTIL },
171700d97012SDavid du Colombier { "V", RELEASE },
171800d97012SDavid du Colombier { "W", WEAK_UNTIL },
171900d97012SDavid du Colombier { "X", NEXT },
172000d97012SDavid du Colombier { "always", ALWAYS },
172100d97012SDavid du Colombier { "eventually", EVENTUALLY },
172200d97012SDavid du Colombier { "until", UNTIL },
172300d97012SDavid du Colombier { "stronguntil",UNTIL },
172400d97012SDavid du Colombier { "weakuntil", WEAK_UNTIL },
172500d97012SDavid du Colombier { "release", RELEASE },
172600d97012SDavid du Colombier { "next", NEXT },
172700d97012SDavid du Colombier { "implies", IMPLIES },
172800d97012SDavid du Colombier { "equivalent", EQUIV },
172900d97012SDavid du Colombier { 0, 0 },
173000d97012SDavid du Colombier };
173100d97012SDavid du Colombier
173200d97012SDavid du Colombier static struct {
1733219b2ee8SDavid du Colombier char *s; int tok; int val; char *sym;
1734219b2ee8SDavid du Colombier } Names[] = {
17357dd7cddfSDavid du Colombier {"active", ACTIVE, 0, 0},
17367dd7cddfSDavid du Colombier {"assert", ASSERT, 0, 0},
17377dd7cddfSDavid du Colombier {"atomic", ATOMIC, 0, 0},
17387dd7cddfSDavid du Colombier {"bit", TYPE, BIT, 0},
17397dd7cddfSDavid du Colombier {"bool", TYPE, BIT, 0},
17407dd7cddfSDavid du Colombier {"break", BREAK, 0, 0},
17417dd7cddfSDavid du Colombier {"byte", TYPE, BYTE, 0},
1742312a1df1SDavid du Colombier {"c_code", C_CODE, 0, 0},
1743312a1df1SDavid du Colombier {"c_decl", C_DECL, 0, 0},
1744312a1df1SDavid du Colombier {"c_expr", C_EXPR, 0, 0},
1745312a1df1SDavid du Colombier {"c_state", C_STATE, 0, 0},
1746312a1df1SDavid du Colombier {"c_track", C_TRACK, 0, 0},
17477dd7cddfSDavid du Colombier {"D_proctype", D_PROCTYPE, 0, 0},
17487dd7cddfSDavid du Colombier {"do", DO, 0, 0},
17497dd7cddfSDavid du Colombier {"chan", TYPE, CHAN, 0},
17507dd7cddfSDavid du Colombier {"else", ELSE, 0, 0},
17517dd7cddfSDavid du Colombier {"empty", EMPTY, 0, 0},
17527dd7cddfSDavid du Colombier {"enabled", ENABLED, 0, 0},
17537dd7cddfSDavid du Colombier {"eval", EVAL, 0, 0},
17547dd7cddfSDavid du Colombier {"false", CONST, 0, 0},
17557dd7cddfSDavid du Colombier {"fi", FI, 0, 0},
175600d97012SDavid du Colombier {"for", FOR, 0, 0},
17577dd7cddfSDavid du Colombier {"full", FULL, 0, 0},
1758*de2caf28SDavid du Colombier {"get_priority", GET_P, 0, 0},
17597dd7cddfSDavid du Colombier {"goto", GOTO, 0, 0},
17607dd7cddfSDavid du Colombier {"hidden", HIDDEN, 0, ":hide:"},
17617dd7cddfSDavid du Colombier {"if", IF, 0, 0},
176200d97012SDavid du Colombier {"in", IN, 0, 0},
17637dd7cddfSDavid du Colombier {"init", INIT, 0, ":init:"},
176400d97012SDavid du Colombier {"inline", INLINE, 0, 0},
17657dd7cddfSDavid du Colombier {"int", TYPE, INT, 0},
17667dd7cddfSDavid du Colombier {"len", LEN, 0, 0},
1767312a1df1SDavid du Colombier {"local", ISLOCAL, 0, ":local:"},
176800d97012SDavid du Colombier {"ltl", LTL, 0, ":ltl:"},
17697dd7cddfSDavid du Colombier {"mtype", TYPE, MTYPE, 0},
17707dd7cddfSDavid du Colombier {"nempty", NEMPTY, 0, 0},
17717dd7cddfSDavid du Colombier {"never", CLAIM, 0, ":never:"},
17727dd7cddfSDavid du Colombier {"nfull", NFULL, 0, 0},
17737dd7cddfSDavid du Colombier {"notrace", TRACE, 0, ":notrace:"},
17747dd7cddfSDavid du Colombier {"np_", NONPROGRESS, 0, 0},
17757dd7cddfSDavid du Colombier {"od", OD, 0, 0},
17767dd7cddfSDavid du Colombier {"of", OF, 0, 0},
17777dd7cddfSDavid du Colombier {"pc_value", PC_VAL, 0, 0},
1778312a1df1SDavid du Colombier {"pid", TYPE, BYTE, 0},
17797dd7cddfSDavid du Colombier {"printf", PRINT, 0, 0},
1780312a1df1SDavid du Colombier {"printm", PRINTM, 0, 0},
17817dd7cddfSDavid du Colombier {"priority", PRIORITY, 0, 0},
17827dd7cddfSDavid du Colombier {"proctype", PROCTYPE, 0, 0},
17837dd7cddfSDavid du Colombier {"provided", PROVIDED, 0, 0},
1784*de2caf28SDavid du Colombier {"return", RETURN, 0, 0},
17857dd7cddfSDavid du Colombier {"run", RUN, 0, 0},
17867dd7cddfSDavid du Colombier {"d_step", D_STEP, 0, 0},
178700d97012SDavid du Colombier {"select", SELECT, 0, 0},
1788*de2caf28SDavid du Colombier {"set_priority", SET_P, 0, 0},
17897dd7cddfSDavid du Colombier {"short", TYPE, SHORT, 0},
17907dd7cddfSDavid du Colombier {"skip", CONST, 1, 0},
17917dd7cddfSDavid du Colombier {"timeout", TIMEOUT, 0, 0},
17927dd7cddfSDavid du Colombier {"trace", TRACE, 0, ":trace:"},
17937dd7cddfSDavid du Colombier {"true", CONST, 1, 0},
17947dd7cddfSDavid du Colombier {"show", SHOW, 0, ":show:"},
17957dd7cddfSDavid du Colombier {"typedef", TYPEDEF, 0, 0},
17967dd7cddfSDavid du Colombier {"unless", UNLESS, 0, 0},
17977dd7cddfSDavid du Colombier {"unsigned", TYPE, UNSIGNED, 0},
17987dd7cddfSDavid du Colombier {"xr", XU, XR, 0},
17997dd7cddfSDavid du Colombier {"xs", XU, XS, 0},
18007dd7cddfSDavid du Colombier {0, 0, 0, 0},
1801219b2ee8SDavid du Colombier };
1802219b2ee8SDavid du Colombier
18037dd7cddfSDavid du Colombier static int
check_name(char * s)1804219b2ee8SDavid du Colombier check_name(char *s)
1805312a1df1SDavid du Colombier { int i;
1806219b2ee8SDavid du Colombier
1807219b2ee8SDavid du Colombier yylval = nn(ZN, 0, ZN, ZN);
180800d97012SDavid du Colombier
180900d97012SDavid du Colombier if (ltl_mode)
181000d97012SDavid du Colombier { for (i = 0; LTL_syms[i].s; i++)
181100d97012SDavid du Colombier { if (strcmp(s, LTL_syms[i].s) == 0)
181200d97012SDavid du Colombier { return LTL_syms[i].tok;
181300d97012SDavid du Colombier } } }
181400d97012SDavid du Colombier
1815219b2ee8SDavid du Colombier for (i = 0; Names[i].s; i++)
181600d97012SDavid du Colombier { if (strcmp(s, Names[i].s) == 0)
1817219b2ee8SDavid du Colombier { yylval->val = Names[i].val;
1818219b2ee8SDavid du Colombier if (Names[i].sym)
1819219b2ee8SDavid du Colombier yylval->sym = lookup(Names[i].sym);
1820*de2caf28SDavid du Colombier if (Names[i].tok == IN && !in_for)
1821*de2caf28SDavid du Colombier { continue;
1822*de2caf28SDavid du Colombier }
1823219b2ee8SDavid du Colombier return Names[i].tok;
182400d97012SDavid du Colombier } }
1825219b2ee8SDavid du Colombier
1826312a1df1SDavid du Colombier if ((yylval->val = ismtype(s)) != 0)
1827219b2ee8SDavid du Colombier { yylval->ismtyp = 1;
1828*de2caf28SDavid du Colombier yylval->sym = (Symbol *) emalloc(sizeof(Symbol));
1829*de2caf28SDavid du Colombier yylval->sym->name = (char *) emalloc(strlen(s)+1);
1830*de2caf28SDavid du Colombier strcpy(yylval->sym->name, s);
1831219b2ee8SDavid du Colombier return CONST;
1832219b2ee8SDavid du Colombier }
1833219b2ee8SDavid du Colombier
1834219b2ee8SDavid du Colombier if (strcmp(s, "_last") == 0)
1835219b2ee8SDavid du Colombier has_last++;
1836219b2ee8SDavid du Colombier
1837*de2caf28SDavid du Colombier if (strcmp(s, "_priority") == 0)
1838*de2caf28SDavid du Colombier has_priority++;
1839*de2caf28SDavid du Colombier
18407dd7cddfSDavid du Colombier if (Inlining >= 0 && !ReDiRect)
18417dd7cddfSDavid du Colombier { Lextok *tt, *t = Inline_stub[Inlining]->params;
1842312a1df1SDavid du Colombier
1843312a1df1SDavid du Colombier for (i = 0; t; t = t->rgt, i++) /* formal pars */
1844312a1df1SDavid du Colombier if (!strcmp(s, t->lft->sym->name) /* varname matches formal */
1845312a1df1SDavid du Colombier && strcmp(s, Inline_stub[Inlining]->anms[i]) != 0) /* actual pars */
18467dd7cddfSDavid du Colombier {
18477dd7cddfSDavid du Colombier #if 0
18487dd7cddfSDavid du Colombier if (verbose&32)
18497dd7cddfSDavid du Colombier printf("\tline %d, replace %s in call of '%s' with %s\n",
18507dd7cddfSDavid du Colombier lineno, s,
18517dd7cddfSDavid du Colombier Inline_stub[Inlining]->nm->name,
18527dd7cddfSDavid du Colombier Inline_stub[Inlining]->anms[i]);
18537dd7cddfSDavid du Colombier #endif
1854312a1df1SDavid du Colombier for (tt = Inline_stub[Inlining]->params; tt; tt = tt->rgt)
18557dd7cddfSDavid du Colombier if (!strcmp(Inline_stub[Inlining]->anms[i],
18567dd7cddfSDavid du Colombier tt->lft->sym->name))
18577dd7cddfSDavid du Colombier { /* would be cyclic if not caught */
185800d97012SDavid du Colombier printf("spin: %s:%d replacement value: %s\n",
185900d97012SDavid du Colombier oFname->name?oFname->name:"--", lineno, tt->lft->sym->name);
186000d97012SDavid du Colombier fatal("formal par of %s contains replacement value",
1861312a1df1SDavid du Colombier Inline_stub[Inlining]->nm->name);
18627dd7cddfSDavid du Colombier yylval->ntyp = tt->lft->ntyp;
18637dd7cddfSDavid du Colombier yylval->sym = lookup(tt->lft->sym->name);
18647dd7cddfSDavid du Colombier return NAME;
18657dd7cddfSDavid du Colombier }
186600d97012SDavid du Colombier
186700d97012SDavid du Colombier /* check for occurrence of param as field of struct */
186800d97012SDavid du Colombier { char *ptr = Inline_stub[Inlining]->anms[i];
1869*de2caf28SDavid du Colombier char *optr = ptr;
187000d97012SDavid du Colombier while ((ptr = strstr(ptr, s)) != NULL)
1871*de2caf28SDavid du Colombier { if ((ptr > optr && *(ptr-1) == '.')
187200d97012SDavid du Colombier || *(ptr+strlen(s)) == '.')
187300d97012SDavid du Colombier { fatal("formal par of %s used in structure name",
187400d97012SDavid du Colombier Inline_stub[Inlining]->nm->name);
187500d97012SDavid du Colombier }
187600d97012SDavid du Colombier ptr++;
187700d97012SDavid du Colombier } }
18787dd7cddfSDavid du Colombier ReDiRect = Inline_stub[Inlining]->anms[i];
18797dd7cddfSDavid du Colombier return 0;
18807dd7cddfSDavid du Colombier } }
1881219b2ee8SDavid du Colombier
18827dd7cddfSDavid du Colombier yylval->sym = lookup(s); /* symbol table */
1883219b2ee8SDavid du Colombier if (isutype(s))
1884219b2ee8SDavid du Colombier return UNAME;
1885219b2ee8SDavid du Colombier if (isproctype(s))
1886219b2ee8SDavid du Colombier return PNAME;
18877dd7cddfSDavid du Colombier if (iseqname(s))
18887dd7cddfSDavid du Colombier return INAME;
1889219b2ee8SDavid du Colombier
1890219b2ee8SDavid du Colombier return NAME;
1891219b2ee8SDavid du Colombier }
1892219b2ee8SDavid du Colombier
1893219b2ee8SDavid du Colombier int
yylex(void)1894219b2ee8SDavid du Colombier yylex(void)
1895219b2ee8SDavid du Colombier { static int last = 0;
1896219b2ee8SDavid du Colombier static int hold = 0;
1897219b2ee8SDavid du Colombier int c;
1898219b2ee8SDavid du Colombier /*
1899219b2ee8SDavid du Colombier * repair two common syntax mistakes with
1900219b2ee8SDavid du Colombier * semi-colons before or after a '}'
1901219b2ee8SDavid du Colombier */
1902219b2ee8SDavid du Colombier if (hold)
1903219b2ee8SDavid du Colombier { c = hold;
1904219b2ee8SDavid du Colombier hold = 0;
1905*de2caf28SDavid du Colombier last_token = c;
1906219b2ee8SDavid du Colombier } else
1907219b2ee8SDavid du Colombier { c = lex();
1908219b2ee8SDavid du Colombier if (last == ELSE
1909219b2ee8SDavid du Colombier && c != SEMI
1910*de2caf28SDavid du Colombier && c != ARROW
1911219b2ee8SDavid du Colombier && c != FI)
1912219b2ee8SDavid du Colombier { hold = c;
1913219b2ee8SDavid du Colombier last = 0;
1914*de2caf28SDavid du Colombier last_token = SEMI;
1915219b2ee8SDavid du Colombier return SEMI;
1916219b2ee8SDavid du Colombier }
1917219b2ee8SDavid du Colombier if (last == '}'
1918219b2ee8SDavid du Colombier && c != PROCTYPE
1919219b2ee8SDavid du Colombier && c != INIT
1920219b2ee8SDavid du Colombier && c != CLAIM
1921219b2ee8SDavid du Colombier && c != SEP
1922219b2ee8SDavid du Colombier && c != FI
1923219b2ee8SDavid du Colombier && c != OD
1924219b2ee8SDavid du Colombier && c != '}'
1925219b2ee8SDavid du Colombier && c != UNLESS
1926219b2ee8SDavid du Colombier && c != SEMI
1927*de2caf28SDavid du Colombier && c != ARROW
1928219b2ee8SDavid du Colombier && c != EOF)
1929219b2ee8SDavid du Colombier { hold = c;
1930219b2ee8SDavid du Colombier last = 0;
1931*de2caf28SDavid du Colombier last_token = SEMI;
1932219b2ee8SDavid du Colombier return SEMI; /* insert ';' */
1933219b2ee8SDavid du Colombier }
1934*de2caf28SDavid du Colombier if (c == SEMI || c == ARROW)
1935312a1df1SDavid du Colombier { /* if context, we're not in a typedef
1936219b2ee8SDavid du Colombier * because they're global.
1937219b2ee8SDavid du Colombier * if owner, we're at the end of a ref
1938219b2ee8SDavid du Colombier * to a struct field -- prevent that the
1939219b2ee8SDavid du Colombier * lookahead is interpreted as a field of
1940219b2ee8SDavid du Colombier * the same struct...
1941219b2ee8SDavid du Colombier */
1942219b2ee8SDavid du Colombier if (context) owner = ZS;
1943219b2ee8SDavid du Colombier hold = lex(); /* look ahead */
1944219b2ee8SDavid du Colombier if (hold == '}'
1945*de2caf28SDavid du Colombier || hold == ARROW
1946219b2ee8SDavid du Colombier || hold == SEMI)
1947219b2ee8SDavid du Colombier { c = hold; /* omit ';' */
1948219b2ee8SDavid du Colombier hold = 0;
1949219b2ee8SDavid du Colombier }
1950219b2ee8SDavid du Colombier }
1951219b2ee8SDavid du Colombier }
1952219b2ee8SDavid du Colombier last = c;
19537dd7cddfSDavid du Colombier
19547dd7cddfSDavid du Colombier if (IArgs)
19557dd7cddfSDavid du Colombier { static int IArg_nst = 0;
1956312a1df1SDavid du Colombier
19577dd7cddfSDavid du Colombier if (strcmp(yytext, ",") == 0)
19587dd7cddfSDavid du Colombier { IArg_cont[++IArgno][0] = '\0';
19597dd7cddfSDavid du Colombier } else if (strcmp(yytext, "(") == 0)
19607dd7cddfSDavid du Colombier { if (IArg_nst++ == 0)
19617dd7cddfSDavid du Colombier { IArgno = 0;
19627dd7cddfSDavid du Colombier IArg_cont[0][0] = '\0';
19637dd7cddfSDavid du Colombier } else
1964*de2caf28SDavid du Colombier { assert(strlen(IArg_cont[IArgno])+strlen(yytext) < sizeof(IArg_cont));
19657dd7cddfSDavid du Colombier strcat(IArg_cont[IArgno], yytext);
1966*de2caf28SDavid du Colombier }
1967312a1df1SDavid du Colombier } else if (strcmp(yytext, ")") == 0)
1968312a1df1SDavid du Colombier { if (--IArg_nst > 0)
1969*de2caf28SDavid du Colombier { assert(strlen(IArg_cont[IArgno])+strlen(yytext) < sizeof(IArg_cont));
1970312a1df1SDavid du Colombier strcat(IArg_cont[IArgno], yytext);
1971*de2caf28SDavid du Colombier }
1972312a1df1SDavid du Colombier } else if (c == CONST && yytext[0] == '\'')
1973312a1df1SDavid du Colombier { sprintf(yytext, "'%c'", yylval->val);
1974*de2caf28SDavid du Colombier assert(strlen(IArg_cont[IArgno])+strlen(yytext) < sizeof(IArg_cont));
1975312a1df1SDavid du Colombier strcat(IArg_cont[IArgno], yytext);
197600d97012SDavid du Colombier } else if (c == CONST)
197700d97012SDavid du Colombier { sprintf(yytext, "%d", yylval->val);
1978*de2caf28SDavid du Colombier assert(strlen(IArg_cont[IArgno])+strlen(yytext) < sizeof(IArg_cont));
197900d97012SDavid du Colombier strcat(IArg_cont[IArgno], yytext);
1980312a1df1SDavid du Colombier } else
1981f3793cddSDavid du Colombier {
1982f3793cddSDavid du Colombier switch (c) {
1983*de2caf28SDavid du Colombier case ARROW: strcpy(yytext, "->"); break; /* NEW */
1984f3793cddSDavid du Colombier case SEP: strcpy(yytext, "::"); break;
1985f3793cddSDavid du Colombier case SEMI: strcpy(yytext, ";"); break;
1986f3793cddSDavid du Colombier case DECR: strcpy(yytext, "--"); break;
1987f3793cddSDavid du Colombier case INCR: strcpy(yytext, "++"); break;
1988f3793cddSDavid du Colombier case LSHIFT: strcpy(yytext, "<<"); break;
1989f3793cddSDavid du Colombier case RSHIFT: strcpy(yytext, ">>"); break;
1990f3793cddSDavid du Colombier case LE: strcpy(yytext, "<="); break;
1991f3793cddSDavid du Colombier case LT: strcpy(yytext, "<"); break;
1992f3793cddSDavid du Colombier case GE: strcpy(yytext, ">="); break;
1993f3793cddSDavid du Colombier case GT: strcpy(yytext, ">"); break;
1994f3793cddSDavid du Colombier case EQ: strcpy(yytext, "=="); break;
1995f3793cddSDavid du Colombier case ASGN: strcpy(yytext, "="); break;
1996f3793cddSDavid du Colombier case NE: strcpy(yytext, "!="); break;
1997f3793cddSDavid du Colombier case R_RCV: strcpy(yytext, "??"); break;
1998f3793cddSDavid du Colombier case RCV: strcpy(yytext, "?"); break;
1999f3793cddSDavid du Colombier case O_SND: strcpy(yytext, "!!"); break;
2000f3793cddSDavid du Colombier case SND: strcpy(yytext, "!"); break;
2001f3793cddSDavid du Colombier case AND: strcpy(yytext, "&&"); break;
2002f3793cddSDavid du Colombier case OR: strcpy(yytext, "||"); break;
2003f3793cddSDavid du Colombier }
2004*de2caf28SDavid du Colombier assert(strlen(IArg_cont[IArgno])+strlen(yytext) < sizeof(IArg_cont));
2005f3793cddSDavid du Colombier strcat(IArg_cont[IArgno], yytext);
2006312a1df1SDavid du Colombier }
20077dd7cddfSDavid du Colombier }
2008219b2ee8SDavid du Colombier return c;
2009219b2ee8SDavid du Colombier }
2010