aboutsummaryrefslogtreecommitdiff
path: root/lexpr.go
diff options
context:
space:
mode:
Diffstat (limited to 'lexpr.go')
-rw-r--r--lexpr.go52
1 files changed, 52 insertions, 0 deletions
diff --git a/lexpr.go b/lexpr.go
new file mode 100644
index 0000000..fc3bbf8
--- /dev/null
+++ b/lexpr.go
@@ -0,0 +1,52 @@
+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
+}