Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/target
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "oxide"
version = "0.1.0"
edition = "2024"
description = "The Oxide programming language: a friendlier Rust"
license = "MIT"

[dependencies]
103 changes: 103 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# Oxide

**A friendlier Rust.** Oxide keeps the ideas that make Rust great — ownership,
borrowing, memory safety without garbage collection, immutability by default —
and removes the parts that make it hard to learn: lifetime annotations, the
struct/impl split, sized-integer soup, and format-macro ceremony.

```oxide
class Point {
x: float,
y: float,

func dist(&self, other: &Point) -> float {
let dx = self.x - other.x;
let dy = self.y - other.y;
return (dx * dx + dy * dy).sqrt();
}
}

func main() {
let a = Point { x: 0.0, y: 0.0 };
let b = Point { x: 3.0, y: 4.0 };
println("distance: {a.dist(&b)}");
}
```

## What Oxide is

- **Ownership and borrow checking, always.** Moves, `&` shared borrows, and
`&mut` exclusive borrows work like Rust's. The difference: lifetimes are
*always inferred* — there is no `'a` syntax anywhere in the language.
- **Classes.** Data and methods live in one block. No inheritance;
composition now, traits later.
- **Simple types.** `int`, `float`, `bool`, `string`. Sized types can come
later when the systems-programming story needs them.
- **String interpolation.** `println("hello {name}")` with real embedded
expressions — no macros required.
- **Compiled to a bytecode VM.** The `oxide` toolchain (written in Rust)
compiles `.ox` files to bytecode and runs them on a custom VM.

## Status

**Milestone 5 complete — the borrow checker is live.** The full v1
pipeline runs: lexer → parser → type checker → **borrow checker** →
bytecode compiler → stack VM. Ownership and borrowing work exactly as
the design doc promises, with zero lifetime annotations:

- **Moves**: assigning, passing, or returning an owned value (string,
list, class) transfers ownership; using the source afterwards is a
compile error with a `.clone()` hint. Copy types (`int`, `float`,
`bool`) just copy.
- **Borrows**: `&x` shares, `&mut x` gives exclusive access; parameters
can take `&[int]`, `&mut Counter`, etc. Aliasing XOR mutation is
enforced, and borrows end at their **last use** (non-lexical), not at
scope end.
- **Errors show both sites** (§8.4): the conflict, where the borrow
began, and a concrete fix —

```
error: cannot modify `scores` while it is borrowed
--> demo.ox:4:5
|
4 | scores[0] = 100;
| ^^^^^^^^^^^^^^^^
--> demo.ox:3:18
|
3 | let first = &scores;
| ^^^^^^ the borrow happens here
= help: finish using the borrow before modifying the value
```

`examples/tour.ox` — one program exercising the *entire* v1 grammar —
now runs end-to-end. Remaining spec gaps: returning references and
whole-value assignment through `&mut` are rejected with restructure
hints (both are candidates for a follow-up milestone), and `unsafe`
does not exist by design.

## Layout

| Path | Purpose |
|------|---------|
| `docs/design.md` | The v1 language design document |
| `src/lexer.rs` | Hand-written lexer (interpolated strings, nested comments) |
| `src/parser.rs` | Recursive-descent + Pratt parser producing the AST |
| `src/ast.rs` / `src/pretty.rs` | AST definitions and tree printer |
| `src/check.rs` / `src/tir.rs` | Type checker lowering the AST to typed IR |
| `src/compile.rs` / `src/bytecode.rs` | Typed IR → stack bytecode, disassembler |
| `src/vm.rs` / `src/value.rs` | The stack VM and runtime values |
| `src/diagnostics.rs` | Span → line/col mapping and caret rendering |
| `examples/hello.ox` | Expressions, variables, `if`, lists, built-ins |
| `examples/functions.ox` | Functions, recursion, and loops |
| `examples/classes.ox` | Classes, methods, composition, `to_str` |
| `examples/borrow.ox` | Moves, clones, `&`/`&mut` borrows, NLL |
| `examples/tour.ox` | One program exercising the entire v1 grammar — runs |

## Toolchain

```
oxide run main.ox # compile and execute
oxide build main.ox # compile, write bytecode disassembly to main.oxb
oxide check main.ox # parse the file and report syntax errors
oxide ast main.ox # parse and print the AST
```
Loading