Site officiel : amalgame.me Tour du langage · Installer · Versions
namespace App
import Amalgame.IO
public class Greeter {
public Name: string
public Greeter(string name) {
this.Name = name
}
public string Hello() {
guard String.Length(this.Name) > 0 else { return "Hello, stranger!" }
return "Hello, {this.Name}!"
}
}Amalgame is a small, statically-typed language whose compiler (amc)
is written in Amalgame and emits portable C. The runtime is a thin
header-only layer over libc and libgc (Boehm GC).
- Self-hosted. The compiler bootstraps itself in about five
seconds. A tracked
snapshot/amc_lib.c(known-good portable C) is the cold-start entry point — onegccinvocation rebuilds the bootstrap binary on any platform. - Predictable output. Source maps cleanly to C. Strings are
char*, lists arevoid**arrays, integers arei64. No VM, no hidden allocations beyond the GC. Generated C isgcc-buildable with-O2. - Multi-platform. Linux, macOS, and Windows binaries are produced
on every
v*tag. Windows is supported via MinGW (Winsock under#ifdef _WIN32in the runtime).
Current version: v0.8.75.
namespace App
import Amalgame.IO
public enum Shape {
Circle(int)
Rect(int, int)
}
public class Program {
public static void Main(string[] args) {
// Match as expression with arm guards and ranges
let n = 42
let bucket = match n {
0 => "zero"
x if x < 0 => "negative"
1..9 => "small"
10..99 => "medium"
_ => "large"
}
Console.WriteLine(bucket)
// List comprehension
let squares = [i * i for i in 0..10 if i % 2 == 0]
Console.WriteLine(String.FromInt(squares.Count()))
// Tuple destructuring
let (q, r) = Program.DivMod(17, 5)
Console.WriteLine("{String.FromInt(q)} rem {String.FromInt(r)}")
// Algebraic enum + destructuring
let s = Shape.Circle(5)
match s {
Circle(r) => Console.WriteLine("r={String.FromInt(r)}")
Rect(w, h) => Console.WriteLine("rect")
}
// Null-safe member access
let maybe: Greeter? = null
let label = maybe?.Hello()
if (label == null) { Console.WriteLine("no greeter") }
}
public static (int, int) DivMod(int a, int b) {
return (a / b, a % b)
}
}A more thorough tour is in docs/guide/02-language-tour.md.
Zero install — a full VS Code with the compiler, extension (syntax/LSP/ DAP), a sample project and the docs, all pre-wired:
docker run --rm -p 8080:8080 ghcr.io/amalgame-lang/amalgame-ide:edge
# open http://localhost:8080 and press F5
# (:latest + :X.Y.Z are published on tagged releases; :edge tracks main)See docker/README.md for build, auth and persistence options.
sudo apt install gcc libgc-dev
git clone https://github.com/amalgame-lang/Amalgame.git && cd Amalgame
gcc -O2 -Iruntime snapshot/amc_lib.c -lgc -lm -o snapshot/amc
./build_amc.sh # builds ./amc from src/ via the snapshot
./amc --version # amc 0.4.14
./tests/run_all_tests.sh # full suite via `amc test ./tests/` (~42s)Tests live as discoverable *_test.am bundles under tests/fmt/,
tests/amc_new/, tests/stdlib_bundle/, and tests/core_bundle/,
each runnable individually via ./amc test ./tests/<bundle>/.
tests/run_all_tests.sh is a one-line wrapper that calls
./amc test ./tests/ (legacy bash runners were dropped 2026-05-24).
tests/fixtures/ is pruned from auto-discovery so canonical fixture
files don't get re-executed when crawling from above.
brew install bdw-gc
git clone https://github.com/amalgame-lang/Amalgame.git && cd Amalgame
GC_PREFIX=$(brew --prefix bdw-gc)
gcc -O2 -Iruntime -I"$GC_PREFIX/include" -L"$GC_PREFIX/lib" \
snapshot/amc_lib.c -lgc -lm -o amc
./amc --versionpacman -S mingw-w64-x86_64-gcc mingw-w64-x86_64-gc
git clone https://github.com/amalgame-lang/Amalgame.git && cd Amalgame
gcc -O2 -Iruntime snapshot/amc_lib.c -lgc -lm -lz -lws2_32 -o amc.exe
./amc.exe --version// hello.am
namespace App
import Amalgame.IO
public class Program {
public static void Main(string[] args) {
Console.WriteLine("Hello, Amalgame!")
}
}./amc hello.am -o hello
gcc -Iruntime hello.c -lgc -lm -o hello
./hello
# → Hello, Amalgame!- Variables (
let/var) with optional type annotation - Primitives:
int,float,double,bool,string,void - Classes with inheritance, interfaces, data classes, records
- Enums (simple) and algebraic enums with destructuring
- Generics (erased to
void*at the C level) - Null-safety:
T?,??coalescing,?.safe member access - Tuples and destructuring:
let (a, b) = f() - Pattern matching with guards, ranges, binders, statement-shaped
arms (
return,break,continue) matchandifas expressions- List comprehensions:
[x*2 for x in xs if x > 0] - String interpolation:
"hello {x}" - Triple-quoted multiline strings:
"""…""" \xHHand\uHHHHescape sequences- Bitwise operators, compound assignments, pipeline
|>, range0..n - Guard clauses:
guard cond else { return } - Decorators (
@inline,@deprecated) mapped to GCC attributes - Capturing closures (since v0.3.4) — multi-param
(x,y) => …and block bodiesx => { … }since v0.3.5 - Higher-order list methods —
xs.Filter / .Map / .Reduce / .ForEach / .Any / .All / .CountIf(since v0.3.6, takes a lambda) - Generic interfaces with static contract verification
(
class Box implements IComparable<int>, since v0.3.5)
Detailed reference: docs/guide/.
Resolver and type-checker errors come with a source snippet and a caret pointing at the offending token:
error[typechecker]: Cannot assign 'string' to 'n' of type 'int'
--> /tmp/test.am:19:13
|
19 | let n: int = p.Name
| ^
error[resolver]: Unknown symbol 'someUndefinedThing'
--> file.am:4:9
|
4 | someUndefinedThing.x()
| ^
amc fmt— formatter that re-emits a parsed AST canonically while preserving comments. Idempotent on every source in this repository. Run it asamc fmt file.am(stdout) oramc fmt -w file.am(rewrite in place).amc --lint file.am— static analysis: unreachable code, unused locals (prefix_to silence), and shadowed names. Warnings are non-fatal and don't bump the exit code.amc test [<dir>]— discovers*_test.amunder<dir>(default.), compiles + runs each, and aggregates[PASS],[FAIL],[SKIP]lines from their stdout. Each test file is a normal Amalgame program with aMainthat prints tag lines per case; no framework required. Exits non-zero if any case FAILs or any file fails to compile.amc lsp— workspace-aware language server speaking JSON-RPC 2.0 on stdio. Publishes diagnostics ondidOpen/didChange, servestextDocument/hover(Markdown tooltip with the inferred type) andtextDocument/completion(every global symbol the resolver knows about, including types declared in any sibling.amfile under the workspace root).amc dap(v0.8.0+) — Debug Adapter Protocol proxy. Detects a DAP-native backend on the host (lldb-dapfrom LLVM 18+,gdb --dapfrom gdb 14+) andexecvp()s into it. Combined withamc build -gand the cgen's#linedirectives, breakpoints set on.amsource files resolve natively via DWARF — no source-map files, no path translation. Works in VS Code (the bundled extension declares theamcdebug type), Neovim, Helix, or any DAP-aware editor.amc migrate <file|dir>— LLM-assisted source-to-Amalgame migration. Auto-detects 21 source languages by extension (TS, Python, Java, C#, Go, Rust, …). Provider auto-selection from env:ANTHROPIC_API_KEY→ claude-api,OPENAI_API_KEY→ chatgpt,GEMINI_API_KEY→ gemini, fallbackclaude(CLI). Directory recursion, result cache by SHA-256 of source + system prompt, cost estimation in--dry-run, automatedamc --checkvalidation. Seedocs/guide/08-llm-commands.md.amc generate "<prompt>"— LLM-driven prose-to-Amalgame. Same provider stack, plus--streamvia the claude CLI for direct stdout passthrough. Ideal for "scaffold me a starting point".amc explain <file.am>— reverse direction: emit a natural-language explanation of an Amalgame source file. Use--lang French(or any other) to translate the explanation.- VS Code syntax highlighting + LSP client in editors/vscode/.
Install with:
ln -s "$(pwd)/editors/vscode" ~/.vscode/extensions/amalgame-0.2.0
src/ Compiler, written in Amalgame
├── lexer/ token.am, lexer.am
├── parser/ ast.am, parser.am
├── resolver/ symbol.am, resolver.am
├── generator/ c_gen.am, gen_test.am
├── formatter/ formatter.am
├── linter.am static analysis (amc --lint)
├── typechecker.am
├── diagnostics.am
├── lsp.am workspace-aware LSP server (amc lsp)
├── migrate.am LLM source-to-Amalgame (amc migrate)
├── generate.am LLM prose-to-Amalgame (amc generate)
├── explain.am LLM Amalgame-to-prose (amc explain)
├── main.am CLI: compile | fmt | test | lsp | migrate | generate | explain
└── amc_lib.c Self-hosted bundle (generated)
runtime/ C runtime (bdwgc, strings, IO, collections, net, env, process)
stdlib/ Stdlib API reference (.am declarations)
snapshot/ Tracked amc_lib.c known-good bootstrap
tools/ save-snapshot.sh, release.sh
tests/ Sample programs + run_*.sh runners
docs/guide/ User guide chapters 1–16 (FR translations for 11–16)
docs/proposals/ Design RFCs (amc-migrate.md tracks LLM roadmap)
editors/vscode/ Syntax highlighting extension
.github/workflows/ CI + tag-driven Release automation
The build pipeline:
src/*.am ─[ ./amc ]─▶ amc_lib.c ─[ gcc ]─▶ amc binary
▲ │
└──────────────────────────────┘
five-second self-rebuild
When ./amc is missing or broken, build_amc.sh falls back to
./snapshot/amc. From a clean clone, rebuild that binary with
gcc snapshot/amc_lib.c … (see snapshot/INFO.md). See
tools/save-snapshot.sh for capturing a new snapshot.
The full board is in ROADMAP_COMPLET.md. The short version, ordered by unlocked-value per day of work:
- Fix the SKIPped samples —
Type.Variantpatterns in match,try / catch, null-safety inference. - Minimal LSP — completion + hover via stdio JSON-RPC, reusing the existing parser, resolver, and type-checker.
- Capturing closures.
- Generic type inference.
Workflow is a simplified gitflow:
maincarries release tags only.developis the integration branch; PRs target it.- Features land via
feature/<name>branches.
git checkout develop
git checkout -b feature/my-thing
# ...
./build_amc.sh && ./tests/run_all_tests.sh
git push -u origin feature/my-thing
gh pr create --base developCI runs on every push and pull request. Releases are produced by
pushing a v* tag — see .github/workflows/release.yml.
The amc compiler runs entirely on the user's machine. It does not
phone home, collect telemetry, log usage statistics, or transmit any
data to external servers. The only network operations are initiated
explicitly by the user:
amc package add <name>fetches a package + its index entry fromgithub.com/amalgame-lang/packages-indexand the package's upstream GitHub repository.amc package search/amc package versionsfetch the curated index from the same source (cached locally for 30 min).amc migrate,amc generate,amc explainare LLM-driven helpers that send your source code (or natural-language prompt) to a third-party AI provider that you select via the--providerflag and authenticate against with your own API key: Anthropic (Claude), OpenAI (ChatGPT), or Google (Gemini), controlled byANTHROPIC_API_KEY/OPENAI_API_KEY/GEMINI_API_KEYenvironment variables. If none of these are set, the commands fall back to invoking a locally-installedclaudeCLI (which makes its own network calls under Anthropic's terms). Don't use these commands on confidential or NDA-bound source code unless you have audited the chosen provider's data retention and training-opt-out policy. Amalgame itself never routes the request through a server we control — it's a direct HTTPS call from your machine to the provider.
The amalgame.me website serves static documentation and does not
set tracking cookies. No personal data is collected by Amalgame as
a project.
Apache License 2.0 © Bastien Mouget