1 /*	idyac.y	(CWI)	1.1	85/03/01	*/
2 %{
3 #include "ideal.h"
4 
5 extern BOXPTR boxlist;
6 
7 yyerror (message)
8 char *message;
9 {
10 	fprintf (stderr, "ideal: ");
11 	fprintf (stderr, "%s ", message);
12 	fprintf (stderr, "near line %d in file %s\n",
13 		lineno,
14 		filename
15 	);
16 }
17 %}
18 %token	BOX VAR BDLIST PUT CONN TO USING
19 %token	CONSTRUCT DRAW OPAQUE LEFT CENTER RIGHT AT
20 %token	NAME CONST STRING
21 %token	LINE CIRCLE ARC SPLINE
22 %token	PATH
23 %token	INTERIOR EXTERIOR
24 %token	LBRACE RBRACE
25 
26 %left '^'
27 %left '+' '-'
28 %left '*' '/'
29 %left '['
30 %left UMINUS
31 
32 %%
33 stuff	:figspec
34 	|	/*empty*/
35 	;
36 
37 figspec	:boxdef	{
38 		forget (((BOXPTR)$1)->name);
39 		((BOXPTR) $1)->next = boxlist;
40 		boxlist = (BOXPTR) $1;
41 	}
42 	|figspec boxdef	{
43 		forget (((BOXPTR)$2)->name);
44 		((BOXPTR)$2)->next = boxlist;
45 		boxlist = (BOXPTR) $2;
46 	}
47 	;
48 
49 boxdef	:body		{$$ = $1;}
50 	|BOX body	{$$ = $2;}
51 	;
52 
53 body	:NAME LBRACE stmts RBRACE	{$$ = (int) boxgen ($1, (STMTPTR) $3);}
54 	|NAME LBRACE RBRACE		{$$ = (int) boxgen ($1, (STMTPTR) NULL);}
55 	;
56 
57 stmts   :stmt		{$$ = $1;}
58 	|stmts stmt	{
59 		if ($2) {
60 			((STMTPTR)$2)->next = (STMTPTR)$1;
61 			$$ = $2;
62 		} else
63 			$$ = $1;
64 	}
65 	;
66 
67 stmt	:varstmt ';'	{$$ = (int) stmtgen (VAR, (char *) $1);}
68 	|eqnstmt ';'	{$$ = (int) stmtgen ('=', (char *) $1);}
69 	|bdlist	';'	{$$ = (int) stmtgen (BDLIST, (char *) $1);}
70 	|putstmt	{$$ = (int) stmtgen (PUT, (char *) $1);}
71 	|connstmt ';'	{$$ = (int) stmtgen (CONN, (char *) $1);}
72 	|penstmt ';'	{if ($1) {
73 				$$ = (int) stmtgen (USING, (char *) $1);
74 			} else {
75 				$$ = (int) NULL;
76 			}
77 		}
78 	|drawstmt ';'	{$$ = (int) stmtgen (DRAW, (char *) $1);}
79 	|opaque	';'	{$$ = (int) stmtgen (OPAQUE, (char *) $1);}
80 	|strstmt ';'	{$$ = (int) stmtgen (STRING, (char *) $1);}
81 	|splstmt ';'	{$$ = (int) stmtgen (SPLINE, (char *) $1);}
82 	|';'		{$$ = (int) NULL;}
83 	|error ';'	{fprintf (stderr, "ideal: syntax error near line %d in file %s\n",
84 				lineno, filename);
85 			yyerrok;
86 			$$ = NULL;
87 	}
88 	;
89 
90 varstmt	:VAR varlist	{$$ = (int) $2;}
91 	;
92 
93 varlist	:NAME	{$$ = (int) namegen ($1);}
94 	|varlist ',' NAME	{
95 		NAMEPTR temp;
96 		temp = (NAMEPTR) namegen ($3);
97 		temp->next = (NAMEPTR)$1;
98 		$$ = (int) temp;
99 	}
100 	;
101 
102 eqnstmt	:expr '=' expr		{$$ = (int) intlgen ('=', (EXPR) $1, (EXPR) $3);}
103 	|expr '~' expr		{$$ = (int) intlgen ('~', (EXPR) $1, (EXPR) $3);}
104 	|eqnstmt '=' expr	{$$ = (int) intlgen ('=', (EXPR) $1, (EXPR) $3);}
105 	|eqnstmt '~' expr	{$$ = (int) intlgen ('~', (EXPR) $1, (EXPR) $3);}
106 	;
107 
108 bdlist	:BDLIST '=' exprlist	{$$ = (int) $3;}
109 	;
110 
111 exprlist:expr		{$$ = (int) exprgen ((EXPR) $1);}
112 	|exprlist ',' expr	{
113 		EXPRPTR temp;
114 		temp = (EXPRPTR) exprgen ((EXPR) $3);
115 		temp->next = (EXPRPTR)$1;
116 		$$ = (int) temp;
117 	}
118 	;
119 
120 putstmt	:putword NAME ':' body	{$$ = (int) putgen ($2, (BOXPTR) $4, $1);}
121 	|putword body		{$$ = (int) putgen (NULL, (BOXPTR) $2, $1);}
122 	|NAME ':' putword body	{$$ = (int) putgen ($1, (BOXPTR) $4, $3);}
123 	;
124 
125 putword	:PUT		{$$ = $1;}
126 	|CONSTRUCT	{$$ = $1;}
127 	;
128 
129 connstmt:CONN knotlist	{$$ = (int) $2;}
130 	;
131 
132 penstmt	:CONN knotlist USING expr body '<' expr ',' expr '>'
133 		{if (!((EXPRPTR) $2)->next || ((EXPRPTR) $2)->next->next) {
134 			fprintf (stderr, "ideal: improper pen statement\n   >>>pen ignored\n");
135 			$$ = (int) NULL;
136 		} else {
137 			$$ = (int) pengen (
138 				((EXPRPTR) $2)->next->expr,
139 				((EXPRPTR) $2)->expr,
140 				(EXPR) $4,
141 				(EXPR) $7,
142 				(EXPR) $9,
143 				(BOXPTR) $5
144 			);
145 			tryfree(((EXPRPTR) $2)->next);
146 			tryfree((EXPRPTR) $2);
147 		}
148 	}
149 	;
150 
151 drawstmt:DRAW NAME	{$$ = (int) miscgen ($2);}
152 	;
153 
154 opaque	:OPAQUE	{$$ = (int) miscgen (INTERIOR);}
155 	|OPAQUE INTERIOR	{$$ = (int) miscgen (INTERIOR);}
156 	|OPAQUE EXTERIOR	{$$ = (int) miscgen (EXTERIOR);}
157 	;
158 
159 strstmt	:LEFT STRING AT expr	{$$ = (int) strgen (LEFT, (char *) $2, (EXPR) $4);}
160 	|CENTER STRING AT expr	{$$ = (int) strgen (CENTER, (char *) $2, (EXPR) $4);}
161 	|STRING AT expr	{$$ = (int) strgen (CENTER, (char *) $1, (EXPR) $3);}
162 	|RIGHT STRING AT expr	{$$ = (int) strgen (RIGHT, (char *) $2, (EXPR) $4);}
163 	;
164 
165 splstmt	:SPLINE knotlist	{$$ = (int) $2;}
166 
167 knotlist:expr		{$$ = (int) exprgen ((EXPR) $1);}
168 	|knotlist TO expr	{
169 		EXPRPTR temp;
170 		temp = (EXPRPTR) exprgen ((EXPR) $3);
171 		temp->next = (EXPRPTR) $1;
172 		$$ = (int) temp;
173 	}
174 	;
175 
176 expr	:'-' expr	%prec UMINUS
177 		{$$ = (int) intlgen ('-', (EXPR) NULL, (EXPR) $2);}
178 	|expr '+' expr	{$$ = (int) intlgen ('+', (EXPR) $1, (EXPR) $3);}
179 	|expr '-' expr	{$$ = (int) intlgen ('-', (EXPR) $1, (EXPR) $3);}
180 	|expr '*' expr	{$$ = (int) intlgen ('*', (EXPR) $1, (EXPR) $3);}
181 	|expr '/' expr	{$$ = (int) intlgen ('/', (EXPR) $1, (EXPR) $3);}
182 	|'^' expr	{$$ = (int) intlgen ('^', (EXPR) NULL, (EXPR) $2);}
183 	|pathname		{$$ = (int) extlgen ((NAMEPTR) $1);}
184 	|CONST			{$$ = $1;}
185 	|'(' expr ')'		{$$ = $2;}
186 	|'(' expr ',' expr ')'	{$$ = (int) intlgen (',', (EXPR) $2, (EXPR) $4);}
187 	|NAME '(' exprlist ')'	{$$ = (int) intlgen (NAME, (EXPR) $1, (EXPR) $3);}
188 	|expr '[' expr ',' expr ']'	{
189 		$$ = (int) bracket (
190 			(EXPR) $1,
191 			(EXPR) $3,
192 			(EXPR) $5
193 		);
194 	}
195 	;
196 
197 pathname:NAME	{$$ = (int) namegen ($1);}
198 	|NAME '.' pathname	{
199 		NAMEPTR temp;
200 		temp = (NAMEPTR) namegen($1);
201 		temp->next = (NAMEPTR)$3;
202 		$$ = (int) temp;
203 	}
204 	;
205