Skip to content

pizlonator/zef

Repository files navigation

Zef Programming Language

Zef is a dynamically-typed, object-oriented scripting language with first-class functions, closures, and garbage collection. It combines a clean, expressive syntax with powerful features like class-based inheritance, nested classes, and a flexible package system.

Key Features

  • Class-Based Object-Oriented Programming - Full support for classes, inheritance, and method overriding
  • First-Class Functions - Functions are objects that can be passed around, stored in variables, and returned from other functions
  • Closures - Lexical scoping with closure capture for powerful functional programming patterns
  • Nested Classes - Classes can be defined inside other classes and methods, with access to outer scopes
  • Accessors - Convenient readable and accessible keywords for getter/setter generation
  • Packages - Namespace system for organizing code
  • Garbage Collection - Concurrent and parallel garbage collector
  • Static Members - Class-level variables and methods
  • Dynamic Inheritance - Class inheritance can be determined at runtime

Installation

Zef uses Meson as its build system.

Prerequisites

  • Fil-C++ version 0.678 or later
  • Meson build system
  • Ninja build tool

Building

# Clone the repository
git clone <repository-url>
cd zef

# Set up the build directory
CXX=/opt/fil/bin/fil++ meson setup build

# Compile
cd build && ninja

The compiled binary will be at build/zef.

Quick Start Guide

Variables

Declare variables with the my keyword:

my x = 42
my name = "Alice"
my pi = 3.14159

Functions

Define functions with the fn keyword:

# Function with parameters
fn greet(name) {
    println("Hello, " + name)
}

# Function returning a value
fn add(a, b) {
    a + b  # Last expression is returned
}

# Anonymous functions / lambdas
fn makeMultiplier(factor) {
    fn (x) x * factor  # Returns a closure
}

my double = makeMultiplier(2)
println(double(5))  # Output: 10

Classes

class Point {
    my x, y

    # Constructor
    fn (inX, inY) {
        x = inX
        y = inY
    }

    # Method with explicit return
    fn distanceFromOrigin {
        (x * x + y * y).sqrt
    }

    # Method returning expression directly
    fn toString "Point(" + x.toString + ", " + y.toString + ")"
}

my p = Point(3, 4)
println(p.toString)  # Output: Point(3, 4)

Inheritance

class Shape {
    fn area 0
}

class Circle : Shape {
    my radius

    fn (r) radius = r

    fn area 3.14159 * radius * radius
}

class Rectangle : Shape {
    my width, height

    fn (w, h) {
        width = w
        height = h
    }

    fn area width * height
}

my shapes = [Circle(5), Rectangle(3, 4)]
my i = 0
while (i < shapes.size) {
    println(shapes[i].area)
    i += 1
}

Accessors

Zef provides convenient accessors for properties:

class Person {
    readable name       # Read-only property with auto getter
    accessible age      # Read-write property with getter and setter
    static my count = 0 # Static class variable

    fn (inName) {
        name = inName
        age = 0
        Person.count += 1
    }
}

my p = Person("Alice")
println(p.name)      # OK: reading readable property
# p.name = "Bob"     # Error: cannot write to readable

p.age = 25           # OK: writing to accessible
println(p.age)       # OK: reading accessible

println(Person.count) # Access static via class

Arrays

my nums = [1, 2, 3]
nums.push(4)
nums.push(5)

println(nums)        # Output: [1, 2, 3, 4, 5]
println(nums[0])     # Output: 1 (zero-indexed)
println(nums.size)   # Output: 5

nums[2] = 100
println(nums)        # Output: [1, 2, 100, 4, 5]

Packages

Organize your code with packages:

package math {
    fn add(a, b) a + b
    fn subtract(a, b) a - b

    package geometry {
        class Point {
            my x, y
            fn (a, b) { x = a; y = b }
            fn toString "(" + x.toString + ", " + y.toString + ")"
        }
    }
}

# Use package members
println(math.add(2, 3))
my p = math.geometry.Point(1, 2)
println(p.toString)

# Packages can be extended
package math {
    fn multiply(a, b) a * b
}

Control Flow

# If statements
my x = 42
if (x > 50) {
    println("big")
} else if (x > 25) {
    println("medium")
} else {
    println("small")
}

# While loops
my i = 0
while (i < 5) {
    println(i)
    i += 1
}

Nested Classes and Closures

Zef supports powerful patterns combining nested classes with closures:

fn makeCounter {
    my count = 0

    class Counter {
        fn () { }  # Constructor

        fn increment {
            count += 1
            count
        }

        fn decrement {
            count -= 1
            count
        }

        fn get count
    }

    Counter()
}

my c1 = makeCounter()
my c2 = makeCounter()

println(c1.increment)  # 1
println(c1.increment)  # 2
println(c2.increment)  # 1 (separate closure)

Dynamic Inheritance

Zef allows runtime determination of base classes:

fn makeBaseClass(value) {
    class Base {
        readable val
        fn () val = value
    }
    Base
}

my x = 42
class MyClass : if (x == 42) makeBaseClass(100) else makeBaseClass(200) {
    fn () super()
}

println(MyClass().val)  # Output: 100

Running Tests

The project includes a comprehensive test suite. Tests are run using the run-tests Ruby script:

# Build first
CXX=/opt/fil/bin/fil++ meson setup build && ninja -C build

# Run all tests
./run-tests

# Run with verbose output
./run-tests --verbose

# Run without strict error matching
./run-tests --no-strict-error

Tests are located in the tests/ directory. Each test file has:

  • .zef - The test script
  • .zef.expected - Expected output (for success tests)
  • .zef.error - Expected error message (for error tests)
  • .zef.memlimit - Optional memory limit in kB (for GC tests)

Running Programs

./build/zef myprogram.zef

Examples

See the tests/ directory for many examples of Zef code, including:

  • deltablue.zef - Constraint solver benchmark
  • richards.zef - Operating system simulator benchmark
  • nbody.zef - N-body physics simulation
  • splay.zef - Splay tree benchmark

About

Zef Programming Language

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors