Skip to content

Pluto is a compiled language that aims for the simplicity, readability and expressiveness of scripting languages with the safety and performance of C/C++, Go. A Go front‑end lowers .pt/.spt to LLVM IR and native binaries. Features include range‑driven auto‑vectorization, scope‑based memory (no nulls, no OOB, no GC), and concurrency by construction.

License

Notifications You must be signed in to change notification settings

thiremani/pluto

Repository files navigation

The Pluto Programming Language

Taking programming to another planet 🚀

Pluto is a compiled language that combines the clarity of scripting languages with the type-safety, performance, and determinism of systems languages.

Functions in Pluto are templates defined in .pt files. Call a template with different argument types and Pluto generates specialized native code for each — no generics syntax, no runtime dispatch. Write concise programs that compile into efficient, fully specialized executables.

Design highlights:

Purity: Functions have read-only inputs and writable outputs; structs are raw data with no hidden pointers.

Range-driven auto-vectorization, safe arrays and slices.

Scope-based memory (no nulls, no out-of-bounds, no GC), and concurrency by construction.


Highlights

  • Go front-end, LLVM back-end; emits native binaries
  • Template functions in .pt: specialized per argument types (generics by use)
  • Range literals with auto-vectorized execution
  • First-class arrays (safe slicing) and link semantics
  • Scope-based memory: no nulls, no out-of-bounds, no garbage collector
  • printf-style formatting; arrays/ranges printable
  • Cross-platform (Linux/macOS/Windows)

Quick example

Hello world (tests/helloworld.spt):

"hello world"
x = "hello 🙏"
x, "👍"

No main(), no print(), no imports. Values on a line get printed.

Compile and run:

./pluto tests/helloworld.spt
./tests/helloworld

Output:

hello world
hello 🙏 👍

Pluto can compile a single .spt file or an entire directory — each .spt produces a native executable.


How Pluto programs are structured

Pluto separates reusable templates from executable scripts:

Extension Purpose
.pt Template files — functions, operators, structs, constants (act as libraries)
.spt Script files — executable programs that compile to native binaries

A directory is the unit of compilation:

math/
├── math.pt      # defines Square, etc.
└── func.spt     # uses them → compiles to ./math/func

Compile and run:

./pluto math
./math/func

Templates and specialization

Templates are defined once with a clear input/output contract. The first line declares the output and input — the indented body describes the transformation.

Think of a template as a black box: data flows in through inputs, gets transformed, and flows out through outputs. Outputs work by reference — calling a template directly modifies the output variable in the caller's scope.

math.pt

# y is the output (writable), x is the input (read-only)
y = Square(x)
	y = x * x

Inputs are read-only — they flow in. Outputs are writable — they flow out. Every function is a transformation.

Generics by use

Call Square with different types — Pluto compiles a specialized version for each:

func.spt

a = Square(2)          # int specialization
b = Square(5.6)        # float specialization
arr = [1 2 3 4 5]
c = Square(arr)        # squares every element
d = Square(arr > 2)    # squares only elements where arr > 2
e = Square(1:5)        # range — executes Square over each value
a, b, c, d, e

No generics syntax, no type parameters. Write the template once — call it with a scalar, an array, or a filtered view. arr > 2 filters the array to elements greater than 2 and passes that subset through.

Generated code is equivalent to handwritten specialized code. There is no runtime overhead.


Ranges as the execution primitive

Ranges are first-class values:

Square(1:5)

Passing a range to a template executes it across all values. The compiler can map these operations to SIMD instructions — this is range-driven auto-vectorization.

Data-parallel execution without explicit loop syntax.


Arrays

Arrays use bracket syntax with no commas:

x = [1 2 3 4 5]
y = [1.1 2.2 3.3]

Arrays are safe by construction — out-of-bounds access is not possible. Comparisons like arr > 2 produce filtered views that work anywhere an array does.


Function model

Functions are pure transformations:

  • Inputs are read-only
  • Outputs are writable
  • Global constants allowed
  • No hidden mutation

This keeps behavior predictable and easier to parallelize.


Memory model

Pluto uses deterministic, scope-based memory:

  • No garbage collector
  • No null values
  • No out-of-bounds access
  • Memory freed when scope ends

Predictable performance with minimal runtime overhead.


Concurrency direction

Pluto is designed so that:

  • Structs are pure data
  • Functions are transformations
  • Inputs are read-only

This enables strong guarantees around race-free execution. The concurrency model is evolving but built around deterministic behavior.


Building and Running

Build the compiler:

go build -o pluto

Compile a directory:

./pluto tests           # Compiles all .spt files in tests/
./tests/helloworld      # Run the compiled executable

Run tests:

python3 test.py                              # Full E2E suite
python3 test.py --leak-check                 # Full suite + memory leak detection
go test -race ./lexer ./parser ./compiler    # Unit tests only

New project setup:

Add a pt.mod file at your project root to define the module path:

module github.com/you/yourproject

Pluto walks up from the working directory to find pt.mod and treats that directory as the project root.

Other commands:

  • ./pluto --version (or -v) — show version
  • ./pluto --clean (or -c) — clear cache for current version

Requirements

  • Go 1.25+
  • LLVM 21 tools on PATH: clang, opt, llc, ld.lld
  • Python 3.x (for running tests)
  • Leak check tools (only for python3 test.py --leak-check):
    • Linux: valgrind
    • macOS: leaks

Installation

Linux

Install LLVM 21 from apt.llvm.org:

wget https://apt.llvm.org/llvm.sh && chmod +x llvm.sh && sudo ./llvm.sh 21
sudo apt install lld-21
export PATH=/usr/lib/llvm-21/bin:$PATH

Build and test:

go build -o pluto
python3 test.py
macOS (Homebrew)
brew install llvm

Set PATH for your architecture:

# Apple Silicon
export PATH=/opt/homebrew/opt/llvm/bin:$PATH

# Intel
export PATH=/usr/local/opt/llvm/bin:$PATH

Build and test:

go build -o pluto
python3 test.py
Windows (MSYS2 UCRT64)

Install MSYS2 and use the "MSYS2 UCRT64" shell.

Install packages:

pacman -S --needed mingw-w64-ucrt-x86_64-{go,llvm,clang,lld,python}

Quick build:

python scripts/msys2_build.py

Or manual build with required environment:

export CGO_ENABLED=1
export CC=clang CXX=clang++
export GOFLAGS='-tags=byollvm'
export CGO_CPPFLAGS="$(llvm-config --cflags) -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS"
export CGO_CXXFLAGS="-std=c++17 $(llvm-config --cxxflags)"
export CGO_LDFLAGS="$(llvm-config --ldflags --libs all --system-libs)"
go build -o pluto.exe

Run tests:

python test.py

Notes:

  • On Windows the produced binary is pluto.exe.
  • The runtime enables %n on UCRT to match POSIX printf behavior.

Status

Pluto is under active development.

Working today:

  • 🎯 Template specialization
  • 📊 Arrays and ranges
  • 🖥️ Native binaries
  • 🧞‍♂️ Cross-platform builds

In progress:

  • 🧵 Concurrency model
  • 🧰 Tooling
  • 📘 Documentation

Philosophy

  • 💎 Purity by design — functions have read-only inputs and writable outputs; structs contain raw data with no hidden pointers
  • ✨ The simplicity of scripting
  • ⚡ The type safety and speed of low-level languages
  • 🧠 Deterministic memory
  • 🔧 Automatic specialization
  • 🔒 Predictable concurrency

Intended for performance-sensitive scripting, numerical work, simulation, and systems tools.


Repository structure

Path Description
main.go CLI entry point
ast/ Abstract syntax tree definitions
lexer/ Tokenizer with indentation-based syntax
parser/ Recursive descent parser
compiler/ Type solving, IR generation, LLVM emission
runtime/ Embedded C runtime linked into executables
tests/ End-to-end tests (.spt inputs, .exp expected outputs)

Architecture

  • Two phases: CodeCompiler parses .pt files and saves function templates and constants; ScriptCompiler compiles specialized versions for each usage in .spt files (if not already cached).
  • Automatic pipeline: generate IR → optimize -O3 via opt → object via llc → link with runtime via clang/lld — all handled transparently.
  • Module resolution: walks up from CWD to find pt.mod and derives module path.
  • Cache layout (versioned to isolate different compiler versions):
    • <PTCACHE>/<version>/runtime/<hash>/ for compiled runtime objects
    • <PTCACHE>/<version>/<module-path>/{code,script} for IR/objects

Troubleshooting

Common issues

undefined: run_build_sh during build (Windows):

  • Ensure GOFLAGS='-tags=byollvm' and CGO flags are set (see Windows installation above)

Missing LLVM tools:

  • Verify opt, llc, clang, ld.lld from LLVM 21 are on PATH

Stale cache behavior:

  • Clear current version: ./pluto --clean
  • Clear all versions:
    • macOS: rm -rf "$HOME/Library/Caches/pluto"
    • Linux: rm -rf "$HOME/.cache/pluto"
    • Windows: rd /s /q %LocalAppData%\pluto
  • Override cache location with PTCACHE environment variable

Encoding issues on Windows:

  • Run from the MSYS2 UCRT64 shell; the runner decodes output as UTF-8

Contributing

  • Commit style: Conventional Commits (e.g., feat(parser): ..., fix(compiler): ...)
  • PRs: include a clear description, linked issues, and tests for changes
  • Go formatting: go fmt ./...
  • Run tests before submitting: python3 test.py

License

Pluto is licensed under the MIT License. See LICENSE.

Vendored third-party code:

  • runtime/third_party/klib/ (klib by Attractive Chaos) — MIT License, see runtime/third_party/klib/LICENSE.txt

About

Pluto is a compiled language that aims for the simplicity, readability and expressiveness of scripting languages with the safety and performance of C/C++, Go. A Go front‑end lowers .pt/.spt to LLVM IR and native binaries. Features include range‑driven auto‑vectorization, scope‑based memory (no nulls, no OOB, no GC), and concurrency by construction.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 3

  •  
  •  
  •