This commit is contained in:
Бондарев Иван 2018-10-03 11:24:02 +02:00
parent 96b47bf568
commit b765e1ad63
2 changed files with 83 additions and 39 deletions

View file

@ -8482,51 +8482,75 @@ namespace PascalABCCompiler.NETGenerator
}
if (real_parameters.Length > 1)
{
if (real_parameters[0].type.is_nullable_type && real_parameters[1] is INullConstantNode)
{
bool tmp = is_dot_expr;
is_dot_expr = true;
TypeInfo ti = helper.GetTypeReference(real_parameters[0].type);
real_parameters[0].visit(this);
is_dot_expr = tmp;
MethodInfo mi = null;
if (real_parameters[0].type is IGenericTypeInstance)
mi = TypeBuilder.GetMethod(ti.tp, typeof(Nullable<>).GetMethod("get_HasValue"));
else
mi = ti.tp.GetMethod("get_HasValue");
il.Emit(OpCodes.Call, mi);
if (ft == basic_function_type.objeq)
il.Emit(OpCodes.Not);
return;
}
else if (real_parameters[1].type.is_nullable_type && real_parameters[0] is INullConstantNode)
{
bool tmp = is_dot_expr;
is_dot_expr = true;
TypeInfo ti = helper.GetTypeReference(real_parameters[1].type);
real_parameters[1].visit(this);
is_dot_expr = tmp;
MethodInfo mi = null;
if (real_parameters[1].type is IGenericTypeInstance)
mi = TypeBuilder.GetMethod(ti.tp, typeof(Nullable<>).GetMethod("get_HasValue"));
else
mi = ti.tp.GetMethod("get_HasValue");
il.Emit(OpCodes.Call, mi);
if (ft == basic_function_type.objeq)
il.Emit(OpCodes.Not);
return;
}
if (real_parameters[0].type.is_nullable_type && real_parameters[1] is INullConstantNode)
{
bool tmp = is_dot_expr;
is_dot_expr = true;
TypeInfo ti = helper.GetTypeReference(real_parameters[0].type);
real_parameters[0].visit(this);
is_dot_expr = tmp;
MethodInfo mi = null;
if (real_parameters[0].type is IGenericTypeInstance)
mi = TypeBuilder.GetMethod(ti.tp, typeof(Nullable<>).GetMethod("get_HasValue"));
else
mi = ti.tp.GetMethod("get_HasValue");
il.Emit(OpCodes.Call, mi);
if (ft == basic_function_type.objeq)
il.Emit(OpCodes.Not);
return;
}
else if (real_parameters[1].type.is_nullable_type && real_parameters[0] is INullConstantNode)
{
bool tmp = is_dot_expr;
is_dot_expr = true;
TypeInfo ti = helper.GetTypeReference(real_parameters[1].type);
real_parameters[1].visit(this);
is_dot_expr = tmp;
MethodInfo mi = null;
if (real_parameters[1].type is IGenericTypeInstance)
mi = TypeBuilder.GetMethod(ti.tp, typeof(Nullable<>).GetMethod("get_HasValue"));
else
mi = ti.tp.GetMethod("get_HasValue");
il.Emit(OpCodes.Call, mi);
if (ft == basic_function_type.objeq)
il.Emit(OpCodes.Not);
return;
}
else if (real_parameters[0].type.is_nullable_type && real_parameters[1].type.is_nullable_type)
{
MethodInfo mi_left = null;
TypeInfo ti_left = helper.GetTypeReference(real_parameters[0].type);
if (real_parameters[0].type is IGenericTypeInstance)
mi_left = TypeBuilder.GetMethod(ti_left.tp, typeof(Nullable<>).GetMethod("GetValueOrDefault", new Type[] { }));
else
mi_left = ti_left.tp.GetMethod("GetValueOrDefault", new Type[] { });
MethodInfo mi_right = null;
TypeInfo ti_right = helper.GetTypeReference(real_parameters[1].type);
if (real_parameters[1].type is IGenericTypeInstance)
mi_right = TypeBuilder.GetMethod(ti_right.tp, typeof(Nullable<>).GetMethod("GetValueOrDefault", new Type[] { }));
else
mi_right = ti_right.tp.GetMethod("GetValueOrDefault", new Type[] { });
is_dot_expr = true;
real_parameters[0].visit(this);
il.Emit(OpCodes.Call, mi_left);
is_dot_expr = true;
real_parameters[1].visit(this);
il.Emit(OpCodes.Call, mi_right);
EmitOperator(value);
if (tmp_dot)
{
is_dot_expr = tmp_dot;
NETGeneratorTools.CreateLocalAndLoad(il, helper.GetTypeReference(value.type).tp);
}
return;
}
}
real_parameters[0].visit(this);
if (real_parameters.Length > 1)
real_parameters[1].visit(this);
//is_dot_expr = tmp_dot;
EmitOperator(value);//кладем соотв. команду
if (tmp_dot == true)
if (tmp_dot)
{
//LocalBuilder lb = il.DeclareLocal(helper.GetTypeReference(value.type).tp);
//il.Emit(OpCodes.Stloc, lb);
//il.Emit(OpCodes.Ldloca, lb);
is_dot_expr = tmp_dot;
NETGeneratorTools.CreateLocalAndLoad(il, helper.GetTypeReference(value.type).tp);
}

20
TestSuite/nullable2.pas Normal file
View file

@ -0,0 +1,20 @@
function f: integer?;
begin
Result := 2;
end;
type TRec = record
i: integer;
end;
begin
var t := System.Nullable&<integer>(2);
assert(t <> 3);
assert(t = 2);
assert(f = 2);
assert(f <> 3);
var r, r2: TRec;
r.i := 2;
r2.i := 3;
assert(System.Nullable&<TRec>(r) = System.Nullable&<TRec>(r));
assert(System.Nullable&<TRec>(r) <> System.Nullable&<TRec>(r2));
end.