+ }
+
+ /* 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);
+
+ }
+
+ }
+
+ /* Return the resulting expression */
+ return Root;
+}
+
+
+
+static ExprNode* BoolOrExpr (void)
+/* Handle boolean or expressions: '||' */
+{
+ /* Get the left leave */
+ ExprNode* Root = BoolAndExpr ();
+
+ /* Check if this is for us */
+ while (CurTok.Tok == TOK_BOOL_OR) {
+
+ ExprNode* Left = Root;
+ ExprNode* Right;
+
+ /* Skip the token */
+ NextToken ();
+
+ /* Get the right operand */
+ Right = BoolAndExpr ();
+
+ /* 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_OR, type_int, RVALUE);
+ SetRightNode (Root, Right);
+ SetLeftNode (Root, Left);
+
+ }
+
+ }
+
+ /* Return the resulting expression */
+ return Root;
+}
+
+
+
+static ExprNode* ConditionalExpr (void)
+/* Handle the ternary operator: ':?' */
+{
+ /* Get the left leave */
+ ExprNode* Cond = BoolOrExpr ();
+
+ /* Check if this is for us */
+ if (CurTok.Tok == TOK_QUEST) {
+
+ ExprNode* Expr1;
+ ExprNode* Expr2;
+ ExprNode* Root;
+ type* Type;
+
+
+ /* Skip the token */
+ NextToken ();
+
+ /* Get the first expression */
+ Expr1 = Expression ();
+
+ /* Colon must follow */
+ ConsumeColon ();
+
+ /* Get the second expression */
+ Expr2 = ConditionalExpr ();
+
+ /* Get the common type of the two expressions */
+ Type = CommonType (Expr1->Type, Expr2->Type);
+
+ /* Create a new ternary token node */
+ Root = AllocExprNode (NT_TERNARY, Type, RVALUE);
+ AppendItem (Root, Cond);
+ AppendItem (Root, Expr1);
+ AppendItem (Root, Expr2);
+
+ /* Return the result */
+ return Root;