Topple/Source Code

From Esolang
Jump to navigation Jump to search

← Back to Topple

Some organization may be made in the near future, but it will not change how the current source code is intended to function. Other than that, this is a finished version.

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.
#define clear() printf("\e[1;1H\e[2J");

char console[MAX_SIZE];
char vals[MAX_SIZE][MAX_SIZE]; // Values, initially planned for multi-char vals. Didn't work lol
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;

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(char *In) { // Reads a given file
	FILE* fptr;
	fptr = fopen(In, "r");
	for(int i = 0; i<MAX_SIZE; i++) console[i]=fgetc(fptr);
    fclose(fptr);
    
	return 0;
}

char proCon(char In[]) { // 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
				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++;
				}

				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; // Condition location
				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++) {
				    if(*vals[j]=='\\') printf("\n");
					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("main.txt");
	proCon(console);

	return 0;
}