+void CheckBoolExpr (ExprDesc* lval)
+/* Check if the given expression is a boolean expression, output a diagnostic
+ * if not.
+ */
+{
+ /* If it's an integer, it's ok. If it's not an integer, but a pointer,
+ * the pointer used in a boolean context is also ok
+ */
+ if (!IsClassInt (lval->Type) && !IsClassPtr (lval->Type)) {
+ Error ("Boolean expression expected");
+ /* To avoid any compiler errors, make the expression a valid int */
+ MakeConstIntExpr (lval, 1);
+ }
+}
+
+
+
/*****************************************************************************/
/* code */
/*****************************************************************************/
-void boolexpr (ExprDesc* lval)
-/* Get a boolean expression */
-{
- /* Read an expression */
- expression (lval);
-
- /* If it's an integer, it's ok. If it's not an integer, but a pointer,
- * the pointer used in a boolean context is also ok
- */
- if (!IsClassInt (lval->Type) && !IsClassPtr (lval->Type)) {
- Error ("Boolean expression expected");
- /* To avoid any compiler errors, make the expression a valid int */
- MakeConstIntExpr (lval, 1);
- }
-}
-
-
-
-void test (unsigned label, int cond)
-/* Generate code to perform test and jump if false. */
+void Test (unsigned Label, int Invert)
+/* Evaluate a boolean test expression and jump depending on the result of
+ * the test and on Invert.
+ */
{
int k;
ExprDesc lval;
- /* Eat the parenthesis */
- ConsumeLParen ();
-
- /* Prepare the expression, setup labels */
+ /* Evaluate the expression */
memset (&lval, 0, sizeof (lval));
-
- /* Generate code to eval the expr */
k = expr (hie0, &lval);
+
+ /* Check for a boolean expression */
+ CheckBoolExpr (&lval);
+
+ /* Check for a constant expression */
if (k == 0 && lval.Flags == E_MCONST) {
+
/* Constant rvalue */
- if (cond == 0 && lval.ConstVal == 0) {
- g_jump (label);
+ if (!Invert && lval.ConstVal == 0) {
+ g_jump (Label);
Warning ("Unreachable code");
- } else if (cond && lval.ConstVal) {
- g_jump (label);
+ } else if (Invert && lval.ConstVal != 0) {
+ g_jump (Label);
}
- ConsumeRParen ();
- return;
- }
- /* If the expr hasn't set condition codes, set the force-test flag */
- if ((lval.Test & E_CC) == 0) {
- lval.Test |= E_FORCETEST;
- }
+ } else {
- /* Load the value into the primary register */
- exprhs (CF_FORCECHAR, k, &lval);
+ /* If the expr hasn't set condition codes, set the force-test flag */
+ if ((lval.Test & E_CC) == 0) {
+ lval.Test |= E_FORCETEST;
+ }
- /* Generate the jump */
- if (cond) {
- g_truejump (CF_NONE, label);
- } else {
- /* Special case (putting this here is a small hack - but hey, the
- * compiler itself is one big hack...): If a semicolon follows, we
- * don't have a statement and may omit the jump.
- */
- if (CurTok.Tok != TOK_SEMI) {
- g_falsejump (CF_NONE, label);
- }
+ /* Load the value into the primary register */
+ exprhs (CF_FORCECHAR, k, &lval);
+
+ /* Generate the jump */
+ if (Invert) {
+ g_truejump (CF_NONE, Label);
+ } else {
+ g_falsejump (CF_NONE, Label);
+ }
}
+}
+
+
+
+void TestInParens (unsigned Label, int Invert)
+/* Evaluate a boolean test expression in parenthesis and jump depending on
+ * the result of the test * and on Invert.
+ */
+{
+ /* Eat the parenthesis */
+ ConsumeLParen ();
+
+ /* Do the test */
+ Test (Label, Invert);
/* Check for the closing brace */
ConsumeRParen ();
-
* from this input error.
*/
+void CheckBoolExpr (ExprDesc* lval);
+/* Check if the given expression is a boolean expression, output a diagnostic
+ * if not.
+ */
+
unsigned assignadjust (type* lhst, ExprDesc* rhs);
/* Adjust the type of the right hand expression so that it can be assigned to
* the type on the left hand side. This function is used for assignment and
void intexpr (ExprDesc* lval);
/* Get an integer expression */
-void boolexpr (ExprDesc* lval);
-/* Get a boolean expression */
-
-void test (unsigned label, int cond);
-/* Generate code to perform test and jump if false. */
-
int hie10 (ExprDesc* lval);
/* Handle ++, --, !, unary - etc. */
void DefineData (ExprDesc* lval);
/* Output a data definition for the given expression */
+void Test (unsigned Label, int Invert);
+/* Evaluate a boolean test expression and jump depending on the result of
+ * the test and on Invert.
+ */
+
+void TestInParens (unsigned Label, int Invert);
+/* Evaluate a boolean test expression in parenthesis and jump depending on
+ * the result of the test * and on Invert.
+ */
+
/* End of expr.h */
/* Generate a jump label and parse the condition */
Label1 = GetLocalLabel ();
- test (Label1, 0);
+ TestInParens (Label1, 0);
/* Parse the if body */
GotBreak = Statement (0);
/* Parse the end condition */
Consume (TOK_WHILE, "`while' expected");
- test (loop, 1);
+ TestInParens (loop, 1);
ConsumeSemi ();
/* Define the break label */
g_defcodelabel (loop);
/* Test the loop condition */
- test (lab, 0);
+ TestInParens (lab, 0);
/* Loop body */
Statement (&PendingToken);
/* Handle a 'for' statement */
{
ExprDesc lval1;
- ExprDesc lval2;
ExprDesc lval3;
int HaveIncExpr;
CodeMark IncExprStart;
/* Parse the test expression */
if (CurTok.Tok != TOK_SEMI) {
- boolexpr (&lval2);
- g_truejump (CF_NONE, lstat);
+ Test (lstat, 1);
g_jump (lab);
} else {
g_jump (lstat);