// Build a binary operator statement public static void BuildBinaryOperator(IronyParser parser, Root root, Expression parentExpression, ParseTreeNode currentNode) { var op = new BinaryOperator(parentExpression, currentNode.FindToken().Convert()); parentExpression.ChildExpressions.Add(op); // Determine which binary operator this is switch (currentNode.ChildNodes[1].Term.ToString()) { case "*": op.OperatorType = BinaryOperatorType.Multiply; break; case "/": op.OperatorType = BinaryOperatorType.Divide; break; case "+": op.OperatorType = BinaryOperatorType.Add; break; case "-": op.OperatorType = BinaryOperatorType.Subtract; break; case "%": op.OperatorType = BinaryOperatorType.Modulo; break; case "<=": op.OperatorType = BinaryOperatorType.LessOrEqual; break; case "<": op.OperatorType = BinaryOperatorType.Less; break; case "==": op.OperatorType = BinaryOperatorType.Equal; break; case "!=": op.OperatorType = BinaryOperatorType.NotEqual; break; case ">=": op.OperatorType = BinaryOperatorType.GreaterOrEqual; break; case ">": op.OperatorType = BinaryOperatorType.Greater; break; case ">>": op.OperatorType = BinaryOperatorType.BitwiseShiftRight; break; case "<<": op.OperatorType = BinaryOperatorType.BitwiseShiftLeft; break; case "&&": op.OperatorType = BinaryOperatorType.LogicalAnd; break; case "||": op.OperatorType = BinaryOperatorType.LogicalOr; break; case "|": op.OperatorType = BinaryOperatorType.BitwiseOr; break; case "&": op.OperatorType = BinaryOperatorType.BitwiseAnd; break; case "^": op.OperatorType = BinaryOperatorType.BitwiseXor; break; case "as": op.OperatorType = BinaryOperatorType.As; break; } // Get the left operand parser.ConsumeParseTree(root, op, currentNode.ChildNodes[0]); // "as" operator is a type case and needs to be handled differently if(op.OperatorType == BinaryOperatorType.As) { var v = new VariableReference(op, null); v.Name = currentNode.ChildNodes[2].ChildNodes[0].FindTokenAndGetText(); op.ChildExpressions.Add(v); } else parser.ConsumeParseTree(root, op, currentNode.ChildNodes[2]); }
// Emit a codedom binary operation expression public static CodeExpression Emit(BinaryOperator op) { // Translate the operator type to a codedom one. CodeBinaryOperatorType opType = CodeBinaryOperatorType.Add; switch (op.OperatorType) { case BinaryOperatorType.Subtract: opType = CodeBinaryOperatorType.Subtract; break; case BinaryOperatorType.Divide: opType = CodeBinaryOperatorType.Divide; break; case BinaryOperatorType.Multiply: opType = CodeBinaryOperatorType.Multiply; break; case BinaryOperatorType.Less: opType = CodeBinaryOperatorType.LessThan; break; case BinaryOperatorType.LessOrEqual: opType = CodeBinaryOperatorType.LessThanOrEqual; break; case BinaryOperatorType.Equal: opType = CodeBinaryOperatorType.IdentityEquality; break; case BinaryOperatorType.NotEqual: opType = CodeBinaryOperatorType.IdentityInequality; break; case BinaryOperatorType.Greater: opType = CodeBinaryOperatorType.GreaterThan; break; case BinaryOperatorType.GreaterOrEqual: opType = CodeBinaryOperatorType.GreaterThanOrEqual; break; case BinaryOperatorType.BitwiseAnd: opType = CodeBinaryOperatorType.BitwiseAnd; break; case BinaryOperatorType.BitwiseOr: opType = CodeBinaryOperatorType.BitwiseOr; break; case BinaryOperatorType.Modulo: opType = CodeBinaryOperatorType.Modulus; break; case BinaryOperatorType.LogicalAnd: opType = CodeBinaryOperatorType.BooleanAnd; break; case BinaryOperatorType.LogicalOr: opType = CodeBinaryOperatorType.BooleanOr; break; case BinaryOperatorType.As: // Casting requires a different set of codedom expressions. var cast = new CodeCastExpression(); cast.TargetType = new CodeTypeReference((op.ChildExpressions[1] as VariableReference).Name); cast.Expression = CodeDomEmitter.EmitCodeExpression(op.ChildExpressions[0]); return cast; } var o = new CodeBinaryOperatorExpression(CodeDomEmitter.EmitCodeExpression(op.ChildExpressions[0]), // left operand opType, // operator CodeDomEmitter.EmitCodeExpression(op.ChildExpressions[1])); // right operand return o; }