# What is C prime

C Prime is a new language very close related to C, C Prime is an very simple addition to c, You could say c prime is c with classes without the bloat. Also unique about C Prime is the C Prime compiler, Because the C Prime compiler will convert your C Prime code to readable, high-performance C code. This code can than be compiled with a normal C compiler.

As c compiler i use the tiny c compiler. The C Prime Preprocessor can be compiled using the tiny c compiler using Musl or Gnu libc. Also your preprocessed code can be compiled using the Tiny c compiler.

Then you can preprocess your Object Oriented c code using the compiled binary. This will generate a folder with readable c files. These can then be compiled using the tiny c compiler.

Compiling the C Prime preprocessor takes only a few milliseconds. and using the C Prime preprocessor to preprocess your object oriented c code to pure c also takes a few milliseconds. It is almost instantaneous. Then compiling your resulting c code with the tiny c compiler takes somewhat longer. still less then 1 second.

# Classes

Creating simple classes.

```C++
#include "console.h"

class application{

	sayHi( char * name ) {

		console.log( "Hi ", name );

	}

	launch() {

		this->sayHi( "John" );

	}

}

void main() {

	application * instance = new application();

	instance->launch();

}
```

# Constructors
Instantiate a class using an constructor.


```C++
class vector3{

	float x;

	float y;

	float z;

	constructor( float x, float y, float z ) {

		this->x = x;

		this->y = y;

		this->z = z;

	}

	display() {

		printf("x: %f, y: %f, z: %f", this->x, this->y, this->z);

	}

}

void main() {

	vector3 * a = new vector3( 1.0, 0.0, 1.0 );

	a->display();

}
```

# Running a webserver
For example to setup a server you can write:


```C++
#include "../http.h"

#include "./fileSystem.h"

#include "./text.h"

#include "./mimeTypes.h"


void handleRequest( struct request * requestInstance, struct text * response ) {

	text * filePath			= new text("www/");

	filePath				+= requestInstance->url;

	// Request information
	printf("server address:	[%s:%u]\n", 	requestInstance->address, requestInstance->port );

	printf("mimeType:		%-30s \n", 	requestInstance->mimeType);

	printf("header:		%-30s \n",			requestInstance->extension );

	printf("method:		%-30s		 \n", 	requestInstance->method );

	printf("version:		%-30s		 \n\n", requestInstance->version );

	if( filesystem->exists( filePath->value ) ) {

		text * content 		= filesystem->readFile( filePath->value, "binary" );

		response			+= "HTTP/1.0 200 OK\r\n";

		response			+= "Server: webserver-c\r\n";

		response			+= "Content-type: " + requestInstance->mimeType + "\r\n\r\n";

		response			+= "Simple test server\r\n";
		//response->appendObject( content );

		free( content );

	} else {

		printf("file does not exists...		%s\n", filePath->value);

	}


}

void main() {
	
	http * serverInstance = new http();

	serverInstance->createServer( handleRequest );

	serverInstance->listen( 8080 );

}
```


	
		
	



```C++
#include "../fileSystem.h"

#include "../console.h"

void main() {
	
	char * directory2			= "./assets/";

	fileSystem * filesystem 	= new fileSystem();

	char * directory			= "./assets/";



	filesystem->writeFile( "./assets/testFile", "content of file" );


	array * files 				= filesystem->readDir( directory );

	int fileCount 				= files->length();

	for ( int i = 0; i < fileCount; ++i )
	{

		char * filename = files->get( i );

		char * path		= directory->concatenate( filename );

		char * source 	= filesystem->readFile( path );


		printf("filename: 	%s\n", path);

		printf("source: 	%s\n\n\n", source);

	}

	if( filesystem->ensureDirectory("./Some/example/assure") ) {

		console.log("Directories successfuly created.");

	}

	if( filesystem->exists( "Some" ) ) {

		console.log("Directories 'Some' does exist.");

	}

}

void abort() {


}
```
	
	


# Extending classes
You can extend one or more classes. This will overide the methods and properties, with the methods and properties of the extended class.


```C++
#include "stdio.h"  

class classB{

	int propertyA = 1;

	void test() {

		printf("%s\n", this->propertyA );

	}

}

class classA{

	int propertyA = 2;

	void test() {

		printf("%s\n", this->propertyA );

	}

}


class inherit extends classB, classA{

	int propertyA = 3;

	void test() {

		printf("%s\n", this->propertyA );

	}

}


#include 

#include "extends.h"

void main() {

	struct inherit * pointer 	= new inherit();

	for (int i = 0; i < 10; ++i)
	{

		struct inherit instance = new inherit();

		instance.propertyA = i;

		instance.test();

	}

}
```

# Console.log

You can print all class instances and arrays using console.log. This is all possible because of datatype overloading and automatic reflection.

Reflection means that the structure of the class is always available at runtime.


```C++
#include "../console.h"

#include "../street.h"

#include "../user.h"

#include "../array.h"



void main() {
	
	struct user	* newUser		= new user();

	newUser->id		= 1;

	newUser->username	= "peter";

	newUser->userlevel	= 2134;

	newUser->hash		= "#234234325";



	struct array * addresses = newUser->addresses;


	address * someAddress = new address();

	someAddress->street = "HiLane";

	someAddress->number	= 1234;

	addresses->add( someAddress );




	address * otherAddress = new address();

	otherAddress->street = "OtherLane";

	otherAddress->number	= 4567;

	addresses->add( otherAddress );

	// todo   newUser->addresses->add( otherAddress );


	printf("adresses count: %i\n\n", addresses->length() );


	char * something 	= "this is from an char * ";

	int somethingElse	= 123;


	console.log( 	"Goedendag", 
					123456, 
					"en een andere text.", 
					something, 
					somethingElse, 
					"something en something", 
					"in native c", 
					23456, 
					newUser, 
					"and some text again" );

}

void abort() {

	
}
```

	
		
	


	

# Datatype overloading
This demostrates how an datatype can be accessed within the called method when using argument overload.

```C++
class console{

	void log( ... ) {

		va_list args;

		va_start( args, count );

		//printf("count: %i\n\n", count);

		for (int i = 0; i < count; ++i)
		{
			int datatype 		= datatypes[i]; // va_arg_type( argumentIndex )

			// this will print the datatype of the argument
			printf("datatype %i\n", datatype);

			if( datatype == 1 ) {

				// do something

			}


			printf(" ");

		}

		printf("\n");

		va_end( args);

	}

}
```

# Operator overload

With operator overload you can manipulate your class instances using operators.

```C++
class vector2{

	int x = 123;

	int y = 234;

	constructor( int x, int y ) {

		this->x = x;

		this->y = y;

	}

	vector2 * operator+( vector2 * b ){

		this->add( b );

		return this;

	}

	vector2 * operator+=( struct vector2 * b ) {

		this->add( b );

		return this;

	}
	
	add( vector2 * a ) {

		this->x += a->x;

		this->y += a->y;

		addition( this->y, a->x );

	}

}
```


# Then you can use those classes like this:


```C++
#include "../text.h"

#include "../vector2.h"

#include "../vector3.h"

#include "../console.h"



void main() {

	text * textB			= new text("ook mooi");

	char * other			= malloc(5000);

	vector3 * newVector3 	= new vector3();

	newVector3->x	= 2;

	newVector3->y	= 2;

	newVector3->z	= 3;


	for (int i = 0; i < 1000; ++i)
	{

		vector3 * vector3B 	= new vector3();


		vector3B->x	= 2;

		vector3B->y	= 3;

		vector3B->z	= 4;


		vector3 * vector3C = new vector3();


		vector3C->x	= 2;

		vector3C->y	= 3;

		vector3C->z	= 4;

		newVector3	= vector3C + ( vector3C + newVector3 + ( ( ( ( vector3B + vector3C ) ) + vector3C ) + vector3B ) );

		newVector3	= newVector3 + ( ( vector3B + vector3C ) + vector3C );

	}

	console->log( newVector3 );

	text * textA		= new text("mooi");
	
	if( textA == textB ) {

		printf("mooi zo");

	}

	text * textC		= new text("mooi");

	text * textD		= new text("mooi");

	
	if( ( ( textA == textC ) && ( textA == textD ) ) && textA == textD ) {

		printf("Good, This works.\n\n");

	}

	char * realChar = "something";

	if( "something" == realChar ) {

		printf("Great.\n\n");

	}

	if( realChar == "something" ) {

		printf("Great.\n\n");

	}

	if( realChar == realChar ) {

		printf("Great.\n\n");

	}

	if( "something" == "something" && realChar == "something" ) {

		printf("Great.\n\n");

	}


// Easy concatenation

	char * fancy	= "aaa ";

	char * aaaa		= " bbb ";

	char * bbbb		= " ccc ";

	char * dddd		= " dddd ";

	other += ( fancy + ( bbbb +  aaaa ) + dddd ) + " eee" + " het is een wonder ";

	other += ("boven wonder" + returnText("this is a normal function") + " and this " + ( "works just good..." + dddd )); 

	other += "something" +  ( returnText("this is a normal function") + textB->toNative() + textB->value );

	other +=  ("and here some text") + (textB->toNative()) ;

	other +=  (  textB->value + ( ( textB->value ) + returnText("this is a normal function") ) + (textB->toNative() + "here some text" + textB->value ) );

	other +=  textB->value + textB->value + ( textB->value + textB->value ) +  ( textB->value + textB->value ) + textB->value + textB->value;

	console.log( "Great ", other );









	vector2 testVector 		= new vector2( 1,  450 );


	//int count = 0;

	for (int i = 0; i < 2000000; ++i)
	{
		vector2  testVector1		= new vector2( 2,  450 );

		vector2 *  testVector2 		= new vector2( 10, 450 );

		testVector					+=  testVector1 + testVector2;

	}

}


char * returnText( char * text ) {

	return text;

}

void abort() {


}
```



# Sqlite3
Using these features C Prime also provides an simplistic sqlite3 class.

```C++
#include "../sqlite.h"

#include "../array.h"

#include "../console.h"

#include "../street.h"

#include "../user.h"

#include "time.h"

void main() {
	
	// sqlite * sql 				= new sqlite("./database/users.sqlite");

	sqlite * sql 				= new sqlite(":memory:");

	sql->selectModel( "user" );


	sql->createTable();

	char * names[20]			= { "piet", "gurbe", "siebe", "gerben", "twain", "piet", "gurbe", "siebe", "gerben", "twain", "piet", "gurbe", "siebe", "gerben", "twain" };

	clock_t tic 				= clock();


	array * usersInsertArray 	= new array();

	for (int i = 0; i <10; ++i) //20000
	{
	
		char * name = names[i];

		struct user * userInstance = new user();

		userInstance->id		= i;

		userInstance->username 	= name;

		userInstance->userlevel	= 3;

		userInstance->hash		= "12345";

		usersInsertArray.add( userInstance );

		//sql->addRow( userInstance );

	}


	sql->addRows( usersInsertArray );



	clock_t toc = clock();

	printf("Multiply: %f seconds, rows: %i\n", (double)( toc - tic ) / CLOCKS_PER_SEC, 10000);



	array * usersA 	= sql->fetchRows( "SELECT * FROM user" );

	//user * firstUser = new user();

	user * firstUser = usersA->get( 1 );

	//firstUser->id =10;

	firstUser->username		= "updated";

	firstUser->userlevel	= 1111;

	firstUser->hash			= "new hash";

	console->log( "??", firstUser, "Yeey console.log workswith , , " );


	sql->update( firstUser );

	printf("before log\n\n");


	

	array * users 	= sql->fetchRows( "SELECT * FROM user  " );

	int userCount	= users->total;
	

	printf("added rows: %i\n", userCount);

	console->createHorisontalLine();

	printf("\e[1m");

	printf("	");

	printf("%-20s", "id" );

	printf("%-30s", "username" );

	printf("%-20s", "userLevel" );

	printf("%-30s", "Hash");

	printf("\e[m");

	printf("\n");

	console->createHorisontalLine();

	printf("users: %i\n", userCount);

	for (int i = 0; i < userCount; ++i)
	{

		struct user * userInstance = users->get( i );

		userInstance->id;

		userInstance->username;

		printf("	");

		printf("%-20i", userInstance->id);

		printf("%-30s", userInstance->username);

		printf("%-20i", userInstance->userlevel);

		printf("%-30s", userInstance->hash);

		printf( "\n" );//%-30s

	}

	sql->free();

	console->createHorisontalLine();

	

}

void abort() {


}
```
