A transpiler-based extension of C. Write modern, expressive code — default parameters, overloading, defer, modules, a math library — and compile with any C compiler. No runtime. No bloat. No OOP.
G-Lang requires GCC (or Clang) to compile your projects, and optionally GDB + VSCodium for debugging. The transpiler itself is a pre-built native binary — no Python needed to run it.
setup.sh builds guild from source, installs it to ~/.local/bin/, and optionally installs the VSCodium extension.
Put your .g files in src/ and run guild build. Guild auto-discovers all .g files, compiles them, and cleans up the intermediate C files automatically.
Multiple .g files can declare the same #module Name. This lets you split a large module across files — useful for NPC systems, rendering layers, or any subsystem that grows too large for one file.
Guild generates NPC_base.c, NPC_pathfind.c, NPC_combat.c, and a single merged NPC.h containing all prototypes. Consumers just #import NPC as normal — the split is invisible from the outside.
For layered architectures (game → engine → graphics), a single guild.toml can orchestrate multiple sub-projects with explicit dependency ordering. Guild builds bottom-up and makes each layer's headers available to layers above it.
Each project can declare its own sources, libs, and flags. The depends key controls build order and include paths — a project's generated headers are automatically available to everything that depends on it.
| Context | Name |
|---|---|
| Language | G / G-Lang |
| File extension | .g |
| Transpiler binary | guild |
| Build command | guild build / guild run |
| Transpile only | guild transpile |
| Source directory | src/ (default, auto-discovered) |
| Generated C output | build/ (auto-cleaned after compile) |
| Debug binary | . (project root) |
| Release binary | release/ |
| Flag | Effect |
|---|---|
| --release | -O2 -DNDEBUG, binary goes to release/ |
| --clean | wipe build dirs before building |
| --keep-c | don't delete generated .c files after compile |
| --transpile-only | skip the compile step |
| --flat | dump everything in cwd (no src/build layout) |
| --src <dir> | override source directory |
| --out <dir> | override C output directory |
| --bin <path> | override binary output path |
Precedence: CLI flag → guild.toml → built-in default.
Real G code from the test suite — every feature shown, compiled and verified against 12 passing test checks.
The full feature test file. Each section exercises a different G-Lang feature end-to-end.
#module Tests #include <stdio.h> #include <string.h> #import TestMath // ── Feature 1: Default zero initialisation ─────────────────────────────────── void test_zero_init() { int i; float f; char c; int^ p; printf("[zero_init] int=%d float=%.1f char=%d pointer=%s\n", i, f, c, p == NULL ? "NULL" : "non-null"); } // ── Feature 2: ^ pointer declaration ──────────────────────────────────────── void test_pointer_syntax() { int value = 42; int^ ptr = &value; printf("[pointer] value via deref=%d\n", *ptr); } // ── Feature 3: Default parameters ──────────────────────────────────────────── int add(int a=10, int b=20) { int result; result = a + b; return result; } // ── Feature 4: Function overloading ────────────────────────────────────────── int describe(int x) { printf("[overload] int: %d\n", x); return x; } float describe(float x) { printf("[overload] float: %.2f\n", x); return x; } double describe(double x) { printf("[overload] double: %.4f\n", x); return x; } int sum(int a, int b) { int r; r = a+b; return r; } int sum(int a, int b, int c) { int r; r = a+b+c; return r; } int sum(int a, int b, int c, int d) { int r; r = a+b+c+d; return r; } float sum(float a, float b) { float r; r = a+b; return r; } // ── Feature 4b: Dot syntax — cross-module calls ────────────────────────────── int test_dot_syntax() { int sq_i = TestMath.square(5); float sq_f = TestMath.square(3.0f); int add2 = TestMath.add(10, 20); int add3 = TestMath.add(10, 20, 30); printf("[module] square(5)=%d square(3.0f)=%.1f add(10,20)=%d add(10,20,30)=%d\n", sq_i, sq_f, add2, add3); int total; total = sq_i + add2 + add3; return total; } // ── Feature 5: defer ───────────────────────────────────────────────────────── void test_defer() { printf("[defer] start\n"); defer { printf("[defer] third (LIFO 1)\n"); } defer { printf("[defer] second (LIFO 2)\n"); } defer { printf("[defer] first (LIFO 3)\n"); } printf("[defer] end of body — defers fire now:\n"); } void test_defer_with_return(int early) { defer { printf("[defer_return] cleanup always runs\n"); } if (early) { printf("[defer_return] early return path\n"); return; } printf("[defer_return] normal return path\n"); } // ── Feature 6: Error-as-value ───────────────────────────────────────────────── int! safe_divide(int a, int b) { if (b == 0) return error(1, "division by zero"); return a / b; } void test_error() { // else {} handles errors inline int result = safe_divide(10, 2) else { printf("error %d: %s\n", err.code, err.msg); result = 0; }; printf("[error] 10/2=%d\n", result); } // ── Feature 10: undefined keyword ──────────────────────────────────────────── void test_undefined() { int safe; int risky = undefined; safe = 100; risky = 200; printf("[undefined] safe=%d risky=%d\n", safe, risky); } // ── Feature 11: Struct defaults + auto typedef ─────────────────────────────── struct Player { float height = 5.10f; float weight = 180.0f; int hp = 100; int mana = 50; int score; }; // ── Feature 12: using keyword — struct embedding ───────────────────────────── struct Transform { float x = 0.0f; float y = 0.0f; float rotation = 0.0f; }; struct Entity { int id = 0; int active = 1; using Transform transform; }; void print_entity(Entity e) { printf("[using] id=%d active=%d x=%.2f y=%.2f rotation=%.2f\n", e.id, e.active, e.x, e.y, e.rotation); }
The simplest workflow: put .g files in src/, run guild build. Guild auto-discovers all .g files, transpiles them, compiles, and cleans up the intermediate C files. The binary lands in the project root for debug builds and release/ for release builds.
# debug build — looks in src/, binary in ./ $ guild build # optimized — binary goes to release/ $ guild build --release # build and run in one step $ guild run # transpile only, no compile $ guild transpile src/World.g -o out/
# keep generated C files (default: cleaned) $ guild build --keep-c # override source / output dirs $ guild build --src lib --out tmp # dump everything in cwd (no src/build layout) $ guild build --flat # wipe build dirs then rebuild $ guild build --clean
For multi-file projects, drop a guild.toml in the project root. Explicit sources lists override auto-discovery. Mix .g and .c files freely.
# Project metadata name = "my_game" version = "0.1.0" [build] # Directory entries scan recursively for .g files sources = ["src/", "npc/"] # Explicit file list also works — or mix both # sources = ["Entity.g", "npc/", "main.c"] # Link against any C library libs = ["SDL2", "m"] # Pass extra flags to gcc flags = ["-Wall", "-Wextra"] # Optional overrides (all have smart defaults) # src_dir = "src" # where to find .g files (if no sources list) # out_dir = "build" # where generated .c files go (auto-cleaned) # bin_dir = "." # debug binary location # rel_dir = "release" # release binary location # keep_c = false # set true to keep generated .c files # cc = "clang" # override compiler (default: gcc)
# debug build (default) $ guild build # optimized release build $ guild build --release # build and run immediately $ guild run # release build and run $ guild run --release # clean generated files $ guild build --clean
# guild build runs this pipeline: # # 1. find guild.toml (searches upward) # 2. discover *.g in src/ (or use sources list) # 3. transpile each .g file → build/ # 4. compile all .c files with gcc # 5. link into the named executable # 6. auto-clean generated .c files # # debug builds auto-add -g for GDB # .g breakpoints work natively via #line # # release builds add -O2 -DNDEBUG
The transpiler is now a native C binary — no Python required to run it. Linux x86-64. GCC required to compile your G projects.
The G-Lang transpiler — pre-built for Linux x86-64
Linux x86-64 · MIT License
Editor integration for .g files
Install via editors/vscode/install.sh
— total downloads & clones
Or clone the full source — includes standard library, test suite, and setup script:
Looking for the original Python toolchain? G-Lang-legacy ↗
The pre-built guild binary targets Linux x86-64. Windows and macOS users can build from source — see GETTING_STARTED.md in the repo.
Any C11 compiler. GCC is the default; set cc = "clang" in guild.toml to switch.
For source-level debugging. Set breakpoints in .g files, step through, inspect variables. Works via standard #line directives — no custom adapter needed.
Only needed for the VSCodium language server (autocomplete, hover, go-to-def). Not required to use the transpiler itself.
C is the language games are built in. From id Software's Quake to modern indie engines, C's performance, predictability, and direct hardware access make it the pragmatic choice. But C has papercuts — small, daily frustrations that accumulate over a project.
G-Lang fixes the papercuts. It's a transpiler that converts G source files to standard C before compilation. The output is readable, debuggable C you can inspect and compile with any C toolchain.
G adds exactly what developers — game developers especially — reach for constantly: default parameters, function overloading, defer for deterministic cleanup, a module system, and a math library that pairs directly with OpenGL, Vulkan, and SDL.
using.guild is a single native C binary. Clone the repo, run bash setup.sh, and go. No Python, no pip, no package managers.G-Lang is at v0.8.0. The transpiler has been fully rewritten in C and the build system has smart defaults — drop .g files in src/, run guild build, and you get a binary with intermediate C files cleaned up automatically. Multiple .g files can share a #module name and are merged into a single header. Multi-project guild.toml handles layered architectures like game → engine → graphics in one build command. Source-level debugging works via standard #line directives in any DWARF-aware tool.
It has not yet been battle-tested in a shipped game. 1.0 means a real game ships with it. That's the milestone.
Built by Garrett Gaston. Source on GitLab. MIT License.
Found a bug? Have a feature idea? Building something with G-Lang? There are two ways to reach us depending on what you need.
Found something broken? Open a GitLab issue — it gets tracked, prioritized, and fixed. GitLab account required.
Open an Issue ↗See what's already been reported, vote on features, or pick up something to contribute to.
View All Issues ↗Questions, ideas, or just want to say you're using G-Lang — use the form below. Goes directly to dev@g-lang.io.