Documentation
¶
Overview ¶
Package exp is a simple and extensible expression language, built on xelf types and literals. It is meant to be used as a base for domain specific languages for a variety of tasks.
Language elements implement the interface El and are pointer of the following types:
Atom for literals, including type literals Sym for unresolved symbols Dyn for unresolved expressions Call for expressions with a resolved form or func specification Named for special tag syntax elements used in call arguments
Parse reads a tree and returns atoms, symbols, named or dynamic expressions. Literals and type symbols as well as type expressions are parsed as atoms. Tag symbols associate to the neighoring elements.
Prog is a program with a type context used to resolve or evaluate elements.
Resl resolves symbol types and dyn expressions to calls or atoms.
The resolution uses the spec signature and is automatic for all function specs and most form specs.
Dynamic expressions are resolved to call expressions. Dynamic expressions starting with a spec use that spec directly, starting with a literal or type lookup a built-in spec. Language extensions can change the dynamic lookup in the program context.
Eval evaluates elements resulting in an atom or partially resolved element.
Index ¶
- Variables
- func DefaultDyn(t typ.Type) (string, bool)
- func MustSig(sig string) typ.Type
- func ResInfo(el El) (typ.Type, lit.Lit)
- func ResType(el El) typ.Type
- func Sig(sig string) (typ.Type, error)
- func Traverse(v Visitor, els ...El) error
- type Atom
- type Builtin
- type Call
- type DataScope
- type Def
- type Dyn
- type El
- type Env
- type ExprBody
- type FuncScope
- type Ghost
- func (Ghost) EnterCall(*Call) error
- func (Ghost) EnterDyn(*Dyn) error
- func (Ghost) EnterNamed(*Tag) error
- func (Ghost) LeaveCall(*Call) error
- func (Ghost) LeaveDyn(*Dyn) error
- func (Ghost) LeaveNamed(*Tag) error
- func (Ghost) VisitLit(*Atom) error
- func (Ghost) VisitSym(*Sym) error
- func (Ghost) VisitType(*Atom) error
- type Impl
- type Layout
- type LookupFunc
- type ParamEnv
- type ParamReslEnv
- type Prog
- func (p *Prog) BuiltinCall(env Env, name string, args []El, src lex.Src) (*Call, error)
- func (p *Prog) Eval(env Env, el El, h typ.Type) (_ El, err error)
- func (p *Prog) EvalAll(env Env, els []El, hint typ.Type) (res []El, err error)
- func (p *Prog) NewCall(s *Spec, args []El, src lex.Src) (*Call, error)
- func (p *Prog) Realize(el El) error
- func (p *Prog) Resl(env Env, el El, h typ.Type) (_ El, err error)
- func (p *Prog) ReslAll(env Env, els []El, h typ.Type) (res []El, err error)
- type ProgEnv
- type Scope
- type Spec
- type Sym
- type Tag
- type Visitor
Constants ¶
This section is empty.
Variables ¶
var ( // ErrRedefine is returned when the symbol is redefined in the same scope. ErrRedefine = cor.StrError("redefined symbol") )
var ErrUnres = cor.StrError("unresolved")
ErrUnres is returned by a resolver if the result is unresolved, but otherwise valid.
var ErrVoid = cor.StrError("void")
var SkipTraverse = cor.StrError("skip traverse")
Functions ¶
Types ¶
type Builtin ¶
type Builtin []LookupFunc
Builtin is an environment based on a slice of simple resolver lookup functions.
The lookup functions are check from start to finish returning the first result. A builtin environment has no parent and cannot define resolvers.
type DataScope ¶
DataScope is a child environment that supports relative paths and is backed by a literal
func NewDataScope ¶
NewDataScope returns a data scope with the given parent environment.
type Def ¶
type Def struct {
// Type is the resolved definition type.
typ.Type
// Lit is the evaluated literal. The literal must be convertible to the definiton type.
Lit lit.Lit
}
Def represents a definition in an environment.
func Lookup ¶
Lookup returns a first resolver with symbol sym found in env or one of its ancestors. If sym starts with a known special prefix only the appropriate environments are called.
func LookupSupports ¶
LookupSupports looks up and returns a resolver that supports behaviour indicated by x or nil.
type El ¶
type El interface {
// WriteBfr writes the element to a bfr.Ctx.
WriteBfr(*bfr.Ctx) error
// String returns the xelf representation as string.
String() string
// Typ returns the element type.
Typ() typ.Type
// Source returns the source position if available.
Source() lex.Src
// Travers calls the appropriate visitor methods for this element and its children.
Traverse(Visitor) error
}
El is the common interface of all language elements.
func Parse ¶
Parse parses the syntax tree a and returns an element or an error. It needs a static environment to distinguish elements.
type Env ¶
type Env interface {
// Parent returns the parent environment or nil for the root environment.
Parent() Env
// Get looks for a definition with symbol sym defined in this environments.
// Implementation assume sym is not empty. Callers must ensure that sym is not empty.
Get(sym string) *Def
// Supports returns whether the environment supports a special behaviour represented by x.
Supports(x byte) bool
}
Env is a scoped symbol environment used to define and lookup resolvers by symbol.
type ExprBody ¶
ExprBody is the body for normal functions consisting of a list of expression elements and its declaration environment that is used for execution.
type Ghost ¶
type Ghost struct{}
Ghost is a no-op visitor, that visits each element, but does not act on any.
func (Ghost) EnterNamed ¶
func (Ghost) LeaveNamed ¶
type Impl ¶
type Impl interface {
// Resl resolves a call and returns the resulting element or an error.
//
// A successful resolution returns a call with all related types resolved and no error.
// If the type hint is not void, it is used to check or infer the element type.
// When parts of the element could not be resolved it returns the special error ErrUnres.
Resl(p *Prog, env Env, c *Call, h typ.Type) (El, error)
// Eval evaluates a call and returns the resulting element or an error.
//
// A successful evaluation returns a literal and no error.
// If the type hint is not void, it is used to check or infer the element type.
// When parts of the element could not be evaluation it returns the special error ErrUnres,
// and - if the context allows it - a partially resolved element.
Eval(p *Prog, env Env, c *Call, h typ.Type) (El, error)
}
type Layout ¶
Layout is a helper to validate form expression arguments.
We distinguish between tag and plain elements in the context of layouts.
The layout is formalizes by the parameter signature. It uses a number of special parameter names, that indicate to the layout how arguments must be parsed. A full form consisting of all possible kinds of accepted elements, is: <form full plain; tags; tail;>
These are the recognised parameter names:
plain accepts any number of plain elements and can be followed by tags tags accepts any number of tag expressions and can be followed by tail args accepts any number of leading plain elements and then tag expression tail accepts any element and must be the last element
Explicit parameter arguments must be at the start before any special parameter.
The parameter types give hints at what types are accepted. The special parameters can only use container types. The tags parameters expect a keyer type, while all others accept an idxer type. If the type is omitted, the layout will not resolve or check that parameter.
func FuncLayout ¶
FuncLayout matches arguments of x to the parameters of f and returns a layout or an error.
type LookupFunc ¶
LookupFunc is a simple spec lookup function used by builtins and libraries.
type ParamReslEnv ¶
func NewParamReslEnv ¶
func NewParamReslEnv(p Env, c *typ.Ctx) *ParamReslEnv
func (*ParamReslEnv) Get ¶
func (ps *ParamReslEnv) Get(s string) *Def
func (*ParamReslEnv) Parent ¶
func (ps *ParamReslEnv) Parent() Env
func (*ParamReslEnv) Supports ¶
func (ps *ParamReslEnv) Supports(x byte) bool
type Prog ¶
type Prog struct {
// Ctx is the type context that stores type variable bindings.
*typ.Ctx
// Unres is a list of all unresolved expressions and type and symbol references.
Unres []El
Dyn func(fst typ.Type) (sym string, consume bool)
}
Prog is the resolution type context and also collects unresolved elements.
func (*Prog) BuiltinCall ¶
BuiltinCall looks up the builtin spec by name and returns a new call or returns an error.
func (*Prog) NewCall ¶
NewCall returns a new call or an error if arguments do not match the spec signature. The call signature is instantiated in the programs type context.
func (*Prog) Realize ¶
Realize finalizes all types in el or returns an error. If successful, el is independent of its type context.
func (*Prog) Resl ¶
Resolve resolves x within env and returns the result or an error.
This method will not resolve any element itself but instead tries to look up an applicable resolver in the environment. If it cannot find a resolver it will add the element to the context's unresolved slice. The resolver implementations usually use this method either directly or indirectly to resolve arguments, which are then again added to the unresolved elements when appropriate.
type Scope ¶
type Scope struct {
// contains filtered or unexported fields
}
Scope is a child environment based on a map of resolvers.
type Sym ¶
type Sym struct {
Name string
// Type is the resolved type of lit in this context or void.
Type typ.Type
// Lit is the resolved literal or nil. Conversion may be required.
Lit lit.Lit
lex.Src
}
Sym is an identifier, that refers to a definition.