emulator2.c |
| /* 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 |