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) { }