# Conflicts:
#	Parsers/PascalABCParserNewSaushkin/ABCPascal.cs
#	Parsers/PascalABCParserNewSaushkin/ABCPascalYacc.cs
This commit is contained in:
Ivan Bondarev 2021-03-28 14:10:45 +02:00
commit 18e948a328
21 changed files with 4126 additions and 2148 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 = "0";
public const string Revision = "2864";
public const string Revision = "2872";
public const string MainVersion = Major + "." + Minor;
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;

View file

@ -1,4 +1,4 @@
%COREVERSION%=0
%REVISION%=2864
%REVISION%=2872
%MINOR%=8
%MAJOR%=3

Binary file not shown.

View file

@ -1,9 +1,15 @@
//
// This CSharp output file generated by Gardens Point LEX
// Version: 1.1.3.301
<<<<<<< HEAD
// Machine: DESKTOP-2BJCJ7I
// DateTime: 28.03.2021 12:12:58
// UserName: ibond
=======
// Machine: DESKTOP-G8V08V4
// DateTime: 25.03.2021 22:57:24
// UserName: ?????????
>>>>>>> 529bc2137e92d657255e34c5bfe9b63138654c02
// GPLEX input file <ABCPascal.lex>
// GPLEX frame file <embedded resource>
//

View file

@ -63,7 +63,7 @@
%type <ex> const_factor const_factor_without_unary_op const_variable_2 const_term const_variable literal_or_number unsigned_number variable_or_literal_or_number
%type <stn> program_block
%type <ob> optional_var class_attribute class_attributes class_attributes1
%type <ob> lambda_unpacked_params lambda_unpacked_params_or_id lambda_list_of_unpacked_params_or_id
%type <ob> lambda_unpacked_params_or_id lambda_list_of_unpacked_params_or_id
%type <stn> member_list_section optional_component_list_seq_end
%type <stn> const_decl only_const_decl
%type <stn> const_decl_sect
@ -83,9 +83,11 @@
%type <stn> exception_handler_list
%type <stn> exception_identifier
%type <stn> typed_const_list1 typed_const_list optional_expr_list elem_list optional_expr_list_with_bracket expr_list const_elem_list1 /*const_expr_list*/ case_label_list const_elem_list optional_const_func_expr_list elem_list1
%type <stn> enumeration_id expr_l1_list
%type <stn> enumeration_id expr_l1_or_unpacked_list
// %type <stn> expr_l1_list
%type <stn> enumeration_id_list
%type <ex> const_simple_expr term term1 typed_const typed_const_plus typed_var_init_expression expr expr_with_func_decl_lambda const_expr const_relop_expr elem range_expr const_elem array_const factor factor_without_unary_op relop_expr expr_dq expr_l1 expr_l1_func_decl_lambda expr_l1_for_lambda simple_expr range_term range_factor
%type <ex> const_simple_expr term term1 typed_const typed_const_plus typed_var_init_expression expr expr_with_func_decl_lambda const_expr const_relop_expr elem range_expr const_elem array_const factor factor_without_unary_op relop_expr expr_dq
%type <ex> lambda_unpacked_params expr_l1 expr_l1_or_unpacked expr_l1_func_decl_lambda expr_l1_for_lambda simple_expr range_term range_factor
%type <ex> external_directive_ident init_const_expr case_label variable var_reference /*optional_write_expr*/ optional_read_expr simple_expr_or_nothing var_question_point expr_l1_for_question_expr expr_l1_for_new_question_expr
%type <ob> for_cycle_type
%type <ex> format_expr format_const_expr const_expr_or_nothing /* simple_expr_with_deref_or_nothing simple_expr_with_deref expr_l1_for_indexer*/
@ -787,16 +789,16 @@ const_name
{ $$ = $1; }
;
expr_l1_list
: expr_l1
{
$$ = new expression_list($1, @$);
}
| expr_l1_list tkComma expr_l1
{
$$ = ($1 as expression_list).Add($3, @$);
}
;
//expr_l1_list
// : expr_l1
// {
// $$ = new expression_list($1, @$);
// }
// | expr_l1_list tkComma expr_l1
// {
// $$ = ($1 as expression_list).Add($3, @$);
// }
// ;
const_relop_expr
: const_simple_expr
@ -4023,8 +4025,13 @@ default_expr
;
tuple
: tkRoundOpen expr_l1 tkComma expr_l1_list lambda_type_ref optional_full_lambda_fp_list tkRoundClose // lambda_type_ref optional_full_lambda_fp_list íóæíî îñòàâèòü ÷òîáû íå áûëî êîíôëèêòîâ ñ ãðàììàòèêîé ëÿìáä
: tkRoundOpen expr_l1_or_unpacked tkComma expr_l1_or_unpacked_list lambda_type_ref optional_full_lambda_fp_list tkRoundClose // lambda_type_ref optional_full_lambda_fp_list íóæíî îñòàâèòü ÷òîáû íå áûëî êîíôëèêòîâ ñ ãðàììàòèêîé ëÿìáä
{
if ($2 is unpacked_list_of_ident_or_list)
parsertools.AddErrorFromResource("EXPRESSION_EXPECTED",@2);
foreach (var ex in ($4 as expression_list).expressions)
if (ex is unpacked_list_of_ident_or_list)
parsertools.AddErrorFromResource("EXPRESSION_EXPECTED",ex.source_context);
/*if ($5 != null)
parsertools.AddErrorFromResource("BAD_TUPLE",@5);
if ($6 != null)
@ -4728,15 +4735,15 @@ lambda_unpacked_params
: tkBackSlashRoundOpen lambda_list_of_unpacked_params_or_id tkComma lambda_unpacked_params_or_id tkRoundClose
{
// ðåçóëüòàò íàäî ïðèñâîèòü êàêîìó òî ñàõàðíîìó ïîëþ â function_lambda_definition
$$ = $2;
($$ as List<ident_or_list>).Add($4 as ident_or_list);
($2 as unpacked_list_of_ident_or_list).Add($4 as ident_or_list);
$$ = $2 as unpacked_list_of_ident_or_list;
}
;
lambda_unpacked_params_or_id
: lambda_unpacked_params // ident_or_list
{
$$ = new ident_or_list($1 as List<ident_or_list>);
$$ = new ident_or_list($1 as unpacked_list_of_ident_or_list);
}
| identifier // ident_or_list
{
@ -4747,17 +4754,38 @@ lambda_unpacked_params_or_id
lambda_list_of_unpacked_params_or_id
: lambda_unpacked_params_or_id
{
$$ = new List<ident_or_list>();
($$ as List<ident_or_list>).Add($1 as ident_or_list);
$$ = new unpacked_list_of_ident_or_list();
($$ as unpacked_list_of_ident_or_list).Add($1 as ident_or_list);
($$ as unpacked_list_of_ident_or_list).source_context = @1;
}
| lambda_list_of_unpacked_params_or_id tkComma lambda_unpacked_params_or_id
{
$$ = $1;
($$ as List<ident_or_list>).Add($3 as ident_or_list);
($$ as unpacked_list_of_ident_or_list).Add($3 as ident_or_list);
($$ as unpacked_list_of_ident_or_list).source_context = LexLocation.MergeAll(@1,@3);
}
;
expr_l1_or_unpacked
: expr_l1
{ $$ = $1; }
| lambda_unpacked_params
{ $$ = $1; }
;
expr_l1_or_unpacked_list
: expr_l1_or_unpacked
{
$$ = new expression_list($1, @$);
}
| expr_l1_or_unpacked_list tkComma expr_l1_or_unpacked
{
$$ = ($1 as expression_list).Add($3, @$);
}
;
func_decl_lambda
: identifier tkArrow lambda_function_body
{
@ -4810,12 +4838,53 @@ func_decl_lambda
$$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formalPars, $8, sl, @$);
else $$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formalPars, null, sl, @$);
}
| tkRoundOpen expr_l1 tkComma expr_l1_list lambda_type_ref optional_full_lambda_fp_list tkRoundClose rem_lambda
| tkRoundOpen expr_l1_or_unpacked tkComma expr_l1_or_unpacked_list lambda_type_ref optional_full_lambda_fp_list tkRoundClose rem_lambda // optional_full_lambda_fp_list - òàê ñäåëàíî èç-çà êîíôëèêòîâ â ãðàìàòèêå
{
var pair = $8 as pair_type_stlist;
if ($5 is lambda_inferred_type)
{
// äîáàâèì ñþäà \(x,y)
// Ïðîéòèñü ïî âñåì expr_list1. Åñëè õîòÿ áû îäíà - òèïà ident_or_list òî ïîéòè ïî ýòîé âåòêå è âûéòè
// óáåäèòüñÿ, ÷òî $6 = null
// ñôîðìèðîâàòü List<expression> äëÿ unpacked_params è ïðèñâîèòü
var has_unpacked = false;
if ($2 is unpacked_list_of_ident_or_list)
has_unpacked = true;
if (!has_unpacked)
foreach (var x in ($4 as expression_list).expressions)
{
if (x is unpacked_list_of_ident_or_list)
{
has_unpacked = true;
break;
}
}
if (has_unpacked) // òóò íîâàÿ âåòêà
{
if ($6 != null)
{
parsertools.AddErrorFromResource("SEMICOLON_IN_PARAMS",@6);
}
var lst_ex = new List<expression>();
lst_ex.Add($2 as expression);
foreach (var x in ($4 as expression_list).expressions)
lst_ex.Add(x);
function_lambda_definition fld = null; //= new function_lambda_definition(lambdaHelper.CreateLambdaName(), null,
//new lambda_inferred_type(new PascalABCCompiler.TreeRealization.lambda_any_type_node(), @2), pair.exprs, @$);
var sl1 = pair.exprs;
if (sl1.expr_lambda_body || SyntaxVisitors.HasNameVisitor.HasName(sl1, "result") != null) // òî íàäî âûâîäèòü
fld = new function_lambda_definition(lambdaHelper.CreateLambdaName(), null, pair.tn, pair.exprs, @$);
else fld = new function_lambda_definition(lambdaHelper.CreateLambdaName(), null, null, pair.exprs, @$);
fld.unpacked_params = lst_ex;
$$ = fld;
return;
}
var formal_pars = new formal_parameters();
var idd = $2 as ident;
if (idd==null)
@ -4879,9 +4948,13 @@ func_decl_lambda
| lambda_unpacked_params rem_lambda // ëÿìáäà ñ ðàñïàêîâêîé
{
var pair = $2 as pair_type_stlist;
// ïîêà ôîðìàëüíûå ïàðàìåòðû - null. Ðàñêðîåì èõ ñàõàðíûì âèçèòîðîì
$$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), null,
new lambda_inferred_type(new PascalABCCompiler.TreeRealization.lambda_any_type_node(), @1), pair.exprs, @$);
($$ as function_lambda_definition).unpacked_params = $1 as List<ident_or_list>;
// unpacked_params - ýòî äëÿ îäíîãî ïàðàìåòðà. Äëÿ íåñêîëüêèõ - íàäî äðóãóþ ñòðóêòóðó. Âîçìîæíî, ñïèñîê ñïèñêîâ
var lst_ex = new List<expression>();
lst_ex.Add($1 as unpacked_list_of_ident_or_list);
($$ as function_lambda_definition).unpacked_params = lst_ex;
}
| expl_func_decl_lambda
{

File diff suppressed because it is too large Load diff

View file

@ -322,6 +322,9 @@ script=

View file

@ -1 +1 @@
3.8.0.2864
3.8.0.2872

View file

@ -1 +1 @@
!define VERSION '3.8.0.2864'
!define VERSION '3.8.0.2872'

View file

@ -1437,7 +1437,7 @@ namespace PascalABCCompiler.SyntaxTree
{
public object RealSemTypeOfResExpr = null; // Result := ex; - семантический тип ex - нужно для лучшего выбора среди перегруженных методов с параметрами-лямбдами
public object RealSemTypeOfResult = null;
public List<ident_or_list> unpacked_params = null; // SSM 04/03/21 - сахарный узел, содержащий параметры, которые необходимо распаковать: (\(x,y,z),\(a,b)))
public List<expression> unpacked_params = null; // SSM 04/03/21 - сахарный узел, содержащий параметры, которые необходимо распаковать: (\(x,y,z),\(a,b)))
public function_lambda_definition(string name, formal_parameters formalPars, type_definition returnType, statement_list body, int usedkw, SourceContext sc)
{
@ -2041,21 +2041,43 @@ namespace PascalABCCompiler.SyntaxTree
public override string UsesPath() => in_file.Value;
}
public class ident_or_list // Это для распаковки параметров в лямбдах \(x,y)
public class ident_or_list : expression // Это для распаковки параметров в лямбдах \(x,y)
{
// только одно поле - ненулевое!
public ident id;
public List<ident_or_list> lst;
public unpacked_list_of_ident_or_list lst;
public ident_or_list(ident id)
{
this.id = id;
this.source_context = id.source_context;
}
public ident_or_list(List<ident_or_list> lst)
public ident_or_list(unpacked_list_of_ident_or_list lst)
{
this.lst = lst;
this.source_context = lst.source_context;
}
}
public class unpacked_list_of_ident_or_list: expression // это для самого верхнего уровня
{
public List<ident_or_list> lst;
public unpacked_list_of_ident_or_list(List<ident_or_list> lst)
{
this.lst = lst;
if (lst != null && lst.Count > 0)
this.source_context = lst[0].source_context;
}
public unpacked_list_of_ident_or_list()
{
lst = new List<ident_or_list>();
}
public void Add(ident_or_list il)
{
lst.Add(il);
if (source_context == null)
source_context = il.source_context;
else source_context = source_context.Merge(il.source_context);
}
}
}

View file

@ -30,10 +30,10 @@ namespace SyntaxVisitors.SugarVisitors
return new ident("#fpl" + UniqueNumStr(), sc);
}
public void CreateUnpackedListOfAssignments(List<ident_or_list> ll, List<statement> res, ident prevname, SourceContext sc)
public void CreateUnpackedListOfAssignments(unpacked_list_of_ident_or_list ll, List<statement> res, ident prevname, SourceContext sc)
{
var idlist = new ident_list();
foreach (var llelem in ll)
foreach (var llelem in ll.lst)
{
if (llelem.lst != null)
{
@ -54,21 +54,44 @@ namespace SyntaxVisitors.SugarVisitors
if (fld.unpacked_params == null)
{
return;
}
var main_param_id = CreateIdent(fld.source_context);
var idlist = new ident_list(main_param_id);
var lam_inft = new lambda_inferred_type(new lambda_any_type_node());
var typp = new typed_parameters(idlist, lam_inft);
fld.formal_parameters = new formal_parameters(typp, fld.source_context);
}
fld.formal_parameters = new formal_parameters();
fld.formal_parameters.source_context = fld.source_context;
// Пусть параметр имеет вид \(x,y)
// Тогда в начало тела лямбды надо добавить var (x,y) = #fpl1;
//var idl = new ident_list(fld.unpacked_params.Select(p => p.id).ToList(),fld.source_context); //
//var ass = new assign_var_tuple(idl, main_param_id, fld.source_context);
List<statement> res = new List<statement>();
CreateUnpackedListOfAssignments(fld.unpacked_params, res, main_param_id, fld.source_context);
foreach (var param in fld.unpacked_params)
{
if (param is unpacked_list_of_ident_or_list unpacked_param)
{
var lam_inft = new lambda_inferred_type(new lambda_any_type_node());
var param_id = CreateIdent(fld.source_context);
var idlist = new ident_list(param_id, unpacked_param.source_context);
var typed_pars = new typed_parameters(idlist, lam_inft, parametr_kind.none, null, unpacked_param.source_context);
fld.formal_parameters.Add(typed_pars, unpacked_param.source_context);
fld.ident_list.Add(param_id);
fld.parameters.Add(param_id);
CreateUnpackedListOfAssignments(unpacked_param, res, param_id, unpacked_param.source_context);
}
else if (param is ident id)
{
var lam_inft = new lambda_inferred_type(new lambda_any_type_node());
var idlist = new ident_list(id,id.source_context);
var typed_pars = new typed_parameters(idlist, lam_inft);
fld.formal_parameters.Add(typed_pars, fld.source_context);
fld.ident_list.Add(id);
fld.parameters.Add(id);
}
}
var stl = fld.proc_body as statement_list;
res.Reverse();

View file

@ -10193,6 +10193,21 @@ begin
end
end;
/// Превращает последовательность в последовательность n-ок соседних элементов
function Nwise<T>(Self: sequence of T; n: integer):sequence of array of T; extensionmethod;
begin
var chunk := new Queue<T>(n);
foreach var x in Self do
begin
chunk.Enqueue(x);
if chunk.Count = n then
begin
yield chunk.ToArray;
chunk.Dequeue;
end;
end;
end;
/// Превращает последовательность в последовательность пар соседних элементов, применяет func к каждой паре полученных элементов и получает новую последовательность
function Pairwise<T, Res>(Self: sequence of T; func: (T,T)->Res): sequence of Res; extensionmethod;
begin

View file

@ -296,6 +296,118 @@ function Cmb<T>(Self: array of T; m: integer): sequence of array of T; extension
/// Возвращает все сочетания по m элементов
function Cmb<T>(Self: sequence of T; m: integer): sequence of array of T; extensionmethod := Self.Combinations(m);
/// Выводит кортеж
function Pr<T1,T2>(Self: (T1,T2)): (T1,T2); extensionmethod;
begin
Result := Self;
Self.Print;
end;
/// Выводит кортеж
function Pr<T1,T2,T3>(Self: (T1,T2,T3)): (T1,T2,T3); extensionmethod;
begin
Result := Self;
Self.Print;
end;
/// Выводит кортеж
function Pr<T1,T2,T3,T4>(Self: (T1,T2,T3,T4)): (T1,T2,T3,T4); extensionmethod;
begin
Result := Self;
Self.Print;
end;
/// Выводит кортеж
function Pr<T1,T2,T3,T4,T5>(Self: (T1,T2,T3,T4,T5)): (T1,T2,T3,T4,T5); extensionmethod;
begin
Result := Self;
Self.Print;
end;
/// Выводит кортеж
function Prln<T1,T2>(Self: (T1,T2)): (T1,T2); extensionmethod;
begin
Result := Self;
Self.Println;
end;
/// Выводит кортеж
function Prln<T1,T2,T3>(Self: (T1,T2,T3)): (T1,T2,T3); extensionmethod;
begin
Result := Self;
Self.Println;
end;
/// Выводит кортеж
function Prln<T1,T2,T3,T4>(Self: (T1,T2,T3,T4)): (T1,T2,T3,T4); extensionmethod;
begin
Result := Self;
Self.Println;
end;
/// Выводит кортеж
function Prln<T1,T2,T3,T4,T5>(Self: (T1,T2,T3,T4,T5)): (T1,T2,T3,T4,T5); extensionmethod;
begin
Result := Self;
Self.Println;
end;
/// Возвращает минимальный элемент кортежа
function Min<T>(Self: (T,T)): T; extensionmethod;
where T: IComparable<T>;
begin
Result := Min(Self[0],Self[1]);
end;
/// Возвращает максимальный элемент кортежа
function Max<T>(Self: (T,T)): T; extensionmethod;
where T: IComparable<T>;
begin
Result := Max(Self[0],Self[1]);
end;
/// Возвращает минимальный элемент кортежа
function Min<T>(Self: (T,T,T)): T; extensionmethod;
where T: IComparable<T>;
begin
Result := Min(Self[0],Self[1],Self[2]);
end;
/// Возвращает максимальный элемент кортежа
function Max<T>(Self: (T,T,T)): T; extensionmethod;
where T: IComparable<T>;
begin
Result := Max(Self[0],Self[1],Self[2]);
end;
/// Возвращает минимальный элемент кортежа
function Min<T>(Self: (T,T,T,T)): T; extensionmethod;
where T: IComparable<T>;
begin
Result := Min(Self[0],Self[1],Self[2],Self[3]);
end;
/// Возвращает максимальный элемент кортежа
function Max<T>(Self: (T,T,T,T)): T; extensionmethod;
where T: IComparable<T>;
begin
Result := Max(Self[0],Self[1],Self[2],Self[3]);
end;
/// Возвращает минимальный элемент кортежа
function Min<T>(Self: (T,T,T,T,T)): T; extensionmethod;
where T: IComparable<T>;
begin
Result := Min(Self[0],Self[1],Self[2],Self[3],Self[4]);
end;
/// Возвращает максимальный элемент кортежа
function Max<T>(Self: (T,T,T,T,T)): T; extensionmethod;
where T: IComparable<T>;
begin
Result := Max(Self[0],Self[1],Self[2],Self[3],Self[4]);
end;
///--
procedure __InitModule__;
begin

View file

@ -66,6 +66,9 @@ function FirstPrimes(n: integer): List<integer>;
function Digits(n: int64): List<integer>;
/// Возвращает список делителей натурального числа
function Divisors(n: integer): List<integer>;
///--
function Divizors(n: integer): List<integer>;
/// Возвращает Sin угла, заданного в градусах
@ -543,7 +546,7 @@ Digits(Self);
{$region Divisors}
/// возвращает список всех делителей натурального числа
function Divizors(n: integer): List<integer>;
function Divisors(n: integer): List<integer>;
begin
n := Abs(n); // foolproof
var L := new List<integer>;
@ -568,9 +571,17 @@ begin
Result := L
end;
/// возвращает список делителей натурального числа
///--
function Divizors(n: integer) := Divisors(n);
/// Возвращает список делителей натурального числа
function Divisors(Self: integer): List<integer>; extensionmethod :=
Divisors(Self);
///--
function Divizors(Self: integer): List<integer>; extensionmethod :=
Divizors(Self);
Divisors(Self);
{$endregion}

11
TestSuite/two_pars.pas Normal file
View file

@ -0,0 +1,11 @@
type
TI = (integer, integer);
procedure p(f: (TI,TI) -> integer);
begin
Assert(f((3, 4), (2, 5)) = 14);
end;
begin
p((\(y1,y2),\(x,z)) -> x + y1 + y2 + z);
end.

View file

@ -0,0 +1,8 @@
begin
var s := Seq(('Умнова',16),('Иванов',23),
('Попова',17),('Козлов',24));
Println('Совершеннолетние:');
s.Where(\(name,age) -> age >= 18).Println;
Println('Сортировка по фамилии:');
s.OrderBy(\(name,age) -> name).Println;
end.

View file

@ -10193,6 +10193,21 @@ begin
end
end;
/// Превращает последовательность в последовательность n-ок соседних элементов
function Nwise<T>(Self: sequence of T; n: integer):sequence of array of T; extensionmethod;
begin
var chunk := new Queue<T>(n);
foreach var x in Self do
begin
chunk.Enqueue(x);
if chunk.Count = n then
begin
yield chunk.ToArray;
chunk.Dequeue;
end;
end;
end;
/// Превращает последовательность в последовательность пар соседних элементов, применяет func к каждой паре полученных элементов и получает новую последовательность
function Pairwise<T, Res>(Self: sequence of T; func: (T,T)->Res): sequence of Res; extensionmethod;
begin

View file

@ -296,6 +296,118 @@ function Cmb<T>(Self: array of T; m: integer): sequence of array of T; extension
/// Возвращает все сочетания по m элементов
function Cmb<T>(Self: sequence of T; m: integer): sequence of array of T; extensionmethod := Self.Combinations(m);
/// Выводит кортеж
function Pr<T1,T2>(Self: (T1,T2)): (T1,T2); extensionmethod;
begin
Result := Self;
Self.Print;
end;
/// Выводит кортеж
function Pr<T1,T2,T3>(Self: (T1,T2,T3)): (T1,T2,T3); extensionmethod;
begin
Result := Self;
Self.Print;
end;
/// Выводит кортеж
function Pr<T1,T2,T3,T4>(Self: (T1,T2,T3,T4)): (T1,T2,T3,T4); extensionmethod;
begin
Result := Self;
Self.Print;
end;
/// Выводит кортеж
function Pr<T1,T2,T3,T4,T5>(Self: (T1,T2,T3,T4,T5)): (T1,T2,T3,T4,T5); extensionmethod;
begin
Result := Self;
Self.Print;
end;
/// Выводит кортеж
function Prln<T1,T2>(Self: (T1,T2)): (T1,T2); extensionmethod;
begin
Result := Self;
Self.Println;
end;
/// Выводит кортеж
function Prln<T1,T2,T3>(Self: (T1,T2,T3)): (T1,T2,T3); extensionmethod;
begin
Result := Self;
Self.Println;
end;
/// Выводит кортеж
function Prln<T1,T2,T3,T4>(Self: (T1,T2,T3,T4)): (T1,T2,T3,T4); extensionmethod;
begin
Result := Self;
Self.Println;
end;
/// Выводит кортеж
function Prln<T1,T2,T3,T4,T5>(Self: (T1,T2,T3,T4,T5)): (T1,T2,T3,T4,T5); extensionmethod;
begin
Result := Self;
Self.Println;
end;
/// Возвращает минимальный элемент кортежа
function Min<T>(Self: (T,T)): T; extensionmethod;
where T: IComparable<T>;
begin
Result := Min(Self[0],Self[1]);
end;
/// Возвращает максимальный элемент кортежа
function Max<T>(Self: (T,T)): T; extensionmethod;
where T: IComparable<T>;
begin
Result := Max(Self[0],Self[1]);
end;
/// Возвращает минимальный элемент кортежа
function Min<T>(Self: (T,T,T)): T; extensionmethod;
where T: IComparable<T>;
begin
Result := Min(Self[0],Self[1],Self[2]);
end;
/// Возвращает максимальный элемент кортежа
function Max<T>(Self: (T,T,T)): T; extensionmethod;
where T: IComparable<T>;
begin
Result := Max(Self[0],Self[1],Self[2]);
end;
/// Возвращает минимальный элемент кортежа
function Min<T>(Self: (T,T,T,T)): T; extensionmethod;
where T: IComparable<T>;
begin
Result := Min(Self[0],Self[1],Self[2],Self[3]);
end;
/// Возвращает максимальный элемент кортежа
function Max<T>(Self: (T,T,T,T)): T; extensionmethod;
where T: IComparable<T>;
begin
Result := Max(Self[0],Self[1],Self[2],Self[3]);
end;
/// Возвращает минимальный элемент кортежа
function Min<T>(Self: (T,T,T,T,T)): T; extensionmethod;
where T: IComparable<T>;
begin
Result := Min(Self[0],Self[1],Self[2],Self[3],Self[4]);
end;
/// Возвращает максимальный элемент кортежа
function Max<T>(Self: (T,T,T,T,T)): T; extensionmethod;
where T: IComparable<T>;
begin
Result := Max(Self[0],Self[1],Self[2],Self[3],Self[4]);
end;
///--
procedure __InitModule__;
begin

View file

@ -66,6 +66,9 @@ function FirstPrimes(n: integer): List<integer>;
function Digits(n: int64): List<integer>;
/// Возвращает список делителей натурального числа
function Divisors(n: integer): List<integer>;
///--
function Divizors(n: integer): List<integer>;
/// Возвращает Sin угла, заданного в градусах
@ -543,7 +546,7 @@ Digits(Self);
{$region Divisors}
/// возвращает список всех делителей натурального числа
function Divizors(n: integer): List<integer>;
function Divisors(n: integer): List<integer>;
begin
n := Abs(n); // foolproof
var L := new List<integer>;
@ -568,9 +571,17 @@ begin
Result := L
end;
/// возвращает список делителей натурального числа
///--
function Divizors(n: integer) := Divisors(n);
/// Возвращает список делителей натурального числа
function Divisors(Self: integer): List<integer>; extensionmethod :=
Divisors(Self);
///--
function Divizors(Self: integer): List<integer>; extensionmethod :=
Divizors(Self);
Divisors(Self);
{$endregion}

View file

@ -54,6 +54,7 @@ ONE_OPERATOR=Expected operator
ONE_STMT=Expected statement
BAD_TUPLE=Badly formed Tuple
EMPTY_STATEMENT_IN_SHORT_PROC_DEFINITION=Statement expected
EXPRESSION_EXPECTED=Expression expected
DUPLICATE_NAMES_IN_ANON_TYPE=Duplicate field names in anonymous type

View file

@ -54,6 +54,7 @@ ONE_OPERATOR=Ожидался оператор
ONE_STMT=Ожидался оператор
BAD_TUPLE=Неправильно сформированный кортеж
EMPTY_STATEMENT_IN_SHORT_PROC_DEFINITION=Ожидался оператор
EXPRESSION_EXPECTED=Ожидалось выражение
DUPLICATE_NAMES_IN_ANON_TYPE=Анонимный тип не может содержать поля с одинаковыми именами
BAD_ANON_TYPE=Неверное определение имени поля анонимного типа