Add common deconstruct procedure to PABCSystem

This commit is contained in:
Alexander Zakharenko 2018-05-05 12:31:48 +03:00
parent 17cb96a479
commit ed621517f3
5 changed files with 75 additions and 4 deletions

View file

@ -0,0 +1,21 @@
// Source
match e with
Person(var value): <ACTION>
end;
// Desugared code
var <>genVar: Person;
if IsTest(e, <>genVar) then
begin
// always the same code
var value: ?; // should be filled during semantic analysis
<>genVar.Deconstruct(value);
<ACTION>
end;
{
info we need to fill the tree:
1. Syntactic nodes of parameters' types
}

45
Patterns/Desugaring.pas Normal file
View file

@ -0,0 +1,45 @@
// Source
match e with
Person(var value): <ACTION>
end;
// Desugared code
var <>genVar: Person;
if IsTest(e, <>genVar) then
begin
// one of 3 cases
// *********************************************************
// 1 - instance deconstruct
var value: ?; // should be filled during semantic analysis
<>genVar.Deconstruct(value);
// 2 - extension deconstruct
var value: ?; // should be filled during semantic analysis
PersonExt.Deconstruct(<>genVar, value);
// 3 - typecast - when there's only one deconstruction parameter and no Deconstruct methods were found
var value := <>genVar;
// *********************************************************
<ACTION>
end;
{
info we need to fill the tree:
1. Method type (instance or static) and a qualifier if static
2. Syntactic nodes of parameters' types
General: how to get the type of expression
case 1:
How to check if a certain type has instance method with given name - option 1
Save information about all Deconstruct methods during creation of a semantic tree - option 2
case 2:
}

View file

@ -88,9 +88,9 @@ namespace PascalABCCompiler.SyntaxTree
/// </summary>
/// <param name="from">Исходное значение</param>
/// <param name="to">Новое значение</param>
public void RenameIdentifierInDescendants(string from, string to)
public void RenameIdentifierInDescendants(string from, string to, bool includingThis = true)
{
foreach (var identifier in DescendantNodes().OfType<ident>().Where(x => x.name == from))
foreach (var identifier in DescendantNodes(TraversalType.PostOrder, null, includingThis).OfType<ident>().Where(x => x.name == from))
identifier.name = to;
}

View file

@ -19318,4 +19318,4 @@ namespace PascalABCCompiler.TreeConverter
}
}
}

View file

@ -1843,6 +1843,7 @@ function KV<TKey, TVal>(key: TKey; value: TVal): KeyValuePair<TKey, TVal>;
// -----------------------------------------------------
//>> Вспомогательные функции для pattern matching
// -----------------------------------------------------
function IsTest<T>(obj: object; var res: T): boolean;
//{{{--doc: Конец секции интерфейса для документации }}}
@ -4205,7 +4206,6 @@ begin
Result := new KeyValuePair<TKey, TVal>(key, value);
end;
function IsTest<T>(obj: object; var res: T): boolean;
begin
if obj is T then
@ -4220,6 +4220,11 @@ begin
end;
end;
procedure Deconstruct<T>(self: T; var res: T); extensionmethod;
begin
res := self;
end;
{function read_lexem: string;
var
c: char;