Skip to content

Fujo930/rake

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Rake — A Pragmatic Programming Language

Rake is a pragmatic, statically-typed programming language designed for readability, safety, and developer joy. It combines Python-style indentation with Rust-inspired type safety and Go-like batteries-included tooling.

println("Hello, Rake!")

fun fib(n: Int) -> Int
    match n
        0 => 0
        1 => 1
        _ => fib(n - 1) + fib(n - 2)

for i in 0..11
    println("fib({i}) = {fib(i)}")

Features

  • Indentation syntax — Significant indentation, no braces, no semicolons
  • Static typing — Type inference with optional type annotations
  • Immutable by defaultname = val for bindings, mut name = val for mutable variables
  • Expression-orientedif is an expression, pattern matching with match
  • Pipeline operatorexpr |> function chains transformations
  • First-class functions — Functions as values, closures with captures
  • Algebraic data types — Structs with named fields
  • Built-in collections — Arrays, Maps with method syntax
  • Rich expression syntax — Arithmetic, comparison, logical, range operators
  • Batteries includedprintln, string/array/map methods, JSON, File I/O, DateTime
  • Type checked — Static type checker catches errors before runtime

Quick Start

cargo build --release
./target/release/rake examples/hello.rake

Or use the REPL:

cargo run

Syntax Overview

Variables & Mutation

name: Int = 42       # immutable, with type annotation
name = "hello"       # immutable, type inferred, rebindable
mut count = 0        # mutable variable
count := count + 1   # reassignment (colon-eq)

Functions

fun add(a: Int, b: Int) -> Int
    a + b

result = add(3, 4)  # => 7

# Pipeline
result = 3 |> add(4)  # => 7

# Closures
fun make_counter()
    mut count = 0
    fun inner()
        count := count + 1
        count
    inner

counter = make_counter()
println(counter())  # => 1

Control Flow

# If is an expression
x = 10
msg = if x > 5
    "big"
else
    if x > 0
        "positive"
    else
        "small or negative"

# While loop
mut i = 0
while i < 5
    println(i)
    i := i + 1

# For loop over range
for item in 0..5
    println(item)

Pattern Matching

fun describe(n: Int) -> String
    match n
        0 => "none"
        1 => "one"
        _ => "many"

Structs

struct Point
    x: Int
    y: Int

p = Point { x: 10, y: 20 }
println(p.x, p.y)

Collections

arr = [1, 2, 3, 4, 5]
println(arr[0])        # => 1
println(arr.len())     # => 5
println(arr.push(6))   # => [1, 2, 3, 4, 5, 6]

map = map_new()
m = map.set("key", "value")
println(m.get("key"))  # => "value"

Roadmap

v0.1 — MVP

  • Lexer with indentation-based syntax
  • Recursive descent Pratt parser
  • AST definitions
  • Tree-walk interpreter
  • Static type checker
  • Built-in functions (print, println, len, int, float, string)
  • Variables and assignment
  • Functions with parameters and return types
  • If/else control flow
  • While and for loops
  • Structs with field access
  • Arrays with indexing
  • Closures with captures
  • REPL for interactive use

v0.2 — Core Language Expansion ✓

  • Range literals (0..10)
  • Multi-line strings (""" syntax)
  • String interpolation ("Hello {name}")
  • Pattern matching (match expressions)
  • Error handling
  • Modules and imports
  • Enum types (sum types)
  • Type aliases

v0.3 — Syntax Redesign & Standard Library ✓

  • Redesigned syntax: fun, mut, :=, |>, if as expression
  • Method call syntax (obj.method(args))
  • Map type (map_new, map.set, map.get, etc.)
  • JSON parsing and stringification
  • File I/O (read_file, write_file, file_exists)
  • DateTime (now())
  • String methods (split, trim, contains, etc.)
  • Array methods (push, pop, contains, etc.)
  • Error handling
  • Modules and imports

v0.4 — Tooling & Developer Experience

  • Formatter (rake fmt)
  • Linter
  • Language Server Protocol (LSP)
  • Package manager integration
  • Error messages with spans and suggestions
  • Debugger support

v0.5 — Performance & Compilation

  • Bytecode compiler and VM
  • LLVM backend for native compilation
  • WASM compilation target
  • JIT compilation
  • AOT compilation with optimization

Future Ideas

  • Algebraic effects for error handling and async
  • Compile-time execution (Zig-style comptime)
  • Borrow checker for memory safety without GC
  • Optional GC for rapid prototyping
  • CSP-style concurrency (Go-style goroutines)
  • Interop with C/Rust libraries
  • Gradual typing modes

Development

Built with Rust (edition 2021) from scratch by a team of one — DeepSeek V4 Flash Free.

Project Structure

src/
├── main.rs      # CLI entry point, REPL, file runner
├── token.rs     # Token types and definitions
├── lexer.rs     # Lexer / tokenizer with indent handling
├── ast.rs       # Abstract Syntax Tree definitions
├── parser.rs    # Recursive descent Pratt parser
├── types.rs     # Type system and type environment
├── checker.rs   # Static type checker
└── eval.rs      # Tree-walk interpreter

Build & Test

cargo build
cargo run examples/hello.rake
cargo run  # REPL mode

Development History

2026-06-06 — Genesis

Rake was born in a single intense development session. Here's how it happened:

Phase 1 — Design (conversation with the human) The human asked what kind of language I would design. I described "Rake" — a pragmatic language combining the best ideas from Python (indentation syntax, readability), Rust (safety, immutability by default), and Go (simplicity, batteries-included tooling). The human gave the green light: "开始吧" (let's begin).

Phase 2 — Foundation (files 1-4)

  • Setup Rust project with Cargo
  • Defined the token system — all keywords, operators, literals, and indentation tokens
  • Built the lexer — a character-by-character tokenizer that handles Python-style significant indentation (INDENT/DEDENT tokens), string escapes, comments, and CRLF line endings

Phase 3 — Parsing (files 5-6)

  • Defined the full AST — expressions, statements, types
  • Built a recursive descent Pratt parser — handles operator precedence, function calls, field access, array indexing, struct literals
  • The biggest challenge: getting Pratt parsing right for postfix operators (function calls, field access). Fixed a subtle bug where prec < min_prec caused RParen to be treated as an infix operator

Phase 4 — Semantics (files 7-9)

  • Type system with Int, Float, String, Bool, Nil, Fn, Struct, Array, Any types
  • Static type checker that validates assignments, function calls, condition types
  • Tree-walk interpreter supporting all language features
  • Built-in functions (print, println, len, int, float, string)

Phase 5 — Testing & Polish

  • Wrote comprehensive example programs (hello.rake, fib.rake)
  • Fixed struct literal parsing (handled Ident { ... } in prefix parser)
  • Fixed assignment parsing (handled ident = expr at statement level)
  • Cleaned up debug output, added .gitignore
  • Committed and published to GitHub

2026-06-06 — v0.2: Core Language Expansion

Range Literals

  • Added DotDot token (..) and Expr::Range in the AST
  • Lexer recognizes .. as DotDot (two consecutive dots, not a float)
  • Parser handles .. at precedence level 4 with left-associative binding
  • Evaluator produces Value::Array from start..end (end-exclusive)
  • for i in 0..10 works automatically since for-in accepts arrays

Multi-line Strings

  • Lexer detects """ at string start and enters multi-line mode
  • Reads until closing """, preserving newlines and indentation
  • Embedded " or "" inside are literal unless followed by " completing the triple

String Interpolation

  • Parser-level desugaring of {name} and {name.field} inside strings
  • Converts "Hello {name}" into "Hello " + name (a Binary(Add) chain)
  • Supports {identifier} and {obj.field} patterns
  • Evaluator auto-converts non-string operands to string in + operations
  • Full expression interpolation ({call()}) deferred to future v0.2.x

Pattern Matching

  • match expr with indented arm blocks
  • Supports literal patterns (Int, String, Bool, Nil), wildcard (_), and binding patterns
  • Binding patterns introduce variables in the arm scope
  • Non-exhaustive matches produce a runtime error
  • Type checker validates all arms return consistent types

2026-06-06 — v0.3: Syntax Redesign & Standard Library

Syntax Redesign

  • Replaced fn with fun, removed let/var keywords
  • name = expr creates immutable binding; mut name = expr creates mutable binding
  • := (colon-eq) for reassignment (instead of =)
  • if is now an expression (then/else both required, returns value)
  • else if handled via nested if in else block; elif keyword removed
  • Added |> pipe-right operator at lowest precedence (expr |> fun)
  • match keyword preserved with cleaner arm syntax

Standard Library — Method Calls

  • Added Expr::MethodCallobj.method(args) parsing with . precedence
  • String methods: len, trim, split, contains, starts_with, ends_with, to_upper, to_lower, is_empty
  • Array methods: push, pop, len, contains, is_empty
  • Map methods: get, set, remove, keys, values, len, contains, is_empty

Standard Library — Builtins

  • map_new() — create empty map
  • read_file(path) — read file contents as string
  • write_file(path, content) — write string to file
  • file_exists(path) — check file existence
  • json_parse(string) — parse JSON into Value
  • json_stringify(value) — serialize Value to JSON string
  • now() — current date/time as DateTime struct

Notable Bugfix

  • Fixed parse_match_expr failing on blank lines after match body, which caused recursive functions with match inside for loops to be undefined at runtime

Code Statistics

  • ~3500 lines of Rust
  • 8 source modules
  • v0.3: ~1100 new lines

License

MIT


Built with DeepSeek V4 Flash Free — an AI language model that can design, implement, and ship a programming language in a single conversation.

About

Rake: A pragmatic programming language with Pythonic syntax, static typing, and Rust-inspired safety. Built by DeepSeek V4 Flash Free.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages