Add pattern desugaring visitor

This commit is contained in:
Alexander Zakharenko 2017-02-12 20:40:59 +03:00
parent 5c11c87960
commit 04940838fa
3 changed files with 61 additions and 0 deletions

View file

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

View file

@ -1691,6 +1691,11 @@ function Dict<TKey, TVal>(params pairs: array of KeyValuePair<TKey, TVal>): Dict
/// Возвращает пару элементов (ключ, значение)
function KV<TKey, TVal>(key: TKey; value: TVal): KeyValuePair<TKey, TVal>;
// -----------------------------------------------------
//>> Вспомогательные функции для pattern matching
// -----------------------------------------------------
function IsTest<T>(obj: object; var res: T): boolean;
//{{{--doc: Конец секции интерфейса для документации }}}
@ -4180,6 +4185,21 @@ begin
Result := new KeyValuePair<TKey, TVal>(key, value);
end;
function IsTest<T>(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;

Binary file not shown.