END_TEST START_TEST (test_Rule_setMath1) { ASTNode_t *math = ASTNode_createWithType(AST_TIMES); ASTNode_t *a = ASTNode_create(); ASTNode_t *b = ASTNode_create(); ASTNode_setName(a, "a"); ASTNode_setName(b, "b"); ASTNode_addChild(math, a); ASTNode_addChild(math, b); char *formula; const ASTNode_t *math1; int i = Rule_setMath(R, math); fail_unless( i == LIBSBML_OPERATION_SUCCESS); fail_unless( Rule_isSetMath(R) ); math1 = Rule_getMath(R); fail_unless( math1 != NULL ); formula = SBML_formulaToString(math1); fail_unless( formula != NULL ); fail_unless( !strcmp(formula, "a * b") ); ASTNode_free(math); }
END_TEST START_TEST (test_L3FormulaFormatter_multiAnd) { StringBuffer_t *sb = StringBuffer_create(42); char *s = StringBuffer_getBuffer(sb); ASTNode_t *n = ASTNode_create(); ASTNode_t *c = ASTNode_create(); ASTNode_setType(n, AST_LOGICAL_AND); s = SBML_formulaToL3String(n); fail_unless( !strcmp(s, "and()"), NULL ); ASTNode_setName(c, "x"); ASTNode_addChild(n, c); s = SBML_formulaToL3String(n); fail_unless( !strcmp(s, "and(x)"), NULL ); safe_free(s); c = ASTNode_create(); ASTNode_setName(c, "y"); ASTNode_addChild(n, c); s = SBML_formulaToL3String(n); fail_unless( !strcmp(s, "x && y"), NULL ); safe_free(s); c = ASTNode_create(); ASTNode_setName(c, "z"); ASTNode_addChild(n, c); s = SBML_formulaToL3String(n); fail_unless( !strcmp(s, "x && y && z"), NULL ); safe_free(s); ASTNode_free(n); }
END_TEST START_TEST (test_FormulaFormatter_multiPlusTimes) { StringBuffer_t *sb = StringBuffer_create(42); char *s = StringBuffer_getBuffer(sb); ASTNode_t *n = ASTNode_create(); ASTNode_t *c = ASTNode_create(); ASTNode_setType(n, AST_PLUS); ASTNode_setName(c, "x"); ASTNode_addChild(n, c); c = ASTNode_create(); ASTNode_setName(c, "y"); ASTNode_addChild(n, c); c = ASTNode_create(); ASTNode_setName(c, "z"); ASTNode_addChild(n, c); s = SBML_formulaToString(n); fail_unless( !strcmp(s, "x + y + z"), NULL ); ASTNode_setType(n, AST_TIMES); s = SBML_formulaToString(n); fail_unless( !strcmp(s, "x * y * z"), NULL ); safe_free(s); ASTNode_free(n); }
END_TEST START_TEST (test_FormulaFormatter_multiDivide) { StringBuffer_t *sb = StringBuffer_create(42); char *s = StringBuffer_getBuffer(sb); ASTNode_t *n = ASTNode_create(); ASTNode_t *c = ASTNode_create(); ASTNode_setType(n, AST_DIVIDE); s = SBML_formulaToString(n); fail_unless( !strcmp(s, " / "), NULL ); ASTNode_setName(c, "x"); ASTNode_addChild(n, c); s = SBML_formulaToString(n); fail_unless( !strcmp(s, " / (x)"), NULL ); safe_free(s); c = ASTNode_create(); ASTNode_setName(c, "y"); ASTNode_addChild(n, c); s = SBML_formulaToString(n); fail_unless( !strcmp(s, "x / y"), NULL ); safe_free(s); c = ASTNode_create(); ASTNode_setName(c, "z"); ASTNode_addChild(n, c); s = SBML_formulaToString(n); fail_unless( !strcmp(s, "x / y / z"), NULL ); safe_free(s); ASTNode_free(n); }
END_TEST START_TEST (test_SpeciesReference_setStoichiometryMath5) { SpeciesReference_t *sr1 = SpeciesReference_create(1, 2); StoichiometryMath_t * sm = StoichiometryMath_create(2, 4); ASTNode_t *math = ASTNode_createWithType(AST_TIMES); ASTNode_t *a = ASTNode_create(); ASTNode_t *b = ASTNode_create(); ASTNode_setName(a, "a"); ASTNode_setName(b, "b"); ASTNode_addChild(math, a); ASTNode_addChild(math, b); StoichiometryMath_setMath(sm, math); int i = SpeciesReference_setStoichiometryMath(sr1, sm); fail_unless( i == LIBSBML_UNEXPECTED_ATTRIBUTE); fail_unless( !SpeciesReference_isSetStoichiometryMath(sr1) ); StoichiometryMath_free(sm); SpeciesReference_free(sr1); }
END_TEST START_TEST (test_SpeciesReference_setStoichiometryMath1) { StoichiometryMath_t * sm = StoichiometryMath_create(2, 4); ASTNode_t *math = ASTNode_createWithType(AST_TIMES); ASTNode_t *a = ASTNode_create(); ASTNode_t *b = ASTNode_create(); ASTNode_setName(a, "a"); ASTNode_setName(b, "b"); ASTNode_addChild(math, a); ASTNode_addChild(math, b); StoichiometryMath_setMath(sm, math); int i = SpeciesReference_setStoichiometryMath(sr, sm); fail_unless( i == LIBSBML_OPERATION_SUCCESS); fail_unless( SpeciesReference_isSetStoichiometryMath(sr) ); fail_unless( SpeciesReference_getStoichiometry(sr) == 1 ); i = SpeciesReference_unsetStoichiometryMath(sr); fail_unless( i == LIBSBML_OPERATION_SUCCESS); fail_unless( !SpeciesReference_isSetStoichiometryMath(sr) ); StoichiometryMath_free(sm); }
END_TEST START_TEST (test_FormulaFormatter_multiAnd) { char *s; ASTNode_t *n = ASTNode_create(); ASTNode_t *c = ASTNode_create(); ASTNode_setType(n, AST_LOGICAL_AND); s = SBML_formulaToString(n); fail_unless( !strcmp(s, "and()"), NULL ); safe_free(s); ASTNode_setName(c, "x"); ASTNode_addChild(n, c); s = SBML_formulaToString(n); fail_unless( !strcmp(s, "and(x)"), NULL ); safe_free(s); c = ASTNode_create(); ASTNode_setName(c, "y"); ASTNode_addChild(n, c); s = SBML_formulaToString(n); fail_unless( !strcmp(s, "and(x, y)"), NULL ); safe_free(s); c = ASTNode_create(); ASTNode_setName(c, "z"); ASTNode_addChild(n, c); s = SBML_formulaToString(n); fail_unless( !strcmp(s, "and(x, y, z)"), NULL ); safe_free(s); ASTNode_free(n); }
END_TEST START_TEST (test_FormulaFormatter_multiPlus) { char *s; ASTNode_t *n = ASTNode_create(); ASTNode_t *c = ASTNode_create(); ASTNode_setType(n, AST_PLUS); s = SBML_formulaToString(n); fail_unless( !strcmp(s, "0"), NULL ); safe_free(s); ASTNode_setName(c, "x"); ASTNode_addChild(n, c); s = SBML_formulaToString(n); fail_unless( !strcmp(s, "x"), NULL ); safe_free(s); c = ASTNode_create(); ASTNode_setName(c, "y"); ASTNode_addChild(n, c); s = SBML_formulaToString(n); fail_unless( !strcmp(s, "x + y"), NULL ); safe_free(s); c = ASTNode_create(); ASTNode_setName(c, "z"); ASTNode_addChild(n, c); s = SBML_formulaToString(n); fail_unless( !strcmp(s, "x + y + z"), NULL ); safe_free(s); ASTNode_free(n); }
END_TEST START_TEST (test_L3FormulaFormatter_multiGT) { StringBuffer_t *sb = StringBuffer_create(42); char *s = StringBuffer_getBuffer(sb); ASTNode_t *n = ASTNode_create(); ASTNode_t *c = ASTNode_create(); ASTNode_setType(n, AST_RELATIONAL_GT); s = SBML_formulaToL3String(n); fail_unless( !strcmp(s, "gt()"), NULL ); ASTNode_setName(c, "x"); ASTNode_addChild(n, c); s = SBML_formulaToL3String(n); fail_unless( !strcmp(s, "gt(x)"), NULL ); safe_free(s); c = ASTNode_create(); ASTNode_setName(c, "y"); ASTNode_addChild(n, c); s = SBML_formulaToL3String(n); fail_unless( !strcmp(s, "x > y"), NULL ); safe_free(s); c = ASTNode_create(); ASTNode_setName(c, "z"); ASTNode_addChild(n, c); s = SBML_formulaToL3String(n); fail_unless( !strcmp(s, "gt(x, y, z)"), NULL ); safe_free(s); ASTNode_free(n); }
END_TEST START_TEST (test_FormulaFormatter_multiOr) { StringBuffer_t *sb = StringBuffer_create(42); char *s = StringBuffer_getBuffer(sb); ASTNode_t *n = ASTNode_create(); ASTNode_t *c = ASTNode_create(); ASTNode_setType(n, AST_LOGICAL_OR); s = SBML_formulaToString(n); fail_unless( !strcmp(s, "or()"), NULL ); ASTNode_setName(c, "x"); ASTNode_addChild(n, c); s = SBML_formulaToString(n); fail_unless( !strcmp(s, "or(x)"), NULL ); safe_free(s); c = ASTNode_create(); ASTNode_setName(c, "y"); ASTNode_addChild(n, c); s = SBML_formulaToString(n); fail_unless( !strcmp(s, "or(x, y)"), NULL ); safe_free(s); c = ASTNode_create(); ASTNode_setName(c, "z"); ASTNode_addChild(n, c); s = SBML_formulaToString(n); fail_unless( !strcmp(s, "or(x, y, z)"), NULL ); safe_free(s); ASTNode_free(n); }
LIBSBML_CPP_NAMESPACE_USE CK_CPPSTART #endif START_TEST (test_L3FormulaFormatter_isFunction) { ASTNode_t *n = ASTNode_create(); ASTNode_t *c = ASTNode_create(); ASTNode_setType(n, AST_NAME); fail_unless( L3FormulaFormatter_isFunction(n, NULL) == 0, NULL ); ASTNode_setType(n, AST_CONSTANT_PI); fail_unless( L3FormulaFormatter_isFunction(n, NULL) == 0, NULL ); ASTNode_setType(n, AST_LAMBDA); fail_unless( L3FormulaFormatter_isFunction(n, NULL) == 1, NULL ); ASTNode_setType(n, AST_FUNCTION); fail_unless( L3FormulaFormatter_isFunction(n, NULL) == 1, NULL ); ASTNode_setType(n, AST_LOGICAL_AND); fail_unless( L3FormulaFormatter_isFunction(n, NULL) == 1, NULL ); ASTNode_setType(n, AST_RELATIONAL_EQ); fail_unless( L3FormulaFormatter_isFunction(n, NULL) == 1, NULL ); ASTNode_setType(n, AST_PLUS); fail_unless( L3FormulaFormatter_isFunction(n, NULL) == 1, NULL ); ASTNode_addChild(n, c); ASTNode_setType(n, AST_LOGICAL_AND); fail_unless( L3FormulaFormatter_isFunction(n, NULL) == 1, NULL ); ASTNode_setType(n, AST_RELATIONAL_EQ); fail_unless( L3FormulaFormatter_isFunction(n, NULL) == 1, NULL ); ASTNode_setType(n, AST_PLUS); fail_unless( L3FormulaFormatter_isFunction(n, NULL) == 1, NULL ); c = ASTNode_create(); ASTNode_addChild(n, c); ASTNode_setType(n, AST_LOGICAL_AND); fail_unless( L3FormulaFormatter_isFunction(n, NULL) == 0, NULL ); ASTNode_setType(n, AST_RELATIONAL_EQ); fail_unless( L3FormulaFormatter_isFunction(n, NULL) == 0, NULL ); ASTNode_setType(n, AST_PLUS); fail_unless( L3FormulaFormatter_isFunction(n, NULL) == 0, NULL ); ASTNode_free(n); }
END_TEST START_TEST (test_L3FormulaFormatter_parseUnits) { StringBuffer_t *sb = StringBuffer_create(42); char *s = StringBuffer_getBuffer(sb); ASTNode_t *n = ASTNode_create(); L3ParserSettings_t* l3ps = L3ParserSettings_create(); ASTNode_setReal(n, 1.1); ASTNode_setUnits(n, "mL"); //default (true) s = SBML_formulaToL3StringWithSettings(n, l3ps); fail_unless( !strcmp(s, "1.1 mL"), NULL ); safe_free(s); //explicit false L3ParserSettings_setParseUnits(l3ps, 0); s = SBML_formulaToL3StringWithSettings(n, l3ps); fail_unless( !strcmp(s, "1.1"), NULL ); safe_free(s); //explicit true L3ParserSettings_setParseUnits(l3ps, 1); s = SBML_formulaToL3StringWithSettings(n, l3ps); fail_unless( !strcmp(s, "1.1 mL"), NULL ); safe_free(s); ASTNode_free(n); L3ParserSettings_free(l3ps); }
END_TEST START_TEST (test_L3FormulaFormatter_collapseMinus) { StringBuffer_t *sb = StringBuffer_create(42); char *s = StringBuffer_getBuffer(sb); ASTNode_t *n = ASTNode_create(); ASTNode_t *c = ASTNode_create(); ASTNode_t *c2 = ASTNode_create(); ASTNode_t *c3 = ASTNode_create(); ASTNode_t *c4 = ASTNode_create(); L3ParserSettings_t* l3ps = L3ParserSettings_create(); ASTNode_setType(n, AST_MINUS); ASTNode_setType(c, AST_MINUS); ASTNode_addChild(n, c); ASTNode_setType(c2, AST_MINUS); ASTNode_addChild(c, c2); ASTNode_setType(c3, AST_MINUS); ASTNode_addChild(c2, c3); ASTNode_setName(c4, "x"); ASTNode_addChild(c3, c4); //default (false) s = SBML_formulaToL3StringWithSettings(n, l3ps); fail_unless( !strcmp(s, "----x"), NULL ); safe_free(s); //explicit false L3ParserSettings_setParseCollapseMinus(l3ps, 0); s = SBML_formulaToL3StringWithSettings(n, l3ps); fail_unless( !strcmp(s, "----x"), NULL ); safe_free(s); //explicit true L3ParserSettings_setParseCollapseMinus(l3ps, 1); s = SBML_formulaToL3StringWithSettings(n, l3ps); fail_unless( !strcmp(s, "x"), NULL ); safe_free(s); ASTNode_free(n); L3ParserSettings_free(l3ps); }
END_TEST START_TEST (test_KineticLaw_setMath2) { ASTNode_t *math = ASTNode_createWithType(AST_TIMES); ASTNode_t *a = ASTNode_create(); ASTNode_setName(a, "a"); ASTNode_addChild(math, a); int i = KineticLaw_setMath(kl, math); fail_unless( i == LIBSBML_INVALID_OBJECT); fail_unless( !KineticLaw_isSetMath(kl) ); ASTNode_free(math); }
END_TEST START_TEST (test_Rule_setMath2) { ASTNode_t *math = ASTNode_createWithType(AST_DIVIDE); ASTNode_t *a = ASTNode_create(); ASTNode_setName(a, "a"); ASTNode_addChild(math, a); int i = Rule_setMath(R, math); fail_unless( i == LIBSBML_INVALID_OBJECT); fail_unless( !Rule_isSetMath(R) ); ASTNode_free(math); }
END_TEST START_TEST (test_FormulaFormatter_formatRational) { StringBuffer_t *sb = StringBuffer_create(10); ASTNode_t *n = ASTNode_create(); char *s; ASTNode_setRational(n, 1, 2); FormulaFormatter_formatRational(sb, n); s = StringBuffer_toString(sb); fail_unless( !strcmp(s, "(1/2)"), NULL ); safe_free(s); ASTNode_free(n); StringBuffer_free(sb); }
END_TEST START_TEST (test_SpeciesReference_setStoichiometryMath2) { StoichiometryMath_t * sm = StoichiometryMath_create(2, 4); ASTNode_t *math = ASTNode_createWithType(AST_TIMES); ASTNode_t *a = ASTNode_create(); ASTNode_setName(a, "a"); ASTNode_addChild(math, a); StoichiometryMath_setMath(sm, math); int i = SpeciesReference_setStoichiometryMath(sr, sm); /* once the StoichiometryMath_setMath function does not set * an invalid ASTNode this changes to i == LIBSBML_OPERATION_SUCCESS fail_unless( i == LIBSBML_INVALID_OBJECT); */ fail_unless ( i == LIBSBML_OPERATION_SUCCESS ); fail_unless( SpeciesReference_isSetStoichiometryMath(sr) ); StoichiometryMath_free(sm); }
END_TEST START_TEST (test_FormulaFormatter_isGrouped) { ASTNode_t *p = ASTNode_create(); ASTNode_t *c; /** Empty parent, p is the root of the tree. **/ fail_unless( FormulaFormatter_isGrouped(NULL, p) == 0, NULL ); ASTNode_free(p); /** "1 + 2 * 3" **/ p = SBML_parseFormula("1 + 2 * 3"); c = ASTNode_getLeftChild(p); fail_unless( FormulaFormatter_isGrouped(p, c) == 0, NULL ); c = ASTNode_getRightChild(p); fail_unless( FormulaFormatter_isGrouped(p, c) == 0, NULL ); ASTNode_free(p); /** "(1 + 2) * 3" **/ p = SBML_parseFormula("(1 + 2) * 3"); c = ASTNode_getLeftChild(p); fail_unless( FormulaFormatter_isGrouped(p, c) == 1, NULL ); c = ASTNode_getRightChild(p); fail_unless( FormulaFormatter_isGrouped(p, c) == 0, NULL ); ASTNode_free(p); /** * "1 + (2 * 3)": * * In this case, explicit grouping is not needed due to operator * precedence rules. */ p = SBML_parseFormula("1 + (2 * 3)"); c = ASTNode_getLeftChild(p); fail_unless( FormulaFormatter_isGrouped(p, c) == 0, NULL ); c = ASTNode_getRightChild(p); fail_unless( FormulaFormatter_isGrouped(p, c) == 0, NULL ); ASTNode_free(p); /** * "foo(1 + 2, 2 * 3)": * * The parent node foo has higher precedence than its children, but * grouping is not nescessary since foo is a function. */ p = SBML_parseFormula("foo(1 + 2, 2 * 3)"); c = ASTNode_getLeftChild(p); fail_unless( FormulaFormatter_isGrouped(p, c) == 0, NULL ); c = ASTNode_getRightChild(p); fail_unless( FormulaFormatter_isGrouped(p, c) == 0, NULL ); ASTNode_free(p); /** * "(a / b) * c": * * In this case, explicit grouping is not needed due to associativity * rules. */ p = SBML_parseFormula("(a / b) * c"); c = ASTNode_getLeftChild(p); fail_unless( FormulaFormatter_isGrouped(p, c) == 0, NULL ); c = ASTNode_getRightChild(p); fail_unless( FormulaFormatter_isGrouped(p, c) == 0, NULL ); ASTNode_free(p); /** * "a / (b * c)": * * In this case, explicit grouping is needed. The operators / and * have * the same precedence, but the parenthesis modifies the associativity. */ p = SBML_parseFormula("a / (b * c)"); c = ASTNode_getLeftChild(p); fail_unless( FormulaFormatter_isGrouped(p, c) == 0, NULL ); c = ASTNode_getRightChild(p); fail_unless( FormulaFormatter_isGrouped(p, c) == 1, NULL ); ASTNode_free(p); /** * "a - (b - c)": * * Rainer Machne reported that the above parsed correctly, but was not * formatted correctly. * * The bug was in FormulaFormatter_isGrouped(). While it was correctly * handling parent and child ASTNodes of the same precedence, it was not * handling the special subcase where parent and child nodes were the * same operator. For grouping, this only matters for the subtraction * and division operators, as they are not associative. * * An exhaustive set of eight tests follow. */ p = SBML_parseFormula("a - (b - c)"); c = ASTNode_getLeftChild(p); fail_unless( FormulaFormatter_isGrouped(p, c) == 0, NULL ); c = ASTNode_getRightChild(p); fail_unless( FormulaFormatter_isGrouped(p, c) == 1, NULL ); ASTNode_free(p); p = SBML_parseFormula("a - b - c"); c = ASTNode_getLeftChild(p); fail_unless( FormulaFormatter_isGrouped(p, c) == 0, NULL ); c = ASTNode_getRightChild(p); fail_unless( FormulaFormatter_isGrouped(p, c) == 0, NULL ); ASTNode_free(p); p = SBML_parseFormula("a + (b + c)"); c = ASTNode_getLeftChild(p); fail_unless( FormulaFormatter_isGrouped(p, c) == 0, NULL ); c = ASTNode_getRightChild(p); fail_unless( FormulaFormatter_isGrouped(p, c) == 0, NULL ); ASTNode_free(p); p = SBML_parseFormula("a + b + c"); c = ASTNode_getLeftChild(p); fail_unless( FormulaFormatter_isGrouped(p, c) == 0, NULL ); c = ASTNode_getRightChild(p); fail_unless( FormulaFormatter_isGrouped(p, c) == 0, NULL ); ASTNode_free(p); p = SBML_parseFormula("a * (b * c)"); c = ASTNode_getLeftChild(p); fail_unless( FormulaFormatter_isGrouped(p, c) == 0, NULL ); c = ASTNode_getRightChild(p); fail_unless( FormulaFormatter_isGrouped(p, c) == 0, NULL ); ASTNode_free(p); p = SBML_parseFormula("a * b * c"); c = ASTNode_getLeftChild(p); fail_unless( FormulaFormatter_isGrouped(p, c) == 0, NULL ); c = ASTNode_getRightChild(p); fail_unless( FormulaFormatter_isGrouped(p, c) == 0, NULL ); ASTNode_free(p); p = SBML_parseFormula("a / (b / c)"); c = ASTNode_getLeftChild(p); fail_unless( FormulaFormatter_isGrouped(p, c) == 0, NULL ); c = ASTNode_getRightChild(p); fail_unless( FormulaFormatter_isGrouped(p, c) == 1, NULL ); ASTNode_free(p); p = SBML_parseFormula("a / b / c"); c = ASTNode_getLeftChild(p); fail_unless( FormulaFormatter_isGrouped(p, c) == 0, NULL ); c = ASTNode_getRightChild(p); fail_unless( FormulaFormatter_isGrouped(p, c) == 0, NULL ); ASTNode_free(p); }
/** * 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; }
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); }
void ev_alter_tree_structure(Model_t *m, ASTNode_t **node_p, ASTNode_t *parent, int child_order, copied_AST *cp_AST){ ASTNode_t *zero_node; ASTNode_t *node, *next_node; ASTNode_t *pc_eq, *pc_cd, *times_node, *and_node, *not_node; unsigned int i, j; int p; ASTNode_t *arg_node_list[MAX_ARG_NUM]; unsigned int arg_node_num; FunctionDefinition_t *fd; ASTNode_t *fd_arg; ASTNode_t *fd_body; node = *node_p; for(i=0; i<ASTNode_getNumChildren(node); i++){ next_node = ASTNode_getChild(node, i); if(ASTNode_getNumChildren(node) == 1 && ASTNode_getType(node) == AST_MINUS){ zero_node = ASTNode_create(); ASTNode_setType(zero_node, AST_REAL); ASTNode_setReal(zero_node, 0); ASTNode_replaceChild(node, 0, zero_node); ASTNode_addChild(*node_p, next_node); }else{ ev_alter_tree_structure(m, &next_node, *node_p, i, cp_AST); } } if(ASTNode_getType(node) == AST_FUNCTION){ arg_node_num = ASTNode_getNumChildren(node); for(i=0; i<arg_node_num; i++){ arg_node_list[i] = ASTNode_getChild(node, i); } for(i=0; i<Model_getNumFunctionDefinitions(m); i++){ fd = (FunctionDefinition_t*)ListOf_get(Model_getListOfFunctionDefinitions(m), i); fd_body = (ASTNode_t*)FunctionDefinition_getBody(fd); if(strcmp(FunctionDefinition_getId(fd), ASTNode_getName(node)) == 0){ fd_body = ASTNode_deepCopy(fd_body); cp_AST->ast[cp_AST->num_of_copied_AST++] = fd_body; for(j=0; j<FunctionDefinition_getNumArguments(fd); j++){ fd_arg = (ASTNode_t*)FunctionDefinition_getArgument(fd, j); ASTNode_replaceArgument(fd_body, (char*)ASTNode_getName(fd_arg), arg_node_list[j]); } /* check_AST(fd_body, NULL); */ if(parent != NULL){ ASTNode_replaceChild(parent, child_order, fd_body); }else{ *node_p = fd_body; } node = *node_p; break; } } } if(ASTNode_getType(node) == AST_FUNCTION_PIECEWISE){ ASTNode_setType(node, AST_PLUS); ASTNode_setName(node, NULL); times_node = ASTNode_createWithType(AST_TIMES); pc_eq = ASTNode_getRightChild(node); ASTNode_addChild(times_node, pc_eq); if(ASTNode_getNumChildren(node) > 3){ and_node = ASTNode_createWithType(AST_LOGICAL_AND); ASTNode_addChild(times_node, and_node); for(p=(int)ASTNode_getNumChildren(node)-2; p >= 1; p = p-2){ pc_cd = ASTNode_getChild(node, p); not_node = ASTNode_createWithType(AST_LOGICAL_NOT); ASTNode_addChild(not_node, pc_cd); ASTNode_addChild(and_node, not_node); } ASTNode_reduceToBinary(and_node); }else{ pc_cd = ASTNode_getChild(node, 1); not_node = ASTNode_createWithType(AST_LOGICAL_NOT); ASTNode_addChild(not_node, pc_cd); ASTNode_addChild(times_node, not_node); } ASTNode_replaceChild(node, ASTNode_getNumChildren(node)-1, times_node); for(p=ASTNode_getNumChildren(node)-2; p >= 1; p = p-2){ times_node = ASTNode_createWithType(AST_TIMES); pc_eq = ASTNode_getChild(node, p-1); pc_cd = ASTNode_getChild(node, p); ASTNode_addChild(times_node, pc_eq); ASTNode_addChild(times_node, ASTNode_deepCopy(pc_cd)); ASTNode_removeChild(node, p); ASTNode_replaceChild(node ,p-1, times_node); } ASTNode_reduceToBinary(node); } return; }