Topple/Topple 1/Source (C99)
Jump to navigation
Jump to search
#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;
}