будь он неладен
This commit is contained in:
Mikhalkovich Stanislav 2019-06-23 14:43:27 +03:00
parent 05e4198ab4
commit 06a053ad74
8 changed files with 86 additions and 8 deletions

View file

@ -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;

View file

@ -1,4 +1,4 @@
%MINOR%=5
%REVISION%=2139
%COREVERSION%=0
%REVISION%=2144
%MINOR%=5
%MAJOR%=3

View file

@ -1 +1 @@
!define VERSION '3.5.0.2139'
!define VERSION '3.5.0.2144'

View 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.

View 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.

View file

@ -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");
}
}
}

View file

@ -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
//Тупая заглушка для примитивных типов. иначе не работает +=, у нас лишком много неявных приведений
//в дальнейшем может вызвать странное поведение, это надо проверить

View file

@ -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 =