int main(void)
{
    // print welcome message
    char* pathbuffer = (char*) calloc(MAX_LINE_LENGTH, sizeof(char));
    if (pathbuffer == NULL)
    {
        perror("calloc error in interpreter\n");
        exit(EXIT_FAILURE);
    }

    assert(readlink("/proc/self/exe", pathbuffer, MAX_LINE_LENGTH) != -1);
    removeExecutableName(pathbuffer);
    strcat(pathbuffer, "/msg/interpreter_welcome.txt");

    // print welcome message
    // assert(system("cat IAT/msg/interpreter_welcome.txt\n") != -1);
    printTextFile(pathbuffer);
    free(pathbuffer);

    // initialize references and cpu
    References* references = initReferences();
    CPUStatus* cpu = initCPU();
    int status = 0;

    // main loop
    while (1)
    {
        interpretPrompt(references, cpu, &status);
        if (status == EXECUTE_HALT)
        {
            break;
        }
    }

    // print status
    printRegisters(cpu);
    printMemory(cpu);

    // garbage collecting
    destroyReferences(references);
    destroyCPU(cpu);

    return EXIT_SUCCESS;
}
void checkCommand(char* buf){

	char* ptr, *p, *tmp;
	char command[BUF];
	bool flag = true;
	vector<char*> splitCommand;
	
	ptr = strtok_r(buf, " ", &p);	

	while( ptr ){
		splitCommand.push_back(ptr);
		ptr = strtok_r(NULL, " \n", &p);	
	}
	

	if( strncmp( buf, ":help", 5) == 0 || strncmp(buf, ":h", 2) == 0){
		cout << helpComm << endl;
	}
	else if( strncmp( splitCommand[0], "alg", 3) == 0){
		ptr = (splitCommand[0]+3);
	
		if( splitCommand.size() >= 3 ){		
			if( strncmp(ptr, "4_1", 3) == 0 ){
				alg4_1(splitCommand[1], splitCommand[2]);
			}
			else if( strncmp(ptr, "4_2", 3) == 0 ){
				alg4_2(splitCommand[1], splitCommand[2]);
			}
			else if( strncmp(ptr, "4_3", 3) == 0 ){
				alg4_3(splitCommand[1], splitCommand[2]);
			}
			else if( strncmp(ptr, "4_4_2", 5) == 0 ){
				alg4_4_2(splitCommand[1], splitCommand[2]);
			}
			else if( strncmp(ptr, "4_4_4", 5) == 0 ){
				alg4_4_4(splitCommand[1], splitCommand[2]);
			}
			else if( strncmp(ptr, "4_5", 3) == 0 ){
				alg4_5(splitCommand[1], splitCommand[2]);
			}
			else if( strncmp(ptr, "4_6", 3) == 0 && splitCommand.size() == 4){
				alg4_6(splitCommand[1], splitCommand[2], splitCommand[3]);
			}
			else if( strncmp(ptr, "4_7", 3) == 0 ){
				alg4_7(splitCommand[1], splitCommand[2]);
			}
			else if( strncmp(ptr, "4_8", 3) == 0 ){
				alg4_8(splitCommand[1], splitCommand[2]);
			}
			else if( strncmp(ptr, "5_6", 3) == 0 ){
				alg5_6(splitCommand[1], splitCommand[2]);
			}
			else if( strncmp(ptr, "5_7", 3) == 0 ){
				alg5_7(splitCommand[1], splitCommand[2]);
			}
			else if( strncmp(ptr, "6_2", 3) == 0 ){
				alg6_2(splitCommand[1], splitCommand[2]);
			}
			else{
				cout << splitCommand[0] << " is not an algorithm or you gave incorrect params, please type :help to see the list" << endl;
				flag = false;
			}
		
			if( splitCommand.size() == 3 && flag){	
				cout << endl;
				printTextFile(splitCommand[2]);
			}
			else if( splitCommand.size() == 4 && flag){
				cout << "A pdf has been produced called: " << splitCommand[2] << ".pdf" << endl;
			}
		}
		else{
			cout << "To few arguments to run an algorithm, please type :h OR :help to get the arguments" << endl;
		}	
	
	}
	else if( strncmp( buf, ":quit", 5) == 0 || strncmp( buf, ":q", 2) == 0 ){
		cout << "haha you want to quit" << endl;
		exit(1);
	}
	else if( strncmp( buf, ":ls", 3) == 0){
		strncpy( command, "ls --hide=*.o ", 15);		
		if( splitCommand.size() == 2){
			strcat(command, splitCommand[1]);
		}
		system(command);
	}
	else if( strncmp( buf, ":vim", 4) == 0 && splitCommand.size() == 2){
		strncpy(command, "vim ", 5);
		strcat(command, splitCommand[1]);
		system(command);
	}
	else if( strncmp( buf, ":cat", 4) == 0 && splitCommand.size() == 2){
		strncpy(command, "cat ", 5);
		strcat(command, splitCommand[1]);
		cout << endl;
		system(command);
		cout << endl;
	}
	else{
		cout << "command not recognize, enter :h OR :help if your lost"  << endl;
	}

}