aboutsummaryrefslogblamecommitdiff
path: root/evaluator.go
blob: 486d45fb416e40508c5aaa78c4c53555ab08c752 (plain) (tree)


















































                                                                   
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
}