This commit is contained in:
parent
debd0ddee6
commit
c3da960cbf
11
TestSuite/errors/err0394.pas
Normal file
11
TestSuite/errors/err0394.pas
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
type
|
||||||
|
t1 = class
|
||||||
|
|
||||||
|
static procedure operator+=(a: t1; d: System.Action<integer>) := exit;
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
var a := new t1;
|
||||||
|
a += ()->Writeln(1);
|
||||||
|
end.
|
||||||
18
TestSuite/lambdas11.pas
Normal file
18
TestSuite/lambdas11.pas
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
type
|
||||||
|
t1 = class
|
||||||
|
l: List<Action0> := new List<Action0>;
|
||||||
|
static procedure operator+=(a: t1; d: Action0);
|
||||||
|
begin
|
||||||
|
a.l.Add(d);
|
||||||
|
end;
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
var i: integer;
|
||||||
|
|
||||||
|
begin
|
||||||
|
var a := new t1;
|
||||||
|
a += ()->Inc(i);
|
||||||
|
a.l[0]();
|
||||||
|
assert(i = 1);
|
||||||
|
end.
|
||||||
8
TestSuite/lambdas12.pas
Normal file
8
TestSuite/lambdas12.pas
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
var i: integer;
|
||||||
|
|
||||||
|
begin
|
||||||
|
var l := new List<Action0>;
|
||||||
|
l += ()->Inc(i);
|
||||||
|
l[0]();
|
||||||
|
assert(i = 1);
|
||||||
|
end.
|
||||||
10
TestSuite/lambdas13.pas
Normal file
10
TestSuite/lambdas13.pas
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
type TProc = procedure;
|
||||||
|
|
||||||
|
var i: integer;
|
||||||
|
|
||||||
|
begin
|
||||||
|
var l := new List<TProc>;
|
||||||
|
l += ()->Inc(i);
|
||||||
|
l[0];
|
||||||
|
assert(i = 1);
|
||||||
|
end.
|
||||||
21
TestSuite/lambdas14.pas
Normal file
21
TestSuite/lambdas14.pas
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
var i: integer;
|
||||||
|
type
|
||||||
|
t1 = class
|
||||||
|
|
||||||
|
static procedure operator+=(a: t1; d: System.Action<integer>);
|
||||||
|
begin
|
||||||
|
i := 1;
|
||||||
|
end;
|
||||||
|
static procedure operator+=(a: t1; d: Action0);
|
||||||
|
begin
|
||||||
|
i := 2;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
var a := new t1;
|
||||||
|
a += ()->Writeln(1);
|
||||||
|
assert(i = 2);
|
||||||
|
a += (x: integer)->Writeln(1);
|
||||||
|
assert(i = 1);
|
||||||
|
end.
|
||||||
|
|
@ -260,7 +260,7 @@ namespace PascalABCCompiler.TreeConverter
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Вывод типа параметров лямбд и типа возвращаемого значения при присваивании лямбды переменной
|
/// Вывод типа параметров лямбд и типа возвращаемого значения при присваивании лямбды переменной
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void InferTypesFromVarStmt(type_node leftType, function_lambda_definition lambdaDef, syntax_tree_visitor visitor)
|
public static void InferTypesFromVarStmt(type_node leftType, function_lambda_definition lambdaDef, syntax_tree_visitor visitor, Operators op = Operators.Undefined)
|
||||||
{
|
{
|
||||||
if (lambdaDef == null)
|
if (lambdaDef == null)
|
||||||
return;
|
return;
|
||||||
|
|
@ -271,7 +271,47 @@ namespace PascalABCCompiler.TreeConverter
|
||||||
if (dii_left == null)
|
if (dii_left == null)
|
||||||
{
|
{
|
||||||
if (leftType != SystemLibrary.SystemLibrary.system_delegate_type)
|
if (leftType != SystemLibrary.SystemLibrary.system_delegate_type)
|
||||||
visitor.AddError(visitor.get_location(lambdaDef), "ILLEGAL_LAMBDA_VARIABLE_TYPE");
|
{
|
||||||
|
if (op != Operators.Undefined)
|
||||||
|
{
|
||||||
|
var sil = leftType.find_in_type(name_reflector.get_name(op));
|
||||||
|
if (sil.Count > 0)
|
||||||
|
{
|
||||||
|
foreach (SymbolInfo si in sil)
|
||||||
|
{
|
||||||
|
if (si.sym_info is function_node)
|
||||||
|
{
|
||||||
|
function_node fn = si.sym_info as function_node;
|
||||||
|
if (fn.parameters.Count == 2)
|
||||||
|
{
|
||||||
|
dii_left = (delegate_internal_interface)fn.parameters[1].type.get_internal_interface(internal_interface_kind.delegate_interface);
|
||||||
|
if (dii_left != null)
|
||||||
|
break;
|
||||||
|
if (fn.parameters[1].type.is_generic_parameter)
|
||||||
|
{
|
||||||
|
compiled_type_node ctn = leftType as compiled_type_node;
|
||||||
|
common_type_node ctn2 = leftType as common_type_node;
|
||||||
|
if (ctn != null && ctn.is_generic_type_instance && fn.parameters[0].type.is_generic_type_instance && ctn.original_generic == fn.parameters[0].type.original_generic)
|
||||||
|
{
|
||||||
|
dii_left = (delegate_internal_interface)ctn.generic_params[0].get_internal_interface(internal_interface_kind.delegate_interface);
|
||||||
|
if (dii_left != null)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ctn2 != null && ctn2.is_generic_type_instance && ctn2.instance_params.Count > 0 && fn.parameters[0].type.is_generic_type_instance && ctn2.original_generic == fn.parameters[0].type.original_generic)
|
||||||
|
{
|
||||||
|
dii_left = (delegate_internal_interface)ctn2.instance_params[0].get_internal_interface(internal_interface_kind.delegate_interface);
|
||||||
|
if (dii_left != null)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dii_left == null)
|
||||||
|
visitor.AddError(visitor.get_location(lambdaDef), "ILLEGAL_LAMBDA_VARIABLE_TYPE");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -135,7 +135,7 @@ namespace PascalABCCompiler.TreeConverter
|
||||||
{
|
{
|
||||||
#region Вывод параметров лямбда-выражения
|
#region Вывод параметров лямбда-выражения
|
||||||
|
|
||||||
LambdaHelper.InferTypesFromVarStmt(to.type, fromAsLambda, this); //lroman//
|
LambdaHelper.InferTypesFromVarStmt(to.type, fromAsLambda, this, _assign.operator_type); //lroman//
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue