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