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.

Disclaimer: The source code will pull text from a separate "main.txt" file. Ensure that such a file exists or that you create one with that file name. That is where Topple code should be written. No harm would otherwise be done if the file did not exist, it would just not work properly or at all.

Source Code

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

#define MAX_SIZE 4097   // Max amount of vals, vars, etc. Currently the best way I know to do this.

#define CLEAR() printf("\e[1;1H\e[2J");

typedef struct variables{
    char name;
    char val;
} var;

char vals[MAX_SIZE];    // Admitted Values
var vars[MAX_SIZE];     // Variables

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 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 fileSize(char *stream){ // Returns the size (# of chars) of a file
    FILE* file = fopen(stream,"r");
    
    int size=0;
    char ch;
    
    while ( (ch = fgetc(file)) != EOF ) size++;
    
    fclose(file);
    return size;
}

void readFile(char *stream, char toFile[]){ // Copies the contents of a file into a given variable
    FILE* file = fopen(stream,"r");
    
    char ch;
    
    int i=0;
    while ( (ch = fgetc(file)) != EOF ) {
        toFile[i]=ch;
        i++;
    }
    
    fclose(file);
}

char proCon(char In[], int size) { // Process Console
    int skip=0;
	for(int i = 0; i <= 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
							for(int j = 0; j < MAX_SIZE; j++) {
								if(vals[j]=='\0') {
									if(vals[j-2]==vals[j-1]) { // Compares last two given vals
										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].name==In[i-2]) {
									for(int k = 0; k<MAX_SIZE; k++) {
										if(vals[k]=='\0') {
											vals[k] = vars[j].val;
											break;
										}
									}
									break;
								}
							}
						} 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++) {
					proCon(subCon,strlen(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,strlen(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,strlen(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].name==condLoc) {
    						condition = vars[j].val-'0';
    						break;
    					}
				    }
				    
					if(!condition) {
						break;
					} else {
						proCon(subCon,strlen(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].name=='\0' || vars[j].name==In[i-2]) {
						vars[j].name = In[i-2];
						vars[j].val = In[i];
						break;
					}
				}
				
			} else if(In[i-1]=='^') {
				if(In[i]=='+'){
				    skip++;
				    for(int j=0; j<MAX_SIZE; j++)
				        if(vars[j].name==In[i-2]) vars[j].val++;
				}else if(In[i]=='-'){
				    skip++;
				    for(int j=0; j<MAX_SIZE; j++)
				        if(vars[j].name==In[i-2]) vars[j].val--;
				}
				
			} else if(In[i-1]=='~') { // Clears console
				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
		vals[i] = '\0';
	}
	int size = fileSize("main.txt");
	char console[size]; // The console... who coulda guessed?
	for(int i=0; i<size; i++) console[i]='\0';
	readFile("main.txt",console);
	proCon(console,size);

	return 0;
}