195376Sgibbs%{
2139749Simp/*-
395376Sgibbs * Sub-parser for macro invocation in the Aic7xxx SCSI
495376Sgibbs * Host adapter sequencer assembler.
595376Sgibbs *
695376Sgibbs * Copyright (c) 2001 Adaptec Inc.
795376Sgibbs * All rights reserved.
895376Sgibbs *
995376Sgibbs * Redistribution and use in source and binary forms, with or without
1095376Sgibbs * modification, are permitted provided that the following conditions
1195376Sgibbs * are met:
1295376Sgibbs * 1. Redistributions of source code must retain the above copyright
1395376Sgibbs *    notice, this list of conditions, and the following disclaimer,
1495376Sgibbs *    without modification.
1595376Sgibbs * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1695376Sgibbs *    substantially similar to the "NO WARRANTY" disclaimer below
1795376Sgibbs *    ("Disclaimer") and any redistribution must be conditioned upon
1895376Sgibbs *    including a substantially similar Disclaimer requirement for further
1995376Sgibbs *    binary redistribution.
2095376Sgibbs * 3. Neither the names of the above-listed copyright holders nor the names
2195376Sgibbs *    of any contributors may be used to endorse or promote products derived
2295376Sgibbs *    from this software without specific prior written permission.
2395376Sgibbs *
2495376Sgibbs * Alternatively, this software may be distributed under the terms of the
2595376Sgibbs * GNU General Public License ("GPL") version 2 as published by the Free
2695376Sgibbs * Software Foundation.
2795376Sgibbs *
2895376Sgibbs * NO WARRANTY
2995376Sgibbs * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3095376Sgibbs * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3195376Sgibbs * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
3295376Sgibbs * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3395376Sgibbs * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3495376Sgibbs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3595376Sgibbs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3695376Sgibbs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
3795376Sgibbs * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
3895376Sgibbs * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3995376Sgibbs * POSSIBILITY OF SUCH DAMAGES.
4095376Sgibbs *
41102668Sgibbs * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_gram.y#5 $
4295376Sgibbs *
4395376Sgibbs * $FreeBSD$
4495376Sgibbs */
4595376Sgibbs
4695376Sgibbs#include <sys/types.h>
4795376Sgibbs
4895376Sgibbs#include <inttypes.h>
4995376Sgibbs#include <regex.h>
5095376Sgibbs#include <stdio.h>
5195376Sgibbs#include <stdlib.h>
5295376Sgibbs#include <string.h>
5395376Sgibbs#include <sysexits.h>
5495376Sgibbs#include <sys/queue.h>
5595376Sgibbs
5695376Sgibbs#include "aicasm.h"
5795376Sgibbs#include "aicasm_symbol.h"
5895376Sgibbs#include "aicasm_insformat.h"
5995376Sgibbs
6095376Sgibbsstatic symbol_t *macro_symbol;
6195376Sgibbs
6295376Sgibbsstatic void add_macro_arg(const char *argtext, int position);
6395376Sgibbs
64193244Sdelphijextern int mmlex(void);
65193244Sdelphijextern int mmparse(void);
66193244Sdelphij
6795376Sgibbs%}
6895376Sgibbs
6995376Sgibbs%union {
7095376Sgibbs	int		value;
7195376Sgibbs	char		*str;
7295376Sgibbs	symbol_t	*sym;
7395376Sgibbs}
7495376Sgibbs
7595376Sgibbs
7695376Sgibbs%token <str> T_ARG
7795376Sgibbs
7895376Sgibbs%token <sym> T_SYMBOL
7995376Sgibbs
8095376Sgibbs%type <value> macro_arglist
8195376Sgibbs
8295376Sgibbs%%
8395376Sgibbs
8495376Sgibbsmacrocall:
8595376Sgibbs	T_SYMBOL '('
8695376Sgibbs	{
8795376Sgibbs		macro_symbol = $1;
8895376Sgibbs	}
8995376Sgibbs	macro_arglist ')'
9095376Sgibbs	{
9195376Sgibbs		if (macro_symbol->info.macroinfo->narg != $4) {
9295376Sgibbs			printf("Narg == %d", macro_symbol->info.macroinfo->narg);
9395376Sgibbs			stop("Too few arguments for macro invocation",
9495376Sgibbs			     EX_DATAERR);
9595376Sgibbs			/* NOTREACHED */
9695376Sgibbs		}
9795376Sgibbs		macro_symbol = NULL;
9895376Sgibbs		YYACCEPT;
9995376Sgibbs	}
10095376Sgibbs;
10195376Sgibbs
10295376Sgibbsmacro_arglist:
10395376Sgibbs	{
10495376Sgibbs		/* Macros can take 0 arguments */
10595376Sgibbs		$$ = 0;
10695376Sgibbs	}
10795376Sgibbs|	T_ARG
10895376Sgibbs	{
10995376Sgibbs		$$ = 1;
11095376Sgibbs		add_macro_arg($1, 1);
11195376Sgibbs	}
11295376Sgibbs|	macro_arglist ',' T_ARG
11395376Sgibbs	{
11495376Sgibbs		if ($1 == 0) {
115165628Syar			stop("Comma without preceding argument in arg list",
11695376Sgibbs			     EX_DATAERR);
11795376Sgibbs			/* NOTREACHED */
11895376Sgibbs		}
11995376Sgibbs		$$ = $1 + 1;
12095376Sgibbs		add_macro_arg($3, $$);
12195376Sgibbs	}
12295376Sgibbs;
12395376Sgibbs
12495376Sgibbs%%
12595376Sgibbs
12695376Sgibbsstatic void
12795376Sgibbsadd_macro_arg(const char *argtext, int argnum)
12895376Sgibbs{
12995376Sgibbs	struct macro_arg *marg;
13095376Sgibbs	int i;
13195376Sgibbs
13295376Sgibbs	if (macro_symbol == NULL || macro_symbol->type != MACRO) {
13395376Sgibbs		stop("Invalid current symbol for adding macro arg",
13495376Sgibbs		     EX_SOFTWARE);
13595376Sgibbs		/* NOTREACHED */
13695376Sgibbs	}
13795376Sgibbs	/*
13895376Sgibbs	 * Macro Invocation.  Find the appropriate argument and fill
13995376Sgibbs	 * in the replace ment text for this call.
14095376Sgibbs	 */
14195376Sgibbs	i = 0;
14295376Sgibbs	STAILQ_FOREACH(marg, &macro_symbol->info.macroinfo->args, links) {
14395376Sgibbs		i++;
14495376Sgibbs		if (i == argnum)
14595376Sgibbs			break;
14695376Sgibbs	}
14795376Sgibbs	if (marg == NULL) {
14895376Sgibbs		stop("Too many arguments for macro invocation", EX_DATAERR);
14995376Sgibbs		/* NOTREACHED */
15095376Sgibbs	}
15195376Sgibbs	marg->replacement_text = strdup(argtext);
15295376Sgibbs	if (marg->replacement_text == NULL) {
15395376Sgibbs		stop("Unable to replicate replacement text", EX_SOFTWARE);
15495376Sgibbs		/* NOTREACHED */
15595376Sgibbs	}
15695376Sgibbs}
15795376Sgibbs
158193244Sdelphijstatic void
15995376Sgibbsmmerror(const char *string)
16095376Sgibbs{
16195376Sgibbs	stop(string, EX_DATAERR);
16295376Sgibbs}
163