README

wdte

GoDoc Go Report Card cover.run

WDTE is a simple, functional-ish, embedded scripting language.

Why does this exist?

Good question. In fact, I found myself asking the same thing, hence the name.

I had a number of design goals in mind when I started working on this project:

  • Extremely simple. Entire grammar is less than 20-30 lines of specification.
  • Grammar is LL(1) parseable.
  • Functional-ish, but not particularly strict about it.
  • Designed primarily for embedding.
  • Extremely easy to use from the binding side. In this case, that's primarily Go.

If you want to try the language yourself, feel free to take a look at the playground. It shows not only some of the features of the language in terms of actually writing code in it, but also how embeddable it is. The playground runs entirely in the browser on the client's end thanks to WebAssembly.

Example

package main

import (
	"fmt"
	"os"
	"strings"

	"github.com/DeedleFake/wdte"
	"github.com/DeedleFake/wdte/wdteutil"
)

const src = `
let i => import 'some/import/path/or/another';

i.print 3;
+ 5 2 -> i.print;
7 -> + 5 -> i.print;
`

func im(from string) (*wdte.Scope, error) {
	return wdte.S().Map(map[wdte.ID]wdte.Func{
		"print": wdteutil.Func("print", func(v interface{}) interface{} {
		fmt.Println(v)
		return v
	}),
	}), nil
}

func Sum(frame wdte.Frame, args ...wdte.Func) wdte.Func {
	frame = frame.Sub("+")

	if len(args) < 2 {
		return wdteutil.SaveArgs(wdte.GoFunc(Sum), args...)
	}

	var sum wdte.Number
	for _, arg := range args {
		sum += arg.(wdte.Number)
	}
	return sum
}

func main() {
	m, err := wdte.Parse(strings.NewReader(src), wdte.ImportFunc(im), nil)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error parsing script: %v\n", err)
		os.Exit(1)
	}

	scope := wdte.S().Add("+", wdte.GoFunc(Sum))

	r := m.Call(wdte.F().WithScope(scope))
	if err, ok := r.(error); ok {
		fmt.Fprintf(os.Stderr, "Error running script: %v\n", err)
		os.Exit(1)
	}
}
Output
3
7
12

Documentation

For an overview of the language's design and features, see the GitHub wiki.

Status

WDTE is in a pre-alpha state. It is filled with bugs and large amounts of stuff are subject to change without warning. That being said, if you're interested in anything, feel free to submit a pull request and get things fixed and/or implemented faster.

Documentation

Overview

Package wdte implements the WDTE scripting language.

WDTE is an embeddable, functionalish scripting language with a primary goal of simplicity of use from the embedding side, which is what this package provides.

Quick Language Overview

In order to understand how this package works, an overview of the language itself is first necessary. WDTE is functional-ish, with some emphasis on the "-ish". Although it generally follows a functional design, it is not purely functional. In WDTE, everything is a function in that everything can be "called", optionally with arguments. Value types return themselves, however, allowing them to be passed around.

WDTE contains a construct called a "compound" which is similar to a function body in most languages. It is surrounded by parentheses and contains a semicolon separated list of expressions, with the last semicolon being optional. The top-level of a WDTE script is a compound without the parentheses. When a compound is executed, each expression is evaluated in turn. If any yield an error, that error is immediately returned from the entire compound. If not, the result of the last expression is returned.

Example 1

# Declare a function called print3 that takes no arguments.
let print3 => (
  let x => 3;
  io.writeln io.stdout x;
);

There are very few functions built-in in WDTE, but the standard library, found in the std directory and its subdirectories, contains a number of useful functions and definitions. For example, the stream module contains iterator functionality, which provides a means of looping over expressions, something which is otherwise not possible.

Example 2

# Import 'stream' and 'array' and assign them to s and a,
# respectively. Note that an import is a compile-time operation,
# unlike normal functions. As such, it must be passed a string
# literal, not a variable.
let s => import 'stream';
let a => import 'arrays';

# Create a function called flatten that takes one argument,
# array.
let flatten array =>
  # Create a new stream that iterates over array.
  a.stream array

  # Create a stream from the previous one that performs a flat
  # map operation. The (@ name arg => ...) syntax is a lambda
  # declaration.
  -> s.flatMap (@ f v => v {
      # If the current element of the stream, v, is an array,
      # recursively flatten it into the stream.
      reflect 'Array' => a.stream v -> s.flatMap f;
    })

  # Collect the previous stream into an array.
  -> s.collect
  ;

This example also demonstrates "chains" and "switches", some features that seem complicated at first but quickly become second nature so with some practice.

A chain is a series of expressions separated by either the chain operator, "->", the ignored chain operator, "--", or the error chain operator, "-|". Each piece of the chain is executed in turn, and the output of the previous section is passed as an argument to the output of the current section. In other words, in the previous example, the chain's execution matches the following pseudocode

r1 = a.stream(array)
r2 = s.flatMap(<lambda>)
r1 = r2(r1)
r2 = s.collect
return r2(r1)

A chain with a use of "--" operates in much the same way, but the output of the piece of the chain immediately following the operator is ignored, meaning that it doesn't affect the remainder of the chain.

The "-|" chain operator is used for error handling. During the evaluation of a chain, if no errors have occurred, chain segements using "-|" are ignored completely. Unlike with "--", they are completely not executed. If, however, an error occurs, all chain segments that don't use "-|" are ignored instead. If a "-|" segment exists in the chain after the location that the error occurred, then that segment is executed next, following which normal execution continues, unless that segment itself returned an error. If no "-|" segment exists, the error is returned from the entire chain.

Chains can also have "slots" assigned to each piece. This is an identifier immediately following the expression of a piece of chain. This identifier is inserted into the scope for the remainder of the chain, allowing manual access to earlier sections of the chain. For example

let io => import 'io';
let file => import 'io/file';

let readFile path =>
  file.open path : f
  -> io.string
  -- io.close f
  ;

The aforementioned switch expression is the only conditional provided by WDTE. It looks like an expression followed by a semicolon separated series of cases in squiggly braces. A case is two expressions separated by the assignment operator, "=>". The original expression is first evaluated, following which each case's left-hand side is evaluated and the result of the original expression's evaluation is passed to it. If and only if this call results in the boolean value true, the right-hand side of that case is returned. If no cases match, the original expression is returned. For example,

func arg1 {
  lhs1 arg2 => rhs1 arg3;
  lhs2 arg4 => rhs2 arg6;
}

This is analogous to the following pseudocode

check = func(arg1)
if lhs := lhs1(arg2); lhs(check) {
  return rhs1(arg3)
}
if lhs := lhs2(arg4); lhs(check) {
  return rhs2(arg6)
}
return check

A few more minor points exist as well:

Array literals are a semicolon list of expression surrounded by
square brackets. Like in compounds and switches, the last
semicolon is optional.

Identifier parsing rules are very loose; essentially, anything
that isn't ambiguous with an existing keyword, operator, or
other syntactic construct is allowed.

All strings are essentially heredocs, allowing newlines like
they're any other character. There's no difference between
single-quoted and double-quoted strings.

There are no boolean literals, but the standard library provides
true and false functions that are essentially the same thing.

Embedding

As previously mentioned, everything in WDTE is a function. In Go terms, everything in WDTE implements the Func type defined in this package. This includes syntactic constructs as well, such as compounds, switches, and chains.

When a script is parsed by one of the parsing functions in this package, it is translated into a recursive series of Func implementations. The specific types that it is translated to are all defined in and exported by this package. For example, the top-level of a script, being itself a compound, results in the instantiation of a Compound.

What this means in terms of embedding is that the only thing required for interaction between Go and WDTE is an interoperative layer of Func implementations. As a functional language, WDTE is stateless; there is no global interpreter state to keep track of at all. Systems for tracking interpreter state, should they be required, are provided by the repl package.

When a Func is called, it is passed a Frame. A Frame keeps track of anything the function needs that isn't directly an argument to the function. This includes the scope in which the Func call should be evaluated. For example, the expression

func arg1 arg2

translates to an instance of the FuncCall implementation of Func. When the FuncCall is "called", it must be given a scope which contains, at a minimum, "func", "arg1", and "arg2", or the call will fail with an error. It is through this mechanism that new functions can be provided to WDTE. A custom scope can be created with new implementations of Func inserted into it. If this scope is inserted into a Frame which is then passed to a call of, for example, the top-level compound created by parsing a script, they will be available during the evaluation.

Example:

const src = `
  let io => import 'io';
  io.writeln io.stdout example;
`

c, _ := wdte.Parse(strings.NewReader(src), std.Import)

scope := std.Scope.Add("example", wdte.String("This is an example."))
r := c.Call(std.F().WithScope(scope))
if err, ok := r.(error); ok {
  log.Fatalln(err)
}

This will print "This is an example." to stdout.

For convenience, a simple function wrapper around the single method required by Func is provided in the form of GoFunc. GoFunc provides a number of extra features, such as automatically converting panics into errors, but for the most part is just a simple wrapper around manual implementations of Func. If more automatic behavior is required, possibly at the cost of some runtime performance, functions for automatically wrapping Go functions are provided in the wdteutil package.

Example
Output:

Index

Examples

Constants

View Source
const (
	NormalChain  = 0
	IgnoredChain = 1 << (iota - 1)
	ErrorChain
)

Variables

This section is empty.

Functions

func Reflect

func Reflect(f Func, name string) bool

    Reflect checks if a Func can be considered to be of a given type. If v implements Reflector, v.Reflect(name) is used to check for compatability. If not, a simple string comparison is done against whatever Go's reflect package claims the short name of the underlying type to be.

    Types

    type Array

    type Array []Func

      An Array represents a WDTE array type. It's similar to a Compound, but when evaluated, it returns itself with its own members replaced with their own evaluations. This allows it to be passed around as a value in the same way as strings and numbers.

      func (Array) At

      func (a Array) At(index Func) (Func, error)

      func (Array) Call

      func (a Array) Call(frame Frame, args ...Func) Func

      func (Array) Len

      func (a Array) Len() int

      func (Array) Reflect

      func (a Array) Reflect(name string) bool

      func (Array) Set

      func (a Array) Set(k, v Func) (Func, error)

      func (Array) String

      func (a Array) String() string

      type Assigner

      type Assigner interface {
      	// Assign produces a subscope from an existing frame, scope, and
      	// function, returning both the new subscope and a function. The
      	// returned function may or may not be related to the original
      	// function, but should be in most cases.
      	//
      	// In the event of an error, the returned scope should be nil to
      	// indicate that the error was not simply stored in the scope, as
      	// that is valid behavior.
      	Assign(frame Frame, scope *Scope, val Func) (*Scope, Func)
      
      	// IDs returns the list of IDs associated with the Assigner. This is
      	// generally the IDs that will be added to a scope via the Assign
      	// method.
      	IDs() []ID
      }

        An Assigner places items into a scope. How exactly iy does this differs, but the general idea is to produce a subscope from a combination of frame, an existing scope, and a function.

        type Atter

        type Atter interface {
        	At(i Func) (Func, error)
        }

          An Atter is a Func that can be indexed, like an array or a string.

          type Bool

          type Bool bool

            Bool is a boolean. Like other primitive types, it simply returns itself when called.

            func (Bool) Call

            func (b Bool) Call(frame Frame, args ...Func) Func

            func (Bool) Compare

            func (b Bool) Compare(other Func) (int, bool)

            func (Bool) Reflect

            func (b Bool) Reflect(name string) bool

            type Chain

            type Chain []*ChainPiece

              Chain is an unevaluated chain expression.

              func (Chain) Call

              func (f Chain) Call(frame Frame, args ...Func) Func

              func (Chain) String

              func (f Chain) String() string

              type ChainPiece

              type ChainPiece struct {
              	Expr Func
              
              	Flags uint
              	Slots Assigner
              }

                A ChainPiece is, as you can probably guess from the name, a piece of a Chain. It stores the underlying expression as well as some extra information necessary for properly evaluating the Chain.

                func (ChainPiece) Call

                func (p ChainPiece) Call(frame Frame, args ...Func) Func

                func (ChainPiece) String

                func (p ChainPiece) String() string

                type Collector

                type Collector struct {
                	Compound Compound
                }

                  Collector wraps a compound, causing it to return its collected scope instead of the last result. If any expression in the compound returns an error, however, then that error is returned instead.

                  func (Collector) Call

                  func (c Collector) Call(frame Frame, args ...Func) Func

                  type Comparer

                  type Comparer interface {
                  	// Compare returns two values. The meaning of the first is dependent
                  	// upon the second. If the second is true, then the first indicates
                  	// ordering via the standard negative, positive, and zero results to
                  	// indicate less than, greater than, and equal, respectively. If the
                  	// second is false, then the first indicates only equality, with
                  	// zero still meaning equal, but other values simply meaning unequal.
                  	Compare(other Func) (int, bool)
                  }

                    A Comparer is a Func that is able to be compared to other functions.

                    type Composite

                    type Composite []Func

                      Composite represents a composite function. When called, it calls its components in reverse order on their previous results. In other words,

                      Composite{func1, func2, func3}.Call(frame, arg1, arg2)
                      

                      is the equivalent of

                      func1 (func2 (func3 arg1 arg2))
                      

                      func (Composite) Call

                      func (c Composite) Call(frame Frame, args ...Func) Func

                      type Compound

                      type Compound []Func

                        A Compound represents a compound expression. Calling it calls each of the expressions in the compound, returning the value of the last one. If the compound is empty, nil is returned.

                        If an element of a compound is an Assigner, it is used to build a new subscope under which the remainder of the elements of the compound will be evaluated. If the element is the last element of the compound, the Func returned by its assignment is returned from the whole compound.

                        func FromAST

                        func FromAST(root ast.Node, im Importer) (Compound, error)

                          FromAST translates an AST into a top-level compound. im is used to handle import statements. If im is nil, a no-op importer is used.

                          func Parse

                          func Parse(r io.Reader, im Importer, macros scanner.MacroMap) (Compound, error)

                            Parse parses an AST from r and then translates it into a top-level compound. im is used to handle import statements. If im is nil, a no-op importer is used. In most cases, std.Import is a good default.

                            func (Compound) Call

                            func (c Compound) Call(frame Frame, args ...Func) Func

                            func (Compound) Collect

                            func (c Compound) Collect(frame Frame) (letScope *Scope, last Func)

                              Collect executes the compound the same as Call, but also returns the collected scope that has been modified by let expressions alongside the usual return value. This is useful when dealing with scopes as modules, as it allows you to evaluate specific functions in a script.

                              type Error

                              type Error struct {
                              	// Err is the error that generated the Error. In a lot of cases,
                              	// this is just a simple error message.
                              	Err error
                              
                              	// Frame is the frame of the function that the error was first
                              	// generated in.
                              	Frame Frame
                              }

                                An Error is returned by any of the built-in functions when they run into an error.

                                func (Error) Call

                                func (e Error) Call(frame Frame, args ...Func) Func

                                func (Error) Error

                                func (e Error) Error() string

                                func (Error) Reflect

                                func (e Error) Reflect(name string) bool

                                func (Error) Unwrap

                                func (e Error) Unwrap() error

                                type Frame

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

                                  A Frame tracks information about the current function call, such as the scope that the function is being executed in and debugging info.

                                  func F

                                  func F() Frame

                                    F returns a top-level frame. This can be used by Go code calling WDTE functions directly if another frame is not available.

                                    In many cases, it may be preferable to use std.F() instead.

                                    func (Frame) Backtrace

                                    func (f Frame) Backtrace(w io.Writer) error

                                      Backtrace prints a backtrace to w.

                                      func (Frame) Context

                                      func (f Frame) Context() context.Context

                                      func (Frame) ID

                                      func (f Frame) ID() ID

                                        ID returns the ID of the frame. This is generally the function that created the frame.

                                        func (Frame) Parent

                                        func (f Frame) Parent() Frame

                                          Parent returns the frame that this frame was created from, or a blank frame if there was none.

                                          func (Frame) Scope

                                          func (f Frame) Scope() *Scope

                                            Scope returns the scope associated with the frame.

                                            func (Frame) Sub

                                            func (f Frame) Sub(id ID) Frame

                                              Sub returns a new child frame of f with the given ID and the same scope as f.

                                              Under most circumstances, a GoFunc should call this before calling any WDTE functions, as it is useful for debugging. For example:

                                              func Example(frame wdte.Frame, args ...wdte.Func) wdte.Func {
                                                  frame = frame.Sub("example")
                                                  ...
                                              }
                                              

                                              func (Frame) WithContext

                                              func (f Frame) WithContext(ctx context.Context) Frame

                                                WithContext returns a copy of f with the given context.

                                                func (Frame) WithScope

                                                func (f Frame) WithScope(scope *Scope) Frame

                                                  WithScope returns a copy of f with the given scope.

                                                  type Func

                                                  type Func interface {
                                                  	// Call calls the function with the given arguments, returning its
                                                  	// return value. frame represents the current call frame, which
                                                  	// tracks scope as well as debugging info.
                                                  	Call(frame Frame, args ...Func) Func
                                                  }

                                                    Func is the base type through which all data is handled by WDTE. It represents everything that can be passed around in the language. This includes functions, of course, expressions, strings, numbers, Go functions, and anything else the client wants to pass into WDTE.

                                                    type FuncCall

                                                    type FuncCall struct {
                                                    	Func Func
                                                    	Args []Func
                                                    }

                                                      A FuncCall is an unevaluated function call. This is usually the right-hand side of a function declaration, but could also be any of various pieces of switches, compounds, or arrays.

                                                      func (FuncCall) Call

                                                      func (f FuncCall) Call(frame Frame, args ...Func) Func

                                                      func (FuncCall) String

                                                      func (f FuncCall) String() string

                                                      type GoFunc

                                                      type GoFunc func(frame Frame, args ...Func) Func

                                                        A GoFunc is an implementation of Func that calls a Go function. This is the easiest way to implement lower-level systems for WDTE scripts to make use of.

                                                        For example, to implement a simple, non-type-safe addition function:

                                                        GoFunc(func(frame wdte.Frame, args ...wdte.Func) wdte.Func {
                                                          frame = frame.Sub("+")
                                                          var sum wdte.Number
                                                          for _, arg := range(args) {
                                                            sum += arg.Call(frame).(wdte.Number)
                                                          }
                                                          return sum
                                                        })
                                                        

                                                        If placed into a scope with the ID "+", this function can then be called from WDTE as follows:

                                                        + 3 6 9
                                                        

                                                        As shown, it is recommended that arguments be passed the given frame when evaluating them. Failing to do so without knowing what you're doing can cause unexpected behavior, including sending the evaluation system into infinite loops or causing panics.

                                                        In the event that a GoFunc panics with an error value, it will be automatically caught and converted into an Error, which will then be returned.

                                                        func (GoFunc) Call

                                                        func (f GoFunc) Call(frame Frame, args ...Func) (r Func)

                                                        func (GoFunc) String

                                                        func (f GoFunc) String() string

                                                        type ID

                                                        type ID string

                                                          ID represents a WDTE ID, such as a local variable.

                                                          type ImportFunc

                                                          type ImportFunc func(from string) (*Scope, error)

                                                            ImportFunc is a wrapper around simple functions to allow them to be used as Importers.

                                                            func (ImportFunc) Import

                                                            func (f ImportFunc) Import(from string) (*Scope, error)

                                                            type Importer

                                                            type Importer interface {
                                                            	Import(from string) (*Scope, error)
                                                            }

                                                              An Importer creates scopes from strings. When parsing a WDTE script, an importer is used to import scopes into namespaces.

                                                              When the WDTE import expression

                                                              import 'example'
                                                              

                                                              is parsed, the associated Importer will be invoked as follows:

                                                              im.Import("example")
                                                              

                                                              type Lambda

                                                              type Lambda struct {
                                                              	ID   ID
                                                              	Expr Func
                                                              	Args []Assigner
                                                              
                                                              	Scope    *Scope
                                                              	Original *Lambda
                                                              }

                                                                A Lambda is a closure. When called, it calls its inner expression with itself and its own arguments placed into the scope. In other words, given the lambda

                                                                (@ ex x y => + x y)
                                                                

                                                                it will create a new subscope containing itself under the ID "ex", and its first and second arguments under the IDs "x" and "y", respectively. It will then evaluate `+ x y` in that new scope.

                                                                func (*Lambda) Call

                                                                func (lambda *Lambda) Call(frame Frame, args ...Func) Func

                                                                func (*Lambda) String

                                                                func (lambda *Lambda) String() string

                                                                type Lenner

                                                                type Lenner interface {
                                                                	Len() int
                                                                }

                                                                  A Lenner is a Func that has a length, such as arrays and strings.

                                                                  type LetAssigner

                                                                  type LetAssigner struct {
                                                                  	Assigner
                                                                  	Expr Func
                                                                  }

                                                                    A LetAssigner assigns a pre-defined expression using an Assigner. Unlike other Assigners, it completely ignores the val argument of its Assign method.

                                                                    func (LetAssigner) Assign

                                                                    func (a LetAssigner) Assign(frame Frame, scope *Scope, val Func) (*Scope, Func)

                                                                    func (LetAssigner) Call

                                                                    func (a LetAssigner) Call(frame Frame, args ...Func) Func

                                                                    func (LetAssigner) String

                                                                    func (a LetAssigner) String() string

                                                                    type Modifier

                                                                    type Modifier struct {
                                                                    	Mods Func
                                                                    	Func Func
                                                                    }

                                                                      Modifier applies modifications to a function before passing it its own arguments by calling Mods and passing it Func.

                                                                      func (Modifier) Call

                                                                      func (m Modifier) Call(frame Frame, args ...Func) Func

                                                                      type Number

                                                                      type Number float64

                                                                        A Number is a number, as parsed from a number literal. That's about it. Like everything else, it's a function. It simply returns itself when called.

                                                                        func (Number) Call

                                                                        func (n Number) Call(frame Frame, args ...Func) Func

                                                                        func (Number) Compare

                                                                        func (n Number) Compare(other Func) (int, bool)

                                                                        func (Number) Reflect

                                                                        func (n Number) Reflect(name string) bool

                                                                        func (Number) String

                                                                        func (n Number) String() string

                                                                        type PatternAssigner

                                                                        type PatternAssigner []Assigner

                                                                          PatternAssigner assigns variables to the corresponding indices of an Atter under the assumption that the Atter uses integer indices. For example, given

                                                                          PatternAssigner{
                                                                            "a",
                                                                            "b",
                                                                            "c"
                                                                          }
                                                                          

                                                                          assiging with a value of

                                                                          wdte.Array{wdte.Number(1), wdte.Number(5), wdte.Number(3)}
                                                                          

                                                                          will result in a subscope with

                                                                          a = 1
                                                                          b = 5
                                                                          c = 3
                                                                          

                                                                          func (PatternAssigner) Assign

                                                                          func (a PatternAssigner) Assign(frame Frame, scope *Scope, val Func) (*Scope, Func)

                                                                          func (PatternAssigner) IDs

                                                                          func (a PatternAssigner) IDs() []ID

                                                                          func (PatternAssigner) String

                                                                          func (a PatternAssigner) String() string

                                                                          type Reflector

                                                                          type Reflector interface {
                                                                          	Reflect(name string) bool
                                                                          }

                                                                            A Reflector is a Func that can determine if it can be treated as the named type or not. For example,

                                                                            s := wdte.String("example")
                                                                            return s.Reflect("string")
                                                                            

                                                                            returns true.

                                                                            type Scope

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

                                                                              Scope is a tiered storage space for local variables. This includes function parameters and chain slots. A nil *Scope is equivalent to a blank, top-level scope.

                                                                              func S

                                                                              func S() *Scope

                                                                                S is a convenience function that returns a blank, top-level scope.

                                                                                func (*Scope) Add

                                                                                func (s *Scope) Add(id ID, val Func) *Scope

                                                                                  Add returns a new subscope with the given variable stored in it.

                                                                                  func (*Scope) At

                                                                                  func (s *Scope) At(i Func) (Func, error)

                                                                                  func (*Scope) Call

                                                                                  func (s *Scope) Call(frame Frame, args ...Func) Func

                                                                                  func (*Scope) Custom

                                                                                  func (s *Scope) Custom(getFunc func(ID) Func, known func(map[ID]struct{})) *Scope

                                                                                    Custom returns a new subscope that uses the given lookup function to retrieve values. If getFunc returns nil, the parent of s will be searched. known is an optional function which adds all variables known to this layer of the scope into the map that it is passed as keys.

                                                                                    func (*Scope) Get

                                                                                    func (s *Scope) Get(id ID) Func

                                                                                      Get returns the value of the variable with the given ID. If the variable doesn't exist in either the current scope or any of its parent scopes, nil is returned.

                                                                                      func (*Scope) Known

                                                                                      func (s *Scope) Known() []ID

                                                                                        Known returns a sorted list of variables that are in scope.

                                                                                        func (*Scope) Map

                                                                                        func (s *Scope) Map(vars map[ID]Func) *Scope

                                                                                          Map returns a subscope that includes the given mapping of variable names to functions. Note that no copy is made of vars, so changing the map after passing it to this method may result in undefined behavior.

                                                                                          func (*Scope) Parent

                                                                                          func (s *Scope) Parent() *Scope

                                                                                            Parent returns the parent of the current scope.

                                                                                            func (*Scope) Reflect

                                                                                            func (s *Scope) Reflect(name string) bool

                                                                                            func (*Scope) Set

                                                                                            func (s *Scope) Set(k, v Func) (Func, error)

                                                                                            func (*Scope) String

                                                                                            func (s *Scope) String() string

                                                                                            func (*Scope) Sub

                                                                                            func (s *Scope) Sub(sub *Scope) *Scope

                                                                                              Sub subscopes sub to s such that variables in sub will shadow variables in s.

                                                                                              type Setter

                                                                                              type Setter interface {
                                                                                              	Set(k, v Func) (Func, error)
                                                                                              }

                                                                                                A Setter is a Func that can produce a new Func from itself with a key-value mapping applied in some way. For example, a scope can produce a subscope with a new variable added to it, or an array can produce a new array with an index modified.

                                                                                                type SimpleAssigner

                                                                                                type SimpleAssigner ID

                                                                                                  SimpleAssigner is an Assigner that assigns a single variable to a value.

                                                                                                  func (SimpleAssigner) Assign

                                                                                                  func (a SimpleAssigner) Assign(frame Frame, scope *Scope, val Func) (*Scope, Func)

                                                                                                  func (SimpleAssigner) IDs

                                                                                                  func (a SimpleAssigner) IDs() []ID

                                                                                                  func (SimpleAssigner) String

                                                                                                  func (a SimpleAssigner) String() string

                                                                                                  type String

                                                                                                  type String string

                                                                                                    A String is a string, as parsed from a string literal. That's about it. Like everything else, it's a function. It simply returns itself when called.

                                                                                                    func (String) At

                                                                                                    func (s String) At(index Func) (Func, error)

                                                                                                    func (String) Call

                                                                                                    func (s String) Call(frame Frame, args ...Func) Func

                                                                                                    func (String) Compare

                                                                                                    func (s String) Compare(other Func) (int, bool)

                                                                                                    func (String) Len

                                                                                                    func (s String) Len() int

                                                                                                    func (String) Reflect

                                                                                                    func (s String) Reflect(name string) bool

                                                                                                    type Sub

                                                                                                    type Sub []Func

                                                                                                      A Sub is a function that is in a subscope. This is most commonly an imported function.

                                                                                                      func (Sub) Call

                                                                                                      func (sub Sub) Call(frame Frame, args ...Func) Func

                                                                                                      type Switch

                                                                                                      type Switch struct {
                                                                                                      	// Check is the condition at the front of the switch.
                                                                                                      	Check Func
                                                                                                      
                                                                                                      	// Cases is the switch's cases. Each contains two functions. The
                                                                                                      	// first index is the left-hand side, while the second is the
                                                                                                      	// right-hand side. When the switch is evaluated, the cases are run
                                                                                                      	// in order. If any matches, the right-hand side is evaluated and
                                                                                                      	// its return value is returned.
                                                                                                      	Cases [][2]Func
                                                                                                      }

                                                                                                        Switch represents a switch expression.

                                                                                                        func (Switch) Call

                                                                                                        func (s Switch) Call(frame Frame, args ...Func) Func

                                                                                                        type Var

                                                                                                        type Var ID

                                                                                                          A Var represents a local variable. When called, it looks itself up in the frame that it's given and calls whatever it finds.

                                                                                                          func (Var) Call

                                                                                                          func (v Var) Call(frame Frame, args ...Func) Func

                                                                                                          Directories

                                                                                                          Path Synopsis
                                                                                                          Package ast provides the parser for WDTE.
                                                                                                          Package ast provides the parser for WDTE.
                                                                                                          cmd
                                                                                                          Package repl provides a layer intended to help with the development of a read-eval-print loop.
                                                                                                          Package repl provides a layer intended to help with the development of a read-eval-print loop.
                                                                                                          Package scanner provides a scanner for WDTE tokens.
                                                                                                          Package scanner provides a scanner for WDTE tokens.
                                                                                                          std
                                                                                                          Package std provides a number of basic WDTE functions.
                                                                                                          Package std provides a number of basic WDTE functions.
                                                                                                          all
                                                                                                          Package all is a convenience package that imports the entire standard library, thus registering it with std.Import.
                                                                                                          Package all is a convenience package that imports the entire standard library, thus registering it with std.Import.
                                                                                                          arrays
                                                                                                          Package arrays contains functions for manipulating arrays.
                                                                                                          Package arrays contains functions for manipulating arrays.
                                                                                                          io
                                                                                                          Package io contains WDTE functions for dealing with files and other types of data streams.
                                                                                                          Package io contains WDTE functions for dealing with files and other types of data streams.
                                                                                                          io/file
                                                                                                          Package file provides functions for dealing with files.
                                                                                                          Package file provides functions for dealing with files.
                                                                                                          math
                                                                                                          Package math contains wdte.Funcs for performing mathematical operations.
                                                                                                          Package math contains wdte.Funcs for performing mathematical operations.
                                                                                                          rand
                                                                                                          Package rand provides functions for generating and dealing with random numbers.
                                                                                                          Package rand provides functions for generating and dealing with random numbers.
                                                                                                          stream
                                                                                                          Package stream provides WDTE functions for manipulating streams of data.
                                                                                                          Package stream provides WDTE functions for manipulating streams of data.
                                                                                                          strings
                                                                                                          Package strings contains functions for dealing with strings.
                                                                                                          Package strings contains functions for dealing with strings.
                                                                                                          Package wdteutil provides higher-level automatic wrappers and convenience functions for Go/WDTE interoperability.
                                                                                                          Package wdteutil provides higher-level automatic wrappers and convenience functions for Go/WDTE interoperability.