extract

package module
v0.0.0-...-eef28a2 Latest Latest
Warning

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

Go to latest
Published: Sep 23, 2024 License: MIT Imports: 11 Imported by: 0

README

Extract

Note: This project is in heavy early development and many, if not all, features described below do not actually exist yet.

Extract is a functional, dynamically-typed scripting language inspired by Lisp and Elixir and running on top of the Go runtime. It has Erlang-like concurrency features and good interaction with Go.

Example

As the language is still in early planning stages, this example is subject to change in backwards-incompatible ways.

(defmodule Example
    (defwhen (fib n) (lte? n 1) n)

    (def (fib n) (+
        (fib (- n 1))
        (fib (- n 2))
    ))
)

(IO.println (fib 5))

Documentation

Overview

Package extract implements the core of the Extract language.

Index

Constants

This section is empty.

Variables

View Source
var ErrPatternMatch = errors.New("arguments did not match defined patterns")

Functions

func Equal

func Equal(v1, v2 any) bool

Equal returns true if one of the following is true, in order:

* v1 is an Equaler and v1.Equal(v2) * v2 is an Equaler and v2.Equal(v1) * v1 == v2

If the last step is reached and either type is not comparable, the result is false.

func EvalAll

func EvalAll[T any](env *Env, seq iter.Seq[T]) iter.Seq[any]

EvalAll returns an iterator that evaluates each element in seq using Eval and yields the results. It uses r as the base Env for the evaluation and updates it with the result of each elements evaluation.

func EvalAllWithRuntime

func EvalAllWithRuntime[T any](env *Env, seq iter.Seq[T]) iter.Seq2[*Env, any]

EvalAllWithRuntime is like EvalAll, but also yields the Env that results from each elements evaluation.

func IsEquatable

func IsEquatable(val any) bool

IsEquatable returns true if val is capable of being equated.

Types

type ArgumentNumError

type ArgumentNumError struct {
	Num      int
	Expected int
}

ArgumentNumError is returned when a function is called with the wrong number of arguments. If the function has a specific number of arguments that it expects, Expected will be >= 0.

func (*ArgumentNumError) Error

func (err *ArgumentNumError) Error() string

type Atom

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

Atom is an interned string. Atoms are comparable and are very efficient to compare, but slightly less efficient to create at runtime or to convert back to a string.

The parser will automatically create these from atom literals.

func MakeAtom

func MakeAtom(str string) Atom

MakeAtom returns an atom representing the given string. The returned atom will be equal to all other atoms returned from this function when called with the same string.

func (Atom) String

func (atom Atom) String() string

String gets the string value that the atom was created from.

type Call

type Call struct {
	*List
}

Call is a function call. It calls the first element of the underlying list with the remainder of the list as arguments. If the list is empty, it just returns the list.

func (Call) Eval

func (call Call) Eval(env *Env, args *List) (*Env, any)

type Env

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

Env is the language's state. It tracks global data that is necessary throughout an Extract program, such as declared modules. A runtime is necessary to properly evaluate Extract code. To do so, use the context returned by a runtime's [Context] method.

func Eval

func Eval(env *Env, expr any, args *List) (*Env, any)

Eval evaluates a value, potentially passing arguments to it. If the value implements Evaluator, its Eval method is called. If not and arguments were provided, the value is returned as the first element of a list containing it and the arguments provided. Otherwise, the value is returned unmodified.

func New

func New(ctx context.Context) *Env

New returns a runtime that has been initialized with the standard global state.

func Run

func Run[T any](env *Env, seq iter.Seq[T]) (e *Env, ret any)

Run runs a list like it's the body of a function. If any elements of the list return an error when evaluated, this function returns early with that error. Otherwise, it returns the result of the evaluation of the last element of the list.

func (*Env) AddModule

func (env *Env) AddModule(name Atom) *Module

AddModule declares a new module with the given name. If the module already exists, it returns nil.

func (*Env) All

func (env *Env) All() iter.Seq2[Ident, any]

All returns an iterator that yields all bound identifiers in the order that they are looked up in.

func (Env) Context

func (env Env) Context() context.Context

func (*Env) GetModule

func (env *Env) GetModule(name Atom) *Module

GetModule finds a declared module with the given name. If no such module has been declared, it returns nil.

func (Env) Let

func (env Env) Let(ident Ident, val any) *Env

Let returns a copy of env in which ident is bound to val.

func (Env) Lookup

func (env Env) Lookup(ident Ident) (any, bool)

Lookup gets the value of ident that it is bound to in the environment. If ident is not bound to anything, it will return false as the second return value.

func (Env) WithContext

func (env Env) WithContext(ctx context.Context) *Env

type Equaler

type Equaler interface {
	Equal(any) bool
}

Equaler is implemented by types that want to define custom equality.

type EvalFunc

type EvalFunc func(env *Env, args *List) (*Env, any)

EvalFunc is a func wrapper for Evaluator.

func (EvalFunc) Eval

func (f EvalFunc) Eval(env *Env, args *List) (*Env, any)

type Evaluator

type Evaluator interface {
	// Eval evaluates the value in the given [Runtime] with the given
	// arguments. It returns the result of the evaluation and a new
	// Runtime representing any modifications that the evaluation has
	// made to it.
	//
	// Most implementations will simply return the Runtime unmodified.
	Eval(env *Env, args *List) (*Env, any)
}

Evaluator is a value that can be evaluated, possibly with arguments, such as a function.

type Func

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

func NewFunc

func NewFunc(env *Env, name Ident, pattern *Pattern, body *List) *Func

func (*Func) AddVariant

func (f *Func) AddVariant(pattern *Pattern, body *List)

func (*Func) Eval

func (f *Func) Eval(env *Env, args *List) (*Env, any)

type Ident

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

Ident is an identifier for bound data, i.e. a declared variable/function.

func MakeIdent

func MakeIdent(str string) Ident

MakeIdent returns a new Ident for the given string. It has the exact same semantics as MakeAtom.

func (Ident) Eval

func (ident Ident) Eval(env *Env, args *List) (*Env, any)

func (Ident) String

func (ident Ident) String() string

type List

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

List is a singly-linked list. It is the core building block of the language. Both a zero-value List and a nil *List are valid lists of length 0.

func CollectList

func CollectList[T any](seq iter.Seq[T]) (list *List)

CollectList creates a new list from the elements of seq in the same order that they are yielded.

func ListOf

func ListOf(vals ...any) (list *List)

ListOf returns a list containing the values provided in the same order.

func PushAll

func PushAll[T any](list *List, seq iter.Seq[T]) *List

PushAll pushes all of the elements of seq onto list and returns the new list that results. Note that the elements will be in the reversed order from that which they are yielded in.

func (*List) All

func (list *List) All() iter.Seq[any]

All returns an iterator over the values stored in the list.

func (*List) Head

func (list *List) Head() any

Head returns the value at the head of the list. In other words, the value of the this node in the linked list.

func (*List) Len

func (list *List) Len() int

Len returns the length of the list. Each node caches the length, so this operation is O(1) despite the linked list nature of the implementation.

func (*List) Push

func (list *List) Push(val any) *List

Push pushes an element onto the list, effectively prepending it. It returns the node representing the new list that is formed.

Note that the old list is still valid, but unmodified.

func (*List) Tail

func (list *List) Tail() *List

Tail returns the tail of the list.

type Module

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

Module is a basic building block of an Extract program. All declared functions must be declared inside of a module. Modules are identified by an atom and are global to a Env once they are declared.

func (*Module) Lookup

func (m *Module) Lookup(ident Ident) (any, bool)

Lookup returns the value associated with the given identifier inside of the module. If nothing with the given identifier has been declared in the module, it returns false as the second return value.

func (*Module) Name

func (m *Module) Name() Atom

Name returns the name of the module.

type NameError

type NameError struct {
	Ident Ident
}

NameError is returned when an identifier was accessed but is not bound in the scope.

func (*NameError) Error

func (err *NameError) Error() string

type Pattern

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

func CompilePattern

func CompilePattern(env *Env, format any) (*Pattern, error)

func (*Pattern) Match

func (p *Pattern) Match(env *Env, val any) (*Env, bool)

type Pinned

type Pinned struct {
	Ident Ident
}

Pinned is an identifier that has been pinned. This is used to signal during pattern matching that the value of an identifier should be matched against instead of simply binding the identifier to a new value.

func (Pinned) Eval

func (p Pinned) Eval(env *Env, args *List) (*Env, any)

Eval returns an error every time because a Pinned should never actually be used as an expression.

type Ref

type Ref struct {
	// In the module that the identifier is being accessed inside of. It
	// can be any expression but it must return an atom or an error.
	In any

	// Name is the identifier being accessed.
	Name Ident
}

Ref is an access of an identifier namespaced with a module.

func (Ref) Eval

func (ref Ref) Eval(env *Env, args *List) (*Env, any)

type TypeError

type TypeError struct {
	Val      any
	Expected []reflect.Type
}

TypeError is returned by expressions that have incorrect types in them in some way. Val is the value that is of the wrong type. If there is information about types that were expected, the Expected field will contain it.

func NewTypeError

func NewTypeError(val any, expected ...reflect.Type) *TypeError

NewTypeError is a convience function that creates a new TypeError.

func (*TypeError) Error

func (err *TypeError) Error() string

type UndefinedModuleError

type UndefinedModuleError struct {
	Name Atom
}

UndefinedModuleError is returned when an attempt is made to access a module that has not been defined.

func (*UndefinedModuleError) Error

func (err *UndefinedModuleError) Error() string

Directories

Path Synopsis
Package literal defines types created by the parser from literals.
Package literal defines types created by the parser from literals.
Package parser implements a parser for Extract code.
Package parser implements a parser for Extract code.
Package scanner implements a scanner for Extract tokens.
Package scanner implements a scanner for Extract tokens.

Jump to

Keyboard shortcuts

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