in src/ct/parser/tree.go [277:352]
func (n *Node) EvalRelation() (*relation.Relation, error) {
r := relation.New()
left := n.left
right := n.right
if left.val != "V" {
left, right = right, left
}
if left.val != "V" {
return nil, fmt.Errorf("bad or missing variable node: %s, %s", left.val, right.val)
}
r.Name = left.EvalVariable()
r.ID, _ = variables.Get().ID(r.Name)
// Check that the attribute node A exists:
if right == nil || right.val != "A" {
return r, nil
}
m := right
r.Unit = m.EvalUnit()
// Check the left branch of A:
setBound := func(b *relation.Limit, lower bool) {
switch {
case lower:
if r.Lower == nil {
r.Lower = b
}
case !lower:
if r.Upper == nil {
r.Upper = b
}
}
}
left = m.left
switch left.val {
case "E":
nums := m.EvalNums()
r.Value = nums
return r, nil
case "B":
b, lower := left.EvalBound()
setBound(b, lower)
case "L", "Y":
r.Lower = left.EvalRange()
}
// Check the right branch of A:
right = m.right
if right == nil {
return r, nil
}
switch right.val {
case "W":
b, lower := right.right.EvalBound()
setBound(b, lower)
case "B":
b, lower := right.EvalBound()
setBound(b, lower)
case "Y":
r.Upper = right.EvalRange()
}
return r, nil
}