xref: /freebsd/sys/dev/aic7xxx/aicasm/aicasm_scan.l (revision b601c69bdbe8755d26570261d7fd4c02ee4eff74)
1 %{
2 /*
3  * Lexical Analyzer for the Aic7xxx SCSI Host adapter sequencer assembler.
4  *
5  * Copyright (c) 1997, 1998 Justin T. Gibbs.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions, and the following disclaimer,
13  *    without modification.
14  * 2. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission.
16  *
17  * Alternatively, this software may be distributed under the terms of the
18  * GNU Public License ("GPL").
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
24  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  * $FreeBSD$
33  */
34 
35 #include <sys/types.h>
36 
37 #include <limits.h>
38 #include <stdio.h>
39 #include <string.h>
40 #include <sysexits.h>
41 #include <sys/queue.h>
42 
43 #include "aicasm.h"
44 #include "aicasm_symbol.h"
45 #include "y.tab.h"
46 
47 #define MAX_STR_CONST 256
48 char string_buf[MAX_STR_CONST];
49 char *string_buf_ptr;
50 int  parren_count;
51 %}
52 
53 PATH		[-/A-Za-z0-9_.]*[./][-/A-Za-z0-9_.]*
54 WORD		[A-Za-z_][-A-Za-z_0-9]*
55 SPACE		[ \t]+
56 
57 %x COMMENT
58 %x CEXPR
59 %x INCLUDE
60 
61 %%
62 \n			{ ++yylineno; }
63 "/*"			{ BEGIN COMMENT;  /* Enter comment eating state */ }
64 <COMMENT>"/*"		{ fprintf(stderr, "Warning! Comment within comment."); }
65 <COMMENT>\n		{ ++yylineno; }
66 <COMMENT>[^*/\n]*	;
67 <COMMENT>"*"+[^*/\n]*	;
68 <COMMENT>"/"+[^*/\n]*	;
69 <COMMENT>"*"+"/"	{ BEGIN INITIAL; }
70 if[ \t]*\(		{
71 				string_buf_ptr = string_buf;
72 				parren_count = 1;
73 				BEGIN CEXPR;
74 				return T_IF;
75 			}
76 <CEXPR>\(		{	*string_buf_ptr++ = '('; parren_count++; }
77 <CEXPR>\)		{
78 				parren_count--;
79 				if (parren_count == 0) {
80 					/* All done */
81 					BEGIN INITIAL;
82 					*string_buf_ptr = '\0';
83 					yylval.sym = symtable_get(string_buf);
84 					return T_CEXPR;
85 				} else {
86 					*string_buf_ptr++ = ')';
87 				}
88 			}
89 <CEXPR>\n		{ ++yylineno; }
90 <CEXPR>[^()\n]+		{
91 				char *yptr = yytext;
92 
93 				while (*yptr != '\0')
94 					*string_buf_ptr++ = *yptr++;
95 			}
96 
97 {SPACE}			;
98 
99 	/* Register/SCB/SRAM definition keywords */
100 register		{ return T_REGISTER; }
101 const			{ yylval.value = FALSE; return T_CONST; }
102 download		{ return T_DOWNLOAD; }
103 address			{ return T_ADDRESS; }
104 access_mode		{ return T_ACCESS_MODE; }
105 RW|RO|WO		{
106 				 if (strcmp(yytext, "RW") == 0)
107 					yylval.value = RW;
108 				 else if (strcmp(yytext, "RO") == 0)
109 					yylval.value = RO;
110 				 else
111 					yylval.value = WO;
112 				 return T_MODE;
113 			}
114 bit			{ return T_BIT; }
115 mask			{ return T_MASK; }
116 alias			{ return T_ALIAS; }
117 size			{ return T_SIZE; }
118 scb			{ return T_SCB; }
119 scratch_ram		{ return T_SRAM; }
120 accumulator		{ return T_ACCUM; }
121 allones			{ return T_ALLONES; }
122 allzeros		{ return T_ALLZEROS; }
123 none			{ return T_NONE; }
124 sindex			{ return T_SINDEX; }
125 A			{ return T_A; }
126 
127 	/* Opcodes */
128 shl			{ return T_SHL; }
129 shr			{ return T_SHR; }
130 ror			{ return T_ROR; }
131 rol			{ return T_ROL; }
132 mvi			{ return T_MVI; }
133 mov			{ return T_MOV; }
134 clr			{ return T_CLR; }
135 jmp			{ return T_JMP; }
136 jc			{ return T_JC;	}
137 jnc			{ return T_JNC;	}
138 je			{ return T_JE;	}
139 jne			{ return T_JNE;	}
140 jz			{ return T_JZ;	}
141 jnz			{ return T_JNZ;	}
142 call			{ return T_CALL; }
143 add			{ return T_ADD; }
144 adc			{ return T_ADC; }
145 bmov			{ return T_BMOV; }
146 inc			{ return T_INC; }
147 dec			{ return T_DEC; }
148 stc			{ return T_STC;	}
149 clc			{ return T_CLC; }
150 cmp			{ return T_CMP;	}
151 not			{ return T_NOT;	}
152 xor			{ return T_XOR;	}
153 test			{ return T_TEST;}
154 and			{ return T_AND;	}
155 or			{ return T_OR;	}
156 ret			{ return T_RET; }
157 nop			{ return T_NOP; }
158 else			{ return T_ELSE; }
159 
160 	/* Allowed Symbols */
161 [-+,:()~|&."{};<>[\]!]	{ return yytext[0]; }
162 
163 	/* Number processing */
164 0[0-7]*			{
165 				yylval.value = strtol(yytext, NULL, 8);
166 				return T_NUMBER;
167 			}
168 
169 0[xX][0-9a-fA-F]+	{
170 				yylval.value = strtoul(yytext + 2, NULL, 16);
171 				return T_NUMBER;
172 			}
173 
174 [1-9][0-9]*		{
175 				yylval.value = strtol(yytext, NULL, 10);
176 				return T_NUMBER;
177 			}
178 
179 	/* Include Files */
180 #include		{ return T_INCLUDE; BEGIN INCLUDE;}
181 <INCLUDE>[<>\"]		{ return yytext[0]; }
182 <INCLUDE>{PATH}		{ yylval.str = strdup(yytext); return T_PATH; }
183 <INCLUDE>;		{ BEGIN INITIAL; return yytext[0]; }
184 <INCLUDE>.		{ stop("Invalid include line", EX_DATAERR); }
185 
186 	/* For parsing C include files with #define foo */
187 #define			{ yylval.value = TRUE; return T_CONST; }
188 	/* Throw away macros */
189 #define[^\n]*[()]+[^\n]* ;
190 {PATH}			{ yylval.str = strdup(yytext); return T_PATH; }
191 
192 {WORD}			{ yylval.sym = symtable_get(yytext);  return T_SYMBOL; }
193 
194 .			{
195 				char buf[255];
196 
197 				snprintf(buf, sizeof(buf), "Invalid character "
198 					 "'%c'", yytext[0]);
199 				stop(buf, EX_DATAERR);
200 			}
201 %%
202 
203 typedef struct include {
204         YY_BUFFER_STATE  buffer;
205         int              lineno;
206         char            *filename;
207 	SLIST_ENTRY(include) links;
208 }include_t;
209 
210 SLIST_HEAD(, include) include_stack;
211 
212 void
213 include_file(file_name, type)
214 	char	*file_name;
215 	include_type type;
216 {
217 	FILE *newfile;
218 	include_t *include;
219 
220 	newfile = NULL;
221 	/* Try the current directory first */
222 	if (includes_search_curdir != 0 || type == SOURCE_FILE)
223 		newfile = fopen(file_name, "r");
224 
225 	if (newfile == NULL && type != SOURCE_FILE) {
226                 path_entry_t include_dir;
227                 for (include_dir = search_path.slh_first;
228                      include_dir != NULL;
229                      include_dir = include_dir->links.sle_next) {
230 			char fullname[PATH_MAX];
231 
232 			if ((include_dir->quoted_includes_only == TRUE)
233 			 && (type != QUOTED_INCLUDE))
234 				continue;
235 
236 			snprintf(fullname, sizeof(fullname),
237 				 "%s/%s", include_dir->directory, file_name);
238 
239 			if ((newfile = fopen(fullname, "r")) != NULL)
240 				break;
241                 }
242         }
243 
244 	if (newfile == NULL) {
245 		perror(file_name);
246 		stop("Unable to open input file", EX_SOFTWARE);
247 		/* NOTREACHED */
248 	}
249 
250 	if (type != SOURCE_FILE) {
251 		include = (include_t *)malloc(sizeof(include_t));
252 		if (include == NULL) {
253 			stop("Unable to allocate include stack entry",
254 			     EX_SOFTWARE);
255 			/* NOTREACHED */
256 		}
257 		include->buffer = YY_CURRENT_BUFFER;
258 		include->lineno = yylineno;
259 		include->filename = yyfilename;
260 		SLIST_INSERT_HEAD(&include_stack, include, links);
261 	}
262 	yy_switch_to_buffer(yy_create_buffer(newfile, YY_BUF_SIZE));
263 	yylineno = 1;
264 	yyfilename = strdup(file_name);
265 }
266 
267 int
268 yywrap()
269 {
270 	include_t *include;
271 
272 	yy_delete_buffer(YY_CURRENT_BUFFER);
273 	(void)fclose(yyin);
274 	if (yyfilename != NULL)
275 		free(yyfilename);
276 	yyfilename = NULL;
277 	include = include_stack.slh_first;
278 	if (include != NULL) {
279 		yy_switch_to_buffer(include->buffer);
280 		yylineno = include->lineno;
281 		yyfilename = include->filename;
282 		SLIST_REMOVE_HEAD(&include_stack, links);
283 		free(include);
284 		return (0);
285 	}
286 	return (1);
287 }
288