Skip to content

Instantly share code, notes, and snippets.

@navin-mohan
Created November 14, 2017 16:31

Revisions

  1. navin-mohan created this gist Nov 14, 2017.
    220 changes: 220 additions & 0 deletions pass1.c
    Original 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;
    }