A simple, readable programming language implemented in C++17 — built by Phyo Thant as a learning project in language design and implementation.
- Variables —
var name = value; - Arithmetic —
+,-,*,/with proper precedence - Strings — double-quoted, concatenation with
+ - Comparisons —
==,!=,<,<=,>,>= - Logical operators —
and,orwith short-circuit evaluation - If/else —
if (cond) { ... } else { ... } - While loops —
while (cond) { ... } - For loops —
for (var i = 0; i < n; i = i + 1) { ... } - Break/Continue — loop control
- Functions —
fun name(params) { ... }withreturn - Closures — functions capture enclosing scope, mutable state
- Recursion — fully supported
- Lexical scoping — blocks create new scopes, inner shadows outer
- Arrays —
[1, 2, 3], index read/writearr[0] = val, nested arrays - File I/O —
readFile(path),writeFile(path, content) - Built-in functions —
len(),push(),pop(),toNum(),toString(),input() - Comments —
// line comments - REPL — interactive mode
- File execution — run
.ptfiles
# Build
g++ -std=c++17 -o pt src/main.cpp src/lexer.cpp src/parser.cpp src/interpreter.cpp
# Run a file
./pt test.pt
# REPL mode
./pt
> print "hello world";
> exitprint "hello world";var x = 10;
var y = 3;
print x + y; // 13
print x * y; // 30
print (x - y) / 2; // 3.5if (x > y) {
print "x is bigger";
} else {
print "nope";
}// while
var i = 0;
while (i < 5) {
print i;
i = i + 1;
}
// for
for (var n = 0; n < 5; n = n + 1) {
print n;
}
// break / continue
var a = 0;
while (a < 10) {
if (a == 3) break;
if (a == 1) { a = a + 1; continue; }
print a;
a = a + 1;
}fun fact(n) {
if (n <= 1) return 1;
return n * fact(n - 1);
}
print fact(6); // 720
// with for loop
fun fact2(n) {
var result = 1;
for (var i = 1; i <= n; i = i + 1) {
result = result * i;
}
return result;
}
print fact2(5); // 120fun makeCounter() {
var count = 0;
fun counter() {
count = count + 1;
return count;
}
return counter;
}
var c = makeCounter();
print c(); // 1
print c(); // 2
print c(); // 3var x = "outer";
{
print x; // outer
var x = "inner";
print x; // inner
}
print x; // outervar arr = [1, 2, 3, 4, 5];
print arr; // [1, 2, 3, 4, 5]
print arr[0]; // 1
arr[2] = 99; // [1, 2, 99, 4, 5]
push(arr, 6); // [1, 2, 99, 4, 5, 6]
print pop(arr); // 6
print len(arr); // 5
// nested arrays
var nested = [[1, 2], [3, 4]];
print nested[0][1]; // 2writeFile("/tmp/data.txt", "hello world");
print readFile("/tmp/data.txt"); // hello world
print readFile("/tmp/nope"); // nil (file doesn't exist)len("hello") // 5
len([1, 2, 3]) // 3
push(arr, val) // append to array
pop(arr) // remove and return last element
toNum("42") // 42
toNum("abc") // nil
toString(42) // "42"
input("name: ") // reads a line from stdin
readFile(path) // read file contents (nil on error)
writeFile(path, content) // write to file (true/false)true and false // false
true or false // true
(10 > 5) and (20 > 10) // truept/
├── pt # compiled binary
├── test.pt # test program
├── src/
│ ├── main.cpp # entry point, REPL, file runner
│ ├── token.h # token type definitions
│ ├── lexer.h/.cpp # scanner — source → tokens
│ ├── ast.h # AST node definitions
│ ├── parser.h/.cpp # parser — tokens → AST
│ └── interpreter.h/.cpp # tree-walk interpreter
Requires a C++17 compiler (g++ or clang++).
g++ -std=c++17 -o pt src/main.cpp src/lexer.cpp src/parser.cpp src/interpreter.cppprogram → declaration* EOF
declaration → funDecl | varDecl | statement
funDecl → "fun" IDENTIFIER "(" parameters? ")" block
varDecl → "var" IDENTIFIER ("=" expression)? ";"
statement → exprStmt | printStmt | block | ifStmt | whileStmt
| forStmt | breakStmt | continueStmt | returnStmt
exprStmt → expression ";"
printStmt → "print" expression ";"
block → "{" declaration* "}"
ifStmt → "if" "(" expression ")" statement ("else" statement)?
whileStmt → "while" "(" expression ")" statement
forStmt → "for" "(" (varDecl | exprStmt | ";") expression? ";" expression? ")" statement
breakStmt → "break" ";"
continueStmt → "continue" ";"
returnStmt → "return" expression? ";"
expression → assignment
assignment → IDENTIFIER "=" assignment | IDENTIFIER "[" expression "]" "=" assignment | or
or → and ("or" and)*
and → equality ("and" equality)*
equality → comparison (("==" | "!=") comparison)*
comparison → term (("<" | "<=" | ">" | ">=") term)*
term → factor (("+" | "-") factor)*
factor → unary (("*" | "/") unary)*
unary → ("!" | "-") unary | call
call → primary ( "(" arguments? ")" | "[" expression "]" )*
primary → NUMBER | STRING | "true" | "false" | "nil"
| IDENTIFIER | "(" expression ")" | "[" (expression ("," expression)*)? "]"
MIT