TODO Consider having a separate walk of the AST that finds common subexpressions. This can be called before or after constant folding to find common subexpressions. PruneAst prunes the given AST based on the given EvalState and generates a new AST. Given AST is copied on write and a new AST is retur
(expr ast.Expr, macroCalls map[int64]ast.Expr, state EvalState)
| 67 | // fold(and thus cache results of) some external calls, then they can prepare |
| 68 | // the overloads accordingly. |
| 69 | func PruneAst(expr ast.Expr, macroCalls map[int64]ast.Expr, state EvalState) *ast.AST { |
| 70 | pruneState := NewEvalState() |
| 71 | for _, id := range state.IDs() { |
| 72 | v, _ := state.Value(id) |
| 73 | pruneState.SetValue(id, v) |
| 74 | } |
| 75 | pruner := &astPruner{ |
| 76 | ExprFactory: ast.NewExprFactory(), |
| 77 | expr: expr, |
| 78 | macroCalls: macroCalls, |
| 79 | state: pruneState, |
| 80 | nextExprID: getMaxID(expr)} |
| 81 | newExpr, _ := pruner.maybePrune(expr) |
| 82 | newInfo := ast.NewSourceInfo(nil) |
| 83 | for id, call := range pruner.macroCalls { |
| 84 | newInfo.SetMacroCall(id, call) |
| 85 | } |
| 86 | return ast.NewAST(newExpr, newInfo) |
| 87 | } |
| 88 | |
| 89 | func (p *astPruner) maybeCreateLiteral(id int64, val ref.Val) (ast.Expr, bool) { |
| 90 | switch v := val.(type) { |