Beispiel #1
0
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
}
Beispiel #2
0
//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
}
Beispiel #3
0
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)
}
Beispiel #4
0
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")
	}
}
Beispiel #5
0
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))
}