Collection matching: var and wildcard paramerters
This commit is contained in:
parent
38f124a682
commit
724ecaa353
|
|
@ -2,7 +2,7 @@
|
|||
// This CSharp output file generated by Gardens Point LEX
|
||||
// Version: 1.1.3.301
|
||||
// Machine: DESKTOP-IF20NRO
|
||||
// DateTime: 3/17/2019 11:23:05 AM
|
||||
// DateTime: 3/30/2019 7:18:34 AM
|
||||
// UserName: FatCow
|
||||
// GPLEX input file <ABCPascal.lex>
|
||||
// GPLEX frame file <embedded resource>
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@
|
|||
// GPPG error listing for yacc source file <ABCPascal.y>
|
||||
// ==========================================================================
|
||||
// Version: 1.3.6
|
||||
// Machine: DESKTOP-A6LT9RI
|
||||
// DateTime: 10.11.2018 23:09:24
|
||||
// UserName: Станислав
|
||||
// Machine: DESKTOP-IF20NRO
|
||||
// DateTime: 3/30/2019 6:53:52 AM
|
||||
// UserName: FatCow
|
||||
// ==========================================================================
|
||||
|
||||
|
||||
|
|
@ -35,6 +35,7 @@
|
|||
%using PascalABCCompiler.ParserTools;
|
||||
%using PascalABCCompiler.Errors;
|
||||
%using System.Linq;
|
||||
%using SyntaxVisitors;
|
||||
|
||||
%namespace GPPGParserScanner
|
||||
|
||||
|
|
@ -42,9 +43,9 @@
|
|||
|
||||
%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> tkIf tkImplementation tkInherited tkInterface /* tkTypeclass tkInstance */ 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> tkLoop
|
||||
%token <ti> tkSequence tkYield
|
||||
|
|
@ -88,7 +89,7 @@
|
|||
%type <stn> exception_handler
|
||||
%type <stn> exception_handler_list
|
||||
%type <stn> exception_identifier
|
||||
%type <stn> typed_const_list1 typed_const_list optional_expr_list elem_list optional_expr_list_with_bracket expr_list const_elem_list1 const_func_expr_list case_label_list const_elem_list optional_const_func_expr_list elem_list1
|
||||
%type <stn> typed_const_list1 typed_const_list optional_expr_list elem_list optional_expr_list_with_bracket expr_list const_elem_list1 /*const_func_expr_list*/ case_label_list const_elem_list optional_const_func_expr_list elem_list1
|
||||
%type <stn> enumeration_id expr_l1_list
|
||||
%type <stn> enumeration_id_list
|
||||
%type <ex> const_simple_expr term simple_term typed_const typed_const_plus typed_var_init_expression expr expr_with_func_decl_lambda const_expr elem range_expr const_elem array_const factor relop_expr expr_dq expr_l1 expr_l1_func_decl_lambda simple_expr range_term range_factor
|
||||
|
|
@ -104,7 +105,6 @@
|
|||
%type <id> func_name_ident param_name const_field_name func_name_with_template_args identifier_or_keyword unit_name exception_variable const_name func_meth_name_ident label_name type_decl_identifier template_identifier_with_equal
|
||||
%type <id> program_param identifier identifier_keyword_operatorname func_class_name_ident /*optional_identifier*/ visibility_specifier
|
||||
%type <id> property_specifier_directives non_reserved
|
||||
//%type <id> typeclass_restriction
|
||||
%type <stn> if_stmt
|
||||
%type <stn> initialization_part
|
||||
%type <stn> template_arguments label_list ident_or_keyword_pointseparator_list ident_list param_name_list
|
||||
|
|
@ -156,7 +156,7 @@
|
|||
%type <stn> simple_property_definition
|
||||
%type <stn> stmt_or_expression unlabelled_stmt stmt case_item
|
||||
%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> 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
|
||||
|
|
@ -166,7 +166,6 @@
|
|||
%type <ex> typeof_expr
|
||||
%type <stn> simple_fp_sect
|
||||
%type <stn> template_param_list template_empty_param_list template_type_params template_type_empty_params
|
||||
//%type <stn> template_type_or_typeclass_params typeclass_params
|
||||
%type <td> template_type
|
||||
%type <stn> try_stmt
|
||||
%type <stn> uses_clause used_units_list
|
||||
|
|
@ -174,7 +173,7 @@
|
|||
%type <stn> used_unit_name
|
||||
%type <stn> unit_header
|
||||
%type <stn> var_decl_sect
|
||||
%type <stn> var_decl var_decl_part /*var_decl_internal*/ field_definition
|
||||
%type <stn> var_decl var_decl_part /*var_decl_internal*/ field_definition var_decl_with_assign_var_tuple
|
||||
%type <stn> var_stmt
|
||||
%type <stn> where_part
|
||||
%type <stn> where_part_list optional_where_section
|
||||
|
|
@ -183,14 +182,20 @@
|
|||
%type <ex> variable_as_type dotted_identifier
|
||||
%type <ex> func_decl_lambda expl_func_decl_lambda
|
||||
%type <td> lambda_type_ref lambda_type_ref_noproctype
|
||||
%type <stn> full_lambda_fp_list lambda_simple_fp_sect lambda_function_body lambda_procedure_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 <ti> tkAssignOrEqual
|
||||
%type <stn> pattern pattern_optional_var match_with pattern_case pattern_cases pattern_out_param pattern_out_param_optional_var
|
||||
%type <ob> pattern_out_param_list pattern_out_param_list_optional_var
|
||||
%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
|
||||
|
||||
%%
|
||||
// Warning: NonTerminal symbol "const_func_expr_list" is unreachable
|
||||
// -----------------------------------------------------------------
|
||||
// Warning: Terminating collection_pattern_var_item fixes the following size-1 NonTerminal set
|
||||
// {collection_pattern_var_item}
|
||||
// Error: NonTerminal symbol "collection_pattern_var_item" has no productions
|
||||
// Error: There are 1 non-terminating NonTerminal Symbols
|
||||
// {collection_pattern_var_item}
|
||||
// -------------------------------------------------------------------------------------------
|
||||
|
||||
parse_goal
|
||||
: program_file
|
||||
|
|
@ -666,26 +671,39 @@ type_decl_sect
|
|||
}
|
||||
;
|
||||
|
||||
var_decl_with_assign_var_tuple
|
||||
: var_decl
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
| tkRoundOpen identifier tkComma ident_list tkRoundClose tkAssign expr_l1 tkSemiColon
|
||||
{
|
||||
($4 as ident_list).Insert(0,$2);
|
||||
$4.source_context = LexLocation.MergeAll(@1,@2,@3,@4,@5);
|
||||
$$ = new var_tuple_def_statement($4 as ident_list, $7, @$);
|
||||
}
|
||||
;
|
||||
|
||||
var_decl_sect
|
||||
: tkVar var_decl
|
||||
: tkVar var_decl_with_assign_var_tuple
|
||||
{
|
||||
$$ = new variable_definitions($2 as var_def_statement, @$);
|
||||
}
|
||||
| tkEvent var_decl
|
||||
| tkEvent var_decl_with_assign_var_tuple
|
||||
{
|
||||
$$ = new variable_definitions($2 as var_def_statement, @$);
|
||||
($2 as var_def_statement).is_event = true;
|
||||
}
|
||||
| var_decl_sect var_decl
|
||||
| var_decl_sect var_decl_with_assign_var_tuple
|
||||
{
|
||||
$$ = ($1 as variable_definitions).Add($2 as var_def_statement, @$);
|
||||
}
|
||||
| tkVar tkRoundOpen identifier tkComma ident_list tkRoundClose tkAssign expr_l1 tkSemiColon
|
||||
/*| tkVar tkRoundOpen identifier tkComma ident_list tkRoundClose tkAssign expr_l1 tkSemiColon
|
||||
{
|
||||
($5 as ident_list).Insert(0,$3);
|
||||
$5.source_context = LexLocation.MergeAll(@1,@2,@3,@4,@5,@6);
|
||||
$$ = new assign_var_tuple($5 as ident_list, $8, @$);
|
||||
}
|
||||
}*/
|
||||
;
|
||||
|
||||
const_decl
|
||||
|
|
@ -966,7 +984,7 @@ optional_const_func_expr_list
|
|||
{ $$ = null; }
|
||||
;
|
||||
|
||||
const_func_expr_list
|
||||
/*const_func_expr_list
|
||||
: const_expr
|
||||
{
|
||||
$$ = new expression_list($1, @$);
|
||||
|
|
@ -975,7 +993,7 @@ const_func_expr_list
|
|||
{
|
||||
$$ = ($1 as expression_list).Add($3, @$);
|
||||
}
|
||||
;
|
||||
;*/
|
||||
|
||||
const_elem_list
|
||||
: const_elem_list1
|
||||
|
|
@ -1146,41 +1164,8 @@ simple_type_decl
|
|||
| template_identifier_with_equal type_decl_type tkSemiColon
|
||||
{
|
||||
$$ = new type_declaration($1, $2, @$);
|
||||
}/*
|
||||
| typeclass_restriction tkEqual tkTypeclass optional_base_classes optional_component_list_seq_end tkSemiColon
|
||||
{
|
||||
$$ = new type_declaration($1 as typeclass_restriction, new typeclass_definition($4 as named_type_reference_list, $5 as class_body_list, @$), @$);
|
||||
}
|
||||
| typeclass_restriction tkEqual tkInstance optional_component_list_seq_end tkSemiColon
|
||||
{
|
||||
$$ = new type_declaration($1 as typeclass_restriction, new instance_definition($4 as class_body_list, @$), @$);
|
||||
}*/
|
||||
;
|
||||
/*
|
||||
typeclass_restriction
|
||||
: simple_type_identifier typeclass_params
|
||||
{
|
||||
$$ = new typeclass_restriction(($1 as named_type_reference).ToString(), $2 as template_param_list, @$);
|
||||
}
|
||||
;
|
||||
|
||||
typeclass_params
|
||||
: tkSquareOpen template_param_list tkSquareClose
|
||||
{
|
||||
$$ = new typeclass_param_list($2 as template_param_list);
|
||||
}
|
||||
;
|
||||
|
||||
template_type_or_typeclass_params
|
||||
: template_type_params
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
| typeclass_params
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
;*/
|
||||
|
||||
type_decl_identifier
|
||||
: identifier
|
||||
|
|
@ -1563,108 +1548,31 @@ proc_type_decl
|
|||
object_type
|
||||
: class_attributes class_or_interface_keyword optional_base_classes optional_where_section optional_component_list_seq_end
|
||||
{
|
||||
$$ = NewObjectType((class_attribute)$1, $2, $3 as named_type_reference_list, $4 as where_definition_list, $5 as class_body_list, @$);
|
||||
class_definition cd = $$ as class_definition;
|
||||
if (cd == null || cd.body == null)
|
||||
break;
|
||||
var ccnt = cd.body.DescendantNodes().OfType<simple_property>().ToArray();
|
||||
var cm = new class_members(access_modifer.private_modifer);
|
||||
foreach (var prop in ccnt)
|
||||
var cd = NewObjectType((class_attribute)$1, $2, $3 as named_type_reference_list, $4 as where_definition_list, $5 as class_body_list, @$);
|
||||
$$ = cd;
|
||||
var tt = cd.DescendantNodes().OfType<class_definition>().Where(cld => cld.keyword == class_keyword.Record);
|
||||
if (tt.Count()>0)
|
||||
{
|
||||
var td = prop.property_type;
|
||||
var ra = prop.accessors?.read_accessor;
|
||||
if ($2.text.ToLower() == "interface" && ra != null && (ra.pr != null || ra.accessor_name != null))
|
||||
parsertools.AddErrorFromResource("INVALID_INTERFACE_MEMBER",ra.source_context);
|
||||
|
||||
if (ra != null && ra.pr != null)
|
||||
foreach (var ttt in tt)
|
||||
{
|
||||
if (prop.parameter_list != null)
|
||||
parsertools.AddErrorFromResource("EXTENDED_INDEXED_PROPERTIES",ra.source_context);
|
||||
var rapr = ra.pr as procedure_definition;
|
||||
(rapr.proc_header as function_header).return_type = td;
|
||||
cm.Add(rapr);
|
||||
if (prop.attr == definition_attribute.Static)
|
||||
{
|
||||
rapr.proc_header.class_keyword = true;
|
||||
procedure_attribute pa = new procedure_attribute(proc_attribute.attr_static);
|
||||
pa.source_context = rapr.proc_header.source_context;
|
||||
rapr.proc_header.proc_attributes = new procedure_attributes_list(pa);
|
||||
}
|
||||
}
|
||||
var wa = prop.accessors?.write_accessor;
|
||||
if ($2.text.ToLower() == "interface" && wa != null && (wa.pr != null || wa.accessor_name != null))
|
||||
parsertools.AddErrorFromResource("INVALID_INTERFACE_MEMBER",wa.source_context);
|
||||
|
||||
if (wa != null && wa.pr != null)
|
||||
{
|
||||
if (prop.parameter_list != null)
|
||||
parsertools.AddErrorFromResource("EXTENDED_INDEXED_PROPERTIES",ra.source_context);
|
||||
var wapr = wa.pr as procedure_definition;
|
||||
wapr.proc_header.parameters.params_list[0].vars_type = td;
|
||||
cm.Add(wapr);
|
||||
if (prop.attr == definition_attribute.Static)
|
||||
{
|
||||
wapr.proc_header.class_keyword = true;
|
||||
procedure_attribute pa = new procedure_attribute(proc_attribute.attr_static);
|
||||
pa.source_context = wapr.proc_header.source_context;
|
||||
wapr.proc_header.proc_attributes = new procedure_attributes_list(pa);
|
||||
}
|
||||
var sc = ttt.source_context;
|
||||
parsertools.AddErrorFromResource("NESTED_RECORD_DEFINITIONS_ARE_FORBIDDEN", new LexLocation(sc.begin_position.line_num, sc.begin_position.column_num-1, sc.end_position.line_num, sc.end_position.column_num, sc.FileName));
|
||||
}
|
||||
}
|
||||
if (cm.Count>0)
|
||||
cd.body.Insert(0, cm);
|
||||
}
|
||||
;
|
||||
|
||||
record_type
|
||||
: tkRecord optional_base_classes optional_where_section member_list_section tkEnd
|
||||
{
|
||||
$$ = NewRecordType($2 as named_type_reference_list, $3 as where_definition_list, $4 as class_body_list, @$);
|
||||
class_definition cd = $$ as class_definition;
|
||||
if (cd == null || cd.body == null)
|
||||
break;
|
||||
var ccnt = cd.body.DescendantNodes().OfType<simple_property>().ToArray();
|
||||
var cm = new class_members(access_modifer.private_modifer);
|
||||
foreach (var prop in ccnt)
|
||||
{
|
||||
var td = prop.property_type;
|
||||
var ra = prop.accessors?.read_accessor;
|
||||
|
||||
if (ra != null && ra.pr != null)
|
||||
{
|
||||
if (prop.parameter_list != null)
|
||||
parsertools.AddErrorFromResource("EXTENDED_INDEXED_PROPERTIES",ra.source_context);
|
||||
var rapr = ra.pr as procedure_definition;
|
||||
(rapr.proc_header as function_header).return_type = td;
|
||||
cm.Add(rapr);
|
||||
if (prop.attr == definition_attribute.Static)
|
||||
{
|
||||
rapr.proc_header.class_keyword = true;
|
||||
procedure_attribute pa = new procedure_attribute(proc_attribute.attr_static);
|
||||
pa.source_context = rapr.proc_header.source_context;
|
||||
rapr.proc_header.proc_attributes = new procedure_attributes_list(pa);
|
||||
}
|
||||
}
|
||||
var wa = prop.accessors?.write_accessor;
|
||||
|
||||
if (wa != null && wa.pr != null && prop.parameter_list == null)
|
||||
{
|
||||
if (prop.parameter_list != null)
|
||||
parsertools.AddErrorFromResource("EXTENDED_INDEXED_PROPERTIES",ra.source_context);
|
||||
var wapr = wa.pr as procedure_definition;
|
||||
wapr.proc_header.parameters.params_list[0].vars_type = td;
|
||||
cm.Add(wapr);
|
||||
if (prop.attr == definition_attribute.Static)
|
||||
{
|
||||
wapr.proc_header.class_keyword = true;
|
||||
procedure_attribute pa = new procedure_attribute(proc_attribute.attr_static);
|
||||
pa.source_context = wapr.proc_header.source_context;
|
||||
wapr.proc_header.proc_attributes = new procedure_attributes_list(pa);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cm.Count>0)
|
||||
cd.body.Insert(0, cm);
|
||||
var nnrt = new class_definition($2 as named_type_reference_list, $4 as class_body_list, class_keyword.Record, null, $3 as where_definition_list, class_attribute.None, false, @$);
|
||||
if (/*nnrt.body!=null && nnrt.body.class_def_blocks!=null &&
|
||||
nnrt.body.class_def_blocks.Count>0 &&*/
|
||||
nnrt.body.class_def_blocks[0].access_mod==null)
|
||||
{
|
||||
nnrt.body.class_def_blocks[0].access_mod = new access_modifer_node(access_modifer.public_modifer);
|
||||
}
|
||||
$$ = nnrt;
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -1760,12 +1668,7 @@ base_class_name
|
|||
: simple_type_identifier
|
||||
{ $$ = $1; }
|
||||
| template_type
|
||||
{ $$ = $1; }/*
|
||||
| typeclass_restriction
|
||||
{
|
||||
var names = new List<ident>();
|
||||
names.Add(($1 as typeclass_restriction).name);
|
||||
$$ = new typeclass_reference(null, names, ($1 as typeclass_restriction).restriction_args); }*/
|
||||
{ $$ = $1; }
|
||||
;
|
||||
|
||||
template_arguments
|
||||
|
|
@ -1798,11 +1701,7 @@ where_part
|
|||
: tkWhere ident_list tkColon type_ref_and_secific_list tkSemiColon
|
||||
{
|
||||
$$ = new where_definition($2 as ident_list, $4 as where_type_specificator_list, @$);
|
||||
}/*
|
||||
| tkWhere typeclass_restriction tkSemiColon
|
||||
{
|
||||
$$ = new where_typeclass_constraint($2 as typeclass_restriction);
|
||||
}*/
|
||||
}
|
||||
;
|
||||
|
||||
type_ref_and_secific_list
|
||||
|
|
@ -2080,12 +1979,23 @@ simple_property_definition
|
|||
{
|
||||
parsertools.AddErrorFromResource("STATIC_PROPERTIES_CANNOT_HAVE_ATTRBUTE_{0}",@7,$7.name);
|
||||
}
|
||||
| tkAuto tkProperty qualified_identifier property_interface tkSemiColon
|
||||
{
|
||||
$$ = NewSimplePropertyDefinition($3 as method_name, $4 as property_interface, null, proc_attribute.attr_none, null, @$);
|
||||
($$ as simple_property).is_auto = true;
|
||||
}
|
||||
| class_or_static tkAuto tkProperty qualified_identifier property_interface tkSemiColon
|
||||
{
|
||||
$$ = NewSimplePropertyDefinition($4 as method_name, $5 as property_interface, null, proc_attribute.attr_none, null, @$);
|
||||
($$ as simple_property).is_auto = true;
|
||||
($$ as simple_property).attr = definition_attribute.Static;
|
||||
}
|
||||
;
|
||||
|
||||
array_defaultproperty
|
||||
:
|
||||
{ $$ = null; }
|
||||
| tkDefault tkSemiColon
|
||||
| tkDefault tkSemiColon
|
||||
{
|
||||
$$ = new property_array_default();
|
||||
$$.source_context = @$;
|
||||
|
|
@ -2182,7 +2092,9 @@ property_specifiers
|
|||
procedure_definition pr = null;
|
||||
if (!parsertools.build_tree_for_formatter)
|
||||
pr = CreateAndAddToClassWriteProc($2 as statement,id,@2);
|
||||
$$ = NewPropertySpecifiersWrite($1, id, pr, $2 as statement, $3 as property_accessors, @$); // $2 ïåðåäà¸òñÿ äëÿ ôîðìàòèðîâàíèÿ
|
||||
if (parsertools.build_tree_for_formatter)
|
||||
$$ = NewPropertySpecifiersWrite($1, id, pr, $2 as statement, $3 as property_accessors, @$); // $2 ïåðåäà¸òñÿ äëÿ ôîðìàòèðîâàíèÿ
|
||||
else $$ = NewPropertySpecifiersWrite($1, id, pr, null, $3 as property_accessors, @$);
|
||||
}
|
||||
}
|
||||
;
|
||||
|
|
@ -2205,7 +2117,9 @@ write_property_specifiers
|
|||
procedure_definition pr = null;
|
||||
if (!parsertools.build_tree_for_formatter)
|
||||
pr = CreateAndAddToClassWriteProc($2 as statement,id,@2);
|
||||
$$ = NewPropertySpecifiersWrite($1, id, pr, $2 as statement, null, @$);
|
||||
if (parsertools.build_tree_for_formatter)
|
||||
$$ = NewPropertySpecifiersWrite($1, id, pr, $2 as statement, null, @$);
|
||||
else $$ = NewPropertySpecifiersWrite($1, id, pr, null, null, @$);
|
||||
}
|
||||
}
|
||||
;
|
||||
|
|
@ -2267,12 +2181,6 @@ var_decl_part
|
|||
{
|
||||
$$ = new var_def_statement($1 as ident_list, $3, $5, definition_attribute.None, false, @$);
|
||||
}
|
||||
/*| tkRoundOpen identifier tkComma ident_list tkRoundClose tkAssign expr_l1
|
||||
{
|
||||
($4 as ident_list).Insert(0,$2);
|
||||
$4.source_context = LexLocation.MergeAll(@1,@2,@3,@4,@5,@6);
|
||||
$$ = new assign_var_tuple($4 as ident_list, $7, @$);
|
||||
}*/
|
||||
;
|
||||
|
||||
typed_var_init_expression
|
||||
|
|
@ -2899,6 +2807,18 @@ pattern_case
|
|||
{
|
||||
$$ = 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, @$);
|
||||
}
|
||||
;
|
||||
|
||||
case_stmt
|
||||
|
|
@ -3373,44 +3293,172 @@ relop_expr
|
|||
{
|
||||
$$ = 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 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, @$);
|
||||
$$ = new is_pattern_expr(isTypeCheck.expr, deconstructorPattern, @$);
|
||||
}
|
||||
|
||||
| term tkIs collection_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_deconstructor_parameter>, $1, @$);
|
||||
$$ = new deconstructor_pattern($3 as List<pattern_parameter>, $1, @$);
|
||||
}
|
||||
;
|
||||
|
||||
pattern_optional_var
|
||||
: 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, @$);
|
||||
}
|
||||
;
|
||||
;
|
||||
|
||||
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, @$);
|
||||
}
|
||||
| tkDotDot
|
||||
{
|
||||
$$ = new collection_pattern_gap_parameter();
|
||||
}
|
||||
;
|
||||
|
||||
collection_pattern_var_item
|
||||
| tkVar identifier tkColon type_ref
|
||||
// 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
|
||||
: 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 { $$ = $1; }
|
||||
;
|
||||
|
||||
tuple_pattern
|
||||
: tkRoundOpen tuple_pattern_expr tkComma tuple_pattern_expr_list lambda_type_ref optional_full_lambda_fp_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)
|
||||
parsertools.AddErrorFromResource("TUPLE_ELEMENTS_COUNT_MUST_BE_LESSEQUAL_7",@$);
|
||||
($4 as expression_list).Insert(0,$2);
|
||||
$$ = new tuple_node($4 as expression_list,@$);
|
||||
}
|
||||
;
|
||||
|
||||
tuple_pattern_expr
|
||||
: tkUnderscore { $$ = new tuple_wild_card(); }
|
||||
| literal_or_number { $$ = $1; }
|
||||
;
|
||||
|
||||
tuple_pattern_expr_list
|
||||
: tuple_pattern_expr
|
||||
{
|
||||
$$ = new expression_list($1, @$);
|
||||
}
|
||||
| tuple_pattern_expr_list tkComma tuple_pattern_expr
|
||||
{
|
||||
$$ = ($1 as expression_list).Add($3, @$);
|
||||
}
|
||||
;
|
||||
|
||||
pattern_out_param_list_optional_var
|
||||
: pattern_out_param_optional_var
|
||||
{
|
||||
$$ = new List<pattern_deconstructor_parameter>();
|
||||
($$ as List<pattern_deconstructor_parameter>).Add($1 as pattern_deconstructor_parameter);
|
||||
$$ = new List<pattern_parameter>();
|
||||
($$ as List<pattern_parameter>).Add($1 as pattern_parameter);
|
||||
}
|
||||
| pattern_out_param_list_optional_var tkSemiColon pattern_out_param_optional_var
|
||||
{
|
||||
var list = $1 as List<pattern_deconstructor_parameter>;
|
||||
list.Add($3 as pattern_deconstructor_parameter);
|
||||
var list = $1 as List<pattern_parameter>;
|
||||
list.Add($3 as pattern_parameter);
|
||||
$$ = list;
|
||||
}
|
||||
| pattern_out_param_list_optional_var tkComma pattern_out_param_optional_var
|
||||
{
|
||||
var list = $1 as List<pattern_deconstructor_parameter>;
|
||||
list.Add($3 as pattern_deconstructor_parameter);
|
||||
var list = $1 as List<pattern_parameter>;
|
||||
list.Add($3 as pattern_parameter);
|
||||
$$ = list;
|
||||
}
|
||||
;
|
||||
|
|
@ -3418,25 +3466,33 @@ pattern_out_param_list_optional_var
|
|||
pattern_out_param_list
|
||||
: pattern_out_param
|
||||
{
|
||||
$$ = new List<pattern_deconstructor_parameter>();
|
||||
($$ as List<pattern_deconstructor_parameter>).Add($1 as pattern_deconstructor_parameter);
|
||||
$$ = new List<pattern_parameter>();
|
||||
($$ as List<pattern_parameter>).Add($1 as pattern_parameter);
|
||||
}
|
||||
| pattern_out_param_list tkSemiColon pattern_out_param
|
||||
{
|
||||
var list = $1 as List<pattern_deconstructor_parameter>;
|
||||
list.Add($3 as pattern_deconstructor_parameter);
|
||||
var list = $1 as List<pattern_parameter>;
|
||||
list.Add($3 as pattern_parameter);
|
||||
$$ = list;
|
||||
}
|
||||
| pattern_out_param_list tkComma pattern_out_param
|
||||
{
|
||||
var list = $1 as List<pattern_deconstructor_parameter>;
|
||||
list.Add($3 as pattern_deconstructor_parameter);
|
||||
var list = $1 as List<pattern_parameter>;
|
||||
list.Add($3 as pattern_parameter);
|
||||
$$ = list;
|
||||
}
|
||||
;
|
||||
|
||||
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, @$);
|
||||
}
|
||||
|
|
@ -3451,7 +3507,15 @@ pattern_out_param
|
|||
;
|
||||
|
||||
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, @$);
|
||||
}
|
||||
|
|
@ -3585,7 +3649,7 @@ typecast_op
|
|||
;
|
||||
|
||||
as_is_expr
|
||||
: is_expr
|
||||
: is_type_expr
|
||||
{ $$ = $1; }
|
||||
| as_expr
|
||||
{ $$ = $1; }
|
||||
|
|
@ -3598,7 +3662,7 @@ as_expr
|
|||
}
|
||||
;
|
||||
|
||||
is_expr
|
||||
is_type_expr
|
||||
: term tkIs simple_or_template_type_reference
|
||||
{
|
||||
$$ = NewAsIsExpr($1, op_typecast.is_op, $3, @$);
|
||||
|
|
@ -4211,9 +4275,7 @@ keyword
|
|||
| tkMatch
|
||||
{ $$ = $1; }
|
||||
| tkWhen
|
||||
{ $$ = $1; }/*
|
||||
| tkInstance
|
||||
{ $$ = $1; }*/
|
||||
{ $$ = $1; }
|
||||
;
|
||||
|
||||
reserved_keyword
|
||||
|
|
@ -4482,15 +4544,8 @@ lambda_type_ref_noproctype
|
|||
}
|
||||
;
|
||||
|
||||
lambda_function_body
|
||||
: expr_l1
|
||||
{
|
||||
//$$ = NewLambdaBody($1, @$);
|
||||
var sl = new statement_list(new assign("result",$1,@$),@$); // íàäî ïîìå÷àòü åù¸ è assign êàê àâòîñãåíåðèðîâàííûé äëÿ ëÿìáäû
|
||||
sl.expr_lambda_body = true;
|
||||
$$ = sl;
|
||||
}
|
||||
| compound_stmt
|
||||
common_lambda_body
|
||||
: compound_stmt
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
|
|
@ -4514,6 +4569,10 @@ lambda_function_body
|
|||
{
|
||||
$$ = new statement_list($1 as statement, @$);
|
||||
}
|
||||
| loop_stmt
|
||||
{
|
||||
$$ = new statement_list($1 as statement, @$);
|
||||
}
|
||||
| case_stmt
|
||||
{
|
||||
$$ = new statement_list($1 as statement, @$);
|
||||
|
|
@ -4534,6 +4593,25 @@ lambda_function_body
|
|||
{
|
||||
$$ = new statement_list($1 as statement, @$);
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
lambda_function_body
|
||||
: expr_l1
|
||||
{
|
||||
var id = SyntaxVisitors.ExprHasNameVisitor.HasName($1, "Result");
|
||||
if (id != null)
|
||||
{
|
||||
parsertools.AddErrorFromResource("RESULT_IDENT_NOT_EXPECTED_IN_THIS_CONTEXT", id.source_context);
|
||||
}
|
||||
var sl = new statement_list(new assign("result",$1,@$),@$); // íàäî ïîìå÷àòü åù¸ è assign êàê àâòîñãåíåðèðîâàííûé äëÿ ëÿìáäû - ÷òîáû çàïðåòèòü ÿâíûé Result
|
||||
sl.expr_lambda_body = true;
|
||||
$$ = sl;
|
||||
}
|
||||
| common_lambda_body
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
lambda_procedure_body
|
||||
|
|
@ -4541,54 +4619,14 @@ lambda_procedure_body
|
|||
{
|
||||
$$ = new statement_list($1 as statement, @$);
|
||||
}
|
||||
| compound_stmt
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
| if_stmt
|
||||
{
|
||||
$$ = new statement_list($1 as statement, @$);
|
||||
}
|
||||
| while_stmt
|
||||
{
|
||||
$$ = new statement_list($1 as statement, @$);
|
||||
}
|
||||
| repeat_stmt
|
||||
{
|
||||
$$ = new statement_list($1 as statement, @$);
|
||||
}
|
||||
| for_stmt
|
||||
{
|
||||
$$ = new statement_list($1 as statement, @$);
|
||||
}
|
||||
| foreach_stmt
|
||||
{
|
||||
$$ = new statement_list($1 as statement, @$);
|
||||
}
|
||||
| case_stmt
|
||||
{
|
||||
$$ = new statement_list($1 as statement, @$);
|
||||
}
|
||||
| try_stmt
|
||||
{
|
||||
$$ = new statement_list($1 as statement, @$);
|
||||
}
|
||||
| lock_stmt
|
||||
{
|
||||
$$ = new statement_list($1 as statement, @$);
|
||||
}
|
||||
| yield_stmt
|
||||
{
|
||||
$$ = new statement_list($1 as statement, @$);
|
||||
}
|
||||
| raise_stmt
|
||||
{
|
||||
$$ = new statement_list($1 as statement, @$);
|
||||
}
|
||||
| assignment
|
||||
{
|
||||
$$ = new statement_list($1 as statement, @$);
|
||||
}
|
||||
| common_lambda_body
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
%%// ==========================================================================
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@
|
|||
%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 match_with pattern_case pattern_cases pattern_out_param pattern_out_param_optional_var tuple_pattern_expr_list const_pattern_expr_list
|
||||
%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
|
||||
|
||||
|
|
@ -3279,7 +3279,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, @$);
|
||||
}
|
||||
|
||||
|
|
@ -3292,14 +3292,14 @@ relop_expr
|
|||
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, @$);
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -3329,10 +3329,18 @@ collection_pattern_list_item
|
|||
{
|
||||
$$ = new const_pattern_parameter($1, @$);
|
||||
}
|
||||
| pattern
|
||||
| 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, @$);
|
||||
|
|
@ -3343,6 +3351,25 @@ collection_pattern_list_item
|
|||
}
|
||||
;
|
||||
|
||||
collection_pattern_var_item
|
||||
: tkVar identifier tkColon type_ref
|
||||
{
|
||||
$$ = 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
|
||||
: const_pattern_expr_list
|
||||
{
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1217,6 +1217,16 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1941,6 +1941,22 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
{
|
||||
}
|
||||
|
||||
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 override void visit(expression _expression)
|
||||
{
|
||||
DefaultVisit(_expression);
|
||||
|
|
@ -4014,6 +4030,22 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -504,6 +504,10 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
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();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
@ -4258,6 +4262,30 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -6673,6 +6673,48 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -49653,18 +49653,20 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
///<summary>
|
||||
///Конструктор с параметрами.
|
||||
///</summary>
|
||||
public deconstructor_pattern(type_definition _type)
|
||||
public deconstructor_pattern(type_definition _type,expression _const_params_check)
|
||||
{
|
||||
this._type=_type;
|
||||
this._const_params_check=_const_params_check;
|
||||
FillParentsInDirectChilds();
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Конструктор с параметрами.
|
||||
///</summary>
|
||||
public deconstructor_pattern(type_definition _type,SourceContext sc)
|
||||
public deconstructor_pattern(type_definition _type,expression _const_params_check,SourceContext sc)
|
||||
{
|
||||
this._type=_type;
|
||||
this._const_params_check=_const_params_check;
|
||||
source_context = sc;
|
||||
FillParentsInDirectChilds();
|
||||
}
|
||||
|
|
@ -49672,20 +49674,22 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
///<summary>
|
||||
///Конструктор с параметрами.
|
||||
///</summary>
|
||||
public deconstructor_pattern(List<pattern_parameter> _parameters,type_definition _type)
|
||||
public deconstructor_pattern(List<pattern_parameter> _parameters,type_definition _type,expression _const_params_check)
|
||||
{
|
||||
this._parameters=_parameters;
|
||||
this._type=_type;
|
||||
this._const_params_check=_const_params_check;
|
||||
FillParentsInDirectChilds();
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Конструктор с параметрами.
|
||||
///</summary>
|
||||
public deconstructor_pattern(List<pattern_parameter> _parameters,type_definition _type,SourceContext sc)
|
||||
public deconstructor_pattern(List<pattern_parameter> _parameters,type_definition _type,expression _const_params_check,SourceContext sc)
|
||||
{
|
||||
this._parameters=_parameters;
|
||||
this._type=_type;
|
||||
this._const_params_check=_const_params_check;
|
||||
source_context = sc;
|
||||
FillParentsInDirectChilds();
|
||||
}
|
||||
|
|
@ -51987,7 +51991,7 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
///</summary>
|
||||
public collection_pattern()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -52219,6 +52223,280 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
}
|
||||
|
||||
|
||||
///<summary>
|
||||
///
|
||||
///</summary>
|
||||
[Serializable]
|
||||
public partial class collection_pattern_wild_card : pattern_parameter
|
||||
{
|
||||
|
||||
///<summary>
|
||||
///Конструктор без параметров.
|
||||
///</summary>
|
||||
public collection_pattern_wild_card()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary> Создает копию узла </summary>
|
||||
public override syntax_tree_node Clone()
|
||||
{
|
||||
collection_pattern_wild_card copy = new collection_pattern_wild_card();
|
||||
copy.Parent = this.Parent;
|
||||
if (source_context != null)
|
||||
copy.source_context = new SourceContext(source_context);
|
||||
return copy;
|
||||
}
|
||||
|
||||
/// <summary> Получает копию данного узла корректного типа </summary>
|
||||
public new collection_pattern_wild_card TypedClone()
|
||||
{
|
||||
return Clone() as collection_pattern_wild_card;
|
||||
}
|
||||
|
||||
///<summary> Заполняет поля Parent в непосредственных дочерних узлах </summary>
|
||||
public override void FillParentsInDirectChilds()
|
||||
{
|
||||
}
|
||||
|
||||
///<summary> Заполняет поля Parent во всем поддереве </summary>
|
||||
public override void FillParentsInAllChilds()
|
||||
{
|
||||
FillParentsInDirectChilds();
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Свойство для получения количества всех подузлов без элементов поля типа List
|
||||
///</summary>
|
||||
public override Int32 subnodes_without_list_elements_count
|
||||
{
|
||||
get
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
///<summary>
|
||||
///Свойство для получения количества всех подузлов. Подузлом также считается каждый элемент поля типа List
|
||||
///</summary>
|
||||
public override Int32 subnodes_count
|
||||
{
|
||||
get
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
///<summary>
|
||||
///Индексатор для получения всех подузлов
|
||||
///</summary>
|
||||
public override syntax_tree_node this[Int32 ind]
|
||||
{
|
||||
get
|
||||
{
|
||||
if(subnodes_count == 0 || ind < 0 || ind > subnodes_count-1)
|
||||
throw new IndexOutOfRangeException();
|
||||
return null;
|
||||
}
|
||||
set
|
||||
{
|
||||
if(subnodes_count == 0 || ind < 0 || ind > subnodes_count-1)
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
}
|
||||
///<summary>
|
||||
///Метод для обхода дерева посетителем
|
||||
///</summary>
|
||||
///<param name="visitor">Объект-посетитель.</param>
|
||||
///<returns>Return value is void</returns>
|
||||
public override void visit(IVisitor visitor)
|
||||
{
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
///<summary>
|
||||
///Возможно без типа
|
||||
///</summary>
|
||||
[Serializable]
|
||||
public partial class collection_pattern_var_parameter : pattern_parameter
|
||||
{
|
||||
|
||||
///<summary>
|
||||
///Конструктор без параметров.
|
||||
///</summary>
|
||||
public collection_pattern_var_parameter()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Конструктор с параметрами.
|
||||
///</summary>
|
||||
public collection_pattern_var_parameter(ident _identifier,type_definition _type)
|
||||
{
|
||||
this._identifier=_identifier;
|
||||
this._type=_type;
|
||||
FillParentsInDirectChilds();
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Конструктор с параметрами.
|
||||
///</summary>
|
||||
public collection_pattern_var_parameter(ident _identifier,type_definition _type,SourceContext sc)
|
||||
{
|
||||
this._identifier=_identifier;
|
||||
this._type=_type;
|
||||
source_context = sc;
|
||||
FillParentsInDirectChilds();
|
||||
}
|
||||
protected ident _identifier;
|
||||
protected type_definition _type;
|
||||
|
||||
///<summary>
|
||||
///
|
||||
///</summary>
|
||||
public ident identifier
|
||||
{
|
||||
get
|
||||
{
|
||||
return _identifier;
|
||||
}
|
||||
set
|
||||
{
|
||||
_identifier=value;
|
||||
if (_identifier != null)
|
||||
_identifier.Parent = this;
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///
|
||||
///</summary>
|
||||
public type_definition type
|
||||
{
|
||||
get
|
||||
{
|
||||
return _type;
|
||||
}
|
||||
set
|
||||
{
|
||||
_type=value;
|
||||
if (_type != null)
|
||||
_type.Parent = this;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary> Создает копию узла </summary>
|
||||
public override syntax_tree_node Clone()
|
||||
{
|
||||
collection_pattern_var_parameter copy = new collection_pattern_var_parameter();
|
||||
copy.Parent = this.Parent;
|
||||
if (source_context != null)
|
||||
copy.source_context = new SourceContext(source_context);
|
||||
if (identifier != null)
|
||||
{
|
||||
copy.identifier = (ident)identifier.Clone();
|
||||
copy.identifier.Parent = copy;
|
||||
}
|
||||
if (type != null)
|
||||
{
|
||||
copy.type = (type_definition)type.Clone();
|
||||
copy.type.Parent = copy;
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
/// <summary> Получает копию данного узла корректного типа </summary>
|
||||
public new collection_pattern_var_parameter TypedClone()
|
||||
{
|
||||
return Clone() as collection_pattern_var_parameter;
|
||||
}
|
||||
|
||||
///<summary> Заполняет поля Parent в непосредственных дочерних узлах </summary>
|
||||
public override void FillParentsInDirectChilds()
|
||||
{
|
||||
if (identifier != null)
|
||||
identifier.Parent = this;
|
||||
if (type != null)
|
||||
type.Parent = this;
|
||||
}
|
||||
|
||||
///<summary> Заполняет поля Parent во всем поддереве </summary>
|
||||
public override void FillParentsInAllChilds()
|
||||
{
|
||||
FillParentsInDirectChilds();
|
||||
identifier?.FillParentsInAllChilds();
|
||||
type?.FillParentsInAllChilds();
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Свойство для получения количества всех подузлов без элементов поля типа List
|
||||
///</summary>
|
||||
public override Int32 subnodes_without_list_elements_count
|
||||
{
|
||||
get
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
///<summary>
|
||||
///Свойство для получения количества всех подузлов. Подузлом также считается каждый элемент поля типа List
|
||||
///</summary>
|
||||
public override Int32 subnodes_count
|
||||
{
|
||||
get
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
///<summary>
|
||||
///Индексатор для получения всех подузлов
|
||||
///</summary>
|
||||
public override syntax_tree_node this[Int32 ind]
|
||||
{
|
||||
get
|
||||
{
|
||||
if(subnodes_count == 0 || ind < 0 || ind > subnodes_count-1)
|
||||
throw new IndexOutOfRangeException();
|
||||
switch(ind)
|
||||
{
|
||||
case 0:
|
||||
return identifier;
|
||||
case 1:
|
||||
return type;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
set
|
||||
{
|
||||
if(subnodes_count == 0 || ind < 0 || ind > subnodes_count-1)
|
||||
throw new IndexOutOfRangeException();
|
||||
switch(ind)
|
||||
{
|
||||
case 0:
|
||||
identifier = (ident)value;
|
||||
break;
|
||||
case 1:
|
||||
type = (type_definition)value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
///<summary>
|
||||
///Метод для обхода дерева посетителем
|
||||
///</summary>
|
||||
///<param name="visitor">Объект-посетитель.</param>
|
||||
///<returns>Return value is void</returns>
|
||||
public override void visit(IVisitor visitor)
|
||||
{
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1456,6 +1456,18 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
///<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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3075,8 +3075,12 @@
|
|||
<Fields />
|
||||
<Methods />
|
||||
<Tags>
|
||||
<CategoryIndices />
|
||||
<TagIndices />
|
||||
<CategoryIndices>
|
||||
<CategoryIndex>0</CategoryIndex>
|
||||
</CategoryIndices>
|
||||
<TagIndices>
|
||||
<TagIndex>9</TagIndex>
|
||||
</TagIndices>
|
||||
</Tags>
|
||||
</SyntaxNode>
|
||||
<SyntaxNode Name="const_pattern_parameter" BaseName="pattern_parameter">
|
||||
|
|
@ -3129,6 +3133,33 @@
|
|||
</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>
|
||||
</SyntaxNodes>
|
||||
<Settings>
|
||||
<FileName>Tree.cs</FileName>
|
||||
|
|
@ -3154,7 +3185,7 @@
|
|||
<Tag Name="Важнейшие" ReferenceCount="207" />
|
||||
<Tag Name="Method_Procedure_Call" ReferenceCount="2" />
|
||||
<Tag Name="Yield" ReferenceCount="8" />
|
||||
<Tag Name="Patterns" ReferenceCount="17" />
|
||||
<Tag Name="Patterns" ReferenceCount="20" />
|
||||
<Tag Name="Typeclasses" ReferenceCount="13" />
|
||||
</Tags>
|
||||
</FilterCategory>
|
||||
|
|
@ -3411,6 +3442,10 @@
|
|||
<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.Language" Value="" />
|
||||
|
|
|
|||
|
|
@ -60,6 +60,15 @@ namespace SyntaxVisitors.SugarVisitors
|
|||
}
|
||||
}
|
||||
|
||||
public class CollectionDesugaringResult
|
||||
{
|
||||
public List<statement> VarParametersDeclarations { get; set; } = new List<statement>();
|
||||
|
||||
public expression SuccessMatchingCheck { get; set; }
|
||||
|
||||
public List<statement> VarParametersAssignments { get; set; } = new List<statement>();
|
||||
}
|
||||
|
||||
public class PatternsDesugaringVisitor : BaseChangeVisitor
|
||||
{
|
||||
private enum PatternLocation { Unknown, IfCondition, Assign }
|
||||
|
|
@ -68,6 +77,7 @@ namespace SyntaxVisitors.SugarVisitors
|
|||
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 GeneratedDeconstructParamPrefix = "<>deconstructParam";
|
||||
|
||||
|
|
@ -252,7 +262,8 @@ namespace SyntaxVisitors.SugarVisitors
|
|||
if (possibleTupleDotNode != null)
|
||||
{
|
||||
var possibleTupleCallString = possibleTupleDotNode.ToString();
|
||||
if (possibleTupleCallString.Contains("System.Tuple.Create")) {
|
||||
if (possibleTupleCallString.Contains("System.Tuple.Create"))
|
||||
{
|
||||
var elemsToCompare = new List<expression>();
|
||||
for (int currentInd = 0; currentInd < possibleTupleCase.parameters.Count; ++currentInd)
|
||||
{
|
||||
|
|
@ -260,7 +271,8 @@ namespace SyntaxVisitors.SugarVisitors
|
|||
if (!(tupleElem is tuple_wild_card))
|
||||
{
|
||||
elemsToCompare.Add(currentInd);
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
possibleTupleCase.parameters[currentInd] = new int32_const(0, patternCase.source_context);
|
||||
}
|
||||
|
|
@ -325,18 +337,20 @@ namespace SyntaxVisitors.SugarVisitors
|
|||
AddDesugaredCaseToResult(ifCheck, ifCheck);
|
||||
}
|
||||
|
||||
private expression GetCollectionItemsEqualCheckBeforeGap(addressed_value matchingExpression, List<pattern_parameter> toCompare)
|
||||
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 const_params)
|
||||
if (param is const_pattern_parameter constParam)
|
||||
{
|
||||
var indexerCall = new indexer(
|
||||
matchingExpression,
|
||||
new expression_list(
|
||||
new int32_const(fromIndex++, matchingExpression.source_context),
|
||||
new int32_const(fromIndex, matchingExpression.source_context),
|
||||
matchingExpression.source_context),
|
||||
matchingExpression.source_context);
|
||||
|
||||
|
|
@ -344,7 +358,7 @@ namespace SyntaxVisitors.SugarVisitors
|
|||
new List<expression>()
|
||||
{
|
||||
indexerCall,
|
||||
const_params.const_param
|
||||
constParam.const_param
|
||||
}
|
||||
);
|
||||
|
||||
|
|
@ -358,19 +372,27 @@ namespace SyntaxVisitors.SugarVisitors
|
|||
|
||||
equalChecks = equalChecks == null ? (expression)equalCall : bin_expr.LogicalAnd(equalChecks, equalCall);
|
||||
}
|
||||
|
||||
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)
|
||||
private expression GetCollectionItemsEqualCheckAfterGap(addressed_value matchingExpression,
|
||||
List<pattern_parameter> toCompare,
|
||||
CollectionDesugaringResult desugaringResult)
|
||||
{
|
||||
var elemFromTail = 1;
|
||||
expression equalChecks = null;
|
||||
foreach (var param in toCompare)
|
||||
{
|
||||
if (param is const_pattern_parameter const_param)
|
||||
{
|
||||
var indexerCall = new indexer(
|
||||
var indexerCall = new indexer(
|
||||
matchingExpression,
|
||||
new expression_list(
|
||||
new bin_expr(
|
||||
|
|
@ -379,16 +401,18 @@ namespace SyntaxVisitors.SugarVisitors
|
|||
matchingExpression,
|
||||
new ident("Count", matchingExpression.source_context)),
|
||||
new expression_list()),
|
||||
new int32_const(elemFromTail++, matchingExpression.source_context),
|
||||
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,
|
||||
const_param.const_param
|
||||
constParam.const_param
|
||||
}
|
||||
);
|
||||
|
||||
|
|
@ -402,10 +426,23 @@ namespace SyntaxVisitors.SugarVisitors
|
|||
|
||||
equalChecks = equalChecks == null ? (expression)equalCall : bin_expr.LogicalAnd(equalChecks, equalCall);
|
||||
}
|
||||
|
||||
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 NewSuccessName() => new ident(GeneratedPatternNamePrefix + "Success" + successVariableCounter++);
|
||||
|
|
@ -462,10 +499,11 @@ namespace SyntaxVisitors.SugarVisitors
|
|||
return desugarResult;
|
||||
}
|
||||
|
||||
private expression DesugarCollectionPattern(collection_pattern pattern, expression matchingExpression)
|
||||
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;
|
||||
|
|
@ -495,14 +533,37 @@ namespace SyntaxVisitors.SugarVisitors
|
|||
}
|
||||
}
|
||||
|
||||
var itemsEqualCalls = GetCollectionItemsEqualCheckBeforeGap(matchingExpression as addressed_value, exprBeforeGap);
|
||||
var successMatchingCheck = GetCollectionItemsEqualCheckBeforeGap(
|
||||
matchingExpression as addressed_value, exprBeforeGap, desugaringResult);
|
||||
|
||||
if (gapItemMet && exprAfterGap.Count != 0)
|
||||
{
|
||||
var afterGapEqual = GetCollectionItemsEqualCheckAfterGap(matchingExpression as addressed_value, exprAfterGap);
|
||||
itemsEqualCalls = itemsEqualCalls == null ? afterGapEqual : bin_expr.LogicalAnd(itemsEqualCalls, afterGapEqual);
|
||||
var afterGapEqual = GetCollectionItemsEqualCheckAfterGap(
|
||||
matchingExpression as addressed_value, exprAfterGap, desugaringResult);
|
||||
|
||||
if (afterGapEqual != null)
|
||||
{
|
||||
successMatchingCheck = successMatchingCheck == null ?
|
||||
afterGapEqual :
|
||||
bin_expr.LogicalAnd(successMatchingCheck, afterGapEqual);
|
||||
}
|
||||
}
|
||||
|
||||
return itemsEqualCalls;
|
||||
var 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
|
||||
);
|
||||
|
||||
successMatchingCheck = successMatchingCheck == null ?
|
||||
collectionLengthCheck :
|
||||
bin_expr.LogicalAnd(collectionLengthCheck, successMatchingCheck);
|
||||
|
||||
desugaringResult.SuccessMatchingCheck = successMatchingCheck == null ?
|
||||
new bool_const(true) :
|
||||
successMatchingCheck;
|
||||
return desugaringResult;
|
||||
}
|
||||
|
||||
private void DesugarIsExpression(is_pattern_expr isPatternExpr)
|
||||
|
|
@ -516,29 +577,16 @@ namespace SyntaxVisitors.SugarVisitors
|
|||
}
|
||||
var patternLocation = GetLocation(isPatternExpr);
|
||||
|
||||
switch (isPatternExpr.right)
|
||||
if (isPatternExpr.right is deconstructor_pattern pattern)
|
||||
{
|
||||
case deconstructor_pattern pattern:
|
||||
{
|
||||
var constParamCheck = DesugarDeconstructorPatternParameters(isPatternExpr.right as deconstructor_pattern);
|
||||
pattern.const_params_check = constParamCheck;
|
||||
|
||||
//AddDefinitionsInUpperStatementList(isPatternExpr, new[] { GetTypeCompatibilityCheck(isPatternExpr) });
|
||||
switch (patternLocation)
|
||||
{
|
||||
case PatternLocation.IfCondition: DesugarIsExpressionInIfCondition(isPatternExpr); break;
|
||||
case PatternLocation.Assign: DesugarIsExpressionInAssignment(isPatternExpr); break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case collection_pattern pattern:
|
||||
{
|
||||
switch (patternLocation)
|
||||
{
|
||||
case PatternLocation.IfCondition: DesugarIsExpressionInIfCondition(isPatternExpr); break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
var constParamCheck = DesugarDeconstructorPatternParameters(isPatternExpr.right as deconstructor_pattern);
|
||||
pattern.const_params_check = constParamCheck;
|
||||
}
|
||||
//AddDefinitionsInUpperStatementList(isPatternExpr, new[] { GetTypeCompatibilityCheck(isPatternExpr) });
|
||||
switch (patternLocation)
|
||||
{
|
||||
case PatternLocation.IfCondition: DesugarIsExpressionInIfCondition(isPatternExpr); break;
|
||||
case PatternLocation.Assign: DesugarIsExpressionInAssignment(isPatternExpr); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -563,6 +611,7 @@ namespace SyntaxVisitors.SugarVisitors
|
|||
|
||||
private void DesugarIsExpressionInAssignment(is_pattern_expr isExpression)
|
||||
{
|
||||
Debug.Assert(isExpression.right is deconstructor_pattern, "Only deconstructor patterns can be used in assignment");
|
||||
var statementsToAdd = ProcessDesugaringForDeconstructorPattern(isExpression);
|
||||
AddDefinitionsInUpperStatementList(isExpression, statementsToAdd);
|
||||
}
|
||||
|
|
@ -576,8 +625,8 @@ namespace SyntaxVisitors.SugarVisitors
|
|||
case deconstructor_pattern dp:
|
||||
if (dp.const_params_check != null)
|
||||
{
|
||||
var ifToAddConstParamsCheck = GetAscendant<if_node>(isExpression);
|
||||
ifToAddConstParamsCheck.condition = bin_expr.LogicalAnd(ifToAddConstParamsCheck.condition, dp.const_params_check);
|
||||
var ifToAddConstParamsCheckTo = GetAscendant<if_node>(isExpression);
|
||||
ifToAddConstParamsCheckTo.condition = bin_expr.LogicalAnd(ifToAddConstParamsCheckTo.condition, dp.const_params_check);
|
||||
}
|
||||
statementsToAdd = ProcessDesugaringForDeconstructorPattern(isExpression);
|
||||
break;
|
||||
|
|
@ -620,10 +669,12 @@ namespace SyntaxVisitors.SugarVisitors
|
|||
private List<statement> ProcessDesugaringForCollectionPattern(is_pattern_expr isExpression)
|
||||
{
|
||||
var pattern = isExpression.right as collection_pattern;
|
||||
var successCheck = DesugarCollectionPattern(pattern, isExpression.left);
|
||||
ReplaceUsingParent(isExpression, successCheck);
|
||||
var desugaringResult = DesugarCollectionPattern(pattern, isExpression.left);
|
||||
ReplaceUsingParent(isExpression, desugaringResult.SuccessMatchingCheck);
|
||||
|
||||
var statementsToAdd = new List<statement>();
|
||||
statementsToAdd.AddRange(desugaringResult.VarParametersDeclarations);
|
||||
//statementsToAdd.AddRange(desugaringResult.VarParametersAssignments);
|
||||
|
||||
return statementsToAdd;
|
||||
}
|
||||
|
|
@ -734,12 +785,12 @@ namespace SyntaxVisitors.SugarVisitors
|
|||
private PatternLocation GetLocation(syntax_tree_node node)
|
||||
{
|
||||
var firstStatement = GetAscendant<statement>(node);
|
||||
|
||||
|
||||
switch (firstStatement)
|
||||
{
|
||||
case if_node _: return PatternLocation.IfCondition;
|
||||
case var_statement _: return PatternLocation.Assign;
|
||||
case assign _ : return PatternLocation.Assign;
|
||||
case assign _: return PatternLocation.Assign;
|
||||
default: return PatternLocation.Unknown;
|
||||
}
|
||||
}
|
||||
|
|
@ -758,7 +809,7 @@ namespace SyntaxVisitors.SugarVisitors
|
|||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private string NewDeconstructParamId()
|
||||
{
|
||||
return GeneratedPatternNamePrefix + "DeconstructParam" + deconstructParamVariableCounter++.ToString();
|
||||
|
|
|
|||
|
|
@ -373,7 +373,7 @@ namespace PascalABCCompiler.TreeConverter
|
|||
public const string is_test_function_name = "__TypeCheckAndAssignForIsMatch";
|
||||
public const string wild_cards_tuple_equal_function_name = "__WildCardsTupleEqual";
|
||||
public const string seq_function_name = "Seq";
|
||||
|
||||
public const string count_property_name = "Count";
|
||||
public static string bounded_array_printable_name_template = "array [{0}..{1}] of {2}";
|
||||
public static string array_printable_name_template = "array of {0}";
|
||||
public static string multi_dim_array_printable_name_template = "array [{0}] of {1}";
|
||||
|
|
|
|||
Loading…
Reference in a new issue