Experiment no 6
Problem Statement: To study & implementation of the macro
expansion.
Theory:
Definition of Macro:
“A macro is a unit of specification for program generation through
expansion.”
A macro definition is enclosed between a macro header statement and a
macro end statement of
the macro.
- A macro prototype statement
- One or more model statements
- Macro pre-processor statement.
A macro prototype statement declares the name of a macro & the
names & kinds of its parameters.
Syntax:
<macro name> [<formal parameter specification> [ ,….]]
Where,
<macro name> apperes in the mnemonic field of an assembly
statement.
<formal parameter specification> is of the form
&<parameter name>[<parameter kind>].
A model statement is a statement from which an assembly language
statement may be generated during macro expansion.
A pre-processor statement is used to perform auxiliary functions
during macro expansion.
Example of macro:
macro
incr &mem_val,&incr_val,®=areg
mover ®,&mem_val
add ®,&incr_val
movem ®,&mem_val
mend
Macro call:
A macro call is called by writing the macro name in the mnemonic
field of an assembly statement.
Syntax:
<macro name> [<actual parameter spec>
[..,…] ]
Where,
An actual parameter typically resembles an operand specification in
an assembly language statement.
e.g. incr A,B
In the example we can see that A, B are actual
parameters.
To implement the macro expansion we need to know the variety of
tables as follows:
- APTAB=actual parameter table:
This table contains the list of actual parameters which are required
at the time of expansion of the macro.
- PNTAB= parameter name table:
This table contains the list of parameters which includes both
keyword as well as positional parameters.
- KPDTAB=keyword parameter default table:
This table contains the list of all default parameters that must be
used while expanding the code that is at the time of macro expansion.
- MDT= macro definition table:
This table contains the information about each
parameter used in the macro definition. The entries for each
statement will decide the actual parameters in the expanded code.
e.g. mover
®,&mem_val from the
macro definition will be changed in the MDT as follows:
mover (p,2),(p,0)
(p,2)
stands for areg,
because we know parameter at second second location is the areg
only.
(p,0)
stands for A,
as A is
one of the memory location used in the statement.
Let’s see the example:
Input file:
macro
incr &mem_val,&incr_val,®=areg
mover ®,&mem_val
add ®,&incr_val
movem ®,&mem_val
mend
start 200
read A
read B
incr A,B
A dc '2'
B dc '4'
End
Output:
1. What is macro? Explain macro expansion.
2. What are different types of parameters used in macro? Explain in
detail.
3. Explain the processing steps of Macro expansion in short.
4. Explain macro definition in detail.
CODE::
main program::
#include<conio.h>
#include<iostream.h>
#include<fstream.h>
#include<string.h>
#include<stdlib.h>
# define MAX 80
# define SI 50
fstream f;
char pnt[SI][SI],mdt[SI][SI],apt[SI][SI],default_value[SI];
int pntab_ptr=0,kpdtp1,mdtp1,kpdtab_ptr=0,mdt_ptr=0,aptab_ptr=0,mnt_i=0;
int mnt_entry;
class mnt
{
char name[SI];
int kpdtp,mdtp,pp,kp;
public:
void set(char name1[],int pp1,int kp1,int mdtp1,int kpdtp1)
{
strcpy(name,name1);
pp=pp1;
kp=kp1;
mdtp=mdtp1;
kpdtp=kpdtp1;
mnt_i++;
}
int get_pp()
{
return pp;
}
int get_kp()
{
return kp;
}
int search(char str[])
{
if(strcmp(str,name)==0)
return 1;
return 0;
}
void modify(int kpdtp1)
{
kpdtp=kpdtp1;
}
}mn;
class kpdtab
{
char para[SI];
char val[SI];
public:
void set(char str_kp[])
{
strcpy(str_kp,strtok(str_kp,"&"));
strcpy(para,strtok(str_kp,"="));
strcpy(val,strtok(NULL,"="));
}
void display()
{
cout<<"\n\n"<<para;
cout<<"\t"<<val;
}
void get_default()
{
strcpy(default_value,val);
}
}kpdt[20];
void macro_expansion( char str[])
{
char str1[SI],str2[SI];
int i;
if(strstr(str,","))
{
strcpy(apt[aptab_ptr],strtok(str,","));
while(strcmp(apt[aptab_ptr],NULL)!=0)
{
aptab_ptr++;
strcpy(apt[aptab_ptr],strtok(NULL,","));
}
int pp1=mn.get_pp();
int kp1=mn.get_kp();
int j=0;
while(aptab_ptr<pp1+kp1)
{
kpdt[j].get_default();
strcpy(apt[aptab_ptr],default_value);
aptab_ptr++;
j++;
}
mdt_ptr=0;
char buf[50];
while(strcmp(mdt[mdt_ptr],"mend")!=0)
{
strcpy(str,mdt[mdt_ptr]);
strcpy(buf,"+");
strcat(buf,strtok(str," "));
strcat(buf," ");
strcpy(str1,strtok(NULL," "));
strcpy(str1,strtok(str1,")"));
strcpy(str2,strtok(NULL,")"));
strcpy(str1,strtok(str1,","));
strcpy(str1,strtok(NULL,","));
int index=atoi(str1);
strcat(buf,apt[index]);
if(str2)
{
strcpy(str2,strtok(str2,","));
strcpy(str2,strtok(NULL,","));
index=atoi(str2);
strcat(buf,",");
strcat(buf,apt[index]);
}
cout<<"\n\n"<<buf;
mdt_ptr++;
}
}
}
void macro_def()
{
int flag=0,i=0,j=0,nofor,pp1=0,kp1=0;
char str[SI],str1[SI],temp[SI],str_name[SI],str2[SI];
char str_p[SI][SI],str_kp[SI][SI];
while(f.getline(str,MAX))
{
if(strcmp(str,"mend")==0)
{
if(kp1==0)
{
kpdtp1=0;
mn.modify(kpdtp1);
}
strcpy(mdt[mdt_ptr],str);
mdt_ptr++;
break;
}
if(flag==0)
{
strcpy(str_name,strtok(str," "));
strcpy(str1,strtok(NULL," "));
strcpy(str_p[i],strtok(str1,","));
while(strcmp(str_p[i],NULL)!=0)
{
i++;
strcpy(str_p[i],strtok(NULL,","));
}
nofor=i;
for(i=0;i<nofor;i++)
{
if(strstr(str_p[i],"="))
{
strcpy(str_kp[j],str_p[i]);
strcpy(str_p[i],strtok(str_p[i],"="));
kp1++;
j++;
}
else
pp1++;
strcpy(temp,strtok(str_p[i],"&"));
strcpy(pnt[pntab_ptr],temp);
pntab_ptr++;
}
j=0;
kpdtp1=kpdtab_ptr;
for(j=0;j<kp1;j++)
{
kpdt[kpdtab_ptr].set(str_kp[j]);
kpdtab_ptr++;
}
mdtp1=mdt_ptr;
mn.set(str_name,pp1,kp1,mdtp1,kpdtp1);
flag=1;
}
else
{
char buf[20];
strcpy(buf,strtok(str," "));
strcat(buf," ");
strcpy(str1,strtok(NULL," "));
if(strstr(str1,","))
{
strcpy(str1,strtok(str1,","));
strcpy(str2,strtok(NULL,","));
if(strstr(str1,"&"))
{
strcpy(str1,strtok(str1,"&"));
for(i=0;i<pp1+kp1;i++)
{
if(strcmp(str1,pnt[i])==0)
{
strcat(buf,"(p,");
char a[10];
itoa(i,a,10);
strcat(buf,a);
strcat(buf,")");
strcat(buf,",");
break;
}
}
}
else
strcpy(buf,str1);
}
else
strcpy(str2,str1);
if(strstr(str2,"&"))
{
strcpy(str2,strtok(str2,"&"));
for(i=0;i<pp1+kp1;i++)
{
if(strcmp(str2,pnt[i])==0)
{
strcat(buf,"(p,");
char a[10];
itoa(i,a,10);
strcat(buf,a);
strcat(buf,")");
break;
}
}
}
else
strcat(buf,str2);
strcpy(mdt[mdt_ptr],buf);
mdt_ptr++;
}
}
cout<<"\n\n\n"<<"PNTAB ::";
for(i=0;i<pp1+kp1;i++)
{
cout<<"\n\n"<<pnt[i];
}
cout<<"\n\n\n"<<"KPDTAB ::";
for(i=kpdtp1;i<kp1;i++)
{
kpdt[i].display();
}
cout<<"\n\n\n"<<"MDT ::";
for(i=mdtp1;i<mdt_ptr;i++)
{
cout<<"\n\n"<<mdt[i];
}
getch();
}
void main()
{
char str[SI],str1[SI],strc[SI],strap[SI];
int macro_flag=0,flag1;
clrscr();
f.open("in.txt",ios::beg|ios::in);
while(f.getline(str,MAX))
{
if(macro_flag==0&&strcmp(str,"macro")==0)
macro_def();
else
{
strcpy(strc,str);
strcpy(str1,strtok(str," "));
if(strcmp(str1,"start")==0)
{
cout<<"\n Program Without Macro Call:-";
macro_flag=1;
cout<<"\n\n"<<strc;
}
else
{
strcpy(strap,strtok(NULL," "));
for(int i=0;i<mnt_i;i++)
{
flag1=mn.search(str1);
if(flag1==1)
{
mnt_entry=i;
macro_expansion(strap);
break;
}
}
if(flag1==0)
cout<<"\n\n"<<strc;
}
if(strcmp(str,"end")==0)
break;
}
}
f.close();
getch();
}
Comments
Post a Comment