Documentation
¶
Index ¶
- Constants
- Variables
- func AllFeatures() []string
- func CompileSyntaxRules(ctx context.Context, env *environment.EnvironmentFrame, ...) (*machine.MachineClosure, error)
- func CopyLibraryBindingsToEnv(lib *CompiledLibrary, bindings map[string]string, ...) error
- func CopyLibraryBindingsToEnvAtPhase(lib *CompiledLibrary, bindings map[string]string, ...) error
- func ExpandAndCompile(ctx context.Context, env *environment.EnvironmentFrame, stx syntax.SyntaxValue, ...) (*machine.NativeTemplate, error)
- func ImportSpecInto(ctx context.Context, specVal values.Value, ...) error
- func IsFeatureSupported(feature string) bool
- func LoadBootstrapSources(ctx context.Context, env *environment.EnvironmentFrame, sources []string, ...) error
- func LookupPhaseBinding[T any](phaseEnv *environment.EnvironmentFrame, sym *values.Symbol, ...) T
- func NewERCompareClosure(useEnv *environment.EnvironmentFrame) *machine.ForeignClosure
- func NewERRenameClosure(defExpandEnv *environment.EnvironmentFrame, introScope *syntax.Scope) *machine.ForeignClosure
- func RegisterAllPhaseHandlers(env *environment.EnvironmentFrame) error
- func RegisterPhaseBindings[F any](env *environment.EnvironmentFrame, ...) error
- func RegisterPrimitiveExpanders(env *environment.EnvironmentFrame) error
- func RegisterSyntaxCompilers(env *environment.EnvironmentFrame) error
- func ResolveAndInstallImportSet(ctx context.Context, datum values.Value, env *environment.EnvironmentFrame, ...) error
- func ResolveLibraryFile(ctx context.Context, res FileResolver, name LibraryName) (fs.File, string, error)
- func VerifyAllPhaseHandlers() error
- func VerifyCompilers() error
- func VerifyExpanders() error
- type ChainFileResolver
- type ClausesWrapper
- type CompileTimeCallContext
- type CompileTimeContinuation
- func (p *CompileTimeContinuation) AppendOperations(ops ...machine.Operation)
- func (p *CompileTimeContinuation) CompileBeginForSyntax(ctctx CompileTimeCallContext, expr syntax.SyntaxValue) error
- func (p *CompileTimeContinuation) CompileCondExpand(ctctx CompileTimeCallContext, expr syntax.SyntaxValue) error
- func (p *CompileTimeContinuation) CompileDefineForSyntax(ctctx CompileTimeCallContext, expr syntax.SyntaxValue) error
- func (p *CompileTimeContinuation) CompileDefineLibrary(ctctx CompileTimeCallContext, expr syntax.SyntaxValue) error
- func (p *CompileTimeContinuation) CompileDefineSyntax(ctctx CompileTimeCallContext, expr syntax.SyntaxValue) error
- func (p *CompileTimeContinuation) CompileEvalWhen(ctctx CompileTimeCallContext, expr syntax.SyntaxValue) error
- func (p *CompileTimeContinuation) CompileExport(_ CompileTimeCallContext, _ syntax.SyntaxValue) error
- func (p *CompileTimeContinuation) CompileExpression(ctctx CompileTimeCallContext, expr syntax.SyntaxValue) error
- func (p *CompileTimeContinuation) CompileImport(ctctx CompileTimeCallContext, expr syntax.SyntaxValue) error
- func (p *CompileTimeContinuation) CompileInclude(ctctx CompileTimeCallContext, expr syntax.SyntaxValue) error
- func (p *CompileTimeContinuation) CompileIncludeCi(_ CompileTimeCallContext, _ syntax.SyntaxValue) error
- func (p *CompileTimeContinuation) CompileMeta(ctctx CompileTimeCallContext, expr syntax.SyntaxValue) error
- func (p *CompileTimeContinuation) CompileQuasisyntax(ctctx CompileTimeCallContext, expr syntax.SyntaxValue) error
- func (p *CompileTimeContinuation) CompileSelfEvaluating(_ CompileTimeCallContext, expr syntax.SyntaxValue) error
- func (p *CompileTimeContinuation) CompileSymbol(ctctx CompileTimeCallContext, expr *syntax.SyntaxSymbol) error
- func (p *CompileTimeContinuation) CompileSyntax(_ CompileTimeCallContext, expr syntax.SyntaxValue) error
- func (p *CompileTimeContinuation) CompileSyntaxCase(ctctx CompileTimeCallContext, expr syntax.SyntaxValue) error
- func (p *CompileTimeContinuation) CompileUnquote(_ CompileTimeCallContext, _ syntax.SyntaxValue) error
- func (p *CompileTimeContinuation) CompileUnquoteSplicing(_ CompileTimeCallContext, _ syntax.SyntaxValue) error
- func (p *CompileTimeContinuation) CompileUnsyntax(_ CompileTimeCallContext, _ syntax.SyntaxValue) error
- func (p *CompileTimeContinuation) CompileUnsyntaxSplicing(_ CompileTimeCallContext, _ syntax.SyntaxValue) error
- func (p *CompileTimeContinuation) CompileValidatedApply(ctctx CompileTimeCallContext, v *validate.ValidatedApply) error
- func (p *CompileTimeContinuation) CompileValidatedBegin(ctctx CompileTimeCallContext, v *validate.ValidatedBegin) error
- func (p *CompileTimeContinuation) CompileValidatedCaseLambda(ctctx CompileTimeCallContext, v *validate.ValidatedCaseLambda) error
- func (p *CompileTimeContinuation) CompileValidatedDefine(ctctx CompileTimeCallContext, v *validate.ValidatedDefine) error
- func (p *CompileTimeContinuation) CompileValidatedDefineFn(ctctx CompileTimeCallContext, v *validate.ValidatedDefine) error
- func (p *CompileTimeContinuation) CompileValidatedDynamicWind(ctctx CompileTimeCallContext, v *validate.ValidatedDynamicWind) error
- func (p *CompileTimeContinuation) CompileValidatedIf(ctctx CompileTimeCallContext, v *validate.ValidatedIf) error
- func (p *CompileTimeContinuation) CompileValidatedLambda(ctctx CompileTimeCallContext, v *validate.ValidatedLambda) error
- func (p *CompileTimeContinuation) CompileValidatedLet(ctctx CompileTimeCallContext, v *validate.ValidatedLet) error
- func (p *CompileTimeContinuation) CompileValidatedQuasiquote(ctctx CompileTimeCallContext, v *validate.ValidatedQuasiquote) error
- func (p *CompileTimeContinuation) CompileValidatedQuote(_ CompileTimeCallContext, v *validate.ValidatedQuote) error
- func (p *CompileTimeContinuation) CompileValidatedSetBang(ctctx CompileTimeCallContext, v *validate.ValidatedSetBang) error
- func (p *CompileTimeContinuation) CompileValidatedWithContinuationMark(ctctx CompileTimeCallContext, v *validate.ValidatedWithContinuationMark) error
- func (p *CompileTimeContinuation) CompileWithSyntax(ctctx CompileTimeCallContext, expr syntax.SyntaxValue) error
- func (p *CompileTimeContinuation) SetFileResolver(r FileResolver)
- func (p *CompileTimeContinuation) SetInlineThreshold(n int)
- func (p *CompileTimeContinuation) SetLibraryCallback(cb func(*CompiledLibrary))
- type CompiledLibrary
- type CompilerFunc
- type ERMacroTransformer
- type EmbedFileResolver
- type ExpanderContext
- func (p *ExpanderContext) Env() *environment.EnvironmentFrame
- func (p *ExpanderContext) Expand(stx syntax.SyntaxValue) (syntax.SyntaxValue, error)
- func (p *ExpanderContext) ExpandOnce(stx syntax.SyntaxValue) (syntax.SyntaxValue, bool, error)
- func (p *ExpanderContext) IntroductionScope() *syntax.Scope
- func (p *ExpanderContext) SetIntroductionScope(scope *syntax.Scope)
- func (p *ExpanderContext) SetUseSiteScope(scope *syntax.Scope)
- func (p *ExpanderContext) UseSiteScope() *syntax.Scope
- type ExpanderTimeContinuation
- func (p *ExpanderTimeContinuation) Context() context.Context
- func (p *ExpanderTimeContinuation) ExpandBodyWithDefineSyntax(forms []syntax.SyntaxValue) ([]syntax.SyntaxValue, error)
- func (p *ExpanderTimeContinuation) ExpandExpression(expr syntax.SyntaxValue) (syntax.SyntaxValue, error)
- func (p *ExpanderTimeContinuation) ExpandOnce(expr syntax.SyntaxValue) (syntax.SyntaxValue, bool, error)
- func (p *ExpanderTimeContinuation) ExpandPrimitiveForm(primName string, sym *syntax.SyntaxSymbol, expr syntax.SyntaxValue) (syntax.SyntaxValue, error)
- func (p *ExpanderTimeContinuation) ExpandSelfEvaluating(expr syntax.SyntaxValue) (syntax.SyntaxValue, error)
- func (p *ExpanderTimeContinuation) ExpandSymbol(expr *syntax.SyntaxSymbol) (syntax.SyntaxValue, error)
- func (p *ExpanderTimeContinuation) ExpandSyntaxArgumentList(args syntax.SyntaxValue) (syntax.SyntaxValue, error)
- func (p *ExpanderTimeContinuation) ExpandSyntaxExpression(sym *syntax.SyntaxSymbol, expr syntax.SyntaxValue) (syntax.SyntaxValue, error)
- func (p *ExpanderTimeContinuation) ExpandSyntaxOrProcedureCall(car syntax.SyntaxValue, cdr syntax.SyntaxValue) (syntax.SyntaxValue, error)
- func (p *ExpanderTimeContinuation) SetMaxDepth(n int)
- type FSFileResolver
- type FeatureRequirement
- func NewAndRequirement(reqs ...FeatureRequirement) FeatureRequirement
- func NewElseRequirement() FeatureRequirement
- func NewFeatureIdentifier(name string) FeatureRequirement
- func NewLibraryRequirement(name LibraryName) FeatureRequirement
- func NewNotRequirement(req FeatureRequirement) FeatureRequirement
- func NewOrRequirement(reqs ...FeatureRequirement) FeatureRequirement
- type FileResolver
- type FreeIdResolution
- type ImportSet
- type LibraryExportIndex
- type LibraryImportEvent
- type LibraryImportObserver
- type LibraryName
- type LibraryRegistry
- func (p *LibraryRegistry) All() []*CompiledLibrary
- func (p *LibraryRegistry) AllNames() []LibraryName
- func (p *LibraryRegistry) FinishLoading(name LibraryName)
- func (p *LibraryRegistry) GetSearchPaths() []string
- func (p *LibraryRegistry) ImportObserver() LibraryImportObserver
- func (p *LibraryRegistry) IsLoading(name LibraryName) bool
- func (p *LibraryRegistry) Lookup(name LibraryName) *CompiledLibrary
- func (p *LibraryRegistry) PrependSearchPath(path string)
- func (p *LibraryRegistry) Register(lib *CompiledLibrary) error
- func (p *LibraryRegistry) SetImportObserver(obs LibraryImportObserver)
- func (p *LibraryRegistry) SetSearchPaths(paths []string)
- func (p *LibraryRegistry) StartLoading(name LibraryName)
- type LibrarySummary
- type OSFileResolver
- type OperationBindPatternVars
- type OperationBuildSyntaxList
- type OperationClearSyntaxCaseInput
- type OperationStoreSyntaxCaseInput
- type OperationSyntaxCaseMatch
- type OperationSyntaxCaseNoMatch
- type OperationSyntaxRulesTransform
- type OperationSyntaxTemplateExpand
- type PhaseEntry
- type PrimitiveExpander
- func (p *PrimitiveExpander) EqualTo(other values.Value) bool
- func (p *PrimitiveExpander) Expand(etc *ExpanderTimeContinuation, sym *syntax.SyntaxSymbol, ...) (syntax.SyntaxValue, error)
- func (p *PrimitiveExpander) IsVoid() bool
- func (p *PrimitiveExpander) Name() string
- func (p *PrimitiveExpander) SchemeString() string
- type PrimitiveExpanderFunc
- type ResolvedImportSet
- type SourcedError
- type SyntaxCaseClause
- type SyntaxCompiler
- type SyntaxCompilerFunc
- type SyntaxRulesClause
Constants ¶
const ( // TransformerSyntaxRules is the leading symbol for (syntax-rules ...) transformers. TransformerSyntaxRules = "syntax-rules" // TransformerERMacro is the leading symbol for (er-macro-transformer ...) transformers. TransformerERMacro = "er-macro-transformer" // FormDefineSyntax is the form name for (define-syntax ...) definitions. FormDefineSyntax = "define-syntax" )
const DefaultInlineThreshold = 5
DefaultInlineThreshold is the default maximum body length for procedure inlining. A lambda body with more expressions than this is not inlined.
const DefaultMaxExpandDepth int = 50000
DefaultMaxExpandDepth bounds structural recursion depth during macro expansion. Without a bound, deeply nested syntax — reachable not from text (the parser caps that, see internal/parser DefaultMaxParseDepth) but from programmatically-constructed syntax such as macro output, datum->syntax, and quasiquote — triggers a fatal, unrecoverable Go stack overflow that kills the host process. 0 means unlimited. Mirrors the VM's DefaultMaxCallDepth and the parser's DefaultMaxParseDepth.
Chosen empirically: the expander overflows the Go stack between ~400k (heavy macro-re-expansion paths) and ~800k (light procedure-call nesting) levels; 50000 leaves an order-of-magnitude margin below the crash while sitting far above any practical program. A flat recursive macro (and/or/cond with N clauses) accumulates expansion depth linearly in N, but such forms are O(N^2) to expand and unusable well before 50000 clauses, so the bound does not regress any program anyone actually runs. Callers with genuinely deeper machine-generated syntax opt out via SetMaxDepth(0) / WithMaxExpandDepth(0).
const ImplementationName = "wile"
ImplementationName is the name of this Scheme implementation.
const SchemeIncludePathEnv = resolver.SchemeIncludePathEnv
SchemeIncludePathEnv is the environment variable name for the Scheme include path.
Variables ¶
var DefaultLibraryPaths = []string{
".",
"./stdlib/lib",
}
DefaultLibraryPaths are the default directories to search for libraries.
Functions ¶
func AllFeatures ¶
func AllFeatures() []string
AllFeatures returns all supported feature identifiers.
func CompileSyntaxRules ¶
func CompileSyntaxRules(ctx context.Context, env *environment.EnvironmentFrame, syntaxRulesForm syntax.SyntaxValue, libraryScope *syntax.Scope) (*machine.MachineClosure, error)
CompileSyntaxRules compiles a syntax-rules form into a transformer procedure.
R7RS Forms:
(syntax-rules (literal ...) (pattern template) ...) (syntax-rules <ellipsis> (literal ...) (pattern template) ...) ; custom ellipsis
The compilation process:
- Parse optional custom ellipsis identifier
- Parse the literals list - these symbols are matched literally, not as variables
- For each clause, identify pattern variables (symbols not in literals list)
- Compile each pattern to bytecode (see match/syntax_compiler.go)
- Create a machine.MachineClosure that, when invoked: - Tries each pattern in order against the input form - On first match, expands the template with captured bindings - Adds an "intro scope" to the expansion for hygiene
The returned closure is stored in the environment with BindingTypeSyntax, allowing the expander to recognize it as a macro transformer.
func CopyLibraryBindingsToEnv ¶
func CopyLibraryBindingsToEnv(lib *CompiledLibrary, bindings map[string]string, targetEnv *environment.EnvironmentFrame) error
CopyLibraryBindingsToEnv copies exported bindings from a library to an environment. bindings is the map from localName -> externalName produced by ApplyToExports. Both runtime and syntax bindings are copied. This is a convenience wrapper that imports to phase 0 (runtime).
func CopyLibraryBindingsToEnvAtPhase ¶
func CopyLibraryBindingsToEnvAtPhase(lib *CompiledLibrary, bindings map[string]string, targetEnv *environment.EnvironmentFrame, targetPhase environment.Phase) error
func ExpandAndCompile ¶ added in v1.13.21
func ExpandAndCompile(ctx context.Context, env *environment.EnvironmentFrame, stx syntax.SyntaxValue, resolver FileResolver, inlineThreshold int, maxExpandDepth int) (*machine.NativeTemplate, error)
ExpandAndCompile runs the expand+compile pipeline on a single syntax value, returning a ready-to-execute template.
A single MacroEvaluator is shared across both phases. If resolver is non-nil, it is set on the compiler for include/load file resolution. inlineThreshold controls procedure inlining (0 disables). maxExpandDepth bounds expander recursion to prevent a fatal Go stack overflow on deeply nested syntax (0 disables the bound; pass DefaultMaxExpandDepth for the standard limit). Errors are wrapped with phase context ("expansion" or "compilation"); callers may add site-specific context on top. Callers may call tpl.Optimize() on the returned template if desired.
func ImportSpecInto ¶ added in v1.17.0
func ImportSpecInto(ctx context.Context, specVal values.Value, callerEnv, targetEnv *environment.EnvironmentFrame, evaluator machine.MacroEvaluator, op string) error
ImportSpecInto parses a single import-spec datum, loads the named library, applies the import set's modifiers (only/except/prefix/rename), and copies the resulting bindings into targetEnv at the spec's phase shift. It is the shared core of the (environment ...), (make-namespace ...), and (namespace-require ...) primitives; op names the calling primitive for error context. callerEnv supplies the library registry for resolution.
func IsFeatureSupported ¶
IsFeatureSupported checks if a feature identifier is supported.
func LoadBootstrapSources ¶ added in v1.17.0
func LoadBootstrapSources(ctx context.Context, env *environment.EnvironmentFrame, sources []string, resolver FileResolver, kind string) error
LoadBootstrapSources runs the canonical bootstrap pipeline — parse → expand → compile → optimize → execute — for each source string against env, using the default inline and expand-depth thresholds. Templates ARE optimized and executed on a pooled top-level context, matching production engine initialization. The kind argument ("macro" / "procedure") names the source category in error context.
This is the single implementation shared by the engine-root (pkg/wile) and internal (internal/bootstrap) bootstrap paths. Each previously kept its own copy of this loop, and the copies had drifted: the internal one ran on a raw, unpooled context and did NOT optimize, so bootstrap procedures loaded via the internal API (test helpers, embedders on the internal API) ran unoptimized while the public NewEngine path optimized them. Consolidating here removes that divergence.
func LookupPhaseBinding ¶
func LookupPhaseBinding[T any]( phaseEnv *environment.EnvironmentFrame, sym *values.Symbol, scopes []*syntax.Scope, ) T
LookupPhaseBinding looks up a binding by symbol in the target phase environment. Returns the value cast to type T if found, or the zero value if not found or if the value is not of type T.
This function handles hygiene by using scoped lookup - it will only match bindings whose scopes are a subset of the symbol's scopes.
func NewERCompareClosure ¶
func NewERCompareClosure(useEnv *environment.EnvironmentFrame) *machine.ForeignClosure
NewERCompareClosure creates the `compare` closure for an ER macro invocation. useEnv is the use-site environment for resolving identifiers. The closure accepts two identifier arguments and returns #t if both resolve to the same binding (pointer equality) or both are unbound with the same name.
func NewERRenameClosure ¶
func NewERRenameClosure( defExpandEnv *environment.EnvironmentFrame, introScope *syntax.Scope, ) *machine.ForeignClosure
NewERRenameClosure creates the `rename` closure for an ER macro invocation. defExpandEnv is the definition-site expand environment. introScope is a fresh scope unique to this macro invocation, used to ensure that renamed symbols not found in the definition-site env (e.g., temporary names like 'tmp') get a unique identity that prevents variable capture. The returned closure accepts a single symbol argument and returns a SyntaxSymbol that resolves to the definition-site binding. Results are cached per symbol name so that (eq? (rename 'x) (rename 'x)) is #t.
func RegisterAllPhaseHandlers ¶ added in v1.10.7
func RegisterAllPhaseHandlers(env *environment.EnvironmentFrame) error
RegisterAllPhaseHandlers registers both syntax compilers (compile phase) and primitive expanders (expand phase) in the correct order. Use this instead of calling RegisterSyntaxCompilers and RegisterPrimitiveExpanders separately at engine/bootstrap/test init sites.
func RegisterPhaseBindings ¶
func RegisterPhaseBindings[F any]( env *environment.EnvironmentFrame, phaseEnv func() *environment.EnvironmentFrame, entries []PhaseEntry[F], wrapper func(name string, fn F) values.Value, ) error
RegisterPhaseBindings binds all entries in the target phase environment. This is a generic helper for registering primitives in expand or compile phases.
Parameters:
- env: The top-level environment
- phaseEnv: Accessor for the target phase (e.g., env.Expand or env.Compile)
- entries: Slice of (name, function) pairs to register
- wrapper: Creates the values.Value wrapper from name and function
func RegisterPrimitiveExpanders ¶
func RegisterPrimitiveExpanders(env *environment.EnvironmentFrame) error
func RegisterSyntaxCompilers ¶
func RegisterSyntaxCompilers(env *environment.EnvironmentFrame) error
RegisterSyntaxCompilers binds all syntax compilers in the compile-time environment (env.Compile()). These bindings serve two purposes:
- Library export/import: findLibraryBinding in library_bindings.go searches the compile environment to locate syntax compilers when exporting or importing forms like syntax-case, define-syntax, etc.
- Scope-aware lookup via LookupSyntaxCompiler for hygiene resolution.
Compilation dispatch itself goes through the forms registry (register.go), not through these bindings. Both paths are populated from syntaxCompilerEntries to stay in sync.
The syntax compilers are bound with BindingTypePrimitive to distinguish them from syntax transformers (BindingTypeSyntax) and regular variables.
func ResolveAndInstallImportSet ¶
func ResolveAndInstallImportSet(ctx context.Context, datum values.Value, env *environment.EnvironmentFrame, phase environment.Phase, evaluator machine.MacroEvaluator) error
ResolveAndInstallImportSet resolves an import set and installs bindings into env at the appropriate phase. Used for top-level imports (both expander and compiler). Library-internal imports share the resolution step (resolveImportSet) but use copyLibraryBindingsDirect for installation.
func ResolveLibraryFile ¶ added in v1.14.0
func ResolveLibraryFile(ctx context.Context, res FileResolver, name LibraryName) (fs.File, string, error)
ResolveLibraryFile resolves a library name to an open file handle, trying each extension in libraryExtensions order. Non-file-not-found errors (security denial, I/O) propagate immediately.
func VerifyAllPhaseHandlers ¶ added in v1.10.7
func VerifyAllPhaseHandlers() error
VerifyAllPhaseHandlers cross-checks all three phase registries: form validators (internal/forms), compilers (Tier 1 + Tier 2), and primitive expanders. Returns the first inconsistency found, or nil.
Call from tests only — not on the production init path.
func VerifyCompilers ¶
func VerifyCompilers() error
VerifyCompilers checks that every form registered in the forms package has a corresponding compiler — either in the registry (Tier 2) or in the type switch (Tier 1). Returns an error listing any gaps.
func VerifyExpanders ¶ added in v1.10.7
func VerifyExpanders() error
VerifyExpanders checks that every Tier 2 syntax compiler entry has a corresponding primitive expander entry. A Tier 2 form without an expander is silently treated as a procedure call during expansion — the most dangerous form of registration drift.
Types ¶
type ChainFileResolver ¶
type ChainFileResolver = resolver.ChainFileResolver
func NewChainFileResolver ¶
func NewChainFileResolver(resolvers []environment.FileResolver) *ChainFileResolver
NewChainFileResolver creates a resolver that searches multiple resolvers.
type ClausesWrapper ¶ added in v1.13.21
type ClausesWrapper struct {
Clauses []*SyntaxRulesClause
}
ClausesWrapper wraps a slice of SyntaxRulesClause as a values.Value for storage in NativeTemplate literals.
func (*ClausesWrapper) EqualTo ¶ added in v1.13.21
func (p *ClausesWrapper) EqualTo(other values.Value) bool
func (*ClausesWrapper) IsVoid ¶ added in v1.13.21
func (p *ClausesWrapper) IsVoid() bool
func (*ClausesWrapper) SchemeString ¶ added in v1.13.21
func (p *ClausesWrapper) SchemeString() string
type CompileTimeCallContext ¶
type CompileTimeCallContext struct {
// contains filtered or unexported fields
}
CompileTimeCallContext carries contextual information through the compilation process. It tracks whether an expression is in tail position, which controls whether the compiler emits SaveContinuation (non-tail) or reuses the current frame (tail).
This structure is passed by value (not pointer) through the compiler, allowing each compilation step to create modified copies without affecting the caller's context.
Tail Call Optimization ¶
Tail call optimization (Steele 1977, R7RS §3.5): tail calls reuse the caller's continuation frame instead of allocating a new one, making recursive procedures in tail position run in constant stack space. See BIBLIOGRAPHY.md "Tail Call Optimization".
The inTail flag tracks whether an expression is in tail position. An expression is in tail position if its value will be the final result of the enclosing procedure. When inTail is true, the compiler can generate a tail call that reuses the current stack frame instead of creating a new one, preventing stack overflow in recursive procedures.
Per R7RS Section 3.5, these positions are tail positions:
- The body of a lambda expression
- The last expression in a begin sequence (if the begin is in tail position)
- The consequent and alternative of an if expression (if the if is in tail position)
- The body of a let/let*/letrec (if the let is in tail position)
These are NOT tail positions (use NotInTail()):
- Function arguments: (f (g x)) - the call to g is not in tail position
- Condition of if: (if (pred x) ...) - pred is not in tail position
- Definitions: (define x (expr)) - expr is not in tail position
- Non-final expressions in begin: (begin (a) (b) (c)) - only c is in tail position
func NewCompileTimeCallContext ¶
func NewCompileTimeCallContext(ctx context.Context, inTail bool) CompileTimeCallContext
NewCompileTimeCallContext creates a new compile-time context. Parameters:
- inTail: true if compiling an expression in tail position
func (CompileTimeCallContext) Context ¶
func (p CompileTimeCallContext) Context() context.Context
Context returns the context associated with this compile-time call context.
func (CompileTimeCallContext) NotInTail ¶
func (p CompileTimeCallContext) NotInTail() CompileTimeCallContext
NotInTail returns a copy of the context with inTail set to false. Use this when compiling sub-expressions that are not in tail position:
- Function arguments
- Condition expressions in if
- Initial values in define/let bindings
- Non-final expressions in begin
Example:
// Compiling (f (g x)) - the call to g is not in tail position err := p.CompileExpression(ctctx.NotInTail(), argExpr)
func (CompileTimeCallContext) WithFrameReuse ¶ added in v1.17.0
func (p CompileTimeCallContext) WithFrameReuse(fr frameReuse) CompileTimeCallContext
WithFrameReuse returns a copy armed with the given frame-reuse disposition. Preserves inTail and ctx.
func (CompileTimeCallContext) WithoutFrameReuse ¶ added in v1.17.0
func (p CompileTimeCallContext) WithoutFrameReuse() CompileTimeCallContext
WithoutFrameReuse returns a copy with the frame-reuse context cleared. Used when descending into a frame-pushing form (let): its body runs in a pushed frame, so a call there is no longer at the parameter-frame depth — neither the in-place OpSelfTailCall nor OpReleaseEnvFrame (both act on the parameter frame) may fire.
type CompileTimeContinuation ¶
type CompileTimeContinuation struct {
// contains filtered or unexported fields
}
CompileTimeContinuation is a continuation used during the compilation phase
func NewCompileTimeContinuation ¶
func NewCompileTimeContinuation(tpl *machine.NativeTemplate, env *environment.EnvironmentFrame, evaluator machine.MacroEvaluator) *CompileTimeContinuation
NewCompileTimeContinuation creates a new CompileTimeContinuation. The file resolver defaults to the one stored on the Namespace. If none is set, falls back to a fresh OSFileResolver.
func (*CompileTimeContinuation) AppendOperations ¶
func (p *CompileTimeContinuation) AppendOperations(ops ...machine.Operation)
AppendOperations appends operations tagged with the current source from the source stack. Routes through the integer-dispatch code[] path: Wave 1-3 operations become direct instructions, everything else goes via machine.OpComplex to the sideTable.
func (*CompileTimeContinuation) CompileBeginForSyntax ¶
func (p *CompileTimeContinuation) CompileBeginForSyntax(ctctx CompileTimeCallContext, expr syntax.SyntaxValue) error
CompileBeginForSyntax handles (begin-for-syntax expr ...).
Evaluates a sequence of expressions at compile time in the expand phase environment. Used for setting up compile-time state (hash tables, registries) that macros can access. No runtime effect — used for side effects only.
func (*CompileTimeContinuation) CompileCondExpand ¶
func (p *CompileTimeContinuation) CompileCondExpand(ctctx CompileTimeCallContext, expr syntax.SyntaxValue) error
CompileCondExpand compiles a cond-expand expression. cond-expand is evaluated at compile-time and expands to the body of the first clause whose feature requirement is satisfied.
Syntax: (cond-expand <clause> ...) where <clause> is (<feature-requirement> <expression> ...)
Example:
(cond-expand (r7rs (display "R7RS")) (else (display "other")))
func (*CompileTimeContinuation) CompileDefineForSyntax ¶
func (p *CompileTimeContinuation) CompileDefineForSyntax(ctctx CompileTimeCallContext, expr syntax.SyntaxValue) error
CompileDefineForSyntax handles (define-for-syntax name expr) or (define-for-syntax (name args...) body...).
This form defines a binding in the expand phase environment that is available during macro expansion. The expression is compiled and evaluated at compile time, and the result is stored in env.Expand().
Unlike define-syntax (which stores macro transformers), define-for-syntax stores regular values with BindingTypeVariable.
func (*CompileTimeContinuation) CompileDefineLibrary ¶
func (p *CompileTimeContinuation) CompileDefineLibrary(ctctx CompileTimeCallContext, expr syntax.SyntaxValue) error
CompileDefineLibrary handles (define-library (lib-name) <library-declaration> ...).
R7RS library syntax:
(define-library <library-name> <library-declaration> ...) <library-declaration> = | (export <export-spec> ...) | (import <import-set> ...) | (begin <command-or-definition> ...) | (include <filename> ...) | (include-ci <filename> ...)
This creates an isolated environment for the library, processes declarations in order, and registers the compiled library in the registry.
func (*CompileTimeContinuation) CompileDefineSyntax ¶
func (p *CompileTimeContinuation) CompileDefineSyntax(ctctx CompileTimeCallContext, expr syntax.SyntaxValue) error
CompileDefineSyntax handles (define-syntax keyword transformer-expr).
This is the compile-time handler for R7RS define-syntax. Unlike most definitions, define-syntax is processed entirely at compile time:
- Parse the form: (define-syntax keyword (syntax-rules ...))
- Compile the syntax-rules transformer to a machine.MachineClosure
- Store the closure in the environment with BindingTypeSyntax
- Emit NO runtime operations (the binding is already established)
The BindingTypeSyntax marker is crucial: when the expander encounters a symbol, it checks if that symbol is bound to a syntax transformer. If so, it invokes the transformer closure to expand the macro.
This is how derived expressions like 'let' work: they're defined as macros using define-syntax, and expand to lambda expressions:
(define-syntax let
(syntax-rules ()
((let ((name val) ...) body)
((lambda (name ...) body) val ...))))
Reference: R7RS Section 5.4 (Syntax definitions)
func (*CompileTimeContinuation) CompileEvalWhen ¶
func (p *CompileTimeContinuation) CompileEvalWhen(ctctx CompileTimeCallContext, expr syntax.SyntaxValue) error
CompileEvalWhen handles (eval-when (phase ...) body ...).
This form controls when code is evaluated based on phase specifiers. Phase names follow Chez Scheme's eval-when (Dybvig, TSPL §12.10):
- expand: evaluate during macro expansion (at compile time)
- compile: evaluate during compilation (currently same as expand)
- run: evaluate at runtime (generate code for normal execution)
Multiple phases can be specified. If both expand and run are specified, the body is evaluated at compile time AND code is generated for runtime.
eval-when is not part of R7RS-small; it is a Wile extension.
Examples:
(eval-when (expand) (display "at expansion time")) (eval-when (run) (display "at runtime")) (eval-when (expand run) (display "both times"))
func (*CompileTimeContinuation) CompileExport ¶
func (p *CompileTimeContinuation) CompileExport(_ CompileTimeCallContext, _ syntax.SyntaxValue) error
CompileExport handles top-level (export <export-spec> ...).
This is only valid within a library definition. At top-level, it's an error.
func (*CompileTimeContinuation) CompileExpression ¶
func (p *CompileTimeContinuation) CompileExpression(ctctx CompileTimeCallContext, expr syntax.SyntaxValue) error
CompileExpression compiles a general expression. Pushes the expression's source context onto the source stack so that all operations emitted during compilation (including infrastructure ops like Branch and Push) are tagged with the source location.
func (*CompileTimeContinuation) CompileImport ¶
func (p *CompileTimeContinuation) CompileImport(ctctx CompileTimeCallContext, expr syntax.SyntaxValue) error
CompileImport handles top-level (import <import-set> ...).
This is for top-level imports outside of a library definition. It loads the specified libraries and binds their exports in the current environment.
Supports Racket-style phased imports:
- (import (scheme base)) ; Phase 0 (runtime)
- (import (for-syntax (scheme base))) ; Phase 1 (expand)
- (import (for-template (scheme base))) ; Phase -1
- (import (for-meta 2 (scheme base))) ; Phase 2
func (*CompileTimeContinuation) CompileInclude ¶
func (p *CompileTimeContinuation) CompileInclude(ctctx CompileTimeCallContext, expr syntax.SyntaxValue) error
CompileInclude compiles an include expression. It reads and compiles all forms from the specified files in order. Each form is expanded and compiled in the current environment.
func (*CompileTimeContinuation) CompileIncludeCi ¶
func (p *CompileTimeContinuation) CompileIncludeCi(_ CompileTimeCallContext, _ syntax.SyntaxValue) error
CompileIncludeCi compiles an include-ci expression.
func (*CompileTimeContinuation) CompileMeta ¶
func (p *CompileTimeContinuation) CompileMeta(ctctx CompileTimeCallContext, expr syntax.SyntaxValue) error
CompileMeta compiles a meta expression.
func (*CompileTimeContinuation) CompileQuasisyntax ¶
func (p *CompileTimeContinuation) CompileQuasisyntax(ctctx CompileTimeCallContext, expr syntax.SyntaxValue) error
CompileQuasisyntax compiles the (quasisyntax template) form.
quasisyntax is like quasiquote but for syntax objects. It supports:
- (unsyntax expr) - evaluate expr and splice result at depth 1
- (unsyntax-splicing expr) - evaluate and splice list at depth 1
- nested quasisyntax increases depth
Like quasiquote, unsyntax only evaluates when depth reaches 0. The result is a syntax object, not a raw datum.
func (*CompileTimeContinuation) CompileSelfEvaluating ¶
func (p *CompileTimeContinuation) CompileSelfEvaluating(_ CompileTimeCallContext, expr syntax.SyntaxValue) error
CompileSelfEvaluating compiles a self-evaluating expression (literal).
func (*CompileTimeContinuation) CompileSymbol ¶
func (p *CompileTimeContinuation) CompileSymbol(ctctx CompileTimeCallContext, expr *syntax.SyntaxSymbol) error
CompileSymbol compiles a syntax symbol expression.
Resolution order (Flatt 2016 "sets of scopes"): a scope-set local match wins over everything, including a ResolvedBinding pin carried from macro expansion. This lets a binding co-introduced by a template — which carries the same intro scope as the reference — shadow a same-named global. The ResolvedBinding and library-scope fallbacks fire only when no lexical binding shadows. See plans/2026-06-15-macro-hygiene-global-shadow-fix.local.md (Change 2).
func (*CompileTimeContinuation) CompileSyntax ¶
func (p *CompileTimeContinuation) CompileSyntax(_ CompileTimeCallContext, expr syntax.SyntaxValue) error
CompileSyntax compiles the (syntax template) form.
Unlike quote which unwraps syntax to raw values, syntax preserves the syntax structure. When used inside syntax-case, pattern variables in the template are substituted with their matched values.
For templates containing ellipsis (...), runtime expansion is used because ellipsis patterns capture variable-length lists that must be expanded dynamically.
(syntax template) -> syntax-object
func (*CompileTimeContinuation) CompileSyntaxCase ¶
func (p *CompileTimeContinuation) CompileSyntaxCase(ctctx CompileTimeCallContext, expr syntax.SyntaxValue) error
CompileSyntaxCase compiles the (syntax-case expr (literal ...) clause ...) form.
R6RS syntax-case is a pattern matching form that provides procedural macro facilities. Unlike syntax-rules which expands to templates, syntax-case evaluates arbitrary Scheme code in the body, with pattern variables bound as local variables.
Syntax:
(syntax-case expr (literal ...) (pattern body) (pattern fender body) ...)
Compilation strategy:
- Compile expr to get the input syntax object
- For each clause, generate pattern matching and body code
- Pattern variables are bound as local variables in the body's scope
- If fender exists, it's evaluated as a guard condition
func (*CompileTimeContinuation) CompileUnquote ¶
func (p *CompileTimeContinuation) CompileUnquote(_ CompileTimeCallContext, _ syntax.SyntaxValue) error
CompileUnquote errors - unquote outside of quasiquote
func (*CompileTimeContinuation) CompileUnquoteSplicing ¶
func (p *CompileTimeContinuation) CompileUnquoteSplicing(_ CompileTimeCallContext, _ syntax.SyntaxValue) error
CompileUnquoteSplicing errors - unquote-splicing outside of quasiquote
func (*CompileTimeContinuation) CompileUnsyntax ¶
func (p *CompileTimeContinuation) CompileUnsyntax(_ CompileTimeCallContext, _ syntax.SyntaxValue) error
CompileUnsyntax errors - unsyntax outside of quasisyntax
func (*CompileTimeContinuation) CompileUnsyntaxSplicing ¶
func (p *CompileTimeContinuation) CompileUnsyntaxSplicing(_ CompileTimeCallContext, _ syntax.SyntaxValue) error
CompileUnsyntaxSplicing errors - unsyntax-splicing outside of quasisyntax
func (*CompileTimeContinuation) CompileValidatedApply ¶
func (p *CompileTimeContinuation) CompileValidatedApply(ctctx CompileTimeCallContext, v *validate.ValidatedApply) error
CompileValidatedApply compiles a validated (apply proc arg1 ... args) form.
R7RS §6.10: apply calls proc with the arguments arg1 ... concatenated with the elements of args (the final argument, which must be a list).
Bytecode (non-tail):
SaveContinuation →after <compile proc> PUSH <compile arg1> PUSH ... <compile argN> PUSH <compile finalList> ; value = finalList OpUnpackListToStack ; stack: [proc, arg1, ..., argN, x1, x2, ...] Pull ; value = proc Apply ; calls proc(arg1, ..., argN, x1, x2, ...) after:
Tail position: same without SaveContinuation/patch.
func (*CompileTimeContinuation) CompileValidatedBegin ¶
func (p *CompileTimeContinuation) CompileValidatedBegin(ctctx CompileTimeCallContext, v *validate.ValidatedBegin) error
CompileValidatedBegin compiles a validated (begin expr...) form.
begin (R7RS 4.2.3) sequences expressions for side effects. All expressions are evaluated left-to-right; the value of the last expression becomes the value of the entire begin form.
R7RS §5.3.2: Internal definitions use letrec* semantics - all defined names are visible throughout the body, enabling forward references between defines.
Example: (begin (display "hello") (newline) 42) => 42 (after printing)
func (*CompileTimeContinuation) CompileValidatedCaseLambda ¶
func (p *CompileTimeContinuation) CompileValidatedCaseLambda(ctctx CompileTimeCallContext, v *validate.ValidatedCaseLambda) error
CompileValidatedCaseLambda compiles a validated (case-lambda [clause] ...) form.
case-lambda (R7RS 4.2.9) creates a procedure that dispatches to different implementations based on the number of arguments. For example:
(case-lambda ((x) (* x x)) ; 1 arg: square ((x y) (* x y)) ; 2 args: multiply ((x y . rest) (apply + x y rest))) ; 2+ args: sum all
At runtime, the VM selects the first clause whose arity matches the call.
func (*CompileTimeContinuation) CompileValidatedDefine ¶
func (p *CompileTimeContinuation) CompileValidatedDefine(ctctx CompileTimeCallContext, v *validate.ValidatedDefine) error
CompileValidatedDefine compiles a validated define form.
func (*CompileTimeContinuation) CompileValidatedDefineFn ¶
func (p *CompileTimeContinuation) CompileValidatedDefineFn(ctctx CompileTimeCallContext, v *validate.ValidatedDefine) error
CompileValidatedDefineFn compiles the function shorthand form of define.
Usage: (define (name param ...) body ...)
(define (name param ... . rest) body ...)
This is syntactic sugar equivalent to:
(define name (lambda (param ...) body ...))
Examples:
(define (square x) (* x x)) ; fixed arity (define (sum . args) (apply + args)) ; variadic (all args) (define (sum x . rest) (apply + x rest)) ; variadic (1+ args)
The function name is bound before compiling the body to enable self-recursion:
(define (fact n) (if (<= n 1) 1 (* n (fact (- n 1)))))
func (*CompileTimeContinuation) CompileValidatedDynamicWind ¶
func (p *CompileTimeContinuation) CompileValidatedDynamicWind(ctctx CompileTimeCallContext, v *validate.ValidatedDynamicWind) error
CompileValidatedDynamicWind compiles a validated (dynamic-wind before thunk after) form.
R7RS §6.10: dynamic-wind calls thunk without arguments, returning the result(s). Before is called whenever execution enters the dynamic extent of the call to thunk, and after is called whenever it exits.
The key insight is that by compiling to bytecode, the cleanup code (calling after) is in the bytecode stream. When a continuation is captured inside the thunk and later restored, the cleanup code will run on normal completion.
Bytecode structure:
<compile before> PUSH <compile thunk> PUSH <compile after> PUSH ; Stack: [before, thunk, after] PEEK_K 2 ; value = before SAVE_CONTINUATION →after_before APPLY ; call before() after_before: ; Stack: [before, thunk, after] OP_PUSH_WIND ; create winding frame PEEK_K 1 ; value = thunk SAVE_CONTINUATION →after_thunk APPLY ; call thunk() after_thunk: ; Stack: [before, thunk, after] PUSH ; save thunk result, Stack: [before, thunk, after, result] OP_POP_WIND ; pop winding frame PEEK_K 1 ; value = after SAVE_CONTINUATION →after_after APPLY ; call after() after_after: ; Stack: [before, thunk, after, result] PEEK_K 0 ; value = result (thunk's return value) DROP DROP DROP DROP ; clean up stack
func (*CompileTimeContinuation) CompileValidatedIf ¶
func (p *CompileTimeContinuation) CompileValidatedIf(ctctx CompileTimeCallContext, v *validate.ValidatedIf) error
CompileValidatedIf compiles a validated (if test conseq [alt]) form. The structure is guaranteed to be valid by the validator.
Constant folding (Aho et al., Compilers §8.5): when the test is a compile-time literal, the entire if-form reduces to one branch. This is the simplest form of constant folding — evaluating known expressions at compile time rather than runtime. See BIBLIOGRAPHY.md "Constant Folding".
func (*CompileTimeContinuation) CompileValidatedLambda ¶
func (p *CompileTimeContinuation) CompileValidatedLambda(ctctx CompileTimeCallContext, v *validate.ValidatedLambda) error
CompileValidatedLambda compiles a validated (lambda params body...) form.
func (*CompileTimeContinuation) CompileValidatedLet ¶
func (p *CompileTimeContinuation) CompileValidatedLet( ctctx CompileTimeCallContext, v *validate.ValidatedLet, ) error
func (*CompileTimeContinuation) CompileValidatedQuasiquote ¶
func (p *CompileTimeContinuation) CompileValidatedQuasiquote(ctctx CompileTimeCallContext, v *validate.ValidatedQuasiquote) error
CompileValidatedQuasiquote compiles a validated (quasiquote template) form. Quasiquote has complex runtime semantics, so we delegate to the existing compiler.
func (*CompileTimeContinuation) CompileValidatedQuote ¶
func (p *CompileTimeContinuation) CompileValidatedQuote(_ CompileTimeCallContext, v *validate.ValidatedQuote) error
CompileValidatedQuote compiles a validated (quote datum) form.
func (*CompileTimeContinuation) CompileValidatedSetBang ¶
func (p *CompileTimeContinuation) CompileValidatedSetBang(ctctx CompileTimeCallContext, v *validate.ValidatedSetBang) error
CompileValidatedSetBang compiles a validated (set! name expr) form.
func (*CompileTimeContinuation) CompileValidatedWithContinuationMark ¶
func (p *CompileTimeContinuation) CompileValidatedWithContinuationMark( ctctx CompileTimeCallContext, v *validate.ValidatedWithContinuationMark, ) error
CompileValidatedWithContinuationMark compiles (with-continuation-mark key val body).
Tail position:
<compile key> PUSH <compile val> SetContMark ; pops key, sets marks[key] = val <compile body in tail>
Non-tail position:
<compile key> PUSH <compile val> SaveContMark ; pops key, saves (key, old) on stack, sets mark <compile body in non-tail> RestoreContMark ; pops (old, key), restores mark
func (*CompileTimeContinuation) CompileWithSyntax ¶
func (p *CompileTimeContinuation) CompileWithSyntax(ctctx CompileTimeCallContext, expr syntax.SyntaxValue) error
CompileWithSyntax compiles the (with-syntax ((pattern expr) ...) body ...) form.
with-syntax is a convenience form for binding pattern variables from expressions. It's equivalent to:
(syntax-case (list expr ...) () ((pattern ...) (let () body ...)))
For now, this implements a simple transformation approach.
func (*CompileTimeContinuation) SetFileResolver ¶
func (p *CompileTimeContinuation) SetFileResolver(r FileResolver)
SetFileResolver overrides the file resolver used by include/load. Nil resets to the environment's resolver (or OSFileResolver as fallback).
func (*CompileTimeContinuation) SetInlineThreshold ¶ added in v1.10.7
func (p *CompileTimeContinuation) SetInlineThreshold(n int)
SetInlineThreshold sets the maximum body length for procedure inlining. 0 disables inlining entirely.
func (*CompileTimeContinuation) SetLibraryCallback ¶
func (p *CompileTimeContinuation) SetLibraryCallback(cb func(*CompiledLibrary))
SetLibraryCallback sets a callback function that will be called when a library is compiled via CompileDefineLibrary. This is used by LoadLibrary to capture the compiled library.
type CompiledLibrary ¶
type CompiledLibrary struct {
Name LibraryName // Library name
Description string // from (description ...) clause; "" if absent
Env *environment.EnvironmentFrame // Library's private environment
Exports map[string]string // external-name -> internal-name
SourceFile string // Path to .sld file (for error messages)
Template *machine.NativeTemplate // Compiled bytecode (for execution)
}
CompiledLibrary holds a loaded and compiled library.
func LoadLibrary ¶
func LoadLibrary(ctx context.Context, name LibraryName, env *environment.EnvironmentFrame, evaluator machine.MacroEvaluator) (*CompiledLibrary, error)
LoadLibrary loads a library by name, compiling and executing it if not already loaded. Returns the CompiledLibrary which can be used to import bindings.
The function: 1. Checks if already loaded (returns cached library) 2. Checks for circular dependencies 3. Resolves and opens the library file via FileResolver 4. Parses and compiles the define-library form 5. Executes the library to create runtime bindings 6. Registers the library in the registry
func NewCompiledLibrary ¶
func NewCompiledLibrary(name LibraryName, env *environment.EnvironmentFrame) *CompiledLibrary
NewCompiledLibrary creates a new compiled library.
func (*CompiledLibrary) AddExport ¶
func (p *CompiledLibrary) AddExport(externalName, internalName string)
AddExport adds an export to the library. If internalName is empty, it defaults to externalName (no rename).
func (*CompiledLibrary) GetInternalName ¶
func (p *CompiledLibrary) GetInternalName(externalName string) string
GetInternalName returns the internal name for an exported external name. Returns empty string if not exported.
func (*CompiledLibrary) IsExported ¶
func (p *CompiledLibrary) IsExported(externalName string) bool
IsExported returns true if the given external name is exported.
type CompilerFunc ¶
type CompilerFunc func(ctc *CompileTimeContinuation, ctctx CompileTimeCallContext, expr *validate.ValidatedLiteral) error
CompilerFunc is the signature for Tier 2 (syntax passthrough) compiler functions. These receive ValidatedLiteral because Tier 2 forms pass through validation as literals with a FormName. Tier 1 forms (if, define, lambda, etc.) are dispatched by type switch in compileValidated and never reach the registry.
func LookupCompiler ¶
func LookupCompiler(name string) CompilerFunc
LookupCompiler returns the compiler function for a form name, or nil.
type ERMacroTransformer ¶
type ERMacroTransformer struct {
// contains filtered or unexported fields
}
ERMacroTransformer wraps a 3-arg machine.MachineClosure to identify it as an explicit-renaming transformer in expandMacroInvocation. The defEnv captures the expand-time environment at the macro definition site, used by the rename closure to resolve definition-site bindings.
func NewERMacroTransformer ¶
func NewERMacroTransformer(closure *machine.MachineClosure, defEnv *environment.EnvironmentFrame) *ERMacroTransformer
func (*ERMacroTransformer) Closure ¶
func (p *ERMacroTransformer) Closure() *machine.MachineClosure
func (*ERMacroTransformer) DefEnv ¶
func (p *ERMacroTransformer) DefEnv() *environment.EnvironmentFrame
func (*ERMacroTransformer) IsVoid ¶
func (p *ERMacroTransformer) IsVoid() bool
func (*ERMacroTransformer) SchemeString ¶
func (p *ERMacroTransformer) SchemeString() string
type EmbedFileResolver ¶
type EmbedFileResolver = resolver.EmbedFileResolver
func NewEmbedFileResolver ¶
func NewEmbedFileResolver(fsys fs.FS) *EmbedFileResolver
NewEmbedFileResolver creates a resolver backed by an embedded filesystem.
type ExpanderContext ¶
type ExpanderContext struct {
// contains filtered or unexported fields
}
ExpanderContext provides access to the macro expander from within Scheme code during macro expansion. It is set on machine.MachineContext when invoking macro transformers, enabling syntax-local-* primitives.
func NewExpanderContext ¶
func NewExpanderContext( env *environment.EnvironmentFrame, expander *ExpanderTimeContinuation, ) *ExpanderContext
NewExpanderContext creates a new ExpanderContext.
func (*ExpanderContext) Env ¶
func (p *ExpanderContext) Env() *environment.EnvironmentFrame
Env returns the environment frame associated with this context.
func (*ExpanderContext) Expand ¶
func (p *ExpanderContext) Expand(stx syntax.SyntaxValue) (syntax.SyntaxValue, error)
Expand fully expands a syntax object.
func (*ExpanderContext) ExpandOnce ¶
func (p *ExpanderContext) ExpandOnce(stx syntax.SyntaxValue) (syntax.SyntaxValue, bool, error)
ExpandOnce performs a single step of macro expansion. Returns (expanded-syntax, did-expand, error). If the input is a macro call, it expands it once and returns (result, true, nil). If the input is not a macro call, it returns (input, false, nil).
func (*ExpanderContext) IntroductionScope ¶
func (p *ExpanderContext) IntroductionScope() *syntax.Scope
IntroductionScope returns the introduction scope for the current macro expansion. This scope is added to identifiers introduced by a macro and can be flipped using syntax-local-introduce.
func (*ExpanderContext) SetIntroductionScope ¶
func (p *ExpanderContext) SetIntroductionScope(scope *syntax.Scope)
SetIntroductionScope sets the introduction scope for the current macro expansion.
func (*ExpanderContext) SetUseSiteScope ¶
func (p *ExpanderContext) SetUseSiteScope(scope *syntax.Scope)
SetUseSiteScope sets the use-site scope for binding forms.
func (*ExpanderContext) UseSiteScope ¶
func (p *ExpanderContext) UseSiteScope() *syntax.Scope
UseSiteScope returns the use-site scope for binding forms. This scope is used by syntax-local-identifier-as-binding to mark identifiers as binding sites.
type ExpanderTimeContinuation ¶
type ExpanderTimeContinuation struct {
// contains filtered or unexported fields
}
ExpanderTimeContinuation is a continuation used during the expansion phase.
It walks the syntax tree, detecting and expanding macro invocations. The env field provides access to macro definitions (BindingTypeSyntax bindings).
func NewExpanderTimeContinuation ¶
func NewExpanderTimeContinuation(ctx context.Context, env *environment.EnvironmentFrame, evaluator machine.MacroEvaluator) *ExpanderTimeContinuation
NewExpanderTimeContinuation creates a new ExpanderTimeContinuation. The returned expander begins a fresh expansion run with its own depth guard defaulted to DefaultMaxExpandDepth; override via SetMaxDepth.
func (*ExpanderTimeContinuation) Context ¶
func (p *ExpanderTimeContinuation) Context() context.Context
Context returns the context associated with this expander continuation.
func (*ExpanderTimeContinuation) ExpandBodyWithDefineSyntax ¶
func (p *ExpanderTimeContinuation) ExpandBodyWithDefineSyntax( forms []syntax.SyntaxValue, ) ([]syntax.SyntaxValue, error)
ExpandBodyWithDefineSyntax expands a sequence of body forms, compiling define-syntax forms as encountered so subsequent forms can use the macros.
This unifies the expansion pattern used by: - Lambda bodies (internal define-syntax) - Library bodies (top-level define-syntax) - Include files (top-level define-syntax)
R7RS §5.3: Internal define-syntax forms must be processed before expanding subsequent body expressions so that locally-defined macros are visible.
R7RS §5.3.2: Bodies use letrec* semantics where all defined names are visible to all initializers. This enables forward references within macros - a macro can reference a definition that appears later in the same body.
func (*ExpanderTimeContinuation) ExpandExpression ¶
func (p *ExpanderTimeContinuation) ExpandExpression(expr syntax.SyntaxValue) (syntax.SyntaxValue, error)
ExpandExpression expands a syntax expression.
This is the single recursion chokepoint of the expander: every descent into a sub-expression — nested cars, argument lists, primitive-form bodies (via child expanders), and macro re-expansion — funnels through here. The depth guard therefore bounds total Go-stack recursion for the whole expansion run, returning a catchable ErrExpandDepthExceeded instead of letting deeply nested (programmatically-constructed) syntax crash the host with a fatal Go stack overflow. See expandDepthGuard and DefaultMaxExpandDepth.
func (*ExpanderTimeContinuation) ExpandOnce ¶
func (p *ExpanderTimeContinuation) ExpandOnce(expr syntax.SyntaxValue) (syntax.SyntaxValue, bool, error)
ExpandOnce performs a single step of macro expansion. Returns (expanded-syntax, did-expand, error). If the input is a macro call, it expands it once and returns (result, true, nil). If the input is not a macro call, it returns (input, false, nil). Unlike ExpandExpression, this does NOT recursively expand the result.
func (*ExpanderTimeContinuation) ExpandPrimitiveForm ¶
func (p *ExpanderTimeContinuation) ExpandPrimitiveForm(primName string, sym *syntax.SyntaxSymbol, expr syntax.SyntaxValue) (syntax.SyntaxValue, error)
ExpandPrimitiveForm handles expansion within primitive forms like if, begin, lambda, define, etc. Some primitives need their subexpressions expanded (like if, begin) while others should be left unchanged (like quote, define-syntax).
This function looks up the primitive expander in the expand environment registry. If found, it invokes the expander; otherwise returns the form unchanged.
func (*ExpanderTimeContinuation) ExpandSelfEvaluating ¶
func (p *ExpanderTimeContinuation) ExpandSelfEvaluating(expr syntax.SyntaxValue) (syntax.SyntaxValue, error)
ExpandSelfEvaluating handles self-evaluating expressions.
func (*ExpanderTimeContinuation) ExpandSymbol ¶
func (p *ExpanderTimeContinuation) ExpandSymbol(expr *syntax.SyntaxSymbol) (syntax.SyntaxValue, error)
ExpandSymbol handles a symbol expression.
func (*ExpanderTimeContinuation) ExpandSyntaxArgumentList ¶
func (p *ExpanderTimeContinuation) ExpandSyntaxArgumentList(args syntax.SyntaxValue) (syntax.SyntaxValue, error)
ExpandSyntaxArgumentList expands each argument in the argument list. It returns a new syntax list with the expanded arguments.
func (*ExpanderTimeContinuation) ExpandSyntaxExpression ¶
func (p *ExpanderTimeContinuation) ExpandSyntaxExpression(sym *syntax.SyntaxSymbol, expr syntax.SyntaxValue) (syntax.SyntaxValue, error)
ExpandSyntaxExpression checks if sym is a macro and expands it, or returns the expression as a procedure call if not.
This is where macro invocation happens:
- Look up the symbol in the expand environment
- If bound with BindingTypeSyntax, it's a macro - invoke the transformer
- If it's a primitive (like quote, if, define-syntax), don't expand args
- Otherwise, treat as procedure call and expand arguments
The transformer closure (machine.MachineClosure from CompileSyntaxRules) is invoked by creating a machine.MachineContext and running it. The transformer:
- Receives the full macro invocation form on the eval stack
- Pattern matches against its clauses (OperationSyntaxRulesTransform)
- Expands the matching template with captured bindings
- Adds an intro scope to the expansion for hygiene
- Returns the expanded syntax in the value register
The expanded result may itself contain macro invocations, so the caller should recursively expand it.
func (*ExpanderTimeContinuation) ExpandSyntaxOrProcedureCall ¶
func (p *ExpanderTimeContinuation) ExpandSyntaxOrProcedureCall(car syntax.SyntaxValue, cdr syntax.SyntaxValue) (syntax.SyntaxValue, error)
ExpandSyntaxOrProcedureCall handles a list expression. The car may be a symbol (possibly a macro), a nested pair (computed procedure), or a self-evaluating value (like in quoted data or malformed expressions).
func (*ExpanderTimeContinuation) SetMaxDepth ¶ added in v1.17.0
func (p *ExpanderTimeContinuation) SetMaxDepth(n int)
SetMaxDepth sets the maximum structural recursion depth allowed during expansion for this run. A value of 0 (or negative, clamped to 0) disables the limit. Mirrors the parser's SetMaxDepth and MachineContext.SetMaxCallDepth.
type FSFileResolver ¶
type FSFileResolver = resolver.FSFileResolver
func NewFSFileResolver ¶
func NewFSFileResolver(fsys fs.FS, env *environment.EnvironmentFrame) *FSFileResolver
NewFSFileResolver creates a resolver backed by a virtual filesystem.
type FeatureRequirement ¶
type FeatureRequirement interface {
// IsSatisfied returns true if this requirement is satisfied.
// The registry parameter is used to check if a library is already loaded.
// The resolver parameter is used to check if a library file exists
// (via the FileResolver chain, supporting both OS and virtual fs.FS).
IsSatisfied(ctx context.Context, registry *LibraryRegistry, resolver FileResolver) bool
}
FeatureRequirement represents a parsed cond-expand feature requirement. Feature requirements can be:
- A symbol (feature identifier)
- (library <library-name>) - check if library is available
- (and <req> ...) - all requirements must be satisfied
- (or <req> ...) - at least one requirement must be satisfied
- (not <req>) - requirement must NOT be satisfied
func NewAndRequirement ¶
func NewAndRequirement(reqs ...FeatureRequirement) FeatureRequirement
NewAndRequirement creates an and requirement.
func NewElseRequirement ¶
func NewElseRequirement() FeatureRequirement
NewElseRequirement creates an else requirement (always satisfied).
func NewFeatureIdentifier ¶
func NewFeatureIdentifier(name string) FeatureRequirement
NewFeatureIdentifier creates a feature identifier requirement.
func NewLibraryRequirement ¶
func NewLibraryRequirement(name LibraryName) FeatureRequirement
NewLibraryRequirement creates a library requirement.
func NewNotRequirement ¶
func NewNotRequirement(req FeatureRequirement) FeatureRequirement
NewNotRequirement creates a not requirement.
func NewOrRequirement ¶
func NewOrRequirement(reqs ...FeatureRequirement) FeatureRequirement
NewOrRequirement creates an or requirement.
type FileResolver ¶
type FileResolver = environment.FileResolver
FileResolver resolves and opens files for include/load operations. The interface is defined in the environment package; this alias keeps the name available in compilation without re-declaration.
Concrete resolver types (OSFileResolver, EmbedFileResolver, FSFileResolver, ChainFileResolver) and their constructors live in the resolver sub-package. Backward-compatible aliases are provided in resolver_compat.go.
type FreeIdResolution ¶ added in v1.13.21
type FreeIdResolution struct {
Global *environment.GlobalIndex
LocalScopes []*syntax.Scope
HasLocalBinding bool
LibScope *syntax.Scope
}
FreeIdResolution records how a free identifier in a syntax-rules template was bound at macro definition time. The match package uses this during template expansion to preserve hygiene.
Implements localScopesProvider, globalBindingProvider, hasLocalBindingProvider, and libraryScopeProvider from the match package.
func (*FreeIdResolution) GetGlobal ¶ added in v1.13.21
func (p *FreeIdResolution) GetGlobal() *environment.GlobalIndex
GetGlobal implements the globalBindingProvider interface.
func (*FreeIdResolution) GetHasLocalBinding ¶ added in v1.13.21
func (p *FreeIdResolution) GetHasLocalBinding() bool
GetHasLocalBinding implements the hasLocalBindingProvider interface.
func (*FreeIdResolution) GetLibraryScope ¶ added in v1.13.21
func (p *FreeIdResolution) GetLibraryScope() *syntax.Scope
GetLibraryScope implements the libraryScopeProvider interface.
func (*FreeIdResolution) GetLocalScopes ¶ added in v1.13.21
func (p *FreeIdResolution) GetLocalScopes() []*syntax.Scope
GetLocalScopes implements the localScopesProvider interface.
type ImportSet ¶
type ImportSet struct {
LibraryName LibraryName // Base library to import from
Only map[string]struct{} // If non-nil, only import these names
Except map[string]struct{} // If non-nil, import all except these
Prefix string // If non-empty, add this prefix to all names
Renames map[string]string // old-name -> new-name
PhaseShift environment.Phase // Phase offset: 0=runtime, 1=for-syntax, -1=for-template
}
ImportSet represents a parsed import specification. It can be a simple library reference or include modifiers.
PhaseShift supports Racket-style phased imports:
- (import (scheme base)) ; Phase 0 (runtime) - default
- (import (for-syntax (scheme base))) ; Phase +1 (expand)
- (import (for-template (scheme base))) ; Phase -1
- (import (for-meta 2 (scheme base))) ; Phase +2
- (import (for-meta -1 (scheme base))) ; Phase -1 (same as for-template)
Phase shifts compose additively: (for-syntax (for-syntax lib)) = phase +2
func NewImportSet ¶
func NewImportSet(name LibraryName) *ImportSet
NewImportSet creates a new import set for a library.
func ParseImportSetFromDatum ¶
ParseImportSetFromDatum parses an import set from datum values. Used at both runtime (by the 'environment' procedure) and compile time (via UnwrapAll on syntax objects).
Import sets can be:
- (<library-name>) : import all exports
- (only <import-set> <id> ...) : import only specified identifiers
- (except <import-set> <id> ...): import all except specified
- (prefix <import-set> <prefix>): add prefix to all imported names
- (rename <import-set> (<old> <new>) ...): rename specific imports
- (for-syntax <import-set>) : import at phase +1 (macro expansion)
- (for-template <import-set>) : import at phase -1
- (for-meta <n> <import-set>) : import at phase +n
func (*ImportSet) ApplyToExports ¶
func (p *ImportSet) ApplyToExports(lib *CompiledLibrary) (map[string]string, error)
ApplyToExports applies the import modifiers and returns the final bindings. Returns a map of local-name -> external-name (the name in the library).
type LibraryExportIndex ¶ added in v1.12.0
type LibraryExportIndex struct {
// contains filtered or unexported fields
}
LibraryExportIndex maps library keys to their summaries. Immutable after construction.
func BuildExportIndex ¶ added in v1.12.0
func BuildExportIndex(ctx context.Context, res FileResolver, reg *LibraryRegistry) (*LibraryExportIndex, error)
BuildExportIndex scans all discoverable library files via the resolver's FileEnumerator, parses their exports, and returns a LibraryExportIndex. Libraries already loaded in reg are skipped (their metadata is already available via the registry). If the resolver does not implement FileEnumerator, an empty index is returned (not an error).
func NewLibraryExportIndexFromEntries ¶ added in v1.12.0
func NewLibraryExportIndexFromEntries(entries map[string]*LibrarySummary) *LibraryExportIndex
NewLibraryExportIndexFromEntries creates an index from pre-built entries.
func (*LibraryExportIndex) Entries ¶ added in v1.12.0
func (p *LibraryExportIndex) Entries() []*LibrarySummary
Entries returns all indexed summaries sorted by library key.
func (*LibraryExportIndex) Lookup ¶ added in v1.12.0
func (p *LibraryExportIndex) Lookup(name LibraryName) *LibrarySummary
Lookup returns the summary for a library, or nil if not indexed.
type LibraryImportEvent ¶
type LibraryImportEvent struct {
Library LibraryName // imported library name, e.g., (scheme base)
SourceFile string // path to .sld file (empty for synthetic libraries)
Exports []string // all names exported by the library
Imported []string // names that actually landed in the importer (after only/except/prefix/rename)
Importer LibraryName // importing library name (zero value for top-level import)
Phase environment.Phase // pipeline phase: environment.PhaseExpand or environment.PhaseCompile
}
LibraryImportEvent records what happened when a library was imported.
type LibraryImportObserver ¶
type LibraryImportObserver func(LibraryImportEvent)
LibraryImportObserver is called when a library is imported. Observers are read-only — they cannot influence the import.
type LibraryName ¶
type LibraryName struct {
Parts []string // e.g., ["scheme", "base"]
}
LibraryName represents an R7RS library name like (scheme base) or (my lib). Library names are lists of identifiers used to uniquely identify a library.
func DiscoverAvailableLibraries ¶
func DiscoverAvailableLibraries(res FileResolver, reg *LibraryRegistry) ([]LibraryName, error)
DiscoverAvailableLibraries returns all importable library names by combining filesystem discovery (via the resolver's FileEnumerator) with registry-known libraries (synthetic extension libraries). Returns a sorted, deduplicated list.
If the resolver does not implement FileEnumerator, only registry libraries are returned. If reg is nil, only filesystem libraries are returned.
func FilePathToLibraryName ¶
func FilePathToLibraryName(path string) (LibraryName, error)
FilePathToLibraryName converts a forward-slash-separated file path with .sld or .scm extension to a LibraryName. This is the inverse of ToFSPath(). Returns an error if the path has no recognized extension or is empty.
func NewLibraryName ¶
func NewLibraryName(parts ...string) LibraryName
NewLibraryName creates a LibraryName from a list of string parts.
func ParseLibraryNameFromDatum ¶
ParseLibraryNameFromDatum extracts a LibraryName from a datum list like (scheme base). Used at both runtime (by the 'environment' procedure) and compile time (via UnwrapAll on syntax objects).
func (LibraryName) Key ¶
func (p LibraryName) Key() string
Key returns a unique string key for map lookups.
func (LibraryName) SchemeString ¶
func (p LibraryName) SchemeString() string
SchemeString returns the Scheme representation like "(scheme base)".
func (LibraryName) String ¶
func (p LibraryName) String() string
String returns a human-readable representation like "scheme/base".
func (LibraryName) ToFSPath ¶
func (p LibraryName) ToFSPath() string
ToFSPath returns the library name as a forward-slash-separated path with .sld extension, suitable for fs.FS and FileResolver operations.
func (LibraryName) ToSchemeValue ¶
func (p LibraryName) ToSchemeValue() values.Value
ToSchemeValue converts a LibraryName to a Scheme list. Parts that parse as nonnegative integers become exact integers; all others become symbols. Matches R7RS library name syntax.
type LibraryRegistry ¶
type LibraryRegistry struct {
// contains filtered or unexported fields
}
LibraryRegistry manages loaded libraries and handles library loading.
func NewLibraryRegistry ¶
func NewLibraryRegistry() *LibraryRegistry
NewLibraryRegistry creates a new library registry with default search paths.
func (*LibraryRegistry) All ¶
func (p *LibraryRegistry) All() []*CompiledLibrary
All returns all loaded libraries, sorted by name key for determinism.
func (*LibraryRegistry) AllNames ¶
func (p *LibraryRegistry) AllNames() []LibraryName
AllNames returns the names of all registered libraries, sorted by key.
func (*LibraryRegistry) FinishLoading ¶
func (p *LibraryRegistry) FinishLoading(name LibraryName)
FinishLoading marks a library as finished loading.
func (*LibraryRegistry) GetSearchPaths ¶
func (p *LibraryRegistry) GetSearchPaths() []string
GetSearchPaths returns the current library search paths.
func (*LibraryRegistry) ImportObserver ¶
func (p *LibraryRegistry) ImportObserver() LibraryImportObserver
ImportObserver returns the current import observer, or nil.
func (*LibraryRegistry) IsLoading ¶
func (p *LibraryRegistry) IsLoading(name LibraryName) bool
IsLoading returns true if the library is currently being loaded. Used to detect circular dependencies.
func (*LibraryRegistry) Lookup ¶
func (p *LibraryRegistry) Lookup(name LibraryName) *CompiledLibrary
Lookup returns a library by name, or nil if not found.
func (*LibraryRegistry) PrependSearchPath ¶
func (p *LibraryRegistry) PrependSearchPath(path string)
PrependSearchPath adds a path to the beginning of the search path list.
func (*LibraryRegistry) Register ¶
func (p *LibraryRegistry) Register(lib *CompiledLibrary) error
Register adds a compiled library to the registry.
func (*LibraryRegistry) SetImportObserver ¶
func (p *LibraryRegistry) SetImportObserver(obs LibraryImportObserver)
SetImportObserver sets an optional observer that is called each time a library is imported. The observer is read-only and cannot influence the import. Pass nil to remove the observer.
func (*LibraryRegistry) SetSearchPaths ¶
func (p *LibraryRegistry) SetSearchPaths(paths []string)
SetSearchPaths sets the library search paths.
func (*LibraryRegistry) StartLoading ¶
func (p *LibraryRegistry) StartLoading(name LibraryName)
StartLoading marks a library as being loaded.
type LibrarySummary ¶ added in v1.12.0
type LibrarySummary struct {
Name LibraryName
Description string
Exports []string
SourceFile string
}
LibrarySummary holds the statically-extracted metadata for a single library definition file (.sld). It captures exports and description without compiling or executing any library code.
func ParseLibrarySummary ¶ added in v1.12.0
func ParseLibrarySummary(ctx context.Context, r io.Reader, filePath string, name LibraryName) (*LibrarySummary, error)
ParseLibrarySummary reads a library definition from r and extracts its export list and description without compiling the library. This is a best-effort parser: malformed export specs are silently skipped.
type OSFileResolver ¶
type OSFileResolver = resolver.OSFileResolver
func NewOSFileResolver ¶
func NewOSFileResolver(env *environment.EnvironmentFrame) *OSFileResolver
NewOSFileResolver creates a resolver backed by the OS filesystem.
type OperationBindPatternVars ¶ added in v1.13.21
type OperationBindPatternVars struct {
machine.OperationBase
PatternVars []string // Ordered list for consistent indexing
}
OperationBindPatternVars binds pattern variables from the last match into a new local environment frame that is pushed onto the current environment.
This operation creates a new environment frame with local slots for each pattern variable, binds the matched values, and makes this the current environment.
func NewOperationBindPatternVars ¶ added in v1.13.21
func NewOperationBindPatternVars(patternVars map[string]struct{}) *OperationBindPatternVars
func (*OperationBindPatternVars) Apply ¶ added in v1.13.21
func (p *OperationBindPatternVars) Apply(mc *machine.MachineContext) (*machine.MachineContext, error)
func (*OperationBindPatternVars) EqualTo ¶ added in v1.13.21
func (p *OperationBindPatternVars) EqualTo(other values.Value) bool
func (*OperationBindPatternVars) OpKind ¶ added in v1.16.0
func (*OperationBindPatternVars) OpKind() machine.OpCode
type OperationBuildSyntaxList ¶ added in v1.13.21
type OperationBuildSyntaxList struct {
machine.OperationBase
Count int
}
OperationBuildSyntaxList builds a syntax list from elements on the eval stack. n elements are popped from the stack (in reverse order) and consed into a list.
func NewOperationBuildSyntaxList ¶ added in v1.13.21
func NewOperationBuildSyntaxList(count int) *OperationBuildSyntaxList
NewOperationBuildSyntaxList creates a new OperationBuildSyntaxList.
func (*OperationBuildSyntaxList) Apply ¶ added in v1.13.21
func (p *OperationBuildSyntaxList) Apply(mc *machine.MachineContext) (*machine.MachineContext, error)
Apply implements the Operation interface.
func (*OperationBuildSyntaxList) EqualTo ¶ added in v1.13.21
func (p *OperationBuildSyntaxList) EqualTo(other values.Value) bool
func (*OperationBuildSyntaxList) OpKind ¶ added in v1.16.0
func (*OperationBuildSyntaxList) OpKind() machine.OpCode
type OperationClearSyntaxCaseInput ¶ added in v1.13.21
type OperationClearSyntaxCaseInput struct {
machine.OperationBase
}
OperationClearSyntaxCaseInput clears the per-context syntax-case state. This is called at the end of a syntax-case form.
func NewOperationClearSyntaxCaseInput ¶ added in v1.13.21
func NewOperationClearSyntaxCaseInput() *OperationClearSyntaxCaseInput
func (*OperationClearSyntaxCaseInput) Apply ¶ added in v1.13.21
func (p *OperationClearSyntaxCaseInput) Apply(mc *machine.MachineContext) (*machine.MachineContext, error)
func (*OperationClearSyntaxCaseInput) EqualTo ¶ added in v1.13.21
func (p *OperationClearSyntaxCaseInput) EqualTo(other values.Value) bool
func (*OperationClearSyntaxCaseInput) OpKind ¶ added in v1.16.0
func (*OperationClearSyntaxCaseInput) OpKind() machine.OpCode
type OperationStoreSyntaxCaseInput ¶ added in v1.13.21
type OperationStoreSyntaxCaseInput struct {
machine.OperationBase
}
OperationStoreSyntaxCaseInput stores the value register into the per-context syntaxCaseState for use by OperationSyntaxCaseMatch.
func NewOperationStoreSyntaxCaseInput ¶ added in v1.13.21
func NewOperationStoreSyntaxCaseInput() *OperationStoreSyntaxCaseInput
func (*OperationStoreSyntaxCaseInput) Apply ¶ added in v1.13.21
func (p *OperationStoreSyntaxCaseInput) Apply(mc *machine.MachineContext) (*machine.MachineContext, error)
func (*OperationStoreSyntaxCaseInput) EqualTo ¶ added in v1.13.21
func (p *OperationStoreSyntaxCaseInput) EqualTo(other values.Value) bool
func (*OperationStoreSyntaxCaseInput) OpKind ¶ added in v1.16.0
func (*OperationStoreSyntaxCaseInput) OpKind() machine.OpCode
type OperationSyntaxCaseMatch ¶ added in v1.13.21
type OperationSyntaxCaseMatch struct {
machine.OperationBase
}
OperationSyntaxCaseMatch performs pattern matching for syntax-case.
Expects:
- Value register: syntaxCaseClause with compiled pattern
- Per-context syntaxCaseState.input: input syntax object (set by OperationStoreSyntaxCaseInput)
Results:
- If match succeeds: value register = #t, pattern bindings stored in context
- If match fails: value register = #f
func NewOperationSyntaxCaseMatch ¶ added in v1.13.21
func NewOperationSyntaxCaseMatch() *OperationSyntaxCaseMatch
func (*OperationSyntaxCaseMatch) Apply ¶ added in v1.13.21
func (p *OperationSyntaxCaseMatch) Apply(mc *machine.MachineContext) (*machine.MachineContext, error)
func (*OperationSyntaxCaseMatch) EqualTo ¶ added in v1.13.21
func (p *OperationSyntaxCaseMatch) EqualTo(other values.Value) bool
func (*OperationSyntaxCaseMatch) OpKind ¶ added in v1.16.0
func (*OperationSyntaxCaseMatch) OpKind() machine.OpCode
type OperationSyntaxCaseNoMatch ¶ added in v1.13.21
type OperationSyntaxCaseNoMatch struct {
machine.OperationBase
}
OperationSyntaxCaseNoMatch is emitted at the end of syntax-case when no clause matches.
func NewOperationSyntaxCaseNoMatch ¶ added in v1.13.21
func NewOperationSyntaxCaseNoMatch() *OperationSyntaxCaseNoMatch
func (*OperationSyntaxCaseNoMatch) Apply ¶ added in v1.13.21
func (p *OperationSyntaxCaseNoMatch) Apply(mc *machine.MachineContext) (*machine.MachineContext, error)
func (*OperationSyntaxCaseNoMatch) EqualTo ¶ added in v1.13.21
func (p *OperationSyntaxCaseNoMatch) EqualTo(other values.Value) bool
func (*OperationSyntaxCaseNoMatch) OpKind ¶ added in v1.16.0
func (*OperationSyntaxCaseNoMatch) OpKind() machine.OpCode
type OperationSyntaxRulesTransform ¶ added in v1.13.21
type OperationSyntaxRulesTransform struct {
machine.OperationBase
}
OperationSyntaxRulesTransform is a VM operation that performs macro expansion.
Execution context:
- Value register: contains clausesWrapper with compiled pattern/template pairs
- Local parameter 0: contains the input form (the macro invocation)
The operation is part of the transformer closure created by CompileSyntaxRules.
func NewOperationSyntaxRulesTransform ¶ added in v1.13.21
func NewOperationSyntaxRulesTransform() *OperationSyntaxRulesTransform
func (*OperationSyntaxRulesTransform) Apply ¶ added in v1.13.21
func (p *OperationSyntaxRulesTransform) Apply(mc *machine.MachineContext) (*machine.MachineContext, error)
func (*OperationSyntaxRulesTransform) EqualTo ¶ added in v1.13.21
func (p *OperationSyntaxRulesTransform) EqualTo(other values.Value) bool
func (*OperationSyntaxRulesTransform) OpKind ¶ added in v1.16.0
func (*OperationSyntaxRulesTransform) OpKind() machine.OpCode
type OperationSyntaxTemplateExpand ¶ added in v1.13.21
type OperationSyntaxTemplateExpand struct {
machine.OperationBase
}
OperationSyntaxTemplateExpand expands a syntax template using the current pattern variable bindings. This is used for templates containing ellipsis, which require runtime expansion rather than compile-time code generation.
The template is stored in the value register (loaded from literals). The result is the expanded syntax object, left in the value register.
func NewOperationSyntaxTemplateExpand ¶ added in v1.13.21
func NewOperationSyntaxTemplateExpand() *OperationSyntaxTemplateExpand
func (*OperationSyntaxTemplateExpand) Apply ¶ added in v1.13.21
func (p *OperationSyntaxTemplateExpand) Apply(mc *machine.MachineContext) (*machine.MachineContext, error)
func (*OperationSyntaxTemplateExpand) EqualTo ¶ added in v1.13.21
func (p *OperationSyntaxTemplateExpand) EqualTo(other values.Value) bool
func (*OperationSyntaxTemplateExpand) OpKind ¶ added in v1.16.0
func (*OperationSyntaxTemplateExpand) OpKind() machine.OpCode
type PhaseEntry ¶
PhaseEntry represents a named item to register in a phase environment.
type PrimitiveExpander ¶
type PrimitiveExpander struct {
// contains filtered or unexported fields
}
PrimitiveExpander wraps a PrimitiveExpanderFunc as a values.Value so it can be stored in the environment.
func LookupPrimitiveExpander ¶
func LookupPrimitiveExpander(env *environment.EnvironmentFrame, sym *values.Symbol, scopes []*syntax.Scope) *PrimitiveExpander
LookupPrimitiveExpander looks up a primitive expander by symbol in the expand environment. Returns the PrimitiveExpander if found, or nil if the symbol does not name a primitive expander.
This function handles hygiene by using scoped lookup - it will only match bindings whose scopes are a subset of the symbol's scopes.
func NewPrimitiveExpander ¶
func NewPrimitiveExpander(name string, fn PrimitiveExpanderFunc) *PrimitiveExpander
NewPrimitiveExpander creates a new primitive expander.
func (*PrimitiveExpander) EqualTo ¶
func (p *PrimitiveExpander) EqualTo(other values.Value) bool
EqualTo implements values.Value interface.
func (*PrimitiveExpander) Expand ¶
func (p *PrimitiveExpander) Expand( etc *ExpanderTimeContinuation, sym *syntax.SyntaxSymbol, expr syntax.SyntaxValue, ) (syntax.SyntaxValue, error)
Expand invokes the primitive expander function.
func (*PrimitiveExpander) IsVoid ¶
func (p *PrimitiveExpander) IsVoid() bool
IsVoid returns false — named handlers are never void.
func (*PrimitiveExpander) Name ¶
func (p *PrimitiveExpander) Name() string
Name returns the handler's name.
func (*PrimitiveExpander) SchemeString ¶
func (p *PrimitiveExpander) SchemeString() string
SchemeString returns the Scheme representation: #<prefix:name>.
type PrimitiveExpanderFunc ¶
type PrimitiveExpanderFunc func( etc *ExpanderTimeContinuation, sym *syntax.SyntaxSymbol, expr syntax.SyntaxValue, ) (syntax.SyntaxValue, error)
PrimitiveExpanderFunc is the type for expand-time special form handlers. These functions handle macro expansion of primitive forms like `if`, `lambda`, `define`, `quote`, etc.
Parameters:
- etc: The expander-time continuation (expander state, carries context)
- sym: The keyword symbol (e.g., 'if', 'lambda')
- expr: The expression arguments (everything after the keyword)
Returns the expanded syntax value.
type ResolvedImportSet ¶
type ResolvedImportSet struct {
ImportSet *ImportSet
Library *CompiledLibrary
Bindings map[string]string // localName -> externalName
}
ResolvedImportSet holds the result of parsing and loading an import set. This is the shared prefix of all import processing: parse the import set datum, load the named library, and apply modifiers (only, except, prefix, rename) to produce the final binding map.
type SourcedError ¶ added in v1.14.0
type SourcedError struct {
Source *syntax.SourceContext
Cause error
}
SourcedError wraps a compilation error with the source location where it occurred. The compiler tracks source context via pushSource/popSource; wrapCompilationError attaches the current source to errors so that callers (especially the public Engine API) can report file:line:col.
Use errors.As to extract the source from an error chain:
var se *compilation.SourcedError
if errors.As(err, &se) && se.Source != nil { ... }
func (*SourcedError) Error ¶ added in v1.14.0
func (p *SourcedError) Error() string
func (*SourcedError) Unwrap ¶ added in v1.14.0
func (p *SourcedError) Unwrap() error
type SyntaxCaseClause ¶ added in v1.13.21
type SyntaxCaseClause struct {
Bytecode []match.SyntaxCommand
PatternVars map[string]struct{}
EllipsisVars map[int]map[string]struct{}
EllipsisDepths map[int]int
}
SyntaxCaseClause wraps compiled pattern info for a syntax-case clause. Created by the compiler, consumed by OperationSyntaxCaseMatch at runtime.
func (*SyntaxCaseClause) EqualTo ¶ added in v1.13.21
func (p *SyntaxCaseClause) EqualTo(other values.Value) bool
func (*SyntaxCaseClause) IsVoid ¶ added in v1.13.21
func (p *SyntaxCaseClause) IsVoid() bool
func (*SyntaxCaseClause) SchemeString ¶ added in v1.13.21
func (p *SyntaxCaseClause) SchemeString() string
type SyntaxCompiler ¶
type SyntaxCompiler struct {
// contains filtered or unexported fields
}
SyntaxCompiler wraps a SyntaxCompilerFunc as a values.Value so it can be stored in the environment.
func LookupSyntaxCompiler ¶
func LookupSyntaxCompiler(env *environment.EnvironmentFrame, sym *values.Symbol, scopes []*syntax.Scope) *SyntaxCompiler
LookupSyntaxCompiler looks up a syntax compiler by symbol in the compile environment. Returns the SyntaxCompiler if found, or nil if the symbol does not name a syntax compiler.
This function handles hygiene by using scoped lookup - it will only match bindings whose scopes are a subset of the symbol's scopes.
func NewSyntaxCompiler ¶
func NewSyntaxCompiler(name string, fn SyntaxCompilerFunc) *SyntaxCompiler
NewSyntaxCompiler creates a new syntax compiler.
func (*SyntaxCompiler) Compile ¶
func (p *SyntaxCompiler) Compile(ctc *CompileTimeContinuation, ctctx CompileTimeCallContext, expr syntax.SyntaxValue) error
Compile invokes the syntax compiler function.
func (*SyntaxCompiler) EqualTo ¶
func (p *SyntaxCompiler) EqualTo(other values.Value) bool
EqualTo implements values.Value interface.
func (*SyntaxCompiler) IsVoid ¶
func (p *SyntaxCompiler) IsVoid() bool
IsVoid returns false — named handlers are never void.
func (*SyntaxCompiler) Name ¶
func (p *SyntaxCompiler) Name() string
Name returns the handler's name.
func (*SyntaxCompiler) SchemeString ¶
func (p *SyntaxCompiler) SchemeString() string
SchemeString returns the Scheme representation: #<prefix:name>.
type SyntaxCompilerFunc ¶
type SyntaxCompilerFunc func(ctc *CompileTimeContinuation, ctctx CompileTimeCallContext, expr syntax.SyntaxValue) error
SyntaxCompilerFunc is the type for compile-time special form handlers. These functions handle syntax-directed compilation of extension forms like `syntax-case`, `import`, `define-syntax`, `include`, etc.
Parameters:
- ctc: The compile-time continuation (compiler state)
- ctctx: The compile-time call context (tail position info, etc.)
- expr: The expression arguments (everything after the keyword)
The function should emit operations via ctc.AppendOperations and return nil on success.
type SyntaxRulesClause ¶ added in v1.13.21
type SyntaxRulesClause struct {
Template syntax.SyntaxValue
Bytecode []match.SyntaxCommand
Matcher *match.SyntaxMatcher
PatternVars map[string]struct{}
PatternVarSyntax map[string]*syntax.SyntaxSymbol
EllipsisVars map[int]map[string]struct{}
FreeIds map[string]*FreeIdResolution
Ellipsis string
LiteralSyntax map[string]*syntax.SyntaxSymbol
}
SyntaxRulesClause represents a single compiled pattern-template pair in a syntax-rules form. Created by the compiler, consumed by OperationSyntaxRulesTransform at runtime.
Source Files
¶
- compile_begin_for_syntax.go
- compile_call.go
- compile_closure.go
- compile_cond_expand.go
- compile_define.go
- compile_define_for_syntax.go
- compile_define_syntax.go
- compile_er_macro.go
- compile_eval_when.go
- compile_helpers.go
- compile_import.go
- compile_let.go
- compile_library_forms.go
- compile_literal_immutability.go
- compile_quasisyntax.go
- compile_syntax_case.go
- compile_syntax_form.go
- compile_syntax_rules.go
- compile_time_call_context.go
- compile_time_continuation.go
- compile_time_continuation_include.go
- compile_time_continuation_library.go
- compile_time_continuation_quasiquote.go
- compile_transformer.go
- compile_validated.go
- compile_with_syntax.go
- compiler_registry.go
- er_macro_compare.go
- er_macro_rename.go
- er_macro_transformer.go
- expand_and_compile.go
- expander_body.go
- expander_context.go
- expander_lambda.go
- expander_let.go
- expander_let_syntax.go
- expander_primitive_forms.go
- expander_time_continuation.go
- features.go
- file_resolver.go
- import_set_datum.go
- letrec_semantics.go
- library_bindings.go
- library_discovery.go
- library_export_index.go
- library_loader.go
- library_registry.go
- load_bootstrap.go
- named_handler_base.go
- op_kind.go
- operation_build_syntax.go
- operation_syntax_case.go
- operation_syntax_rules_transform.go
- phase_registry.go
- primitive_expander.go
- primitive_expanders_registry.go
- quasi_expand.go
- register.go
- resolver_compat.go
- sourced_error.go
- syntax_bridge_types.go
- syntax_compiler.go
- syntax_compilers_registry.go
Directories
¶
| Path | Synopsis |
|---|---|
|
Package resolver provides file resolution infrastructure for the Scheme compiler.
|
Package resolver provides file resolution infrastructure for the Scheme compiler. |
|
Package sourceload provides file-finding and load-stack tracking for locating source files across virtual filesystems.
|
Package sourceload provides file-finding and load-stack tracking for locating source files across virtual filesystems. |