sx

package module
v0.0.0-...-00f4f51 Latest Latest
Warning

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

Go to latest
Published: Dec 5, 2025 License: EUPL-1.2 Imports: 11 Imported by: 12

README

sx - symbolic expressions

Sx is a collection of libraries and frameworks to work with s-expressions.

See for more information on its project page.

Types

Sx support the following atomic, immutable types:

  • Numbers contain numeric values. Currently, only integer values are supported. There is no maximum or minimum integer value. They optionally start with a + or - sign and contain only digits 0, ..., 9.
  • Strings are UTF-8 encoded Unicode character sequences. They are delimited by " characters. Special characters inside the string, like the " character itself, are escaped by the \ character.
  • Symbols are sequences of printable / visible Unicode characters. They are typically used to bind them to values within an environment. Another use case is symbolic computation.

Sx supports nested lists. A list is delimited by parentheses: ( ... ). Within a list, all values are separated by space characters, including new line. Lists can be nested. Internally, lists are created by pairs. The first part of a pair, called "car", contains the actual value stored at the beginning of a list. The second part, called "cdr", typically links to the next pair. This allows multiple lists to share elements. A proper list is a list, where the last elements second part is the empty list. The last element of a list may be a pair, where the second part references a values except a list. Such lists are improper lists. Since the second part may reference any value, even earlier elements of a list, lists may be circular. Single pairs are denoted as (X . Y), where the car references S and the cdr references Y (Y is not a list).

All other types supported by Sx cannot be specified via the reader.

  • Vector is a mutable sequence of values, to be used if direct access to values of a longer sequence is needed. A list has only O(n) access. Vectors are typically more memory efficient, compared to pair lists. However, they cannot be process recursively and they are not able to share elements.
  • Undefined contains just the undefined value. It is signalled by some functions that should not abort with an error.

There is no special boolean value. The empty list (), the empty string "", and the undefined value are considered as a "false" value. All other values are treated as a "true" value. Most functions that return a boolean value currently return the empty list to signal a "false" value or return either the number 1 or the symbol T as a "true" value.

Vectors and lists are both sequences and share some common functions / methods. You can calculate the length of a sequence, check for a length less than a value, fetch the n-th element of a sequence, convert a sequence to a pair list, and iterate over the elements in a ordered way.

Documentation

Overview

Package sx provides the basic objects to work with symbolic expressions.

Index

Constants

View Source
const (
	InitName    = "INIT"
	KeywordName = "KEYWORD"
)

Predefined package names.

View Source
const VectorName = "vector"

VectorName is the name of the (vector ...) builtin

Variables

View Source
var (
	SymbolQuote           = initPackage.MakeSymbol("quote")
	SymbolQuasiquote      = initPackage.MakeSymbol("quasiquote")
	SymbolUnquote         = initPackage.MakeSymbol("unquote")
	SymbolUnquoteSplicing = initPackage.MakeSymbol("unquote-splicing")
)

Names of quotation symbols.

Used in packages sxbuiltins, sxreader.

View Source
var ErrZeroNotAllowed = errors.New("number zero not allowed")

ErrZeroNotAllowed is signalled with an argument must not be zero, e.g. for division.

View Source
var T = MakeSymbol("T")

T is the default true object.

Functions

func AllPackages

func AllPackages() iter.Seq[*Package]

AllPackages returns an iterator of all packages.

func IsFalse

func IsFalse(obj Object) bool

IsFalse returns true, if the given object will be interpreted as "false" in a boolean context.

func IsList

func IsList(obj Object) bool

IsList returns true, if the object is a list, not just a pair. A list must have a nil value at the last cdr.

func IsNil

func IsNil(obj Object) bool

IsNil returns true, if the given object is the nil object.

func IsTrue

func IsTrue(obj Object) bool

IsTrue returns true, if the given object will be interpreted as "true" in a boolean context.

func IsUndefined

func IsUndefined(obj Object) bool

IsUndefined returns true iff the object is a undefined value

func NumCmp

func NumCmp(x, y Number) int

NumCmp compares the two number and returns -1 if x < y, 0 if x = y, and 1 if x > y.

func Print

func Print(w io.Writer, obj Object) (int, error)

Print writes the string representation to a io.Writer.

Types

type ErrImproper

type ErrImproper struct{ Pair *Pair }

ErrImproper is signalled if an improper list is found where it is not appropriate.

func (ErrImproper) Error

func (err ErrImproper) Error() string

Error returns a textual representation for this error.

type ErrSymbolFrozen

type ErrSymbolFrozen struct{ Symbol *Symbol }

ErrSymbolFrozen is returned when trying to update a frozen symbol.

func (ErrSymbolFrozen) Error

func (err ErrSymbolFrozen) Error() string

type Int64

type Int64 int64

Int64 is a number that store 64 bit integer values.

func (Int64) GoString

func (i Int64) GoString() string

GoString returns the Go string representation.

func (Int64) IsAtom

func (Int64) IsAtom() bool

IsAtom always returns true because a symbol is an atomic value.

func (Int64) IsEqual

func (i Int64) IsEqual(other Object) bool

IsEqual compare two objects.

func (Int64) IsNil

func (i Int64) IsNil() bool

IsNil return true, if it is a nil integer value.

func (Int64) IsTrue

func (i Int64) IsTrue() bool

IsTrue returns true if Int64 can be interpreted as a "true" value.

func (Int64) IsZero

func (i Int64) IsZero() bool

IsZero returns true if the value is zero.

func (Int64) String

func (i Int64) String() string

String returns the string representation.

type ListBuilder

type ListBuilder struct {
	// contains filtered or unexported fields
}

ListBuilder is a helper to build a list sequentially from start to end.

func (*ListBuilder) Add

func (lb *ListBuilder) Add(obj Object)

Add an object to the list builder.

func (*ListBuilder) AddN

func (lb *ListBuilder) AddN(objs ...Object)

AddN adds multiple objects to the list builder.

func (*ListBuilder) Collect

func (lb *ListBuilder) Collect(seq iter.Seq[Object])

Collect all values of the iterator into a list.

func (*ListBuilder) ExtendBang

func (lb *ListBuilder) ExtendBang(lst *Pair)

ExtendBang the list by the given list, reusing the given list

func (*ListBuilder) IsEmpty

func (lb *ListBuilder) IsEmpty() bool

IsEmpty returns true, if no element was added.

func (*ListBuilder) Last

func (lb *ListBuilder) Last() *Pair

Last returns the last pair.

func (*ListBuilder) List

func (lb *ListBuilder) List() *Pair

List the result, but not resetting the builder.

func (*ListBuilder) Reset

func (lb *ListBuilder) Reset()

Reset the list builder.

type Number

type Number interface {
	Object

	// Returns true iff the number is equal to zero.
	IsZero() bool
}

Number value store numbers.

func GetNumber

func GetNumber(obj Object) (Number, bool)

GetNumber returns the object as a number, if possible.

func NumAdd

func NumAdd(x, y Number) Number

NumAdd adds the two numbers.

func NumDiv

func NumDiv(x, y Number) (Number, error)

NumDiv divides the first by the second number.

func NumMod

func NumMod(x, y Number) (Number, error)

NumMod divides the first by the second number.

func NumMul

func NumMul(x, y Number) Number

NumMul multiplies the two numbers.

func NumNeg

func NumNeg(x Number) Number

NumNeg negates the given number.

func NumSub

func NumSub(x, y Number) Number

NumSub subtracts the two numbers.

func ParseInteger

func ParseInteger(s string) (Number, error)

ParseInteger parses the string as an integer value and returns its value as a number.

type Object

type Object interface {
	fmt.Stringer
	fmt.GoStringer

	// IsNil checks if the concrete object is nil.
	IsNil() bool

	// IsAtom returns true iff the object is an object that is not further decomposable.
	IsAtom() bool

	// IsTrue returns true, of the value can be considered as a "true" value.
	IsTrue() bool

	// IsEqual compare two objects for deep equality.
	IsEqual(Object) bool
}

Object is the generic value all s-expressions must fulfill.

func MakeBoolean

func MakeBoolean(b bool) Object

MakeBoolean creates a new Boolean object.

type Package

type Package struct {
	// contains filtered or unexported fields
}

Package maps symbol names to Symbols.

func CurrentPackage

func CurrentPackage() *Package

CurrentPackage returns the currently selected package.

func FindPackage

func FindPackage(name string) *Package

FindPackage returns the package with the given name.

func GetPackage

func GetPackage(obj Object) (*Package, bool)

GetPackage returns the object as a package if possible.

func KeywordPackage

func KeywordPackage() *Package

KeywordPackage return the package that manages keyword symbols.

func MakePackage

func MakePackage(name string) (*Package, error)

MakePackage builds a new package.

func MustMakePackage

func MustMakePackage(name string) *Package

MustMakePackage builds a new package and panics if something went wrong.

func (*Package) AllSymbols

func (pkg *Package) AllSymbols() iter.Seq[*Symbol]

AllSymbols returns an iterator of all symbols currently manages by the package.

func (*Package) FindSymbol

func (pkg *Package) FindSymbol(name string) *Symbol

FindSymbol returns the symbol with the given name.

func (*Package) GoString

func (pkg *Package) GoString() string

GoString returns the go string representation.

func (*Package) IsAtom

func (pkg *Package) IsAtom() bool

IsAtom always returns true because a symbol is an atomic value.

func (*Package) IsEqual

func (pkg *Package) IsEqual(other Object) bool

IsEqual compare the symbol with an object.

func (*Package) IsEqualPackage

func (pkg *Package) IsEqualPackage(other *Package) bool

IsEqualPackage compare two packages.

func (*Package) IsNil

func (pkg *Package) IsNil() bool

IsNil may return true if a symbol pointer is nil.

func (*Package) IsTrue

func (pkg *Package) IsTrue() bool

IsTrue returns true if package can be interpreted as a "true" value.

func (*Package) MakeSymbol

func (pkg *Package) MakeSymbol(name string) *Symbol

MakeSymbol builds a symbol with the given string value. It tries to re-use symbols, so that symbols can be compared by their reference, not by their content.

func (*Package) Name

func (pkg *Package) Name() string

Name returns the package name.

func (*Package) Size

func (pkg *Package) Size() int

Size returns the number of symbols created by the package.

func (*Package) String

func (pkg *Package) String() string

String returns the string representation.

type Pair

type Pair struct {
	// contains filtered or unexported fields
}

Pair is a node containing a value for the element and a pointer to the tail. In other lisps it is often called "cell", "cons", "cons-cell", or "list".

func Cons

func Cons(car, cdr Object) *Pair

Cons creates a pair, often called a "cons cell".

func GetPair

func GetPair(obj Object) (*Pair, bool)

GetPair returns the object as a pair.

func MakeList

func MakeList(objs ...Object) *Pair

MakeList creates a new list with the given objects.

func Nil

func Nil() *Pair

Nil returns the nil list.

func (*Pair) AppendBang

func (pair *Pair) AppendBang(obj Object) *Pair

AppendBang updates the given pair by setting a new pair with the given object and nil as its new second object.

func (*Pair) Assoc

func (pair *Pair) Assoc(obj Object) *Pair

Assoc returns the first pair of a list where the car IsEqual to the given object.

func (*Pair) Car

func (pair *Pair) Car() Object

Car returns the first object of a pair.

func (*Pair) Cdr

func (pair *Pair) Cdr() Object

Cdr returns the second object of a pair.

func (*Pair) Cons

func (pair *Pair) Cons(car Object) *Pair

Cons prepends a value in front of a given listreturning the new list.

func (*Pair) Copy

func (pair *Pair) Copy() *Pair

Copy returns a copy of the given pair list.

func (*Pair) ExtendBang

func (pair *Pair) ExtendBang(obj *Pair) *Pair

ExtendBang updates the given pair by extending it with the second pair list after its end. Returns the last list node of the newly formed list beginning with `lst`, which is also the last list node of the list starting with `val`.

func (*Pair) GoString

func (pair *Pair) GoString() string

GoString returns the go string representation.

func (*Pair) Head

func (pair *Pair) Head() *Pair

Head returns the first object as a pair, if possible. Otherwise it returns nil.

func (*Pair) IsAtom

func (pair *Pair) IsAtom() bool

IsAtom returns true, if the list is an atom.

func (*Pair) IsEqual

func (pair *Pair) IsEqual(other Object) bool

IsEqual compare two objects.

func (*Pair) IsNil

func (pair *Pair) IsNil() bool

IsNil return true, if it is a nil pair object.

func (*Pair) IsTrue

func (pair *Pair) IsTrue() bool

IsTrue returns true if pair can be interpreted as a "true" value.

func (*Pair) Last

func (pair *Pair) Last() (Object, error)

Last returns the last element of a non-empty list.

func (*Pair) LastPair

func (pair *Pair) LastPair() *Pair

LastPair returns the last pair of the given pair list, or nil.

func (*Pair) Length

func (pair *Pair) Length() int

Length returns the length of the pair list.

The list must not be circular.

func (*Pair) LengthEqual

func (pair *Pair) LengthEqual(n int) bool

LengthEqual returns true if the length of the pair list is equal to the given number.

pair.LengthEqual(n) is typically much faster than pair.Length() == n.

func (*Pair) LengthGreater

func (pair *Pair) LengthGreater(n int) bool

LengthGreater returns true if the length of the pair list is greater than the given number.

pair.LengthGreater(n) is typically much faster than pair.Length() > n.

func (*Pair) LengthLess

func (pair *Pair) LengthLess(n int) bool

LengthLess returns true if the length of the pair list is less than the given number.

pair.LengthLess(n) is typically much faster than pair.Length() < n.

func (*Pair) MakeList

func (pair *Pair) MakeList() *Pair

MakeList builds a list. Basically, the same pair is returned. This method is needed to make Sequence interface happy.

func (*Pair) Nth

func (pair *Pair) Nth(n int) (Object, error)

Nth returns the n'th object of the pair list. It is an error, if n < 0 or if the list length is less than n.

func (*Pair) Pairs

func (pair *Pair) Pairs() iter.Seq[*Pair]

Pairs returns an iterator of all pair nodes.

func (*Pair) Print

func (pair *Pair) Print(w io.Writer) (int, error)

Print write the string representation to the given Writer.

func (*Pair) RemoveAssoc

func (pair *Pair) RemoveAssoc(obj Object) *Pair

RemoveAssoc deletes all pairs from the association list, where the car IsEqual to the given object. A new list is created.

func (*Pair) Reverse

func (pair *Pair) Reverse() (*Pair, error)

Reverse returns a reversed pair list.

func (*Pair) SetCar

func (pair *Pair) SetCar(obj Object)

SetCar sets the car of the pair to the given object.

func (*Pair) SetCdr

func (pair *Pair) SetCdr(obj Object)

SetCdr sets the cdr of the pair to the given object.

func (*Pair) String

func (pair *Pair) String() string

String returns the string representation.

func (*Pair) Tail

func (pair *Pair) Tail() *Pair

Tail returns the second object as a pair, if possible. Otherwise it returns nil.

func (*Pair) Values

func (pair *Pair) Values() iter.Seq[Object]

Values returns an iterator of all objects in the pair list.

type Printable

type Printable interface {
	// Print emits the string representation on the given Writer
	Print(io.Writer) (int, error)
}

Printable is a object that has is specific representation, which is different to String().

type Sequence

type Sequence interface {
	Object

	// Length returns the length of the sequence.
	Length() int

	// LengthLess reports whether the length of the sequence is less than
	// the given number.
	LengthLess(n int) bool

	// LengthGreater reports whether the length of the sequence is greater than
	// the given number.
	LengthGreater(n int) bool

	// LengthEqual reports whether the length of the sequence is equal to the
	// given number.
	LengthEqual(n int) bool

	// Nth returns the n-th element of a sequence.
	Nth(n int) (Object, error)

	// MakeList returns the sequence as a pair list. If sequence is already a
	// pair list, it is returned without copying it.
	MakeList() *Pair

	// Values() returns an iterator over all elements of the sequence in
	// natural order.
	Values() iter.Seq[Object]
}

Sequence is an Object that has a finite, ordered set of elements.

func GetSequence

func GetSequence(obj Object) (Sequence, bool)

GetSequence returns the object as a Sequence, if possible.

type String

type String struct {
	// contains filtered or unexported fields
}

String represents a string object.

func GetString

func GetString(obj Object) (String, bool)

GetString returns the object as a string, if possible

func MakeString

func MakeString(s string) String

MakeString creates a String from a string.

func (String) GetValue

func (s String) GetValue() string

GetValue returns the string value of a String.

func (String) GoString

func (s String) GoString() string

GoString returns the go string representation.

func (String) IsAtom

func (String) IsAtom() bool

IsAtom always returns true because a string is an atomic value.

func (String) IsEqual

func (s String) IsEqual(other Object) bool

IsEqual compares two objects for equivalence.

func (String) IsEqualString

func (s String) IsEqualString(other String) bool

IsEqualString compares two strings.

func (String) IsNil

func (String) IsNil() bool

IsNil return true, if it is a nil string value.

func (String) IsTrue

func (s String) IsTrue() bool

IsTrue returns true if string can be interpreted as a "true" value.

func (String) Print

func (s String) Print(w io.Writer) (int, error)

Print write the string representation to the given Writer.

func (String) String

func (s String) String() string

String returns the string representation.

type Symbol

type Symbol struct {
	// contains filtered or unexported fields
}

Symbol represent a symbol value.

func GetSymbol

func GetSymbol(obj Object) (*Symbol, bool)

GetSymbol returns the object as a symbol if possible.

func MakeSymbol

func MakeSymbol(name string) *Symbol

MakeSymbol creates a symbol from a string.

func (*Symbol) Bind

func (sym *Symbol) Bind(val Object) error

Bind a value to the symbol.

func (*Symbol) Bound

func (sym *Symbol) Bound() (Object, bool)

Bound returns the bound value.

func (*Symbol) Freeze

func (sym *Symbol) Freeze()

Freeze the symbol so that bound value cannot be changed any more.

func (*Symbol) GetValue

func (sym *Symbol) GetValue() string

GetValue return the string value of the symbol.

func (*Symbol) GoString

func (sym *Symbol) GoString() string

GoString returns the go string representation.

func (*Symbol) IsAtom

func (*Symbol) IsAtom() bool

IsAtom always returns true because a symbol is an atomic value.

func (*Symbol) IsEqual

func (sym *Symbol) IsEqual(other Object) bool

IsEqual compare the symbol with an object.

func (*Symbol) IsEqualSymbol

func (sym *Symbol) IsEqualSymbol(other *Symbol) bool

IsEqualSymbol compare two symbols.

func (*Symbol) IsFrozen

func (sym *Symbol) IsFrozen() bool

IsFrozen returns true if symbol is frozen.

func (*Symbol) IsKeyword

func (sym *Symbol) IsKeyword() bool

IsKeyword returns true, if the symbols package is the keyword package.

func (*Symbol) IsNil

func (sym *Symbol) IsNil() bool

IsNil may return true if a symbol pointer is nil.

func (*Symbol) IsTrue

func (sym *Symbol) IsTrue() bool

IsTrue returns true if symbol can be interpreted as a "true" value.

func (*Symbol) Package

func (sym *Symbol) Package() *Package

Package returns the Package that created the symbol.

func (*Symbol) Print

func (sym *Symbol) Print(w io.Writer) (length int, err error)

Print write the string representation to the given Writer.

func (*Symbol) String

func (sym *Symbol) String() string

String returns the string representation.

type Undefined

type Undefined struct{}

Undefined is an object that signal a 'no value'.

func MakeUndefined

func MakeUndefined() Undefined

MakeUndefined creates an undefined objact.

func (Undefined) GoString

func (udef Undefined) GoString() string

GoString returns a string representation to be used in Go code.

func (Undefined) IsAtom

func (Undefined) IsAtom() bool

IsAtom always returns false because an undefined value is never atomic.

func (Undefined) IsEqual

func (Undefined) IsEqual(other Object) bool

IsEqual returns true if the other value has the same content.

func (Undefined) IsNil

func (Undefined) IsNil() bool

IsNil always returns false because an undefined value is never nil.

func (Undefined) IsTrue

func (Undefined) IsTrue() bool

IsTrue returns true if undefined can be interpreted as a "true" value. Hint: it will never ;)

func (Undefined) String

func (Undefined) String() string

String returns a strinf representation.

type Vector

type Vector []Object

Vector is a sequence of Objects.

func Collect

func Collect(it iter.Seq[Object]) Vector

Collect values from seq into a new vector and return it.

func GetVector

func GetVector(obj Object) (Vector, bool)

GetVector returns the object as a vector, if possible.

func (Vector) GoString

func (v Vector) GoString() string

GoString returns the string representation to be used in Go code.

func (Vector) IsAtom

func (v Vector) IsAtom() bool

IsAtom signals an atomic value. Only the empty vector is atomic.

func (Vector) IsEqual

func (v Vector) IsEqual(other Object) bool

IsEqual compares the vector with another object to have the same content.

func (Vector) IsNil

func (v Vector) IsNil() bool

IsNil returns true, if the vector should be treated like the Nil() object.

func (Vector) IsTrue

func (v Vector) IsTrue() bool

IsTrue returns true if vector can be interpreted as a "true" value.

func (Vector) Length

func (v Vector) Length() int

Length returns the length of the vector.

func (Vector) LengthEqual

func (v Vector) LengthEqual(n int) bool

LengthEqual return true, if the length of the vector is equal to the given value.

func (Vector) LengthGreater

func (v Vector) LengthGreater(n int) bool

LengthGreater return true, if the length of the vector is greater than the given value.

func (Vector) LengthLess

func (v Vector) LengthLess(n int) bool

LengthLess return true, if the length of the vector is less than the given value.

func (Vector) MakeList

func (v Vector) MakeList() *Pair

MakeList builds a pair list from the vector.

func (Vector) Nth

func (v Vector) Nth(n int) (Object, error)

Nth returns the object at the given position. It is an error if the position is less than zero or greater than the vector length.

func (Vector) Print

func (v Vector) Print(w io.Writer) (int, error)

Print write the string representation to the given Writer.

func (Vector) String

func (v Vector) String() string

func (Vector) Values

func (v Vector) Values() iter.Seq[Object]

Values returns an iterator over the sequence of vector elements.

Source Files

  • boolean.go
  • const.go
  • list.go
  • number.go
  • package.go
  • sequence.go
  • string.go
  • sx.go
  • symbol.go
  • undef.go
  • vector.go

Directories

Path Synopsis
Package main provides a simple interpreter for s-expressions.
Package main provides a simple interpreter for s-expressions.
Package sxbuiltins contains functions that help to build builtin functions.
Package sxbuiltins contains functions that help to build builtin functions.
Package sxeval allows to evaluate s-expressions.
Package sxeval allows to evaluate s-expressions.
Package sxreader implements a way to read symbolic expression into an internal representation.
Package sxreader implements a way to read symbolic expression into an internal representation.

Jump to

Keyboard shortcuts

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