/**
  * Avalia a expressão e retorna o seu valor (resolve a expessão)
  * @param TreeNode|TreeLeaf $treeNode Arvore que será analizada
  * @return float|int|null Resultado da expressão
  */
 public function evaluate($treeNode = null)
 {
     $result = null;
     if ($treeNode == null) {
         $result = $this->treeNode == null ? 0 : $this->evaluate($this->treeNode);
     } else {
         if ($treeNode instanceof TreeLeaf) {
             /**
              * SE é uma folha, então so tem o valor numérico
              */
             $result = $treeNode->getValue();
         } else {
             /**
              * Aqui é nó binário, então existe o lado esquerdo, direito e o operador
              */
             $operator = $treeNode->getOperator();
             /**
              * Chama recursivamente cada lado do nó (que podem ser outros nós)
              */
             $valueLeft = $this->evaluate($treeNode->getLeft());
             $valueRight = $this->evaluate($treeNode->getRight());
             /**
              * Executa as operações
              */
             switch ($operator) {
                 case '+':
                     $result = $valueLeft + $valueRight;
                     break;
                 case '-':
                     $result = $valueLeft - $valueRight;
                     break;
                 case '*':
                     $result = $valueLeft * $valueRight;
                     break;
                 case '/':
                     $result = $valueLeft / $valueRight;
                     break;
                 case '^':
                     $result = $valueLeft ^ $valueRight;
                     break;
             }
         }
     }
     return $result;
 }
 public function testTreeLeafRelationships()
 {
     /* structure:
      *
      * o1
      *  -> o2
      *  -> o3
      *
      * o4
      *
      * thus it would be expected that o1 has 2 children and o4 is a
      * leaf with no parents or children.
      */
     $o1 = new TreeLeaf();
     $o1->name = 'o1';
     $o1->save();
     $o2 = new TreeLeaf();
     $o2->name = 'o2';
     $o2->Parent = $o1;
     $o2->save();
     $o3 = new TreeLeaf();
     $o3->name = 'o3';
     $o3->Parent = $o1;
     $o3->save();
     //$o1->refresh();
     $o4 = new TreeLeaf();
     $o4->name = 'o4';
     $o4->save();
     $this->assertFalse(isset($o1->Parent));
     $this->assertTrue(isset($o2->Parent));
     $this->assertTrue($o2->Parent === $o1);
     $this->assertFalse(isset($o4->Parent));
     $this->assertTrue(count($o1->Children) == 2);
     $this->assertTrue(count($o1->get('Children')) == 2);
     $this->assertTrue(count($o4->Children) == 0);
 }