/**
 * Visits the given ASTNode as a unary minus.  For this node only the
 * traversal is preorder.
 */
void
L3FormulaFormatter_visitUMinus ( const ASTNode_t *parent,
                                 const ASTNode_t *node,
                                 StringBuffer_t  *sb, 
                                 const L3ParserSettings_t *settings )
{
  //Unary minus is *not* the highest precedence, since it is superceded by 'power'
  unsigned int group;
  
  //If we are supposed to collapse minuses, do so.
  if (L3ParserSettings_getParseCollapseMinus(settings)) {
    if (ASTNode_getNumChildren(node) == 1 &&
        ASTNode_isUMinus(ASTNode_getLeftChild(node))) {
      L3FormulaFormatter_visit(parent, ASTNode_getLeftChild(ASTNode_getLeftChild(node)), sb, settings);
      return;
    }
  }
  
  group = L3FormulaFormatter_isGrouped(parent, node, settings);

  if (group)
  {
    StringBuffer_appendChar(sb, '(');
  }
  StringBuffer_appendChar(sb, '-');
  L3FormulaFormatter_visit ( node, ASTNode_getLeftChild(node), sb, settings);
  if (group)
  {
    StringBuffer_appendChar(sb, ')');
  }
}
/**
 * Visits the given ASTNode, translating the piecewise function
 * to the much simpler 'x % y' format.
 */
void
L3FormulaFormatter_visitModulo ( const ASTNode_t *parent,
                                 const ASTNode_t *node,
                                 StringBuffer_t  *sb, 
                                 const L3ParserSettings_t *settings )
{
  unsigned int group       = L3FormulaFormatter_isGrouped(parent, node, settings);
  const ASTNode_t* subnode = ASTNode_getLeftChild(node);
  if (group)
  {
    StringBuffer_appendChar(sb, '(');
  }

  //Get x and y from the first child of the piecewise function, 
  // then the first child of that (times), and the first child
  // of that (minus).
  L3FormulaFormatter_visit ( subnode, ASTNode_getLeftChild(subnode), sb, settings);
  StringBuffer_appendChar(sb, ' ');
  StringBuffer_appendChar(sb, '%');
  StringBuffer_appendChar(sb, ' ');
  subnode = ASTNode_getRightChild(subnode);
  L3FormulaFormatter_visit ( node, ASTNode_getLeftChild(subnode), sb, settings);

  if (group)
  {
    StringBuffer_appendChar(sb, ')');
  }
}
/**
 * Visits the given ASTNode as a function.  For this node only the
 * traversal is preorder.
 */
void
L3FormulaFormatter_visitFunction ( const ASTNode_t *parent,
                                   const ASTNode_t *node,
                                   StringBuffer_t  *sb, 
                                   const L3ParserSettings_t *settings )
{
  unsigned int numChildren = ASTNode_getNumChildren(node);
  unsigned int n;


  L3FormulaFormatter_format(sb, node, settings);
  StringBuffer_appendChar(sb, '(');

  if (numChildren > 0)
  {
    L3FormulaFormatter_visit( node, ASTNode_getChild(node, 0), sb, settings);
  }

  for (n = 1; n < numChildren; n++)
  {
    StringBuffer_appendChar(sb, ',');
    StringBuffer_appendChar(sb, ' ');
    L3FormulaFormatter_visit( node, ASTNode_getChild(node, n), sb, settings);
  }

  StringBuffer_appendChar(sb, ')');
}
/**
 * Visits the given ASTNode node.  This function is really just a
 * dispatcher to either SBML_formulaToL3String_visitFunction() or
 * SBML_formulaToL3String_visitOther().
 */
void
L3FormulaFormatter_visit ( const ASTNode_t *parent,
                           const ASTNode_t *node,
                           StringBuffer_t  *sb, 
                           const L3ParserSettings_t *settings )
{

  if (ASTNode_isLog10(node))
  {
    L3FormulaFormatter_visitLog10(parent, node, sb, settings);
  }
  else if (ASTNode_isSqrt(node))
  {
    L3FormulaFormatter_visitSqrt(parent, node, sb, settings);
  }
  else if (isTranslatedModulo(node))
  {
    L3FormulaFormatter_visitModulo(parent, node, sb, settings);
  }
  else if (L3FormulaFormatter_isFunction(node, settings))
  {
    L3FormulaFormatter_visitFunction(parent, node, sb, settings);
  }
  else if (ASTNode_isUMinus(node))
  {
    L3FormulaFormatter_visitUMinus(parent, node, sb, settings);
  }
  else if (ASTNode_hasTypeAndNumChildren(node, AST_LOGICAL_NOT, 1))
  {
    L3FormulaFormatter_visitUNot(parent, node, sb, settings);
  }
  else if (ASTNode_hasTypeAndNumChildren(node, AST_QUALIFIER_LOGBASE, 1))
  {
    L3FormulaFormatter_visit(node, ASTNode_getChild(node, 0), sb, settings);
  }
  else if (ASTNode_hasTypeAndNumChildren(node, AST_QUALIFIER_DEGREE, 1))
  {
    L3FormulaFormatter_visit(node, ASTNode_getChild(node, 0), sb, settings);
  }
  else if (ASTNode_hasTypeAndNumChildren(node, AST_SEMANTICS, 1))
  {
    L3FormulaFormatter_visit(node, ASTNode_getChild(node, 0), sb, settings);
  }
  else
  {
    L3FormulaFormatter_visitOther(parent, node, sb, settings);
  }
}
/**
 * Visits the given ASTNode and continues the inorder traversal.
 */
void
L3FormulaFormatter_visitOther ( const ASTNode_t *parent,
                                const ASTNode_t *node,
                                StringBuffer_t  *sb, 
                                const L3ParserSettings_t *settings )
{
  unsigned int numChildren = ASTNode_getNumChildren(node);
  unsigned int group       = L3FormulaFormatter_isGrouped(parent, node, settings);
  unsigned int n;


  if (group)
  {
    StringBuffer_appendChar(sb, '(');
  }

  if (numChildren == 0) {
    L3FormulaFormatter_format(sb, node, settings);
  }

  else if (numChildren == 1)
  {
    //I believe this would only be called for invalid ASTNode setups,
    // but this could in theory occur.  This is the safest 
    // behavior I can think of.
    L3FormulaFormatter_format(sb, node, settings);
    StringBuffer_appendChar(sb, '(');
    L3FormulaFormatter_visit( node, ASTNode_getChild(node, 0), sb, settings);
    StringBuffer_appendChar(sb, ')');
  }

  else {
    L3FormulaFormatter_visit( node, ASTNode_getChild(node, 0), sb, settings);

    for (n = 1; n < numChildren; n++)
    {
      L3FormulaFormatter_format(sb, node, settings);
      L3FormulaFormatter_visit( node, ASTNode_getChild(node, n), sb, settings);
    }
  }

  if (group)
  {
    StringBuffer_appendChar(sb, ')');
  }
}
/**
 * Visits the given ASTNode as the function "root(2, x)" and in doing so,
 * formats it as "sqrt(x)" (where x is any subexpression).
 */
void
L3FormulaFormatter_visitSqrt ( const ASTNode_t *parent,
                               const ASTNode_t *node,
                               StringBuffer_t  *sb, 
                               const L3ParserSettings_t *settings )
{
  StringBuffer_append(sb, "sqrt(");
  L3FormulaFormatter_visit(node, ASTNode_getChild(node, 1), sb, settings);
  StringBuffer_appendChar(sb, ')');
}
LIBSBML_EXTERN
char *
SBML_formulaToL3StringWithSettings (const ASTNode_t *tree, const L3ParserSettings_t *settings)
{
  char           *s;
  StringBuffer_t *sb = StringBuffer_create(128);

  if (tree == NULL)
  {
    return NULL;
  }

  L3FormulaFormatter_visit(NULL, tree, sb, settings);
  s = StringBuffer_getBuffer(sb);
  safe_free(sb);
  return s;
}
/**
 * Visits the given ASTNode as a unary not.
 */
void
L3FormulaFormatter_visitUNot ( const ASTNode_t *parent,
                               const ASTNode_t *node,
                               StringBuffer_t  *sb, 
                               const L3ParserSettings_t *settings )
{
  //Unary not is also not the highest precedence, since it is superceded by 'power'
  unsigned int group       = L3FormulaFormatter_isGrouped(parent, node, settings);

  if (group)
  {
    StringBuffer_appendChar(sb, '(');
  }
  StringBuffer_appendChar(sb, '!');
  L3FormulaFormatter_visit ( node, ASTNode_getLeftChild(node), sb, settings);
  if (group)
  {
    StringBuffer_appendChar(sb, ')');
  }
}
Exemple #9
0
END_TEST

START_TEST (test_L3FormulaFormatter_accessWithNULL)
{

  // ensure we survive NULL arguments
  L3FormulaFormatter_format(NULL, NULL, NULL);
  L3FormulaFormatter_formatFunction(NULL, NULL, NULL);
  L3FormulaFormatter_formatOperator(NULL, NULL);
  L3FormulaFormatter_visit(NULL, NULL, NULL, NULL);
  L3FormulaFormatter_visitFunction(NULL, NULL, NULL, NULL);
  L3FormulaFormatter_visitLog10(NULL, NULL, NULL, NULL);
  L3FormulaFormatter_visitOther(NULL, NULL, NULL, NULL);
  L3FormulaFormatter_visitSqrt(NULL, NULL, NULL, NULL);
  L3FormulaFormatter_visitUMinus(NULL, NULL, NULL, NULL);

  fail_unless( L3FormulaFormatter_isFunction(NULL, NULL) == 0 );
  fail_unless( L3FormulaFormatter_isGrouped(NULL, NULL, NULL) == 0 );
  fail_unless( SBML_formulaToL3String(NULL) == NULL );
  
}