This commit is contained in:
Ivan Bondarev 2023-05-17 21:07:00 +02:00
commit 41d9e2ab1b
11 changed files with 69 additions and 13 deletions

View file

@ -15,7 +15,7 @@ internal static class RevisionClass
public const string Major = "3";
public const string Minor = "9";
public const string Build = "0";
public const string Revision = "3280";
public const string Revision = "3282";
public const string MainVersion = Major + "." + Minor;
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;

View file

@ -1,4 +1,4 @@
%COREVERSION%=0
%REVISION%=3280
%REVISION%=3282
%MINOR%=9
%MAJOR%=3

View file

@ -1 +1 @@
3.9.0.3280
3.9.0.3282

View file

@ -1 +1 @@
!define VERSION '3.9.0.3280'
!define VERSION '3.9.0.3282'

View file

@ -46956,7 +46956,8 @@ namespace PascalABCCompiler.SyntaxTree
///<summary>
///
///Это внутри begin:var (a,b) := (1,2);
///</summary>
[Serializable]
public partial class assign_var_tuple : statement
@ -50962,7 +50963,7 @@ namespace PascalABCCompiler.SyntaxTree
///<summary>
///
///Это только в секции до begin: var (a,b) := (3,4); begin
///</summary>
[Serializable]
public partial class var_tuple_def_statement : var_def_statement

View file

@ -3520,7 +3520,7 @@
<HelpData Key="assign_tuple" Value="" />
<HelpData Key="assign_tuple.expr" Value="" />
<HelpData Key="assign_tuple.vars" Value="" />
<HelpData Key="assign_var_tuple" Value="" />
<HelpData Key="assign_var_tuple" Value="Это внутри begin:var (a,b) := (1,2);&#xD;&#xA;" />
<HelpData Key="assign_var_tuple.expr" Value="" />
<HelpData Key="assign_var_tuple.idents" Value="" />
<HelpData Key="attribute" Value="" />
@ -4858,7 +4858,7 @@
<HelpData Key="var_statement." Value="" />
<HelpData Key="var_statement.override string ToString()" Value="" />
<HelpData Key="var_statement.var_def" Value="" />
<HelpData Key="var_tuple_def_statement" Value="" />
<HelpData Key="var_tuple_def_statement" Value="Это только в секции до begin: var (a,b) := (3,4); begin" />
<HelpData Key="variable_definitions" Value="Секция описания переменных (до beginа). Состоит из var_def_statement. Не путать с var_statement - однострочным описанием переменной внутри begin-end" />
<HelpData Key="variable_definitions." Value="" />
<HelpData Key="variable_definitions.override string ToString()" Value="" />

View file

@ -120,6 +120,7 @@ namespace SyntaxVisitors.SugarVisitors
visit(assvartup.expr); // В assvartup.expr могут содержаться лямбды, в которых будут другие assign_var_tuple.
// И вообще другой синтаксический сахар, размещённый в этом визиторе
}
public override void visit(var_tuple_def_statement vtd)
{
// Состоит из var_def_statements. Некоторые являются var_tuple_def_statement

View file

@ -19,6 +19,13 @@ namespace SyntaxVisitors.SugarVisitors
get { return new TupleVisitor(); }
}
private int num = 0;
public string UniqueName()
{
num++;
return "#tup_vis"+num.ToString();
}
public override void visit(read_accessor_name wn)
{
DefaultVisit(wn);
@ -48,6 +55,8 @@ namespace SyntaxVisitors.SugarVisitors
ProcessNode(ls.to_statement);
}
// Здесь раскрываются ситуации когда справа - кортеж с константами: var (a,b) := (1,2) и только это.
// Остальное раскрывается в AssignTuplesDesugarVisitor
public override void visit(assign_var_tuple assvartup)
{
if (assvartup.expr is tuple_node tn && tn.el.expressions.All(ex => ex is const_node) && !tn.el.expressions.Any(ex => ex is nil_const))
@ -94,6 +103,33 @@ namespace SyntaxVisitors.SugarVisitors
}
ReplaceStatementUsingParent(asstup, sl);
}
else if (asstup.expr is tuple_node tn1 && !tn1.el.expressions.Any(ex => ex is nil_const))
{
var n = asstup.vars.variables.Count();
if (n > tn1.el.Count)
throw new SyntaxVisitorError("TOO_MANY_ELEMENTS_ON_LEFT_SIDE_OF_TUPLE_ASSIGNMENT", asstup.vars.variables[0]);
var sl = new List<statement>();
for (var i = 0; i < n; i++)
{
var temp_id = new ident(UniqueName(), tn1.el.expressions[i].source_context);
var var_def = new var_def_statement(temp_id, tn1.el.expressions[i], tn1.el.expressions[i].source_context);
var a = new var_statement(var_def, tn1.el.expressions[i].source_context);
sl.Add(a);
}
//for (var i = 0; i < n; i++)
for (var i = n-1; i >=0; i--)
{
var a = new assign(asstup.vars.variables[i],
(sl[i] as var_statement).var_def.vars.idents[0],
Operators.Assignment,
asstup.vars.variables[i].source_context);
sl.Add(a);
}
ReplaceStatementUsingParent(asstup, sl);
}
else
{
DefaultVisit(asstup);
@ -111,6 +147,7 @@ namespace SyntaxVisitors.SugarVisitors
}
}
// А это по идее до begin - там немного другие узлы и внешний контекст
public override void visit(var_tuple_def_statement vtd)
{
if (vtd.inital_value is tuple_node tn && tn.el.expressions.All(ex => ex is const_node) && !tn.el.expressions.Any(ex => ex is nil_const))

View file

@ -3000,8 +3000,9 @@ namespace PascalABCCompiler.TreeConverter
return AddError<function_node>(new SeveralFunctionsCanBeCalled(loc, list)); // или другое сообщение
// Теперь раз в list осталась одна функция, найти её в functions и только её и оставить
functions.RemoveAll(fun => fun.sym_info != list[0]);
if (functions.Count == 0)
// Надо делать копию functions иначе это влияет на следующий код
var functions1 = functions.Where(fun => fun.sym_info == list[0]).ToList();
if (functions1.Count == 0)
return AddError<function_node>(new NoFunctionWithSameArguments(FunctionName, loc, true)); // это не должно случиться, но вдруг
// Вот и в functions осталась одна функция
// Теперь делаем словарь сопоставлений именам -> expression_node (в параметрах)
@ -3016,7 +3017,7 @@ namespace PascalABCCompiler.TreeConverter
// Я бы очистил хвост parameters и добавлял бы в него как раньше параметры по умолчанию
parameters.remove_range(indexOfFirstNamedArgumentSem, parameters.Count - indexOfFirstNamedArgumentSem); // удалить хвост
var fun1 = functions[0].sym_info as function_node; // это - единственная функция
var fun1 = functions1[0].sym_info as function_node; // это - единственная функция
var is_ext = fun1.is_extension_method;
for (int i = indexOfFirstNamedArgument + (is_ext ? 1 : 0); i < fun1.parameters.Count; i++) // сверить это с другим кодом
{
@ -3031,7 +3032,7 @@ namespace PascalABCCompiler.TreeConverter
// syntax_nodes_parameters мне кажется всё испортят - там именованные аргументы стоят не на своих местах!!!
// Это единственный - опасный и потенциально с ошибками вызов!
// Но ощущение, что всё верно, т.к. это нужно только для параметров лямбд, а у именованных аргументов их быть не может
list = select_function_helper(parameters, functions, loc, syntax_nodes_parameters, only_from_not_extensions, out err_out);
list = select_function_helper(parameters, functions1, loc, syntax_nodes_parameters, only_from_not_extensions, out err_out);
if (err_out != null)
return AddError<function_node>(err_out);
return list[0];

View file

@ -5910,6 +5910,9 @@ namespace PascalABCCompiler.TreeConverter
// Семантическая разница между exprs.Count и s_n_p.Count равна 1 !!! Только здесь! И вот ее и передавать!
// exprs.Count = 3; s_n_p = 2; false - не удаляем 1 параметр
// Добавил последний параметр = 1 - это единственное место где длина exprs на 1 больше
// Это первый вызов. Будет второй поэтому надо сохранить копию expr до вызова
var exprs_copy = exprs.Clone();
fn = convertion_data_and_alghoritms.select_function(exprs, sil, subloc, syntax_nodes_parameters, false, 1);
if (fn == null && skip_first_parameter)
{
@ -5921,8 +5924,10 @@ namespace PascalABCCompiler.TreeConverter
Errors.Error last_err = LastError();
skip_first_parameter = false;
sil = tmp_sil;
exprs = exprs_copy;
exprs.remove_at(0);
// exprs.Count = 2; s_n_p = 2; true - удаляем 1 параметр, пропускаем расширения
// Только для методов, исключая методы расширения
fn = convertion_data_and_alghoritms.select_function(exprs, sil, subloc, syntax_nodes_parameters,true);
if (fn == null)
{
@ -5943,8 +5948,11 @@ namespace PascalABCCompiler.TreeConverter
throw last_err;
}
}
// Это значит, что нашли метод расширения, но на всякий случай ищем метод поскольку он имеет приоритет
else if (fn != null && skip_first_parameter && sil.Count() > 1 && !sil.HasOnlyExtensionMethods())
{
var exprs_saved = exprs; // запомнили то что нашли - вдруг здесь не найдем
exprs = exprs_copy; // восстановили начальное exprs
function_node tmp_fn = fn;
exprs.remove_at(0);
sil = tmp_sil;
@ -5954,7 +5962,8 @@ namespace PascalABCCompiler.TreeConverter
{
fn = tmp_fn;
RemoveLastError();
exprs.AddElementFirst(exp);
exprs = exprs_saved; // восстановили - т.к. здесь не нашли
//exprs.AddElementFirst(exp);
}
}
}

View file

@ -13,6 +13,13 @@ namespace PascalABCCompiler.TreeRealization
public class expressions_list : extended_collection<expression_node>
{
public override string ToString() => string.Join(", ", this._elements);
public expressions_list Clone()
{
var exprl = new expressions_list();
foreach (var elem in this)
exprl.AddElement(elem);
return exprl;
}
}
[Serializable]