schemeutil

package
v1.20.0 Latest Latest
Warning

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

Go to latest
Published: Aug 26, 2026 License: Apache-2.0 Imports: 5 Imported by: 0

Documentation

Overview

Package schemeutil provides conversion utilities between syntax, datum, and Go types.

Syntax/Datum Conversion

To strip source location and scope information from a syntax object, call syntax.SyntaxValue.UnwrapAll on it directly. There is no SyntaxValueToDatum here — an earlier function by that name had no production callers and was deleted in favor of the method form, which also handles circular structures correctly via its visited-set cache.

String Utilities for R7RS Lexical Syntax

Boolean conversion (BoolToBoolean and friends) lives in package values, not here.

Index

Constants

View Source
const DefaultMaxDatumToSyntaxDepth = 10000

DefaultMaxDatumToSyntaxDepth bounds structural NESTING depth when converting a datum to syntax. Without a bound, a deeply nested datum — one built at runtime, so no reader ever bounded it — triggers a fatal, unrecoverable Go stack overflow that kills the host process. Same rationale, and the same value, as parser.DefaultMaxParseDepth and values.DefaultMaxWriteDepth: what the reader refuses to READ and the writer refuses to WRITE, the converter refuses to CONVERT. Declared here rather than taken from pkg/parser because parser imports this package.

LENGTH is not bounded and does not need to be: both spine walks are iterative, so a list of any length costs constant stack.

Variables

This section is empty.

Functions

func DatumToSyntaxValue

func DatumToSyntaxValue(ctx context.Context, sctx *syntax.SourceContext, o values.Value) (syntax.SyntaxValue, error)

DatumToSyntaxValue wraps a raw Scheme datum in syntax objects, attaching the provided SourceContext for source location and scope tracking. Recursively wraps pairs, vectors, and boxed values. If the input is already a SyntaxValue, it is returned unchanged.

A circular datum is refused with werr.ErrCircularList. It has to be: every caller hands the result to the expander or the compiler, and a circular program is not a program. Before the refusal, (eval x) on a datum with a car, vector or box cycle killed the HOST PROCESS with a runtime stack overflow — a throw, not a panic, so no recover could contain it and every other engine in the process died with it. A cdr cycle failed more quietly and worse: the spine walk's ErrCircularList was discarded, the list was silently truncated at the cycle, and the mangled graph surfaced downstream as a diagnostic naming an internal syntax type.

Refusing here rather than memoizing into a cyclic syntax graph is the same rule the compiler already applies to circular quoted data, and it is the only one that terminates: a faithful cyclic graph merely moves the hang into the expander, which was measured before this shape was chosen.

func IndexExponentMarker

func IndexExponentMarker(s string) int

IndexExponentMarker returns the byte index of the first R7RS float exponent marker in s — any of e, E, s, S, f, F, d, D, l, L — or -1 if none is present. The marker set is deliberately wider than NormalizeExponentMarker's: callers detecting whether a token *is* scientific notation must recognize e/E, whereas NormalizeExponentMarker omits e/E because strconv.ParseFloat already accepts them and only the short s/f/d/l forms need folding. R7RS §7.1.1: all exponent markers are equivalent in Wile.

func IsSyntaxComment

func IsSyntaxComment(v values.Value) bool

IsSyntaxComment returns true if the given value is a SyntaxComment.

func NormalizeExponentMarker

func NormalizeExponentMarker(s string) string

NormalizeExponentMarker replaces an R7RS short float exponent marker (s, S, f, F, d, D, l, L) with 'e' so that strconv.ParseFloat can parse the number. R7RS §7.1.1: all exponent markers have the same meaning in Wile. Only the first marker is replaced; strings without one are returned unchanged.

func TrimPrefixCI

func TrimPrefixCI(s, prefix string) string

TrimPrefixCI returns s without the provided leading prefix string, using ASCII case-insensitive comparison. If s doesn't start with prefix (case-insensitively), s is returned unchanged.

func TrimSuffixCI

func TrimSuffixCI(s, suffix string) string

TrimSuffixCI returns s without the provided trailing suffix string, using ASCII case-insensitive comparison. If s doesn't end with suffix (case-insensitively), s is returned unchanged.

Types

This section is empty.

Jump to

Keyboard shortcuts

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