feel

package module
v1.0.6 Latest Latest
Warning

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

Go to latest
Published: Mar 8, 2026 License: MIT Imports: 15 Imported by: 1

README

feel

An interpreter for the FEEL - Friendly Enough Expression Language, written in Go(lang). FEEL is broadly used in DMN and BPMN to provide rule engine and script support. The feel module can be imported into other Go projects or used as command line executable.

Credits

This library is based on work of @superisaac/FEEL.go and many thanks and credits go to him.

Build

  • run make build to build feel interpreter bin/feel
  • run make test to run testing

Use in golang applications

import (
  feel "github.com/pbinitiative/feel"
)

res, err := feel.EvalString("5 + 7")

Examples, with using the CLI tool


% bin/feel -c '"hello " + "world"'
"hello world"

% bin/feel -c '(function(a, b) a + b)(5, 8)'
13

# dump AST tree instead of evaluating the script
% bin/feel -c 'bind("a", 5); if a > 3 then "larger" else "smaller"' -ast
(explist (call bind ["a", 5]) (if (> a 3) "larger"  "smaller"))

% bin/feel -c 'some x in [3, 4, 8, 9] satisfies x % 2 = 0'
4

% bin/feel -c 'every x in [3, 4, 8, 9] satisfies x % 2 = 0'
[
  4,
  8
]

Documentation

Index

Constants

View Source
const (
	TokenEOF               = "eof"
	TokenSpace             = "space"
	TokenCommentSingleLine = "comment/singleline"
	TokenCommentMultiline  = "comment/multiline"

	TokenName = "name"
	//TokenFuncall  = "funcall"
	TokenTemporal = "temporal"
	TokenString   = "string"

	TokenKeyword = "keyword"
	TokenNumber  = "number"
)
View Source
const (
	Prec = 34 * 8
)

Variables

View Source
var (
	ErrParseNumber = errors.New("fail to parse number")
)
View Source
var ErrParseTemporal = errors.New("fail to parse temporal value")
View Source
var Zero = N(0)

Functions

func CompareValues

func CompareValues(leftVal, rightVal any) int

func EvalString

func EvalString(input string) (any, error)

func EvalStringWithScope

func EvalStringWithScope(input string, scope Scope) (any, error)

func ParseTemporalValue

func ParseTemporalValue(temporalStr string) (interface{}, error)

Types

type ArgSizeError

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

func (ArgSizeError) Error

func (self ArgSizeError) Error() string

type ArgTypeError

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

func (ArgTypeError) Error

func (self ArgTypeError) Error() string

type ArrayNode

type ArrayNode struct {
	Elements []Node
	// contains filtered or unexported fields
}

func (ArrayNode) Eval

func (arrNode ArrayNode) Eval(intp *Interpreter) (any, error)

func (ArrayNode) Repr

func (arrNode ArrayNode) Repr() string

func (ArrayNode) TextRange

func (arrNode ArrayNode) TextRange() TextRange

type Binop

type Binop struct {
	Op    string
	Left  Node
	Right Node
	// contains filtered or unexported fields
}

Binop binary operator

func (Binop) Eval

func (binop Binop) Eval(intp *Interpreter) (any, error)

func (Binop) Repr

func (binop Binop) Repr() string

func (Binop) TextRange

func (binop Binop) TextRange() TextRange

type BoolNode

type BoolNode struct {
	Value bool
	// contains filtered or unexported fields
}

func (BoolNode) Eval

func (boolNode BoolNode) Eval(intp *Interpreter) (any, error)

Eval Evaluate bool node

func (BoolNode) Repr

func (boolNode BoolNode) Repr() string

func (BoolNode) TextRange

func (boolNode BoolNode) TextRange() TextRange

type DotOp

type DotOp struct {
	Left Node
	Attr string
	// contains filtered or unexported fields
}

DotOp function call

func (DotOp) Eval

func (dotop DotOp) Eval(intp *Interpreter) (any, error)

func (DotOp) Repr

func (dotop DotOp) Repr() string

func (DotOp) TextRange

func (dotop DotOp) TextRange() TextRange

type EvalError

type EvalError struct {
	Code    int
	Short   string
	Message string
}

func NewErrBadInput added in v0.1.5

func NewErrBadInput(row int, column int, inputText string) *EvalError

func NewErrBadOp

func NewErrBadOp(leftType, op, rightType string) *EvalError

func NewErrIndex

func NewErrIndex(msg string) *EvalError

func NewErrKeyNotFound

func NewErrKeyNotFound(keyName string) *EvalError

func NewErrKeywordArgument

func NewErrKeywordArgument(argName string) *EvalError

NewErrKeywordArgument argument errors

func NewErrTooFewArguments

func NewErrTooFewArguments(required []string) *EvalError

func NewErrTooManyArguments

func NewErrTooManyArguments() *EvalError

func NewErrTypeMismatch

func NewErrTypeMismatch(expectType string) *EvalError

func NewEvalError

func NewEvalError(code int, short string, msgs ...string) *EvalError

func (EvalError) Error

func (evalError EvalError) Error() string

type EveryExpr

type EveryExpr struct {
	Varname    string
	ListExpr   Node
	FilterExpr Node
	// contains filtered or unexported fields
}

EveryExpr Every expression

func (EveryExpr) Eval

func (ee EveryExpr) Eval(intp *Interpreter) (any, error)

func (EveryExpr) Repr

func (ee EveryExpr) Repr() string

func (EveryExpr) TextRange

func (ee EveryExpr) TextRange() TextRange

type ExprList

type ExprList struct {
	Elements []Node
	// contains filtered or unexported fields
}

ExprList Expression List

func (ExprList) Eval

func (exprList ExprList) Eval(intp *Interpreter) (any, error)

func (ExprList) Repr

func (exprList ExprList) Repr() string

func (ExprList) TextRange

func (exprList ExprList) TextRange() TextRange

type FEELDate

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

func ParseDate

func ParseDate(timeStr string) (*FEELDate, error)

func (FEELDate) Date

func (d FEELDate) Date() time.Time

func (FEELDate) GetAttr

func (d FEELDate) GetAttr(name string) (interface{}, bool)

func (FEELDate) MarshalJSON

func (d FEELDate) MarshalJSON() ([]byte, error)

func (FEELDate) String

func (d FEELDate) String() string

type FEELDatetime

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

func MustParseDatetime

func MustParseDatetime(temporalStr string) *FEELDatetime

func ParseDatetime

func ParseDatetime(temporalStr string) (*FEELDatetime, error)

func (*FEELDatetime) Add

func (dt *FEELDatetime) Add(dur *FEELDuration) *FEELDatetime

func (FEELDatetime) Compare

func (dt FEELDatetime) Compare(other FEELDatetime) int

func (FEELDatetime) Date

func (dt FEELDatetime) Date() time.Time

func (FEELDatetime) Equal

func (dt FEELDatetime) Equal(other FEELDatetime) bool

func (FEELDatetime) GetAttr

func (dt FEELDatetime) GetAttr(name string) (interface{}, bool)

func (FEELDatetime) MarshalJSON

func (dt FEELDatetime) MarshalJSON() ([]byte, error)

func (FEELDatetime) String

func (dt FEELDatetime) String() string

func (*FEELDatetime) Sub

func (dt *FEELDatetime) Sub(v HasTime) *FEELDuration

func (FEELDatetime) Time

func (dt FEELDatetime) Time() time.Time

type FEELDuration

type FEELDuration struct {
	Neg     bool
	Years   int
	Months  int
	Days    int
	Hours   int
	Minutes int
	Seconds int
}

func NewFEELDuration

func NewFEELDuration(dur time.Duration) *FEELDuration

func ParseDuration

func ParseDuration(temporalStr string) (*FEELDuration, error)

func (FEELDuration) Duration

func (duration FEELDuration) Duration() time.Duration

func (FEELDuration) GetAttr

func (duration FEELDuration) GetAttr(name string) (interface{}, bool)

func (FEELDuration) MarshalJSON

func (duration FEELDuration) MarshalJSON() ([]byte, error)

func (FEELDuration) Negative

func (duration FEELDuration) Negative() *FEELDuration

func (FEELDuration) String

func (duration FEELDuration) String() string

type FEELTime

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

func ParseTime

func ParseTime(temporalStr string) (*FEELTime, error)

func (FEELTime) GetAttr

func (t FEELTime) GetAttr(name string) (interface{}, bool)

func (FEELTime) MarshalJSON

func (t FEELTime) MarshalJSON() ([]byte, error)

func (FEELTime) String

func (t FEELTime) String() string

func (FEELTime) Time

func (t FEELTime) Time() time.Time

type ForExpr

type ForExpr struct {
	Varname    string
	ListExpr   Node
	ReturnExpr Node
	// contains filtered or unexported fields
}

ForExpr FOR expression

func (ForExpr) Eval

func (fe ForExpr) Eval(intp *Interpreter) (any, error)

func (ForExpr) Repr

func (fe ForExpr) Repr() string

func (ForExpr) TextRange

func (fe ForExpr) TextRange() TextRange

type FunCall

type FunCall struct {
	FunRef Node
	Args   []funcallArg
	// contains filtered or unexported fields
}

func (FunCall) Eval

func (fc FunCall) Eval(intp *Interpreter) (any, error)

func (FunCall) EvalFunDef

func (fc FunCall) EvalFunDef(intp *Interpreter, funDef *FunDef) (any, error)

func (FunCall) EvalMacro

func (fc FunCall) EvalMacro(intp *Interpreter, macro *Macro) (any, error)

func (FunCall) EvalNativeFun

func (fc FunCall) EvalNativeFun(intp *Interpreter, funDef *NativeFun) (any, error)

func (FunCall) Repr

func (fc FunCall) Repr() string

func (FunCall) TextRange

func (fc FunCall) TextRange() TextRange

type FunDef

type FunDef struct {
	Args []string
	Body Node
	// contains filtered or unexported fields
}

FunDef function definition

func (FunDef) Eval

func (fd FunDef) Eval(intp *Interpreter) (any, error)

func (FunDef) EvalCall

func (fd FunDef) EvalCall(intp *Interpreter, args []any) (any, error)

func (FunDef) Repr

func (fd FunDef) Repr() string

func (FunDef) TextRange

func (fd FunDef) TextRange() TextRange

type HasAttrs

type HasAttrs interface {
	GetAttr(name string) (interface{}, bool)
}

type HasDate

type HasDate interface {
	Date() time.Time
}

type HasTime

type HasTime interface {
	Time() time.Time
}

type IfExpr

type IfExpr struct {
	Cond       Node
	ThenBranch Node
	ElseBranch Node
	// contains filtered or unexported fields
}

func (IfExpr) Eval

func (ifExpr IfExpr) Eval(intp *Interpreter) (any, error)

func (IfExpr) Repr

func (ifExpr IfExpr) Repr() string

func (IfExpr) TextRange

func (ifExpr IfExpr) TextRange() TextRange

type Interpreter

type Interpreter struct {
	ScopeStack []Scope
}

func NewIntepreter

func NewIntepreter() *Interpreter

func (*Interpreter) Bind

func (i *Interpreter) Bind(name string, value any)

Bind the value to the name of current scope

func (Interpreter) Len

func (i Interpreter) Len() int

func (*Interpreter) Pop

func (i *Interpreter) Pop() Scope

func (*Interpreter) Push

func (i *Interpreter) Push(scp Scope)

func (*Interpreter) PushEmpty

func (i *Interpreter) PushEmpty()

func (Interpreter) Resolve

func (i Interpreter) Resolve(name string) (any, bool)

Resolve a name from the top of scopestack to bottom

func (Interpreter) Set

func (i Interpreter) Set(name string, value any) bool

Set the name and set to new value

func (Interpreter) String

func (i Interpreter) String() string

type Macro

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

func NewMacro

func NewMacro(fn MacroDef) *Macro

func (*Macro) Help

func (self *Macro) Help(help string) *Macro

func (*Macro) Optional

func (self *Macro) Optional(argNames ...string) *Macro

func (*Macro) Required

func (self *Macro) Required(argNames ...string) *Macro

func (*Macro) Vararg

func (self *Macro) Vararg(argName string) *Macro

type MacroDef

type MacroDef func(intp *Interpreter, args map[string]Node, varArgs []Node) (interface{}, error)

type MapNode

type MapNode struct {
	Values []mapItem
	// contains filtered or unexported fields
}

func (MapNode) Eval

func (mapNode MapNode) Eval(intp *Interpreter) (any, error)

func (MapNode) Repr

func (mapNode MapNode) Repr() string

func (MapNode) TextRange

func (mapNode MapNode) TextRange() TextRange

type MultiTests

type MultiTests struct {
	Elements []Node
	// contains filtered or unexported fields
}

func (MultiTests) Eval

func (mt MultiTests) Eval(intp *Interpreter) (any, error)

func (MultiTests) Repr

func (mt MultiTests) Repr() string

func (MultiTests) TextRange

func (mt MultiTests) TextRange() TextRange

type NativeFun

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

func NewNativeFunc

func NewNativeFunc(fn NativeFunDef) *NativeFun

func (NativeFun) ArgNameAt

func (nativeFun NativeFun) ArgNameAt(at int) (string, bool)

func (*NativeFun) Call

func (nativeFun *NativeFun) Call(intp *Interpreter, args map[string]interface{}) (interface{}, error)

func (*NativeFun) Help

func (nativeFun *NativeFun) Help(help string) *NativeFun

func (*NativeFun) Optional

func (nativeFun *NativeFun) Optional(argNames ...string) *NativeFun

func (*NativeFun) Required

func (nativeFun *NativeFun) Required(argNames ...string) *NativeFun

func (*NativeFun) Vararg

func (nativeFun *NativeFun) Vararg(argName string) *NativeFun

type NativeFunDef

type NativeFunDef func(args map[string]interface{}) (interface{}, error)

NativeFunDef native function

type Node

type Node interface {
	Repr() string
	Eval(*Interpreter) (interface{}, error)
	TextRange() TextRange
}

func ParseString

func ParseString(input string) (Node, error)

type NullNode

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

func (NullNode) Eval

func (nullNode NullNode) Eval(intp *Interpreter) (any, error)

func (NullNode) Repr

func (nullNode NullNode) Repr() string

func (NullNode) TextRange

func (nullNode NullNode) TextRange() TextRange

type NullValue

type NullValue struct {
}

func (NullValue) Equal

func (self NullValue) Equal(other NullValue) bool

func (NullValue) MarshalJSON

func (self NullValue) MarshalJSON() ([]byte, error)

type Number

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

func N

func N(v interface{}) *Number

func NewNumber

func NewNumber(strn string) *Number

func NewNumberFromFloat

func NewNumberFromFloat(input float64) *Number

func NewNumberFromInt64

func NewNumberFromInt64(input int64) *Number

func ParseNumberWithErr

func ParseNumberWithErr(v interface{}) (*Number, error)

func (*Number) Add

func (n *Number) Add(other *Number) *Number

func (*Number) Cmp

func (n *Number) Cmp(other *Number) int

func (Number) Compare

func (n Number) Compare(other Number) int

func (Number) Equal

func (n Number) Equal(other Number) bool

func (Number) Float64

func (n Number) Float64() float64

func (*Number) FloatDiv

func (n *Number) FloatDiv(other *Number) *Number

func (Number) Int

func (n Number) Int() int

func (Number) Int64

func (n Number) Int64() int64

func (*Number) IntDiv

func (n *Number) IntDiv(other *Number) *Number

func (*Number) IntMod

func (n *Number) IntMod(other *Number) *Number

func (Number) MarshalJSON

func (n Number) MarshalJSON() ([]byte, error)

func (*Number) Mul

func (n *Number) Mul(other *Number) *Number

func (Number) String

func (n Number) String() string

func (*Number) Sub

func (n *Number) Sub(other *Number) *Number

type NumberNode

type NumberNode struct {
	Value string
	// contains filtered or unexported fields
}

func (NumberNode) Eval

func (numberNode NumberNode) Eval(intp *Interpreter) (any, error)

Eval Evaluate Number node

func (NumberNode) Repr

func (numberNode NumberNode) Repr() string

func (NumberNode) TextRange

func (numberNode NumberNode) TextRange() TextRange

type Parser

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

func NewParser

func NewParser(scanner *Scanner) *Parser

func (Parser) CurrentToken

func (p Parser) CurrentToken() ScannerToken

func (*Parser) Parse

func (p *Parser) Parse() (Node, error)

func (Parser) Unexpected

func (p Parser) Unexpected(expects ...string) *UnexpectedToken

type Prelude

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

func GetPrelude

func GetPrelude() *Prelude

func (*Prelude) Bind

func (self *Prelude) Bind(name string, value interface{}) *Prelude

func (*Prelude) Load

func (self *Prelude) Load()

func (*Prelude) Resolve

func (self *Prelude) Resolve(name string) (interface{}, bool)

type RangeNode

type RangeNode struct {
	StartOpen bool
	Start     Node

	EndOpen bool
	End     Node
	// contains filtered or unexported fields
}

func (RangeNode) Eval

func (rangeNode RangeNode) Eval(intp *Interpreter) (any, error)

func (RangeNode) Repr

func (rangeNode RangeNode) Repr() string

func (RangeNode) TextRange

func (rangeNode RangeNode) TextRange() TextRange

type RangeValue

type RangeValue struct {
	StartOpen bool
	Start     any

	EndOpen bool
	End     any
}

func (RangeValue) AfterPoint

func (rv RangeValue) AfterPoint(p any) (bool, error)

func (RangeValue) AfterRange

func (rv RangeValue) AfterRange(other RangeValue) (bool, error)

func (RangeValue) BeforePoint

func (rv RangeValue) BeforePoint(p any) (bool, error)

func (RangeValue) BeforeRange

func (rv RangeValue) BeforeRange(other RangeValue) (bool, error)

func (RangeValue) Contains

func (rv RangeValue) Contains(p any) bool

func (RangeValue) Includes

func (rv RangeValue) Includes(other RangeValue) (bool, error)

func (RangeValue) Position

func (rv RangeValue) Position(p any) (int, error)

type ScanPosition

type ScanPosition struct {
	Row    int
	Column int
}

type Scanner

type Scanner struct {
	Pos   ScanPosition
	Eaten int
	// contains filtered or unexported fields
}

func NewScanner

func NewScanner(input string) *Scanner

func (Scanner) Current

func (scanner Scanner) Current() ScannerToken

func (*Scanner) Next

func (scanner *Scanner) Next() error

func (*Scanner) Tokens

func (scanner *Scanner) Tokens() ([]ScannerToken, error)

Tokens Find all tokens

type ScannerToken

type ScannerToken struct {
	Kind  string
	Value string
	Pos   ScanPosition
}

func (ScannerToken) Expect

func (token ScannerToken) Expect(tokenKinds ...string) bool

func (ScannerToken) ExpectKeywords

func (token ScannerToken) ExpectKeywords(words ...string) bool

func (ScannerToken) IsOp

func (token ScannerToken) IsOp() bool

type Scope

type Scope map[string]interface{}

type SomeExpr

type SomeExpr struct {
	Varname    string
	ListExpr   Node
	FilterExpr Node
	// contains filtered or unexported fields
}

SomeExpr some expression

func (SomeExpr) Eval

func (sexpr SomeExpr) Eval(intp *Interpreter) (any, error)

func (SomeExpr) Repr

func (sexpr SomeExpr) Repr() string

func (SomeExpr) TextRange

func (sexpr SomeExpr) TextRange() TextRange

type StringNode

type StringNode struct {
	Value string
	// contains filtered or unexported fields
}

func (StringNode) Content

func (stringNode StringNode) Content() string

func (StringNode) Eval

func (stringNode StringNode) Eval(intp *Interpreter) (any, error)

func (StringNode) Repr

func (stringNode StringNode) Repr() string

func (StringNode) TextRange

func (stringNode StringNode) TextRange() TextRange

type TemporalNode

type TemporalNode struct {
	Value string
	// contains filtered or unexported fields
}

func (TemporalNode) Content

func (tempNode TemporalNode) Content() string

func (TemporalNode) Eval

func (tempNode TemporalNode) Eval(intp *Interpreter) (any, error)

func (TemporalNode) Repr

func (tempNode TemporalNode) Repr() string

func (TemporalNode) TextRange

func (tempNode TemporalNode) TextRange() TextRange

type TextRange

type TextRange struct {
	Start ScanPosition
	End   ScanPosition
}

type UnexpectedToken

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

func NewUnexpectedToken

func NewUnexpectedToken(token ScannerToken, callers []string, expects []string) *UnexpectedToken

func (UnexpectedToken) Error

func (self UnexpectedToken) Error() string

type Var

type Var struct {
	Name string
	// contains filtered or unexported fields
}

Var variable

func (Var) Eval

func (v Var) Eval(intp *Interpreter) (any, error)

func (Var) Repr

func (v Var) Repr() string

func (Var) TextRange

func (v Var) TextRange() TextRange

Jump to

Keyboard shortcuts

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