Coffee++

Coffee++ is a little language that compiles into C++. It has been created to have something similar to CoffeeScript for C++. Currently Coffee++ is in a alpha state and not at all usable or final. Check out the source on Github to get involved.

The golden rule of Coffee++ is: "It's just C++". The code compiles one-to-one into the equivalent C++, and there is no runtime library. You can use any existing C++ library seamlessly from Coffee++ (and vice-versa).

Overview

source file Test.cf++

include iostream

int main():
	age := 5
	dog := Dog(age)
	if age != 7:
		dog.bark()

class Dog:
	public Dog(int age):
		this->age := age
	public void bark():
		std::cout << "Woof!\n"
	private int age

compiled Test.hpp

#pragma once

int main();

class Dog {
public:
	Dog();
	void bark();
private:
	int age;
};

compiled Test.cpp

#include "test.hpp"

#include <iostream>

int main() {
	auto age = 5;
	auto dog = Dog(age);
	if (age != 7) {
		dog.bark();
	}
}

Dog::Dog(int age) : age(age) {
}

void Dog::bark() {
	std::cout << "Woof!\n";
}

Language Reference

Indentation and Functions

Coffee++ uses significant whitespace. Choose tabs or a specific number of spaces and stick to your choice throughout your file.

Functions are definied by appending a : at the end of the line.

Example.cf++

int main(int argc, char** argv):
	return 1

void foo():
	return

Example.hpp

#pragma once

int main(int argc, char** argv);

void foo();

Example.cpp

int main(int argc, char** argv) {
	return 1;
}

void foo() {
	return;
}

If, Else, For and While

You can leave out the brackets and range-based for uses in instead of :. Otherwise there's no difference to C++.

The := operator automatically declares variables using auto.

Example.cf++

for i := 0; i < 5; ++i:
	if i == 2 || i == 4:
		continue
	else:
		std::cout << i << std::endl

i := 10
do:
	i -= 2
while i != 0

numbers := std::vector<int>{1, 2, 3}
for int& number in numbers:
	++number

Example.cpp

for (auto i = 0; i < 5; ++i) {
	if (i == 2 || i == 4) {
		continue;
	} else {
		std::cout << i << std::endl;
	}
}

auto i = 10;
do {
	i -= 2;
} while (i != 0);

auto numbers = std::vector<int>{1, 2, 3};
for (int& number : numbers) {
	++number;
}

Include

To include a library you can use the include statement, append header to only include it inside the header file:

Example.cf++

include iostream
include boost/array.hpp header

Example.hpp

#pragma once

#include <boost/array.hpp>

Example.cpp

#include "Example.hpp"

#include <iostream>

If you want to include a local file use import. Appending forward will also forward declare the class with the same name as the file:

Example.cf++

import legacy.h
import Foo
import Bar forward
import Test header

Example.hpp

#pragma once

#include "Test.hpp"

class Bar;

Example.cpp

#include "Example.hpp"

#include "legacy.h"
#include "Foo.hpp"
#include "Bar.hpp"

Classes

Classes are definied as in C++ with the difference that public, protected and private must be written before every function (similar to Java).

Example.cf++

class Example:
	private int a

	public void foo():
		return

	private static int b = 7
	protected int c

Example.hpp

#pragma once

class Example {
public:
	void foo();
protected:
	int c;
private:
	int a;
	int b;
};

Example.cpp

#include "Example.hpp"

void Example::foo() {
	return;
}

int Example::b = 7;

Member Initialization

Too initialize a member use this-> and the := operator. Unlike in C++, members are not initilized in order of their declaration, but in order of initialization.

Example.cf++

class Example:
	public Example(int counter):
		this->a := ++counter;
		this->b := ++counter;
	private int b
	private int a

Example.hpp

#pragma once

class Example {
public:
	Example(int counter);
private:
	int a;
	int b;
};

Example.cpp

#include "Example.hpp"

Example::Example(int counter) :
a(++counter),
b(++counter) {
}