Skip to content

Instantly share code, notes, and snippets.

@navin-mohan
Created November 14, 2017 16:31
Show Gist options
  • Save navin-mohan/852af85b8baf9ec73a9277e7aaad73e8 to your computer and use it in GitHub Desktop.
Save navin-mohan/852af85b8baf9ec73a9277e7aaad73e8 to your computer and use it in GitHub Desktop.
#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