Topple/Topple 1/Source (C++)
Jump to navigation
Jump to search
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cctype>
#include <string>
#include <ctime>
#define CLEAR() printf("\e[1;1H\e[2J");
typedef struct{
char name;
char val;
}var;
void read_file(FILE* file, char dest[]){ // Reads the contents of a given file into a given variable
int pos=0;
char ch;
while((ch=fgetc(file))!=EOF){
dest[pos]=ch;
pos++;
}
}
long long file_size(std::string file_name){
char ch;
int size=0;
FILE* file = fopen(file_name.c_str(),"r");
while((ch=fgetc(file))!=EOF && ch!='\0' && ch!=0)++size;
fclose(file);
return size;
}
unsigned long long random(int min, int max){
srand(static_cast<unsigned int>(time(0)));
int num1=min+(time(0)%max);
int num2=num1;
while(num1==num2){
std::cout<<num1<<" "<<num2;
num1=min+(time(NULL)%max);
}
return num1;
}
long arr_len(char data[]){ // Returns the length of a given char array
int size=0;
for(int i=0;data[i]!='\0';i++)++size;
return size;
}
long var_amnt(var vars[]){ // Returns length of a given variable array
int size=0;
for(int i=0;vars[i].name!='\0';i++)++size;
return size;
}
long var_loc(var vars[], char var_name){ // Returns the index of a given variable
for(int i=0;vars[i].name!='\0';i++){
if(vars[i].name==var_name) return i;
}
return -1;
}
void print(char data[],int delete_values){ // Outputs data and, if 'delete_values' is true, "deletes" it
for(int i=0; data[i]!='\0'; i++){
std::cout<<(char)data[i];
if(delete_values) data[i]='\0';
}
}
namespace topple_data{
// array size is temporary, probably
char held_data[256];
var variables[64];
}
//when true, characters are ignored until false
int commenting=0;
void process_code(char code[],int size,int start,int end){ // Interprets a given char array as Topple code
int sub_start=start; // start of code blocks
int sub_end=end; // end of code blocks
int condition=0; // if condition, also acts as loop amount and while condition
int nest=0; // keeps track of nested ifs/loops
for(int let=start; let<size && let<end; let++){
if(code[let]=='_') ::commenting=!::commenting;
if(::commenting)continue; // toggles commenting on/off
switch(code[let]){
case '.': // Activates command characters, admits non-command characters
if(code[let-1]=='#') // admits a random number between 0 and 9
topple_data::held_data[arr_len(topple_data::held_data)]=random(0,9)+'0';
else if(code[let-1]=='^'){ // calls a variable by a given name
topple_data::held_data[arr_len(topple_data::held_data)]=topple_data::variables[var_loc(topple_data::variables,code[let-2])].val;
}
else if(code[let-1]=='?'){ // returns whether two given values are equal
topple_data::held_data[arr_len(topple_data::held_data)-2]=(topple_data::held_data[arr_len(topple_data::held_data)-1]==topple_data::held_data[arr_len(topple_data::held_data)-2])+'0';
topple_data::held_data[arr_len(topple_data::held_data)-1]='\0';
}
else if(code[let-1]=='!'){
std::cin>>topple_data::held_data[arr_len(topple_data::held_data)];
}
else if(code[let-1]=='\\') // next line (\n)
topple_data::held_data[arr_len(topple_data::held_data)]='\n';
else topple_data::held_data[arr_len(topple_data::held_data)]=code[let-1];
break;
// output
case ',': // outputs the previous character w/o admitting
std::cout<<code[let-1];
break;
case '@': // outputs held data and deletes them
print(topple_data::held_data,1);
break;
case '&': // outputs held data w/o deleting them
print(topple_data::held_data,0);
break;
// IFs/Loops
case '(': // if statement
sub_start=let;
++nest;
condition=(topple_data::held_data[arr_len(topple_data::held_data)-1]!='0');
topple_data::held_data[arr_len(topple_data::held_data)-1]='\0';
for(int space=let+1; space<size && space<end && nest; space++){ // finds the end of a code block
/* Turn to function somehow, used elsewhere */
++let;
if(code[space]=='(')++nest;
else if(code[space]==')')--nest;
sub_end=space;
}
if(condition)process_code(code,size,sub_start+1,sub_end);
break;
case '[': // else statement
sub_start=let;
++nest;
for(int space=let+1; space<size && space<end && nest; space++){
++let;
if(code[space]=='[')++nest;
else if(code[space]==']')--nest;
sub_end=space;
}
if(!condition) process_code(code,size,sub_start+1,sub_end);
break;
case '<': // for loop
sub_start=let;
++nest;
condition=(topple_data::held_data[arr_len(topple_data::held_data)-1])-'0';
topple_data::held_data[arr_len(topple_data::held_data)-1]='\0';
for(int space=let+1; space<size && space<end && nest; space++){
++let;
if(code[space]=='<')++nest;
else if(code[space]=='>')--nest;
sub_end=space;
}
for(int i=0; i<condition; i++) process_code(code,size,sub_start+1,sub_end);
break;
case '{': // while loop
sub_start=let;
++nest;
condition=topple_data::held_data[arr_len(topple_data::held_data)-1];
topple_data::held_data[arr_len(topple_data::held_data)-1]='\0';
for(int space=let+1; space<size && space<end && nest; space++){
++let;
if(code[space]=='<')++nest;
else if(code[space]=='>')--nest;
sub_end=space;
}
while(topple_data::variables[var_loc(topple_data::variables,condition)].val!='0')process_code(code,size,sub_start+1,sub_end);
break;
// variable management
case '=': // (re)defines variables
if(var_loc(topple_data::variables,code[let-1])==-1){
topple_data::variables[var_amnt(topple_data::variables)].val=code[let+1];
topple_data::variables[var_amnt(topple_data::variables)].name=code[let-1];
}else{
topple_data::variables[var_loc(topple_data::variables,code[let-1])].val=code[let+1];
}
break;
case '^': // increments/decrements variables
if(code[let+1]=='+') topple_data::variables[var_loc(topple_data::variables,code[let-1])].val++;
else if(code[let+1]=='-') topple_data::variables[var_loc(topple_data::variables,code[let-1])].val--;
break;
// index-dependent commands
case ':':
std::cout<<topple_data::held_data[code[let-1]-'0'];
break;
case ';':
topple_data::held_data[arr_len(topple_data::held_data)]=topple_data::held_data[code[let-1]-'0'];
break;
// other
case '~': // deletes admitted values
for(int i=0; i<arr_len(topple_data::held_data); i++) topple_data::held_data[i]='\0';
case '|': // clears the console
CLEAR();
break;
case '*': // exits the program
exit(topple_data::held_data[arr_len(topple_data::held_data)-1]);
break;
}
}
}
int main(){
FILE* file = fopen("main.topp","r");
int size = file_size("main.topp");
char code[size];
read_file(file,code);
process_code(code,size,0,arr_len(code));
fclose(file);
return 0;
}