pascalabcnet/AdditionalLanguages/SPython/SyntaxTreeConverters/SPythonStandardTreeConverter/RetainUsedGlobalVariablesVisitor.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

79 lines
2.7 KiB
C#

using PascalABCCompiler.SyntaxTree;
using System.Collections.Generic;
namespace Languages.SPython.Frontend.Converters
{
public class RetainUsedGlobalVariablesVisitor : BaseChangeVisitor
{
private HashSet<string> variablesUsedAsGlobal = new HashSet<string>();
private int scopeCounter = 0;
private declarations decls;
private bool isUnitCompiled = false;
public RetainUsedGlobalVariablesVisitor(HashSet<string> variablesUsedAsGlobal)
{
this.variablesUsedAsGlobal = variablesUsedAsGlobal;
}
// нужны методы из BaseChangeVisitor, но порядок обхода из WalkingVisitorNew
public override void DefaultVisit(syntax_tree_node n)
{
for (var i = 0; i < n.subnodes_count; i++)
ProcessNode(n[i]);
}
public override void Enter(syntax_tree_node stn)
{
if (stn is statement_list)
{
scopeCounter++;
}
if (stn is program_module pm)
{
decls = pm.program_block.defs;
}
if (stn is interface_node intn)
{
isUnitCompiled = true;
decls = intn.interface_definitions;
}
base.Enter(stn);
}
public override void Exit(syntax_tree_node stn)
{
if (stn is statement_list)
{
scopeCounter--;
}
base.Exit(stn);
}
public override void visit(var_statement _var_statement)
{
ident id = _var_statement.var_def.vars.idents[0];
if (scopeCounter == 1 && (isUnitCompiled || variablesUsedAsGlobal.Contains(id.name)))
{
//variablesUsedAsGlobal.Remove(id.name);
SourceContext sc = _var_statement.source_context;
statement replace_to = new empty_statement();
type_definition td = _var_statement.var_def.vars_type;
if (_var_statement.var_def.inital_value != null)
{
replace_to = new assign(id, _var_statement.var_def.inital_value, sc);
}
if (td == null)
{
(replace_to as assign).first_assignment_defines_type = true;
td = new named_type_reference(new ident("integer"));
}
var vds = new var_def_statement(new ident_list(id, id.source_context), td, null, definition_attribute.None, false, sc);
decls.Add(new variable_definitions(vds, sc), sc);
ReplaceStatement(_var_statement, replace_to);
}
}
}
}