A small, readable scripting language with three execution engines.
Dynamic typing · try/oops exceptions · classes with shared identity · a tree-walk interpreter, a bytecode VM, and an optional native-C compiler.
- Why QuantoScript?
- Installation
- Quick Start
- Language Tour
- Execution Engines
- Compiled Bytecode (
.qvm) - Native Compiler
- Standard Library
- Command-Line Interface
- Package Manager
- Building from Source
- Project Structure
- Known Limitations
- Roadmap
- Contributing
- License
QuantoScript is a small, embeddable scripting language designed for readability and simplicity — think Python's clarity with a simpler, brace-based syntax. It ships with three execution engines: a tree-walk interpreter for fast iteration, a bytecode VM for performance, and an optional native-C compiler for compute-heavy numeric code.
| Braces, not indentation | Blocks are delimited with { } — no significant whitespace. |
| Friendly keywords | maybe instead of elif, oops instead of except. |
| 1-based indexing | Lists and strings start at index 1. |
| Shared object identity | Class instances are references, not copies. |
| Matching engines | The same program runs on the interpreter or the bytecode VM with identical output. |
| Native fast-path | Arithmetic-heavy code can compile to C for a ~10× speedup. |
| Single-file core | The whole language is one C99 amalgamation — easy to embed and vendor. |
The fastest way to get QuantoScript is the one-line installer. It downloads a
prebuilt, self-contained binary (OpenSSL bundled in — no dependencies to install),
places it under ~/.quanto, and adds it to your PATH. No compiler and no sudo
required.
curl -fsSL https://raw.githubusercontent.com/PySudo/QuantoScript/main/install.sh | shirm https://raw.githubusercontent.com/PySudo/QuantoScript/main/install.ps1 | iexThen open a new terminal and run qs --help.
Prebuilt binaries are provided for macOS (Apple Silicon), Linux (x86-64), and Windows (x86-64). On Intel Macs and ARM64 Linux, the installer will ask you to build from source until binaries for those platforms are published.
Installer options
macOS / Linux (install.sh)
# Install a specific version
curl -fsSL https://raw.githubusercontent.com/PySudo/QuantoScript/main/install.sh | sh -s -- --version 1.1.3
# Custom install prefix (default: ~/.quanto)
QUANTO_INSTALL="$HOME/.local" curl -fsSL .../install.sh | sh
# Don't touch your shell profile
NO_MODIFY_PATH=1 curl -fsSL .../install.sh | sh
# Uninstall
curl -fsSL https://raw.githubusercontent.com/PySudo/QuantoScript/main/install.sh | sh -s -- --uninstallWindows (install.ps1)
# Install a specific version
& ([scriptblock]::Create((irm https://raw.githubusercontent.com/PySudo/QuantoScript/main/install.ps1))) -Version 1.1.3
# Uninstall
& ([scriptblock]::Create((irm https://raw.githubusercontent.com/PySudo/QuantoScript/main/install.ps1))) -UninstallPrefer to build it yourself? See Building from Source.
Already installed? Skip straight to Hello World. Otherwise build the interpreter with
make (see Building from Source for OpenSSL notes).
qs examples/full_tour.qs # run a script
qs # or drop into the REPLHello, World!
print("Hello, World!")
func greet(name) {
return "Hello, " + name + "!"
}
print(greet("QuantoScript"))
qs hello.qs # tree-walk interpreter
qs vm hello.qs # bytecode VM (identical output)x = 42 # integer
pi = 3.14 # float
name = "QS" # string
flag = true # boolean
nothing = null # null
items = [1, 2, 3] # list
user = {"name": "QS"} # map
func add(a, b) {
return a + b
}
print(add(3, 4)) # 7
double = fn(x) -> x * 2 # lambda expression
print(double(5)) # 10
if x > 10 {
print("big")
} maybe x > 5 { # "maybe" == "else if"
print("medium")
} else {
print("small")
}
repeat 5 { i = i + 1 } # counted loop
while x < 100 { x = x * 2 } # conditional loop
func safe_div(a, b) {
if b == 0 {
oops("division by zero") # raise
}
return a / b
}
try {
print(safe_div(10, 0))
} oops e { # catch, binding the error to `e`
print("caught: " + e)
}
class Person {
init(name) {
self.name = name
}
greet() {
print("Hi, I'm " + self.name)
}
}
p = Person("Alice")
p.greet() # Hi, I'm Alice
c = p # c and p reference the SAME object
c.name = "Bob"
p.greet() # Hi, I'm Bob
Note: Put each statement in a method body on its own line — semicolon-separated statements are not supported.
nums = [3, 1, 4, 1, 5]
print(len(nums)) # 5
nums.append(9)
print(nums.contains(4)) # true
user = {"name": "QS", "version": 1}
print(user["name"]) # QS
print(user.keys()) # [name, version]
Built-in methods
| Type | Methods |
|---|---|
| String | title · contains · replace · startsWith · endsWith · split · join · indexOf · substring · trimStart · trimEnd · repeat · reverse |
| List | append · extend · sort · contains · flatten · map · filter · find · find_type · sum |
| Map | keys · values · items · has · remove · extend |
len(value) is a built-in function (not a method) that works on strings and lists.
See The QuantoScript Guide for the complete language reference.
The interpreter and the bytecode VM run the same source and produce identical output.
| Engine | Command | Best for |
|---|---|---|
| Tree-walk interpreter | qs program.qs |
Development, debugging, quick scripts |
| Bytecode VM | qs vm program.qs |
Better runtime performance |
| Native C compiler | qs native program.qs |
~10× speedup on arithmetic-heavy code |
Compile QuantoScript to a stable binary bytecode format for faster startup and distribution without shipping source.
qs build program.qs # -> program.qvm
qs build program.qs -o custom.qvm # custom output path
qs vm program.qvm # run compiled bytecode
qs vm --dump-bytecode program.qs # disassemble for debuggingThe .qvm format (version 4) includes a magic-header check, version validation,
and a CRC32 checksum of the source, and it rejects malformed files. See
Bytecode and Native Builds for details.
For arithmetic-heavy workloads, QuantoScript can emit C and compile it to a native binary:
qs native program.qs # emit a_native.c
gcc -O2 a_native.c -o program_native
./program_nativeSupported: integer arithmetic, if/else, while, repeat, variable assignment,
print.
Not supported: functions, strings, lists, maps, closures, classes, exceptions.
Import modules with from "<module>" import <names>. Public modules live in stdlib/;
internal runtime hooks (sys_*) stay hidden.
User code → stdlib modules → native runtime → OS
from "stdlib/http.qs" import get, post
from "stdlib/json.qs" import parse, stringify
from "stdlib/os.qs" import run, capture, cwd, chdir, exists
from "stdlib/fs.qs" import read, write, list_dir
from "stdlib/text.qs" import lower, upper, split
from "stdlib/time.qs" import now, localtime
from "stdlib/log.qs" import info, warn, error
from "stdlib/websocket.qs" import connect, send, recv, close
Examples
# HTTP
from "stdlib/http.qs" import get
resp = get("https://httpbin.org/get")
print(resp)
# JSON
from "stdlib/json.qs" import parse
data = parse("{\"key\": \"value\"}")
# Process execution
from "stdlib/os.qs" import run, capture, exists
run("echo Hello") # returns exit code
version = capture("git --version") # returns stdout
print(exists("gcc")) # true / false
| Module | Purpose |
|---|---|
core.qs |
Environment-variable helpers (env) |
math.qs |
Numeric utilities |
text.qs |
String processing |
fs.qs |
File system operations |
os.qs |
Process execution & working directory |
http.qs |
HTTP client (get, post, put, delete, patch) |
net.qs |
Low-level networking |
websocket.qs |
WebSocket client |
json.qs |
JSON parse / stringify |
url.qs |
URL percent-encoding (url_encode, url_decode) |
time.qs |
Time and clock operations |
log.qs |
Structured logging |
random.qs |
Pseudo-random numbers |
async.qs |
Task queue (experimental — see Known Limitations) |
At runtime, stdlib modules are resolved via the QUANTO_HOME environment variable.
Run qs home to print the configured location. See
Imports for how paths are resolved.
qs interactive REPL
qs <file.qs> run with the tree-walk interpreter
qs run <file.qs|.qvm> run with the bytecode VM
qs vm <file.qs|.qvm> run with the bytecode VM (alias for run)
qs build <file.qs> [-o out.qvm] compile to .qvm bytecode
qs native <file.qs> emit native C (a_native.c)
qs compile <file.qs> [out] compile to a native binary
qs init scaffold a new project
qs check <file.qs> validate syntax without executing
qs fmt <file.qs> format source code
qs lint <file.qs> report common mistakes
qs doc <file.qs> generate documentation from comments
qs profile <file.qs> profile function calls
qs test [directory] run *_test.qs files
qs install <github-url> install a package
qs list list installed packages
qs remove <package> remove a package
qs home print the QUANTO_HOME directory
qs version print the version
Flags
--dump-bytecode print compiled bytecode to stderr
--trace print a per-instruction VM trace
--sandbox [path] restrict file access to the given path
QuantoScript has a built-in, git-backed package manager. Packages are cloned from
GitHub into a local packages/ directory, and their quanto.json dependencies are
resolved recursively.
qs install https://github.com/owner/repo
qs list
qs remove repofrom "packages/owner_repo/main.qs" import something
Scaffold a project with a manifest via qs init, which creates main.qs,
a test/ directory, and a quanto.json.
QuantoScript is a single C99 amalgamation (src/quanto.c). It requires a C compiler
and OpenSSL (used by the HTTP/WebSocket stack). Networking libraries differ per
platform.
| Platform | Toolchain | OpenSSL |
|---|---|---|
| macOS | Xcode Command Line Tools (clang) or gcc |
brew install openssl@3 |
| Linux | gcc / clang |
libssl-dev (Debian/Ubuntu) or openssl-devel (Fedora) |
| Windows | MSYS2 / MinGW-w64 gcc |
pacman -S mingw-w64-ucrt-x86_64-openssl |
Homebrew installs OpenSSL outside the default search path, so point the compiler at it:
SSL=$(brew --prefix openssl@3)
cc -std=c99 -O2 -Isrc -I"$SSL/include" src/quanto.c -o qs \
-L"$SSL/lib" -lssl -lcrypto -lpthread -lmgcc -std=c99 -O2 -Isrc src/quanto.c -o qs \
-lssl -lcrypto -lpthread -ldl -lmgcc -std=c99 -O2 -Isrc src/quanto.c -o qs.exe \
-lssl -lcrypto -lws2_32 -lwinhttp -lwininet -lcrypt32 -lbcrypt -lregexThe
-lregexflag (packagemingw-w64-ucrt-x86_64-libsystre) enables the real regular-expression back-end forregex_match/regex_find/regex_replace. It is optional: without it those built-ins fall back to literal substring matching. TheMakefiledetects it automatically.
The Makefile auto-detects OpenSSL (Homebrew on macOS, pkg-config elsewhere):
make # build build/qs
make test # build and run the regression suite
make clean # remove build artifactsUseful overrides:
make OPENSSL_DIR=/path/to/openssl # point at a specific OpenSSL prefix
make STATIC_SSL=1 # statically link OpenSSL (self-contained binary)
make CC=clang # choose the compilercmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build
# Optional: self-contained binary and packaging
cmake -S . -B build -DQS_STATIC_OPENSSL=ON && cmake --build build
cpack --config build/CPackConfig.cmake # produce a .tar.gz / .zipBuilding with -DQS_PYTHON and the Python headers enables the Python FFI examples.
src/ C source (single-file amalgamation)
quanto.c Entry point that includes the parts below
parts/ Language modules (.inc): parser, VM, compiler, runtime, CLI, …
stdlib/ Standard library modules (.qs)
examples/ Example programs (see full_tour.qs)
tests/ Regression and stress test suite
docs/guide/ The QuantoScript Guide (language documentation)
tools/ Benchmarks, CMake helpers, packaging metadata
scripts/ Build and install scripts
build/ Build output (gitignored)
This is a v1.1.3 release. The following are known and tracked:
- Closures that capture an enclosing function's local variables work in the
tree-walk interpreter but not in the bytecode VM, which reports an unknown variable.
Nested
funcdeclarations are not supported. - Class method bodies take one statement per line; semicolon-separated statements are not supported.
- Return type annotations are parsed but not yet enforced.
- Async/await is not functional. The
stdlib/async.qstask queue hangs with two or more tasks and can crash non-deterministically under load. Single-taskspawn/run/resultwork. See Standard Library § async. - Python embedding requires the
-DQS_PYTHONbuild flag and Python headers.
| Version | Focus |
|---|---|
| v1.2.0 | Working closures, richer string/map methods |
| v2.0.0 | Async/await, broader native-compiler coverage |
Issues and pull requests are welcome. See CONTRIBUTING.md for guidelines and CHANGELOG.md for release history. When submitting changes, please run the regression suite first:
make testReleased under the MIT License.