multiple constant matching
This commit is contained in:
parent
1f9e140730
commit
1d6c0e334a
|
|
@ -3189,7 +3189,7 @@ namespace CodeFormatters
|
|||
|
||||
public override void visit(const_pattern _const_pattern)
|
||||
{
|
||||
visit_node(_const_pattern.pattern_expression);
|
||||
visit_node(_const_pattern.pattern_expressions);
|
||||
add_space_after = false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// This CSharp output file generated by Gardens Point LEX
|
||||
// Version: 1.1.3.301
|
||||
// Machine: DESKTOP-IF20NRO
|
||||
// DateTime: 1/22/2019 9:37:35 AM
|
||||
// DateTime: 1/27/2019 3:56:43 PM
|
||||
// UserName: FatCow
|
||||
// GPLEX input file <ABCPascal.lex>
|
||||
// GPLEX frame file <embedded resource>
|
||||
|
|
|
|||
|
|
@ -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 match_with pattern_case pattern_cases pattern_out_param pattern_out_param_optional_var tuple_pattern_expr_list
|
||||
%type <stn> pattern pattern_optional_var 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
|
||||
%type <ex> const_pattern_expression tuple_pattern tuple_pattern_expr
|
||||
|
||||
|
|
@ -3284,15 +3284,26 @@ pattern_optional_var
|
|||
{
|
||||
$$ = new deconstructor_pattern($3 as List<pattern_deconstructor_parameter>, $1, @$);
|
||||
}
|
||||
| const_pattern_expression
|
||||
| const_pattern_expr_list
|
||||
{
|
||||
$$ = new const_pattern($1, @$);
|
||||
$$ = 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; }
|
||||
: literal_or_number { $$ = $1; }
|
||||
| tuple_pattern { $$ = $1; }
|
||||
;
|
||||
|
||||
tuple_pattern
|
||||
|
|
@ -3311,8 +3322,8 @@ tuple_pattern
|
|||
;
|
||||
|
||||
tuple_pattern_expr
|
||||
: tkQuestion { $$ = null; }
|
||||
| expr_l1 { $$ = $1; }
|
||||
: tkQuestion { $$ = new tuple_wild_card(); }
|
||||
| literal_or_number { $$ = $1; }
|
||||
;
|
||||
|
||||
tuple_pattern_expr_list
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1192,6 +1192,11 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
{
|
||||
DefaultVisit(_const_pattern);
|
||||
}
|
||||
|
||||
public virtual void visit(tuple_wild_card _tuple_wild_card)
|
||||
{
|
||||
DefaultVisit(_tuple_wild_card);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1901,6 +1901,14 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
{
|
||||
}
|
||||
|
||||
public virtual void pre_do_visit(tuple_wild_card _tuple_wild_card)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void post_do_visit(tuple_wild_card _tuple_wild_card)
|
||||
{
|
||||
}
|
||||
|
||||
public override void visit(expression _expression)
|
||||
{
|
||||
DefaultVisit(_expression);
|
||||
|
|
@ -3934,9 +3942,16 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
{
|
||||
DefaultVisit(_const_pattern);
|
||||
pre_do_visit(_const_pattern);
|
||||
visit(const_pattern.pattern_expression);
|
||||
visit(const_pattern.pattern_expressions);
|
||||
post_do_visit(_const_pattern);
|
||||
}
|
||||
|
||||
public override void visit(tuple_wild_card _tuple_wild_card)
|
||||
{
|
||||
DefaultVisit(_tuple_wild_card);
|
||||
pre_do_visit(_tuple_wild_card);
|
||||
post_do_visit(_tuple_wild_card);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -494,6 +494,8 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
return new semantic_check_sugared_var_def_statement_node();
|
||||
case 236:
|
||||
return new const_pattern();
|
||||
case 237:
|
||||
return new tuple_wild_card();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
@ -4188,7 +4190,18 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
public void read_const_pattern(const_pattern _const_pattern)
|
||||
{
|
||||
read_pattern_node(_const_pattern);
|
||||
_const_pattern.pattern_expression = _read_node() as expression;
|
||||
_const_pattern.pattern_expressions = _read_node() as expression_list;
|
||||
}
|
||||
|
||||
|
||||
public void visit(tuple_wild_card _tuple_wild_card)
|
||||
{
|
||||
read_tuple_wild_card(_tuple_wild_card);
|
||||
}
|
||||
|
||||
public void read_tuple_wild_card(tuple_wild_card _tuple_wild_card)
|
||||
{
|
||||
read_expression(_tuple_wild_card);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6584,17 +6584,29 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
public void write_const_pattern(const_pattern _const_pattern)
|
||||
{
|
||||
write_pattern_node(_const_pattern);
|
||||
if (_const_pattern.pattern_expression == null)
|
||||
if (_const_pattern.pattern_expressions == null)
|
||||
{
|
||||
bw.Write((byte)0);
|
||||
}
|
||||
else
|
||||
{
|
||||
bw.Write((byte)1);
|
||||
_const_pattern.pattern_expression.visit(this);
|
||||
_const_pattern.pattern_expressions.visit(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void visit(tuple_wild_card _tuple_wild_card)
|
||||
{
|
||||
bw.Write((Int16)237);
|
||||
write_tuple_wild_card(_tuple_wild_card);
|
||||
}
|
||||
|
||||
public void write_tuple_wild_card(tuple_wild_card _tuple_wild_card)
|
||||
{
|
||||
write_expression(_tuple_wild_card);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -51266,37 +51266,37 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
///<summary>
|
||||
///Конструктор с параметрами.
|
||||
///</summary>
|
||||
public const_pattern(expression _pattern_expression)
|
||||
public const_pattern(expression_list _pattern_expressions)
|
||||
{
|
||||
this._pattern_expression=_pattern_expression;
|
||||
this._pattern_expressions=_pattern_expressions;
|
||||
FillParentsInDirectChilds();
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Конструктор с параметрами.
|
||||
///</summary>
|
||||
public const_pattern(expression _pattern_expression,SourceContext sc)
|
||||
public const_pattern(expression_list _pattern_expressions,SourceContext sc)
|
||||
{
|
||||
this._pattern_expression=_pattern_expression;
|
||||
this._pattern_expressions=_pattern_expressions;
|
||||
source_context = sc;
|
||||
FillParentsInDirectChilds();
|
||||
}
|
||||
protected expression _pattern_expression;
|
||||
protected expression_list _pattern_expressions;
|
||||
|
||||
///<summary>
|
||||
///
|
||||
///</summary>
|
||||
public expression pattern_expression
|
||||
public expression_list pattern_expressions
|
||||
{
|
||||
get
|
||||
{
|
||||
return _pattern_expression;
|
||||
return _pattern_expressions;
|
||||
}
|
||||
set
|
||||
{
|
||||
_pattern_expression=value;
|
||||
if (_pattern_expression != null)
|
||||
_pattern_expression.Parent = this;
|
||||
_pattern_expressions=value;
|
||||
if (_pattern_expressions != null)
|
||||
_pattern_expressions.Parent = this;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -51308,10 +51308,10 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
copy.Parent = this.Parent;
|
||||
if (source_context != null)
|
||||
copy.source_context = new SourceContext(source_context);
|
||||
if (pattern_expression != null)
|
||||
if (pattern_expressions != null)
|
||||
{
|
||||
copy.pattern_expression = (expression)pattern_expression.Clone();
|
||||
copy.pattern_expression.Parent = copy;
|
||||
copy.pattern_expressions = (expression_list)pattern_expressions.Clone();
|
||||
copy.pattern_expressions.Parent = copy;
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
|
@ -51325,15 +51325,15 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
///<summary> Заполняет поля Parent в непосредственных дочерних узлах </summary>
|
||||
public override void FillParentsInDirectChilds()
|
||||
{
|
||||
if (pattern_expression != null)
|
||||
pattern_expression.Parent = this;
|
||||
if (pattern_expressions != null)
|
||||
pattern_expressions.Parent = this;
|
||||
}
|
||||
|
||||
///<summary> Заполняет поля Parent во всем поддереве </summary>
|
||||
public override void FillParentsInAllChilds()
|
||||
{
|
||||
FillParentsInDirectChilds();
|
||||
pattern_expression?.FillParentsInAllChilds();
|
||||
pattern_expressions?.FillParentsInAllChilds();
|
||||
}
|
||||
|
||||
///<summary>
|
||||
|
|
@ -51368,7 +51368,7 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
switch(ind)
|
||||
{
|
||||
case 0:
|
||||
return pattern_expression;
|
||||
return pattern_expressions;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
@ -51379,7 +51379,7 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
switch(ind)
|
||||
{
|
||||
case 0:
|
||||
pattern_expression = (expression)value;
|
||||
pattern_expressions = (expression_list)value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -51397,6 +51397,106 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
}
|
||||
|
||||
|
||||
///<summary>
|
||||
///
|
||||
///</summary>
|
||||
[Serializable]
|
||||
public partial class tuple_wild_card : expression
|
||||
{
|
||||
|
||||
///<summary>
|
||||
///Конструктор без параметров.
|
||||
///</summary>
|
||||
public tuple_wild_card()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary> Создает копию узла </summary>
|
||||
public override syntax_tree_node Clone()
|
||||
{
|
||||
tuple_wild_card copy = new tuple_wild_card();
|
||||
copy.Parent = this.Parent;
|
||||
if (source_context != null)
|
||||
copy.source_context = new SourceContext(source_context);
|
||||
if (attributes != null)
|
||||
{
|
||||
copy.attributes = (attribute_list)attributes.Clone();
|
||||
copy.attributes.Parent = copy;
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
/// <summary> Получает копию данного узла корректного типа </summary>
|
||||
public new tuple_wild_card TypedClone()
|
||||
{
|
||||
return Clone() as tuple_wild_card;
|
||||
}
|
||||
|
||||
///<summary> Заполняет поля Parent в непосредственных дочерних узлах </summary>
|
||||
public override void FillParentsInDirectChilds()
|
||||
{
|
||||
if (attributes != null)
|
||||
attributes.Parent = this;
|
||||
}
|
||||
|
||||
///<summary> Заполняет поля Parent во всем поддереве </summary>
|
||||
public override void FillParentsInAllChilds()
|
||||
{
|
||||
FillParentsInDirectChilds();
|
||||
attributes?.FillParentsInAllChilds();
|
||||
}
|
||||
|
||||
///<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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -393,6 +393,11 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
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()
|
||||
{
|
||||
return string.Format("{0} {2} {1}", left, right, OperatorServices.ToString(operation_type, LanguageId.PascalABCNET));
|
||||
|
|
|
|||
|
|
@ -1426,6 +1426,12 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
///<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_wild_card.
|
||||
///</summary>
|
||||
///<param name="_tuple_wild_card">Node to visit</param>
|
||||
///<returns> Return value is void </returns>
|
||||
void visit(tuple_wild_card _tuple_wild_card);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3057,7 +3057,7 @@
|
|||
</SyntaxNode>
|
||||
<SyntaxNode Name="const_pattern" BaseName="pattern_node">
|
||||
<Fields>
|
||||
<SyntaxField Name="pattern_expression" SyntaxType="expression" />
|
||||
<SyntaxField Name="pattern_expressions" SyntaxType="expression_list" />
|
||||
</Fields>
|
||||
<Methods />
|
||||
<Tags>
|
||||
|
|
@ -3069,6 +3069,14 @@
|
|||
</TagIndices>
|
||||
</Tags>
|
||||
</SyntaxNode>
|
||||
<SyntaxNode Name="tuple_wild_card" BaseName="expression">
|
||||
<Fields />
|
||||
<Methods />
|
||||
<Tags>
|
||||
<CategoryIndices />
|
||||
<TagIndices />
|
||||
</Tags>
|
||||
</SyntaxNode>
|
||||
</SyntaxNodes>
|
||||
<Settings>
|
||||
<FileName>Tree.cs</FileName>
|
||||
|
|
@ -3373,6 +3381,7 @@
|
|||
<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="constructor" 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="" />
|
||||
|
|
@ -4296,6 +4305,7 @@
|
|||
<HelpData Key="tuple_node.el" Value="" />
|
||||
<HelpData Key="tuple_node_for_formatter" Value="" />
|
||||
<HelpData Key="tuple_node_for_formatter.el" Value="" />
|
||||
<HelpData Key="tuple_wild_card" 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, SourceContext sc): this(new ident(name),type,sc)" Value="" />
|
||||
|
|
|
|||
|
|
@ -159,20 +159,33 @@ namespace SyntaxVisitors.SugarVisitors
|
|||
void DesugarConstPatternCase(expression matchingExpression, pattern_case patternCase)
|
||||
{
|
||||
Debug.Assert(patternCase.pattern is const_pattern);
|
||||
var patternExpressionNode = patternCase.pattern as const_pattern;
|
||||
//var tuple_pattern_case = patternExpressionNode.pattern_expression as method_call;
|
||||
|
||||
var eqParams = new expression_list(
|
||||
new List<expression>()
|
||||
{
|
||||
var equalCalls = new List<method_call>();
|
||||
foreach (var patternExpression in patternExpressionNode.pattern_expressions.expressions)
|
||||
{
|
||||
var eqParams = new expression_list(
|
||||
new List<expression>()
|
||||
{
|
||||
matchingExpression,
|
||||
(patternCase.pattern as const_pattern).pattern_expression
|
||||
}
|
||||
);
|
||||
var equalsCallNode = new method_call(
|
||||
new dot_node(new ident("object"), new ident("Equals")),
|
||||
eqParams,
|
||||
patternCase.source_context);
|
||||
|
||||
var ifCondition = patternCase.condition == null ? (expression)equalsCallNode : bin_expr.LogicalAnd(equalsCallNode, patternCase.condition);
|
||||
patternExpression
|
||||
}
|
||||
);
|
||||
equalCalls.Add(
|
||||
new method_call(
|
||||
new dot_node(new ident("object"), new ident("Equals")),
|
||||
eqParams,
|
||||
patternCase.source_context
|
||||
)
|
||||
);
|
||||
}
|
||||
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 в результат
|
||||
|
|
|
|||
Loading…
Reference in a new issue