return method;
} else {
- if (IsNumber (expression.Type))
+ var type = GetNotNullableOf (expression.Type);
+
+ if (IsIntOrBool (type))
return null;
if (oper_name != null) {
- method = GetUnaryOperator (oper_name, expression.Type, expression);
+ method = GetUnaryOperator (oper_name, GetNotNullableOf (type), expression);
if (method != null)
return method;
}
static UnaryExpression MakeSimpleUnary (ExpressionType et, Expression expression, MethodInfo method)
{
- return new UnaryExpression (et, expression, GetResultType (expression, method), method);
+ bool is_lifted;
+
+ if (method == null) {
+ is_lifted = IsNullable (expression.Type);
+ } else {
+ // FIXME: implement
+ is_lifted = false;
+ }
+
+ return new UnaryExpression (et, expression, GetResultType (expression, method), method, is_lifted);
}
static BinaryExpression MakeBoolBinary (ExpressionType et, Expression left, Expression right, bool liftToNull, MethodInfo method)
// TODO: check for valid convertions
- return new UnaryExpression (ExpressionType.Convert, expression, type, method);
+ return new UnaryExpression (ExpressionType.Convert, expression, type, method, false);
}
public static UnaryExpression ConvertChecked (Expression expression, Type type)
// TODO: check for valid convertions
- return new UnaryExpression (ExpressionType.ConvertChecked, expression, type, method);
+ return new UnaryExpression (ExpressionType.ConvertChecked, expression, type, method, false);
}
public static ElementInit ElementInit (MethodInfo addMethod, params Expression [] arguments)
{
method = UnaryCoreCheck ("op_LogicalNot", expression, method);
+ if (method == null)
+ method = UnaryCoreCheck ("op_OnesComplement", expression, method);
+
return MakeSimpleUnary (ExpressionType.Not, expression, method);
}
Expression operand;
MethodInfo method;
+ bool is_lifted;
+ bool is_lifted_to_null;
public Expression Operand {
get { return operand; }
get { return method; }
}
- [MonoTODO]
public bool IsLifted {
- get { throw new NotImplementedException (); }
+ get { return is_lifted; }
}
- [MonoTODO]
public bool IsLiftedToNull {
- get { throw new NotImplementedException (); }
+ get { return is_lifted_to_null; }
}
internal UnaryExpression (ExpressionType node_type, Expression operand)
this.operand = operand;
}
- internal UnaryExpression (ExpressionType node_type, Expression operand, Type type, MethodInfo method)
+ internal UnaryExpression (ExpressionType node_type, Expression operand, Type type, MethodInfo method, bool is_lifted)
: base (node_type, type)
{
this.operand = operand;
this.method = method;
+ this.is_lifted = is_lifted;
+ this.is_lifted_to_null = is_lifted;
}
void EmitArrayLength (EmitContext ec)
ec.ig.Emit (OpCodes.Unbox_Any, type);
}
+ void EmitUnaryOperator (EmitContext ec)
+ {
+ var ig = ec.ig;
+
+ switch (NodeType) {
+ case ExpressionType.Not:
+ if (GetNotNullableOf (operand.Type) == typeof (bool)) {
+ ig.Emit (OpCodes.Ldc_I4_0);
+ ig.Emit (OpCodes.Ceq);
+ } else
+ ig.Emit (OpCodes.Not);
+ break;
+ }
+ }
+
internal override void Emit (EmitContext ec)
{
switch (this.NodeType) {
case ExpressionType.TypeAs:
EmitTypeAs (ec);
return;
+ case ExpressionType.Not:
+ if (!is_lifted) {
+ operand.Emit (ec);
+ EmitUnaryOperator (ec);
+ } else
+ throw new NotImplementedException ();
+ return;
+ case ExpressionType.UnaryPlus:
+ return;
default:
throw new NotImplementedException (this.NodeType.ToString ());
}