C program of Macro Processor Opcode | C codechamp

C program of Macro Processor Opcode | C codechamp

1157
7
SHARE

C program of Macro processor : A macro processor is a program that reads a file (or files) and scans them for certain keywords. When a keyword is found, it is replaced by some text. The keyword or text combination is called a macro. A macro processor enables you to define and to use macros in your assembly programs. When you define a macro, you provide text (usually assembly code) that you want to associate with a macro name. Then, when you want to include the macro text in your assembly program, you provide the name of the macro. The assembler replaces the macro name with the text specified in the macro definition.

Functions used in of Macro Processor :

Before going further, we must know what are the functions used in the program and what is their use. Let see the functions used in Macro processor C program :

MACROPROCESSOR MAIN FUNCTION
If (EXPANDING=FALSE)
   Read each line and call GETLINE() and PROCESSLINE() until END keyword encounters.
PROCESSLINE ( ) FUNCTION
If OPCODE is a macroname then call EXPAND ( ) function.
Else if OPCODE is MACRO ,then call DEFINE ( ) function.
Else write line to expanded file as such.
DEFINE( )

Enter Macro name into CODECHAMP structure.Enter macro prototype into DEFINETAB structure. Set LEVEL=1 and substitute parameters with positional notations and enter to DEFINETAB structure.
If OPCODE=MACRO then LEVEL++;
If OPCODE=MEND then LEVEL–;
Continue this until LEVEL=0
Store beginning and end of definition as pointers within CODECHAMP structure.

EXPAND ( ) FUNTCION

IF (EXPANDING = TRUE)
Set up arguments from macro invocation in ARGUMENTTAB.
Write macro statement to expanded file  as a comment line.
Call GETLINE() and PROCESSLINE() till macro definition ends.
At end, set EXPANDING=FALSE.

GETLINE ( ) FUNCTION

If EXPANDING is TRUE, read from DEFINETAB (data structure where macro body is stored) and substitute arguments for positional notations.
If  EXPANDING is FALSE , read next line from input file.

NOTE : This program accepts an input file “input.txt” and generates the expanded output file “output.txt”. Steps to take care before running program :

1. Input file contains two parts : Macro and second Main program.

Separate the Macro and Main program with one blank line .

Also keep in mind leaving a blank empty line below the main program “END” statement. Else the code will go in  infinite loop.

Sample Input.txt file :

COPY START 1000
RDBUFF MACRO P,Q,R
CLEAR A
CLEAR S
CLEAR X
+LDT #4096
TD P
JEQ *-3
RD P
STCH Q
JLT *-19
LDA R
COMP #0
STX R
MEND

//main program(make sure one empty line is present here)
FIRST STL RETADR
RDBUFF F1,BUFF1,L1
CLEAR X
RDBUFF F2,BUFF2,L2
RDBUFF F3,BUFF3,L3
JLT *-19
STA
END
//(make sure one empty line here)

Now lets see which takes above input.txt file as input  and generates output expanded code.

Note: Originally this code has been written by Vipin Pillai, i have corrected and optimized his code.

C program of Macro processor :

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void GETLINE(); /*Getline function */
void PROCESSLINE(); /*Process line function*/
void DEFINE();/*Define Function*/
void EXPAND();/*Expand the opcode function*/
FILE *output; /*Output file */
FILE *input; /*Input file containing Macro and Main program */

char label[10],opcode[10],operand[25];
char line[20];
int namcount=0, defcount=0;
int EXPANDING;
int curr;

struct codechamp
{
 char name[10];
 int start,end;
}mycodechamp[15];

struct definetab
{
 char macroline[25];
}mydefinetab[25];

struct argumenttab
{
 char arg[3][9];
}myargumenttab;

/*Main function*/
int main()
{
 EXPANDING=0;
 printf("----------------------------------------------------\n");
 printf("-------------Made by C codechamp--------------------\n");
 printf("----------------------------------------------------\n\n");
 printf("\t C PROGRAM OF MACRO OPCODE ASSEMBLER\n\n");
 input =fopen("input.txt","r");                          
 output=fopen("output.txt","w");
 GETLINE();
 while(strcmp(opcode,"END")!=0)
 {  
   PROCESSLINE();
   GETLINE();
 }
 fprintf(output,"%s",line);
 printf("\nExpaned output file has been successfully created.\n");
 system("pause");
 getch();
 return 1;
}

/* GETLINE FUNCTION */
void GETLINE()
{    
char word1[10],word2[10],word3[10],buff[10];
int count=0,i,j=0;
if(EXPANDING)
strcpy(line,mydefinetab[curr++].macroline);
else 
fgets(line,20,input);
opcode[0]='\0';label[0]='\0';operand[0]='\0';word1[0]='\0';word2[0]='\0';word3[0]='\0';

for(i=0;line[i]!='\0';i++)
{
  if(line[i]!=' ')
    buff[j++]=line[i];
  else
  {
    buff[j]='\0';
    strcpy(word3,word2);
    strcpy(word2,word1);
    strcpy(word1,buff);
    j=0;
    count++;
    }
}
buff[j-1]='\0';
strcpy(word3,word2);
strcpy(word2,word1);
strcpy(word1,buff);

switch(count)
 {
  case 0:strcpy(opcode,word1);break;
  case 1:{strcpy(opcode,word2);strcpy(operand,word1);}break;
  case 2:{strcpy(label,word3);strcpy(opcode,word2);strcpy(operand,word1);}break;
  }
}

/* PROCESSLINE Function */
void PROCESSLINE()
{
  int i;
  for(i=0;i<namcount;i++)
  if(!strcmp(opcode,mycodechamp[i].name))
  {
    EXPAND();
    return;
    }
  if(!strcmp(opcode,"MACRO"))
    DEFINE();
  else 
    fprintf(output,"%s",line);
}

/* Define Fucntion */   
void DEFINE()
{
  int LEVEL,i=0,j=0,k=0;
  char param[5][9];
  char s[3];
  strcpy(s,"123");
  strcpy(mycodechamp[namcount].name,label);
  mycodechamp[namcount].start=defcount;
  strcpy(mydefinetab[defcount].macroline,line);
  while(operand[i]!='\0')
  {
    if(operand[i]!=',')
      param[j][k++]=operand[i];
    else
      {
        param[j++][k]='\0';
        k=0;
        }
       i++;
   }
   param[j][k]='\0';
   LEVEL=1;
   while(LEVEL>0)
   {
     GETLINE();
     if(operand[0]!='\0')
     {
       for(i=0;i<3;i++)
       {
         if(!strcmp(operand,param[i]))
           {
            operand[0]='?';
            operand[1]=s[i];
            operand[2]='\0';
            }
        }
      }
     if(!strcmp(opcode,"MACRO"))
       LEVEL++;
     else if(!strcmp(opcode,"MEND"))
       LEVEL--;

     strcpy(mydefinetab[defcount].macroline,opcode);
     if(operand[0]!='\0')
     {
      strcat(mydefinetab[defcount].macroline," ");
      strcat(mydefinetab[defcount].macroline,operand);
      strcat(mydefinetab[defcount].macroline,"\n");
     }
     strcat(mydefinetab[defcount++].macroline,"\n");
  }
  mycodechamp[namcount++].end=defcount;
}

/*Expand Function */
void EXPAND()
{
  int i,end=0,j=0,k=0;
  EXPANDING=1;
  int arg=0;
  fprintf(output,"//%s",line);
  for(i=0;i<namcount;i++)
  {
    if(!strcmp(opcode,mycodechamp[i].name))
    {
      curr=mycodechamp[i].start;
      end=mycodechamp[i].end;
      while(operand[i]!='\0')
      {
        if(operand[i]!=',')
          myargumenttab.arg[j][k++]=operand[i];
        else
        {
          myargumenttab.arg[j++][k]='\n';
          k=0;
         }
        i++;
       }                              
       myargumenttab.arg[j][k]='\n';                
     }
  }
  while(curr<(end-1))
  {
    GETLINE();
    if(operand[0]=='?')
    strcpy(operand,myargumenttab.arg[operand[1]-'0'-1]);
    fprintf(output,"%s %s %s",label,opcode,operand);
   }
  EXPANDING=0;
}

We hope you all have enjoyed the C program of Macro Processor. If you have any issues with above code or logic as us in form of comments.

Note : Add a blank line below END keyword in input.txt file otherwise it will go in infinite loop.

Uniqueness is the key! and Quality is what we deliver.

7 COMMENTS

  1. Currently it sounds like WordPress is the top blogging platform out there right now. (from what I’ve read) Is that what you are using on your blog?

  2. Hi, I am working on a class project which includes designing a C one pass macro processor. How different will this be from the above code that u have given?

LEAVE A REPLY