#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include "s.h"
extern char* check(char [],int);
char *opcode;
/*function for code parsing*/
char * parse(char s[30])
{
extern long int loc_ctr;
extern int line_count;
extern int err_count;
extern FILE * list_file;
char temp[30];
char *res;
char label[10],mnem[10],op1[20],op2[20],*mode,*de;
char t1[30],t2[30],r1[30],r2[30],w1[10],w2[10];
extern symtab sy;
extern lb_rand lb;
static char at='a';
char *imm,*relative;
char mem_lb[30];
char *addr;
int immed=0,memory=0,rel=0;
int byte=0,doub=1;
int sym_adr;
int l=0,m=0,o1=0,o2=0,un_ref=0;
int i=0,j,ef=0,flag=0;
int word;
int mem=-1;//a:0,a[]:1
FILE *inter = fopen("intr","a");
fprintf(list_file,"\n%s ",s);
space(strlen(s));
/*skip initial spaces*/
while(s[i]==' ')
i++;
j=0;
if(isalpha(s[i]))
{
while(isalpha(s[i]))
temp[j++]=s[i++];
temp[j]='\0';
flag=1;
}
/*skip spaces b/w label name & :*/
while(s[i]==' ')
i++;
/*: found indicates valid label*/
if(s[i]==':' && flag==1)
{
strcpy(label,temp);
l=1;
i++;
}
/*if : not found then mnemonic*/
else if(isalpha(s[i]) || s[i]==' ' || s[i]=='\n' || s[i]=='\0' ||isdigit(s[i]))
{
strcpy(mnem,temp);
m=1;
j=0;
while(isalpha(s[i]) || isdigit(s[i]) || s[i]=='[' || s[i]==']')
temp[j++]=s[i++];
temp[j]='\0';
strcpy(op1,temp);
o1=1;
}
else ef=1; //error flag set
while(s[i]==' ')
i++;
/*if no label */
if(s[i]==',') // , separator b/w op1 & op2
{
i++;
if(isalpha(s[i]) || isdigit(s[i]) || s[i]=='[' || s[i]==']' || s[i]==' ')
{
j=0;
while(s[i]==' ')
i++;
while(isalpha(s[i]) || isdigit(s[i]) || s[i]=='[' || s[i]==']')
temp[j++]=s[i++];
temp[j]='\0';
strcpy(op2,temp);
o2=1;
}
}
else //if ther exists label so mnem follows
{
while(s[i]==' ')
i++;
if(isalpha(s[i]))
{
j=0;
while(isalpha(s[i]))
temp[j++]=s[i++];
temp[j]='\0';
strcpy(mnem,temp);
m=1;
}
while(s[i]==' ')
i++;
if(isalpha(s[i]) || isdigit(s[i]) || s[i]=='[' || s[i]==']' || s[i]==' ')
{
j=0;
while(isalpha(s[i]) || isdigit(s[i]) || s[i]=='[' || s[i]==']')
temp[j++]=s[i++];
temp[j]='\0';
strcpy(op1,temp);
o1=1;
while(s[i]==' ')
i++;
if(s[i]==',')
{
i++;
while(s[i]==' ')
i++;
if(isalpha(s[i]) || isdigit(s[i]) || s[i]=='[' || s[i]==']' || s[i]==' ')
{
j=0;
while(isalpha(s[i]) || isdigit(s[i]) || s[i]=='[' || s[i]==']')
temp[j++]=s[i++];
i++;
temp[j]='\0';
strcpy(op2,temp);
o2=1;
}
else ef=1;
}
}
}
if(l==0 && m==0) ef=1;
/*set default values for the oprnd types for optb function*/
strcpy(t1,"n");
strcpy(t2,"n");
if(ef!=1)
{
if(l==1)
{
if(sy.check_key(label)==1 && sy.check_sym(label)==1)
{
sy.insert(label,"0");loc_ctr++;
}
else {printf("\nDuplicate Label (%d)",line_count);err_count++;}
}
if(o1==1)
{
//operand 1 split into relative & table eg. 50[bx]
struct split opr1=opsplit(op1);
if(opr1.n==0) //0 indicate no split -> perform on earlier value
{
struct operand o1=oprnd(op1);
if(o1.reg==1) //check in reg table
{
strcpy(r1,o1.r);
strcpy(w1,o1.w);
strcpy(t1,o1.t);
}
else if(isdigit(op1[0])) strcpy(t1,"i");
else
{
sym_adr=sy.get_addr(op1);
if(sym_adr!=-1 && strcmp(mnem,"call")!=0 && strcmp(mnem,"jmp")!=0)
{
strcpy(w1,sy.get_w(op1));
addr=sy.get_loctr(sym_adr); memory=1;
strcpy(t1,"m");
strcpy(r1,"110");
de="0";
mem=0;
}
//check entry in symbol table
else
{
strcpy(t1,"m");
un_ref=1;
}
//need to check for unreferenced
}
}
else if(opr1.n==1)
{
struct operand o1=oprnd(opr1.y);
if(o1.reg==1)
{
strcpy(r1,o1.r);
}
else {printf("\nInvalid indirect line (%d)",line_count);err_count++;}
if(isdigit(opr1.x[0]))
{
imm=check(opr1.x,-1);
if(strlen(imm)==8) mode="01";
else if(strlen(imm)==16) mode="10";
strcpy(w1,"0");
strcpy(t1,"m");
rel=1;
}
else
{
sym_adr=sy.get_addr(opr1.x);
if(sym_adr!=-1)
{
strcpy(w1,sy.get_w(opr1.x));
addr=sy.get_loctr(sym_adr);
memory=1;
strcpy(t1,"m");
de="0";
mem=1;
for(i=0;i<strlen(addr);i++)
mem_lb[i]=*(addr+i);
mem_lb[i]='\0';
}
}
}
//if .x if digit
else if(isdigit(opr1.x[0])) strcpy(t1,"i");
}
else strcpy(t1,"n"); //default
if(memory==1)
{
for(i=0;i<strlen(addr);i++)
mem_lb[i]=*(addr+i);
mem_lb[i]='\0';
}
if(o2==1)
{
struct split opr2=opsplit(op2);
if(opr2.n==0)
{
struct operand o2=oprnd(op2);
if(o2.reg==1)
{
strcpy(r2,o2.r);
strcpy(w2,o2.w);
strcpy(t2,o2.t);
}
else if(isdigit(op2[0])) strcpy(t2,"i");
else
{
sym_adr=sy.get_addr(op2); if(sym_adr!=-1)
{
strcpy(w2,sy.get_w(op2)); addr=sy.get_loctr(sym_adr);
memory=1;
strcpy(t2,"m");
strcpy(r2,"110");
de="0";
mem=0;
for(i=0;i<strlen(addr);i++)
mem_lb[i]=*(addr+i);
mem_lb[i]='\0';
}
}
}
else if(opr2.n==1)
{
struct operand o2=oprnd(opr2.y);
if(o2.reg==1)
{
strcpy(r2,o2.r);
de="0";
}
else {printf("invalid indirect line (%d)",line_count);err_count++;}
if(isdigit(opr2.x[0]))
{
imm=check(opr2.x,-1);
if(strlen(imm)==8) mode="01";
else if(strlen(imm)==16) mode="10"; strcpy(w2,"0");
strcpy(t2,"m");
de="1";
rel=1;
}
else
{
sym_adr=sy.get_addr(opr2.x);
if(sym_adr!=-1)
{
strcpy(w2,sy.get_w(opr2.x));
addr=sy.get_loctr(sym_adr);
memory=1;
strcpy(t2,"m");
de="0";
mem=1;
for(i=0;i<strlen(addr);i++)
mem_lb[i]=*(addr+i);
mem_lb[i]='\0';
}
}
}
else if(isdigit(opr2.x[0])) strcpy(t2,"i");
}
else strcpy(t2,"n");
if(strlen(t1)==0) strcpy(t1,"n");
if(m==1)
{
if(strcmp(mnem,"in")==0)
opcode=optb(mnem,op1,op2);
else if(strcmp(mnem,"out")==0)
opcode=optb(mnem,op1,op2);
else if(strcmp(mnem,"rol")==0 || strcmp(mnem,"ror")==0 || strcmp(mnem,"shl")==0 || strcmp(mnem,"shr")==0 || strcmp(mnem,"rcr")==0 || strcmp(mnem,"rcl")==0 || strcmp(mnem,"sar")==0)
{
opcode=optb(mnem,t1,op2);
res=pat(opcode,"w",w1);
res=pat(res,"rim",r1);
}
else
{
if(strcmp(t1,"i")!=0 && strcmp(t2,"i")!=0 && o1==1 && o2==1 && strcmp(w1,w2)!=0)
{
printf("\nOprnd mismatch line (%d)",line_count);
err_count++;
return "x";
}
opcode=optb(mnem,t1,t2); //retrieve opcode where mnem,type1,type2
}
if(strcmp(t1,"r")==0 && strcmp(t2,"r")==0)
{
de="0";
mode="11";
}
else if(strcmp(t1,"r")==0 && strcmp(t2,"i")==0)
{
de="0";
mode="11";
}
else if(strcmp(t1,"s")==0 || strcmp(t2,"s")==0)
{
de="1";
mode="11";
}
else if(rel==1) {strcat(opcode,imm);}
else
{
de="1";
}
if(strcmp(t2,"i")==0)
{
if(strcmp(w1,"0")==0)
{
imm=check(op2,byte);
if(strlen(imm)==8) strcat(opcode,imm);
else printf("error");
}
else if(strcmp(w1,"1")==0)
{
imm=check(op2,doub);
strcat(opcode,imm);
}
else printf("error");
}
else if(strcmp(t1,"i")==0 && strcmp(t2,"n")==0)
{
imm=check(op1,byte);
if(strlen(imm)==8) strcat(opcode,imm);
else printf("error");
}
if(memory==1)
{
strcat(opcode,mem_lb);
mode="00";
if(strcmp(t2,"m")==0) strcpy(w1,w2); res=pat(opcode,"w",w1);
res=pat(res,"d",de);
if(strcmp(de,"1")==0) res=pat(res,"rim",r2);
else res=pat(res,"rim",r2);
}
else if(un_ref==1)
{
char ct[]="xxxxxxxxxxxxxxxx";
ct[strlen(ct)-1]=at;
lb.ins(op1,ct,loc_ctr);
strcat(opcode,ct);
at+=1;
}
res=pat(opcode,"d",de);
res=pat(res,"w",w1);
res=pat(res,"mo",mode);
if(strlen(r1)==2)
res=pat(res,"sg",r1);
else if(strlen(r2)==2)
res=pat(res,"sg",r2);
if(strcmp(de,"1")==0)
{
res=pat(res,"reg",r1);
if(mem==0) res=pat(res,"rim","110");
else
res=pat(res,"rim",r2);
}
else if(strcmp(de,"0")==0)
{
res=pat(res,"reg",r2);
if(mem==0)
res=pat(res,"rim","110");
else
res=pat(res,"rim",r1);
}
res=pat(res,"rim",r1);
res=pat(res,"rim",r2);
fprintf(list_file,"%s",res);
space(strlen(res));
fprintf(list_file,"Loctr=%d\n",loc_ctr);
fprintf(inter,"%s",res);
fclose(inter);
}
else printf("Error");
loc_ctr+=strlen(res)/8;
}
}