Snail programming language interpreter
Project description
Snail
What do you get when you shove a snake in a shell?
Snail, while I hope it is useful to myself and others, is my attempt at improving my knowledge of AI code developement. Things are probably broken in interesting and horrible ways.
Snail is a programming language that compiles to Python, combining Python's power with Perl/awk-inspired syntax for quick scripts and one-liners. No more whitespace sensitivity—just curly braces and concise expressions.
✨ What Makes Snail Unique
Curly Braces, Not Indentation
Write Python logic without worrying about tabs vs spaces:
def process(items) {
for item in items {
if item > 0 { print(item) }
else { continue }
}
}
Built-in Subprocess Pipelines
Shell commands are first-class citizens with $() capture and | piping:
# Capture command output with interpolation
name = "world"
greeting = $(echo hello {name})
# Pipe data through commands
result = "foo\nbar\nbaz" | $(grep bar) | $(cat -n)
# Check command status
@(make build)? # returns exit code on failure instead of raising
Compact Error Handling
The ? operator makes error handling terse yet expressive:
# Swallow exception, get the error object
err = risky_operation()?
# Provide a fallback value (exception available as $e)
value = parse_json(data):{}?
details = fetch_url(url):"Error: {$e}"?
# Access attributes directly
name = risky()?.__class__.__name__
args = risky()?.args[0]
Regex Literals
Pattern matching without import re:
if email in /^[\w.]+@[\w.]+$/ {
print("Valid email")
}
# Compiled regex for reuse
pattern = /\d{3}-\d{4}/
match = pattern.search(phone)
Awk Mode
Process files line-by-line with familiar awk semantics:
#!/usr/bin/env -S snail --awk -f
BEGIN { total = 0 }
/^[0-9]+/ { total = total + int($f[0]) }
END { print("Sum:", total) }
Built-in variables: $l (line), $f (fields), $n (line number), $fn (per-file line number), $p (file path), $m (last match).
Pipeline Operator
The | operator enables data pipelining through objects that implement __pipeline__:
# Pipe data to subprocess stdin
result = "hello\nworld" | $(grep hello)
# Chain multiple transformations
output = "foo\nbar" | $(grep foo) | $(wc -l)
# Custom pipeline handlers
class Doubler {
def __pipeline__(self, x) { return x * 2 }
}
doubled = 21 | Doubler() # yields 42
JSON Queries with JMESPath
Parse and query JSON data with the json() function and structured pipeline accessor:
# Parse JSON and query with $[jmespath]
data = json($(curl -s api.example.com/users))
names = data | $[users[*].name]
first_email = data | $[users[0].email]
# Inline parsing and querying
result = json('{"foo": 12}') | $[foo]
Full Python Interoperability
Snail compiles to Python AST—import any Python module, use any library:
import pandas as pd
from pathlib import Path
df = pd.read_csv(Path("data.csv"))
filtered = df[df["value"] > 100]
🚀 Quick Start
# Install from PyPI
pip install snail
# Run a one-liner
snail "print('Hello, Snail!')"
# Execute a script
snail -f script.snail
# Awk mode for text processing
cat data.txt | snail --awk '/error/ { print($l) }'
🏗️ Architecture
Snail compiles to Python through a multi-stage pipeline:
flowchart TB
subgraph Input
A[Snail Source Code]
end
subgraph Parsing["Parsing (Pest PEG Parser)"]
B1[crates/snail-parser/src/snail.pest<br/>Grammar Definition]
B2[crates/snail-parser/<br/>Parser Implementation]
end
subgraph AST["Abstract Syntax Tree"]
C1[crates/snail-ast/src/ast.rs<br/>Program AST]
C2[crates/snail-ast/src/awk.rs<br/>AwkProgram AST]
end
subgraph Lowering["Lowering & Code Generation"]
D1[crates/snail-lower/<br/>AST → Python AST Transform]
D2[python/snail/runtime/<br/>Runtime Helpers]
D3[crates/snail-codegen/<br/>Python AST → Source Code]
end
subgraph Execution
E1[python/snail/cli.py<br/>CLI Interface]
E2[pyo3 extension<br/>in-process exec]
end
A -->|Regular Mode| B1
A -->|Awk Mode| B1
B1 --> B2
B2 -->|Regular| C1
B2 -->|Awk| C2
C1 --> D1
C2 --> D1
D1 --> D2
D1 --> D3
D2 --> D3
D3 --> E1
E1 --> E2
E2 --> F[Python Execution]
style A fill:#e1f5ff
style F fill:#e1ffe1
style D2 fill:#fff4e1
Key Components:
- Parser: Uses Pest parser generator with PEG grammar defined in
src/snail.pest - AST: Separate representations for regular Snail (
Program) and awk mode (AwkProgram) with source spans for error reporting - Lowering: Transforms Snail AST into Python AST, emitting helper calls backed by
snail.runtime?operator →__snail_compact_try$(cmd)subprocess capture →__SnailSubprocessCapture@(cmd)subprocess status →__SnailSubprocessStatus- Regex literals →
__snail_regex_searchand__snail_regex_compile
- Code Generation: Converts Python AST to Python source for in-process execution
- CLI: Python wrapper (
python/snail/cli.py) that executes via the extension module
📚 Documentation
- Language Reference — Complete syntax and semantics
- examples/all_syntax.snail — Every feature in one file
- examples/awk.snail — Awk mode examples
🔌 Editor Support
Vim/Neovim plugin with syntax highlighting, formatting, and run commands:
Plug 'sudonym1/snail', { 'rtp': 'extras/vim' }
See extras/vim/README.md for details. Tree-sitter grammar available in extras/tree-sitter-snail/.
🛠️ Building from Source
Prerequisites
Python 3.10+ (required at runtime)
Snail runs in-process via a Pyo3 extension module, so it uses the active Python environment.
Installation per platform:
- Ubuntu/Debian:
sudo apt install python3 python3-dev - Fedora/RHEL:
sudo dnf install python3 python3-devel - macOS:
brew install python@3.12(or use the system Python 3) - Windows: Download from python.org
No Python packages required: Snail vendors jmespath under snail.vendor.
Rust toolchain (cargo and rustc)
Install Rust using rustup:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
This installs cargo (Rust's package manager) and rustc (the Rust compiler). After installation, restart your shell or run:
source $HOME/.cargo/env
Verify installation:
cargo --version # Should show cargo 1.70+
rustc --version # Should show rustc 1.70+
python3 --version # Should show Python 3.10+
maturin (build tool)
pip install maturin
Build and Install
# Clone the repository
git clone https://github.com/sudonym1/snail.git
cd snail
# Create and activate a venv (recommended)
python3 -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Build and install into the venv
maturin develop
# Or build wheels for distribution
maturin build --release
Running Tests
# Run all Rust tests (parser, lowering, awk mode; excludes proptests by default)
cargo test
# Run tests including property-based tests (proptests)
cargo test --features run-proptests
# Check code formatting and linting
cargo fmt --check
cargo clippy -- -D warnings
# Build with all features enabled (required before committing)
cargo build --features run-proptests
# Run Python CLI tests
python -m pytest python/tests
Note on Proptests: The snail-proptest crate contains property-based tests that are skipped by default to keep development iteration fast. Use --features run-proptests to run them. Before committing, verify that cargo build --features run-proptests compiles successfully.
Troubleshooting
Using with virtual environments:
Activate the environment before running snail so it uses the same interpreter:
# Create and activate a venv
python3 -m venv myenv
source myenv/bin/activate # On Windows: myenv\Scripts\activate
# Install and run
pip install snail
snail "import sys; print(sys.prefix)"
📋 Project Status
See docs/PLANNING.md for the development roadmap.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file snail_lang-0.3.4.tar.gz.
File metadata
- Download URL: snail_lang-0.3.4.tar.gz
- Upload date:
- Size: 67.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b08d0863659d48fe369cc1ad35b0495477e18f560fd227deb1da6b15032ecb44
|
|
| MD5 |
0b277d1ea6a1d5160f089730acb2c99c
|
|
| BLAKE2b-256 |
897c35da919f5ac6bde07c8bb3667f6002e3d4e4e18ae75f35aee437241ea72c
|
Provenance
The following attestation bundles were made for snail_lang-0.3.4.tar.gz:
Publisher:
release.yml on sudonym1/snail
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
snail_lang-0.3.4.tar.gz -
Subject digest:
b08d0863659d48fe369cc1ad35b0495477e18f560fd227deb1da6b15032ecb44 - Sigstore transparency entry: 814242945
- Sigstore integration time:
-
Permalink:
sudonym1/snail@93a33f4fe78ac08f5f06baa9d062cbc1a89fc89a -
Branch / Tag:
refs/tags/v0.3.4 - Owner: https://github.com/sudonym1
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@93a33f4fe78ac08f5f06baa9d062cbc1a89fc89a -
Trigger Event:
push
-
Statement type:
File details
Details for the file snail_lang-0.3.4-cp310-abi3-win_amd64.whl.
File metadata
- Download URL: snail_lang-0.3.4-cp310-abi3-win_amd64.whl
- Upload date:
- Size: 500.7 kB
- Tags: CPython 3.10+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
49c12b58a59b50796847d2a3bdf198d72e59cab46b34582b2f684414f6363f95
|
|
| MD5 |
63daace1f42890a22a36a56f32a949e2
|
|
| BLAKE2b-256 |
c0cc57df58fe86811a3047123d0d22eddb3e7555c094932068d75ff11af72c1d
|
Provenance
The following attestation bundles were made for snail_lang-0.3.4-cp310-abi3-win_amd64.whl:
Publisher:
release.yml on sudonym1/snail
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
snail_lang-0.3.4-cp310-abi3-win_amd64.whl -
Subject digest:
49c12b58a59b50796847d2a3bdf198d72e59cab46b34582b2f684414f6363f95 - Sigstore transparency entry: 814242956
- Sigstore integration time:
-
Permalink:
sudonym1/snail@93a33f4fe78ac08f5f06baa9d062cbc1a89fc89a -
Branch / Tag:
refs/tags/v0.3.4 - Owner: https://github.com/sudonym1
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@93a33f4fe78ac08f5f06baa9d062cbc1a89fc89a -
Trigger Event:
push
-
Statement type:
File details
Details for the file snail_lang-0.3.4-cp310-abi3-manylinux_2_34_x86_64.whl.
File metadata
- Download URL: snail_lang-0.3.4-cp310-abi3-manylinux_2_34_x86_64.whl
- Upload date:
- Size: 4.4 MB
- Tags: CPython 3.10+, manylinux: glibc 2.34+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8bba59c7c0959ff288a173a67e2cf3b6c307e3bc356e10dbb7d76196cec93dc7
|
|
| MD5 |
c65ebc47e99eee33f5f0542cf60c5625
|
|
| BLAKE2b-256 |
b715ce68e2ebc6f77e232700b7478675cc85a7b95e8f1c8008ba28a32159893b
|
Provenance
The following attestation bundles were made for snail_lang-0.3.4-cp310-abi3-manylinux_2_34_x86_64.whl:
Publisher:
release.yml on sudonym1/snail
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
snail_lang-0.3.4-cp310-abi3-manylinux_2_34_x86_64.whl -
Subject digest:
8bba59c7c0959ff288a173a67e2cf3b6c307e3bc356e10dbb7d76196cec93dc7 - Sigstore transparency entry: 814242953
- Sigstore integration time:
-
Permalink:
sudonym1/snail@93a33f4fe78ac08f5f06baa9d062cbc1a89fc89a -
Branch / Tag:
refs/tags/v0.3.4 - Owner: https://github.com/sudonym1
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@93a33f4fe78ac08f5f06baa9d062cbc1a89fc89a -
Trigger Event:
push
-
Statement type:
File details
Details for the file snail_lang-0.3.4-cp310-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: snail_lang-0.3.4-cp310-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 543.0 kB
- Tags: CPython 3.10+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
66a91541989e17b6a68a460b5041bd3fe3e1ddacda6456b90a9aaeac61f38507
|
|
| MD5 |
350079eb5303a2387ae326e0789a2261
|
|
| BLAKE2b-256 |
5c1a97130881c8f003cf88f0745e8417addf143b80fa05ef45e70ed57561c3af
|
Provenance
The following attestation bundles were made for snail_lang-0.3.4-cp310-abi3-macosx_11_0_arm64.whl:
Publisher:
release.yml on sudonym1/snail
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
snail_lang-0.3.4-cp310-abi3-macosx_11_0_arm64.whl -
Subject digest:
66a91541989e17b6a68a460b5041bd3fe3e1ddacda6456b90a9aaeac61f38507 - Sigstore transparency entry: 814242949
- Sigstore integration time:
-
Permalink:
sudonym1/snail@93a33f4fe78ac08f5f06baa9d062cbc1a89fc89a -
Branch / Tag:
refs/tags/v0.3.4 - Owner: https://github.com/sudonym1
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@93a33f4fe78ac08f5f06baa9d062cbc1a89fc89a -
Trigger Event:
push
-
Statement type: