aicasm_macro_gram.y revision 1.2
11.1Sfvdl%{
21.2Schristos/*	$NetBSD: aicasm_macro_gram.y,v 1.2 2006/11/25 16:48:32 christos Exp $	*/
31.1Sfvdl
41.1Sfvdl/*
51.1Sfvdl * Sub-parser for macro invocation in the Aic7xxx SCSI
61.1Sfvdl * Host adapter sequencer assembler.
71.1Sfvdl *
81.1Sfvdl * Copyright (c) 2001 Adaptec Inc.
91.1Sfvdl * All rights reserved.
101.1Sfvdl *
111.1Sfvdl * Redistribution and use in source and binary forms, with or without
121.1Sfvdl * modification, are permitted provided that the following conditions
131.1Sfvdl * are met:
141.1Sfvdl * 1. Redistributions of source code must retain the above copyright
151.1Sfvdl *    notice, this list of conditions, and the following disclaimer,
161.1Sfvdl *    without modification.
171.1Sfvdl * 2. Redistributions in binary form must reproduce at minimum a disclaimer
181.1Sfvdl *    substantially similar to the "NO WARRANTY" disclaimer below
191.1Sfvdl *    ("Disclaimer") and any redistribution must be conditioned upon
201.1Sfvdl *    including a substantially similar Disclaimer requirement for further
211.1Sfvdl *    binary redistribution.
221.1Sfvdl * 3. Neither the names of the above-listed copyright holders nor the names
231.1Sfvdl *    of any contributors may be used to endorse or promote products derived
241.1Sfvdl *    from this software without specific prior written permission.
251.1Sfvdl *
261.1Sfvdl * Alternatively, this software may be distributed under the terms of the
271.1Sfvdl * GNU General Public License ("GPL") version 2 as published by the Free
281.1Sfvdl * Software Foundation.
291.1Sfvdl *
301.1Sfvdl * NO WARRANTY
311.1Sfvdl * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
321.1Sfvdl * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
331.1Sfvdl * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
341.1Sfvdl * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
351.1Sfvdl * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
361.1Sfvdl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
371.1Sfvdl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
381.1Sfvdl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
391.1Sfvdl * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
401.1Sfvdl * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
411.1Sfvdl * POSSIBILITY OF SUCH DAMAGES.
421.1Sfvdl *
431.1Sfvdl * $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm_macro_gram.y,v 1.2 2002/08/31 06:39:40 gibbs Exp $
441.1Sfvdl */
451.1Sfvdl
461.1Sfvdl#include <sys/types.h>
471.1Sfvdl
481.1Sfvdl#include <inttypes.h>
491.1Sfvdl#include <regex.h>
501.1Sfvdl#include <stdio.h>
511.1Sfvdl#include <stdlib.h>
521.1Sfvdl#include <string.h>
531.1Sfvdl#include <sysexits.h>
541.1Sfvdl
551.1Sfvdl#ifdef __linux__
561.1Sfvdl#include "../queue.h"
571.1Sfvdl#else
581.1Sfvdl#include <sys/queue.h>
591.1Sfvdl#endif
601.1Sfvdl
611.1Sfvdl#include "aicasm.h"
621.1Sfvdl#include "aicasm_symbol.h"
631.1Sfvdl#include "aicasm_insformat.h"
641.1Sfvdl
651.1Sfvdlstatic symbol_t *macro_symbol;
661.1Sfvdl
671.1Sfvdlstatic void add_macro_arg(const char *argtext, int position);
681.1Sfvdl
691.1Sfvdl%}
701.1Sfvdl
711.1Sfvdl%union {
721.1Sfvdl	int		value;
731.1Sfvdl	char		*str;
741.1Sfvdl	symbol_t	*sym;
751.1Sfvdl}
761.1Sfvdl
771.1Sfvdl
781.1Sfvdl%token <str> T_ARG
791.1Sfvdl
801.1Sfvdl%token <sym> T_SYMBOL
811.1Sfvdl
821.1Sfvdl%type <value> macro_arglist
831.1Sfvdl
841.1Sfvdl%%
851.1Sfvdl
861.1Sfvdlmacrocall:
871.1Sfvdl	T_SYMBOL '('
881.1Sfvdl	{
891.1Sfvdl		macro_symbol = $1;
901.1Sfvdl	}
911.1Sfvdl	macro_arglist ')'
921.1Sfvdl	{
931.1Sfvdl		if (macro_symbol->info.macroinfo->narg != $4) {
941.1Sfvdl			printf("Narg == %d", macro_symbol->info.macroinfo->narg);
951.1Sfvdl			stop("Too few arguments for macro invocation",
961.1Sfvdl			     EX_DATAERR);
971.1Sfvdl			/* NOTREACHED */
981.1Sfvdl		}
991.1Sfvdl		macro_symbol = NULL;
1001.1Sfvdl		YYACCEPT;
1011.1Sfvdl	}
1021.1Sfvdl;
1031.1Sfvdl
1041.1Sfvdlmacro_arglist:
1051.1Sfvdl	{
1061.1Sfvdl		/* Macros can take 0 arguments */
1071.1Sfvdl		$$ = 0;
1081.1Sfvdl	}
1091.1Sfvdl|	T_ARG
1101.1Sfvdl	{
1111.1Sfvdl		$$ = 1;
1121.1Sfvdl		add_macro_arg($1, 1);
1131.1Sfvdl	}
1141.1Sfvdl|	macro_arglist ',' T_ARG
1151.1Sfvdl	{
1161.1Sfvdl		if ($1 == 0) {
1171.2Schristos			stop("Comma without preceding argument in arg list",
1181.1Sfvdl			     EX_DATAERR);
1191.1Sfvdl			/* NOTREACHED */
1201.1Sfvdl		}
1211.1Sfvdl		$$ = $1 + 1;
1221.1Sfvdl		add_macro_arg($3, $$);
1231.1Sfvdl	}
1241.1Sfvdl;
1251.1Sfvdl
1261.1Sfvdl%%
1271.1Sfvdl
1281.1Sfvdlstatic void
1291.1Sfvdladd_macro_arg(const char *argtext, int argnum)
1301.1Sfvdl{
1311.1Sfvdl	struct macro_arg *marg;
1321.1Sfvdl	int i;
1331.1Sfvdl
1341.1Sfvdl	if (macro_symbol == NULL || macro_symbol->type != MACRO) {
1351.1Sfvdl		stop("Invalid current symbol for adding macro arg",
1361.1Sfvdl		     EX_SOFTWARE);
1371.1Sfvdl		/* NOTREACHED */
1381.1Sfvdl	}
1391.1Sfvdl	/*
1401.1Sfvdl	 * Macro Invocation.  Find the appropriate argument and fill
1411.1Sfvdl	 * in the replace ment text for this call.
1421.1Sfvdl	 */
1431.1Sfvdl	i = 0;
1441.1Sfvdl	STAILQ_FOREACH(marg, &macro_symbol->info.macroinfo->args, links) {
1451.1Sfvdl		i++;
1461.1Sfvdl		if (i == argnum)
1471.1Sfvdl			break;
1481.1Sfvdl	}
1491.1Sfvdl	if (marg == NULL) {
1501.1Sfvdl		stop("Too many arguments for macro invocation", EX_DATAERR);
1511.1Sfvdl		/* NOTREACHED */
1521.1Sfvdl	}
1531.1Sfvdl	marg->replacement_text = strdup(argtext);
1541.1Sfvdl	if (marg->replacement_text == NULL) {
1551.1Sfvdl		stop("Unable to replicate replacement text", EX_SOFTWARE);
1561.1Sfvdl		/* NOTREACHED */
1571.1Sfvdl	}
1581.1Sfvdl}
1591.1Sfvdl
1601.1Sfvdlvoid
1611.1Sfvdlmmerror(const char *string)
1621.1Sfvdl{
1631.1Sfvdl	stop(string, EX_DATAERR);
1641.1Sfvdl}
165