/CoffeeCat

CoffeeCat is a toy programming language and a source-to-source compiler that produces C++.

Primary LanguageC++

CoffeeCat

CoffeeCat is a programming language that makes it easy to write reliable code and gives you more time to work on ideas and solving problems.

It's designed with micro-controllers in mind, so it's very fast and lean, yet high-level enough to be a very productive language. It works by trans-compiling high level CoffeeCat code into C++.

Intro

CoffeeCat is a high level language for micro-controllers. Before CoffeeCat, if you wanted to program a micro-controller (such as an Arduino or STM32 board), you would probably need to use C or C++. These are great languages but they can be a little tedious to develop with.

The CoffeeCat language is simple and convenient. It has a Python-esque / C# feel and provides high-level abstraction and safety without adding any bloat. The CoffeeCat compiler turns CoffeeCat into equivalent C++ code, so you have the simplicity of a high level language with the speed and efficiency of C++.

The compiler only produces a subset of C++. It does not have pointers, it does not use exceptions, it doesn't use new/delete and all objects must be initialised at declaration. Method access modifiers (public/protected/private) are also removed and all member methods and variables are made public. As they say in Python circles, "Simple is better than complex" and "We're all consenting adults here".

Some may point out that you can't read or write to hardware registers without pointers! CoffeeCat allows for C++ inlining partly for that reason.

For most of its functionality, CoffeeCat depends on the Embedded Tool Kit. It uses ETK for strings, arrays, lists and various other functions.

CoffeeCat has both arrays and lists. Arrays are bounds checked so it's impossible to corrupt memory by writing past the end. Lists give the illusion of dynamic growth and shrinkage, but in fact they have a user-specified maximum size and do not use heap memory. Lists cannot cause memory fragmentation.

Pointers don't exist in CoffeeCat due to their perceived (by newbies) complexity and potential dangers. C++ introduced references which are safer than pointers, but the syntax for passing a reference to a function is not very explicit. Unless you look at the function definition you can't tell if you're passing a reference or a copy. CoffeeCat deals with this by passing const references by default. This is efficient and safe because the function can access but not modify the original object. To explicitly copy the object, you must use the copy keyword and to pass a non-const reference you must use the out keyword - similar to C#.

CoffeeCat is mostly interchangeable with C++. C++ code can easily use code generated by CoffeeCat, and CoffeeCat can use most C++ existing code too. There are some exceptions - for example copy constructors of C++ classes must be public and not implicitly deleted.

The Syntax

CoffeeCat uses indents to specify blocks of code. The CoffeeCat lexer identifies both four spaces and tabs as an indent, so unlike Python it won't choke if you use tabs and spaces interchangeably. That annoys me about Python. White space is white space, especially when 99.9% of text editors let you change tab width.

CoffeeCat source ``` int main(): io.print("Hello world!\n") ``` Output main.cpp ``` #include "main.h"

int main() { io.print("Hello world!\n"); }

main.h

#ifndef MAIN_H #define MAIN_H

#include <etk/etk.h> #include "stdlib/stdlib.h"

int main();

#endif

C++ inlining

void write_pin(var value): int16 gpio_a = 0x5392 extern("(*gpio_a) = value")

Output

void write_pin(auto value) { int16_t gpio_a = 0x5392; (*gpio_a) = value; }

<h2>The Compiler</h2>
<p>The CoffeeCat compiler has a hand coded lexer and recursive descent parser that uses backtracking, lookahead and elements of precedence passing to generate a parse tree. The parse tree is then traversed using a visitor pattern to generate C++ source and header files. 
<p>CoffeeCat might appear to do nothing more than simply convert Python-esque syntax into C++ syntax, but it's more than a simple syntax translator. It's a full programming language that completely breaks down the input source files to generate new but equivalent C++. By giving the compiler so much insight into the CoffeeCat code, all manner of interesting transformations and possibilities arise. 
<p>The compiler is written in C++, but as CoffeeCat grows it will hopefully become a self-hosting compiler. 
<p>Command line arguments are
<ul>
    <li>-o output_directory</li>
    <li>-h Builds a project header file</li>
    <li>All source files are added to the end</li>
</ul>
<p>Eg
'''
coffeecat -o ./output -h main.cof test.cof
'''
<h2>Development Status</h2>
<p>The parse can correctly build a parse tree for 95% of the language and C++ code generation is still an area of research.