1/*****************************************************************************/
2/* */
3/* testexpr.c */
4/* */
5/* Test an expression and jump */
6/* */
7/* */
8/* */
9/* (C) 2004 Ullrich von Bassewitz */
10/* Römerstraße 52 */
11/* D-70794 Filderstadt */
12/* EMail: uz@cc65.org */
13/* */
14/* */
15/* This software is provided 'as-is', without any expressed or implied */
16/* warranty. In no event will the authors be held liable for any damages */
17/* arising from the use of this software. */
18/* */
19/* Permission is granted to anyone to use this software for any purpose, */
20/* including commercial applications, and to alter it and redistribute it */
21/* freely, subject to the following restrictions: */
22/* */
23/* 1. The origin of this software must not be misrepresented; you must not */
24/* claim that you wrote the original software. If you use this software */
25/* in a product, an acknowledgment in the product documentation would be */
26/* appreciated but is not required. */
27/* 2. Altered source versions must be plainly marked as such, and must not */
28/* be misrepresented as being the original software. */
29/* 3. This notice may not be removed or altered from any source */
30/* distribution. */
31/* */
32/*****************************************************************************/
33
34
35
36/* cc65 */
37#include "codegen.h"
38#include "error.h"
39#include "expr.h"
40#include "loadexpr.h"
41#include "scanner.h"
42#include "testexpr.h"
43
44
45
46/*****************************************************************************/
47/* Code */
48/*****************************************************************************/
49
50
51
52unsigned Test (unsigned Label, int Invert)
53/* Evaluate a boolean test expression and jump depending on the result of
54** the test and on Invert. The function returns one of the TESTEXPR_xx codes
55** defined above. If the jump is always true, a warning is output.
56*/
57{
58 ExprDesc Expr;
59 unsigned Result;
60
61 /* Read a boolean expression */
62 BoolExpr (hie0, &Expr);
63
64 /* Check for a constant expression */
65 if (ED_IsConstAbs (&Expr)) {
66
67 /* Result is constant, so we know the outcome */
68 Result = (Expr.IVal != 0);
69
70 /* Constant rvalue */
71 if (!Invert && Expr.IVal == 0) {
72 g_jump (Label);
73 Warning ("Unreachable code");
74 } else if (Invert && Expr.IVal != 0) {
75 g_jump (Label);
76 }
77
78 } else {
79
80 /* Result is unknown */
81 Result = TESTEXPR_UNKNOWN;
82
83 /* If the expr hasn't set condition codes, set the force-test flag */
84 if (!ED_IsTested (&Expr)) {
85 ED_MarkForTest (&Expr);
86 }
87
88 /* Load the value into the primary register */
89 LoadExpr (CF_FORCECHAR, &Expr);
90
91 /* Generate the jump */
92 if (Invert) {
93 g_truejump (CF_NONE, Label);
94 } else {
95 g_falsejump (CF_NONE, Label);
96 }
97 }
98
99 /* Return the result */
100 return Result;
101}
102
103
104
105unsigned TestInParens (unsigned Label, int Invert)
106/* Evaluate a boolean test expression in parenthesis and jump depending on
107** the result of the test * and on Invert. The function returns one of the
108** TESTEXPR_xx codes defined above. If the jump is always true, a warning is
109** output.
110*/
111{
112 unsigned Result;
113
114 /* Eat the parenthesis */
115 ConsumeLParen ();
116
117 /* Do the test */
118 Result = Test (Label, Invert);
119
120 /* Check for the closing brace */
121 ConsumeRParen ();
122
123 /* Return the result of the expression */
124 return Result;
125}
126