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 /evaluator.go |
first commit
Diffstat (limited to 'evaluator.go')
-rw-r--r-- | evaluator.go | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/evaluator.go b/evaluator.go new file mode 100644 index 0000000..486d45f --- /dev/null +++ b/evaluator.go @@ -0,0 +1,51 @@ +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 +} |