Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdbool.h>
- #define SIZE 8
- #define SIZE_OF_REJESTRY 16
- #define SIZE_OF_MEMORY 256
- #define SEPARATOR '%'
- #define NUMBER_OF_ARGUMENTS 3
- #define CORE_DUMP 0
- #define GET_INT 1
- #define PUT_INT 2
- #define GET_CHAR 3
- #define PUT_CHAR 4
- #define PUT_STRING 5
- /*PODSTAWOWA STRUKTURA*/
- typedef struct func_data{
- int pc_index;
- int func_code;
- int ARG[NUMBER_OF_ARGUMENTS];
- struct func_data *next;
- } func_data;
- func_data *func_data_create_node(int index, int f_num, int *arg)
- {
- int i;
- func_data *output = malloc(sizeof(func_data));
- if(output == NULL) exit(1);
- output->pc_index = index;
- output->func_code = f_num;
- output->next = NULL;
- for(i = 0; i < 3; ++i) output->ARG[i] = arg[i];
- return output;
- }
- void func_data_add_node(func_data *f, int index, int f_num, int *arg)
- {
- func_data *output = func_data_create_node(index, f_num, arg);
- while(f->next != NULL) f = f->next;
- f->next = output;
- }
- func_data *func_data_find_pc(func_data *f, int index)
- {
- func_data *output = f;
- while(output != NULL && output->pc_index != index) output = output->next;
- return output;
- }
- void func_data_release(func_data *f)
- {
- func_data *storage = f;
- while(f != NULL){
- storage = f->next;
- free(f);
- f = storage;
- }
- }
- /*INNE funkcje*/
- void show_arr(int A[], int n)
- {
- int i;
- for(i = 0; i < n; ++i) printf("%d ", A[i]);
- printf("\n");
- }
- /*Funkcja dokonujaca poprawna operacje modulo na liczbach*/
- int modulo(int a, int b)
- {
- while(a < 0) a += b;
- return a % b;
- }
- /*wyswietla string*/
- void show_string(int *A)
- {
- int i = 0;
- while( A[i] != 0){
- putchar(A[i]);
- i++;
- }
- }
- /*FUNKCJA WCZYTUJACA DANE*/
- char* read_string(int *length)
- {
- int size = 2, i = 0;
- char *output;
- char ch;
- int part = 0;
- /*Alokowanie mapieci tak ze bedzie przechowywana na steercie*/
- output = malloc(size * sizeof(char));
- /*Sprawdzanie czy pamiec zostala zaalokowana*/
- if(!output) exit(1);
- while((ch = getchar()) != EOF && part < 4){
- *(output + i) = ch;
- ++i;
- if(ch == SEPARATOR) part++;
- /*Realokowanie pamieci w przypadku gdy liczba
- wczytanych danych przekracza zaalokowana pamiec*/
- if(i > size - 1){
- size *= 2;
- output = realloc(output, size * sizeof(char));
- /*Sprawdzanie czy pamiec zostala zaalokowana*/
- if(!output) exit(1);
- }
- }
- /*Ustawienie dlugosci*/
- *length = i;
- /*Ustanowienie znaku konca tablicy '\0'*/
- *(output + i) = '\0';
- return output;
- }
- /*KONWERTOWANIE LICZBY*/
- void find_value_and_base(char ch, int *value, int *base)
- {
- if(ch >= '0' && ch <= '9'){
- *value = ch - '0';
- *base = 10;
- }
- else if(ch >= 'A' && ch <= 'P'){
- *value = ch - 'A';
- *base = 16;
- }
- else if(ch >= 'Q' && ch <= 'X'){
- *value = ch - 'Q';
- *base = 8;
- }
- else if(ch >= 'Y' && ch <= 'Z'){
- if(ch == 'Y') *value = 1;
- else *value = 0;
- *base = 2;
- }
- }
- int convert_dexal(char *string, int length)
- {
- int i, output = 0;
- int value = 0, base = 0;
- /*show_arr1(string, length);*/
- for(i = 0; i < length; ++i){
- find_value_and_base(string[i], &value, &base);
- output = output * base + value;
- /*printf("VALUE %d, BASE %d, OUTPUT %d\n", value, base, output);*/
- }
- return output;
- }
- /*WYPELNIA PAMIEC I REJESTR*/
- void fill_data(int *Arr, int *start, char *Input, int length)
- {
- int i = *start;
- int j = 0;
- int value, not_blank, blank_after;
- while(i < length && Input[i] != SEPARATOR){
- while(i < length && (Input[i] == ' ' || Input[i] == '\n' || Input[i] == '\t') && Input[i] != SEPARATOR)++i;
- if(Input[i] != SEPARATOR){
- not_blank = i;
- while(i < length && Input[i] != ' ' && Input[i] != '\n' && Input[i] != '\t' && Input[i] != SEPARATOR)++i;
- blank_after = i;
- value = convert_dexal(Input + not_blank, blank_after - not_blank);
- Arr[j] = value;
- ++j;
- }
- }
- ++i;/* nalezy sie zastanowic czy bedzie mialo to sens, ma chyba*/
- *start = i;
- }
- void get_function_data(char *inp, int *start, int len, func_data *f)
- {
- int i = *start, j;
- int not_blank, f_code, pc_index = 0;
- int Parameters[3] = {0};
- while(i < len && inp[i] != SEPARATOR){
- /*Pomin nieznaczace symbole*/
- while(i < len && (inp[i] == ' ' || inp[i] == '\n' || inp[i] == '\t')
- && inp[i] != SEPARATOR) ++i;
- if(inp[i] != SEPARATOR){
- not_blank = i;
- f_code = convert_dexal (inp + not_blank, 1);
- j = 0;
- /*Wypelnij tablice parametrow*/
- while(i < len && inp[i] != ' ' && inp[i] != '\n' && inp[i] != '\t'
- && inp[i] != SEPARATOR){
- Parameters[j] = convert_dexal(inp + not_blank + j + 1 , 1);
- ++i;
- ++j;
- }
- /*Uzupelnij strukture*/
- func_data_add_node(f, pc_index, f_code, Parameters);
- pc_index++;
- }
- }
- ++i;
- *start = i;
- }
- /*TO JEST ZLE*/
- /*MALE FUNKCJE*/
- void core_dump(int val)
- {
- fprintf(stderr, "%d", val);
- }
- /*0*/
- void divide(int *REJESTRY, int a, int b, int c, int *PC)
- {
- int temp_c = REJESTRY[c], temp_b;
- int next_index = modulo(a + 1, SIZE_OF_REJESTRY);
- if(temp_c != 0){
- temp_b = REJESTRY[b];
- REJESTRY[a] = temp_b / temp_c;
- REJESTRY[next_index] = temp_b % temp_c;
- }
- *PC = *PC + 1;
- }
- void push(int *REJESTRY, int *MEMORY, int a, int b, int *PC)
- {
- int index = modulo( --REJESTRY[a], SIZE_OF_MEMORY);
- MEMORY[index] = REJESTRY[b];
- *PC = *PC + 1;
- }
- void halt(int *REJESTRY, int a, int *PC)
- {
- exit(REJESTRY[a]);
- *PC = *PC + 1;
- }
- /*1*/
- void return_function(int *REJESTRY, int *MEMORY, int a, int b, int c, int *PC)
- {
- int temp_c = *PC;
- *PC = MEMORY[REJESTRY[a]];
- REJESTRY[a] += REJESTRY[c] + 1;
- REJESTRY[a] = modulo(REJESTRY[a], SIZE_OF_MEMORY);
- REJESTRY[b] = temp_c;
- }
- void pop(int *REJESTRY, int *MEMORY, int a, int b, int *PC)
- {
- REJESTRY[b] = MEMORY[REJESTRY[a]];
- *PC = *PC + 1;
- }
- void return_from_subroutine(int *REJESTRY, int a, int c, int *PC)
- {
- int temp_c = *PC;
- *PC = REJESTRY[c];
- REJESTRY[a] = temp_c;
- }
- /*2*/
- void compare(int *REJESTRY, int a, int b, int c, int *PC)
- {
- REJESTRY[a] = (REJESTRY[b] < REJESTRY[c]) ? 1 : 0;
- *PC = *PC + 1;
- }
- void shift_left(int *REJESTRY, int a, int b, int *PC)
- {
- REJESTRY[a] = REJESTRY[b] << 1; /*czy takze modulo*/
- REJESTRY[a] = modulo(REJESTRY[a], SIZE_OF_MEMORY);
- *PC = *PC + 1;
- }
- /*3*/
- void subtract(int *REJESTRY, int a, int b, int c, int *PC)
- {
- REJESTRY[a] = modulo(REJESTRY[b] - REJESTRY[c], SIZE_OF_MEMORY);
- *PC = *PC + 1;
- }
- void shift_right(int *REJESTRY, int a, int b, int *PC)
- {
- REJESTRY[a] = REJESTRY[b] >> 1;
- REJESTRY[a] = modulo(REJESTRY[a], SIZE_OF_MEMORY);
- *PC = *PC + 1;
- }
- /*4*/
- void load_index(int *REJESTRY, int *MEMORY, int a, int b, int c, int *PC)
- {
- int index_in_memory = modulo(REJESTRY[b] + REJESTRY[c], SIZE_OF_MEMORY);
- REJESTRY[a] = MEMORY[index_in_memory];
- *PC = *PC + 1;
- }
- void add(int *REJESTRY, int a, int b, int c, int *PC)
- {
- REJESTRY[a] = modulo(REJESTRY[b] + REJESTRY[c], SIZE_OF_MEMORY);
- *PC = *PC + 1;
- printf("U\n");
- show_arr(REJESTRY, SIZE_OF_REJESTRY);
- }
- /*5*/
- void store_index(int *REJESTRY, int *MEMORY, int a, int b, int c, int *PC)
- {
- int index = modulo(REJESTRY[b] + REJESTRY[c], SIZE_OF_MEMORY);
- *PC = *PC + 1;
- MEMORY[index] = REJESTRY[a];
- }
- void bitwise_or(int *REJESTRY, int a, int b, int c, int *PC)
- {
- REJESTRY[a] = REJESTRY[b] | REJESTRY[c];
- *PC = *PC + 1;
- }
- /*6*/
- /*PYTANKO*/
- void multiply(int *REJESTRY, int a, int b, int c, int *PC)
- {
- int temp = REJESTRY[b] * REJESTRY[c];
- int index_next = modulo(a + 1, SIZE_OF_REJESTRY);
- REJESTRY[a] = temp % SIZE_OF_MEMORY;
- REJESTRY[index_next] = temp / SIZE_OF_MEMORY;
- *PC = *PC + 1;
- }
- void bitwise_and(int *REJESTRY, int a, int b, int c, int *PC)
- {
- REJESTRY[a] = REJESTRY[b] & REJESTRY[c];
- *PC = *PC + 1;
- }
- /*7*/
- void call_indexed(int *REJESTRY, int *MEMORY, int a, int b, int c, int *PC)
- {
- int temp_pc = *PC;
- *PC = modulo(MEMORY[REJESTRY[b] + REJESTRY[c]], SIZE_OF_MEMORY);
- REJESTRY[a] = temp_pc;
- }
- void bitwise_exclusive_or(int *REJESTRY, int a, int b, int c, int *PC)
- {
- REJESTRY[a] = REJESTRY[b] ^ REJESTRY[c];
- *PC = *PC + 1;
- }
- /*8*/
- void jump_if_zero(int *REJESTRY, int a, int b, int c, int *PC)
- {
- if(REJESTRY[a] == 0) {*PC = modulo(b * 16 + c, SIZE_OF_MEMORY);printf("jest zero\n");}/*czy dobrze*/
- printf("I\n");
- show_arr(REJESTRY, SIZE_OF_REJESTRY);
- printf("PC wynosi %d\n", *PC);
- }
- /*9*/
- void jump_if_not_zero(int *REJESTRY, int a, int b, int c, int *PC)
- {
- if(REJESTRY[a] != 0) *PC = modulo(b * 16 + c, SIZE_OF_MEMORY);
- }
- /*10*/
- void call_subroutine(int *REJESTRY, int a, int b, int c, int *PC)
- {
- REJESTRY[a] = *PC;
- *PC = modulo(b * 16 + c, SIZE_OF_MEMORY);
- }
- /*11*/
- void call(int *REJESTRY, int *MEMORY, int a, int b, int c, int *PC)
- {
- MEMORY[modulo(--REJESTRY[a], SIZE_OF_REJESTRY)] = *PC;
- *PC = modulo(b * 16 + c, SIZE_OF_MEMORY);
- }
- /*12*/
- /*PYTANKO*/
- void load_register(int *REJESTRY, int *MEMORY, int a, int b, int c, int *PC)
- {
- REJESTRY[a] = modulo(MEMORY[b * 16 + c], SIZE_OF_MEMORY);
- *PC = *PC + 1;
- }
- /*13*/
- void store_register(int *REJESTRY, int *MEMORY, int a, int b, int c, int *PC)
- {
- MEMORY[modulo(b * 16 + c, SIZE_OF_MEMORY)] = REJESTRY[a];
- *PC = *PC + 1;
- }
- /*14*/
- void load_constant(int *REJESTRY, int a, int b, int c, int *PC)
- {
- /*nie mam to sensu mnozyc przez 16 i tak nic z tego samo c zostanie*/
- REJESTRY[a] = modulo(b * 16 + c, SIZE_OF_MEMORY);
- *PC = *PC + 1;
- }
- /*15*/
- void system_call(int *REJESTRY, int *MEMORY, int a, int b, int c, int *PC)
- {
- int bc = modulo(b * 16 + c, SIZE_OF_MEMORY);
- int temp_a;
- int next_index = modulo(a + 1, SIZE_OF_REJESTRY);
- *PC = *PC + 1;
- switch(bc){
- case CORE_DUMP: /* 0 */
- core_dump(REJESTRY[a]);
- break;
- case GET_INT: /* 1 */
- if(scanf("%d", &temp_a) != 1) REJESTRY[next_index] = 0;
- else{
- REJESTRY[next_index] = 1;
- REJESTRY[a] = temp_a;
- printf("PCAB\n");
- show_arr(REJESTRY, SIZE_OF_REJESTRY);
- }
- break;
- case PUT_INT: /* 2 */
- printf("WYPISUJE\n");
- printf("%d", REJESTRY[a]);
- break;
- case GET_CHAR: /* 3 */
- temp_a = getchar();
- if(temp_a == EOF) REJESTRY[next_index] = 0;
- else{
- REJESTRY[next_index] = 1;
- REJESTRY[a] = temp_a;
- }
- break;
- case PUT_CHAR: /* 4 */
- printf("PRZED OSTATNIE\n");
- putchar(REJESTRY[a]);
- break;
- case PUT_STRING: /* 5 */
- /*dopoki nie ma \0 wypisuj*/
- show_string(&MEMORY[REJESTRY[a]]);
- //printf("%s", &MEMORY[REJESTRY[a]]);/*ze co to ma znaczyc printf("%s", &mem[reg[a]]);*/
- break;
- default:
- /*nic nie rób */
- break;
- }
- }
- /*chyba tez zle*/
- /* SEDNO PROGRAMU*/
- void interpret(func_data *f, int *REJESTRY, int *MEMORY, int *PC)
- {
- int a = f->ARG[0];
- int b = f->ARG[1];
- int c = f->ARG[2];
- int f_code = f->func_code;
- printf("w func data: pc %d, f->code %d, paratmetry: ",f->pc_index, f_code);
- show_arr(f->ARG, NUMBER_OF_ARGUMENTS);
- switch(f_code){
- case 0:
- if(b != c) divide(REJESTRY, a, b, c, PC);
- else if(a != b && b == c) push(REJESTRY, MEMORY, a, b, PC);
- else halt(REJESTRY, a, PC);
- break;
- case 1:
- if(a != b && a != c) return_function(REJESTRY, MEMORY, a, b, c, PC);
- else if(a != b && a == c) pop(REJESTRY, MEMORY, a, b, PC);
- else return_from_subroutine(REJESTRY, a, c, PC);
- break;
- case 2:
- if(b != c) compare(REJESTRY, a, b, c, PC);
- else shift_left(REJESTRY, a, b, PC);
- break;
- case 3:
- if(b != c) subtract(REJESTRY, a, b, c, PC);
- else shift_right(REJESTRY, a, b, PC);
- break;
- case 4:
- if(b <= c) load_index(REJESTRY, MEMORY, a, b, c, PC);
- else add(REJESTRY, a, b, c, PC);
- break;
- case 5:
- if(b <= c) store_index(REJESTRY, MEMORY, a, b, c, PC);
- else bitwise_or(REJESTRY, a, b, c, PC);
- break;
- case 6:
- if(b <= c) multiply(REJESTRY, a, b, c, PC);
- else bitwise_and(REJESTRY, a, b, c, PC);
- break;
- case 7:
- if(b <= c) call_indexed(REJESTRY, MEMORY, a, b, c, PC);
- else bitwise_exclusive_or(REJESTRY, a, b, c, PC);
- break;
- case 8:
- jump_if_zero(REJESTRY, a, b, c, PC);
- break;
- case 9:
- jump_if_not_zero(REJESTRY, a, b, c, PC);
- break;
- case 10:
- call_subroutine(REJESTRY, a, b, c, PC);
- break;
- case 11:
- call(REJESTRY, MEMORY, a, b, c, PC);
- break;
- case 12:
- load_register(REJESTRY, MEMORY, a, b, c, PC);
- break;
- case 13:
- store_register(REJESTRY, MEMORY, a, b, c, PC);
- break;
- case 14:
- load_constant(REJESTRY, a, b, c, PC);
- break;
- case 15:
- system_call(REJESTRY, MEMORY, a, b, c, PC);
- break;
- default:
- /*NIEZNANA INSTRUKCJA*/
- break;
- }
- }
- void implementation(func_data *f, int *REJESTRY, int *MEMORY, int *PC)
- {
- bool not_found = false;
- func_data *help_str1;
- while(!not_found){
- help_str1 = func_data_find_pc(f, *PC);
- if(help_str1 == NULL) not_found = true;
- else interpret(f, REJESTRY, MEMORY, PC);
- }
- }
- int main(void)
- {
- int length = 1, start = 0, PC = 0;
- char *input = read_string(&length);
- int REJESTRY[SIZE_OF_REJESTRY] = {0}, MEMORY[SIZE_OF_MEMORY] = {0},
- Fake[NUMBER_OF_ARGUMENTS] = {-1, -1, -1};
- func_data *func1 = func_data_create_node(-1, -1, Fake);
- func_data *func2 = func_data_create_node(-1, -1, Fake);
- func_data *test;
- /*wypelnianie rejestru i pamieci*/
- fill_data(REJESTRY, &start, input, length);
- fill_data(MEMORY, &start, input, length);
- /*wypelnianie dwoch struktur*/
- get_function_data(input, &start, length, func1);
- get_function_data(input, &start, length, func2);
- func1 = func1->next;
- func2 = func2->next;
- implementation(func1, REJESTRY, MEMORY, &PC);
- implementation(func2, REJESTRY, MEMORY, &PC);
- /*
- test = func1->next;
- printf("PIERWSZY:\n");
- while(test){
- printf("pc_index %d, func_num %d ", test->pc_index, test->func_code);
- show_arr(test->ARG, NUMBER_OF_ARGUMENTS);
- test = test->next;
- }
- test = func2->next;
- printf("DRUGI:\n");
- while(test){
- printf("pc_index %d, func_num %d ", test->pc_index, test->func_code);
- show_arr(test->ARG, NUMBER_OF_ARGUMENTS);
- test = test->next;
- }
- */
- func_data_release(func1);
- func_data_release(func2);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement