lisp

package
v1.16.8 Latest Latest
Warning

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

Go to latest
Published: Mar 29, 2024 License: BSD-3-Clause Imports: 15 Imported by: 4

Documentation

Index

Constants

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 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 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 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 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 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) 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 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
}

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) 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)

ErrorAssociate associates the LError value lerr with env's current call stack and source location. ErrorAssociate panics if lerr is not LError.

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

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.

NOTE: Eval shouldn't unquote v during evaluation -- a difference between Eval and the “eval” builtin function, but it does. For some reason macros won't work without this unquoting.

func (*LEnv) EvalSExpr

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

EvalSExpr evaluates s and returns the resulting LVal.

func (*LEnv) FunCall

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

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.

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

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.

func (*LEnv) LoadFile

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.

func (*LEnv) LoadLocation

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.

func (*LEnv) LoadString

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

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) 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
}

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.

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.

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 panics if v.Type is not LArray

func (*LVal) ArrayIndex

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

ArrayIndex returns the value at

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.

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.

BUG: sorted-map comparison is not implemented

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 panics 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 panics 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 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
	Symbols   map[string]*LVal
	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 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 {
}

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
	// 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).

func StandardRuntime

func StandardRuntime() *Runtime

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

func (*Runtime) GenEnvID

func (r *Runtime) GenEnvID() uint

func (*Runtime) GenSym

func (r *Runtime) GenSym() string

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.

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.

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

Jump to

Keyboard shortcuts

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