This commit is contained in:
Александр Погорелов 2019-05-25 12:30:15 +03:00
parent 0eabf5a39e
commit 4f9ebdb5ae
10 changed files with 2696 additions and 2570 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: 5/25/2019 9:19:01 AM
// DateTime: 5/25/2019 12:15:20 PM
// UserName: FatCow
// GPLEX input file <ABCPascal.lex>
// GPLEX frame file <embedded resource>

View file

@ -58,7 +58,7 @@
%type <stn> attribute_declarations
%type <stn> ot_visibility_specifier
%type <stn> one_attribute attribute_variable
%type <ex> const_factor const_variable_2 const_term const_variable literal_or_number unsigned_number variable_or_literal_or_number
%type <ex> const_factor const_variable_2 const_term const_variable const_pattern_variable const_pattern_variable_2 literal_or_number unsigned_number variable_or_literal_or_number
%type <stn> program_block
%type <ob> optional_var class_attribute class_attributes class_attributes1
%type <stn> member_list_section optional_component_list_seq_end
@ -3414,7 +3414,7 @@ const_pattern_expr_list
const_pattern_expression
: literal_or_number { $$ = $1; }
| identifier { $$ = $1; }
| const_pattern_variable { $$ = $1; }
| tkNil
{
$$ = new nil_const();
@ -3422,6 +3422,39 @@ const_pattern_expression
}
;
const_pattern_variable
: identifier
{ $$ = $1; }
| sizeof_expr
{ $$ = $1; }
| typeof_expr
{ $$ = $1; }
| const_pattern_variable const_pattern_variable_2
{
$$ = NewConstVariable($1, $2, @$);
}
| const_pattern_variable tkAmpersend template_type_params
{
$$ = new ident_with_templateparams($1 as addressed_value, $3 as template_param_list, @$);
}
;
const_pattern_variable_2
: tkPoint identifier_or_keyword
{
$$ = new dot_node(null, $2 as addressed_value, @$);
}
| tkDeref
{
$$ = new roof_dereference();
$$.source_context = @$;
}
| tkSquareOpen const_elem_list tkSquareClose
{
$$ = new indexer($2 as expression_list, @$);
}
;
tuple_pattern
: tkRoundOpen tuple_pattern_item_list tkRoundClose
{

File diff suppressed because it is too large Load diff

View file

@ -285,25 +285,14 @@ namespace SyntaxVisitors.SugarVisitors
var patternExpressionNode = patternCase.pattern as const_pattern;
var statementsToAdd = new List<statement>();
var equalCalls = new List<method_call>();
var equalCalls = new List<bin_expr>();
foreach (var patternExpression in patternExpressionNode.pattern_expressions.expressions)
{
statementsToAdd.Add(GetTypeCompatibilityCheck(matchingExpression, patternExpression));
// Matching not tuples
var eqParams = new expression_list(
new List<expression>()
{
matchingExpression,
patternExpression
}
);
equalCalls.Add(
new method_call(
new dot_node(new ident("object"), new ident("Equals")),
eqParams,
patternCase.source_context
new bin_expr(matchingExpression, patternExpression, Operators.Equal, patternCase.source_context
)
);
}
@ -355,7 +344,7 @@ namespace SyntaxVisitors.SugarVisitors
);
equalChecks = equalChecks == null ? (expression)equalCall : bin_expr.LogicalAnd(equalChecks, equalCall);
desugaringResult.ElemTypeChecks.Add(GetTypeCompatibilityCheck(constParam.const_param, indexerCall));
desugaringResult.ElemTypeChecks.Add(GetTypeCompatibilityCheck(indexerCall, constParam.const_param));
}
if (param is collection_pattern_var_parameter varParam)
@ -410,7 +399,7 @@ namespace SyntaxVisitors.SugarVisitors
);
equalChecks = equalChecks == null ? (expression)equalCall : bin_expr.LogicalAnd(equalChecks, equalCall);
desugaringResult.ElemTypeChecks.Add(GetTypeCompatibilityCheck(constParam.const_param, indexerCall));
desugaringResult.ElemTypeChecks.Add(GetTypeCompatibilityCheck(indexerCall, constParam.const_param));
}
if (param is collection_pattern_var_parameter varParam)
@ -603,7 +592,7 @@ namespace SyntaxVisitors.SugarVisitors
desugaringResult.SuccessMatchingCheck = desugaringResult.SuccessMatchingCheck == null ?
(expression)equalCall :
bin_expr.LogicalAnd(desugaringResult.SuccessMatchingCheck, equalCall);
desugaringResult.ElemTypeChecks.Add(GetTypeCompatibilityCheck(constParam.const_param, tupleItemCall));
desugaringResult.ElemTypeChecks.Add(GetTypeCompatibilityCheck(tupleItemCall, constParam.const_param));
}
}

View file

@ -0,0 +1,8 @@
begin
var l: List<integer>;
match l with
nil: assert(true);
else
assert(false);
end;
end.

View file

@ -0,0 +1,9 @@
begin
var l: byte;
l := 1;
match l with
1: assert(true);
else
assert(false);
end;
end.

View file

@ -0,0 +1,7 @@
begin
var l: (A, B, C);
match l with
l.B: assert(false);
l.A: assert(true);
end;
end.

View file

@ -0,0 +1,10 @@
const c = 2;
begin
var l := 2;
match l with
c: assert(true);
else
assert(false);
end;
end.

View file

@ -0,0 +1,9 @@
begin
var l: ^integer;
l := nil;
match l with
nil: assert(true);
else
assert(false);
end;
end.

View file

@ -266,23 +266,28 @@ namespace PascalABCCompiler.TreeConverter
{
var patternNode = convert_strong(patternExpression);
var patternType = patternNode.type;
var expressionType = convert_strong(matchedExpression).type;
var expressionNode = convert_strong(matchedExpression);
var expressionType = expressionNode.type;
if ((patternExpression is ident) && !(patternNode is constant_node))
if (!(patternNode is constant_node))
{
AddError(get_location(patternExpression), "MATCHING_WITH_NON_CONST");
}
var possible_convertion = type_table.get_convertions(patternType, expressionType);
var expressionTypeName = expressionType.BaseFullName;
var patternTypeName = patternType.BaseFullName;
var tupleName = "System.Tuple";
if (type_table.is_derived(patternType, expressionType) ||
type_table.is_derived(expressionType, patternType) ||
possible_convertion.first != null ||
AreTheSameType(patternType, expressionType) ||
(expressionTypeName.StartsWith(tupleName) &&
patternTypeName.StartsWith(tupleName) &&
int.Parse(expressionTypeName.Substring(tupleName.Length + 1, 1)) ==
int.Parse(patternTypeName.Substring(tupleName.Length + 1, 1))))
int.Parse(patternTypeName.Substring(tupleName.Length + 1, 1))) ||
(expressionType.IsPointer && patternNode is null_const_node) ||
(patternType.IsPointer && expressionNode is null_const_node))
return;
AddError(get_location(matchedExpression), "EXPRESSION_OF_TYPE_{0}_CANNOT_BE_MATCHED_AGAINST_PATTERN_WITH_TYPE_{1}", expressionType.name, patternType.name);