xref: /freebsd/sys/dev/aic7xxx/aicasm/aicasm_scan.l (revision 1b6c76a2fe091c74f08427e6c870851025a9cf67)
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  * $Id: //depot/src/aic7xxx/aicasm/aicasm_scan.l#4 $
33  *
34  * $FreeBSD$
35  */
36 
37 #include <sys/types.h>
38 
39 #include <limits.h>
40 #include <stdio.h>
41 #include <string.h>
42 #include <sysexits.h>
43 #ifdef __linux__
44 #include "../queue.h"
45 #else
46 #include <sys/queue.h>
47 #endif
48 
49 #include "aicasm.h"
50 #include "aicasm_symbol.h"
51 #include "y.tab.h"
52 
53 #define MAX_STR_CONST 256
54 char string_buf[MAX_STR_CONST];
55 char *string_buf_ptr;
56 int  parren_count;
57 %}
58 
59 PATH		[-/A-Za-z0-9_.]*[./][-/A-Za-z0-9_.]*
60 WORD		[A-Za-z_][-A-Za-z_0-9]*
61 SPACE		[ \t]+
62 
63 %x COMMENT
64 %x CEXPR
65 %x INCLUDE
66 
67 %%
68 \n			{ ++yylineno; }
69 "/*"			{ BEGIN COMMENT;  /* Enter comment eating state */ }
70 <COMMENT>"/*"		{ fprintf(stderr, "Warning! Comment within comment."); }
71 <COMMENT>\n		{ ++yylineno; }
72 <COMMENT>[^*/\n]*	;
73 <COMMENT>"*"+[^*/\n]*	;
74 <COMMENT>"/"+[^*/\n]*	;
75 <COMMENT>"*"+"/"	{ BEGIN INITIAL; }
76 if[ \t]*\(		{
77 				string_buf_ptr = string_buf;
78 				parren_count = 1;
79 				BEGIN CEXPR;
80 				return T_IF;
81 			}
82 <CEXPR>\(		{	*string_buf_ptr++ = '('; parren_count++; }
83 <CEXPR>\)		{
84 				parren_count--;
85 				if (parren_count == 0) {
86 					/* All done */
87 					BEGIN INITIAL;
88 					*string_buf_ptr = '\0';
89 					yylval.sym = symtable_get(string_buf);
90 					return T_CEXPR;
91 				} else {
92 					*string_buf_ptr++ = ')';
93 				}
94 			}
95 <CEXPR>\n		{ ++yylineno; }
96 <CEXPR>[^()\n]+	{
97 				char *yptr = yytext;
98 
99 				while (*yptr != '\0') {
100 					/* Remove duplicate spaces */
101 					if (*yptr == '\t')
102 						*yptr = ' ';
103 					if (*yptr == ' '
104 					 && string_buf_ptr != string_buf
105 					 && string_buf_ptr[-1] == ' ')
106 						yptr++;
107 					else
108 						*string_buf_ptr++ = *yptr++;
109 				}
110 			}
111 
112 {SPACE}			;
113 
114 	/* Register/SCB/SRAM definition keywords */
115 register		{ return T_REGISTER; }
116 const			{ yylval.value = FALSE; return T_CONST; }
117 download		{ return T_DOWNLOAD; }
118 address			{ return T_ADDRESS; }
119 access_mode		{ return T_ACCESS_MODE; }
120 RW|RO|WO		{
121 				 if (strcmp(yytext, "RW") == 0)
122 					yylval.value = RW;
123 				 else if (strcmp(yytext, "RO") == 0)
124 					yylval.value = RO;
125 				 else
126 					yylval.value = WO;
127 				 return T_MODE;
128 			}
129 BEGIN_CRITICAL		{ return T_BEGIN_CS; }
130 END_CRITICAL		{ return T_END_CS; }
131 bit			{ return T_BIT; }
132 mask			{ return T_MASK; }
133 alias			{ return T_ALIAS; }
134 size			{ return T_SIZE; }
135 scb			{ return T_SCB; }
136 scratch_ram		{ return T_SRAM; }
137 accumulator		{ return T_ACCUM; }
138 allones			{ return T_ALLONES; }
139 allzeros		{ return T_ALLZEROS; }
140 none			{ return T_NONE; }
141 sindex			{ return T_SINDEX; }
142 A			{ return T_A; }
143 
144 	/* Opcodes */
145 shl			{ return T_SHL; }
146 shr			{ return T_SHR; }
147 ror			{ return T_ROR; }
148 rol			{ return T_ROL; }
149 mvi			{ return T_MVI; }
150 mov			{ return T_MOV; }
151 clr			{ return T_CLR; }
152 jmp			{ return T_JMP; }
153 jc			{ return T_JC;	}
154 jnc			{ return T_JNC;	}
155 je			{ return T_JE;	}
156 jne			{ return T_JNE;	}
157 jz			{ return T_JZ;	}
158 jnz			{ return T_JNZ;	}
159 call			{ return T_CALL; }
160 add			{ return T_ADD; }
161 adc			{ return T_ADC; }
162 bmov			{ return T_BMOV; }
163 inc			{ return T_INC; }
164 dec			{ return T_DEC; }
165 stc			{ return T_STC;	}
166 clc			{ return T_CLC; }
167 cmp			{ return T_CMP;	}
168 not			{ return T_NOT;	}
169 xor			{ return T_XOR;	}
170 test			{ return T_TEST;}
171 and			{ return T_AND;	}
172 or			{ return T_OR;	}
173 ret			{ return T_RET; }
174 nop			{ return T_NOP; }
175 else			{ return T_ELSE; }
176 
177 	/* Allowed Symbols */
178 [-+,:()~|&."{};<>[\]!]	{ return yytext[0]; }
179 
180 	/* Number processing */
181 0[0-7]*			{
182 				yylval.value = strtol(yytext, NULL, 8);
183 				return T_NUMBER;
184 			}
185 
186 0[xX][0-9a-fA-F]+	{
187 				yylval.value = strtoul(yytext + 2, NULL, 16);
188 				return T_NUMBER;
189 			}
190 
191 [1-9][0-9]*		{
192 				yylval.value = strtol(yytext, NULL, 10);
193 				return T_NUMBER;
194 			}
195 
196 	/* Include Files */
197 #include		{ return T_INCLUDE; BEGIN INCLUDE;}
198 <INCLUDE>[<>\"]		{ return yytext[0]; }
199 <INCLUDE>{PATH}		{ yylval.str = strdup(yytext); return T_PATH; }
200 <INCLUDE>;		{ BEGIN INITIAL; return yytext[0]; }
201 <INCLUDE>.		{ stop("Invalid include line", EX_DATAERR); }
202 
203 	/* For parsing C include files with #define foo */
204 #define			{ yylval.value = TRUE; return T_CONST; }
205 	/* Throw away macros */
206 #define[^\n]*[()]+[^\n]* ;
207 {PATH}			{ yylval.str = strdup(yytext); return T_PATH; }
208 
209 {WORD}			{ yylval.sym = symtable_get(yytext);  return T_SYMBOL; }
210 
211 .			{
212 				char buf[255];
213 
214 				snprintf(buf, sizeof(buf), "Invalid character "
215 					 "'%c'", yytext[0]);
216 				stop(buf, EX_DATAERR);
217 			}
218 %%
219 
220 typedef struct include {
221         YY_BUFFER_STATE  buffer;
222         int              lineno;
223         char            *filename;
224 	SLIST_ENTRY(include) links;
225 }include_t;
226 
227 SLIST_HEAD(, include) include_stack;
228 
229 void
230 include_file(char *file_name, include_type type)
231 {
232 	FILE *newfile;
233 	include_t *include;
234 
235 	newfile = NULL;
236 	/* Try the current directory first */
237 	if (includes_search_curdir != 0 || type == SOURCE_FILE)
238 		newfile = fopen(file_name, "r");
239 
240 	if (newfile == NULL && type != SOURCE_FILE) {
241                 path_entry_t include_dir;
242                 for (include_dir = search_path.slh_first;
243                      include_dir != NULL;
244                      include_dir = include_dir->links.sle_next) {
245 			char fullname[PATH_MAX];
246 
247 			if ((include_dir->quoted_includes_only == TRUE)
248 			 && (type != QUOTED_INCLUDE))
249 				continue;
250 
251 			snprintf(fullname, sizeof(fullname),
252 				 "%s/%s", include_dir->directory, file_name);
253 
254 			if ((newfile = fopen(fullname, "r")) != NULL)
255 				break;
256                 }
257         }
258 
259 	if (newfile == NULL) {
260 		perror(file_name);
261 		stop("Unable to open input file", EX_SOFTWARE);
262 		/* NOTREACHED */
263 	}
264 
265 	if (type != SOURCE_FILE) {
266 		include = (include_t *)malloc(sizeof(include_t));
267 		if (include == NULL) {
268 			stop("Unable to allocate include stack entry",
269 			     EX_SOFTWARE);
270 			/* NOTREACHED */
271 		}
272 		include->buffer = YY_CURRENT_BUFFER;
273 		include->lineno = yylineno;
274 		include->filename = yyfilename;
275 		SLIST_INSERT_HEAD(&include_stack, include, links);
276 	}
277 	yy_switch_to_buffer(yy_create_buffer(newfile, YY_BUF_SIZE));
278 	yylineno = 1;
279 	yyfilename = strdup(file_name);
280 }
281 
282 int
283 yywrap()
284 {
285 	include_t *include;
286 
287 	yy_delete_buffer(YY_CURRENT_BUFFER);
288 	(void)fclose(yyin);
289 	if (yyfilename != NULL)
290 		free(yyfilename);
291 	yyfilename = NULL;
292 	include = include_stack.slh_first;
293 	if (include != NULL) {
294 		yy_switch_to_buffer(include->buffer);
295 		yylineno = include->lineno;
296 		yyfilename = include->filename;
297 		SLIST_REMOVE_HEAD(&include_stack, links);
298 		free(include);
299 		return (0);
300 	}
301 	return (1);
302 }
303