
R#
My own programming language. It reads like Python and compiles through C to a native executable.
Projects › R#

My own programming language. It reads like Python and compiles through C to a native executable.
R# (Rosary Sharp) is a programming language I’m building from scratch. The idea is simple: write code that feels like Python, and get a program that runs at C speed. The compiler is written in C++ and turns .rsh files into C, then a normal C compiler turns that into an .exe. No interpreter and no garbage collector.
It’s early. The language spec is finished and the lexer is being written now, so none of the code below compiles yet. This is what it’s being built to run.
fn fib(n: int) -> int:
if n < 2:
return n
return fib(n - 1) + fib(n - 2)
fn main():
for i in 0..10:
print("fib({i}) = {fib(i)}")
let can’t change, var can."{pi:.2f}" uses Python’s format specs, and they’re checked when you compile, so .2f on a string is an error before the program ever runs.list[int], map[string, int], slices, for k, v in my_map.Result or Option, match takes them apart, and ? passes an error up.impl blocks compile down to plain C functions, so calling one costs nothing extra.enum Shape:
Circle(radius: float)
Rect(w: float, h: float)
fn area(s: Shape) -> float:
match s:
Circle(r): return 3.14159 * r * r
Rect(w, h): return w * h
fn main():
let shapes = [Circle(2.0), Rect(3.0, 4.0)]
for s in shapes:
print("area = {area(s):.1f}")
Numbers are copied. Strings, lists, maps and structs are reference counted: passing one around shares it, and it’s freed the moment nothing uses it anymore. That makes cleanup predictable, with no garbage collector pausing the program. .copy() makes a real copy when you want one. The catch is that objects pointing at each other in a loop never get freed, which is a known limit of v0.1.
Any C library is one line away. Declare the function and call it:
import c "math.h"
extern fn sqrt(x: f64) -> f64
fn main():
print("sqrt 2 = {sqrt(2.0)}")
Anything that touches raw pointers has to go inside an unsafe: block.
.rsh → lexer → parser → type checker
→ C11 code + small runtime
→ clang / gcc / zig cc → native .exe
The generated C keeps #line markers, so if the C compiler or a debugger complains, it points at the right line in the .rsh file and not the generated C. R#’s own errors show the file, the line and a caret under the problem, like Rust’s.
Resultrsharp build and rsharp runClasses, user-made generics, async and threads are left out of the first version on purpose, so it stays small enough for one person to finish.
```rsh title="fib.rsh" in the Markdown puts the file name on the block, and it's shown as a tab with content: attr(data-title). Line numbers come from a CSS counter() on each line.linear-gradient clipped to the text with a hard stop at 1ch. That works because in a monospace font every character is exactly 1ch wide. Section headings are written like R# comments.:has(:checked) + :not(:has(:checked)) and blinks like the cursor.rsharp run hello.rsh one character per steps() frame, then the output appears.