Documentation ¶
Overview ¶
Package core contains the high level internal function of Serene
Index ¶
- Constants
- Variables
- func Def(rt *Runtime, scope IScope, args *List) (IExpr, IError)
- func DefMacro(rt *Runtime, scope IScope, args *List) (IExpr, IError)
- func Eval(rt *Runtime, forms *Block) (IExpr, IError)
- func EvalForms(rt *Runtime, scope IScope, expressions IExpr) (IExpr, IError)
- func EvalNSBody(rt *Runtime, ns *Namespace) (*Namespace, IError)
- func Fn(rt *Runtime, scope IScope, args *List) (IExpr, IError)
- func HashNativeFn(rt *Runtime, scope IScope, n Node, args *List) (IExpr, IError)
- func ListStartsWith(l *List, sym string) bool
- func MakeDouble(x interface{}) (*Double, IError)
- func MakeFnScope(rt *Runtime, parent IScope, bindings, values IColl) (*Scope, IError)
- func MakeInteger(x interface{}) (*Integer, IError)
- func MakeKeyword(n Node, name string) (*Keyword, IError)
- func MakeSymbol(n Node, s string) (*Symbol, IError)
- func NSForm(rt *Runtime, scope IScope, args *List) (IExpr, IError)
- func ParseToAST(ns string, input *string) (*Block, IError)
- func Pr(rt *Runtime, forms ...IRepresentable)
- func PrNativeFn(rt *Runtime, scope IScope, n Node, args *List) (IExpr, IError)
- func Print(rt *Runtime, forms ...IRepresentable)
- func PrintError(rt *Runtime, err IError)
- func PrintNativeFn(rt *Runtime, scope IScope, n Node, args *List) (IExpr, IError)
- func Println(rt *Runtime, forms ...IRepresentable)
- func PrintlnNativeFn(rt *Runtime, scope IScope, n Node, args *List) (IExpr, IError)
- func Prn(rt *Runtime, forms ...IRepresentable)
- func PrnNativeFn(rt *Runtime, scope IScope, n Node, args *List) (IExpr, IError)
- func REPL(flags map[string]bool)
- func ReadBytes(ns string, input *[]byte) (*Block, IError)
- func ReadString(ns string, input *string) (*Block, IError)
- func RequireNamespace(rt *Runtime, namespace IExpr) (IExpr, IError)
- func RequireNativeFn(rt *Runtime, scope IScope, n Node, args *List) (IExpr, IError)
- func Run(flags map[string]bool, args []string)
- type Binding
- type Block
- func (b *Block) Append(form IExpr)
- func (b *Block) Count() int
- func (b *Block) GetLocation() *ast.Location
- func (b *Block) GetType() ast.NodeType
- func (b *Block) Hash() uint32
- func (b *Block) SetContent(body []IExpr)
- func (b *Block) String() string
- func (b *Block) ToDebugStr() string
- func (b *Block) ToSlice() []IExpr
- type Bool
- type CallStack
- type CallStackItem
- type Double
- type ErrType
- type Error
- func (e *Error) Error() string
- func (e *Error) GetDescription() *string
- func (e *Error) GetErrType() ErrType
- func (e *Error) GetErrno() errors.Errno
- func (e *Error) GetStackTrace() *TraceBack
- func (e *Error) SetNode(n *Node)
- func (e *Error) String() string
- func (e *Error) ToDebugStr() string
- func (e *Error) WithError(err error) IError
- type ExecutionScope
- type Frame
- type Function
- func (f *Function) Apply(rt *Runtime, scope IScope, n Node, args *List) (IExpr, IError)
- func (f *Function) GetBody() *Block
- func (f *Function) GetName() string
- func (f *Function) GetParams() IColl
- func (f *Function) GetScope() IScope
- func (f *Function) GetType() ast.NodeType
- func (f *Function) Hash() uint32
- func (f *Function) IsMacro() bool
- func (f *Function) SetName(name string)
- func (f *Function) String() string
- func (f *Function) ToDebugStr() string
- type ICallStack
- type IColl
- type ICountable
- type IDebuggable
- type IError
- func MakeError(rt *Runtime, e IExpr, msg string) IError
- func MakePlainError(msg string) IError
- func MakeRuntimeError(rt *Runtime, e IExpr, errno errors.Errno, msg string) IError
- func MakeSemanticError(rt *Runtime, e IExpr, errno errors.Errno, msg string) IError
- func MakeSyntaxErrorf(n Node, msg string, a ...interface{}) IError
- func ProcessInstruction(rt *Runtime, form *Instruction) IError
- type IExpr
- type IFn
- type INamespace
- type INumber
- type IParsable
- type IPrintable
- type IRepresentable
- type IScopable
- type IScope
- type ISeq
- type Instruction
- type Integer
- func (i *Integer) F64() float64
- func (i *Integer) GetExecutionScope() IScope
- func (i *Integer) GetType() ast.NodeType
- func (i *Integer) Hash() uint32
- func (i *Integer) I64() int64
- func (i *Integer) SetExecutionScope(scope IScope)
- func (i *Integer) String() string
- func (i *Integer) ToDebugStr() string
- type Keyword
- type List
- func (l *List) AppendToList(e IExpr) *List
- func (l *List) Cons(e IExpr) IExpr
- func (l *List) Count() int
- func (l *List) First() IExpr
- func (l *List) GetType() ast.NodeType
- func (l *List) Hash() uint32
- func (l *List) Rest() ISeq
- func (l *List) String() string
- func (l *List) ToDebugStr() string
- func (l *List) ToSlice() []IExpr
- type Namespace
- func (n *Namespace) DefineGlobal(k string, v IExpr, public bool)
- func (n *Namespace) GetExecutionScope() IScope
- func (n *Namespace) GetLocation() *ast.Location
- func (n *Namespace) GetName() string
- func (n *Namespace) GetRootScope() IScope
- func (n *Namespace) GetType() ast.NodeType
- func (n *Namespace) Hash() uint32
- func (n *Namespace) LookupExternal(alias string) *Namespace
- func (n *Namespace) LookupGlobal(rt *Runtime, sym *Symbol) *Binding
- func (n *Namespace) SetExecutionScope(scope IScope)
- func (n *Namespace) String() string
- func (n *Namespace) ToDebugStr() string
- type NativeFunction
- func (f *NativeFunction) Apply(rt *Runtime, scope IScope, n Node, args *List) (IExpr, IError)
- func (f *NativeFunction) GetName() string
- func (f *NativeFunction) GetType() ast.NodeType
- func (f *NativeFunction) Hash() uint32
- func (f *NativeFunction) String() string
- func (f *NativeFunction) ToDebugStr() string
- type Nil
- type Node
- type NothingType
- func (n NothingType) GetExecutionScope() IScope
- func (n NothingType) GetLocation() *ast.Location
- func (n NothingType) GetType() ast.NodeType
- func (n NothingType) Hash() uint32
- func (n NothingType) SetExecutionScope(scope IScope)
- func (n NothingType) String() string
- func (n NothingType) ToDebugStr() string
- type Runtime
- func (r *Runtime) CreateNS(name, source string, setAsCurrent bool)
- func (r *Runtime) CurrentNS() *Namespace
- func (r *Runtime) GetNS(ns string) (*Namespace, bool)
- func (r *Runtime) InsertNS(nsName string, ns *Namespace)
- func (r *Runtime) IsDebugMode() bool
- func (r *Runtime) IsQQSimplificationEnabled() bool
- func (r *Runtime) LookupBuiltin(k string) IExpr
- type Scope
- type String
- type StringParser
- type Symbol
- type TraceBack
Constants ¶
const FALSEFORM string = "false"
const NILFORM string = "nil"
const NSFORM string = "ns"
const ( // Pop a function from the call stack. We use this // instruction at the end of function bodies. So // function bodies will clean up after themselves PopStack instructionType = iota )
Instruction types
const TRUEFORM string = "true"
Variables ¶
var BUILTINS = map[string]NativeFunction{ "pr": MakeNativeFn("pr", PrNativeFn), "prn": MakeNativeFn("prn", PrnNativeFn), "print": MakeNativeFn("print", PrintNativeFn), "println": MakeNativeFn("println", PrintlnNativeFn), "require": MakeNativeFn("require", RequireNativeFn), "hash": MakeNativeFn("hash", HashNativeFn), }
BUILTINS is used in the Runtime to support builtin functions of the language which are implemented in Go
var Nothing = NothingType{}
Functions ¶
func Def ¶
Def defines a global binding in the current namespace. The first arguments in `args` has to be a symbol ( none ns qualified ) and the second param should be the value of the binding
func DefMacro ¶
Def defines a macro in the current namespace. The first arguments in `args` has to be a symbol ( none ns qualified ) and the rest of params should be the body of the macro. Unlike other expressions in Serene `defmacro` DOES NOT evaluate its arguments. That is what makes macros great
func Eval ¶
Eval the given `Block` of code with the given runtime `rt`. The Important part here is that any expression that we need to Eval has to be wrapped in a Block. Don't confused the concept of Block with blocks from other languages which specify by using `{}` or indent or what ever. Blocks in terms of Serene are just arrays of expressions and nothing more.
func EvalForms ¶
EvalForms evaluates the given expr `expressions` (it can be a list, block, symbol or anything else) with the given runtime `rt` and the scope `scope`.
func EvalNSBody ¶
EvalNSBody evals the body of the given namespace `ns` using the given runtime `rt`. It makes sure that the body starts with a `ns` special form with the same name as the ns argument.
func Fn ¶
Fn defines a function inside the given scope `scope` with the given `args`. `args` contains the argument list, docstring and body of the function.
func HashNativeFn ¶
func ListStartsWith ¶
func MakeDouble ¶
func MakeFnScope ¶
MakeFnScope a new scope for the body of a function. It binds the `bindings` to the given `values`.
func MakeInteger ¶
func ParseToAST ¶
ParseToAST is the entry function to the reader/parser which converts the `input` string to a `Block` of code. A block by itself is not something available to the language. It's just anbstraction for a ordered collection of expressions. It doesn't have anything to do with the concept of blocks from other programming languages.
func Pr ¶
func Pr(rt *Runtime, forms ...IRepresentable)
func Print ¶
func Print(rt *Runtime, forms ...IRepresentable)
func PrintError ¶
func PrintNativeFn ¶
func Println ¶
func Println(rt *Runtime, forms ...IRepresentable)
func PrintlnNativeFn ¶
func Prn ¶
func Prn(rt *Runtime, forms ...IRepresentable)
func RequireNamespace ¶
RequireNamespace finds and loads the naemspace which is addressed by the given expression `namespace` and add the loaded namespace to the list of available namespaces on the runtime and add the correct reference to the current namespace. If `namespace` is a symbol, then the name of the symbol would be used as the ns name and an alias with the same name will be added to the current namespace as the external reference. If it is a IColl (List at the moment), then the symbol in the first element would be the ns name and the second symbol will be the name of the alias to be used.
func RequireNativeFn ¶
Types ¶
type Block ¶
type Block struct { ExecutionScope // contains filtered or unexported fields }
Block struct represents a group of forms. Don't confuse it with code blocks from other languages that specify a block using curly brackets and indentation. Blocks in serene are just a group of forms and nothing more.
func (*Block) GetLocation ¶
func (*Block) SetContent ¶
func (*Block) ToDebugStr ¶
type Bool ¶
type Bool struct { Node ExecutionScope // contains filtered or unexported fields }
func (*Bool) ToDebugStr ¶
type CallStack ¶
type CallStack struct {
// contains filtered or unexported fields
}
func MakeCallStack ¶
func (*CallStack) GetCurrentFn ¶
func (*CallStack) ToTraceBack ¶
type CallStackItem ¶
type CallStackItem struct {
// contains filtered or unexported fields
}
type Double ¶
type Double struct { Node // contains filtered or unexported fields }
func (*Double) GetExecutionScope ¶
func (*Double) SetExecutionScope ¶
func (*Double) ToDebugStr ¶
type Error ¶
func (*Error) GetDescription ¶
func (*Error) GetErrType ¶
func (*Error) GetStackTrace ¶
func (*Error) ToDebugStr ¶
type ExecutionScope ¶
type ExecutionScope struct {
// contains filtered or unexported fields
}
func (*ExecutionScope) GetExecutionScope ¶
func (e *ExecutionScope) GetExecutionScope() IScope
func (*ExecutionScope) SetExecutionScope ¶
func (e *ExecutionScope) SetExecutionScope(scope IScope)
type Frame ¶
type Function ¶
type Function struct { // Node struct holds the necessary functions to make // Functions locatable Node ExecutionScope // contains filtered or unexported fields }
Function struct represent a user defined function.
func MakeFunction ¶
MakeFunction Create a function with the given `params` and `body` in the given `scope`.
func (*Function) ToDebugStr ¶
type ICallStack ¶
type IColl ¶
type IColl interface { ISeq ICountable ToSlice() []IExpr Cons(e IExpr) IExpr }
IColl describes a collection of values. A finite collection.
type ICountable ¶
type ICountable interface {
Count() int
}
type IDebuggable ¶
type IDebuggable interface {
ToDebugStr() string
}
IDebuggable is the interface designed for converting forms to a string form which are meant to be used as debug data
type IError ¶
type IError interface { // In order to point to a specific point in the input ast.ILocatable // We want errors to be printable by the `print` family IRepresentable IDebuggable GetErrType() ErrType GetErrno() errors.Errno GetDescription() *string GetStackTrace() *TraceBack // To wrap Golan rrrrors WithError(err error) IError // Some errors might doesn't have any node available to them // at the creation time. SetNode allows us to the the appropriate // node later in time. SetNode(n *Node) }
IError defines the necessary functionality of the internal errors.
func MakeError ¶
MakeError creates an Error which points to the given IExpr `e` as the root of the error.
func MakePlainError ¶
func MakeRuntimeError ¶
func MakeSemanticError ¶
func MakeSyntaxErrorf ¶
func ProcessInstruction ¶
func ProcessInstruction(rt *Runtime, form *Instruction) IError
ProcessInstruction is the main function to process instructions
type IExpr ¶
type IExpr interface { ast.ILocatable ast.ITypable hash.IHashable IRepresentable IDebuggable IScopable }
IExpr is the most important interface in Serene which basically represents a VALUE in Serene. All the forms (beside special formss) has to implement this interface.
func MakeStackPop ¶
type INamespace ¶
type INumber ¶
type IParsable ¶
type IParsable interface { // Returns the current position in the buffer GetLocation() int GetSource() *ast.Source Buffer() *[]string // contains filtered or unexported methods }
IParsable defines the common interface which any parser has to implement.
type IPrintable ¶
type IPrintable interface { IRepresentable PrintToString() string }
IPrintable is the interface which any value that wants to have a string representation for printing has to implement. The `print` family functions will use this interface to convert forms to string first and if the value doesn't implement this interface they will resort to `IRepresentable`
type IRepresentable ¶
IRepresentable is the interface which any value that wants to have a string representation has to implement. Serene will use this string where ever it needs to present a value as string.
type IScopable ¶
type IScopable interface { // GetExecutionScope returns an attached execution scope if there's // any, nil otherwise. GetExecutionScope() IScope // SetExecutionScope sets the given scope as the execution scope of // the current implementor SetExecutionScope(scope IScope) }
IScopable is the interface describing how to get the execution scope of the value. During the evaluation of the forms in Serene we might rewrite the execution tree to eliminate tail calls. In order to do that we should be able to attach the execution scope to any form that we need to rewrite.
type Instruction ¶
type Instruction struct { // Just to be compatible with IExpr --- Node ExecutionScope Type instructionType }
func (*Instruction) GetType ¶
func (n *Instruction) GetType() ast.NodeType
func (*Instruction) Hash ¶
func (n *Instruction) Hash() uint32
func (*Instruction) String ¶
func (n *Instruction) String() string
func (*Instruction) ToDebugStr ¶
func (n *Instruction) ToDebugStr() string
type Integer ¶
type Integer struct { Node ExecutionScope // contains filtered or unexported fields }
func (*Integer) GetExecutionScope ¶
func (*Integer) SetExecutionScope ¶
func (*Integer) ToDebugStr ¶
type Keyword ¶
type Keyword struct { Node ExecutionScope // contains filtered or unexported fields }
func (*Keyword) Eval ¶
Eval initializes the keyword by looking up the possible alias name and set it in the keyword.
func (*Keyword) IsNSQualified ¶
func (*Keyword) ToDebugStr ¶
type List ¶
type List struct { Node ExecutionScope // contains filtered or unexported fields }
func MakeEmptyList ¶
func (*List) AppendToList ¶
func (*List) ToDebugStr ¶
type Namespace ¶
type Namespace struct {
// contains filtered or unexported fields
}
func (*Namespace) DefineGlobal ¶
DefineGlobal inserts the given expr `v` to the root scope of `n`. The `public` parameter determines whether the public value is accessible publicly or not (in other namespaces).
func (*Namespace) GetExecutionScope ¶
func (*Namespace) GetLocation ¶
func (*Namespace) GetRootScope ¶
func (*Namespace) LookupExternal ¶
LookupExternal looks up the given `alias` in the `externals` table of the namespace.
func (*Namespace) LookupGlobal ¶
LookupGlobal looks up the value represented by the ns qualified symbol `sym` in the external symbols table. Simply looking up a public value from an external namespace.
func (*Namespace) SetExecutionScope ¶
func (*Namespace) ToDebugStr ¶
type NativeFunction ¶
type NativeFunction struct { // Node struct holds the necessary functions to make // Functions locatable Node ExecutionScope // contains filtered or unexported fields }
func MakeNativeFn ¶
func MakeNativeFn(name string, f nativeFnHandler) NativeFunction
func (*NativeFunction) GetName ¶
func (f *NativeFunction) GetName() string
func (*NativeFunction) GetType ¶
func (f *NativeFunction) GetType() ast.NodeType
func (*NativeFunction) Hash ¶
func (f *NativeFunction) Hash() uint32
func (*NativeFunction) String ¶
func (f *NativeFunction) String() string
func (*NativeFunction) ToDebugStr ¶
func (f *NativeFunction) ToDebugStr() string
type Node ¶
type Node struct {
// contains filtered or unexported fields
}
Node struct is simply representing a Node in the AST which provides the functionalities required to trace the code based on the location.
func MakeNode ¶
MakeNode creates a new Node in the the given `input` that points to a range of characters starting from the `start` till the `end`.
func MakeNodeFromExpr ¶
func MakeNodeFromExpr(e ast.ILocatable) Node
MakeNodeFromExpr creates a new Node from the given `ILocatable`. We use the Node to pass it to other IExpr constructors to keep the reference to the original form in the input string
func MakeNodeFromExprs ¶
MakeNodeFromExprs creates a new Node from the given slice of `IExpr`s. We use the Node to pass it to other IExpr constructors to keep the reference to the original form in the input string
func MakeNodeFromLocation ¶
MakeNodeFromLocation creates a new Node for the given Location `loc`
func MakeSinglePointNode ¶
MakeSinglePointNode creates a not the points to a single char in the input
func (Node) GetLocation ¶
GetLocation returns the location of the Node in the source input
type NothingType ¶
type NothingType struct{}
func (NothingType) GetExecutionScope ¶
func (n NothingType) GetExecutionScope() IScope
func (NothingType) GetLocation ¶
func (n NothingType) GetLocation() *ast.Location
func (NothingType) GetType ¶
func (n NothingType) GetType() ast.NodeType
func (NothingType) Hash ¶
func (n NothingType) Hash() uint32
func (NothingType) SetExecutionScope ¶
func (n NothingType) SetExecutionScope(scope IScope)
func (NothingType) String ¶
func (n NothingType) String() string
func (NothingType) ToDebugStr ¶
func (n NothingType) ToDebugStr() string
type Runtime ¶
type Runtime struct { Stack CallStack // contains filtered or unexported fields }
Runtime is the most important data structure in Serene which hold the necessary information and the state of the interpreter at runtime (duh!). At any given time and thread only on Runtime has to exist and we always need to pass a pointer to the runtime around and avoid copying. (We don't have multithread support just yet but the Runtime must be thread safe).
func MakeRuntime ¶
MakeRuntime creates a Runtime and returns a pointer to it. Any runtime initialization such as adding default namespaces and vice versa has to happen here.
func (*Runtime) CreateNS ¶
CreateNS is a helper function to create a namespace and set it to be the current namespace of the runtime. `MakeNS` is much preferred
func (*Runtime) GetNS ¶
GetNS returns a pointer to the `Namespace` specified with the given name `ns` on the runtime.
func (*Runtime) IsDebugMode ¶
func (*Runtime) IsQQSimplificationEnabled ¶
IsQQSimplificationEnabled returns a boolean value indicating whether simplification of quasiquotation is enabled or not. If yes, we have to replace the quasiquote expanded forms with a simpler form to gain a better performance.
func (*Runtime) LookupBuiltin ¶
type String ¶
type String struct { Node ExecutionScope // contains filtered or unexported fields }
func MakeString ¶
func (*String) PrintToString ¶
func (*String) ToDebugStr ¶
type StringParser ¶
type StringParser struct {
// contains filtered or unexported fields
}
StringParser is an implementation of the IParsable that operates on strings. To put it simply it parses input strings
func (*StringParser) Buffer ¶
func (sp *StringParser) Buffer() *[]string
func (*StringParser) GetLocation ¶
func (sp *StringParser) GetLocation() int
func (*StringParser) GetSource ¶
func (sp *StringParser) GetSource() *ast.Source
type Symbol ¶
type Symbol struct { Node ExecutionScope // contains filtered or unexported fields }