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); }
/** * 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; }