aicasm_scan.l revision 66270
189051Sjake%{
289051Sjake/*
3182916Smarius * Lexical Analyzer for the Aic7xxx SCSI Host adapter sequencer assembler.
489051Sjake *
589051Sjake * Copyright (c) 1997, 1998 Justin T. Gibbs.
689051Sjake * All rights reserved.
789051Sjake *
889051Sjake * Redistribution and use in source and binary forms, with or without
989051Sjake * modification, are permitted provided that the following conditions
1089051Sjake * are met:
1189051Sjake * 1. Redistributions of source code must retain the above copyright
1289051Sjake *    notice, this list of conditions, and the following disclaimer,
1389051Sjake *    without modification.
1489051Sjake * 2. The name of the author may not be used to endorse or promote products
1589051Sjake *    derived from this software without specific prior written permission.
1689051Sjake *
1789051Sjake * Alternatively, this software may be distributed under the terms of the
1889051Sjake * GNU Public License ("GPL").
1989051Sjake *
2089051Sjake * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
2189051Sjake * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2289051Sjake * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2389051Sjake * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
2489051Sjake * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2589051Sjake * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2689051Sjake * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2789051Sjake * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28114188Sjake * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29114188Sjake * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30114188Sjake * SUCH DAMAGE.
3189051Sjake *
3289051Sjake * $Id: //depot/src/aic7xxx/aicasm/aicasm_scan.l#3 $
33207248Smarius *
3489051Sjake * $FreeBSD: head/sys/dev/aic7xxx/aicasm/aicasm_scan.l 66270 2000-09-22 22:19:55Z gibbs $
3589051Sjake */
36166105Smarius
37182730Smarius#include <sys/types.h>
3889051Sjake
3989051Sjake#include <limits.h>
4089051Sjake#include <stdio.h>
4189051Sjake#include <string.h>
4289051Sjake#include <sysexits.h>
4389051Sjake#ifdef __linux__
4491617Sjake#include "../queue.h"
45100899Sjake#else
46182916Smarius#include <sys/queue.h>
47203833Smarius#endif
48207248Smarius
49203833Smarius#include "aicasm.h"
50203833Smarius#include "aicasm_symbol.h"
51203833Smarius#include "y.tab.h"
52203833Smarius
53182916Smarius#define MAX_STR_CONST 256
54182916Smariuschar string_buf[MAX_STR_CONST];
55207248Smariuschar *string_buf_ptr;
56182916Smariusint  parren_count;
57182916Smarius%}
58182916Smarius
59182916SmariusPATH		[-/A-Za-z0-9_.]*[./][-/A-Za-z0-9_.]*
60182916SmariusWORD		[A-Za-z_][-A-Za-z_0-9]*
61182916SmariusSPACE		[ \t]+
62182916Smarius
63182916Smarius%x COMMENT
64182916Smarius%x CEXPR
65182916Smarius%x INCLUDE
66182916Smarius
67182916Smarius%%
68182916Smarius\n			{ ++yylineno; }
69182916Smarius"/*"			{ BEGIN COMMENT;  /* Enter comment eating state */ }
70182916Smarius<COMMENT>"/*"		{ fprintf(stderr, "Warning! Comment within comment."); }
71182916Smarius<COMMENT>\n		{ ++yylineno; }
72182916Smarius<COMMENT>[^*/\n]*	;
73203833Smarius<COMMENT>"*"+[^*/\n]*	;
74182916Smarius<COMMENT>"/"+[^*/\n]*	;
75182916Smarius<COMMENT>"*"+"/"	{ BEGIN INITIAL; }
76182916Smariusif[ \t]*\(		{
77182916Smarius				string_buf_ptr = string_buf;
78182916Smarius				parren_count = 1;
79182916Smarius				BEGIN CEXPR;
80182916Smarius				return T_IF;
81182916Smarius			}
82182916Smarius<CEXPR>\(		{	*string_buf_ptr++ = '('; parren_count++; }
83182916Smarius<CEXPR>\)		{
84182916Smarius				parren_count--;
85182916Smarius				if (parren_count == 0) {
86182916Smarius					/* All done */
87182916Smarius					BEGIN INITIAL;
88182916Smarius					*string_buf_ptr = '\0';
89182916Smarius					yylval.sym = symtable_get(string_buf);
90182916Smarius					return T_CEXPR;
91182916Smarius				} else {
92182916Smarius					*string_buf_ptr++ = ')';
93182916Smarius				}
94182916Smarius			}
95182916Smarius<CEXPR>\n		{ ++yylineno; }
96182916Smarius<CEXPR>[^()\n]+	{
97182916Smarius				char *yptr = yytext;
98182916Smarius
99203833Smarius				while (*yptr != '\0') {
100182916Smarius					/* Remove duplicate spaces */
101182916Smarius					if (*yptr == '\t')
102182916Smarius						*yptr = ' ';
103182916Smarius					if (*yptr == ' '
104182916Smarius					 && string_buf_ptr != string_buf
105182916Smarius					 && string_buf_ptr[-1] == ' ')
106182916Smarius						yptr++;
107182916Smarius					else
108182916Smarius						*string_buf_ptr++ = *yptr++;
109182916Smarius				}
110182916Smarius			}
111182916Smarius
112182916Smarius{SPACE}			;
113182916Smarius
114182916Smarius	/* Register/SCB/SRAM definition keywords */
115182916Smariusregister		{ return T_REGISTER; }
116182916Smariusconst			{ yylval.value = FALSE; return T_CONST; }
11791617Sjakedownload		{ return T_DOWNLOAD; }
118182916Smariusaddress			{ return T_ADDRESS; }
119182916Smariusaccess_mode		{ return T_ACCESS_MODE; }
12091617SjakeRW|RO|WO		{
12191617Sjake				 if (strcmp(yytext, "RW") == 0)
12291617Sjake					yylval.value = RW;
123102040Sjake				 else if (strcmp(yytext, "RO") == 0)
124102040Sjake					yylval.value = RO;
12591617Sjake				 else
12691617Sjake					yylval.value = WO;
12791617Sjake				 return T_MODE;
128182916Smarius			}
129182916SmariusBEGIN_CRITICAL		{ return T_BEGIN_CS; }
130182916SmariusEND_CRITICAL		{ return T_END_CS; }
131182916Smariusbit			{ return T_BIT; }
132182916Smariusmask			{ return T_MASK; }
133182916Smariusalias			{ return T_ALIAS; }
134182916Smariussize			{ return T_SIZE; }
135182916Smariusscb			{ return T_SCB; }
136182916Smariusscratch_ram		{ return T_SRAM; }
137182916Smariusaccumulator		{ return T_ACCUM; }
138182916Smariusallones			{ return T_ALLONES; }
139182916Smariusallzeros		{ return T_ALLZEROS; }
140182916Smariusnone			{ return T_NONE; }
141203833Smariussindex			{ return T_SINDEX; }
142182916SmariusA			{ return T_A; }
143182916Smarius
144182916Smarius	/* Opcodes */
145182916Smariusshl			{ return T_SHL; }
146182916Smariusshr			{ return T_SHR; }
147182916Smariusror			{ return T_ROR; }
148182916Smariusrol			{ return T_ROL; }
149182916Smariusmvi			{ return T_MVI; }
150182916Smariusmov			{ return T_MOV; }
15191617Sjakeclr			{ return T_CLR; }
152182916Smariusjmp			{ return T_JMP; }
153182916Smariusjc			{ return T_JC;	}
154182916Smariusjnc			{ return T_JNC;	}
155182916Smariusje			{ return T_JE;	}
156182916Smariusjne			{ return T_JNE;	}
157182916Smariusjz			{ return T_JZ;	}
158182916Smariusjnz			{ return T_JNZ;	}
15991617Sjakecall			{ return T_CALL; }
160182916Smariusadd			{ return T_ADD; }
161182916Smariusadc			{ return T_ADC; }
16291617Sjakebmov			{ return T_BMOV; }
163182916Smariusinc			{ return T_INC; }
16491617Sjakedec			{ return T_DEC; }
165182916Smariusstc			{ return T_STC;	}
16691617Sjakeclc			{ return T_CLC; }
16791617Sjakecmp			{ return T_CMP;	}
168100899Sjakenot			{ return T_NOT;	}
169182916Smariusxor			{ return T_XOR;	}
170182916Smariustest			{ return T_TEST;}
171182916Smariusand			{ return T_AND;	}
17291617Sjakeor			{ return T_OR;	}
17391617Sjakeret			{ return T_RET; }
17491617Sjakenop			{ return T_NOP; }
17591617Sjakeelse			{ return T_ELSE; }
176182916Smarius
17791617Sjake	/* Allowed Symbols */
178182916Smarius[-+,:()~|&."{};<>[\]!]	{ return yytext[0]; }
17991617Sjake
180182916Smarius	/* Number processing */
18191617Sjake0[0-7]*			{
18289051Sjake				yylval.value = strtol(yytext, NULL, 8);
18391617Sjake				return T_NUMBER;
18489051Sjake			}
18591617Sjake
18691617Sjake0[xX][0-9a-fA-F]+	{
18791617Sjake				yylval.value = strtoul(yytext + 2, NULL, 16);
188182730Smarius				return T_NUMBER;
18989051Sjake			}
19091617Sjake
19189051Sjake[1-9][0-9]*		{
19291617Sjake				yylval.value = strtol(yytext, NULL, 10);
19391617Sjake				return T_NUMBER;
19491617Sjake			}
19591617Sjake
19691617Sjake	/* Include Files */
197182730Smarius#include		{ return T_INCLUDE; BEGIN INCLUDE;}
198182730Smarius<INCLUDE>[<>\"]		{ return yytext[0]; }
19991617Sjake<INCLUDE>{PATH}		{ yylval.str = strdup(yytext); return T_PATH; }
200182730Smarius<INCLUDE>;		{ BEGIN INITIAL; return yytext[0]; }
201182730Smarius<INCLUDE>.		{ stop("Invalid include line", EX_DATAERR); }
202182730Smarius
203207537Smarius	/* For parsing C include files with #define foo */
204207537Smarius#define			{ yylval.value = TRUE; return T_CONST; }
205207537Smarius	/* Throw away macros */
206207537Smarius#define[^\n]*[()]+[^\n]* ;
207207537Smarius{PATH}			{ yylval.str = strdup(yytext); return T_PATH; }
208207537Smarius
209182730Smarius{WORD}			{ yylval.sym = symtable_get(yytext);  return T_SYMBOL; }
210209138Smarius
211182730Smarius.			{
212207537Smarius				char buf[255];
213182730Smarius
214204152Smarius				snprintf(buf, sizeof(buf), "Invalid character "
215182730Smarius					 "'%c'", yytext[0]);
216207537Smarius				stop(buf, EX_DATAERR);
217207537Smarius			}
218182730Smarius%%
219204152Smarius
220182730Smariustypedef struct include {
221207537Smarius        YY_BUFFER_STATE  buffer;
222204152Smarius        int              lineno;
223182730Smarius        char            *filename;
22489051Sjake	SLIST_ENTRY(include) links;
22591617Sjake}include_t;
22689051Sjake
22791617SjakeSLIST_HEAD(, include) include_stack;
22891617Sjake
22991617Sjakevoid
23091617Sjakeinclude_file(char *file_name, include_type type)
23191617Sjake{
23291617Sjake	FILE *newfile;
23391617Sjake	include_t *include;
234207537Smarius
23591617Sjake	newfile = NULL;
236207537Smarius	/* Try the current directory first */
23789051Sjake	if (includes_search_curdir != 0 || type == SOURCE_FILE)
23889051Sjake		newfile = fopen(file_name, "r");
23991783Sjake
24091783Sjake	if (newfile == NULL && type != SOURCE_FILE) {
24191783Sjake                path_entry_t include_dir;
24289051Sjake                for (include_dir = search_path.slh_first;
243181701Smarius                     include_dir != NULL;
24489051Sjake                     include_dir = include_dir->links.sle_next) {
245207537Smarius			char fullname[PATH_MAX];
24691783Sjake
24789051Sjake			if ((include_dir->quoted_includes_only == TRUE)
24891783Sjake			 && (type != QUOTED_INCLUDE))
24991783Sjake				continue;
25091783Sjake
25189051Sjake			snprintf(fullname, sizeof(fullname),
252102040Sjake				 "%s/%s", include_dir->directory, file_name);
253102040Sjake
25491783Sjake			if ((newfile = fopen(fullname, "r")) != NULL)
25591783Sjake				break;
25689051Sjake                }
25789051Sjake        }
25891783Sjake
25991783Sjake	if (newfile == NULL) {
260207537Smarius		perror(file_name);
26191783Sjake		stop("Unable to open input file", EX_SOFTWARE);
26291783Sjake		/* NOTREACHED */
26389051Sjake	}
264181701Smarius
265181701Smarius	if (type != SOURCE_FILE) {
26689051Sjake		include = (include_t *)malloc(sizeof(include_t));
26791783Sjake		if (include == NULL) {
26891617Sjake			stop("Unable to allocate include stack entry",
26991617Sjake			     EX_SOFTWARE);
27091617Sjake			/* NOTREACHED */
27189051Sjake		}
272222828Smarius		include->buffer = YY_CURRENT_BUFFER;
273222828Smarius		include->lineno = yylineno;
274222828Smarius		include->filename = yyfilename;
275222828Smarius		SLIST_INSERT_HEAD(&include_stack, include, links);
27689051Sjake	}
27789051Sjake	yy_switch_to_buffer(yy_create_buffer(newfile, YY_BUF_SIZE));
278203838Smarius	yylineno = 1;
27989051Sjake	yyfilename = strdup(file_name);
280222828Smarius}
28189051Sjake
282222828Smariusint
28389051Sjakeyywrap()
28491783Sjake{
28589051Sjake	include_t *include;
28689051Sjake
28789051Sjake	yy_delete_buffer(YY_CURRENT_BUFFER);
28889051Sjake	(void)fclose(yyin);
28989051Sjake	if (yyfilename != NULL)
29089051Sjake		free(yyfilename);
29189051Sjake	yyfilename = NULL;
29289051Sjake	include = include_stack.slh_first;
29391617Sjake	if (include != NULL) {
29489051Sjake		yy_switch_to_buffer(include->buffer);
29589051Sjake		yylineno = include->lineno;
29691617Sjake		yyfilename = include->filename;
297		SLIST_REMOVE_HEAD(&include_stack, links);
298		free(include);
299		return (0);
300	}
301	return (1);
302}
303