expression/execute.go
Alexander Kiryukhin cc4c01c69c
first commit
2022-07-01 02:16:07 +03:00

45 lines
988 B
Go

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
}
}