Skip to content

Commit

Permalink
Exploid binop identities when optimizing #115
Browse files Browse the repository at this point in the history
  • Loading branch information
dbaumgarten committed Oct 29, 2021
1 parent efcfddb commit e38deb4
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 0 deletions.
74 changes: 74 additions & 0 deletions pkg/optimizers/static_expressions.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ func (o *StaticExpressionOptimizer) OptimizeExpressionNonRecursive(exp ast.Expre

return varToConst(res, n.Exp1.Start())
}

if binop, is := exp.(*ast.BinaryOperation); is {
return simplifyIdentities(binop)
}

return nil
}

Expand Down Expand Up @@ -130,3 +135,72 @@ func varToConst(v *vm.Variable, pos ast.Position) ast.Expression {
Position: pos,
}
}

func simplifyIdentities(binop *ast.BinaryOperation) ast.Expression {

if _, is := binop.Exp1.(*ast.StringConstant); is {
return binop
}
if _, is := binop.Exp2.(*ast.StringConstant); is {
return binop
}

switch binop.Operator {
case "+":
if isNumConstWithValue(binop.Exp1, "0") {
return binop.Exp2
}
if isNumConstWithValue(binop.Exp2, "0") {
return binop.Exp1
}
case "-":
if isNumConstWithValue(binop.Exp1, "0") {
return &ast.UnaryOperation{
Position: binop.Start(),
Operator: "-",
Exp: binop.Exp2,
}
}
if isNumConstWithValue(binop.Exp2, "0") {
return binop.Exp1
}
case "*":
if isNumConstWithValue(binop.Exp1, "1") {
return binop.Exp2
}
if isNumConstWithValue(binop.Exp2, "1") {
return binop.Exp1
}
if isNumConstWithValue(binop.Exp1, "0") {
return &ast.NumberConstant{Position: binop.Start(), Value: "0"}
}
if isNumConstWithValue(binop.Exp2, "0") {
return &ast.NumberConstant{Position: binop.Start(), Value: "0"}
}
case "/":
if isNumConstWithValue(binop.Exp2, "1") {
return binop.Exp1
}
case "^":
if isNumConstWithValue(binop.Exp2, "0") {
return &ast.NumberConstant{Position: binop.Start(), Value: "1"}
}
if isNumConstWithValue(binop.Exp2, "1") {
return binop.Exp1
}
}

return binop
}

// checkis if check is a NumberConstant and if it's value matches expected
func isNumConstWithValue(check ast.Expression, expected string) bool {

if num, is := check.(*ast.NumberConstant); is {
if num.Value == expected {
return true
}
}

return false
}
12 changes: 12 additions & 0 deletions pkg/optimizers/static_expressions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,18 @@ var staticCases = map[string]string{
"a=123+100+a": "a=223+a",
"a=a+(123+100)+b": "a=a+223+b",
"a=a+(123+100)+b*(10*10)": "a=a+223+b*100",
"a=0+b": "a=b",
"a=b+0": "a=b",
"a=b-0": "a=b",
"a=0-b": "a=-b",
"a=0*b": "a=0",
"a=b*0": "a=0",
"a=1*b": "a=b",
"a=b*1": "a=b",
"a=b/1": "a=b",
"a=b^0": "a=1",
"a=b^1": "a=b",
"a=\"a\"*1": "a=\"a\"*1",
}

func TestStaticExpressions(t *testing.T) {
Expand Down

0 comments on commit e38deb4

Please sign in to comment.