public override object Exec(StringType firstOperand, object arg)
        {
            // * String WriteType and bounded type variables
            if (TypeExpression.As <StringType>(this.secondOperand) != null)
            {
                return(0);
            }
            // * WriteType variable
            TypeVariable typeVariable = this.secondOperand as TypeVariable;

            if (typeVariable != null && typeVariable.Substitution == null)
            {
                // * A free variable is complete promotion
                return(0);
            }
            // * Union type
            UnionType unionType = TypeExpression.As <UnionType>(this.secondOperand);

            if (unionType != null)
            {
                return(unionType.SuperType(firstOperand));
            }
            // * Field type and bounded type variable
            FieldType fieldType = TypeExpression.As <FieldType>(this.secondOperand);

            if (fieldType != null)
            {
                return(firstOperand.AcceptOperation(new PromotionLevelOperation(fieldType.FieldTypeExpression), arg));
            }
            // * Use the BCL object oriented approach
            return(firstOperand.AsClassType().AcceptOperation(this, arg));
        }
        public override object Exec(StringType operand, object arg)
        {
            if (this.union.Count == 1)
            {
                return(null);
            }

            string notThisType = this.codeGenerator.NewLabel;
            string endLabel    = this.codeGenerator.NewLabel;

            operand.AcceptOperation(new CGRuntimeIsInstructionOperation <T>(this.indent, this.codeGenerator), arg);
            this.codeGenerator.brfalse(this.indent, notThisType);
            operand.AcceptOperation(new CGRuntimeFreshTEPromotionOperation <T>(this.indent, this.codeGenerator), arg);
            this.codeGenerator.br(this.indent, endLabel);
            this.codeGenerator.WriteLabel(this.indent, notThisType);
            // As the expected type is an String, we must call its ToString method
            this.codeGenerator.CallVirt(this.indent, "instance", "string", "[mscorlib]System.Object", "ToString", null);
            this.codeGenerator.WriteLabel(this.indent, endLabel);
            return(null);
        }
 public override object Exec(StringType firstTypeExpression, object arg)
 {
     return(this.node.Operator == ArithmeticOperator.Plus ? StringType.Instance : firstTypeExpression.AcceptOperation(new MajorTypeOperation(this.secondTypeExpression), arg));
 }