public Expression ParseBooleanFactor() { Expression node; switch (Lexer.CurrentToken.TokenType) { case tkLpar: return(ParseBooleanParentisizedExpression()); default: node = ParseExpression(); switch (Lexer.CurrentToken.TokenType) { case tkLess: Lexer.GetNextToken(); node = new BinaryBooleanExpression(node, BinaryExpression.BinaryOperator.LessThan, ParseExpression()); break; case tkGreater: Lexer.GetNextToken(); node = new BinaryBooleanExpression(node, BinaryExpression.BinaryOperator.GreaterThan, ParseExpression()); break; case tkEqual: Lexer.GetNextToken(); node = new BinaryBooleanExpression(node, BinaryExpression.BinaryOperator.Equal, ParseExpression()); break; case tkNotEqual: Lexer.GetNextToken(); node = new BinaryBooleanExpression(node, BinaryExpression.BinaryOperator.NotEqual, ParseExpression()); break; case tkEqualLess: Lexer.GetNextToken(); node = new BinaryBooleanExpression(node, BinaryExpression.BinaryOperator.LessEqualThan, ParseExpression()); break; case tkEqualGreater: Lexer.GetNextToken(); node = new BinaryBooleanExpression(node, BinaryExpression.BinaryOperator.GreaterEqualThan, ParseExpression()); break; } return(node); } }
private static void EmitBinaryBooleanExpression(BinaryBooleanExpression binaryBoolean, ILGenerator methodIL) { switch (binaryBoolean.OperatorKind) { case BinaryExpression.BinaryOperator.Conjuction: EmitPrimitiveBinaryOperation(binaryBoolean.LeftOperand, binaryBoolean.RightOperand, OpCodes.And, methodIL); break; case BinaryExpression.BinaryOperator.Disjunction: EmitPrimitiveBinaryOperation(binaryBoolean.LeftOperand, binaryBoolean.RightOperand, OpCodes.Or, methodIL); break; case BinaryExpression.BinaryOperator.StrictDisjunction: EmitPrimitiveBinaryOperation(binaryBoolean.LeftOperand, binaryBoolean.RightOperand, OpCodes.Xor, methodIL); break; case BinaryExpression.BinaryOperator.LessThan: EmitBooleanRelationOperation(binaryBoolean.LeftOperand, binaryBoolean.RightOperand, OpCodes.Blt, methodIL); break; case BinaryExpression.BinaryOperator.GreaterThan: EmitBooleanRelationOperation(binaryBoolean.LeftOperand, binaryBoolean.RightOperand, OpCodes.Bgt, methodIL); break; case BinaryExpression.BinaryOperator.LessEqualThan: EmitBooleanRelationOperation(binaryBoolean.LeftOperand, binaryBoolean.RightOperand, OpCodes.Ble, methodIL); break; case BinaryExpression.BinaryOperator.GreaterEqualThan: EmitBooleanRelationOperation(binaryBoolean.LeftOperand, binaryBoolean.RightOperand, OpCodes.Bge, methodIL); break; case BinaryExpression.BinaryOperator.Equal: if (OperandsHaveSameTypes(binaryBoolean, new InnerTypes.String())) { EmitStringEquality(binaryBoolean.LeftOperand, binaryBoolean.RightOperand, methodIL); } else { EmitBooleanRelationOperation(binaryBoolean.LeftOperand, binaryBoolean.RightOperand, OpCodes.Beq, methodIL); } break; case BinaryExpression.BinaryOperator.NotEqual: if (OperandsHaveSameTypes(binaryBoolean, new InnerTypes.String())) { EmitStringEquality(binaryBoolean.LeftOperand, binaryBoolean.RightOperand, methodIL); } else { EmitBooleanRelationOperation(binaryBoolean.LeftOperand, binaryBoolean.RightOperand, OpCodes.Beq, methodIL); } EmitInversion(methodIL); break; default: throw new Exception(); } }
public Expression ParseBooleanConjunction() { Expression node = ParseBooleanInversion(); if (Match(tkAnd)) { Lexer.GetNextToken(); node = new BinaryBooleanExpression(node, BinaryExpression.BinaryOperator.Conjuction, ParseBooleanConjunction()); } return(node); }
public Expression ParseBooleanSrtrictDisjunction() { Expression node = ParseBooleanConjunction(); if (Match(tkXor)) { Lexer.GetNextToken(); node = new BinaryBooleanExpression(node, BinaryExpression.BinaryOperator.StrictDisjunction, ParseBooleanSrtrictDisjunction()); } return(node); }
public static void TryToCastBinaryBooleanExpression(BinaryBooleanExpression binaryBoolean) { switch (binaryBoolean.OperatorKind) { case BinaryExpression.BinaryOperator.Equal: case BinaryExpression.BinaryOperator.NotEqual: case BinaryExpression.BinaryOperator.LessThan: case BinaryExpression.BinaryOperator.GreaterThan: case BinaryExpression.BinaryOperator.LessEqualThan: case BinaryExpression.BinaryOperator.GreaterEqualThan: InnerType LOperandType = TypeResolver.ResolveExpressionType(binaryBoolean.LeftOperand); InnerType ROperandType = TypeResolver.ResolveExpressionType(binaryBoolean.RightOperand); InnerType toType = HigherPriorityType(LOperandType, ROperandType); TryToCastExpression(binaryBoolean.LeftOperand, toType); TryToCastExpression(binaryBoolean.RightOperand, toType); break; default: TryToCastExpression(binaryBoolean.LeftOperand, new Undefined()); TryToCastExpression(binaryBoolean.RightOperand, new Undefined()); break; } }
public static InnerType ResolveBinaryBooleanExpressionType(BinaryBooleanExpression binaryBooleanExpression) { InnerType LOperandType = ResolveExpressionType(binaryBooleanExpression.LeftOperand); InnerType ROperandType = ResolveExpressionType(binaryBooleanExpression.RightOperand); switch (binaryBooleanExpression.OperatorKind) { case BinaryExpression.BinaryOperator.Equal: case BinaryExpression.BinaryOperator.NotEqual: if ((LOperandType is PrimitiveType && ROperandType is PrimitiveType) || (LOperandType is String && ROperandType is String)) { return(new Boolean()); } if (LOperandType != ROperandType) { ReportErrorInBooleanExpression(new OperatorWithWrongOperandTypes($"Operator [{binaryBooleanExpression.GetOperatorRepresentation()}] must be located between two operands of the same type", binaryBooleanExpression.SourceContext)); return(LOperandType); } ReportErrorInBooleanExpression(new OperatorWithWrongOperandTypes($"Operator [{binaryBooleanExpression.GetOperatorRepresentation()}] must be located between two operands of the primitive type", binaryBooleanExpression.SourceContext)); if (!(LOperandType is PrimitiveType) | !(LOperandType is String)) { return(LOperandType); } else { return(ROperandType); } case BinaryExpression.BinaryOperator.Conjuction: case BinaryExpression.BinaryOperator.Disjunction: case BinaryExpression.BinaryOperator.StrictDisjunction: if (LOperandType is Boolean && ROperandType is Boolean) { return(new Boolean()); } ReportErrorInBooleanExpression(new OperatorWithWrongOperandTypes($"Operator [{binaryBooleanExpression.GetOperatorRepresentation()}] must be located between two operands of the logical type", binaryBooleanExpression.SourceContext)); if (!(LOperandType is Boolean)) { return(LOperandType); } else { return(ROperandType); } case BinaryExpression.BinaryOperator.LessThan: case BinaryExpression.BinaryOperator.GreaterThan: case BinaryExpression.BinaryOperator.LessEqualThan: case BinaryExpression.BinaryOperator.GreaterEqualThan: if (LOperandType is NumericType && ROperandType is NumericType) { return(new Boolean()); } ReportErrorInBooleanExpression(new OperatorWithWrongOperandTypes($"Operator [{binaryBooleanExpression.GetOperatorRepresentation()}] must be located between two numeric operands", binaryBooleanExpression.SourceContext)); if (!(LOperandType is NumericType)) { return(LOperandType); } else { return(ROperandType); } default: return(new Undefined()); } }