v4.5.0
Two new portable constructs — @@fsm recognizers and @@:self — plus verbatim
type/value passthrough and exception-free C++/Swift output.
4.5.0 is a feature release with two headline additions and a set of contract and
portability fixes. @@fsm brings a regular-language recognizer construct to all 17
targets at full parity; @@:self makes self-reference portable; verbatim
passthrough closes the last gap between the “Frame has no type system” contract and
what codegen did; and C++/Swift core output is now exception-free so it builds where
exceptions are compiled out (notably Godot web). This release has breaking
hard-cuts, all mechanical to fix; Frame is pre-public-beta, so no published program
is affected. See the migration guide.
Highlights
@@fsm— finite-state recognizers, all 17 languages (RFC-0042). A new top-level construct that compiles a regular-language recognizer to a Pike-VM-backed state machine, emitted at full behavioral parity on every backend. It implements the RE2 dialect across the regular-language feature set: literal / character-class / Unicode\d \w \salphabets (and\p{…}via@@[allow(unicode_classes)]);|ordered choice; greedy and lazy quantifiers; edge and interior anchors; character-, byte-, and Unicode-aware word boundaries\b/\B; inline flags(?i)/(?m)/(?s)and scoped(?ims:…)/(?-i:…); captures with action blocks;when-conditional and stage-reference transition targets; a token alphabet; multi-match states; embedding; and Mode-C sub-fsm call-out. The action-body statement grammar is specified in RFC-0050.@@:self— portable, blessed self-reference (RFC-0046). Write@@:self.field,@@:self.action(), and@@:self.field.method()(embed calls), including inside return expressions and across systems; framec lowers each to its target’s nativeself/thisidiom on all 17 backends. This replaces the per-language textual self-rewriters with segment-driven lowering.- Verbatim type & value passthrough (#61, #59, #62). The leftover type-alias
tables (
int→i64,str→String,float→f64, …) and the state-variable “portable init” wrapping (""→String::from("")) are gone. You write your target’s own type names and init values and they reach the generated code unchanged — which also fixes a float-literal corruption bug those layers hid ($.x: f64 = 0.0previously emitted0). Section comments emit verbatim too. - Exception-free C++/Swift core output (RFC-0049). Core dispatch maintains its
context-stack invariant with each language’s idiomatic scope-cleanup (RAII /
defer) instead of a mandatory catch-and-rethrow, so generated C++ now compiles and links under-fno-exceptions— unblocking Godot web GDExtensions. The opt-in@@[persist]and@@[async]features keep a compiled-out throw/abort fallback. Exceptions are optional, not the rule.
Breaking changes
See the migration guide for the canonical→native table, worked before/after, and the state-var-initializer change.
- Type annotations are no longer aliased. A source that wrote a Frame-canonical
name (
: int,: str,: float) and relied on framec mapping it to the target’s native type now emits that name verbatim. Where the canonical name is native nothing changes; where it isn’t — notablystreverywhere, andint/floaton Rust — write the native name (String/i64/f64, …). - State-variable init values are no longer wrapped. A
String-typed state var initialized with a bare""now emits""instead ofString::from(""). Write the native init value for the target. - State variables now require an explicit initializer (#84,
E610). The synthesized-default value table was removed. A state var declared without an initializer is anE610error — give it the native init value for its declared type, exactly as for a domain field.
Action required
Sources already written in native type names and native init values, with every
state variable initialized, generate identical output to 4.4.x and need nothing.
Otherwise, rewrite the affected annotations/values to your target’s native spelling
and add the missing initializers — see the migration guide for
the per-target table. The new @@fsm and @@:self constructs are additive; no
existing source needs to adopt them.