Created
November 14, 2017 16:31
-
-
Save navin-mohan/852af85b8baf9ec73a9277e7aaad73e8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <ctype.h> | |
#include <string.h> | |
#define TAB_SIZE 100 | |
#define SYMBOL_SIZE 30 | |
#define OPCODE_SIZE 10 | |
typedef unsigned int uint; | |
typedef struct{ | |
char sym[SYMBOL_SIZE]; | |
int loc; | |
}Symbol; | |
typedef struct{ | |
char opcode[OPCODE_SIZE]; | |
int val; | |
}Opcode; | |
Symbol symtab[TAB_SIZE]; | |
Opcode optab[TAB_SIZE]; | |
uint hash_str(char* str){ | |
uint hash = 0; | |
uint n,i; | |
for(i=0;*(str+i) != '\0';++i){ | |
if(isalpha(*(str+i))) | |
n = tolower(*(str+i)) - 'a' + 1; | |
else | |
n = 27; | |
hash = ((hash << 3) + n) % TAB_SIZE; | |
} | |
return hash; | |
} | |
void initialize_optab(char* filename){ | |
FILE *fp = fopen(filename,"r"); | |
char buf[OPCODE_SIZE]; | |
int val,hash; | |
for(val=0;val<TAB_SIZE;++val){ | |
optab[val].val = -1; | |
optab[val].opcode[0] = '\0'; | |
} | |
if(fp !=NULL){ | |
while(!feof(fp)){ | |
fscanf(fp,"%s %d\n",buf,&val); | |
hash = hash_str(buf); | |
optab[hash].val = val; | |
strcpy(optab[hash].opcode,buf); | |
} | |
fclose(fp); | |
} | |
else | |
exit(1); | |
} | |
int in_optab(char* opcode){ | |
return optab[hash_str(opcode)].val != -1; | |
} | |
void initialize_symtab(){ | |
int i; | |
for(i=0;i<TAB_SIZE;++i){ | |
symtab[i].sym[0] = '\0'; | |
symtab[i].loc = -1; | |
} | |
} | |
void insert_to_symtab(char* sym,int loc){ | |
int hash = hash_str(sym); | |
strcpy(symtab[hash].sym,sym); | |
symtab[hash].loc=loc; | |
} | |
int in_symtab(char* sym){ | |
return symtab[hash_str(sym)].loc != -1; | |
} | |
void parse_line(char* line,char* label,char* opcode,char* operands){ | |
char* p=line,buf[3][50]; | |
int flag=0,i=0; | |
for(;*p;p++) | |
if(*p == ':'){ | |
flag=1; | |
break; | |
} | |
p = strtok(line,": \n"); | |
while(p != NULL){ | |
sprintf(buf[i],"%s",p); | |
++i; | |
p = strtok(NULL,": \n"); | |
} | |
label[0] = '\0'; | |
opcode[0] = '\0'; | |
operands[0] = '\0'; | |
switch(i){ | |
case 1:{ | |
strcpy(opcode,buf[0]); | |
break; | |
} | |
case 2:{ | |
if(flag){ | |
strcpy(label,buf[0]); | |
strcpy(opcode,buf[1]); | |
}else{ | |
strcpy(opcode,buf[0]); | |
strcpy(operands,buf[1]); | |
} | |
break; | |
} | |
case 3:{ | |
strcpy(label,buf[0]); | |
strcpy(opcode,buf[1]); | |
strcpy(operands,buf[2]); | |
break; | |
} | |
} | |
} | |
int str_to_i(char* str){ | |
int dec = 0; | |
for(;*str;++str) | |
dec = dec*10 + (*str - '0'); | |
return dec; | |
} | |
void print_symtab(){ | |
int i=0; | |
printf("\nSYMTAB\n"); | |
for(;i<TAB_SIZE;++i) | |
if(symtab[i].loc != -1) | |
printf("%s %d\n",symtab[i].sym,symtab[i].loc); | |
printf("\n"); | |
} | |
void print_optab(){ | |
int i=0; | |
printf("\nOPTAB\n"); | |
for(;i<TAB_SIZE;++i) | |
if(optab[i].val != -1) | |
printf("%s %d\n",optab[i].opcode,optab[i].val); | |
printf("\n"); | |
} | |
int main(int argc,char* argv[]){ | |
char label[30],opcode[30],operands[30],str[100]; | |
FILE *fp = fopen(argv[1],"r"); | |
int locctr = 0,starting_addr=0; | |
initialize_symtab(); | |
initialize_optab("optab.txt"); | |
if(fp == NULL) | |
exit(1); | |
fgets(str,100,fp); | |
parse_line(str,label,opcode,operands); | |
if(strcmp(opcode,"START") == 0){ | |
starting_addr = str_to_i(operands); | |
locctr = starting_addr; | |
fgets(str,100,fp); | |
parse_line(str,label,opcode,operands); | |
} | |
while(!feof(fp) && strcmp(opcode,"END") != 0){ | |
printf("%d %s %s %s\n",locctr,label[0]?label:" - ",opcode,operands ); | |
if(label[0]){ | |
if(in_symtab(label)){ | |
printf("Duplicate Symbol!\n%s\n",label); | |
exit(1); | |
}else | |
insert_to_symtab(label,locctr); | |
} | |
if(in_optab(opcode) || strcmp(opcode,"WORD") == 0) | |
locctr+=3; | |
else if(strcmp(opcode,"RESW") == 0) | |
locctr+= 3*str_to_i(operands); | |
else if(strcmp(opcode,"RESB") == 0) | |
locctr+= str_to_i(operands); | |
else if(strcmp(opcode,"BYTE") == 0) | |
locctr += strlen(operands); | |
else{ | |
printf("Invalid opcode!\n%s\n",opcode); | |
exit(1); | |
} | |
fgets(str,100,fp); | |
parse_line(str,label,opcode,operands); | |
} | |
print_optab(); | |
print_symtab(); | |
printf("Length: %d\n",locctr - starting_addr); | |
fclose(fp); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment