func (this *Mem) getFunc(expr *ast.Expr) funcs.Bool { if f, ok := this.funcs[expr]; ok { return f } f, err := compose.NewBool(expr) if err != nil { panic(err) } compose.SetContext(f, this.context) this.funcs[expr] = f return f }
func (this *exprToFunc) Visit(node interface{}) interface{} { if this.err != nil { return this } leaf, ok := node.(*ast.LeafNode) if ok { f, err := compose.NewBool(leaf.Expr) if err != nil { this.err = err return this } this.m[leaf.Expr] = f } return this }
func TestNoEqualError(t *testing.T) { exprStr := Sprint(StringEq(ElemStrings(NewListOfString([]String{StringVar()}), IntConst(3)), StringConst("0123456789"))) t.Logf(exprStr) e, err := parser.NewParser().ParseExpr(exprStr) if err != nil { t.Fatal(err) } b, err := compose.NewBool(e) if err != nil { t.Fatal(err) } f, err := compose.NewBoolFunc(b) if err != nil { t.Fatal(err) } if v, err := f.Eval(debug.NewStringValue("0")); err != nil { t.Fatal(err) } else if v { t.Fatalf("expected false") } }
func (this *simplifier) simplify(p *ast.Pattern, top bool) *ast.Pattern { cRef := func(cp *ast.Pattern) *ast.Pattern { if top { return cp } return checkRef(this.refs, cp) } cachesimp := func(sp *ast.Pattern) *ast.Pattern { if _, ok := this.cache[sp]; ok { return sp } s := this.simplify(sp, false) this.cache[s] = struct{}{} return s } simp := func(sp *ast.Pattern) *ast.Pattern { return this.simplify(sp, false) } typ := p.GetValue() switch v := typ.(type) { case *ast.Empty: return p case *ast.TreeNode: child := cachesimp(v.GetPattern()) if isNotZany(child) { return emptyset } name := v.GetName() b := nameexpr.NameToFunc(v.GetName()) if funcs.IsFalse(b) { return emptyset } if funcs.IsTrue(b) { name = ast.NewAnyName() } return cRef(ast.NewTreeNode(name, child)) case *ast.LeafNode: b, err := compose.NewBool(v.GetExpr()) if err != nil { //Don't simplify if there is an error to keep this function signature simple. return p } if funcs.IsFalse(b) { return emptyset } return p case *ast.Concat: return cRef(simplifyConcat( simp(v.GetLeftPattern()), simp(v.GetRightPattern()), )) case *ast.Or: return cRef(simplifyOr(this.refs, simp(v.GetLeftPattern()), simp(v.GetRightPattern()), this.record, )) case *ast.And: return cRef(simplifyAnd(this.refs, simp(v.GetLeftPattern()), simp(v.GetRightPattern()), this.record, )) case *ast.ZeroOrMore: return cRef(simplifyZeroOrMore(simp(v.GetPattern()))) case *ast.Reference: return p case *ast.Not: return cRef(simplifyNot(simp(v.GetPattern()))) case *ast.ZAny: return p case *ast.Contains: return cRef(simplifyContains(simp(v.GetPattern()))) case *ast.Optional: return simplifyOptional(simp(v.GetPattern())) case *ast.Interleave: return cRef(simplifyInterleave(this.refs, cachesimp(v.GetLeftPattern()), cachesimp(v.GetRightPattern()), )) } panic(fmt.Sprintf("unknown pattern typ %T", typ)) }
func derivCall(refs ast.RefLookup, p *ast.Pattern, label parser.Value) ([]*ast.Pattern, error) { typ := p.GetValue() switch v := typ.(type) { case *ast.Empty: return []*ast.Pattern{}, nil case *ast.ZAny: return []*ast.Pattern{}, nil case *ast.TreeNode: b := nameexpr.NameToFunc(v.GetName()) f, err := compose.NewBoolFunc(b) if err != nil { return nil, err } eval, err := f.Eval(label) if err != nil { return nil, err } if eval { return []*ast.Pattern{v.GetPattern()}, nil } return []*ast.Pattern{ast.NewNot(ast.NewZAny())}, nil case *ast.LeafNode: b, err := compose.NewBool(v.GetExpr()) if err != nil { return nil, err } f, err := compose.NewBoolFunc(b) if err != nil { return nil, err } eval, err := f.Eval(label) if err != nil { return nil, err } if eval { return []*ast.Pattern{ast.NewEmpty()}, nil } return []*ast.Pattern{ast.NewNot(ast.NewZAny())}, nil case *ast.Concat: l, err := derivCall(refs, v.GetLeftPattern(), label) if err != nil { return nil, err } if !Nullable(refs, v.GetLeftPattern()) { return l, nil } r, err := derivCall(refs, v.GetRightPattern(), label) if err != nil { return nil, err } return append(l, r...), nil case *ast.Or: return derivCall2(refs, v.GetLeftPattern(), v.GetRightPattern(), label) case *ast.And: return derivCall2(refs, v.GetLeftPattern(), v.GetRightPattern(), label) case *ast.Interleave: return derivCall2(refs, v.GetLeftPattern(), v.GetRightPattern(), label) case *ast.ZeroOrMore: return derivCall(refs, v.GetPattern(), label) case *ast.Reference: return derivCall(refs, refs[v.GetName()], label) case *ast.Not: return derivCall(refs, v.GetPattern(), label) case *ast.Contains: return derivCall(refs, ast.NewConcat(ast.NewZAny(), ast.NewConcat(v.GetPattern(), ast.NewZAny())), label) case *ast.Optional: return derivCall(refs, ast.NewOr(v.GetPattern(), ast.NewEmpty()), label) } panic(fmt.Sprintf("unknown pattern typ %T", typ)) }