Улучшение паттерн матчинга (#1949)

Матчинг констант, таплов, коллекций. Улучшение матчинга по типам.
This commit is contained in:
Alexandr Pogorelov 2019-05-24 10:04:17 +03:00 committed by GitHub
parent de395b0106
commit 8a432eee6e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
45 changed files with 9024 additions and 4275 deletions

View file

@ -3166,7 +3166,11 @@ namespace CodeFormatters
if (_is_pattern_expr.left != null) if (_is_pattern_expr.left != null)
visit_node(_is_pattern_expr.left); visit_node(_is_pattern_expr.left);
sb.Append(" is "); if (_is_pattern_expr.right == null ||
!(_is_pattern_expr.right is collection_pattern) && !(_is_pattern_expr.right is tuple_pattern))
sb.Append(" is ");
else
add_space_before = true;
if (_is_pattern_expr.right != null) if (_is_pattern_expr.right != null)
visit_node(_is_pattern_expr.right); visit_node(_is_pattern_expr.right);
@ -3211,6 +3215,80 @@ namespace CodeFormatters
DecOffset(); DecOffset();
} }
public override void visit(const_pattern _const_pattern)
{
visit_node(_const_pattern.pattern_expressions);
add_space_after = false;
}
public override void visit(const_pattern_parameter _const_parameter)
{
visit_node(_const_parameter.const_param);
add_space_after = false;
}
public override void visit(wild_card_deconstructor_parameter _wild_card_deconstructor_parameter)
{
sb.Append("_");
add_space_after = true;
}
public override void visit(tuple_pattern_var_parameter _tuple_pattern_var_parameter)
{
sb.Append("var");
SetKeywordOffset("var");
read_from_beg_pos = true;
visit_node(_tuple_pattern_var_parameter.identifier);
}
public override void visit(tuple_pattern_wild_card _tuple_pattern_wild_card)
{
sb.Append("_");
add_space_after = true;
}
public override void visit(tuple_pattern _tuple_pattern)
{
sb.Append("(");
foreach (var parameter in _tuple_pattern.parameters)
{
visit_node(parameter);
add_space_after = true;
}
add_space_after = false;
}
public override void visit(collection_pattern _collection_pattern)
{
sb.Append("[");
foreach (var parameter in _collection_pattern.parameters)
{
visit_node(parameter);
add_space_after = true;
}
add_space_after = false;
}
public override void visit(collection_pattern_gap_parameter _collection_pattern_gap_parameter)
{
sb.Append("..");
add_space_after = true;
}
public override void visit(collection_pattern_var_parameter _collection_pattern_var_parameter)
{
sb.Append("var");
SetKeywordOffset("var");
read_from_beg_pos = true;
visit_node(_collection_pattern_var_parameter.identifier);
}
public override void visit(collection_pattern_wild_card _collection_pattern_wild_card)
{
sb.Append("_");
add_space_after = true;
}
public override void visit(deconstructor_pattern _deconstructor_pattern) public override void visit(deconstructor_pattern _deconstructor_pattern)
{ {
visit_node(_deconstructor_pattern.type); visit_node(_deconstructor_pattern.type);
@ -3224,18 +3302,34 @@ namespace CodeFormatters
public override void visit(var_deconstructor_parameter _var_deconstructor_parameter) public override void visit(var_deconstructor_parameter _var_deconstructor_parameter)
{ {
sb.Append("var"); if (_var_deconstructor_parameter.var_keyword_used)
SetKeywordOffset("var"); {
read_from_beg_pos = true; sb.Append("var");
SetKeywordOffset("var");
read_from_beg_pos = true;
}
visit_node(_var_deconstructor_parameter.identifier); visit_node(_var_deconstructor_parameter.identifier);
if (_var_deconstructor_parameter.type != null) if (_var_deconstructor_parameter.type != null)
visit_node(_var_deconstructor_parameter.type); visit_node(_var_deconstructor_parameter.type);
} }
public override void visit(recursive_pattern_parameter _recursive_pattern_parameter)
{
visit_node(_recursive_pattern_parameter.pattern);
}
public override void visit(recursive_deconstructor_parameter _recursive_deconstructor_parameter) public override void visit(recursive_deconstructor_parameter _recursive_deconstructor_parameter)
{ {
visit_node(_recursive_deconstructor_parameter.pattern); visit_node(_recursive_deconstructor_parameter.pattern);
} }
public override void visit(recursive_tuple_parameter _recursive_tuple_parameter)
{
visit_node(_recursive_tuple_parameter.pattern);
}
public override void visit(recursive_collection_parameter _recursive_collection_parameter)
{
visit_node(_recursive_collection_parameter.pattern);
}
public override void visit(var_tuple_def_statement _var_tuple_def_statement) public override void visit(var_tuple_def_statement _var_tuple_def_statement)
{ {

View file

@ -777,7 +777,7 @@ namespace CodeCompletion
} }
else else
{ {
foreach (pattern_deconstructor_parameter pdp in _deconstructor_pattern.parameters) foreach (pattern_parameter pdp in _deconstructor_pattern.parameters)
{ {
if (pdp is var_deconstructor_parameter) if (pdp is var_deconstructor_parameter)
{ {

View file

@ -1682,7 +1682,7 @@ namespace CodeCompletion
public override void visit(deconstructor_pattern _deconstructor_pattern) public override void visit(deconstructor_pattern _deconstructor_pattern)
{ {
_deconstructor_pattern.type.visit(this); _deconstructor_pattern.type.visit(this);
foreach (pattern_deconstructor_parameter pdp in _deconstructor_pattern.parameters) foreach (pattern_parameter pdp in _deconstructor_pattern.parameters)
pdp.visit(this); pdp.visit(this);
} }
public override void visit(recursive_deconstructor_parameter _recursive_deconstructor_parameter) public override void visit(recursive_deconstructor_parameter _recursive_deconstructor_parameter)

View file

@ -0,0 +1,43 @@
type
CardInfo = auto class
public
cardNumber: string;
cv: integer;
end;
Person = class
public
name: string;
age: integer;
card: CardInfo;
constructor(name: string; age: integer; card: CardInfo);
begin
self.name := name;
self.age := age;
self.card := card;
end;
procedure Deconstruct(var name: string; var age: integer; var card: CardInfo);
begin
name := self.name;
age := self.age;
card := self.card;
end;
end;
begin
var a := Arr(1, 9, 8, 7, 2, 3, 4, 5);
// Расширенный is
if a is [1, .., var x, _, 5] then
Println(x);
// match .. with
match a with
[1, 9, 8, _, 2]: print(1);
[.., var y, var x]: print(x + y);
[_, .., _]: print(3);
end;
end.

View file

@ -0,0 +1,46 @@
type
CardInfo = auto class
public
cardNumber: string;
cv: integer;
end;
Person = class
public
name: string;
age: integer;
card: CardInfo;
constructor(name: string; age: integer; card: CardInfo);
begin
self.name := name;
self.age := age;
self.card := card;
end;
procedure Deconstruct(var name: string; var age: integer; var card: CardInfo);
begin
name := self.name;
age := self.age;
card := self.card;
end;
end;
begin
var p1 := new Person('Вася', 11, new CardInfo('12345671', 321));
var p2 := new Person('Петя', 12, new CardInfo('12345672', 322));
var p3 := new Person('Маша', 13, new CardInfo('12345673', 323));
var personArr := Arr(p1, p2, p3);
// Расширенный is
if personArr is [Person(name1, 11, CardInfo(_, cv)), _, Person(name2, 13, _)] then
println(name1, cv, name2);
// match .. with
match personArr with
[_, _, Person('Вася', age, _)]: print(age);
[var p, .., Person('Маша', _, _)]: print((p as Person).name);
[..]: print(1);
end;
end.

View file

@ -0,0 +1,43 @@
type
CardInfo = auto class
public
cardNumber: string;
cv: integer;
end;
Person = class
name: string;
age: integer;
card: List<CardInfo> := new List<CardInfo>();
constructor(name: string; age: integer; card: List<CardInfo>);
begin
self.name := name;
self.age := age;
self.card := card;
end;
procedure Deconstruct(var name: string; var age: integer; var card: List<CardInfo>);
begin
name := self.name;
age := self.age;
card := self.card;
end;
end;
begin
var cards := new List<CardInfo>();
cards.Add(new CardInfo('12345671', 321));
cards.Add(new CardInfo('12345672', 322));
cards.Add(new CardInfo('12345673', 323));
cards.Add(new CardInfo('12345674', 324));
var p := new Person('Вася', 21, cards);
// match .. with
match p with
Person('Петя', _, _): print('Петя');
Person('Вася', _, [_, _, var x]): print(x);
Person(name, _, [CardInfo(_, 321), .., CardInfo(_, 324)]): print(name);
end;
end.

View file

@ -0,0 +1,8 @@
begin
var a := 3.14;
match a with
1.0, 2.0, 3.0: Println(1);
3.13, 3.14, 3.15, 3.16: print(2);
123.0: print(3);
end;
end.

View file

@ -0,0 +1,7 @@
begin
match (1, 2, 'string') with
(1, _, var x): Println(x);
(1, _, 'strin'): print(2);
(_, _, 'string'): print(3);
end;
end.

View file

@ -0,0 +1,40 @@
type
CardInfo = auto class
public
cardNumber: string;
cv: integer;
end;
Person = class
name: string;
age: integer;
card: CardInfo;
constructor(name: string; age: integer; card: CardInfo);
begin
self.name := name;
self.age := age;
self.card := card;
end;
procedure Deconstruct(var name: string; var age: integer; var card: CardInfo);
begin
name := self.name;
age := self.age;
card := self.card;
end;
end;
begin
var a := new Person('Вася', 11, new CardInfo('12345678', 324));
// Расширенный is
if a is Person(_, var age, CardInfo(_, var cv)) then Println(age, cv);
// match .. with
match a with
Person('Петя', 12, CardInfo('12345678', var cv)): Println(cv);
Person('Вася', _, CardInfo(cardNum, 324)): Println(cardNum);
Person(_, _, CardInfo(_, x)): Println(x);
end;
end.

View file

@ -2313,7 +2313,7 @@ namespace PascalABCCompiler.SyntaxTree
} }
} }
public void CompareInternal(pattern_deconstructor_parameter left, pattern_deconstructor_parameter right) public void CompareInternal(pattern_parameter left, pattern_parameter right)
{ {
if (left == null && right != null || left != null && right == null) if (left == null && right != null || left != null && right == null)
throw_not_equal(left, right); throw_not_equal(left, right);

File diff suppressed because it is too large Load diff

View file

@ -191,6 +191,7 @@ UNICODEARROW \x890
"[" { return (int)Tokens.tkSquareOpen; } "[" { return (int)Tokens.tkSquareOpen; }
"]" { return (int)Tokens.tkSquareClose; } "]" { return (int)Tokens.tkSquareClose; }
"?" { return (int)Tokens.tkQuestion; } "?" { return (int)Tokens.tkQuestion; }
"_" { return (int)Tokens.tkUnderscore; }
"?." { return (int)Tokens.tkQuestionPoint; } "?." { return (int)Tokens.tkQuestionPoint; }
"??" { return (int)Tokens.tkDoubleQuestion; } "??" { return (int)Tokens.tkDoubleQuestion; }
"?[" { return (int)Tokens.tkQuestionSquareOpen; } "?[" { return (int)Tokens.tkQuestionSquareOpen; }

View file

@ -32,7 +32,7 @@
%start parse_goal %start parse_goal
%token <ti> tkDirectiveName tkAmpersend tkColon tkDotDot tkPoint tkRoundOpen tkRoundClose tkSemiColon tkSquareOpen tkSquareClose tkQuestion tkQuestionPoint tkDoubleQuestion tkQuestionSquareOpen %token <ti> tkDirectiveName tkAmpersend tkColon tkDotDot tkPoint tkRoundOpen tkRoundClose tkSemiColon tkSquareOpen tkSquareClose tkQuestion tkUnderscore tkQuestionPoint tkDoubleQuestion tkQuestionSquareOpen
%token <ti> tkSizeOf tkTypeOf tkWhere tkArray tkCase tkClass tkAuto tkStatic tkConst tkConstructor tkDestructor tkElse tkExcept tkFile tkFor tkForeach tkFunction tkMatch tkWhen %token <ti> tkSizeOf tkTypeOf tkWhere tkArray tkCase tkClass tkAuto tkStatic tkConst tkConstructor tkDestructor tkElse tkExcept tkFile tkFor tkForeach tkFunction tkMatch tkWhen
%token <ti> tkIf tkImplementation tkInherited tkInterface tkProcedure tkOperator tkProperty tkRaise tkRecord tkSet tkType tkThen tkUses tkVar tkWhile tkWith tkNil %token <ti> tkIf tkImplementation tkInherited tkInterface tkProcedure tkOperator tkProperty tkRaise tkRecord tkSet tkType tkThen tkUses tkVar tkWhile tkWith tkNil
%token <ti> tkGoto tkOf tkLabel tkLock tkProgram tkEvent tkDefault tkTemplate tkPacked tkExports tkResourceString tkThreadvar tkSealed tkPartial tkTo tkDownto %token <ti> tkGoto tkOf tkLabel tkLock tkProgram tkEvent tkDefault tkTemplate tkPacked tkExports tkResourceString tkThreadvar tkSealed tkPartial tkTo tkDownto
@ -146,7 +146,7 @@
%type <stn> simple_property_definition %type <stn> simple_property_definition
%type <stn> stmt_or_expression unlabelled_stmt stmt case_item %type <stn> stmt_or_expression unlabelled_stmt stmt case_item
%type <td> set_type %type <td> set_type
%type <ex> as_is_expr as_is_constexpr is_expr as_expr power_expr power_constexpr %type <ex> as_is_expr as_is_constexpr is_type_expr as_expr power_expr power_constexpr
%type <td> unsized_array_type simple_type_or_ simple_type simple_type_question/*array_name_for_new_expr*/ foreach_stmt_ident_dype_opt fptype type_ref fptype_noproctype array_type %type <td> unsized_array_type simple_type_or_ simple_type simple_type_question/*array_name_for_new_expr*/ foreach_stmt_ident_dype_opt fptype type_ref fptype_noproctype array_type
%type <td> template_param template_empty_param structured_type unpacked_structured_type empty_template_type_reference simple_or_template_type_reference type_ref_or_secific for_stmt_decl_or_assign type_decl_type %type <td> template_param template_empty_param structured_type unpacked_structured_type empty_template_type_reference simple_or_template_type_reference type_ref_or_secific for_stmt_decl_or_assign type_decl_type
%type <stn> type_ref_and_secific_list %type <stn> type_ref_and_secific_list
@ -175,8 +175,10 @@
%type <stn> full_lambda_fp_list lambda_simple_fp_sect lambda_function_body lambda_procedure_body common_lambda_body optional_full_lambda_fp_list %type <stn> full_lambda_fp_list lambda_simple_fp_sect lambda_function_body lambda_procedure_body common_lambda_body optional_full_lambda_fp_list
%type <ob> field_in_unnamed_object list_fields_in_unnamed_object func_class_name_ident_list rem_lambda variable_list var_ident_list %type <ob> field_in_unnamed_object list_fields_in_unnamed_object func_class_name_ident_list rem_lambda variable_list var_ident_list
%type <ti> tkAssignOrEqual %type <ti> tkAssignOrEqual
%type <stn> pattern pattern_optional_var match_with pattern_case pattern_cases pattern_out_param pattern_out_param_optional_var %type <stn> pattern pattern_optional_var const_pattern collection_pattern tuple_pattern collection_pattern_list_item tuple_pattern_item collection_pattern_var_item match_with pattern_case pattern_cases pattern_out_param pattern_out_param_optional_var const_pattern_expr_list
%type <ob> pattern_out_param_list pattern_out_param_list_optional_var %type <ob> pattern_out_param_list pattern_out_param_list_optional_var collection_pattern_expr_list tuple_pattern_item_list
%type <ex> const_pattern_expression
%% %%
parse_goal parse_goal
@ -2806,6 +2808,22 @@ pattern_case
{ {
$$ = new pattern_case($1 as pattern_node, $3 as statement, null, @$); $$ = new pattern_case($1 as pattern_node, $3 as statement, null, @$);
} }
| const_pattern tkWhen expr_l1 tkColon unlabelled_stmt
{
$$ = new pattern_case($1 as pattern_node, $5 as statement, $3, @$);
}
| const_pattern tkColon unlabelled_stmt
{
$$ = new pattern_case($1 as pattern_node, $3 as statement, null, @$);
}
| collection_pattern tkColon unlabelled_stmt
{
$$ = new pattern_case($1 as pattern_node, $3 as statement, null, @$);
}
| tuple_pattern tkColon unlabelled_stmt
{
$$ = new pattern_case($1 as pattern_node, $3 as statement, null, @$);
}
; ;
case_stmt case_stmt
@ -3282,44 +3300,188 @@ relop_expr
{ {
$$ = new bin_expr($1, $3, $2.type, @$); $$ = new bin_expr($1, $3, $2.type, @$);
} }
| is_expr tkRoundOpen pattern_out_param_list tkRoundClose | is_type_expr tkRoundOpen pattern_out_param_list tkRoundClose
{ {
var isTypeCheck = $1 as typecast_node; var isTypeCheck = $1 as typecast_node;
var deconstructorPattern = new deconstructor_pattern($3 as List<pattern_deconstructor_parameter>, isTypeCheck.type_def, @$); var deconstructorPattern = new deconstructor_pattern($3 as List<pattern_parameter>, isTypeCheck.type_def, null, @$);
$$ = new is_pattern_expr(isTypeCheck.expr, deconstructorPattern, @$); $$ = new is_pattern_expr(isTypeCheck.expr, deconstructorPattern, @$);
} }
| term tkIs collection_pattern
{
$$ = new is_pattern_expr($1, $3 as pattern_node, @$);
}
| term tkIs tuple_pattern
{
$$ = new is_pattern_expr($1, $3 as pattern_node, @$);
}
; ;
pattern pattern
: simple_or_template_type_reference tkRoundOpen pattern_out_param_list tkRoundClose : simple_or_template_type_reference tkRoundOpen pattern_out_param_list tkRoundClose
{ {
$$ = new deconstructor_pattern($3 as List<pattern_deconstructor_parameter>, $1, @$); $$ = new deconstructor_pattern($3 as List<pattern_parameter>, $1, null, @$);
} }
; ;
pattern_optional_var pattern_optional_var
: simple_or_template_type_reference tkRoundOpen pattern_out_param_list_optional_var tkRoundClose : simple_or_template_type_reference tkRoundOpen pattern_out_param_list_optional_var tkRoundClose
{ {
$$ = new deconstructor_pattern($3 as List<pattern_deconstructor_parameter>, $1, @$); $$ = new deconstructor_pattern($3 as List<pattern_parameter>, $1, null, @$);
} }
; ;
collection_pattern
: tkSquareOpen collection_pattern_expr_list tkSquareClose
{
$$ = new collection_pattern($2 as List<pattern_parameter>, @$);
}
;
collection_pattern_expr_list
: collection_pattern_list_item
{
$$ = new List<pattern_parameter>();
($$ as List<pattern_parameter>).Add($1 as pattern_parameter);
}
| collection_pattern_expr_list tkComma collection_pattern_list_item
{
var list = $1 as List<pattern_parameter>;
list.Add($3 as pattern_parameter);
$$ = list;
}
;
collection_pattern_list_item
: literal_or_number
{
$$ = new const_pattern_parameter($1, @$);
}
| collection_pattern_var_item
{
$$ = $1;
}
| tkUnderscore
{
$$ = new collection_pattern_wild_card(@$);
}
/*| pattern
{
$$ = new recursive_deconstructor_parameter($1 as pattern_node, @$);
}*/
| pattern_optional_var
{
$$ = new recursive_deconstructor_parameter($1 as pattern_node, @$);
}
| collection_pattern
{
$$ = new recursive_collection_parameter($1 as pattern_node, @$);
}
| tuple_pattern
{
$$ = new recursive_tuple_parameter($1 as pattern_node, @$);
}
| tkDotDot
{
$$ = new collection_pattern_gap_parameter(@$);
}
;
collection_pattern_var_item
: tkVar identifier
{
$$ = new collection_pattern_var_parameter($2, null, @$);
}
;
const_pattern
: const_pattern_expr_list
{
$$ = new const_pattern($1 as expression_list, @$);
}
;
const_pattern_expr_list
: const_pattern_expression
{
$$ = new expression_list($1, @$);
}
| const_pattern_expr_list tkComma const_pattern_expression
{
$$ = ($1 as expression_list).Add($3, @$);
}
;
const_pattern_expression
: literal_or_number { $$ = $1; }
;
tuple_pattern
: tkRoundOpen tuple_pattern_item_list tkRoundClose
{
if (($2 as List<pattern_parameter>).Count>6)
parsertools.AddErrorFromResource("TUPLE_ELEMENTS_COUNT_MUST_BE_LESSEQUAL_7",@$);
$$ = new tuple_pattern($2 as List<pattern_parameter>, @$);
}
;
tuple_pattern_item
: tkUnderscore
{
$$ = new tuple_pattern_wild_card(@$);
}
| literal_or_number
{
$$ = new const_pattern_parameter($1, @$);
}
| tkVar identifier
{
$$ = new tuple_pattern_var_parameter($2, null, @$);
}
| pattern_optional_var
{
$$ = new recursive_deconstructor_parameter($1 as pattern_node, @$);
}
| collection_pattern
{
$$ = new recursive_collection_parameter($1 as pattern_node, @$);
}
| tuple_pattern
{
$$ = new recursive_tuple_parameter($1 as pattern_node, @$);
}
;
tuple_pattern_item_list
: tuple_pattern_item
{
$$ = new List<pattern_parameter>();
($$ as List<pattern_parameter>).Add($1 as pattern_parameter);
}
| tuple_pattern_item_list tkComma tuple_pattern_item
{
var list = $1 as List<pattern_parameter>;
list.Add($3 as pattern_parameter);
$$ = list;
}
;
pattern_out_param_list_optional_var pattern_out_param_list_optional_var
: pattern_out_param_optional_var : pattern_out_param_optional_var
{ {
$$ = new List<pattern_deconstructor_parameter>(); $$ = new List<pattern_parameter>();
($$ as List<pattern_deconstructor_parameter>).Add($1 as pattern_deconstructor_parameter); ($$ as List<pattern_parameter>).Add($1 as pattern_parameter);
} }
| pattern_out_param_list_optional_var tkSemiColon pattern_out_param_optional_var | pattern_out_param_list_optional_var tkSemiColon pattern_out_param_optional_var
{ {
var list = $1 as List<pattern_deconstructor_parameter>; var list = $1 as List<pattern_parameter>;
list.Add($3 as pattern_deconstructor_parameter); list.Add($3 as pattern_parameter);
$$ = list; $$ = list;
} }
| pattern_out_param_list_optional_var tkComma pattern_out_param_optional_var | pattern_out_param_list_optional_var tkComma pattern_out_param_optional_var
{ {
var list = $1 as List<pattern_deconstructor_parameter>; var list = $1 as List<pattern_parameter>;
list.Add($3 as pattern_deconstructor_parameter); list.Add($3 as pattern_parameter);
$$ = list; $$ = list;
} }
; ;
@ -3327,59 +3489,91 @@ pattern_out_param_list_optional_var
pattern_out_param_list pattern_out_param_list
: pattern_out_param : pattern_out_param
{ {
$$ = new List<pattern_deconstructor_parameter>(); $$ = new List<pattern_parameter>();
($$ as List<pattern_deconstructor_parameter>).Add($1 as pattern_deconstructor_parameter); ($$ as List<pattern_parameter>).Add($1 as pattern_parameter);
} }
| pattern_out_param_list tkSemiColon pattern_out_param | pattern_out_param_list tkSemiColon pattern_out_param
{ {
var list = $1 as List<pattern_deconstructor_parameter>; var list = $1 as List<pattern_parameter>;
list.Add($3 as pattern_deconstructor_parameter); list.Add($3 as pattern_parameter);
$$ = list; $$ = list;
} }
| pattern_out_param_list tkComma pattern_out_param | pattern_out_param_list tkComma pattern_out_param
{ {
var list = $1 as List<pattern_deconstructor_parameter>; var list = $1 as List<pattern_parameter>;
list.Add($3 as pattern_deconstructor_parameter); list.Add($3 as pattern_parameter);
$$ = list; $$ = list;
} }
; ;
pattern_out_param pattern_out_param
: tkVar identifier tkColon type_ref : tkUnderscore
{
$$ = new wild_card_deconstructor_parameter(@$);
}
| literal_or_number
{
$$ = new const_pattern_parameter($1, @$);
}
| tkVar identifier tkColon type_ref
{ {
$$ = new var_deconstructor_parameter($2, $4, @$); $$ = new var_deconstructor_parameter($2, $4, true, @$);
} }
| tkVar identifier | tkVar identifier
{ {
$$ = new var_deconstructor_parameter($2, null, @$); $$ = new var_deconstructor_parameter($2, null, true, @$);
} }
| pattern | pattern
{ {
$$ = new recursive_deconstructor_parameter($1 as pattern_node, @$); $$ = new recursive_deconstructor_parameter($1 as pattern_node, @$);
} }
| collection_pattern
{
$$ = new recursive_collection_parameter($1 as pattern_node, @$);
}
| tuple_pattern
{
$$ = new recursive_tuple_parameter($1 as pattern_node, @$);
}
; ;
pattern_out_param_optional_var pattern_out_param_optional_var
: identifier tkColon type_ref : tkUnderscore
{
$$ = new wild_card_deconstructor_parameter(@$);
}
| literal_or_number
{
$$ = new const_pattern_parameter($1, @$);
}
| identifier tkColon type_ref
{ {
$$ = new var_deconstructor_parameter($1, $3, @$); $$ = new var_deconstructor_parameter($1, $3, false, @$);
} }
| identifier | identifier
{ {
$$ = new var_deconstructor_parameter($1, null, @$); $$ = new var_deconstructor_parameter($1, null, false, @$);
} }
| tkVar identifier tkColon type_ref | tkVar identifier tkColon type_ref
{ {
$$ = new var_deconstructor_parameter($2, $4, @$); $$ = new var_deconstructor_parameter($2, $4, true, @$);
} }
| tkVar identifier | tkVar identifier
{ {
$$ = new var_deconstructor_parameter($2, null, @$); $$ = new var_deconstructor_parameter($2, null, true, @$);
} }
| pattern_optional_var | pattern_optional_var
{ {
$$ = new recursive_deconstructor_parameter($1 as pattern_node, @$); $$ = new recursive_deconstructor_parameter($1 as pattern_node, @$);
} }
| collection_pattern
{
$$ = new recursive_collection_parameter($1 as pattern_node, @$);
}
| tuple_pattern
{
$$ = new recursive_tuple_parameter($1 as pattern_node, @$);
}
; ;
simple_expr_or_nothing simple_expr_or_nothing
@ -3494,7 +3688,7 @@ typecast_op
; ;
as_is_expr as_is_expr
: is_expr : is_type_expr
{ $$ = $1; } { $$ = $1; }
| as_expr | as_expr
{ $$ = $1; } { $$ = $1; }
@ -3507,7 +3701,7 @@ as_expr
} }
; ;
is_expr is_type_expr
: term tkIs simple_or_template_type_reference : term tkIs simple_or_template_type_reference
{ {
$$ = NewAsIsExpr($1, op_typecast.is_op, $3, @$); $$ = NewAsIsExpr($1, op_typecast.is_op, $3, @$);

File diff suppressed because it is too large Load diff

View file

@ -1153,9 +1153,9 @@ namespace PascalABCCompiler.SyntaxTree
DefaultVisit(_deconstructor_pattern); DefaultVisit(_deconstructor_pattern);
} }
public virtual void visit(pattern_deconstructor_parameter _pattern_deconstructor_parameter) public virtual void visit(pattern_parameter _pattern_parameter)
{ {
DefaultVisit(_pattern_deconstructor_parameter); DefaultVisit(_pattern_parameter);
} }
public virtual void visit(desugared_deconstruction _desugared_deconstruction) public virtual void visit(desugared_deconstruction _desugared_deconstruction)
@ -1187,6 +1187,71 @@ namespace PascalABCCompiler.SyntaxTree
{ {
DefaultVisit(_semantic_check_sugared_var_def_statement_node); DefaultVisit(_semantic_check_sugared_var_def_statement_node);
} }
public virtual void visit(const_pattern _const_pattern)
{
DefaultVisit(_const_pattern);
}
public virtual void visit(tuple_pattern_wild_card _tuple_pattern_wild_card)
{
DefaultVisit(_tuple_pattern_wild_card);
}
public virtual void visit(const_pattern_parameter _const_pattern_parameter)
{
DefaultVisit(_const_pattern_parameter);
}
public virtual void visit(wild_card_deconstructor_parameter _wild_card_deconstructor_parameter)
{
DefaultVisit(_wild_card_deconstructor_parameter);
}
public virtual void visit(collection_pattern _collection_pattern)
{
DefaultVisit(_collection_pattern);
}
public virtual void visit(collection_pattern_gap_parameter _collection_pattern_gap_parameter)
{
DefaultVisit(_collection_pattern_gap_parameter);
}
public virtual void visit(collection_pattern_wild_card _collection_pattern_wild_card)
{
DefaultVisit(_collection_pattern_wild_card);
}
public virtual void visit(collection_pattern_var_parameter _collection_pattern_var_parameter)
{
DefaultVisit(_collection_pattern_var_parameter);
}
public virtual void visit(recursive_collection_parameter _recursive_collection_parameter)
{
DefaultVisit(_recursive_collection_parameter);
}
public virtual void visit(recursive_pattern_parameter _recursive_pattern_parameter)
{
DefaultVisit(_recursive_pattern_parameter);
}
public virtual void visit(tuple_pattern _tuple_pattern)
{
DefaultVisit(_tuple_pattern);
}
public virtual void visit(tuple_pattern_var_parameter _tuple_pattern_var_parameter)
{
DefaultVisit(_tuple_pattern_var_parameter);
}
public virtual void visit(recursive_tuple_parameter _recursive_tuple_parameter)
{
DefaultVisit(_recursive_tuple_parameter);
}
} }

View file

@ -1837,11 +1837,11 @@ namespace PascalABCCompiler.SyntaxTree
{ {
} }
public virtual void pre_do_visit(pattern_deconstructor_parameter _pattern_deconstructor_parameter) public virtual void pre_do_visit(pattern_parameter _pattern_parameter)
{ {
} }
public virtual void post_do_visit(pattern_deconstructor_parameter _pattern_deconstructor_parameter) public virtual void post_do_visit(pattern_parameter _pattern_parameter)
{ {
} }
@ -1893,6 +1893,110 @@ namespace PascalABCCompiler.SyntaxTree
{ {
} }
public virtual void pre_do_visit(const_pattern _const_pattern)
{
}
public virtual void post_do_visit(const_pattern _const_pattern)
{
}
public virtual void pre_do_visit(tuple_pattern_wild_card _tuple_pattern_wild_card)
{
}
public virtual void post_do_visit(tuple_pattern_wild_card _tuple_pattern_wild_card)
{
}
public virtual void pre_do_visit(const_pattern_parameter _const_pattern_parameter)
{
}
public virtual void post_do_visit(const_pattern_parameter _const_pattern_parameter)
{
}
public virtual void pre_do_visit(wild_card_deconstructor_parameter _wild_card_deconstructor_parameter)
{
}
public virtual void post_do_visit(wild_card_deconstructor_parameter _wild_card_deconstructor_parameter)
{
}
public virtual void pre_do_visit(collection_pattern _collection_pattern)
{
}
public virtual void post_do_visit(collection_pattern _collection_pattern)
{
}
public virtual void pre_do_visit(collection_pattern_gap_parameter _collection_pattern_gap_parameter)
{
}
public virtual void post_do_visit(collection_pattern_gap_parameter _collection_pattern_gap_parameter)
{
}
public virtual void pre_do_visit(collection_pattern_wild_card _collection_pattern_wild_card)
{
}
public virtual void post_do_visit(collection_pattern_wild_card _collection_pattern_wild_card)
{
}
public virtual void pre_do_visit(collection_pattern_var_parameter _collection_pattern_var_parameter)
{
}
public virtual void post_do_visit(collection_pattern_var_parameter _collection_pattern_var_parameter)
{
}
public virtual void pre_do_visit(recursive_collection_parameter _recursive_collection_parameter)
{
}
public virtual void post_do_visit(recursive_collection_parameter _recursive_collection_parameter)
{
}
public virtual void pre_do_visit(recursive_pattern_parameter _recursive_pattern_parameter)
{
}
public virtual void post_do_visit(recursive_pattern_parameter _recursive_pattern_parameter)
{
}
public virtual void pre_do_visit(tuple_pattern _tuple_pattern)
{
}
public virtual void post_do_visit(tuple_pattern _tuple_pattern)
{
}
public virtual void pre_do_visit(tuple_pattern_var_parameter _tuple_pattern_var_parameter)
{
}
public virtual void post_do_visit(tuple_pattern_var_parameter _tuple_pattern_var_parameter)
{
}
public virtual void pre_do_visit(recursive_tuple_parameter _recursive_tuple_parameter)
{
}
public virtual void post_do_visit(recursive_tuple_parameter _recursive_tuple_parameter)
{
}
public override void visit(expression _expression) public override void visit(expression _expression)
{ {
DefaultVisit(_expression); DefaultVisit(_expression);
@ -3804,6 +3908,8 @@ namespace PascalABCCompiler.SyntaxTree
{ {
DefaultVisit(_pattern_node); DefaultVisit(_pattern_node);
pre_do_visit(_pattern_node); pre_do_visit(_pattern_node);
for (int i = 0; i < parameters.Count; i++)
visit(pattern_node.parameters[i]);
post_do_visit(_pattern_node); post_do_visit(_pattern_node);
} }
@ -3858,17 +3964,16 @@ namespace PascalABCCompiler.SyntaxTree
{ {
DefaultVisit(_deconstructor_pattern); DefaultVisit(_deconstructor_pattern);
pre_do_visit(_deconstructor_pattern); pre_do_visit(_deconstructor_pattern);
for (int i = 0; i < parameters.Count; i++)
visit(deconstructor_pattern.parameters[i]);
visit(deconstructor_pattern.type); visit(deconstructor_pattern.type);
visit(deconstructor_pattern.const_params_check);
post_do_visit(_deconstructor_pattern); post_do_visit(_deconstructor_pattern);
} }
public override void visit(pattern_deconstructor_parameter _pattern_deconstructor_parameter) public override void visit(pattern_parameter _pattern_parameter)
{ {
DefaultVisit(_pattern_deconstructor_parameter); DefaultVisit(_pattern_parameter);
pre_do_visit(_pattern_deconstructor_parameter); pre_do_visit(_pattern_parameter);
post_do_visit(_pattern_deconstructor_parameter); post_do_visit(_pattern_parameter);
} }
public override void visit(desugared_deconstruction _desugared_deconstruction) public override void visit(desugared_deconstruction _desugared_deconstruction)
@ -3893,7 +3998,6 @@ namespace PascalABCCompiler.SyntaxTree
{ {
DefaultVisit(_recursive_deconstructor_parameter); DefaultVisit(_recursive_deconstructor_parameter);
pre_do_visit(_recursive_deconstructor_parameter); pre_do_visit(_recursive_deconstructor_parameter);
visit(recursive_deconstructor_parameter.pattern);
post_do_visit(_recursive_deconstructor_parameter); post_do_visit(_recursive_deconstructor_parameter);
} }
@ -3921,6 +4025,104 @@ namespace PascalABCCompiler.SyntaxTree
visit(semantic_check_sugared_var_def_statement_node.lst[i]); visit(semantic_check_sugared_var_def_statement_node.lst[i]);
post_do_visit(_semantic_check_sugared_var_def_statement_node); post_do_visit(_semantic_check_sugared_var_def_statement_node);
} }
public override void visit(const_pattern _const_pattern)
{
DefaultVisit(_const_pattern);
pre_do_visit(_const_pattern);
visit(const_pattern.pattern_expressions);
post_do_visit(_const_pattern);
}
public override void visit(tuple_pattern_wild_card _tuple_pattern_wild_card)
{
DefaultVisit(_tuple_pattern_wild_card);
pre_do_visit(_tuple_pattern_wild_card);
post_do_visit(_tuple_pattern_wild_card);
}
public override void visit(const_pattern_parameter _const_pattern_parameter)
{
DefaultVisit(_const_pattern_parameter);
pre_do_visit(_const_pattern_parameter);
visit(const_pattern_parameter.const_param);
post_do_visit(_const_pattern_parameter);
}
public override void visit(wild_card_deconstructor_parameter _wild_card_deconstructor_parameter)
{
DefaultVisit(_wild_card_deconstructor_parameter);
pre_do_visit(_wild_card_deconstructor_parameter);
post_do_visit(_wild_card_deconstructor_parameter);
}
public override void visit(collection_pattern _collection_pattern)
{
DefaultVisit(_collection_pattern);
pre_do_visit(_collection_pattern);
post_do_visit(_collection_pattern);
}
public override void visit(collection_pattern_gap_parameter _collection_pattern_gap_parameter)
{
DefaultVisit(_collection_pattern_gap_parameter);
pre_do_visit(_collection_pattern_gap_parameter);
post_do_visit(_collection_pattern_gap_parameter);
}
public override void visit(collection_pattern_wild_card _collection_pattern_wild_card)
{
DefaultVisit(_collection_pattern_wild_card);
pre_do_visit(_collection_pattern_wild_card);
post_do_visit(_collection_pattern_wild_card);
}
public override void visit(collection_pattern_var_parameter _collection_pattern_var_parameter)
{
DefaultVisit(_collection_pattern_var_parameter);
pre_do_visit(_collection_pattern_var_parameter);
visit(collection_pattern_var_parameter.identifier);
visit(collection_pattern_var_parameter.type);
post_do_visit(_collection_pattern_var_parameter);
}
public override void visit(recursive_collection_parameter _recursive_collection_parameter)
{
DefaultVisit(_recursive_collection_parameter);
pre_do_visit(_recursive_collection_parameter);
post_do_visit(_recursive_collection_parameter);
}
public override void visit(recursive_pattern_parameter _recursive_pattern_parameter)
{
DefaultVisit(_recursive_pattern_parameter);
pre_do_visit(_recursive_pattern_parameter);
visit(recursive_pattern_parameter.pattern);
post_do_visit(_recursive_pattern_parameter);
}
public override void visit(tuple_pattern _tuple_pattern)
{
DefaultVisit(_tuple_pattern);
pre_do_visit(_tuple_pattern);
post_do_visit(_tuple_pattern);
}
public override void visit(tuple_pattern_var_parameter _tuple_pattern_var_parameter)
{
DefaultVisit(_tuple_pattern_var_parameter);
pre_do_visit(_tuple_pattern_var_parameter);
visit(tuple_pattern_var_parameter.identifier);
visit(tuple_pattern_var_parameter.type);
post_do_visit(_tuple_pattern_var_parameter);
}
public override void visit(recursive_tuple_parameter _recursive_tuple_parameter)
{
DefaultVisit(_recursive_tuple_parameter);
pre_do_visit(_recursive_tuple_parameter);
post_do_visit(_recursive_tuple_parameter);
}
} }

View file

@ -479,7 +479,7 @@ namespace PascalABCCompiler.SyntaxTree
case 228: case 228:
return new deconstructor_pattern(); return new deconstructor_pattern();
case 229: case 229:
return new pattern_deconstructor_parameter(); return new pattern_parameter();
case 230: case 230:
return new desugared_deconstruction(); return new desugared_deconstruction();
case 231: case 231:
@ -492,6 +492,32 @@ namespace PascalABCCompiler.SyntaxTree
return new var_tuple_def_statement(); return new var_tuple_def_statement();
case 235: case 235:
return new semantic_check_sugared_var_def_statement_node(); return new semantic_check_sugared_var_def_statement_node();
case 236:
return new const_pattern();
case 237:
return new tuple_pattern_wild_card();
case 238:
return new const_pattern_parameter();
case 239:
return new wild_card_deconstructor_parameter();
case 240:
return new collection_pattern();
case 241:
return new collection_pattern_gap_parameter();
case 242:
return new collection_pattern_wild_card();
case 243:
return new collection_pattern_var_parameter();
case 244:
return new recursive_collection_parameter();
case 245:
return new recursive_pattern_parameter();
case 246:
return new tuple_pattern();
case 247:
return new tuple_pattern_var_parameter();
case 248:
return new recursive_tuple_parameter();
} }
return null; return null;
} }
@ -3964,6 +3990,19 @@ namespace PascalABCCompiler.SyntaxTree
public void read_pattern_node(pattern_node _pattern_node) public void read_pattern_node(pattern_node _pattern_node)
{ {
read_syntax_tree_node(_pattern_node); read_syntax_tree_node(_pattern_node);
if (br.ReadByte() == 0)
{
_pattern_node.parameters = null;
}
else
{
_pattern_node.parameters = new List<pattern_parameter>();
Int32 ssyy_count = br.ReadInt32();
for(Int32 ssyy_i = 0; ssyy_i < ssyy_count; ssyy_i++)
{
_pattern_node.parameters.Add(_read_node() as pattern_parameter);
}
}
} }
@ -4053,31 +4092,19 @@ namespace PascalABCCompiler.SyntaxTree
public void read_deconstructor_pattern(deconstructor_pattern _deconstructor_pattern) public void read_deconstructor_pattern(deconstructor_pattern _deconstructor_pattern)
{ {
read_pattern_node(_deconstructor_pattern); read_pattern_node(_deconstructor_pattern);
if (br.ReadByte() == 0)
{
_deconstructor_pattern.parameters = null;
}
else
{
_deconstructor_pattern.parameters = new List<pattern_deconstructor_parameter>();
Int32 ssyy_count = br.ReadInt32();
for(Int32 ssyy_i = 0; ssyy_i < ssyy_count; ssyy_i++)
{
_deconstructor_pattern.parameters.Add(_read_node() as pattern_deconstructor_parameter);
}
}
_deconstructor_pattern.type = _read_node() as type_definition; _deconstructor_pattern.type = _read_node() as type_definition;
_deconstructor_pattern.const_params_check = _read_node() as expression;
} }
public void visit(pattern_deconstructor_parameter _pattern_deconstructor_parameter) public void visit(pattern_parameter _pattern_parameter)
{ {
read_pattern_deconstructor_parameter(_pattern_deconstructor_parameter); read_pattern_parameter(_pattern_parameter);
} }
public void read_pattern_deconstructor_parameter(pattern_deconstructor_parameter _pattern_deconstructor_parameter) public void read_pattern_parameter(pattern_parameter _pattern_parameter)
{ {
read_syntax_tree_node(_pattern_deconstructor_parameter); read_syntax_tree_node(_pattern_parameter);
} }
@ -4101,9 +4128,10 @@ namespace PascalABCCompiler.SyntaxTree
public void read_var_deconstructor_parameter(var_deconstructor_parameter _var_deconstructor_parameter) public void read_var_deconstructor_parameter(var_deconstructor_parameter _var_deconstructor_parameter)
{ {
read_pattern_deconstructor_parameter(_var_deconstructor_parameter); read_pattern_parameter(_var_deconstructor_parameter);
_var_deconstructor_parameter.identifier = _read_node() as ident; _var_deconstructor_parameter.identifier = _read_node() as ident;
_var_deconstructor_parameter.type = _read_node() as type_definition; _var_deconstructor_parameter.type = _read_node() as type_definition;
_var_deconstructor_parameter.var_keyword_used = br.ReadBoolean();
} }
@ -4114,8 +4142,7 @@ namespace PascalABCCompiler.SyntaxTree
public void read_recursive_deconstructor_parameter(recursive_deconstructor_parameter _recursive_deconstructor_parameter) public void read_recursive_deconstructor_parameter(recursive_deconstructor_parameter _recursive_deconstructor_parameter)
{ {
read_pattern_deconstructor_parameter(_recursive_deconstructor_parameter); read_recursive_pattern_parameter(_recursive_deconstructor_parameter);
_recursive_deconstructor_parameter.pattern = _read_node() as pattern_node;
} }
@ -4178,6 +4205,156 @@ namespace PascalABCCompiler.SyntaxTree
} }
} }
public void visit(const_pattern _const_pattern)
{
read_const_pattern(_const_pattern);
}
public void read_const_pattern(const_pattern _const_pattern)
{
read_pattern_node(_const_pattern);
_const_pattern.pattern_expressions = _read_node() as expression_list;
}
public void visit(tuple_pattern_wild_card _tuple_pattern_wild_card)
{
read_tuple_pattern_wild_card(_tuple_pattern_wild_card);
}
public void read_tuple_pattern_wild_card(tuple_pattern_wild_card _tuple_pattern_wild_card)
{
read_pattern_parameter(_tuple_pattern_wild_card);
}
public void visit(const_pattern_parameter _const_pattern_parameter)
{
read_const_pattern_parameter(_const_pattern_parameter);
}
public void read_const_pattern_parameter(const_pattern_parameter _const_pattern_parameter)
{
read_pattern_parameter(_const_pattern_parameter);
_const_pattern_parameter.const_param = _read_node() as expression;
}
public void visit(wild_card_deconstructor_parameter _wild_card_deconstructor_parameter)
{
read_wild_card_deconstructor_parameter(_wild_card_deconstructor_parameter);
}
public void read_wild_card_deconstructor_parameter(wild_card_deconstructor_parameter _wild_card_deconstructor_parameter)
{
read_pattern_parameter(_wild_card_deconstructor_parameter);
}
public void visit(collection_pattern _collection_pattern)
{
read_collection_pattern(_collection_pattern);
}
public void read_collection_pattern(collection_pattern _collection_pattern)
{
read_pattern_node(_collection_pattern);
}
public void visit(collection_pattern_gap_parameter _collection_pattern_gap_parameter)
{
read_collection_pattern_gap_parameter(_collection_pattern_gap_parameter);
}
public void read_collection_pattern_gap_parameter(collection_pattern_gap_parameter _collection_pattern_gap_parameter)
{
read_pattern_parameter(_collection_pattern_gap_parameter);
}
public void visit(collection_pattern_wild_card _collection_pattern_wild_card)
{
read_collection_pattern_wild_card(_collection_pattern_wild_card);
}
public void read_collection_pattern_wild_card(collection_pattern_wild_card _collection_pattern_wild_card)
{
read_pattern_parameter(_collection_pattern_wild_card);
}
public void visit(collection_pattern_var_parameter _collection_pattern_var_parameter)
{
read_collection_pattern_var_parameter(_collection_pattern_var_parameter);
}
public void read_collection_pattern_var_parameter(collection_pattern_var_parameter _collection_pattern_var_parameter)
{
read_pattern_parameter(_collection_pattern_var_parameter);
_collection_pattern_var_parameter.identifier = _read_node() as ident;
_collection_pattern_var_parameter.type = _read_node() as type_definition;
}
public void visit(recursive_collection_parameter _recursive_collection_parameter)
{
read_recursive_collection_parameter(_recursive_collection_parameter);
}
public void read_recursive_collection_parameter(recursive_collection_parameter _recursive_collection_parameter)
{
read_recursive_pattern_parameter(_recursive_collection_parameter);
}
public void visit(recursive_pattern_parameter _recursive_pattern_parameter)
{
read_recursive_pattern_parameter(_recursive_pattern_parameter);
}
public void read_recursive_pattern_parameter(recursive_pattern_parameter _recursive_pattern_parameter)
{
read_pattern_parameter(_recursive_pattern_parameter);
_recursive_pattern_parameter.pattern = _read_node() as pattern_node;
}
public void visit(tuple_pattern _tuple_pattern)
{
read_tuple_pattern(_tuple_pattern);
}
public void read_tuple_pattern(tuple_pattern _tuple_pattern)
{
read_pattern_node(_tuple_pattern);
}
public void visit(tuple_pattern_var_parameter _tuple_pattern_var_parameter)
{
read_tuple_pattern_var_parameter(_tuple_pattern_var_parameter);
}
public void read_tuple_pattern_var_parameter(tuple_pattern_var_parameter _tuple_pattern_var_parameter)
{
read_pattern_parameter(_tuple_pattern_var_parameter);
_tuple_pattern_var_parameter.identifier = _read_node() as ident;
_tuple_pattern_var_parameter.type = _read_node() as type_definition;
}
public void visit(recursive_tuple_parameter _recursive_tuple_parameter)
{
read_recursive_tuple_parameter(_recursive_tuple_parameter);
}
public void read_recursive_tuple_parameter(recursive_tuple_parameter _recursive_tuple_parameter)
{
read_recursive_pattern_parameter(_recursive_tuple_parameter);
}
} }

View file

@ -6188,6 +6188,27 @@ namespace PascalABCCompiler.SyntaxTree
public void write_pattern_node(pattern_node _pattern_node) public void write_pattern_node(pattern_node _pattern_node)
{ {
write_syntax_tree_node(_pattern_node); write_syntax_tree_node(_pattern_node);
if (_pattern_node.parameters == null)
{
bw.Write((byte)0);
}
else
{
bw.Write((byte)1);
bw.Write(_pattern_node.parameters.Count);
for(Int32 ssyy_i = 0; ssyy_i < _pattern_node.parameters.Count; ssyy_i++)
{
if (_pattern_node.parameters[ssyy_i] == null)
{
bw.Write((byte)0);
}
else
{
bw.Write((byte)1);
_pattern_node.parameters[ssyy_i].visit(this);
}
}
}
} }
@ -6371,27 +6392,6 @@ namespace PascalABCCompiler.SyntaxTree
public void write_deconstructor_pattern(deconstructor_pattern _deconstructor_pattern) public void write_deconstructor_pattern(deconstructor_pattern _deconstructor_pattern)
{ {
write_pattern_node(_deconstructor_pattern); write_pattern_node(_deconstructor_pattern);
if (_deconstructor_pattern.parameters == null)
{
bw.Write((byte)0);
}
else
{
bw.Write((byte)1);
bw.Write(_deconstructor_pattern.parameters.Count);
for(Int32 ssyy_i = 0; ssyy_i < _deconstructor_pattern.parameters.Count; ssyy_i++)
{
if (_deconstructor_pattern.parameters[ssyy_i] == null)
{
bw.Write((byte)0);
}
else
{
bw.Write((byte)1);
_deconstructor_pattern.parameters[ssyy_i].visit(this);
}
}
}
if (_deconstructor_pattern.type == null) if (_deconstructor_pattern.type == null)
{ {
bw.Write((byte)0); bw.Write((byte)0);
@ -6401,18 +6401,27 @@ namespace PascalABCCompiler.SyntaxTree
bw.Write((byte)1); bw.Write((byte)1);
_deconstructor_pattern.type.visit(this); _deconstructor_pattern.type.visit(this);
} }
if (_deconstructor_pattern.const_params_check == null)
{
bw.Write((byte)0);
}
else
{
bw.Write((byte)1);
_deconstructor_pattern.const_params_check.visit(this);
}
} }
public void visit(pattern_deconstructor_parameter _pattern_deconstructor_parameter) public void visit(pattern_parameter _pattern_parameter)
{ {
bw.Write((Int16)229); bw.Write((Int16)229);
write_pattern_deconstructor_parameter(_pattern_deconstructor_parameter); write_pattern_parameter(_pattern_parameter);
} }
public void write_pattern_deconstructor_parameter(pattern_deconstructor_parameter _pattern_deconstructor_parameter) public void write_pattern_parameter(pattern_parameter _pattern_parameter)
{ {
write_syntax_tree_node(_pattern_deconstructor_parameter); write_syntax_tree_node(_pattern_parameter);
} }
@ -6454,7 +6463,7 @@ namespace PascalABCCompiler.SyntaxTree
public void write_var_deconstructor_parameter(var_deconstructor_parameter _var_deconstructor_parameter) public void write_var_deconstructor_parameter(var_deconstructor_parameter _var_deconstructor_parameter)
{ {
write_pattern_deconstructor_parameter(_var_deconstructor_parameter); write_pattern_parameter(_var_deconstructor_parameter);
if (_var_deconstructor_parameter.identifier == null) if (_var_deconstructor_parameter.identifier == null)
{ {
bw.Write((byte)0); bw.Write((byte)0);
@ -6473,6 +6482,7 @@ namespace PascalABCCompiler.SyntaxTree
bw.Write((byte)1); bw.Write((byte)1);
_var_deconstructor_parameter.type.visit(this); _var_deconstructor_parameter.type.visit(this);
} }
bw.Write(_var_deconstructor_parameter.var_keyword_used);
} }
@ -6484,16 +6494,7 @@ namespace PascalABCCompiler.SyntaxTree
public void write_recursive_deconstructor_parameter(recursive_deconstructor_parameter _recursive_deconstructor_parameter) public void write_recursive_deconstructor_parameter(recursive_deconstructor_parameter _recursive_deconstructor_parameter)
{ {
write_pattern_deconstructor_parameter(_recursive_deconstructor_parameter); write_recursive_pattern_parameter(_recursive_deconstructor_parameter);
if (_recursive_deconstructor_parameter.pattern == null)
{
bw.Write((byte)0);
}
else
{
bw.Write((byte)1);
_recursive_deconstructor_parameter.pattern.visit(this);
}
} }
@ -6575,6 +6576,225 @@ namespace PascalABCCompiler.SyntaxTree
} }
} }
public void visit(const_pattern _const_pattern)
{
bw.Write((Int16)236);
write_const_pattern(_const_pattern);
}
public void write_const_pattern(const_pattern _const_pattern)
{
write_pattern_node(_const_pattern);
if (_const_pattern.pattern_expressions == null)
{
bw.Write((byte)0);
}
else
{
bw.Write((byte)1);
_const_pattern.pattern_expressions.visit(this);
}
}
public void visit(tuple_pattern_wild_card _tuple_pattern_wild_card)
{
bw.Write((Int16)237);
write_tuple_pattern_wild_card(_tuple_pattern_wild_card);
}
public void write_tuple_pattern_wild_card(tuple_pattern_wild_card _tuple_pattern_wild_card)
{
write_pattern_parameter(_tuple_pattern_wild_card);
}
public void visit(const_pattern_parameter _const_pattern_parameter)
{
bw.Write((Int16)238);
write_const_pattern_parameter(_const_pattern_parameter);
}
public void write_const_pattern_parameter(const_pattern_parameter _const_pattern_parameter)
{
write_pattern_parameter(_const_pattern_parameter);
if (_const_pattern_parameter.const_param == null)
{
bw.Write((byte)0);
}
else
{
bw.Write((byte)1);
_const_pattern_parameter.const_param.visit(this);
}
}
public void visit(wild_card_deconstructor_parameter _wild_card_deconstructor_parameter)
{
bw.Write((Int16)239);
write_wild_card_deconstructor_parameter(_wild_card_deconstructor_parameter);
}
public void write_wild_card_deconstructor_parameter(wild_card_deconstructor_parameter _wild_card_deconstructor_parameter)
{
write_pattern_parameter(_wild_card_deconstructor_parameter);
}
public void visit(collection_pattern _collection_pattern)
{
bw.Write((Int16)240);
write_collection_pattern(_collection_pattern);
}
public void write_collection_pattern(collection_pattern _collection_pattern)
{
write_pattern_node(_collection_pattern);
}
public void visit(collection_pattern_gap_parameter _collection_pattern_gap_parameter)
{
bw.Write((Int16)241);
write_collection_pattern_gap_parameter(_collection_pattern_gap_parameter);
}
public void write_collection_pattern_gap_parameter(collection_pattern_gap_parameter _collection_pattern_gap_parameter)
{
write_pattern_parameter(_collection_pattern_gap_parameter);
}
public void visit(collection_pattern_wild_card _collection_pattern_wild_card)
{
bw.Write((Int16)242);
write_collection_pattern_wild_card(_collection_pattern_wild_card);
}
public void write_collection_pattern_wild_card(collection_pattern_wild_card _collection_pattern_wild_card)
{
write_pattern_parameter(_collection_pattern_wild_card);
}
public void visit(collection_pattern_var_parameter _collection_pattern_var_parameter)
{
bw.Write((Int16)243);
write_collection_pattern_var_parameter(_collection_pattern_var_parameter);
}
public void write_collection_pattern_var_parameter(collection_pattern_var_parameter _collection_pattern_var_parameter)
{
write_pattern_parameter(_collection_pattern_var_parameter);
if (_collection_pattern_var_parameter.identifier == null)
{
bw.Write((byte)0);
}
else
{
bw.Write((byte)1);
_collection_pattern_var_parameter.identifier.visit(this);
}
if (_collection_pattern_var_parameter.type == null)
{
bw.Write((byte)0);
}
else
{
bw.Write((byte)1);
_collection_pattern_var_parameter.type.visit(this);
}
}
public void visit(recursive_collection_parameter _recursive_collection_parameter)
{
bw.Write((Int16)244);
write_recursive_collection_parameter(_recursive_collection_parameter);
}
public void write_recursive_collection_parameter(recursive_collection_parameter _recursive_collection_parameter)
{
write_recursive_pattern_parameter(_recursive_collection_parameter);
}
public void visit(recursive_pattern_parameter _recursive_pattern_parameter)
{
bw.Write((Int16)245);
write_recursive_pattern_parameter(_recursive_pattern_parameter);
}
public void write_recursive_pattern_parameter(recursive_pattern_parameter _recursive_pattern_parameter)
{
write_pattern_parameter(_recursive_pattern_parameter);
if (_recursive_pattern_parameter.pattern == null)
{
bw.Write((byte)0);
}
else
{
bw.Write((byte)1);
_recursive_pattern_parameter.pattern.visit(this);
}
}
public void visit(tuple_pattern _tuple_pattern)
{
bw.Write((Int16)246);
write_tuple_pattern(_tuple_pattern);
}
public void write_tuple_pattern(tuple_pattern _tuple_pattern)
{
write_pattern_node(_tuple_pattern);
}
public void visit(tuple_pattern_var_parameter _tuple_pattern_var_parameter)
{
bw.Write((Int16)247);
write_tuple_pattern_var_parameter(_tuple_pattern_var_parameter);
}
public void write_tuple_pattern_var_parameter(tuple_pattern_var_parameter _tuple_pattern_var_parameter)
{
write_pattern_parameter(_tuple_pattern_var_parameter);
if (_tuple_pattern_var_parameter.identifier == null)
{
bw.Write((byte)0);
}
else
{
bw.Write((byte)1);
_tuple_pattern_var_parameter.identifier.visit(this);
}
if (_tuple_pattern_var_parameter.type == null)
{
bw.Write((byte)0);
}
else
{
bw.Write((byte)1);
_tuple_pattern_var_parameter.type.visit(this);
}
}
public void visit(recursive_tuple_parameter _recursive_tuple_parameter)
{
bw.Write((Int16)248);
write_recursive_tuple_parameter(_recursive_tuple_parameter);
}
public void write_recursive_tuple_parameter(recursive_tuple_parameter _recursive_tuple_parameter)
{
write_recursive_pattern_parameter(_recursive_tuple_parameter);
}
} }

File diff suppressed because it is too large Load diff

View file

@ -33,7 +33,7 @@ namespace PascalABCCompiler.SyntaxTree
DirectDescendants DirectDescendants
} }
public enum SemanticCheckType { MatchedExpression, MatchedExpressionAndType } public enum SemanticCheckType { MatchedExpression, MatchedExpressionAndType, MatchedExpressionAndExpression, MatchedTuple }
public partial class syntax_tree_node public partial class syntax_tree_node
{ {
@ -393,6 +393,11 @@ namespace PascalABCCompiler.SyntaxTree
return new bin_expr(left, right, Operators.LogicalAND); return new bin_expr(left, right, Operators.LogicalAND);
} }
public static bin_expr LogicalOr(expression left, expression right)
{
return new bin_expr(left, right, Operators.LogicalOR);
}
public override string ToString() public override string ToString()
{ {
return string.Format("{0} {2} {1}", left, right, OperatorServices.ToString(operation_type, LanguageId.PascalABCNET)); return string.Format("{0} {2} {1}", left, right, OperatorServices.ToString(operation_type, LanguageId.PascalABCNET));
@ -1093,8 +1098,8 @@ namespace PascalABCCompiler.SyntaxTree
public partial class simple_property public partial class simple_property
{ {
public simple_property(ident name, type_definition type, property_accessors accessors, SourceContext sc = null) public simple_property(ident name, type_definition type, property_accessors accessors, SourceContext sc = null)
: this(name, type, null, accessors, null, null, definition_attribute.None,proc_attribute.attr_none,false, null, sc) : this(name, type, null, accessors, null, null, definition_attribute.None, proc_attribute.attr_none, false, null, sc)
{ } { }
} }
@ -1709,7 +1714,7 @@ namespace PascalABCCompiler.SyntaxTree
public partial class expression public partial class expression
{ {
//public object semantic_ex; //public object semantic_ex;
public expression Plus(expression e) public expression Plus(expression e)
{ {
return new bin_expr(this, e, Operators.Plus); return new bin_expr(this, e, Operators.Plus);
@ -1814,19 +1819,12 @@ namespace PascalABCCompiler.SyntaxTree
public partial class deconstructor_pattern public partial class deconstructor_pattern
{ {
public bool IsRecursive => parameters.Any(x => x is recursive_deconstructor_parameter);
public override string ToString() => $"{type}({string.Join(", ", parameters.Select(x => x.ToString()))})"; public override string ToString() => $"{type}({string.Join(", ", parameters.Select(x => x.ToString()))})";
} }
public partial class var_deconstructor_parameter public partial class pattern_node
{ {
public override string ToString() => identifier.ToString() + (type == null ? "" : $": {type}"); public bool IsRecursive => parameters.Any(x => x is recursive_pattern_parameter);
}
public partial class recursive_deconstructor_parameter
{
public override string ToString() => pattern.ToString();
} }
public partial class typecast_node public partial class typecast_node
@ -1842,5 +1840,58 @@ namespace PascalABCCompiler.SyntaxTree
public bool visited = false; public bool visited = false;
} }
public partial class var_deconstructor_parameter
{
public override string ToString() => identifier.ToString() + (type == null ? "" : $": {type}");
} }
public partial class recursive_deconstructor_parameter
{
public override string ToString() => pattern.ToString();
}
public partial class tuple_pattern_wild_card
{
///<summary>
///Конструктор c параметрами
///</summary>
public tuple_pattern_wild_card(SourceContext sc)
{
this.source_context = sc;
}
}
public partial class collection_pattern_wild_card
{
///<summary>
///Конструктор c параметрами
///</summary>
public collection_pattern_wild_card(SourceContext sc)
{
this.source_context = sc;
}
}
public partial class collection_pattern_gap_parameter
{
///<summary>
///Конструктор c параметрами
///</summary>
public collection_pattern_gap_parameter(SourceContext sc)
{
this.source_context = sc;
}
}
public partial class wild_card_deconstructor_parameter
{
///<summary>
///Конструктор c параметрами
///</summary>
public wild_card_deconstructor_parameter(SourceContext sc)
{
this.source_context = sc;
}
}
}

View file

@ -1379,11 +1379,11 @@ namespace PascalABCCompiler.SyntaxTree
///<returns> Return value is void </returns> ///<returns> Return value is void </returns>
void visit(deconstructor_pattern _deconstructor_pattern); void visit(deconstructor_pattern _deconstructor_pattern);
///<summary> ///<summary>
///Method to visit pattern_deconstructor_parameter. ///Method to visit pattern_parameter.
///</summary> ///</summary>
///<param name="_pattern_deconstructor_parameter">Node to visit</param> ///<param name="_pattern_parameter">Node to visit</param>
///<returns> Return value is void </returns> ///<returns> Return value is void </returns>
void visit(pattern_deconstructor_parameter _pattern_deconstructor_parameter); void visit(pattern_parameter _pattern_parameter);
///<summary> ///<summary>
///Method to visit desugared_deconstruction. ///Method to visit desugared_deconstruction.
///</summary> ///</summary>
@ -1420,6 +1420,84 @@ namespace PascalABCCompiler.SyntaxTree
///<param name="_semantic_check_sugared_var_def_statement_node">Node to visit</param> ///<param name="_semantic_check_sugared_var_def_statement_node">Node to visit</param>
///<returns> Return value is void </returns> ///<returns> Return value is void </returns>
void visit(semantic_check_sugared_var_def_statement_node _semantic_check_sugared_var_def_statement_node); void visit(semantic_check_sugared_var_def_statement_node _semantic_check_sugared_var_def_statement_node);
///<summary>
///Method to visit const_pattern.
///</summary>
///<param name="_const_pattern">Node to visit</param>
///<returns> Return value is void </returns>
void visit(const_pattern _const_pattern);
///<summary>
///Method to visit tuple_pattern_wild_card.
///</summary>
///<param name="_tuple_pattern_wild_card">Node to visit</param>
///<returns> Return value is void </returns>
void visit(tuple_pattern_wild_card _tuple_pattern_wild_card);
///<summary>
///Method to visit const_pattern_parameter.
///</summary>
///<param name="_const_pattern_parameter">Node to visit</param>
///<returns> Return value is void </returns>
void visit(const_pattern_parameter _const_pattern_parameter);
///<summary>
///Method to visit wild_card_deconstructor_parameter.
///</summary>
///<param name="_wild_card_deconstructor_parameter">Node to visit</param>
///<returns> Return value is void </returns>
void visit(wild_card_deconstructor_parameter _wild_card_deconstructor_parameter);
///<summary>
///Method to visit collection_pattern.
///</summary>
///<param name="_collection_pattern">Node to visit</param>
///<returns> Return value is void </returns>
void visit(collection_pattern _collection_pattern);
///<summary>
///Method to visit collection_pattern_gap_parameter.
///</summary>
///<param name="_collection_pattern_gap_parameter">Node to visit</param>
///<returns> Return value is void </returns>
void visit(collection_pattern_gap_parameter _collection_pattern_gap_parameter);
///<summary>
///Method to visit collection_pattern_wild_card.
///</summary>
///<param name="_collection_pattern_wild_card">Node to visit</param>
///<returns> Return value is void </returns>
void visit(collection_pattern_wild_card _collection_pattern_wild_card);
///<summary>
///Method to visit collection_pattern_var_parameter.
///</summary>
///<param name="_collection_pattern_var_parameter">Node to visit</param>
///<returns> Return value is void </returns>
void visit(collection_pattern_var_parameter _collection_pattern_var_parameter);
///<summary>
///Method to visit recursive_collection_parameter.
///</summary>
///<param name="_recursive_collection_parameter">Node to visit</param>
///<returns> Return value is void </returns>
void visit(recursive_collection_parameter _recursive_collection_parameter);
///<summary>
///Method to visit recursive_pattern_parameter.
///</summary>
///<param name="_recursive_pattern_parameter">Node to visit</param>
///<returns> Return value is void </returns>
void visit(recursive_pattern_parameter _recursive_pattern_parameter);
///<summary>
///Method to visit tuple_pattern.
///</summary>
///<param name="_tuple_pattern">Node to visit</param>
///<returns> Return value is void </returns>
void visit(tuple_pattern _tuple_pattern);
///<summary>
///Method to visit tuple_pattern_var_parameter.
///</summary>
///<param name="_tuple_pattern_var_parameter">Node to visit</param>
///<returns> Return value is void </returns>
void visit(tuple_pattern_var_parameter _tuple_pattern_var_parameter);
///<summary>
///Method to visit recursive_tuple_parameter.
///</summary>
///<param name="_recursive_tuple_parameter">Node to visit</param>
///<returns> Return value is void </returns>
void visit(recursive_tuple_parameter _recursive_tuple_parameter);
} }

View file

@ -2865,7 +2865,9 @@
</Tags> </Tags>
</SyntaxNode> </SyntaxNode>
<SyntaxNode Name="pattern_node" BaseName="syntax_tree_node"> <SyntaxNode Name="pattern_node" BaseName="syntax_tree_node">
<Fields /> <Fields>
<ExtendedField Name="parameters" Type="List&lt;pattern_parameter&gt;" CreateVariable="true" DeleteVariable="false" />
</Fields>
<Methods /> <Methods />
<Tags> <Tags>
<CategoryIndices> <CategoryIndices>
@ -2954,8 +2956,8 @@
</SyntaxNode> </SyntaxNode>
<SyntaxNode Name="deconstructor_pattern" BaseName="pattern_node"> <SyntaxNode Name="deconstructor_pattern" BaseName="pattern_node">
<Fields> <Fields>
<ExtendedField Name="parameters" Type="List&lt;pattern_deconstructor_parameter&gt;" CreateVariable="true" DeleteVariable="false" />
<SyntaxField Name="type" SyntaxType="type_definition" /> <SyntaxField Name="type" SyntaxType="type_definition" />
<SyntaxField Name="const_params_check" SyntaxType="expression" />
</Fields> </Fields>
<Methods /> <Methods />
<Tags> <Tags>
@ -2967,7 +2969,7 @@
</TagIndices> </TagIndices>
</Tags> </Tags>
</SyntaxNode> </SyntaxNode>
<SyntaxNode Name="pattern_deconstructor_parameter" BaseName="syntax_tree_node"> <SyntaxNode Name="pattern_parameter" BaseName="syntax_tree_node">
<Fields /> <Fields />
<Methods /> <Methods />
<Tags> <Tags>
@ -2994,10 +2996,11 @@
</TagIndices> </TagIndices>
</Tags> </Tags>
</SyntaxNode> </SyntaxNode>
<SyntaxNode Name="var_deconstructor_parameter" BaseName="pattern_deconstructor_parameter"> <SyntaxNode Name="var_deconstructor_parameter" BaseName="pattern_parameter">
<Fields> <Fields>
<SyntaxField Name="identifier" SyntaxType="ident" /> <SyntaxField Name="identifier" SyntaxType="ident" />
<SyntaxField Name="type" SyntaxType="type_definition" /> <SyntaxField Name="type" SyntaxType="type_definition" />
<ExtendedField Name="var_keyword_used" Type="bool" CreateVariable="false" DeleteVariable="false" />
</Fields> </Fields>
<Methods /> <Methods />
<Tags> <Tags>
@ -3009,10 +3012,8 @@
</TagIndices> </TagIndices>
</Tags> </Tags>
</SyntaxNode> </SyntaxNode>
<SyntaxNode Name="recursive_deconstructor_parameter" BaseName="pattern_deconstructor_parameter"> <SyntaxNode Name="recursive_deconstructor_parameter" BaseName="recursive_pattern_parameter">
<Fields> <Fields />
<SyntaxField Name="pattern" SyntaxType="pattern_node" />
</Fields>
<Methods /> <Methods />
<Tags> <Tags>
<CategoryIndices> <CategoryIndices>
@ -3056,6 +3057,174 @@
<TagIndices /> <TagIndices />
</Tags> </Tags>
</SyntaxNode> </SyntaxNode>
<SyntaxNode Name="const_pattern" BaseName="pattern_node">
<Fields>
<SyntaxField Name="pattern_expressions" SyntaxType="expression_list" />
</Fields>
<Methods />
<Tags>
<CategoryIndices>
<CategoryIndex>0</CategoryIndex>
</CategoryIndices>
<TagIndices>
<TagIndex>9</TagIndex>
</TagIndices>
</Tags>
</SyntaxNode>
<SyntaxNode Name="tuple_pattern_wild_card" BaseName="pattern_parameter">
<Fields />
<Methods />
<Tags>
<CategoryIndices>
<CategoryIndex>0</CategoryIndex>
</CategoryIndices>
<TagIndices>
<TagIndex>9</TagIndex>
</TagIndices>
</Tags>
</SyntaxNode>
<SyntaxNode Name="const_pattern_parameter" BaseName="pattern_parameter">
<Fields>
<SyntaxField Name="const_param" SyntaxType="expression" />
</Fields>
<Methods />
<Tags>
<CategoryIndices>
<CategoryIndex>0</CategoryIndex>
</CategoryIndices>
<TagIndices>
<TagIndex>9</TagIndex>
</TagIndices>
</Tags>
</SyntaxNode>
<SyntaxNode Name="wild_card_deconstructor_parameter" BaseName="pattern_parameter">
<Fields />
<Methods />
<Tags>
<CategoryIndices>
<CategoryIndex>0</CategoryIndex>
</CategoryIndices>
<TagIndices>
<TagIndex>9</TagIndex>
</TagIndices>
</Tags>
</SyntaxNode>
<SyntaxNode Name="collection_pattern" BaseName="pattern_node">
<Fields />
<Methods />
<Tags>
<CategoryIndices>
<CategoryIndex>0</CategoryIndex>
</CategoryIndices>
<TagIndices>
<TagIndex>9</TagIndex>
</TagIndices>
</Tags>
</SyntaxNode>
<SyntaxNode Name="collection_pattern_gap_parameter" BaseName="pattern_parameter">
<Fields />
<Methods />
<Tags>
<CategoryIndices>
<CategoryIndex>0</CategoryIndex>
</CategoryIndices>
<TagIndices>
<TagIndex>9</TagIndex>
</TagIndices>
</Tags>
</SyntaxNode>
<SyntaxNode Name="collection_pattern_wild_card" BaseName="pattern_parameter">
<Fields />
<Methods />
<Tags>
<CategoryIndices>
<CategoryIndex>0</CategoryIndex>
</CategoryIndices>
<TagIndices>
<TagIndex>9</TagIndex>
</TagIndices>
</Tags>
</SyntaxNode>
<SyntaxNode Name="collection_pattern_var_parameter" BaseName="pattern_parameter">
<Fields>
<SyntaxField Name="identifier" SyntaxType="ident" />
<SyntaxField Name="type" SyntaxType="type_definition" />
</Fields>
<Methods />
<Tags>
<CategoryIndices>
<CategoryIndex>0</CategoryIndex>
</CategoryIndices>
<TagIndices>
<TagIndex>9</TagIndex>
</TagIndices>
</Tags>
</SyntaxNode>
<SyntaxNode Name="recursive_collection_parameter" BaseName="recursive_pattern_parameter">
<Fields />
<Methods />
<Tags>
<CategoryIndices>
<CategoryIndex>0</CategoryIndex>
</CategoryIndices>
<TagIndices>
<TagIndex>9</TagIndex>
</TagIndices>
</Tags>
</SyntaxNode>
<SyntaxNode Name="recursive_pattern_parameter" BaseName="pattern_parameter">
<Fields>
<SyntaxField Name="pattern" SyntaxType="pattern_node" />
</Fields>
<Methods />
<Tags>
<CategoryIndices>
<CategoryIndex>0</CategoryIndex>
</CategoryIndices>
<TagIndices>
<TagIndex>9</TagIndex>
</TagIndices>
</Tags>
</SyntaxNode>
<SyntaxNode Name="tuple_pattern" BaseName="pattern_node">
<Fields />
<Methods />
<Tags>
<CategoryIndices>
<CategoryIndex>0</CategoryIndex>
</CategoryIndices>
<TagIndices>
<TagIndex>9</TagIndex>
</TagIndices>
</Tags>
</SyntaxNode>
<SyntaxNode Name="tuple_pattern_var_parameter" BaseName="pattern_parameter">
<Fields>
<SyntaxField Name="identifier" SyntaxType="ident" />
<SyntaxField Name="type" SyntaxType="type_definition" />
</Fields>
<Methods />
<Tags>
<CategoryIndices>
<CategoryIndex>0</CategoryIndex>
</CategoryIndices>
<TagIndices>
<TagIndex>9</TagIndex>
</TagIndices>
</Tags>
</SyntaxNode>
<SyntaxNode Name="recursive_tuple_parameter" BaseName="recursive_pattern_parameter">
<Fields />
<Methods />
<Tags>
<CategoryIndices>
<CategoryIndex>0</CategoryIndex>
</CategoryIndices>
<TagIndices>
<TagIndex>9</TagIndex>
</TagIndices>
</Tags>
</SyntaxNode>
</SyntaxNodes> </SyntaxNodes>
<Settings> <Settings>
<FileName>Tree.cs</FileName> <FileName>Tree.cs</FileName>
@ -3081,7 +3250,7 @@
<Tag Name="Важнейшие" ReferenceCount="207" /> <Tag Name="Важнейшие" ReferenceCount="207" />
<Tag Name="Method_Procedure_Call" ReferenceCount="2" /> <Tag Name="Method_Procedure_Call" ReferenceCount="2" />
<Tag Name="Yield" ReferenceCount="8" /> <Tag Name="Yield" ReferenceCount="8" />
<Tag Name="Patterns" ReferenceCount="12" /> <Tag Name="Patterns" ReferenceCount="25" />
<Tag Name="Typeclasses" ReferenceCount="13" /> <Tag Name="Typeclasses" ReferenceCount="13" />
</Tags> </Tags>
</FilterCategory> </FilterCategory>
@ -3118,6 +3287,8 @@
<HelpData Key=".from" Value="" /> <HelpData Key=".from" Value="" />
<HelpData Key=".guardstats" Value="" /> <HelpData Key=".guardstats" Value="" />
<HelpData Key=".handlers" Value="" /> <HelpData Key=".handlers" Value="" />
<HelpData Key=".i" Value="" />
<HelpData Key=".item_expression" Value="" />
<HelpData Key=".left" Value="" /> <HelpData Key=".left" Value="" />
<HelpData Key=".lists" Value="" /> <HelpData Key=".lists" Value="" />
<HelpData Key=".listunitsections" Value="" /> <HelpData Key=".listunitsections" Value="" />
@ -3132,6 +3303,7 @@
<HelpData Key=".parameters" Value="" /> <HelpData Key=".parameters" Value="" />
<HelpData Key=".params" Value="" /> <HelpData Key=".params" Value="" />
<HelpData Key=".pattern" Value="" /> <HelpData Key=".pattern" Value="" />
<HelpData Key=".pattern_expression" Value="" />
<HelpData Key=".procdef" Value="" /> <HelpData Key=".procdef" Value="" />
<HelpData Key=".res" Value="" /> <HelpData Key=".res" Value="" />
<HelpData Key=".restriction" Value="" /> <HelpData Key=".restriction" Value="" />
@ -3328,6 +3500,17 @@
<HelpData Key="class_predefinition.class_name" Value="" /> <HelpData Key="class_predefinition.class_name" Value="" />
<HelpData Key="closure_substituting_node" Value="" /> <HelpData Key="closure_substituting_node" Value="" />
<HelpData Key="closure_substituting_node.substitution" Value="" /> <HelpData Key="closure_substituting_node.substitution" Value="" />
<HelpData Key="collection_pattern" Value="" />
<HelpData Key="collection_pattern.collection_items" Value="" />
<HelpData Key="collection_pattern_expr_item" Value="" />
<HelpData Key="collection_pattern_expr_item.item_expression" Value="" />
<HelpData Key="collection_pattern_gap_item" Value="" />
<HelpData Key="collection_pattern_gap_parameter" Value="" />
<HelpData Key="collection_pattern_item" Value="" />
<HelpData Key="collection_pattern_var_parameter" Value="Возможно без типа" />
<HelpData Key="collection_pattern_var_parameter.identifier" Value="" />
<HelpData Key="collection_pattern_var_parameter.type" Value="" />
<HelpData Key="collection_pattern_wild_card" Value="" />
<HelpData Key="compilation_unit" Value="" /> <HelpData Key="compilation_unit" Value="" />
<HelpData Key="compilation_unit." Value="" /> <HelpData Key="compilation_unit." Value="" />
<HelpData Key="compilation_unit.Language" Value="" /> <HelpData Key="compilation_unit.Language" Value="" />
@ -3346,6 +3529,10 @@
<HelpData Key="compiler_directive_list.compiler_directive_list Add(compiler_directive _compiler_directive, SourceContext sc)" Value="" /> <HelpData Key="compiler_directive_list.compiler_directive_list Add(compiler_directive _compiler_directive, SourceContext sc)" Value="" />
<HelpData Key="compiler_directive_list.compiler_directive_list(compiler_directive _compiler_directive, SourceContext sc)" Value="" /> <HelpData Key="compiler_directive_list.compiler_directive_list(compiler_directive _compiler_directive, SourceContext sc)" Value="" />
<HelpData Key="compiler_directive_list.directives" Value="" /> <HelpData Key="compiler_directive_list.directives" Value="" />
<HelpData Key="const_deconstructor_parameter" Value="" />
<HelpData Key="const_deconstructor_parameter.const_param" Value="" />
<HelpData Key="const_deconstructor_parameter.i" Value="" />
<HelpData Key="const_deconstructor_parameter.value" Value="" />
<HelpData Key="const_definition" Value="" /> <HelpData Key="const_definition" Value="" />
<HelpData Key="const_definition.const_name" Value="" /> <HelpData Key="const_definition.const_name" Value="" />
<HelpData Key="const_definition.const_value" Value="" /> <HelpData Key="const_definition.const_value" Value="" />
@ -3356,6 +3543,11 @@
<HelpData Key="const_method_call.parametres" Value="" /> <HelpData Key="const_method_call.parametres" Value="" />
<HelpData Key="const_method_call.unit_name" Value="" /> <HelpData Key="const_method_call.unit_name" Value="" />
<HelpData Key="const_node" Value="Константа" /> <HelpData Key="const_node" Value="Константа" />
<HelpData Key="const_pattern" Value="паттерн для константного матчинга" />
<HelpData Key="const_pattern.pattern_expression" Value="" />
<HelpData Key="const_pattern.pattern_expressions" Value="" />
<HelpData Key="const_pattern_parameter" Value="" />
<HelpData Key="const_pattern_parameter.const_param" Value="" />
<HelpData Key="constructor" Value="" /> <HelpData Key="constructor" Value="" />
<HelpData Key="constructor.constructor(formal_parameters fp): this(fp, null)" Value="" /> <HelpData Key="constructor.constructor(formal_parameters fp): this(fp, null)" Value="" />
<HelpData Key="constructor.constructor(formal_parameters fp,SourceContext sc): this(null, fp, new procedure_attributes_list(proc_attribute.attr_overload), null, false, false, null, null)" Value="" /> <HelpData Key="constructor.constructor(formal_parameters fp,SourceContext sc): this(null, fp, new procedure_attributes_list(proc_attribute.attr_overload), null, false, false, null, null)" Value="" />
@ -3393,6 +3585,7 @@
<HelpData Key="deconstruction_variables_definition" Value="Список объявлений для deconstructor pattern" /> <HelpData Key="deconstruction_variables_definition" Value="Список объявлений для deconstructor pattern" />
<HelpData Key="deconstruction_variables_definition.definitions" Value="" /> <HelpData Key="deconstruction_variables_definition.definitions" Value="" />
<HelpData Key="deconstructor_pattern" Value="" /> <HelpData Key="deconstructor_pattern" Value="" />
<HelpData Key="deconstructor_pattern.const_params_check" Value="Проверка соответствия для константных параметрах деконструирования" />
<HelpData Key="deconstructor_pattern.parameters" Value="Результат деконструирования" /> <HelpData Key="deconstructor_pattern.parameters" Value="Результат деконструирования" />
<HelpData Key="deconstructor_pattern.type" Value="Деконструируемый тип" /> <HelpData Key="deconstructor_pattern.type" Value="Деконструируемый тип" />
<HelpData Key="default_indexer_property_node" Value="" /> <HelpData Key="default_indexer_property_node" Value="" />
@ -3512,6 +3705,8 @@
<HelpData Key="exception_identifier.type_name" Value="" /> <HelpData Key="exception_identifier.type_name" Value="" />
<HelpData Key="exception_identifier.variable" Value="" /> <HelpData Key="exception_identifier.variable" Value="" />
<HelpData Key="exit_directive" Value="" /> <HelpData Key="exit_directive" Value="" />
<HelpData Key="expr_collection_pattern_item" Value="" />
<HelpData Key="expr_collection_pattern_item.item_expression" Value="" />
<HelpData Key="expression" Value="Выражение" /> <HelpData Key="expression" Value="Выражение" />
<HelpData Key="expression." Value="" /> <HelpData Key="expression." Value="" />
<HelpData Key="expression_as_statement" Value="" /> <HelpData Key="expression_as_statement" Value="" />
@ -3706,6 +3901,7 @@
<HelpData Key="interface_node.uses_modules" Value="" /> <HelpData Key="interface_node.uses_modules" Value="" />
<HelpData Key="interface_node.using_namespaces" Value="" /> <HelpData Key="interface_node.using_namespaces" Value="" />
<HelpData Key="is_pattern_expr" Value="" /> <HelpData Key="is_pattern_expr" Value="" />
<HelpData Key="is_pattern_expr.constDeconstructorParamCheck" Value="" />
<HelpData Key="is_pattern_expr.left" Value="" /> <HelpData Key="is_pattern_expr.left" Value="" />
<HelpData Key="is_pattern_expr.right" Value="" /> <HelpData Key="is_pattern_expr.right" Value="" />
<HelpData Key="jump_stmt" Value="" /> <HelpData Key="jump_stmt" Value="" />
@ -3936,6 +4132,8 @@
<HelpData Key="pattern_deconstructor_parameter.name" Value="" /> <HelpData Key="pattern_deconstructor_parameter.name" Value="" />
<HelpData Key="pattern_deconstructor_parameter.type" Value="" /> <HelpData Key="pattern_deconstructor_parameter.type" Value="" />
<HelpData Key="pattern_node" Value="" /> <HelpData Key="pattern_node" Value="" />
<HelpData Key="pattern_node.parameters" Value="" />
<HelpData Key="pattern_parameter" Value="Базовый класс параметра для pattern_node" />
<HelpData Key="proc_block" Value="" /> <HelpData Key="proc_block" Value="" />
<HelpData Key="procedure_attribute" Value="" /> <HelpData Key="procedure_attribute" Value="" />
<HelpData Key="procedure_attribute.attribute_type" Value="" /> <HelpData Key="procedure_attribute.attribute_type" Value="" />
@ -4078,8 +4276,15 @@
<HelpData Key="record_type_parts" Value="" /> <HelpData Key="record_type_parts" Value="" />
<HelpData Key="record_type_parts.fixed_part" Value="" /> <HelpData Key="record_type_parts.fixed_part" Value="" />
<HelpData Key="record_type_parts.variant_part" Value="" /> <HelpData Key="record_type_parts.variant_part" Value="" />
<HelpData Key="recursive_collection_parameter" Value="Рекурсивный паттерн-параметр. " />
<HelpData Key="recursive_collection_parameter.pattern" Value="" />
<HelpData Key="recursive_collection_pattern" Value="Рекурсивный паттерн-параметр. " />
<HelpData Key="recursive_collection_pattern.pattern" Value="" />
<HelpData Key="recursive_deconstructor_parameter" Value="Параметр-паттерн. Часть рекурсивного паттерна." /> <HelpData Key="recursive_deconstructor_parameter" Value="Параметр-паттерн. Часть рекурсивного паттерна." />
<HelpData Key="recursive_deconstructor_parameter.pattern" Value="" /> <HelpData Key="recursive_deconstructor_parameter.pattern" Value="" />
<HelpData Key="recursive_pattern_parameter" Value="Рекурсивный паттерн-параметр." />
<HelpData Key="recursive_pattern_parameter.pattern" Value="" />
<HelpData Key="recursive_tuple_parameter" Value="Рекурсивный паттерн-параметр." />
<HelpData Key="ref_type" Value="" /> <HelpData Key="ref_type" Value="" />
<HelpData Key="ref_type.pointed_to" Value="" /> <HelpData Key="ref_type.pointed_to" Value="" />
<HelpData Key="repeat_node" Value="Цикл с постусловием (repeat)" /> <HelpData Key="repeat_node" Value="Цикл с постусловием (repeat)" />
@ -4280,6 +4485,12 @@
<HelpData Key="tuple_node.el" Value="" /> <HelpData Key="tuple_node.el" Value="" />
<HelpData Key="tuple_node_for_formatter" Value="" /> <HelpData Key="tuple_node_for_formatter" Value="" />
<HelpData Key="tuple_node_for_formatter.el" Value="" /> <HelpData Key="tuple_node_for_formatter.el" Value="" />
<HelpData Key="tuple_pattern" Value="" />
<HelpData Key="tuple_pattern_var_parameter" Value="" />
<HelpData Key="tuple_pattern_var_parameter.identifier" Value="" />
<HelpData Key="tuple_pattern_var_parameter.type" Value="" />
<HelpData Key="tuple_pattern_wild_card" Value="" />
<HelpData Key="tuple_wild_card" Value="" />
<HelpData Key="type_declaration" Value="" /> <HelpData Key="type_declaration" Value="" />
<HelpData Key="type_declaration.type_declaration(string name, type_definition type): this(new ident(name),type)" Value="" /> <HelpData Key="type_declaration.type_declaration(string name, type_definition type): this(new ident(name),type)" Value="" />
<HelpData Key="type_declaration.type_declaration(string name, type_definition type, SourceContext sc): this(new ident(name),type,sc)" Value="" /> <HelpData Key="type_declaration.type_declaration(string name, type_definition type, SourceContext sc): this(new ident(name),type,sc)" Value="" />
@ -4444,6 +4655,7 @@
<HelpData Key="var_deconstructor_parameter" Value="Параметр-объявление переменной (возможно без типа)" /> <HelpData Key="var_deconstructor_parameter" Value="Параметр-объявление переменной (возможно без типа)" />
<HelpData Key="var_deconstructor_parameter.identifier" Value="" /> <HelpData Key="var_deconstructor_parameter.identifier" Value="" />
<HelpData Key="var_deconstructor_parameter.type" Value="" /> <HelpData Key="var_deconstructor_parameter.type" Value="" />
<HelpData Key="var_deconstructor_parameter.var_keyword_used" Value="" />
<HelpData Key="var_def_list" Value="" /> <HelpData Key="var_def_list" Value="" />
<HelpData Key="var_def_list.var_def_list Add(var_def_statement _var_def_statement)" Value="" /> <HelpData Key="var_def_list.var_def_list Add(var_def_statement _var_def_statement)" Value="" />
<HelpData Key="var_def_list.var_def_list Add(var_def_statement _var_def_statement, SourceContext sc)" Value="" /> <HelpData Key="var_def_list.var_def_list Add(var_def_statement _var_def_statement, SourceContext sc)" Value="" />
@ -4537,6 +4749,9 @@
<HelpData Key="while_node.statements" Value="Тело цикла" /> <HelpData Key="while_node.statements" Value="Тело цикла" />
<HelpData Key="while_type_specificator_list" Value="" /> <HelpData Key="while_type_specificator_list" Value="" />
<HelpData Key="while_type_specificator_list.defs" Value="" /> <HelpData Key="while_type_specificator_list.defs" Value="" />
<HelpData Key="wild_card_deconstructor_parameter" Value="" />
<HelpData Key="wild_card_deconstructor_parameter.exp" Value="" />
<HelpData Key="wildcard_deconstructor_parameter" Value="" />
<HelpData Key="with_statement" Value="Представление оператора with в синтаксическом дереве." /> <HelpData Key="with_statement" Value="Представление оператора with в синтаксическом дереве." />
<HelpData Key="with_statement." Value="" /> <HelpData Key="with_statement." Value="" />
<HelpData Key="with_statement.do_with" Value="Список объектов, с которыми производить действия." /> <HelpData Key="with_statement.do_with" Value="Список объектов, с которыми производить действия." />

View file

@ -46,7 +46,7 @@ namespace SyntaxVisitors.SugarVisitors
{ {
var result = new List<statement>(); var result = new List<statement>();
result.Add(CastVariableDefinition); result.Add(CastVariableDefinition);
result.Add(new desugared_deconstruction(DeconstructionVariables, CastVariable, patternContext)); result.Add(new desugared_deconstruction(DeconstructionVariables, CastVariable, patternContext));
result.Add(SuccessVariableDefinition); result.Add(SuccessVariableDefinition);
return result; return result;
@ -60,23 +60,52 @@ namespace SyntaxVisitors.SugarVisitors
} }
} }
public class CollectionDesugaringResult
{
public List<statement> VarParametersDeclarations { get; set; } = new List<statement>();
public expression SuccessMatchingCheck { get; set; }
public expression CollectionLengthCheck { get; set; }
public List<semantic_check_sugared_statement_node> ElemTypeChecks { get; set; } = new List<semantic_check_sugared_statement_node>();
}
public class TupleDesugaringResult
{
public List<statement> VarParametersDeclarations { get; set; } = new List<statement>();
public expression SuccessMatchingCheck { get; set; }
public statement TupleLengthCheck { get; set; }
public List<semantic_check_sugared_statement_node> ElemTypeChecks { get; set; } = new List<semantic_check_sugared_statement_node>();
}
public class PatternsDesugaringVisitor : BaseChangeVisitor public class PatternsDesugaringVisitor : BaseChangeVisitor
{ {
private enum PatternLocation { Unknown, IfCondition, Assign } private enum PatternLocation { Unknown, IfCondition, Assign }
private const string DeconstructMethodName = compiler_string_consts.deconstruct_method_name; private const string DeconstructMethodName = compiler_string_consts.deconstruct_method_name;
private const string IsTestMethodName = compiler_string_consts.is_test_function_name; private const string IsTestMethodName = compiler_string_consts.is_test_function_name;
private const string WildCardsTupleEqualFunctionName = compiler_string_consts.wild_cards_tuple_equal_function_name;
private const string SeqFunctionName = compiler_string_consts.seq_function_name;
private const string CountPropertyName = compiler_string_consts.count_property_name;
private const string GeneratedPatternNamePrefix = "<>pattern"; private const string GeneratedPatternNamePrefix = "<>pattern";
private const string GeneratedDeconstructParamPrefix = "<>deconstructParam";
private int generalVariableCounter = 0; private int generalVariableCounter = 0;
private int successVariableCounter = 0; private int successVariableCounter = 0;
private int labelVariableCounter = 0; private int labelVariableCounter = 0;
private int deconstructParamVariableCounter = 0;
private if_node _previousIf; private if_node _previousIf;
private statement desugaredMatchWith; private statement desugaredMatchWith;
private List<if_node> processedIfNodes = new List<if_node>(); private List<if_node> processedIfNodes = new List<if_node>();
//const matching
private List<statement> typeChecks = new List<statement>();
public static PatternsDesugaringVisitor New => new PatternsDesugaringVisitor(); public static PatternsDesugaringVisitor New => new PatternsDesugaringVisitor();
public override void visit(match_with matchWith) public override void visit(match_with matchWith)
@ -95,26 +124,45 @@ namespace SyntaxVisitors.SugarVisitors
if (patternCase == null) if (patternCase == null)
continue; continue;
if (patternCase.pattern is deconstructor_pattern) switch (patternCase.pattern)
{ {
// Проверяем встречался ли уже такой тип при деконструкции case deconstructor_pattern pattern:
// SSM 02.01.19 пока закомментировал этот кусок т.к. при этом коде падает стандартный пример ArithmSimplify.cs. #1408 снова открыл
/*var deconstructionType = (patternCase.pattern as deconstructor_pattern).
type as named_type_reference;
if (deconstructionType != null &&
deconstructionType.names != null &&
deconstructionType.names.Count != 0)
{
var deconstructionTypeName = deconstructionType.names[0].name;
if (usedDeconstructionTypes.Contains(deconstructionTypeName))
{ {
throw new SyntaxVisitorError("REPEATED_DECONSTRUCTION_TYPE", // Проверяем встречался ли уже такой тип при деконструкции
patternCase.pattern.source_context); // SSM 02.01.19 пока закомментировал этот кусок т.к. при этом коде падает стандартный пример ArithmSimplify.cs. #1408 снова открыл
} /*var deconstructionType = (patternCase.pattern as deconstructor_pattern).
usedDeconstructionTypes.Add(deconstructionTypeName); type as named_type_reference;
} */ if (deconstructionType != null &&
deconstructionType.names != null &&
deconstructionType.names.Count != 0)
{
var deconstructionTypeName = deconstructionType.names[0].name;
if (usedDeconstructionTypes.Contains(deconstructionTypeName))
{
throw new SyntaxVisitorError("REPEATED_DECONSTRUCTION_TYPE",
patternCase.pattern.source_context);
}
usedDeconstructionTypes.Add(deconstructionTypeName);
} */
DesugarDeconstructorPatternCase(matchWith.expr, patternCase); DesugarDeconstructorPatternCase(matchWith.expr, patternCase);
break;
}
case const_pattern p:
{
DesugarConstPatternCase(matchWith.expr, patternCase);
break;
}
case collection_pattern p:
{
DesugarDeconstructorPatternCase(matchWith.expr, patternCase);
break;
}
case tuple_pattern p:
{
DesugarDeconstructorPatternCase(matchWith.expr, patternCase);
break;
}
} }
} }
@ -124,6 +172,11 @@ namespace SyntaxVisitors.SugarVisitors
if (desugaredMatchWith == null) if (desugaredMatchWith == null)
desugaredMatchWith = new empty_statement(); desugaredMatchWith = new empty_statement();
if (typeChecks.Count != 0)
{
typeChecks.Add(desugaredMatchWith);
desugaredMatchWith = new statement_list(typeChecks);
}
// Замена выражения match with на новое несахарное поддерево и его обход // Замена выражения match with на новое несахарное поддерево и его обход
ReplaceUsingParent(matchWith, desugaredMatchWith); ReplaceUsingParent(matchWith, desugaredMatchWith);
visit(desugaredMatchWith); visit(desugaredMatchWith);
@ -135,21 +188,247 @@ namespace SyntaxVisitors.SugarVisitors
throw new SyntaxVisitorError("PATTERN_MATHING_IS_NOT_SUPPORTED_IN_THIS_CONTEXT", isPatternExpr.source_context); throw new SyntaxVisitorError("PATTERN_MATHING_IS_NOT_SUPPORTED_IN_THIS_CONTEXT", isPatternExpr.source_context);
Debug.Assert(GetAscendant<statement_list>(isPatternExpr) != null, "Couldn't find statement list in upper nodes"); Debug.Assert(GetAscendant<statement_list>(isPatternExpr) != null, "Couldn't find statement list in upper nodes");
DesugarIsExpression(isPatternExpr); DesugarIsExpression(isPatternExpr);
} }
void DesugarDeconstructorPatternCase(expression matchingExpression, pattern_case patternCase) private void DesugarDeconstructorPatternCase(expression matchingExpression, pattern_case patternCase)
{ {
Debug.Assert(patternCase.pattern is deconstructor_pattern); //var paramCheckExpr = DesugarDeconstructorPatternParameters(patternCase.pattern as deconstructor_pattern);
var isExpression = new is_pattern_expr(matchingExpression, patternCase.pattern); var isExpression = new is_pattern_expr(matchingExpression, patternCase.pattern, patternCase.source_context);
var ifCondition = patternCase.condition == null ? (expression)isExpression : bin_expr.LogicalAnd(isExpression, patternCase.condition); var ifCondition = patternCase.condition == null ? (expression)isExpression : bin_expr.LogicalAnd(isExpression, patternCase.condition);
var ifCheck = SubtreeCreator.CreateIf(ifCondition, patternCase.case_action); var ifCheck = SubtreeCreator.CreateIf(ifCondition, patternCase.case_action);
// Добавляем полученные statements в результат // Добавляем полученные statements в результат
AddDesugaredCaseToResult(ifCheck, ifCheck); AddDesugaredCaseToResult(ifCheck, ifCheck);
} }
private type_definition GetTypeDefinitionForConstParam(expression constParamExpr)
{
switch (constParamExpr)
{
case string_const type:
return new named_type_reference("string");
case char_const type:
return new named_type_reference("char");
case int32_const type:
return new named_type_reference("integer");
case int64_const type:
return new named_type_reference("integer");
case double_const type:
return new named_type_reference("double");
}
return null;
}
private expression DesugarDeconstructorPatternParameters(deconstructor_pattern pattern)
{
expression paramCheckExpr = null;
for (int i = 0; i < pattern.parameters.Count; ++i)
{
if (pattern.parameters[i] is const_pattern_parameter constPattern)
{
var constParamIdent = new ident(NewDeconstructParamId(), pattern.parameters[i].source_context);
var eqParams = new expression_list(
new List<expression>()
{
constPattern.const_param,
constParamIdent
}
);
var constParamCheck = new method_call(
new dot_node(new ident("object"), new ident("Equals")),
eqParams,
pattern.source_context
);
pattern.parameters[i] = new var_deconstructor_parameter(
constParamIdent,
GetTypeDefinitionForConstParam(constPattern.const_param),
false,
pattern.parameters[i].source_context);
paramCheckExpr = paramCheckExpr == null ? (expression)constParamCheck : bin_expr.LogicalAnd(paramCheckExpr, constParamCheck);
}
if (pattern.parameters[i] is wild_card_deconstructor_parameter)
{
var wildCardGeneratedParamIdent = new ident(NewDeconstructParamId(), pattern.parameters[i].source_context);
pattern.parameters[i] = new var_deconstructor_parameter(
wildCardGeneratedParamIdent,
null,
false,
pattern.parameters[i].source_context);
}
if (pattern.parameters[i] is recursive_deconstructor_parameter deconstructor_param)
{
if (deconstructor_param.pattern is deconstructor_pattern deconstructor_pattern)
{
var recursiveChecks = DesugarDeconstructorPatternParameters(deconstructor_pattern);
paramCheckExpr = paramCheckExpr == null ?
recursiveChecks :
bin_expr.LogicalAnd(paramCheckExpr, recursiveChecks);
}
}
}
return paramCheckExpr;
}
private void DesugarConstPatternCase(expression matchingExpression, pattern_case patternCase)
{
Debug.Assert(patternCase.pattern is const_pattern);
var patternExpressionNode = patternCase.pattern as const_pattern;
var statementsToAdd = new List<statement>();
var equalCalls = new List<method_call>();
foreach (var patternExpression in patternExpressionNode.pattern_expressions.expressions)
{
statementsToAdd.Add(GetTypeCompatibilityCheck(matchingExpression, patternExpression));
// Matching not tuples
var eqParams = new expression_list(
new List<expression>()
{
matchingExpression,
patternExpression
}
);
equalCalls.Add(
new method_call(
new dot_node(new ident("object"), new ident("Equals")),
eqParams,
patternCase.source_context
)
);
}
typeChecks.AddRange(statementsToAdd);
expression orPatternCases = equalCalls[0];
for (int i = 1; i < equalCalls.Count; ++i)
{
orPatternCases = bin_expr.LogicalOr(orPatternCases, equalCalls[i]);
}
var ifCondition = patternCase.condition == null ? orPatternCases : bin_expr.LogicalAnd(orPatternCases, patternCase.condition);
var ifCheck = SubtreeCreator.CreateIf(ifCondition, patternCase.case_action);
// Добавляем полученные statements в результат
AddDesugaredCaseToResult(ifCheck, ifCheck);
}
private expression GetCollectionItemsEqualCheckBeforeGap(addressed_value matchingExpression,
List<pattern_parameter> toCompare,
CollectionDesugaringResult desugaringResult)
{
var fromIndex = 0;
expression equalChecks = null;
foreach (var param in toCompare)
{
if (param is const_pattern_parameter constParam)
{
var indexerCall = new indexer(
matchingExpression,
new expression_list(
new int32_const(fromIndex, matchingExpression.source_context),
matchingExpression.source_context),
matchingExpression.source_context);
var eqParams = new expression_list(
new List<expression>()
{
indexerCall,
constParam.const_param
}
);
var equalCall = new method_call(
new dot_node(
new ident("object"),
new ident("Equals")),
eqParams,
matchingExpression.source_context
);
equalChecks = equalChecks == null ? (expression)equalCall : bin_expr.LogicalAnd(equalChecks, equalCall);
desugaringResult.ElemTypeChecks.Add(GetTypeCompatibilityCheck(constParam.const_param, indexerCall));
}
if (param is collection_pattern_var_parameter varParam)
{
desugaringResult.VarParametersDeclarations.Add(
new var_statement(varParam.identifier,
GetIndexerCallForCollectionPattern(matchingExpression as addressed_value, fromIndex)));
}
++fromIndex;
}
return equalChecks;
}
private expression GetCollectionItemsEqualCheckAfterGap(addressed_value matchingExpression,
List<pattern_parameter> toCompare,
CollectionDesugaringResult desugaringResult)
{
var elemFromTail = 1;
expression equalChecks = null;
foreach (var param in toCompare)
{
var indexerCall = new indexer(
matchingExpression,
new expression_list(
new bin_expr(
new method_call(
new dot_node(
matchingExpression,
new ident("Count", matchingExpression.source_context)),
new expression_list()),
new int32_const(elemFromTail, matchingExpression.source_context),
Operators.Minus),
matchingExpression.source_context),
matchingExpression.source_context);
if (param is const_pattern_parameter constParam)
{
var eqParams = new expression_list(
new List<expression>()
{
indexerCall,
constParam.const_param
}
);
var equalCall = new method_call(
new dot_node(
new ident("object"),
new ident("Equals")),
eqParams,
matchingExpression.source_context
);
equalChecks = equalChecks == null ? (expression)equalCall : bin_expr.LogicalAnd(equalChecks, equalCall);
desugaringResult.ElemTypeChecks.Add(GetTypeCompatibilityCheck(constParam.const_param, indexerCall));
}
if (param is collection_pattern_var_parameter varParam)
{
desugaringResult.VarParametersDeclarations.Add(
new var_statement(varParam.identifier, indexerCall));
}
++elemFromTail;
}
return equalChecks;
}
private expression GetIndexerCallForCollectionPattern(addressed_value matchingExpression, int ind)
{
var indexerCall = new indexer(matchingExpression, new int32_const(ind), matchingExpression.source_context);
return indexerCall;
}
private ident NewGeneralName() => new ident(GeneratedPatternNamePrefix + "GenVar" + generalVariableCounter++); private ident NewGeneralName() => new ident(GeneratedPatternNamePrefix + "GenVar" + generalVariableCounter++);
@ -179,7 +458,7 @@ namespace SyntaxVisitors.SugarVisitors
_previousIf = newIf; _previousIf = newIf;
} }
private DeconstructionDesugaringResult DesugarPattern(deconstructor_pattern pattern, expression matchingExpression) private DeconstructionDesugaringResult DesugarDeconstructorPattern(deconstructor_pattern pattern, expression matchingExpression)
{ {
Debug.Assert(!pattern.IsRecursive, "All recursive patterns should be desugared into simple patterns at this point"); Debug.Assert(!pattern.IsRecursive, "All recursive patterns should be desugared into simple patterns at this point");
@ -207,23 +486,153 @@ namespace SyntaxVisitors.SugarVisitors
return desugarResult; return desugarResult;
} }
private CollectionDesugaringResult DesugarCollectionPattern(collection_pattern pattern, expression matchingExpression)
{
Debug.Assert(!pattern.IsRecursive, "All recursive patterns should be desugared into simple patterns at this point");
var desugaringResult = new CollectionDesugaringResult();
var collectionItems = pattern.parameters;
var gapItemMet = false;
var gapIndex = 0;
var exprBeforeGap = new List<pattern_parameter>();
var exprAfterGap = new List<pattern_parameter>();
for (int i = 0; i < collectionItems.Count; ++i)
{
if (collectionItems[i] is collection_pattern_gap_parameter)
{
if (gapItemMet)
{
throw new SyntaxVisitorError("REPEATED_DOTDOT_COLLECTION_PATTERN_EXPR",
pattern.source_context);
}
gapItemMet = true;
gapIndex = i;
continue;
}
if (gapItemMet)
{
exprAfterGap.Insert(0, collectionItems[i]);
}
else
{
exprBeforeGap.Add(collectionItems[i]);
}
}
var successMatchingCheck = GetCollectionItemsEqualCheckBeforeGap(
matchingExpression as addressed_value, exprBeforeGap, desugaringResult);
if (gapItemMet && exprAfterGap.Count != 0)
{
var afterGapEqual = GetCollectionItemsEqualCheckAfterGap(
matchingExpression as addressed_value, exprAfterGap, desugaringResult);
if (afterGapEqual != null)
{
successMatchingCheck = successMatchingCheck == null ?
afterGapEqual :
bin_expr.LogicalAnd(successMatchingCheck, afterGapEqual);
}
}
// если добавлять в and, то все равно ран тайм эррор, будто вычисляет все, даже если первое = false
desugaringResult.CollectionLengthCheck = new bin_expr(
new dot_node(matchingExpression as addressed_value, new ident(CountPropertyName), pattern.source_context),
new int32_const(exprBeforeGap.Count + exprAfterGap.Count),
Operators.GreaterEqual,
pattern.source_context
);
if (!gapItemMet)
{
var lengthWithoutGapCheck = new bin_expr(
new dot_node(matchingExpression as addressed_value, new ident(CountPropertyName), pattern.source_context),
new int32_const(exprBeforeGap.Count),
Operators.Equal,
pattern.source_context
);
successMatchingCheck = successMatchingCheck == null ?
lengthWithoutGapCheck :
bin_expr.LogicalAnd(lengthWithoutGapCheck, successMatchingCheck);
}
desugaringResult.SuccessMatchingCheck = successMatchingCheck == null ?
new bool_const(true) :
successMatchingCheck;
return desugaringResult;
}
private TupleDesugaringResult DesugarTuplePattern(tuple_pattern pattern, expression matchingExpression)
{
Debug.Assert(!pattern.IsRecursive, "All recursive patterns should be desugared into simple patterns at this point");
var desugaringResult = new TupleDesugaringResult();
var tupleItems = pattern.parameters;
for (int i = 0; i < tupleItems.Count; ++i)
{
var tupleItemCall = new dot_node(
matchingExpression as addressed_value,
new ident("Item" + (i + 1).ToString()),
matchingExpression.source_context);
if (tupleItems[i] is tuple_pattern_var_parameter varParam)
{
desugaringResult.VarParametersDeclarations.Add(
new var_statement(
varParam.identifier,
tupleItemCall,
matchingExpression.source_context
)
);
}
if (tupleItems[i] is const_pattern_parameter constParam)
{
var eqParams = new expression_list(
new List<expression>()
{
tupleItemCall,
constParam.const_param
}
);
var equalCall = new method_call(
new dot_node(new ident("object"), new ident("Equals")),
eqParams,
pattern.source_context
);
desugaringResult.SuccessMatchingCheck = desugaringResult.SuccessMatchingCheck == null ?
(expression)equalCall :
bin_expr.LogicalAnd(desugaringResult.SuccessMatchingCheck, equalCall);
desugaringResult.ElemTypeChecks.Add(GetTypeCompatibilityCheck(constParam.const_param, tupleItemCall));
}
}
desugaringResult.TupleLengthCheck = GetTypeCompatibilityCheck(matchingExpression, new int32_const(tupleItems.Count));
if (desugaringResult.SuccessMatchingCheck == null)
{
desugaringResult.SuccessMatchingCheck = new bool_const(true);
}
return desugaringResult;
}
private void DesugarIsExpression(is_pattern_expr isPatternExpr) private void DesugarIsExpression(is_pattern_expr isPatternExpr)
{ {
Debug.Assert(isPatternExpr.right is deconstructor_pattern); if (isPatternExpr.right.IsRecursive)
var patternLocation = GetLocation(isPatternExpr);
var pattern = isPatternExpr.right as deconstructor_pattern;
//AddDefinitionsInUpperStatementList(isPatternExpr, new[] { GetTypeCompatibilityCheck(isPatternExpr) });
if (pattern.IsRecursive)
{ {
var desugaredRecursiveIs = DesugarRecursiveDeconstructor(isPatternExpr.left, pattern); var desugaredRecursiveIs = DesugarRecursiveParameters(isPatternExpr.left, isPatternExpr.right);
ReplaceUsingParent(isPatternExpr, desugaredRecursiveIs); ReplaceUsingParent(isPatternExpr, desugaredRecursiveIs);
desugaredRecursiveIs.visit(this); desugaredRecursiveIs.visit(this);
return; return;
} }
var patternLocation = GetLocation(isPatternExpr);
if (isPatternExpr.right is deconstructor_pattern pattern)
{
var constParamCheck = DesugarDeconstructorPatternParameters(isPatternExpr.right as deconstructor_pattern);
pattern.const_params_check = constParamCheck;
}
//AddDefinitionsInUpperStatementList(isPatternExpr, new[] { GetTypeCompatibilityCheck(isPatternExpr) });
switch (patternLocation) switch (patternLocation)
{ {
case PatternLocation.IfCondition: DesugarIsExpressionInIfCondition(isPatternExpr); break; case PatternLocation.IfCondition: DesugarIsExpressionInIfCondition(isPatternExpr); break;
@ -231,54 +640,70 @@ namespace SyntaxVisitors.SugarVisitors
} }
} }
private expression DesugarRecursiveDeconstructor(expression expression, deconstructor_pattern pattern) private expression DesugarRecursiveParameters(expression expression, pattern_node pattern)
{ {
List<pattern_deconstructor_parameter> parameters = pattern.parameters; List<pattern_parameter> parameters = pattern.parameters;
expression conjunction = new is_pattern_expr(expression, pattern); expression conjunction = new is_pattern_expr(expression, pattern, pattern.source_context);
for (int i = 0; i < parameters.Count; i++) for (int i = 0; i < parameters.Count; i++)
{ {
if (parameters[i] is recursive_deconstructor_parameter parameter) if (parameters[i] is recursive_pattern_parameter parameter)
{ {
//var parameterType = (parameter.pattern as deconstructor_pattern).type; //var parameterType = (parameter.pattern as deconstructor_pattern).type;
var newName = NewGeneralName(); var newName = NewGeneralName();
var varParameter = new var_deconstructor_parameter(newName, null); pattern_parameter varParameter = null;
if (pattern is deconstructor_pattern)
{
varParameter = new var_deconstructor_parameter(newName, null, false);
}
else if (pattern is collection_pattern)
{
varParameter = new collection_pattern_var_parameter(newName, null);
}
else if (pattern is tuple_pattern)
{
varParameter = new tuple_pattern_var_parameter(newName, null);
}
parameters[i] = varParameter; parameters[i] = varParameter;
varParameter.Parent = parameters[i]; varParameter.Parent = parameters[i];
conjunction = bin_expr.LogicalAnd(conjunction, DesugarRecursiveDeconstructor(newName, parameter.pattern as deconstructor_pattern)); conjunction = bin_expr.LogicalAnd(conjunction, DesugarRecursiveParameters(newName, parameter.pattern));
} }
} }
return conjunction; return conjunction;
} }
private void DesugarIsExpressionInAssignment(is_pattern_expr isExpression) private void DesugarIsExpressionInAssignment(is_pattern_expr isExpression)
{ {
var pattern = isExpression.right as deconstructor_pattern; // TODO: Кинуть тут эксепшн
var desugaringResult = DesugarPattern(pattern, isExpression.left); Debug.Assert(isExpression.right is deconstructor_pattern, "Only deconstructor patterns can be used in assignment");
ReplaceUsingParent(isExpression, desugaringResult.SuccessVariable); var statementsToAdd = ProcessDesugaringForDeconstructorPattern(isExpression);
var statementsToAdd = desugaringResult.GetDeconstructionDefinitions(pattern.source_context);
statementsToAdd.Add(GetMatchedExpressionCheck(isExpression.left));
statementsToAdd.Add(GetTypeCompatibilityCheck(isExpression));
statementsToAdd.Add(desugaringResult.GetPatternCheckWithDeconstrunctorCall());
AddDefinitionsInUpperStatementList(isExpression, statementsToAdd); AddDefinitionsInUpperStatementList(isExpression, statementsToAdd);
} }
private void DesugarIsExpressionInIfCondition(is_pattern_expr isExpression) private void DesugarIsExpressionInIfCondition(is_pattern_expr isExpression)
{ {
var pattern = isExpression.right as deconstructor_pattern; List<statement> statementsToAdd = null;
var desugaringResult = DesugarPattern(pattern, isExpression.left);
ReplaceUsingParent(isExpression, desugaringResult.SuccessVariable);
var statementsToAdd = desugaringResult.GetDeconstructionDefinitions(pattern.source_context); switch (isExpression.right)
statementsToAdd.Add(GetMatchedExpressionCheck(isExpression.left)); {
statementsToAdd.Add(GetTypeCompatibilityCheck(isExpression)); case deconstructor_pattern dp:
statementsToAdd.Add(desugaringResult.GetPatternCheckWithDeconstrunctorCall()); if (dp.const_params_check != null)
{
var ifToAddConstParamsCheckTo = GetAscendant<if_node>(isExpression);
ifToAddConstParamsCheckTo.condition = bin_expr.LogicalAnd(ifToAddConstParamsCheckTo.condition, dp.const_params_check);
}
statementsToAdd = ProcessDesugaringForDeconstructorPattern(isExpression);
break;
case collection_pattern cp:
statementsToAdd = ProcessDesugaringForCollectionPattern(isExpression);
break;
case tuple_pattern cp:
statementsToAdd = ProcessDesugaringForTuplePattern(isExpression);
break;
}
var enclosingIf = GetAscendant<if_node>(isExpression); var enclosingIf = GetAscendant<if_node>(isExpression);
// Если уже обрабатывался ранее (второй встретившийся в том же условии is), то не изменяем if // Если уже обрабатывался ранее (второй встретившийся в том же условии is), то не изменяем if
if (processedIfNodes.Contains(enclosingIf)) if (processedIfNodes.Contains(enclosingIf))
AddDefinitionsInUpperStatementList(isExpression, statementsToAdd); AddDefinitionsInUpperStatementList(isExpression, statementsToAdd);
// Иначе помещаем определения и if-then в отдельный блок, а else после этого блока // Иначе помещаем определения и if-then в отдельный блок, а else после этого блока
else else
@ -294,12 +719,77 @@ namespace SyntaxVisitors.SugarVisitors
} }
} }
private List<statement> ProcessDesugaringForDeconstructorPattern(is_pattern_expr isExpression)
{
var pattern = isExpression.right as deconstructor_pattern;
var desugaringResult = DesugarDeconstructorPattern(pattern, isExpression.left);
/*
var isParent = isExpression.Parent;
expression isReplacement = isExpression;
while (!(isParent is if_node))
{
if (isParent is bin_expr binParent)
{
if (binParent.right == isReplacement)
{
isReplacement = new bin_expr(binParent.left, binParent.right, binParent.operation_type, binParent.source_context);
}
if (binParent.left == isReplacement)
{
isReplacement = binParent.left;
}
}
isParent = isParent.Parent;
}*/
ReplaceUsingParent(isExpression, desugaringResult.SuccessVariable);
var statementsToAdd = desugaringResult.GetDeconstructionDefinitions(pattern.source_context);
statementsToAdd.Add(GetMatchedExpressionCheck(isExpression.left));
statementsToAdd.Add(GetTypeCompatibilityCheck(isExpression));
statementsToAdd.Add(desugaringResult.GetPatternCheckWithDeconstrunctorCall());
return statementsToAdd;
}
private List<statement> ProcessDesugaringForCollectionPattern(is_pattern_expr isExpression)
{
var pattern = isExpression.right as collection_pattern;
var desugaringResult = DesugarCollectionPattern(pattern, isExpression.left);
ReplaceUsingParent(isExpression, desugaringResult.SuccessMatchingCheck);
var statementsToAdd = new List<statement>();
statementsToAdd.AddRange(desugaringResult.VarParametersDeclarations);
statementsToAdd.AddRange(desugaringResult.ElemTypeChecks);
return statementsToAdd;
}
private List<statement> ProcessDesugaringForTuplePattern(is_pattern_expr isExpression)
{
var pattern = isExpression.right as tuple_pattern;
var desugaringResult = DesugarTuplePattern(pattern, isExpression.left);
ReplaceUsingParent(isExpression, desugaringResult.SuccessMatchingCheck);
var statementsToAdd = new List<statement>();
statementsToAdd.Add(desugaringResult.TupleLengthCheck);
statementsToAdd.AddRange(desugaringResult.VarParametersDeclarations);
statementsToAdd.AddRange(desugaringResult.ElemTypeChecks);
return statementsToAdd;
}
private semantic_check_sugared_statement_node GetMatchedExpressionCheck(expression matchedExpression) private semantic_check_sugared_statement_node GetMatchedExpressionCheck(expression matchedExpression)
=> new semantic_check_sugared_statement_node(SemanticCheckType.MatchedExpression, new List<syntax_tree_node>() { matchedExpression }); => new semantic_check_sugared_statement_node(SemanticCheckType.MatchedExpression, new List<syntax_tree_node>() { matchedExpression });
private semantic_check_sugared_statement_node GetTypeCompatibilityCheck(is_pattern_expr expression) => private semantic_check_sugared_statement_node GetTypeCompatibilityCheck(is_pattern_expr expression) =>
new semantic_check_sugared_statement_node(SemanticCheckType.MatchedExpressionAndType, new List<syntax_tree_node>() { expression.left, (expression.right as deconstructor_pattern).type }); new semantic_check_sugared_statement_node(SemanticCheckType.MatchedExpressionAndType, new List<syntax_tree_node>() { expression.left, (expression.right as deconstructor_pattern).type });
private semantic_check_sugared_statement_node GetTypeCompatibilityCheck(expression expression1, expression expression2) =>
new semantic_check_sugared_statement_node(SemanticCheckType.MatchedExpressionAndExpression, new List<syntax_tree_node>() { expression1, expression2 });
private semantic_check_sugared_statement_node GetTypeCompatibilityCheck(expression tuple, int32_const length) =>
new semantic_check_sugared_statement_node(SemanticCheckType.MatchedTuple, new List<syntax_tree_node>() { tuple, length });
private statement_list ConvertIfNode(if_node ifNode, List<statement> statementsBeforeIf, out statement elseBody) private statement_list ConvertIfNode(if_node ifNode, List<statement> statementsBeforeIf, out statement elseBody)
{ {
// if e then <then> else <else> // if e then <then> else <else>
@ -397,12 +887,12 @@ namespace SyntaxVisitors.SugarVisitors
private PatternLocation GetLocation(syntax_tree_node node) private PatternLocation GetLocation(syntax_tree_node node)
{ {
var firstStatement = GetAscendant<statement>(node); var firstStatement = GetAscendant<statement>(node);
switch (firstStatement) switch (firstStatement)
{ {
case if_node _: return PatternLocation.IfCondition; case if_node _: return PatternLocation.IfCondition;
case var_statement _: return PatternLocation.Assign; case var_statement _: return PatternLocation.Assign;
case assign _ : return PatternLocation.Assign; case assign _: return PatternLocation.Assign;
default: return PatternLocation.Unknown; default: return PatternLocation.Unknown;
} }
} }
@ -421,6 +911,11 @@ namespace SyntaxVisitors.SugarVisitors
return null; return null;
} }
private string NewDeconstructParamId()
{
return GeneratedPatternNamePrefix + "DeconstructParam" + deconstructParamVariableCounter++.ToString();
}
} }
} }

View file

@ -1971,6 +1971,37 @@ function KV<TKey, TVal>(key: TKey; value: TVal): KeyValuePair<TKey, TVal>;
function __TypeCheckAndAssignForIsMatch<T>(obj: object; var res: T): boolean; function __TypeCheckAndAssignForIsMatch<T>(obj: object; var res: T): boolean;
function __WildCardsTupleEqual<T1, T2, T3, T4>(
first: Tuple<T1, T2>;
second: Tuple<T3, T4>;
elemsToCompare: sequence of integer): boolean;
function __WildCardsTupleEqual<T1, T2, T3, T4, T5, T6>(
first: Tuple<T1, T2, T3>;
second: Tuple<T4, T5, T6>;
elemsToCompare: sequence of integer): boolean;
function __WildCardsTupleEqual<T1, T2, T3, T4, T5, T6, T7, T8>(
first: Tuple<T1, T2, T3, T4>;
second: Tuple<T5, T6, T7, T8>;
elemsToCompare: sequence of integer): boolean;
function __WildCardsTupleEqual<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(
first: Tuple<T1, T2, T3, T4, T5>;
second: Tuple<T6, T7, T8, T9, T10>;
elemsToCompare: sequence of integer): boolean;
function __WildCardsTupleEqual<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(
first: Tuple<T1, T2, T3, T4, T5, T6>;
second: Tuple<T7, T8, T9, T10, T11, T12>;
elemsToCompare: sequence of integer): boolean;
function __WildCardsTupleEqual<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(
first: Tuple<T1, T2, T3, T4, T5, T6, T7>;
second: Tuple<T8, T9, T10, T11, T12, T13, T14>;
elemsToCompare: sequence of integer): boolean;
// ----------------------------------------------------- // -----------------------------------------------------
// Стандартные классы исключений // Стандартные классы исключений
// ----------------------------------------------------- // -----------------------------------------------------
@ -4486,6 +4517,112 @@ begin
end; end;
end; end;
function __WildCardsTupleEqual<T1, T2, T3, T4>(
first: Tuple<T1, T2>;
second: Tuple<T3, T4>;
elemsToCompare: sequence of integer): boolean;
begin
Result := True;
foreach var ind in elemsToCompare do
begin
case ind of
0: Result := Result and first.Item1.Equals(second.Item1);
1: Result := Result and first.Item2.Equals(second.Item2);
end;
end;
end;
function __WildCardsTupleEqual<T1, T2, T3, T4, T5, T6>(
first: Tuple<T1, T2, T3>;
second: Tuple<T4, T5, T6>;
elemsToCompare: sequence of integer): boolean;
begin
Result := True;
foreach var ind in elemsToCompare do
begin
case ind of
0: Result := Result and first.Item1.Equals(second.Item1);
1: Result := Result and first.Item2.Equals(second.Item2);
2: Result := Result and first.Item3.Equals(second.Item3);
end;
end;
end;
function __WildCardsTupleEqual<T1, T2, T3, T4, T5, T6, T7, T8>(
first: Tuple<T1, T2, T3, T4>;
second: Tuple<T5, T6, T7, T8>;
elemsToCompare: sequence of integer): boolean;
begin
Result := True;
foreach var ind in elemsToCompare do
begin
case ind of
0: Result := Result and first.Item1.Equals(second.Item1);
1: Result := Result and first.Item2.Equals(second.Item2);
2: Result := Result and first.Item3.Equals(second.Item3);
3: Result := Result and first.Item4.Equals(second.Item4);
end;
end;
end;
function __WildCardsTupleEqual<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(
first: Tuple<T1, T2, T3, T4, T5>;
second: Tuple<T6, T7, T8, T9, T10>;
elemsToCompare: sequence of integer): boolean;
begin
Result := True;
foreach var ind in elemsToCompare do
begin
case ind of
0: Result := Result and first.Item1.Equals(second.Item1);
1: Result := Result and first.Item2.Equals(second.Item2);
2: Result := Result and first.Item3.Equals(second.Item3);
3: Result := Result and first.Item4.Equals(second.Item4);
4: Result := Result and first.Item5.Equals(second.Item5);
end;
end;
end;
function __WildCardsTupleEqual<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(
first: Tuple<T1, T2, T3, T4, T5, T6>;
second: Tuple<T7, T8, T9, T10, T11, T12>;
elemsToCompare: sequence of integer): boolean;
begin
Result := True;
foreach var ind in elemsToCompare do
begin
case ind of
0: Result := Result and first.Item1.Equals(second.Item1);
1: Result := Result and first.Item2.Equals(second.Item2);
2: Result := Result and first.Item3.Equals(second.Item3);
3: Result := Result and first.Item4.Equals(second.Item4);
4: Result := Result and first.Item5.Equals(second.Item5);
5: Result := Result and first.Item6.Equals(second.Item6);
end;
end;
end;
function __WildCardsTupleEqual<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(
first: Tuple<T1, T2, T3, T4, T5, T6, T7>;
second: Tuple<T8, T9, T10, T11, T12, T13, T14>;
elemsToCompare: sequence of integer): boolean;
begin
Result := True;
foreach var ind in elemsToCompare do
begin
case ind of
0: Result := Result and first.Item1.Equals(second.Item1);
1: Result := Result and first.Item2.Equals(second.Item2);
2: Result := Result and first.Item3.Equals(second.Item3);
3: Result := Result and first.Item4.Equals(second.Item4);
4: Result := Result and first.Item5.Equals(second.Item5);
5: Result := Result and first.Item6.Equals(second.Item6);
6: Result := Result and first.Item7.Equals(second.Item7);
end;
end;
end;
///-- ///--
procedure Deconstruct<T>(self: T; var res: T); extensionmethod; procedure Deconstruct<T>(self: T; var res: T); extensionmethod;
begin begin

View file

@ -0,0 +1,10 @@
begin
var a := Arr(1, 9, 8, 7, 2, 3, 4, 5);
var c: procedure := () -> begin
match a with
[.., 4, var x]: assert(x = 5);
end;
end;
c;
end.

View file

@ -0,0 +1,46 @@
type
CardInfo = auto class
public
cardNumber: string;
cv: integer;
end;
Person = class
public
name: string;
age: integer;
card: CardInfo;
constructor(name: string; age: integer; card: CardInfo);
begin
self.name := name;
self.age := age;
self.card := card;
end;
procedure Deconstruct(var name: string; var age: integer; var card: CardInfo);
begin
name := self.name;
age := self.age;
card := self.card;
end;
end;
begin
var p1 := new Person('Вася', 11, new CardInfo('12345671', 321));
var p2 := new Person('Петя', 12, new CardInfo('12345672', 322));
var p3 := new Person('Маша', 13, new CardInfo('12345673', 323));
var personArr := Arr(p1, p2, p3);
// Расширенный is
if personArr is [Person(name1, 11, CardInfo(_, cv)), _, Person(name2, 13, _)] then
assert(name1.Equals('Вася') and (cv = 321) and name2.Equals('Маша'));
// match .. with
match personArr with
[_, _, Person('Вася', var age, _)]: assert(false);
[var p, .., Person('Маша', _, _)]: assert((p as Person).name.Equals('Вася'));
[..]: assert(false);
end;
end.

View file

@ -0,0 +1,43 @@
type
CardInfo = auto class
public
cardNumber: string;
cv: integer;
end;
Person = class
name: string;
age: integer;
card: List<CardInfo> := new List<CardInfo>();
constructor(name: string; age: integer; card: List<CardInfo>);
begin
self.name := name;
self.age := age;
self.card := card;
end;
procedure Deconstruct(var name: string; var age: integer; var card: List<CardInfo>);
begin
name := self.name;
age := self.age;
card := self.card;
end;
end;
begin
var cards := new List<CardInfo>();
cards.Add(new CardInfo('12345671', 321));
cards.Add(new CardInfo('12345672', 322));
cards.Add(new CardInfo('12345673', 323));
cards.Add(new CardInfo('12345674', 324));
var p := new Person('Вася', 21, cards);
// match .. with
match p with
Person('Петя', _, _): assert(false);
Person('Вася', _, [_, _, var x]): assert(false);
Person(name, _, [CardInfo(_, 321), .., CardInfo(_, 324)]): assert(name.Equals('Вася'));
end;
end.

View file

@ -0,0 +1,8 @@
begin
var a := 3.14;
match a with
1.0, 2.0, 3.0: assert(false);
3.13, 3.14, 3.15, 3.16: ;
123.0: assert(false);
end;
end.

View file

@ -0,0 +1,7 @@
begin
match (1, 2, 'string') with
(1, _, 'str'): assert(false);
(1, _, 'strin'): assert(false);
(_, _, 'string'): ;
end;
end.

View file

@ -0,0 +1,40 @@
type
CardInfo = auto class
public
cardNumber: string;
cv: integer;
end;
Person = class
name: string;
age: integer;
card: CardInfo;
constructor(name: string; age: integer; card: CardInfo);
begin
self.name := name;
self.age := age;
self.card := card;
end;
procedure Deconstruct(var name: string; var age: integer; var card: CardInfo);
begin
name := self.name;
age := self.age;
card := self.card;
end;
end;
begin
var a := new Person('Вася', 11, new CardInfo('12345678', 324));
// Расширенный is
if a is Person(_, var age, CardInfo(_, var cv)) then assert((age = 11) and (cv = 324));
// match .. with
match a with
Person('Петя', 12, CardInfo('12345678', var cv)): assert(false);
Person('Вася', _, CardInfo(cardNum, 324)): assert(cardNum.Equals('12345678'));
Person(_, _, CardInfo(_, x)): assert(false);
end;
end.

View file

@ -144,9 +144,9 @@ namespace PascalABCCompiler.TreeConverter
} }
} }
private bool AreTheSameType(type_node type1, type_node type2) => private bool AreTheSameType(type_node type1, type_node type2) =>
type1 != null && type1 != null &&
type2 != null && type2 != null &&
convertion_data_and_alghoritms.possible_equal_types(type1, type2); convertion_data_and_alghoritms.possible_equal_types(type1, type2);
private bool IsSelfParameter(parameter parameter) => parameter.name.ToLower() == compiler_string_consts.self_word; private bool IsSelfParameter(parameter parameter) => parameter.name.ToLower() == compiler_string_consts.self_word;
@ -209,7 +209,7 @@ namespace PascalABCCompiler.TreeConverter
if (node is generic_instance_type_node genericNode) if (node is generic_instance_type_node genericNode)
foreach (var index in genericNode.instance_params.Aggregate( foreach (var index in genericNode.instance_params.Aggregate(
Enumerable.Empty<int>(), Enumerable.Empty<int>(),
(indices, nextNode) => indices.Concat(GenericParameterIndices(nextNode))) (indices, nextNode) => indices.Concat(GenericParameterIndices(nextNode)))
.Distinct()) .Distinct())
yield return index; yield return index;
@ -261,5 +261,40 @@ namespace PascalABCCompiler.TreeConverter
AddError(get_location(matchedExpression), "EXPRESSION_OF_TYPE_{0}_CANNOT_BE_MATCHED_AGAINST_PATTERN_WITH_TYPE_{1}", expression.name, type.name); AddError(get_location(matchedExpression), "EXPRESSION_OF_TYPE_{0}_CANNOT_BE_MATCHED_AGAINST_PATTERN_WITH_TYPE_{1}", expression.name, type.name);
} }
private void CheckIfCanBeMatched(expression matchedExpression, expression patternExpression)
{
var patternType = convert_strong(patternExpression).type;
var expressionType = convert_strong(matchedExpression).type;
var expressionTypeName = expressionType.BaseFullName;
var patternTypeName = patternType.BaseFullName;
var tupleName = "System.Tuple";
if (type_table.is_derived(patternType, expressionType) ||
type_table.is_derived(expressionType, patternType) ||
AreTheSameType(patternType, expressionType) ||
(expressionTypeName.StartsWith(tupleName) &&
patternTypeName.StartsWith(tupleName) &&
int.Parse(expressionTypeName.Substring(tupleName.Length + 1, 1)) ==
int.Parse(patternTypeName.Substring(tupleName.Length + 1, 1))))
return;
AddError(get_location(matchedExpression), "EXPRESSION_OF_TYPE_{0}_CANNOT_BE_MATCHED_AGAINST_PATTERN_WITH_TYPE_{1}", expressionType.name, patternType.name);
}
private void CheckIfCanBeMatched(expression tuple, int32_const length)
{
var expressionType = convert_strong(tuple).type;
var expressionTypeName = expressionType.BaseFullName;
var tupleName = "System.Tuple";
if (expressionTypeName.StartsWith(tupleName) &&
int.Parse(expressionTypeName.Substring(tupleName.Length + 1, 1)) == length.val)
return;
AddError(get_location(tuple),
"EXPRESSION_OF_TYPE_{0}_CANNOT_BE_MATCHED_AGAINST_PATTERN_WITH_TYPE_{1}", expressionType.name, "Tuple`" + length.val);
}
} }
} }

View file

@ -1,437 +1,439 @@
// Copyright (c) Ivan Bondarev, Stanislav Mihalkovich (for details please see \doc\copyright.txt) // Copyright (c) Ivan Bondarev, Stanislav Mihalkovich (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) // This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
//Строковые константы. //Строковые константы.
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using PascalABCCompiler.TreeRealization; using PascalABCCompiler.TreeRealization;
namespace PascalABCCompiler.TreeConverter namespace PascalABCCompiler.TreeConverter
{ {
public static class compiler_string_consts public static class compiler_string_consts
{ {
public static Dictionary<string, string> oper_names = new Dictionary<string, string>(); public static Dictionary<string, string> oper_names = new Dictionary<string, string>();
static int tvnc = 0; static int tvnc = 0;
public static string GetTempVariableName() public static string GetTempVariableName()
{ {
return "$TV" + (tvnc++).ToString() + "$"; return "$TV" + (tvnc++).ToString() + "$";
} }
static compiler_string_consts() static compiler_string_consts()
{ {
oper_names[plus_name] = "op_Addition"; oper_names[plus_name] = "op_Addition";
oper_names[minus_name] = "op_Subtraction"; oper_names[minus_name] = "op_Subtraction";
oper_names[mul_name] = "op_Multiply"; oper_names[mul_name] = "op_Multiply";
oper_names[div_name] = "op_Division"; oper_names[div_name] = "op_Division";
oper_names[idiv_name] = "op_Division"; oper_names[idiv_name] = "op_Division";
oper_names[and_name] = "op_BitwiseAnd"; oper_names[and_name] = "op_BitwiseAnd";
oper_names[or_name] = "op_BitwiseOr"; oper_names[or_name] = "op_BitwiseOr";
oper_names[eq_name] = "op_Equality"; oper_names[eq_name] = "op_Equality";
oper_names[gr_name] = "op_GreaterThan"; oper_names[gr_name] = "op_GreaterThan";
oper_names[greq_name] = "op_GreaterThanOrEqual"; oper_names[greq_name] = "op_GreaterThanOrEqual";
oper_names[sm_name] = "op_LessThan"; oper_names[sm_name] = "op_LessThan";
oper_names[smeq_name] = "op_LessThanOrEqual"; oper_names[smeq_name] = "op_LessThanOrEqual";
oper_names[mod_name] = "op_Modulus"; oper_names[mod_name] = "op_Modulus";
oper_names[not_name] = "op_LogicalNot"; oper_names[not_name] = "op_LogicalNot";
oper_names[noteq_name] = "op_Inequality"; oper_names[noteq_name] = "op_Inequality";
} }
public static string GetNETOperName(string name) public static string GetNETOperName(string name)
{ {
string oper_name = null; string oper_name = null;
if (oper_names.TryGetValue(name, out oper_name)) if (oper_names.TryGetValue(name, out oper_name))
return oper_name; return oper_name;
return null; return null;
} }
public static string GetConnectedFunctionName(string class_name, string func_name) public static string GetConnectedFunctionName(string class_name, string func_name)
{ {
if (oper_names.ContainsKey(func_name)) if (oper_names.ContainsKey(func_name))
func_name = oper_names[func_name]; func_name = oper_names[func_name];
return class_name + "_" + func_name; return class_name + "_" + func_name;
} }
public static string GetGenericTypeInformation(string name, out int generic_param_count) public static string GetGenericTypeInformation(string name, out int generic_param_count)
{ {
generic_param_count = 0; generic_param_count = 0;
if (name == null) if (name == null)
{ {
return null; return null;
} }
string rez = name; string rez = name;
int ind = name.IndexOf(compiler_string_consts.generic_params_infix); int ind = name.IndexOf(compiler_string_consts.generic_params_infix);
if (ind > 0) if (ind > 0)
{ {
rez = name.Substring(0, ind); rez = name.Substring(0, ind);
if (name.Length > ind + 1) if (name.Length > ind + 1)
{ {
try try
{ {
generic_param_count = Convert.ToInt32(name.Substring(ind + 1)); generic_param_count = Convert.ToInt32(name.Substring(ind + 1));
} }
catch catch
{ {
generic_param_count = 0; generic_param_count = 0;
} }
} }
} }
return rez; return rez;
} }
public static string ImplementationSectionNamespaceName = "_implementation______"; public static string ImplementationSectionNamespaceName = "_implementation______";
public static readonly string bool_type_name = "boolean"; public static readonly string bool_type_name = "boolean";
public static readonly string byte_type_name = "byte"; public static readonly string byte_type_name = "byte";
public static readonly string sbyte_type_name = "shortint"; public static readonly string sbyte_type_name = "shortint";
public static readonly string short_type_name = "smallint"; public static readonly string short_type_name = "smallint";
public static readonly string ushort_type_name = "word"; public static readonly string ushort_type_name = "word";
public static readonly string integer_type_name = "integer";//longint public static readonly string integer_type_name = "integer";//longint
public static readonly string uint_type_name = "longword";//cardinal public static readonly string uint_type_name = "longword";//cardinal
public static readonly string long_type_name = "int64";//int64 public static readonly string long_type_name = "int64";//int64
public static readonly string ulong_type_name = "uint64"; public static readonly string ulong_type_name = "uint64";
//public static readonly string decimal_type_name = "decimal"; //public static readonly string decimal_type_name = "decimal";
public static readonly string real_type_name = "real"; public static readonly string real_type_name = "real";
public static readonly string float_type_name = "single"; public static readonly string float_type_name = "single";
public static readonly string char_type_name = "char"; public static readonly string char_type_name = "char";
public static readonly string string_type_name = "string"; public static readonly string string_type_name = "string";
public static readonly string pointer_type_name = "pointer"; public static readonly string pointer_type_name = "pointer";
public static readonly string object_type_name = "object"; public static readonly string object_type_name = "object";
public static readonly string true_const_name = "true"; public static readonly string true_const_name = "true";
public static readonly string false_const_name = "false"; public static readonly string false_const_name = "false";
public static readonly string base_exception_class_name = "Exception"; public static readonly string base_exception_class_name = "Exception";
public static readonly string combine_method_name = "Combine"; public static readonly string combine_method_name = "Combine";
public static readonly string remove_method_name = "Remove"; public static readonly string remove_method_name = "Remove";
public static readonly string base_enum_class_name = "Enum"; public static readonly string base_enum_class_name = "Enum";
public static readonly string void_class_name = "void"; public static readonly string void_class_name = "void";
public static string value = "value"; public static string value = "value";
public static readonly string object_equals_name = "Equals"; public static readonly string object_equals_name = "Equals";
public static readonly string plus_name = "+"; public static readonly string plus_name = "+";
public static readonly string minus_name = "-"; public static readonly string minus_name = "-";
public static readonly string mul_name = "*"; public static readonly string mul_name = "*";
public static readonly string div_name = "/"; public static readonly string div_name = "/";
public static readonly string idiv_name = "div"; public static readonly string idiv_name = "div";
public static readonly string mod_name = "mod"; public static readonly string mod_name = "mod";
public static readonly string explicit_operator_name = "op_Explicit"; public static readonly string explicit_operator_name = "op_Explicit";
public static readonly string implicit_operator_name = "op_Implicit"; public static readonly string implicit_operator_name = "op_Implicit";
//public static string CommandLineArgsVariableName = "CommandLineArgs"; //public static string CommandLineArgsVariableName = "CommandLineArgs";
public static string MainArgsParamName = "args"; public static string MainArgsParamName = "args";
public static string IsConsoleApplicationVariableName = "IsConsoleApplication"; public static string IsConsoleApplicationVariableName = "IsConsoleApplication";
public static readonly string plusassign_name = "+="; public static readonly string plusassign_name = "+=";
public static readonly string minusassign_name = "-="; public static readonly string minusassign_name = "-=";
public static readonly string multassign_name = "*="; public static readonly string multassign_name = "*=";
public static readonly string divassign_name = "/="; public static readonly string divassign_name = "/=";
public static readonly string power_name = "**"; public static readonly string power_name = "**";
public static readonly string gr_name = ">"; public static readonly string gr_name = ">";
public static readonly string sm_name = "<"; public static readonly string sm_name = "<";
public static readonly string greq_name = ">="; public static readonly string greq_name = ">=";
public static readonly string smeq_name = "<="; public static readonly string smeq_name = "<=";
public static readonly string eq_name = "="; public static readonly string eq_name = "=";
public static readonly string noteq_name = "<>"; public static readonly string noteq_name = "<>";
public static readonly string or_name = "or"; public static readonly string or_name = "or";
public static readonly string xor_name = "xor"; public static readonly string xor_name = "xor";
public static readonly string not_name = "not"; public static readonly string not_name = "not";
public static readonly string and_name = "and"; public static readonly string and_name = "and";
public static readonly string as_name = "as"; public static readonly string as_name = "as";
public static readonly string is_name = "is"; public static readonly string is_name = "is";
public static readonly string in_name = "in"; public static readonly string in_name = "in";
public static readonly string shl_name = "shl"; public static readonly string shl_name = "shl";
public static readonly string shr_name = "shr"; public static readonly string shr_name = "shr";
public static readonly string assign_name = ":="; public static readonly string assign_name = ":=";
public static readonly string unary_param_name = "param"; public static readonly string unary_param_name = "param";
public static readonly string left_param_name = "left"; public static readonly string left_param_name = "left";
public static readonly string right_param_name = "right"; public static readonly string right_param_name = "right";
public static readonly string main_function_name = "Main"; public static readonly string main_function_name = "Main";
public static readonly string c_main_function_name = "main"; public static readonly string c_main_function_name = "main";
public static readonly string temp_main_function_name = "$Main"; public static readonly string temp_main_function_name = "$Main";
public static readonly string initialization_function_name = "$Initialization"; public static readonly string initialization_function_name = "$Initialization";
public static readonly string finalization_function_name = "$Finalization"; public static readonly string finalization_function_name = "$Finalization";
public static readonly string function_return_value_prefix = "$rv_"; public static readonly string function_return_value_prefix = "$rv_";
public static readonly string empty_function_name = "empty_function"; public static readonly string empty_function_name = "empty_function";
public static readonly string break_procedure_name = "break"; public static readonly string break_procedure_name = "break";
public static readonly string continue_procedure_name = "continue"; public static readonly string continue_procedure_name = "continue";
public static readonly string exit_procedure_name = "exit"; public static readonly string exit_procedure_name = "exit";
public static readonly string temp_for_variable_name = "$tfr_"; public static readonly string temp_for_variable_name = "$tfr_";
public static readonly string lower_array_const_name = "LowerIndex"; public static readonly string lower_array_const_name = "LowerIndex";
public static readonly string upper_array_const_name = "UpperIndex"; public static readonly string upper_array_const_name = "UpperIndex";
public static readonly string pascal_array_name = "$pascal_array"; public static readonly string pascal_array_name = "$pascal_array";
public static readonly string indexer_name = "[]"; public static readonly string indexer_name = "[]";
public static readonly string internal_array_name = "NullBasedArray"; public static readonly string internal_array_name = "NullBasedArray";
public static readonly string simple_array_name = "simple_array"; public static readonly string simple_array_name = "simple_array";
public static readonly string get_val_pascal_array_name = "get_val"; public static readonly string get_val_pascal_array_name = "get_val";
public static readonly string set_val_pascal_array_name = "set_val"; public static readonly string set_val_pascal_array_name = "set_val";
public static readonly string index_property_pascal_array_name = "index"; public static readonly string index_property_pascal_array_name = "index";
public static readonly string system_unit_name = "PascalABCSystem"; public static readonly string system_unit_name = "PascalABCSystem";
public static readonly string delegate_type_name_template = "$delegate"; public static readonly string delegate_type_name_template = "$delegate";
public static readonly string roof_name = "^"; public static readonly string roof_name = "^";
public static readonly string string_concat_method_name = "Concat"; public static readonly string string_concat_method_name = "Concat";
public static readonly string to_string_method_name = "ToString"; public static readonly string to_string_method_name = "ToString";
public static readonly string base_delegate_type_name = "delegate"; public static readonly string base_delegate_type_name = "delegate";
public static readonly string base_array_type_name = "array"; public static readonly string base_array_type_name = "array";
public static readonly string net_constructor_name = ".ctor"; public static readonly string net_constructor_name = ".ctor";
public static readonly string method_group_type_name = "Method group"; public static readonly string method_group_type_name = "Method group";
public static readonly string invoke_method_name = "Invoke"; public static readonly string invoke_method_name = "Invoke";
public static readonly string begin_invoke_method_name = "BeginInvoke"; public static readonly string begin_invoke_method_name = "BeginInvoke";
public static readonly string end_invoke_method_name = "EndInvoke"; public static readonly string end_invoke_method_name = "EndInvoke";
public static readonly string callback_string = "callback"; public static readonly string callback_string = "callback";
public static readonly string result_string = "result"; public static readonly string result_string = "result";
public static readonly string object_in_par_string = "'object'"; public static readonly string object_in_par_string = "'object'";
public static readonly string omp_get_nested = "omp_get_nested"; public static readonly string omp_get_nested = "omp_get_nested";
public static readonly string omp_set_nested = "omp_set_nested"; public static readonly string omp_set_nested = "omp_set_nested";
public static readonly string OMP_NESTED = "OMP_NESTED"; public static readonly string OMP_NESTED = "OMP_NESTED";
public static readonly string set_length_procedure_name = "SetLength"; public static readonly string set_length_procedure_name = "SetLength";
public static readonly string set_length_for_short_string = "SetLengthForShortString"; public static readonly string set_length_for_short_string = "SetLengthForShortString";
public static readonly string self_word = "self"; public static readonly string self_word = "self";
public static string get_pointer_type_name_by_type_name(string type_name) public static string get_pointer_type_name_by_type_name(string type_name)
{ {
return (roof_name + type_name); return (roof_name + type_name);
} }
public static string format_procedure_name = "FormatValue"; public static string format_procedure_name = "FormatValue";
public static string read_procedure_name = "read"; public static string read_procedure_name = "read";
public static string write_procedure_name = "write"; public static string write_procedure_name = "write";
public static string writeln_procedure_name = "writeln"; public static string writeln_procedure_name = "writeln";
public static string readln_procedure_name = "readln"; public static string readln_procedure_name = "readln";
public static string text_file_name_type_name = "Text"; public static string text_file_name_type_name = "Text";
public static string TextFileInitProcedureName = "TextFileInit"; public static string TextFileInitProcedureName = "TextFileInit";
public static string StringDefaultPropertySetProcedureName = "StringDefaultPropertySet"; public static string StringDefaultPropertySetProcedureName = "StringDefaultPropertySet";
public static string BinaryFileTypeName = "BinaryFile"; public static string BinaryFileTypeName = "BinaryFile";
public static string AbstractBinaryFileTypeName = "AbstractBinaryFile"; public static string AbstractBinaryFileTypeName = "AbstractBinaryFile";
public static string BinaryFileInitProcedureName = "BinaryFileInit"; public static string BinaryFileInitProcedureName = "BinaryFileInit";
public static string BinaryFileReadProcedureName = "BinaryFileRead"; public static string BinaryFileReadProcedureName = "BinaryFileRead";
public static string TypedFileTypeName = "TypedFile"; public static string TypedFileTypeName = "TypedFile";
public static string TypedFileInitProcedureName = "TypedFileInit"; public static string TypedFileInitProcedureName = "TypedFileInit";
public static string TypedFileReadProcedureName = "TypedFileRead"; public static string TypedFileReadProcedureName = "TypedFileRead";
public static string ShortStringTypeName = "ShortString"; public static string ShortStringTypeName = "ShortString";
public static string ShortStringTypeInitProcedure = "InitShortString"; public static string ShortStringTypeInitProcedure = "InitShortString";
public static string PointerOutputTypeName = "PointerOutput"; public static string PointerOutputTypeName = "PointerOutput";
public static string PascalReadAccessorName = "read"; public static string PascalReadAccessorName = "read";
public static string PascalWriteAccessorName = "write"; public static string PascalWriteAccessorName = "write";
public static string AssignSetName = "AssignSetFrom"; public static string AssignSetName = "AssignSetFrom";
public static string TypedSetInitProcedure = "TypedSetInit"; public static string TypedSetInitProcedure = "TypedSetInit";
public static string TypedSetInitProcedureWithBounds = "TypedSetInitWithBounds"; public static string TypedSetInitProcedureWithBounds = "TypedSetInitWithBounds";
public static string TypedSetInitWithShortString = "TypedSetInitWithShortString"; public static string TypedSetInitWithShortString = "TypedSetInitWithShortString";
public static string AssignSetProcedure = "AssignSet"; public static string AssignSetProcedure = "AssignSet";
public static string AssignSetProcedureWithBounds = "AssignSetWithBounds"; public static string AssignSetProcedureWithBounds = "AssignSetWithBounds";
public static string ClipShortStringInSetFunction = "ClipShortStringInSet"; public static string ClipShortStringInSetFunction = "ClipShortStringInSet";
public static string ClipShortStringInSetProcedure = "ClipShortStringInSetProcedure"; public static string ClipShortStringInSetProcedure = "ClipShortStringInSetProcedure";
public static string union_of_set = "Union"; public static string union_of_set = "Union";
public static string intersect_of_set = "Intersect"; public static string intersect_of_set = "Intersect";
public static string subtract_of_set = "Subtract"; public static string subtract_of_set = "Subtract";
public static string in_set = "InSet"; public static string in_set = "InSet";
public static string CreateSetProcedure = "CreateSet"; public static string CreateSetProcedure = "CreateSet";
public static string IncludeProcedure = "Include"; public static string IncludeProcedure = "Include";
public static string ExcludeProcedure = "Exclude"; public static string ExcludeProcedure = "Exclude";
public static string DiapasonType = "Diapason"; public static string DiapasonType = "Diapason";
public static string CreateDiapason = "CreateDiapason"; public static string CreateDiapason = "CreateDiapason";
public static string CreateObjDiapason = "CreateObjDiapason"; public static string CreateObjDiapason = "CreateObjDiapason";
public static string CompareSetEquals = "CompareSetEquals"; public static string CompareSetEquals = "CompareSetEquals";
public static string CompareSetInEquals = "CompareSetInEquals"; public static string CompareSetInEquals = "CompareSetInEquals";
public static string CompareSetLess = "CompareSetLess"; public static string CompareSetLess = "CompareSetLess";
public static string CompareSetLessEqual = "CompareSetLessEqual"; public static string CompareSetLessEqual = "CompareSetLessEqual";
public static string CompareSetGreater = "CompareSetGreater"; public static string CompareSetGreater = "CompareSetGreater";
public static string CompareSetGreaterEqual = "CompareSetGreaterEqual"; public static string CompareSetGreaterEqual = "CompareSetGreaterEqual";
public static string IncProcedure = "Inc"; public static string IncProcedure = "Inc";
public static string DecProcedure = "Dec"; public static string DecProcedure = "Dec";
public static string SuccFunction = "Succ"; public static string SuccFunction = "Succ";
public static string PredFunction = "Pred"; public static string PredFunction = "Pred";
public static string OrdFunction = "Ord"; public static string OrdFunction = "Ord";
public static string ClipProcedure = "ClipSet"; public static string ClipProcedure = "ClipSet";
public static string ClipFunction = "ClipSetFunc"; public static string ClipFunction = "ClipSetFunc";
public static string ClipShortString = "ClipShortString"; public static string ClipShortString = "ClipShortString";
public static string GetCharInShortString = "GetCharInShortString"; public static string GetCharInShortString = "GetCharInShortString";
public static string SetCharInShortString = "SetCharInShortString"; public static string SetCharInShortString = "SetCharInShortString";
public static string read_short_string = "ReadShortString"; public static string read_short_string = "ReadShortString";
public static string read_short_string_from_file = "ReadShortStringFromFile"; public static string read_short_string_from_file = "ReadShortStringFromFile";
public static string Insert = "Insert"; public static string Insert = "Insert";
public static string Delete = "Delete"; public static string Delete = "Delete";
public static string InsertInShortString = "InsertInShortString"; public static string InsertInShortString = "InsertInShortString";
public static string AssertProcedure = "Assert"; public static string AssertProcedure = "Assert";
public static string CopyWithSizeFunction = "CopyWithSize"; public static string CopyWithSizeFunction = "CopyWithSize";
public static string Low = "Low"; public static string Low = "Low";
public static string High = "High"; public static string High = "High";
public static string ArrayCopyFunction = "Copy"; public static string ArrayCopyFunction = "Copy";
public static string check_in_range = "check_in_range"; public static string check_in_range = "check_in_range";
public static string check_in_range_char = "check_in_range_char"; public static string check_in_range_char = "check_in_range_char";
public static string ShortStringTypeNameTemplate = string_type_name + "[{0}]"; public static string ShortStringTypeNameTemplate = string_type_name + "[{0}]";
public static string GetCurrentLineFunction = "__GetCurrentLine__"; public static string GetCurrentLineFunction = "__GetCurrentLine__";
public static string GetCurrentFileFunction = "__GetCurrentFile__"; public static string GetCurrentFileFunction = "__GetCurrentFile__";
public static string GetShortStringTypeName(int length) public static string GetShortStringTypeName(int length)
{ {
if (length < 256) if (length < 256)
return string.Format(ShortStringTypeNameTemplate, length); return string.Format(ShortStringTypeNameTemplate, length);
else return string.Format(ShortStringTypeName); else return string.Format(ShortStringTypeName);
} }
public static string TypedFileTypeNameTemplate = "file of {0}"; public static string TypedFileTypeNameTemplate = "file of {0}";
public static string TypedSetTypeNameTemplate = "set of {0}"; public static string TypedSetTypeNameTemplate = "set of {0}";
public static string GetTypedFileTypeName(string elem_type_name) public static string GetTypedFileTypeName(string elem_type_name)
{ {
return string.Format(TypedFileTypeNameTemplate, elem_type_name); return string.Format(TypedFileTypeNameTemplate, elem_type_name);
} }
public static string GetSetTypeName(string elem_type_name) public static string GetSetTypeName(string elem_type_name)
{ {
return string.Format(TypedSetTypeNameTemplate, elem_type_name); return string.Format(TypedSetTypeNameTemplate, elem_type_name);
} }
public static string array_word = "array"; public static string array_word = "array";
private static string of_word = "of"; private static string of_word = "of";
private static string space = " "; private static string space = " ";
public static string result_variable_name = "result"; public static string result_variable_name = "result";
public static string event_add_method_nameformat = event_add_method_prefix + "{0}"; public static string event_add_method_nameformat = event_add_method_prefix + "{0}";
public static string event_remove_method_nameformat = event_remove_method_prefix + "{0}"; public static string event_remove_method_nameformat = event_remove_method_prefix + "{0}";
public static string event_add_method_prefix = "add_"; public static string event_add_method_prefix = "add_";
public static string event_remove_method_prefix = "remove_"; public static string event_remove_method_prefix = "remove_";
public static string default_constructor_name = "create"; public static string default_constructor_name = "create";
// SSM - Константы директив компилятора. Вообще разбросаны по коду. Пусть будут здесь (3.1.2011) // SSM - Константы директив компилятора. Вообще разбросаны по коду. Пусть будут здесь (3.1.2011)
public static string compiler_directive_apptype = "apptype"; public static string compiler_directive_apptype = "apptype";
public static string compiler_directive_reference = "reference"; public static string compiler_directive_reference = "reference";
public static string include_namespace_directive = "includenamespace"; public static string include_namespace_directive = "includenamespace";
public static string compiler_savepcu = "savepcu"; public static string compiler_savepcu = "savepcu";
public static string compiler_directive_nullbasedstrings = "nullbasedstrings"; public static string compiler_directive_nullbasedstrings = "nullbasedstrings";
public static string compiler_directive_nullbasedstrings_ON = "string_nullbased+"; public static string compiler_directive_nullbasedstrings_ON = "string_nullbased+";
public static string compiler_directive_nullbasedstrings_OFF = "string_nullbased-"; public static string compiler_directive_nullbasedstrings_OFF = "string_nullbased-";
public static string compiler_directive_initstring_as_empty_ON = "string_initempty+"; public static string compiler_directive_initstring_as_empty_ON = "string_initempty+";
public static string compiler_directive_initstring_as_empty_OFF = "string_initempty-"; public static string compiler_directive_initstring_as_empty_OFF = "string_initempty-";
public static string compiler_directive_resource = "resource"; public static string compiler_directive_resource = "resource";
public static string compiler_directive_platformtarget = "platformtarget"; public static string compiler_directive_platformtarget = "platformtarget";
public static string compiler_directive_faststrings = "faststrings"; public static string compiler_directive_faststrings = "faststrings";
// SSM (3.1.2011) Перенес эти константы сюда. // SSM (3.1.2011) Перенес эти константы сюда.
public static string version_string = "version"; public static string version_string = "version";
public static string product_string = "product"; public static string product_string = "product";
public static string company_string = "company"; public static string company_string = "company";
public static string copyright_string = "copyright"; public static string copyright_string = "copyright";
public static string trademark_string = "trademark"; public static string trademark_string = "trademark";
public static string main_resource_string = "mainresource"; public static string main_resource_string = "mainresource";
public static string title_string = "title"; public static string title_string = "title";
public static string description_string = "description"; public static string description_string = "description";
public static string system_unit_marker = "__IS_SYSTEM_MODULE"; public static string system_unit_marker = "__IS_SYSTEM_MODULE";
public static string system_unit_file_name = "PABCSystem"; public static string system_unit_file_name = "PABCSystem";
public static string extensions_unit_file_name = "PABCExtensions"; public static string extensions_unit_file_name = "PABCExtensions";
public static string get_array_type_name(string type_name, int rank) public static string get_array_type_name(string type_name, int rank)
{ {
if (rank == 1) if (rank == 1)
return (array_word + space + of_word + space + type_name); return (array_word + space + of_word + space + type_name);
else else
{ {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.Append(',', rank - 1); sb.Append(',', rank - 1);
return array_word + "[" + sb.ToString() + "]" + space + of_word + space + type_name; return array_word + "[" + sb.ToString() + "]" + space + of_word + space + type_name;
} }
} }
public static readonly string new_array_procedure_name = "__new_array"; public static readonly string new_array_procedure_name = "__new_array";
public static readonly string new_procedure_name = "new"; public static readonly string new_procedure_name = "new";
public static readonly string dispose_procedure_name = "dispose"; public static readonly string dispose_procedure_name = "dispose";
public static string pointer_net_type_name_intptr = "System.IntPtr"; public static string pointer_net_type_name_intptr = "System.IntPtr";
public static string pointer_net_type_name_void = "System.Void*"; public static string pointer_net_type_name_void = "System.Void*";
public static string record_const_type_name = "RecordConst"; public static string record_const_type_name = "RecordConst";
public static string array_const_type_name = "ArrayConst"; public static string array_const_type_name = "ArrayConst";
public static string auto_type_name = "AutoType"; // SSM 25.06.16 - тип, который определяется на этапе компиляции при первом присваивании public static string auto_type_name = "AutoType"; // SSM 25.06.16 - тип, который определяется на этапе компиляции при первом присваивании
public static string ienumerable_auto_type_name = "IEnumerableAutoType"; // SSM 05.07.16 - тип, который определяется на этапе компиляции при первом присваивании public static string ienumerable_auto_type_name = "IEnumerableAutoType"; // SSM 05.07.16 - тип, который определяется на этапе компиляции при первом присваивании
public static string recort_printable_name_template = "record{0}end"; public static string recort_printable_name_template = "record{0}end";
public static string set_name = "TypedSet"; public static string set_name = "TypedSet";
public const string deconstruct_method_name = "deconstruct"; public const string deconstruct_method_name = "deconstruct";
public const string is_test_function_name = "__TypeCheckAndAssignForIsMatch"; public const string is_test_function_name = "__TypeCheckAndAssignForIsMatch";
public const string wild_cards_tuple_equal_function_name = "__WildCardsTupleEqual";
public static string bounded_array_printable_name_template = "array [{0}..{1}] of {2}"; public const string seq_function_name = "Seq";
public static string array_printable_name_template = "array of {0}"; public const string count_property_name = "Count";
public static string multi_dim_array_printable_name_template = "array [{0}] of {1}"; public static string bounded_array_printable_name_template = "array [{0}..{1}] of {2}";
public static readonly string generic_params_infix = "`"; public static string array_printable_name_template = "array of {0}";
public static string multi_dim_array_printable_name_template = "array [{0}] of {1}";
public static string GetAccessorName(string accessorTemplate, string name) public static readonly string generic_params_infix = "`";
{
return string.Format(accessorTemplate, name); public static string GetAccessorName(string accessorTemplate, string name)
} {
public static string GetGetAccessorName(string name) return string.Format(accessorTemplate, name);
{ }
return GetAccessorName("get_{0}", name); public static string GetGetAccessorName(string name)
} {
public static string GetSetAccessorName(string name) return GetAccessorName("get_{0}", name);
{ }
return GetAccessorName("set_{0}", name); public static string GetSetAccessorName(string name)
} {
public static string GetAddHandler(string name) return GetAccessorName("set_{0}", name);
{ }
return "add_" + name; public static string GetAddHandler(string name)
} {
public static string GetRemoveHandler(string name) return "add_" + name;
{ }
return "remove_" + name; public static string GetRemoveHandler(string name)
} {
public static string IEnumerableInterfaceName = "System.Collections.IEnumerable"; return "remove_" + name;
public static string IGenericEnumerableInterfaceName = "System.Collections.Generic.IEnumerable`1"; }
public static string GetEnumeratorMethodName = "GetEnumerator"; public static string IEnumerableInterfaceName = "System.Collections.IEnumerable";
public static string IEnumeratorInterfaceName = "System.Collections.IEnumerator"; public static string IGenericEnumerableInterfaceName = "System.Collections.Generic.IEnumerable`1";
public static string IGenericEnumeratorInterfaceName = "System.Collections.Generic.IEnumerator`1"; public static string GetEnumeratorMethodName = "GetEnumerator";
public static string CurrentPropertyName = "Current"; public static string IEnumeratorInterfaceName = "System.Collections.IEnumerator";
public static string IGenericEnumeratorInterfaceName = "System.Collections.Generic.IEnumerator`1";
public static string static_ctor_prefix = "$sctor$"; public static string CurrentPropertyName = "Current";
public static string generic_param_kind_prefix = "$kind_of$";
public static string CheckCanUsePointerOnType_proc_name = "CheckCanUsePointerOnType"; public static string static_ctor_prefix = "$sctor$";
public static string CheckCanUseTypeForBinaryFiles_proc_name = "CheckCanUseTypeForBinaryFiles"; public static string generic_param_kind_prefix = "$kind_of$";
public static string CheckCanUseTypeForTypedFiles_proc_name = "CheckCanUseTypeForTypedFiles"; public static string CheckCanUsePointerOnType_proc_name = "CheckCanUsePointerOnType";
public static string RuntimeDetermineType_func_name = "RuntimeDetermineType"; public static string CheckCanUseTypeForBinaryFiles_proc_name = "CheckCanUseTypeForBinaryFiles";
public static string RuntimeInitializeFunction_func_name = "RuntimeInitialize"; public static string CheckCanUseTypeForTypedFiles_proc_name = "CheckCanUseTypeForTypedFiles";
public static string PointerToStringFunction_func_name = "PointerToString"; public static string RuntimeDetermineType_func_name = "RuntimeDetermineType";
public static string GetRuntimeSizeFunction_func_name = "GetRuntimeSize"; public static string RuntimeInitializeFunction_func_name = "RuntimeInitialize";
public static string StrProcedure_func_name = "Str"; public static string PointerToStringFunction_func_name = "PointerToString";
public static string PascalABCVersion_func_name = "PascalABCVersion"; public static string GetRuntimeSizeFunction_func_name = "GetRuntimeSize";
public static string ChrUnicodeFunction_func_name = "ChrUnicode"; public static string StrProcedure_func_name = "Str";
public static string ExceptionName = "System.Exception"; public static string PascalABCVersion_func_name = "PascalABCVersion";
public static string value_in_accessor_name = "$value"; public static string ChrUnicodeFunction_func_name = "ChrUnicode";
public static string synonym_value_name = "$synonym"; public static string ExceptionName = "System.Exception";
public static string file_of_attr_name = "$Attributes.$FileOfAttr"; public static string value_in_accessor_name = "$value";
public static string set_of_attr_name = "$Attributes.$SetOfAttr"; public static string synonym_value_name = "$synonym";
public static string type_synonim_attr_name = "$Attributes.$TypeSynonimAttr"; public static string file_of_attr_name = "$Attributes.$FileOfAttr";
public static string template_class_attr_name = "$Attributes.$TemplateClassAttr"; public static string set_of_attr_name = "$Attributes.$SetOfAttr";
public static string short_string_attr_name = "$Attributes.$ShortStringAttr"; public static string type_synonim_attr_name = "$Attributes.$TypeSynonimAttr";
public static string global_attr_name = "$GlobAttr"; public static string template_class_attr_name = "$Attributes.$TemplateClassAttr";
public static string class_unit_attr_name = "$ClassUnitAttr"; public static string short_string_attr_name = "$Attributes.$ShortStringAttr";
public static string pabc_rtl_dll_name = "PABCRtl.dll"; public static string global_attr_name = "$GlobAttr";
public static string ObjectType = "Object"; public static string class_unit_attr_name = "$ClassUnitAttr";
public static string StringType = "string"; public static string pabc_rtl_dll_name = "PABCRtl.dll";
public static string config_variable_name = "__CONFIG__"; public static string ObjectType = "Object";
} public static string StringType = "string";
public static string config_variable_name = "__CONFIG__";
} }
}

View file

@ -20162,6 +20162,18 @@ namespace PascalABCCompiler.TreeConverter
var type = st.lst[1] as type_definition; var type = st.lst[1] as type_definition;
CheckIfCanBeMatched(expr, type); CheckIfCanBeMatched(expr, type);
} }
else if (st.typ is SemanticCheckType.MatchedExpressionAndExpression)
{
var matchedExpr = st.lst[0] as expression;
var patternExpr = st.lst[1] as expression;
CheckIfCanBeMatched(matchedExpr, patternExpr);
}
else if (st.typ is SemanticCheckType.MatchedTuple)
{
var tuple = st.lst[0] as expression;
var length = st.lst[1] as int32_const;
CheckIfCanBeMatched(tuple, length);
}
// !Patterns // !Patterns
else else
{ {

View file

@ -1971,6 +1971,37 @@ function KV<TKey, TVal>(key: TKey; value: TVal): KeyValuePair<TKey, TVal>;
function __TypeCheckAndAssignForIsMatch<T>(obj: object; var res: T): boolean; function __TypeCheckAndAssignForIsMatch<T>(obj: object; var res: T): boolean;
function __WildCardsTupleEqual<T1, T2, T3, T4>(
first: Tuple<T1, T2>;
second: Tuple<T3, T4>;
elemsToCompare: sequence of integer): boolean;
function __WildCardsTupleEqual<T1, T2, T3, T4, T5, T6>(
first: Tuple<T1, T2, T3>;
second: Tuple<T4, T5, T6>;
elemsToCompare: sequence of integer): boolean;
function __WildCardsTupleEqual<T1, T2, T3, T4, T5, T6, T7, T8>(
first: Tuple<T1, T2, T3, T4>;
second: Tuple<T5, T6, T7, T8>;
elemsToCompare: sequence of integer): boolean;
function __WildCardsTupleEqual<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(
first: Tuple<T1, T2, T3, T4, T5>;
second: Tuple<T6, T7, T8, T9, T10>;
elemsToCompare: sequence of integer): boolean;
function __WildCardsTupleEqual<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(
first: Tuple<T1, T2, T3, T4, T5, T6>;
second: Tuple<T7, T8, T9, T10, T11, T12>;
elemsToCompare: sequence of integer): boolean;
function __WildCardsTupleEqual<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(
first: Tuple<T1, T2, T3, T4, T5, T6, T7>;
second: Tuple<T8, T9, T10, T11, T12, T13, T14>;
elemsToCompare: sequence of integer): boolean;
// ----------------------------------------------------- // -----------------------------------------------------
// Стандартные классы исключений // Стандартные классы исключений
// ----------------------------------------------------- // -----------------------------------------------------
@ -4486,6 +4517,112 @@ begin
end; end;
end; end;
function __WildCardsTupleEqual<T1, T2, T3, T4>(
first: Tuple<T1, T2>;
second: Tuple<T3, T4>;
elemsToCompare: sequence of integer): boolean;
begin
Result := True;
foreach var ind in elemsToCompare do
begin
case ind of
0: Result := Result and first.Item1.Equals(second.Item1);
1: Result := Result and first.Item2.Equals(second.Item2);
end;
end;
end;
function __WildCardsTupleEqual<T1, T2, T3, T4, T5, T6>(
first: Tuple<T1, T2, T3>;
second: Tuple<T4, T5, T6>;
elemsToCompare: sequence of integer): boolean;
begin
Result := True;
foreach var ind in elemsToCompare do
begin
case ind of
0: Result := Result and first.Item1.Equals(second.Item1);
1: Result := Result and first.Item2.Equals(second.Item2);
2: Result := Result and first.Item3.Equals(second.Item3);
end;
end;
end;
function __WildCardsTupleEqual<T1, T2, T3, T4, T5, T6, T7, T8>(
first: Tuple<T1, T2, T3, T4>;
second: Tuple<T5, T6, T7, T8>;
elemsToCompare: sequence of integer): boolean;
begin
Result := True;
foreach var ind in elemsToCompare do
begin
case ind of
0: Result := Result and first.Item1.Equals(second.Item1);
1: Result := Result and first.Item2.Equals(second.Item2);
2: Result := Result and first.Item3.Equals(second.Item3);
3: Result := Result and first.Item4.Equals(second.Item4);
end;
end;
end;
function __WildCardsTupleEqual<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(
first: Tuple<T1, T2, T3, T4, T5>;
second: Tuple<T6, T7, T8, T9, T10>;
elemsToCompare: sequence of integer): boolean;
begin
Result := True;
foreach var ind in elemsToCompare do
begin
case ind of
0: Result := Result and first.Item1.Equals(second.Item1);
1: Result := Result and first.Item2.Equals(second.Item2);
2: Result := Result and first.Item3.Equals(second.Item3);
3: Result := Result and first.Item4.Equals(second.Item4);
4: Result := Result and first.Item5.Equals(second.Item5);
end;
end;
end;
function __WildCardsTupleEqual<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(
first: Tuple<T1, T2, T3, T4, T5, T6>;
second: Tuple<T7, T8, T9, T10, T11, T12>;
elemsToCompare: sequence of integer): boolean;
begin
Result := True;
foreach var ind in elemsToCompare do
begin
case ind of
0: Result := Result and first.Item1.Equals(second.Item1);
1: Result := Result and first.Item2.Equals(second.Item2);
2: Result := Result and first.Item3.Equals(second.Item3);
3: Result := Result and first.Item4.Equals(second.Item4);
4: Result := Result and first.Item5.Equals(second.Item5);
5: Result := Result and first.Item6.Equals(second.Item6);
end;
end;
end;
function __WildCardsTupleEqual<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(
first: Tuple<T1, T2, T3, T4, T5, T6, T7>;
second: Tuple<T8, T9, T10, T11, T12, T13, T14>;
elemsToCompare: sequence of integer): boolean;
begin
Result := True;
foreach var ind in elemsToCompare do
begin
case ind of
0: Result := Result and first.Item1.Equals(second.Item1);
1: Result := Result and first.Item2.Equals(second.Item2);
2: Result := Result and first.Item3.Equals(second.Item3);
3: Result := Result and first.Item4.Equals(second.Item4);
4: Result := Result and first.Item5.Equals(second.Item5);
5: Result := Result and first.Item6.Equals(second.Item6);
6: Result := Result and first.Item7.Equals(second.Item7);
end;
end;
end;
///-- ///--
procedure Deconstruct<T>(self: T; var res: T); extensionmethod; procedure Deconstruct<T>(self: T; var res: T); extensionmethod;
begin begin

View file

@ -19,6 +19,7 @@ LAMBDA_EXPRESSIONS_CANNOT_CONTAIN_YIELD=Лямбда-выражения не м
PATTERN_MATHING_IS_NOT_SUPPORTED_IN_THIS_CONTEXT=Сопоставление с образцом не поддерживается в данном контексте PATTERN_MATHING_IS_NOT_SUPPORTED_IN_THIS_CONTEXT=Сопоставление с образцом не поддерживается в данном контексте
ONLY_ONE_DECONSTRUCT_ALLOWED=Можно определить только один пользовательский деконструктор ONLY_ONE_DECONSTRUCT_ALLOWED=Можно определить только один пользовательский деконструктор
REPEATED_DECONSTRUCTION_TYPE=Повторение типов при сопоставлении с образцом REPEATED_DECONSTRUCTION_TYPE=Повторение типов при сопоставлении с образцом
REPEATED_DOTDOT_COLLECTION_PATTERN_EXPR=Конструкция '..' встречена более одного раза в выражении для сопоставления
Var_{0}_is_already_defined=Переменная {0} уже определена Var_{0}_is_already_defined=Переменная {0} уже определена