#include <stdio.h>
#include <stdlib.h>

char storage[64];
char *storeptr = storage;


int main(int argc, char *argv[])
{


FILE *filePointer;
FILE *createptr;

char entrypoint_reached = 0;


char ch;



filePointer = fopen(argv[1], "r");
createptr = fopen(argv[2],"w");


fprintf(createptr,"%s", "#include <stdio.h>\n\n//general\nint Stack_1[1024] = {0};\nint Stack_2[254] = { 0 };\nint iterator_1 = -1 ;\nint iterator_2 = -1 ;\nint *iterator[2] = { &iterator_1,&iterator_2 };\nint Actual_iterator = 0;\nint *Collection_stack[2] = {Stack_1,Stack_2} ;\nint Actual_stack = 0;\nvoid change_stack(int n){Actual_stack = n - 1; Actual_iterator = n - 1;}\n//element for condition/check\nint state[256] = {0};\nvoid (*previous[256]) ();\nvoid (*next[256]) ();\nint current_state = 0;\nvoid *last_function;\nint size_array = 0;\nint general_value = 1;\n//function for control flow\nvoid *no_match_function;\nvoid (*no_match_function_call[1]) ();\nint no_match_on = 0;\nvoid match_fail(void (*p)()){no_match_function_call[0] = p;no_match_on = 1;}\nvoid stop_match_fail(){no_match_on = 0;}\nvoid condition(void (*p)(), int target_state, void (*n)()){\nstate[size_array] = target_state;\nprevious[size_array] = p;\nnext[size_array] = n;\nsize_array++;\n};\nint check(){\nfor(int i = 0; i <= size_array;i++){\nif(current_state == state[i]){\nif(previous[i]   == last_function ){ (*next[i])(); return 1; }; };\n};\nif(no_match_on == 1){(*no_match_function_call[0])(); return 1;}\nreturn -1;\n};\n//function to interact with stack\nvoid number(int n){ *iterator[Actual_iterator] = *iterator[Actual_iterator] + 1;\nCollection_stack[Actual_stack][*iterator[Actual_iterator]] = n ;}\nvoid pop(){ Collection_stack[Actual_stack][*iterator[Actual_iterator]] = 0 ;\n *iterator[Actual_iterator] = *iterator[Actual_iterator] - 1;}\nvoid inc(){Collection_stack[Actual_stack][*iterator[Actual_iterator]] =\n Collection_stack[Actual_stack][*iterator[Actual_iterator]] + 1 ; }\nvoid dup(){  *iterator[Actual_iterator] = *iterator[Actual_iterator] + 1; \nCollection_stack[Actual_stack][*iterator[Actual_iterator]] = Collection_stack[Actual_stack][*iterator[Actual_iterator] - 1 ]; }\nvoid push(){ iterator_2++;Stack_2[iterator_2] = Stack_1[iterator_1];Stack_1[iterator_1] = 0; }\nvoid back(){ Stack_1[iterator_1] =  Stack_2[iterator_2]; Stack_2[iterator_2] = 0; iterator_2--;  }\n//function to interact with state\nvoid push_state(){ current_state = Collection_stack[Actual_stack][*iterator[Actual_iterator]] ;\n Collection_stack[Actual_stack][*iterator[Actual_iterator]] = 0 ; *iterator[Actual_iterator] =\n *iterator[Actual_iterator] - 1;}\nvoid copy_state(){current_state = Collection_stack[Actual_stack]\n[*iterator[Actual_iterator]] ;}\nvoid def_state(int n){ current_state = n ;}\n//function to interact with iterator\nvoid set_iterator( int n ){ iterator_1 = n - 1  ;};\nvoid iterate(int n){ iterator_1 = iterator_1 + n ; if( iterator_1 < -1 ){ current_state = -1 ;\n iterator_1 = -1; }; };\nvoid get_iterator(){ \niterator_1 = Stack_2[iterator_2]; ; Stack_2[iterator_2] = 0; iterator_2--; \n}\n// math\nvoid add(){\n Collection_stack[Actual_stack][*iterator[Actual_iterator] - 1] = Collection_stack[Actual_stack][*iterator[Actual_iterator] - 1] + Collection_stack[Actual_stack][*iterator[Actual_iterator]];\nCollection_stack[Actual_stack][*iterator[Actual_iterator]] = 0;\n*iterator[Actual_iterator] = *iterator[Actual_iterator] - 1; }\nvoid sub(){ \nCollection_stack[Actual_stack][*iterator[Actual_iterator] - 1] = Collection_stack[Actual_stack][*iterator[Actual_iterator] - 1] - Collection_stack[Actual_stack][*iterator[Actual_iterator]];\nCollection_stack[Actual_stack][*iterator[Actual_iterator]] = 0;\n*iterator[Actual_iterator] = *iterator[Actual_iterator] - 1; }\nvoid mul(){ \nCollection_stack[Actual_stack][*iterator[Actual_iterator] - 1] = Collection_stack[Actual_stack][*iterator[Actual_iterator] - 1] * Collection_stack[Actual_stack][*iterator[Actual_iterator]];\nCollection_stack[Actual_stack][*iterator[Actual_iterator]] = 0;\n*iterator[Actual_iterator] = *iterator[Actual_iterator] - 1; }\nvoid div(){ \nCollection_stack[Actual_stack][*iterator[Actual_iterator] - 1] = Collection_stack[Actual_stack][*iterator[Actual_iterator] - 1] / Collection_stack[Actual_stack][*iterator[Actual_iterator]];\nCollection_stack[Actual_stack][*iterator[Actual_iterator]] = 0;\n*iterator[Actual_iterator] = *iterator[Actual_iterator] - 1; }\nvoid iadd( int n ) { Collection_stack[Actual_stack][*iterator[Actual_iterator]] = \nCollection_stack[Actual_stack][*iterator[Actual_iterator]] + n ; };\nvoid isub( int n ) { Collection_stack[Actual_stack][*iterator[Actual_iterator]] = \nCollection_stack[Actual_stack][*iterator[Actual_iterator]] - n ; };\nvoid imul( int n ) { Collection_stack[Actual_stack][*iterator[Actual_iterator]] = \nCollection_stack[Actual_stack][*iterator[Actual_iterator]] * n ; };\nvoid idiv( int n ) { Collection_stack[Actual_stack][*iterator[Actual_iterator]] = \nCollection_stack[Actual_stack][*iterator[Actual_iterator]] / n ; };\n//logic\nvoid equal(){ *iterator[Actual_iterator] = *iterator[Actual_iterator] + 1;\nCollection_stack[Actual_stack][*iterator[Actual_iterator]] = ( Collection_stack[Actual_stack][*iterator[Actual_iterator] - 2] == Collection_stack[Actual_stack][*iterator[Actual_iterator] -1] )  ;}\n//io function\nvoid print(char *string){ printf(\"%s\\n\", string);}\nvoid input(){ char input[1024 - iterator_1] ; fgets(input, (1024 - iterator_1) ,stdin);\nint i = 0; while(input[i] != \'\\0\'){iterator_1++;Stack_1[iterator_1] = input[i];i++;}\nStack_1[iterator_1] = 0;Stack_1[iterator_1] = 0;iterator_1--;}\nvoid print_stack(){for(int i = 0; i <= 254;i++){printf(\"%d \",  Collection_stack[Actual_stack][i] );};printf(\"\\n\");}\nvoid print_stack_ascii(){for(int i = 0; i <= 254;i++){printf(\"%c\", Collection_stack[Actual_stack][i]);};printf(\"\\n\");}\n\n"

);



while ((ch = fgetc(filePointer)) != EOF)
{
switch(ch){
case '.': 
ch = fgetc(filePointer);
while ((ch != ':') && (ch != '!') ){*storeptr =ch; storeptr++;ch = fgetc(filePointer);}
fseek(filePointer,-1,SEEK_CUR); 
break;
case ':':
fprintf(createptr,"void ");
fprintf(createptr,"%s",storage);
fprintf(createptr,"()");
while ((ch = fgetc(filePointer)) != '{'){fprintf(createptr,"%c",ch);}
fprintf(createptr,"{");
fprintf(createptr,"last_function = ");
fprintf(createptr,"%s",storage);
fprintf(createptr,";\n");
for(int i = 0 ;i <= 64;i++){storage[i] = 0;};
storeptr =storage;
break;
case '!':
fprintf(createptr,"int main(int argc, char *argv[])");
entrypoint_reached = 1;

break;
case '"':
fprintf(createptr,"\"");
while ((ch = fgetc(filePointer)) != '"'){fprintf(createptr,"%c",ch);}
fprintf(createptr,"\"");
break;

case '(':
fprintf(createptr,"(");
//while ((ch = fgetc(filePointer)) != ')'){fprintf(createptr,"%c",ch);}
//fseek(filePointer,-1,SEEK_CUR);
break;
case ')':
fprintf(createptr,")");
fprintf(createptr,";");
break;
case '>':
fprintf(createptr,"condition(");
while ((ch = fgetc(filePointer)) != ';'){fprintf(createptr,"%c",ch);}
fprintf(createptr,",");
while ((ch = fgetc(filePointer)) != ';'){fprintf(createptr,"%c",ch);}
fprintf(createptr,",");
while ((ch = fgetc(filePointer)) != ';'){fprintf(createptr,"%c",ch);}
fprintf(createptr,");");
break;
case '*':
fseek(createptr,-5,SEEK_CUR); 
fprintf(createptr,"while( general_value > 0 ){general_value = check();};general_value = 1;");
break;
case '}':
if(entrypoint_reached == 1){ fprintf(createptr,"return 0;"); }
fprintf(createptr,"}");
break;
default: fprintf(createptr,"%c",ch);break;
};
;}






return 0;
}
