Jedi Master
Jedi Master
Posts: 336
Joined: Sun Aug 09, 2009 9:16 am
Allegiance:: Jedi
User avatar
Jedi Master
Jedi Master
Re: C++ GUI Frameworks

Post by Matthew »

I don't know much about the Windows APIs. I've never used them. They can do anything you want for Windows though.

Pointers are necessary in many cases. You may need them regardless. Especially in C. C++ uses more OOP with abstraction over pointers.
Administrator
Administrator
Posts: 3307
Joined: Thu Dec 24, 2009 2:06 am
Allegiance:: Space Rome
Location: ON, Canada
User avatar
Administrator
Administrator
Re: C++ GUI Frameworks

Post by Scott »

Matthew wrote:I don't know much about the Windows APIs. I've never used them. They can do anything you want for Windows though.
Going from the little source I've looked over it is very scary (even simple tasks such as opening a windows) although of course complicated code can often mean flexibility.
Matthew wrote:Pointers are necessary in many cases. You may need them regardless. Especially in C. C++ uses more OOP with abstraction over pointers.
I'm sure they are but in my travels I have yet to need them.

I seem to have run into another problem that I wouldn't mind if you looked over:

Code: Select all

#include <iostream>
#include <time.h>   //Both of these are needed for Code::Blocks to use rand
#include <stdlib.h> //Both of these are needed for Code::Blocks to use rand
#include <windows.h>

//ADD TWO PLAYER WHERE THEY HAVE TO TRAP EACH OTHER - ONE CREATES TRAPS, OTHER ATTEMPTS TO ATTACK THE OTHER PLAYER
//ADD TRAPS AS AN ARRAY (MULTI-DIMENSIONAL) WITH RANDOM GRID LOCATOR - EASIER TO CREATE MULTIPLE TRAPS ESPECIALLY FOR TWO PLAYER *DONE*

#define HEIGHT 8
#define WIDTH 12
#define TRAPS 5 //How many traps? The more traps the longer it takes to load
#define ENEMIES 3    //How many enemies? The more enemies the longer it takes to load

char GameBoard[HEIGHT][WIDTH]; //GameBoard

int i, j; //Global Counters

int action, enemyMove;
bool quit = false;
int posy = 0, posx = 0; //Player pOSition - X-grid/Y-grid
int tosy = (HEIGHT-1), tosx = (WIDTH-1); //Treasure pOSition
int TrapLocations[TRAPS][2]; //Trap location array
int EnemyLocations[ENEMIES][2]; //Enemy location array

char player = 'G'; //The Player Character
char board = '.'; //Blank Board
char trap = 'T'; //Trap symbol
char treasure = 'X'; //Treasure symbol
char enemy = 'E'; //Enemy character

using namespace std;

void BlankBoard(char GameBoard[HEIGHT][WIDTH]); //Used once to create a blank board
void PrintBoard(char GameBoard[HEIGHT][WIDTH]); //Prints out the current board
void ActionLoop(char GameBoard[HEIGHT][WIDTH]); //Handles all events around a user's turn
void EnemyMove(char GameBoard[HEIGHT][WIDTH]); //Handles enemy moves
bool AmIDead(char GameBoard[HEIGHT][WIDTH]); //Checks to see if player is dead

int main()
{
    cout << "Please wait while the game loads...";

    for (i = 0; i < TRAPS; i++)
    {
        srand( (unsigned)time(0) );
        TrapLocations[i][0] = (rand() % (HEIGHT) + 1);
        TrapLocations[i][1] = (rand() % (WIDTH) + 1);
        Sleep(125); //Because seed is based on time this increases the randomness although decreases portability because
                    //of the need of <windows.h>
    }

    for (i = 0; i < ENEMIES; i++)
    {
        srand( (unsigned)time(0) );
        EnemyLocations[i][0] = (rand() % (HEIGHT) + 1);
        EnemyLocations[i][1] = (rand() % (WIDTH) + 1);
        Sleep(125); //Because seed is based on time this increases the randomness although decreases portability because
                    //of the need of <windows.h>
    }

    cout << string(100, '\n');
    cout << "Welcome to Dungeon Crawl!\n";
    cout << "Use the arrows on the number pad followed by enter to move\nNOTE: Make sure NUM LOCK is on!\n";
    cout << "To begin press ENTER\n> ";
    cin.get();

    BlankBoard(GameBoard);
    GameBoard[posy][posx] = player; //Creates the player on the board
    GameBoard[tosy][tosx] = treasure; //Creates the treasure
    for (i = 0; i < TRAPS; i++) //Creating traps
    {
        while (GameBoard[TrapLocations[i][0]][TrapLocations[i][1]] != board)
        {
            TrapLocations[i][0] = (rand() % (HEIGHT) + 1);
            TrapLocations[i][1] = (rand() % (WIDTH) + 1);
        }
        GameBoard[TrapLocations[i][0]][TrapLocations[i][1]] = trap;
    }
    for (i = 0; i < ENEMIES; i++) //Creating enemies
    {
        while (GameBoard[EnemyLocations[i][0]][EnemyLocations[i][1]] != board)
        {
            EnemyLocations[i][0] = (rand() % (HEIGHT) + 1);
            EnemyLocations[i][1] = (rand() % (WIDTH) + 1);
        }
        GameBoard[EnemyLocations[i][0]][EnemyLocations[i][1]] = enemy;
    }

    while (quit == false)
    {
        cout << string(100, '\n');
        if (! AmIDead(GameBoard)) //if it returns false //'!' = NOT so replace AmIDead(GameBoard) with the return value
        ActionLoop(GameBoard);
        AmIDead(GameBoard);
    }

    cout << "\n\nPress ENTER to exit\n";
    cin.get();
    cin.get();
    return 0;
}

void BlankBoard(char GameBoard[HEIGHT][WIDTH])
{
    for (i = 0; i < HEIGHT; i++)
    {
        for (j = 0; j < WIDTH; j++)
        {
            GameBoard[i][j] = board;
        }
    }
}

void PrintBoard(char GameBoard[HEIGHT][WIDTH])
{
    for (i = 0; i < HEIGHT; i++)
    {
        for (j = 0; j < WIDTH; j++)
        {
            cout << GameBoard[i][j];
        }
        cout << endl;
    }
}

void ActionLoop(char GameBoard[HEIGHT][WIDTH])
{
    PrintBoard(GameBoard);
    cout << "\n> ";
    cin >> action;
    while (action != 2 && action != 4 && action != 6 && action != 8)
    {
        cout << "Please only use 2, 4, 6, and 8 on your number pad as arrows.\n";
        cout << "Once you choose a number press ENTER to confirm\n> ";
        cin >> action;
    }

    switch (action)
    {
        case 2:
        if (posy == (HEIGHT-1))
        break;
        else
        {
            GameBoard[posy][posx] = board;
            posy += 1;
            GameBoard[posy][posx] = player;
            break;
        }

        case 4:
        if (posx == 0)
        break;
        else
        {
            GameBoard[posy][posx] = board;
            posx -= 1;
            GameBoard[posy][posx] = player;
            break;
        }

        case 6:
        if (posx == (WIDTH-1))
        break;
        else
        {
            GameBoard[posy][posx] = board;
            posx += 1;
            GameBoard[posy][posx] = player;
            break;
        }

        case 8:
        if (posy == 0)
        break;
        else
        {
            GameBoard[posy][posx] = board;
            posy -= 1;
            GameBoard[posy][posx] = player;
            break;
        }
    }
    if (posy == tosy && posx == tosx)
    {
        cout << "You win!\n";
        quit = true;
    }
    EnemyMove(GameBoard); //Enemies move
}

void EnemyMove(char GameBoard[HEIGHT][WIDTH])
{
    srand ( (unsigned)time(0) );

    for (i = 0; i < ENEMIES; i++)
    {
        enemyMove = (rand() % 4 + 1);

        switch (enemyMove)
        {
            case 1:
            if (GameBoard[EnemyLocations[i][0]-1][EnemyLocations[i][1]] == board || GameBoard[EnemyLocations[i][0]-1][EnemyLocations[i][1]] == player)
            {
                GameBoard[EnemyLocations[i][0]][EnemyLocations[i][1]] = board;
                GameBoard[--EnemyLocations[i][0]][EnemyLocations[i][1]] = enemy;
            }
            break;

            case 2:
            if (GameBoard[EnemyLocations[i][0]][EnemyLocations[i][1]+1] == board || GameBoard[EnemyLocations[i][0]][EnemyLocations[i][1]+1] == player)
            {
                GameBoard[EnemyLocations[i][0]][EnemyLocations[i][1]] = board;
                GameBoard[EnemyLocations[i][0]][++EnemyLocations[i][1]] = enemy;
            }
            break;

            case 3:
            if (GameBoard[EnemyLocations[i][0]+1][EnemyLocations[i][1]] || GameBoard[EnemyLocations[i][0]+1][EnemyLocations[i][1]] == player)
            {
                GameBoard[EnemyLocations[i][0]][EnemyLocations[i][1]] = board;
                GameBoard[++EnemyLocations[i][0]][EnemyLocations[i][1]] = enemy;
            }
            break;

            case 4:
            if (GameBoard[EnemyLocations[i][0]][EnemyLocations[i][1]-1] == board || GameBoard[EnemyLocations[i][0]][EnemyLocations[i][1]-1] == player)
            {
                GameBoard[EnemyLocations[i][0]][EnemyLocations[i][1]] = board;
                GameBoard[EnemyLocations[i][0]][--EnemyLocations[i][1]] = enemy;
            }
            break;
        }
    }
}

bool AmIDead(char GameBoard[HEIGHT][WIDTH])
{
    for (i = 0; i < TRAPS; i++)
    {
        if (GameBoard[TrapLocations[i][0]][TrapLocations[i][1]] == player)
        {
            cout << "You lose...\n";
            quit = true;
            return true;
        }
    }
    for (i = 0; i < ENEMIES; i++)
    {
        if (GameBoard[EnemyLocations[i][0]][EnemyLocations[i][1]] == player)
        {
            cout << "You lose...\n";
            quit = true;
            return true;
        }
    }
    return false;
}
It was giving me lots of trouble but luckily I could iron out most of the bugs and whatnot but collision checking (although much simpler - seeing if you are dead or not) is not working very well. If you see a discrepancy let me know. Sorry for the poor Mac compatibility again :8(:

Just a neat link I wanted to share...Apparently, and I italicize because I'm not 100%, but apparently this equation was part of the Team Fortress 2 lighting system/engine/whatever you want to call it.
Image
Jedi Master
Jedi Master
Posts: 336
Joined: Sun Aug 09, 2009 9:16 am
Allegiance:: Jedi
User avatar
Jedi Master
Jedi Master
Re: C++ GUI Frameworks

Post by Matthew »

No idea what that series is supposed to be...?

You don't need Sleep at all. Remove it. rand() will give you the same random number based upon the seed, per call, regardless of the time.

Are the enemies supposed to eat the traps or something? Can you explain how the game works in a bit more detail?

Edit: :o You still have multiple srand()s
Administrator
Administrator
Posts: 3307
Joined: Thu Dec 24, 2009 2:06 am
Allegiance:: Space Rome
Location: ON, Canada
User avatar
Administrator
Administrator
Re: C++ GUI Frameworks

Post by Scott »

Matthew wrote:No idea what that series is supposed to be...?
You mean the equation...?
Matthew wrote:You don't need Sleep at all. Remove it. rand() will give you the same random number based upon the seed, per call, regardless of the time.
But if srand uses time, then wouldn't the Sleep change the seed? If not then I will take out the srands() (which I forgot were still there) and the Sleep.
Matthew wrote:Are the enemies supposed to eat the traps or something? Can you explain how the game works in a bit more detail?
Actually I've managed to complete it and fix all errors.

Code: Select all

#include <iostream>
#include <time.h>   //Both of these are needed for Code::Blocks to use rand
#include <stdlib.h> //Both of these are needed for Code::Blocks to use rand
#include <windows.h>

//ADD TWO PLAYER WHERE THEY HAVE TO TRAP EACH OTHER - ONE CREATES TRAPS, OTHER ATTEMPTS TO ATTACK THE OTHER PLAYER
//ADD TRAPS AS AN ARRAY (MULTI-DIMENSIONAL) WITH RANDOM GRID LOCATOR - EASIER TO CREATE MULTIPLE TRAPS ESPECIALLY FOR TWO PLAYER *DONE*

#define HEIGHT 10
#define WIDTH 12
#define TRAPS 8 //How many traps? The more traps the longer it takes to load
#define ENEMIES 12 //How many enemies? The more enemies the longer it takes to load

char GameBoard[HEIGHT][WIDTH]; //GameBoard

int i, j; //Global Counters

int action, enemyMove;
bool quit = false;
int posy = 0, posx = 0; //Player pOSition - X-grid/Y-grid
int tosy = (HEIGHT-1), tosx = (WIDTH-1); //Treasure pOSition
int TrapLocations[TRAPS][2]; //Trap location array
int EnemyLocations[ENEMIES][2]; //Enemy location array

char player = 'G'; //The Player Character
char board = '.'; //Blank Board
char trap = 'T'; //Trap symbol
char treasure = 'X'; //Treasure symbol
char enemy = 'E'; //Enemy character

using namespace std;

void BlankBoard(char GameBoard[HEIGHT][WIDTH]); //Used once to create a blank board
void PrintBoard(char GameBoard[HEIGHT][WIDTH]); //Prints out the current board
void ActionLoop(char GameBoard[HEIGHT][WIDTH]); //Handles all events around a user's turn
void EnemyMove(char GameBoard[HEIGHT][WIDTH]); //Handles enemy moves
bool AmIDead(char GameBoard[HEIGHT][WIDTH]); //Checks to see if player is dead

int main()
{
    cout << "Please wait while the game loads...";

    for (i = 0; i < TRAPS; i++)
    {
        srand( (unsigned)time(0) );
        TrapLocations[i][0] = (rand() % (HEIGHT) + 1);
        TrapLocations[i][1] = (rand() % (WIDTH) + 1);
        Sleep(125); //Because seed is based on time this increases the randomness although decreases portability because
                    //of the need of <windows.h>
    }

    for (i = 0; i < ENEMIES; i++)
    {
        srand( (unsigned)time(0) );
        EnemyLocations[i][0] = (rand() % (HEIGHT) + 1);
        EnemyLocations[i][1] = (rand() % (WIDTH) + 1);
        Sleep(125); //Because seed is based on time this increases the randomness although decreases portability because
                    //of the need of <windows.h>
    }

    cout << string(100, '\n');
    cout << "Welcome to Dungeon Crawl!\n";
    cout << "Use the arrows on the number pad followed by enter to move\nNOTE: Make sure NUM LOCK is on!\n";
    cout << "To begin press ENTER\n> ";
    cin.get();

    BlankBoard(GameBoard);
    GameBoard[posy][posx] = player; //Creates the player on the board
    GameBoard[tosy][tosx] = treasure; //Creates the treasure
    for (i = 0; i < TRAPS; i++) //Creating traps
    {
        while (GameBoard[TrapLocations[i][0]][TrapLocations[i][1]] != board)
        {
            TrapLocations[i][0] = (rand() % (HEIGHT) + 1);
            TrapLocations[i][1] = (rand() % (WIDTH) + 1);
        }
        GameBoard[TrapLocations[i][0]][TrapLocations[i][1]] = trap;
    }
    for (i = 0; i < ENEMIES; i++) //Creating enemies
    {
        while (GameBoard[EnemyLocations[i][0]][EnemyLocations[i][1]] != board)
        {
            EnemyLocations[i][0] = (rand() % (HEIGHT) + 1);
            EnemyLocations[i][1] = (rand() % (WIDTH) + 1);
        }
        GameBoard[EnemyLocations[i][0]][EnemyLocations[i][1]] = enemy;
    }

    while (quit == false)
    {
        cout << string(20, '\n');
        ActionLoop(GameBoard); //Prints board, goes through steps with user, and goes through enemy moves
    }

    cout << "\nPress ENTER to exit\n";
    cin.get();
    cin.get();
    return 0;
}

void BlankBoard(char GameBoard[HEIGHT][WIDTH])
{
    for (i = 0; i < HEIGHT; i++)
    {
        for (j = 0; j < WIDTH; j++)
        {
            GameBoard[i][j] = board;
        }
    }
}

void PrintBoard(char GameBoard[HEIGHT][WIDTH])
{
    for (i = 0; i < HEIGHT; i++)
    {
        for (j = 0; j < WIDTH; j++)
        {
            cout << GameBoard[i][j];
        }
        cout << endl;
    }
}

void ActionLoop(char GameBoard[HEIGHT][WIDTH])
{
    PrintBoard(GameBoard);
    if (! AmIDead(GameBoard))
    {
        cout << "\n> ";
        cin >> action;
        while (action != 2 && action != 4 && action != 6 && action != 8)
        {
            cout << "Please only use 2, 4, 6, and 8 on your number pad as arrows.\n";
            cout << "Once you choose a number press ENTER to confirm\n> ";
            cin >> action;
        }

        switch (action)
        {
            case 2:
            if (posy == (HEIGHT-1))
            break;
            else
            {
                GameBoard[posy][posx] = board;
                posy += 1;
                GameBoard[posy][posx] = player;
                break;
            }

            case 4:
            if (posx == 0)
            break;
            else
            {
                GameBoard[posy][posx] = board;
                posx -= 1;
                GameBoard[posy][posx] = player;
                break;
            }

            case 6:
            if (posx == (WIDTH-1))
            break;
            else
            {
                GameBoard[posy][posx] = board;
                posx += 1;
                GameBoard[posy][posx] = player;
                break;
            }

            case 8:
            if (posy == 0)
            break;
            else
            {
                GameBoard[posy][posx] = board;
                posy -= 1;
                GameBoard[posy][posx] = player;
                break;
            }
        }
        if (posy == tosy && posx == tosx)
        {
            cout << "\nYou win!\a\a\n";
            quit = true;
        }
        EnemyMove(GameBoard); //Enemies move
    }
}

void EnemyMove(char GameBoard[HEIGHT][WIDTH])
{
    srand ( (unsigned)time(0) );

    for (i = 0; i < ENEMIES; i++)
    {
        enemyMove = (rand() % 4 + 1);

        switch (enemyMove)
        {
            case 1:
            if (GameBoard[EnemyLocations[i][0]-1][EnemyLocations[i][1]] == board || GameBoard[EnemyLocations[i][0]-1][EnemyLocations[i][1]] == player)
            {
                GameBoard[EnemyLocations[i][0]][EnemyLocations[i][1]] = board;
                GameBoard[--EnemyLocations[i][0]][EnemyLocations[i][1]] = enemy;
                break;
            }
            else
            break;

            case 2:
            if ((GameBoard[EnemyLocations[i][0]][EnemyLocations[i][1]+1] == board || GameBoard[EnemyLocations[i][0]][EnemyLocations[i][1]+1] == player) && EnemyLocations[i][1]+1 < WIDTH)
            {
                GameBoard[EnemyLocations[i][0]][EnemyLocations[i][1]] = board;
                GameBoard[EnemyLocations[i][0]][++EnemyLocations[i][1]] = enemy;
                break;
            }
            else
            break;

            case 3:
            if ((GameBoard[EnemyLocations[i][0]+1][EnemyLocations[i][1]] == board || GameBoard[EnemyLocations[i][0]+1][EnemyLocations[i][1]] == player) && EnemyLocations[i][0]+1 < HEIGHT)
            {
                GameBoard[EnemyLocations[i][0]][EnemyLocations[i][1]] = board;
                GameBoard[++EnemyLocations[i][0]][EnemyLocations[i][1]] = enemy;
                break;
            }
            else
            break;

            case 4:
            if ((GameBoard[EnemyLocations[i][0]][EnemyLocations[i][1]-1] == board || GameBoard[EnemyLocations[i][0]][EnemyLocations[i][1]-1] == player) && EnemyLocations[i][1]-1 > -1)
            {
                GameBoard[EnemyLocations[i][0]][EnemyLocations[i][1]] = board;
                GameBoard[EnemyLocations[i][0]][--EnemyLocations[i][1]] = enemy;
                break;
            }
            else
            break;
        }
    }
}

bool AmIDead(char GameBoard[HEIGHT][WIDTH])
{
    for (i = 0; i < TRAPS; i++)
    {
        if (GameBoard[TrapLocations[i][0]][TrapLocations[i][1]] == player)
        {
            cout << "\nYou lose...\a\n";
            quit = true;
            return true;
        }
    }
    for (i = 0; i < ENEMIES; i++)
    {
        if (EnemyLocations[i][0] == posy && EnemyLocations[i][1] == posx)
        {
            cout << "\nYou lose...\a\n";
            quit = true;
            return true;
        }
    }
    return false;
}
Yes, the srands are still there. I will take them upon confirmation.
Image
Jedi Master
Jedi Master
Posts: 336
Joined: Sun Aug 09, 2009 9:16 am
Allegiance:: Jedi
User avatar
Jedi Master
Jedi Master
Re: C++ GUI Frameworks

Post by Matthew »

It's a series and not an equation, no?

The seed never changes. It's a constant. Here's how a pseudo-random number generator works:

You give the generator a seed number.
The generator makes a new number which is completely chaotic from the last number.
The last step repeats.
Administrator
Administrator
Posts: 3307
Joined: Thu Dec 24, 2009 2:06 am
Allegiance:: Space Rome
Location: ON, Canada
User avatar
Administrator
Administrator
Re: C++ GUI Frameworks

Post by Scott »

Matthew wrote:It's a series and not an equation, no?
Oh ya, I guess it is :?:
Matthew wrote:The seed never changes. It's a constant. Here's how a pseudo-random number generator works:

You give the generator a seed number.
The generator makes a new number which is completely chaotic from the last number.
The last step repeats.
I took out the extra srands and still works. Thanks for the clarification.
Image
Jedi Master
Jedi Master
Posts: 336
Joined: Sun Aug 09, 2009 9:16 am
Allegiance:: Jedi
User avatar
Jedi Master
Jedi Master
Re: C++/C programming discussion

Post by Matthew »

I thought the topic needed a change of title.

At the moment I'm making a Python to C converter. I've replicated the functionality of Python operators in C as well as variables (Limited to integers, floating-point numbers,booleans, the None value and strings at the moment). Next I need to create a Python expression to C expression converter which will use my C implementations of Python operators.

Here is the C library being used, so far:

Code: Select all

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <stdint.h>
#include <math.h>

typedef enum {
	INT = 0,
	FLOAT = 1,
	STRING = 2,
	NONE = 3,
	BOOL = 4
} TYPE;

typedef struct {
	TYPE type;
	void * data;
} Variable;

typedef Variable ** var; //Convenience typedef for pointer to variable pointer

typedef struct {
	size_t size;
	Variable *** pool; //Pointer to the array of pointers to the Variable structure pointers. Pointer required for memory allocation and array consists of pointers to pointers so the pointers to the Variable structures can be changed throughtout different functions.
} VarPool; //Variable pools will just be used to deallocate all variables at the end of a scope

VarPool * global_pool; //Pool for global scope
VarPool ** temp_pool_stack; //Keeps track of pools for temporary variables in expressions
unsigned int pool_stack_size;
VarPool ** pool_stack; //Keeps track of pools in stack
unsigned int pool_stack_size;

char ** string_pool; //Hold strings needing deletion
unsigned int string_pool_size;

void init_pool_stack(){
	pool_stack = malloc(sizeof(VarPool *)); //Start with global_pool
	pool_stack_size = 1;
	global_pool = malloc(sizeof(VarPool));
	pool_stack[0] = global_pool;
	global_pool->pool = NULL;
	global_pool->size = 0;
	//Temp pool stack
	temp_pool_stack = malloc(sizeof(VarPool *));
	temp_pool_stack[0] = malloc(sizeof(VarPool));
	temp_pool_stack[0]->pool = NULL;
	temp_pool_stack[0]->size = 0;
	//Assign NULL pointer to string pool
	string_pool = NULL;
	string_pool_size = 0;
}

void make_pool(){
	VarPool * var_pool = malloc(sizeof(VarPool));
	pool_stack_size++;
	pool_stack = realloc(pool_stack, pool_stack_size*sizeof(VarPool *));
	pool_stack[pool_stack_size-1] = var_pool;
	var_pool->pool = NULL;
	var_pool->size = 0;
	//Temporary variable pool
	var_pool = malloc(sizeof(VarPool));
	temp_pool_stack = realloc(temp_pool_stack, pool_stack_size*sizeof(VarPool *));
	temp_pool_stack[pool_stack_size-1] = var_pool;
	var_pool->pool = NULL;
	var_pool->size = 0;
}

Variable ** new_var(){ //Makes new variable
	Variable ** return_variable = malloc(sizeof(Variable *));
	Variable * new_variable = malloc(sizeof(Variable));
	new_variable->data = NULL;
	VarPool * var_pool = pool_stack[pool_stack_size-1]; //Current variable pool on top of stack
	var_pool->size++;
	var_pool->pool = realloc(var_pool->pool,var_pool->size*sizeof(Variable **));
	*return_variable = new_variable;
	var_pool->pool[var_pool->size - 1] = return_variable;
	return return_variable; //Return pointer to new pointer so pointer can be changed to NULL when deleted
}

Variable ** assign_int(Variable ** variable,int64_t integer){
	Variable * var_ptr = *variable;
	free(var_ptr->data); //Free previous data
	int64_t * data = malloc(sizeof(int64_t));
	*data = integer;
	var_ptr->data = data;
	var_ptr->type = INT;
	return variable;
}

Variable ** assign_float(Variable ** variable,double number){
	Variable * var_ptr = *variable;
	free(var_ptr->data); //Free previous data
	double * data = malloc(sizeof(double));
	*data = number;
	var_ptr->data = data;
	var_ptr->type = FLOAT;
	return variable;
}

Variable ** assign_string(Variable ** variable,char * string){
	Variable * var_ptr = *variable;
	free(var_ptr->data); //Free previous data
	var_ptr->data = malloc(strlen(string)*sizeof(char));
	strcpy(var_ptr->data,string);
	var_ptr->type = STRING;
	return variable;
}

Variable ** assign_none(Variable ** variable){
	Variable * var_ptr = *variable;
	free(var_ptr->data); //Free previous data
	var_ptr->data = NULL;
	var_ptr->type = NONE;
	return variable;
}

Variable ** assign_bool(Variable ** variable,bool boolean){
	Variable * var_ptr = *variable;
	free(var_ptr->data); //Free previous data
	bool * data = malloc(sizeof(bool));
	*data = boolean;
	var_ptr->data = data;
	var_ptr->type = BOOL;
	return variable;
}

Variable ** new_temp_var(){
	Variable ** return_variable = malloc(sizeof(Variable *));
	Variable * new_variable = malloc(sizeof(Variable));
	new_variable->data = NULL;
	VarPool * var_pool = temp_pool_stack[pool_stack_size-1]; //Current temporary variable pool on top of stack
	var_pool->size++;
	var_pool->pool = realloc(var_pool->pool,var_pool->size*sizeof(Variable **));
	*return_variable = new_variable;
	var_pool->pool[var_pool->size - 1] = return_variable;
	return return_variable; //Return pointer to new pointer so pointer can be changed to NULL when deleted
}

Variable ** temp_int(int64_t integer){
	Variable ** new_variable = new_temp_var();
	Variable * var_ptr = *new_variable;
	int64_t * data = malloc(sizeof(int64_t));
	*data = integer;
	var_ptr->data = data;
	var_ptr->type = INT;
	return new_variable;
}

Variable ** temp_float(double number){
	Variable ** new_variable = new_temp_var();
	Variable * var_ptr = *new_variable;
	double * data = malloc(sizeof(double));
	*data = number;
	var_ptr->data = data;
	var_ptr->type = FLOAT;
	return new_variable;
}

Variable ** temp_string(char * string){
	Variable ** new_variable = new_temp_var();
	Variable * var_ptr = *new_variable;
	var_ptr->data = malloc(strlen(string)*sizeof(char));
	strcpy(var_ptr->data,string);
	var_ptr->type = STRING;
	return new_variable;
}

Variable ** temp_none(){
	Variable ** new_variable = new_temp_var();
	Variable * var_ptr = *new_variable;
	var_ptr->data = NULL;
	var_ptr->type = NONE;
	return new_variable;
}

Variable ** temp_bool(bool boolean){
	Variable ** new_variable = new_temp_var();
	Variable * var_ptr = *new_variable;
	bool * data = malloc(sizeof(bool));
	*data = boolean;
	var_ptr->data = data;
	var_ptr->type = BOOL;
	return new_variable;
}

void empty_temporary_pool(){
	VarPool * var_pool = temp_pool_stack[pool_stack_size-1]; //Current variable pool on top of stack
	for (int x = 0; x < var_pool->size; x++) {
		if(*var_pool->pool[x] != NULL){
			free((*var_pool->pool[x])->data);//Free variable data
			free(*var_pool->pool[x]); //Free variable
		}
		free(var_pool->pool[x]); //Free variable pointer
	}
	var_pool->size = 0;
}

//Return c values from variables. Empty temporary pool when done to clear expression data

bool bool_val(Variable ** var_ptr){
	Variable * variable = *var_ptr;
	bool ans;
	switch (variable->type) {
		case INT:
			ans = *(int64_t *)(variable->data) != 0;
			break;
		case FLOAT:
			ans = *(double *)(variable->data) != 0;
			break;
		case STRING:
			ans = strlen(variable->data) != 0;
			break;
		case NONE:
			ans = false;
			break;
		case BOOL:
			ans = *(bool *)(variable->data);
			break;
	}
	empty_temporary_pool();
	return ans;
}

Variable ** to_int(Variable ** var_ptr){
	Variable * variable = *var_ptr;
	switch (variable->type) {
		case INT:
			return var_ptr;
			break;
		case FLOAT:
			return temp_int((int64_t)*(double *)(variable->data) != 0);
			break;
		case STRING:
			return temp_int(strtol(variable->data,NULL,10));
			break;
		case BOOL:
			return temp_int((int64_t)*(bool *)(variable->data));
			break;
	}
	return temp_int(0);
}

int64_t int_val(Variable ** var_ptr){
	Variable * variable = *var_ptr;
	int64_t ans;
	switch (variable->type) {
		case INT:
			ans = *(int64_t *)(variable->data);
			break;
		case FLOAT:
			ans = (int64_t)*(double *)(variable->data);
			break;
		case STRING:
			ans = strtol(variable->data,NULL,10);
			break;
		case NONE:
			ans = false;
			break;
		case BOOL:
			ans = (int64_t)*(bool *)(variable->data);
			break;
	}
	empty_temporary_pool();
	return ans;
}

char * string_val(Variable ** var_ptr){
	Variable * variable = *var_ptr;
	char * ans;
	long long int integer;
	double number;
	switch (variable->type) {
		case INT:
			integer = *(int64_t *)(variable->data);
			ans = malloc(sizeof(char) * (int)(log10(integer)) + 1);
			sprintf(ans,"%lli",integer );
			break;
		case FLOAT:
			number = *(double *)(variable->data);
			ans = malloc(sizeof(char) * (int)(log10(number)) + 1);
			sprintf(ans,"%f",number);
			break;
		case STRING:
			ans = malloc(sizeof(char) * strlen(variable->data));
			strcpy(ans,variable->data);
			break;
		case NONE:
			ans = malloc(sizeof(char) * 5);
			ans = "None";
			break;
		case BOOL:
			if (*(bool *)(variable->data)) {
				ans = malloc(sizeof(char) * 5);
				ans = "True";
			}else {
				ans = malloc(sizeof(char) * 6);
				ans = "False";
			}

			break;
	}
	empty_temporary_pool();
	//Add string to string pool
	string_pool_size++;
	string_pool = realloc(string_pool, sizeof(char *)*string_pool_size);
	string_pool[string_pool_size - 1] = ans;
	return ans;
}

//Arithmetic

Variable ** add(Variable ** var1_ptr, Variable ** var2_ptr){
	Variable * var1 = *var1_ptr;
	Variable * var2 = *var2_ptr;
	switch (var1->type) {
		case INT:
			switch (var2->type) {
				case INT:
					return temp_int(*(int64_t *)(var1->data) * *(int64_t *)(var2->data));
					break;
				case FLOAT:
					return temp_float(*(int64_t *)(var1->data) * *(double *)(var2->data));
					break;
				case BOOL:
					return temp_int(*(int64_t *)(var1->data) * *(bool *)(var2->data));
					break;
			}
			break;
		case STRING:
			if (var2->type == STRING) {
				char * new_string = malloc(sizeof(char) * (strlen(var1->data) + strlen(var2->data)));
				strcpy(new_string,var1->data);
				strcat(new_string,var2->data);
				Variable ** return_val =  temp_string(new_string);
				free(new_string);
				return return_val;
			}
			break;
		case FLOAT:
			switch (var2->type) {
				case INT:
					return temp_float(*(double *)(var1->data) * *(int64_t *)(var2->data));
					break;
				case FLOAT:
					return temp_float(*(double *)(var1->data) * *(double *)(var2->data));
					break;
				case BOOL:
					return temp_float(*(double *)(var1->data) * *(bool *)(var2->data));
					break;
			}
			break;
		case BOOL:
			switch (var2->type) {
				case INT:
					return temp_int(*(bool *)(var1->data) * *(int64_t *)(var2->data));
					break;
				case FLOAT:
					return temp_float(*(bool *)(var1->data) * *(double *)(var2->data));
					break;
				case BOOL:
					return temp_int(*(bool *)(var1->data) * *(bool *)(var2->data));
					break;
			}
			break;
	}
	return temp_bool(false);
}

Variable ** subtract(Variable ** var1_ptr, Variable ** var2_ptr){
	Variable * var1 = *var1_ptr;
	Variable * var2 = *var2_ptr;
	switch (var1->type) {
		case INT:
			switch (var2->type) {
				case INT:
					return temp_int(*(int64_t *)(var1->data) - *(int64_t *)(var2->data));
					break;
				case FLOAT:
					return temp_float(*(int64_t *)(var1->data) - *(double *)(var2->data));
					break;
				case BOOL:
					return temp_int(*(int64_t *)(var1->data) - *(bool *)(var2->data));
					break;
			}
			break;
		case FLOAT:
			switch (var2->type) {
				case INT:
					return temp_float(*(double *)(var1->data) - *(int64_t *)(var2->data));
					break;
				case FLOAT:
					return temp_float(*(double *)(var1->data) - *(double *)(var2->data));
					break;
				case BOOL:
					return temp_float(*(double *)(var1->data) - *(bool *)(var2->data));
					break;
			}
			break;
		case BOOL:
			switch (var2->type) {
				case INT:
					return temp_int(*(bool *)(var1->data) - *(int64_t *)(var2->data));
					break;
				case FLOAT:
					return temp_float(*(bool *)(var1->data) - *(double *)(var2->data));
					break;
				case BOOL:
					return temp_int(*(bool *)(var1->data) - *(bool *)(var2->data));
					break;
			}
			break;
	}
	return temp_bool(false);
}

Variable ** multiply(Variable ** var1_ptr, Variable ** var2_ptr){
	Variable * var1 = *var1_ptr;
	Variable * var2 = *var2_ptr;
	long long int integer;
	switch (var1->type) {
		case INT:
			switch (var2->type) {
				case INT:
					return temp_int(*(int64_t *)(var1->data) * *(int64_t *)(var2->data));
					break;
				case FLOAT:
					return temp_float(*(int64_t *)(var1->data) * *(double *)(var2->data));
					break;
				case STRING:
					integer = (long long int)*(int64_t *)(var1->data);
					if (integer) {
						char * new_string = malloc(sizeof(char) * strlen(var2->data) * integer);
						strcpy(new_string,var2->data);
						for (int x = 1; x < integer; x++) {
							strcat(new_string,var2->data);
						}
						Variable ** return_val =  temp_string(new_string);
						free(new_string);
						return return_val;
					}else{
						return temp_string("");
					}
					break;
				case BOOL:
					return temp_int(*(int64_t *)(var1->data) * *(bool *)(var2->data));
					break;
			}
			break;
		case STRING:
			if (var2->type == INT) {
				integer = (long long int)*(int64_t *)(var2->data);
				if (integer) {
					char * new_string = malloc(sizeof(char) * strlen(var1->data) * integer);
					strcpy(new_string,var1->data);
					for (int x = 1; x < integer; x++) {
						strcat(new_string,var1->data);
					}
					Variable ** return_val =  temp_string(new_string);
					free(new_string);
					return return_val;
				}else{
					return temp_string("");
				}
			}else if (var2->type == BOOL) {
				if (*(bool *)(var2->data)) {
					return var1_ptr;
				}else{
					return temp_string("");
				}
			}
			break;
		case FLOAT:
			switch (var2->type) {
				case INT:
					return temp_float(*(double *)(var1->data) * *(int64_t *)(var2->data));
					break;
				case FLOAT:
					return temp_float(*(double *)(var1->data) * *(double *)(var2->data));
					break;
				case BOOL:
					return temp_float(*(double *)(var1->data) * *(bool *)(var2->data));
					break;
			}
			break;
		case BOOL:
			switch (var2->type) {
				case INT:
					return temp_int(*(bool *)(var1->data) * *(int64_t *)(var2->data));
					break;
				case FLOAT:
					return temp_float(*(bool *)(var1->data) * *(double *)(var2->data));
					break;
				case STRING:
					if (*(bool *)(var1->data)) {
						return var2_ptr;
					}else{
						return temp_string("");
					}
					break;
				case BOOL:
					return temp_int(*(bool *)(var1->data) * *(bool *)(var2->data));
					break;
			}
			break;
	}
	return temp_bool(false);
}

Variable ** divide(Variable ** var1_ptr, Variable ** var2_ptr){
	Variable * var1 = *var1_ptr;
	Variable * var2 = *var2_ptr;
	switch (var1->type) {
		case INT:
			switch (var2->type) {
				case INT:
					return temp_int(*(int64_t *)(var1->data) / *(int64_t *)(var2->data));
					break;
				case FLOAT:
					return temp_float(*(int64_t *)(var1->data) / *(double *)(var2->data));
					break;
				case BOOL:
					return temp_int(*(int64_t *)(var1->data) / *(bool *)(var2->data));
					break;
			}
			break;
		case FLOAT:
			switch (var2->type) {
				case INT:
					return temp_float(*(double *)(var1->data) / *(int64_t *)(var2->data));
					break;
				case FLOAT:
					return temp_float(*(double *)(var1->data) / *(double *)(var2->data));
					break;
				case BOOL:
					return temp_float(*(double *)(var1->data) / *(bool *)(var2->data));
					break;
			}
			break;
		case BOOL:
			switch (var2->type) {
				case INT:
					return temp_int(*(bool *)(var1->data) / *(int64_t *)(var2->data));
					break;
				case FLOAT:
					return temp_float(*(bool *)(var1->data) / *(double *)(var2->data));
					break;
				case BOOL:
					return temp_int(*(bool *)(var1->data) / *(bool *)(var2->data));
					break;
			}
			break;
	}
	return temp_bool(false);
}

Variable ** exponentiate(Variable ** var1_ptr, Variable ** var2_ptr){
	Variable * var1 = *var1_ptr;
	Variable * var2 = *var2_ptr;
	switch (var1->type) {
		case INT:
			switch (var2->type) {
				case INT:
					return temp_int(pow(*(int64_t *)(var1->data), *(int64_t *)(var2->data)));
					break;
				case FLOAT:
					return temp_float(pow(*(int64_t *)(var1->data), *(double *)(var2->data)));
					break;
				case BOOL:
					return temp_int(pow(*(int64_t *)(var1->data), *(bool *)(var2->data)));
					break;
			}
			break;
		case FLOAT:
			switch (var2->type) {
				case INT:
					return temp_float(pow(*(double *)(var1->data), *(int64_t *)(var2->data)));
					break;
				case FLOAT:
					return temp_float(pow(*(double *)(var1->data), *(double *)(var2->data)));
					break;
				case BOOL:
					return temp_float(pow(*(double *)(var1->data), *(bool *)(var2->data)));
					break;
			}
			break;
		case BOOL:
			switch (var2->type) {
				case INT:
					return temp_int(pow(*(bool *)(var1->data), *(int64_t *)(var2->data)));
					break;
				case FLOAT:
					return temp_float(pow(*(bool *)(var1->data), *(double *)(var2->data)));
					break;
				case BOOL:
					return temp_int(pow(*(bool *)(var1->data), *(bool *)(var2->data)));
					break;
			}
			break;
	}
	return temp_bool(false);
}

Variable ** modulo(Variable ** var1_ptr, Variable ** var2_ptr){
	Variable * var1 = *var1_ptr;
	Variable * var2 = *var2_ptr;
	switch (var1->type) {
		case INT:
			switch (var2->type) {
				case INT:
					return temp_int(*(int64_t *)(var1->data) % *(int64_t *)(var2->data));
					break;
				case BOOL:
					return temp_int(*(int64_t *)(var1->data) % *(bool *)(var2->data));
					break;
			}
			break;
		case BOOL:
			switch (var2->type) {
				case INT:
					return temp_int(*(bool *)(var1->data) % *(int64_t *)(var2->data));
					break;
				case BOOL:
					return temp_int(*(bool *)(var1->data) % *(bool *)(var2->data));
					break;
			}
			break;
	}
	return temp_bool(false);
}

Variable ** negative(Variable ** var_ptr){
	Variable * variable = *var_ptr;
	switch (variable->type) {
		case INT:
			return temp_int(-*(int64_t *)(variable->data));
			break;
		case FLOAT:
			return temp_float(-*(double *)(variable->data));
			break;
		case BOOL:
			return temp_int(-*(bool *)(variable->data));
			break;
	}
	return temp_bool(false);
}

//Boolean algebra

Variable ** and(Variable ** var1_ptr, Variable ** var2_ptr){
	Variable * var1 = *var1_ptr;
	switch (var1->type) {
		case INT:
			if(*(int64_t *)(var1->data)){
				return var2_ptr;
			}else{
				return var1_ptr;
			}
			break;
		case FLOAT:
			if (*(double *)(var1->data)) {
				return var2_ptr;
			}else{
				return var1_ptr;
			}
			break;
		case STRING:
			if (strlen(var1->data)) {
				return var2_ptr;
			}else{
				return var1_ptr;
			}
			break;
		case NONE:
			return var1_ptr;
			break;
		case BOOL:
			if(*(bool *)(var1->data)){
				return var2_ptr;
			}else{
				return var1_ptr;
			}
			break;
	}
	return temp_bool(false);
}

Variable ** or(Variable ** var1_ptr, Variable ** var2_ptr){
	Variable * var1 = *var1_ptr;
	switch (var1->type) {
		case INT:
			if(*(int64_t *)(var1->data)){
				return var1_ptr;
			}else{
				return var2_ptr;
			}
			break;
		case FLOAT:
			if (*(double *)(var1->data)) {
				return var1_ptr;
			}else{
				return var2_ptr;
			}
			break;
		case STRING:
			if (strlen(var1->data)) {
				return var1_ptr;
			}else{
				return var2_ptr;
			}
			break;
		case NONE:
			return var2_ptr;
			break;
		case BOOL:
			if(*(bool *)(var1->data)){
				return var1_ptr;
			}else{
				return var2_ptr;
			}
			break;
	}
	return temp_bool(false);
}

Variable ** negate(Variable ** var_ptr){
	return temp_bool(!*(bool *)((*var_ptr)->data));
}

//Binary

Variable ** bitxor(Variable ** var1_ptr, Variable ** var2_ptr){
	Variable * var1 = *var1_ptr;
	Variable * var2 = *var2_ptr;
	switch (var1->type) {
		case INT:
			switch (var2->type) {
				case INT:
					return temp_int(*(int64_t *)(var1->data) ^ *(int64_t *)(var2->data));
					break;
				case BOOL:
					return temp_int(*(int64_t *)(var1->data) ^ *(bool *)(var2->data));
					break;
			}
			break;
		case BOOL:
			switch (var2->type) {
				case INT:
					return temp_int(*(bool *)(var1->data) ^ *(int64_t *)(var2->data));
					break;
				case BOOL:
					return temp_int(*(bool *)(var1->data) ^ *(bool *)(var2->data));
					break;
			}
			break;
	}
	return temp_bool(false);
}

Variable ** bitor(Variable ** var1_ptr, Variable ** var2_ptr){
	Variable * var1 = *var1_ptr;
	Variable * var2 = *var2_ptr;
	switch (var1->type) {
		case INT:
			switch (var2->type) {
				case INT:
					return temp_int(*(int64_t *)(var1->data) | *(int64_t *)(var2->data));
					break;
				case BOOL:
					return temp_int(*(int64_t *)(var1->data) | *(bool *)(var2->data));
					break;
			}
			break;
		case BOOL:
			switch (var2->type) {
				case INT:
					return temp_int(*(bool *)(var1->data) | *(int64_t *)(var2->data));
					break;
				case BOOL:
					return temp_int(*(bool *)(var1->data) | *(bool *)(var2->data));
					break;
			}
			break;
	}
	return temp_bool(false);
}

Variable ** bitand(Variable ** var1_ptr, Variable ** var2_ptr){
	Variable * var1 = *var1_ptr;
	Variable * var2 = *var2_ptr;
	switch (var1->type) {
		case INT:
			switch (var2->type) {
				case INT:
					return temp_int(*(int64_t *)(var1->data) & *(int64_t *)(var2->data));
					break;
				case BOOL:
					return temp_int(*(int64_t *)(var1->data) & *(bool *)(var2->data));
					break;
			}
			break;
		case BOOL:
			switch (var2->type) {
				case INT:
					return temp_int(*(bool *)(var1->data) & *(int64_t *)(var2->data));
					break;
				case BOOL:
					return temp_int(*(bool *)(var1->data) & *(bool *)(var2->data));
					break;
			}
			break;
	}
	return temp_bool(false);
}

Variable ** shift_left(Variable ** var1_ptr, Variable ** var2_ptr){
	Variable * var1 = *var1_ptr;
	Variable * var2 = *var2_ptr;
	switch (var1->type) {
		case INT:
			switch (var2->type) {
				case INT:
					return temp_int(*(int64_t *)(var1->data) << *(int64_t *)(var2->data));
					break;
				case BOOL:
					return temp_int(*(int64_t *)(var1->data) << *(bool *)(var2->data));
					break;
			}
			break;
		case BOOL:
			switch (var2->type) {
				case INT:
					return temp_int(*(bool *)(var1->data) << *(int64_t *)(var2->data));
					break;
				case BOOL:
					return temp_int(*(bool *)(var1->data) << *(bool *)(var2->data));
					break;
			}
			break;
	}
	return temp_bool(false);
}

Variable ** shift_right(Variable ** var1_ptr, Variable ** var2_ptr){
	Variable * var1 = *var1_ptr;
	Variable * var2 = *var2_ptr;
	switch (var1->type) {
		case INT:
			switch (var2->type) {
				case INT:
					return temp_int(*(int64_t *)(var1->data) >> *(int64_t *)(var2->data));
					break;
				case BOOL:
					return temp_int(*(int64_t *)(var1->data) >> *(bool *)(var2->data));
					break;
			}
			break;
		case BOOL:
			switch (var2->type) {
				case INT:
					return temp_int(*(bool *)(var1->data) >> *(int64_t *)(var2->data));
					break;
				case BOOL:
					return temp_int(*(bool *)(var1->data) >> *(bool *)(var2->data));
					break;
			}
			break;
	}
	return temp_bool(false);
}

Variable ** bitnot(Variable ** var_ptr){
	Variable * variable = *var_ptr;
	switch (variable->type) {
		case INT:
			return temp_int(~*(int64_t *)(variable->data));
			break;
		case BOOL:
			return temp_int(~*(bool *)(variable->data));
			break;
	}
	return temp_bool(false);
}

//Comparison

bool c_less_than(Variable ** var1_ptr, Variable ** var2_ptr){
	Variable * var1 = *var1_ptr;
	Variable * var2 = *var2_ptr;
	switch (var1->type) {
		case INT:
			switch (var2->type) {
				case INT:
					return (*(int64_t *)(var1->data) < *(int64_t *)(var2->data));
					break;
				case FLOAT:
					return (*(int64_t *)(var1->data) < *(double *)(var2->data));
					break;
				case STRING:
					return true;
					break;
				case NONE:
					return false;
					break;
				case BOOL:
					return (*(int64_t *)(var1->data) < *(bool *)(var2->data));
					break;
			}
			break;
		case FLOAT:
			switch (var2->type) {
				case INT:
					return (*(double *)(var1->data) < *(int64_t *)(var2->data));
					break;
				case FLOAT:
					return (*(double *)(var1->data) < *(double *)(var2->data));
					break;
				case STRING:
					return true;
					break;
				case NONE:
					return false;
					break;
				case BOOL:
					return (*(double *)(var1->data) < *(bool *)(var2->data));
					break;
			}
			break;
		case STRING:
			switch (var2->type) {
				case INT:
					return false;
					break;
				case FLOAT:
					return false;
					break;
				case STRING:
					return (strlen(var1->data) < strlen(var2->data));
					break;
				case NONE:
					return false;
					break;
				case BOOL:
					return false;
					break;
			}
			break;
		case NONE:
			return !(var2->type == NONE);
			break;
		case BOOL:
			switch (var2->type) {
				case INT:
					return (*(bool *)(var1->data) < (*(int64_t *)(var2->data) != 0));
					break;
				case FLOAT:
					return (*(bool *)(var1->data) < (*(double *)(var2->data) != 0));
					break;
				case STRING:
					return true;
					break;
				case NONE:
					return false;
					break;
				case BOOL:
					return (*(bool *)(var1->data) < *(bool *)(var2->data));
					break;
			}
			break;
	}
	return false;
}

bool c_more_than(Variable ** var1_ptr, Variable ** var2_ptr){
	Variable * var1 = *var1_ptr;
	Variable * var2 = *var2_ptr;
	switch (var1->type) {
		case INT:
			switch (var2->type) {
				case INT:
					return (*(int64_t *)(var1->data) > *(int64_t *)(var2->data));
					break;
				case FLOAT:
					return (*(int64_t *)(var1->data) > *(double *)(var2->data));
					break;
				case STRING:
					return false;
					break;
				case NONE:
					return true;
					break;
				case BOOL:
					return (*(int64_t *)(var1->data) > *(bool *)(var2->data));
					break;
			}
			break;
		case FLOAT:
			switch (var2->type) {
				case INT:
					return (*(double *)(var1->data) > *(int64_t *)(var2->data));
					break;
				case FLOAT:
					return (*(double *)(var1->data) > *(double *)(var2->data));
					break;
				case STRING:
					return false;
					break;
				case NONE:
					return true;
					break;
				case BOOL:
					return (*(double *)(var1->data) > *(bool *)(var2->data));
					break;
			}
			break;
		case STRING:
			switch (var2->type) {
				case INT:
					return true;
					break;
				case FLOAT:
					return true;
					break;
				case STRING:
					return (strlen(var1->data) > strlen(var2->data));
					break;
				case NONE:
					return true;
					break;
				case BOOL:
					return true;
					break;
			}
			break;
		case NONE:
			return false;
			break;
		case BOOL:
			switch (var2->type) {
				case INT:
					return (*(bool *)(var1->data) > (*(int64_t *)(var2->data) != 0));
					break;
				case FLOAT:
					return (*(bool *)(var1->data) > (*(double *)(var2->data) != 0));
					break;
				case STRING:
					return false;
					break;
				case NONE:
					return true;
					break;
				case BOOL:
					return (*(bool *)(var1->data) > *(bool *)(var2->data));
					break;
			}
			break;
	}
	return false;
}

Variable ** less_than(int number, ...){
	va_list args;
	va_start(args,number);
	Variable ** prior = NULL;
	Variable ** this;
	for(int x = 0; x < number; x++){
		this = va_arg(args, Variable **);
		if (prior != NULL) {
			if (!c_less_than(prior, this)){
				va_end(args);
				return temp_bool(false);
			}
		}
		prior = this;
	}
	va_end(args);
	return temp_bool(true);
}

Variable ** more_than(int number, ...){
	va_list args;
	va_start(args,number);
	Variable ** prior = NULL;
	Variable ** this;
	for(int x = 0; x < number; x++){
		this = va_arg(args, Variable **);
		if (prior != NULL) {
			if (!c_more_than(prior, this)){
				va_end(args);
				return temp_bool(false);
			}
		}
		prior = this;
	}
	va_end(args);
	return temp_bool(true);
}

Variable ** less_than_or_equal(int number, ...){
	va_list args;
	va_start(args,number);
	Variable ** prior = NULL;
	Variable ** this;
	for(int x = 0; x < number; x++){
		this = va_arg(args, Variable **);
		if (prior != NULL) {
			if (!c_more_than(prior, this)){
				va_end(args);
				return temp_bool(true);
			}
		}
		prior = this;
	}
	va_end(args);
	return temp_bool(false);
}

Variable ** more_than_or_equal(int number, ...){
	va_list args;
	va_start(args,number);
	Variable ** prior = NULL;
	Variable ** this;
	for(int x = 0; x < number; x++){
		this = va_arg(args, Variable **);
		if (prior != NULL) {
			if (!c_less_than(prior, this)){
				va_end(args);
				return temp_bool(true);
			}
		}
		prior = this;
	}
	va_end(args);
	return temp_bool(false);
}

bool c_is_same(Variable ** var1_ptr, Variable ** var2_ptr){
	Variable * var1 = *var1_ptr;
	Variable * var2 = *var2_ptr;
	if (var1->data == var2->data) {
		//Data pointers are the same so the variables are considered identical in the python sense.
		return true;
	}else{
		return false;
	}
}

Variable ** is_same(int number, ...){
	va_list args;
	va_start(args,number);
	Variable ** prior = NULL;
	Variable ** this;
	for(int x = 0; x < number; x++){
		this = va_arg(args, Variable **);
		if (prior != NULL) {
			if (!c_is_same(prior, this)){
				va_end(args);
				return temp_bool(false);
			}
		}
		prior = this;
	}
	va_end(args);
	return temp_bool(true);
}

bool c_is_equal(Variable ** var1_ptr, Variable ** var2_ptr){
	Variable * var1 = *var1_ptr;
	Variable * var2 = *var2_ptr;
	switch (var1->type) {
		case INT:
			switch (var2->type) {
				case INT:
					return (*(int64_t *)(var1->data) == *(int64_t *)(var2->data));
					break;
				case FLOAT:
					return (*(int64_t *)(var1->data) == *(double *)(var2->data));
					break;
				case BOOL:
					return ((*(int64_t *)(var1->data) != 0) == *(bool *)(var2->data));
					break;
				default:
					return false;
					break;
			}
			break;
		case FLOAT:
			switch (var2->type) {
				case INT:
					return (*(double *)(var1->data) == *(int64_t *)(var2->data));
					break;
				case FLOAT:
					return (*(double *)(var1->data) == *(double *)(var2->data));
					break;
				case BOOL:
					return ((*(double *)(var1->data) != 0) == *(bool *)(var2->data));
					break;
				default:
					return false;
					break;
			}
			break;
		case STRING:
			if (var2->type == STRING) {
				return (strcmp(var1->data, var2->data) == 0);
			}else{
				return false;
			}
			break;
		case NONE:
			return (var2->type == NONE);
			break;
		case BOOL:
			switch (var2->type) {
				case INT:
					return (*(bool *)(var1->data) == (*(int64_t *)(var2->data) != 0));
					break;
				case FLOAT:
					return (*(bool *)(var1->data) == (*(double *)(var2->data) != 0));
					break;
				case BOOL:
					return (*(bool *)(var1->data) == *(bool *)(var2->data));
					break;
				default:
					return false;
					break;
			}
			break;
	}
	return false;
}

Variable ** is_equal(int number, ...){
	va_list args;
	va_start(args,number);
	Variable ** prior = NULL;
	Variable ** this;
	for(int x = 0; x < number; x++){
		this = va_arg(args, Variable **);
		if (prior != NULL) {
			if (!c_is_equal(prior, this)){
				va_end(args);
				return temp_bool(false);
			}
		}
		prior = this;
	}
	va_end(args);
	return temp_bool(true);
}

Variable ** is_not_equal(int number, ...){
	va_list args;
	va_start(args,number);
	Variable ** prior = NULL;
	Variable ** this;
	for(int x = 0; x < number; x++){
		this = va_arg(args, Variable **);
		if (prior != NULL) {
			if (c_is_equal(prior, this)){
				va_end(args);
				return temp_bool(false);
			}
		}
		prior = this;
	}
	va_end(args);
	return temp_bool(true);
}

void delete_var(Variable ** variable){ //From python del statement to delete variables before emptying pool
	//Free variable and data
	Variable * var_ptr = *variable;
	free(var_ptr->data);
	free(var_ptr);
	*variable = NULL; //change pointer to variable to NULL. This can only be done by passing in a pointer to the pointer.
}

void empty_pool(){ //Frees all data from variable pool
	VarPool * var_pool = pool_stack[pool_stack_size-1]; //Current variable pool on top of stack
	for (int x = 0; x < var_pool->size; x++) {
		if(*var_pool->pool[x] != NULL){
			free((*var_pool->pool[x])->data);//Free variable data
			free(*var_pool->pool[x]); //Free variable
		}
		free(var_pool->pool[x]); //Free variable pointer
	}
	free(var_pool->pool); //Free pool variable array
	free(var_pool); //Free variable pool structure
	empty_temporary_pool(); //May not be done yet
	pool_stack_size--;
	pool_stack = realloc(pool_stack, pool_stack_size*sizeof(VarPool *));
	//Free temporary pool and pop it off the stack
	free(temp_pool_stack[pool_stack_size]->pool); //Free pool variable array
	free(temp_pool_stack[pool_stack_size]); //Free variable pool structure
	temp_pool_stack = realloc(temp_pool_stack, pool_stack_size*sizeof(VarPool *));
	//Free string data and completely clear string pool
	for (int x = 0; x < string_pool_size; x++) {
		free(string_pool[x]);
	}
	string_pool_size = 0;
	free(string_pool);
	string_pool = NULL;
}

int main(){
	init_pool_stack();
	puts(string_val(add(temp_string("1 and "), add(temp_string("2"),temp_string(" and 3")))));
	//Does almost the same as
	//print "He" + "l"*((2**2)*2 >> 2) + ("o"*((4/2)-1) or True) + ("!" or False) + ""*((~6+5 & 1) and not True) + '!'*(4 ^ 6)
	//But the add operator goes from right to left. It doesn't matter for this test
	puts(string_val(add(temp_string("He"),add(multiply(temp_string("l"), shift_right(multiply(exponentiate(temp_int(2), temp_int(2)), temp_int(2)), temp_int(2))), add(or(multiply(temp_string("o"), subtract(divide(temp_int(4), temp_int(2)), temp_int(1))), temp_bool(true)), add(or(temp_string("!"), temp_bool(false)), add(multiply(temp_string(""), and(bitand(add(bitnot(temp_int(6)), temp_int(5)), temp_int(1)), negate(temp_bool(true)))), multiply(temp_string("!"), bitxor(temp_int(4), temp_int(6))))))))));
	empty_pool(); //Finally empty globals pool which will deallocate pool_stack
	return 0;
}
Administrator
Administrator
Posts: 3307
Joined: Thu Dec 24, 2009 2:06 am
Allegiance:: Space Rome
Location: ON, Canada
User avatar
Administrator
Administrator
Re: C++/C programming discussion

Post by Scott »

So the purpose is to convert Python code to C?
Image
Jedi Master
Jedi Master
Posts: 336
Joined: Sun Aug 09, 2009 9:16 am
Allegiance:: Jedi
User avatar
Jedi Master
Jedi Master
Re: C++/C programming discussion

Post by Matthew »

Yes. The expression converter is proving to be extremely difficult to programme but I have some ideas.

The brakets are the pain. Brakets work differently than operators. Operators are as simple as this:

5*4+5

You find the operators in reverse order of evaluation. In his case, you evaluate the addition last so you split the + operation first.

add(5*4,5)

You do the multiplication first so you split it last:

add(multiply(5,4),5)

Now just think how hard it is with brakets on top of that. My idea is to begin by processing the brakets. I will recursively travel throughout the brakets until I reach an expression with no more brakets and I will convert that expression before traveling back out through the brakets and into the next ones.
Administrator
Administrator
Posts: 3307
Joined: Thu Dec 24, 2009 2:06 am
Allegiance:: Space Rome
Location: ON, Canada
User avatar
Administrator
Administrator
Re: C++/C programming discussion

Post by Scott »

Matthew wrote:Now just think how hard it is with brakets on top of that. My idea is to begin by processing the brakets. I will recursively travel throughout the brakets until I reach an expression with no more brakets and I will convert that expression before traveling back out through the brakets and into the next ones.
I can imagine the pain that would cause to figure out. Is this program for actual professional/production code use? Or just as a project? Either way I think it's a cool idea. Do you plan on the program to read a .py source file and then convert it? Or something else? Sorry for all the questions but it's a neat concept and I am just wondering how you are doing it (in case I try one - but much simpler - for Ruby to C++ - just for fun :))
Image
Jedi Master
Jedi Master
Posts: 336
Joined: Sun Aug 09, 2009 9:16 am
Allegiance:: Jedi
User avatar
Jedi Master
Jedi Master
Re: C++/C programming discussion

Post by Matthew »

Well, I've got it working to an extent. It fails when I have a braket at the beginning of the python expression so I suspect I need to fix a buffer overflow somewhere. Buffer overflows are very easy with string manipulation in C. I should use the memory safe versions.

At the moment it's just a project but may make it's way into a practical tool for many programmers to use. I'll have a license to prevent commercial use without permission but I'll give it away for free for those that want to use it for non-comercial projects.

The program will convert python source code which are usually stored in py files.

At first it wont convert much. I plan to add lists and OOP eventually.
Administrator
Administrator
Posts: 3307
Joined: Thu Dec 24, 2009 2:06 am
Allegiance:: Space Rome
Location: ON, Canada
User avatar
Administrator
Administrator
Re: C++/C programming discussion

Post by Scott »

Matthew wrote:Well, I've got it working to an extent. It fails when I have a braket at the beginning of the python expression so I suspect I need to fix a buffer overflow somewhere. Buffer overflows are very easy with string manipulation in C. I should use the memory safe versions.

At the moment it's just a project but may make it's way into a practical tool for many programmers to use. I'll have a license to prevent commercial use without permission but I'll give it away for free for those that want to use it for non-comercial projects.

The program will convert python source code which are usually stored in py files.

At first it wont convert much. I plan to add lists and OOP eventually.
Sounds cool. Have you thought about making it open source? Oh, and how do you get it to read a file? Is it just like reading from a text file? If so, I'd really like to play around with that idea as well.
Image
Jedi Master
Jedi Master
Posts: 336
Joined: Sun Aug 09, 2009 9:16 am
Allegiance:: Jedi
User avatar
Jedi Master
Jedi Master
Re: C++/C programming discussion

Post by Matthew »

I'm using fopen, fclose and getch. I think those are in the stdio.h library (cstdio.h for C++).

I'd love people to use it for non-comercial means but I don't want people using it commercially without some type of deal with me. I'm not saying those deals would happen but I don't like the idea of a lot of work being used to make profit without any share myself.

My TimeSPlitters fan game will be open-source because I can't be used commercially anyway. People could update it and sell the game but then people are paying for the updates and not the original work because they can get the original work for free anyway.
Administrator
Administrator
Posts: 3307
Joined: Thu Dec 24, 2009 2:06 am
Allegiance:: Space Rome
Location: ON, Canada
User avatar
Administrator
Administrator
Re: C++/C programming discussion

Post by Scott »

Matthew wrote:I'm using fopen, fclose and getch. I think those are in the stdio.h library (cstdio.h for C++).

I'd love people to use it for non-comercial means but I don't want people using it commercially without some type of deal with me. I'm not saying those deals would happen but I don't like the idea of a lot of work being used to make profit without any share myself.

My TimeSPlitters fan game will be open-source because I can't be used commercially anyway. People could update it and sell the game but then people are paying for the updates and not the original work because they can get the original work for free anyway.
Would fstream and getline() work as well?
Image
Jedi Master
Jedi Master
Posts: 336
Joined: Sun Aug 09, 2009 9:16 am
Allegiance:: Jedi
User avatar
Jedi Master
Jedi Master
Re: C++/C programming discussion

Post by Matthew »

fstream is a C++ class which I've never used. You may try it and it can work but I wouldn't know how to help.
Post Reply