diff --git a/SyntaxVisitors/SugarVisitors/IsPatternVisitor.cs b/SyntaxVisitors/SugarVisitors/IsPatternVisitor.cs new file mode 100644 index 000000000..0e0f97df9 --- /dev/null +++ b/SyntaxVisitors/SugarVisitors/IsPatternVisitor.cs @@ -0,0 +1,41 @@ +using PascalABCCompiler.SyntaxTree; +using PascalABCCompiler.TreeConversion; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace SyntaxVisitors.SugarVisitors +{ + public class IsPatternVisitor : BaseChangeVisitor + { + public static IsPatternVisitor New => new IsPatternVisitor(); + + public override void visit(is_pattern_expr isPatternExpr) + { + if (isPatternExpr.right is type_pattern) + DesugarTypePattern(isPatternExpr); + } + + void DesugarTypePattern(is_pattern_expr isPatternExpr) + { + // Замена is_pattern на вызов вспомогательной функции PABCSystem.IsTest + expression expression = isPatternExpr.left; + type_pattern pattern = isPatternExpr.right as type_pattern; + var isTestFunc = SubtreeCreator.CreateSystemFunctionCall("IsTest", expression, pattern.identifier); + ReplaceUsingParent(isPatternExpr, isTestFunc); + + // Объявление переменной в ближайшем statement_list + for (int i = listNodes.Count - 1; i >= 0; i--) + { + var statements = listNodes[i] as statement_list; + if (statements != null) + { + statements.InsertBefore( + listNodes[i + 1] as statement, + new var_statement(pattern.identifier, pattern.type)); + } + } + } + } +} diff --git a/TestSuite/CompilationSamples/PABCSystem.pas b/TestSuite/CompilationSamples/PABCSystem.pas index f2912fc37..1407e71eb 100644 --- a/TestSuite/CompilationSamples/PABCSystem.pas +++ b/TestSuite/CompilationSamples/PABCSystem.pas @@ -1691,6 +1691,11 @@ function Dict(params pairs: array of KeyValuePair): Dict /// Возвращает пару элементов (ключ, значение) function KV(key: TKey; value: TVal): KeyValuePair; +// ----------------------------------------------------- +//>> Вспомогательные функции для pattern matching +// ----------------------------------------------------- +function IsTest(obj: object; var res: T): boolean; + //{{{--doc: Конец секции интерфейса для документации }}} @@ -4180,6 +4185,21 @@ begin Result := new KeyValuePair(key, value); end; + +function IsTest(obj: object; var res: T): boolean; +begin + if obj is T then + begin + res := T(obj); + Result := true; + end + else + begin + res := default(T); + Result := false; + end; +end; + {function read_lexem: string; var c: char; diff --git a/bin/Lib/PABCRtl.dll b/bin/Lib/PABCRtl.dll index 0d135b58a..1e80d81dd 100644 Binary files a/bin/Lib/PABCRtl.dll and b/bin/Lib/PABCRtl.dll differ