Topple/Source Code

From Esolang
Jump to navigation Jump to search

← Back to Topple

Disclaimer: The current source file is bugged. The fixed file will be added ASAP

Source Code

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>


#define MAX_SIZE 1025 // Size of console, max amount of vals/vars, etc. Currently the best way I know to do this.

char console[MAX_SIZE];
char vals[MAX_SIZE][MAX_SIZE]; // Values
char vars[MAX_SIZE][2]; // Variables ([0]=name,[1]=value)

int nest = 0; // Keeps track of nested IFs, FORs, etc. while processing them. Ensures that code outside of an IF or FOR is not included
int ifRun = 1; // Bool, If 0, ELSE code ([] brackets) will run. Otherwise, nothing happens.
int commenting = 0; // Bool, Allows for commenting w/ proper punctuation

char input;

void clear() {
	printf("\e[1;1H\e[2J");
}

long long timeInMilliseconds(void) { // Returns the current time in milliseconds
	struct timeval tv;
	gettimeofday(&tv,NULL);
	return (((long long)tv.tv_sec)*1000)+(tv.tv_usec/1000);
}

int readFile() { // Reads a given file
	FILE* fptr;
	fptr = fopen("main.txt", "r");
	for(int i = 0; i<MAX_SIZE; i++) console[i]=fgetc(fptr);


	return 0;
}

char proCon(char In[MAX_SIZE]) { // Process Console
    int skip=0;
	for(int i = 0; i < MAX_SIZE; i++) { // Skips characters used in an IF, ELSE, or FOR
		if(!commenting) {
			if(skip) {
				skip--;
				continue;
			}

			if(In[i]=='.') { // "Admits" a given character
				for(int j = 0; j<MAX_SIZE; j++) {
					if(*vals[j] == '\0') {
						if(In[i-1] == '\\') {
							*vals[j] = '\n';

						} else if(In[i-1] == '!') { // Takes User Input
							scanf(" %c",&input);
							*vals[j] = input;

						} else if(In[i-1]=='?') { // IF statement
							// Conditional True/False
							for(int j = 0; j < MAX_SIZE; j++) {
								if(*vals[j]=='\0') {
									if(*vals[j-2]==*vals[j-1]) {
										*vals[j-2] = '1'; // True
									} else {
										*vals[j-2] = '0'; // False
									}

									*vals[j-1] = '\0';
									break;
								}
							}

						} else if(In[i-1]=='#') { // Returns a random number (0 - 9)

							srand(timeInMilliseconds()); // Sets seed for the random stuff
							int num1=rand()%10;
							int num2=num1;
							while(num1 == num2) { // Continuously randomizing num1 until it is no longer the same as num2.
								srand(timeInMilliseconds());
								num1 = rand()%10;
							}

							*vals[j] = num1+'0';
							break;

						} else if(In[i-1]=='^') { // Calls variables
							for(int j = 0; j<MAX_SIZE; j++) {
								if(vars[j][0]==In[i-2]) {
									for(int k = 0; k<MAX_SIZE; k++) {
										if(*vals[k]=='\0') {
											*vals[k] = vars[j][1];
											break;
										}
									}
									break;
								}
							}
							
						} else if(In[i-1]=='$') { // Returns 0 if there are no admitted characters, 1 if there are
        				    for(int j=0; j<MAX_SIZE; j++){
        				        if(*vals[j]=='\0'){
        				            int hasValue = (*vals[0]!='\0');
        				            *vals[j]=(hasValue+'0');
        				            break;
        				        }
        				    }

						} else if(In[i-1]=='+') { // Increments an admitted character at a given index by 1
							*vals[In[i-2]-'0']+=1;

						} else if(In[i-1]=='-') { // Decrements an admitted character at a given index by 1
							*vals[In[i-2]-'0']-=1;

						} else {
							*vals[j] = In[i-1];
						}

						break;
					}
				}
			}


			if(In[i]==',') { // Output characters w/o admitting them, but cannot use commands or special characters
				if(In[i-1]=='\\') {
					printf("\n");
				} else {
					printf("%c",In[i-1]);
				}

			} else if(In[i-1]=='<') { // FOR Loop, loops a given number of times
				nest++;
				int r=0;
				for(int j = 0; j < MAX_SIZE; j++) {
					if(*vals[j] == '\0') {
						r = *vals[j-1]-'0';
						*vals[j-1]='\0';
						break;
					}
				}

				char subCon[MAX_SIZE];
				for(int k = 0; k<MAX_SIZE; k++) subCon[k]='\0';

				for(int j = 0; In[i+j]!='\0'; j++) {
					if(In[i+j]=='<') nest++;
					if(In[i+j]=='>') nest--;


					if(!nest) break;

					subCon[j] = In[i+j];
					skip+=j+1;
				}

				//printf("%d\n",r);
				for(int j = 0; j < r && j>=0; j++) {
					proCon(subCon);
				}

			} else if(In[i-1]=='(') { // IF Statement, runs if the last admitted character is non-zero
				int condition=0;
				nest++;
				for(int j = 0; j < MAX_SIZE; j++) { // Finds last admitted character and checks if it's a non-zero value.
					if(*vals[j] == '\0') {
						condition = (*vals[j-1]!='0');
						*vals[j-1] = '\0';
						break;
					}
				}

				char subCon[MAX_SIZE];
				for(int j = 0; j<MAX_SIZE; j++) subCon[j]='\0';

				for(int j = 0; In[i+j]!='\0'; j++) {
					if(In[i+j]=='(') nest++;
					if(In[i+j]==')') nest--;
					if(!nest) {
						skip+=j+1;
						break;
					}
					subCon[j] = In[i+j];
				}

				if(condition) {
					proCon(subCon);
					ifRun=1;
				} else {
					ifRun=0;
				}

			} else if(In[i-1]=='[') { // ELSE Statement. If the last IF or WHILE Statement did not run, this will run in place of it.
				nest++;

				char subCon[MAX_SIZE];
				for(int j = 0; j<MAX_SIZE; j++) subCon[j]='\0';

				for(int j = 0; In[i+j]!='\0'; j++) {
					if(In[i+j]=='[') nest++;
					if(In[i+j]==']') nest--;
					if(!nest) {
						skip+=j+1;
						break;
					}
					subCon[j] = In[i+j];
				}
				if(!ifRun) {
					proCon(subCon);
					ifRun=1;
				}

			} else if(In[i-1]=='{') { // WHILE loop, loops for as long as a given variable is non-zero
			    char condLoc;
				char condition;
				nest++;
				
				for(int j=0; j<MAX_SIZE; j++){
				    if(*vals[j]=='\0'){
				        condLoc=*vals[j-1];
				        *vals[j-1]='\0';
				        break;
				    }
				}

				char subCon[MAX_SIZE];
				for(int j = 0; j<MAX_SIZE; j++) subCon[j]='\0';

				for(int j = 0; In[i+j]!='\0'; j++) {
					if(In[i+j]=='{') nest++;
					if(In[i+j]=='}') nest--;
					if(!nest) {
						break;
					}
					skip++;
					subCon[j] = In[i+j];
				}
				while(1) {
				    for(int j = 0; j<MAX_SIZE; j++) {
    					if(vars[j][0]==condLoc) {
    						condition = vars[j][1]-'0';
    						break;
    					}
				    }
				    
					if(!condition) {
						break;
					} else {
						proCon(subCon);
					}
					

				}


			} else if(In[i-1]=='@') { // Outputs all admitted characters, then clears
				for(int j = 0; j<MAX_SIZE; j++) {
					printf("%c",*vals[j]);
					*vals[j] = '\0';
				}
			} else if(In[i-1]=='&') { // Outputs all admitted characters w/o clearing
				for(int j = 0; j<MAX_SIZE; j++) {
					printf("%c",*vals[j]);
				}

			} else if(In[i-1]=='|') { // Clears all admitted data
				for(int j = 0; j<MAX_SIZE; j++)
					*vals[j] = '\0';


			} else if(In[i-1]==':') { // Outputs admitted character at a given index
				*vals[In[i-2]-'0'] = '\0';
				for(int j = In[i-2]-'0'; j < MAX_SIZE; j++) *vals[j]=*vals[j+1];
				
			} else if(In[i-1]==';') { //  Pulls an admitted value from a given index and admits it again
				for(int j = 0; j < MAX_SIZE; j++){
				    if(*vals[j]=='\0'){
				        *vals[j] = *vals[In[i-2]-'0'];
				        break;
				    }
				}
			
			} else if(In[i-1]=='=') { // Defines variables
				for(int j = 0; j<MAX_SIZE; j++) {
					if(vars[j][0]=='\0' || vars[j][0]==In[i-2]) {
						vars[j][0] = In[i-2];
						vars[j][1] = In[i];
						break;
					}
				}
				
			} else if(In[i-1]=='~') {
				clear();

			} else if(In[i-1]=='*') { // Quits the program
			    exit(0);
			}
		}
		if(In[i]=='_') { // Toggles commenting
			commenting = !commenting;
		}

	}

}

int main() {

	for(int i = 0; i < MAX_SIZE; i++) { // Clears values and variables before use
		for(int j = 0; j < MAX_SIZE; j++) {
			vars[i][j] = '\0';
		}
		*vals[i] = '\0';
	}
	readFile();
	proCon(console);

	return 0;
}