expression/evaluator.go

52 lines
944 B
Go
Raw Permalink Normal View History

2022-07-01 02:16:07 +03:00
package expression
import (
"go/scanner"
"go/token"
)
type Evaluator struct {
operators map[token.Token]Operator
functions map[string]func(stack *Stack) error
}
func New() *Evaluator {
return &Evaluator{
operators: DefaultOperators,
functions: DefaultFunctions,
}
}
func (e *Evaluator) Eval(expression string) (any, error) {
s := scanner.Scanner{}
fset := token.NewFileSet()
file := fset.AddFile("", fset.Base(), len(expression))
s.Init(file, []byte(expression), nil, scanner.ScanComments)
tokens := make(chan Token)
go func() {
for {
pos, tok, lit := s.Scan()
if tok == token.SEMICOLON {
continue
}
if tok == token.EOF {
break
}
tokens <- Token{
Token: tok,
Literal: lit,
Pos: int(pos),
}
}
close(tokens)
}()
rpnTokens := e.ToPRN(tokens)
return e.execute(rpnTokens)
}
type Operator struct {
fn func(stack *Stack) error
priority int
isLeftAssoc bool
}