slovo/docs/language/SPEC-v1.md
2026-05-22 12:21:49 +02:00

5625 lines
222 KiB
Markdown

# Slovo v1 Specification
Status: living beta contract for `1.0.0-beta`, with the post-beta
`1.0.0-beta.1` tooling/install update. The language contract integrates
promoted language slices through `exp-125` and the historical publication
baseline through `exp-123`. `1.0.0-beta` is the first real general-purpose
beta release. `exp-125` completed the unsigned numeric and stdlib breadth
precursor scope, `exp-124` is the last tagged experimental alpha language
contract before beta, and `exp-123` is the last tagged experimental
documentation/tooling contract before beta. `1.0.0-beta` includes direct
`u32` and `u64` value flow, decimal suffixed literals `42u32` / `42u64`,
same-type unsigned
arithmetic/comparison, unsigned print/format/parse-result runtime lanes, and
matching staged stdlib helper parity alongside the previously promoted
project/package, collection, composite-data, docs, and diagnostics surface.
exp-121 broadens
unary enum payload variants to current known non-recursive struct types while
keeping the same-payload-type-per-enum rule when payload variants are present
and reusing existing immutable enum flow and `match` payload binding behavior.
The earlier exp-120 broadens direct struct field declarations to the current
promoted fixed immutable array family over `i32`, `i64`, `f64`, `bool`, and
`string`. The earlier exp-118 broadens fixed immutable arrays with one
connected `string` element lane alongside the earlier exp-117 direct scalar
array family `i32`, `i64`, `f64`, and `bool`. The earlier exp-119 keeps the
exp-118 language surface unchanged while refreshing the earlier benchmark/
publication baseline around five kernels: `math-loop`, `branch-loop`,
`parse-loop`, `array-index-loop`, and `string-eq-loop`. The earlier exp-114
promotes same-type mutable whole-value
local reassignment for already-supported non-array composite value families.
The earlier exp-113 promotes direct mutable `bool`, `i64`, and `f64` locals,
and the earlier exp-112 promotes immutable `bool` locals. The earlier exp-111
broadens the concrete `std.io` facade with one connected stdin helper package
over the already promoted `std.io.read_stdin_result`,
`std.string.parse_*_result`, and the exp-109 bridge surface. The earlier
`v2.0.0-beta.1` tag name is historical and is not a beta maturity claim.
Base release: Slovo v0
Date started: 2026-05-16
## 1. Purpose
Slovo v1 grows the v0 language kernel without weakening the project rule that
made v0 reliable:
> A feature is supported only when Slovo docs and Glagol behavior agree across
> surface syntax, typed-core meaning, lowering behavior, formatter behavior,
> diagnostics, examples, and tests.
This file is a living post-v0 contract. A section is compiler-supported only
when it is marked promoted, has fixtures in `examples/supported/` and
`examples/formatter/`, is implemented in Glagol, and is covered by tests.
Current v1 release surface and explicit experimental targets:
- struct value flow through immutable locals, parameters, returns, calls
returning structs, and field access through stored struct values
- option/result value flow through immutable locals, parameters, calls
returning option/result values, and tag observation with `is_some`, `is_none`,
`is_ok`, and `is_err`, plus explicit trap-based `i32` payload extraction
with `unwrap_some`, `unwrap_ok`, and `unwrap_err`
- array value flow for fixed-size arrays over direct scalar `i32`, `i64`,
`f64`, `bool`, fixed-size `string`, direct known enum, and current known
non-recursive struct element families through immutable locals, parameters,
returns, calls returning arrays, and runtime-checked dynamic indexing with
`i32` index expressions
- runtime string support through direct immutable source string literals,
immutable and whole-value mutable string locals, string parameters, string
returns, calls returning strings, string equality, string byte length, and
legacy compiler/runtime compatibility aliases `(print_string value)` and
`(string_len value)`
- local binding surface through immutable `let` plus same-type mutable `var` /
`set` flows for direct `bool`, `i64`, `f64`, `string`, current concrete vec
families, current concrete option/result families, current known struct
values, and current enum values, while fixed arrays remain immutable
- legacy compiler/runtime compatibility alias `(print_bool value)`
- v1 tooling contracts for `slovo.diagnostic` machine diagnostics,
`slovo.artifact-manifest` output manifests, and LLVM span/source-map
direction
- v1.3 project mode for flat local projects with `slovo.toml`, explicit local
imports, explicit export lists, deterministic module ordering, multi-file
diagnostics, and project artifact-manifest fields, once the matching Glagol
v1.3 gates pass
- v1.4 source-level `match` for existing `(option i32)`, `(option i64)`,
`(option f64)`, `(option bool)`, `(option string)`, and `(result i32 i32)`
values, with exhaustive arms,
immutable arm payload bindings, arm-local expression bodies, common arm
result types, formatter layout, and named diagnostics, once the matching
Glagol v1.4 gates pass
- v1.5 standard-runtime alpha names `std.io.print_i32`,
`std.io.print_string`, `std.io.print_bool`, and `std.string.len` as
compiler-known source-level names over the existing runtime behavior, with
legacy `print_i32`, `print_string`, `print_bool`, and `string_len` names
remaining compatibility aliases, once the matching Glagol v1.5 gates pass
- v1.6 memory and unsafe design slice: lexical `unsafe` remains the only unsafe
boundary; `alloc`, `dealloc`, `load`, `store`, `ptr_add`,
`unchecked_index`, `reinterpret`, and `ffi_call` are compiler-known reserved
unsafe heads that require `UnsafeRequired` in safe code and
`UnsupportedUnsafeOperation` inside lexical `unsafe` until a future release
defines execution semantics
- v1.7 developer experience hardening: tooling-only contracts for
`glagol new`, `glagol fmt --check`, `glagol fmt --write`, `glagol doc`, and
a local release-gate script, without adding source language syntax,
semantics, LSP, stable debug metadata, or stable source maps
- `v2.0.0-beta.1` experimental integration/readiness release: the accumulated
v1.1-v1.7 surface is supported for small real flat local projects through
`glagol new`, `check`, `fmt --check/--write`, `test`, `build`, `doc`,
artifact manifests, JSON diagnostics, and the release-gate script
- `exp-1` owned runtime strings: compiler-known `std.string.concat` accepts two
`string` values and returns an immutable runtime-owned `string`; existing
string equality, length, printing, locals, parameters, returns, and calls work
over both literal-backed and runtime-owned strings
- `exp-2` collections alpha plus `exp-94` vec-i64 baseline, `exp-99`
vec-string baseline, and `exp-103` vec-f64 baseline: concrete growable
vector types `(vec i32)`, `(vec i64)`, `(vec f64)`, and `(vec string)`,
compiler-known
`std.vec.i32.empty`, `std.vec.i32.append`, `std.vec.i32.len`,
`std.vec.i32.index`, compiler-known `std.vec.i64.empty`,
`std.vec.i64.append`, `std.vec.i64.len`, and `std.vec.i64.index`,
compiler-known `std.vec.f64.empty`, `std.vec.f64.append`,
`std.vec.f64.len`, and `std.vec.f64.index`,
compiler-known `std.vec.string.empty`, `std.vec.string.append`,
`std.vec.string.len`, and `std.vec.string.index`, vector equality with `=`
on same-family operands, and immutable vector flow through locals,
parameters, returns, calls, and top-level tests
- `exp-3` standard IO and host environment: compiler-known
`std.io.eprint`, `std.process.argc`, `std.process.arg`, `std.env.get`,
`std.fs.read_text`, and `std.fs.write_text` with stage-specific runtime
traps and integer write status
- `exp-4` user enum alpha: payloadless user-defined enum declarations,
zero-argument qualified variant constructors, immutable local, parameter,
return, and call flow, same-enum equality, and exhaustive payloadless enum
`match`
- `exp-16` unary i32 enum payloads alpha: user-defined enum variants may be
payloadless or carry one `i32` payload; qualified constructors pass zero or
one argument accordingly; enum `match` arms bind exactly one immutable
arm-local payload name for payload variants; same-enum equality compares
tag plus payload for payload variants and tag for payloadless variants
- `exp-17` project enum imports alpha: project/workspace module export lists
may include top-level enum names, import lists may import exported enum
names, and imported enum types preserve exactly the exp-4 payloadless plus
exp-16 unary `i32` payload surface
- `exp-18` enum struct fields alpha: struct field declarations may use current
user-defined enum type names directly, struct construction may initialize
those fields with payloadless or unary `i32` enum values, and field access
may flow into same-enum equality or exhaustive enum `match`
- `exp-19` primitive struct fields alpha: struct field declarations may use
direct `bool` and immutable `string` field types alongside direct `i32` and
exp-18 enum fields; field access may flow into existing bool predicate
positions, string equality, and `std.string.len`
- `exp-112` immutable bool locals alpha: direct immutable `bool` locals
declared with `let`, initialized from already promoted bool expressions, and
reusable in existing predicate, return, call, test, and `main` positions
- `exp-113` mutable scalar locals alpha: direct mutable `bool`, `i64`, and
`f64` locals declared with `var`, plus same-type `set` reassignment from
already promoted scalar expressions
- `exp-114` mutable composite locals alpha: same-type mutable whole-value
reassignment with `var` / `set` for `string`, current concrete vec
families, current concrete option/result families, current known struct
values, and current enum values
- `exp-20` f64 numeric primitive alpha: direct `f64` parameters, returns,
immutable locals, calls, decimal literals, same-type `f64`
arithmetic/comparison, and `std.io.print_f64`
- `exp-21` i64 numeric primitive alpha: direct `i64` parameters, returns,
immutable locals, calls, explicit signed decimal `i64` literal atoms,
same-type `i64` arithmetic/comparison, and `std.io.print_i64`
- `exp-22` numeric widening conversions alpha: explicit
`std.num.i32_to_i64 : (i32) -> i64`,
`std.num.i32_to_f64 : (i32) -> f64`, and
`std.num.i64_to_f64 : (i64) -> f64` calls over the existing numeric
primitives
- `exp-23` checked i64-to-i32 conversion alpha: exactly one checked narrowing
standard-runtime call,
`std.num.i64_to_i32_result : (i64) -> (result i32 i32)`, returning `ok`
for signed `i32` range values and `err 1` for out-of-range values
- `exp-24` integer to string alpha: exactly two integer formatting
standard-runtime calls,
`std.num.i32_to_string : (i32) -> string` and
`std.num.i64_to_string : (i64) -> string`, returning decimal signed ASCII
strings with `-` only for negative values and no leading `+`
- `exp-25` string parse i64 result alpha: exactly one string parse
standard-runtime call,
`std.string.parse_i64_result : (string) -> (result i64 i32)`, returning
`ok value` for in-range ASCII signed decimal `i64` text and `err 1` for
parse failure or out-of-range input
- `exp-125` current Slovo-side unsigned target: direct `u32`/`u64`
parameters, returns, immutable locals, calls, decimal suffixed literals
`42u32` / `42u64`, same-type unsigned arithmetic/comparison,
`std.io.print_u32`, `std.io.print_u64`, `std.num.u32_to_string`,
`std.num.u64_to_string`, `std.string.parse_u32_result`,
`std.string.parse_u64_result`, and matching staged source-helper parity
across `std.result`, `std.option`, `std.string`, `std.num`, `std.io`,
`std.env`, `std.fs`, `std.process`, and `std.cli`
- `exp-26` f64 to string alpha: exactly one finite `f64` formatting
standard-runtime call,
`std.num.f64_to_string : (f64) -> string`, returning finite decimal ASCII
text for promoted finite `f64` inputs
- `exp-27` checked f64 to i32 result alpha: exactly one checked `f64` to
`i32` result standard-runtime call,
`std.num.f64_to_i32_result : (f64) -> (result i32 i32)`, returning `ok`
value only for finite, exactly integral inputs inside the signed `i32` range
and `err 1` for non-finite, fractional, or out-of-range input
- `exp-28` string parse f64 result alpha: exactly one string parse
standard-runtime call,
`std.string.parse_f64_result : (string) -> (result f64 i32)`, returning
`ok value` for complete finite ASCII decimal `f64` text and `err 1` for
ordinary parse failure, non-finite text, trailing or leading unsupported
characters, or out-of-domain input
- `exp-29` numeric struct fields alpha: direct immutable struct field
declarations whose field types are exactly `i64` or `f64`, alongside
already supported direct `i32`, `bool`, immutable `string`, and current enum
fields; accessed fields may flow into existing same-type numeric
arithmetic/comparison and existing numeric print/format helpers
- `exp-120` fixed array struct fields alpha: direct immutable struct field
declarations whose field types are exactly the current promoted fixed-array
families `(array i32 N)`, `(array i64 N)`, `(array f64 N)`, `(array bool N)`,
and `(array string N)` with positive literal lengths; field access returns
the declared array type and may flow into existing checked `index`
- `exp-121` non-recursive struct enum payloads alpha: unary enum payload
variants may use current known non-recursive struct types, payload variants
in one enum still share the same payload type when payload variants are
present, and bound payload values reuse existing field access behavior
- `exp-30` standard library source layout alpha: establish `std/` as the
source home for staged standard library modules and examples, including
narrow source-authored `std/math.slo` helpers, without automatic
standard-library import/search, replacing compiler-known `std.*` calls,
stable APIs, manifest schema changes, or beta maturity
- `exp-31` checked f64 to i64 result alpha: exactly one checked `f64` to
`i64` result standard-runtime call,
`std.num.f64_to_i64_result : (f64) -> (result i64 i32)`, returning `ok`
value only for finite, exactly integral inputs inside the signed `i64` range
and `err 1` for non-finite, fractional, or out-of-range input
- `exp-32` standard math source helpers alpha: staged `std/math.slo` includes
source-authored `abs_i64`, `min_i64`, `max_i64`, `clamp_i64`,
`square_i64`, `abs_f64`, `min_f64`, `max_f64`, and `clamp_f64` alongside
the existing `i32` helpers and `square_f64`, without automatic
standard-library import/search or new compiler-known runtime names
- `exp-33` standard result source helpers alpha: staged `std/result.slo`
includes concrete `is_err_*` and `unwrap_err_*` helpers for the already
promoted result families, plus `unwrap_or_i32`, `unwrap_or_i64`,
`unwrap_or_string`, and `unwrap_or_f64`, without automatic standard-library
import/search or new compiler-known runtime names
- `exp-34` string parse bool result alpha: exactly one string parse
standard-runtime call,
`std.string.parse_bool_result : (string) -> (result bool i32)`, returning
`ok true` for exactly `true`, `ok false` for exactly `false`, and `err 1`
for empty input, uppercase/mixed-case text, leading/trailing whitespace,
numeric text, or any other text
- `exp-35` standard result bool source helpers alpha: staged
`std/result.slo` includes `is_ok_bool`, `is_err_bool`, `unwrap_ok_bool`,
`unwrap_err_bool`, and `unwrap_or_bool` for `(result bool i32)`, without
automatic standard-library import/search, compiler-known runtime names,
generic result helpers, or stable ABI/layout claims
- `exp-36` standard option source helpers alpha: staged `std/option.slo`
includes `is_some_i32`, `is_none_i32`, `unwrap_some_i32`, and
`unwrap_or_i32` for `(option i32)`, without automatic standard-library
import/search, compiler-known runtime names, generic option helpers, option
payloads beyond `i32`, or stable ABI/layout claims
- `exp-37` standard time source facade alpha: staged `std/time.slo` includes
`monotonic_ms` and `sleep_ms_zero` wrappers over the already released exp-8
`std.time.*` calls, without automatic standard-library import/search,
compiler-loaded standard-library source, compiler-known runtime names,
wall-clock/calendar/timezone APIs, high-resolution timers, async timers,
cancellation, scheduling guarantees, or stable ABI/layout claims
- `exp-38` standard host source facades alpha: staged `std/random.slo`,
`std/env.slo`, and `std/fs.slo` add narrow source wrappers over already
released random, environment, and text filesystem calls, without automatic
standard-library import/search, compiler-loaded standard-library source,
compiler-known runtime names, random seed/range/bytes/float/UUID/crypto
APIs, environment mutation/enumeration, binary/directory/streaming/async
filesystem APIs, rich host error ADTs, or stable ABI/layout claims
- `exp-39` standard math extensions and benchmark scaffold alpha: staged
`std/math.slo` adds source-authored `neg`, `cube`, zero/positive/negative
predicates, and inclusive `in_range` helpers for `i32`, `i64`, and finite
`f64`, while the matching Glagol benchmark scaffold remains local timing
evidence only
- `exp-44` standard library source search alpha: project-mode source may
explicitly import `(import std.math (...))`, resolving to repo-root
`std/math.slo` with its own export list; still no automatic std imports,
workspace/package std imports, registry behavior, `std.slo` aggregator,
broad standard-library APIs, stable ABI/layout, or beta maturity
- `exp-45` standard result and option source search alpha: project-mode
source may explicitly import `(import std.result (...))` and
`(import std.option (...))`, resolving to repo-root `std/result.slo` and
`std/option.slo` with their own export lists; still no automatic std
imports, workspace/package std imports, generic result/option helpers,
registry behavior, broad standard-library APIs, stable ABI/layout, or beta
maturity
- `exp-46` workspace standard source search alpha: workspace packages may
explicitly import standard source modules such as
`(import std.option (...))`, using the same repo-root standard source
lookup; still no automatic std imports, workspace dependency syntax for
std, installed stdlib paths, registry behavior, stable ABI/layout, or beta
maturity
- `exp-47` standard host facade source search alpha: project-mode source may
explicitly import `std.time`, `std.random`, `std.env`, and `std.fs`,
resolving to staged repo-root source facades with their own export lists;
still no automatic std imports, installed stdlib paths, broad host APIs,
stable ABI/layout, or beta maturity
- `exp-48` standard core facade source search alpha: project-mode source may
explicitly import `std.string` and `std.num`, resolving to staged repo-root
source facades with their own export lists; still no automatic std imports,
installed stdlib paths, generic parse/format APIs, broad numeric casts,
stable ABI/layout, or beta maturity
- `exp-49` standard IO facade source search alpha: project-mode source may
explicitly import `std.io`, resolving to the staged repo-root source facade
with its own export list; still no automatic std imports, installed stdlib
paths, broad IO APIs, formatted output APIs, stable ABI/layout, or beta
maturity
- `exp-50` installed standard library discovery alpha: explicit
standard-source imports may resolve staged `std/*.slo` files from an
installed `share/slovo/std` toolchain layout; still no automatic std
imports, package registry behavior, lockfiles, package std dependencies,
stable install layout guarantees, broad standard-library APIs, stable
ABI/layout, or beta maturity
- `exp-51` standard library path list alpha: `SLOVO_STD_PATH` may name an
ordered OS path list of standard-library roots; still no automatic std
imports, package registry behavior, lockfiles, semantic version solving,
stable package manager behavior, broad standard-library APIs, stable
ABI/layout, or beta maturity
- `exp-52` standard process facade source search alpha: project-mode source
may explicitly import `std.process`, resolving to the staged repo-root
source facade with its own export list; still no automatic std imports,
package registry behavior, process spawning, exit/status control,
current-directory APIs, signal handling, stable ABI/layout, or beta maturity
- `exp-53` standard CLI source facade alpha: project-mode source may
explicitly import `std.cli`, resolving to the staged repo-root source
facade with its own export list; the facade composes `std.process` and
`std.string`; still no automatic std imports, package registry behavior,
shell parsing, option/flag parsing, subcommands, environment-backed
configuration, stable CLI framework APIs, stable ABI/layout, or beta
maturity
- `exp-54` standard CLI typed arguments alpha: staged `std.cli` adds
`arg_i64_result`, `arg_i64_or_zero`, `arg_f64_result`,
`arg_f64_or_zero`, `arg_bool_result`, and `arg_bool_or_false`
- `exp-55` result f64 bool source flow alpha: source may construct and match
the concrete `(result f64 i32)` and `(result bool i32)` families directly;
still no generic results, broad payload families, generic result
combinators, stable ABI/layout, or beta maturity
- `exp-56` integer remainder alpha: `%` is supported for same-width `i32` and
`i64` operands, and `std.math` adds concrete remainder/even/odd helpers;
still no floating-point remainder, modulo semantics beyond signed integer
remainder, bit operations, generic math, stable ABI/layout, or beta maturity
- `exp-57` integer bitwise alpha: `bit_and`, `bit_or`, and `bit_xor` are
supported for same-width `i32` and `i64` operands, and `std.math` adds
concrete bitwise wrappers; still no shifts, bit-not, unsigned arithmetic,
bit-width-specific integer families, generic math, stable ABI/layout, or
beta maturity
- `exp-58` boolean logic alpha: `and` and `or` are short-circuiting boolean
forms, and `not` negates a boolean value; still no truthiness, variadic
boolean operators, pattern guards, macro expansion, stable ABI/layout, or
beta maturity
- `exp-119` benchmark/publication refresh alpha: no language-surface change
over exp-118; current benchmark/publication evidence widens from three
kernels to five by adding `array-index-loop` and `string-eq-loop`, while
keeping local-machine-only framing and no threshold claim
- `exp-122` composite data benchmark/publication refresh alpha: no
language-surface change over exp-121; current benchmark/publication
evidence target widens from five kernels to seven by adding
`array-struct-field-loop` and `enum-struct-payload-loop`, while keeping
local-machine-only framing and no threshold claim
- `exp-120` fixed array struct fields alpha: current promoted fixed immutable
arrays may also appear as direct struct fields with immutable struct flow and
checked indexing after field access, without adding array mutation, field
mutation, nested arrays, or beta maturity
- `exp-121` non-recursive struct enum payloads alpha: current known
non-recursive struct types may also appear as unary enum payload variants
with immutable enum flow and `match` payload binding exposing existing field
access behavior, without adding direct array/vec/option/result payloads,
equality requirements for struct-payload enums, mutation, or beta maturity
- `exp-59` benchmark/publication alpha: no language-surface change over
exp-58; an earlier benchmark/publication baseline was refreshed against the
paired Glagol hosted-build optimization
- `exp-5` local packages/workspaces: explicit workspace members, package
name/version metadata, local path dependencies, package-qualified imports,
deterministic package graph ordering, and artifact-manifest package graph
recording
- `exp-6` C FFI scalar imports alpha: top-level imported C function
declarations with `i32` parameters, `i32` or internal `unit` returns,
lexical `(unsafe ...)` at imported C call sites, explicit local C source
linking, and artifact-manifest foreign-import metadata
- `exp-7` test selection and test-run metadata alpha: `glagol test
<file.slo|project> --filter <substring>`, legacy
`glagol --run-tests --filter <substring> <file.slo>`, deterministic
display-name substring filtering, skipped accounting, zero-match success,
and additive test-report manifest metadata
- `exp-8` host time and sleep alpha: compiler-known
`std.time.monotonic_ms: () -> i32` and
`std.time.sleep_ms: (i32) -> unit`, non-negative host monotonic elapsed
milliseconds with implementation-owned epoch, non-negative millisecond
sleep with `0` valid, exact negative-duration trap text, deterministic
`sleep_ms 0` test-runner behavior, and conservative `monotonic_ms`
structural or non-negative host-value test-runner support
- `exp-9` reliability, performance, and ecosystem hardening: released
hardening-only experimental contract over the exp-8 baseline, with no source
syntax, type-system, standard-runtime, manifest-schema, ABI/layout,
package, runtime-capability, public-performance, or beta-maturity expansion
- `exp-10` result-based host errors alpha: concrete `(result string i32)`,
additive `std.process.arg_result`, `std.env.get_result`,
`std.fs.read_text_result`, and `std.fs.write_text_result`, ordinary host
failure as `err 1`, and exp-3 calls unchanged
- `exp-11` basic randomness alpha: exactly one compiler-known
standard-runtime operation, `std.random.i32: () -> i32`, returning a
non-negative implementation-owned pseudo-random or host-random `i32` for
basic CLI use only
- `exp-12` standard input result alpha: exactly one compiler-known
standard-runtime operation, `std.io.read_stdin_result: () -> (result string
i32)`, reading remaining stdin as text and returning `ok` text, with
ordinary EOF as `ok ""` and ordinary host/input failure as `err 1`
- `exp-13` string parse i32 result alpha: exactly one compiler-known
standard-runtime operation,
`std.string.parse_i32_result: (string) -> (result i32 i32)`, parsing an
entire ASCII decimal signed `i32` string with optional leading `-`, success
as `ok` value, and ordinary parse failure as `err 1`
- `exp-14` standard runtime conformance alignment: released experimental
alignment over the exp-13 surface, adding `STANDARD_RUNTIME.md`, byte-identical
exp-8 time/sleep fixtures, explicit fixture inventory and byte-alignment
gates, and no new source syntax, type forms, runtime APIs, `std.*` names,
manifest schema version, ABI/layout promise, runtime headers/libraries, or
beta maturity
- `exp-15` result helper standard names alpha: compiler-known source-level
`std.result.is_ok`, `std.result.is_err`, `std.result.unwrap_ok`, and
`std.result.unwrap_err` for only the already supported `(result i32 i32)`,
`(result i64 i32)`, `(result string i32)`, and exp-28 returned
`(result f64 i32)` families, plus exp-34 returned `(result bool i32)`, with
legacy unqualified helper names retained as compatibility syntax
v1 scope-freeze decisions are also part of this contract. They clarify what
remains outside v1 rather than adding language features:
- struct field mutation and whole-struct value mutation remain deferred beyond
v1 unless a later explicit promotion updates this spec, examples,
diagnostics, and Glagol tests
- option/result mapping, equality, printing, non-`i32` payloads and
extraction, nested option/result values, arrays or structs containing
option/results, enum payloads beyond exp-16 unary `i32` variants, exp-116
unary direct scalar/string variants, and exp-121 unary current known
non-recursive struct variants, enum import behavior beyond exp-17 explicit
local export/import lists, enum values in containers or nested structs
beyond exp-18 direct fields, generic payloads, string containers beyond
exp-19 direct struct fields and exp-118 fixed immutable arrays, and
user-catchable exceptions remain deferred
unless explicitly promoted later;
exp-10 promotes only the concrete `(result string i32)` family and does not
broaden general option/result support
- `bool` printing is promoted in v1.2 through legacy compiler/runtime
compatibility alias `print_bool`
- `unit` remains an internal builtin result type for supported unit-producing
body forms; `print_unit`, user-declared `unit`, and stored `unit` values
remain unsupported in v1.2
- runtime printing remains limited to legacy compatibility aliases
`print_i32`, `print_string`, and `print_bool` plus v1.5
`std.io.print_i32`, `std.io.print_string`, and `std.io.print_bool`, plus
exp-20 `std.io.print_f64` and exp-21 `std.io.print_i64`;
broader standard-runtime printing remains deferred
- lexical `unsafe` remains the only accepted unsafe boundary; pointer types,
allocation, deallocation, load, store, pointer arithmetic, reinterpretation,
unchecked indexing, raw memory execution, and FFI remain deferred
- stable ABI and stable layout promises remain deferred; v1.6 keeps memory
model direction staged toward safe values by default, future affine
ownership, and explicit unsafe regions
- exp-1 does not change the v1 stable ABI/layout deferral; runtime-owned string
representation, allocator behavior, cleanup timing, and C symbols remain
implementation-owned
- exp-3 does not change the v1 stable ABI/layout deferral; host helper
symbols, path handling, process/environment shims, and runtime string
storage remain implementation-owned
- exp-4 does not change the v1 stable ABI/layout deferral; enum runtime
representation, discriminant values, helper symbols, reflection, and
conversions remain implementation-owned
- exp-5 does not add remote registries, version solving, package publishing,
package generics, package re-exports, or cross-package ABI stability
- exp-6 does not stabilize pointer types, allocation/deallocation, raw unsafe
head execution, ownership/lifetime rules, C exports, callbacks, headers,
libraries, broad linker configuration, ABI, or layout
- exp-7 does not add source language syntax, LSP, debug metadata, source maps,
SARIF, watch/daemon protocols, documentation comments, lint categories,
benchmarks, or richer test-runner features beyond the filtered alpha
- exp-8 does not add source language syntax, threads, tasks, channels, async,
cancellation, actors, shared memory, data-race freedom, scheduling
guarantees, timers, wall-clock/calendar/timezone APIs, high-resolution
timers, signal handling, stable ABI/layout, or stable runtime helper symbols
- exp-10 does not change exp-3 host calls or add general host error ADTs,
platform-specific codes, error messages, `result string Error`, broader host
APIs, manifest schema versions, stable ABI/layout, or beta maturity
- exp-11 does not add seed APIs, cryptographic or security promises, bytes
APIs, ranges or bounds arguments, floats, random strings, UUIDs, stable
helper ABI/layout, randomness-specific manifest fields, or beta maturity
- exp-12 does not add trap-based `std.io.read_stdin`, line iteration, prompt
APIs, terminal mode, binary stdin, streaming, async, encoding or Unicode
promises beyond existing string bytes, stable helper ABI/layout, manifest
schema changes, or beta maturity
- exp-13 does not add trap-based `std.string.parse_i32`, parsing floats,
bools, strings, or bytes, whitespace/locale/base-prefix/underscore/plus-sign
parsing, generic parse APIs, parse error messages or richer codes, Unicode
digit parsing, string indexing or slicing, tokenizer/scanner APIs, stdin
line APIs, stable helper ABI/layout, manifest schema changes, or beta
maturity
- exp-15 does not add `std.result.map`, `std.result.unwrap_or`,
`std.result.and_then`, option helper standard names, new payload families,
generic result support, user-defined error payloads, enum payloads, runtime
ABI/layout claims, manifest schema changes, or beta maturity
- exp-33 does not add generic `std.result.map`, generic
`std.result.unwrap_or`, `std.result.and_then`, option helper standard names,
new result payload families, automatic `std` imports, compiler-loaded
`std/` source, runtime ABI/layout claims, manifest schema changes, or beta
maturity
- exp-34 does not add generic parse APIs, trap-based parse, bool parsing
beyond exactly complete ASCII lowercase `true` and `false`, string/bytes
parse, whitespace trimming, case-insensitive parsing, locale/Unicode
boolean parsing, numeric boolean parsing, rich parse errors,
source-authored `std/result.slo` bool wrappers, automatic `std` imports,
compiler-loaded `std` source, runtime ABI/layout claims, manifest schema
changes, or beta maturity
- exp-35 does not add source-authored generic result helpers,
`std.result.map`, generic `std.result.unwrap_or`, `std.result.and_then`,
option helper names, broad result payload families, automatic `std`
imports, compiler-loaded `std` source, source constructors for
`(result bool i32)`, general source `match` over `(result bool i32)` beyond
compiler-supported fixture flow, runtime ABI/layout claims, manifest schema
changes, or beta maturity
- exp-36 does not add automatic `std` imports, repo-root `std/` search,
compiler-loaded `std` source, new compiler-known `std.*` runtime names,
generic option helpers, option payload families beyond `(option i32)`,
option mapping/chaining helpers, stable standard-library APIs, runtime
ABI/layout claims, manifest schema changes, or beta maturity
- exp-37 does not add automatic `std` imports, repo-root `std/` search,
compiler-loaded `std` source, new compiler-known `std.*` runtime names,
wall-clock/calendar/timezone APIs, high-resolution timers, async timers,
cancellation, scheduling guarantees, stable standard-library APIs, runtime
ABI/layout claims, manifest schema changes, or beta maturity
- exp-38 does not add automatic `std` imports, repo-root `std` search,
compiler-loaded `std` source, new compiler-known `std.*` runtime names,
random seed/range/bytes/float/UUID/crypto APIs, environment mutation/
enumeration, binary/directory/streaming/async filesystem APIs, rich host
error ADTs, runtime ABI/layout claims, manifest schema changes, or beta
maturity
- exp-39 does not add automatic `std` imports, repo-root `std` search,
compiler-loaded `std` source, new compiler-known `std.*` runtime names,
trigonometry, `sqrt`, `pow`, logarithms, modulo, bit operations, generic
math, overloads, traits, mixed numeric arithmetic, optimizer guarantees,
benchmark thresholds, runtime ABI/layout claims, manifest schema changes,
or beta maturity
- exp-20 does not add `f32`, `i64/u64/u32/u16/u8/i16/i8`, `char`, `bytes`,
`decimal`, numeric casts, implicit promotion, mixed `i32`/`f64` arithmetic,
generic numeric operators, f64 arrays/vectors/options/results/enum payloads/
struct fields, mutable `f64` locals, `parse_f64`, random floats, broader
math library calls, stable NaN/infinity/rounding semantics, stable print
formatting beyond newline-terminated output, stable ABI/layout, manifest
schema changes, or beta maturity
- exp-21 does not add `f32`, unsigned integers, narrower integer widths beyond
the existing `i32`, `char`, `bytes`, `decimal`, numeric casts, implicit
promotion, mixed `i32`/`i64`/`f64` arithmetic, generic numeric operators,
i64 arrays/vectors/options/results/enum payloads/struct fields, mutable
`i64` locals, random `i64`, broader math library calls, stable
divide-by-zero or overflow diagnostics, stable ABI/layout, manifest schema
changes, or beta maturity
- exp-22 does not add implicit numeric promotion, mixed numeric arithmetic or
comparison, narrowing or checked numeric conversions, cast syntax, `f32`,
unsigned or narrower integer families, numeric parse/format APIs, stable
floating rounding/formatting guarantees, stable ABI/layout, manifest schema
changes, or beta maturity
- exp-23 does not add implicit numeric promotion, cast syntax, `std.num.cast`,
checked cast generics, mixed numeric operators, any narrowing conversion
other than `std.num.i64_to_i32_result`, `f64` conversions, unsigned or
narrower integer families, numeric parse/format APIs, stable ABI/layout,
manifest schema changes, or beta maturity
- exp-24 does not add `f64` formatting, parse APIs beyond the released
i32/i64 result calls, locale/base/radix/grouping/padding controls, generic
format/display traits, implicit conversions, stable standard-library
implementation source, stable ABI/layout/ownership, manifest schema changes,
or beta maturity
- exp-25 does not add `f64` parse, generic parse, leading `+`, whitespace
trimming, underscores, base/radix prefixes, locale-aware parsing, Unicode
digit parsing, rich parse errors, stable helper ABI/layout/ownership,
manifest schema changes, or beta maturity
- exp-26 does not add `f32`, `f64` parse, generic format/display/
interpolation APIs, locale/base/radix/grouping/padding/precision controls,
stable NaN/infinity text, implicit conversion, stable helper ABI/layout/
ownership, manifest schema changes, or beta maturity
- exp-27 does not add unchecked `f64` to `i32`, casts or cast syntax, generic
`cast_checked`, `f32`, unsigned or narrower integer families, additional
numeric conversion families, `f64` parse, mixed numeric arithmetic, numeric
containers, stable helper ABI/layout/ownership, manifest schema changes, or
beta maturity
- exp-28 does not add generic parse, bool/string/bytes parse, locale parsing,
Unicode digit parsing, underscores, rich parse errors, stable helper
ABI/layout/ownership, result genericity, f64 containers, mixed numeric
arithmetic, manifest schema changes, or beta maturity
## 2. Compatibility Baseline
All Slovo v0 supported fixtures remain valid unless a future section explicitly
defines a migration. Migration-level changes must follow
`MIGRATION_POLICY.md`.
The v0 baseline includes:
- modules
- functions
- top-level tests
- `i32` parameters and returns
- direct `(option i32)` and `(result i32 i32)` constructor returns
- local `i32` `let` and `var`
- `set`
- `+`, `=`, and `<`
- user calls
- `print_i32`
- value-producing `if`
- first-pass `while`
- first-pass structs with immediate field access
- first-pass fixed `i32` arrays and literal indexing
- first-pass option/result constructors
- lexical `unsafe` blocks for otherwise supported safe forms
## 3. v1 Release Gate
Slovo v1 is releasable only when:
- every supported v1 feature is specified in this file
- every supported v1 feature has a fixture under `examples/supported/`
- formatter fixtures exist for every supported v1 surface form
- Glagol keeps a golden machine-diagnostic fixture inventory for every
current explicitly rejected v1 boundary
- Glagol keeps textual lowering-inspector golden fixtures for every promoted
v1 feature family named in section 9.5
- speculative examples remain clearly separated from supported fixtures
- Glagol implements every supported v1 form or rejects source-reachable
unsupported forms with structured diagnostics
- stable LLVM debug metadata, DWARF emission, and source-map files remain
deferred; textual lowering-inspector fixtures are sufficient for v1
- future features add diagnostic and lowering-inspector coverage before
promotion
- Slovo and Glagol roadmaps agree on support status
- v0 compatibility fixtures still pass
## 4. Proposed v1 Priority Order
v1 should complete existing v0 value families before adding unrelated syntax.
Recommended order:
1. Struct value flow
2. Option/result value flow and observation
3. Array value flow and dynamic indexing
4. Runtime string contract
5. Tooling contract improvements
The first accepted v1 slice is struct value flow. The second accepted v1 slice
is option/result value flow and tag observation. The option/result payload
access extension promotes explicit trap-based `i32` extraction forms. The third
accepted v1 slice is array value flow and dynamic indexing for fixed-size
direct scalar arrays. The fourth accepted v1 slice is direct runtime
string-literal printing through `print_string`. The fifth accepted v1 slice is the tooling
contract for versioned machine diagnostics, textual artifact manifests, and
LLVM/source-span direction. The v1.2 practical runtime values release extends
the string slice conservatively and promotes `print_bool` without changing the
v1.1 single-file CLI/toolchain assumptions. The v1.3 project-mode release adds
flat local projects and explicit local modules without adding packages,
dependencies, registries, version solving, workspaces, macros, public ABI,
cross-package visibility, incremental builds, watch/LSP, path escapes, or
generated code. The v1.4 core-language release promotes only source-level
`match` for the existing `(option i32)`, `(option i64)`, `(option f64)`,
`(option bool)`, `(option string)`, and `(result i32 i32)` families without
adding user-defined enums/ADTs, generic payloads, mutation, vectors, broad
numeric expansion, ownership, or layout/ABI promises. The v1.5 standard
library alpha promotes only compiler-known `std.*` source names for the
existing print and string-length runtime behavior, without adding imports,
packages, new data types, IO breadth, allocation, Unicode length semantics, or
ABI promises. The v1.6 memory and unsafe design slice reserves raw unsafe
operation heads for `UnsafeRequired` and `UnsupportedUnsafeOperation` gates
without promoting raw-memory execution. The v1.7 developer experience
hardening release adds only tooling contracts for scaffolding, formatter
check/write modes, deterministic Markdown documentation generation, and a local
release-gate script. `v2.0.0-beta.1` promotes the integrated v1.1-v1.7
workflow as experimental-ready for small flat local projects without adding
new source language syntax or semantics. The later `1.0.0-beta` release is
the first real general-purpose beta milestone. The released compiler-supported
experimental steps are exp-1 owned runtime strings, exp-2 collections alpha,
exp-3 host IO/environment, exp-4 payloadless user enums, exp-5 local
packages/workspaces, exp-6 C FFI scalar imports alpha, exp-7 test
selection/test-run metadata alpha, exp-8 host time/sleep alpha, exp-9
hardening, exp-10 result-based host errors, exp-11 basic randomness, and
exp-12 standard input result alpha, and exp-13 string parse i32 result alpha.
The current released conformance-alignment stage is exp-14 Standard Runtime
Conformance Alignment over the exp-13 surface; it seeds documentation,
fixture, and release-gate conformance without adding source syntax, type
forms, runtime APIs, `std.*` names, manifest schema versions, ABI/layout
promises, runtime headers/libraries, or beta maturity. exp-15 promotes only
preferred `std.result.*` helper names for already
supported concrete result families. These stages do not
promote
generic vectors, broader collections, broad host error ADTs, broad parsing,
result mapping/chaining or generic result helpers,
registries, version solving, package publishing, generics, user-visible
deallocation, broad FFI, LSP, debug metadata, source maps, or stable
ABI/layout promises.
Unsafe raw memory, FFI, pointers, allocation, unchecked indexing, and stable
ABI/layout promises are no longer open v1 execution decisions. They remain
deferred unless an explicit later promotion changes this file.
## 4.1 v1.3 Project Mode And Modules
Status: frozen v1.3 Slovo-side contract. Implementation support requires the
matching Glagol v1.3 gates.
Project mode is selected only when `glagol check`, `glagol test`, or
`glagol build` receives a project root containing `slovo.toml` or the manifest
file itself. Passing one `.slo` file keeps the v1.2 single-file behavior
unchanged.
The manifest is named exactly `slovo.toml`:
```toml
[project]
name = "example"
source_root = "src"
entry = "main"
```
`project.name` is required and must be an ASCII lowercase package-shaped
identifier using `a-z`, `0-9`, and `-`, starting with `a-z`.
`project.source_root` is optional and defaults to `src`; it must be a relative
path under the project root. `project.entry` is optional and defaults to
`main`; it must be a flat module identifier. Unknown manifest sections or keys
are diagnostics. Path escapes from the project root or source root remain
outside v1.3.
v1.3 project modules are immediate `.slo` children of the source root. The
module name is flat, the file stem must match the module declaration, and the
project module set is every immediate `.slo` file in the source root.
The module declaration may include an explicit export list:
```slo
(module math (export add_one Point))
```
The only import form is:
```slo
(import math (add_one Point))
```
Import forms appear after the module declaration and before local `struct`,
`fn`, and `test` declarations. Imported names are unqualified top-level names
inside the importing module. v1.3 has no import aliases, glob imports,
qualified access, or re-exports.
Only exported top-level `fn` and `struct` declarations are importable in the
v1.3 baseline. The later exp-17 experimental contract extends the same
export/import mechanism to top-level enum names in project and workspace
modules. Top-level tests, local bindings, parameters, fields, module names as
values, imported names, builtins, legacy compiler/runtime aliases,
compiler-known standard-runtime names, generated declarations, and
macro-expanded declarations are not exportable or importable.
Name resolution is local declarations, then explicit imported names, then
builtins, legacy aliases, and compiler-known standard-runtime names. v1.3
rejects duplicate local names, duplicate import-list names, duplicate
export-list names, and local/import collisions as `DuplicateName`. Importing
the same unqualified name from two different modules is `AmbiguousName` at the
later import name span; v1.3 does not defer that case to a later use-site.
Project operations are deterministic: source files are sorted
lexicographically by UTF-8 byte order; graph validation uses topological order
with lexicographic tie breaking; tests run by deterministic module order and
source order within each module; artifact manifests list source files, modules,
diagnostics, imports, and outputs deterministically.
Required project diagnostics are:
- `DuplicateName`
- `MissingImport`
- `ImportCycle`
- `AmbiguousName`
- `Visibility`
Source-reachable multi-file diagnostics must include file identity, byte spans,
line/column spans, and related spans for cross-file context. Project artifact
manifests remain `slovo.artifact-manifest` version `1` and record project root,
manifest path, source root, project name, entry module, modules, import edges,
test counts when applicable, diagnostics counts, and build outputs.
v1.3 explicitly defers packages, dependencies, remote registries, version
solving, lockfiles, workspaces, hierarchical modules, import aliases, glob
imports, qualified access, re-exports, macros, public ABI, cross-package
visibility, incremental builds, watch mode, LSP, SARIF, path escapes,
generated code, project formatting, build profiles, cross-compilation, object
output, library output, header output, stable debug metadata, DWARF, and
standalone source-map files.
## 4.2 v1.4 Core Language Expansion
Status: frozen v1.4 Slovo-side contract. Implementation support requires the
matching Glagol v1.4 gates.
v1.4 promotes source-level `match` for already-supported option/result values:
```slo
(match value
((some payload)
payload)
((none)
0))
(match value
((ok payload)
payload)
((err code)
code))
```
The only promoted match subject types are `(option i32)`, `(option i64)`,
`(option f64)`, `(option bool)`, `(option string)`, and `(result i32 i32)`.
An option match must cover exactly `some` and `none`; a result match must
cover exactly `ok` and `err`. Duplicate arms are diagnostics. Arm order is
preserved and does not change semantics.
The only promoted patterns are `(some binding)`, `(none)`, `(ok binding)`, and
`(err binding)`. Payload bindings are immutable and scoped to the selected arm
body only. A payload binding may not collide with a name visible at the match
site or with a local introduced in the same arm body. Identical binding names
in different arms are allowed because arm scopes are disjoint.
Each arm body contains one or more expressions. Non-final arm expressions are
evaluated in source order, and the final expression is the arm value. v1.4 does
not add a general `(block ...)` expression; match arms are the only new nested
body context.
The match expression type is the common final-expression type of all arms. Arm
type mismatches are diagnostics. The subject is evaluated once, only the
selected arm body is evaluated, and matching does not use the trap-based
`unwrap_*` runtime path.
Required match diagnostics are:
- `MatchSubjectTypeMismatch`
- `UnsupportedMatchPayloadType`
- `NonExhaustiveMatch`
- `DuplicateMatchArm`
- `MalformedMatchPattern`
- `MatchArmTypeMismatch`
- `MatchBindingCollision`
- `UnsupportedMatchMutation`
- `UnsupportedMatchContainer`
Existing tag observers and `unwrap_*` forms remain supported, but new examples
prefer `match` for payload-dependent option/result control flow.
The normative v1.4 release contract is
`.llm/V1_4_CORE_LANGUAGE_EXPANSION.md`.
## 4.3 v1.5 Standard Library Alpha
Status: frozen v1.5 Slovo-side contract. Implementation support requires the
matching Glagol v1.5 gates.
v1.5 promotes a conservative source-level standard-runtime namespace over
existing v1.2 runtime behavior:
```slo
(std.io.print_i32 value)
(std.io.print_string value)
(std.io.print_bool value)
(std.string.len value)
```
These names are compiler-known v1.5 standard-runtime names. They do not require
imports, do not name user modules, do not create package dependencies, and are
not stable C ABI symbols.
The exact promoted signatures are:
- `std.io.print_i32`: exactly one `i32`, returns builtin `unit`, same stdout
behavior as legacy `print_i32`
- `std.io.print_string`: exactly one `string`, returns builtin `unit`, same
stdout behavior and string-literal constraints as legacy `print_string`
- `std.io.print_bool`: exactly one `bool`, returns builtin `unit`, same stdout
behavior as legacy `print_bool`
- `std.string.len`: exactly one `string`, returns `i32`, same decoded-byte
count semantics as legacy `string_len`
Existing legacy intrinsic names `print_i32`, `print_string`, `print_bool`, and
`string_len` remain compatibility aliases. New examples prefer `std.*` names.
The promoted `std.*` names are reserved from user function/export shadowing.
Unknown or unpromoted `std.*` calls must produce a structured diagnostic; the
suggested code is `UnsupportedStandardLibraryCall`. Arity and type mismatches
for promoted `std.*` calls should use the existing arity/type diagnostics where
applicable.
v1.5 explicitly defers `std.io.print_unit`, file IO, environment variables,
process arguments, time, vectors/collections, allocation, user-defined
standard modules, imports/packages, overloading, generic APIs, Unicode length
semantics, and ABI/layout promises.
The normative v1.5 release contract is
`.llm/V1_5_STANDARD_LIBRARY_ALPHA.md`.
## 4.4 v1.7 Developer Experience Hardening
Status: frozen v1.7 Slovo-side contract. Implementation support requires the
matching Glagol v1.7 gates.
v1.7 adds tooling contracts only. It does not add source language syntax,
type-system behavior, runtime behavior, standard-runtime names, package
management, dependency management, LSP support, stable debug metadata, DWARF,
or stable source-map files.
`glagol new <project-dir> [--name <name>]` scaffolds a valid v1.3-style
project with `slovo.toml`, `src/main.slo`, and a small testable `main` module
using only already-supported language forms. It must fail without overwriting
non-empty target directories.
`glagol fmt <file.slo>` remains stdout formatting. `glagol fmt --check
<file-or-project>` checks canonical formatting without writing files.
`glagol fmt --write <file-or-project>` writes canonical formatting for one file
or for all immediate `.slo` project source modules in deterministic v1.3
module order. `--check` and `--write` are mutually exclusive.
`glagol doc <file-or-project> -o <dir>` generates deterministic Markdown
documentation from current source structure: modules, imports/exports,
structs, functions, and tests. It is a documentation generator, not a semantic
reflection API, and it does not expose stable typed-core, debug metadata,
source-map, ABI, layout, runtime reflection, or compiler-internal contracts.
The repository must provide a local release-gate script or documented command
entry point that runs the full v1 release gate for the matching Slovo and
Glagol release without network, tag, push, or release-publication side effects.
The normative v1.7 release contract is
`.llm/V1_7_DEVELOPER_EXPERIENCE_HARDENING.md`.
### 4.4.1 Post-Beta Tooling Additions
`1.0.0-beta.1` adds tooling-only conveniences after the `1.0.0-beta`
language baseline. These commands do not change source syntax or typed-core
semantics.
`glagol run <file.slo|project>` builds through the same hosted native path as
`glagol build`, writes an executable under `.slovo/build` by default, executes
it, forwards stdout/stderr, and exits with the program exit status. `-o
<binary>` may override the generated executable path.
`glagol clean <file.slo|project>` removes the generated `.slovo/build`
directory for the given source file directory or project root. It does not
remove custom `-o` build outputs.
`glagol new <project-dir> --template binary|library|workspace` supports three
scaffold shapes. `binary` is the default project with `src/main.slo`.
`library` creates a checkable/testable project with `src/lib.slo`. `workspace`
creates a local two-package workspace using the existing `[workspace]`,
`[package]`, and local path dependency rules.
`scripts/install.sh` installs the beta toolchain layout under a configurable
prefix:
```text
<prefix>/bin/glagol
<prefix>/share/slovo/std/*.slo
<prefix>/share/slovo/runtime/runtime.c
```
Installed `glagol` must discover the standard-library sources and runtime C
input relative to its executable. `SLOVO_STD_PATH` remains the standard-library
source override. `SLOVO_RUNTIME_C` and `GLAGOL_RUNTIME_C` may override the
runtime C input for native builds.
### 4.4.2 Runtime Resource Foundation Additions
Post-`1.0.0-beta.1` main adds the first beta resource-handle foundation for
read-only text files. This is intended for a future `1.0.0-beta.2` bundle and
does not change source syntax.
`std.fs.open_text_read_result <path>` has signature
`(string) -> (result i32 i32)`. Success returns `ok handle`, where `handle` is
a positive opaque process-local `i32`. Ordinary open failure or handle-table
exhaustion returns `err 1`.
`std.fs.read_open_text_result <handle>` has signature
`(i32) -> (result string i32)`. Success reads remaining text from the open
handle and returns `ok text`. Invalid, closed, or failed reads return `err 1`.
`std.fs.close_result <handle>` has signature
`(i32) -> (result i32 i32)`. Success closes the handle and returns `ok 0`.
Invalid, already closed, or failed close operations return `err 1`.
The same beta.2-pre runtime foundation adds narrow filesystem status and
mutation calls:
```text
std.fs.exists: (string) -> bool
std.fs.is_file: (string) -> bool
std.fs.is_dir: (string) -> bool
std.fs.remove_file_result: (string) -> (result i32 i32)
std.fs.create_dir_result: (string) -> (result i32 i32)
```
`exists`, `is_file`, and `is_dir` collapse ordinary metadata failures to
`false`. `remove_file_result` removes one file and `create_dir_result` creates
one directory; both return `ok 0` on success and `err 1` on ordinary host
failure.
Resource handles are beta values. They are not host file descriptors, stable
ABI values, transferable capabilities, or ownership-checked affine values.
Writable handles, binary IO, directory handles, directory enumeration,
recursive filesystem operations, process handles, sockets, async/event-loop
resources, rich host-error ADTs, platform-specific error codes, finalizers,
destructors, and automatic cleanup remain deferred.
## 4.5 v2.0.0-beta.1 Experimental Integration Readiness
Status: current experimental Slovo-side release contract, released 2026-05-17.
Implementation support requires the matching Glagol experimental gate.
`v2.0.0-beta.1` is an experimental integration/readiness release based on
v1.7. It makes the accumulated v1.1-v1.7 surface supported for small real flat
local projects using `glagol new`, `glagol check`, `glagol fmt --check`,
`glagol fmt --write`, `glagol test`, `glagol build`, `glagol doc`, artifact
manifests, JSON diagnostics, and the release-gate script.
The experimental language surface is exactly the gate-proven v1.1-v1.7 surface:
`i32`, `bool`, builtin internal `unit`, tests, locals, `if`, `while`, structs,
fixed direct scalar and fixed string arrays with checked indexing, string value
flow, option/result values and the exact v1.4 match slice, standard-runtime
alpha names, and the v1.6 lexical unsafe boundary with reserved unsafe heads.
Basic IO is limited to `std.io.print_i32`, `std.io.print_string`,
`std.io.print_bool`, and `std.string.len`. File IO, environment variables,
process arguments, time, broader runtime IO, vectors, growable collections,
stable ABI/layout, FFI, raw-memory execution, LSP, stable debug metadata,
stable source-map files, and package registries remain future post-beta work.
Vectors and other growable collections are not required for this experimental
release unless they are separately implemented and gate-proven in Glagol.
Fixed direct scalar arrays with checked indexing satisfy the experimental gate
because this release is an integration milestone, while growable collections
require allocation, ownership/lifetime, mutation, capacity, diagnostics,
lowering, runtime tests, and docs that remain future post-beta work.
The normative experimental release contract is
`.llm/V2_0_0_BETA_1_RELEASE_CONTRACT.md`.
## 4.6 exp-1 Owned Runtime Strings
Status: current experimental compiler-supported contract after matching Glagol
exp-1 gates.
exp-1 promotes exactly one new standard-runtime string operation:
```slo
(std.string.concat left right)
```
The signature is:
```text
std.string.concat: (string, string) -> string
```
The result is an immutable runtime-owned `string` whose decoded byte sequence
is the left operand followed by the right operand. Existing string equality,
`std.string.len`, `std.io.print_string`, string locals, string parameters,
string returns, and calls returning `string` apply to both literal-backed
strings and runtime-owned strings.
`std.string.concat` is compiler-known. It requires no import, does not name a
user module, does not create a package dependency, and is not a stable C ABI
symbol. No legacy `string_concat` alias is introduced.
The compiler/runtime owns cleanup for runtime-owned strings. Cleanup timing,
allocator choice, runtime helper names, object layout, and pointer
representation are not source-visible and are not stable ABI/layout promises.
Safe Slovo code cannot manually free, retain, borrow, or mutate a string.
Allocation failure traps with:
```text
slovo runtime error: string allocation failed
```
The message is written to stderr with a trailing newline and the process exits
with code `1`.
The exact `std.string.concat` name is reserved from user function, export,
import, local, and parameter shadowing. Unknown or unpromoted `std.*` calls
continue to use structured standard-library diagnostics.
exp-1 explicitly defers mutable strings, string containers, string indexing,
string slicing, interpolation, formatting APIs, user-visible deallocation,
file IO, packages, generics, growable collections, raw-memory execution, FFI,
and stable ABI/layout promises.
The normative exp-1 contract is
`.llm/EXP_1_OWNED_RUNTIME_STRINGS.md`.
## 4.7 exp-2 Collections Alpha
Status: current experimental compiler-supported contract after matching Glagol
exp-103 gates.
exp-2 promotes one concrete growable vector type, and exp-94 extends the slice
with exactly one additional concrete growable vector type. exp-99 extends the
same slice with one more concrete growable vector type, and exp-103 extends
it again with one more concrete growable vector type:
```text
(vec i32)
(vec f64)
(vec i64)
(vec string)
```
Together the slice promotes exactly sixteen compiler-known standard-runtime
operations:
```text
std.vec.i32.empty: () -> (vec i32)
std.vec.i32.append: ((vec i32), i32) -> (vec i32)
std.vec.i32.len: ((vec i32)) -> i32
std.vec.i32.index: ((vec i32), i32) -> i32
std.vec.f64.empty: () -> (vec f64)
std.vec.f64.append: ((vec f64), f64) -> (vec f64)
std.vec.f64.len: ((vec f64)) -> i32
std.vec.f64.index: ((vec f64), i32) -> f64
std.vec.i64.empty: () -> (vec i64)
std.vec.i64.append: ((vec i64), i64) -> (vec i64)
std.vec.i64.len: ((vec i64)) -> i32
std.vec.i64.index: ((vec i64), i32) -> i64
std.vec.string.empty: () -> (vec string)
std.vec.string.append: ((vec string), string) -> (vec string)
std.vec.string.len: ((vec string)) -> i32
std.vec.string.index: ((vec string), i32) -> string
```
The source call forms are:
```slo
(std.vec.i32.empty)
(std.vec.i32.append values value)
(std.vec.i32.len values)
(std.vec.i32.index values index)
(std.vec.f64.empty)
(std.vec.f64.append values value)
(std.vec.f64.len values)
(std.vec.f64.index values index)
(std.vec.i64.empty)
(std.vec.i64.append values value)
(std.vec.i64.len values)
(std.vec.i64.index values index)
(std.vec.string.empty)
(std.vec.string.append values value)
(std.vec.string.len values)
(std.vec.string.index values index)
```
An exp-2 `(vec i32)`, exp-94 `(vec i64)`, exp-99 `(vec string)`, and
exp-103 `(vec f64)` are immutable runtime-owned vectors. They may flow
through immutable `let` locals, parameters, returns, calls returning the
same vector family, and top-level tests.
`std.vec.i32.append` returns a new immutable runtime-owned vector containing
the input vector's elements followed by the appended `i32`; it must not mutate
the input vector. `std.vec.i64.append` returns a new immutable runtime-owned
vector containing the input vector's elements followed by the appended `i64`;
it must not mutate the input vector. `std.vec.f64.append` returns a new
immutable runtime-owned vector containing the input vector's elements
followed by the appended `f64`; it must not mutate the input vector.
`std.vec.string.append` returns a new
immutable runtime-owned vector containing the input vector's elements followed
by the appended `string`; it must not mutate the input vector.
`std.vec.i32.len`, `std.vec.i64.len`, `std.vec.f64.len`, and
`std.vec.string.len` return vector length as `i32`. `std.vec.i32.index`
returns an `i32` element, `std.vec.i64.index` returns an `i64` element,
`std.vec.f64.index` returns an `f64` element, and `std.vec.string.index`
returns a `string` element, after the same runtime bounds check equivalent
to `0 <= index && index < len`.
Vector equality uses `=` with either two `(vec i32)` operands, two
`(vec i64)` operands, two `(vec f64)` operands, or two `(vec string)`
operands, returns `bool`, and compares length and element values in order.
It is not pointer identity, allocation identity, capacity equality, or
layout equality.
Allocation failure traps with:
```text
slovo runtime error: vector allocation failed
```
Index failure traps with:
```text
slovo runtime error: vector index out of bounds
```
Both messages are written to stderr with a trailing newline and exit the
process with code `1`.
The `std.vec.i32.*`, `std.vec.i64.*`, `std.vec.f64.*`, `std.vec.bool.*`, and
`std.vec.string.*` names are compiler-known. They require no import, do not
name user modules, do not create package dependencies, and are not stable C
ABI symbols or stable runtime helper symbols. The exact promoted names are
reserved from user function, export, import, local, and parameter
shadowing.
The latest released Slovo-side collection target after exp-107 is `exp-108`,
Standard Vec String, F64, And Bool Prefix And Suffix Helpers Alpha. It
broadens `std/vec_string.slo`, `std/vec_f64.slo`, and `std/vec_bool.slo`
with exactly `starts_with`, `without_prefix`, `ends_with`, and
`without_suffix` over the already released concrete vec-string, vec-f64, and
vec-bool helper surfaces. The helper lanes stay source-authored,
recursive, and immutable and do not widen the promoted collection runtime
surface beyond those connected prefix/suffix helpers.
The collections alpha slice explicitly defers generic vectors, vector element
types other than `i32`, `i64`, `f64`, `bool`, and `string`, vector mutation, vector
`var`, vector `set`, vector literals besides empty/append construction, a `push`
alias, nested vectors, vectors in arrays, vectors in structs, vectors in
options, vectors in results, iterators, slices, maps, sets, user-visible
deallocation, stable ABI/layout/helper-symbol promises, package expansion,
and IO expansion.
The collection fixture targets are:
```text
examples/supported/vec-i32.slo
examples/formatter/vec-i32.slo
examples/supported/vec-bool.slo
examples/formatter/vec-bool.slo
examples/supported/vec-i64.slo
examples/formatter/vec-i64.slo
examples/supported/vec-string.slo
examples/formatter/vec-string.slo
```
They are current compiler-supported fixtures.
The normative contracts are `.llm/EXP_2_COLLECTIONS_ALPHA.md` and
`.llm/EXP_94_STANDARD_VEC_I64_BASELINE_ALPHA.md` plus
`.llm/EXP_99_STANDARD_VEC_STRING_BASELINE_ALPHA.md`.
## 4.8 exp-3 Standard IO And Host Environment
Status: current experimental compiler-supported contract after matching Glagol
exp-3 gates.
exp-3 promotes exactly six compiler-known host functions:
```text
std.io.eprint: (string) -> unit
std.process.argc: () -> i32
std.process.arg: (i32) -> string
std.env.get: (string) -> string
std.fs.read_text: (string) -> string
std.fs.write_text: (string string) -> i32
```
The source call forms are:
```slo
(std.io.eprint value)
(std.process.argc)
(std.process.arg index)
(std.env.get name)
(std.fs.read_text path)
(std.fs.write_text path text)
```
`std.io.eprint` writes the string to stderr without appending a newline and
returns builtin `unit`. `std.process.argc` returns the process argument count
as `i32`. `std.process.arg` uses zero-based indexing and returns a `string`.
Out-of-range argument access traps with:
```text
slovo runtime error: process argument index out of bounds
```
`std.env.get` returns the environment variable value as `string`; a missing
variable returns the empty string in exp-3.
`std.fs.read_text` reads a whole text file and returns `string`. Host read
failure traps with:
```text
slovo runtime error: file read failed
```
`std.fs.write_text` writes a whole string to a path and returns `0` on success
or `1` on host failure.
The trap messages are written to stderr with a trailing newline and exit with
code `1`. Strings returned by process, environment, and file APIs are
immutable runtime-provided strings. exp-3 does not promise whether host strings
are copied, borrowed from host process storage, or allocated by private runtime
helpers; source code cannot observe storage identity or cleanup timing. File
read allocation failure is reported through the exp-3 file-read trap in this
stage.
The promoted names are compiler-known. They require no import, do not name user
modules, do not create package dependencies, and are not stable C ABI symbols
or stable runtime helper symbols. The exact promoted names are reserved from
user function, export, import, local, and parameter shadowing.
exp-3 explicitly defers networking, async IO, binary file APIs, directory
traversal, terminal control, platform abstraction, general host error ADTs,
`result string Error`, package interaction, stdin full read or line iteration,
randomness, time, stable ABI/layout, and stable runtime helper symbols.
The exp-3 fixtures are:
```text
examples/supported/host-io.slo
examples/formatter/host-io.slo
```
They are current compiler-supported fixtures.
The normative exp-3 contract is
`.llm/EXP_3_STANDARD_IO_HOST_ENV.md`.
## 4.9 exp-4 User Data Types And Polymorphism
Status: current experimental compiler-supported contract after matching Glagol
exp-4 gates.
exp-4 promotes payloadless user-defined enum declarations only:
```slo
(enum Name VariantA VariantB)
```
An enum declaration must have at least one variant. Variant values are
constructed through zero-argument qualified calls:
```slo
(Name.VariantA)
```
An exp-4 enum value may flow through immutable `let` locals, parameters,
returns, calls returning the enum type, equality with `=`, and top-level tests.
Enum equality is defined only for two values of the same enum type and compares
variant identity.
`match` supports enum subjects with exhaustive payloadless variant arms:
```slo
(match value
((Name.VariantA)
body...)
((Name.VariantB)
body...))
```
Every variant of the subject enum must appear exactly once. Enum match arms
have one or more expression bodies, and the final expression of each arm must
share a common result type, following the existing option/result match rule.
The runtime/backend representation is compiler-owned. exp-4 makes no stable
layout, discriminant value, ABI, helper-symbol, reflection, or conversion to
`i32` promise.
exp-4 explicitly defers payload variants, tuple variants, record variants,
generic enums, generic functions, type aliases, traits, interfaces, protocols,
methods, derives, variant payload binding, wildcard patterns, rest patterns,
guards, nested patterns, enum values in arrays, enum values in struct fields,
enum values in options, enum values in results, enum values in vectors, enum
mutation, enum printing, enum ordering, enum hashing, reflection, explicit
discriminants, enum constructors with arguments, unqualified variant
constructors, stable ABI/layout, stable helper symbols, and moving
option/result to ordinary standard-library types.
The exp-4 fixtures are:
```text
examples/supported/enum-basic.slo
examples/formatter/enum-basic.slo
```
They are current compiler-supported fixtures.
The normative exp-4 contract is
`.llm/EXP_4_USER_ADTS_ALPHA.md`.
### 4.9.1 exp-16 Unary I32 Enum Payloads Alpha
Status: released experimental Slovo contract. Matching Glagol exp-16 gates are
required before broader compiler-support claims.
exp-16 extends user-defined enum declarations to allow payloadless variants
and unary `i32` payload variants in the same enum:
```slo
(enum Reading
Missing
(Value i32)
(Offset i32))
```
Payloadless variants continue to use zero-argument qualified constructors:
```slo
(Reading.Missing)
```
Payload variants use qualified constructors with exactly one `i32` argument:
```slo
(Reading.Value value)
```
Enum values may flow through immutable locals, parameters, returns, calls,
top-level tests, and `main`.
`match` supports exhaustive arms for both payloadless and unary payload
variants:
```slo
(match reading
((Reading.Missing)
0)
((Reading.Value payload)
payload))
```
Payload variants require exactly one binding in match arms. Payloadless
variants take no binding. Payload bindings are immutable names scoped only to
the selected arm body.
Enum equality is defined only for two values of the same enum type. Payload
variants compare by tag and payload value. Payloadless variants compare by tag.
The runtime/backend representation is compiler-owned. exp-16 makes no stable
layout, discriminant value, ABI, helper-symbol, reflection, printing, hashing,
ordering, or conversion to `i32` promise.
exp-16 explicitly defers payload types other than `i32`, multiple payloads,
record variants, tuple variants beyond one `i32`, string/bool/struct/enum
payloads, generic enums, generic functions, type aliases, traits, methods,
derives, wildcard/rest/nested enum patterns, pattern guards, enum payload
mutation, enum values inside arrays/structs/options/results/vectors, enum
printing/ordering/hash/reflection/discriminants/stable ABI/layout, moving
option/result to ordinary standard-library types, manifest schema changes,
runtime ABI/layout claims, and beta maturity.
The exp-16 fixtures are:
```text
examples/supported/enum-payload-i32.slo
examples/formatter/enum-payload-i32.slo
```
The normative exp-16 contract is
`.llm/EXP_16_UNARY_I32_ENUM_PAYLOADS_ALPHA.md`.
### 4.9.2 exp-17 Project Enum Imports Alpha
Status: released experimental Slovo contract. Matching Glagol exp-17 gates are
required before broader compiler-support claims.
exp-17 extends explicit project and workspace module boundaries so export
lists may include top-level enum names:
```slo
(module readings (export Reading))
```
Import lists may import those exported enum names:
```slo
(import readings (Reading))
```
In exp-5 workspace packages, the existing package-qualified module import form
may also import exported enum names from direct local dependencies:
```slo
(import sensors.readings (Reading))
```
Imported enum types may be used in function signatures, immutable local type
annotations, calls/returns, same-enum equality, exhaustive enum matches, and
qualified constructors.
The enum surface is exactly the exp-4 payloadless enum surface plus the exp-16
unary `i32` payload enum surface. No other payload types, generic enums,
containers, mutation, printing, ordering, hashing, reflection, stable
ABI/layout, manifest schema changes, registry/package-manager behavior, or
beta maturity are added.
The exp-17 project fixture is:
```text
examples/projects/enum-imports/slovo.toml
examples/projects/enum-imports/src/readings.slo
examples/projects/enum-imports/src/main.slo
```
No formatter project fixture is defined because the current Slovo formatter
fixture convention is single-file fixtures under `examples/formatter/`, not
whole project directories.
The normative exp-17 contract is
`.llm/EXP_17_PROJECT_ENUM_IMPORTS_ALPHA.md`.
### 4.9.3 exp-18 Enum Struct Fields Alpha
Status: released experimental Slovo contract. Matching Glagol exp-18 gates are
required before broader compiler-support claims.
exp-18 extends struct field declarations so field types may be current
user-defined enum type names:
```slo
(enum Status Ready Blocked)
(enum Reading
Missing
(Value i32))
(struct TaggedReading
(status Status)
(reading Reading))
```
Struct construction uses the existing field initializer form, with enum values
provided through the already promoted qualified enum constructors:
```slo
(TaggedReading (status (Status.Ready)) (reading (Reading.Value payload)))
```
Field access through an enum-typed field returns the declared enum type:
```slo
(. tagged reading)
```
That field access expression may be used in same-enum equality and exhaustive
enum `match`:
```slo
(= (. tagged status) (Status.Ready))
(match (. tagged reading)
((Reading.Missing)
0)
((Reading.Value payload)
payload))
```
The enum field surface is exactly the exp-4 payloadless enum surface plus the
exp-16 unary `i32` payload enum surface. Enum-typed struct fields may flow
through struct construction, immutable struct locals, struct parameters,
struct returns, calls returning structs, field access, top-level tests, and
`main`.
exp-18 does not add enum payload types other than `i32`, multiple payloads,
record variants, tuple variants beyond one `i32`, enum values inside arrays,
options, results, or vectors, arrays/options/results/vectors containing
enum-typed structs, nested structs, struct mutation, enum mutation, printing,
ordering, hashing, reflection, import aliases/globs/re-exports, manifest
schema changes, package-manager behavior, stable ABI/layout, generics, or beta
maturity.
The exp-18 fixtures are:
```text
examples/supported/enum-struct-fields.slo
examples/formatter/enum-struct-fields.slo
```
The normative exp-18 contract is
`.llm/EXP_18_ENUM_STRUCT_FIELDS_ALPHA.md`.
### 4.9.4 exp-19 Primitive Struct Fields Alpha
Status: released experimental Slovo contract. Matching Glagol exp-19 gates are
required before broader compiler-support claims.
exp-19 extends struct field declarations so field types may be direct `bool`
and immutable `string`, alongside already supported direct `i32` and exp-18
enum fields:
```slo
(struct PrimitiveRecord
(id i32)
(active bool)
(label string))
```
Struct construction uses the existing field initializer form:
```slo
(PrimitiveRecord (id id) (active (= id 7)) (label label))
```
Field access through a primitive field returns the declared primitive type:
```slo
(. record active)
(. record label)
```
Those field access expressions may be used in existing operations for the
declared type:
```slo
(if (. record active) (. record id) 0)
(= (. record label) "alpha")
(std.string.len (. record label))
```
The primitive field surface is exactly direct `i32`, direct `bool`, and
immutable direct `string`. Primitive-typed struct fields may flow through
struct construction, immutable struct locals, struct parameters, struct
returns, calls returning structs, field access, top-level tests, and `main`.
exp-19 does not add arrays, vectors, options, or results containing
primitive-field structs, primitive fields inside containers, nested structs,
struct mutation, mutable string locals, string assignment, string mutation,
ownership/cleanup guarantees beyond existing string behavior, broader string
operations, printing beyond existing legacy and v1.5 calls, package/import
widening, manifest schema changes, stable ABI/layout, generics, methods,
traits, or beta maturity.
The exp-19 fixtures are:
```text
examples/supported/primitive-struct-fields.slo
examples/formatter/primitive-struct-fields.slo
```
The normative exp-19 contract is
`.llm/EXP_19_PRIMITIVE_STRUCT_FIELDS_ALPHA.md`.
### 4.9.4a exp-112 Immutable Bool Locals Alpha
Status: released experimental Slovo contract. Matching Glagol exp-112 gates
are required before broader compiler-support claims.
exp-112 broadens local bindings with direct immutable `bool` locals:
```slo
(let flag bool true)
```
The promoted surface is:
- immutable `let` locals declared as `bool`
- local initializers from already promoted bool literals, parameters, calls
returning bool, and `if` expressions returning bool
- local references in existing predicate, return, call, top-level test, and
`main` positions
Mutable `bool` locals remain unsupported; exp-112 does not broaden `var` or
`set`.
The exp-112 fixtures are:
```text
examples/supported/local-variables.slo
examples/formatter/local-variables.slo
examples/projects/std-import-io/
```
The supported/formatter local-variables fixture keeps the earlier i32 local
surface and now also includes direct immutable bool locals. The current
`std-import-io` explicit import fixture uses bool locals in its stdin bool
fallback helper path once the compiler accepts that local family.
exp-112 does not add mutable `bool` locals, bool assignment, new boolean
operators, broader local-type widening, automatic imports, compiler-known
runtime names, manifest schema changes, stable ABI/layout, or beta maturity.
The normative exp-112 contract is
`.llm/EXP_112_IMMUTABLE_BOOL_LOCALS_ALPHA.md`.
### 4.9.4b exp-113 Mutable Scalar Locals Alpha
Status: released experimental Slovo contract. Matching Glagol exp-113 gates
are required before broader compiler-support claims.
exp-113 broadens local bindings with mutable scalar var/set flows:
```slo
(var total i64 40i64)
(set total (+ total 2i64))
```
The promoted surface is:
- mutable `var` locals declared as `bool`, `i64`, or `f64`
- `set` reassignment from already promoted same-type scalar expressions for
those declared local types
- use in ordinary function bodies, top-level tests, and `main`
The exp-113 fixtures are:
```text
examples/supported/local-variables.slo
examples/formatter/local-variables.slo
```
The supported/formatter local-variables fixture retains the earlier i32 local
surface and exp-112 immutable bool locals, and now also covers mutable
`bool`, `i64`, and `f64` local var/set flows.
exp-113 does not add mutable `string` locals, vector mutation, option/result
mutation, struct or enum mutation, mixed-type assignment, automatic imports,
compiler-known runtime names, manifest schema changes, stable ABI/layout, or
beta maturity.
The normative exp-113 contract is
`.llm/EXP_113_MUTABLE_SCALAR_LOCALS_ALPHA.md`.
### 4.9.4c exp-114 Mutable Composite Locals Alpha
Status: released experimental Slovo contract. Matching Glagol exp-114 gates
are required before broader compiler-support claims.
exp-114 broadens local bindings with mutable whole-value composite var/set
flows:
```slo
(var label string "oak")
(set label "slovo")
```
The promoted surface is:
- mutable `var` locals declared as `string`
- mutable `var` locals declared as the current concrete vec families:
`(vec i32)`, `(vec i64)`, `(vec f64)`, `(vec bool)`, and `(vec string)`
- mutable `var` locals declared as the current concrete option families:
`(option i32)`, `(option i64)`, `(option f64)`, `(option bool)`, and
`(option string)`
- mutable `var` locals declared as the current concrete result families:
`(result i32 i32)`, `(result i64 i32)`, `(result f64 i32)`,
`(result bool i32)`, and `(result string i32)`
- mutable `var` locals declared as current known struct value types
- mutable `var` locals declared as current enum value types
- `set` reassignment from already promoted expressions of the exact same local
type
- use in ordinary function bodies, top-level tests, and `main`
The reassignment is whole-value only. Existing field access, vec indexing,
option/result observers and payload extraction, equality, and enum/option/
result `match` continue to operate after the reassignment.
The exp-114 fixtures are:
```text
examples/supported/composite-locals.slo
examples/formatter/composite-locals.slo
```
The supported/formatter composite-locals fixture covers same-type mutable
whole-value local reassignment for strings, the current concrete vec families,
the current concrete option/result families, current known struct values, and
current enum values.
exp-114 does not add mutable arrays, array mutation, field mutation, vector
element mutation, option/result payload mutation, enum payload mutation,
mixed-type assignment, automatic imports, compiler-known runtime names,
manifest schema changes, stable ABI/layout, or beta maturity.
The normative exp-114 contract is
`.llm/EXP_114_MUTABLE_COMPOSITE_LOCALS_ALPHA.md`.
### 4.9.5 exp-20 F64 Numeric Primitive Alpha
Status: released experimental Slovo contract. Matching Glagol exp-20 gates are
required before broader compiler-support claims.
exp-20 introduces direct `f64` as the first non-`i32` numeric primitive:
```slo
(fn half ((value f64)) -> f64
(/ value 2.0))
```
The promoted direct `f64` surface is:
- `f64` function parameters and returns
- immutable `let` locals declared as `f64`
- calls passing and returning `f64`
- decimal `f64` literals in `f64` contexts
- same-type `f64` `+`, `-`, `*`, and `/`
- same-type `f64` `=`, `<`, `>`, `<=`, and `>=`
- `std.io.print_f64`
- top-level tests and `main` bodies; `main` still returns `i32`
`std.io.print_f64` accepts exactly one `f64`, returns builtin `unit`, and
prints an implementation-owned finite `f64` textual representation plus a
newline. Source-level NaN and infinity literals are unsupported in exp-20.
exp-20 does not stabilize exact printed digits beyond newline-terminated
output.
All promoted arithmetic and comparison is same-type `f64`. exp-20 does not add
mixed `i32`/`f64` arithmetic, numeric casts, implicit promotion, overloaded
operators, or generic numeric abstractions.
The exp-20 fixtures are:
```text
examples/supported/f64-numeric-primitive.slo
examples/formatter/f64-numeric-primitive.slo
```
The normative exp-20 contract is
`.llm/EXP_20_F64_NUMERIC_PRIMITIVE_ALPHA.md`.
### 4.9.6 exp-22 Numeric Widening Conversions Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-22
gates are required before broader compiler-support claims.
exp-22 promotes exactly three explicit compiler-known standard-runtime calls
over the current `i32`, `i64`, and `f64` numeric primitives:
- `std.num.i32_to_i64 : (i32) -> i64`
- `std.num.i32_to_f64 : (i32) -> f64`
- `std.num.i64_to_f64 : (i64) -> f64`
The promoted calls are ordinary source calls and can feed same-type arithmetic
or comparison after conversion. exp-22 does not introduce implicit promotion,
mixed numeric arithmetic/comparison, narrowing or checked conversions, cast
syntax, `f32`, unsigned or narrower integer families, numeric parse/format
APIs, stable ABI/layout, manifest schema changes, or beta maturity.
The exp-22 fixtures are byte-identical:
```text
examples/supported/numeric-widening-conversions.slo
examples/formatter/numeric-widening-conversions.slo
```
The normative exp-22 contract is
`.llm/EXP_22_NUMERIC_WIDENING_CONVERSIONS_ALPHA.md`.
### 4.9.7 exp-23 Checked I64-To-I32 Conversion Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-23
gates are required before broader compiler-support claims.
exp-23 promotes exactly one checked narrowing compiler-known standard-runtime
call:
- `std.num.i64_to_i32_result : (i64) -> (result i32 i32)`
The promoted call is an ordinary source call. It returns `ok value` when the
signed `i64` input is within the signed `i32` range `-2147483648` through
`2147483647`, and returns `err 1` when the input is outside that range. Range
failure does not trap.
The returned `(result i32 i32)` value uses the existing result helper surface.
exp-23 does not introduce implicit promotion, mixed numeric
arithmetic/comparison, cast syntax, `std.num.cast`, checked cast generics, any
other narrowing conversion, `f64` conversions, unsigned or narrower integer
families, numeric parse/format APIs, stable ABI/layout, manifest schema
changes, or beta maturity.
The exp-23 fixtures are byte-identical:
```text
examples/supported/checked-i64-to-i32-conversion.slo
examples/formatter/checked-i64-to-i32-conversion.slo
```
The normative exp-23 contract is
`.llm/EXP_23_CHECKED_I64_TO_I32_CONVERSION_ALPHA.md`.
### 4.9.8 exp-24 Integer To String Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-24
gates are required before broader compiler-support claims.
exp-24 promotes exactly two integer formatting compiler-known
standard-runtime calls:
- `std.num.i32_to_string : (i32) -> string`
- `std.num.i64_to_string : (i64) -> string`
The promoted calls are ordinary source calls. Each returns the decimal signed
ASCII string for the input value. Negative values include a leading `-`;
non-negative values have no leading `+`.
Returned strings use the existing `string` surface: string equality,
`std.string.len`, immutable locals, function returns, calls, and
`std.io.print_string`. The implementation is compiler/runtime-backed for now
and may later move into Slovo `std` source once the language can host it.
exp-24 does not introduce `f64` formatting, parse APIs beyond the released
i32/i64 result calls, locale/base/radix, grouping, or padding controls,
generic format/display traits, implicit conversions, stable standard-library
implementation source, stable helper ABI/layout/ownership, manifest schema
changes, or beta maturity.
The exp-24 fixtures are byte-identical:
```text
examples/supported/integer-to-string.slo
examples/formatter/integer-to-string.slo
```
The normative exp-24 contract is
`.llm/EXP_24_INTEGER_TO_STRING_ALPHA.md`.
### 4.9.9 exp-25 String Parse I64 Result Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-25
gates are required before broader compiler-support claims.
exp-25 promotes exactly one string parse compiler-known standard-runtime call:
- `std.string.parse_i64_result : (string) -> (result i64 i32)`
The promoted call parses the entire input string as a non-empty ASCII signed
decimal `i64`. Accepted input has an optional leading `-`, one or more ASCII
digits, and a numeric value in the signed `i64` range. Success returns
`ok value`; ordinary parse failure and out-of-range input return `err 1`.
The empty string, a lone `-`, any leading `+`, whitespace, non-digits,
underscores, base/radix prefixes, suffixes, locale-specific digits or
separators, Unicode digits, trailing bytes, and out-of-range values all return
`err 1`. Ordinary parse failure and range failure do not trap.
exp-25 extends the supported concrete result families to include
`(result i64 i32)` for result observation, extraction, direct matching, and
fixture value flow. It does not add generic results, stable result ABI/layout,
or result helper behavior beyond the explicitly supported concrete family.
The exp-25 fixtures are byte-identical:
```text
examples/supported/string-parse-i64-result.slo
examples/formatter/string-parse-i64-result.slo
```
The normative exp-25 contract is
`.llm/EXP_25_STRING_PARSE_I64_RESULT_ALPHA.md`.
### 4.9.10 exp-26 F64 To String Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-26
gates are required before broader compiler-support claims.
exp-26 promotes exactly one finite `f64` formatting compiler-known
standard-runtime call:
- `std.num.f64_to_string : (f64) -> string`
The promoted call returns finite decimal ASCII text for promoted finite `f64`
inputs. The exp-26 fixture values are `0.0`, `3.5`, `-1.5`, and `10.0`.
This slice does not define `f32`, `f64` parse, generic format/display/
interpolation APIs, locale/base/radix/grouping/padding/precision controls,
stable NaN/infinity text, implicit conversion, stable helper ABI/layout/
ownership, manifest schema changes, or beta maturity.
The exp-26 fixtures are byte-identical:
```text
examples/supported/f64-to-string.slo
examples/formatter/f64-to-string.slo
```
The normative exp-26 contract is `.llm/EXP_26_F64_TO_STRING_ALPHA.md`.
### 4.9.11 exp-27 Checked F64 To I32 Result Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-27
gates are required before broader compiler-support claims.
exp-27 promotes exactly one checked `f64` to `i32` result compiler-known
standard-runtime call:
- `std.num.f64_to_i32_result : (f64) -> (result i32 i32)`
The promoted call returns `ok value` only when the input is finite, exactly
integral, and within the signed `i32` range `-2147483648` through
`2147483647`. It returns `err 1` for non-finite, fractional, or out-of-range
input. Ordinary conversion failure does not trap.
The exp-27 fixture values are `0.0 -> ok 0`, `-12.0 -> ok -12`,
`3.5 -> err 1`, and `2147483648.0 -> err 1`.
This slice does not define unchecked `f64` to `i32`, casts or cast syntax,
generic `cast_checked`, `f32`, unsigned or narrower integer families,
additional numeric conversion families, `f64` parse, mixed numeric arithmetic,
numeric containers, stable helper ABI/layout/ownership, manifest schema
changes, or beta maturity.
The exp-27 fixtures are byte-identical:
```text
examples/supported/f64-to-i32-result.slo
examples/formatter/f64-to-i32-result.slo
```
The normative exp-27 contract is
`.llm/EXP_27_F64_TO_I32_RESULT_ALPHA.md`.
### 4.9.12 exp-28 String Parse F64 Result Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-28
gates are required before broader compiler-support claims.
exp-28 promotes exactly one string parse compiler-known standard-runtime call:
- `std.string.parse_f64_result : (string) -> (result f64 i32)`
The promoted call parses the entire input string as finite ASCII decimal
`f64` text. Accepted fixture input has an optional leading `-`, one or more
ASCII digits before a decimal point, a decimal point `.`, one or more ASCII
digits after the decimal point, and a finite value representable as `f64`.
Success returns `ok value`.
Ordinary parse failure, non-finite text, leading or trailing unsupported
characters, and out-of-domain input return `err 1`. Ordinary parse failure
and domain failure do not trap.
The exp-28 fixture values are `12.5 -> ok 12.5`, `-0.25 -> ok -0.25`,
`abc -> err 1`, and `nan -> err 1`.
This slice does not define generic parse, bool/string/bytes parse, locale
parsing, Unicode digit parsing, underscores, rich parse errors, stable helper
ABI/layout/ownership, result genericity, f64 containers, mixed numeric
arithmetic, manifest schema changes, or beta maturity.
The exp-28 fixtures are byte-identical:
```text
examples/supported/string-parse-f64-result.slo
examples/formatter/string-parse-f64-result.slo
```
The normative exp-28 contract is
`.llm/EXP_28_STRING_PARSE_F64_RESULT_ALPHA.md`.
### 4.9.13 exp-29 Numeric Struct Fields Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-29
gates are required before broader compiler-support claims.
exp-29 promotes direct immutable struct field declarations whose field types
are exactly `i64` or `f64`, alongside the already supported direct `i32`,
`bool`, immutable `string`, and current enum fields.
Struct constructors may initialize `i64` fields from `i64` values and explicit
signed decimal `i64` literal atoms. They may initialize `f64` fields from
finite `f64` values and finite decimal `f64` literals. The exp-20 finite-only
policy remains in force; non-finite `f64` literals are not promoted.
Immutable struct values carrying numeric fields may flow through locals,
parameters, returns, and calls. Field access returns the declared `i64` or
`f64` type. Accessed fields may be used with existing same-type
arithmetic/comparison and existing numeric print/format helpers where already
supported.
This slice does not define struct field mutation, nested structs,
arrays/vectors/options/results as fields, enum payload widening, numeric
containers, `f32`, unsigned or narrower integer families, mixed numeric
arithmetic, implicit conversions, new parse/format APIs, generic structs,
methods, traits, stable ABI/layout/ownership, manifest schema changes, FFI
layout claims, or beta maturity.
The exp-29 fixtures are byte-identical:
```text
examples/supported/numeric-struct-fields.slo
examples/formatter/numeric-struct-fields.slo
```
The normative exp-29 contract is
`.llm/EXP_29_NUMERIC_STRUCT_FIELDS_ALPHA.md`.
### 4.9.14 exp-30 Standard Library Source Layout Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-30
gates are required before broader compiler-support claims.
exp-30 establishes `std/` as the Slovo source home for staged standard library
modules and examples:
```text
std/README.md
std/io.slo
std/string.slo
std/num.slo
std/result.slo
std/math.slo
```
The source files use current valid Slovo where practical. Because current
project import support does not promote a repo-root `std/` search path, the
staged files use plain flat module declarations such as `(module math)`.
`std/math.slo` contains narrow source-authored helpers expressible with the
current language: `abs_i32`, `min_i32`, `max_i32`, `clamp_i32`,
`square_i32`, and `square_f64`. The other staged modules may wrap already
promoted compiler-known standard-runtime calls with short module-local names.
This slice does not define automatic standard-library imports, replacement of
compiler-known `std.*` calls with source implementations, new compiler-known
`std.*` operation names, generics, traits, overloads, module/package registry
changes, stable standard-library APIs, stable ABI/layout/ownership, manifest
schema changes, broad math, trigonometry, `pow`, `sqrt`, `f32`, unsigned or
narrower integers, mixed numeric arithmetic, numeric containers, or beta
maturity.
The exp-30 formatter example is:
```text
examples/formatter/std-source-layout-alpha.slo
```
The normative exp-30 contract is
`.llm/EXP_30_STANDARD_LIBRARY_SOURCE_LAYOUT_ALPHA.md`.
### 4.9.15 exp-31 Checked F64 To I64 Result Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-31
gates are required before broader compiler-support claims.
exp-31 promotes exactly one checked `f64` to `i64` result compiler-known
standard-runtime call:
- `std.num.f64_to_i64_result : (f64) -> (result i64 i32)`
The promoted call returns `ok value` only when the input is finite, exactly
integral, and within the signed `i64` range `-9223372036854775808` through
`9223372036854775807`. It returns `err 1` for non-finite, fractional, or
out-of-range input. Ordinary conversion failure does not trap.
The exp-31 fixture values are `0.0 -> ok 0i64`, `-12.0 -> ok -12i64`,
`3.5 -> err 1`, and `9223372036854776000.0 -> err 1`. The out-of-range value
is the formatter-stable spelling of the accepted exact positive out-of-range
literal `9223372036854775808.0`; detailed edge behavior around the `f64`/`i64`
limits is implementation-owned Glagol test coverage rather than a larger Slovo
fixture matrix.
This slice does not define unchecked casts, unchecked `f64` to `i64`, casts or
cast syntax, generic `cast_checked`, `f32`, unsigned or narrower integer
families, additional numeric conversion families, mixed numeric arithmetic,
broad math APIs, numeric containers, stable helper ABI/layout/ownership,
manifest schema changes, or beta maturity.
The exp-31 fixtures are byte-identical:
```text
examples/supported/f64-to-i64-result.slo
examples/formatter/f64-to-i64-result.slo
```
The normative exp-31 contract is
`.llm/EXP_31_CHECKED_F64_TO_I64_RESULT_ALPHA.md`.
### 4.9.16 exp-32 Standard Math Source Helpers Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-32
source-check and formatter gates are required before broader compiler-support
claims.
exp-32 extends staged `std/math.slo` with narrow source-authored helpers over
existing numeric primitives. The existing exp-30 helpers remain:
- `abs_i32 : (i32) -> i32`
- `min_i32 : (i32, i32) -> i32`
- `max_i32 : (i32, i32) -> i32`
- `clamp_i32 : (i32, i32, i32) -> i32`
- `square_i32 : (i32) -> i32`
- `square_f64 : (f64) -> f64`
exp-32 adds:
- `abs_i64 : (i64) -> i64`
- `min_i64 : (i64, i64) -> i64`
- `max_i64 : (i64, i64) -> i64`
- `clamp_i64 : (i64, i64, i64) -> i64`
- `square_i64 : (i64) -> i64`
- `abs_f64 : (f64) -> f64`
- `min_f64 : (f64, f64) -> f64`
- `max_f64 : (f64, f64) -> f64`
- `clamp_f64 : (f64, f64, f64) -> f64`
These are ordinary Slovo source functions using existing same-type arithmetic
and comparison, `if`, literals, calls, and explicit signatures. `clamp_*` is
defined as `max(low, min(value, high))` in source and does not reorder or
validate bounds.
Current Slovo promotes two ways to use these helpers. Projects may keep the
earlier local-copy pattern and import a local `math.slo`, or, as of exp-44,
may explicitly import the repo-root standard module with
`(import std.math (...))`. exp-44 does not make the helpers implicit.
This slice does not define new compiler-known `std.*` operation names,
standard-runtime catalog entries, replacement of compiler-known `std.*` calls
with source implementations, broad math, trigonometry, `sqrt`, `pow`, `f32`,
unsigned or narrower integers, generic math, overloads, traits, mixed numeric
arithmetic, numeric containers, stable standard-library APIs, stable
ABI/layout/ownership, manifest schema changes, or beta maturity.
The exp-32 source fixture is:
```text
std/math.slo
```
The normative exp-32 contract is
`.llm/EXP_32_STANDARD_MATH_SOURCE_HELPERS_ALPHA.md`.
### 4.9.16a exp-44 Standard Library Source Search Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-44
project-mode gates are required before broader compiler-support claims.
exp-44 promotes the first explicit standard-library source import address:
```slo
(import std.math (abs_i32 square_i32 abs_i64 square_i64 abs_f64 square_f64))
```
The external import name `std.math` resolves to the staged repo-root source
file `std/math.slo`. The source file still declares the flat module
`(module math ...)`, but now carries an explicit export list for the promoted
math helper names.
The exp-44 fixture is:
```text
examples/projects/std-import-math/
```
This slice does not define automatic standard-library imports, a `std.slo`
aggregator, aliases, glob imports, qualified member access, workspace/package
standard-library imports, package registry behavior, broad standard-library
APIs, stable standard-library APIs, stable ABI/layout/ownership, optimizer
guarantees, benchmark thresholds, or beta maturity.
The normative exp-44 contract is
`.llm/EXP_44_STANDARD_LIBRARY_SOURCE_SEARCH_ALPHA.md`.
### 4.9.17 exp-33 Standard Result Source Helpers Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-33
source-check and formatter gates are required before broader compiler-support
claims.
exp-33 extends staged `std/result.slo` with narrow source-authored helpers for
already promoted concrete result families. The existing i32 wrappers remain:
- `is_ok_i32 : ((result i32 i32)) -> bool`
- `is_err_i32 : ((result i32 i32)) -> bool`
- `unwrap_ok_i32 : ((result i32 i32)) -> i32`
- `unwrap_err_i32 : ((result i32 i32)) -> i32`
exp-33 fills out concrete err wrappers:
- `is_err_i64 : ((result i64 i32)) -> bool`
- `unwrap_err_i64 : ((result i64 i32)) -> i32`
- `is_err_string : ((result string i32)) -> bool`
- `unwrap_err_string : ((result string i32)) -> i32`
- `is_err_f64 : ((result f64 i32)) -> bool`
- `unwrap_err_f64 : ((result f64 i32)) -> i32`
exp-33 also adds concrete fallback helpers:
- `unwrap_or_i32 : ((result i32 i32), i32) -> i32`
- `unwrap_or_i64 : ((result i64 i32), i64) -> i64`
- `unwrap_or_string : ((result string i32), string) -> string`
- `unwrap_or_f64 : ((result f64 i32), f64) -> f64`
These are ordinary Slovo source functions using existing `std.result.is_ok`,
`std.result.is_err`, `std.result.unwrap_ok`, `std.result.unwrap_err`, `if`,
parameters, and explicit signatures. Each `unwrap_or_*` helper returns the ok
payload when the result is ok and returns the supplied fallback otherwise.
`unwrap_or_string` uses the existing `(result string i32)` `match` shape to
return the payload or fallback without requiring string-valued `if`.
exp-74 later broadens the same staged module with concrete source
constructors `ok_i32`, `err_i32`, `ok_i64`, `err_i64`, `ok_string`,
`err_string`, `ok_f64`, `err_f64`, `ok_bool`, and `err_bool`. exp-109 later
adds the concrete bridge helpers `ok_or_none_i32`, `ok_or_none_i64`,
`ok_or_none_string`, `ok_or_none_f64`, and `ok_or_none_bool`.
At exp-33, Slovo did not yet promote automatic `std` imports, a repo-root
`std/` search path, or compiler-loaded standard library source. exp-45 later
promotes the explicit `std.result` source-search path while keeping automatic
imports deferred.
This slice does not define new compiler-known `std.*` operation names,
standard-runtime catalog entries, replacement of compiler-known `std.*` calls
with source implementations, generic `std.result.map`, generic
`std.result.unwrap_or`, `std.result.and_then`, option helper names, new result
payload families, generic result helpers, stable standard-library APIs, stable
ABI/layout/ownership, manifest schema changes, or beta maturity.
The exp-33 source fixture is:
```text
std/result.slo
```
The normative exp-33 contract is
`.llm/EXP_33_STANDARD_RESULT_SOURCE_HELPERS_ALPHA.md`.
### 4.9.18 exp-34 String Parse Bool Result Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-34
gates are required before broader compiler-support claims.
exp-34 promotes exactly one string parse compiler-known standard-runtime call:
- `std.string.parse_bool_result : (string) -> (result bool i32)`
The promoted call parses the entire input string as exactly one ASCII
lowercase boolean token. Accepted input is exactly `true` or `false`. Success
returns `ok true` for `true` and `ok false` for `false`.
Ordinary parse failure returns `err 1`. The empty string, uppercase or
mixed-case text, leading or trailing whitespace, numeric text, locale-specific
text, Unicode lookalikes, suffixes, prefixes, and any other text all return
`err 1`. Ordinary parse failure does not trap.
exp-34 extends the supported concrete result families only as needed for the
returned `(result bool i32)` parse value and existing compiler-known result
observation/extraction. It does not add source-authored `std/result.slo` bool
wrappers, generic results, stable result ABI/layout, or result helper behavior
beyond the explicitly supported concrete family.
The exp-34 fixtures are byte-identical:
```text
examples/supported/string-parse-bool-result.slo
examples/formatter/string-parse-bool-result.slo
```
The normative exp-34 contract is
`.llm/EXP_34_STRING_PARSE_BOOL_RESULT_ALPHA.md`.
### 4.9.19 exp-35 Standard Result Bool Source Helpers Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-35
source-check and formatter gates are required before broader compiler-support
claims.
exp-35 extends staged `std/result.slo` with the next conservative
source-authored concrete result helper slice for the exp-34 returned
`(result bool i32)` family:
- `is_ok_bool : ((result bool i32)) -> bool`
- `is_err_bool : ((result bool i32)) -> bool`
- `unwrap_ok_bool : ((result bool i32)) -> bool`
- `unwrap_err_bool : ((result bool i32)) -> i32`
- `unwrap_or_bool : ((result bool i32), bool) -> bool`
These are ordinary Slovo source functions using existing compiler-supported
`std.result.is_ok`, `std.result.is_err`, `std.result.unwrap_ok`,
`std.result.unwrap_err`, `if`, parameters, and explicit signatures.
`unwrap_or_bool` returns the ok payload when the result is ok and returns the
supplied fallback otherwise.
At exp-35, Slovo did not yet promote automatic `std` imports, a repo-root
`std/` search path, or compiler-loaded standard library source. exp-45 later
promotes the explicit `std.result` source-search path while keeping automatic
imports deferred.
This slice does not define new compiler-known `std.*` operation names,
standard-runtime catalog entries, replacement of compiler-known `std.*` calls
with source implementations, source-authored generic result helpers,
generic `std.result.map`, generic `std.result.unwrap_or`,
`std.result.and_then`, option helper names, broad result payload families,
source constructors for `(result bool i32)`, general source `match` over
`(result bool i32)` beyond compiler-supported fixture flow, stable
standard-library APIs, stable ABI/layout/ownership, manifest schema changes,
or beta maturity.
The exp-35 source fixture is:
```text
std/result.slo
```
The normative exp-35 contract is
`.llm/EXP_35_STANDARD_RESULT_BOOL_SOURCE_HELPERS_ALPHA.md`.
### 4.9.20 exp-36 Standard Option Source Helpers Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-36
source-check and formatter gates are required before broader compiler-support
claims.
exp-36 adds staged `std/option.slo` with a conservative source-authored helper
slice for the already supported `(option i32)` family:
- `is_some_i32 : ((option i32)) -> bool`
- `is_none_i32 : ((option i32)) -> bool`
- `unwrap_some_i32 : ((option i32)) -> i32`
- `unwrap_or_i32 : ((option i32), i32) -> i32`
exp-75 later adds `some_i32 : (i32) -> (option i32)` and
`none_i32 : () -> (option i32)`. exp-95 broadens the same staged module and
the same conservative option slice to concrete `(option i64)` with:
- `some_i64 : (i64) -> (option i64)`
- `none_i64 : () -> (option i64)`
- `is_some_i64 : ((option i64)) -> bool`
- `is_none_i64 : ((option i64)) -> bool`
- `unwrap_some_i64 : ((option i64)) -> i64`
- `unwrap_or_i64 : ((option i64), i64) -> i64`
exp-100 broadens the same staged module again to concrete `(option string)`
with:
- `some_string : (string) -> (option string)`
- `none_string : () -> (option string)`
- `is_some_string : ((option string)) -> bool`
- `is_none_string : ((option string)) -> bool`
- `unwrap_some_string : ((option string)) -> string`
- `unwrap_or_string : ((option string), string) -> string`
exp-102 broadens the same staged module again to concrete `(option f64)` and
`(option bool)` with:
- `some_f64 : (f64) -> (option f64)`
- `none_f64 : () -> (option f64)`
- `is_some_f64 : ((option f64)) -> bool`
- `is_none_f64 : ((option f64)) -> bool`
- `unwrap_some_f64 : ((option f64)) -> f64`
- `unwrap_or_f64 : ((option f64), f64) -> f64`
- `some_bool : (bool) -> (option bool)`
- `none_bool : () -> (option bool)`
- `is_some_bool : ((option bool)) -> bool`
- `is_none_bool : ((option bool)) -> bool`
- `unwrap_some_bool : ((option bool)) -> bool`
- `unwrap_or_bool : ((option bool), bool) -> bool`
exp-109 later adds concrete option-to-result bridge helpers for all current
concrete option families:
- `some_or_err_i32 : ((option i32), i32) -> (result i32 i32)`
- `some_or_err_i64 : ((option i64), i32) -> (result i64 i32)`
- `some_or_err_f64 : ((option f64), i32) -> (result f64 i32)`
- `some_or_err_bool : ((option bool), i32) -> (result bool i32)`
- `some_or_err_string : ((option string), i32) -> (result string i32)`
These are ordinary Slovo source functions using existing compiler-supported
`is_some`, `is_none`, `unwrap_some`, `ok`, `err`, `if`, parameters, and
explicit signatures. `unwrap_or_i32` returns the `some` payload when present
and returns the supplied fallback for `none`. Each `some_or_err_*` helper
returns `ok` with the option payload when present and returns `err err_code`
for `none`.
Current Slovo keeps standard-library organization as flat staged `std/*.slo`
facades. exp-45 later promotes explicit `std.option` source search for this
module. A future `std.slo` aggregator/reexport layer, inspired by Zig's
facade/reexport approach, remains deferred until broader standard-library
source organization is promoted.
This slice does not define new compiler-known `std.*` operation names,
standard-runtime catalog entries, automatic `std` imports, repo-root `std/`
search, compiler-loaded standard-library source, replacement of
compiler-known calls with source implementations, generic option helpers,
option payload families beyond `(option i32)`, `(option i64)`, `(option f64)`,
`(option bool)`, and `(option string)`, stable
standard-library APIs, stable ABI/layout/ownership, manifest schema changes,
or beta maturity.
The exp-36 source fixture is:
```text
std/option.slo
```
The normative exp-36 contract is
`.llm/EXP_36_STANDARD_OPTION_SOURCE_HELPERS_ALPHA.md`.
### 4.9.20a exp-45 Standard Result And Option Source Search Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-45
project-mode gates are required before broader compiler-support claims.
exp-45 extends explicit standard-library source search to result and option
helpers:
```slo
(import std.result (unwrap_or_i32 is_ok_bool unwrap_or_bool))
(import std.option (is_some_i32 unwrap_or_i32))
```
The external import names resolve to staged repo-root source files:
```text
std/result.slo
std/option.slo
```
Both files keep flat module declarations, `(module result ...)` and
`(module option ...)`, and now carry explicit export lists for their promoted
helper names.
The exp-45 fixtures are:
```text
examples/projects/std-import-result/
examples/projects/std-import-option/
```
This slice does not define automatic standard-library imports, a `std.slo`
aggregator, aliases, glob imports, qualified member access, workspace/package
standard-library imports, package registry behavior, generic result helpers,
generic option helpers, broad standard-library APIs, stable ABI/layout/
ownership, optimizer guarantees, benchmark thresholds, or beta maturity.
The normative exp-45 contract is
`.llm/EXP_45_STANDARD_RESULT_OPTION_SOURCE_SEARCH_ALPHA.md`.
### 4.9.20b exp-46 Workspace Standard Source Search Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-46
workspace gates are required before broader compiler-support claims.
exp-46 extends explicit standard-library source search from single projects to
workspace packages. Package source may import a staged standard module without
declaring a package dependency:
```slo
(import std.option (is_some_i32 unwrap_or_i32))
```
The exp-46 fixture is:
```text
examples/workspaces/std-import-option/
```
This slice does not define automatic standard-library imports, workspace
dependency syntax for std, package registry behavior, installed toolchain
stdlib paths, a `std.slo` aggregator, generic option helpers, broad
standard-library APIs, stable ABI/layout/ownership, optimizer guarantees,
benchmark thresholds, or beta maturity.
The normative exp-46 contract is
`.llm/EXP_46_WORKSPACE_STANDARD_SOURCE_SEARCH_ALPHA.md`.
### 4.9.20c exp-47 Standard Host Facade Source Search Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-47
project-mode gates are required before broader compiler-support claims.
exp-47 extends explicit standard-library source search to the host facade
modules staged in exp-37 and exp-38:
```slo
(import std.time (monotonic_ms sleep_ms_zero))
(import std.random (random_i32 random_i32_non_negative))
(import std.env (get get_result))
(import std.fs (read_text read_text_result write_text_status write_text_result))
```
The external import names resolve to staged repo-root source files:
```text
std/time.slo
std/random.slo
std/env.slo
std/fs.slo
```
The files keep flat module declarations, `(module time ...)`,
`(module random ...)`, `(module env ...)`, and `(module fs ...)`, and now
carry explicit export lists for their promoted facade names.
The exp-47 fixtures are:
```text
examples/projects/std-import-time/
examples/projects/std-import-random/
examples/projects/std-import-env/
examples/projects/std-import-fs/
```
This slice does not define automatic standard-library imports, a `std.slo`
aggregator, aliases, glob imports, qualified member access, workspace
dependency syntax for std, package registry behavior, installed toolchain
stdlib paths, broad host APIs, wall-clock/calendar/timezone APIs,
high-resolution timers, random ranges/seeds/bytes/floats/UUIDs, environment
mutation/enumeration, binary/directory/streaming/async filesystem APIs, rich
host error ADTs, stable ABI/layout/ownership, optimizer guarantees, benchmark
thresholds, or beta maturity.
The normative exp-47 contract is
`.llm/EXP_47_STANDARD_HOST_FACADE_SOURCE_SEARCH_ALPHA.md`.
### 4.9.20d exp-48 Standard Core Facade Source Search Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-48
project-mode gates are required before broader compiler-support claims.
exp-48 extends explicit standard-library source search to the pure core
facade modules:
```slo
(import std.string (len concat parse_i32_result parse_i64_result parse_f64_result parse_bool_result))
(import std.num (i32_to_i64 i32_to_f64 i64_to_f64 i64_to_i32_result f64_to_i32_result f64_to_i64_result i32_to_string i64_to_string f64_to_string))
```
The external import names resolve to staged repo-root source files:
```text
std/string.slo
std/num.slo
```
The files keep flat module declarations, `(module string ...)` and
`(module num ...)`, and now carry explicit export lists for their promoted
facade names.
The exp-48 fixtures are:
```text
examples/projects/std-import-string/
examples/projects/std-import-num/
```
This slice does not define automatic standard-library imports, a `std.slo`
aggregator, aliases, glob imports, qualified member access, package registry
behavior, installed toolchain stdlib paths, generic parse/format APIs, string
indexing/slicing/tokenization, mutable strings, string containers, broad
numeric casts, unsigned or narrower integer families, mixed numeric
arithmetic, decimal/char/byte types, stable ABI/layout/ownership, optimizer
guarantees, benchmark thresholds, or beta maturity.
The normative exp-48 contract is
`.llm/EXP_48_STANDARD_CORE_FACADE_SOURCE_SEARCH_ALPHA.md`.
### 4.9.20e exp-49 Standard IO Facade Source Search Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-49
project-mode gates are required before broader compiler-support claims.
exp-49 extends explicit standard-library source search to the staged IO
facade module:
```slo
(import std.io (print_i32_zero print_i64_zero print_f64_zero print_string_zero print_bool_zero))
```
The external import name resolves to the staged repo-root source file:
```text
std/io.slo
```
The file keeps its flat module declaration, `(module io ...)`, and now carries
an explicit export list for its promoted facade names.
The exp-49 fixture is:
```text
examples/projects/std-import-io/
```
Later staged-source expansions keep the same `std/io.slo` module path.
exp-73 adds `print_i32_value`, `print_i64_value`, `print_f64_value`,
`print_string_value`, and `print_bool_value` as source-authored print
wrappers that preserve the printed value. exp-111 adds a connected stdin
helper package:
`read_stdin_result`, `read_stdin_option`, `read_stdin_or`,
`read_stdin_i32_result`, `read_stdin_i32_option`, `read_stdin_i32_or_zero`,
`read_stdin_i32_or`, `read_stdin_i64_result`, `read_stdin_i64_option`,
`read_stdin_i64_or_zero`, `read_stdin_i64_or`, `read_stdin_f64_result`,
`read_stdin_f64_option`, `read_stdin_f64_or_zero`, `read_stdin_f64_or`,
`read_stdin_bool_result`, `read_stdin_bool_option`,
`read_stdin_bool_or_false`, and `read_stdin_bool_or`. These later helpers
remain ordinary source over the promoted `std.io.read_stdin_result` runtime
lane, the concrete `std.string.parse_*_result` helpers, and the exp-109
`std.result.ok_or_none_*` bridge helpers, and do not add new runtime names.
This slice does not define automatic standard-library imports, a `std.slo`
aggregator, aliases, glob imports, qualified member access, package registry
behavior, installed toolchain stdlib paths, new compiler-known IO names,
formatted output APIs, stdin expansion, terminal control, stream abstractions,
async IO, stable stdout/stderr buffering semantics beyond existing runtime
behavior, stable ABI/layout/ownership, optimizer guarantees, benchmark
thresholds, or beta maturity.
The normative exp-49 contract is
`.llm/EXP_49_STANDARD_IO_FACADE_SOURCE_SEARCH_ALPHA.md`.
### 4.9.20f exp-50 Installed Standard Library Discovery Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-50
installed-discovery gates are required before broader toolchain-support
claims.
exp-50 extends explicit standard-library source search to installed
toolchain layouts. Project and workspace source still imports staged standard
modules explicitly:
```slo
(import std.math (abs_i32))
```
The staged source modules remain flat files under `std/*.slo`. A compiler may
discover those files from an installed standard-library directory such as:
```text
share/slovo/std
```
This slice does not define automatic standard-library imports, a `std.slo`
aggregator, aliases, glob imports, qualified member access, package registry
behavior, lockfiles, package std dependencies, a stable package manager,
stable install layout guarantees beyond this alpha discovery candidate, new
compiler-known runtime names, broad standard-library APIs, stable
ABI/layout/ownership, optimizer guarantees, benchmark thresholds, or beta
maturity.
The normative exp-50 contract is
`.llm/EXP_50_INSTALLED_STANDARD_LIBRARY_DISCOVERY_ALPHA.md`.
### 4.9.20g exp-51 Standard Library Path List Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-51
path-list gates are required before broader package-resolution claims.
exp-51 refines explicit standard-library source search by allowing
`SLOVO_STD_PATH` to name an ordered OS path list of standard-library roots.
A tool resolves a requested `std.<module>` import from the first listed root
that contains the corresponding module file.
This slice supports partial override roots during standard-library
development. It does not define automatic standard-library imports, a
`std.slo` aggregator, aliases, glob imports, qualified member access, package
registry behavior, lockfiles, package std dependencies, semantic version
solving, stable package manager behavior, broad standard-library APIs, stable
ABI/layout/ownership, optimizer guarantees, benchmark thresholds, or beta
maturity.
The normative exp-51 contract is
`.llm/EXP_51_STANDARD_LIBRARY_PATH_LIST_ALPHA.md`.
### 4.9.20h exp-52 Standard Process Facade Source Search Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-52
project-mode gates are required before broader compiler-support claims.
exp-52 extends explicit standard-library source search to the staged process
facade module:
```slo
(import std.process (argc arg arg_result has_arg))
```
The external import name resolves to the staged repo-root source file:
```text
std/process.slo
```
The file keeps its flat module declaration, `(module process ...)`, and
exports wrappers over existing `std.process.argc`, `std.process.arg`, and
`std.process.arg_result`, plus the source-authored `has_arg` helper.
The exp-52 fixture is:
```text
examples/projects/std-import-process/
```
This slice does not define automatic standard-library imports, a `std.slo`
aggregator, aliases, glob imports, qualified member access, package registry
behavior, lockfiles, package std dependencies, new compiler-known process
runtime names, process spawning, exit/status control, current-directory APIs,
signal handling, stable ABI/layout/ownership, optimizer guarantees, benchmark
thresholds, or beta maturity.
The normative exp-52 contract is
`.llm/EXP_52_STANDARD_PROCESS_FACADE_SOURCE_SEARCH_ALPHA.md`.
### 4.9.20i exp-53 Standard CLI Source Facade Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-53
project-mode gates are required before broader compiler-support claims.
exp-53 extends explicit standard-library source search to the staged CLI
facade module:
```slo
(import std.cli (arg_text_result arg_i32_result arg_i32_or_zero))
```
The external import name resolves to the staged repo-root source file:
```text
std/cli.slo
```
The file keeps its flat module declaration, `(module cli ...)`, imports
`std.process` and `std.string` as ordinary standard source modules, and
exports `arg_text_result`, `arg_i32_result`, and `arg_i32_or_zero`.
The exp-53 fixture is:
```text
examples/projects/std-import-cli/
```
This slice does not define automatic standard-library imports, a `std.slo`
aggregator, aliases, glob imports, qualified member access, package registry
behavior, lockfiles, package std dependencies, new compiler-known runtime
names, shell parsing, option/flag parsing, subcommands, environment-backed
configuration, stable CLI framework APIs, stable ABI/layout/ownership,
optimizer guarantees, benchmark thresholds, or beta maturity.
The normative exp-53 contract is
`.llm/EXP_53_STANDARD_CLI_SOURCE_FACADE_ALPHA.md`.
### 4.9.20j exp-54 Standard CLI Typed Arguments Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-54
project-mode gates are required before broader compiler-support claims.
exp-54 extends the staged CLI facade helper list:
```slo
(import std.cli (arg_text_result arg_i32_result arg_i32_or_zero arg_i64_result arg_i64_or_zero arg_f64_result arg_f64_or_zero arg_bool_result arg_bool_or_false))
```
The external import name still resolves to:
```text
std/cli.slo
```
The file remains ordinary source and continues to import `std.process` and
`std.string`. It adds typed result and fallback helpers for the current
`i32`, `i64`, `f64`, and `bool` parse-result families.
The exp-54 fixture remains:
```text
examples/projects/std-import-cli/
```
This slice does not define automatic standard-library imports, a `std.slo`
aggregator, aliases, glob imports, qualified member access, package registry
behavior, lockfiles, package std dependencies, new compiler-known runtime
names, shell parsing, option/flag parsing, subcommands, environment-backed
configuration, stable CLI framework APIs, stable ABI/layout/ownership,
optimizer guarantees, benchmark thresholds, or beta maturity.
The normative exp-54 contract is
`.llm/EXP_54_STANDARD_CLI_TYPED_ARGUMENTS_ALPHA.md`.
### 4.9.20k exp-55 Result F64 Bool Source Flow Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-55
checker, formatter, test-runner, and LLVM gates are required before broader
compiler-support claims.
exp-55 promotes source constructors for:
```slo
(ok f64 i32 1.5)
(err f64 i32 1)
(ok bool i32 true)
(err bool i32 1)
```
Source `match` may bind the `f64` or `bool` ok payload and the `i32` err
payload for those concrete result families:
```slo
(match value
((ok payload)
payload)
((err code)
fallback))
```
The exp-55 fixture is:
```text
examples/supported/result-f64-bool-match.slo
```
This slice does not define generic result types, result payload families
beyond the already promoted concrete families, generic `map`/`and_then`,
exception handling, stable ABI/layout/ownership, optimizer guarantees,
benchmark thresholds, or beta maturity.
The normative exp-55 contract is
`.llm/EXP_55_RESULT_F64_BOOL_SOURCE_FLOW_ALPHA.md`.
### 4.9.20l exp-56 Integer Remainder Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-56
parser, checker, formatter, test-runner, LLVM, and standard-source gates are
required before broader compiler-support claims.
exp-56 promotes the `%` binary operator for same-width signed integer
operands:
```slo
(% 17 5)
(% -17 5)
(% 42i64 5i64)
(% -17i64 5i64)
```
The result type is `i32` for `i32` operands and `i64` for `i64` operands.
The sign behavior follows signed remainder semantics: the remainder carries
the dividend sign for negative dividends. Remainder by zero is a test-runner
runtime error and remains an invalid program behavior for hosted code, just
like division by zero in the current numeric slice.
exp-56 also extends `std/math.slo` with source-authored helpers:
```text
rem_i32, is_even_i32, is_odd_i32
rem_i64, is_even_i64, is_odd_i64
```
The exp-56 fixture is:
```text
examples/supported/integer-remainder.slo
examples/formatter/integer-remainder.slo
```
This slice does not define floating-point remainder, Euclidean modulo,
unsigned arithmetic, bit operations, generic math, mixed numeric arithmetic,
stable ABI/layout/ownership, optimizer guarantees, benchmark thresholds, or
beta maturity.
The normative exp-56 contract is `.llm/EXP_56_INTEGER_REMAINDER_ALPHA.md`.
### 4.9.20m exp-57 Integer Bitwise Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-57
parser, checker, formatter, test-runner, LLVM, and standard-source gates are
required before broader compiler-support claims.
exp-57 promotes explicit bitwise binary heads for same-width signed integer
operands:
```slo
(bit_and 6 3)
(bit_or 4 2)
(bit_xor 7 3)
(bit_and 6i64 3i64)
(bit_or 4i64 2i64)
(bit_xor 7i64 3i64)
```
The result type is `i32` for `i32` operands and `i64` for `i64` operands.
The heads are intentionally named forms rather than symbolic operators so
they remain clear in the S-expression surface.
exp-57 also extends `std/math.slo` with source-authored helpers:
```text
bit_and_i32, bit_or_i32, bit_xor_i32
bit_and_i64, bit_or_i64, bit_xor_i64
```
The exp-57 fixtures are:
```text
examples/supported/integer-bitwise.slo
examples/formatter/integer-bitwise.slo
```
This slice does not define shifts, bit-not, unsigned arithmetic,
bit-width-specific integer families, floating-point bitwise operations,
generic math, mixed numeric arithmetic, stable ABI/layout/ownership,
optimizer guarantees, benchmark thresholds, or beta maturity.
The normative exp-57 contract is `.llm/EXP_57_INTEGER_BITWISE_ALPHA.md`.
### 4.9.20n exp-58 Boolean Logic Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-58
parser, formatter, checker, test-runner, LLVM, and fixture gates are required
before broader compiler-support claims.
exp-58 promotes boolean logic forms:
```slo
(and left right)
(or left right)
(not value)
```
`and` and `or` short-circuit and are specified as source forms lowered
through existing `if` semantics:
- `(and left right)` evaluates `right` only when `left` is true.
- `(or left right)` evaluates `right` only when `left` is false.
- `(not value)` returns `false` for true input and `true` for false input.
The exp-58 fixtures are:
```text
examples/supported/boolean-logic.slo
examples/formatter/boolean-logic.slo
```
This slice does not define truthiness, variadic boolean operators, pattern
guards, macro expansion, stable ABI/layout/ownership, optimizer guarantees,
benchmark thresholds, or beta maturity.
The normative exp-58 contract is `.llm/EXP_58_BOOLEAN_LOGIC_ALPHA.md`.
### 4.9.20p exp-119 Benchmark Suite Extension And Whitepaper Refresh Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-119
benchmark-suite extension, publication refresh, and verification gates are
required before broader compiler-support claims.
exp-119 does not add new source syntax or new type forms. It keeps the
exp-118 language surface unchanged while widening the current benchmark/
publication baseline from three kernels to five:
- `math-loop`
- `branch-loop`
- `parse-loop`
- `array-index-loop`
- `string-eq-loop`
The exp-119 publication fixtures are:
```text
docs/SLOVO_WHITEPAPER.md
docs/SLOVO_WHITEPAPER.pdf
docs/SLOVO_MANIFEST.pdf
WHITEPAPER.pdf
```
This slice does not define language-surface changes, standard-library API
changes, compiler-known runtime names, optimizer guarantees, benchmark
thresholds, cross-machine performance claims, stable ABI/layout/ownership, or
beta maturity.
The normative exp-119 contract is
`.llm/EXP_119_BENCHMARK_SUITE_EXTENSION_AND_WHITEPAPER_REFRESH_ALPHA.md`.
### 4.9.20r exp-121 Non-Recursive Struct Enum Payloads Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-121
gates are required before broader compiler-support claims.
exp-121 promotes unary enum payload variants whose payload type is a current
known non-recursive struct type. Where payload variants are present in one
enum, those payload variants still share the same payload type.
Qualified constructors may build those enum values from matching struct-valued
expressions. Immutable enum values carrying those payloads may flow through
locals, parameters, returns, calls, tests, and `main`. Exhaustive `match`
continues to bind exactly one immutable payload name per payload arm, and the
bound struct payload reuses existing field access behavior, including checked
indexing through array-bearing struct fields where already promoted by
exp-120.
This slice does not define enum equality requirements for struct-payload
enums, direct array/vec/option/result payloads, multiple payload fields,
recursive/cyclic payloads, mutation, generics, stable ABI/layout/ownership
claims, or beta maturity.
The exp-121 fixtures are:
```text
examples/supported/enum-payload-structs.slo
examples/formatter/enum-payload-structs.slo
```
The normative exp-121 contract is
`.llm/EXP_121_NON_RECURSIVE_STRUCT_ENUM_PAYLOADS_ALPHA.md`.
### 4.9.20t exp-123 Owned Vector Benchmark Suite Extension And Whitepaper Refresh Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-123
benchmark-suite extension, publication refresh, and verification gates are
required before broader compiler-support claims.
exp-123 does not add new source syntax or new type forms. It keeps the
exp-121 language surface unchanged while widening the current benchmark/
publication baseline from seven kernels to nine:
- `math-loop`
- `branch-loop`
- `parse-loop`
- `array-index-loop`
- `string-eq-loop`
- `array-struct-field-loop`
- `enum-struct-payload-loop`
- `vec-i32-index-loop`
- `vec-string-eq-loop`
The two additional kernels are publication evidence for the already promoted
runtime-owned vector lanes over `i32` and `string`.
The exp-123 publication fixtures are:
```text
docs/SLOVO_WHITEPAPER.md
docs/SLOVO_WHITEPAPER.pdf
docs/SLOVO_MANIFEST.pdf
WHITEPAPER.pdf
```
This slice does not define language-surface changes, standard-library API
changes, compiler-known runtime names, optimizer guarantees, benchmark
thresholds, cross-machine performance claims, stable ABI/layout/ownership, or
beta maturity.
The normative exp-123 contract is
`.llm/EXP_123_OWNED_VECTOR_BENCHMARK_SUITE_EXTENSION_AND_WHITEPAPER_REFRESH_ALPHA.md`.
### 4.9.20s exp-122 Composite Data Benchmark Suite Extension And Whitepaper Refresh Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-122
benchmark-suite extension, publication refresh, and verification gates are
required before broader compiler-support claims.
exp-122 does not add new source syntax or new type forms. It keeps the
exp-121 language surface unchanged while widening the current benchmark/
publication baseline from five kernels to seven:
- `math-loop`
- `branch-loop`
- `parse-loop`
- `array-index-loop`
- `string-eq-loop`
- `array-struct-field-loop`
- `enum-struct-payload-loop`
The two additional kernels are composite-data publication evidence for the
already promoted exp-120 fixed-array struct-field surface and exp-121 unary
non-recursive struct enum payload surface.
The exp-122 publication fixtures are:
```text
docs/SLOVO_WHITEPAPER.md
docs/SLOVO_WHITEPAPER.pdf
docs/SLOVO_MANIFEST.pdf
WHITEPAPER.pdf
```
This slice does not define language-surface changes, standard-library API
changes, compiler-known runtime names, optimizer guarantees, benchmark
thresholds, cross-machine performance claims, stable ABI/layout/ownership, or
beta maturity.
The normative exp-122 contract is
`.llm/EXP_122_COMPOSITE_DATA_BENCHMARK_SUITE_EXTENSION_AND_WHITEPAPER_REFRESH_ALPHA.md`.
### 4.9.20q exp-120 Fixed Array Struct Fields Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-120
gates are required before broader compiler-support claims.
exp-120 promotes direct immutable struct field declarations whose field types
are exactly the current promoted fixed immutable array families:
- `(array i32 N)`
- `(array i64 N)`
- `(array f64 N)`
- `(array bool N)`
- `(array string N)`
where `N` is a positive literal length.
Struct constructors may initialize those fields from matching fixed-array
expressions. Immutable struct values carrying those fields may flow through
locals, parameters, returns, and calls. Field access returns the declared
fixed-array type, and the existing checked `index` form may consume that field
access result with `i32` index expressions.
This slice does not define zero-length arrays, mutable arrays, element
mutation, field mutation, array equality, array printing, nested arrays,
arrays of unsupported element kinds, slices, generics, stable
ABI/layout/ownership claims, or beta maturity.
The exp-120 fixtures are:
```text
examples/supported/array-struct-fields.slo
examples/formatter/array-struct-fields.slo
```
The normative exp-120 contract is
`.llm/EXP_120_FIXED_ARRAY_STRUCT_FIELDS_ALPHA.md`.
### 4.9.20o exp-59 Hosted Build Optimization And Benchmark Publication Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-59
hosted-build, publication, and verification gates are required before broader
compiler-support claims.
exp-59 does not add new source syntax or new type forms. It keeps the exp-58
language surface unchanged while recording the paired Glagol hosted-build
optimization and an earlier benchmark/publication baseline.
The exp-59 publication fixtures are:
```text
docs/SLOVO_WHITEPAPER.md
docs/SLOVO_WHITEPAPER.pdf
docs/SLOVO_MANIFEST.pdf
WHITEPAPER.pdf
```
This slice does not define language-surface changes, standard-library API
changes, optimizer guarantees, benchmark thresholds, cross-machine
performance claims, stable ABI/layout/ownership, or beta maturity.
The normative exp-59 contract is
`.llm/EXP_59_HOSTED_BUILD_OPTIMIZATION_AND_BENCHMARK_PUBLICATION_ALPHA.md`.
### 4.9.21 exp-37 Standard Time Source Facade Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-37
source-check and formatter gates are required before broader compiler-support
claims.
exp-37 adds staged `std/time.slo` with a conservative source facade over the
already released exp-8 time calls:
- `monotonic_ms : () -> i32`
- `sleep_ms_zero : () -> i32`
`monotonic_ms` returns `std.time.monotonic_ms`. `sleep_ms_zero` calls
`std.time.sleep_ms 0` and then returns `0`. The integer-returning sleep
wrapper is intentionally narrow and zero-duration because user-defined
unit-return functions are not generally supported today and positive-duration
timing assertions remain deferred.
Current Slovo keeps standard-library organization as flat staged `std/*.slo`
facades. A future `std.slo` aggregator/reexport layer, inspired by Zig's flat
standard facade discipline, waits until Slovo has promoted import/search
semantics for standard-library source.
This slice does not define new compiler-known `std.*` operation names,
standard-runtime catalog entries, automatic `std` imports, repo-root `std/`
search, compiler-loaded standard-library source, replacement of
compiler-known calls with source implementations, wall-clock/calendar/timezone
APIs, high-resolution timers, async timers, cancellation, scheduling
guarantees, stable standard-library APIs, stable ABI/layout/ownership,
manifest schema changes, or beta maturity.
The exp-37 source fixture is:
```text
std/time.slo
```
The normative exp-37 contract is
`.llm/EXP_37_STANDARD_TIME_SOURCE_FACADE_ALPHA.md`.
### 4.9.22 exp-38 Standard Host Source Facades Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-38
source-check and formatter gates are required before broader compiler-support
claims.
exp-38 adds staged host source facades over already released random,
environment, and text filesystem calls:
- `std/random.slo`
- `std/env.slo`
- `std/fs.slo`
The source facade functions are:
- `random_i32 : () -> i32`
- `random_i32_non_negative : () -> bool`
- `get : (string) -> string`
- `get_result : (string) -> (result string i32)`
- `read_text : (string) -> string`
- `read_text_result : (string) -> (result string i32)`
- `write_text_status : (string, string) -> i32`
- `write_text_result : (string, string) -> (result i32 i32)`
Current Slovo keeps standard-library organization as flat staged `std/*.slo`
facades. A future `std.slo` aggregator/reexport layer, inspired by Zig's flat
standard facade discipline, waits until Slovo has promoted import/search
semantics for standard-library source.
This slice does not define new compiler-known `std.*` operation names,
standard-runtime catalog entries, automatic `std` imports, repo-root `std/`
search, compiler-loaded standard-library source, replacement of
compiler-known calls with source implementations, seed/range/bytes/float/
UUID/crypto random APIs, environment mutation/enumeration, platform-specific
error codes, rich host error ADTs, binary file APIs, directory traversal,
streaming file IO, async file IO, richer filesystem metadata APIs, stable
standard-library APIs, stable ABI/layout/ownership, manifest schema changes,
or beta maturity.
The normative exp-38 contract is
`.llm/EXP_38_STANDARD_HOST_SOURCE_FACADES_ALPHA.md`.
### 4.9.23 exp-39 Standard Math Extensions And Benchmark Scaffold Alpha
Status: released experimental alpha Slovo contract. Matching Glagol exp-39
source-check, formatter, benchmark scaffold, and promotion gates are required
before broader compiler-support claims.
exp-39 extends staged `std/math.slo` with ordinary source-authored helpers
over existing numeric primitives. The exp-32 `abs`, `min`, `max`, `clamp`, and
`square` helper families remain.
exp-39 adds these helper families for `i32`, `i64`, and finite `f64`:
- `neg_* : (T) -> T`
- `cube_* : (T) -> T`
- `is_zero_* : (T) -> bool`
- `is_positive_* : (T) -> bool`
- `is_negative_* : (T) -> bool`
- `in_range_* : (T, T, T) -> bool`
The concrete promoted names are `neg_i32`, `cube_i32`, `is_zero_i32`,
`is_positive_i32`, `is_negative_i32`, `in_range_i32`, `neg_i64`,
`cube_i64`, `is_zero_i64`, `is_positive_i64`, `is_negative_i64`,
`in_range_i64`, `neg_f64`, `cube_f64`, `is_zero_f64`, `is_positive_f64`,
`is_negative_f64`, and `in_range_f64`.
These are ordinary Slovo source functions using existing same-type arithmetic
and comparison, `if`, literals, calls, and explicit signatures. `cube_*` is
defined in terms of multiplication through `square_*`. `in_range_*` is
inclusive and returns false when the lower bound check fails; it does not
validate or reorder bounds.
The matching Glagol `benchmarks/math-loop/` scaffold is tooling evidence only.
It compares local Slovo executable timing against C, Rust, and Python on the
same machine with a shared deterministic checksum. It does not define a Slovo
semantic feature, optimizer guarantee, or public performance threshold.
This slice does not define new compiler-known `std.*` operation names,
standard-runtime catalog entries, automatic `std` imports, repo-root `std/`
search, compiler-loaded standard-library source, replacement of
compiler-known calls with source implementations, trigonometry, `sqrt`, `pow`,
logarithms, modulo, bit operations, unsigned or narrower integers, `f32`,
generic math, overloads, traits, mixed numeric arithmetic, numeric containers,
stable standard-library APIs, stable ABI/layout/ownership, optimizer
guarantees, benchmark thresholds, manifest schema changes, or beta maturity.
The exp-39 source fixture is:
```text
std/math.slo
```
The normative exp-39 contract is
`.llm/EXP_39_STANDARD_MATH_EXTENSIONS_AND_BENCHMARK_SCAFFOLD_ALPHA.md`.
## 4.10 exp-5 Local Packages And Workspaces
Status: current experimental compiler-supported contract after matching Glagol
exp-5 gates.
exp-5 promotes only a closed local package/workspace hygiene slice:
- workspace `slovo.toml` manifests with explicit local members
- package `slovo.toml` manifests with package name/version metadata
- local path dependencies between workspace packages
- package-qualified imports for dependency modules
- deterministic package graph ordering
- artifact-manifest recording of the local package graph
The minimal exp-5 fixture is:
```text
examples/workspaces/exp-5-local/
```
exp-5 explicitly defers remote registries, version solving, broad lockfiles,
build scripts, generated code, package publishing, semver compatibility,
package-level generics, package re-exports, package archives, optional/dev/
target dependencies, registry authentication, and cross-package ABI stability.
The normative exp-5 contract is `.llm/EXP_5_LOCAL_PACKAGES_ALPHA.md`.
## 4.11 exp-6 C FFI Scalar Imports Alpha
Status: current experimental compiler-supported contract after matching Glagol
exp-6 gates.
exp-6 promotes only top-level imported C function declarations with `i32`
parameters and `i32` or internal `unit` returns:
```slo
(import_c c_add ((lhs i32) (rhs i32)) -> i32)
```
Calls to imported C functions must occur inside lexical `(unsafe ...)`.
Hosted builds use explicit local C source link inputs for the fixture, and
artifact manifests record source module, import name, C symbol name, ordered
parameter types, return type, link inputs, and an experimental fixture ABI
marker.
The minimal exp-6 fixture is:
```text
examples/ffi/exp-6-c-add/
```
exp-6 explicitly defers pointer types, allocation/deallocation, raw unsafe
head execution, ownership/lifetime rules, C exports, callbacks, headers,
libraries, broad linker configuration, foreign globals, foreign structs,
unions, enums, stable ABI, and stable layout.
The normative exp-6 contract is `.llm/EXP_6_C_FFI_SCALAR_IMPORTS_ALPHA.md`.
## 4.12 exp-7 Test Selection And Test-Run Metadata Alpha
Status: current experimental compiler-supported contract after matching Glagol
exp-7 gates.
exp-7 promotes only test selection and richer test-run metadata:
```text
glagol test <file.slo|project> --filter <substring>
glagol --run-tests --filter <substring> <file.slo>
```
Filtering is a deterministic, case-sensitive substring match against decoded
test display names. Selected tests execute in existing order. Non-selected
tests are skipped before evaluation and counted as skipped. Zero matches is a
successful run. Test reports and artifact manifests expose total discovered,
selected, passed, failed, skipped, and optional filter metadata.
exp-7 explicitly defers LSP, editor protocols, debug metadata, source maps,
SARIF, watch/daemon protocols, documentation comments, lint categories,
benchmarks, test tags/groups/retries/sharding/parallelism, and new source
language syntax.
The normative exp-7 contract is `.llm/EXP_7_TEST_SELECTION_ALPHA.md`.
## 4.13 exp-8 Host Time And Sleep Alpha
Status: released experimental compiler-supported contract after matching
Slovo and Glagol exp-8 gates, 2026-05-18.
exp-8 promotes exactly two compiler-known standard-runtime operations:
```text
std.time.monotonic_ms: () -> i32
std.time.sleep_ms: (i32) -> unit
```
The source call forms are ordinary calls:
```slo
(std.time.monotonic_ms)
(std.time.sleep_ms ms)
```
`std.time.monotonic_ms` returns host monotonic elapsed time in milliseconds as
a non-negative `i32`. The epoch is implementation-owned and is not wall-clock
time. If host monotonic time is unavailable, the implementation may trap with:
```text
slovo runtime error: monotonic time unavailable
```
`std.time.sleep_ms` accepts a non-negative `i32` duration in milliseconds and
returns builtin `unit`. `0` is valid and is a no-op/yield-style sleep.
Negative runtime values trap with:
```text
slovo runtime error: sleep_ms negative duration
```
If a non-negative host sleep fails, the implementation may trap with:
```text
slovo runtime error: sleep failed
```
The promoted names are compiler-known. They require no import, do not name user
modules, do not create package dependencies, and are not stable C ABI symbols
or stable runtime helper symbols. The exact promoted names are reserved from
user function, export, import, local, and parameter shadowing.
The exp-8 test-runner contract is intentionally narrow: `sleep_ms 0` is
deterministic and returns `unit`; positive sleeps are not required in
conformance tests; `monotonic_ms` tests are structural or assert only that an
executed host value is non-negative. exp-8 tests must not assert elapsed-time
precision, wall-clock correspondence, scheduling behavior, or high-resolution
timing.
Artifact manifests record `std.time.monotonic_ms` and `std.time.sleep_ms`
usage only if existing manifest patterns already record standard-runtime usage
metadata. Otherwise exp-8 defers extra time-specific manifest metadata.
exp-8 explicitly defers threads, tasks, channels, async, cancellation, actors,
shared memory, data-race freedom, scheduling guarantees, timers, wall-clock
time, calendar dates, time zones, high-resolution timers, signal handling,
source language syntax, stable ABI/layout, and stable runtime helper symbols.
The normative exp-8 release contract is `.llm/EXP_8_HOST_TIME_SLEEP_ALPHA.md`.
## 4.14 exp-9 Reliability Performance And Ecosystem Hardening
Status: released experimental compiler-supported contract after matching
Slovo and Glagol exp-9 gates, 2026-05-18.
exp-9 is a hardening-only target over the released exp-8 baseline. It accepts
no new source syntax, type-system behavior, standard-runtime names, manifest
schema version, runtime capabilities, package features, ABI/layout promises,
public performance thresholds, or beta maturity claim.
The exp-9 release requires compatibility inventory and migration notes for
`v2.0.0-beta.1` and exp-1 through exp-8, property/fuzz-style parser,
formatter, diagnostic, project-graph, and runtime API coverage where
feasible, source-reachable panic audit and disposition, benchmark fixtures or
documented benchmark smoke, and release review confirming no accidental
language or stable-ABI expansion.
The normative exp-9 release contract is
`.llm/EXP_9_RELIABILITY_PERFORMANCE_ECOSYSTEM_HARDENING.md`.
## 4.15 exp-10 Result-Based Host Errors Alpha
Status: released experimental compiler-supported contract after matching
Slovo and Glagol exp-10 gates, 2026-05-18. exp-10 is not a beta maturity
claim.
exp-10 promotes exactly one new concrete result family:
```text
(result string i32)
```
This family mirrors the existing `(result i32 i32)` support as narrowly as
possible: immutable locals, parameters, returns, calls returning result
values, `is_ok`, `is_err`, `unwrap_ok`, `unwrap_err`, exhaustive `match` arms,
and formatter support. It does not promote generic result types.
exp-10 promotes exactly four additive compiler-known host calls:
```text
std.process.arg_result: (i32) -> (result string i32)
std.env.get_result: (string) -> (result string i32)
std.fs.read_text_result: (string) -> (result string i32)
std.fs.write_text_result: (string string) -> (result i32 i32)
```
The only ordinary host failure code promised by exp-10 is `err 1`.
`std.fs.write_text_result` returns `ok 0` on success and `err 1` on ordinary
host write failure. The string-returning calls return `ok` with an immutable
runtime-provided string on success and `err 1` on ordinary host failure.
The exp-3 calls remain unchanged. `std.process.arg`, `std.env.get`,
`std.fs.read_text`, and `std.fs.write_text` keep their exp-3 trap,
empty-string, and integer-status behavior.
exp-10 fixtures are:
```text
examples/supported/host-io-result.slo
examples/formatter/host-io-result.slo
```
Artifact manifests record exp-10 standard-runtime usage only if existing
manifest patterns already record standard-runtime usage metadata. Otherwise no
exp-10-specific manifest field or schema version change is promoted.
exp-10 explicitly defers `result string Error`, general host error ADTs,
platform-specific error codes, error messages, result equality, result
printing, mapping, nested results, result containers, new host API families,
stable ABI/layout/helper symbols, and beta maturity.
The normative exp-10 release contract is
`.llm/EXP_10_RESULT_BASED_HOST_ERRORS_ALPHA.md`.
## 4.16 exp-11 Basic Randomness Alpha
Status: released experimental compiler-supported contract after matching
Glagol exp-11 gates passed. exp-11 is not a beta maturity claim.
exp-11 promotes exactly one compiler-known standard-runtime operation:
```text
std.random.i32: () -> i32
```
Source call form:
```slo
(std.random.i32)
```
`std.random.i32` returns a non-negative implementation-owned pseudo-random or
host-random `i32` suitable only for basic command-line program use. No seed
API, distribution, entropy source, sequence stability, cross-platform
reproducibility, or cryptographic/security suitability is promised.
If the runtime cannot produce a value, it must trap with the exact message:
```text
slovo runtime error: random i32 unavailable
```
The test runner must be deterministic enough for Glagol tests. It may return
an implementation-owned non-negative sample or sequence, and fixtures may
assert only structural properties such as non-negativity.
exp-11 release fixtures are:
```text
examples/supported/random.slo
examples/formatter/random.slo
```
Artifact manifests record exp-11 standard-runtime usage only if existing
manifest patterns already record standard-runtime usage metadata. Otherwise no
randomness-specific manifest field or schema version change is promoted.
exp-11 explicitly defers seed APIs, crypto/security promises, bytes APIs,
ranges or bounds arguments, floats, random strings, UUIDs, broader
`std.random.*` names, randomness-specific manifest fields, stable
ABI/layout/helper symbols, and beta maturity.
The normative exp-11 release contract is
`.llm/EXP_11_BASIC_RANDOMNESS_ALPHA.md`.
## 4.17 exp-12 Standard Input Result Alpha
Status: released experimental compiler-supported contract after matching
Glagol exp-12 gates passed, 2026-05-18. exp-12 is not a beta maturity claim.
exp-12 promotes exactly one compiler-known standard-runtime operation:
```text
std.io.read_stdin_result: () -> (result string i32)
```
Source call form:
```slo
(std.io.read_stdin_result)
```
`std.io.read_stdin_result` reads the remaining standard input as text and
returns `(ok string i32 text)` on success. Ordinary EOF with no bytes is
success with the empty string. Ordinary host/input failure returns
`(err string i32 1)`. The only ordinary failure code promised by exp-12 is
`err 1`.
The test runner must be deterministic enough for Glagol tests. It may return
an implementation-owned fixed input string as `ok`, including the empty
string.
exp-12 release fixtures are:
```text
examples/supported/stdin-result.slo
examples/formatter/stdin-result.slo
```
Existing exp-3 and exp-10 host calls stay unchanged. Artifact manifests record
exp-12 standard-runtime usage only if existing manifest patterns already
record standard-runtime usage metadata. Otherwise no stdin-specific manifest
field or schema version change is promoted.
exp-12 explicitly defers trap-based `std.io.read_stdin`, line iteration,
prompt APIs, terminal mode, binary stdin, streaming, async, encoding or
Unicode promises beyond existing string bytes, stable ABI/layout/helper
symbols, manifest schema changes, and beta maturity.
The normative exp-12 release contract is
`.llm/EXP_12_STDIN_RESULT_ALPHA.md`.
## 4.18 exp-13 String Parse I32 Result Alpha
Status: released experimental compiler-supported contract after matching
Glagol exp-13 gates passed, 2026-05-18. exp-13 is not a beta maturity claim.
exp-13 promotes exactly one compiler-known standard-runtime operation:
```text
std.string.parse_i32_result: (string) -> (result i32 i32)
```
Source call form:
```slo
(std.string.parse_i32_result text)
```
`std.string.parse_i32_result` parses the entire input string as ASCII decimal
signed `i32`. Accepted input has an optional leading `-`, followed by at least
one ASCII digit `0` through `9`, with no other leading, trailing, embedded, or
non-ASCII digit bytes. The numeric value must be in the signed `i32` range
`-2147483648` through `2147483647`.
Success returns `(ok i32 i32 value)`. The empty string, a lone `-`, non-digit
bytes, leading `+`, whitespace, trailing bytes, non-ASCII digits, and
out-of-range values return `(err i32 i32 1)`. The only ordinary parse error
code promised by exp-13 is `err 1`.
exp-13 adds no new result family. It uses the existing `(result i32 i32)`
constructors, observers, unwraps, and `match` behavior.
The intended exp-12 composition shape is structural:
```slo
(let input (result string i32) (std.io.read_stdin_result))
(match input
((ok text)
(std.string.parse_i32_result text))
((err code)
(err i32 i32 code)))
```
Fixtures must not assume a particular stdin payload. A trailing newline read
from stdin is a trailing byte and therefore returns `(err i32 i32 1)` unless a
future contract adds trimming or line APIs.
The later exp-111 staged `std/io.slo` stdin helpers follow the same rule:
their explicit-import fixture stays structural and payload-agnostic because
the runner may provide implementation-owned stdin text.
exp-13 release fixtures are:
```text
examples/supported/string-parse-i32-result.slo
examples/formatter/string-parse-i32-result.slo
```
Artifact manifests record exp-13 standard-runtime usage only if existing
manifest patterns already record standard-runtime usage metadata. Otherwise no
parse-specific manifest field or schema version change is promoted.
exp-13 explicitly defers trap-based `std.string.parse_i32`, parsing floats,
bools, strings, or bytes, whitespace trimming, locale-aware parsing, base
prefixes, radix arguments, underscores, plus-sign acceptance, generic parse
APIs, parse error messages, richer parse error codes, parse error ADTs,
Unicode digit parsing, string indexing and slicing, tokenizer/scanner APIs,
stdin line APIs, stable ABI/layout/helper symbols, manifest schema changes,
and beta maturity.
The normative exp-13 contract is
`.llm/EXP_13_STRING_PARSE_I32_RESULT_ALPHA.md`.
## 4.19 exp-14 Standard Runtime Conformance Alignment
Status: released experimental conformance alignment. exp-14 is not a beta
maturity claim.
exp-14 seeds standard-runtime conformance/readiness over the released exp-13
surface. It aligns documentation, fixture inventory, fixture byte checks, and
release gates around already promoted compiler-known `std.*` behavior.
exp-14 adds the normative catalog:
```text
STANDARD_RUNTIME.md
```
The catalog lists every promoted compiler-known `std.*` operation through
exp-13 with signature, release, fixture, behavior/trap/result note, manifest
note, and deferrals. It does not make legacy compatibility aliases such as
`print_i32`, `print_string`, `print_bool`, or `string_len` into `std.*`
operations.
exp-14 adds byte-identical canonical Slovo fixtures for the already released
exp-8 host time/sleep names:
```text
examples/supported/time-sleep.slo
examples/formatter/time-sleep.slo
```
The fixture uses only `std.time.sleep_ms 0` and structural/non-negative
`std.time.monotonic_ms` checks. It must not assert positive-duration timing,
elapsed-time precision, scheduler behavior, wall-clock correspondence, or
ordering across threads.
exp-14 requires the current supported fixture inventory to stay explicit and
requires Slovo/Glagol supported and formatter fixtures to stay byte-aligned
where matching files exist.
exp-14 also requires a fresh-project workflow to cover `new`, `check`,
`fmt --check`, `test`, `doc`, and `build` where the hosted toolchain exists.
That workflow, or an added conformance project, must exercise existing
features together: modules/imports, tests, strings, `std.string.concat`,
`std.string.parse_i32_result`, result `match`, `(vec i32)`, `(vec i64)`,
enum `match`, and `std.io.print_i32`.
The exp-14 release gate includes Slovo and Glagol diff checks,
`cargo fmt --check`, `cargo test`, ignored promotion gate, binary smoke, LLVM
smoke, fixture byte-alignment checks, fresh-project workflow checks,
artifact-manifest no-schema-drift checks, and release review `PASS`.
exp-14 adds no source syntax, type forms, runtime APIs, compiler-known
`std.*` names, standard library functions, manifest schema version,
ABI/layout promise, runtime headers/libraries, or beta maturity.
The normative exp-14 release contract is
`.llm/EXP_14_STANDARD_RUNTIME_CONFORMANCE_ALIGNMENT.md`.
## 4.20 exp-15 Result Helper Standard Names Alpha
Status: released experimental alpha. exp-15 is not a beta maturity claim.
exp-15 promotes standard source-level names for the existing result helper
surface:
```text
std.result.is_ok
std.result.is_err
std.result.unwrap_ok
std.result.unwrap_err
```
These names are accepted only for the currently supported concrete result
families:
```text
(result i32 i32)
(result string i32)
```
They are the preferred names for new source. Existing unqualified result
helper forms `is_ok`, `is_err`, `unwrap_ok`, and `unwrap_err` remain
compatibility syntax where they are already supported.
exp-15 adds byte-identical canonical fixtures:
```text
examples/supported/result-helpers.slo
examples/formatter/result-helpers.slo
```
The fixture covers ok/err observation and unwraps for both supported result
families.
exp-15 adds no result mapping, chaining, `unwrap_or`, option helper standard
names, new payload families, generic result, user-defined error payloads, enum
payloads, manifest schema changes, runtime ABI/layout promises, stable helper
symbols, runtime headers/libraries, or beta maturity.
The normative exp-15 release contract is
`.llm/EXP_15_RESULT_HELPER_STANDARD_NAMES_ALPHA.md`.
## 5. Slice 1: Struct Value Flow
Status: promoted as `examples/supported/struct-value-flow.slo`.
### 5.1 Goal
v0 structs can be declared, constructed, and immediately field-accessed:
```slo
(. (Point (x 20) (y 22)) x)
```
v1 should make structs usable as ordinary values in the supported subset.
Later promoted slices may broaden the direct field-type family while reusing
the same constructor, local, parameter, return, call, and field-access flow.
The first v1 struct slice promotes:
- struct locals
- struct parameters
- struct returns
- calls returning structs
- field access through stored struct values
Struct field mutation and whole-struct value mutation are intentionally
deferred beyond v1. They must not be claimed as supported until a later
promotion specifies syntax, typed-core meaning, lowering, formatting,
diagnostics, examples, and tests at the same standard.
### 5.2 Surface Syntax
Struct declaration syntax remains:
```slo
(struct Point
(x i32)
(y i32))
```
Constructor syntax remains:
```slo
(Point (x 20) (y 22))
```
Local storage uses the existing local declaration shape:
```slo
(let p Point (Point (x 20) (y 22)))
(. p x)
```
Function parameters and returns use the nominal struct name:
```slo
(fn point_x ((p Point)) -> i32
(. p x))
(fn make_point ((x i32) (y i32)) -> Point
(Point (x x) (y y)))
```
### 5.3 Type Rules
- Struct names are nominal types.
- Struct names must be declared before use.
- A struct local declared with `let` is immutable and supported.
- A struct local declared with `var` is deferred beyond v1 until field/value
mutation is explicitly promoted.
- A function parameter of struct type is immutable and supported.
- A function may return a struct value when the struct has only supported v1
field types.
- A call may produce a struct value when the callee return type is a declared
supported struct.
- Field access through a value of known struct type returns the field type.
- The first struct-flow slice supports `i32` fields. exp-18 additionally
supports direct fields whose types are current user-defined enum names.
exp-19 additionally supports direct `bool` and immutable `string` fields.
- exp-29 additionally supports direct immutable `i64` and finite `f64` fields.
- exp-120 additionally supports direct fixed immutable array fields over
`i32`, `i64`, `f64`, `bool`, and `string` element families with positive
literal lengths.
- Nested struct fields remain deferred unless separately specified.
### 5.4 Lowering Direction
The typed core represents struct values as nominal typed expressions. The
promoted slice requires checked forms for:
- struct constructor expressions
- field access expressions
- immutable struct local bindings
- struct-typed parameters
- struct-typed return values
- calls whose result type is a struct
The explicit constructor and field-access forms are:
```text
StructConstruct {
name,
fields,
result_type
}
StructFieldAccess {
value,
field,
result_type
}
```
Glagol uses a compiler-owned LLVM aggregate representation for v1 struct
values, but v1 does not promise a stable external ABI or cross-module layout.
Source field declaration order currently drives the implementation aggregate
order inside a closed compilation unit; it is not a public ABI promise.
The implementation prioritizes correctness and verification over layout
optimization.
### 5.5 Formatter Rules
Formatter behavior preserves v0 style:
- top-level struct declarations are multi-line
- constructor expressions with inline `i32` fields may stay inline
- local declarations containing constructors follow existing local formatting
- field access remains `(. value field)`
If constructor expressions become too complex for one line, v1 must define a
canonical multiline layout before support is claimed.
### 5.6 Diagnostics
The promoted struct-flow slice requires the existing structured diagnostic
format: machine-readable code, source span, line/column range, and any useful
expected/found or hint fields.
The promoted slice is covered by Glagol diagnostics for:
- constructor field type mismatch
- missing constructor field
- unknown constructor field
- constructor field order mismatch if declaration order remains required
- unsupported struct field type
- empty struct declaration
- unknown field access
- `MutableStructLocalUnsupported` when a struct local uses `var`
Before v1 release, the diagnostic matrix must also cover:
- unknown struct type in local declaration
- unknown struct type in function parameter
- unknown struct type in function return
- duplicate struct declarations
- duplicate struct fields
- duplicate constructor fields
- field access on non-struct value
- unsupported struct field/value mutation because mutation remains deferred
- unsupported nested struct field if nested structs remain deferred
### 5.7 Fixtures
The first v1 struct-flow promotion adds:
```text
examples/supported/struct-value-flow.slo
examples/formatter/struct-value-flow.slo
```
Later promoted struct-field slices additionally use:
```text
examples/supported/array-struct-fields.slo
examples/formatter/array-struct-fields.slo
```
Glagol mirrors these with compiler fixtures and a mutable-struct-local
diagnostic snapshot. monorepo promotion verification must run both the
default Glagol promotion gate and its ignored Slovo/Glagol alignment gate.
## 6. Slice 2: Option/Result Value Flow And Payload Access
Status: promoted as `examples/supported/option-result-flow.slo` and
`examples/supported/option-result-payload.slo`.
### 6.1 Goal
v0 option/result support allowed only direct constructor returns. The v1
option/result flow slice makes first-pass `i32` option/result values usable as
ordinary immutable values. The payload-access extension promotes explicit
trap-based unary extraction for `i32` payloads. The v1.4 core-language
expansion later promotes source-level `match` for the same concrete
option/result families while keeping broader algebraic-data-type behavior
deferred.
The promoted option/result contract supports:
- immutable `(option i32)`, `(option i64)`, `(option f64)`, `(option bool)`,
`(option string)`, and `(result i32 i32)` locals
- `(option i32)`, `(option i64)`, `(option f64)`, `(option bool)`,
`(option string)`, and `(result i32 i32)` function parameters
- calls returning option/result values
- tag observation with `is_some`, `is_none`, `is_ok`, and `is_err`
- explicit payload extraction with `unwrap_some`, `unwrap_ok`, and
`unwrap_err`
The exp-10 release additionally promotes only the concrete `(result string i32)`
family for result-based host errors. That family follows the same result
value-flow, observer, unwrap, and match rules where the `ok` payload is
`string` and the `err` payload is `i32`.
Direct constructor-return functions remain part of the v0 baseline. Returning
option/result values from locals, call results, or value-producing `if`
expressions is not part of this promoted slice until fixtures and tests cover
those forms.
### 6.2 Surface Syntax
Constructors remain:
```slo
(some i32 value)
(none i32)
(some i64 value)
(none i64)
(some f64 value)
(none f64)
(some bool value)
(none bool)
(some string value)
(none string)
(ok i32 i32 value)
(err i32 i32 value)
```
Local storage uses the existing local declaration shape:
```slo
(let value (option i32) (some i32 42))
(let wide (option i64) (some i64 42i64))
(let fraction (option f64) (some f64 42.5))
(let flag (option bool) (some bool true))
(let text (option string) (some string "hello"))
(let status (result i32 i32) (ok i32 i32 42))
```
Function parameters and returns use the existing type forms:
```slo
(fn option_score ((value (option i32))) -> i32
(if (is_some value)
1
0))
(fn option_wide_score ((value (option i64))) -> i32
(if (is_some value)
1
0))
(fn option_fraction_score ((value (option f64))) -> i32
(if (is_some value)
1
0))
(fn option_flag_score ((value (option bool))) -> i32
(if (is_some value)
1
0))
(fn option_text_score ((value (option string))) -> i32
(if (is_some value)
1
0))
(fn result_failure_score ((value (result i32 i32))) -> i32
(if (is_err value)
1
0))
```
The promoted tag observers are unary forms:
```slo
(is_some option-value)
(is_none option-value)
(is_ok result-value)
(is_err result-value)
(std.result.is_ok result-value)
(std.result.is_err result-value)
```
The promoted payload extractors are unary forms:
```slo
(unwrap_some option-value)
(unwrap_ok result-value)
(unwrap_err result-value)
(std.result.unwrap_ok result-value)
(std.result.unwrap_err result-value)
```
They are intentionally trap-based extraction forms. They are not pattern
matching and do not introduce user-catchable exceptions.
For result values, exp-15 makes the `std.result.*` forms the preferred source
surface. The unqualified result helpers remain compatibility syntax where they
were already supported. Option helper standard names are not promoted.
### 6.3 Type Rules
- The promoted slice supports `(option i32)`, `(option i64)`,
`(option f64)`, `(option bool)`, `(option string)`, `(result i32 i32)`,
the exp-10 family
`(result string i32)`, and the
exp-25 family `(result i64 i32)`.
- Payloads and extraction beyond those concrete families remain unsupported;
`unwrap_ok` returns `string` for `(result string i32)` and `i64` for
`(result i64 i32)`.
- Option/result locals are supported only with immutable `let`.
- Option/result parameters are immutable.
- `is_some` and `is_none` require `(option i32)`, `(option i64)`,
`(option f64)`, `(option bool)`, or `(option string)` and return `bool`.
- `is_ok` and `is_err` require `(result i32 i32)` or the exp-10
family `(result string i32)` and return `bool`.
- `std.result.is_ok` and `std.result.is_err` have the same result-family type
rules as the legacy unqualified compatibility observers.
- `unwrap_some` requires `(option i32)`, `(option i64)`, `(option f64)`,
`(option bool)`, or `(option string)` and returns the matching concrete
payload type.
- `unwrap_ok` requires `(result i32 i32)` and returns `i32`, or requires the
exp-10 family `(result string i32)` and returns `string`.
- `unwrap_err` requires `(result i32 i32)` or the exp-10 family
`(result string i32)` and returns `i32`.
- `std.result.unwrap_ok` and `std.result.unwrap_err` have the same result-family
type rules and trap behavior as the legacy unqualified compatibility
extractors.
- `unwrap_some` traps at runtime when its operand is `none`.
- `unwrap_ok` traps at runtime when its operand is `err`.
- `unwrap_err` traps at runtime when its operand is `ok`.
- Source-level option/result `match` for `(option i32)`, `(option i64)`,
`(option f64)`, `(option bool)`, `(option string)`, and `(result i32 i32)`
is promoted by v1.4. exp-10 promotes the same result `match` shape for
`(result string i32)`. Mapping remains deferred.
- Option/result equality remains unsupported and deferred beyond v1.
- Printing option/result values remains unsupported and deferred beyond v1.
- Nested option/result values, arrays of options/results, and structs
containing option/results remain deferred beyond v1.
- Additional option/result payload families beyond the current
`(option i32)`, `(option i64)`, `(option f64)`, `(option bool)`,
`(option string)`, and released concrete result slices remain deferred.
- Payload traps are not user-catchable exceptions in v1; user-catchable
exceptions remain deferred beyond v1.
### 6.4 Lowering Direction
The typed core represents current option/result values as tagged concrete
payload aggregates. The promoted slice requires checked forms for:
- option/result constructors
- immutable option/result local bindings
- option/result typed parameters
- option/result typed return values
- calls whose result type is option/result
- tag observers
- payload extractors
Glagol uses a compiler-owned tagged aggregate representation for current
option/result values. The tag indicates `some`/`ok` when true and `none`/`err`
when false. This is closed-module implementation behavior, not a stable
external ABI or layout promise.
Payload extraction must lower through an explicit tag check before payload
access. On the non-matching tag, the generated runtime path traps. The exact
trap helper, block names, aggregate layout, and ABI are implementation-owned,
but the check-before-payload-access shape is part of the v1 contract so Glagol
tests can verify it.
The v1.2 runtime error messages for payload traps are stable:
```text
slovo runtime error: unwrap_some on none
slovo runtime error: unwrap_ok on err
slovo runtime error: unwrap_err on ok
```
The message is written to stderr with a trailing newline. The process then
exits with code `1`. These traps are not user-catchable Slovo exceptions.
### 6.5 Formatter Rules
Formatter behavior preserves the current compact style:
- constructors stay inline when their payload expression is compact
- option/result local declarations use one-line local formatting
- option/result parameter and return types print as `(option i32)`,
`(option i64)`, `(option string)`, and `(result i32 i32)`
- exp-10 `(result string i32)` parameter and return types print in the same
canonical type-form style
- tag observers print as unary expression forms
- payload extractors print as unary expression forms
- exp-15 `std.result.*` observers and payload extractors print as unary
expression forms and remain inline when used as expressions
v1.4 promotes option/result `match`; its canonical multiline layout is defined
in section 4.2 and `.llm/V1_4_CORE_LANGUAGE_EXPANSION.md`.
### 6.6 Diagnostics
The promoted slice keeps the existing structured diagnostic format. It is
covered by Glagol diagnostics for:
- malformed option/result constructors
- non-`i32` option/result payload types
- constructor payload type mismatch
- option/result equality
- option/result printing
- option observers applied to non-option values
- result observers applied to non-result values
- `unwrap_some` applied to non-option values
- `unwrap_ok` or `unwrap_err` applied to non-result values
- `std.result.*` helpers applied to non-result values or unsupported result
families
Before v1 release, the diagnostic matrix must also cover:
- non-`i32` option/result payloads in function parameter position
- non-`i32` option/result payloads in function return position
- unsupported option/result mapping if such forms become source-reachable
without promotion
### 6.7 Fixtures
The option/result value-flow and payload-access promotion adds:
```text
examples/supported/option-result-flow.slo
examples/formatter/option-result-flow.slo
examples/supported/option-result-payload.slo
examples/formatter/option-result-payload.slo
```
The exp-10 result-based host errors release adds:
```text
examples/supported/host-io-result.slo
examples/formatter/host-io-result.slo
```
The exp-13 string parse i32 result release adds:
```text
examples/supported/string-parse-i32-result.slo
examples/formatter/string-parse-i32-result.slo
```
The exp-15 result helper standard names release adds:
```text
examples/supported/result-helpers.slo
examples/formatter/result-helpers.slo
```
Glagol mirrors these with compiler fixtures, formatter coverage, test-runner
coverage, LLVM shape checks, runtime trap checks, observer diagnostics, and
payload-extractor diagnostics.
## 7. Slice 3: Array Value Flow And Dynamic Indexing
Status: promoted as `examples/supported/array-value-flow.slo`, widened by
exp-117 through `examples/supported/array-direct-scalars.slo` and
`examples/supported/array-direct-scalars-value-flow.slo`, then broadened again
by exp-118 through `examples/supported/array-string.slo` and
`examples/supported/array-string-value-flow.slo`.
### 7.1 Goal
v0 arrays support fixed `(array i32 N)` constructors, immutable array locals
initialized from matching constructors, and literal indexing. The v1 array
slice keeps those v0 forms valid and broadens fixed-size direct scalar arrays
plus one concrete `string` array lane as ordinary values in the supported
subset, including immutable locals initialized from matching array-valued
expressions.
The promoted slice supports:
- fixed array types `(array T N)` with positive literal `N` when `T` is one of
`i32`, `i64`, `f64`, `bool`, or `string`
- fixed array constructors over those promoted element families
- immutable array locals initialized from any supported expression that checks
as the exact declared `(array T N)` type
- `(array T N)` function parameters
- `(array T N)` function returns
- calls returning `(array T N)` values
- dynamic `(index array-expr index-expr)` when `index-expr` checks as `i32`
The slice intentionally does not promote array mutation, arrays of other
unsupported element types, zero-length arrays, slices, array equality,
printing arrays, nested arrays, unchecked indexing, or any stable ABI/layout
promise.
### 7.2 Surface Syntax
Fixed array type syntax remains:
```slo
(array T N)
```
For this slice, `T` is exactly one of `i32`, `i64`, `f64`, `bool`, or
`string`.
Constructor syntax remains:
```slo
(array T value...)
```
Function parameters and returns may use fixed direct scalar or `string` array
types:
```slo
(fn pick ((values (array i64 3)) (i i32)) -> i64
(index values i))
(fn make_values () -> (array bool 3)
(array bool true false true))
(fn make_words () -> (array string 3)
(array string "sun" "moon" "star"))
```
A call may return an array value and feed another supported array expression
position:
```slo
(fn pick_from_return ((i i32)) -> bool
(index (make_values) i))
```
Immutable array locals may be initialized from any supported array-valued
expression with the exact declared type:
```slo
(fn local_array_flow ((i i32)) -> f64
(let values (array f64 3) (array f64 1.0 2.0 3.0))
(index values i))
```
Index syntax remains:
```slo
(index array-expr index-expr)
```
For this slice, `index-expr` may be any supported expression that checks as
`i32`. Literal indexing remains valid.
### 7.3 Type Rules
- `N` in `(array T N)` is a positive source integer literal in type position.
- The promoted element types are exactly `i32`, `i64`, `f64`, `bool`, and
`string`.
- Array constructors produce `(array T count)` values.
- Constructor values are checked left to right and must each check as `T`.
- In an expected-type context, `(array T count)` is valid for `(array T N)`
only when `count == N`.
- Immutable array locals declared with `let` may be initialized by any
supported expression that checks as exactly the declared `(array T N)` type,
including direct constructors, parameters, and call results.
- This slice does not promote mutable array locals.
- Function parameters may have type `(array T N)`.
- Function returns may have type `(array T N)`.
- Calls may produce `(array T N)` when the callee return type is a promoted
fixed array type.
- Supported array values may be passed to parameters with the exact same
`(array T N)` type.
- Returning an array expression requires the exact declared `(array T N)`
return type.
- `index` requires an array expression that checks as `(array T N)`.
Promoted index bases are any supported expression with that type, including
immediate constructors, immutable array locals, array parameters, and calls
returning promoted fixed arrays.
- `index` requires an index expression that checks as `i32`.
- `index` returns `T`.
- Array equality remains unsupported.
- Printing arrays remains unsupported.
- Nested arrays and arrays of structs/options/results remain deferred.
### 7.4 Bounds Behavior
Literal out-of-bounds indexing remains a structured diagnostic. A literal index
must satisfy `0 <= index < N`; if it does not, checking fails before lowering.
Dynamic indexing must be checked at runtime by Glagol. For every accepted
dynamic index expression, the lowered program must evaluate the array
expression once, evaluate the index expression once, then branch through an
explicit bounds check equivalent to:
```text
0 <= index && index < N
```
If the check succeeds, the selected element is read and returned. If the check
fails, execution must enter an explicit runtime trap path before any
out-of-bounds element access occurs. The trap path may be compiler-owned and is
not a stable Slovo runtime ABI in v1, but it must be visible in lowering or
LLVM output well enough for Glagol tests to verify that dynamic array access is
not unchecked.
Top-level tests that trigger the runtime trap should be reported as trapped
tests by Glagol's test runner once that runner covers trap results. This slice
does not require Slovo to standardize a user-catchable exception value.
The v1.2 runtime error message for a failed dynamic bounds check is stable:
```text
slovo runtime error: array index out of bounds
```
The message is written to stderr with a trailing newline. The process then
exits with code `1`. For `glagol test`, the trapped top-level test is reported
as a trapped test and the command exits with code `1`. For `glagol build`, the
produced executable exits with code `1`.
### 7.5 Lowering Direction
The typed core represents promoted arrays as fixed-length aggregate values with
compiler-owned layout. The promoted slice requires checked forms for:
- fixed promoted array types
- fixed promoted array constructor expressions
- immutable array local bindings whose initializer checks as the exact declared
fixed promoted array type
- array-typed parameters
- array-typed return values
- calls whose result type is a fixed promoted array
- literal and dynamic array indexing
The array index core form records whether bounds were proven at check time or
must be checked at runtime:
```text
ArrayIndex {
array: TExpr<Array(element_type, length)>,
index: TExpr<i32>,
bounds: LiteralInBounds | RuntimeChecked,
result_type: element_type,
span,
array_span,
index_span
}
```
Literal in-bounds indices may lower to direct aggregate extraction. Dynamic
indices lower to a runtime-checked element access with a trap edge. Glagol may
copy fixed arrays between local storage, parameters, returns, and call results
using any compiler-owned aggregate representation, but v1 does not promise a
stable LLVM, C, FFI, or cross-module ABI layout.
### 7.6 Formatter Rules
Formatter behavior preserves the current compact array style:
- `(array T N)` types print inline
- constructors with inline promoted values print as `(array T value...)`
- array local declarations print with existing one-line local formatting when
their initializer is inline
- array parameter and return types print inline in function signatures
- index expressions print as `(index array-expr index-expr)` when both
operands are inline
- function and test body indentation follows the existing
one-body-form-per-line rule
If later slices add multiline array constructors, slices, or pattern-style
array forms, those slices must define their own canonical layouts.
### 7.7 Diagnostics
The promoted slice keeps the existing structured diagnostic format. It is
covered by the v0 array diagnostics for malformed types, malformed
constructors, unsupported element types, zero-length arrays, empty
constructors, constructor length mismatch, element type mismatch, malformed
index syntax, indexing non-arrays, non-`i32` index expressions, literal
out-of-bounds indices, mutable array locals, array equality, array printing,
and array mutation.
The v1 promotion changes the first-pass `UnsupportedArraySignatureType`
boundary: exact `(array T N)` parameters and returns are now supported for the
direct scalar and `string` element families. Unsupported array signature
diagnostics remain required for other unsupported element types, zero-length
arrays, nested arrays, arrays containing unsupported value types, and any
future array type form not promoted here.
Dynamic indices are no longer rejected as `DynamicArrayIndexUnsupported` when
the index expression checks as `i32`. That diagnostic remains appropriate only
for compilers or modes that explicitly target the v0 baseline.
The promoted array slice also requires diagnostics or lowering checks for these
source-reachable promoted boundaries:
- array return expression type mismatch
- array argument type mismatch
- array local initializer type mismatch when an immutable array local
initializer does not check as the exact declared fixed promoted array type
- missing runtime trap lowering if a dynamic index reaches LLVM unchecked
Future diagnostics for newly promoted array forms remain separate from this
slice. In particular, later slices that promote mutable arrays, array mutation,
zero-length arrays, other unsupported array element types, nested arrays,
slices, equality, printing, unchecked indexing, or stable layout must define
their own diagnostics before claiming support.
### 7.8 Fixtures
The current array fixtures for this slice are:
```text
examples/supported/array-direct-scalars.slo
examples/supported/array-value-flow.slo
examples/supported/array-direct-scalars-value-flow.slo
examples/supported/array-string.slo
examples/supported/array-string-value-flow.slo
examples/formatter/array-direct-scalars.slo
examples/formatter/array-value-flow.slo
examples/formatter/array-direct-scalars-value-flow.slo
examples/formatter/array-string.slo
examples/formatter/array-string-value-flow.slo
```
Glagol mirrors these with compiler fixtures, formatter coverage, test-runner
coverage, LLVM checks that dynamic indexing branches to an explicit trap path,
and diagnostics for unsupported array forms.
## 8. Slice 4: Runtime Strings And Practical Runtime Values
Status: promoted as `examples/supported/string-print.slo`, extended in v1.2
through `examples/supported/string-value-flow.slo` and
`examples/supported/print-bool.slo`, then given v1.5 standard-runtime names in
`examples/supported/standard-runtime.slo`. exp-1 adds
`examples/supported/owned-string-concat.slo` as the first
owned-runtime-string compiler-supported fixture. exp-13 adds
`examples/supported/string-parse-i32-result.slo` as the first string parse
result compiler-supported fixture. exp-34 adds
`examples/supported/string-parse-bool-result.slo` for the exact lowercase bool
parse result slice.
### 8.1 Goal
The first runtime string slice promoted enough string behavior to print
compiler-emitted immutable source literals from ordinary programs. Slovo v1.2
extends that slice conservatively so immutable strings can flow through small
programs without introducing allocation or ownership. exp-1 adds one narrow
heap-created owned-string operation, `std.string.concat`, while preserving the
same source type and keeping memory management out of user code.
The promoted slice supports:
- source string literals as immutable runtime literals
- ASCII-plus-current-escape literal semantics, without a full Unicode promise
- legacy compiler/runtime compatibility alias `(print_string value)`
- direct string-literal printing in a normal `i32` function body
- immutable string locals with `let`
- string parameters and string returns
- calls returning strings
- string equality with `=`
- string byte length with legacy compatibility alias `(string_len value)`
- top-level tests whose final expression uses string equality or compares a
string length result
- bool printing with legacy compatibility alias `(print_bool value)`
- v1.5 source-level standard-runtime names for the same print and string
length behavior: `std.io.print_i32`, `std.io.print_string`,
`std.io.print_bool`, and `std.string.len`
- exp-1 `std.string.concat`, returning an immutable runtime-owned `string`
from two `string` operands
- exp-13 released `std.string.parse_i32_result`, returning an existing
`(result i32 i32)` value from an entire ASCII decimal signed `i32` string
- exp-34 released `std.string.parse_bool_result`, returning `(result bool i32)`
for exact lowercase `true`/`false` parsing with `err 1` ordinary failures
Everything else in the string family remains deferred until separately
specified, implemented, diagnosed, formatted, and tested.
### 8.2 Surface Syntax
String literals continue to use double quotes:
```slo
"hello"
```
The first promoted runtime string consumer is:
```slo
(print_string "hello")
```
`print_string` has exactly one argument of type `string`, returns builtin
`unit`, and prints the string followed by a newline. Like `print_i32`, it is a
legacy compiler/runtime compatibility alias paired with runtime lowering.
v1.5 promotes the source-level standard-runtime name `std.io.print_string` for
the same behavior. Neither spelling is a user-defined function, import,
foreign function, package dependency, or stable runtime ABI.
v1.2 promotes string value flow:
```slo
(let value string "hello")
(fn echo ((value string)) -> string
value)
(fn call_return () -> string
(echo "hello"))
```
v1.2 promotes string equality and length through the legacy alias:
```slo
(= "hello" (call_return))
(string_len "hello")
```
`=` accepts two `string` operands and returns `bool`. String equality compares
the decoded byte sequence before the trailing NUL byte. It is not
locale-sensitive and makes no Unicode normalization promise.
`string_len` has exactly one `string` argument and returns `i32`. It counts
decoded bytes before the trailing NUL byte. It is not a Unicode scalar count,
grapheme count, display width, or locale-sensitive length.
v1.5 promotes `std.string.len` for the same behavior:
```slo
(std.string.len "hello")
```
exp-1 promotes `std.string.concat` as the first heap-created string operation:
```slo
(std.string.concat "hello, " "slovo")
```
`std.string.concat` has exactly two `string` arguments and returns `string`.
The result is immutable and runtime-owned by the compiler/runtime. It is usable
with existing string equality, `std.string.len`, `std.io.print_string`, string
locals, parameters, returns, and calls returning `string`. No import is
required, no legacy alias is introduced, and no user-visible allocation or
deallocation form is exposed.
v1.2 promotes bool printing through the legacy alias:
```slo
(print_bool (= "hello" "hello"))
```
`print_bool` has exactly one `bool` argument, returns builtin `unit`, and
prints `true` or `false` followed by a newline. v1.5 promotes
`std.io.print_bool` for the same behavior. v1.5 also promotes
`std.io.print_i32` for the same behavior as legacy `print_i32`.
Slovo v1.5 does not define a broader standard-runtime printing contract. The
only supported printing forms are legacy compatibility aliases `print_i32`,
`print_string`, and `print_bool`, plus source-level standard-runtime names
`std.io.print_i32`, `std.io.print_string`, and `std.io.print_bool`. Unit
printing, composite value printing, overloaded print forms, file IO, imports,
packages, and stable runtime print ABI bindings remain deferred beyond v1.5.
A supported ordinary program may use `print_string` or `std.io.print_string`
as a sequential body form before an `i32` final expression:
```slo
(fn main () -> i32
(print_string "hello")
0)
```
`print_string` and `std.io.print_string` are not supported as the final
expression of an `i32` function or `bool` test because they return builtin
`unit`.
`bool` remains a checked value type for promoted conditions, tests,
option/result observers, string equality, `print_bool`, and
`std.io.print_bool`.
`unit` remains an internal builtin result type for unit-producing forms such as
`set`, `while`, legacy print aliases, and `std.io.print_*` calls.
User-declared `unit` return types, `unit` parameters, `unit` locals, stored
`unit` values, `print_unit`, and using `unit` as a user-visible final result
remain unsupported in v1.2.
### 8.3 Literal Semantics
The promoted literal domain is intentionally narrow:
- unescaped literal content is ASCII source text
- the required current escapes are newline `\n`, tab `\t`, quote `\"`, and
backslash `\\`
- decoded literal bytes are immutable
- embedded NUL bytes and arbitrary byte escapes are not part of the promoted
slice
- this slice makes no promise that arbitrary Unicode source text is accepted,
normalized, encoded, compared, or printed correctly
For the v1.2/v1.5 slice, the source literal denotes a runtime literal, not an
owned heap string. Every promoted string value originates from a source string
literal or from propagating such a value through an immutable local, parameter,
return, or call result.
exp-1 extends this by allowing one heap-created string source:
`std.string.concat`. The result is runtime-owned and immutable, but ownership
is not source-visible. No Slovo program can mutate, manually allocate, free,
retain, or otherwise manage the storage behind a promoted string value.
### 8.4 Type Boundary
The checker assigns source string literals the builtin type `string`.
Promoted uses of `string` values:
- direct argument to `print_string` or `std.io.print_string`
- immutable `let` locals with type `string`
- mutable `var` locals with type `string` plus same-type `set` reassignment
- function parameters with type `string`
- function returns with type `string`
- call results whose declared return type is `string`
- operands to `=` when both operands check as `string`
- argument to `string_len` or `std.string.len`
- exp-1 arguments to and result from `std.string.concat`
Still deferred:
- string ordering or comparison other than equality
- string values inside arrays or vectors
- slices or borrowed substring views
- concatenation beyond exp-1 `std.string.concat`
- indexing
- ownership or lifetime annotations
- user-defined runtime bindings involving `string`
### 8.5 Runtime Representation And Lowering
The runtime representation for this slice is still a borrowed immutable
NUL-terminated byte pointer to compiler-emitted static storage. v1.2 does not
add allocation.
Required lowering shape:
- each promoted string literal lowers to immutable static storage containing the
decoded ASCII-plus-escape bytes followed by one trailing NUL byte
- string locals, parameters, returns, and call results lower as copies of that
borrowed immutable pointer value
- `(print_string value)` lowers to a runtime call that receives a borrowed
pointer to that storage and writes the bytes followed by a newline
- `(print_bool value)` lowers to a runtime call that writes `true\n` or
`false\n`
- string equality lowers to a byte-sequence comparison before the trailing NUL
- `(string_len value)` lowers to a byte count before the trailing NUL
- v1.5 `std.io.print_string`, `std.io.print_bool`, and `std.string.len` lower
through the same implementation paths as their legacy aliases
- exp-1 `std.string.concat` lowers to a runtime-owned immutable string
allocation, byte copy, and trailing terminator write; allocation failure
traps with `slovo runtime error: string allocation failed`
- since embedded NUL is not promoted, printing observes the whole decoded
literal and equality/length observe the whole decoded value
Typed-core shape:
```text
StringLiteral {
bytes,
type: string,
span
}
CallIntrinsic {
name: print_string,
args: [StringLiteral],
type: unit,
span
}
StringLet {
name,
type: string,
value: TExpr<string>,
span
}
CallIntrinsic {
name: string_len,
args: [TExpr<string>],
type: i32,
span
}
StringEquals {
left: TExpr<string>,
right: TExpr<string>,
type: bool,
span
}
CallIntrinsic {
name: print_bool,
args: [TExpr<bool>],
type: unit,
span
}
StdStringConcat {
left: TExpr<string>,
right: TExpr<string>,
type: string,
span
}
```
This representation is not a stable Slovo ABI. Slovo v1 does not promise a C
signature, symbol name, pointer type spelling, address space, literal
deduplication behavior, static object layout, allocator interaction, or FFI
contract for strings. exp-1 also does not promise a stable runtime-owned string
layout, allocator, cleanup timing, helper symbol, or C ABI.
### 8.6 Formatter Rules
Formatter behavior preserves the current compact call style:
```slo
(fn main () -> i32
(print_string "hello")
0)
```
String literals stay inline when used as the direct argument to `print_string`,
as immutable string local initializers, as string returns, as string equality
operands, and as `string_len` arguments. String parameter and return types print
as `string`. `string_len` and `print_bool` use the same compact call style as
other promoted intrinsics. v1.5 `std.io.print_*` and `std.string.len` calls use
the same compact call style. exp-1 `std.string.concat` uses the same compact
call style and remains inline when nested in `std.io.print_string`,
`std.string.len`, equality, local initializers, returns, and user calls. The
formatter must preserve the decoded literal meaning when re-emitting the
current supported escapes.
### 8.7 Diagnostics
The promoted slice keeps the existing structured diagnostic format. It is
acceptable to reuse general diagnostics when the expected/found data is clear.
Required promoted-boundary diagnostics:
- malformed or unterminated string literals must be reported as structured
lexer/parser diagnostics before checking
- `(print_string)` and `(print_string a b)` must report an arity diagnostic
with expected `1`
- `(print_string value)` where `value` is not `string` must report a type
diagnostic with expected `string` and found checked type
- using `print_string` as an `i32` function result or `bool` test result must
report the existing result-type diagnostic for found `unit`
- `(string_len)` and `(string_len a b)` must report an arity diagnostic with
expected `1`
- `(string_len value)` where `value` is not `string` must report a type
diagnostic with expected `string` and found checked type
- `(= left right)` where exactly one operand is `string` must report a type
diagnostic; both operands must be `string` for string equality
- `(print_bool)` and `(print_bool a b)` must report an arity diagnostic with
expected `1`
- `(print_bool value)` where `value` is not `bool` must report a type
diagnostic with expected `bool` and found checked type
- `(std.string.concat)`, `(std.string.concat a)`, and
`(std.string.concat a b c)` must report an arity diagnostic with expected `2`
- `(std.string.concat left right)` where either operand is not `string` must
report a type diagnostic with expected `string` and the found checked type
- using `std.string.concat` where a non-`string` result is required must report
the existing result-type diagnostic for found `string`
- declaring, exporting, importing, or binding a name that shadows
`std.string.concat` must produce a structured reserved-name diagnostic
- `print_unit` must report an unsupported intrinsic/form diagnostic, or a
structured unknown-call diagnostic if the implementation has no intrinsic
entry for it
- string ordering/comparison other than equality, string containers beyond the
current direct struct fields, current fixed string arrays, current direct
fixed-array struct fields, and current concrete option/result families,
slices, concatenation beyond exp-1
`std.string.concat`, indexing, mutation, user-visible allocation,
user-visible deallocation, and user-defined runtime bindings must remain
unsupported with structured diagnostics or explicit backend-feature
diagnostics; they must not reach a backend panic
Future diagnostics for broader string features remain separate from this
slice.
### 8.8 Fixtures
The runtime string promotions add:
```text
examples/supported/string-print.slo
examples/supported/string-value-flow.slo
examples/supported/print-bool.slo
examples/formatter/string-print.slo
examples/formatter/string-value-flow.slo
examples/formatter/print-bool.slo
```
exp-1 adds:
```text
examples/supported/owned-string-concat.slo
examples/formatter/owned-string-concat.slo
```
The exp-1 fixture files are current compiler-supported fixtures after the
matching Glagol exp-1 release gate.
Glagol mirrors these with compiler fixtures, formatter coverage, test-runner
coverage, LLVM checks that literals lower to immutable static NUL-terminated
storage, executable/runtime checks that `print_string` prints the decoded
literal plus a newline, string equality and length checks, `print_bool`
stdout checks, and diagnostics for the deferred boundaries.
### 8.9 v1.5 Standard Runtime Names
v1.5 adds source-level standard-runtime names for stable v1.2 runtime behavior:
```slo
(std.io.print_i32 value)
(std.io.print_string value)
(std.io.print_bool value)
(std.string.len value)
```
These names are compiler-known. They are not user modules, not importable
module members, not package dependencies, not foreign functions, and not stable
C ABI symbols. No import is required to call them.
The promoted names have exactly the same type and behavior contracts as the
legacy compatibility aliases:
- `std.io.print_i32`: one `i32`, returns builtin `unit`
- `std.io.print_string`: one `string`, returns builtin `unit`
- `std.io.print_bool`: one `bool`, returns builtin `unit`
- `std.string.len`: one `string`, returns `i32`
Unknown or unpromoted `std.*` calls must produce a structured diagnostic; the
suggested code is `UnsupportedStandardLibraryCall`. Arity and type mismatches
for the promoted `std.*` calls use existing arity/type diagnostics where
applicable. The promoted names are reserved from user function/export
shadowing.
v1.5 adds:
```text
examples/supported/standard-runtime.slo
examples/formatter/standard-runtime.slo
```
### 8.10 exp-1 Owned Runtime String Name
exp-1 adds one standard-runtime name:
```slo
(std.string.concat left right)
```
The name is compiler-known and has the exact signature:
```text
std.string.concat: (string, string) -> string
```
The result is an immutable runtime-owned string. Existing `string` operations
do not distinguish source-visible value kinds: literal-backed strings and
runtime-owned strings both have type `string`.
`std.string.concat` is not an importable module member, not a user-defined
function, not a package dependency, not a foreign function, and not a stable C
ABI symbol. The implementation may lower through any runtime helper and
allocator strategy that preserves the source contract.
No source-visible deallocation form is promoted. Runtime-owned string cleanup
is an implementation responsibility and is not observable except that
supported safe source must not require manual free and must not expose
use-after-free.
Allocation failure traps with:
```text
slovo runtime error: string allocation failed
```
The trap is process-terminating and exits with code `1`.
### 8.11 exp-13 String Parse I32 Result Name
exp-13 adds one standard-runtime name:
```slo
(std.string.parse_i32_result text)
```
The name is compiler-known and has the exact signature:
```text
std.string.parse_i32_result: (string) -> (result i32 i32)
```
The result uses the existing `(result i32 i32)` family. Success returns
`(ok i32 i32 value)`. Ordinary parse failure returns `(err i32 i32 1)`.
The parser accepts the entire string only when it is ASCII decimal signed
`i32`: optional leading `-`, one or more ASCII digits, and an in-range value.
It rejects empty input, a lone `-`, `+`, whitespace, trailing bytes,
non-digits, non-ASCII digits, and out-of-range values with `err 1`.
`std.string.parse_i32_result` is not an importable module member, not a
user-defined function, not a package dependency, not a foreign function, and
not a stable C ABI symbol. The implementation may lower through any runtime
helper strategy that preserves the source contract.
### 8.12 exp-14 Standard Runtime Catalog
exp-14 adds no new standard-runtime names. It adds `STANDARD_RUNTIME.md` as a
conformance catalog for the compiler-known `std.*` operations promoted through
exp-13.
The catalog is documentation and release-gate inventory. It must match the
already promoted names, signatures, fixture references, behavior/trap/result
notes, manifest notes, and deferrals. It must not add imports, user modules,
package dependencies, runtime APIs, helper-symbol promises, ABI/layout
promises, manifest schema versions, runtime headers/libraries, or beta
maturity.
### 8.13 exp-15 Result Helper Standard Names
exp-15 adds four standard-runtime source names:
```slo
(std.result.is_ok value)
(std.result.is_err value)
(std.result.unwrap_ok value)
(std.result.unwrap_err value)
```
The names are compiler-known and accepted only for `(result i32 i32)`,
`(result i64 i32)`, `(result string i32)`, exp-28 returned
`(result f64 i32)`, and exp-34 returned `(result bool i32)`.
The exact signatures are:
```text
std.result.is_ok: ((result i32 i32)) -> bool
std.result.is_ok: ((result i64 i32)) -> bool
std.result.is_ok: ((result string i32)) -> bool
std.result.is_ok: ((result f64 i32)) -> bool
std.result.is_ok: ((result bool i32)) -> bool
std.result.is_err: ((result i32 i32)) -> bool
std.result.is_err: ((result i64 i32)) -> bool
std.result.is_err: ((result string i32)) -> bool
std.result.is_err: ((result f64 i32)) -> bool
std.result.is_err: ((result bool i32)) -> bool
std.result.unwrap_ok: ((result i32 i32)) -> i32
std.result.unwrap_ok: ((result i64 i32)) -> i64
std.result.unwrap_ok: ((result string i32)) -> string
std.result.unwrap_ok: ((result f64 i32)) -> f64
std.result.unwrap_ok: ((result bool i32)) -> bool
std.result.unwrap_err: ((result i32 i32)) -> i32
std.result.unwrap_err: ((result i64 i32)) -> i32
std.result.unwrap_err: ((result string i32)) -> i32
std.result.unwrap_err: ((result f64 i32)) -> i32
std.result.unwrap_err: ((result bool i32)) -> i32
```
These forms lower to the same typed-core observer and payload-extraction
operations as the legacy unqualified compatibility forms. The existing
`unwrap_ok on err` and `unwrap_err on ok` trap behavior applies.
`std.result.*` helper names are not importable module members, not
user-defined functions, not package dependencies, not foreign functions, and
not stable C ABI symbols. The implementation may lower through any helper
strategy that preserves the source contract.
## 9. Slice 5: Tooling Contracts
Status: promoted as a tooling contract only. This slice does not add source
syntax, runtime behavior, type-system behavior, or a native executable output
requirement.
### 9.1 Machine Diagnostic Schema
Slovo v1 keeps the v0 rule that diagnostics have both human-readable and
machine-readable forms generated from one compiler diagnostic object. Human
rendering may choose layout and surrounding prose, but the machine form is a
stable tool API.
The v1 machine diagnostic schema is `slovo.diagnostic` version `1`.
Every machine diagnostic emitted for a v1 compiler boundary must include:
- schema marker: `slovo.diagnostic`
- version marker: `1`
- severity
- stable PascalCase diagnostic code
- concise message
- source file path
- primary zero-based, half-open byte span
- primary one-based line/column range
Optional fields:
- expected value, type, arity, or form
- found value, type, arity, or form
- safe repair hint
- related spans, each represented as a repeated `(related (span ...))` form
with its own file path, byte span, line/column range, and optional message
Machine-readable diagnostic example:
```slo
(diagnostic
(schema slovo.diagnostic)
(version 1)
(severity error)
(code TypeMismatch)
(message "expected i32, found string")
(file "main.slo")
(span
(bytes 42 49)
(range 12 8 12 15))
(expected i32)
(found string)
(hint "Use an integer value or convert explicitly."))
```
Related span example:
```slo
(related
(span
(file "main.slo")
(bytes 10 14)
(range 2 8 2 12)
(message "original declaration")))
```
Each related span is emitted as its own repeated `(related ...)` form. The
related message belongs to that related span object; it is not a top-level
diagnostic message.
The primary and related byte spans are zero-based and half-open. Line values
are one-based source line numbers. Column values are one-based byte columns
within the original UTF-8 source line; a tab counts as one input byte. The end
column is the first byte column after the highlighted range on the end line.
Diagnostic locations are derived from original source text, not from formatter
output.
The schema version belongs in every machine diagnostic and every golden
diagnostic fixture. Future machine-shape changes require a documented schema
migration and updated Glagol snapshots.
### 9.2 Artifact Manifest Schema
Slovo v1 defines a narrow textual artifact manifest for compiler outputs and
test reports. The manifest records what a tool invocation consumed, what mode
it ran in, whether it succeeded, which diagnostic schema applies, and where
generated textual or structured artifacts can be found.
The v1 artifact manifest schema is `slovo.artifact-manifest` version `1`.
Every manifest must include:
- schema marker: `slovo.artifact-manifest`
- version marker: `1`
- source path
- command string
- mode
- success marker
- diagnostics schema version
- primary output, either as a kind/path pair, stdout text, or explicit
no-output marker
- generated artifact references, which may be empty
Optional field:
- test report summary. When present in v1, it contains `total`, `passed`,
`failed`, and `skipped` counts.
Compiler-output manifest example:
```slo
(artifact-manifest
(schema slovo.artifact-manifest)
(version 1)
(source "examples/supported/add.slo")
(command "glagol compile examples/supported/add.slo --emit llvm")
(mode emit-llvm)
(success true)
(diagnostics-schema-version 1)
(primary-output
(kind llvm-ir)
(path "build/add.ll"))
(artifacts
(artifact
(kind llvm-ir)
(path "build/add.ll"))))
```
Test-report manifest example:
```slo
(artifact-manifest
(schema slovo.artifact-manifest)
(version 1)
(source "examples/supported/top-level-test.slo")
(command "glagol test examples/supported/top-level-test.slo")
(mode test)
(success true)
(diagnostics-schema-version 1)
(primary-output
(kind stdout)
(stdout "1 passed\n"))
(artifacts)
(test-report
(total 1)
(passed 1)
(failed 0)
(skipped 0)))
```
Successful modes that intentionally produce no primary text may use:
```slo
(primary-output
(kind no-output))
```
Recommended v1 modes are `check`, `format`, `emit-llvm`,
`inspect-lowering`, and `test`. Recommended output and artifact kinds are
`diagnostics`, `formatted-source`, `llvm-ir`, `lowering-inspector`, `stdout`,
`stderr`, `no-output`, and `test-report`.
A failed invocation still writes a manifest when the tool mode supports
manifests. In that case `(success false)` is paired with a diagnostics artifact
or stdout/stderr output whose diagnostics use schema version `1`.
This contract does not require native executable output. LLVM IR, formatted
source, inspector output, diagnostics, stdout/stderr capture, and test reports
are sufficient v1 artifacts.
### 9.3 LLVM Source-Map And Debug-Info Direction
Slovo v1 requires compiler data to preserve diagnostic source spans through
parse, check, typed core, lowering, and LLVM IR emission. This is a tooling
requirement so diagnostics, lowering inspectors, trap checks, and artifact
manifests can point back to original source.
Stable LLVM debug metadata, DWARF emission, and source-map files are deferred.
Future promotion should map Slovo source spans to generated LLVM functions,
basic blocks, instructions, runtime intrinsic calls, and explicit trap paths.
Array bounds traps and option/result payload traps should carry the source span
of the Slovo operation that can trap.
Lowering-inspector golden fixtures are textual compiler-tree artifacts. They
show accepted source as compiler-owned tree output, such as surface and checked
forms, and are not a substitute for or a promise of stable LLVM debug metadata,
DWARF, or standalone source-map files.
### 9.4 Formatter Stability Contract
Formatter stability is a promoted v1 tooling contract. Every promoted fixture
under `examples/formatter/` defines canonical output. Formatting a promoted
fixture must produce the same source bytes again, including line comments,
indentation, blank-line placement, and a final newline. Reformatting formatter
output must be idempotent.
The v1 formatter is not a width-based pretty printer. It may normalize spacing
and indentation for supported forms, but it does not promise terminal-width
measurement, column reflow, or wrapping of long inline calls/forms. Long inline
forms stay inline unless their form has an explicit canonical multiline shape.
Line comments are supported only as full-line comments in these positions:
- before top-level forms
- inside `fn` and `test` bodies before body expressions
- after the final `fn` or `test` body expression and before the closing paren
- after the last top-level form
All other comment positions are unsupported in v1 and must be rejected with
structured diagnostics, not silently dropped or moved. In particular, v1 rejects
comments inside:
- `(module ...)` forms
- `(struct ...)` forms
- `fn` and `test` headers before their body begins
- type forms such as `(array i32 N)`, `(option i32)`, `(result i32 i32)`,
exp-2 `(vec i32)`, exp-94 `(vec i64)`, exp-103 `(vec f64)`, and exp-4
enum type names
- inline expression forms, including calls, field access, array constructors,
struct constructors, option/result constructors, observers, unwraps, match
patterns, comparisons, arithmetic, `string_len`, `std.string.len`,
`print_i32`, `print_string`, `print_bool`, `std.io.print_i32`,
`std.io.print_string`, `std.io.print_bool`, `std.io.print_f64`, exp-2
`std.vec.i32.*` calls, exp-94 `std.vec.i64.*` calls, exp-103
`std.vec.f64.*` calls, exp-99 `std.vec.string.*` calls, exp-3 host calls, exp-4 qualified enum
constructors, and exp-13
`std.string.parse_i32_result` calls, and exp-15 `std.result.*` helper calls
Nested promoted forms have these stable shapes:
- `if`, `while`, `unsafe`, and `match` use their existing multiline
indentation and do not collapse to a single line because their contents are
short
- calls, field access, arrays, struct constructors, option/result constructors,
option/result observers, option/result unwraps, `string_len`,
`std.string.len`, legacy print aliases, `std.io.print_*` calls, and exp-2
`std.vec.i32.*` calls, exp-94 `std.vec.i64.*` calls, exp-103
`std.vec.f64.*` calls, exp-99 `std.vec.string.*` calls, exp-3 host calls,
and exp-4 qualified enum
constructors, exp-13 `std.string.parse_i32_result` calls, exp-15
`std.result.*` helper calls, exp-20 `std.io.print_f64` calls, exp-21
`std.io.print_i64` calls, exp-22 `std.num.*` conversion calls, exp-23
`std.num.i64_to_i32_result` calls, exp-24 integer-to-string calls, and
exp-25 `std.string.parse_i64_result` calls, and exp-26
`std.num.f64_to_string` calls, and exp-27
`std.num.f64_to_i32_result` calls, and exp-28
`std.string.parse_f64_result` calls, and exp-31
`std.num.f64_to_i64_result` calls, and exp-34
`std.string.parse_bool_result` calls remain inline when used as expressions
Unsupported formatter positions must produce diagnostics using the v1
`slovo.diagnostic` schema. A formatter diagnostic must identify the unsupported
position with a machine-readable code, source span, line/column range, and a
message or hint that names the accepted v1 comment/layout positions.
### 9.5 Glagol Promotion Obligations
Before a promoted v1 boundary is treated as complete, Glagol must provide and
keep an explicit coverage inventory. This is a Slovo-to-Glagol contract
obligation; it does not by itself claim that the current Glagol implementation
has already completed every listed fixture.
- golden machine diagnostic fixtures using `slovo.diagnostic` version `1`
for every promoted v1 boundary and every current explicitly rejected
source-reachable v1 boundary
- a diagnostic fixture inventory that maps each explicitly rejected v1
boundary to the golden fixture and diagnostic code that prove it
- tests that assert the diagnostic schema and version markers are present
- textual lowering-inspector golden fixtures for every promoted v1 feature
family:
- add/canonical
- top-level tests
- locals
- if
- while
- struct
- struct value flow
- array
- array value flow
- option/result
- option/result flow
- option/result payload
- option/result match
- string print
- string value flow
- print bool
- standard runtime alpha
- unsafe
- formatter comments/stability, only where inspector mode applies to source
accepted by lowering
- artifact manifest examples or tests for successful compiler output,
diagnostic failure, and test-report output
- source-span preservation through the compiler data needed by diagnostics and
LLVM emission
- no source-reachable panic for supported v1 source or for explicitly
unsupported source at promoted boundaries
Future feature families must extend both inventories before promotion: accepted
source needs textual lowering-inspector golden fixtures, and every new
explicitly rejected source-reachable boundary needs golden machine-diagnostic
coverage.
### 9.6 v1.7 Tooling Extensions
v1.7 hardens developer experience tooling while preserving all v1.6 language
semantics. The promoted tooling extensions are:
- project scaffolding with `glagol new <project-dir> [--name <name>]`
- formatter check mode with `glagol fmt --check <file-or-project>`
- formatter write mode with `glagol fmt --write <file-or-project>`
- deterministic Markdown documentation generation with
`glagol doc <file-or-project> -o <dir>`
- a local release-gate script contract
Project scaffolding emits the existing v1.3 project shape: `slovo.toml` plus
flat source modules under `src`. The generated main module must be testable
using only already-promoted language forms. Scaffolding must reject non-empty
target directories without overwriting existing content.
Formatter check/write modes use the canonical formatter rules from section
9.4. Project formatting applies only to immediate `.slo` modules under the
manifest source root and uses deterministic v1.3 module ordering. Plain
`glagol fmt <file.slo>` continues to write formatted source to stdout.
Documentation generation records modules, imports/exports, structs, functions,
and tests as deterministic Markdown. It is generated documentation, not
runtime reflection, typed-core reflection, debug metadata, DWARF, source maps,
or ABI/layout information.
LSP, watch mode, daemon protocols, SARIF, debug adapters, stable debug
metadata, DWARF emission, and standalone source-map files remain deferred.
## 10. Slice 6: Unsafe, Memory, And FFI
Status: v1.6 reservation and gating contract. Raw-memory execution remains
deferred.
Slovo v1 keeps v0 lexical `unsafe` as the only accepted unsafe boundary.
Lexical `unsafe` permits otherwise supported safe forms in an unsafe block; it
does not promote raw memory, pointer, allocation, unchecked indexing, or FFI
operations.
v1.6 reserves the following compiler-known unsafe operation heads:
- `alloc`
- `dealloc`
- `load`
- `store`
- `ptr_add`
- `unchecked_index`
- `reinterpret`
- `ffi_call`
These names are recognized before ordinary user-call lookup. Safe code that
uses any reserved unsafe head must be rejected with `UnsafeRequired`.
Code inside lexical `(unsafe ...)` that uses any reserved unsafe head must be
rejected with `UnsupportedUnsafeOperation` until a future release defines that
operation's syntax, type rules, lowering, runtime behavior, diagnostics, and
tests.
User functions, imports, exports, and parameters must not shadow these
compiler-known unsafe heads. Such declarations must be rejected with a
structured duplicate/reserved-name diagnostic.
The v1.6 memory direction is staged: safe values remain the default; future
memory work is expected to define affine ownership plus explicit unsafe
regions before raw memory can execute. v1.6 makes no stable ABI, layout, FFI,
allocator, ownership, or raw-memory execution promise.
A future raw-memory or FFI contract must specify:
- pointer types
- allocation and deallocation
- load and store
- pointer arithmetic
- unchecked indexing
- reinterpretation
- FFI call shape
- ownership of allocation failures and cleanup behavior
- ownership, affine/resource, and lifetime rules
- diagnostics beyond the v1.6 `UnsafeRequired` and
`UnsupportedUnsafeOperation` gates
No stable ABI or layout promise is made in v1. Stable ABI and stable layout
promises remain deferred until a future spec explicitly promotes them.
## 11. Deferred Until Future Beta Unless Promoted Explicitly
- broad conformance suite, stable beta compatibility policy, semantic
versioning, and deprecation policy
- struct field mutation and whole-struct value mutation
- option/result mapping, equality, printing, payload families beyond the
current exp-10 `(result string i32)` slice and the exp-36/exp-75/exp-95/
exp-100/exp-102/exp-109 concrete `(option i32)` / `(option i64)` /
`(option f64)` / `(option bool)` / `(option string)` source helper slices,
nested
option/result values, arrays or structs containing option/results, generic
payloads, enum payloads beyond exp-16 unary `i32` variants, exp-116 unary
direct scalar/string variants, and exp-121 unary current known
non-recursive struct variants, enum import behavior beyond exp-17 explicit
local export/import lists, enum values in containers or nested structs
beyond exp-18 direct fields, general payload ADTs, and user-catchable
exceptions
- unit printing and user-declared or stored `unit` values
- broader standard-runtime printing beyond v1.5 `std.io.print_i32`,
`std.io.print_string`, and `std.io.print_bool`
- `std.io.print_unit`, host IO beyond the exp-3 slice, exp-10 `*_result`
slice, and exp-12 stdin-result slice, networking, async IO, binary file
APIs, directory traversal, terminal control, platform abstraction, general
host error ADTs, stdin APIs beyond exp-12, parsing APIs beyond exp-13
`std.string.parse_i32_result`, exp-25 `std.string.parse_i64_result`, exp-28
`std.string.parse_f64_result`, and exp-34 exact lowercase
`std.string.parse_bool_result`,
result helper payload families beyond the explicitly listed
`(result i32 i32)`, `(result i64 i32)`, `(result string i32)`, exp-28
returned `(result f64 i32)`, and exp-34 returned `(result bool i32)`
families, generic option helpers beyond exp-36/exp-75/exp-95/exp-100/
exp-102/exp-109
concrete option source helpers,
randomness beyond the exp-11 target, time beyond
the exp-8 host time/sleep target, vectors/collections beyond the exp-2
`(vec i32)`, exp-94 `(vec i64)`, exp-99 `(vec string)`, and exp-103
`(vec f64)` targets,
user-defined standard modules, overloading, and generic standard-library APIs
- numeric primitives and conversions beyond exp-20 direct `f64`, exp-21
direct `i64`, exp-22 explicit `std.num.i32_to_i64`,
`std.num.i32_to_f64`, and `std.num.i64_to_f64` calls, exp-23
`std.num.i64_to_i32_result`, exp-24 `std.num.i32_to_string` and
`std.num.i64_to_string`, exp-25 `std.string.parse_i64_result`, exp-27
`std.num.f64_to_i32_result`, exp-28 `std.string.parse_f64_result`, exp-31
`std.num.f64_to_i64_result`, and
existing `i32`/`bool`, including `f32`,
unsigned integers, narrower integer widths, `char`, `bytes`, `decimal`,
numeric casts or conversions beyond exp-22 explicit widening calls, the
exp-23 checked `i64 -> i32` result call, the exp-27 checked
`f64 -> i32` result call, and the exp-31 checked `f64 -> i64` result call,
implicit promotion, mixed `i32`/`i64`/`f64`
arithmetic, generic numeric operators, numeric container families beyond the
current fixed direct-scalar arrays, current concrete vec families, current
concrete option/result families, and current direct numeric enum payloads,
numeric struct fields beyond exp-29 direct `i64` and finite `f64` fields,
random floats or random
`i64`, f64 formatting beyond exp-26 finite decimal text,
locale/base/radix/grouping/padding formatting controls, generic
format/display traits, and stable numeric formatting or ABI/layout promises
- standard math source helpers beyond the exp-39 `std/math.slo` helper slice
and exp-44 explicit `std.math` import path, including trigonometry, `sqrt`,
`pow`, exponentials, logarithms, rounding APIs, generic math, overloads,
traits, automatic std imports, workspace dependency syntax for std,
package std dependency declarations, and mixed numeric helper families
- standard result source helpers beyond the released exp-33, exp-35,
exp-74, and exp-109 `std/result.slo` concrete helper slices, exp-45
explicit `std.result` project import path, and exp-46 workspace
source-search model, including generic `std.result.map`, generic
`std.result.unwrap_or`, `std.result.and_then`, broader
result/option bridge or transpose/flatten helpers, generic result helpers,
and new result payload families
- standard option source helpers beyond the released exp-36/exp-75/exp-95/
exp-100/exp-102/exp-109 `std/option.slo` concrete helper slices, exp-45
explicit `std.option` project import path, and exp-46 workspace
source-search model, including generic option helpers,
option mapping/chaining, broader option/result bridge helpers, and option
payload families beyond `i32`, `i64`, `f64`, `bool`, and `string`
- standard time source helpers beyond the released exp-37 `std/time.slo`
facade wrappers, including wall-clock/calendar/timezone APIs,
high-resolution timers, async timers, cancellation, and scheduling
guarantees
- generic vectors, vector element types other than `i32`, vector mutation,
vector literals beyond empty/append construction, `push`, nested vectors,
vectors in arrays/structs/options/results, iterators, slices, maps, sets,
user-visible vector deallocation, and stable vector ABI/layout/helper symbols
- string concatenation beyond exp-1 `std.string.concat`, parsing beyond
exp-13 `std.string.parse_i32_result`, exp-25
`std.string.parse_i64_result`, and exp-28
`std.string.parse_f64_result`, plus exp-34 exact lowercase
`std.string.parse_bool_result`, indexing, slicing, string containers beyond
the current direct struct fields, current fixed string arrays, current
direct fixed-array struct fields, and current concrete option/result
families, user-visible string allocation or deallocation, Unicode length or
digit semantics, and stable string ABI/layout
- pointer types, allocation, deallocation, load, store, pointer arithmetic,
reinterpretation, unchecked indexing, raw memory operations, and FFI
- stable ABI and stable layout promises
- macros
- generics
- package management
- ownership and affine resources
- concurrency
- direct machine-code backend
- stable cross-language ABI