Documentation
¶
Overview ¶
Package syntax implements Scheme syntax representation with hygiene support.
The package wraps Scheme values with source location and scope information:
Syntax Types ¶
- SyntaxSymbol: symbols with scope tracking for hygiene
- SyntaxPair: cons cells with recursive scope propagation
- SyntaxVector: vectors with source context
- SyntaxObject: wrapper for self-evaluating values
All syntax types implement SyntaxValue, which provides:
- [SyntaxValue.SourceContext]: source location, scopes, and origin
- [SyntaxValue.Unwrap]: shallow unwrap to underlying value
- [SyntaxValue.UnwrapAll]: deep recursive unwrap
Hygiene ¶
The package implements Flatt's "sets of scopes" model for macro hygiene:
- Scope: unique identifier with optional rebinding flag
- [SourceContext.Scopes]: scope set attached to syntax objects
- ScopesMatch: binding/reference scope subset check
Source Tracking ¶
- SourceContext: file, line, column, text, scopes, and origin
- SourceIndexes: position within source (line, column, byte offset)
- OriginInfo: macro expansion chain for debugging
Index ¶
- func EqualTo(a, b SyntaxValue) bool
- func FormatOriginChain(origin *OriginInfo, maxDepth int) string
- func HasScope(scopes []*Scope, target *Scope) bool
- func IsSyntaxEmptyList(v SyntaxValue) bool
- func IsSyntaxList(v SyntaxValue) bool
- func IsSyntaxVoid(v SyntaxValue) bool
- func ScopesMatch(useScopes, bindingScopes []*Scope) bool
- func UnwrapAllShared(sv SyntaxValue, cache map[SyntaxValue]values.Value) values.Value
- type OriginInfo
- type Scope
- type SourceContext
- func (p *SourceContext) Clone() *SourceContext
- func (p *SourceContext) EqualTo(value values.Value) bool
- func (p *SourceContext) IsVoid() bool
- func (p *SourceContext) SchemeString() string
- func (p *SourceContext) WithOrigin(origin *OriginInfo) *SourceContext
- func (p *SourceContext) WithScope(scope *Scope) *SourceContext
- func (p *SourceContext) WithScopes(scopes []*Scope) *SourceContext
- func (p *SourceContext) WithoutScopes() *SourceContext
- type SourceIndexes
- func (p SourceIndexes) Column() int
- func (p SourceIndexes) EqualTo(o values.Value) bool
- func (p *SourceIndexes) Inc(n int) int
- func (p SourceIndexes) Index() int
- func (p SourceIndexes) IsVoid() bool
- func (p SourceIndexes) Line() int
- func (p *SourceIndexes) NewLine() int
- func (p SourceIndexes) SchemeString() string
- func (p *SourceIndexes) Tab() int
- type SymbolInterner
- type SyntaxComment
- func (p *SyntaxComment) AddScope(scope *Scope) SyntaxValue
- func (p *SyntaxComment) EqualTo(v values.Value) bool
- func (p *SyntaxComment) IsVoid() bool
- func (p *SyntaxComment) SchemeString() string
- func (b *SyntaxComment) SourceContext() *SourceContext
- func (p *SyntaxComment) Unwrap() values.Value
- func (p *SyntaxComment) UnwrapAll() values.Value
- type SyntaxDatumComment
- func (p *SyntaxDatumComment) AddScope(_ *Scope) SyntaxValue
- func (p *SyntaxDatumComment) EqualTo(v values.Value) bool
- func (p *SyntaxDatumComment) IsVoid() bool
- func (p *SyntaxDatumComment) SchemeString() string
- func (b *SyntaxDatumComment) SourceContext() *SourceContext
- func (p *SyntaxDatumComment) Unwrap() values.Value
- func (p *SyntaxDatumComment) UnwrapAll() values.Value
- type SyntaxDatumLabel
- func (p *SyntaxDatumLabel) AddScope(_ *Scope) SyntaxValue
- func (p *SyntaxDatumLabel) EqualTo(v values.Value) bool
- func (p *SyntaxDatumLabel) IsVoid() bool
- func (p *SyntaxDatumLabel) SchemeString() string
- func (b *SyntaxDatumLabel) SourceContext() *SourceContext
- func (p *SyntaxDatumLabel) Unwrap() values.Value
- func (p *SyntaxDatumLabel) UnwrapAll() values.Value
- type SyntaxDatumLabelAssignment
- func (p *SyntaxDatumLabelAssignment) AddScope(_ *Scope) SyntaxValue
- func (p *SyntaxDatumLabelAssignment) EqualTo(v values.Value) bool
- func (p *SyntaxDatumLabelAssignment) IsVoid() bool
- func (p *SyntaxDatumLabelAssignment) SchemeString() string
- func (b *SyntaxDatumLabelAssignment) SourceContext() *SourceContext
- func (p *SyntaxDatumLabelAssignment) Unwrap() values.Value
- func (p *SyntaxDatumLabelAssignment) UnwrapAll() values.Value
- type SyntaxDirective
- func (p *SyntaxDirective) AddScope(_ *Scope) SyntaxValue
- func (p *SyntaxDirective) EqualTo(v values.Value) bool
- func (p *SyntaxDirective) IsVoid() bool
- func (p *SyntaxDirective) SchemeString() string
- func (b *SyntaxDirective) SourceContext() *SourceContext
- func (p *SyntaxDirective) Unwrap() values.Value
- func (p *SyntaxDirective) UnwrapAll() values.Value
- type SyntaxForEachFunc
- type SyntaxObject
- func (p *SyntaxObject) Datum() values.Value
- func (p *SyntaxObject) EqualTo(v values.Value) bool
- func (p *SyntaxObject) IsEmptyList() bool
- func (p *SyntaxObject) IsPair() bool
- func (p *SyntaxObject) IsVoid() bool
- func (p *SyntaxObject) SchemeString() string
- func (b *SyntaxObject) SourceContext() *SourceContext
- func (p *SyntaxObject) Unwrap() values.Value
- func (p *SyntaxObject) UnwrapAll() values.Value
- type SyntaxPair
- func (p *SyntaxPair) AddScope(scope *Scope) SyntaxValue
- func (p *SyntaxPair) Append(vs values.Value) values.Value
- func (p *SyntaxPair) AsSyntaxVector() *SyntaxVector
- func (p *SyntaxPair) AsVector() *values.Vector
- func (p *SyntaxPair) Car() values.Value
- func (p *SyntaxPair) Cdr() values.Value
- func (p *SyntaxPair) EqualTo(o values.Value) bool
- func (p *SyntaxPair) ForEach(ctx context.Context, fn values.ForEachFunc) (values.Value, error)
- func (p *SyntaxPair) IsEmptyList() bool
- func (p *SyntaxPair) IsList() bool
- func (p *SyntaxPair) IsPair() bool
- func (p *SyntaxPair) IsVoid() bool
- func (p *SyntaxPair) Length() int
- func (p *SyntaxPair) SchemeString() string
- func (p *SyntaxPair) SetCar(v values.Value)
- func (p *SyntaxPair) SetCdr(v values.Value)
- func (p *SyntaxPair) SetSyntaxCar(v SyntaxValue)
- func (p *SyntaxPair) SetSyntaxCdr(v SyntaxValue)
- func (b *SyntaxPair) SourceContext() *SourceContext
- func (p *SyntaxPair) SyntaxAppend(vs SyntaxValue) SyntaxValue
- func (p *SyntaxPair) SyntaxCar() SyntaxValue
- func (p *SyntaxPair) SyntaxCdr() SyntaxValue
- func (p *SyntaxPair) SyntaxForEach(ctx context.Context, fn SyntaxForEachFunc) (SyntaxValue, error)
- func (p *SyntaxPair) Unwrap() values.Value
- func (p *SyntaxPair) UnwrapAll() values.Value
- type SyntaxSymbol
- func (p *SyntaxSymbol) AddScope(scope *Scope) SyntaxValue
- func (p *SyntaxSymbol) Datum() *values.Symbol
- func (p *SyntaxSymbol) EqualTo(o values.Value) bool
- func (p *SyntaxSymbol) IsVoid() bool
- func (p *SyntaxSymbol) SchemeString() string
- func (p *SyntaxSymbol) Scopes() []*Scope
- func (b *SyntaxSymbol) SourceContext() *SourceContext
- func (p *SyntaxSymbol) Unwrap() values.Value
- func (p *SyntaxSymbol) UnwrapAll() values.Value
- func (p *SyntaxSymbol) WithResolvedBinding(binding any) *SyntaxSymbol
- type SyntaxTuple
- type SyntaxValue
- type SyntaxVector
- func (p *SyntaxVector) AddScope(scope *Scope) SyntaxValue
- func (p *SyntaxVector) EqualTo(o values.Value) bool
- func (p *SyntaxVector) ForEach(ctx context.Context, fn values.ForEachFunc) (values.Value, error)
- func (p *SyntaxVector) IsVoid() bool
- func (p *SyntaxVector) SchemeString() string
- func (b *SyntaxVector) SourceContext() *SourceContext
- func (p *SyntaxVector) SyntaxForEach(ctx context.Context, fn SyntaxForEachFunc) (SyntaxValue, error)
- func (p *SyntaxVector) Unwrap() values.Value
- func (p *SyntaxVector) UnwrapAll() values.Value
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func EqualTo ¶
func EqualTo(a, b SyntaxValue) bool
EqualTo compares two syntax values for equality, handling nil and pointer identity.
func FormatOriginChain ¶
func FormatOriginChain(origin *OriginInfo, maxDepth int) string
FormatOriginChain returns a formatted string showing the macro expansion chain. maxDepth limits how many expansions to show (0 = unlimited).
func IsSyntaxEmptyList ¶
func IsSyntaxEmptyList(v SyntaxValue) bool
IsSyntaxEmptyList returns true if the value is the syntax empty list singleton.
func IsSyntaxList ¶
func IsSyntaxList(v SyntaxValue) bool
IsSyntaxList returns true if the value is a proper syntax list.
func IsSyntaxVoid ¶
func IsSyntaxVoid(v SyntaxValue) bool
IsSyntaxVoid returns true if the value is nil or void.
func ScopesMatch ¶
ScopesMatch checks if two sets of scopes are compatible for binding resolution. This implements the core hygiene check using Flatt's "sets of scopes" model: A reference matches a binding if the binding's scope set is a SUBSET of the reference's scope set.
This ensures: - Top-level bindings (empty scope set) match any reference: {} ⊆ X for all X - A macro-introduced binding only matches references with that macro's intro scope - User bindings don't capture macro-introduced identifiers (different scope sets)
Implementation note: Linear scan with pointer equality is intentionally used here. Scope sets are typically 0-4 elements (one per lexical form: macro invocation, lambda, let-syntax, with-binding-scope). For sets this small, linear scan is faster than hash-based or bitmap approaches due to cache locality and zero allocation overhead.
func UnwrapAllShared ¶
func UnwrapAllShared(sv SyntaxValue, cache map[SyntaxValue]values.Value) values.Value
UnwrapAllShared recursively unwraps a syntax value while preserving object identity. This is essential for datum labels (R7RS §2.4) where #n# must refer to the exact same object as #n=. The cache parameter tracks already-unwrapped syntax values to ensure the same SyntaxValue always unwraps to the same values.Value. This also handles circular structures by pre-registering placeholders before recursing.
Types ¶
type OriginInfo ¶
type OriginInfo struct {
Identifier string // Macro name that caused expansion (e.g., "let", "my-macro")
ApplicationID uint64 // Unique ID for this macro invocation (from intro scope)
Location *SourceContext // Where the macro was invoked (use-site)
TemplateLocation *SourceContext // Where the macro template was defined (definition-site)
Parent *OriginInfo // Previous link in origin chain (for nested macros)
}
OriginInfo tracks macro expansion chains for debugging and error reporting. Each OriginInfo represents one macro expansion in the chain, enabling:
- Tracing generated code back to the macro that created it
- Identifying which invocation (by unique ID) produced specific code
- Locating the template source that was expanded
func (*OriginInfo) Depth ¶
func (p *OriginInfo) Depth() int
Depth returns the length of the origin chain.
type Scope ¶
type Scope struct {
// IsRebinding indicates whether this scope can potentially rebind auxiliary syntax.
// True for let-syntax/letrec-syntax scopes which create local macro bindings.
// False for with-binding-scope which only adds scopes for binding hygiene.
// This distinction is used in literalScopesMatch to correctly handle auxiliary
// syntax like => and else in cond/case.
IsRebinding bool
// contains filtered or unexported fields
}
Scope is an identity marker for macro hygiene. Each macro invocation creates a fresh Scope. Hygiene checking uses pointer equality to determine if a binding's scopes are a subset of a reference's scopes. This implements Flatt's "sets of scopes" model where scopes are just unique tags, not environment hierarchies.
func AddScopeToSet ¶
AddScopeToSet adds a scope to a set if not already present
func FlipScopeInSet ¶
FlipScopeInSet toggles the presence of a scope in a set. If the scope is present, it is removed; if absent, it is added. This is the core operation for syntax-local-introduce.
func NewRebindingScope ¶
func NewRebindingScope() *Scope
NewRebindingScope creates a new scope that can potentially rebind auxiliary syntax. Used by let-syntax and letrec-syntax to mark scopes that could shadow literals.
func NewScope ¶
func NewScope() *Scope
NewScope creates a new scope with unique identity for hygiene tracking. By default, scopes are not rebinding scopes.
func RemoveScopeFromSet ¶
RemoveScopeFromSet removes a scope from a set
type SourceContext ¶
type SourceContext struct {
Text string
File string
Start SourceIndexes
End SourceIndexes
Scopes []*Scope // Scopes associated with this source location
Origin *OriginInfo // Macro expansion origin chain (nil if not from macro)
}
SourceContext holds source location and hygiene information for a syntax object.
func NewSourceContext ¶
func NewSourceContext(text, file string, start, end SourceIndexes) *SourceContext
NewSourceContext creates a new source context with the given location info.
func NewZeroValueSourceContext ¶
func NewZeroValueSourceContext() *SourceContext
NewZeroValueSourceContext creates an empty source context.
func (*SourceContext) Clone ¶ added in v1.4.0
func (p *SourceContext) Clone() *SourceContext
Clone returns a shallow copy of the SourceContext. The Scopes slice and Origin pointer are shared with the original; callers that need to mutate those fields should assign new values after cloning (which is exactly what the With* methods do).
func (*SourceContext) EqualTo ¶
func (p *SourceContext) EqualTo(value values.Value) bool
EqualTo returns true if this source context equals the given value.
func (*SourceContext) IsVoid ¶
func (p *SourceContext) IsVoid() bool
IsVoid returns true if the source context is nil.
func (*SourceContext) SchemeString ¶
func (p *SourceContext) SchemeString() string
SchemeString returns the Scheme representation of the source context.
func (*SourceContext) WithOrigin ¶
func (p *SourceContext) WithOrigin(origin *OriginInfo) *SourceContext
WithOrigin returns a new SourceContext with the given origin chain. Used to attach macro expansion tracking information to syntax objects.
func (*SourceContext) WithScope ¶
func (p *SourceContext) WithScope(scope *Scope) *SourceContext
WithScope returns a new SourceContext with an additional scope.
This is the primitive operation for adding hygiene scopes to syntax objects. In Flatt's "sets of scopes" model, each syntax object carries a set of scopes that identifies its binding context.
Design Decision: Scopes are stored in SourceContext rather than on individual syntax types. This treats scopes as source-location metadata, keeping the syntax types simpler and the scope management centralized.
The new scope is prepended to the list (most recent scope first). This doesn't affect the ScopesMatch algorithm, which uses set membership.
Returns a NEW SourceContext (immutable design for syntax objects).
func (*SourceContext) WithScopes ¶
func (p *SourceContext) WithScopes(scopes []*Scope) *SourceContext
WithScopes returns a new SourceContext with additional scopes
func (*SourceContext) WithoutScopes ¶
func (p *SourceContext) WithoutScopes() *SourceContext
WithoutScopes returns a new SourceContext with scopes cleared. Used when creating template identifiers that should not inherit use-site scopes during macro expansion (Flatt 2016 hygiene model).
type SourceIndexes ¶
type SourceIndexes struct {
// contains filtered or unexported fields
}
SourceIndexes tracks position within a source file (index, column, line).
func NewSourceIndexes ¶
func NewSourceIndexes(index, column, line int) SourceIndexes
NewSourceIndexes creates a new SourceIndexes with the given position.
func (SourceIndexes) Column ¶
func (p SourceIndexes) Column() int
Column returns the column number within the current line (0-based).
func (SourceIndexes) EqualTo ¶
func (p SourceIndexes) EqualTo(o values.Value) bool
EqualTo returns true if the positions are equal.
func (*SourceIndexes) Inc ¶
func (p *SourceIndexes) Inc(n int) int
Inc advances the position by n characters on the same line.
func (SourceIndexes) Index ¶
func (p SourceIndexes) Index() int
Index returns the absolute byte position in the source.
func (SourceIndexes) IsVoid ¶
func (p SourceIndexes) IsVoid() bool
IsVoid returns false; SourceIndexes is never void.
func (SourceIndexes) Line ¶
func (p SourceIndexes) Line() int
Line returns the line number (1-based).
func (*SourceIndexes) NewLine ¶
func (p *SourceIndexes) NewLine() int
NewLine updates column and line tracking for a newline character. The index should already have been advanced by Inc(n) before calling this.
func (SourceIndexes) SchemeString ¶
func (p SourceIndexes) SchemeString() string
SchemeString returns a string representation of the position.
func (*SourceIndexes) Tab ¶
func (p *SourceIndexes) Tab() int
Tab updates column tracking for a tab character (8-column tab stops). The index should already have been advanced by Inc(n) before calling this.
type SymbolInterner ¶
SymbolInterner is an interface for interning symbols. This allows SyntaxSymbol to cache interned symbols without importing the environment package (which would create a circular dependency).
type SyntaxComment ¶
type SyntaxComment struct {
Text string
// contains filtered or unexported fields
}
SyntaxComment represents a source comment (line or block) with source location.
func NewSyntaxComment ¶
func NewSyntaxComment(text string, sctx *SourceContext) *SyntaxComment
NewSyntaxComment creates a new syntax comment with the given text and source context.
func (*SyntaxComment) AddScope ¶
func (p *SyntaxComment) AddScope(scope *Scope) SyntaxValue
AddScope returns the comment unchanged (comments don't participate in hygiene).
func (*SyntaxComment) EqualTo ¶
func (p *SyntaxComment) EqualTo(v values.Value) bool
EqualTo returns true if the comments have the same text.
func (*SyntaxComment) IsVoid ¶
func (p *SyntaxComment) IsVoid() bool
IsVoid returns true if the comment is nil.
func (*SyntaxComment) SchemeString ¶
func (p *SyntaxComment) SchemeString() string
SchemeString returns the comment text.
func (*SyntaxComment) SourceContext ¶
func (b *SyntaxComment) SourceContext() *SourceContext
SourceContext returns the source context.
func (*SyntaxComment) Unwrap ¶
func (p *SyntaxComment) Unwrap() values.Value
func (*SyntaxComment) UnwrapAll ¶
func (p *SyntaxComment) UnwrapAll() values.Value
UnwrapAll returns the comment text as a string value.
type SyntaxDatumComment ¶
type SyntaxDatumComment struct {
Label string
Value SyntaxValue
// contains filtered or unexported fields
}
SyntaxDatumComment represents a datum comment (#;datum).
func NewSyntaxDatumComment ¶
func NewSyntaxDatumComment(label string, value SyntaxValue, sctx *SourceContext) *SyntaxDatumComment
NewSyntaxDatumComment creates a new datum comment.
func (*SyntaxDatumComment) AddScope ¶
func (p *SyntaxDatumComment) AddScope(_ *Scope) SyntaxValue
AddScope returns the comment unchanged (comments don't participate in hygiene).
func (*SyntaxDatumComment) EqualTo ¶
func (p *SyntaxDatumComment) EqualTo(v values.Value) bool
EqualTo compares datum comments by label and value.
func (*SyntaxDatumComment) IsVoid ¶
func (p *SyntaxDatumComment) IsVoid() bool
IsVoid returns true if the comment is nil.
func (*SyntaxDatumComment) SchemeString ¶
func (p *SyntaxDatumComment) SchemeString() string
SchemeString returns a string representation of the datum comment.
func (*SyntaxDatumComment) SourceContext ¶
func (b *SyntaxDatumComment) SourceContext() *SourceContext
SourceContext returns the source context.
func (*SyntaxDatumComment) Unwrap ¶
func (p *SyntaxDatumComment) Unwrap() values.Value
func (*SyntaxDatumComment) UnwrapAll ¶
func (p *SyntaxDatumComment) UnwrapAll() values.Value
UnwrapAll recursively unwraps the commented value.
type SyntaxDatumLabel ¶
type SyntaxDatumLabel struct {
Label int
// contains filtered or unexported fields
}
SyntaxDatumLabel represents a datum label reference (#n#).
func NewSyntaxDatumLabel ¶
func NewSyntaxDatumLabel(label int, sctx *SourceContext) *SyntaxDatumLabel
NewSyntaxDatumLabel creates a new datum label reference with the given number.
func (*SyntaxDatumLabel) AddScope ¶
func (p *SyntaxDatumLabel) AddScope(_ *Scope) SyntaxValue
AddScope returns the label unchanged (labels don't participate in hygiene).
func (*SyntaxDatumLabel) EqualTo ¶
func (p *SyntaxDatumLabel) EqualTo(v values.Value) bool
EqualTo returns true if the labels have the same number.
func (*SyntaxDatumLabel) IsVoid ¶
func (p *SyntaxDatumLabel) IsVoid() bool
IsVoid returns true if the label is nil.
func (*SyntaxDatumLabel) SchemeString ¶
func (p *SyntaxDatumLabel) SchemeString() string
SchemeString returns the label number as a string.
func (*SyntaxDatumLabel) SourceContext ¶
func (b *SyntaxDatumLabel) SourceContext() *SourceContext
SourceContext returns the source context.
func (*SyntaxDatumLabel) Unwrap ¶
func (p *SyntaxDatumLabel) Unwrap() values.Value
func (*SyntaxDatumLabel) UnwrapAll ¶
func (p *SyntaxDatumLabel) UnwrapAll() values.Value
UnwrapAll returns the label number as an integer value.
type SyntaxDatumLabelAssignment ¶
type SyntaxDatumLabelAssignment struct {
Label int
Value values.Value
// contains filtered or unexported fields
}
SyntaxDatumLabelAssignment represents a datum label assignment (#n=datum).
func NewSyntaxDatumLabelAssignment ¶
func NewSyntaxDatumLabelAssignment(label int, value values.Value, sctx *SourceContext) *SyntaxDatumLabelAssignment
NewSyntaxDatumLabelAssignment creates a new datum label assignment.
func (*SyntaxDatumLabelAssignment) AddScope ¶
func (p *SyntaxDatumLabelAssignment) AddScope(_ *Scope) SyntaxValue
AddScope returns the assignment unchanged (labels don't participate in hygiene).
func (*SyntaxDatumLabelAssignment) EqualTo ¶
func (p *SyntaxDatumLabelAssignment) EqualTo(v values.Value) bool
EqualTo returns true if both assignments are the same object.
func (*SyntaxDatumLabelAssignment) IsVoid ¶
func (p *SyntaxDatumLabelAssignment) IsVoid() bool
IsVoid returns true if the assignment is nil.
func (*SyntaxDatumLabelAssignment) SchemeString ¶
func (p *SyntaxDatumLabelAssignment) SchemeString() string
SchemeString returns the Scheme representation of the label.
func (*SyntaxDatumLabelAssignment) SourceContext ¶
func (b *SyntaxDatumLabelAssignment) SourceContext() *SourceContext
SourceContext returns the source context.
func (*SyntaxDatumLabelAssignment) Unwrap ¶
func (p *SyntaxDatumLabelAssignment) Unwrap() values.Value
func (*SyntaxDatumLabelAssignment) UnwrapAll ¶
func (p *SyntaxDatumLabelAssignment) UnwrapAll() values.Value
UnwrapAll recursively unwraps the assigned value.
type SyntaxDirective ¶
type SyntaxDirective struct {
Name string
// contains filtered or unexported fields
}
SyntaxDirective represents a reader directive (#!fold-case, etc.).
func NewSyntaxDirective ¶
func NewSyntaxDirective(name string, sctx *SourceContext) *SyntaxDirective
NewSyntaxDirective creates a new reader directive with the given name.
func (*SyntaxDirective) AddScope ¶
func (p *SyntaxDirective) AddScope(_ *Scope) SyntaxValue
AddScope returns the directive unchanged (directives don't participate in hygiene).
func (*SyntaxDirective) EqualTo ¶
func (p *SyntaxDirective) EqualTo(v values.Value) bool
EqualTo returns true if both directives have the same name.
func (*SyntaxDirective) IsVoid ¶
func (p *SyntaxDirective) IsVoid() bool
IsVoid returns true if the directive is nil.
func (*SyntaxDirective) SchemeString ¶
func (p *SyntaxDirective) SchemeString() string
SchemeString returns the directive name.
func (*SyntaxDirective) SourceContext ¶
func (b *SyntaxDirective) SourceContext() *SourceContext
SourceContext returns the source context.
func (*SyntaxDirective) Unwrap ¶
func (p *SyntaxDirective) Unwrap() values.Value
func (*SyntaxDirective) UnwrapAll ¶
func (p *SyntaxDirective) UnwrapAll() values.Value
UnwrapAll returns the directive name as a string value.
type SyntaxForEachFunc ¶
SyntaxForEachFunc is the callback type for iterating over syntax tuples.
type SyntaxObject ¶
type SyntaxObject struct {
// contains filtered or unexported fields
}
SyntaxObject wraps a non-compound Scheme value with source context.
func NewSyntaxObject ¶
func NewSyntaxObject(v values.Value, sctx *SourceContext) *SyntaxObject
NewSyntaxObject creates a new SyntaxObject wrapping the given value and source context. It panics if the value is already a syntax value to prevent double-wrapping.
func (*SyntaxObject) Datum ¶
func (p *SyntaxObject) Datum() values.Value
Datum returns the underlying datum of the syntax object.
func (*SyntaxObject) EqualTo ¶
func (p *SyntaxObject) EqualTo(v values.Value) bool
EqualTo performs pointer comparison only, matching Chez Scheme/Racket behavior. Two syntax objects are equal? only if they are the same object. For value comparison of syntax objects, use bound-identifier=? or free-identifier=?.
func (*SyntaxObject) IsEmptyList ¶
func (p *SyntaxObject) IsEmptyList() bool
IsEmptyList returns true if the wrapped datum is the empty list.
func (*SyntaxObject) IsPair ¶
func (p *SyntaxObject) IsPair() bool
IsPair returns true if the wrapped datum is a pair.
func (*SyntaxObject) IsVoid ¶
func (p *SyntaxObject) IsVoid() bool
IsVoid returns true if the syntax object is nil.
func (*SyntaxObject) SchemeString ¶
func (p *SyntaxObject) SchemeString() string
SchemeString returns the Scheme representation of the syntax object.
func (*SyntaxObject) SourceContext ¶
func (b *SyntaxObject) SourceContext() *SourceContext
SourceContext returns the source context.
func (*SyntaxObject) Unwrap ¶
func (p *SyntaxObject) Unwrap() values.Value
func (*SyntaxObject) UnwrapAll ¶
func (p *SyntaxObject) UnwrapAll() values.Value
UnwrapAll recursively unwraps all syntax wrappers and returns the underlying value.
type SyntaxPair ¶
type SyntaxPair struct {
Values [2]SyntaxValue
// contains filtered or unexported fields
}
SyntaxPair wraps a Scheme pair (cons cell) with source context.
func NewSyntaxCons ¶
func NewSyntaxCons(v0, v1 SyntaxValue, sctx *SourceContext) *SyntaxPair
NewSyntaxCons creates a new syntax pair (cons cell).
func (*SyntaxPair) AddScope ¶
func (p *SyntaxPair) AddScope(scope *Scope) SyntaxValue
AddScope recursively propagates a scope to all nested symbols.
This implements scope propagation for Flatt's "sets of scopes" hygiene. When a macro expands, the intro scope must be added to all identifiers (symbols) in the expansion. This method walks the pair structure and calls AddScope on each element, ultimately reaching the symbols.
Only symbols store scopes for hygiene resolution. Pairs just propagate.
func (*SyntaxPair) Append ¶
func (p *SyntaxPair) Append(vs values.Value) values.Value
Append appends a value to the end of the list.
func (*SyntaxPair) AsSyntaxVector ¶
func (p *SyntaxPair) AsSyntaxVector() *SyntaxVector
AsSyntaxVector converts the list to a syntax vector.
func (*SyntaxPair) AsVector ¶
func (p *SyntaxPair) AsVector() *values.Vector
AsVector converts the SyntaxPair (assumed to be a proper list) into a Vector of unwrapped values.
func (*SyntaxPair) EqualTo ¶
func (p *SyntaxPair) EqualTo(o values.Value) bool
EqualTo performs pointer comparison only, matching Chez Scheme/Racket behavior. Two syntax objects are equal? only if they are the same object. For value comparison of syntax objects, use bound-identifier=? or free-identifier=?.
func (*SyntaxPair) ForEach ¶
func (p *SyntaxPair) ForEach(ctx context.Context, fn values.ForEachFunc) (values.Value, error)
ForEach iterates over the elements of the list.
func (*SyntaxPair) IsEmptyList ¶
func (p *SyntaxPair) IsEmptyList() bool
IsEmptyList returns true if the pair represents an empty list.
func (*SyntaxPair) IsList ¶
func (p *SyntaxPair) IsList() bool
IsList returns true if the pair forms a proper list.
func (*SyntaxPair) IsPair ¶
func (p *SyntaxPair) IsPair() bool
IsPair returns true; SyntaxPair is always a pair.
func (*SyntaxPair) IsVoid ¶
func (p *SyntaxPair) IsVoid() bool
IsVoid returns true if the pair is nil.
func (*SyntaxPair) SchemeString ¶
func (p *SyntaxPair) SchemeString() string
SchemeString returns a string representation of the syntax pair.
func (*SyntaxPair) SetCar ¶
func (p *SyntaxPair) SetCar(v values.Value)
SetCar sets the car of the pair.
func (*SyntaxPair) SetCdr ¶
func (p *SyntaxPair) SetCdr(v values.Value)
SetCdr sets the cdr of the pair.
func (*SyntaxPair) SetSyntaxCar ¶
func (p *SyntaxPair) SetSyntaxCar(v SyntaxValue)
SetSyntaxCar sets the car of the pair to a syntax value.
func (*SyntaxPair) SetSyntaxCdr ¶
func (p *SyntaxPair) SetSyntaxCdr(v SyntaxValue)
SetSyntaxCdr sets the cdr of the pair to a syntax value.
func (*SyntaxPair) SourceContext ¶
func (b *SyntaxPair) SourceContext() *SourceContext
SourceContext returns the source context.
func (*SyntaxPair) SyntaxAppend ¶
func (p *SyntaxPair) SyntaxAppend(vs SyntaxValue) SyntaxValue
SyntaxAppend appends a syntax value to the end of the list.
func (*SyntaxPair) SyntaxCar ¶
func (p *SyntaxPair) SyntaxCar() SyntaxValue
SyntaxCar returns the car as a syntax value.
func (*SyntaxPair) SyntaxCdr ¶
func (p *SyntaxPair) SyntaxCdr() SyntaxValue
SyntaxCdr returns the cdr as a syntax value.
func (*SyntaxPair) SyntaxForEach ¶
func (p *SyntaxPair) SyntaxForEach(ctx context.Context, fn SyntaxForEachFunc) (SyntaxValue, error)
SyntaxForEach iterates over the syntax elements of the list.
func (*SyntaxPair) Unwrap ¶
func (p *SyntaxPair) Unwrap() values.Value
Unwrap returns a regular Scheme pair without recursively unwrapping.
func (*SyntaxPair) UnwrapAll ¶
func (p *SyntaxPair) UnwrapAll() values.Value
UnwrapAll recursively unwraps the pair and returns a regular Scheme pair.
type SyntaxSymbol ¶
type SyntaxSymbol struct {
Sym *values.Symbol
// ResolvedBinding holds a pre-resolved binding for free identifiers in macro templates.
// This is set during macro expansion for identifiers that should resolve to bindings
// in the macro's definition environment rather than the use-site environment.
// Type: *environment.GlobalIndex (stored as any to avoid circular import).
// nil for normal symbols; only set for free identifiers from macros.
ResolvedBinding any
// contains filtered or unexported fields
}
SyntaxSymbol wraps a Scheme symbol with source context and hygiene scopes.
func NewSyntaxSymbol ¶
func NewSyntaxSymbol(key string, sctx *SourceContext) *SyntaxSymbol
NewSyntaxSymbol creates a new syntax symbol from a key string.
func NewSyntaxSymbolForSymbol ¶
func NewSyntaxSymbolForSymbol(sym *values.Symbol, sctx *SourceContext) *SyntaxSymbol
NewSyntaxSymbolForSymbol creates a new syntax symbol from an existing symbol.
func NewSyntaxSymbolForSyntaxSymbol ¶
func NewSyntaxSymbolForSyntaxSymbol(sym *SyntaxSymbol, sctx *SourceContext) *SyntaxSymbol
NewSyntaxSymbolForSyntaxSymbol creates a new syntax symbol with a different source context.
func (*SyntaxSymbol) AddScope ¶
func (p *SyntaxSymbol) AddScope(scope *Scope) SyntaxValue
AddScope returns a new SyntaxSymbol with an additional scope. This is the core operation for implementing hygiene in Flatt's "sets of scopes" model. When a macro expands, an "intro scope" is added to all identifiers in the expansion. This scope distinguishes macro-introduced identifiers from user-provided ones.
The method returns a NEW SyntaxSymbol (syntax objects are immutable) with the scope added to its SourceContext. The SyntaxValue return type supports recursive scope propagation through nested syntax structures.
Example: When swap! macro introduces "tmp", that "tmp" gets the macro's intro scope. A user's "tmp" at the call site doesn't have this scope, so they're distinguished during variable resolution (see ScopesMatch in scope_utils.go).
func (*SyntaxSymbol) Datum ¶
func (p *SyntaxSymbol) Datum() *values.Symbol
Datum returns the underlying symbol.
func (*SyntaxSymbol) EqualTo ¶
func (p *SyntaxSymbol) EqualTo(o values.Value) bool
EqualTo performs pointer comparison only, matching Chez Scheme/Racket behavior. Two syntax objects are equal? only if they are the same object. For value comparison of syntax objects, use bound-identifier=? or free-identifier=?.
func (*SyntaxSymbol) IsVoid ¶
func (p *SyntaxSymbol) IsVoid() bool
IsVoid returns true if the syntax symbol is nil.
func (*SyntaxSymbol) SchemeString ¶
func (p *SyntaxSymbol) SchemeString() string
SchemeString returns a string representation of the syntax symbol.
func (*SyntaxSymbol) Scopes ¶
func (p *SyntaxSymbol) Scopes() []*Scope
Scopes returns the scopes of this syntax symbol
func (*SyntaxSymbol) SourceContext ¶
func (b *SyntaxSymbol) SourceContext() *SourceContext
SourceContext returns the source context.
func (*SyntaxSymbol) Unwrap ¶
func (p *SyntaxSymbol) Unwrap() values.Value
func (*SyntaxSymbol) UnwrapAll ¶
func (p *SyntaxSymbol) UnwrapAll() values.Value
UnwrapAll returns the underlying symbol value.
func (*SyntaxSymbol) WithResolvedBinding ¶
func (p *SyntaxSymbol) WithResolvedBinding(binding any) *SyntaxSymbol
WithResolvedBinding returns a new SyntaxSymbol with the given pre-resolved binding. This is used during macro expansion to tag free identifiers with their definition-site bindings, enabling proper resolution across library boundaries.
type SyntaxTuple ¶
type SyntaxTuple interface {
values.Tuple
SyntaxValue
SyntaxCar() SyntaxValue
SyntaxCdr() SyntaxValue
AsSyntaxVector() *SyntaxVector
SyntaxAppend(value SyntaxValue) SyntaxValue
SyntaxForEach(ctx context.Context, fn SyntaxForEachFunc) (SyntaxValue, error)
}
SyntaxTuple is the interface for syntax lists (pairs and vectors).
var ( // SyntaxEmptyList is the empty list singleton. // It implements SyntaxTuple but is not *SyntaxPair, enforcing type safety // parallel to values.EmptyList. Pointer identity enables O(1) equality checks. SyntaxEmptyList SyntaxTuple = &syntaxEmptyListType{} )
type SyntaxValue ¶
type SyntaxValue interface {
values.Value
SourceContext() *SourceContext
Unwrap() values.Value
UnwrapAll() values.Value
}
SyntaxValue is the interface for all syntax objects. It provides access to source context and unwrapping capabilities.
var SyntaxVoid SyntaxValue = syntaxVoidType{}
SyntaxVoid is the singleton syntax void value.
func AddScopeToSyntax ¶
func AddScopeToSyntax(stx SyntaxValue, scope *Scope) SyntaxValue
AddScopeToSyntax adds a scope to a syntax object. Returns a new syntax object with the scope added. This is used by syntax-local-identifier-as-binding to mark identifiers as binding sites. Only symbols and pairs receive scopes; self-evaluating literals (SyntaxObject) are returned unchanged.
func FlipScope ¶
func FlipScope(stx SyntaxValue, scope *Scope) SyntaxValue
FlipScope toggles the presence of a scope on a syntax object. Returns a new syntax object with the scope flipped. This is used by syntax-local-introduce to make introduced identifiers behave as if they came from the macro use site.
func SyntaxForEach ¶
func SyntaxForEach(ctx context.Context, o SyntaxValue, fn func(ctx context.Context, i int, hasNext bool, v SyntaxValue) error) (SyntaxValue, error)
SyntaxForEach iterates over a syntax tuple, calling fn for each element.
func SyntaxList ¶
func SyntaxList(sc *SourceContext, os ...SyntaxValue) SyntaxValue
SyntaxList constructs a syntax list from the given elements. The sc parameter provides a fallback source context for the list container. Each intermediate pair uses the source context of its car element when available, preserving per-element source location information for better error reporting.
type SyntaxVector ¶
type SyntaxVector struct {
Values []SyntaxValue
// contains filtered or unexported fields
}
SyntaxVector wraps a Scheme vector with source context.
func NewSyntaxVector ¶
func NewSyntaxVector(sc *SourceContext, vs ...SyntaxValue) *SyntaxVector
NewSyntaxVector creates a new syntax vector with the given source context and elements.
func (*SyntaxVector) AddScope ¶
func (p *SyntaxVector) AddScope(scope *Scope) SyntaxValue
AddScope recursively propagates a scope to all nested syntax values.
This implements scope propagation for Flatt's "sets of scopes" hygiene. When a macro expands, the intro scope must be added to all identifiers (symbols) in the expansion. This method walks the vector structure and calls AddScope on each element, ultimately reaching the symbols.
Only symbols store scopes for hygiene resolution. Vectors just propagate.
func (*SyntaxVector) EqualTo ¶
func (p *SyntaxVector) EqualTo(o values.Value) bool
EqualTo performs pointer comparison only, matching Chez Scheme/Racket behavior. Two syntax objects are equal? only if they are the same object. For value comparison of syntax objects, use bound-identifier=? or free-identifier=?.
func (*SyntaxVector) ForEach ¶ added in v1.2.0
func (p *SyntaxVector) ForEach(ctx context.Context, fn values.ForEachFunc) (values.Value, error)
ForEach iterates over the elements of the vector as regular values in index order. It provides tuple-style iteration compatible with values.ForEachFunc callbacks.
func (*SyntaxVector) IsVoid ¶
func (p *SyntaxVector) IsVoid() bool
IsVoid returns true if the syntax vector is nil.
func (*SyntaxVector) SchemeString ¶
func (p *SyntaxVector) SchemeString() string
SchemeString returns the Scheme representation of the syntax vector.
func (*SyntaxVector) SourceContext ¶
func (b *SyntaxVector) SourceContext() *SourceContext
SourceContext returns the source context.
func (*SyntaxVector) SyntaxForEach ¶ added in v1.2.0
func (p *SyntaxVector) SyntaxForEach(ctx context.Context, fn SyntaxForEachFunc) (SyntaxValue, error)
SyntaxForEach iterates over the syntax elements of the vector. A nil receiver is treated as the distinguished syntax void value and results in no iteration and a SyntaxVoid tail.
The callback is invoked for each element with its index and a boolean indicating whether there is another element after the current one. If the callback returns an error, iteration stops immediately and the error is returned.
func (*SyntaxVector) Unwrap ¶
func (p *SyntaxVector) Unwrap() values.Value
func (*SyntaxVector) UnwrapAll ¶
func (p *SyntaxVector) UnwrapAll() values.Value
UnwrapAll recursively unwraps all elements to produce a plain values.Vector.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package syntaxtest provides test helpers for the syntax package.
|
Package syntaxtest provides test helpers for the syntax package. |