Blame as10k1/macro.c

Packit Service b98cfc
/***************************************************************************
Packit Service b98cfc
                          macro.c  - various functions to handle macros
Packit Service b98cfc
                             -------------------
Packit Service b98cfc
    Date                 : May 23 2000
Packit Service b98cfc
    Copyright            : (C) 2000 by Daniel Bertrand
Packit Service b98cfc
    Email                : d.bertrand@ieee.ca
Packit Service b98cfc
 ***************************************************************************/
Packit Service b98cfc
Packit Service b98cfc
/***************************************************************************
Packit Service b98cfc
 *                                                                         *
Packit Service b98cfc
 *   This program is free software; you can redistribute it and/or modify  *
Packit Service b98cfc
 *   it under the terms of the GNU General Public License as published by  *
Packit Service b98cfc
 *   the Free Software Foundation; either version 2 of the License, or     *
Packit Service b98cfc
 *   (at your option) any later version.                                   *
Packit Service b98cfc
 *                                                                         *
Packit Service b98cfc
 ***************************************************************************/
Packit Service b98cfc
Packit Service b98cfc
#include<string.h>
Packit Service b98cfc
#include<stdio.h>
Packit Service b98cfc
#include"types.h"
Packit Service b98cfc
#include"proto.h"
Packit Service b98cfc
#include <ctype.h>
Packit Service b98cfc
Packit Service b98cfc
int macro_ctn;
Packit Service b98cfc
struct macrdef macro[MAX_DEF_MACRO];
Packit Service b98cfc
extern char *listing,listtemp[60];
Packit Service b98cfc
extern FILE *listfile;
Packit Service b98cfc
Packit Service b98cfc
//determines if an opcode neumonic is a macro
Packit Service b98cfc
Packit Service b98cfc
int ismacro(char *mac)
Packit Service b98cfc
{
Packit Service b98cfc
       
Packit Service b98cfc
        int i;
Packit Service b98cfc
        
Packit Service b98cfc
        for(i=0;i
Packit Service b98cfc
                if(strcasecmp(macro[i].name,mac)==0){
Packit Service b98cfc
                        return(i);
Packit Service b98cfc
                }
Packit Service b98cfc
        }
Packit Service b98cfc
        return(-1);
Packit Service b98cfc
}
Packit Service b98cfc
Packit Service b98cfc
//defines a new macro, adds it to the macro list
Packit Service b98cfc
void new_macro(char *symbol, char *line, char *operand)
Packit Service b98cfc
{
Packit Service b98cfc
        extern int source_line_num;
Packit Service b98cfc
        struct sym *sym;
Packit Service b98cfc
Packit Service b98cfc
	if (macro_ctn >= MAX_DEF_MACRO)
Packit Service b98cfc
                as_exit("Parse Error: Too many macros");
Packit Service b98cfc
Packit Service b98cfc
        if(isalpha(*symbol)==0)
Packit Service b98cfc
                as_exit("Parse Error: Symbol must start with an alpha character");
Packit Service b98cfc
        
Packit Service b98cfc
        if(ismacro(symbol)!=-1)
Packit Service b98cfc
                as_exit("Parsed Error: macro is already defined");
Packit Service b98cfc
Packit Service b98cfc
        if(issymbol(symbol,&sym)!=-1)
Packit Service b98cfc
                as_exit("Parse Error: Symbol is already defined");
Packit Service b98cfc
Packit Service b98cfc
        macro[macro_ctn].line_num=source_line_num;
Packit Service b98cfc
        macro[macro_ctn].ptr=line;
Packit Service b98cfc
        strcpy(macro[macro_ctn].name,symbol); 
Packit Service b98cfc
        macro[macro_ctn].operands=operand;
Packit Service b98cfc
        macro_ctn++;
Packit Service b98cfc
        
Packit Service b98cfc
}
Packit Service b98cfc
Packit Service b98cfc
//called from parsed() when a macro is used, stores the arguments and recursively calls the parse().
Packit Service b98cfc
Packit Service b98cfc
void macro_expand(int macnum,char *operand )
Packit Service b98cfc
{
Packit Service b98cfc
        char *line,*next;
Packit Service b98cfc
        int done=0,i,old;
Packit Service b98cfc
        extern unsigned int macro_depth;
Packit Service b98cfc
        extern int macro_line_num;
Packit Service b98cfc
        char string[MAX_LINE_LENGTH];
Packit Service b98cfc
       
Packit Service b98cfc
        //initialize macro use:
Packit Service b98cfc
        i=0;
Packit Service b98cfc
       
Packit Service b98cfc
        if(macro_depth+1> MAX_MAC_DEPTH)
Packit Service b98cfc
                as_exit("Error exceeded maximum number of recursive macro calls");
Packit Service b98cfc
Packit Service b98cfc
        old=macro_line_num;
Packit Service b98cfc
        macro_line_num=macro[macnum].line_num;
Packit Service b98cfc
        macro_operand(macro[macnum].operands,operand);
Packit Service b98cfc
        macro_depth++;
Packit Service b98cfc
        
Packit Service b98cfc
        line=macro[macnum].ptr;
Packit Service b98cfc
        next=line;
Packit Service b98cfc
Packit Service b98cfc
        
Packit Service b98cfc
        while((*next!= '\n') )         //skip to the line after the macro definition
Packit Service b98cfc
                next++;
Packit Service b98cfc
        line=next;
Packit Service b98cfc
        
Packit Service b98cfc
        
Packit Service b98cfc
        //Expand the macro calling parse()
Packit Service b98cfc
        
Packit Service b98cfc
        while(done!=-1)
Packit Service b98cfc
        {
Packit Service b98cfc
                
Packit Service b98cfc
                while((*next!= '\n') )
Packit Service b98cfc
                        next++;
Packit Service b98cfc
                
Packit Service b98cfc
                *next='\0';
Packit Service b98cfc
   
Packit Service b98cfc
                strcpy(&string[0],line);
Packit Service b98cfc
                listtemp[0]='\0';
Packit Service b98cfc
                done=parse(string, line);
Packit Service b98cfc
                macro_line_num++;
Packit Service b98cfc
                *next='\n';
Packit Service b98cfc
		if(listing){
Packit Service b98cfc
			if(done==1)
Packit Service b98cfc
				sprintf(listtemp,"macro expansion done");
Packit Service b98cfc
			if(done!=-3)
Packit Service b98cfc
				fprintf(listfile,"%-50s ||   %s\n",listtemp,line);
Packit Service b98cfc
		}
Packit Service b98cfc
                if(done==-1)
Packit Service b98cfc
                        break;
Packit Service b98cfc
                next++;
Packit Service b98cfc
        line=next;
Packit Service b98cfc
        }
Packit Service b98cfc
        macro_line_num=old;
Packit Service b98cfc
        macro_depth--;
Packit Service b98cfc
Packit Service b98cfc
        return;
Packit Service b98cfc
Packit Service b98cfc
}
Packit Service b98cfc
//assigns calling arguments with defined symbols.
Packit Service b98cfc
void macro_operand(char *symbols,char *val)
Packit Service b98cfc
{
Packit Service b98cfc
        char tmp[MAX_LINE_LENGTH],*ptr=symbols,*sym=tmp,*next_sym=sym,*next_val=val;
Packit Service b98cfc
        extern unsigned int macro_depth;
Packit Service b98cfc
       
Packit Service b98cfc
       
Packit Service b98cfc
        if(symbols==NULL&&val==NULL)
Packit Service b98cfc
                return;
Packit Service b98cfc
        if(symbols==NULL||val==NULL)
Packit Service b98cfc
                as_exit("error in macro_operand, Null operand list");
Packit Service b98cfc
                
Packit Service b98cfc
       
Packit Service b98cfc
        while(*ptr!='\n' && *ptr!=';')
Packit Service b98cfc
                ptr++;
Packit Service b98cfc
        *ptr='\0';
Packit Service b98cfc
         
Packit Service b98cfc
        strcpy(tmp,symbols);
Packit Service b98cfc
        
Packit Service b98cfc
        //#ifdef DEBUG        
Packit Service b98cfc
        //        printf("syms:\"%s\",vals:\"%s\"\n",sym,val);
Packit Service b98cfc
        //#endif
Packit Service b98cfc
          *ptr='\n';
Packit Service b98cfc
        
Packit Service b98cfc
        while(1){
Packit Service b98cfc
Packit Service b98cfc
                //skip over blanks:
Packit Service b98cfc
                advance(next_sym);
Packit Service b98cfc
                advance(next_val);
Packit Service b98cfc
                
Packit Service b98cfc
                
Packit Service b98cfc
                sym = next_sym;
Packit Service b98cfc
                val = next_val;
Packit Service b98cfc
               
Packit Service b98cfc
                if(*next_val=='\0' && *next_sym=='\0')
Packit Service b98cfc
                        return;
Packit Service b98cfc
                if(*next_sym=='\0')
Packit Service b98cfc
                        as_exit("Error, To many arguments for defined Macro");
Packit Service b98cfc
                
Packit Service b98cfc
                
Packit Service b98cfc
                if(*next_val=='\0')
Packit Service b98cfc
                        as_exit("Error, Not enough arguments for defined macro");
Packit Service b98cfc
Packit Service b98cfc
                
Packit Service b98cfc
                
Packit Service b98cfc
                while(*next_sym != '\0' && *next_sym!= ',' )
Packit Service b98cfc
                        next_sym++;
Packit Service b98cfc
Packit Service b98cfc
                while(*next_val != '\0' && *next_val!= ',' )
Packit Service b98cfc
                        next_val++;
Packit Service b98cfc
                //                                 printf("sym=\"%s\";val=\"%s\"(=0x%x)\n",sym, val,arg_decode(val,0) );
Packit Service b98cfc
                if( sym!=next_sym || val!=next_val ){
Packit Service b98cfc
                        update_symbol(sym,TYPE_MACRO_ARG,arg_decode(val,0),macro_depth+1);
Packit Service b98cfc
                }
Packit Service b98cfc
               
Packit Service b98cfc
        }
Packit Service b98cfc
        
Packit Service b98cfc
} 
Packit Service b98cfc
Packit Service b98cfc
Packit Service b98cfc
Packit Service b98cfc
Packit Service b98cfc
Packit Service b98cfc
Packit Service b98cfc
Packit Service b98cfc
Packit Service b98cfc
Packit Service b98cfc
Packit Service b98cfc
Packit Service b98cfc
Packit Service b98cfc
Packit Service b98cfc
Packit Service b98cfc
Packit Service b98cfc
Packit Service b98cfc
Packit Service b98cfc
Packit Service b98cfc
Packit Service b98cfc
Packit Service b98cfc