Именованные аргументы.

Малое покрытие тестами
This commit is contained in:
Mikhalkovich Stanislav 2023-05-04 23:58:43 +03:00
parent 19999eb0ca
commit 49c432411a
14 changed files with 125 additions and 30 deletions

View file

@ -15,7 +15,7 @@ internal static class RevisionClass
public const string Major = "3";
public const string Minor = "8";
public const string Build = "3";
public const string Revision = "3270";
public const string Revision = "3271";
public const string MainVersion = Major + "." + Minor;
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;

View file

@ -1,4 +1,4 @@
%COREVERSION%=3
%REVISION%=3270
%MINOR%=8
%REVISION%=3271
%COREVERSION%=3
%MAJOR%=3

View file

@ -2,7 +2,7 @@
// This CSharp output file generated by Gardens Point LEX
// Version: 1.1.3.301
// Machine: DESKTOP-G8V08V4
// DateTime: 03.05.2023 20:40:49
// DateTime: 04.05.2023 13:28:23
// UserName: ?????????
// GPLEX input file <ABCPascal.lex>
// GPLEX frame file <embedded resource>

View file

@ -3268,8 +3268,8 @@ expr_with_func_decl_lambda
expr_with_func_decl_lambda_ass
: expr
{ $$ = $1; }
| tkIdentifier tkAssign expr
{ $$ = $3; }
| identifier tkAssign expr_l1
{ $$ = new name_assign_expr($1,$3,@$); }
| func_decl_lambda
{ $$ = $1; }
| tkInherited

View file

@ -2,9 +2,9 @@
// GPPG version 1.3.6
// Machine: DESKTOP-G8V08V4
// DateTime: 03.05.2023 20:40:49
// DateTime: 04.05.2023 13:28:23
// UserName: ?????????
// Input file <ABCPascal.y>
// Input file <D:\PABC_Git\Parsers\PascalABCParserNewSaushkin\ABCPascal.y>
// options: no-lines gplex
@ -60,7 +60,7 @@ public abstract class ScanBase : AbstractScanner<PascalABCSavParser.Union,LexLoc
public partial class GPPGParser: ShiftReduceParser<PascalABCSavParser.Union, LexLocation>
{
// Verbatim content from ABCPascal.y
// Verbatim content from D:\PABC_Git\Parsers\PascalABCParserNewSaushkin\ABCPascal.y
// <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD> GPPGParser, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> gppg
public syntax_tree_node root; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
@ -72,7 +72,7 @@ public partial class GPPGParser: ShiftReduceParser<PascalABCSavParser.Union, Lex
public ParserLambdaHelper lambdaHelper = new ParserLambdaHelper();
public GPPGParser(AbstractScanner<PascalABCSavParser.Union, LexLocation> scanner) : base(scanner) { }
// End verbatim content from ABCPascal.y
// End verbatim content from D:\PABC_Git\Parsers\PascalABCParserNewSaushkin\ABCPascal.y
#pragma warning disable 649
private static Dictionary<int, string> aliasses;
@ -549,7 +549,7 @@ public partial class GPPGParser: ShiftReduceParser<PascalABCSavParser.Union, Lex
states[371] = new State(-763);
states[372] = new State(new int[]{139,1461,141,47,83,49,84,50,78,52,76,53,157,54,85,55,43,390,40,428,8,430,19,269,20,274,142,152,144,153,143,155,152,157,155,158,154,159,153,160,74,462},new int[]{-111,373,-147,426,-151,48,-152,51,-191,427,-257,437,-295,438,-15,700,-165,149,-167,150,-166,154,-16,156,-17,439,-112,465,-58,701});
states[373] = new State(new int[]{8,374,7,385,140,420,4,421,108,-769,109,-769,110,-769,111,-769,112,-769,90,-769,10,-769,96,-769,99,-769,31,-769,102,-769,2,-769,136,-769,134,-769,116,-769,115,-769,129,-769,130,-769,131,-769,132,-769,128,-769,114,-769,113,-769,126,-769,127,-769,124,-769,6,-769,5,-769,118,-769,123,-769,121,-769,119,-769,122,-769,120,-769,135,-769,133,-769,16,-769,9,-769,98,-769,12,-769,97,-769,30,-769,83,-769,82,-769,81,-769,80,-769,79,-769,84,-769,13,-769,117,-769,74,-769,49,-769,56,-769,139,-769,141,-769,78,-769,76,-769,157,-769,85,-769,43,-769,40,-769,19,-769,20,-769,142,-769,144,-769,143,-769,152,-769,155,-769,154,-769,153,-769,55,-769,89,-769,38,-769,23,-769,95,-769,52,-769,33,-769,53,-769,100,-769,45,-769,34,-769,51,-769,58,-769,72,-769,70,-769,36,-769,68,-769,69,-769,11,-780,17,-780});
states[374] = new State(new int[]{54,42,142,152,144,153,143,155,152,157,155,158,154,159,153,160,61,162,11,358,133,362,114,367,113,368,140,369,139,383,141,1453,83,49,84,50,78,52,76,249,157,54,85,55,43,390,40,1456,8,652,19,269,20,274,74,462,38,598,5,607,18,674,35,683,42,687,9,-805},new int[]{-68,375,-72,377,-89,378,-87,379,-101,28,-99,29,-98,310,-105,320,-83,325,-82,331,-96,357,-15,43,-165,149,-167,150,-166,154,-16,156,-57,161,-199,380,-113,382,-132,372,-111,384,-147,445,-151,48,-152,51,-191,427,-257,437,-295,438,-17,439,-112,465,-58,466,-116,469,-173,470,-268,471,-97,472,-264,476,-266,477,-267,588,-240,589,-117,590,-242,597,-120,606,-323,1457,-100,659,-324,682,-71,1458,-88,650});
states[374] = new State(new int[]{54,42,142,152,144,153,143,155,152,157,155,158,154,159,153,160,61,162,11,358,133,362,114,367,113,368,140,369,139,383,141,47,83,49,84,50,78,52,76,249,157,54,85,55,43,390,40,1456,8,652,19,269,20,274,74,462,38,598,5,607,18,674,35,683,42,687,9,-805},new int[]{-68,375,-72,377,-89,378,-87,379,-101,28,-99,29,-98,310,-105,320,-83,325,-82,331,-96,357,-15,43,-165,149,-167,150,-166,154,-16,156,-57,161,-199,380,-113,382,-132,372,-111,384,-147,1453,-151,48,-152,51,-191,427,-257,437,-295,438,-17,439,-112,465,-58,466,-116,469,-173,470,-268,471,-97,472,-264,476,-266,477,-267,588,-240,589,-117,590,-242,597,-120,606,-323,1457,-100,659,-324,682,-71,1458,-88,650});
states[375] = new State(new int[]{9,376});
states[376] = new State(-785);
states[377] = new State(-804);
@ -1628,13 +1628,13 @@ public partial class GPPGParser: ShiftReduceParser<PascalABCSavParser.Union, Lex
states[1450] = new State(new int[]{12,1451});
states[1451] = new State(-795);
states[1452] = new State(new int[]{5,321,6,34});
states[1453] = new State(new int[]{108,1454,125,-825,8,-825,7,-825,140,-825,4,-825,15,-825,136,-825,134,-825,116,-825,115,-825,129,-825,130,-825,131,-825,132,-825,128,-825,114,-825,113,-825,126,-825,127,-825,124,-825,6,-825,5,-825,118,-825,123,-825,121,-825,119,-825,122,-825,120,-825,135,-825,133,-825,16,-825,9,-825,98,-825,13,-825,117,-825,11,-825,17,-825});
states[1454] = new State(new int[]{54,42,142,152,144,153,143,155,152,157,155,158,154,159,153,160,61,162,11,358,133,362,114,367,113,368,140,369,139,383,141,47,83,49,84,50,78,52,76,249,157,54,85,55,43,390,40,428,8,430,19,269,20,274,74,462,38,598,5,607},new int[]{-87,1455,-101,28,-99,29,-98,310,-105,320,-83,325,-82,331,-96,357,-15,43,-165,149,-167,150,-166,154,-16,156,-57,161,-199,380,-113,382,-132,372,-111,384,-147,426,-151,48,-152,51,-191,427,-257,437,-295,438,-17,439,-112,465,-58,466,-116,469,-173,470,-268,471,-97,472,-264,476,-266,477,-267,588,-240,589,-117,590,-242,597,-120,606});
states[1453] = new State(new int[]{108,1454,125,446,8,-786,7,-786,140,-786,4,-786,15,-786,136,-786,134,-786,116,-786,115,-786,129,-786,130,-786,131,-786,132,-786,128,-786,114,-786,113,-786,126,-786,127,-786,124,-786,6,-786,5,-786,118,-786,123,-786,121,-786,119,-786,122,-786,120,-786,135,-786,133,-786,16,-786,9,-786,98,-786,13,-786,117,-786,11,-786,17,-786});
states[1454] = new State(new int[]{54,42,142,152,144,153,143,155,152,157,155,158,154,159,153,160,61,162,11,358,133,362,114,367,113,368,140,369,139,383,141,47,83,49,84,50,78,52,76,249,157,54,85,55,43,390,40,428,8,430,19,269,20,274,74,462,38,598},new int[]{-101,1455,-99,29,-98,310,-105,450,-83,325,-82,331,-96,357,-15,43,-165,149,-167,150,-166,154,-16,156,-57,161,-199,380,-113,382,-132,372,-111,384,-147,426,-151,48,-152,51,-191,427,-257,437,-295,438,-17,439,-112,465,-58,466,-116,469,-173,470,-268,471,-97,472,-264,476,-266,477,-267,588,-240,589,-117,590,-242,597});
states[1455] = new State(-596);
states[1456] = new State(new int[]{141,47,83,49,84,50,78,52,76,53,157,54,85,55,9,-598,98,-594},new int[]{-147,429,-151,48,-152,51});
states[1457] = new State(new int[]{9,-597,98,-593});
states[1458] = new State(new int[]{98,1459});
states[1459] = new State(new int[]{54,42,142,152,144,153,143,155,152,157,155,158,154,159,153,160,61,162,11,358,133,362,114,367,113,368,140,369,139,383,141,1453,83,49,84,50,78,52,76,249,157,54,85,55,43,390,40,1456,8,652,19,269,20,274,74,462,38,598,5,607,18,674,35,683,42,687},new int[]{-89,1460,-88,444,-87,379,-101,28,-99,29,-98,310,-105,320,-83,325,-82,331,-96,357,-15,43,-165,149,-167,150,-166,154,-16,156,-57,161,-199,380,-113,382,-132,372,-111,384,-147,445,-151,48,-152,51,-191,427,-257,437,-295,438,-17,439,-112,465,-58,466,-116,469,-173,470,-268,471,-97,472,-264,476,-266,477,-267,588,-240,589,-117,590,-242,597,-120,606,-323,1457,-100,659,-324,682});
states[1459] = new State(new int[]{54,42,142,152,144,153,143,155,152,157,155,158,154,159,153,160,61,162,11,358,133,362,114,367,113,368,140,369,139,383,141,47,83,49,84,50,78,52,76,249,157,54,85,55,43,390,40,1456,8,652,19,269,20,274,74,462,38,598,5,607,18,674,35,683,42,687},new int[]{-89,1460,-88,444,-87,379,-101,28,-99,29,-98,310,-105,320,-83,325,-82,331,-96,357,-15,43,-165,149,-167,150,-166,154,-16,156,-57,161,-199,380,-113,382,-132,372,-111,384,-147,1453,-151,48,-152,51,-191,427,-257,437,-295,438,-17,439,-112,465,-58,466,-116,469,-173,470,-268,471,-97,472,-264,476,-266,477,-267,588,-240,589,-117,590,-242,597,-120,606,-323,1457,-100,659,-324,682});
states[1460] = new State(-589);
states[1461] = new State(-773);
states[1462] = new State(new int[]{141,47,83,49,84,50,78,52,76,53,157,54,85,55,152,157,155,158,154,159,153,160,114,367,113,368,142,152,144,153,143,155,8,665,12,-278,98,-278},new int[]{-271,1463,-272,1464,-93,180,-106,289,-107,290,-180,492,-147,206,-151,48,-152,51,-16,489,-199,490,-165,493,-167,150,-166,154});
@ -2461,7 +2461,7 @@ public partial class GPPGParser: ShiftReduceParser<PascalABCSavParser.Union, Lex
rules[593] = new Rule(-88, new int[]{-323});
rules[594] = new Rule(-88, new int[]{40});
rules[595] = new Rule(-89, new int[]{-87});
rules[596] = new Rule(-89, new int[]{141,108,-87});
rules[596] = new Rule(-89, new int[]{-147,108,-101});
rules[597] = new Rule(-89, new int[]{-323});
rules[598] = new Rule(-89, new int[]{40});
rules[599] = new Rule(-87, new int[]{-101});
@ -5766,8 +5766,8 @@ public partial class GPPGParser: ShiftReduceParser<PascalABCSavParser.Union, Lex
case 595: // expr_with_func_decl_lambda_ass -> expr
{ CurrentSemanticValue.ex = ValueStack[ValueStack.Depth-1].ex; }
break;
case 596: // expr_with_func_decl_lambda_ass -> tkIdentifier, tkAssign, expr
{ CurrentSemanticValue.ex = ValueStack[ValueStack.Depth-1].ex; }
case 596: // expr_with_func_decl_lambda_ass -> identifier, tkAssign, expr_l1
{ CurrentSemanticValue.ex = new name_assign_expr(ValueStack[ValueStack.Depth-3].id,ValueStack[ValueStack.Depth-1].ex,CurrentLocationSpan); }
break;
case 597: // expr_with_func_decl_lambda_ass -> func_decl_lambda
{ CurrentSemanticValue.ex = ValueStack[ValueStack.Depth-1].ex; }

View file

@ -1 +1 @@
3.8.3.3270
3.8.3.3271

View file

@ -1 +1 @@
!define VERSION '3.8.3.3270'
!define VERSION '3.8.3.3271'

View file

@ -3579,7 +3579,7 @@ namespace PascalABCCompiler.SyntaxTree
public void read_name_assign_expr(name_assign_expr _name_assign_expr)
{
read_syntax_tree_node(_name_assign_expr);
read_expression(_name_assign_expr);
_name_assign_expr.name = _read_node() as ident;
_name_assign_expr.expr = _read_node() as expression;
}

View file

@ -5446,7 +5446,7 @@ namespace PascalABCCompiler.SyntaxTree
public void write_name_assign_expr(name_assign_expr _name_assign_expr)
{
write_syntax_tree_node(_name_assign_expr);
write_expression(_name_assign_expr);
if (_name_assign_expr.name == null)
{
bw.Write((byte)0);

View file

@ -41925,7 +41925,7 @@ namespace PascalABCCompiler.SyntaxTree
///
///</summary>
[Serializable]
public partial class name_assign_expr : syntax_tree_node
public partial class name_assign_expr : expression
{
///<summary>
@ -42001,6 +42001,11 @@ namespace PascalABCCompiler.SyntaxTree
copy.Parent = this.Parent;
if (source_context != null)
copy.source_context = new SourceContext(source_context);
if (attributes != null)
{
copy.attributes = (attribute_list)attributes.Clone();
copy.attributes.Parent = copy;
}
if (name != null)
{
copy.name = (ident)name.Clone();
@ -42023,6 +42028,8 @@ namespace PascalABCCompiler.SyntaxTree
///<summary> Заполняет поля Parent в непосредственных дочерних узлах </summary>
public override void FillParentsInDirectChilds()
{
if (attributes != null)
attributes.Parent = this;
if (name != null)
name.Parent = this;
if (expr != null)
@ -42033,6 +42040,7 @@ namespace PascalABCCompiler.SyntaxTree
public override void FillParentsInAllChilds()
{
FillParentsInDirectChilds();
attributes?.FillParentsInAllChilds();
name?.FillParentsInAllChilds();
expr?.FillParentsInAllChilds();
}

View file

@ -2534,7 +2534,7 @@
</TagIndices>
</Tags>
</SyntaxNode>
<SyntaxNode Name="name_assign_expr" BaseName="syntax_tree_node">
<SyntaxNode Name="name_assign_expr" BaseName="expression">
<Fields>
<SyntaxField Name="name" SyntaxType="ident" />
<SyntaxField Name="expr" SyntaxType="expression" />

View file

@ -2881,11 +2881,88 @@ namespace PascalABCCompiler.TreeConverter
//Первый параметр - выходной. Он содержит выражения с необходимыми преобразованиями типов.
public function_node select_function(expressions_list parameters, List<SymbolInfo> functions, location loc, List<SyntaxTree.expression> syntax_nodes_parameters = null, bool only_from_not_extensions = false)
{
Errors.Error err_out;
var list = select_function_helper(parameters, functions, loc, syntax_nodes_parameters, only_from_not_extensions, out err_out);
if (err_out != null)
return AddError<function_node>(err_out);
return list[0];
// с какого номера начинаются именованные параметры
var indexOfFirstNamedArgument = -1;
if (syntax_nodes_parameters != null)
indexOfFirstNamedArgument = syntax_nodes_parameters.FindIndex(exp => exp is SyntaxTree.name_assign_expr);
if (indexOfFirstNamedArgument == -1)
{
Errors.Error err_out;
var list = select_function_helper(parameters, functions, loc, syntax_nodes_parameters, only_from_not_extensions, out err_out);
if (err_out != null)
return AddError<function_node>(err_out);
return list[0];
}
else
{
// сделаем копию parameters без именованных аргументов
var parameters_helper = new expressions_list();
for (int i = 0; i < indexOfFirstNamedArgument; i++)
parameters_helper.AddElement(parameters[i]);
Errors.Error err_out;
var list = select_function_helper(parameters_helper, functions, loc, syntax_nodes_parameters, only_from_not_extensions, out err_out);
if (list.Count == 0 && err_out != null)
return AddError<function_node>(err_out);
// Теперь ищем среди оставшихся параметров именованные
// Создадим множество имен именованных аргументов
var hs = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
for (int i = indexOfFirstNamedArgument; i < syntax_nodes_parameters.Count; i++)
{
var nae = syntax_nodes_parameters[i] as SyntaxTree.name_assign_expr;
hs.Add(nae.name.name);
}
// В syntax_nodes_parameters и parameters по идее должно быть одно и то же количество значений
// Удалим из functions все неподходящие, где нет таких имен параметров в оставшейся части
list.RemoveAll(ff =>
{
var names = ff.parameters.Skip(indexOfFirstNamedArgument).Select(par => par.name);
var hsnames = new HashSet<string>(names, StringComparer.OrdinalIgnoreCase);
return !hs.IsProperSubsetOf(hsnames);
// то есть все имена в именованных аргументах должны находиться среди оставшихся параметров по умолчанию
});
if (list.Count == 0)
return AddError<function_node>(new NoFunctionWithSameArguments(loc, true)); // или false - не знаю
if (list.Count > 1)
return AddError<function_node>(new SeveralFunctionsCanBeCalled(loc, list)); // или другое сообщение
// Теперь раз в list осталась одна функция, найти её в functions и только её и оставить
functions.RemoveAll(fun => fun.sym_info != list[0]);
if (functions.Count == 0)
return AddError<function_node>(new NoFunctionWithSameArguments(loc, true)); // это не должно случиться, но вдруг
// Вот и в functions осталась одна функция
// Теперь делаем словарь сопоставлений именам -> expression_node (в параметрах)
var dict = new Dictionary<string, expression_node>(StringComparer.OrdinalIgnoreCase); // Это словарь именованных аргументов
for (int i = indexOfFirstNamedArgument; i < syntax_nodes_parameters.Count; i++)
{
var nae = syntax_nodes_parameters[i] as SyntaxTree.name_assign_expr;
dict[nae.name.name] = parameters[i]; // parameters и syntax_nodes_parameters д.б.одной длины
}
// Вот теперь как-то хвост в parameters надо менять на параметры по умолчанию или на те, что хранятся в dict
// Я бы очистил хвост parameters и добавлял бы в него как раньше параметры по умолчанию
parameters.remove_range(indexOfFirstNamedArgument, parameters.Count - indexOfFirstNamedArgument); // удалить хвост
var fun1 = functions[0].sym_info as function_node;
for (int i = indexOfFirstNamedArgument; i < fun1.parameters.Count; i++) // сверить это с другим кодом
{
var par = fun1.parameters[i];
var paramexpr = par.default_value;
var name = par.name;
if (dict.ContainsKey(name))
paramexpr = dict[name]; // вместо значения по умолчанию взять значение именованного параметра
parameters.AddElement(paramexpr);
}
// И наконец всё готово!!!
// syntax_nodes_parameters мне кажется всё испортят - там именованные аргументы стоят не на своих местах!!!
// Это единственный - опасный и потенциально с ошибками вызов!
// Но ощущение, что всё верно, т.к. это нужно только для параметров лямбд, а у именованных аргументов их быть не может
list = select_function_helper(parameters, functions, loc, syntax_nodes_parameters, only_from_not_extensions, out err_out);
if (err_out != null)
return AddError<function_node>(err_out);
return list[0];
}
// для именованных параметров последовательность может быть такая
// Если именованных параметров при вызове нет, то - этот алгоритм. Если есть, то
// 1. Оставить только неименованные параметры и вызвать select_function_helper

View file

@ -19507,6 +19507,12 @@ namespace PascalABCCompiler.TreeConverter
return_value(create_constructor_call(tn, exprs, get_location(_new_expr.type), new Tuple<bool, List<expression>>(lambdas_are_in_parameters, syntax_nodes_parameters)));
}
public override void visit(SyntaxTree.name_assign_expr node)
{
var ex = convert_strong(node.expr); // на этом уровне имя никак не учитывать. Оно учтется ТОЛЬКО в select_function
return_value(ex);
}
public override void visit(SyntaxTree.where_type_specificator_list node)
{
throw new NotSupportedError(get_location(node));

View file

@ -50,7 +50,7 @@ namespace VisualPascalABCPlugins
{
return;
}
prepare_node_with_text(subnode,node_name+":"+subnode.GetType().Name);
prepare_node_with_text(subnode,node_name+": "+subnode.GetType().Name);
}
public void prepare_collection(IEnumerable inum,string collection_name)
@ -1145,8 +1145,12 @@ namespace VisualPascalABCPlugins
prepare_node(node.proc_body, "proc_body");
prepare_node(node.procdef, "procdef");
}
public override void visit(name_assign_expr node)
{
prepare_node(node.name, "name");
prepare_node(node.expr, "expr");
}
}
}