func (this *ifExprs) addIfExpr(cond funcs.Bool, then, els *ast.Pattern) { // efficienctly append the then and else return to two copies of the current returns. if this.ret != nil { this.cond = cond thenterms := make([]*ast.Pattern, len(this.ret)+1) copy(thenterms, this.ret) thenterms[len(thenterms)-1] = then this.then = &ifExprs{ret: thenterms} this.els = &ifExprs{ret: append(this.ret, els)} this.ret = nil return } // remove duplicate condition if funcs.Equal(this.cond, cond) { this.then.addReturn(then) this.els.addReturn(els) return } // remove impossible (always false) then condition if funcs.IsFalse(funcs.Simplify(funcs.And(this.cond, cond))) { this.then.addReturn(els) this.els.addIfExpr(cond, then, els) return } // remove impossible (always false) else condition if funcs.IsFalse(funcs.Simplify(funcs.And(this.cond, funcs.Not(cond)))) { this.then.addIfExpr(cond, then, els) this.els.addReturn(then) return } this.then.addIfExpr(cond, then, els) this.els.addIfExpr(cond, then, els) return }
//NameToFunc compiles a parsed name expression into a function. func NameToFunc(n *ast.NameExpr) funcs.Bool { typ := n.GetValue() switch v := typ.(type) { case *ast.Name: if v.DoubleValue != nil { return funcs.DoubleEq(funcs.DoubleVar(), funcs.DoubleConst(v.GetDoubleValue())) } else if v.IntValue != nil { return funcs.IntEq(funcs.IntVar(), funcs.IntConst(v.GetIntValue())) } else if v.UintValue != nil { return funcs.UintEq(funcs.UintVar(), funcs.UintConst(v.GetUintValue())) } else if v.BoolValue != nil { return funcs.BoolEq(funcs.BoolVar(), funcs.BoolConst(v.GetBoolValue())) } else if v.StringValue != nil { return funcs.StringEq(funcs.StringVar(), funcs.StringConst(v.GetStringValue())) } else if v.BytesValue != nil { return funcs.BytesEq(funcs.BytesVar(), funcs.BytesConst(v.GetBytesValue())) } panic(fmt.Sprintf("unknown name expr name %#v", v)) case *ast.AnyName: return funcs.BoolConst(true) case *ast.AnyNameExcept: return funcs.Not(NameToFunc(v.GetExcept())) case *ast.NameChoice: return funcs.Or(NameToFunc(v.GetLeft()), NameToFunc(v.GetRight())) } panic(fmt.Sprintf("unknown name expr typ %T", typ)) }