53 lines
1 KiB
Go
53 lines
1 KiB
Go
|
package lexpr
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
type Lexpr struct {
|
||
|
operators map[string]Operator
|
||
|
functions map[string]func(ts *TokenStack) error
|
||
|
variables map[string]any
|
||
|
}
|
||
|
|
||
|
func New(opts ...Opt) *Lexpr {
|
||
|
l := &Lexpr{}
|
||
|
for _, o := range opts {
|
||
|
o(l)
|
||
|
}
|
||
|
return l
|
||
|
}
|
||
|
|
||
|
func (l *Lexpr) Eval(ctx context.Context, expression string) chan Result {
|
||
|
lexer := newLex()
|
||
|
lexems := lexer.parse(ctx, expression)
|
||
|
tokens := l.tokenize(ctx, lexems)
|
||
|
rpnTokens := infixToRpn(ctx, tokens)
|
||
|
return l.execute(ctx, rpnTokens)
|
||
|
}
|
||
|
|
||
|
func (l *Lexpr) SetFunction(name string, fn func(ts *TokenStack) error) *Lexpr {
|
||
|
l.functions[strings.ToLower(name)] = fn
|
||
|
return l
|
||
|
}
|
||
|
|
||
|
func (l *Lexpr) SetOperator(name string, fn func(ts *TokenStack) error, priority int, leftAssoc bool) *Lexpr {
|
||
|
l.operators[strings.ToLower(name)] = Operator{
|
||
|
handler: fn,
|
||
|
priority: priority,
|
||
|
leftAssoc: leftAssoc,
|
||
|
}
|
||
|
return l
|
||
|
}
|
||
|
|
||
|
func (l *Lexpr) SetVariable(name string, value any) *Lexpr {
|
||
|
l.variables[strings.ToLower(name)] = value
|
||
|
return l
|
||
|
}
|
||
|
|
||
|
type Result struct {
|
||
|
Value any
|
||
|
Error error
|
||
|
}
|