Created
November 14, 2017 16:31
Revisions
-
navin-mohan created this gist
Nov 14, 2017 .There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,220 @@ #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; }