registry

package
v1.18.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 10, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

Documentation

Overview

Package registry provides a plugin architecture for registering Scheme primitives.

The registry allows extensions to register primitives that are applied to environments at initialization time. Primitives can be registered for different phases: runtime, expand-time, and compile-time.

Key Types

  • Registry: central store for primitive registrations
  • PrimitiveSpec: defines a single primitive (name, params, implementation)
  • [Phase]: bit flags controlling environment placement (Runtime, Expand, Compile)
  • Extension: interface for modular primitive packages

Registration

reg := registry.NewRegistry()
reg.AddPrimitives([]registry.PrimitiveSpec{
    {Name: "my-func", ParamCount: 1, Impl: myFuncImpl},
}, registry.PhaseSetRuntime|registry.PhaseSetExpand)

Application

After registration, apply the registry to an environment:

err := reg.Apply(ctx, env)

Extensions

Extensions implement the Extension interface and can be composed:

var Extension = registry.NewExtension("myext", AddToRegistry)

The RegistryBuilder type provides a convenient way to compose multiple registration functions into a single extension.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BuildValidator

func BuildValidator(spec PrimitiveSpec) machine.ForeignFunction

BuildValidator creates a contract validation function from a PrimitiveSpec's ParamTypes. Returns nil if the spec has no type contracts (zero-overhead path for uncontracted primitives).

The returned function is installed on ForeignClosure.validate and runs after argument binding but before the implementation. Each argument is checked against its declared TypeConstraint via TypeConstraint.Check; a mismatch is wrapped with "<primitive>: argument <n>" context so the caller can locate the offending position.

For non-variadic primitives, each position 0..ParamCount-1 is checked against ParamTypes[i].

For variadic primitives, positions 0..ParamCount-2 are fixed args and are checked directly via mc.Arg(i). Position ParamCount-1 holds the rest list (a values.Tuple); each rest element is checked against the last entry in ParamTypes. When len(ParamTypes) is shorter than ParamCount (permitted by validateParamTypes), any fixed position i beyond len(ParamTypes)-1 reuses types[len(ParamTypes)-1] — the last declared constraint acts as the catch-all for unspecified fixed slots and for rest-list elements.

Types

type ApplyOption

type ApplyOption func(*applyConfig)

ApplyOption configures the behavior of Registry.Apply. Options are applied in order; later options override earlier ones.

func WithContractEnforcement

func WithContractEnforcement() ApplyOption

WithContractEnforcement installs a type-checking validator on each registered primitive whose spec declares ParamTypes. The validator runs after argument binding and before the implementation, rejecting mismatched types with a wrapped error. Disabled by default — validators cost nothing when not installed (ForeignClosure.validate stays nil).

func WithRuntimeTarget

func WithRuntimeTarget(frame *environment.EnvironmentFrame) ApplyOption

WithRuntimeTarget routes PhaseRuntime primitive registration and global values into the given frame instead of env. Used by bootstrap to seat primitives in the immutable sealed base while expand-phase prims stay in env.Expand() and compile-time bindings stay in env.Compile(). Defaults to env (backward compatible — a flat library env passes its own frame, the engine root passes its sealed base).

func WithStableBasePrimitives

func WithStableBasePrimitives() ApplyOption

WithStableBasePrimitives stamps every capture-safe primitive (!spec.InvokesProcedure: +, -, car, cons, assq, vector-ref, sqrt, …) Stable when it is bound ambiently, so the frame-reclaim classifier may trust calls to it as non-rebindable without an explicit (import (scheme base)). Imported primitives are already immutable; this closes the ambient-registration path, where Registry.Apply binds primitives directly into the base namespace without an Imported flag (Phase 2 finding #1).

Scope is the capture-safe set, which must match CaptureSafe (stamped above from the same !spec.InvokesProcedure): the classifier trusts a primitive callee only when CaptureSafe AND Stable both hold, so a capture-safe primitive left un-stamped here would be CaptureSafe yet never trusted. Procedure-invoking primitives (apply, map, sort, eval, with-exception-handler, …) are InvokesProcedure:true, so they are neither CaptureSafe nor stamped Stable and stay R7RS-mutable even under the flag.

Disabled by default. The engine appends it only under WithImmutableTopLevel(), where the set!/redefine enforcement (compile_validated.go) makes Stable a guarantee the classifier may rest a verdict on. The deviation it introduces — capture-safe primitives become non-rebindable — is exactly the opt-in optimization contract.

type BindingSpec

type BindingSpec struct {
	Name    string
	Doc     string
	DocOnly bool
}

BindingSpec defines a compile-time binding with optional documentation.

DocOnly entries carry doc text but do not install an environment binding — Apply skips them. They are appended via AddDocumentation or AddDocOnlyPrimitive and are the post-Phase-1 unification of what used to be a separate `docs []DocEntry` slice (collapsed per Finding 2 of plans/2026-05-18-registry-structural-reduction.md).

type Closeable

type Closeable interface {
	Close() error
}

Closeable is an opt-in interface for extensions that hold resources (goroutines, file handles, connections) and need cleanup when the engine is shut down. Extensions that implement this interface will have Close called by Engine.Close().

type Describer

type Describer interface {
	Description() string
}

Describer is an optional interface that extensions can implement to provide a human-readable library description. The description is shown by ,doc (wile <ext>) and ,libraries in the REPL.

type DocSearchResult

type DocSearchResult struct {
	Name     string
	Doc      string
	Category string
	Keywords []string
}

DocSearchResult holds one search hit from SearchDoc.

func NonPrimitiveDocs

func NonPrimitiveDocs(reg *Registry) []DocSearchResult

NonPrimitiveDocs returns doc search results from binding specs (including DocOnly entries registered via AddDocumentation / AddDocOnlyPrimitive). Each entry's Doc, Category, and Keywords are extracted via docparse.ParseDocstring.

Post-Phase-1: single walk. Pre-Phase-1 this walked BindingSpecs + Docs as two separate sources; they were unified into bindingSpecs (with DocOnly distinguishing them).

func SearchDoc

SearchDoc searches all documentation sources for case-insensitive substring matches on name, doc text, category, or keywords.

Sources searched in order:

  1. Registry primitives — real primitives AND doc-only primitives (the latter carry full PrimitiveSpec metadata; both take precedence over non-primitive sources below).
  2. Registry binding specs — includes real bindings AND simple DocOnly entries registered via AddDocumentation (post-Phase-1 unification).
  3. Environment bindings (if env is non-nil)
  4. Loaded libraries (if libs is non-nil)
  5. Unloaded library exports (if exports is non-nil)

Primitives take precedence over non-primitives with the same name. Results are sorted by name. env, libs, and exports may be nil.

type Extension

type Extension interface {
	// Name returns the extension name for logging/debugging.
	Name() string
	// AddToRegistry registers primitives with the registry.
	AddToRegistry(r *Registry) error
}

Extension represents a loadable extension that adds primitives to a registry.

func NewDescribedExtension

func NewDescribedExtension(name, description string, fn func(*Registry) error) Extension

NewDescribedExtension creates an Extension with a name, human-readable description, and registration function. It is the canonical constructor for simple extensions and is used by every shipped extension. It is shorthand for NewExtension(name, fn, WithDescription(description)); reach for the option form directly only when composing additional options.

func NewExtension

func NewExtension(name string, fn func(*Registry) error, opts ...ExtensionOption) Extension

NewExtension creates an Extension from a name, a registration function, and zero or more capability options.

type ExtensionFunc

type ExtensionFunc struct {
	// contains filtered or unexported fields
}

ExtensionFunc adapts a function to the Extension interface and carries the three optional capabilities as slots. The slots are populated via the ExtensionOption functions passed to NewExtension.

*ExtensionFunc unconditionally satisfies LibraryNamer, Describer, and Closeable. Unset slots are reported as the zero value (empty string, nil slice, nil error). Engine code interprets emptiness uniformly as "not set" and falls back to defaults — there is no behavioral distinction between "did not opt in" and "opted in with the zero value."

func (*ExtensionFunc) AddToRegistry

func (p *ExtensionFunc) AddToRegistry(r *Registry) error

AddToRegistry registers primitives with the registry.

func (*ExtensionFunc) Close

func (p *ExtensionFunc) Close() error

Close runs the configured close hook, or returns nil if no hook was set.

func (*ExtensionFunc) Description

func (p *ExtensionFunc) Description() string

Description returns the extension's description, or "" if unset.

func (*ExtensionFunc) LibraryName

func (p *ExtensionFunc) LibraryName() []string

LibraryName returns the configured R7RS library name parts, or nil if unset. A nil/empty return signals "use the default (wile <name>)" to the engine.

func (*ExtensionFunc) Name

func (p *ExtensionFunc) Name() string

Name returns the extension name.

type ExtensionOption

type ExtensionOption func(*ExtensionFunc)

ExtensionOption configures an ExtensionFunc at construction time.

func WithClose

func WithClose(fn func() error) ExtensionOption

WithClose attaches a cleanup hook called by Engine.Close().

func WithDescription

func WithDescription(s string) ExtensionOption

WithDescription attaches a human-readable description, surfaced by ,doc (wile <ext>) and ,libraries in the REPL.

func WithLibraryName

func WithLibraryName(parts ...string) ExtensionOption

WithLibraryName overrides the default R7RS library name. The default, applied when this option is not used, is (wile <ext.Name()>).

type GlobalValue

type GlobalValue struct {
	Name  string
	Value values.Value
}

GlobalValue pairs a name with a value to be registered as a global binding.

type InitFunc

type InitFunc func() error

InitFunc is called after all primitives and global values are registered.

type LibraryDoc

type LibraryDoc struct {
	Name        string // canonical Scheme form, e.g. "(wile math)"
	Description string
}

LibraryDoc is a read-only view of a loaded library, sufficient for documentation search.

type LibraryExportDoc

type LibraryExportDoc struct {
	Name        string // canonical Scheme form, e.g. "(srfi 1)"
	Description string
	Exports     []string
}

LibraryExportDoc is a read-only view of an indexed (possibly unloaded) library and the names it exports.

type LibraryExportSearcher

type LibraryExportSearcher interface {
	AllLibraryExports() []LibraryExportDoc
}

LibraryExportSearcher enumerates indexed library exports for SearchDoc.

type LibraryNamer

type LibraryNamer interface {
	LibraryName() []string
}

LibraryNamer is an optional interface that extensions can implement to control their R7RS library name. Extensions that don't implement this get the default name (wile <ext.Name()>).

type LibrarySearcher

type LibrarySearcher interface {
	AllLibraries() []LibraryDoc
}

LibrarySearcher enumerates loaded libraries for SearchDoc. Defining the dependency as a narrow interface keeps the registry package free of any import of machine/compilation — the concrete adapter lives in the caller's package (see registry/core). Per the Interface Segregation Principle, SearchDoc depends only on the enumeration it uses, not on the full library-registry surface.

type NamespaceInit

type NamespaceInit func(env *environment.EnvironmentFrame) error

NamespaceInit is a per-engine initializer run by Apply once per engine, with that engine's runtime environment frame. Extensions use it to build per-Namespace state (e.g. I/O port parameters + caches) that must not be shared across engines.

type PhaseSet

type PhaseSet uint8

PhaseSet is a bitset over non-negative environment.Phase values, used to declare which phases a primitive is registered for. The companion type environment.Phase is a typed enum identifying a single phase; PhaseSet is the registration vocabulary that says "this primitive is available at runtime", "at runtime and expand", etc.

Representable phases are 0 ≤ phase < phaseSetBits. environment.PhaseTemplate (-1) and any phase ≥ phaseSetBits are unrepresentable. With(unrepresentable) panics; Has(unrepresentable) returns false. Both ends of the illegal-value space are checked — silent shift overflow on a uint8 bitset would otherwise hide the upper bound.

PhaseSet is intended as a registration-time API: Add* helpers and the extension authoring path build PhaseSet values from compile-time constants. If a runtime caller appears (constructing a PhaseSet from a Scheme integer, for example), introduce an error-returning sibling such as TryWith rather than relying on the panic semantics here.

ADDING A NEW PHASE requires updates in these locations:

  1. environment/phase_registry.go — add a Phase constant; ensure 0 ≤ value < phaseSetBits below if the new phase should be representable in a PhaseSet.
  2. registry/phase.go (this file) — add PhaseSet<Name> bit constant and extend phaseSetBits if the bitset width must grow.
  3. registry/apply.go — extend phaseTargets with the new phase if primitives may register at it.
  4. wile/options.go — add re-export so embedders can name the constant.

The init() assertion below verifies bit positions match Phase indices, catching drift from steps (1)+(2).

const (
	PhaseSetRuntime PhaseSet = 1 << iota // matches environment.PhaseRuntime (=0)
	PhaseSetExpand                       // matches environment.PhaseExpand  (=1)
	PhaseSetCompile                      // matches environment.PhaseCompile (=2)
)

PhaseSet bit constants. Each bit position equals 1 << int(environment.Phase). init() asserts the values stay in sync with environment.Phase.

func (PhaseSet) Has

func (s PhaseSet) Has(p environment.Phase) bool

Has reports whether p is in the set. Returns false for any phase that cannot appear in a PhaseSet — negative phases (e.g., PhaseTemplate) and phases ≥ phaseSetBits.

func (PhaseSet) String

func (s PhaseSet) String() string

String returns a pipe-separated list of phase names in the set, or "none" if the set is empty.

func (PhaseSet) With

func (s PhaseSet) With(p environment.Phase) PhaseSet

With returns a new PhaseSet with p added. Panics if p is unrepresentable (negative, e.g. PhaseTemplate, or ≥ phaseSetBits — would silently shift past the bitset width). PhaseSet is a registration-time API; programmer errors at this layer should fail loudly. If a runtime caller is added, introduce a non-panicking sibling rather than weakening this contract.

type PrimitiveRegistration

type PrimitiveRegistration struct {
	Spec   PrimitiveSpec
	Phases PhaseSet
}

PrimitiveRegistration holds a primitive and its phases.

type PrimitiveSpec

type PrimitiveSpec struct {
	Name       string
	ParamCount int
	IsVariadic bool
	Impl       machine.ForeignFunction
	Doc        string   // optional: brief description
	ParamNames []string // optional: parameter names
	Category   string   // optional: grouping category
	// ParamTypes is an optional type contract per parameter. When IsVariadic
	// is true, the last slot annotates the per-element type of the rest list
	// (the Tuple at mc.Arg(ParamCount-1)), not the type of the rest list
	// itself. So `+` declares ParamCount:1, IsVariadic:true, ParamTypes:[TypeNumber],
	// meaning "every element of the variadic tail must be a Number."
	ParamTypes []values.TypeConstraint
	ReturnType values.TypeConstraint // optional: return type (nil = unspecified)
	Keywords   []string              // optional: searchable tags
	// InvokesProcedure marks a primitive that may call back into a Scheme
	// procedure (apply, map, sort, for-each, call/cc, dynamic-wind, …) and could
	// thereby transitively capture a continuation. Default false = "does not invoke
	// a Scheme procedure" = capture-safe: the frame-reclaim classifier may trust a
	// tail call to it as non-capturing. The flipped default is a SOUNDNESS
	// COMMITMENT — an unannotated procedure-invoking primitive would be wrongly
	// trusted.
	//
	// REQUIRED for any primitive whose Impl reaches ApplyCallable or runs a
	// sub-context (sub.Run()): set InvokesProcedure:true. Two guards in pkg/wile
	// enforce this — TestInvokesProcedureStaticGuard discovers the requirement
	// statically (AST of the Impl's call graph) and fails CI when the annotation is
	// missing; TestInvokesProcedureCompleteness pins the curated set behaviorally.
	//
	// It flows to BindingMeta.CaptureSafe at registration; the classifier reads the
	// binding flag because pkg/internal/validate must not import pkg/registry.
	InvokesProcedure bool
}

PrimitiveSpec defines a primitive to be registered.

type Registry

type Registry struct {
	// contains filtered or unexported fields
}

Registry is the central registry for primitives.

ADDING A NEW REGISTRY CATEGORY requires updates in these locations:

  1. Registry struct (this file) — add the slice field
  2. NewRegistry (this file) — initialize the slice with a reasonable capacity
  3. Registry.deepCopy (this file) — extend the make + copy block to include the new slice
  4. Add<Category> / Add<Category>s — registration entry points (mutex-locked appender + optional singular forwarder)
  5. <Category>Count / <Category>s — accessor pair returning a count and a defensive copy
  6. Registry.Apply (registry/apply.go) — materialize the new category into the environment at the appropriate lifecycle step

All eight categories today (primitives, bindingSpecs, docPrimitives, initFuncs, macroSources, procedureSources, globalValues, namespaceInits) follow this pattern. Forgetting any step is a silent aliasing or drift hazard — Clone, Without, WithoutCategory, and WithoutBindings all assume deepCopy covers every field.

Note: the `docs []DocEntry` slice was removed in Phase 1 (plans/2026-05-18-registry-structural-reduction.md, Finding 2): simple AddDocumentation entries now share bindingSpecs (DocOnly=true); rich AddDocOnlyPrimitive entries moved to the dedicated docPrimitives slice (preserves full PrimitiveSpec metadata).

func NewRegistry

func NewRegistry() *Registry

NewRegistry creates a new empty registry.

func (*Registry) AddBinding

func (p *Registry) AddBinding(name string)

AddBinding registers a compile-time only binding (no runtime value). Singular forwarder to AddBindings.

func (*Registry) AddBindingSpecs

func (p *Registry) AddBindingSpecs(specs []BindingSpec)

AddBindingSpecs registers multiple compile-time bindings with optional documentation.

func (*Registry) AddBindings

func (p *Registry) AddBindings(names []string)

AddBindings registers multiple compile-time only bindings. Forwarder to AddBindingSpecs; the spec-typed form is the single source of truth for mutex lifecycle.

func (*Registry) AddDocOnlyPrimitive

func (p *Registry) AddDocOnlyPrimitive(spec PrimitiveSpec)

AddDocOnlyPrimitive registers a documentation-only primitive entry. It does not create a runtime binding — used for Scheme-defined procedures that are already bound in the environment but need registry visibility for apropos/topics. Skips registration if a primitive with the same name already exists (Go primitives take precedence).

Post-Phase-1: the entry lands in the dedicated docPrimitives slice (separate tier from real primitives). The full PrimitiveSpec metadata — Category, ParamNames, ParamTypes, ReturnType, Keywords — is preserved. Surfaced by SearchDoc / ,doc / ,apropos / PrimitivesByCategory; not visible via Primitives() or FindPrimitive (those return real primitives only).

func (*Registry) AddDocumentation

func (p *Registry) AddDocumentation(name, doc string)

AddDocumentation registers a documentation entry for a named binding. The documentation is applied to existing bindings during ApplyDocs. Forwarder to AddBindingSpecs with DocOnly=true — the doc-only entry lives in the bindingSpecs slice but Apply skips installing a binding for it.

func (*Registry) AddGlobalValue

func (p *Registry) AddGlobalValue(name string, value values.Value)

AddGlobalValue registers a named value to be bound as a global variable. Unlike AddPrimitive, this takes an arbitrary Value rather than a ForeignFunction.

func (*Registry) AddInitFunc

func (p *Registry) AddInitFunc(f InitFunc)

AddInitFunc registers an initialization function.

func (*Registry) AddMacroSource

func (p *Registry) AddMacroSource(source string)

AddMacroSource adds Scheme source code for bootstrap macros.

func (*Registry) AddNamespaceInit

func (p *Registry) AddNamespaceInit(fn NamespaceInit)

AddNamespaceInit registers a per-engine initializer run by Apply once per engine, with that engine's runtime environment frame. Extensions use it to build per-Namespace state (e.g. I/O port parameters + caches) that must not be shared across engines.

func (*Registry) AddPrimitive

func (p *Registry) AddPrimitive(spec PrimitiveSpec, phases PhaseSet)

AddPrimitive registers a primitive with the given phases. Singular forwarder to AddPrimitives; the plural form is the single source of truth for validation + mutex lifecycle.

func (*Registry) AddPrimitives

func (p *Registry) AddPrimitives(specs []PrimitiveSpec, phases PhaseSet)

AddPrimitives registers multiple primitives with the given phases.

func (*Registry) AddProcedureSource

func (p *Registry) AddProcedureSource(source string)

AddProcedureSource registers a runtime-procedure source (define forms) to be loaded into the sealed-base frame, separate from macro sources (define-syntax forms) which load into the mutable expand frame.

func (*Registry) Apply

func (p *Registry) Apply(ctx context.Context, env *environment.EnvironmentFrame, opts ...ApplyOption) error

Apply materializes registry contents into an environment: compile-time bindings, runtime/expand-time primitives, global values, and init functions (in that order).

func (*Registry) ApplyDocs

func (p *Registry) ApplyDocs(env *environment.EnvironmentFrame)

ApplyDocs attaches documentation entries to existing bindings in the environment. It searches all phases for each documented name and sets the doc string on every matching binding. This is necessary because some names (e.g., special forms) have bindings in multiple phases (expand and compile), and the REPL's ,doc command may find any of them.

Post-Phase-1: single walk over bindingSpecs (both real bindings with non-empty Doc and DocOnly entries land here). The earlier two-source merge — `docs` slice + bindingSpecs casted via DocEntry(spec) — collapsed when DocEntry was unified into BindingSpec.

func (*Registry) BindingCount

func (p *Registry) BindingCount() int

BindingCount returns the number of compile-time bindings.

func (*Registry) BindingSpecs

func (p *Registry) BindingSpecs() []BindingSpec

BindingSpecs returns a defensive copy of the compile-time binding specs.

func (*Registry) Bindings

func (p *Registry) Bindings() []string

Bindings returns the names of real compile-time bindings (DocOnly=false). DocOnly entries are excluded — use Docs() for those. BindingSpecs() returns the unfiltered slice if both are needed.

func (*Registry) Clone

func (p *Registry) Clone() *Registry

Clone creates a copy of the registry.

func (*Registry) DocPrimitives

func (p *Registry) DocPrimitives() []PrimitiveSpec

DocPrimitives returns a defensive copy of the doc-only primitives (entries registered via AddDocOnlyPrimitive). These carry the full PrimitiveSpec metadata (Category, ParamNames, ParamTypes, ReturnType, Keywords) but no Impl and no environment binding — used to surface Scheme-defined procedures via ,doc / ,apropos / SearchDoc.

func (*Registry) Docs

func (p *Registry) Docs() []BindingSpec

Docs returns a defensive copy of the doc-only binding specs (those with DocOnly=true). These are simple Name+Doc entries registered via AddDocumentation — they carry doc text but install no environment binding. Real bindings (DocOnly=false) are returned by BindingSpecs.

Doc-only *primitives* with full metadata (registered via AddDocOnlyPrimitive) live in DocPrimitives, not here.

func (*Registry) FindPrimitive

func (p *Registry) FindPrimitive(name string, phase PhaseSet) (PrimitiveRegistration, bool)

FindPrimitive returns the first registered primitive with the given name. If phase is the empty PhaseSet (zero), any phase matches; otherwise only primitives whose Phases overlap with phase are considered.

When phase is zero, doc-only primitives (registered via AddDocOnlyPrimitive, stored in docPrimitives with Phases=0) are returned as a fallback after the real-primitives search. When phase is non-zero, doc-only primitives are never returned — they have Phases=0 which cannot overlap.

func (*Registry) GlobalValues

func (p *Registry) GlobalValues() []GlobalValue

GlobalValues returns a copy of the global value registrations.

func (*Registry) HasPrimitive

func (p *Registry) HasPrimitive(name string, phase PhaseSet) bool

HasPrimitive reports whether a primitive with the given name is registered. If phase is the empty PhaseSet (zero), any phase matches; otherwise only primitives whose Phases overlap with phase are considered.

func (*Registry) InitFuncs

func (p *Registry) InitFuncs() []InitFunc

InitFuncs returns a copy of the initialization functions.

func (*Registry) MacroSources

func (p *Registry) MacroSources() []string

MacroSources returns copies of macro source strings.

func (*Registry) NamespaceInits

func (p *Registry) NamespaceInits() []NamespaceInit

NamespaceInits returns a defensive copy of the registered per-engine namespace initializers.

func (*Registry) PrimitiveByName

func (p *Registry) PrimitiveByName(name string) (PrimitiveRegistration, bool)

PrimitiveByName returns the registration for the named primitive, if any. Real primitives take precedence; doc-only primitives (Phases=0) are returned as a fallback when no real primitive with that name exists.

func (*Registry) PrimitiveCount

func (p *Registry) PrimitiveCount() int

PrimitiveCount returns the number of registered primitives.

func (*Registry) PrimitiveNames

func (p *Registry) PrimitiveNames() []string

PrimitiveNames returns the names of all registered primitives in registration order.

func (*Registry) Primitives

func (p *Registry) Primitives() []PrimitiveRegistration

Primitives returns a copy of the primitive registrations.

func (*Registry) PrimitivesByCategory

func (p *Registry) PrimitivesByCategory() map[string][]PrimitiveRegistration

PrimitivesByCategory returns registered primitives grouped by category. Primitives with no category are grouped under the empty string key. Includes both real primitives and doc-only primitives (the latter surface under their declared Category for ,doc / ,topics presentation). Doc-only entries appear with Phases=0 in the result.

func (*Registry) ProcedureSources

func (p *Registry) ProcedureSources() []string

ProcedureSources returns copies of procedure source strings.

func (*Registry) RuntimePrimitiveNamesRange

func (p *Registry) RuntimePrimitiveNamesRange(startIndex, endIndex int) []string

RuntimePrimitiveNamesRange returns the names of runtime primitives registered in the index range [startIndex, endIndex). If endIndex is negative, all primitives from startIndex onward are included. Negative startIndex is treated as 0.

func (*Registry) RuntimePrimitiveNamesSince

func (p *Registry) RuntimePrimitiveNamesSince(startIndex int) []string

RuntimePrimitiveNamesSince returns the names of primitives registered at index >= startIndex that have PhaseSetRuntime. If startIndex is negative it is treated as 0. If startIndex exceeds the primitive count, nil is returned.

func (*Registry) WithProcedureSources

func (p *Registry) WithProcedureSources(sources []string) *Registry

WithProcedureSources returns a new Registry whose bootstrap procedure sources are replaced by the given slice; all other fields are copied unchanged via deepCopy. Used by a dialect to substitute a bootstrap fragment (e.g. swap the mutating vector-map/string-map for a mutation-free one) without mutating the shared registry. The receiver is never modified.

func (*Registry) Without

func (p *Registry) Without(names ...string) *Registry

Without returns a new Registry with the named primitives removed. Names that don't match any registered primitive are silently ignored. All non-primitive fields are copied unchanged via deepCopy.

func (*Registry) WithoutBindings

func (p *Registry) WithoutBindings(names ...string) *Registry

WithoutBindings returns a new Registry with the named compile-time bindings removed. Use after Without to fully erase a name that exists as both a primitive and a compile-time binding (e.g., set!). All other fields are copied unchanged via deepCopy.

Post-Phase-1: only real bindings (DocOnly=false) are removed. DocOnly entries with the same name are preserved — they carry documentation for names that may live elsewhere (Scheme-defined procedures, library exports). Removing them would silently strip docs that the embedder likely wants kept.

func (*Registry) WithoutCategory

func (p *Registry) WithoutCategory(categories ...string) *Registry

WithoutCategory returns a new Registry with all primitives in the named categories removed. Categories are matched against PrimitiveSpec.Category. All non-primitive fields are copied unchanged via deepCopy.

type RegistryBuilder

type RegistryBuilder []func(*Registry) error

RegistryBuilder collects functions that add primitives to a registry.

func NewRegistryBuilder

func NewRegistryBuilder(funcs ...func(*Registry) error) RegistryBuilder

NewRegistryBuilder creates a builder with the given registration functions.

func (RegistryBuilder) AddToRegistry

func (p RegistryBuilder) AddToRegistry(r *Registry) error

AddToRegistry applies all registration functions to the registry.

func (RegistryBuilder) Build

func (p RegistryBuilder) Build() (*Registry, error)

Build creates a new registry and applies all registration functions.

func (*RegistryBuilder) Register

func (p *RegistryBuilder) Register(funcs ...func(*Registry) error)

Register adds registration functions to the builder.

Directories

Path Synopsis
Package core provides the essential primitives required for Scheme to function.
Package core provides the essential primitives required for Scheme to function.
Package helpers provides shared utility functions for primitive implementations.
Package helpers provides shared utility functions for primitive implementations.
Package testhelpers provides shared test infrastructure for Scheme primitive tests.
Package testhelpers provides shared test infrastructure for Scheme primitive tests.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL