emulator2.c
contents ::
  emulator2.c
  e1
  input
  simple

/* Machine Emulator program for programing contest */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int stoi(char s[]);
void register_store(char * dest, int value);

enum arith  { ADD, SUB, MUL };
enum branch { BEQ, BNE, BLT, BLE, BGT, BGE };

struct labels{
  char *name;
  int index;
};

int r1=0,r2=0,r3=0,r4=0,r5=0,r6=0,r7=0,r8=0;
int r9=0,r10=0,r11=0,r12=0,r13=0,r14=0,r15=0,r16=0;

void arithmetic(char * dest, char * reg1, char * reg2, int op){
  char new_word[20];
  char new_buff[20];
  int new_length=0;
  int value1=0, value2=0;
  
  while(dest[new_length]!=','){
    new_word[new_length]=dest[new_length++];
  }
  new_word[new_length]='\0';
  
  new_length=0;
  if(squeeze(reg1,"R")>-1){
    while(reg1[new_length]!=','){
      new_buff[new_length]=reg1[new_length++];
    }
    new_buff[new_length]='\0';
    new_length=0;
    value1 = get_register(new_buff);
  } else
    value1 = stoi(reg1);
  if(squeeze(reg2,"R")>-1){
    value2 = get_register(reg2);
  } else
    value2 = stoi(reg2);
  
  if(op == ADD)
    register_store(new_word, value1+value2);
  else if(op == MUL){
    register_store(new_word, value1*value2);
  } else if(op == SUB){ 
    register_store(new_word, value1-value2);
  } else {
    printf("Operation Error\n");
    exit(EXIT_FAILURE);
  }
    
}

int branch(char * dest, char * reg1, char * reg2, int op, int counter, char ** wordlist, int i){
  int value1=0, value2=0;
  int j=0;
  char new_word[20];
  int new_length=0;
  int found = 0;
  int BLE_z,BLE_i=0;
  char BLE_buffer[21];
  int BLE_length = 0;
  int BLE_false = 0;
  int BLE_found = 0;
  int BLE_rerun = 0;
  
  while(dest[new_length]!=','){
    new_word[new_length]=dest[new_length++];
  }
  new_word[new_length]='\0';
  BLE_length = new_length;
  
  new_length=0;
  
  if(squeeze(reg1,"R")>-1){
    while(reg1[new_length]!=',')
      new_length++;
    reg1[new_length]='\0';
    value1 = get_register(reg1);
  } else 
    value1 = stoi(reg1);
  new_length=0;
  if(squeeze(reg2,"R")>-1){
    while(reg2[new_length]!=',')
      new_length++;
    reg2[new_length]='\0';
    value2 = get_register(reg2);
  } else 
    value2 = stoi(reg2);
  
  if((op == BLE && value1<=value2) ||
     (op == BEQ && value1==value2) ||
     (op == BLT && value1<value2) ||
     (op == BGT && value1>value2) ||
     (op == BGE && value1>=value2) ||
     (op == BNE && value1!=value2))
    goto BLE_search;
  else goto ret;
  
 BLE_search:
  for(BLE_z=0; BLE_z<counter; BLE_z++){         
    sscanf(wordlist[BLE_z], "%s", BLE_buffer);
    BLE_found=0;
    BLE_i=0;
    while(wordlist[BLE_z][BLE_i]==new_word[BLE_i] && new_word[BLE_i] != '\0'){
      BLE_found++;
      BLE_i++;
      goto BLE_found;
    }
  }
  
 BLE_found:
  new_length=0;
  while(wordlist[BLE_z][new_length]!=':'){
    BLE_buffer[new_length]=wordlist[BLE_z][new_length++];
  }
  BLE_buffer[new_length]='\0';
  new_length=0;
  
  if(BLE_found && strcmp(new_word,BLE_buffer)==0){
            
    i=BLE_z;
  } else{ 
    printf("Jump error :(");
    return 0;
  }
  
  i = BLE_z;
  
 ret:
  return i; 
}

int my_strlen(char s[]){
  int i=0;
  while(s[i]!='\0')
   i++;
  return i;
}

void register_store(char * dest, int value){

  if(strcmp(dest,"R1")==0){
    r1 = value;
  } else if(strcmp(dest,"R2")==0){
    r2 = value;
  } else if(strcmp(dest,"R3")==0){
    r3 = value;
  } else if(strcmp(dest,"R4")==0){
    r4 = value;
  } else if(strcmp(dest,"R5")==0){
    r5 = value;
  } else if(strcmp(dest,"R6")==0){
    r6 = value;
  } else if(strcmp(dest,"R7")==0){
    r7 = value;
  } else if(strcmp(dest,"R8")==0){
    r8 = value;
  } else if(strcmp(dest,"R9")==0){
    r9 = value;
  } else if(strcmp(dest,"R10")==0){
    r10 = value;
  } else if(strcmp(dest,"R11")==0){
    r11 = value;
  } else if(strcmp(dest,"R12")==0){
    r12 = value;
  } else if(strcmp(dest,"R13")==0){
    r13 = value;
  } else if(strcmp(dest,"R14")==0){
    r14 = value;
  } else if(strcmp(dest,"R15")==0){
    r15 = value;
  } else if(strcmp(dest,"R16")==0){
    r16 = value;
  } else {
    printf("Register error: %s is not a valid register.\n", dest);
    exit(EXIT_FAILURE);
  }
}

int get_register(char *dest){ 
  if(strcmp(dest,"R1")==0){
    return r1;
  } else if(strcmp(dest,"R2")==0){
    return r2;
  } else if(strcmp(dest,"R3")==0){
    return r3;
  } else if(strcmp(dest,"R4")==0){
    return r4;
  } else if(strcmp(dest,"R5")==0){
    return r5;
  } else if(strcmp(dest,"R6")==0){
    return r6;
  } else if(strcmp(dest,"R7")==0){
    return r7;
  } else if(strcmp(dest,"R8")==0){
    return r8;
  } else if(strcmp(dest,"R9")==0){
    return r9;
  } else if(strcmp(dest,"R10")==0){
    return r10;
  } else if(strcmp(dest,"R11")==0){
    return r11;
  } else if(strcmp(dest,"R12")==0){
    return r12;
  } else if(strcmp(dest,"R13")==0){
    return r13;
  } else if(strcmp(dest,"R14")==0){
    return r14;
  } else if(strcmp(dest,"R15")==0){
    return r15;
  } else if(strcmp(dest,"R16")==0){
    return r16;
  } else {
    printf("Register error: %s is not a valid register.\n", dest);
    exit(EXIT_FAILURE);
  }
}


int squeeze(char s1[],char s2[]){
  int i, j, z;
  int in = 0;

  for(i = 0; s1[i]!='\0'; i++){
    for(j = 0; s2[j]!='\0'; j++){
      if(s1[i]==s2[j]){
         in=1;
         break;
      }
    }
    if(in==1){
      return i;
    }
  }
  
  return -1;
  printf("%s\n", s1);
}

int read_code(char ** wordlist){
  int length = 0;
  char c = '\0';
  char word[150];
  int counter = 0;

  while((c=getchar())!=EOF && c!='#'){
    /* deal with comments */
    if(c=='%')while((c=getchar())!='\n');

    if(c!='\n')
      word[length++]=c;
    else if(length>1) {
      word[length]='\0';
      wordlist[counter] = malloc((length) * sizeof wordlist[0][0]);
      strcpy(wordlist[counter++], word);
      length=0;
    }
  }

  return counter;
}

main(){
  char *wordlist[150];
  int counter = 0;
  int inp[20];
  int inp_size=20;
  int inp_count=0;
  int label_size = 20;
  int label_count = 0;
  char word[150];
  int length = 0;
  int i=0;
  char c ='\0';
  char d ='\0';
  int m=0;
  char dest[150], reg1[150], reg2[150];
  struct labels *jump;
  jump = malloc(label_size * sizeof jump);

  counter = read_code(wordlist);

  for(i=0; i<counter; i++){
     sscanf(wordlist[i],"%s",word);
     if(strcmp(word,"ADD")==0){
       /* Operation for Add commmand */
       sscanf(wordlist[i],"%s %s %s %s",word, dest, reg1, reg2);
       arithmetic(dest, reg1, reg2, ADD);
       
     } else if(strcmp(word,"BEQ")==0){
      /* Operation for equal to */
       int j=0;
       sscanf(wordlist[i],"%s %s %s %s",word, dest, reg1, reg2);
       j = branch(dest, reg1, reg2, BEQ, counter, wordlist, i);
       i = j;
     } else if(strcmp(word,"BGE")==0){
      /* Operation for Greater than or equal to */
       int j=0;
       sscanf(wordlist[i],"%s %s %s %s",word, dest, reg1, reg2);
       j = branch(dest, reg1, reg2, BGE, counter, wordlist, i);
       i = j;
     } else if(strcmp(word,"BGT")==0){
      /* Operation for Greater than */
       int j=0;
       sscanf(wordlist[i],"%s %s %s %s",word, dest, reg1, reg2);
       j = branch(dest, reg1, reg2, BGT, counter, wordlist, i);
       i = j;
     } else if(strcmp(word,"BLE")==0){
       /* Operation for Less than or Equal to */
       int j=0;
       sscanf(wordlist[i],"%s %s %s %s",word, dest, reg1, reg2);
       j = branch(dest, reg1, reg2, BLE, counter, wordlist, i);
       i = j;

     } else if(strcmp(word,"BLT")==0){
       /* Operation for Less than */
       int j=0;
       sscanf(wordlist[i],"%s %s %s %s",word, dest, reg1, reg2);
       j = branch(dest, reg1, reg2, BLT, counter, wordlist, i);
       i = j;

     } else if(strcmp(word,"BNE")==0){
       /* Operation for Not Equal to */
       int j=0;
       sscanf(wordlist[i],"%s %s %s %s",word, dest, reg1, reg2);
       j = branch(dest, reg1, reg2, BNE, counter, wordlist, i);
       i = j;
     } else if(strcmp(word,"BRU")==0){
       /* Operation for Not Equal to */
       int j=0;
       sscanf(wordlist[i],"%s %s",word, dest);

       for(j=0; j<label_count; j++){
          if(strcmp(dest,jump[j].name)==0)
            break;
       }
       i=jump[j-1].index;
     } else if(strcmp(word,"HLT")==0){
     } else if(strcmp(word,"INP")==0){
       /* operatiorn for inp operand */
       int value = 0;
       sscanf(wordlist[i],"%s %s",word, dest);
       scanf("%d", &value);
       register_store(dest, value);
     } else if(strcmp(word,"MOV")==0){
       /* Operation for MOV operand */
       char new_word[20];
       char new_buff[20];
       int new_length=0;
       int value = 0;
       sscanf(wordlist[i],"%s %s %s",word, dest, reg1);
       
       while(dest[new_length]!=','){
          new_word[new_length]=dest[new_length++];
       }
       new_word[new_length]='\0';
       
       if(squeeze(reg1,"R")>-1){
          value = get_register(reg1);
       } else 
          value = stoi(reg1);
       register_store(new_word, value);
       
     } else if(strcmp(word,"MUL")==0){

       /* Operation for multiply commmand */
       sscanf(wordlist[i],"%s %s %s %s",word, dest, reg1, reg2);
       arithmetic(dest, reg1, reg2, MUL);

     } else if(strcmp(word,"OUT")==0){

       /* Operation for OUT */
       sscanf(wordlist[i],"%s %s",word, dest);
       printf("%d\n",get_register(dest));

     } else if(strcmp(word,"SUB")==0){

       /* Operation for Subtraction operand */
       sscanf(wordlist[i],"%s %s %s %s",word, dest, reg1, reg2);
       arithmetic(dest, reg1, reg2, SUB);

      } else {
       /* Operation for Label */
       char new_word[20];
       int new_length=0;
       int home = 0;
       int z = 0;
       if(label_count == label_size){
          printf("Labels full");
          exit(EXIT_FAILURE);
          
       }
       
       while(word[new_length]!=':'){
          new_word[new_length]=word[new_length++];
       }
       new_word[new_length]='\0';

       for(z=0; z<label_count; z++){
          if(strcmp(jump[z].name,new_word)==0){
            home=1;
            break;
          }
       }
       
       if(!home){
          jump[label_count].name = malloc(new_length * sizeof new_word[0]);
          strcpy(jump[label_count].name,new_word);
          jump[label_count].index = i;
          label_count++;
       }
     }
  }
  return 0;
}
                                                                   
int stoi(char s[]){
  int sign = 1;
  int i,j,r;
  i=1;
  r=0;

  for(j=my_strlen(s)-1; j>=0; j--){
    if(j==0 && s[j] == '-')
      sign = -1;
    else {
      r+=((s[j]-'0')*i);
      i*=10;
    }
  }
  return (r * sign);
}

James Little