texpr

package module
v0.0.0-...-746e001 Latest Latest
Warning

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

Go to latest
Published: Apr 14, 2023 License: MIT Imports: 7 Imported by: 0

README

texpr

Text based expression evaluator with types.

The goal of this module is to provide a way for non-technical people to learn a basic expression language and utilize it in their software. The module provides all the information necessary to provide a visual development experience where the user will be able to type and the system can estimate what they can enter next (auto-complete). The parsing and type checking aspects of the module provide positional data to aid in communicating broken expressions.

Features

  • Types & values (simple fields, methods, or operations) are entirely user defined.
  • Easy to understand left to right evaluation & parsing. ex: user.createDate.hour
  • Types can have parameterized values (methods). ex: today.addDays(2)
  • Type methods can be symbols which appear operation like: today.minute+(today.hour*(60))>(120)
  • Expressions are case insensitive. ex: TODAY=(today)
  • Basic generic support in parameterized values.
  • Compilation utilities provide a way for the developer to convert expressions into a runnable function, SQL, etc.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrNoExpression = NewParseError(nil, "undefined expression")

No expression was passed to the parse function.

View Source
var ErrNoRoot = NewParseError(nil, "undefined root type")

No root type was specified in the options for parsing.

View Source
var ErrNoTypes = NewParseError(nil, "undefined types")

No types are defined in the system.

Functions

func Compile

func Compile[CE any](e *Expr, source CompileSource[CE]) (CE, error)

Compiles the given expression into the desired compiled expression (CE). If there was any error or a type or value compiler was not specified an error will be returned.

func TypeOf

func TypeOf[T any]() reflect.Type

Types

type CompileSource

type CompileSource[CE any] interface {
	// Returns the initial compiled expression value. This is passed to the compiler functions for the
	// first expressions in a chain.
	GetInitial(e *Expr) (CE, error)
	// Returns a compiled value for a constant expression.
	GetConstantCompiled(e *Expr, root *Type, previous CE, arguments []CE) (CE, error)
	// Returns a compiler for a value expression.
	GetValueCompiler(e *Expr, root *Type, previous CE) (Compiler[CE], error)
}

A helper to the compile function.

type CompileSourceLookup

type CompileSourceLookup[CE any] struct {
	// The initial compiled expression value. This is passed to the compiler functions for the
	// first expressions in a chain.
	Initial CE
	// Compilers for each type and their values.
	TypeCompilers TypeCompilers[CE]
	// A compiler for a constant expression.
	ConstantCompiler Compiler[CE]
}

A CompileSource implementation where compilers are looked up based on type->value.

func (CompileSourceLookup[CE]) GetConstantCompiled

func (csl CompileSourceLookup[CE]) GetConstantCompiled(e *Expr, root *Type, previous CE, arguments []CE) (CE, error)

func (CompileSourceLookup[CE]) GetInitial

func (csl CompileSourceLookup[CE]) GetInitial(e *Expr) (CE, error)

func (CompileSourceLookup[CE]) GetValueCompiler

func (csl CompileSourceLookup[CE]) GetValueCompiler(e *Expr, root *Type, previous CE) (Compiler[CE], error)

type Compiler

type Compiler[CE any] func(e *Expr, root *Type, previous CE, arguments []CE) (CE, error)

A compiler is a function that is given an expression, the root type, a previously compiled expression (CE), argument CEs, and returns a CE for the given expression.

type Expr

type Expr struct {
	// The string parsed from the expression input.
	Token string
	// The start position of the expression in the input.
	Start Position
	// The end position of the expression in the input.
	End Position
	// If this expression is a constant value and not a value.
	Constant bool
	// The parsed value if this expression is a constant.
	Parsed any
	// The value this expression is in the parent type.
	Value *Value
	// The parent type if any. If prev is nil this represents the root type.
	ParentType *Type
	// The type of this value/constant.
	Type *Type
	// The arguments to pass as the parameters to the value.
	Arguments []*Expr
	// The next expression in the chain on the result of this one.
	Next *Expr
	// The previous expression in the chain or nil. When nil this is either a constant
	// or a value on the root type.
	Prev *Expr
	// The expression this is an argument for, which is only set on the first expression in a chain.
	Parent *Expr
	// The parameter this expression is on if any. This is only set for the first expression in the chain.
	Parameter *Parameter
	// The system that created the expression.
	System *System
}

func (*Expr) Chain

func (e *Expr) Chain() []*Expr

Returns a slice of all expressions in the chain starting with this expression.

func (*Expr) Last

func (e *Expr) Last() *Expr

Returns the last expression in this chain.

func (Expr) String

func (e Expr) String() string

Converts the expression to a string.

func (*Expr) TypeOneOf

func (e *Expr) TypeOneOf(types []*Type) bool

Returns if the type on this expression is one of the given types. If this expression is nil or has no type then this will return whether the given types are empty. Otherwise the type on the expression must match one of the given types.

type Options

type Options struct {
	// The type that is used as the root of the expressions.
	RootType TypeName
	// The expected types if any. If none are given then the type of the expression is returned.
	// If one or more are given then the expression is automatically cast to a desired type
	// if possible, otherwise errors if it can't meet the expected types.
	ExpectedTypes []TypeName
	// The expression to parse.
	Expression string
}

The parse options for an expression string into an Expression struct.

type Parameter

type Parameter struct {
	// The expected type for the parameter. Either this or Generic is required.
	Type TypeName `json:"type,omitempty"`
	// If there is no expected type, but this parameter and potentially others need to be the same type.
	// The generic parameters can also decide the type of generic value.
	Generic bool `json:"generic,omitempty"`
	// The name of the parameter.
	Name string `json:"name,omitempty"`
	// A more detailed description of the parameter.
	Description string `json:"description,omitempty"`
	// A default value, making this an optional parameter. This must be a valid value that can be parsed by the type.
	Default *string `json:"default,omitempty"`
	// contains filtered or unexported fields
}

A parameter to a parameterized value. Type or Generic is required.

func (Parameter) ParameterType

func (p Parameter) ParameterType() *Type

type ParseError

type ParseError struct {
	Message   string
	Expr      *Expr
	Parameter *Parameter
	Start     *Position
	End       *Position
}

An error occurred during the parsing or linking of System.Parse.

func NewParseError

func NewParseError(expr *Expr, message string) ParseError

Creates a new parse error given the expression (if any) and the message.

func (ParseError) Error

func (e ParseError) Error() string

The parse error message.

type Position

type Position struct {
	// The index of the character in Options.Expression
	Index int
	// The line of the character, where \n delimits lines.
	Line int
	// The column of the character in its line.
	Column int
}

The position of a character in a multi-line string.

func (Position) String

func (p Position) String() string

The string representation of a position.

type Reflect

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

func NewReflect

func NewReflect(options ReflectOptions) (r *Reflect, err error)

func (Reflect) Compile

func (r Reflect) Compile(e *Expr) ReflectCompiled

func (Reflect) Parse

func (r Reflect) Parse(opts Options) (*Expr, error)

type ReflectCompiled

type ReflectCompiled func(root any) (any, error)

type ReflectConversion

type ReflectConversion struct {
	Type        TypeName
	ConvertTo   func(v any) (any, error)
	ConvertFrom func(v any) (any, error)
}

type ReflectOptions

type ReflectOptions struct {
	Conversions map[reflect.Type]ReflectConversion
	Types       map[reflect.Type]Type
}

type System

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

A type system that validates types, values, parameters, etc.

func NewSystem

func NewSystem(types []Type) (System, error)

Returns a new system and if any errors were found building the system.

func NewSystemRequired

func NewSystemRequired(types []Type) System

Returns a System given a set of types and panics if any of the types, values, parameters, etc are malformed.

func (System) Parse

func (sys System) Parse(opts Options) (*Expr, error)

Parses an expression with the given set of options. Even if the expression is invalid it will be returned and all attempts of determining types and values will be made to best inform the user precisely what is wrong and what is valid.

func (System) ParseOrder

func (s System) ParseOrder() []*Type

Returns the types that can parse constants in the order determined by the system.

func (System) Type

func (s System) Type(name TypeName) *Type

Returns the type in the system with the given name, or nil if none exists.

func (System) Types

func (s System) Types() []*Type

Returns the types given to the system.

type SystemError

type SystemError struct {
	Message   string
	Type      *Type
	Value     *Value
	Parameter *Parameter
	Path      *string
}

An error occurred building a system from types.

func (SystemError) Error

func (e SystemError) Error() string

type Type

type Type struct {
	// The name of this type, should be unique.
	Name TypeName `json:"name"`
	// A description of this type.
	Description string `json:"description,omitempty"`
	// All values of this type.
	Values []Value `json:"values,omitempty"`
	// All types that this type can be converted to, and which value path can be used to do it.
	As map[TypeName]string `json:"as,omitempty"`
	// The type might be an enumerated value which means it has to be one of the specified values.
	// Parse can be specified to validate this and return a different data type other than string.
	Enums []string `json:"enums,omitempty"`
	// A custom parse function that converts a constant into a real value that is stored in Expression.Parsed.
	// If the given input does not match the type an error must be returned.
	Parse func(x string) (any, error) `json:"-"`
	// The parse order of the type. By default all types are considered equal and have an order of 0.
	// Higher parse orders are used first. For all types with the same parse order they are ordered
	// whether they have a Parse function (it prefers this). For two types with equivalent parse function
	// specificity they are ordered by type name length (preferring longer types before shorter).
	ParseOrder int `json:"parseOrder,omitempty"`
	// contains filtered or unexported fields
}

A data type in an expression system. It can have values, with and without parameters. It can also be automatically cast to another type with the `As` field.

func (Type) AsValue

func (t Type) AsValue(other TypeName) *Value

Returns the value that's used to convert to the given type. If this type was not given to a system then a nil panic will occur.

func (Type) EnumFor

func (t Type) EnumFor(input string) (string, bool)

Returns the enum value that matches the given text. If this type was not given to a system then a nil panic will occur.

func (Type) ParseInput

func (t Type) ParseInput(input string) (any, error)

Parses the constant input and returns a matching value. If there is no parse or matching enum option then an error is returned.

func (Type) Value

func (t Type) Value(path string) *Value

Returns the value with the given path, case insensitive. If this type was not given to a system then a nil panic will occur.

type TypeCompilers

type TypeCompilers[CE any] map[TypeName]ValueCompilers[CE]

A set of value compilers mapped by a type.

type TypeName

type TypeName string

A name for a type.

func NameOf

func NameOf[T any]() TypeName

type Value

type Value struct {
	// The main path for the value. Alternatives can be specified with Aliases.
	Path string `json:"path"`
	// The aliases to the path, to allow for more than one way to refer to the value.
	Aliases []string `json:"aliases,omitempty"`
	// The description of the value.
	Description string `json:"description,omitempty"`
	// The type of the value.
	Type TypeName `json:"type,omitempty"`
	// If the value is has a generic type that's determined based on one or more generic parameters.
	Generic bool `json:"generic,omitempty"`
	// The parameters for the value.
	Parameters []Parameter `json:"parameters,omitempty"`
	// If the last parameter can be specified any number of times.
	Variadic bool `json:"variadic,omitempty"`
	// contains filtered or unexported fields
}

A value (possibly with parameters) on a type.

func (Value) GetType

func (v Value) GetType(e *Expr) *Type

Determines the type for this value for the given expression. If this value is generic the types of the generic parameters will be used to determine the returned type.

func (Value) MaxParameters

func (v Value) MaxParameters() int

Returns the maximum number of possible parameters. If this value is not parameterized this returns 0. If this value is parameterized and variadic it returns the largest possible int.

func (Value) MinParameters

func (v Value) MinParameters() int

Returns the minimum number of required parameters

func (Value) Parameter

func (v Value) Parameter(i int) *Parameter

Returns the parameter at the given index. If this value is variadic and `i` goes beyond the defined parameters the last parameter is defined. If no parameter exists at the given index then nil is returned.

func (Value) ValueType

func (v Value) ValueType() *Type

The calculated type of the value. This will only be non-nil when the value is passed to a system.

type ValueCompilers

type ValueCompilers[CE any] map[string]Compiler[CE]

A set of compilers mapped by their lowecased paths.

Jump to

Keyboard shortcuts

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