parent
05e4198ab4
commit
06a053ad74
|
|
@ -15,7 +15,7 @@ internal static class RevisionClass
|
|||
public const string Major = "3";
|
||||
public const string Minor = "5";
|
||||
public const string Build = "0";
|
||||
public const string Revision = "2139";
|
||||
public const string Revision = "2144";
|
||||
|
||||
public const string MainVersion = Major + "." + Minor;
|
||||
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
%MINOR%=5
|
||||
%REVISION%=2139
|
||||
%COREVERSION%=0
|
||||
%REVISION%=2144
|
||||
%MINOR%=5
|
||||
%MAJOR%=3
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
!define VERSION '3.5.0.2139'
|
||||
!define VERSION '3.5.0.2144'
|
||||
|
|
|
|||
18
TestSuite/lambda_proc_func_1.pas
Normal file
18
TestSuite/lambda_proc_func_1.pas
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
procedure p1(p: ()->());
|
||||
begin
|
||||
Assert(1=2);
|
||||
end;
|
||||
|
||||
procedure p1<T>(f: ()->T);
|
||||
begin
|
||||
Assert(1=1);
|
||||
end;
|
||||
|
||||
begin
|
||||
p1(
|
||||
function->
|
||||
begin
|
||||
Result := 1;
|
||||
end
|
||||
)
|
||||
end.
|
||||
20
TestSuite/lambda_proc_func_2.pas
Normal file
20
TestSuite/lambda_proc_func_2.pas
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
procedure p1(p: procedure);
|
||||
begin
|
||||
Assert(1=2)
|
||||
//write('procedure')
|
||||
end;
|
||||
|
||||
procedure p1(f: ()->integer);
|
||||
begin
|
||||
Assert(1=1)
|
||||
//write('function')
|
||||
end;
|
||||
|
||||
begin
|
||||
p1(
|
||||
function->
|
||||
begin
|
||||
Result := 1;
|
||||
end
|
||||
)
|
||||
end.
|
||||
|
|
@ -323,7 +323,7 @@ namespace PascalABCCompiler.TreeConverter
|
|||
// lambdaDef.usedkeyword == 1 // function
|
||||
var b = lambdaDef.usedkeyword == 0 && TryConvertFuncLambdaBodyWithMethodCallToProcLambdaBody(lambdaDef); // пытаться конвертировать только если мы явно не указали, что это функция
|
||||
if (!b)
|
||||
throw new SimpleSemanticError(visitor.get_location(lambdaDef), "UNABLE_TO_CONVERT_FUNCTIONAL_TYPE_TO_PROCEDURAL_TYPE");
|
||||
visitor.AddError(visitor.get_location(lambdaDef), "UNABLE_TO_CONVERT_FUNCTIONAL_TYPE_TO_PROCEDURAL_TYPE");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1731,7 +1731,7 @@ namespace PascalABCCompiler.TreeConverter
|
|||
// Эту функцию можно написать оптимальнее - без внешнего while. Например.
|
||||
// Запускаем алгоритм сортировки на частичном порядке. Ищем min из оставшихся и меняем его местами с текущим.
|
||||
// Потом проходимся по частично отсортированному и из пары соседних удаляем тот, что меньше
|
||||
private void functions_delete_greater(List<function_node> set_of_possible_functions, possible_type_convertions_list_list tcll)
|
||||
private void delete_greater_functions(List<function_node> set_of_possible_functions, possible_type_convertions_list_list tcll)
|
||||
{
|
||||
bool remove = true;
|
||||
while (remove)
|
||||
|
|
@ -1958,6 +1958,44 @@ namespace PascalABCCompiler.TreeConverter
|
|||
Errors.Error err = null;
|
||||
possible_type_convertions_list tc = get_conversions(parameters, set_of_possible_functions[i].parameters,
|
||||
is_alone_method_defined, loc, out err);
|
||||
|
||||
var proc_func_OK_flag = true;
|
||||
// Цикл по всем параметрам. Если формальный - процедура, а фактический - функция, то tc делать = null и взводить специальный флаг чтобы не возиться с делегатами дальше
|
||||
|
||||
if (set_of_possible_functions.Count >= 2 && set_of_possible_functions[i].parameters.Count == parameters.Count)
|
||||
for (var k = 0; k < parameters.Count; k++)
|
||||
{
|
||||
var fact = parameters[k];
|
||||
var formal = set_of_possible_functions[i].parameters[k];
|
||||
if (fact.type is delegated_methods dm)
|
||||
{
|
||||
var fact_is_function_with_return_value = dm.proper_methods.Count > 0 && dm.proper_methods[0].function.return_value_type != null;
|
||||
var form_is_procedure = false;
|
||||
|
||||
//if (formal.type is compiled_type_node || // Это на случай System.Action или ()->()
|
||||
// formal.type is compiled_type_node) // Это на случай procedure
|
||||
{
|
||||
var d = formal.type.internal_interfaces;
|
||||
if (d != null && d.ContainsKey(internal_interface_kind.delegate_interface))
|
||||
{
|
||||
var q = d[internal_interface_kind.delegate_interface] as delegate_internal_interface;
|
||||
if (q != null && q.return_value_type == null) // Это процедура
|
||||
form_is_procedure = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (fact_is_function_with_return_value && form_is_procedure)
|
||||
{
|
||||
proc_func_OK_flag = false;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (proc_func_OK_flag == false)
|
||||
tc = null;
|
||||
// Вот здесь - если фактический параметр - функция, а формальный - процедура хотя бы в одном параметре, то надо нивелировать все преобразования и присваивать tc=null и не влазить в следующий код!!!
|
||||
if (err != null)
|
||||
return AddError<function_node>(err);
|
||||
//fix dlja lambd i extension metodov (c->c.IsDigit)
|
||||
|
|
@ -2017,7 +2055,9 @@ namespace PascalABCCompiler.TreeConverter
|
|||
return set_of_possible_functions[0];
|
||||
}
|
||||
|
||||
functions_delete_greater(set_of_possible_functions,tcll); // SSM 06/06/19 refactoring
|
||||
// Если остались параметры функция и процедура - обе без параметров, но функция возвращает T, то функция будет удалена этим алгоритмом, что неправильно!
|
||||
// Потому что не учитывается вызов - в вызове может быть функция!!
|
||||
delete_greater_functions(set_of_possible_functions,tcll); // SSM 06/06/19 refactoring
|
||||
|
||||
//Тупая заглушка для примитивных типов. иначе не работает +=, у нас лишком много неявных приведений
|
||||
//в дальнейшем может вызвать странное поведение, это надо проверить
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ namespace PascalABCCompiler.TreeRealization
|
|||
private System.Collections.Generic.Dictionary<type_node, type_intersection_node> type_intersections;
|
||||
//new System.Collections.Generic.Dictionary<type_node, type_intersection_node>();
|
||||
private List<type_node> generated_type_intersections = null;//new List<type_node>();
|
||||
private System.Collections.Generic.Dictionary<internal_interface_kind, internal_interface> internal_interfaces;
|
||||
public System.Collections.Generic.Dictionary<internal_interface_kind, internal_interface> internal_interfaces;
|
||||
//new System.Collections.Generic.Dictionary<internal_interface_kind, internal_interface>();
|
||||
|
||||
//private System.Collections.Generic.Dictionary<type_node, type_conversion> explicit_type_conversions =
|
||||
|
|
|
|||
Loading…
Reference in a new issue