diff options
author | Alexander Kiryukhin <i@neonxp.dev> | 2022-07-01 02:16:07 +0300 |
---|---|---|
committer | Alexander Kiryukhin <i@neonxp.dev> | 2022-07-01 02:16:07 +0300 |
commit | cc4c01c69c238c92602b393ed87575ba5edad352 (patch) | |
tree | 12416835a04c98dba8450d6e799754fb32c7ca0f /execute.go |
first commit
Diffstat (limited to 'execute.go')
-rw-r--r-- | execute.go | 45 |
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 + } +} |