-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexpression.go
80 lines (71 loc) · 1.64 KB
/
expression.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package goexpression
import (
"fmt"
"strconv"
"github.com/huangxingx/goexpression/operate"
)
//Expression ...
type Expression struct {
inputExpression string // 表达式字符串
suffixExpressionList []string // 后缀表达式
}
// NewExpress
// usage:
// expressStr := "1+2+3"
// exp := goexpression.NewExpress(expressStr)
// result := exp.Execute(nil)
// fmt.Printf("%s = %.2f", expressStr, result.(float64))
// // 6.00
func NewExpress(expression string) *Expression {
mpn := parse2mpn(expression)
suffixExpress := parseSuffixExpression(mpn)
return &Expression{
inputExpression: expression,
suffixExpressionList: suffixExpress,
}
}
//Execute
// param map[string]interface{} 参数
func (e *Expression) Execute(param map[string]interface{}) interface{} {
stack := NewStack()
var tmpResult interface{}
for _, v := range e.suffixExpressionList {
// number or keywork
if IsNum(v) || isKeyWork(v) {
stack.Push(v)
continue
}
// op
iOperate := operate.GetOperate(v)
if iOperate == nil {
// var
value, ok := param[v]
if !ok {
panic(fmt.Sprintf("var %s not value", v))
}
stack.Push(value)
continue
}
// 单目运算符
number := iOperate.GetOperateNumber()
if number == 1 {
oneValue := stack.Pop()
tmpResult = iOperate.Execute(v, oneValue, nil)
} else {
v2 := stack.Pop()
v1 := stack.Pop()
tmpResult = iOperate.Execute(v, v1, v2)
}
stack.Push(tmpResult)
}
result := stack.Pop()
if !stack.IsEmpty() {
stack.Print()
panic(fmt.Sprintf("execute err: stack.len > 0"))
}
return result
}
func IsNum(s string) bool {
_, err := strconv.ParseFloat(s, 64)
return err == nil
}