This commit is contained in:
Alexander Zakharenko 2018-06-17 14:21:52 +03:00
parent f5e5a56cfc
commit 21301a8fb4
4 changed files with 30 additions and 5 deletions

View file

@ -33,6 +33,8 @@ namespace PascalABCCompiler.SyntaxTree
DirectDescendants
}
public enum SugaredExpressionType { MatchedExpression }
public partial class syntax_tree_node
{

View file

@ -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>

View file

@ -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");
}
}
}

View file

@ -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");