+ default:
+ Internal ("Unexpected token");
+ }
+
+ }
+
+ /* Return the resulting expression */
+ return Root;
+}
+
+
+
+static ExprNode* AndExpr (void)
+/* Handle and expressions: '&' */
+{
+ /* Get the left leave */
+ ExprNode* Root = EqualityExpr ();
+
+ /* Check if this is for us */
+ while (CurTok.Tok == TOK_AND) {
+
+ ExprNode* Left = Root;
+ ExprNode* Right;
+
+ /* Skip the token */
+ NextToken ();
+
+ /* Get the right operand */
+ Right = EqualityExpr ();
+
+ /* Type check */
+ if (!IsClassInt (Left->Type) || !IsClassInt (Right->Type)) {
+
+ /* Print a diagnostic */
+ Error ("Operation not allowed for these types");
+
+ /* Remove the unneeded nodes */
+ FreeExprTree (Right);
+ FreeExprTree (Left);
+
+ /* Create something safe */
+ Root = GetIntNode (0);
+
+ } else {
+
+ /* Check if both operands are constant */
+ if (Left->NT == NT_CONST && Right->NT == NT_CONST) {
+
+ /* Get the constant result */
+ int Result = GetBoolRep (Left) & GetBoolRep (Right);
+
+ /* Remove the unneeded nodes */
+ FreeExprTree (Right);
+ FreeExprTree (Left);
+
+ /* Create a constant result */
+ Root = GetIntNode (Result);
+
+ } else {
+
+ /* Make an operator node */
+ Root = AllocExprNode (NT_AND, type_int, RVALUE);
+ SetRightNode (Root, Right);
+ SetLeftNode (Root, Left);
+
+ }
+ }
+ }
+
+ /* Return the resulting expression */
+ return Root;
+}
+
+
+
+static ExprNode* XorExpr (void)
+/* Handle xor expressions: '^' */
+{
+ /* Get the left leave */
+ ExprNode* Root = AndExpr ();
+
+ /* Check if this is for us */
+ while (CurTok.Tok == TOK_XOR) {
+
+ ExprNode* Left = Root;
+ ExprNode* Right;
+
+ /* Skip the token */
+ NextToken ();
+
+ /* Get the right operand */
+ Right = AndExpr ();
+
+ /* Type check */
+ if (!IsClassInt (Left->Type) || !IsClassInt (Right->Type)) {
+
+ /* Print a diagnostic */
+ Error ("Operation not allowed for these types");
+
+ /* Remove the unneeded nodes */
+ FreeExprTree (Right);
+ FreeExprTree (Left);
+
+ /* Create something safe */
+ Root = GetIntNode (0);
+
+ } else {
+
+ /* Check if both operands are constant */
+ if (Left->NT == NT_CONST && Right->NT == NT_CONST) {
+
+ /* Get the constant result */
+ int Result = GetBoolRep (Left) ^ GetBoolRep (Right);
+
+ /* Remove the unneeded nodes */
+ FreeExprTree (Right);
+ FreeExprTree (Left);
+
+ /* Create a constant result */
+ Root = GetIntNode (Result);
+
+ } else {
+
+ /* Make an operator node */
+ Root = AllocExprNode (NT_XOR, type_int, RVALUE);
+ SetRightNode (Root, Right);
+ SetLeftNode (Root, Left);
+
+ }
+ }
+ }
+
+ /* Return the resulting expression */
+ return Root;
+}
+
+
+
+static ExprNode* OrExpr (void)
+/* Handle or expressions: '|' */
+{
+ /* Get the left leave */
+ ExprNode* Root = XorExpr ();
+
+ /* Check if this is for us */
+ while (CurTok.Tok == TOK_OR) {
+
+ ExprNode* Left = Root;
+ ExprNode* Right;
+
+ /* Skip the token */
+ NextToken ();
+
+ /* Get the right operand */
+ Right = XorExpr ();
+
+ /* Type check */
+ if (!IsClassInt (Left->Type) || !IsClassInt (Right->Type)) {
+
+ /* Print a diagnostic */
+ Error ("Operation not allowed for these types");
+
+ /* Remove the unneeded nodes */
+ FreeExprTree (Right);
+ FreeExprTree (Left);
+
+ /* Create something safe */
+ Root = GetIntNode (0);
+
+ } else {
+
+ /* Check if both operands are constant */
+ if (Left->NT == NT_CONST && Right->NT == NT_CONST) {
+
+ /* Get the constant result */
+ int Result = GetBoolRep (Left) | GetBoolRep (Right);
+
+ /* Remove the unneeded nodes */
+ FreeExprTree (Right);
+ FreeExprTree (Left);
+
+ /* Create a constant result */
+ Root = GetIntNode (Result);
+
+ } else {
+
+ /* Make an operator node */
+ Root = AllocExprNode (NT_OR, type_int, RVALUE);
+ SetRightNode (Root, Right);
+ SetLeftNode (Root, Left);
+
+ }
+ }
+ }
+
+ /* Return the resulting expression */
+ return Root;
+}
+
+
+
+static ExprNode* BoolAndExpr (void)
+/* Handle boolean and expressions: '&&' */
+{
+ /* Get the left leave */
+ ExprNode* Root = OrExpr ();
+
+ /* Check if this is for us */
+ while (CurTok.Tok == TOK_BOOL_AND) {
+
+ ExprNode* Left = Root;
+ ExprNode* Right;
+
+ /* Skip the token */
+ NextToken ();
+
+ /* Get the right operand */
+ Right = OrExpr ();
+
+ /* Check if both operands are constant */
+ if (Left->NT == NT_CONST && Right->NT == NT_CONST) {
+
+ /* Get the constant result */
+ int Result = GetBoolRep (Left) && GetBoolRep (Right);
+
+ /* Remove the unneeded nodes */
+ FreeExprTree (Right);
+ FreeExprTree (Left);
+
+ /* Create a constant result */
+ Root = GetIntNode (Result);
+
+ } else {
+
+ /* Make an operator node */
+ Root = AllocExprNode (NT_BOOL_AND, type_int, RVALUE);
+ SetRightNode (Root, Right);
+ SetLeftNode (Root, Left);
+