A programming language, written in C

Ceflo

Named after my best friend, who talked me out of quitting.

There was a moment when I wanted to give up on computer science. Ceflo, my best friend, lifted my spirits and asked me to build one project I could pour all of my will into.

So in 2022 and 2023 I worked on this interpreter until the early hours of the morning, night after night. I gave it her name. Today it finally stands as something solid.

Lines of C
6,047
Tests passing
189
Dependencies
0
First commit
March 2023

Try it, right here

Not a simulation: the same C source, compiled to WebAssembly and running on your device.

CF main.cf

Booting sandbox…

  • 5 second limit. The run lives in a Worker that gets killed, so loops can't freeze the page.
  • 256 MB of memory, at most. Past that, the interpreter stops with its own error.
  • No way out. A sandboxed frame with no cookies, no network, and a virtual filesystem.

How fast is it?

Honest numbers: Ceflo walks a tree, CPython runs bytecode with decades of tuning behind it. Ceflo stays within 1.4× to 3.2×. Shorter is faster.

fib(32), recursive calls

2.08 s
0.66 s

while loop, 20M iterations

6.64 s
4.85 s

list, 2M append + read

3.06 s
1.18 s

map, 500k insert + read

1.11 s
0.77 s

Median of 5 runs, whole process. Intel Core i5-10210U, Linux, gcc 13 with -O3, Python 3.12.3, November 2026. The browser build above is slower than this native one.

When it goes wrong

Real output from the native build. Errors point at the column, and every run cleans up after itself.

$ ./Ceflo oops.cf
erreur de syntaxe: `expression` attendu, mais `)` trouvé
  --> oops.cf:1:12
    1 | println(1 +)
      |            ^

Inside

  1. 01Lexercuts the text into tokens
  2. 02Parserone function per grammar rule
  3. 03ASTnever changes at runtime
  4. 04Visitorone function per node type

Add a garbage collector, closures, structs, enums, match, maps, native libraries in C, an os module, and a VS Code extension with autocompletion. The tests also run under AddressSanitizer, and with a collector firing on every allocation.

Read the source on GitHub ↗