Intent-oriented programming language where intent drives subjects through zones with compile-time verified contracts.
C
3
3,803 commits
updated Sep 27, 2026
Meet Gyri, the Nautilus.
An intent-first language that closes complex behavior into executable units and derives the rest of the structure from purpose.
Developer experience is a core language invariant: 개발자가 즐거워야 유저도 즐겁다. Pergyra asks developers to state intent, resources, authority, and real boundaries. Proof strategy, execution lane, materialization, and ABI choices are compiler-derived by default and remain inspectable instead of becoming routine source-level ceremony.
Intent는 ‘프로그래머의 의도’를 주석처럼 표현하는 것이 아니라, 여러 compiler fact가 동일한 목적에서 발생했다는 귀속 관계를 보존하는 정적 identity다.
Intent is a static identity that preserves the attribution of compiler facts to one purpose, not a comment about programmer intention. It binds independently owned facts without replacing their owners or granting authority. Attribution is checked against declaration identity, not merely equal names or values. This is the canonical design contract, not a claim that every self-host path already enforces it end to end; see the bounded implementation audit.
The machine layer applies the same separation at the physical boundary:
Region is address evidence, not permission to perform a machine operation.
Intent preserves purpose attribution; it does not grant access to an address.
The current DeviceSlot<T> bridge checks explicit machine facts and a declared
host-sim window. A runtime mapping provider is an admission boundary, not an
MMIO implementation or proof of real hardware behavior. Grant/Region are
not beta-stable user syntax. See the
machine-layer contract and implementation limits.
Korean README · Intent-First Design · Syntax Reference · Grammar · Naming Convention · All Documentation
Current Status: Executable experimental alpha, currently in a late-stage alpha / beta-closure sprint. The remaining beta work is not about widening the language surface; it is about freezing a narrower stable subset and aligning
syntax -> semantic -> runtime -> C -> LLVM -> diagnostics -> regression -> docson that subset. Beta subset candidate being frozen: generics (exact/ability/multi-boundplus implemented default type argument actual resolution),own/refanchored slot-handle boundaries with generalized provenance/escape diagnostics, collections (Array<T>, local borrowedSlice<T>plusSliceCopy,List<T>,Set<T>,HashMap<String, T>,HashMap<Int, T>,HashMap<Long, T>,HashMap<Bool, T>), and runtime observability (last / history / active / recent). This is a scoped beta contract candidate, not a whole-language stability claim. Stable subset source of truth:docs/107_beta_stable_subset.md. Explicit reject / beta-out-of-scope: unsupported map key kinds, broader generic generalization, richer multi-instance observability queries, the full quantum resource model, and any ownership combination that still escapes the current semantic contract.QubitSlot/ClaimQubit/Measure/Entangleremain a partialv2 / experimentalsurface. Anti-hype rule: Do not describe Pergyra as production-ready, Rust-level memory safe, AI-first, quantum-ready, zero-cost, or fully proven. Current external claims must matchdocs/118_slot_model_rigor_audit.md,docs/119_pergyra_lineage_positioning.md, anddocs/120_vision_and_capability_audit.md.
Pergyra documents every major surface with one of these labels:
stable subset
explicit reject
beta-out-of-scope
Current classification snapshot:
intent, world, zone, subject, relation, effect, projection, authority, handoff, runtime observability, anchored ownership boundaries, the generic contract system, module visibility/export contracts, and parallelparallel is the core execution primitive; it is separate from intent, which remains the orchestration contract corefunc, let, control flow, basic callable values, Option / Result, and the collection implementations needed by the core contract languagespawn, async, await, select, channel, cancellation, coroutine/fiber machinery, OOP-style class convenience, and FP combinator libraries are support/style surfaces unless explicitly promotedparallel execution primitivepgy.core + pgy.foundation; pgy.execution keeps the parallel family explicit without promoting fiber/coroutine to core identityfmap-style abstraction (soft-no - see docs/04_generic_design.md)Array<T>, local borrowed Slice<T> with SliceCopy, List<T>, Set<T>, HashMap<String, T>, HashMap<Int, T>, HashMap<Long, T>, HashMap<Bool, T>last / history / active / recentThis policy exists to prevent partial surfaces from being described as complete.
Pergyra is a compiled language with C and LLVM backends. It distinguishes who acts, where they act, and what qualifies them at the language level.
.pgy -> Lexer -> Parser -> Semantic Typed AST -> HIR -> DIR -> RIR -> MIR
| |-> LLVM Backend -> Binary
| |-> C Backend -> GCC -> Binary
|
|-> AIR (read-only synthesis, verification-only)
drift / abstraction-safety check
HIR normalizes language structure and pass-friendly program shapeDIR locks domain contracts such as role/ability, zone/world, intent-step relationsRIR locks slot/resource/projection/authority/lifecycle semanticsMIR locks CFG/SSA/cleanup/resource-flow before backend emissionMIR, not RIRAIR is a side-loaded verification IR synthesized from HIR/RIR; it never lowers to backends and exists solely for intent-to-implementation abstraction-safety checks (see docs/104_air_compiler_architecture.md)Pergyra is intent-first in teaching order, even though subject remains the core host in lowering/runtime terms.
Use this reading order for docs, tutorials, and canonical examples:
teaching / reading order: intent -> world -> zone -> subject
host / lowering order: subject-core
Rules:
intent first: what contract is being executedworld and zone: where the contract is allowed to runsubject: who carries the host state and actionsThis distinction is deliberate:
subject, readers mislearn Pergyra as a subject-first authoring languageintent outward, then show the supporting declarations# Build compiler and LSP only; test binaries are not part of the default build.
make all
# Development build with frontend/runtime test binaries materialized.
make all-with-tests
# Run
./bin/pgy examples/hello.pgy --run -v
# Inspect IR layers
./bin/pgy examples/hello.pgy --hir
./bin/pgy examples/hello.pgy --dir
./bin/pgy examples/hello.pgy --rir
./bin/pgy examples/hello.pgy --mir
# LLVM backend (optional)
make LLVM_ENABLED=1 all
./bin/pgy examples/hello.pgy --emit-llvm -o hello.ll
Requires GCC (C11) and GNU Make. LLVM 14+ optional.
Recent regression entrypoints:
make test-transpile
make test-abi
make llvm-test-backend-compare
make example-test-smoke
make ir-pipeline-test-smoke
make fmt-test-smoke
make stdlib-test-smoke
make package-module-resolver-test-smoke
make unicode-policy-test-smoke
make beta-test-suite-freeze-test-smoke
make observability-schema-test-smoke
make memory-concurrency-model-test-smoke
make tooling-conformance-test-smoke
make dogfood-webgl-test-smoke
Propagation parity is currently locked through world_fixpoint_abi, projection_chain_abi, zone_frontier_abi, intent_authority_snapshot_abi, handoff_projection_frontier_abi, handoff_world_state_frontier_abi, handoff_layer_state_frontier_abi, world_embedded_projection_abi, world_embedded_method_projection_abi, world_embedded_branch_projection_abi, world_embedded_action_frontier_abi, and world_embedded_action_pool_frontier_abi in make test-abi, with zone lifecycle bounded frontier emission and C/LLVM runtime parity checked again in make llvm-test-backend-compare.
Current beta-readiness source of truth: docs/100_beta_readiness_checklist.md. The older docs/98_beta_closure_readiness_report.md is a historical snapshot.
Current CI support matrix:
llvm-config --libs core evidence is present. A C:/Program Files/LLVM/lib directory alone is not beta support evidence.make ci-macos; macOS LLVM/backend parity remains out-of-beta until a dedicated LLVM support contract is green.Official build/runtime paths:
make ci-linuxwindows-latest + msys2/setup-msys2 with a native MSYS2/MinGW runtimemake ci-windows intentionally rejects plain Linux-hosted gccFailure policy snapshot:
Bool, Result<T>, or queryable runtime stateHard-fail boundary snapshot:
Unwrap(result) on ErrUnwrapOption(option) on NoneRecent backend hygiene snapshot:
make test-all output stays signal-firstprojection_chain_abi, zone_frontier_abi, intent_authority_snapshot_abi, handoff_projection_frontier_abi, handoff_world_state_frontier_abi, handoff_layer_state_frontier_abi, world_embedded_projection_abi, world_embedded_method_projection_abi, world_embedded_branch_projection_abi, world_embedded_action_frontier_abi, and world_embedded_action_pool_frontier_abi, and current direct regression checks are test-semantic 2146 passed, test-transpile 670 passed, make test-abi, ABI pipeline integration (196 passed), make test-all, make llvm-test-smoke, and make llvm-test-backend-compare (43/43 backend-compare cases)Stable example guidance:
WebGL note: examples/wasm_hello/ is a dogfood host-bridge example over C
--emit-c, not stable WebGL language surface. Real WebGL APIs belong to the
post-beta pgy.render.webgl module track.
examples/hello.pgy - smallest ordinary log/value pathexamples/basic.pgy - basic ordinary-value syntax; no Slot lifecycle APIsexamples/logistics_intent_probe/examples/order_analytics/examples/battle_simulator/examples/biome_simulator/examples/slots_simple.pgyexamples/resource_scheduler_async_probe/examples/wasm_hello/ - WebGL/WASM host bridge via C --emit-c, not stable WebGL language surfaceexamples/intent_contract_pair_minimal.pgyexamples/authority_contract_pair_minimal.pgyexamples/transfer_contract_pair_minimal.pgyexamples/party_system_demo.pgy and
examples/world_roster_city.pgy are not stable syntax referencesAuthoring-surface references:
let x: Int = 10;
let name: String = "Alice";
let count = 0;
let msg = "hello";
func Add(a: Int, b: Int) -> Int
{
return a + b;
}
func main()
{
let result = Add(3, 4);
PrintInt(result);
}
Ordinary values, pure computations, and logs do not require
ClaimSlot / Write / Read / Release.
func Main() -> Void
{
Log("Hello, Pergyra!");
}
Use Slot<T>, SecureSlot<T>, DeviceSlot<T>, and pin/view syntax when
code crosses an explicit resource, authority, backend-handle, or lifecycle
boundary. Slot is the resource-boundary model; it is not the default value
model.
Slot is not a Rust-style borrow checker. The beta safety model is layered: static checks reject unsafe boundary transitions, while runtime Slot handles validate generation, token capability, release state, and pin state at the resource boundary. This is a deliberate address-abstraction choice, not a claim of full Rust lifetime proof.
if hp > 0
{
Print("alive");
}
else
{
Print("dead");
}
while i < 10
{
PrintInt(i);
i = i + 1;
}
Pergyra uses 6 keywords to declare types. Each keyword carries intended distinct semantics.
| Keyword | Role | Memory | Behavior | Implementation |
|---|---|---|---|---|
subject | Active entity (protagonist) | Reference (ptr self) | action + func | Full |
class | Passive thing (tool) | Value | func only | Full |
struct | Pure data | Value | None | Full |
vessel | Internal state (inside subject) | Value | None | Semantic + codegen surface |
object | Internal projection/view contract | Value | func only | Distinct projection contract |
tobject | Transfer/export boundary contract | Value | func only | Distinct transfer contract |
Current implementation state:
subjectandclassare separated in semantic and codegen paths.objectandtobjectare distinct declaration surfaces and contracts:objectis the local/internal projection contract;tobjectis the publish/transfer/export boundary contract.
subject Player
{
let name: String;
let hp: Int;
vessel stats: PlayerStats;
}
class Weapon
{
let name: String;
let damage: Int;
func DamageText(self) -> String
{
return self.name;
}
}
struct Position
{
let x: Int;
let y: Int;
}
vessel PlayerStats
{
let level: Int;
let xp: Int;
}
object PlayerView
{
let name: String;
let hp: Int;
}
tobject PlayerReceipt
{
let name: String;
let hp: Int;
}
Rule of thumb:
object for internal projection/read modelstobject for publish/transfer/export boundariesworld still counts as object-style projection observation, not automatic boundary publicationability Combatable
{
func CanFight(self) -> Bool;
}
role Combatable for Player
{
func CanFight(self) -> Bool
{
return self.hp > 0;
}
}
subject Player
{
let hp: Int;
action Attack(self, target: Player)
within BattleZone
authorized by self
{
target.hp = target.hp - 10;
}
}
zone BattleZone
{
subject slot attacker: Player;
subject slot defender: Player;
authority attacker;
}
actionis declared insidesubject. Azonedefines subject slots and authority boundaries.
world GameServer
{
zone battle: BattleZone;
}
relation Alliance between subject, subject
{
let trust: Int;
}
effect Poison for bearer: subject
{
let damage_per_tick: Int;
let remaining: Int;
}
relation is not a plain struct. It declares shared state between endpoints, and the compiler can validate that zone links satisfy the declared endpoint contract.
Intents declare why a subject moves. They are callable, drive subjects through zone-bound steps, and provide built-in observability.
intent DriveCar(cockpit: CockpitZone, driver: Driver)
{
exclusive;
priority: 3;
step Ignite
{
// Compact form: who/where/using come from `on:` and zone context.
// `authorized by` is reused only from an explicit action contract.
on: driver.Ignite();
compensate: driver.RollbackIgnite();
pre: true;
post: driver.started;
}
success: true;
failure: false;
}
func Main() -> Void
{
let d = Driver(0, false);
let cockpit = CockpitZone(Driver(99, true));
let ok = DriveCar(cockpit, d); // call intent like a function
Log("ok=" + ToString(ok));
Log("trace:");
Log(IntentLastTrace()); // built-in observability
}
Features:
Compact intent is the preferred beta authoring style. Explicit who, where,
using, requires, and authorized by remain valid when inference is
ambiguous or when the author wants the boundary to be visually explicit.
who is the actor/provenance axis; authorized by is the approval/authority
axis. They may name the same participant, but one never substitutes for the
other.
exclusive / concurrent - conflict policypriority - numeric priority for schedulingon: - event trigger (action call)compensate: - rollback action on failurepre / post / guard / invariant / expect - conditionsIntentLastTrace(), IntentHistoryCount() - runtime observabilityintent: inside a step - sub-intent orchestrationExample:
intent Charge(checkout: CheckoutZone, buyer: Buyer)
{
step verify
{
where: CheckoutZone;
using: checkout;
who: buyer;
expect: true;
}
}
intent Checkout(checkout: CheckoutZone, buyer: Buyer)
{
step pay
{
intent: Charge(checkout, buyer);
expect: true;
}
}
Available without import:
let map: Map<String, Int> = Map();
MapSet(map, "key", 42);
let val: Int = MapGet(map, "key");
let list: List<Int> = List();
ListPush(list, 10);
let item: Int = ListGet(list, 0);
let queue: Queue<Int> = Queue();
QueuePush(queue, 1);
let front: Int = QueuePop(queue);
let values: Array<Int> = [1, 2, 3];
let view: Slice<Int> = values.Slice(0, 2);
let owned: Array<Int> = SliceCopy(view);
Set<T>is connected through the semantic/C/LLVM path viaSetNew,SetAdd,SetHas,SetRemove, andSetSize.Array<T>uses literals such as[1, 2, 3]plusArrayPush,ArrayPop, andArrayLength.Slice<T>is a borrowed local view; useSliceCopy(view)when an ownedArray<T>snapshot must cross a boundary.
use)use fsm;
use timer;
use cooldown;
let state = FsmNew();
FsmAddState(state, 0, "idle");
FsmAddState(state, 1, "attack");
FsmTransition(state, 0, 1);
let t = TimerNew(100);
TimerTick(t, 16);
let cd = CooldownNew(60);
CooldownTrigger(cd);
| Target | Style | Example |
|---|---|---|
| Keywords | lowercase | let, func, subject |
| Types / Built-in functions | PascalCase | Player, ToString, MapSet |
| Local variables | camelCase | playerHp, eventCount |
| Constants | UPPER_SNAKE | MAX_HP, TILE_SIZE |
| File names | snake_case | battle_zone.pgy |
Full details: Naming Convention
PergyraLang/
src/
lexer/ # Tokenizer
parser/ # AST generation
semantic/ # Type checking, slot analysis
codegen/ # C / LLVM backends
compiler/ # Compilation driver
runtime/ # Runtime library
examples/ # .pgy examples
docs/ # Design documents
editor/ # VS Code extension
assets/branding/ # Gyri the Nautilus
Not every example has the same contract strength.
compile-smoke covered: the example is exercised by current regression smoke and is the recommended reference surfacedesign sketch: the example may intentionally show future or aspirational syntax and should not be used as a stable referenceSource of truth:
Recommended examples to start from:
examples/hello.pgy - smallest ordinary log/value pathexamples/basic.pgy - ordinary values, functions, control flow, and loggingexamples/logistics_intent_probe/ - IR/domain pipeline probeexamples/order_analytics/ - larger compile-smoke covered application exampleexamples/subject_object_tobject/ - nominal/projection baselineResource-boundary examples are intentionally separate:
examples/slots_simple.pgy - explicit Slot lifecycle and scoped with slotexamples/resource_scheduler_async_probe/ - async/parallel/resource probeexamples/ownership_forwarding_probe/ - current own/ref anchored-slot boundary subsetDogfood bridge examples:
examples/wasm_hello/ - beta dogfood bridge: C --emit-c plus optional EmscriptenDesign-sketch examples:
examples/party_system_demo.pgyexamples/world_roster_city.pgymake all-with-tests # Build compiler plus test binaries
make test-all # Run the frontend/runtime regression bundle
make test-semantic # Semantic analysis
make test-transpile # C backend
make llvm-test-backend-compare # C/LLVM parity
make rebuild # Clean + rebuild the default compiler/LSP binaries
If a build looks stale ("Nothing to be done" while sources changed), see Build Troubleshooting.
.pgysource.pergyra.vscode/ settings select the workspace-local compiler
and LSP, an MSYS2 UCRT64 terminal on Windows, and focused build/self-host/doc
tasks. F5 configurations run either extension in an Extension Host.Pergyra is not yet registered with github-linguist/linguist,
so GitHub's Language bar currently classifies .pgy as "Other". The
.gitattributes at the repo root forward-declares
linguist-language=Pergyra; it is a no-op until the Linguist entry is merged
and then activates automatically.
The submission checklist (sample selection, TextMate grammar extraction, color candidates, "in use" adoption strategy) is tracked in docs/96_linguist_submission.md.
BSD 3-Clause License. See LICENSE.
3,803 commits
C
58.9%
Shell
36.3%
Python
3.3%
Makefile
1.2%
Intent-oriented programming language where intent drives subjects through zones with compile-time verified contracts.
C
3
3,803 commits
updated Sep 27, 2026
Meet Gyri, the Nautilus.
An intent-first language that closes complex behavior into executable units and derives the rest of the structure from purpose.
Developer experience is a core language invariant: 개발자가 즐거워야 유저도 즐겁다. Pergyra asks developers to state intent, resources, authority, and real boundaries. Proof strategy, execution lane, materialization, and ABI choices are compiler-derived by default and remain inspectable instead of becoming routine source-level ceremony.
Intent는 ‘프로그래머의 의도’를 주석처럼 표현하는 것이 아니라, 여러 compiler fact가 동일한 목적에서 발생했다는 귀속 관계를 보존하는 정적 identity다.
Intent is a static identity that preserves the attribution of compiler facts to one purpose, not a comment about programmer intention. It binds independently owned facts without replacing their owners or granting authority. Attribution is checked against declaration identity, not merely equal names or values. This is the canonical design contract, not a claim that every self-host path already enforces it end to end; see the bounded implementation audit.
The machine layer applies the same separation at the physical boundary:
Region is address evidence, not permission to perform a machine operation.
Intent preserves purpose attribution; it does not grant access to an address.
The current DeviceSlot<T> bridge checks explicit machine facts and a declared
host-sim window. A runtime mapping provider is an admission boundary, not an
MMIO implementation or proof of real hardware behavior. Grant/Region are
not beta-stable user syntax. See the
machine-layer contract and implementation limits.
Korean README · Intent-First Design · Syntax Reference · Grammar · Naming Convention · All Documentation
Current Status: Executable experimental alpha, currently in a late-stage alpha / beta-closure sprint. The remaining beta work is not about widening the language surface; it is about freezing a narrower stable subset and aligning
syntax -> semantic -> runtime -> C -> LLVM -> diagnostics -> regression -> docson that subset. Beta subset candidate being frozen: generics (exact/ability/multi-boundplus implemented default type argument actual resolution),own/refanchored slot-handle boundaries with generalized provenance/escape diagnostics, collections (Array<T>, local borrowedSlice<T>plusSliceCopy,List<T>,Set<T>,HashMap<String, T>,HashMap<Int, T>,HashMap<Long, T>,HashMap<Bool, T>), and runtime observability (last / history / active / recent). This is a scoped beta contract candidate, not a whole-language stability claim. Stable subset source of truth:docs/107_beta_stable_subset.md. Explicit reject / beta-out-of-scope: unsupported map key kinds, broader generic generalization, richer multi-instance observability queries, the full quantum resource model, and any ownership combination that still escapes the current semantic contract.QubitSlot/ClaimQubit/Measure/Entangleremain a partialv2 / experimentalsurface. Anti-hype rule: Do not describe Pergyra as production-ready, Rust-level memory safe, AI-first, quantum-ready, zero-cost, or fully proven. Current external claims must matchdocs/118_slot_model_rigor_audit.md,docs/119_pergyra_lineage_positioning.md, anddocs/120_vision_and_capability_audit.md.
Pergyra documents every major surface with one of these labels:
stable subset
explicit reject
beta-out-of-scope
Current classification snapshot:
intent, world, zone, subject, relation, effect, projection, authority, handoff, runtime observability, anchored ownership boundaries, the generic contract system, module visibility/export contracts, and parallelparallel is the core execution primitive; it is separate from intent, which remains the orchestration contract corefunc, let, control flow, basic callable values, Option / Result, and the collection implementations needed by the core contract languagespawn, async, await, select, channel, cancellation, coroutine/fiber machinery, OOP-style class convenience, and FP combinator libraries are support/style surfaces unless explicitly promotedparallel execution primitivepgy.core + pgy.foundation; pgy.execution keeps the parallel family explicit without promoting fiber/coroutine to core identityfmap-style abstraction (soft-no - see docs/04_generic_design.md)Array<T>, local borrowed Slice<T> with SliceCopy, List<T>, Set<T>, HashMap<String, T>, HashMap<Int, T>, HashMap<Long, T>, HashMap<Bool, T>last / history / active / recentThis policy exists to prevent partial surfaces from being described as complete.
Pergyra is a compiled language with C and LLVM backends. It distinguishes who acts, where they act, and what qualifies them at the language level.
.pgy -> Lexer -> Parser -> Semantic Typed AST -> HIR -> DIR -> RIR -> MIR
| |-> LLVM Backend -> Binary
| |-> C Backend -> GCC -> Binary
|
|-> AIR (read-only synthesis, verification-only)
drift / abstraction-safety check
HIR normalizes language structure and pass-friendly program shapeDIR locks domain contracts such as role/ability, zone/world, intent-step relationsRIR locks slot/resource/projection/authority/lifecycle semanticsMIR locks CFG/SSA/cleanup/resource-flow before backend emissionMIR, not RIRAIR is a side-loaded verification IR synthesized from HIR/RIR; it never lowers to backends and exists solely for intent-to-implementation abstraction-safety checks (see docs/104_air_compiler_architecture.md)Pergyra is intent-first in teaching order, even though subject remains the core host in lowering/runtime terms.
Use this reading order for docs, tutorials, and canonical examples:
teaching / reading order: intent -> world -> zone -> subject
host / lowering order: subject-core
Rules:
intent first: what contract is being executedworld and zone: where the contract is allowed to runsubject: who carries the host state and actionsThis distinction is deliberate:
subject, readers mislearn Pergyra as a subject-first authoring languageintent outward, then show the supporting declarations# Build compiler and LSP only; test binaries are not part of the default build.
make all
# Development build with frontend/runtime test binaries materialized.
make all-with-tests
# Run
./bin/pgy examples/hello.pgy --run -v
# Inspect IR layers
./bin/pgy examples/hello.pgy --hir
./bin/pgy examples/hello.pgy --dir
./bin/pgy examples/hello.pgy --rir
./bin/pgy examples/hello.pgy --mir
# LLVM backend (optional)
make LLVM_ENABLED=1 all
./bin/pgy examples/hello.pgy --emit-llvm -o hello.ll
Requires GCC (C11) and GNU Make. LLVM 14+ optional.
Recent regression entrypoints:
make test-transpile
make test-abi
make llvm-test-backend-compare
make example-test-smoke
make ir-pipeline-test-smoke
make fmt-test-smoke
make stdlib-test-smoke
make package-module-resolver-test-smoke
make unicode-policy-test-smoke
make beta-test-suite-freeze-test-smoke
make observability-schema-test-smoke
make memory-concurrency-model-test-smoke
make tooling-conformance-test-smoke
make dogfood-webgl-test-smoke
Propagation parity is currently locked through world_fixpoint_abi, projection_chain_abi, zone_frontier_abi, intent_authority_snapshot_abi, handoff_projection_frontier_abi, handoff_world_state_frontier_abi, handoff_layer_state_frontier_abi, world_embedded_projection_abi, world_embedded_method_projection_abi, world_embedded_branch_projection_abi, world_embedded_action_frontier_abi, and world_embedded_action_pool_frontier_abi in make test-abi, with zone lifecycle bounded frontier emission and C/LLVM runtime parity checked again in make llvm-test-backend-compare.
Current beta-readiness source of truth: docs/100_beta_readiness_checklist.md. The older docs/98_beta_closure_readiness_report.md is a historical snapshot.
Current CI support matrix:
llvm-config --libs core evidence is present. A C:/Program Files/LLVM/lib directory alone is not beta support evidence.make ci-macos; macOS LLVM/backend parity remains out-of-beta until a dedicated LLVM support contract is green.Official build/runtime paths:
make ci-linuxwindows-latest + msys2/setup-msys2 with a native MSYS2/MinGW runtimemake ci-windows intentionally rejects plain Linux-hosted gccFailure policy snapshot:
Bool, Result<T>, or queryable runtime stateHard-fail boundary snapshot:
Unwrap(result) on ErrUnwrapOption(option) on NoneRecent backend hygiene snapshot:
make test-all output stays signal-firstprojection_chain_abi, zone_frontier_abi, intent_authority_snapshot_abi, handoff_projection_frontier_abi, handoff_world_state_frontier_abi, handoff_layer_state_frontier_abi, world_embedded_projection_abi, world_embedded_method_projection_abi, world_embedded_branch_projection_abi, world_embedded_action_frontier_abi, and world_embedded_action_pool_frontier_abi, and current direct regression checks are test-semantic 2146 passed, test-transpile 670 passed, make test-abi, ABI pipeline integration (196 passed), make test-all, make llvm-test-smoke, and make llvm-test-backend-compare (43/43 backend-compare cases)Stable example guidance:
WebGL note: examples/wasm_hello/ is a dogfood host-bridge example over C
--emit-c, not stable WebGL language surface. Real WebGL APIs belong to the
post-beta pgy.render.webgl module track.
examples/hello.pgy - smallest ordinary log/value pathexamples/basic.pgy - basic ordinary-value syntax; no Slot lifecycle APIsexamples/logistics_intent_probe/examples/order_analytics/examples/battle_simulator/examples/biome_simulator/examples/slots_simple.pgyexamples/resource_scheduler_async_probe/examples/wasm_hello/ - WebGL/WASM host bridge via C --emit-c, not stable WebGL language surfaceexamples/intent_contract_pair_minimal.pgyexamples/authority_contract_pair_minimal.pgyexamples/transfer_contract_pair_minimal.pgyexamples/party_system_demo.pgy and
examples/world_roster_city.pgy are not stable syntax referencesAuthoring-surface references:
let x: Int = 10;
let name: String = "Alice";
let count = 0;
let msg = "hello";
func Add(a: Int, b: Int) -> Int
{
return a + b;
}
func main()
{
let result = Add(3, 4);
PrintInt(result);
}
Ordinary values, pure computations, and logs do not require
ClaimSlot / Write / Read / Release.
func Main() -> Void
{
Log("Hello, Pergyra!");
}
Use Slot<T>, SecureSlot<T>, DeviceSlot<T>, and pin/view syntax when
code crosses an explicit resource, authority, backend-handle, or lifecycle
boundary. Slot is the resource-boundary model; it is not the default value
model.
Slot is not a Rust-style borrow checker. The beta safety model is layered: static checks reject unsafe boundary transitions, while runtime Slot handles validate generation, token capability, release state, and pin state at the resource boundary. This is a deliberate address-abstraction choice, not a claim of full Rust lifetime proof.
if hp > 0
{
Print("alive");
}
else
{
Print("dead");
}
while i < 10
{
PrintInt(i);
i = i + 1;
}
Pergyra uses 6 keywords to declare types. Each keyword carries intended distinct semantics.
| Keyword | Role | Memory | Behavior | Implementation |
|---|---|---|---|---|
subject | Active entity (protagonist) | Reference (ptr self) | action + func | Full |
class | Passive thing (tool) | Value | func only | Full |
struct | Pure data | Value | None | Full |
vessel | Internal state (inside subject) | Value | None | Semantic + codegen surface |
object | Internal projection/view contract | Value | func only | Distinct projection contract |
tobject | Transfer/export boundary contract | Value | func only | Distinct transfer contract |
Current implementation state:
subjectandclassare separated in semantic and codegen paths.objectandtobjectare distinct declaration surfaces and contracts:objectis the local/internal projection contract;tobjectis the publish/transfer/export boundary contract.
subject Player
{
let name: String;
let hp: Int;
vessel stats: PlayerStats;
}
class Weapon
{
let name: String;
let damage: Int;
func DamageText(self) -> String
{
return self.name;
}
}
struct Position
{
let x: Int;
let y: Int;
}
vessel PlayerStats
{
let level: Int;
let xp: Int;
}
object PlayerView
{
let name: String;
let hp: Int;
}
tobject PlayerReceipt
{
let name: String;
let hp: Int;
}
Rule of thumb:
object for internal projection/read modelstobject for publish/transfer/export boundariesworld still counts as object-style projection observation, not automatic boundary publicationability Combatable
{
func CanFight(self) -> Bool;
}
role Combatable for Player
{
func CanFight(self) -> Bool
{
return self.hp > 0;
}
}
subject Player
{
let hp: Int;
action Attack(self, target: Player)
within BattleZone
authorized by self
{
target.hp = target.hp - 10;
}
}
zone BattleZone
{
subject slot attacker: Player;
subject slot defender: Player;
authority attacker;
}
actionis declared insidesubject. Azonedefines subject slots and authority boundaries.
world GameServer
{
zone battle: BattleZone;
}
relation Alliance between subject, subject
{
let trust: Int;
}
effect Poison for bearer: subject
{
let damage_per_tick: Int;
let remaining: Int;
}
relation is not a plain struct. It declares shared state between endpoints, and the compiler can validate that zone links satisfy the declared endpoint contract.
Intents declare why a subject moves. They are callable, drive subjects through zone-bound steps, and provide built-in observability.
intent DriveCar(cockpit: CockpitZone, driver: Driver)
{
exclusive;
priority: 3;
step Ignite
{
// Compact form: who/where/using come from `on:` and zone context.
// `authorized by` is reused only from an explicit action contract.
on: driver.Ignite();
compensate: driver.RollbackIgnite();
pre: true;
post: driver.started;
}
success: true;
failure: false;
}
func Main() -> Void
{
let d = Driver(0, false);
let cockpit = CockpitZone(Driver(99, true));
let ok = DriveCar(cockpit, d); // call intent like a function
Log("ok=" + ToString(ok));
Log("trace:");
Log(IntentLastTrace()); // built-in observability
}
Features:
Compact intent is the preferred beta authoring style. Explicit who, where,
using, requires, and authorized by remain valid when inference is
ambiguous or when the author wants the boundary to be visually explicit.
who is the actor/provenance axis; authorized by is the approval/authority
axis. They may name the same participant, but one never substitutes for the
other.
exclusive / concurrent - conflict policypriority - numeric priority for schedulingon: - event trigger (action call)compensate: - rollback action on failurepre / post / guard / invariant / expect - conditionsIntentLastTrace(), IntentHistoryCount() - runtime observabilityintent: inside a step - sub-intent orchestrationExample:
intent Charge(checkout: CheckoutZone, buyer: Buyer)
{
step verify
{
where: CheckoutZone;
using: checkout;
who: buyer;
expect: true;
}
}
intent Checkout(checkout: CheckoutZone, buyer: Buyer)
{
step pay
{
intent: Charge(checkout, buyer);
expect: true;
}
}
Available without import:
let map: Map<String, Int> = Map();
MapSet(map, "key", 42);
let val: Int = MapGet(map, "key");
let list: List<Int> = List();
ListPush(list, 10);
let item: Int = ListGet(list, 0);
let queue: Queue<Int> = Queue();
QueuePush(queue, 1);
let front: Int = QueuePop(queue);
let values: Array<Int> = [1, 2, 3];
let view: Slice<Int> = values.Slice(0, 2);
let owned: Array<Int> = SliceCopy(view);
Set<T>is connected through the semantic/C/LLVM path viaSetNew,SetAdd,SetHas,SetRemove, andSetSize.Array<T>uses literals such as[1, 2, 3]plusArrayPush,ArrayPop, andArrayLength.Slice<T>is a borrowed local view; useSliceCopy(view)when an ownedArray<T>snapshot must cross a boundary.
use)use fsm;
use timer;
use cooldown;
let state = FsmNew();
FsmAddState(state, 0, "idle");
FsmAddState(state, 1, "attack");
FsmTransition(state, 0, 1);
let t = TimerNew(100);
TimerTick(t, 16);
let cd = CooldownNew(60);
CooldownTrigger(cd);
| Target | Style | Example |
|---|---|---|
| Keywords | lowercase | let, func, subject |
| Types / Built-in functions | PascalCase | Player, ToString, MapSet |
| Local variables | camelCase | playerHp, eventCount |
| Constants | UPPER_SNAKE | MAX_HP, TILE_SIZE |
| File names | snake_case | battle_zone.pgy |
Full details: Naming Convention
PergyraLang/
src/
lexer/ # Tokenizer
parser/ # AST generation
semantic/ # Type checking, slot analysis
codegen/ # C / LLVM backends
compiler/ # Compilation driver
runtime/ # Runtime library
examples/ # .pgy examples
docs/ # Design documents
editor/ # VS Code extension
assets/branding/ # Gyri the Nautilus
Not every example has the same contract strength.
compile-smoke covered: the example is exercised by current regression smoke and is the recommended reference surfacedesign sketch: the example may intentionally show future or aspirational syntax and should not be used as a stable referenceSource of truth:
Recommended examples to start from:
examples/hello.pgy - smallest ordinary log/value pathexamples/basic.pgy - ordinary values, functions, control flow, and loggingexamples/logistics_intent_probe/ - IR/domain pipeline probeexamples/order_analytics/ - larger compile-smoke covered application exampleexamples/subject_object_tobject/ - nominal/projection baselineResource-boundary examples are intentionally separate:
examples/slots_simple.pgy - explicit Slot lifecycle and scoped with slotexamples/resource_scheduler_async_probe/ - async/parallel/resource probeexamples/ownership_forwarding_probe/ - current own/ref anchored-slot boundary subsetDogfood bridge examples:
examples/wasm_hello/ - beta dogfood bridge: C --emit-c plus optional EmscriptenDesign-sketch examples:
examples/party_system_demo.pgyexamples/world_roster_city.pgymake all-with-tests # Build compiler plus test binaries
make test-all # Run the frontend/runtime regression bundle
make test-semantic # Semantic analysis
make test-transpile # C backend
make llvm-test-backend-compare # C/LLVM parity
make rebuild # Clean + rebuild the default compiler/LSP binaries
If a build looks stale ("Nothing to be done" while sources changed), see Build Troubleshooting.
.pgysource.pergyra.vscode/ settings select the workspace-local compiler
and LSP, an MSYS2 UCRT64 terminal on Windows, and focused build/self-host/doc
tasks. F5 configurations run either extension in an Extension Host.Pergyra is not yet registered with github-linguist/linguist,
so GitHub's Language bar currently classifies .pgy as "Other". The
.gitattributes at the repo root forward-declares
linguist-language=Pergyra; it is a no-op until the Linguist entry is merged
and then activates automatically.
The submission checklist (sample selection, TextMate grammar extraction, color candidates, "in use" adoption strategy) is tracked in docs/96_linguist_submission.md.
BSD 3-Clause License. See LICENSE.
3,803 commits
C
58.9%
Shell
36.3%
Python
3.3%
Makefile
1.2%