aboutsummaryrefslogtreecommitdiff
path: root/execute.go
diff options
context:
space:
mode:
Diffstat (limited to 'execute.go')
-rw-r--r--execute.go45
1 files changed, 45 insertions, 0 deletions
diff --git a/execute.go b/execute.go
new file mode 100644
index 0000000..8062d32
--- /dev/null
+++ b/execute.go
@@ -0,0 +1,45 @@
+package expression
+
+import (
+ "fmt"
+ "go/token"
+ "strings"
+)
+
+func (e *Evaluator) execute(tokens chan Token) (any, error) {
+ stack := Stack{}
+ for tok := range tokens {
+ switch {
+ case tok.IsNumber():
+ stack.Push(tok)
+ case tok.IsOperator():
+ op := e.operators[tok.Token]
+ if err := op.fn(&stack); err != nil {
+ return nil, err
+ }
+ case tok.IsFunc():
+ fn, fnEsist := e.functions[strings.ToLower(tok.Literal)]
+ if !fnEsist {
+ return nil, fmt.Errorf("unknown function %s at %d", tok.Literal, tok.Pos)
+ }
+ if err := fn(&stack); err != nil {
+ return nil, err
+ }
+ case tok.IsError():
+ return nil, fmt.Errorf("Error at token %d: %w", tok.Pos, tok.Error())
+ }
+ }
+ if len(stack) != 1 {
+ return nil, fmt.Errorf("Expected exact one returning value, go %+v", stack)
+ }
+ result := stack.Pop()
+ switch result.Token {
+ case token.INT:
+ n, _ := result.Int()
+ return n, nil
+ case token.FLOAT:
+ return result.Float(), nil
+ default:
+ return result.Literal, nil
+ }
+}