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).
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";
}
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;
}
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;
}
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 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;
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) {
}