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