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