Добавил несколько тестов, поправил грамматику

This commit is contained in:
Александр Погорелов 2019-04-26 20:30:28 +03:00
parent 1168b3d2bd
commit 22151fef3a
22 changed files with 2435 additions and 2156 deletions

View file

@ -2,7 +2,7 @@
// This CSharp output file generated by Gardens Point LEX
// Version: 1.1.3.301
// Machine: DESKTOP-IF20NRO
// DateTime: 4/11/2019 10:23:58 AM
// DateTime: 4/25/2019 5:35:11 PM
// UserName: FatCow
// GPLEX input file <ABCPascal.lex>
// GPLEX frame file <embedded resource>

View file

@ -4,7 +4,7 @@
// ==========================================================================
// Version: 1.3.6
// Machine: DESKTOP-IF20NRO
// DateTime: 3/30/2019 6:53:52 AM
// DateTime: 4/25/2019 5:34:59 PM
// UserName: FatCow
// ==========================================================================
@ -185,9 +185,9 @@
%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 <ti> tkAssignOrEqual
%type <stn> pattern pattern_optional_var const_pattern collection_pattern collection_pattern_list_item collection_pattern_var_item match_with pattern_case pattern_cases pattern_out_param pattern_out_param_optional_var tuple_pattern_expr_list const_pattern_expr_list
%type <ob> pattern_out_param_list pattern_out_param_list_optional_var collection_pattern_expr_list
%type <ex> const_pattern_expression tuple_pattern tuple_pattern_expr
%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 collection_pattern_expr_list tuple_pattern_item_list
%type <ex> const_pattern_expression
%%
// Warning: Terminating collection_pattern_var_item fixes the following size-1 NonTerminal set
@ -2819,6 +2819,10 @@ pattern_case
{
$$ = 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
@ -3296,7 +3300,7 @@ relop_expr
| is_type_expr tkRoundOpen pattern_out_param_list tkRoundClose
{
var isTypeCheck = $1 as typecast_node;
var deconstructorPattern = new deconstructor_pattern($3 as List<pattern_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, @$);
}
@ -3304,19 +3308,23 @@ relop_expr
{
$$ = new is_pattern_expr($1, $3 as pattern_node, @$);
}
| term tkIs tuple_pattern
{
$$ = new is_pattern_expr($1, $3 as pattern_node, @$);
}
;
pattern
: simple_or_template_type_reference tkRoundOpen pattern_out_param_list tkRoundClose
{
$$ = new deconstructor_pattern($3 as List<pattern_parameter>, $1, @$);
$$ = new deconstructor_pattern($3 as List<pattern_parameter>, $1, null, @$);
}
;
pattern_optional_var
: simple_or_template_type_reference tkRoundOpen pattern_out_param_list_optional_var tkRoundClose
{
$$ = new deconstructor_pattern($3 as List<pattern_parameter>, $1, @$);
$$ = new deconstructor_pattern($3 as List<pattern_parameter>, $1, null, @$);
}
;
@ -3354,14 +3362,22 @@ collection_pattern_list_item
{
$$ = new collection_pattern_wild_card();
}
| pattern
/*| 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();
@ -3369,24 +3385,13 @@ collection_pattern_list_item
;
collection_pattern_var_item
| tkVar identifier tkColon type_ref
| tkVar identifier
//--^
// Error: Syntax error, unexpected '|', expecting ':'
// --------------------------------------------------
{
$$ = new collection_pattern_var_parameter($2, $4, @$);
}
| tkVar identifier
{
$$ = new collection_pattern_var_parameter($2, null, @$);
}
| identifier tkColon type_ref
{
$$ = new collection_pattern_var_parameter($1, $3, @$);
}
| identifier
{
$$ = new collection_pattern_var_parameter($1, null, @$);
}
;
const_pattern
@ -3408,38 +3413,56 @@ const_pattern_expr_list
;
const_pattern_expression
: literal_or_number { $$ = $1; }
| tuple_pattern { $$ = $1; }
: literal_or_number { $$ = $1; }
;
tuple_pattern
: tkRoundOpen tuple_pattern_expr tkComma tuple_pattern_expr_list lambda_type_ref optional_full_lambda_fp_list tkRoundClose
: tkRoundOpen tuple_pattern_item_list tkRoundClose
{
/*if ($5 != null)
parsertools.AddErrorFromResource("BAD_TUPLE",@5);
if ($6 != null)
parsertools.AddErrorFromResource("BAD_TUPLE",@6);*/
if (($4 as expression_list).Count>6)
if (($2 as List<pattern_parameter>).Count>6)
parsertools.AddErrorFromResource("TUPLE_ELEMENTS_COUNT_MUST_BE_LESSEQUAL_7",@$);
($4 as expression_list).Insert(0,$2);
$$ = new tuple_node($4 as expression_list,@$);
$$ = new tuple_pattern($2 as List<pattern_parameter>, @$);
}
;
tuple_pattern_expr
: tkUnderscore { $$ = new tuple_wild_card(); }
| literal_or_number { $$ = $1; }
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_expr_list
: tuple_pattern_expr
tuple_pattern_item_list
: tuple_pattern_item
{
$$ = new expression_list($1, @$);
$$ = new List<pattern_parameter>();
($$ as List<pattern_parameter>).Add($1 as pattern_parameter);
}
| tuple_pattern_expr_list tkComma tuple_pattern_expr
| tuple_pattern_item_list tkComma tuple_pattern_item
{
$$ = ($1 as expression_list).Add($3, @$);
var list = $1 as List<pattern_parameter>;
list.Add($3 as pattern_parameter);
$$ = list;
}
;
@ -3504,6 +3527,14 @@ pattern_out_param
{
$$ = 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
@ -3535,6 +3566,14 @@ pattern_out_param_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, @$);
}
;
simple_expr_or_nothing

View file

@ -3368,22 +3368,10 @@ collection_pattern_list_item
;
collection_pattern_var_item
: tkVar identifier tkColon type_ref
{
$$ = new collection_pattern_var_parameter($2, $4, @$);
}
| tkVar identifier
: tkVar identifier
{
$$ = new collection_pattern_var_parameter($2, null, @$);
}
| identifier tkColon type_ref
{
$$ = new collection_pattern_var_parameter($1, $3, @$);
}
| identifier
{
$$ = new collection_pattern_var_parameter($1, null, @$);
}
;
const_pattern
@ -3426,22 +3414,10 @@ tuple_pattern_item
{
$$ = new const_pattern_parameter($1, @$);
}
| tkVar identifier tkColon type_ref
{
$$ = new tuple_pattern_var_parameter($2, $4, @$);
}
| tkVar identifier
{
$$ = new tuple_pattern_var_parameter($2, null, @$);
}
| identifier tkColon type_ref
{
$$ = new tuple_pattern_var_parameter($1, $3, @$);
}
| identifier
{
$$ = new tuple_pattern_var_parameter($1, null, @$);
}
| pattern_optional_var
{
$$ = new recursive_deconstructor_parameter($1 as pattern_node, @$);

File diff suppressed because it is too large Load diff

View file

@ -720,6 +720,25 @@ namespace SyntaxVisitors.SugarVisitors
{
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));

View file

@ -1886,6 +1886,37 @@ function KV<TKey, TVal>(key: TKey; value: TVal): KeyValuePair<TKey, TVal>;
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;
// -----------------------------------------------------
// Стандартные классы исключений
// -----------------------------------------------------
@ -4369,6 +4400,112 @@ begin
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;
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.