func (this *Mem) newCallTree(parentPatterns int, node *ifExprs) (*CallNode, error) { if node.ret != nil { ps := node.ret zippedPatterns, zipper := zip(ps) zipperIndex := this.zis.add(zipper) stackElement := stackElm{ parentPatterns: parentPatterns, childrenZipper: zipperIndex, } stackIndex := this.stackElms.add(stackElement) zippedPatternIndex := this.patterns.add(zippedPatterns) return &CallNode{ child: zippedPatternIndex, stackIndex: stackIndex, }, nil } then, err := this.newCallTree(parentPatterns, node.then) if err != nil { return nil, err } els, err := this.newCallTree(parentPatterns, node.els) if err != nil { return nil, err } f, err := compose.NewBoolFunc(node.cond) if err != nil { return nil, err } return &CallNode{ cond: f, then: then, els: els, }, nil }
//EvalName evaluates a name expression given a name value. func EvalName(nameExpr *ast.NameExpr, name parser.Value) bool { f := NameToFunc(nameExpr) b, err := compose.NewBoolFunc(f) if err != nil { panic(err) } v, err := b.Eval(name) if err != nil { panic(err) } return v }
func (this *ifExprs) eval(label parser.Value) ([]*ast.Pattern, error) { if this.ret != nil { return this.ret, nil } f, err := compose.NewBoolFunc(this.cond) if err != nil { return nil, err } cond, err := f.Eval(label) if err != nil { return nil, err } if cond { return this.then.eval(label) } return this.els.eval(label) }
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 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)) }