pascalabcnet/AdditionalLanguages/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/GeneratorObjectDesugarVisitor.cs
Александр Земляк 17f6a9b956
Spython test suite (#3362)
* Reorganize files in TestSuite dir for multiple languages

* Add SPython samples to TestSuite

* Update TestRunner to support multiple languages

* Delete dll files accidentally pushed

* Update .gitignore

* Revert "Delete dll files accidentally pushed"

This reverts commit 62bcba2b821d58ae51ec98e9dadcf621bb0fc003.

* Update testing dir path in Testing.cs

* Improve TestRunner output

* Add random module and it's usage sample

* Reorganize gitignore files

* Move pascal tests back to TestSuite and create new TestSuiteLanguagePlugins folder for SPython

* Revert "Update testing dir path in Testing.cs"

This reverts commit 7d94eafb25292421bce8315520b4f6a0de001bbd.

* Revert crlf changes in pascal tests

* Test changes of _RebuildReleaseAndRunTestsForGitHubActions.bat

* Revert "Test changes of _RebuildReleaseAndRunTestsForGitHubActions.bat"

This reverts commit 234ceae3e3a339fbc68a6170e2bd201dab14d67d.

* Test changes in StorageLocationPicker

* Another test changes in StorageLocationPicker.cs

* Rename LanguagePlugins folder to AdditionalLanguages

* Decouple TestRunner from language names and parameters

* Revert calling TestRunner without parameters in .bat files

* Fix formatter tests nogui exception handling

* Small refactoring in Testing.cs and TestRunner fix of working directory
2025-12-21 21:11:52 +03:00

105 lines
4.7 KiB
C#

using PascalABCCompiler;
using PascalABCCompiler.SyntaxTree;
using System.Collections.Generic;
namespace Languages.SPython.Frontend.Converters
{
internal class GeneratorObjectDesugarVisitor : BaseChangeVisitor
{
private ParserLambdaHelper lambdaHelper = new ParserLambdaHelper();
private syntax_tree_node root;
private bool replaceRoot = false;
private syntax_tree_node lastDesugaredNode = null;
public GeneratorObjectDesugarVisitor(syntax_tree_node root)
{
this.root = root;
}
public syntax_tree_node UpdatedRoot()
{
if (replaceRoot) return lastDesugaredNode;
return root;
}
public override void visit(generator_object _generator_object)
{
base.visit(_generator_object);
dot_node dn;
ident_list idList;
formal_parameters formalPars;
statement_list sl;
function_lambda_definition lambda;
method_call mc;
// [ expr1 for ident in expr2 if expr3 ] -> expr2.Where(ident -> expr3).Select(ident -> expr1)
if (_generator_object._condition != null)
{
string ident_name = _generator_object._ident.name;
idList = new ident_list(new ident(ident_name), _generator_object._ident.source_context);
formalPars = new formal_parameters(new typed_parameters(idList, new lambda_inferred_type(new lambda_any_type_node_syntax(), _generator_object._ident.source_context), parametr_kind.none, null, _generator_object._ident.source_context), _generator_object._ident.source_context);
dn = new dot_node(_generator_object._range as addressed_value, (new ident("Where")) as addressed_value, _generator_object.source_context);
sl = new statement_list(new assign(StringConstants.result_var_name, _generator_object._condition, _generator_object._condition.source_context), _generator_object._condition.source_context); //!
sl.expr_lambda_body = true;
lambda = new function_lambda_definition(
lambdaHelper.CreateLambdaName(), formalPars,
new lambda_inferred_type(new lambda_any_type_node_syntax(), _generator_object._ident.source_context), sl, _generator_object.source_context);
mc = new method_call(dn as addressed_value, new expression_list(lambda as expression), _generator_object.source_context);
dn = new dot_node(mc as addressed_value, (new ident("Select")) as addressed_value, _generator_object.source_context);
}
// [ expr1 for ident in expr2 ] -> expr2.Select(ident -> expr1)
else
dn = new dot_node(_generator_object._range as addressed_value, (new ident("Select")) as addressed_value, _generator_object.source_context);
idList = new ident_list(_generator_object._ident, _generator_object._ident.source_context);
formalPars = new formal_parameters(new typed_parameters(idList, new lambda_inferred_type(new lambda_any_type_node_syntax(), _generator_object._ident.source_context), parametr_kind.none, null, _generator_object._ident.source_context), _generator_object._ident.source_context);
sl = new statement_list(new assign(StringConstants.result_var_name, _generator_object._expr, _generator_object._expr.source_context), _generator_object._expr.source_context);
sl.expr_lambda_body = true;
lambda = new function_lambda_definition(
lambdaHelper.CreateLambdaName(), formalPars,
new lambda_inferred_type(new lambda_any_type_node_syntax(), _generator_object._ident.source_context), sl, _generator_object.source_context);
method_call replaceTo = new method_call(dn as addressed_value, new expression_list(lambda as expression), _generator_object.source_context);
if (root != _generator_object)
Replace(_generator_object, replaceTo);
else
{
replaceRoot = true;
lastDesugaredNode = replaceTo;
}
}
}
public class ParserLambdaHelper
{
private int lambda_num = 0;
public List<function_lambda_definition> lambdaDefinitions;
public static string lambdaPrefix = "<>lambda";
public ParserLambdaHelper()
{
lambdaDefinitions = new List<function_lambda_definition>();
}
public string CreateLambdaName()
{
lambda_num++;
return lambdaPrefix + lambda_num.ToString();
}
public bool IsLambdaName(ident id)
{
return id.name.StartsWith(lambdaPrefix);
}
}
}