lisp

package
v1.47.1 Latest Latest
Warning

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

Go to latest
Published: Apr 9, 2026 License: BSD-3-Clause Imports: 17 Imported by: 4

Documentation

Index

Constants

View Source
const (
	CondParseError          = "parse-error"
	CondScanError           = "scan-error"
	CondUnmatchedSyntax     = "unmatched-syntax"
	CondMismatchedSyntax    = "mismatched-syntax"
	CondInvalidSymbol       = "invalid-symbol"
	CondInvalidOctalLiteral = "invalid-octal-literal"
	CondInvalidHexLiteral   = "invalid-hex-literal"
	CondOverflow            = "integer-overflow-error"
)

Parse error condition names. These are stable API for programmatic error classification in LSP and tooling integrations.

View Source
const (
	CondContextCancelled  = "context-cancelled"
	CondStepLimitExceeded = "step-limit-exceeded"
)

Evaluation limit condition names.

View Source
const (
	DefaultMaxLogicalStackHeight  = 50000
	DefaultMaxPhysicalStackHeight = 25000
)

Default stack depth limits. These match the values used by the test harness and provide protection against unbounded recursion exhausting the Go goroutine stack. Applications that need deeper stacks can override these via WithMaximumLogicalStackHeight and WithMaximumPhysicalStackHeight.

View Source
const AnonArgSymbolPrefix = "%"

AnonArgSymbolPrefix is used to indicate unnamed arguments in the anonymous function shorthand “(expr ...)”.

View Source
const DefaultLangPackage = "lisp"

DefaultLangPackage is the name of default language package

View Source
const DefaultMaxAlloc = 10 * 1024 * 1024 // 10 million (bytes or elements)

DefaultMaxAlloc is the per-operation allocation size cap (in bytes for strings, in elements for sequences) enforced by builtins like concat, append, map, zip, reverse, make-sequence, and JSON load. Each operation checks its own output size independently — this is not a cumulative memory budget. It prevents a single malicious or accidental call from exhausting memory. Applications can override this via Runtime.MaxAlloc.

View Source
const DefaultMaxMacroExpansionDepth = 1000

DefaultMaxMacroExpansionDepth is the maximum number of successive macro expansions allowed before Eval returns an error. This prevents infinite macro expansion from exhausting memory or running forever.

View Source
const DefaultUserPackage = "user"

DefaultUserPackage is the name of the entry point package for interpreting user code.

View Source
const ElpsVersion = "1.7"
View Source
const FalseSymbol = "false"

FalseSymbol is the language's defacto false boolean value, though nil is also considered false by functions and operators expecting a boolean.

View Source
const KeyArgSymbol = "&key"

KeyArgSymbol is the symbol used to indicate keyword arguments to a function. Keyword arguments are declared following optional arguments. Keyword arguments may be supplied in any order and must specify the symbol they wish should be bound to by preceding the argument value with a keyward symbol.

View Source
const MetaArgPrefix = "&"

MetadaArgPrefix is a disallowed prefix for formal argument symbols. Any symbol beginning with MetaArgPrefix in a formal argument list will be treated with special meaning an unrecognized symbols will cause a runtime error to occur.

View Source
const OptArgSymbol = "&optional"

OptArgSymbol is the symbol used to indicate optional arguments to a function. Optional arguments are bound to given arguments if there are arguments left over following the binding of required arguments, otherwise they are bound to nil.

View Source
const TrueSymbol = "true"

TrueSymbol is the language's defacto true boolean value, though anything other than nil and 'false are considered true by functions and operators expecting a boolean.

View Source
const VarArgSymbol = "&rest"

VarArgSymbol is the symbol that indicates a variadic function argument in a function's list of formal arguments. Functions may have at most one variadic argument. Variadic arguments must be defined following optional arguments and are bound after all optional arguments are bound.

Currently, it is an error to declare a function which has both variadic and keyword arguments. While this may change it will always be discouraged due to the difficulty handling such mixtures of argument types. It would be better to define separate functions, one with keyward args and the other with variadic args.

Variables

This section is empty.

Functions

func GoError

func GoError(v *LVal) error

GoError returns an error that represents v. If v is not LError then nil is returned.

func GoFloat64

func GoFloat64(v *LVal) (float64, bool)

GoFloat64 converts the numeric value that v represents to a float64 and returns it with the value true. If v does not represent a number GoFloat64 returns a false second argument

func GoInt

func GoInt(v *LVal) (int, bool)

GoInt converts the numeric value that v represents to and int and returns it with the value true. If v does not represent a number GoInt returns a false second argument

func GoMap

func GoMap(v *LVal) (map[interface{}]interface{}, bool)

GoMap converts an LSortMap to its Go equivalent and returns it with a true second argument. If v does not represent a map GoMap returns a false second argument. Application's using custom Map implementations which allow arbitrary keys may not be able to construct a native Go map, in which case GoMap returns (nil, true).

func GoSlice

func GoSlice(v *LVal) ([]interface{}, bool)

GoSlice returns the string that v represents and the value true. If v does not represent a string GoSlice returns a false second argument

func GoString

func GoString(v *LVal) (string, bool)

GoString returns the string that v represents and the value true. If v does not represent a string GoString returns a false second argument

func GoValue

func GoValue(v *LVal) interface{}

GoValue converts v to its natural representation in Go. Quotes are ignored and all lists are turned into slices. Symbols are converted to strings. The value Nil() is converted to nil. Functions are returned as is.

NOTE: These semantics may change. It's unclear what the exact need is in corner cases.

func JoinDocStrings added in v1.16.12

func JoinDocStrings(parts []string) string

JoinDocStrings joins multiple doc string parts into a single string. Non-empty strings are joined with spaces. Empty strings produce blank lines, acting as paragraph separators.

func Not

func Not(v *LVal) bool

Not interprets v as a boolean value and returns its negation.

func RegisterDefaultBuiltin

func RegisterDefaultBuiltin(name string, formals *LVal, fn LBuiltin)

RegisterDefaultBuiltin adds the given function to the list returned by DefaultBuiltins.

func RegisterDefaultMacro

func RegisterDefaultMacro(name string, formals *LVal, fn LBuiltin)

RegisterDefaultMacro adds the given function to the list returned by DefaultMacros.

func RegisterDefaultSpecialOp

func RegisterDefaultSpecialOp(name string, formals *LVal, fn LBuiltin)

RegisterDefaultSpecialOp adds the given function to the list returned by DefaultSpecialOps.

func SymbolName

func SymbolName(v *LVal) (string, bool)

SymbolName returns the name of the symbol that v represents and the value true. If v does not represent a symbol SymbolName returns a false second argument

func True

func True(v *LVal) bool

True interprets v as a boolean and returns the result.

NOTE: I don't like this name, really. But I can't think of a better one.

Types

type CallFrame

type CallFrame struct {
	Source        *token.Location
	FID           string
	Package       string
	Name          string
	HeightLogical int
	Terminal      bool
	TROBlock      bool // Stop tail-recursion optimization from collapsing this frame
}

CallFrame is one frame in the CallStack

func (*CallFrame) QualifiedFunName

func (f *CallFrame) QualifiedFunName(ignore ...string) string

QualifiedFunName returns the qualified name for the function on the top of the stack. If ignore is non-empty QualifiedFunName returns unqualified names for functions in the given packages.

func (*CallFrame) String

func (f *CallFrame) String() string

type CallStack

type CallStack struct {
	Frames            []CallFrame
	MaxHeightLogical  int
	MaxHeightPhysical int
}

CallStack is a function call stack.

func (*CallStack) CheckHeight

func (s *CallStack) CheckHeight() error

func (*CallStack) Copy

func (s *CallStack) Copy() *CallStack

Copy creates a copy of the current stack so that it can be attach to a runtime error.

func (*CallStack) DebugPrint

func (s *CallStack) DebugPrint(w io.Writer) (int, error)

DebugPrint prints s

func (*CallStack) Pop

func (s *CallStack) Pop() CallFrame

Pop removes the top CallFrame from the stack and returns it. If the stack is empty Pop returns nil.

func (*CallStack) PushFID

func (s *CallStack) PushFID(src *token.Location, fid string, pkg string, name string) error

PushFID pushes a new stack frame with the given FID onto s.

func (*CallStack) TerminalFID

func (s *CallStack) TerminalFID(fid string) int

TerminalFID determines if a chain of terminal stack frames that ends with fid (i.e. fid is a candidate for tail-recursion optimization) and returns the number of frames in the shortest such chain. If no such chain of terminal frames can be found then 0 is returned.

If a stack frame with TROBlock is found then the search for a terminal chain is prematurely terminated as a failure.

NOTE: If tail-recursion optimization is working then the chain of calls found by TerminalFID is unique.

func (*CallStack) Top

func (s *CallStack) Top() *CallFrame

Top returns the CallFrame at the top of the stack or nil if none exists.

type Config

type Config func(env *LEnv) *LVal

Config is a function that configures a root environment or its runtime.

func WithContext added in v1.25.0

func WithContext(ctx context.Context) Config

WithContext returns a Config that sets the initial context.Context for the root environment. The context is checked at each evaluation step; if it is cancelled or its deadline expires, evaluation returns a CondContextCancelled error. For per-call context control, use the *Context methods on LEnv instead.

func WithDebugger added in v1.21.0

func WithDebugger(d Debugger) Config

WithDebugger returns a Config that attaches a debugger to the runtime. When a debugger is attached, tail recursion optimization is disabled to provide predictable stepping behavior and stack traces.

func WithLibrary added in v1.16.3

func WithLibrary(l SourceLibrary) Config

WithLibrary returns a Config that makes environments use l as a source library.

func WithLoader

func WithLoader(fn Loader) Config

WithLoader returns a Config that executes fn and ensures that the environment's working package is reset following execution of fn. Despite fn having the same signature as a Config WithLoader allows a Loader to function more like the LEnv methods LoadFile, LoadString, etc.

func WithMaxAlloc added in v1.20.0

func WithMaxAlloc(n int) Config

WithMaxAlloc returns a Config that sets the per-operation allocation size cap (in bytes for strings, in elements for sequences). This limits the output size of any single builtin call, not cumulative memory usage.

func WithMaxMacroExpansionDepth added in v1.20.0

func WithMaxMacroExpansionDepth(n int) Config

WithMaxMacroExpansionDepth returns a Config that limits the number of successive macro expansions during evaluation. This prevents infinite macro expansion from exhausting memory.

func WithMaxSteps added in v1.25.0

func WithMaxSteps(n int64) Config

WithMaxSteps returns a Config that sets the maximum number of evaluation steps before evaluation returns a CondStepLimitExceeded error. A step is counted for each Eval entry, each TRO iteration, and each macro re-expansion. A value of 0 means unlimited (the default).

func WithMaximumLogicalStackHeight

func WithMaximumLogicalStackHeight(n int) Config

WithMaximumLogicalStackHeight returns a Config that will prevent an execution environment from allowing the logical stack height to exceed n. The logical height of the stack is the stack's physical height plus the number of stack frames which have been elided due to tail recursive call optimizations.

func WithMaximumPhysicalStackHeight

func WithMaximumPhysicalStackHeight(n int) Config

WithMaximumPhysicalStackHeight returns a Config that will prevent an execution environment from allowing the physical stack height to exceed n. The physical stack height is the literal number of frames in the call stack and does not account for stack frames elided due to tail recursive call optimizations.

func WithReader

func WithReader(r Reader) Config

WithReader returns a Config that makes environments use r to parse source streams. There is no default Reader for an environment.

func WithStderr

func WithStderr(w io.Writer) Config

WithStderr returns a Config that makes environments write debugging output to w instead of the default, os.Stderr.

type DebugAction added in v1.21.0

type DebugAction int

DebugAction represents the action the interpreter should take after the debugger resumes execution from a paused state.

const (
	// DebugContinue resumes execution until the next breakpoint.
	DebugContinue DebugAction = iota

	// DebugStepInto pauses on the next OnEval call regardless of depth.
	DebugStepInto

	// DebugStepOver pauses on the next OnEval call at the same or
	// lesser stack depth (does not descend into function calls).
	DebugStepOver

	// DebugStepOut pauses on the next OnEval call at a lesser stack
	// depth (waits until the current function returns).
	DebugStepOut
)

type Debugger added in v1.21.0

type Debugger interface {
	// IsEnabled returns true when the debugger is actively debugging.
	// A dormant debugger (attached but not yet activated) returns false,
	// allowing the interpreter to skip all other hook calls.
	IsEnabled() bool

	// OnEval is called before evaluating any expression with a real source
	// location (v.Source != nil). Synthetic expressions from macro expansion
	// are skipped.
	// Returns true if the debugger wants execution to pause (breakpoint hit
	// or step complete).
	OnEval(env *LEnv, expr *LVal) bool

	// WaitIfPaused blocks until the debugger allows execution to continue.
	// Called when OnEval returns true. The eval goroutine blocks here while
	// the DAP server goroutine processes user commands.
	// Returns the action to take after resuming.
	WaitIfPaused(env *LEnv, expr *LVal) DebugAction

	// OnFunEntry is called when a function is entered, after formal
	// parameters have been bound in the function's lexical environment.
	// env is the caller's environment; fenv is the function's environment
	// with parameter bindings in scope. For builtins (which have no lexical
	// env), this hook is not called.
	OnFunEntry(env *LEnv, fun *LVal, fenv *LEnv)

	// OnFunReturn is called after a function returns.
	// fun is the function value, result is the return value.
	OnFunReturn(env *LEnv, fun, result *LVal)

	// AfterFunCall is called in Eval after EvalSExpr returns, giving the
	// debugger a chance to pause at the call-site expression when the
	// stack depth has decreased (step-out from tail position). Returns
	// true if execution should pause.
	AfterFunCall(env *LEnv) bool

	// OnError is called when an error condition is created (in
	// ErrorCondition and ErrorConditionf). Returns true if the debugger
	// wants execution to pause (exception breakpoint). When true, the
	// interpreter calls WaitIfPaused with the error value.
	OnError(env *LEnv, lerr *LVal) bool
}

Debugger is called by the interpreter at key execution points to support breakpoints, stepping, and variable inspection. When Runtime.Debugger is nil, no hook calls are made and there is zero overhead on the hot path.

Hook calls use a two-check gate pattern:

if d := env.Runtime.Debugger; d != nil && d.IsEnabled() { ... }

The nil check is free (branch-predicted not-taken). IsEnabled allows a debugger to remain attached but dormant, further reducing overhead when not actively debugging.

type ErrorVal

type ErrorVal LVal

ErrorVal implements the error interface so that errors can be first class lisp objects. The error message is stored in the Str field while contextual information (e.g. call stack) can be stored in the Cells slice.

func (*ErrorVal) Condition added in v1.17.0

func (e *ErrorVal) Condition() string

Condition returns the error condition name (e.g., "parse-error", "unmatched-syntax"). This is the programmatic error classification stored in the LVal.Str field for LError values.

func (*ErrorVal) Error

func (e *ErrorVal) Error() string

Error implements the error interface. When the error condition is not “error” it wil be printed preceding the error message. Otherwise, the name of the function that generated the error will be printed preceding the error, if the function can be determined.

func (*ErrorVal) ErrorMessage

func (e *ErrorVal) ErrorMessage() string

ErrorMessage returns the underlying message in the error.

func (*ErrorVal) FunName

func (e *ErrorVal) FunName() string

FunName returns the qualified name of function on the top of the call stack when the error occurred.

func (*ErrorVal) WriteTrace

func (e *ErrorVal) WriteTrace(w io.Writer) (int, error)

WriteTrace writes the error and a stack trace to w

type FSLibrary added in v1.16.14

type FSLibrary struct {
	FS fs.FS
}

FSLibrary implements SourceLibrary using an fs.FS, providing natural confinement via the fs.FS contract (which rejects ".." path components and absolute paths). Use os.DirFS(dir) to create an fs.FS rooted at a directory.

func (*FSLibrary) LoadSource added in v1.16.14

func (lib *FSLibrary) LoadSource(ctx SourceContext, loc string) (string, string, []byte, error)

LoadSource reads loc from the embedded fs.FS. The fs.FS contract inherently prevents path traversal — paths must be unrooted slash- separated sequences without ".." elements.

type FunctionInfo added in v1.17.0

type FunctionInfo struct {
	Name      string // empty for lambda
	Kind      string // "defun", "defmacro", or "lambda"
	Params    []ParamInfo
	DocString string
	Source    *token.Location
}

FunctionInfo holds metadata extracted from a defun, defmacro, or lambda s-expression.

func InspectFunction added in v1.17.0

func InspectFunction(node *LVal) *FunctionInfo

InspectFunction extracts metadata from a defun, defmacro, or lambda s-expression. Returns nil if node is not a recognized form.

type LBuiltin

type LBuiltin func(env *LEnv, args *LVal) *LVal

LBuiltin is a function that performs executes a lisp function.

type LBuiltinDef

type LBuiltinDef interface {
	Name() string
	Formals() *LVal
	Eval(env *LEnv, args *LVal) *LVal
}

LBuiltinDef is a built-in function

func DefaultBuiltins

func DefaultBuiltins() []LBuiltinDef

DefaultBuiltins returns the default set of LBuiltinDefs added to LEnv objects when LEnv.AddBuiltins is called without arguments.

func DefaultMacros

func DefaultMacros() []LBuiltinDef

DefaultMacros returns the default set of LBuiltinDef added to LEnv objects when LEnv.AddMacros is called without arguments.

func DefaultSpecialOps

func DefaultSpecialOps() []LBuiltinDef

DefaultSpecialOps returns the default set of LBuiltinDef added to LEnv objects when LEnv.AddSpecialOps is called without arguments.

type LEnv

type LEnv struct {
	Loc     *token.Location
	Scope   map[string]*LVal
	FunName map[string]string
	Parent  *LEnv
	Runtime *Runtime
	ID      uint
	// contains filtered or unexported fields
}

LEnv is a lisp environment.

func NewEnv

func NewEnv(parent *LEnv) *LEnv

NewEnv returns initializes and returns a new LEnv.

func NewEnvRuntime

func NewEnvRuntime(rt *Runtime) *LEnv

NewEnvRuntime initializes a new LEnv, like NewEnv, but it explicitly specifies the runtime to use. NewEnvRuntime is only suitable for creating root LEnv object, so it does not take a parent argument. When rt is nil StandardRuntime() called to create a new Runtime for the returned LEnv. It is an error to use the same runtime object in multiple calls to NewEnvRuntime if the two envs are not in the same tree and doing so will have unspecified results.

func (*LEnv) AddBuiltins

func (env *LEnv) AddBuiltins(external bool, funs ...LBuiltinDef)

AddBuiltins binds the given funs to their names in env. When called with no arguments AddBuiltins adds the DefaultBuiltins to env.

func (*LEnv) AddMacros

func (env *LEnv) AddMacros(external bool, macs ...LBuiltinDef)

AddMacros binds the given macros to their names in env. When called with no arguments AddMacros adds the DefaultMacros to env.

func (*LEnv) AddSpecialOps

func (env *LEnv) AddSpecialOps(external bool, ops ...LBuiltinDef)

AddSpecialOps binds the given special operators to their names in env. When called with no arguments AddSpecialOps adds the DefaultSpecialOps to env.

func (*LEnv) Context added in v1.25.0

func (env *LEnv) Context() context.Context

Context returns the context.Context currently associated with this environment. If no context has been set, context.Background() is returned.

func (*LEnv) Copy

func (env *LEnv) Copy() *LEnv

Copy returns a new LEnv with a copy of env.Scope but a shared parent and stack (not quite a deep copy).

func (*LEnv) DefinePackage

func (env *LEnv) DefinePackage(name *LVal) *LVal

func (*LEnv) Error

func (env *LEnv) Error(msg ...interface{}) *LVal

Error returns an LError value with an error message given by rendering msg.

Error may be called either with an error or with any number of *LVal values. It is invalid to pass an error argument with any other values and doing so will result in a runtime panic.

Unlike the exported function, the Error method returns LVal with a copy env.Runtime.Stack.

func (*LEnv) ErrorAssociate

func (env *LEnv) ErrorAssociate(lerr *LVal) *LVal

ErrorAssociate associates the LError value lerr with env's current call stack and source location. ErrorAssociate returns an LError if lerr is not an error value (indicating a bug in the caller), or nil on success.

func (*LEnv) ErrorCondition

func (env *LEnv) ErrorCondition(condition string, v ...interface{}) *LVal

ErrorCondition returns an LError the given condition type and an error message computed by rendering msg.

ErrorCondition may be called either with an error or with any number of *LVal values. It is invalid to pass ErrorCondition an error argument with any other values and doing so will result in a runtime panic.

Unlike the exported function, the ErrorCondition method returns an LVal with a copy env.Runtime.Stack.

func (*LEnv) ErrorConditionf

func (env *LEnv) ErrorConditionf(condition string, format string, v ...interface{}) *LVal

ErrorConditionf returns an LError value with the given condition type and a a formatted error message rendered using fmt.Sprintf.

Unlike the exported function, the ErrorConditionf method returns an LVal with a copy env.Runtime.Stack.

func (*LEnv) Errorf

func (env *LEnv) Errorf(format string, v ...interface{}) *LVal

Errorf returns an LError value with a formatted error message.

Unlike the exported function, the Errorf method returns an LVal with a copy env.Runtime.Stack.

func (*LEnv) Eval deprecated

func (env *LEnv) Eval(v *LVal) *LVal

Eval evaluates v in the context (scope) of env and returns the resulting LVal. Eval does not modify v.

Deprecated: Use EvalContext for cancellation and timeout support.

func (*LEnv) EvalContext added in v1.25.0

func (env *LEnv) EvalContext(ctx context.Context, v *LVal) *LVal

EvalContext evaluates v with the given context. If ctx is cancelled or its deadline expires during evaluation, a CondContextCancelled error is returned.

func (*LEnv) EvalSExpr

func (env *LEnv) EvalSExpr(s *LVal) *LVal

EvalSExpr evaluates s and returns the resulting LVal.

func (*LEnv) FunCall deprecated

func (env *LEnv) FunCall(fun, args *LVal) *LVal

FunCall invokes regular function fun with the argument list args.

Deprecated: Use FunCallContext for cancellation and timeout support.

func (*LEnv) FunCallContext added in v1.25.0

func (env *LEnv) FunCallContext(ctx context.Context, fun, args *LVal) *LVal

FunCallContext invokes regular function fun with args under the given context. If ctx is cancelled or its deadline expires during the call, a CondContextCancelled error is returned.

func (*LEnv) GenSym

func (env *LEnv) GenSym() *LVal

func (*LEnv) Get

func (env *LEnv) Get(k *LVal) *LVal

Get takes an LSymbol k and returns the LVal it is bound to in env.

func (*LEnv) GetFun

func (env *LEnv) GetFun(fun *LVal) *LVal

GetFun returns a function referenced by the given LVal. If fun is already an LFun, then fun is returned. If fun is a symbol then GetFun looks for a function bound to the symbol. If fun does not reference a symbol then an error is returned.

GetFun is a suitable for backing an implementation of functional programing constructs, like funcall, map, reduce, etc.

func (*LEnv) GetFunGlobal added in v1.2.0

func (env *LEnv) GetFunGlobal(fun *LVal) *LVal

GetFunGlobal is like GetFun but only accesses the global package environment.

func (*LEnv) GetFunName

func (env *LEnv) GetFunName(f *LVal) string

GetFunName returns the function name (if any) known to be bound to the given function. If the function's FID is bound in its package then the global name of the function is returned. When the function is bound within a local scope then the local name used to reference the function (if any) is returned.

Safety: the error path in this function is cosmetic-only and does not mask data corruption. Every caller (MacroCall, SpecialOpCall, funCall, call, profiler) has already verified that f.Type == LFun before reaching here, so pkgFunName should never fail. The fallback to f.Str only affects the human-readable name shown in error messages and stack traces — it cannot influence evaluation, binding, or control flow. We log at BUG level so the issue is visible in diagnostics without changing the return type to an error that every caller would have to handle for an unreachable code path.

func (*LEnv) GetGlobal

func (env *LEnv) GetGlobal(k *LVal) *LVal

GetGlobal takes LSymbol k and returns the value it is bound to in the current package.

func (*LEnv) InPackage

func (env *LEnv) InPackage(name *LVal) *LVal

func (*LEnv) Lambda

func (env *LEnv) Lambda(formals *LVal, body []*LVal) *LVal

Lambda returns a new Lambda with fun.Env and fun.Package set automatically.

func (*LEnv) Load deprecated

func (env *LEnv) Load(name string, r io.Reader) *LVal

Load reads LVals from r and evaluates them as if in a progn. The value returned by the last evaluated LVal will be retured. After evaluating expressions the current package is restored to the current package at the time Load was called, in case loaded source made calls to "in-package". If env.Runtime.Reader has not been set then an error will be returned by Load.

Deprecated: Use LoadContext for cancellation and timeout support.

func (*LEnv) LoadContext added in v1.25.0

func (env *LEnv) LoadContext(ctx context.Context, name string, r io.Reader) *LVal

LoadContext reads LVals from r and evaluates them with the given context.

func (*LEnv) LoadFile deprecated

func (env *LEnv) LoadFile(loc string) *LVal

LoadFile attempts to use env.Runtime.Library to read a lisp source file and evaluate expressions it contains. Any error encountered will prevent execution of loaded source and be returned. After evaluating expressions the current package is restored to the current package at the time Load was called, in case loaded source made calls to "in-package". If env.Runtime.Reader has not been set then an error will be returned by Load.

Deprecated: Use LoadFileContext for cancellation and timeout support.

func (*LEnv) LoadFileContext added in v1.25.0

func (env *LEnv) LoadFileContext(ctx context.Context, loc string) *LVal

LoadFileContext loads and evaluates a source file with the given context.

func (*LEnv) LoadLocation deprecated

func (env *LEnv) LoadLocation(name string, loc string, r io.Reader) *LVal

LoadLocation attempts to use env.Runtime.Library to read a lisp source file, specifying its name and location explicity, and evaluate the expressions it contains. Because the name and location of the stream are specfied explicitly LoadLocation does not depend explicity on an env.Runtime.Library implementation. Any error encountered will prevent execution of loaded source and be returned. After evaluating expressions the current package is restored to the current package at the time Load was called, in case loaded source made calls to "in-package". If env.Runtime.Reader has not been set then an error will be returned by Load.

Deprecated: Use LoadLocationContext for cancellation and timeout support.

func (*LEnv) LoadLocationContext added in v1.25.0

func (env *LEnv) LoadLocationContext(ctx context.Context, name, loc string, r io.Reader) *LVal

LoadLocationContext loads and evaluates a source stream at a given location with the given context.

func (*LEnv) LoadString deprecated

func (env *LEnv) LoadString(name, exprs string) *LVal

LoadString loads and evaluates expressions from a string.

Deprecated: Use LoadStringContext for cancellation and timeout support.

func (*LEnv) LoadStringContext added in v1.25.0

func (env *LEnv) LoadStringContext(ctx context.Context, name, exprs string) *LVal

LoadStringContext loads and evaluates a string with the given context.

func (*LEnv) MacroCall

func (env *LEnv) MacroCall(fun, args *LVal) *LVal

MacroCall invokes macro fun with argument list args.

func (*LEnv) New added in v1.14.0

func (env *LEnv) New(typ *LVal, args *LVal) *LVal

New takes a typedef along with a list of constructor arguments and returns an LTaggedValue containing the result of invoking the typedef's constructor with the given arguments. A typedef is an LTaggedVal itself that wraps a list holding the defined type name along with a constructor.

New requires that the system have typedef tagged-values. Generally that will be enabled by calling InitializeTypedef or InitializeUserEnv when initializing the top-level enviornment.

func (*LEnv) Put

func (env *LEnv) Put(k, v *LVal) *LVal

Put takes an LSymbol k and binds it to v in env. If k is already bound to a value the binding is updated so that k is bound to v.

func (*LEnv) PutGlobal

func (env *LEnv) PutGlobal(k, v *LVal) *LVal

PutGlobal takes an LSymbol k and binds it to v in current package.

func (*LEnv) SetPackageDoc added in v1.16.12

func (env *LEnv) SetPackageDoc(doc string)

SetPackageDoc sets the documentation string for the current package.

func (*LEnv) SetSymbolDoc added in v1.16.12

func (env *LEnv) SetSymbolDoc(name, doc string)

SetSymbolDoc sets the documentation string for a symbol in the current package.

func (*LEnv) SpecialOpCall

func (env *LEnv) SpecialOpCall(fun, args *LVal) *LVal

SpecialOpCall invokes special operator fun with the argument list args.

func (*LEnv) TaggedValue added in v1.14.0

func (env *LEnv) TaggedValue(typ *LVal, val *LVal) *LVal

TaggedValue is a low-level function to create a tagged-value and should be used with great care and testing. The first argument must be a symbol and is used as the type of the returned tagged-value. The second argument is the value being tagged.

The type of a tagged-value should be a qualified symbol (e.g. 'lisp:mytype). Unqualified type names can clash with primitive type symbols (e.g. 'string) which can lead to program failures.

func (*LEnv) Terminal

func (env *LEnv) Terminal(expr *LVal) *LVal

func (*LEnv) Update

func (env *LEnv) Update(k, v *LVal) *LVal

Update updates the binding of k to v within the scope of env. Update can update either lexical or global bindings. If k is not bound by env, an enclosing LEnv, or the current package an error condition is signaled.

func (*LEnv) UsePackage

func (env *LEnv) UsePackage(name *LVal) *LVal

type LFunData

type LFunData struct {
	Builtin LBuiltin
	Env     *LEnv
	FID     string
	Package string
}

func (*LFunData) Copy

func (fd *LFunData) Copy() *LFunData

type LFunType

type LFunType uint8

LFunType denotes special functions, either macros or special operators.

const (
	LFunNone LFunType = iota
	LFunMacro
	LFunSpecialOp
)

LFunType constants. LFunNone indicates a normal function.

func (LFunType) String added in v1.15.0

func (ft LFunType) String() string

type LType

type LType uint

LType is the type of an LVal

const (
	// LInvalid (0) is not a valid lisp type.
	LInvalid LType = iota
	// LInt values store an int in the LVal.Int field.
	LInt
	// LFloat values store a float64 in the LVal.Float field.
	LFloat
	// LError values use the LVal.Cells slice to store the following items:
	//		[0] a symbol representing the error "condition" (class name)
	//		[1:] error data (of any type)
	//
	// In addition, LError values store a copy of the function call stack at
	// the time of their creation in the LVal.Native field.
	//
	// TODO:  Make the stack a first class type (or some composite type) so
	// that it could be inspected during a condition handler.
	LError
	// LSymbol values store a string representation of the symbol in the
	// LVal.Str field.
	LSymbol
	LQSymbol // TODO:  Remove this... I can't believe it actually has usages
	// LSExpr values are "list" values in lisp and store their values in
	// LVal.Cells.
	LSExpr
	// LFun values use the following fields in an LVal:
	// 		LVal.Str      The local name used to reference the function (if any)
	// 		LVal.Native   An LFunData object
	//
	// In addition to these fields, a function defined in lisp (with defun,
	// lambda, defmacro, etc) uses the LVal.Cells field to store the following
	// items:
	//		[0]  a list describing the function's arguments
	//		[1:] body expressions of the function (potentially no expressions)
	//
	// NOTE:  Native go functions (LBuiltin) don't have a lexical environment
	// by default.  If a native function needs a lexical environment in order
	// to evaluate further expressions it is expected to create one.  See the
	// implementation of the builtin “let”.
	//
	// NOTE: Cells[1] in an LFun may contain a string literal which contains a
	// docstring.  To match common-lisp semantics and maintain backwards
	// compatibility a function with a body consisting of only a string literal
	// returns the string constant and is considered to have no documentation.
	// A builtin function may also include a docstring in Cells[1].
	LFun
	// LQuote values are special values only used to represents two or more
	// levels of quoting (e.g. ”3 or ”””'()).  The quoted value is stored
	// in LVals.Cells[0].  The first level of quoting takes places by setting
	// the LVal.Quoted field on a value with a normal value in LVal.Type.
	// LQuote values must always have a true LVal.Quoted field.
	LQuote
	// LString values store a string in the LVal.Str field.
	LString
	// LBytes values store a *[]byte in the LVal.Native field.  LVal.Native,
	// and the contained pointer, must must never be nil (the slice being
	// pointed to may be nil though).
	LBytes
	// LSortMap value uses the LVal.Map field to store a map.
	//
	// TODO:  Use a tree-based map (that is potentially stored in Cells).  A
	// tree based map would be capable of supporting integer keys.
	LSortMap
	// LArray values use the LVal.Cells slice to store the following items:
	//		[0] a list containing dimension cardinalities in index 0
	//  	[1] a list containing row-major ordered array values
	LArray
	// LNative values store a Go value in the LVal.Native field and can be used
	// by builtin functions to store values of any type.
	LNative
	// LTaggedVal is a user-defined type that uses the following fields in an
	// LVal:
	// 		LVal.Str      The user-defined type name
	// 		LVal.Cells[0] The user-data for the typed-value
	LTaggedVal
	// Mark LVals are used to trasmit information down the stack through return
	// values.  Because the LEnv does not evaluate expressions using a stack
	// based virtual machine these Mark values, which often wrap other LVal
	// data in their Cells, are passed back from functions.  Typically the
	// environment is solely responsible for managing mark values and
	// applications should never see them during calls to builtin functions.
	LMarkTerminal  // LEnv marks the frame as terminal and evaluates tho contained expr
	LMarkTailRec   // LEnv resumes a call a set number of frames down the stack.
	LMarkMacExpand // LEnv will evaluate the returned LVal a subsequent time.
	// LTypeMax is not a real type but represents a value numerically greater
	// than all valid LType values.  It also can be used to determine the
	// number of valid LType values.
	LTypeMax
)

Possible LValType values

func (LType) String

func (t LType) String() string

type LVal

type LVal struct {
	Native interface{}

	Source *token.Location

	// Str used by LSymbol and LString values
	Str string

	// Cells used by many values as a storage space for lisp objects.
	//
	// TODO: Consider making Cells' type []LVal instead of []*LVal to reduce
	// the burden on the allocator/gc.
	Cells []*LVal

	// Type is the native type for a value in lisp.
	Type LType

	// Fields used for numeric types.
	Int   int
	Float float64

	// FunType used to further classify LFun values.
	FunType LFunType

	// Quoted is a flag indicating a single level of quoting.
	Quoted bool

	// Spliced denotes the value as needing to be spliced into a parent value.
	Spliced bool

	// Meta holds formatting metadata, only populated in format-preserving mode.
	Meta *SourceMeta

	// MacroExpansion holds debug metadata for nodes produced by macro
	// expansion. Only populated when a debugger is attached — nil in
	// production (zero overhead: 8-byte nil pointer).
	MacroExpansion *MacroExpansionInfo
}

LVal is a lisp value

func Array

func Array(dims *LVal, cells []*LVal) *LVal

Array returns an LVal representing an array reference. The dims argument is be a list of integers sizes for each dimension of the array. If non-empty, cells provides the backing storage for the array. The dims argument may be nil, in which case a vector (one dimensional array) is returned. If dims is non-nil then cells must either be nil or have one element for every array element, in row-major order.

func Bool

func Bool(b bool) *LVal

Bool returns an LVal with truthiness identical to b.

The returned value is a shared singleton — callers MUST NOT mutate it.

func Bytes

func Bytes(b []byte) *LVal

Bytes returns an LVal representing binary data b.

func Error

func Error(err error) *LVal

Error returns an LError representing err. Errors store their message in Cells and their condition type in Str. The error condition type must be a valid lisp symbol.

Errors generated during expression evaluation typically have a non-nil Stack field. The Env.Error() method is typically the preferred method for creating error LVal objects because it initializes Stack with an appropriate value.

func ErrorCondition

func ErrorCondition(condition string, err error) *LVal

ErrorCondition returns an LError representing err and having the given condition type. Errors store their message/data in Cells and their condition type in Str. The condition type must be a valid lisp symbol.

Errors generated during expression evaluation typically have a non-nil Stack field. The Env.Error() method is typically the preferred method for creating error LVal objects because it initializes Stack with an appropriate value.

func ErrorConditionf

func ErrorConditionf(condition string, format string, v ...interface{}) *LVal

ErrorConditionf returns an LError with a formatted error message. Errors store their message in Cells and their condition type in Str. The condition type must be a valid symbol.

Errors generated during expression evaluation typically have a non-nil Stack field. The Env.ErrorConditionf() method is typically the preferred method for creating error LVal objects because it initializes Stack with an appropriate value.

func Errorf

func Errorf(format string, v ...interface{}) *LVal

Errorf returns an LError with a formatted error message. Errors store their message in Cells and their condition type in Str. The condition type must be a valid symbol.

Errors generated during expression evaluation typically have a non-nil Stack field. The Env.Errorf() method is typically the preferred method for creating error LVal objects because it initializes Stack with an appropriate value.

func Float

func Float(x float64) *LVal

Float returns an LVal representation of the number x

func Formals

func Formals(argSymbols ...string) *LVal

Formals returns an LVal reprsenting a function's formal argument list containing symbols with the given names.

func Fun

func Fun(fid string, formals *LVal, fn LBuiltin) *LVal

Fun returns an LVal representing a function

func FunRef added in v1.13.0

func FunRef(symbol, fun *LVal) *LVal

FunRef returns a reference to fun that uses the local name symbol.

func GetType added in v1.14.0

func GetType(v *LVal) *LVal

GetType returns a quoted symbol denoting v's type.

func InitializeTypedef added in v1.14.0

func InitializeTypedef(env *LEnv) *LVal

InitializeTypedef injects the meta-typedef object so `new` and `deftype` can be used to create user-defined types. The name of the injected typedef object is not exported and it should not be handled without abstraction in general because user error can break the type system.

See LEnv.TaggedValue for more information about creating tagged-values.

func InitializeUserEnv

func InitializeUserEnv(env *LEnv, config ...Config) *LVal

InitializeUserEnv creates the default user environment.

func Int

func Int(x int) *LVal

Int returns an LVal representing the number x.

func Macro

func Macro(fid string, formals *LVal, fn LBuiltin) *LVal

Macro returns an LVal representing a macro

func MakeVector added in v1.14.0

func MakeVector(n int) *LVal

MakeVector returns a vector with n cells initialized to Nil.

func Native

func Native(v interface{}) *LVal

Native returns an LVal containng a native Go value.

func Nil

func Nil() *LVal

Nil returns an LVal representing nil, an empty list, an absent value.

The returned value is a shared singleton — callers MUST NOT mutate it. If you need a mutable empty list (e.g., to append children), use SExpr(nil) directly.

func QExpr

func QExpr(cells []*LVal) *LVal

QExpr returns an LVal representing an Q-expression, a quoted expression, a list. Provided cells are used as backing storage for the returned list and are not copied.

func QSymbol

func QSymbol(s string) *LVal

QSymbol returns an LVal representing the quoted symbol

func Quote

func Quote(v *LVal) *LVal

Quote quotes v and returns the quoted value. The LVal v is modified.

func SExpr

func SExpr(cells []*LVal) *LVal

SExpr returns an LVal representing an S-expression, a symbolic expression. Provided cells are used as backing storage for the returned expression and are not copied.

func SortedMap

func SortedMap() *LVal

SortedMap returns an LVal representing a sorted map

func SortedMapFromData added in v1.14.0

func SortedMapFromData(data *MapData) *LVal

SortedMapFromData returns sorted-map with the given backing implementation. Applications calling this function must make ensure the Map implementation provided satisfies the semantics of Map methods.

func SpecialOp

func SpecialOp(fid string, formals *LVal, fn LBuiltin) *LVal

SpecialOp returns an LVal representing a special operator. Special operators are function which receive unevaluated results, like macros. However values returned by special operations do not require further evaluation, unlike macros.

func Splice

func Splice(v *LVal) *LVal

Splice is used in the implementation of quasiquote to insert a list into an outer slist.

func SplitSymbol added in v1.2.0

func SplitSymbol(sym *LVal) *LVal

func String

func String(str string) *LVal

String returns an LVal representing the string str.

func Symbol

func Symbol(s string) *LVal

Symbol returns an LVal representing the symbol s

func Value

func Value(v interface{}) *LVal

Value conveniently converts v to an LVal. Types which can be represented directly in lisp will be converted to the appropriate LVal. All other types will be turned into a Native LVal. Value is the inverse of the GoValue function.

func Vector added in v1.14.0

func Vector(cells []*LVal) *LVal

Vector returns an LVal representing a vector, a 1-dimensional array. Provided cells are used as backing storage for the returned vector and are not copied.

func (*LVal) ArrayDims

func (v *LVal) ArrayDims() *LVal

ArrayDims returns the dimensions of an array. ArrayDims returns an error if v.Type is not LArray.

func (*LVal) ArrayIndex

func (v *LVal) ArrayIndex(index ...*LVal) *LVal

ArrayIndex returns the value at the given index in an array.

func (*LVal) Builtin

func (v *LVal) Builtin() LBuiltin

func (*LVal) Bytes

func (v *LVal) Bytes() []byte

Bytes returns the []byte stored in v. Bytes panics if v.Type is not LBytes.

func (*LVal) CallStack

func (v *LVal) CallStack() *CallStack

func (*LVal) Copy

func (v *LVal) Copy() *LVal

Copy creates a deep copy of the receiver.

func (*LVal) Docstring added in v1.16.6

func (v *LVal) Docstring() string

Docstring returns the docstring of the function reference v. If v is not a function Docstring returns the empty string. For user-defined functions, consecutive leading string expressions in the body are concatenated to form the docstring (the body must contain at least one non-string expression after the doc strings). Empty strings produce paragraph breaks.

func (*LVal) Env

func (v *LVal) Env() *LEnv

func (*LVal) Equal

func (v *LVal) Equal(other *LVal) *LVal

Equal returns a non-nil value if v and other are logically equal, under the rules used by the "equal?" function.

func (*LVal) EqualNum

func (v *LVal) EqualNum(other *LVal) *LVal

func (*LVal) FID

func (v *LVal) FID() string

func (*LVal) FunData

func (v *LVal) FunData() *LFunData

func (*LVal) IsMacro

func (v *LVal) IsMacro() bool

IsMacro returns true if v is a macro function. IsMacro doesn't actually check v.Type, only v.FunType.

func (*LVal) IsNil

func (v *LVal) IsNil() bool

IsNil returns true if v represents a nil value.

func (*LVal) IsNumeric

func (v *LVal) IsNumeric() bool

IsNumeric returns true if v has a primitive numeric type (int, float64).

func (*LVal) IsSpecialFun

func (v *LVal) IsSpecialFun() bool

IsSpecialFun returns true if v is a special function. IsSpecialFun doesn't actually check v.Type, only v.FunType.

func (*LVal) IsSpecialOp

func (v *LVal) IsSpecialOp() bool

IsSpecialOp returns true if v is a special operator. IsMacro doesn't actually check v.Type, only v.FunType.

func (*LVal) Len

func (v *LVal) Len() int

Len returns the length of the list v.

func (*LVal) Map

func (v *LVal) Map() *MapData

func (*LVal) MapEntries added in v1.14.0

func (v *LVal) MapEntries() *LVal

MapEntries returns a list of key-value pairs in the map. MapEntries

func (*LVal) MapGet

func (v *LVal) MapGet(k interface{}) *LVal

MapGet returns the value corresponding to k in v or an LError if k is not present in v. MapGet panics if v.Type is not LSortMap.

func (*LVal) MapKeys

func (v *LVal) MapKeys() *LVal

MapKeys returns a list of keys in the map. MapKeys panics if v.Type is not LSortMap. The type of each map key is retained from the first type a value was set for that key. For example, if the MapSet(Symbol("a"), Int(1)) is called before MapSet(String("a"), Int(2)) then MapKey() will contain the symbol and not the string.

func (*LVal) MapSet

func (v *LVal) MapSet(k interface{}, val *LVal) *LVal

MapSet sets k to val in v. MapSet returns an error if v.Type is not LSortMap. String and symbol keys are coerced to avoid programming errors causing symbol and string keys with equal string values from existing in the same map.

func (*LVal) Package

func (v *LVal) Package() string

func (*LVal) SetCallStack

func (v *LVal) SetCallStack(stack *CallStack)

func (*LVal) String

func (v *LVal) String() string

func (*LVal) UserData added in v1.14.0

func (v *LVal) UserData() *LVal

UserData returns the user-data associated with an LTaggedVal. UserData returns an error if v is not an LTaggedVal.

type Loader

type Loader func(*LEnv) *LVal

func LoaderMust

func LoaderMust(fn Loader, err error) Loader

LoaderMust returns its first argument when err is nil. If err is nil LoaderMust panics.

func TextLoader

func TextLoader(r Reader, name string, stream io.Reader) (Loader, error)

TextLoader parses a text stream using r and returns a Loader which evaluates the stream's expressions when called. The reader will be invoked only once. TextLoader will return an error if r produces any reference types (bytes, map, array, native, etc).

type LocationReader

type LocationReader interface {
	// ReadLocation the contents of r, associated with physical location loc,
	// and return the sequence of LVals that it contains.  The returned LVals
	// should be executed as if inside a progn.
	ReadLocation(name string, loc string, r io.Reader) ([]*LVal, error)
}

LocationReader is like Reader but assigns physical locations to the tokens from r.

type LogicalStackOverflowError

type LogicalStackOverflowError struct {
	Height int
}

func (*LogicalStackOverflowError) Error

func (e *LogicalStackOverflowError) Error() string

type MacroExpansionContext added in v1.23.0

type MacroExpansionContext struct {
	CallSite *token.Location // where the macro was invoked
	Name     string          // qualified macro name (e.g. "lisp:defun")
	DefSite  *token.Location // macro definition location (nil for builtins)
	Args     []*LVal         // unevaluated call-site arguments (for debugger scope)
}

MacroExpansionContext is shared by all nodes in a single macro expansion. It records the macro call site, name, definition site, and unevaluated arguments for debugger inspection.

type MacroExpansionInfo added in v1.23.0

type MacroExpansionInfo struct {
	*MacroExpansionContext       // shared across all nodes in one expansion
	ID                     int64 // unique per node, monotonically increasing
}

MacroExpansionInfo is attached to LVal nodes produced by macro expansion. It is only allocated when a debugger is attached (Runtime.Debugger != nil), so production code pays zero allocation cost.

type Map added in v1.14.0

type Map interface {
	Len() int
	// Get returns the value associated with the given key and a bool signaling
	// if the key was found in the map.  The first value returned by Get may be
	// an LError type if the implementation does not support the type of key
	// given.
	Get(key *LVal) (*LVal, bool)
	// Set associates key with val in the map.  Set may return an LError value
	// if the
	Set(key *LVal, val *LVal) *LVal
	// Del removes any association it has with key.  Del may return an LError
	// value if key was not a supported type or if the map does not support
	// dissociation.
	Del(key *LVal) *LVal
	// Keys returns a (sorted) list of keys with associated values in the map.
	Keys() *LVal
	// Entries copies its entries into the first Len() elements of buf.
	// Entries are represented as lists with two elements.  Entries returns the
	// number of elements written (i.e. Len) or an error if any was encountered.
	Entries(buf []*LVal) *LVal
}

type MapData added in v1.14.0

type MapData struct {
	Map
}

MapData is a concrete type to store in an interface as to avoid expensive runtime interface type checking

type Package

type Package struct {
	Name       string
	Doc        string
	Symbols    map[string]*LVal
	SymbolDocs map[string]string
	FunNames   map[string]string
	Externals  []string
}

Package is a named set of bound symbols. A package is interpreted code and belongs to the LEnv that creates it.

func NewPackage

func NewPackage(name string) *Package

NewPackage initializes and returns a package with the given name.

func (*Package) Exports

func (pkg *Package) Exports(sym ...string)

Exports declares symbols exported by the package. The symbols are not required to be bound at the time Exports is called.

func (*Package) Get

func (pkg *Package) Get(k *LVal) *LVal

Get takes an LSymbol k and returns the LVal it is bound to in pkg.

func (*Package) GetFunName

func (pkg *Package) GetFunName(fid string) string

GetFunName returns the function name (if any) known to be bound to the given FID.

func (*Package) Put

func (pkg *Package) Put(k, v *LVal) *LVal

Put takes an LSymbol k and binds it to v in pkg.

func (*Package) Update

func (pkg *Package) Update(k, v *LVal) *LVal

Update takes an LSymbol k and updates the binding of k in pkg so that k is bound v. If k is not bound in package an error is returned.

type PackageRegistry

type PackageRegistry struct {
	Packages map[string]*Package
	Lang     string // A default package used by all other packages
}

PackageRegistry contains a set of packages.

func NewRegistry

func NewRegistry() *PackageRegistry

NewRegistry initializes and returns a new PackageRegistry.

func (*PackageRegistry) DefinePackage

func (r *PackageRegistry) DefinePackage(name string) *Package

type ParamInfo added in v1.17.0

type ParamInfo struct {
	Name string
	Kind ParamKind
}

ParamInfo describes a single parameter in a function signature.

func ParseFormals added in v1.17.0

func ParseFormals(formals *LVal) []ParamInfo

ParseFormals extracts parameter info from a formals LVal. The formals list uses &optional, &rest, and &key markers to separate parameter kinds.

type ParamKind added in v1.17.0

type ParamKind int

ParamKind classifies a function parameter.

const (
	ParamRequired ParamKind = iota
	ParamOptional
	ParamRest
	ParamKey
)

func (ParamKind) String added in v1.17.0

func (k ParamKind) String() string

type PhysicalStackOverflowError

type PhysicalStackOverflowError struct {
	Height int
}

func (*PhysicalStackOverflowError) Error

type Profiler added in v1.9.0

type Profiler interface {
	// Start the process, and returns a function to stop.
	Start(function *LVal) func()
}

Interface for a profiler

type Reader

type Reader interface {
	// Read the contents of r and return the sequence of LVals that it
	// contains.  The returned LVals should be executed as if inside a progn.
	Read(name string, r io.Reader) ([]*LVal, error)
}

Reader abstracts a parser implementation so that it may be implemented in a separate package as an optional/swappable component.

type RelativeFileSystemLibrary

type RelativeFileSystemLibrary struct {
	// RootDir, when non-empty, confines all file access to this directory
	// tree. Any attempt to load a file outside RootDir (including via ..
	// path components) will return an error. When empty, no confinement
	// is applied and the existing behavior is preserved.
	RootDir string
}

RelativeFileSystemLibrary implements SourceLibrary and reads lisp source files from the filesystem, relative to the source context location.

In order to read filepaths relative to a source file's location the application's implementation of Runtime.Reader must implement LocationReader.

func (*RelativeFileSystemLibrary) LoadSource

func (lib *RelativeFileSystemLibrary) LoadSource(ctx SourceContext, loc string) (string, string, []byte, error)

LoadSource attempts to open loc as a filepath.

type Runtime

type Runtime struct {
	Registry               *PackageRegistry
	Package                *Package
	Stderr                 io.Writer
	Stack                  *CallStack
	Reader                 Reader
	Library                SourceLibrary
	Profiler               Profiler
	Debugger               Debugger // nil = disabled (zero overhead on hot path)
	MaxAlloc               int      // Per-operation allocation size cap (0 = use default). Not cumulative.
	MaxMacroExpansionDepth int      // Maximum macro expansion iterations (0 = use default).
	// contains filtered or unexported fields
}

Runtime is an object underlying a family of tree of LEnv values. It is responsible for holding shared environment state, generating identifiers, and writing debugging output to a stream (typically os.Stderr).

Step Limits: Runtime supports optional instruction counting via MaxSteps. Context cancellation is handled per-evaluation via LEnv.evalCtx, which is set by the *Context methods on LEnv (e.g. EvalContext) or the WithContext Config option. When neither context nor step limits are configured, limit checks are two nil/zero comparisons with negligible overhead.

Concurrency: Runtime and its associated LEnv tree are NOT safe for concurrent use from multiple goroutines. All calls to Eval, Load, and any other methods that read or mutate Runtime or LEnv state must be serialized by the caller. To evaluate ELPS code concurrently, create a separate Runtime (and LEnv tree) per goroutine.

The only thread-safe operations are GenEnvID and GenSym, which use atomic counters internally. All other fields — including Registry, Package, Stack, conditionStack, and the LEnv Scope maps — are unprotected.

func StandardRuntime

func StandardRuntime() *Runtime

StandardRuntime returns a new Runtime with an empty package registry and Stderr set to os.Stderr.

func (*Runtime) CheckAlloc added in v1.20.0

func (r *Runtime) CheckAlloc(n int) string

CheckAlloc returns a non-empty error message if n exceeds the per-operation allocation size cap. This is a point-in-time check for a single operation, not a cumulative memory tracker. Callers should use this before allocating buffers or sequences whose size is determined by user input.

func (*Runtime) CurrentCondition added in v1.16.13

func (r *Runtime) CurrentCondition() *LVal

CurrentCondition returns the condition currently being handled, or nil.

func (*Runtime) GenEnvID

func (r *Runtime) GenEnvID() uint

func (*Runtime) GenSym

func (r *Runtime) GenSym() string

func (*Runtime) MaxAllocBytes added in v1.16.14

func (r *Runtime) MaxAllocBytes() int

MaxAllocBytes returns the effective per-operation allocation size cap. Each builtin that allocates a buffer or sequence checks its output size against this limit independently — it is NOT a cumulative memory tracker. If MaxAlloc is zero, DefaultMaxAlloc is returned.

func (*Runtime) MaxMacroExpansions added in v1.20.0

func (r *Runtime) MaxMacroExpansions() int

MaxMacroExpansions returns the effective maximum macro expansion depth. If MaxMacroExpansionDepth is zero, DefaultMaxMacroExpansionDepth is returned.

func (*Runtime) PopCondition added in v1.16.13

func (r *Runtime) PopCondition() *LVal

PopCondition removes and returns the top condition from the stack.

func (*Runtime) PushCondition added in v1.16.13

func (r *Runtime) PushCondition(err *LVal)

PushCondition pushes an error onto the condition stack, making it available to rethrow within a handler-bind handler.

func (*Runtime) ResetSteps added in v1.25.0

func (r *Runtime) ResetSteps()

ResetSteps resets the cumulative step counter to zero.

func (*Runtime) Steps added in v1.25.0

func (r *Runtime) Steps() int64

Steps returns the cumulative step count since the last ResetSteps call (or since Runtime creation). Each call to Eval, each tail-recursion iteration, and each macro re-expansion increments the counter by one.

type SourceContext

type SourceContext interface {
	// Name is the name of the current source stream being evaluated which
	// caused the SourceLibrary LoadLocation operation.  Name is like Location
	// but is not necessarily tied to a physical location, or otherwise may be
	// ambiguous.
	//
	// NOTE:  Name may not be generated by the Runtime SourceLibrary due to
	// functions being sourced externally (in particular, the core language and
	// application standard library).  As such, the Name of a SourceContext is
	// meant only for informal use to assist humans and should not be relied
	// upon by a SourceLibrary.
	Name() string

	// Location is the current source location (e.g. file path) being evaluated
	// which caused the SourceLibrary LoadSource operation.  This may be used
	// in determining the location of relative target source locations.  If
	// executing code is not sourced from a lisp file then Location will return
	// an empty string -- this includes LoadSource operations triggered from
	// native Go functions and raw strings/[]bytes containing lisp code.
	// SourceLibraries should interpret an empty Location string as the process
	// working directory.
	Location() string
}

SourceContext provides an execution context allowing SourceLibraries flexibility in determining how to interpret a path.

NOTE: SourceContext may be expanded with new methods yielding externally defined implementations incompatible.

func NewSourceContext added in v1.22.0

func NewSourceContext(name, loc string) SourceContext

NewSourceContext creates a SourceContext with the given name and location. This is useful for callers that need to construct a SourceContext for SourceLibrary.LoadSource calls outside of normal evaluation flow (e.g., DAP source request handlers).

type SourceLibrary

type SourceLibrary interface {
	// LoadSource returns the data contained in the source file specified by a
	// location string obtained through a user call.  For example, the call
	// `(load-file "foo.txt")` would pass loc "foo.txt" to LoadSource).
	// LoadSource also receives a SourceContext object which may be used to
	// determine the physical path to the target location (e.g. what file is
	// loading "foo.txt"?).
	//
	// LoadSource returns four values: a name and true-location unambiguously
	// identifying the file, the file data, and any error that occurred while
	// retrieving data.  An interpreter must use trueloc as an identifier for
	// the requested source file anywhere the SourceContext ctx is unavailable.
	LoadSource(ctx SourceContext, loc string) (name, trueloc string, data []byte, err error)
}

SourceLibrary is responsible for loading source code from a given path. It is up to the SourceLibrary implementation how a source location should be interpreted. Depending on the application a SourceLibrary implementation may require a Runtime with Reader that implements LocationReader -- though the LocationReader implementation should not need to depend on the LocationReader implementation beyond that.

type SourceMeta added in v1.16.10

type SourceMeta struct {
	OriginalText            string         // original token text for literals (preserves escapes, numeric bases)
	BracketType             rune           // '(' or '[' for LSExpr nodes
	LeadingComments         []*token.Token // comment tokens preceding this node
	TrailingComment         *token.Token   // inline comment on same line after this node
	InnerTrailingComments   []*token.Token // comments between last child and closing bracket
	BlankLinesBefore        int            // blank lines (newline count - 1) before this node (or before its leading comments)
	BlankLinesAfterComments int            // blank lines between last leading comment and the expression
	PrecedingSpaces         int            // spaces before this token on the same line (for column alignment)
	NewlineBefore           bool           // true if at least one newline preceded this node in source
	ClosingBracketNewline   bool           // true if closing bracket was on its own line in source
}

SourceMeta holds formatting metadata for an LVal, populated only when parsing in format-preserving mode. Nil in normal parsing — zero cost.

Directories

Path Synopsis
Package lisplib is used to conveniently load the standard library for the elps environment
Package lisplib is used to conveniently load the standard library for the elps environment
x
debugger
Package debugger implements the ELPS debugger engine (Layer 1).
Package debugger implements the ELPS debugger engine (Layer 1).
debugger/dapserver
Package dapserver implements a DAP (Debug Adapter Protocol) server for the ELPS debugger engine.
Package dapserver implements a DAP (Debug Adapter Protocol) server for the ELPS debugger engine.
debugger/debugrepl
Package debugrepl provides an interactive CLI debug REPL built on top of the extensible repl.RunEnv function and the debugger engine.
Package debugrepl provides an interactive CLI debug REPL built on top of the extensible repl.RunEnv function and the debugger engine.

Jump to

Keyboard shortcuts

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