Skip to content

Commit 16131b1

Browse files
committed
Copy type and location on patch
1 parent 0fd1cfa commit 16131b1

File tree

4 files changed

+57
-20
lines changed

4 files changed

+57
-20
lines changed

bench_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,26 @@ func Benchmark_access(b *testing.B) {
7373
b.Fatal(err)
7474
}
7575
}
76+
77+
func Benchmark_call(b *testing.B) {
78+
type Env struct {
79+
Fn func(string, string, string) bool
80+
}
81+
82+
program, err := expr.Compile(`Fn("", "", "")`, expr.Env(Env{}))
83+
if err != nil {
84+
b.Fatal(err)
85+
}
86+
87+
env := Env{Fn: func(s string, s2 string, s3 string) bool {
88+
return s+s2+s3 == ""
89+
}}
90+
91+
for n := 0; n < b.N; n++ {
92+
_, err = vm.Run(program, env)
93+
}
94+
95+
if err != nil {
96+
b.Fatal(err)
97+
}
98+
}

checker/patcher.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,13 @@ func (p *operatorPatcher) Exit(node *ast.Node) {
3232
secondArgType := fnType.Type.In(1)
3333

3434
if leftType == firstArgType && rightType == secondArgType {
35-
*node = &ast.FunctionNode{
35+
newNode := &ast.FunctionNode{
3636
Name: fn,
3737
Arguments: []ast.Node{binaryNode.Left, binaryNode.Right},
3838
}
39+
newNode.SetType((*node).GetType())
40+
newNode.SetLocation((*node).GetLocation())
41+
*node = newNode
3942
}
4043
}
4144
}

compiler/compiler.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,12 @@ func (c *compiler) FunctionNode(node *ast.FunctionNode) {
426426
for _, arg := range node.Arguments {
427427
c.compile(arg)
428428
}
429-
c.emit(OpCall, c.makeConstant(Call{Name: node.Name, Size: len(node.Arguments)})...)
429+
c.emit(OpCall, c.makeConstant(
430+
Call{
431+
Name: node.Name,
432+
Size: len(node.Arguments),
433+
})...,
434+
)
430435
}
431436

432437
func (c *compiler) BuiltinNode(node *ast.BuiltinNode) {

optimizer/optimizer.go

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,21 @@ type fold struct{}
99
type inRange struct{}
1010
type constRange struct{}
1111

12+
func patch(node *Node, newNode Node) {
13+
newNode.SetType((*node).GetType())
14+
newNode.SetLocation((*node).GetLocation())
15+
*node = newNode
16+
}
17+
1218
func (*fold) Enter(node *Node) {}
1319
func (*fold) Exit(node *Node) {
1420
switch n := (*node).(type) {
1521
case *UnaryNode:
1622
if n.Operator == "-" {
1723
if i, ok := n.Node.(*IntegerNode); ok {
18-
*node = &IntegerNode{
24+
patch(node, &IntegerNode{
1925
Value: -i.Value,
20-
}
26+
})
2127
}
2228
}
2329

@@ -26,24 +32,24 @@ func (*fold) Exit(node *Node) {
2632
case "+":
2733
if a, ok := n.Left.(*IntegerNode); ok {
2834
if b, ok := n.Right.(*IntegerNode); ok {
29-
*node = &IntegerNode{
35+
patch(node, &IntegerNode{
3036
Value: a.Value + b.Value,
31-
}
37+
})
3238
}
3339
}
3440
if a, ok := n.Left.(*StringNode); ok {
3541
if b, ok := n.Right.(*StringNode); ok {
36-
*node = &StringNode{
42+
patch(node, &StringNode{
3743
Value: a.Value + b.Value,
38-
}
44+
})
3945
}
4046
}
4147
case "**":
4248
if a, ok := n.Left.(*IntegerNode); ok {
4349
if b, ok := n.Right.(*IntegerNode); ok {
44-
*node = &FloatNode{
50+
patch(node, &FloatNode{
4551
Value: math.Pow(float64(a.Value), float64(b.Value)),
46-
}
52+
})
4753
}
4854
}
4955
}
@@ -61,9 +67,9 @@ func (*fold) Exit(node *Node) {
6167
for i, a := range n.Nodes {
6268
value[i] = a.(*IntegerNode).Value
6369
}
64-
*node = &ConstantNode{
70+
patch(node, &ConstantNode{
6571
Value: value,
66-
}
72+
})
6773
}
6874

6975
string:
@@ -77,9 +83,9 @@ func (*fold) Exit(node *Node) {
7783
for i, a := range n.Nodes {
7884
value[i] = a.(*StringNode).Value
7985
}
80-
*node = &ConstantNode{
86+
patch(node, &ConstantNode{
8187
Value: value,
82-
}
88+
})
8389
}
8490

8591
}
@@ -94,7 +100,7 @@ func (*inRange) Exit(node *Node) {
94100
if rng, ok := n.Right.(*BinaryNode); ok && rng.Operator == ".." {
95101
if from, ok := rng.Left.(*IntegerNode); ok {
96102
if to, ok := rng.Right.(*IntegerNode); ok {
97-
*node = &BinaryNode{
103+
patch(node, &BinaryNode{
98104
Operator: "and",
99105
Left: &BinaryNode{
100106
Operator: ">=",
@@ -106,12 +112,12 @@ func (*inRange) Exit(node *Node) {
106112
Left: n.Left,
107113
Right: to,
108114
},
109-
}
115+
})
110116
if n.Operator == "not in" {
111-
*node = &UnaryNode{
117+
patch(node, &UnaryNode{
112118
Operator: "not",
113119
Node: *node,
114-
}
120+
})
115121
}
116122
}
117123
}
@@ -132,9 +138,9 @@ func (*constRange) Exit(node *Node) {
132138
for i := range value {
133139
value[i] = min.Value + i
134140
}
135-
*node = &ConstantNode{
141+
patch(node, &ConstantNode{
136142
Value: value,
137-
}
143+
})
138144
}
139145
}
140146
}

0 commit comments

Comments
 (0)