Added all source files
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
// ast.go
|
||||
package expr
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
//-------- ast
|
||||
|
||||
type ast struct {
|
||||
root *term
|
||||
}
|
||||
|
||||
func NewAst() *ast {
|
||||
return &ast{}
|
||||
}
|
||||
|
||||
func (self *ast) String() string {
|
||||
var sb strings.Builder
|
||||
if self.root == nil {
|
||||
sb.WriteString("(nil)")
|
||||
} else {
|
||||
self.root.toString(&sb)
|
||||
}
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
func (self *ast) addTokens(tokens ...*Token) (err error) {
|
||||
for _, tk := range tokens {
|
||||
if err = self.addToken(tk); err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (self *ast) addToken(tk *Token) (err error) {
|
||||
if t := newTerm(tk, nil); t != nil {
|
||||
err = self.addTerm(t)
|
||||
} else {
|
||||
err = fmt.Errorf("No term constructor for token %q", tk.String())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (self *ast) addTerm(node *term) (err error) {
|
||||
if self.root == nil {
|
||||
self.root = node
|
||||
} else {
|
||||
self.root, err = self.insert(self.root, node)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (self *ast) insert(tree, node *term) (root *term, err error) {
|
||||
if tree.getPriority() < node.getPriority() {
|
||||
root = tree
|
||||
if tree.isComplete() {
|
||||
var subRoot *term
|
||||
last := tree.removeLastChild()
|
||||
subRoot, err = self.insert(last, node)
|
||||
subRoot.setParent(tree)
|
||||
} else {
|
||||
node.setParent(tree)
|
||||
}
|
||||
} else if !node.isLeaf() {
|
||||
root = node
|
||||
tree.setParent(node)
|
||||
} else {
|
||||
err = fmt.Errorf("two adjacent operators: %q and %q", tree, node)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (self *ast) eval(ctx exprContext) (result any, err error) {
|
||||
if self.root != nil {
|
||||
result, err = self.root.compute(ctx)
|
||||
} else {
|
||||
err = errors.New("empty expression")
|
||||
}
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user