Fix #872
This commit is contained in:
parent
f5e5a56cfc
commit
21301a8fb4
|
|
@ -33,6 +33,8 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
DirectDescendants
|
||||
}
|
||||
|
||||
public enum SugaredExpressionType { MatchedExpression }
|
||||
|
||||
public partial class syntax_tree_node
|
||||
{
|
||||
|
||||
|
|
|
|||
|
|
@ -111,8 +111,9 @@ namespace SyntaxVisitors.SugarVisitors
|
|||
|
||||
public override void visit(is_pattern_expr isPatternExpr)
|
||||
{
|
||||
// TODO Patterns: convert to compilation error
|
||||
Debug.Assert(GetLocation(isPatternExpr) != PatternLocation.Unknown, "Is-pattern expression is in an unknown context");
|
||||
if (GetLocation(isPatternExpr) == PatternLocation.Unknown)
|
||||
throw new SyntaxVisitorError("PATTERN_MATHING_IS_NOT_SUPPORTED_IN_THIS_CONTEXT", isPatternExpr.source_context);
|
||||
|
||||
Debug.Assert(GetAscendant<statement_list>(isPatternExpr) != null, "Couldn't find statement list in upper nodes");
|
||||
|
||||
DesugarIsExpression(isPatternExpr);
|
||||
|
|
@ -235,6 +236,7 @@ namespace SyntaxVisitors.SugarVisitors
|
|||
ReplaceUsingParent(isExpression, desugaringResult.SuccessVariable);
|
||||
|
||||
var statementsToAdd = desugaringResult.GetDeconstructionDefinitions(pattern.source_context);
|
||||
statementsToAdd.Add(GetMatchedExpressionCheck(isExpression.left));
|
||||
statementsToAdd.Add(desugaringResult.GetPatternCheckWithDeconstrunctorCall());
|
||||
|
||||
AddDefinitionsInUpperStatementList(isExpression, statementsToAdd);
|
||||
|
|
@ -247,11 +249,12 @@ namespace SyntaxVisitors.SugarVisitors
|
|||
ReplaceUsingParent(isExpression, desugaringResult.SuccessVariable);
|
||||
|
||||
var statementsToAdd = desugaringResult.GetDeconstructionDefinitions(pattern.source_context);
|
||||
statementsToAdd.Add(GetMatchedExpressionCheck(isExpression.left));
|
||||
statementsToAdd.Add(desugaringResult.GetPatternCheckWithDeconstrunctorCall());
|
||||
|
||||
var enclosingIf = GetAscendant<if_node>(isExpression);
|
||||
// Если уже обрабатывался ранее (второй встретившийся в том же условии is), то не изменяем if
|
||||
if (processedIfNodes.Contains(enclosingIf))
|
||||
if (processedIfNodes.Contains(enclosingIf))
|
||||
AddDefinitionsInUpperStatementList(isExpression, statementsToAdd);
|
||||
// Иначе помещаем определения и if-then в отдельный блок, а else после этого блока
|
||||
else
|
||||
|
|
@ -267,6 +270,9 @@ namespace SyntaxVisitors.SugarVisitors
|
|||
}
|
||||
}
|
||||
|
||||
private semantic_check_sugared_statement_node GetMatchedExpressionCheck(expression matchedExpression)
|
||||
=> new semantic_check_sugared_statement_node(SugaredExpressionType.MatchedExpression, new List<syntax_tree_node>() { matchedExpression });
|
||||
|
||||
private statement_list ConvertIfNode(if_node ifNode, List<statement> statementsBeforeIf, out statement elseBody)
|
||||
{
|
||||
// if e then <then> else <else>
|
||||
|
|
|
|||
|
|
@ -211,5 +211,16 @@ namespace PascalABCCompiler.TreeConverter
|
|||
if (parameter.parameter_type != SemanticTree.parameter_type.var && parameter is common_parameter p)
|
||||
AddError(p.loc, "DECONSTRUCTION_PARAMETERS_SHOULD_HAVE_VAR_MODIFIER");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Проверяет выражение, сопоставляемое с образцом
|
||||
/// </summary>
|
||||
/// <param name="matchedExpression"></param>
|
||||
private void CheckMatchedExpression(expression matchedExpression)
|
||||
{
|
||||
var convertedExpression = convert_strong(matchedExpression);
|
||||
if (convertedExpression.type.IsPointer)
|
||||
AddError(get_location(matchedExpression), "PATTERN_MATCHING_DOESNT_SUPPORT_POINTERS");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12276,8 +12276,7 @@ namespace PascalABCCompiler.TreeConverter
|
|||
commonNode.name.ToLower() == compiler_string_consts.deconstruct_method_name)
|
||||
{
|
||||
var deconstructor = commonNode;
|
||||
|
||||
// TODO Patterns: add warning for non-extension deconstruct
|
||||
|
||||
if (!deconstructor.is_extension_method)
|
||||
{
|
||||
//AddWarning();
|
||||
|
|
@ -19413,6 +19412,13 @@ namespace PascalABCCompiler.TreeConverter
|
|||
var expr = st.lst[0] as SyntaxTree.expression;
|
||||
semantic_check_loop_stmt(expr);
|
||||
}
|
||||
// Patterns
|
||||
else if (st.typ is SugaredExpressionType.MatchedExpression)
|
||||
{
|
||||
var expr = st.lst[0] as expression;
|
||||
CheckMatchedExpression(expr);
|
||||
}
|
||||
// !Patterns
|
||||
else
|
||||
{
|
||||
AddError(get_location(st), "MISSED_SEMANTIC_CHECK_FOR_SUGARED_NODE_{0}", (st.typ as System.Type)?.Name??"Unknown");
|
||||
|
|
|
|||
Loading…
Reference in a new issue