Skip to content

lantos1618/zenlang

Repository files navigation

Zen Programming Language

LANGUAGE_SPEC.zen IS THE SOURCE OF TRUTH

A revolutionary programming language with ZERO KEYWORDS. All control flow through pattern matching (?), UFC (Uniform Function Call), and powerful metaprogramming.

"No keywords. Pure expression. Allocator-driven concurrency."

Project Status

The Zen language has achieved significant progress with core language features working well. The project maintains a strong test suite and continues to evolve toward a complete implementation of the zero-keywords design philosophy.

Core Design Principles

From LANGUAGE_SPEC.zen:

  1. No keywords - No if/else/while/for/match/async/await/impl/trait/class/interface/null
  2. Only two @ symbols - @std (standard library) and @this (current scope)
  3. Pattern matching with ? - Replaces all conditional keywords
  4. UFC (Uniform Function Call) - Any function can be called as method
  5. Allocators determine sync/async - No function coloring
  6. Explicit pointer types - Ptr<>, MutPtr<>, RawPtr<> (no * or &)
  7. No null/nil - Only Option<T> with .Some(T) and .None
  8. No unions, no tuples - Only structs and enums
  9. Assignment operators - = (immutable), ::= (mutable), : (type definition)
  10. Error propagation - .raise() not exceptions
  11. Loops - loop() for infinite, .loop() for collections, ranges like (0..10)
  12. Traits - via .implements() and .requires() from @std.meta
  13. Compile-time metaprogramming - Full AST access

Quick Start

# Build the compiler
cargo build --release

# Run a Zen program
cargo run --bin zen <file.zen>

# Run showcase example
cargo run --bin zen examples/showcase.zen

# Run test suite
cargo test --all

Documentation

For contributors, see the docs/design/ folder:

  • ARCHITECTURE.md - LLVM primitives vs Zen-level features
  • STDLIB_DESIGN.md - Standard library architecture
  • SAFE_POINTERS_DESIGN.md - Ptr type-safety design

Language Features by Example

All examples directly from LANGUAGE_SPEC.zen.

Variables - Six Forms, No Keywords

// From LANGUAGE_SPEC.zen lines 299-306
x: i32               // Forward declaration (immutable)
x = 10               // Assignment
y = 10               // Immutable assignment (type inferred)
z: i32 = 20          // Immutable with type
w:: i32              // Mutable forward declaration
w = 20               // Assignment
v ::= 30             // Mutable assignment (type inferred)
u:: i32 = 40         // Mutable with type

Pattern Matching - Replaces All Conditionals

// Boolean patterns (lines 352-361)
is_ready = true
is_ready ? { 
    io.println("Starting game!") 
}

has_data = false
has_data ?
    | true { process_data() }
    | false { io.println("Waiting for data...") }

// Enum patterns (lines 325-335)
entity ?
    | Player { 
        io.println("Player health: ${entity.get_health()}")
    }
    | Enemy { 
        io.println("Enemy health: ${entity.get_health()}")
    }

Structs and Enums

// Struct definition (lines 117-120)
Point: {
    x:: f64,         // Mutable field
    y:: f64 = 0      // With default value
}

// Enum (sum type) definition (line 166)
Shape: Circle, Rectangle

// Enum with variants for overloading (line 172)
GameEntity: Player, Enemy, Powerup

Traits - Behavioral Types

// Trait definition (lines 123-127)
Geometric: {
    area: (self) f64,
    perimeter: (self) f64,
}

// Implementation (lines 136-143)
Circle.implements(Geometric, {
    area = (self) f64 {
        return math.pi * self.radius * self.radius
    },
    perimeter = (self) f64 {
        return 2.0 * math.pi * self.radius
    },
})

// Requirement (line 168)
Shape.requires(Geometric)  // All Shape variants must implement Geometric

UFC (Uniform Function Call)

// UFC overloading based on enum variants (lines 174-181)
get_health = (e: GameEntity.Player) u32 { return 100 }
get_health = (e: GameEntity.Enemy) u32 { return 50 }
get_health = (e: GameEntity.Powerup) u32 { return 0 }

// Can call as:
player.get_health()  // UFC style
get_health(player)   // Traditional style

Option and Result - No Null

// Option type (line 110)
Option<T>: Some: T, None

// Result type (line 113)
Result<T, E>: Ok: T, Err: E

// Option handling (lines 462-473)
maybe_radius: Option<f64> = Some(5.5)
maybe_radius ?
    | Some(r) {
        circle = Circle { center: Point { x: 100, y: 100 }, radius: r }
        io.println("Created circle with area: ${circle.area()}")
    }
    | None {
        io.println("No radius provided")
    }

Error Propagation with .raise()

// Error propagation (lines 206-211)
load_config = (path: string) Result<Config, Error> {
    file = File.open(path).raise()      // If Err, returns early
    contents = file.read_all().raise()   // Propagates errors
    config = json.parse(contents).raise()
    return Ok(config)
}

Loops and Ranges

// Range iteration (lines 432-434)
(0..10).loop((i) {
    io.println("Count: ${i}")
})

// Step ranges (lines 437-439)
(0..100).step(10).loop((i) {
    io.println("Step: ${i}")  // 0, 10, 20, ...
})

// Collection iteration with UFC (lines 442-445)
shapes.loop((shape) {
    total_area = total_area + shape.area()
})

// Infinite loop (lines 453-459)
counter ::= 0
loop(() {
    counter = counter + 1
    counter > 10 ?
        | true { break }
        | false { continue }
})

Allocator-Driven Concurrency

// Multisync function - sync or async based on allocator! (lines 215-224)
fetch_game_data = (url: string, alloc: Allocator) Result<Data, Error> {
    client = HttpClient(alloc)  // Behavior determined by allocator
    @this.defer(client.deinit())
    
    // This blocks or doesn't based on allocator!
    response = client.get(url)
    response ?
        | Ok(data) { return Ok(parse_data(data)) }
        | Err(e) { return Err(e) }
}

// Usage (lines 308-314)
sync_alloc = GPA.init()        // Sync allocator - everything blocks
async_alloc = AsyncPool.init() // Async allocator - non-blocking

Pointers - Explicit, No Symbols

// Explicit pointer types (lines 364-371)
circle = Circle { center: Point { x: 100, y: 100 }, radius: 50 }
circle_ptr: Ptr<Circle> = circle.ref()          // Immutable pointer
circle_mut: MutPtr<Circle> = circle.mut_ref()   // Mutable pointer

io.println("Circle area: ${circle_ptr.val.area()}")  // .val to dereference
circle_mut.val.radius = 75                           // Modify through pointer
io.println("Address: ${circle_ptr.addr}")            // Access address

Metaprogramming and Reflection

// Runtime reflection (lines 244-272)
inspect_type = (T: type) void {
    ast = reflect.ast(T)
    ast.kind ?
        | Struct(s) {
            io.println("Struct: ${s.name}")
            s.fields.loop((f) {
                io.println("  Field: ${f.name}: ${f.type}")
            })
        }
        | Enum(e) {
            io.println("Enum: ${e.name}")
            e.variants.loop((v) {
                io.println("  Variant: ${v.name}")
            })
        }
}

// Compile-time AST modification (lines 275-281)
@meta.comptime((){
    original = reflect.ast(parse_radius)
    new_body = original.body.prepend(
        AST.Call("io.println", ["Parsing radius from: ${s}"])
    )
    meta.replace(parse_radius, original.with_body(new_body))
})

Concurrency Primitives

// Actors for lazy/streaming iteration (lines 228-240)
create_fibonacci = () Actor {
    outer = 100  // Captured automatically
    return Actor((receiver) {
        a ::= 0
        b ::= 1
        loop(() {
            receiver.send(a + outer)
            temp = a + b
            a = b
            b = temp
        })
    })
}

// Channels (lines 397-412)
message_chan = Channel<string>(10)  // Buffered channel
@this.defer(message_chan.close())

// Mutex (lines 415-423)
counter_mutex = Mutex<u32>(0)
counter_mutex.lock() ?
    | Ok(val) {
        val = val + 1
        counter_mutex.unlock()
    }
    | Err(e) { io.println("Lock failed: ${e}") }

// Atomics (lines 426-429)
atomic_counter = AtomicU32(0)
atomic_counter.fetch_add(1)

Mixed Type Vectors

// DynVec can hold multiple variant types! (lines 316-335)
entities = DynVec<GameEntity.Player, GameEntity.Enemy>(sync_alloc)
entities.push(GameEntity.Player)
entities.push(GameEntity.Enemy)

// Loop over mixed types with pattern matching
entities.loop((entity) {
    entity ?
        | Player { io.println("Player health: ${entity.get_health()}") }
        | Enemy { io.println("Enemy health: ${entity.get_health()}") }
})

Module System

// Imports (lines 92-106)
{ io, maths } = @std
{ String, StringBuilder } = @std
{ Vec, DynVec } = @std

// Module exports (lines 492-502)
module.exports = {
    Shape: Shape,
    Circle: Circle,
    Rectangle: Rectangle,
    get_health: get_health,
}

// Imports in other files
Circle2D = module.import("shapes2d").Circle
shapes = module.import("shapes2d")

Build System

Current: Makefile + Cargo

The Zen compiler itself is built using Cargo (Rust's build system) with a Makefile wrapper for convenience:

  • make build or cargo build - Build the compiler
  • make test or cargo test - Run test suite
  • make lint - Run linter

The compiler is built with cargo and make. The build.zen system is a future, self-hosted goal and is not yet functional.

See the docs/design/ folder for architecture details.

Future: Self-Hosted build.zen

The long-term vision is a self-hosted build system written in Zen. Example build.zen files exist in tools/ and examples/ as demonstrations only, but the compiler cannot yet execute them. This is a future goal, not current functionality.

Implementation Status

Current Status: 90% Language Core Complete | Active Development

Test Suite

Run tests with cargo test --all. See tests/ for integration tests and tests/lsp/ for LSP feature tests.

Project Structure

  • / - Root contains LANGUAGE_SPEC.zen and configuration
  • /src/ - Compiler source (Rust/LLVM)
  • /stdlib/ - Standard library modules (Zen code)
  • /tests/ - Integration and unit tests
  • /examples/ - Example programs including showcase.zen
  • /docs/ - Documentation (including design/ subfolder)
  • /tools/ - Future self-hosted tooling (non-functional)

Working Features

  • Zero keywords design - Complete
  • Pattern matching with ? - All forms working
  • All 6 variable forms - Immutable/mutable, typed/inferred
  • Basic types - i8/i16/i32/i64, f32/f64, bool, string
  • Structs and enums - Full support with payloads
  • UFC - Method chaining and overloading
  • String interpolation - "${expr}" syntax
  • String methods - .len(), .substr(), .char_at(), .split(), .to_i32(), .to_i64(), .to_f64(), .trim(), .contains(), .starts_with(), .ends_with(), .index_of()
  • ⚠️ Range iteration - (0..10).loop(), (1..=5).loop() (parser issue: currently executes once instead of iterating)
  • Range structs - Can store and use ranges as values
  • Infinite loops - loop() with break/continue
  • Block expressions - Return last expression
  • Closures - Arrow functions with captures
  • Enum patterns - Both Enum.Variant and .Variant
  • Option - Some/None with pattern matching
  • Result<T,E> - Ok/Err with basic support
  • Error propagation - .raise() extracts values correctly
  • Vec - Growable vector with push/pop/get
  • Allocator system - GPA allocator with Allocator trait
  • Behaviors system - Structural contracts without keywords
  • Core intrinsics (13) - Memory allocation, pointer arithmetic, enum operations

Partially Working

  • ⚠️ Generic instantiation - Basic Result/Option work, complex nested types need work
  • ⚠️ Result<T,E> returns - Pattern matching works, function returns have type mismatch

Partially Implemented

  • ⚠️ Pointer wrappers - Ptr, MutPtr, RawPtr defined but need more testing
  • ⚠️ comptime blocks - Parsed and executed, but don't generate code

Not Yet Implemented (Stubs Only)

  • Collections - HashMap, Set, Queue, Stack are stubs with TODO placeholders
  • inline_c() - Returns void, needs Clang integration
  • Dynamic FFI - load_library/get_symbol return errors
  • Atomic operations - Defined but no LLVM codegen
  • sizeof/alignof - Compile-time only, sizeof hardcoded to 8
  • Actor model - Message passing concurrency (design only)
  • Channels - CSP-style concurrency (design only)
  • Module exports - module.exports/import syntax
  • Build system - Self-hosted build.zen
  • Iterator trait - Manual index loops required

Contributing

This project implements the specification in LANGUAGE_SPEC.zen. All contributions must align with this specification.

License

MIT

About

The first fully made programming language by Claude

Resources

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •  

Languages