A small interpreted language for experimenting with typed state, control flow, and reactive language ideas.
Getting started | Language snapshot | Project layout | Roadmap
Causis is a C++-built programming language project focused on growing a clean, understandable core before moving into its longer-term reactive ambitions.
Today, the repository contains:
- a lexer
- a recursive-descent parser
- a tree-walk interpreter
- lexical block scoping
- typed bindings with runtime checks
- functions and basic control flow
The current implementation is best thought of as an early language core, not a finished language product.
The project explores a language model built around a few ideas:
letfor immutable bindingsstatefor explicit mutable state- approachable syntax with familiar control flow
- incremental development toward richer reactive constructs
That means the README should describe the language as it exists now, while still making the direction clear: Causis is building toward reactivity on top of a simple executable core.
The current language supports:
- immutable declarations with
let - mutable declarations with
state - optional declared types on bindings
- integer, floating-point, string, and boolean literals
- arithmetic:
+,-,*,/ - comparisons:
>,>=,<,<=,==,!= - boolean logic:
&&,||,!,^ - reassignment with
= - block scopes with
{ ... } - functions with typed parameters and optional return types
returnif,else if,elsewhileforbreakandcontinueprint(...)
Supported declared types currently include:
boolstringuint8,int8uint16,int16uint32,int32uint64,int64float32,float64
Type checks are enforced at runtime. Integer declarations also perform range checks for the smaller integer types currently modeled by the interpreter.
let seed: int32 = 2;
state total: int32 = 0;
fn add(a: int32, b: int32) -> int32 {
return a + b;
}
for (state i: int32 = 0; i < 3; i = i + 1) {
total = total + i;
}
if (add(seed, total) > 4) {
print("ready\n");
} else {
print("waiting\n");
}
You can find a larger end-to-end example in examples/program.au.
Running the sample program today:
./build/causis examples/program.auproduces:
=== logic ===
true
=== types ===
255
-8
65000
-1234
42
9000
3.75
typed values
=== blocks ===
5
=== functions ===
9
4
0
=== if / else if / else ===
200
=== while ===
0
1
2
while total=3
=== for ===
0
1
2
=== break / continue while ===
1
3
=== break / continue for ===
0
2
3
That sample exercises the main pieces of the language that are implemented in this repository right now.
- CMake 3.20 or newer
- A C++20-compatible compiler
cmake -S . -B build
cmake --build build./build/causis examples/program.au./build/parser_debug examples/program.auparser_debug is a developer utility that prints lexer output, statement kinds, and expression tree information to help inspect parsing behavior.
- include/causis contains the language headers, AST definitions, runtime value model, and environment types.
- src/Lexer.cpp implements tokenization.
- src/Parser.cpp implements recursive-descent parsing.
- src/Interpreter.cpp executes the AST with runtime type checks and scoped environments.
- src/main.cpp provides the CLI entrypoint.
- tests/parser_debug.cpp provides the parser inspection executable.
- examples contains sample Causis programs.
Causis is still in an early stage. Some important pieces are intentionally missing or incomplete:
- no static type checker
- no modules or imports
- no user-defined data types
- no collections or arrays
- no closures beyond storing function environments for calls
- no dedicated diagnostic system beyond thrown runtime and parse errors
- no reactive
deriveorwhenmodel yet
Near-term work likely includes:
- improving diagnostics and source-aware error reporting
- expanding the value model and type system
- adding richer expression and statement forms
- introducing the first real reactive constructs
- strengthening tests around parsing and interpretation
The long-term goal for Causis is not just to be another small interpreter. The interesting part is the language direction: explicit state, predictable control flow, and eventually a stronger reactive model built on top of a readable core.
For now, the emphasis is on making the implementation easy to reason about and extending it one solid piece at a time.