END_TEST


START_TEST (test_FormulaFormatter_formatReal)
{
  StringBuffer_t *sb = StringBuffer_create(42);
  char           *s  = StringBuffer_getBuffer(sb);
  ASTNode_t      *n  = ASTNode_create();


  /** 1.2 **/
  ASTNode_setReal(n, 1.2);
  FormulaFormatter_formatReal(sb, n);

  fail_unless( !strcmp(s, "1.2"), NULL );
  StringBuffer_reset(sb);


  /** 1e-100 **/
  ASTNode_setRealWithExponent(n, 1, -100);
  FormulaFormatter_formatReal(sb, n);

  fail_unless( !strcmp(s, "1.000000e-100"), NULL );
  StringBuffer_reset(sb);



  /** NaN **/
  ASTNode_setReal(n, util_NaN());
  FormulaFormatter_formatReal(sb, n);

  fail_unless( !strcmp(s, "NaN"), NULL );
  StringBuffer_reset(sb);

  /** Inf **/
  ASTNode_setReal(n, util_PosInf());
  FormulaFormatter_formatReal(sb, n);

  fail_unless( !strcmp(s, "INF"), NULL );
  StringBuffer_reset(sb);


  /** -Inf **/
  ASTNode_setReal(n, util_NegInf());
  FormulaFormatter_formatReal(sb, n);

  fail_unless( !strcmp(s, "-INF"), NULL );
  StringBuffer_reset(sb);


  /** -0 **/
  ASTNode_setReal(n, util_NegZero());
  FormulaFormatter_formatReal(sb, n);

  fail_unless( !strcmp(s, "-0"), NULL );
  StringBuffer_reset(sb);


  StringBuffer_free(sb);
  ASTNode_free(n);
}
예제 #2
0
/**
 * Reduces the given stack (containing SLR parser states and ASTNodes) by
 * the given grammar rule.
 */
ASTNode_t *
FormulaParser_reduceStackByRule (Stack_t *stack, long rule)
{
  ASTNode_t *result = NULL;
  ASTNode_t *lexpr, *rexpr, *operator;

  /**
   * Rule  1: Stmt    -> Expr
   * Rule  9: Expr    -> NUMBER
   * Rule 10: Expr    -> NAME
   * Rule 13: OptArgs -> Args
   */
  if (rule == 1 || rule == 9 || rule == 10 || rule == 13)
  {
    Stack_pop(stack);
    result = Stack_pop(stack);

    if (rule == 10)
    {
      /**
       * Convert result to a recognized L2 function constant (if
       * applicable).
       */
      ASTNode_canonicalize(result);
    }
  }

  /**
   * Rule 2: Expr -> Expr PLUS   Expr
   * Rule 3: Expr -> Expr MINUS  Expr
   * Rule 4: Expr -> Expr TIMES  Expr
   * Rule 5: Expr -> Expr DIVIDE Expr
   * Rule 6: Expr -> Expr POWER  Expr
   */
  else if (rule >= 2 && rule <= 6)
  {
    Stack_pop(stack);
    rexpr = Stack_pop(stack);

    Stack_pop(stack);
    operator = Stack_pop(stack);

    Stack_pop(stack);
    lexpr = Stack_pop(stack);

    ASTNode_addChild(operator, lexpr);
    ASTNode_addChild(operator, rexpr);

    result = operator;
  }

  /**
   * Rule 7: Expr -> MINUS Expr
   */
  else if (rule == 7)
  {
    Stack_pop(stack);
    lexpr = Stack_pop(stack);

    Stack_pop(stack);
    operator = Stack_pop(stack);

    /**
     * Perform a simple tree reduction, if possible.
     *
     * If Expr is an AST_INTEGER or AST_REAL (or AST_REAL_E), simply negate
     * the numeric value.  Otheriwse, a (unary) AST_MINUS node should be
     * returned.
     */
    if (ASTNode_getType(lexpr) == AST_INTEGER)
    {
      ASTNode_setInteger(lexpr, - ASTNode_getInteger(lexpr));
      ASTNode_free(operator);
      result = lexpr;
    }
    else if ( ASTNode_getType(lexpr) == AST_REAL)
    {
      ASTNode_setReal(lexpr, - ASTNode_getReal(lexpr));
      ASTNode_free(operator);
      result = lexpr;
    }
    else if (ASTNode_getType(lexpr) == AST_REAL_E)
    {
      ASTNode_setRealWithExponent( lexpr,
                                   - ASTNode_getMantissa(lexpr),
                                     ASTNode_getExponent(lexpr) );
      ASTNode_free(operator);
      result = lexpr;
    }
    else
    {
      ASTNode_addChild(operator, lexpr);
      result = operator;
    }
  }

  /**
   * Rule 8: Expr -> LPAREN Expr RPAREN
   */
  else if (rule == 8)
  {
    Stack_pop(stack);
    ASTNode_free( Stack_pop(stack) );

    Stack_pop(stack);
    result = Stack_pop(stack);

    Stack_pop(stack);
    ASTNode_free( Stack_pop(stack) );
  }

  /**
   * Rule 11: Expr -> NAME LPAREN OptArgs RPAREN
   */
  else if (rule == 11)
  {
    Stack_pop(stack);
    ASTNode_free( Stack_pop(stack) );

    Stack_pop(stack);
    lexpr = Stack_pop(stack);

    Stack_pop(stack);
    ASTNode_free( Stack_pop(stack) );

    Stack_pop(stack);
    result = Stack_pop(stack);
    ASTNode_setType(result, AST_FUNCTION);

    if (lexpr != NULL)
    {
      /**
       * Swap child pointers.  In effect the NAME / AST_FUNCTION
       * represented by result (which has no children) will "adopt" the
       * children of OptArgs which are the arguments to the AST_FUNCTION.
       *
       * After this, OptArgs (lexpr) is no longer needed.
       */
      ASTNode_swapChildren(lexpr, result);
      ASTNode_free(lexpr);
    }

    /**
     * Convert result to a recognized L2 function constant (if applicable).
     */
    ASTNode_canonicalize(result);
  }

  /**
   * Rule 12: OptArgs -> [empty]
   */
  else if (rule == 12)
  {
    result = NULL;
  }

  /**
   * Rule 14: Args -> Expr
   */
  else if (rule == 14)
  {
    Stack_pop(stack);
    lexpr = Stack_pop(stack);


    result = ASTNode_create();
    ASTNode_addChild(result, lexpr);
  }

  /**
   * Rule 15: Args -> Args COMMA Expr
   */
  else if (rule == 15)
  {
    Stack_pop(stack);
    lexpr = Stack_pop(stack);

    Stack_pop(stack);
    ASTNode_free( Stack_pop(stack) );

    Stack_pop(stack);
    result = Stack_pop(stack);

    ASTNode_addChild(result, lexpr);
  }

  return result;
}