/** File pars_tree.c
 */

#include <stdlib.h>

#include "defines.h"
#include "utils.h"

#include "parser.h"
#include "pars_tree.h"

static int depth = 0;


 ParsTreeNode *ptree_init (void)
{
 return ptree_node_new (PTREE_ROOT);
}

ParsTreeNode *ptree_node_new (ParsTreeNodeType typ)
{
  ParsTreeNode *retval;
  retval = malloc (sizeof (ParsTreeNode));
  retval->typ 	  = typ;
  retval->elder	  = NULL;
  retval->brother = NULL;
  retval->child   = NULL;
  retval->cmd 	  = NULL;
  return retval;
}


ParsTreeNode *ptree_child_append (ParsTreeNode *node ,ParsTreeNodeType typ ,char *cmd)
{
  ParsTreeNode *retval = ptree_node_new (typ);
  retval->elder	  = node;
  node->child     = retval;
  retval->cmd 	  = copy_string (NULL ,cmd);
  depth++;
  return retval;
}

ParsTreeNode *ptree_brother_append (ParsTreeNode *node ,ParsTreeNodeType typ ,char *cmd)
{
  ParsTreeNode *retval = ptree_node_new (typ);
  retval->elder	  = node;
  node->brother   = retval;
  retval->cmd 	  = copy_string (NULL ,cmd);
  return retval;
}


int ptree_node_free (ParsTreeNode *node)
{
  if (node->brother != NULL || node->child != NULL) {
    errmsg ("Trying to free a non terminal parser tree node");
    return RETURN_FAILURE;
  }
  ParsTreeNode *elder = node->elder;
  if (node == elder->child) depth--;
  xfree (node->cmd);
  xfree (node);
  return RETURN_SUCCESS;
}

ParsTreeNode *ptree_if_begin (ParsTreeNode *node)
{
  ParsTreeNode *retval = ptree_child_append (node ,PTREE_IF_BEGIN ,NULL);

  // puts parser in PARSER_TYPE_PUSH mode

  return retval;
}

int ptree_brace_close (ParsTreeNode *node)
{
  ParsTreeNode *nd ,*nde;
  nd = node;
  int block_depth = depth;
  while (depth == block_depth) {
    nde = nd->elder;

    // needs parser reantrancy ... ??
    //    if (parser (nde->cmd ,PARSER_TYPE_VOID)    != RETURN_SUCCESS) return RETURN_FAILURE;
    if (ptree_node_free (nd)  != RETURN_SUCCESS) return RETURN_FAILURE;
    nd = nde;
  }
  return RETURN_SUCCESS;
}

