TinyOne is the first major generation of TinyLang, a portable systems programming language designed around a compact VM, bounded runtime assumptions, stable host-integration direction, and a small reasoning surface.
TinyLang is not tiny because its syntax is minimal. It is tiny where systems usually become expensive: runtime footprint, allocator design, host assumptions, VM behavior, platform dependencies, and implementation burden.
The current Rust implementation includes a lexer, compiler, bytecode optimizer, verifier, portable VM, heap/runtime model, bytecode artifact support, adaptive execution support, host integration surfaces, CLI tooling, and early allocator-integration scaffolding.
Current crate version: 0.6.0.
The current Rust crate lives in TinyOne/ in this checkout. TinyLang is the
durable language identity. TinyOne is the current beta implementation line for
the intended v1 generation, not a separate language that users must relearn.
Future major generations may use names such as TinyTwo or TinyThree while
remaining generations of TinyLang.
Contents
- Source crate:
TinyOne/ - C FFI header:
tinylang.h - Public documentation:
docs/ - Design notes and future-direction documents:
Developer/ - Developer tools:
Tools/ - Allocator work-in-progress:
Ralloc/
TinyLang is pre-1.0 software. The language, bytecode format, builtin set, JSON artifacts, C ABI, and documentation process are still allowed to change while the implementation is being brought into line with the intended v1 surface.
TinyLang is designed to stay small at the architectural level, not necessarily at the syntax level.
The language may expose a broad syntax, many types, builtins, default syntax, VM/runtime support, host interop, and a growing standard library. The constraint is that each feature should preserve a compact operational model. When code, syscalls, assembly, platform assumptions, or runtime machinery can be removed without damaging reasoning or capability, they should be removed.
The largest implementation pieces may be the VM and memory allocator, but even those should remain compact, inspectable, and understandable. The goal is a capable language with a compact operational core that remains portable across systems.
TinyLang is intended to be a capable all-in-one language/runtime implementation with a compact operational core for:
- low-level programming
- high-level integration
- explicit memory and pointer work
- VM-enforced runtime safety
- deterministic non-GC cleanup direction
- practical multithreaded workloads
- compiler, bytecode, verifier, VM, JIT, FFI, and allocator education
TinyLang does not aim to hide unsafe operations. Operations that can affect memory, runtime state, pointer provenance, or host resources should be explicit and checked by the runtime wherever possible.
Build the Rust crate and CLI executable:
cargo build --manifest-path TinyOne/Cargo.toml
Run the repo-local CI/release gate from the repository root:
scripts/ci-gate.sh
The gate runs the practical current checks and reports removed-stdlib fallout
honestly instead of restoring or assuming a root stdlib/ tree.
This creates the debug executable at TinyOne/target/debug/tinylang. Build
with --release when you want the optimized executable at
TinyOne/target/release/tinylang. The Windows executable name is
tinylang.exe. The examples below assume the executable is available on
PATH as tinylang.
Run the command-line tool directly:
tinylang --help
Run a source file with the default adaptive JIT mode:
tinylang program.to
Run the same source through the portable VM:
tinylang --mode vm program.to
Compile and verify without running:
tinylang --check program.to
Emit bytecode and JIT listings:
tinylang --emit-bytecode program.tobc.json program.to tinylang --emit-jit program.jit.txt program.to
Run a bytecode artifact:
tinylang --run-bytecode program.tobc.json
The CLI supports:
usage: tinylang [OPTIONS] [path]
Options:
--mode {jit,vm} Execution mode (default: jit)
--check Compile only, do not run
--emit-bytecode PATH Write a bytecode artifact to PATH
--emit-jit PATH Write a JIT listing to PATH
--run-bytecode PATH Run a compiled bytecode artifact
--input VALUE Supply a program input value (repeatable)
--stdin Read input values from stdin
--verbose Print program metadata before running
-h, --help Show help
The implemented language currently includes:
- integer and string literals
nullletbindings- assignment to existing variables
- expression statements
printif,else if, andelsewhilebreakandcontinue- top-level
fndeclarations - top-level
structdeclarations - arrays
- strings as heap objects
- structs as heap objects
- pointer cells through
alloc,load,store, andunsafe free - raw pointers for objects, arrays, struct fields, buffers, and cells
- unsafe-gated pointer arithmetic, raw loads/stores, and buffer reads/writes
- imports with namespaces and
tinyone.jsonmanifest resolution - exported module declarations
- deterministic input through
--inputand--stdin - fixed-width runtime integer values for low-level memory work
- boolean operators
&&,||, and!producing0or1
Example:
fn add(left, right) {
return left + right
}
let answer = add(40, 2)
print answer
Current compiler constraints:
- functions and structs are top-level only
- functions must be defined before ordinary calls
- recursive self-calls are supported from inside the function body
- nested functions are rejected
- top-level executable statements are rejected inside imported modules
- imports must appear before declarations or executable statements
- functions may read earlier top-level variables, but direct assignment to top-level slots from inside functions is rejected
compile_filesupports import resolution;compile_sourcestyle APIs do not resolve imports because they compile anonymous source without a resolver
TinyLang runs through this pipeline:
source -> lexer -> compiler -> bytecode -> peephole optimizer -> verifier -> VM/JIT
The runtime includes:
- fixed-slot stack frames
- a generational heap slab
- heap references with generation checks
- raw pointer values with runtime provenance checks
- explicit manual deallocation through unsafe operations
- checked arithmetic and checked division
- resource limits for arrays, buffers, heap payload, heap object slots, nested calls, artifacts, verifier work, and filesystem reads
- shutdown heap draining through report APIs
TinyLang does not use a tracing garbage collector. The current runtime uses a VM-owned heap with generation validation and explicit unsafe deallocation. The longer-term design documents describe deterministic cleanup, indexed reference counting, global allocation-table authority, region-based lifetime batching, and Ralloc-backed allocation work.
TinyLang has two execution backends:
vm- Portable bytecode interpreter. It is the simpler backend and is the main reference path for behavior checks.
jit- Adaptive lowered-bytecode tier. It is not a native machine-code JIT. It compiles verified bytecode into internal JIT ops, caches compiled programs by fingerprint, emits inspectable listings, and quickens hot back edges.
Both public run paths verify bytecode before execution.
The crate builds as an rlib and cdylib. The C header is tinylang.h.
The FFI surface uses JSON-over-C-string entry points:
tinyone_lex_source_jsontinyone_compile_source_jsontinyone_compile_file_jsontinyone_run_source_jsontinyone_run_file_jsontinyone_run_artifact_jsontinyone_jit_listing_jsontinyone_free_string
Returned strings must be released with tinyone_free_string. The ABI is
explicitly unstable before v1.
The main documentation tree is docs/:
docs/index.mdroutes readers by audiencedocs/syntax/describes syntaxdocs/abi/describes ABI contracts and versioningdocs/ffi/describes C and Rust integrationdocs/architecture.mddescribes the pipeline and module mapdocs/bytecode.mddescribes opcodes, artifacts, verifier rules, and JITdocs/memory-model.mddescribes heap handles, pointer checks, and limitsdocs/stdlib.mddescribes builtins and stdlib bridge behaviordocs/v1-roadmap.mdtracks stable-ABI blockers
The change-document process is defined by the TinyLang documentation-change system:
TOR- TinyLang Request. A lightweight request for a change, fix, clarification, or improvement.
TOP- TinyLang Proposal. A structured design proposal for significant language, compiler, tooling, documentation, standard-library, ecosystem, or governance changes.
TOIN- TinyLang Implementation Notice. A release-facing or pre-release notice explaining what is being implemented, what changed, and how users should migrate.
The intended path is:
TOR -> TOP -> TOIN
Small accepted changes may go directly from TOR to TOIN. Major language changes should not skip the TOP stage.
Tools/hash.py- Stdlib-only file, tree, and manifest hashing tool for release manifests, audit checkpoints, and source-tree integrity checks.
Tools/loc.py- Small line-count and audit utility for source and documentation files.
Examples:
python3 Tools/hash.py README.rst python3 Tools/hash.py --tree . --format json --list-files python3 Tools/hash.py --check manifest.json python3 Tools/loc.py --audit --docs --json
This section intentionally records gaps between current implementation, documentation, tests, and earlier claims.
- The old README referred to
Rust/and rootstdlib/paths. The live Rust crate is currently underTinyOne/. - Some historical planning documents still use
Rust/Cargo.tomlcommand examples; active user-facing docs useTinyOne/Cargo.toml. - Some tests still assume a root
stdlib/tinyone.jsonmanifest. That rootstdlib/tree is intentionally absent in the current checkout while the standard-library surface moves into the runtime/system layer. - Historical release-helper examples may still assume
Rust/targetorRust/Cargo.toml. Active tooling should useTinyOne/and excludes currentTinyOne/targetandRalloc/targetbuild outputs by default. - Some docs describe raw pointer kinds such as
structandcellwhile the implementation uses object, array, buffer, field, and null pointer kinds. - Some docs describe generation changes as happening on free; the current heap increments generations when a slot is reused for allocation.
cargo test --manifest-path TinyOne/Cargo.tomlcurrently fails instdlib_modules_compile_via_manifest_importbecausestdlib/tinyone.jsonis missing.cargo test --manifest-path TinyOne/Cargo.toml --features testing-hookscurrently has testing-hook type drift: the test facade derivesEqfor a structure containingVec<RuntimeValue>whileRuntimeValueis onlyPartialEq, and the facade still hasProgram/Arc<Program>mismatch points.- The default crate build currently emits warnings for unused imports, variables, fields, methods, and staged heap variants.
- The C FFI smoke test depends on a built debug
cdyliband may skip when that library is not present.
- Enum syntax appears in fixtures, but the live lexer/parser do not implement
enumsyntax yet. - Type annotations, float literals, and boolean literal syntax appear in newer
fixture names, but the current lexer/parser do not implement
:,->, floats, ortrue/falselanguage syntax as first-class tokens. - Some 43-type runtime variants are representable but not fully behavior-wired.
Several newer heap/type paths still use explicit
unimplemented!stubs. - The static/hybrid type-system direction is documented, but a full static type checker is not implemented yet.
- The peephole optimizer is conservative. It folds branch-free constant arithmetic/comparison chunks and intentionally avoids chunks with jumps.
- The adaptive JIT is not native code generation.
thread_spawnsupport is VM-oriented today. The JIT context path does not appear to set the program reference needed bythread_spawn.- Mutex unlock currently checks locked/unlocked state but does not prove the unlocking thread is the owner.
TinyAllocatoris currently a tracking and hook scaffold. It does not yet back TinyLang heap allocations with real Ralloc native allocations.- The in-repository
Ralloc/tree is an embedded allocator workspace, but it is not wired as a dependency of the TinyLang crate. - The Phase 2 allocator documents call out required future work: real Ralloc backing, allocator sidecar storage, atomic table update during reallocate, larger/dynamic arena capacity, real thread ownership, and global allocation table state expansion.
Useful commands:
cargo check --manifest-path TinyOne/Cargo.toml cargo test --manifest-path TinyOne/Cargo.toml cargo test --manifest-path TinyOne/Cargo.toml --features testing-hooks cargo build --release --manifest-path TinyOne/Cargo.toml --bin tinylang-bench ./TinyOne/target/release/tinylang-bench cargo build --release --manifest-path TinyOne/Cargo.toml --bin tinylang-bench ./TinyOne/target/release/tinylang-bench --quick --repeats 1
Current state:
cargo check --manifest-path TinyOne/Cargo.tomlpasses, but with warnings.- The default test suite is not clean because of the missing root stdlib manifest.
- The feature-gated language fixture suite needs testing-hook repairs before it can be treated as a clean verification gate.
.
|-- README.rst
|-- LICENSE.md
|-- tinylang.h
|-- TinyOne/
| |-- Cargo.toml
| |-- src/
| |-- tests/
| `-- Cargo.lock
|-- docs/
| |-- abi/
| |-- ffi/
| |-- syntax/
| |-- architecture.md
| |-- bytecode.md
| |-- memory-model.md
| |-- stdlib.md
| `-- v1-roadmap.md
|-- Developer/
| |-- typing_system.md
| |-- ownership_semantics_and_memory_safety.md
| |-- phase_2.md
| `-- phase_2_allocator.md
|-- Tools/
| |-- hash.py
| `-- loc.py
`-- Ralloc/
|-- Cargo.toml
|-- src/
|-- include/
`-- tests/
The TinyOne/ directory name is still present on disk for the Rust crate.
The user-facing language name is TinyLang. TinyOne names this major generation
of the TinyLang implementation line.
The v1 direction is documented in docs/v1-roadmap.md and the design notes
under Developer/. Major themes include:
- stable JSON response schemas
- stable C ABI policy
- safer verified-program execution typing
- clearer public/private bytecode program ownership
- better test coverage for Phase 2 builtins and artifact limits
- static/hybrid type-system work
- explicit numeric semantics
- deterministic ownership and allocator integration
- documentation cleanup after the crate path move
See LICENSE.md.