pascalabcnet/TreeConverter/OpenMP/OpenMP.cs

2270 lines
116 KiB
C#
Raw Normal View History

// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt)
2015-06-01 22:15:17 +03:00
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
2015-05-14 22:35:07 +03:00
using System.Collections.Generic;
using System.Text;
using PascalABCCompiler.TreeRealization;
using System.Collections;
namespace PascalABCCompiler.TreeConverter
{
class OpenMPException : Exception
{
string msg;
public SyntaxTree.SourceContext SC;
public OpenMPException(string message)
{
msg = message;
}
public OpenMPException(string message, SyntaxTree.SourceContext source_context)
{
msg = message;
SC = source_context;
}
public override string ToString()
{
return msg;
}
}
class StackLoopVariables
{
Stack<string> names = new Stack<string>();
public StackLoopVariables()
{ }
public StackLoopVariables(string var_name)
{
Push(var_name);
}
public void Push(string var_name)
{
names.Push(var_name);
}
public string Pop()
{
return names.Pop();
}
public bool Contains(string var_name)
{
return names.Contains(var_name);
}
public void Clear()
{ names.Clear(); }
}
class ReductionDirective
{
public ReductionOperations Oper;
public List<string> variables = new List<string>();
}
class VarInfoContainer
{
public List<SemanticTree.IConstantDefinitionNode> Constants =
new List<SemanticTree.IConstantDefinitionNode>();
public List<SemanticTree.IVAriableDefinitionNode> SharedVariables =
new List<SemanticTree.IVAriableDefinitionNode>();
public List<SemanticTree.IVAriableDefinitionNode> PrivateVariables =
new List<SemanticTree.IVAriableDefinitionNode>();
public List<SemanticTree.IVAriableDefinitionNode> ReductionVariables =
new List<SemanticTree.IVAriableDefinitionNode>();
public List<ReductionOperations> ReductionActions = new List<ReductionOperations>();
public void UnionWith(VarInfoContainer container)
{
foreach (SemanticTree.IConstantDefinitionNode node in container.Constants)
if (!Constants.Contains(node))
Constants.Add(node);
foreach (SemanticTree.IVAriableDefinitionNode node in container.SharedVariables)
if (!SharedVariables.Contains(node))
SharedVariables.Add(node);
foreach (SemanticTree.IVAriableDefinitionNode node in container.PrivateVariables)
if (!PrivateVariables.Contains(node))
PrivateVariables.Add(node);
for (int i = 0; i < container.ReductionVariables.Count; ++i )
if (!ReductionVariables.Contains(container.ReductionVariables[i]))
{
ReductionVariables.Add(container.ReductionVariables[i]);
ReductionActions.Add(container.ReductionActions[i]);
}
}
}
class ContextInfo
{
public ContextInfo(syntax_tree_visitor syntax_tree_visitor)
{
SaveContext(syntax_tree_visitor);
}
public common_type_node converted_type;
public statement_list_stack statement_list_stack;
public SemanticTree.field_access_level curr_fal;
public List<var_definition_node> current_var_defs;
public Stack<code_block> block_stack;
public statement_node_stack cycle_stack;
public Hashtable current_member_decls;
public common_function_node_stack function_node_stack;
public SymbolInfo current_last_created_function;
2015-05-14 22:35:07 +03:00
public bool SemanticRulesThrowErrorWithoutSave;
public void SaveContext(syntax_tree_visitor syntax_tree_visitor)
{
converted_type = syntax_tree_visitor.context.converted_type;
syntax_tree_visitor.context.converted_type = null;
statement_list_stack = syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack;
syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack = new statement_list_stack();
curr_fal = syntax_tree_visitor.context.get_field_access_level();
current_var_defs = syntax_tree_visitor.context.var_defs;
syntax_tree_visitor.context.var_defs = new List<var_definition_node>();
block_stack = syntax_tree_visitor.context.block_stack;
syntax_tree_visitor.context.block_stack = new Stack<code_block>();
cycle_stack = syntax_tree_visitor.context.CyclesStack;
syntax_tree_visitor.context.CyclesStack = new statement_node_stack();
current_member_decls = syntax_tree_visitor.context.member_decls;
syntax_tree_visitor.context.member_decls = new Hashtable();
function_node_stack = syntax_tree_visitor.context.func_stack;
syntax_tree_visitor.context.func_stack = new common_function_node_stack();
current_last_created_function = syntax_tree_visitor.context.last_created_function;
New languages engine (#3120) * Implement first version of languages interfaces and classes ParsersController заменен на LanguageProvider. * Update ParserTools.csproj * Update RemoteCompiler.cs * Update TestRunner * Rename LanguageIntegrator project to Languages * Update TestRunner * Rename Parsers folder * Rename PascalABCParser.dll to PascalABCLanguage.dll * Reorganise LanguageIntegrator and rename DocTagsParser * Update Release Generators * Update language loading messages * Update linux version * Move BaseParser fields to ILanguage interface * Revert "Update Release Generators" This reverts commit 26a991c71b81e643d9fbd9a815ddca222768dda9. * Revert "Rename PascalABCParser.dll to PascalABCLanguage.dll" * Clean the mess in parser folders * Organize namespaces properly * Revert "Rename LanguageIntegrator project to Languages" * Add new enclosing folders for standard languages * Organize namespaces of LanguageIntegrator properly * Rename StandardLanguages to Languages * Comment the rest of Visual basic source code * Update OutputPath in pascal parser project * Move BaseParser methods to IParser * Restore Pascal parser project initial structure * Add PascalLanguage project * Move SyntaxTreeConverters project to Languages\Pascal folder * Rename SemanticRules in parser project * Rename Errors1 to Errors in parser project * Delete LambdaConverter dll from installer * Update language integrator to load *Language.dll files * Move lambda converter project to pascal lanuage dir * Revert "Delete LambdaConverter dll from installer" This reverts commit dd56f559ebe4f8c4c5c33752d44e6953001b96a5. * Switch off VBNETParser building * Delete syntax tree converters controller * Delete lambda converter dll from repository * Reorganize syntax tree to semantic tree conversion stage * Add BaseLanguage class to make language initialization more neat * Delete syntax tree post processors entity from ILanguage and refactor ABCStatistics calls * Add new IDocParser interface for documentation comments parser * Clean up folders * Add helper data structures to reduce parameters amount in CompileInterface and CompileImplementation * Add documentation to language classes * Move Union struct in global namespace and project (ParserTools) * Add more comments and a safe select language method * Rename SemanticRules class * Fix directives format null bug * Add System.Linq ref to LanguageIntegrator * Delete SyntaxToSemanticTreeConverter interface * Add BaseSyntaxTreeConverter * Call safe select language method in intellisence * Delete source files providers from parsers * Rename GetSyntaxTree method * Change Prebuild tree to be virtual - not abstract * Refresh documentation a bit * Add temporary language check for ABCHealth button * Add parser reference to parser tools * Move current compilation unit assigning higher to avoid bug with unit check * Delete null DirectiveInfo's and refactor directives' code * Add a few more comments
2024-05-25 12:26:32 +03:00
SemanticRulesThrowErrorWithoutSave = SemanticRulesConstants.ThrowErrorWithoutSave;
SemanticRulesConstants.ThrowErrorWithoutSave = true;
2015-05-14 22:35:07 +03:00
}
public void RestoreContext(syntax_tree_visitor syntax_tree_visitor)
{
New languages engine (#3120) * Implement first version of languages interfaces and classes ParsersController заменен на LanguageProvider. * Update ParserTools.csproj * Update RemoteCompiler.cs * Update TestRunner * Rename LanguageIntegrator project to Languages * Update TestRunner * Rename Parsers folder * Rename PascalABCParser.dll to PascalABCLanguage.dll * Reorganise LanguageIntegrator and rename DocTagsParser * Update Release Generators * Update language loading messages * Update linux version * Move BaseParser fields to ILanguage interface * Revert "Update Release Generators" This reverts commit 26a991c71b81e643d9fbd9a815ddca222768dda9. * Revert "Rename PascalABCParser.dll to PascalABCLanguage.dll" * Clean the mess in parser folders * Organize namespaces properly * Revert "Rename LanguageIntegrator project to Languages" * Add new enclosing folders for standard languages * Organize namespaces of LanguageIntegrator properly * Rename StandardLanguages to Languages * Comment the rest of Visual basic source code * Update OutputPath in pascal parser project * Move BaseParser methods to IParser * Restore Pascal parser project initial structure * Add PascalLanguage project * Move SyntaxTreeConverters project to Languages\Pascal folder * Rename SemanticRules in parser project * Rename Errors1 to Errors in parser project * Delete LambdaConverter dll from installer * Update language integrator to load *Language.dll files * Move lambda converter project to pascal lanuage dir * Revert "Delete LambdaConverter dll from installer" This reverts commit dd56f559ebe4f8c4c5c33752d44e6953001b96a5. * Switch off VBNETParser building * Delete syntax tree converters controller * Delete lambda converter dll from repository * Reorganize syntax tree to semantic tree conversion stage * Add BaseLanguage class to make language initialization more neat * Delete syntax tree post processors entity from ILanguage and refactor ABCStatistics calls * Add new IDocParser interface for documentation comments parser * Clean up folders * Add helper data structures to reduce parameters amount in CompileInterface and CompileImplementation * Add documentation to language classes * Move Union struct in global namespace and project (ParserTools) * Add more comments and a safe select language method * Rename SemanticRules class * Fix directives format null bug * Add System.Linq ref to LanguageIntegrator * Delete SyntaxToSemanticTreeConverter interface * Add BaseSyntaxTreeConverter * Call safe select language method in intellisence * Delete source files providers from parsers * Rename GetSyntaxTree method * Change Prebuild tree to be virtual - not abstract * Refresh documentation a bit * Add temporary language check for ABCHealth button * Add parser reference to parser tools * Move current compilation unit assigning higher to avoid bug with unit check * Delete null DirectiveInfo's and refactor directives' code * Add a few more comments
2024-05-25 12:26:32 +03:00
SemanticRulesConstants.ThrowErrorWithoutSave = SemanticRulesThrowErrorWithoutSave;
2015-05-14 22:35:07 +03:00
syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack = statement_list_stack;
syntax_tree_visitor.context.converted_type = converted_type;
syntax_tree_visitor.context.var_defs = current_var_defs;
syntax_tree_visitor.context.set_field_access_level(curr_fal);
syntax_tree_visitor.context.block_stack = block_stack;
syntax_tree_visitor.context.CyclesStack = cycle_stack;
syntax_tree_visitor.context.member_decls = current_member_decls;
syntax_tree_visitor.context.func_stack = function_node_stack;
syntax_tree_visitor.context.last_created_function = current_last_created_function;
}
}
class DirectiveInfo
{
/// <summary>
/// Вспомогательная функция возвращает содержится ли переменная в списке переменных редукции
/// </summary>
/// <param name="rds"></param>
/// <param name="var"></param>
/// <returns></returns>
private static bool ContainsVarible(List<ReductionDirective> rds, string var)
{
foreach (ReductionDirective red_dir in rds)
if (red_dir.variables.Contains(var))
return true;
return false;
}
/// <summary>
///Из списка приватных переменных убираем все переменные редукции и возвращаем этот список
/// </summary>
/// <param name="privs"></param>
/// <param name="reds"></param>
/// <returns></returns>
private static List<string> FiltrPrivVarsReductionsVars(List<string> privs, List<ReductionDirective> reds)
{
List<string> res = new List<string>();
foreach (string var in privs)
if (!ContainsVarible(reds, var))
res.Add(var);
return res;
}
public DirectiveInfo(SyntaxTree.compiler_directive dir)
{
Reductions = new List<ReductionDirective>();
Privates = new List<string>();
string DirText = dir.Directive.text.ToLower();
if (DirText.StartsWith("critical ") || DirText.Length == "critical".Length)
{
Kind = DirectiveKind.Critical;
DirText = DirText.Substring("critical".Length).Trim().Replace(" ", "");
Name = DirText;
//Если что, потом допилим
}
else if (DirText.StartsWith("parallel "))
{
DirText = DirText.Substring("parallel".Length).Trim();
if (DirText.StartsWith("for ") || DirText.Length == "for".Length)
{
Kind = DirectiveKind.ParallelFor;
DirText = DirText.Substring("for".Length).Trim();
ProcessClauses(DirText, dir.Directive.source_context, true);
}
else if (DirText.StartsWith("sections ") || DirText.Length == "sections".Length)
{
Kind = DirectiveKind.ParallelSections;
DirText = DirText.Substring("sections".Length).Trim();
ProcessClauses(DirText, dir.Directive.source_context, false);
}
else
{
Kind = DirectiveKind.Unknown;
PutError(DirText.Length, dir.Directive.source_context, "OMPERROR_UNKNOWN_DIRECTIVE");
}
}
else
{
Kind = DirectiveKind.Unknown;
2018-07-25 22:40:20 +03:00
PutError(DirText.Length, dir.Directive.source_context != null ? dir.Directive.source_context : dir.source_context, "OMPERROR_UNKNOWN_DIRECTIVE");
2015-05-14 22:35:07 +03:00
}
}
//DirSC - SC текста директивы
private void ProcessClauses(string Text, SyntaxTree.SourceContext DirSC, bool AllowReduction)
{
if (Text == "")
return;
if (Text.StartsWith("private ") || Text.StartsWith("private("))
{
Text = Text.Substring("private".Length).Trim();
if (!Text.StartsWith("("))
{
PutError(Text.Length, DirSC, "OMPERROR_ERROR_IN_CLAUSE_PARAMETERS");
return;
}
int ClosePos = Text.IndexOf(")");
if (ClosePos == -1)
{
PutError(Text.Length, DirSC, "OMPERROR_ERROR_IN_CLAUSE_PARAMETERS");
return;
}
string ClauseParam = Text.Substring(1, ClosePos - 1).Trim();
if (ClauseParam.Length == 0)
{
PutError(Text.Length, DirSC, "OMPERROR_ERROR_IN_CLAUSE_PARAMETERS");
return;
}
int err_code;
List<string> prs = ProcessPrivateParametrs(ClauseParam, Privates, out err_code);
if (err_code == 0)
{
prs = FiltrPrivVarsReductionsVars(prs, Reductions);
Privates.AddRange(prs);
}
else if (err_code == 1)
{
PutError(Text.Length, DirSC, "OMPERROR_ERROR_IN_CLAUSE_PARAMETERS");
return;
}
else
{
PutError(Text.Length, DirSC, "OMPERROR_WARNING_IN_CLAUSE_PARAMETERS_REPEATED_VARS");
//return;
if (prs != null)
{
prs = FiltrPrivVarsReductionsVars(prs, Reductions);
Privates.AddRange(prs);
}
}
Text = Text.Substring(ClosePos + 1).Trim();
}
else if (AllowReduction && (Text.StartsWith("reduction") || Text.StartsWith("reduction(")))
{
Text = Text.Substring("reduction".Length).Trim();
if (!Text.StartsWith("("))
{
PutError(Text.Length, DirSC, "OMPERROR_ERROR_IN_CLAUSE_PARAMETERS");
return;
}
int ClosePos = Text.IndexOf(")");
if (ClosePos == -1)
{
PutError(Text.Length, DirSC, "OMPERROR_ERROR_IN_CLAUSE_PARAMETERS");
return;
}
string ClauseParam = Text.Substring(1, ClosePos - 1).Trim();
if (ClauseParam.Length == 0)
{
PutError(Text.Length, DirSC, "OMPERROR_ERROR_IN_CLAUSE_PARAMETERS");
return;
}
int err_code;
ReductionDirective rd = ProcessReductionParametrs(ClauseParam, Reductions, out err_code);
if (err_code == 0)
{
if (rd != null) Reductions.Add(rd);
}
else if (err_code == 1)
{
PutError(Text.Length, DirSC, "OMPERROR_ERROR_IN_CLAUSE_PARAMETERS");
return;
}
else
{
PutError(Text.Length, DirSC, "OMPERROR_WARNING_IN_CLAUSE_PARAMETERS_REPEATED_VARS");
if (rd != null && rd.variables.Count != 0)
Reductions.Add(rd);
//return;
}
Text = Text.Substring(ClosePos + 1).Trim();
}
else
{
PutError(Text.Length, DirSC, "OMPERROR_ERROR_IN_CLAUSE");
return;
}
ProcessClauses(Text, DirSC, AllowReduction);
}
/// <summary>
/// Обрабатывает параметры редукции и возвращает их
/// </summary>
/// <param name="param_text">текст, содержащий параметры редукции</param>
/// <param name="rds"> список уже построенных кляуз редукции</param>
/// <param name="err_code">код ошибки. 0 - нет ошибок,1-ошибка в параметрах редукции, 2- повторно обьявленная переменная редукции проигнорирована </param>
/// <returns></returns>
private ReductionDirective ProcessReductionParametrs(string param_text, List<ReductionDirective> rds, out int err_code)
{
//string err_mes = "Ошибка в директиве OpenMP. Неверные параметры reduction. Опция проигнорирована!";
// теперь надо найти параметры редукции
ReductionDirective rd = new ReductionDirective();
int state = 1;
int ind = 0;
err_code = 0;
string ident = "";
while (ind < param_text.Length)
{
switch (state)
{
case 1:
if (param_text[ind] == '+')
{
rd.Oper = ReductionOperations.plus;
state = 7;
}
else if (param_text[ind] == '-')
{
rd.Oper = ReductionOperations.minus;
state = 7;
}
else if (param_text[ind] == '*')
{
rd.Oper = ReductionOperations.mult;
state = 7;
}
else if (param_text[ind] == 'o')
state = 2;
else if (param_text[ind] == 'x')
state = 3;
else if (param_text[ind] == 'a')
state = 4;
else if (param_text[ind] != ' ')
{
err_code = 1;
return null;
}
break;
case 2: if (param_text[ind] == 'r')
{
rd.Oper = ReductionOperations.or;
state = 7;
}
else
{
err_code = 1;
return null;
}
break;
case 3: if (param_text[ind] == 'o')
{
state = 5;
}
else
{
err_code = 1;
return null;
}
break;
case 4: if (param_text[ind] == 'n')
{
state = 6;
}
else
{
err_code = 1;
return null;
}
break;
case 5: if (param_text[ind] == 'r')
{
rd.Oper = ReductionOperations.xor;
state = 7;
}
else
{
err_code = 1;
return null;
}
break;
case 6: if (param_text[ind] == 'd')
{
rd.Oper = ReductionOperations.and;
state = 7;
}
else
{
err_code = 1;
return null;
}
break;
case 7: if (param_text[ind] == ':')
{
state = 8;
}
else if (param_text[ind] != ' ')
{
err_code = 1;
return null;
}
break;
case 8:
if (param_text[ind] == '_' || param_text[ind] >= 'A' && param_text[ind] <= 'z')
{
state = 9;
ident += param_text[ind];
}
else if (param_text[ind] != ' ')
{
err_code = 1;
return null;
}
break;
case 9:// читаем имя идентификатора
if (param_text[ind] == '_' || param_text[ind] >= 'A' && param_text[ind] <= 'z' || param_text[ind] >= '0' && param_text[ind] <= '9')
{
ident += param_text[ind];
}
else if (param_text[ind] == ' ')
{
state = 10;
if (ContainsVarible(rds, ident.ToLower()))
{
err_code = 2;
}
else
{
rd.variables.Add(ident.ToLower());
}
ident = "";
}
else if (param_text[ind] == ',')
{
state = 8;
if (rd.variables.Contains(ident.ToLower()) || ContainsVarible(rds, ident.ToLower()))
{
err_code = 2;
}
else
{
rd.variables.Add(ident.ToLower());
}
ident = "";
}
else
{
err_code = 1;
return null;
}
break;
case 10:
if (param_text[ind] == ',')
state = 8;
else if (param_text[ind] != ' ')
{
err_code = 1;
return null;
}
break;
}
ind++;
}
if (state != 9 && state != 10)
{
err_code = 1;
return null;
}
if (state == 9)
if (ContainsVarible(rds, ident.ToLower()))
{
err_code = 2;
}
else
{
rd.variables.Add(ident.ToLower());
}
return rd;
}
private List<string> ProcessPrivateParametrs(string param_text, List<string> privateVars, out int err_code)
{
List<string> res = new List<string>();
int ind = 0;
//string err_mes = "Ошибка в директиве OpenMP. Неверные параметры директивы private. Опция проигнорирована!";
// надо найти переменные private
int state = 1;
err_code = 0;
string ident = "";
while (ind < param_text.Length)
{
switch (state)
{
case 1:
if (param_text[ind] == '_' || param_text[ind] >= 'A' && param_text[ind] <= 'z')
{
state = 2;
ident += param_text[ind];
}
else if (param_text[ind] != ' ')
{
err_code = 1;
res.Clear();
return res;
}
break;
case 2:// читаем дальше имя идентификатора
if (param_text[ind] == '_' || param_text[ind] >= 'A' && param_text[ind] <= 'z' || param_text[ind] >= '0' && param_text[ind] <= '9')
{
ident += param_text[ind];
}
else if (param_text[ind] == ' ')
{
state = 3;
if (res.Contains(ident.ToLower()) || privateVars.Contains(ident.ToLower()))
{
err_code = 2;
}
else
res.Add(ident.ToLower());
ident = "";
}
else if (param_text[ind] == ',')
{
state = 1;
if (res.Contains(ident.ToLower()) || privateVars.Contains(ident.ToLower()))
{
err_code = 2;
}
else
res.Add(ident.ToLower());
ident = "";
}
else
{
err_code = 1;
res.Clear();
return res;
}
break;
case 3:
if (param_text[ind] == ',')
state = 1;
else if (param_text[ind] != ' ')
{
err_code = 1;
res.Clear();
return res;
}
break;
}
ind++;
}
if (state != 2 && state != 3)
{
err_code = 1;
res.Clear();
return res;
}
if (state == 2)
{
if (res.Contains(ident.ToLower()) || privateVars.Contains(ident.ToLower()))
{
err_code = 2;
}
else
res.Add(ident.ToLower());
}
return res;
}
private void PutError(int TextLength, SyntaxTree.SourceContext DirSC, string ErrorName)
{
2018-11-26 22:02:24 +03:00
if (DirSC != null)
{
int bp = DirSC.Length - TextLength - "omp".Length;
SC = new SyntaxTree.SourceContext(DirSC.begin_position.line_num,
DirSC.begin_position.column_num + bp,
DirSC.begin_position.line_num,
DirSC.begin_position.column_num + bp);
}
2015-05-14 22:35:07 +03:00
this.ErrorName = ErrorName;
}
/// <summary>
/// Тип директивы
/// </summary>
public DirectiveKind Kind;
/// <summary>
/// Имя (в случае если это критическая секция)
/// </summary>
public string Name;
/// <summary>
/// Список предложений
/// </summary>
public List<string> Privates;
public List<ReductionDirective> Reductions;
/// <summary>
/// Если есть ошибка - здесь будет храниться ее позиция. Иначе - null.
/// </summary>
public SyntaxTree.SourceContext SC;
public string ErrorName;
}
class Clause
{
/// <summary>
/// Тип предложения
/// </summary>
public ClauseKind Kind;
/// <summary>
/// Оператор редукции
/// </summary>
public ReductionOperations Oper;
/// <summary>
/// Список имен переменных
/// </summary>
public List<string> Names;
}
public enum ParallelPosition { Outside, InsideParallel, InsideSequential }
public enum ReductionOperations { plus, minus, mult, xor, and, or }
public enum DirectiveKind { Critical, ParallelFor, ParallelSections, Unknown }
public enum ClauseKind { Private, Reduction }
internal class OpenMP
{
#region Флаги
//В программе встречаются критические секции
public static bool LocksFound = false;
private static bool LocksInitialized = false;
//после инициализации хранит название класса с обьектами для блокировок
private static string LocksName = "";
// хранит имя булевской глобальной переменной, означающей, что мы в текущий момент в параллельной секции
private static string InParallelSection = "";
private static bool InParallelSectionCreated = false;
//временно удаленные директивы
private static Dictionary<SyntaxTree.syntax_tree_node, SyntaxTree.compiler_directive> DisabledDirectives = new Dictionary<PascalABCCompiler.SyntaxTree.syntax_tree_node, PascalABCCompiler.SyntaxTree.compiler_directive>();
//В программе встречаются директивы parallel for
public static bool ForsFound = false;
//в программе встречаются директивы parallel sections
public static bool SectionsFound = false;
#endregion
#region Инициализация
public static StackLoopVariables LoopVariables = new StackLoopVariables();
/// <summary>
/// Словарь, возвращающий по директиве (compiler_directive) информацию о ней (DirectiveInfo)
/// </summary>
public static Dictionary<SyntaxTree.compiler_directive, DirectiveInfo> DirInfosTable = new Dictionary<SyntaxTree.compiler_directive, DirectiveInfo>();
//приведение класса в исходное состояние
public static void InternalReset()
{
DisabledDirectives = new Dictionary<PascalABCCompiler.SyntaxTree.syntax_tree_node, PascalABCCompiler.SyntaxTree.compiler_directive>();
LocksName = "";
LocksFound = false;
LocksInitialized = false;
ForsFound = false;
SectionsFound = false;
LoopVariables.Clear();
DirInfosTable.Clear();
InParallelSection = "";
InParallelSectionCreated = false;
}
//инициализация OpenMP
public static void InitOpenMP(List<SyntaxTree.compiler_directive> directives, syntax_tree_visitor visitor, SyntaxTree.compilation_unit cu)
{
//Из-за переноса этой проверки в секцию инициализации - оно не всегда успевает инициализироваться до выполнения этого кода.
//Будем надеяться, что условие никогда не выполнится. Без постороннего вмешательства (замена файлов старыми версиями) - не должно.
//if (SystemLibrary.SystemLibInitializer.OMP_Available == null || SystemLibrary.SystemLibInitializer.OMP_Available.NotFound)
//{
// visitor.AddWarning(new Errors.CommonWarning(PascalABCCompiler.StringResources.Get("OMPERROR_OMP_NOT_AVAILABLE"), cu.file_name, cu.source_context.begin_position.line_num, cu.source_context.begin_position.column_num));
// return;
//}
foreach (SyntaxTree.compiler_directive dir in directives)
{
if (dir.Name.text.ToLower() == "omp")
{
string DirText = dir.Directive.text.ToLower();
DirectiveInfo dirInf = new DirectiveInfo(dir);
DirInfosTable.Add(dir, dirInf);
if (dirInf.Kind == DirectiveKind.ParallelFor)
ForsFound = true;
else if (dirInf.Kind == DirectiveKind.ParallelSections)
SectionsFound = true;
else if (dirInf.Kind == DirectiveKind.Critical)
LocksFound = true;
else
{
2018-11-26 22:02:24 +03:00
visitor.AddWarning(new Errors.CommonWarning(PascalABCCompiler.StringResources.Get(dirInf.ErrorName),
dir.source_context.FileName,
dirInf.SC != null ? dirInf.SC.begin_position.line_num : dir.source_context.begin_position.line_num,
dirInf.SC != null ? dirInf.SC.begin_position.column_num : dir.source_context.begin_position.column_num));
2015-05-14 22:35:07 +03:00
}
}
}
//уже не нужно
//if (ForsFound && SystemLibrary.SystemLibInitializer.OMP_ParallelFor.NotFound)
//{
// visitor.AddWarning(new Errors.CommonWarning(PascalABCCompiler.StringResources.Get("OMPERROR_PARALLELIZATION_FOR_NOT_AVAILABLE"), cu.file_name, cu.source_context.begin_position.line_num, cu.source_context.begin_position.column_num));
// ForsFound = false;
//}
//if (SectionsFound && SystemLibrary.SystemLibInitializer.OMP_ParallelSections.NotFound)
//{
// visitor.AddWarning(new Errors.CommonWarning(PascalABCCompiler.StringResources.Get("OMPERROR_PARALLELIZATION_SECTIONS_NOT_AVAILABLE"), cu.file_name, cu.source_context.begin_position.line_num, cu.source_context.begin_position.column_num));
// SectionsFound = false;
//}
//"оторванные" директивы:
//можно использовать директивы синхронизации и вне параллельных областей.
//if (!SectionsFound && !ForsFound && LocksFound)
//{
// visitor.AddWarning(new Errors.CommonWarning(PascalABCCompiler.StringResources.Get("OMPERROR_USING_CRITICAL_SECTIONS_OUTSIDE_PARALLEL_STRUCTURES"), cu.file_name, cu.source_context.begin_position.line_num, cu.source_context.begin_position.column_num));
// LocksFound = false;
//}
}
//инициализация критических секций с созданием класса
private static void InitCriticals(syntax_tree_visitor visitor)
{
//генерируем класс
SyntaxTree.type_declarations TypeDecls = new PascalABCCompiler.SyntaxTree.type_declarations();
SyntaxTree.type_declaration TypeDecl = new PascalABCCompiler.SyntaxTree.type_declaration();
TypeDecls.types_decl.Add(TypeDecl);
LocksName = visitor.context.get_free_name("$locks_container{0}");
TypeDecl.type_name = new PascalABCCompiler.SyntaxTree.ident(LocksName);
SyntaxTree.class_definition ClassDef = new PascalABCCompiler.SyntaxTree.class_definition();
TypeDecl.type_def = ClassDef;
2017-06-06 05:24:32 +03:00
SyntaxTree.class_body_list ClassBody = new PascalABCCompiler.SyntaxTree.class_body_list();
2015-05-14 22:35:07 +03:00
ClassDef.body = ClassBody;
SyntaxTree.class_members ClassMember = new PascalABCCompiler.SyntaxTree.class_members();
ClassBody.class_def_blocks.Add(ClassMember);
ClassMember.access_mod = new PascalABCCompiler.SyntaxTree.access_modifer_node(PascalABCCompiler.SyntaxTree.access_modifer.public_modifer);
List<string> ProcessedNames = new List<string>();
foreach (KeyValuePair<SyntaxTree.compiler_directive, DirectiveInfo> pair in DirInfosTable)
{
if (pair.Value.Kind == DirectiveKind.Critical)
{
string LockName = "$default";
if (pair.Value.Name.Length != 0)
LockName = pair.Value.Name;
if (ProcessedNames.Contains(LockName))
continue;
ProcessedNames.Add(LockName);
SyntaxTree.var_def_statement vds = new PascalABCCompiler.SyntaxTree.var_def_statement();
SyntaxTree.ident_list idl = new PascalABCCompiler.SyntaxTree.ident_list();
vds.vars = idl;
idl.Add(new SyntaxTree.ident(LockName));
SyntaxTree.named_type_reference ntr = new PascalABCCompiler.SyntaxTree.named_type_reference();
vds.vars_type = ntr;
ntr.Add(new SyntaxTree.ident("object"));
SyntaxTree.new_expr ne = new PascalABCCompiler.SyntaxTree.new_expr();
vds.inital_value = ne;
ne.type = ntr;
vds.var_attr = PascalABCCompiler.SyntaxTree.definition_attribute.Static;
ClassMember.members.Add(vds);
}
}
//сохраняем контекст
ContextInfo contextInfo = new ContextInfo(visitor);
try
{
visitor.visit(TypeDecls);
LocksInitialized = true;
}
finally
{
//восстанавливаем контекст
contextInfo.RestoreContext(visitor);
}
}
#endregion
#region Обработка критических секций
public static void TryConvertCritical(ref SyntaxTree.statement st, syntax_tree_visitor visitor, SyntaxTree.compiler_directive directive)
{
if (!LocksInitialized)
InitCriticals(visitor);
string LockName = "$default";
if (DirInfosTable[directive].Name.Length != 0)
LockName = DirInfosTable[directive].Name;
SyntaxTree.lock_stmt LockStmt = new PascalABCCompiler.SyntaxTree.lock_stmt();
LockStmt.lock_object = new SyntaxTree.dot_node(new SyntaxTree.ident(LocksName), new SyntaxTree.ident(LockName));
LockStmt.stmt = st;
st = LockStmt;
}
public static void DisableDirective(SyntaxTree.syntax_tree_node node, Dictionary<SyntaxTree.syntax_tree_node, SyntaxTree.compiler_directive> linker)
{
if (!linker.ContainsKey(node))
return;
SyntaxTree.compiler_directive dir = linker[node];
if (DirInfosTable.ContainsKey(dir) && DirInfosTable[dir].Kind == DirectiveKind.Critical)
{
DisabledDirectives.Add(node, dir);
linker.Remove(node);
}
}
public static void EnableDirective(SyntaxTree.syntax_tree_node node, Dictionary<SyntaxTree.syntax_tree_node, SyntaxTree.compiler_directive> linker)
{
if (!DisabledDirectives.ContainsKey(node))
return;
SyntaxTree.compiler_directive dir = DisabledDirectives[node];
DisabledDirectives.Remove(node);
linker.Add(node, dir);
}
#endregion
public static bool IsParallelSectionsDirective(SyntaxTree.compiler_directive directive)
{
return DirInfosTable.ContainsKey(directive) && DirInfosTable[directive].Kind == DirectiveKind.ParallelSections;
}
public static bool IsParallelForDirective(SyntaxTree.compiler_directive directive)
{
return DirInfosTable.ContainsKey(directive) && DirInfosTable[directive].Kind == DirectiveKind.ParallelFor;
}
public static bool IsCriticalDirective(SyntaxTree.compiler_directive directive)
{
return DirInfosTable.ContainsKey(directive) && DirInfosTable[directive].Kind == DirectiveKind.Critical;
}
#region Распараллеливание For
//Проверки на доступность OMP и директиву проводятся перед вызовом.
internal static statements_list TryConvertFor(statements_list for_head_stmts, SyntaxTree.for_node for_node, for_node fn, var_definition_node loop_variable, expression_node fromInclusive, expression_node toInclusive, syntax_tree_visitor syntax_tree_visitor)
{
try
{
location loc = fn.location;
statements_list omp_stmts = new statements_list(loc);
statements_list head_stmts = new statements_list(loc);
syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_push(head_stmts);
if (!InParallelSectionCreated)
CreateInParallelVariable(syntax_tree_visitor, out InParallelSection);
//если omp доступен то (выполнять паралельно) иначе (выполнять for)
if_node ifnode = CreateIfCondition(syntax_tree_visitor, omp_stmts, for_head_stmts, loc);
head_stmts.statements.AddElement(ifnode);
//генерим ветку в случае когда доступен omp
if (!GenerateOMPParallelForCall(fn.body, for_node, loop_variable, omp_stmts, syntax_tree_visitor, fromInclusive, toInclusive))
{
syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_pop();
return null;
}
syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_pop();
return head_stmts;
}
catch (OpenMPException e)
{
Exception ex = new Exception(e.ToString());
syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_pop();
syntax_tree_visitor.WarningsList.Add(new OMP_BuildigError(ex, syntax_tree_visitor.get_location(new SyntaxTree.syntax_tree_node(e.SC))));
}
catch (Exception e)
{
syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_pop();
syntax_tree_visitor.WarningsList.Add(new OMP_BuildigError(e, fn.location));
}
return null;
}
private static bool GenerateOMPParallelForCall(statement_node body, SyntaxTree.for_node for_node, var_definition_node loop_variable, statements_list omp_stmts, syntax_tree_visitor syntax_tree_visitor, expression_node fromInclusive, expression_node toInclusive)
{
SyntaxTree.statement syntax_body = for_node.statements;
expression_node omp_call = null;
base_function_call bfc = body as base_function_call;
if (bfc != null && bfc.parameters.Count == 1 && bfc.parameters[0] is variable_reference &&
((variable_reference)bfc.parameters[0]).VariableDefinition == loop_variable && ((bfc.function.parameters[0].type as type_node).PrintableName.ToLower() == "integer"))
{
//если тело цикла - вызов функции с одни параметром - переменной цикла,
//если при этом у вызываемой функции тип параметра - integer, а не какой-нибудь object, как это бывает с write и вообще может быть с перегрузкой
//то генерировать класс не надо.
//генерируем вызов и все
omp_call = syntax_tree_visitor.CreateDelegateCall(bfc);
if (omp_call == null)
{
syntax_tree_visitor.AddWarning(new OMP_ConstructionNotSupportedNow(body.location));
syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_pop();
return false;
}
base_function_call omp_parallel_for_call = null;
if (SystemLibrary.SystemLibInitializer.OMP_ParallelFor.sym_info is common_namespace_function_node)
omp_parallel_for_call = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.OMP_ParallelFor.sym_info as common_namespace_function_node, body.location);
else
omp_parallel_for_call = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.OMP_ParallelFor.sym_info as compiled_function_node, body.location);
omp_parallel_for_call.parameters.AddElement(fromInclusive);
omp_parallel_for_call.parameters.AddElement(toInclusive);
omp_parallel_for_call.parameters.AddElement(omp_call);
omp_stmts.statements.AddElement(omp_parallel_for_call);
}
else
{
//ищем используемые переменные, получаем редукцию из директивы и составляем список переменных по типам
VarFinderSyntaxVisitor VFvis = new VarFinderSyntaxVisitor(syntax_body, syntax_tree_visitor.context, true);
SyntaxTree.compiler_directive dir = syntax_tree_visitor.DirectivesToNodesLinks[for_node];
//if (DirInfosTable[dir].ErrorName == "WARNING_IN_CLAUSE_PARAMETERS_REPEATED_VARS")
Refactoring of Compiler.cs (#2984) * Add first comments * Finish commenting for Compile and CompileUnit * Write TODO sections * Add a few clarifications * splitted some functions from compile * Written some methods from Compile to functions * Update variable names * Refactor - stage 1 Refactor GetUsesSection and IsPossibleNameSpace * Refactor - stage 2 Rename a few functions and variables * Correct an inaccuracy * Added comments, look through CompileUnit * Rename a few functions and add new comments * Split CompileUnit to Subfunctions Add IsUnitCompiled, IsUnitInPCU, InitializeNewUnit, GetSourceCode, GenSyntaxTree, GenUnitDocumentation, CheckDLLDirectiveOnlyForLibraries, MatchErrorsToBadNodes, CheckIfUnitModule, SetUseDLLForSystemUnits, CompileInterfaceDependencies, CompileCurrentUnitInterface, GetImplementationUsesSection, CompileImplementationDependencies, CompileCurrentUnitImplementation * Added some TODOs * Return uses_unit_in original name Renaming of syntax tree nodes leads to internal compiler errors * Extract GenerateILCode method * Add checking if recompilation needed method Needs to be discussed and revised * Add functions for catch blocks in Compile * Extract building semantic tree method Creating main function to be moved to another class * Rename UnitsSortedList * Edit CompileUnitsFromDelayedList method * Change a few variable names, make CreateRCFile function and add comments * Make code more "user-friendly" * Add TODOs 31.11.23 * Create PrebuildSemanticTreeActionsMethod * Refactor semantic checks section in initialize new unit method * Refactor Adding standard units to uses method * Return file_name and compiler_directives original names to avoid internal compilation errors * Refactor GetReferences Method * Initial refactoring of IncludeNamespaces function * Create three more methods and wrap important code in regions * Add TODO's * Resolve merge conflicts * Add returned value to ConstructSyntaxTree method * Fix UnitsSortedList NotFoundError in PCUWriter * Workaround commit * Update PABCSystem after tests' changes * Rename syntax trees in some methods * Delete CurrentSyntaxUnit variable * Revert unnecessary project files changes * Squashed commit of the following: commit f4d7599f1a39252feac97bd5391f46dfdc25f6f4 Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 22 11:43:29 2023 +0300 added links to identarranger commit 3bd5d33e2b2969884e61a3279ff9c353013b57fe Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 22 11:43:03 2023 +0300 Change extension for verybasic to yavb commit 61294c6e7d405e1c68516cc81d3a109e8a1ee295 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Tue Nov 21 09:33:57 2023 +0300 Change Program Example commit 86971488341ed6bf13c39e13a513d7ac0c51c285 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Tue Nov 21 09:28:59 2023 +0300 Add IndentArranger to Compile commit 2ce50bbbf9db22c4243b247b870f6935ce206d26 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Fri Nov 17 10:00:31 2023 +0300 Add Semicolon After Each Statement commit 796309d340e8d8ba730ff9418fa376f34fb7fd36 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Wed Nov 15 18:49:11 2023 +0300 Add Alpha Version of Python-style If-statement commit 5eb88f946fe8254b4f5c5a56ed0a567b3be51227 Merge: ab4ce5b0 0162b637 Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 15 16:54:26 2023 +0300 Merge branch 'IndentArranger' into VeryBasicLanguage commit ab4ce5b0e32d42004726e3dc45cc0d8a65e53f56 Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 15 16:53:51 2023 +0300 Fixes from seminar commit af74012289d0d08517c13499a2a66cb543fc06d2 Author: Владислав Крылов <krylov@sfedu.ru> Date: Sun Nov 12 18:57:29 2023 +0300 finally working! fully implemented compatibility commit 58a39c313324b468d1eec207ba3f5f6eddf74ef2 Author: Владислав Крылов <krylov@sfedu.ru> Date: Sun Nov 12 11:58:16 2023 +0300 more compatibility with pabc Now verybasic statements translate to pascal compiler added .bat script for autobuilding verybasic commit 0162b6376b8fe970704f26213bf9f0f670dfb12e Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Sun Nov 12 10:06:14 2023 +0300 Update test.txt commit 1b759ab1cd7ee2ffeb14afff0418ddf0f30b0399 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Sun Nov 12 10:05:36 2023 +0300 Add Indent and Unindent Keywords to Generated File commit cabda7f3985651cff2a8740f1a5bdea8fe7ac892 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Fri Nov 10 21:25:52 2023 +0300 Add Generation of Output File commit 306f033d0176ab559e3622b8505427dbe2e0e203 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Thu Nov 9 20:42:18 2023 +0300 Update IndentArranger.sln commit 60c0ceced1aa3a7d2e33de0facb1126e295f43b5 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Thu Nov 9 20:41:22 2023 +0300 Add IndentArranger commit 1f4556c4573dae154fcc167b41ff6ab9e8122136 Author: Владислав Крылов <krylov@sfedu.ru> Date: Mon Nov 6 22:48:36 2023 +0300 Made my own VeryBasicParser project Copied some code from SaushkinParser Tried to compile it and implement into Pascal Doesn't work due to grammatik issue * Squashed commit of the following: commit 4e73d9ac3ffef68312f06a74dc83afffcf3ccbee Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 22 15:08:10 2023 +0300 Fixed GPPG (i think so at least) commit e5cfc220828b37fb2f35e565683019716ec3f0ce Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 22 11:44:27 2023 +0300 Update Compiler.cs commit 4698e2e75a5f3b4f523a8bc7733a50e8abb4fca1 Merge: 22aaf2b2 f4d7599f Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 22 11:43:54 2023 +0300 Merge branch 'IndentArrangerTemp' into VeryBasicLanguage commit f4d7599f1a39252feac97bd5391f46dfdc25f6f4 Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 22 11:43:29 2023 +0300 added links to identarranger commit 3bd5d33e2b2969884e61a3279ff9c353013b57fe Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 22 11:43:03 2023 +0300 Change extension for verybasic to yavb commit 22aaf2b2508278a9ffce525ffed52419bf72c23f Merge: c326174f 61294c6e Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 22 11:26:36 2023 +0300 Merge branch 'IndentArrangerTemp' into VeryBasicLanguage commit 61294c6e7d405e1c68516cc81d3a109e8a1ee295 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Tue Nov 21 09:33:57 2023 +0300 Change Program Example commit 86971488341ed6bf13c39e13a513d7ac0c51c285 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Tue Nov 21 09:28:59 2023 +0300 Add IndentArranger to Compile commit c326174ff5ecccf9c4f76d58aea4653f047af049 Author: Владислав Крылов <krylov@sfedu.ru> Date: Sun Nov 19 15:03:19 2023 +0300 Added UniversalParserHelper and GPPG ShiftReduceParser moved to another project UniversalParserHelper project added, most of it copied from SaushkinParser commit 2ce50bbbf9db22c4243b247b870f6935ce206d26 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Fri Nov 17 10:00:31 2023 +0300 Add Semicolon After Each Statement commit 796309d340e8d8ba730ff9418fa376f34fb7fd36 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Wed Nov 15 18:49:11 2023 +0300 Add Alpha Version of Python-style If-statement commit 5eb88f946fe8254b4f5c5a56ed0a567b3be51227 Merge: ab4ce5b0 0162b637 Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 15 16:54:26 2023 +0300 Merge branch 'IndentArranger' into VeryBasicLanguage commit ab4ce5b0e32d42004726e3dc45cc0d8a65e53f56 Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 15 16:53:51 2023 +0300 Fixes from seminar commit af74012289d0d08517c13499a2a66cb543fc06d2 Author: Владислав Крылов <krylov@sfedu.ru> Date: Sun Nov 12 18:57:29 2023 +0300 finally working! fully implemented compatibility commit 58a39c313324b468d1eec207ba3f5f6eddf74ef2 Author: Владислав Крылов <krylov@sfedu.ru> Date: Sun Nov 12 11:58:16 2023 +0300 more compatibility with pabc Now verybasic statements translate to pascal compiler added .bat script for autobuilding verybasic commit 0162b6376b8fe970704f26213bf9f0f670dfb12e Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Sun Nov 12 10:06:14 2023 +0300 Update test.txt commit 1b759ab1cd7ee2ffeb14afff0418ddf0f30b0399 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Sun Nov 12 10:05:36 2023 +0300 Add Indent and Unindent Keywords to Generated File commit cabda7f3985651cff2a8740f1a5bdea8fe7ac892 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Fri Nov 10 21:25:52 2023 +0300 Add Generation of Output File commit 306f033d0176ab559e3622b8505427dbe2e0e203 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Thu Nov 9 20:42:18 2023 +0300 Update IndentArranger.sln commit 60c0ceced1aa3a7d2e33de0facb1126e295f43b5 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Thu Nov 9 20:41:22 2023 +0300 Add IndentArranger commit 1f4556c4573dae154fcc167b41ff6ab9e8122136 Author: Владислав Крылов <krylov@sfedu.ru> Date: Mon Nov 6 22:48:36 2023 +0300 Made my own VeryBasicParser project Copied some code from SaushkinParser Tried to compile it and implement into Pascal Doesn't work due to grammatik issue * Changed GPPG project NET Framework version, added .dll to gitignore * Adding UniversalParserHelper to project, trying to include VeryBasic * Managed dependencies and got VeryBasicLanguage to work * Change extension of a test program * Rebuild changes What should be added to .gitignore? * Fix bug related to err0524_res_unit.pas * Rebuild Parser * Change Indent and Unindent tokens * Add Symbol Table to ParserABC.y * Change Indent Space Number to 2 * Add While Loop * Add Some Operations to Parser * Make Initialization Node at the Beginning of a program * Create Grammar.txt * Test program added * Add ELIF and SyntaxHighlight * Fix TableSymbol * Add Division * Add Method Call * Add For Loop * Rename SPython Parser Folder * Add documented comments for CompileUnit method * Added Errors to SPython Added Errors.cs Removed link to PABCSaushkinParser Minor fixes * Create default constructor for SourceContext * Move null check of currentUnit to upper level in CompileUnit * Move CreateMainFunction method from Compiler to TreeConverter class * Add gppg and parserhelper to visualpascalabcnet dependencies * Updated installer files to include GPPG and UniversalParserHelper * Rename GPPG to ShiftReduceParser * Fix ShiftReduceParser project dependencies * Fix ShiftReduceParserDependencies second iteration * Workaround commit * Update PABCSystem after tests' changes * Refactor ConvertDirectives method * Get rid of legacy standard modules code * Return varBeginOffset and beginOffset calculation to Compiler class Размещение метода в SyntaxTreeToSemanticTreeConverter не целесообразно. В комментарии видимо имелось в виду что-то другое. * Workaround commit * Update PABCSystem after tests' changes * Revert SPython changes Оставляем только изменения связанные с рефакторингом. * Update .gitignore Co-authored-by: Sun Serega <sunserega2@gmail.com> * Resolve a few Sun Serega treds * Delete comments in ParsersController.cs * Replace specific path with path variable in Studio.bat * Add comment in Studio.bat file and return FileName in CompilerError.cs * Fix TreeSubsidiary.cs encoding and sectCore.nsh indents * Return old version of TestRunner.exe * Rename some variables and polish a few methods * Uncomment accidentally commented code * Replace spaces with tabs * Changed dll name from GPPG * Revert "Changed dll name from GPPG" This reverts commit c485cc8cb787809b7e9dfa8a361e75f17ed39893. * Update .gitignore * Delete Libraries/ShiftReduceParser.dll * Delete bin\ShiftReduceParser.dll * Replace tabs with spaces * Update encoding in Studio.bat * Fix bug with PABCrtl excluded files * Refactor StandardModule class * Add null checks to make debuging easier * Delete unnecessary null checks in SymTable.cs --------- Co-authored-by: Владислав Крылов <krylov@sfedu.ru> Co-authored-by: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Co-authored-by: Sun Serega <sunserega2@gmail.com>
2023-12-18 22:33:27 +03:00
// syntax_tree_visitor.AddWarning(new Errors.CommonWarning(StringResources.Get(DirInfosTable[dir].ErrorName), for_node.source_context.file_name, DirInfosTable[dir].SC.begin_position.line_num, DirInfosTable[dir].SC.begin_position.column_num));
2015-05-14 22:35:07 +03:00
//else if (DirInfosTable[dir].ErrorName == "ERROR_IN_CLAUSE_PARAMETERS")
//{
Refactoring of Compiler.cs (#2984) * Add first comments * Finish commenting for Compile and CompileUnit * Write TODO sections * Add a few clarifications * splitted some functions from compile * Written some methods from Compile to functions * Update variable names * Refactor - stage 1 Refactor GetUsesSection and IsPossibleNameSpace * Refactor - stage 2 Rename a few functions and variables * Correct an inaccuracy * Added comments, look through CompileUnit * Rename a few functions and add new comments * Split CompileUnit to Subfunctions Add IsUnitCompiled, IsUnitInPCU, InitializeNewUnit, GetSourceCode, GenSyntaxTree, GenUnitDocumentation, CheckDLLDirectiveOnlyForLibraries, MatchErrorsToBadNodes, CheckIfUnitModule, SetUseDLLForSystemUnits, CompileInterfaceDependencies, CompileCurrentUnitInterface, GetImplementationUsesSection, CompileImplementationDependencies, CompileCurrentUnitImplementation * Added some TODOs * Return uses_unit_in original name Renaming of syntax tree nodes leads to internal compiler errors * Extract GenerateILCode method * Add checking if recompilation needed method Needs to be discussed and revised * Add functions for catch blocks in Compile * Extract building semantic tree method Creating main function to be moved to another class * Rename UnitsSortedList * Edit CompileUnitsFromDelayedList method * Change a few variable names, make CreateRCFile function and add comments * Make code more "user-friendly" * Add TODOs 31.11.23 * Create PrebuildSemanticTreeActionsMethod * Refactor semantic checks section in initialize new unit method * Refactor Adding standard units to uses method * Return file_name and compiler_directives original names to avoid internal compilation errors * Refactor GetReferences Method * Initial refactoring of IncludeNamespaces function * Create three more methods and wrap important code in regions * Add TODO's * Resolve merge conflicts * Add returned value to ConstructSyntaxTree method * Fix UnitsSortedList NotFoundError in PCUWriter * Workaround commit * Update PABCSystem after tests' changes * Rename syntax trees in some methods * Delete CurrentSyntaxUnit variable * Revert unnecessary project files changes * Squashed commit of the following: commit f4d7599f1a39252feac97bd5391f46dfdc25f6f4 Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 22 11:43:29 2023 +0300 added links to identarranger commit 3bd5d33e2b2969884e61a3279ff9c353013b57fe Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 22 11:43:03 2023 +0300 Change extension for verybasic to yavb commit 61294c6e7d405e1c68516cc81d3a109e8a1ee295 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Tue Nov 21 09:33:57 2023 +0300 Change Program Example commit 86971488341ed6bf13c39e13a513d7ac0c51c285 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Tue Nov 21 09:28:59 2023 +0300 Add IndentArranger to Compile commit 2ce50bbbf9db22c4243b247b870f6935ce206d26 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Fri Nov 17 10:00:31 2023 +0300 Add Semicolon After Each Statement commit 796309d340e8d8ba730ff9418fa376f34fb7fd36 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Wed Nov 15 18:49:11 2023 +0300 Add Alpha Version of Python-style If-statement commit 5eb88f946fe8254b4f5c5a56ed0a567b3be51227 Merge: ab4ce5b0 0162b637 Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 15 16:54:26 2023 +0300 Merge branch 'IndentArranger' into VeryBasicLanguage commit ab4ce5b0e32d42004726e3dc45cc0d8a65e53f56 Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 15 16:53:51 2023 +0300 Fixes from seminar commit af74012289d0d08517c13499a2a66cb543fc06d2 Author: Владислав Крылов <krylov@sfedu.ru> Date: Sun Nov 12 18:57:29 2023 +0300 finally working! fully implemented compatibility commit 58a39c313324b468d1eec207ba3f5f6eddf74ef2 Author: Владислав Крылов <krylov@sfedu.ru> Date: Sun Nov 12 11:58:16 2023 +0300 more compatibility with pabc Now verybasic statements translate to pascal compiler added .bat script for autobuilding verybasic commit 0162b6376b8fe970704f26213bf9f0f670dfb12e Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Sun Nov 12 10:06:14 2023 +0300 Update test.txt commit 1b759ab1cd7ee2ffeb14afff0418ddf0f30b0399 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Sun Nov 12 10:05:36 2023 +0300 Add Indent and Unindent Keywords to Generated File commit cabda7f3985651cff2a8740f1a5bdea8fe7ac892 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Fri Nov 10 21:25:52 2023 +0300 Add Generation of Output File commit 306f033d0176ab559e3622b8505427dbe2e0e203 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Thu Nov 9 20:42:18 2023 +0300 Update IndentArranger.sln commit 60c0ceced1aa3a7d2e33de0facb1126e295f43b5 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Thu Nov 9 20:41:22 2023 +0300 Add IndentArranger commit 1f4556c4573dae154fcc167b41ff6ab9e8122136 Author: Владислав Крылов <krylov@sfedu.ru> Date: Mon Nov 6 22:48:36 2023 +0300 Made my own VeryBasicParser project Copied some code from SaushkinParser Tried to compile it and implement into Pascal Doesn't work due to grammatik issue * Squashed commit of the following: commit 4e73d9ac3ffef68312f06a74dc83afffcf3ccbee Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 22 15:08:10 2023 +0300 Fixed GPPG (i think so at least) commit e5cfc220828b37fb2f35e565683019716ec3f0ce Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 22 11:44:27 2023 +0300 Update Compiler.cs commit 4698e2e75a5f3b4f523a8bc7733a50e8abb4fca1 Merge: 22aaf2b2 f4d7599f Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 22 11:43:54 2023 +0300 Merge branch 'IndentArrangerTemp' into VeryBasicLanguage commit f4d7599f1a39252feac97bd5391f46dfdc25f6f4 Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 22 11:43:29 2023 +0300 added links to identarranger commit 3bd5d33e2b2969884e61a3279ff9c353013b57fe Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 22 11:43:03 2023 +0300 Change extension for verybasic to yavb commit 22aaf2b2508278a9ffce525ffed52419bf72c23f Merge: c326174f 61294c6e Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 22 11:26:36 2023 +0300 Merge branch 'IndentArrangerTemp' into VeryBasicLanguage commit 61294c6e7d405e1c68516cc81d3a109e8a1ee295 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Tue Nov 21 09:33:57 2023 +0300 Change Program Example commit 86971488341ed6bf13c39e13a513d7ac0c51c285 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Tue Nov 21 09:28:59 2023 +0300 Add IndentArranger to Compile commit c326174ff5ecccf9c4f76d58aea4653f047af049 Author: Владислав Крылов <krylov@sfedu.ru> Date: Sun Nov 19 15:03:19 2023 +0300 Added UniversalParserHelper and GPPG ShiftReduceParser moved to another project UniversalParserHelper project added, most of it copied from SaushkinParser commit 2ce50bbbf9db22c4243b247b870f6935ce206d26 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Fri Nov 17 10:00:31 2023 +0300 Add Semicolon After Each Statement commit 796309d340e8d8ba730ff9418fa376f34fb7fd36 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Wed Nov 15 18:49:11 2023 +0300 Add Alpha Version of Python-style If-statement commit 5eb88f946fe8254b4f5c5a56ed0a567b3be51227 Merge: ab4ce5b0 0162b637 Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 15 16:54:26 2023 +0300 Merge branch 'IndentArranger' into VeryBasicLanguage commit ab4ce5b0e32d42004726e3dc45cc0d8a65e53f56 Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 15 16:53:51 2023 +0300 Fixes from seminar commit af74012289d0d08517c13499a2a66cb543fc06d2 Author: Владислав Крылов <krylov@sfedu.ru> Date: Sun Nov 12 18:57:29 2023 +0300 finally working! fully implemented compatibility commit 58a39c313324b468d1eec207ba3f5f6eddf74ef2 Author: Владислав Крылов <krylov@sfedu.ru> Date: Sun Nov 12 11:58:16 2023 +0300 more compatibility with pabc Now verybasic statements translate to pascal compiler added .bat script for autobuilding verybasic commit 0162b6376b8fe970704f26213bf9f0f670dfb12e Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Sun Nov 12 10:06:14 2023 +0300 Update test.txt commit 1b759ab1cd7ee2ffeb14afff0418ddf0f30b0399 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Sun Nov 12 10:05:36 2023 +0300 Add Indent and Unindent Keywords to Generated File commit cabda7f3985651cff2a8740f1a5bdea8fe7ac892 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Fri Nov 10 21:25:52 2023 +0300 Add Generation of Output File commit 306f033d0176ab559e3622b8505427dbe2e0e203 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Thu Nov 9 20:42:18 2023 +0300 Update IndentArranger.sln commit 60c0ceced1aa3a7d2e33de0facb1126e295f43b5 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Thu Nov 9 20:41:22 2023 +0300 Add IndentArranger commit 1f4556c4573dae154fcc167b41ff6ab9e8122136 Author: Владислав Крылов <krylov@sfedu.ru> Date: Mon Nov 6 22:48:36 2023 +0300 Made my own VeryBasicParser project Copied some code from SaushkinParser Tried to compile it and implement into Pascal Doesn't work due to grammatik issue * Changed GPPG project NET Framework version, added .dll to gitignore * Adding UniversalParserHelper to project, trying to include VeryBasic * Managed dependencies and got VeryBasicLanguage to work * Change extension of a test program * Rebuild changes What should be added to .gitignore? * Fix bug related to err0524_res_unit.pas * Rebuild Parser * Change Indent and Unindent tokens * Add Symbol Table to ParserABC.y * Change Indent Space Number to 2 * Add While Loop * Add Some Operations to Parser * Make Initialization Node at the Beginning of a program * Create Grammar.txt * Test program added * Add ELIF and SyntaxHighlight * Fix TableSymbol * Add Division * Add Method Call * Add For Loop * Rename SPython Parser Folder * Add documented comments for CompileUnit method * Added Errors to SPython Added Errors.cs Removed link to PABCSaushkinParser Minor fixes * Create default constructor for SourceContext * Move null check of currentUnit to upper level in CompileUnit * Move CreateMainFunction method from Compiler to TreeConverter class * Add gppg and parserhelper to visualpascalabcnet dependencies * Updated installer files to include GPPG and UniversalParserHelper * Rename GPPG to ShiftReduceParser * Fix ShiftReduceParser project dependencies * Fix ShiftReduceParserDependencies second iteration * Workaround commit * Update PABCSystem after tests' changes * Refactor ConvertDirectives method * Get rid of legacy standard modules code * Return varBeginOffset and beginOffset calculation to Compiler class Размещение метода в SyntaxTreeToSemanticTreeConverter не целесообразно. В комментарии видимо имелось в виду что-то другое. * Workaround commit * Update PABCSystem after tests' changes * Revert SPython changes Оставляем только изменения связанные с рефакторингом. * Update .gitignore Co-authored-by: Sun Serega <sunserega2@gmail.com> * Resolve a few Sun Serega treds * Delete comments in ParsersController.cs * Replace specific path with path variable in Studio.bat * Add comment in Studio.bat file and return FileName in CompilerError.cs * Fix TreeSubsidiary.cs encoding and sectCore.nsh indents * Return old version of TestRunner.exe * Rename some variables and polish a few methods * Uncomment accidentally commented code * Replace spaces with tabs * Changed dll name from GPPG * Revert "Changed dll name from GPPG" This reverts commit c485cc8cb787809b7e9dfa8a361e75f17ed39893. * Update .gitignore * Delete Libraries/ShiftReduceParser.dll * Delete bin\ShiftReduceParser.dll * Replace tabs with spaces * Update encoding in Studio.bat * Fix bug with PABCrtl excluded files * Refactor StandardModule class * Add null checks to make debuging easier * Delete unnecessary null checks in SymTable.cs --------- Co-authored-by: Владислав Крылов <krylov@sfedu.ru> Co-authored-by: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Co-authored-by: Sun Serega <sunserega2@gmail.com>
2023-12-18 22:33:27 +03:00
// syntax_tree_visitor.AddWarning(new Errors.CommonWarning(StringResources.Get(DirInfosTable[dir].ErrorName), for_node.source_context.file_name, DirInfosTable[dir].SC.begin_position.line_num, DirInfosTable[dir].SC.begin_position.column_num));
2015-05-14 22:35:07 +03:00
//}
//else
if (DirInfosTable[dir].ErrorName !=null)//== "ERROR_IN_CLAUSE")
{
syntax_tree_visitor.AddWarning(new Errors.CommonWarning(PascalABCCompiler.StringResources.Get(DirInfosTable[dir].ErrorName), for_node.source_context.FileName, DirInfosTable[dir].SC.begin_position.line_num, DirInfosTable[dir].SC.begin_position.column_num));
}
VarInfoContainer Vars = GetVarInfoContainer(VFvis, DirInfosTable[dir].Reductions, DirInfosTable[dir].Privates, syntax_tree_visitor, dir);
//сохраняем контекст
ContextInfo contextInfo = new ContextInfo(syntax_tree_visitor);
string ClassName = syntax_tree_visitor.context.get_free_name("$for_class{0}");
try
{
//создаем и конвертируем класс
SyntaxTree.class_members member;
SyntaxTree.type_declarations Decls = CreateClass(ClassName, out member, Vars);
member.members.Add(CreateMethod("Method", syntax_body, for_node.loop_variable.name, member, Vars));
syntax_tree_visitor.visit(Decls);
}
finally
{
//восстанавливаем контекст
contextInfo.RestoreContext(syntax_tree_visitor);
}
//создаем инициализацию, вызов и финализацию
string ObjName = syntax_tree_visitor.context.get_free_name("$for_obj{0}");
SyntaxTree.dot_node dn = new SyntaxTree.dot_node(new SyntaxTree.ident(ObjName), new SyntaxTree.ident("Method"));
SyntaxTree.statement_list stl = CreateInitPart(ClassName, ObjName, Vars);
stl.subnodes.Add(CreateNestedRegionBorder(true));
stl.subnodes.Add(CreateOMPParallelForCall(dn, for_node.initial_value, for_node.finish_value));
stl.subnodes.Add(CreateNestedRegionBorder(false));
stl.subnodes.AddRange(CreateFinalPart(ObjName, Vars).subnodes);
omp_stmts.statements.AddElement(syntax_tree_visitor.ret.visit(stl));
}
return true;
}
#endregion
#region Распараллеливание секций
internal static statements_list TryConvertSections(statements_list semantic_stmts, SyntaxTree.statement_list syntax_stmts, syntax_tree_visitor syntax_tree_visitor)
{
try
{
location loc = semantic_stmts.location;
statements_list omp_stmts = new statements_list(loc);
statements_list head_stmts = new statements_list(loc);
syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_push(head_stmts);
if (!InParallelSectionCreated)
CreateInParallelVariable(syntax_tree_visitor, out InParallelSection);
//если omp доступен то (выполнять паралельно) иначе (выполнять последовательно операторы)
if_node ifnode = CreateIfCondition(syntax_tree_visitor, omp_stmts, semantic_stmts, loc);
head_stmts.statements.AddElement(ifnode);
//генерим ветку в случае когда доступен omp
if (!GenerateOMPParallelSectionsCall(semantic_stmts, syntax_stmts, omp_stmts, syntax_tree_visitor))
{
syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_pop();
return null;
}
syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_pop();
return head_stmts;
}
catch (OpenMPException e)
{
Exception ex = new Exception(e.ToString());
syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_pop();
syntax_tree_visitor.WarningsList.Add(new OMP_BuildigError(ex, syntax_tree_visitor.get_location(new SyntaxTree.syntax_tree_node(e.SC))));
}
catch (Exception e)
{
syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_pop();
syntax_tree_visitor.WarningsList.Add(new OMP_BuildigError(e, semantic_stmts.location));
}
return null;
}
private static bool GenerateOMPParallelSectionsCall(statements_list stmts, SyntaxTree.statement_list syntax_stmts, statements_list omp_stmts, syntax_tree_visitor syntax_tree_visitor)
{
SyntaxTree.expression_list delegates = new PascalABCCompiler.SyntaxTree.expression_list();
SyntaxTree.statement_list stlInit = new PascalABCCompiler.SyntaxTree.statement_list();
SyntaxTree.statement_list stlFinal = new PascalABCCompiler.SyntaxTree.statement_list();
VarInfoContainer Vars = new VarInfoContainer();
string ClassName = syntax_tree_visitor.context.get_free_name("$section_class{0}");
List<SyntaxTree.statement> Sections = new List<PascalABCCompiler.SyntaxTree.statement>();
foreach (SyntaxTree.statement syntax_statement in syntax_stmts.subnodes)
{
if (syntax_statement is SyntaxTree.empty_statement)
continue; //А зачем? ;-)
if (syntax_statement is SyntaxTree.var_statement)
{
//выдать предупреждение. Это не нормально для параллельных секций
syntax_tree_visitor.visit(syntax_statement as SyntaxTree.var_statement);
}
else
{
//ищем используемые переменные
VarFinderSyntaxVisitor VFvis = new VarFinderSyntaxVisitor(syntax_statement, syntax_tree_visitor.context, false);
SyntaxTree.compiler_directive dir = syntax_tree_visitor.DirectivesToNodesLinks[syntax_stmts];
//if (DirInfosTable[dir].ErrorName == "WARNING_IN_CLAUSE_PARAMETERS_REPEATED_VARS")
Refactoring of Compiler.cs (#2984) * Add first comments * Finish commenting for Compile and CompileUnit * Write TODO sections * Add a few clarifications * splitted some functions from compile * Written some methods from Compile to functions * Update variable names * Refactor - stage 1 Refactor GetUsesSection and IsPossibleNameSpace * Refactor - stage 2 Rename a few functions and variables * Correct an inaccuracy * Added comments, look through CompileUnit * Rename a few functions and add new comments * Split CompileUnit to Subfunctions Add IsUnitCompiled, IsUnitInPCU, InitializeNewUnit, GetSourceCode, GenSyntaxTree, GenUnitDocumentation, CheckDLLDirectiveOnlyForLibraries, MatchErrorsToBadNodes, CheckIfUnitModule, SetUseDLLForSystemUnits, CompileInterfaceDependencies, CompileCurrentUnitInterface, GetImplementationUsesSection, CompileImplementationDependencies, CompileCurrentUnitImplementation * Added some TODOs * Return uses_unit_in original name Renaming of syntax tree nodes leads to internal compiler errors * Extract GenerateILCode method * Add checking if recompilation needed method Needs to be discussed and revised * Add functions for catch blocks in Compile * Extract building semantic tree method Creating main function to be moved to another class * Rename UnitsSortedList * Edit CompileUnitsFromDelayedList method * Change a few variable names, make CreateRCFile function and add comments * Make code more "user-friendly" * Add TODOs 31.11.23 * Create PrebuildSemanticTreeActionsMethod * Refactor semantic checks section in initialize new unit method * Refactor Adding standard units to uses method * Return file_name and compiler_directives original names to avoid internal compilation errors * Refactor GetReferences Method * Initial refactoring of IncludeNamespaces function * Create three more methods and wrap important code in regions * Add TODO's * Resolve merge conflicts * Add returned value to ConstructSyntaxTree method * Fix UnitsSortedList NotFoundError in PCUWriter * Workaround commit * Update PABCSystem after tests' changes * Rename syntax trees in some methods * Delete CurrentSyntaxUnit variable * Revert unnecessary project files changes * Squashed commit of the following: commit f4d7599f1a39252feac97bd5391f46dfdc25f6f4 Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 22 11:43:29 2023 +0300 added links to identarranger commit 3bd5d33e2b2969884e61a3279ff9c353013b57fe Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 22 11:43:03 2023 +0300 Change extension for verybasic to yavb commit 61294c6e7d405e1c68516cc81d3a109e8a1ee295 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Tue Nov 21 09:33:57 2023 +0300 Change Program Example commit 86971488341ed6bf13c39e13a513d7ac0c51c285 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Tue Nov 21 09:28:59 2023 +0300 Add IndentArranger to Compile commit 2ce50bbbf9db22c4243b247b870f6935ce206d26 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Fri Nov 17 10:00:31 2023 +0300 Add Semicolon After Each Statement commit 796309d340e8d8ba730ff9418fa376f34fb7fd36 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Wed Nov 15 18:49:11 2023 +0300 Add Alpha Version of Python-style If-statement commit 5eb88f946fe8254b4f5c5a56ed0a567b3be51227 Merge: ab4ce5b0 0162b637 Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 15 16:54:26 2023 +0300 Merge branch 'IndentArranger' into VeryBasicLanguage commit ab4ce5b0e32d42004726e3dc45cc0d8a65e53f56 Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 15 16:53:51 2023 +0300 Fixes from seminar commit af74012289d0d08517c13499a2a66cb543fc06d2 Author: Владислав Крылов <krylov@sfedu.ru> Date: Sun Nov 12 18:57:29 2023 +0300 finally working! fully implemented compatibility commit 58a39c313324b468d1eec207ba3f5f6eddf74ef2 Author: Владислав Крылов <krylov@sfedu.ru> Date: Sun Nov 12 11:58:16 2023 +0300 more compatibility with pabc Now verybasic statements translate to pascal compiler added .bat script for autobuilding verybasic commit 0162b6376b8fe970704f26213bf9f0f670dfb12e Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Sun Nov 12 10:06:14 2023 +0300 Update test.txt commit 1b759ab1cd7ee2ffeb14afff0418ddf0f30b0399 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Sun Nov 12 10:05:36 2023 +0300 Add Indent and Unindent Keywords to Generated File commit cabda7f3985651cff2a8740f1a5bdea8fe7ac892 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Fri Nov 10 21:25:52 2023 +0300 Add Generation of Output File commit 306f033d0176ab559e3622b8505427dbe2e0e203 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Thu Nov 9 20:42:18 2023 +0300 Update IndentArranger.sln commit 60c0ceced1aa3a7d2e33de0facb1126e295f43b5 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Thu Nov 9 20:41:22 2023 +0300 Add IndentArranger commit 1f4556c4573dae154fcc167b41ff6ab9e8122136 Author: Владислав Крылов <krylov@sfedu.ru> Date: Mon Nov 6 22:48:36 2023 +0300 Made my own VeryBasicParser project Copied some code from SaushkinParser Tried to compile it and implement into Pascal Doesn't work due to grammatik issue * Squashed commit of the following: commit 4e73d9ac3ffef68312f06a74dc83afffcf3ccbee Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 22 15:08:10 2023 +0300 Fixed GPPG (i think so at least) commit e5cfc220828b37fb2f35e565683019716ec3f0ce Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 22 11:44:27 2023 +0300 Update Compiler.cs commit 4698e2e75a5f3b4f523a8bc7733a50e8abb4fca1 Merge: 22aaf2b2 f4d7599f Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 22 11:43:54 2023 +0300 Merge branch 'IndentArrangerTemp' into VeryBasicLanguage commit f4d7599f1a39252feac97bd5391f46dfdc25f6f4 Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 22 11:43:29 2023 +0300 added links to identarranger commit 3bd5d33e2b2969884e61a3279ff9c353013b57fe Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 22 11:43:03 2023 +0300 Change extension for verybasic to yavb commit 22aaf2b2508278a9ffce525ffed52419bf72c23f Merge: c326174f 61294c6e Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 22 11:26:36 2023 +0300 Merge branch 'IndentArrangerTemp' into VeryBasicLanguage commit 61294c6e7d405e1c68516cc81d3a109e8a1ee295 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Tue Nov 21 09:33:57 2023 +0300 Change Program Example commit 86971488341ed6bf13c39e13a513d7ac0c51c285 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Tue Nov 21 09:28:59 2023 +0300 Add IndentArranger to Compile commit c326174ff5ecccf9c4f76d58aea4653f047af049 Author: Владислав Крылов <krylov@sfedu.ru> Date: Sun Nov 19 15:03:19 2023 +0300 Added UniversalParserHelper and GPPG ShiftReduceParser moved to another project UniversalParserHelper project added, most of it copied from SaushkinParser commit 2ce50bbbf9db22c4243b247b870f6935ce206d26 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Fri Nov 17 10:00:31 2023 +0300 Add Semicolon After Each Statement commit 796309d340e8d8ba730ff9418fa376f34fb7fd36 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Wed Nov 15 18:49:11 2023 +0300 Add Alpha Version of Python-style If-statement commit 5eb88f946fe8254b4f5c5a56ed0a567b3be51227 Merge: ab4ce5b0 0162b637 Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 15 16:54:26 2023 +0300 Merge branch 'IndentArranger' into VeryBasicLanguage commit ab4ce5b0e32d42004726e3dc45cc0d8a65e53f56 Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 15 16:53:51 2023 +0300 Fixes from seminar commit af74012289d0d08517c13499a2a66cb543fc06d2 Author: Владислав Крылов <krylov@sfedu.ru> Date: Sun Nov 12 18:57:29 2023 +0300 finally working! fully implemented compatibility commit 58a39c313324b468d1eec207ba3f5f6eddf74ef2 Author: Владислав Крылов <krylov@sfedu.ru> Date: Sun Nov 12 11:58:16 2023 +0300 more compatibility with pabc Now verybasic statements translate to pascal compiler added .bat script for autobuilding verybasic commit 0162b6376b8fe970704f26213bf9f0f670dfb12e Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Sun Nov 12 10:06:14 2023 +0300 Update test.txt commit 1b759ab1cd7ee2ffeb14afff0418ddf0f30b0399 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Sun Nov 12 10:05:36 2023 +0300 Add Indent and Unindent Keywords to Generated File commit cabda7f3985651cff2a8740f1a5bdea8fe7ac892 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Fri Nov 10 21:25:52 2023 +0300 Add Generation of Output File commit 306f033d0176ab559e3622b8505427dbe2e0e203 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Thu Nov 9 20:42:18 2023 +0300 Update IndentArranger.sln commit 60c0ceced1aa3a7d2e33de0facb1126e295f43b5 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Thu Nov 9 20:41:22 2023 +0300 Add IndentArranger commit 1f4556c4573dae154fcc167b41ff6ab9e8122136 Author: Владислав Крылов <krylov@sfedu.ru> Date: Mon Nov 6 22:48:36 2023 +0300 Made my own VeryBasicParser project Copied some code from SaushkinParser Tried to compile it and implement into Pascal Doesn't work due to grammatik issue * Changed GPPG project NET Framework version, added .dll to gitignore * Adding UniversalParserHelper to project, trying to include VeryBasic * Managed dependencies and got VeryBasicLanguage to work * Change extension of a test program * Rebuild changes What should be added to .gitignore? * Fix bug related to err0524_res_unit.pas * Rebuild Parser * Change Indent and Unindent tokens * Add Symbol Table to ParserABC.y * Change Indent Space Number to 2 * Add While Loop * Add Some Operations to Parser * Make Initialization Node at the Beginning of a program * Create Grammar.txt * Test program added * Add ELIF and SyntaxHighlight * Fix TableSymbol * Add Division * Add Method Call * Add For Loop * Rename SPython Parser Folder * Add documented comments for CompileUnit method * Added Errors to SPython Added Errors.cs Removed link to PABCSaushkinParser Minor fixes * Create default constructor for SourceContext * Move null check of currentUnit to upper level in CompileUnit * Move CreateMainFunction method from Compiler to TreeConverter class * Add gppg and parserhelper to visualpascalabcnet dependencies * Updated installer files to include GPPG and UniversalParserHelper * Rename GPPG to ShiftReduceParser * Fix ShiftReduceParser project dependencies * Fix ShiftReduceParserDependencies second iteration * Workaround commit * Update PABCSystem after tests' changes * Refactor ConvertDirectives method * Get rid of legacy standard modules code * Return varBeginOffset and beginOffset calculation to Compiler class Размещение метода в SyntaxTreeToSemanticTreeConverter не целесообразно. В комментарии видимо имелось в виду что-то другое. * Workaround commit * Update PABCSystem after tests' changes * Revert SPython changes Оставляем только изменения связанные с рефакторингом. * Update .gitignore Co-authored-by: Sun Serega <sunserega2@gmail.com> * Resolve a few Sun Serega treds * Delete comments in ParsersController.cs * Replace specific path with path variable in Studio.bat * Add comment in Studio.bat file and return FileName in CompilerError.cs * Fix TreeSubsidiary.cs encoding and sectCore.nsh indents * Return old version of TestRunner.exe * Rename some variables and polish a few methods * Uncomment accidentally commented code * Replace spaces with tabs * Changed dll name from GPPG * Revert "Changed dll name from GPPG" This reverts commit c485cc8cb787809b7e9dfa8a361e75f17ed39893. * Update .gitignore * Delete Libraries/ShiftReduceParser.dll * Delete bin\ShiftReduceParser.dll * Replace tabs with spaces * Update encoding in Studio.bat * Fix bug with PABCrtl excluded files * Refactor StandardModule class * Add null checks to make debuging easier * Delete unnecessary null checks in SymTable.cs --------- Co-authored-by: Владислав Крылов <krylov@sfedu.ru> Co-authored-by: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Co-authored-by: Sun Serega <sunserega2@gmail.com>
2023-12-18 22:33:27 +03:00
// syntax_tree_visitor.AddWarning(new Errors.CommonWarning(StringResources.Get(DirInfosTable[dir].ErrorName), syntax_stmts.source_context.file_name, DirInfosTable[dir].SC.begin_position.line_num, DirInfosTable[dir].SC.begin_position.column_num));
2015-05-14 22:35:07 +03:00
//else if (DirInfosTable[dir].ErrorName == "ERROR_IN_CLAUSE_PARAMETERS")
//{
Refactoring of Compiler.cs (#2984) * Add first comments * Finish commenting for Compile and CompileUnit * Write TODO sections * Add a few clarifications * splitted some functions from compile * Written some methods from Compile to functions * Update variable names * Refactor - stage 1 Refactor GetUsesSection and IsPossibleNameSpace * Refactor - stage 2 Rename a few functions and variables * Correct an inaccuracy * Added comments, look through CompileUnit * Rename a few functions and add new comments * Split CompileUnit to Subfunctions Add IsUnitCompiled, IsUnitInPCU, InitializeNewUnit, GetSourceCode, GenSyntaxTree, GenUnitDocumentation, CheckDLLDirectiveOnlyForLibraries, MatchErrorsToBadNodes, CheckIfUnitModule, SetUseDLLForSystemUnits, CompileInterfaceDependencies, CompileCurrentUnitInterface, GetImplementationUsesSection, CompileImplementationDependencies, CompileCurrentUnitImplementation * Added some TODOs * Return uses_unit_in original name Renaming of syntax tree nodes leads to internal compiler errors * Extract GenerateILCode method * Add checking if recompilation needed method Needs to be discussed and revised * Add functions for catch blocks in Compile * Extract building semantic tree method Creating main function to be moved to another class * Rename UnitsSortedList * Edit CompileUnitsFromDelayedList method * Change a few variable names, make CreateRCFile function and add comments * Make code more "user-friendly" * Add TODOs 31.11.23 * Create PrebuildSemanticTreeActionsMethod * Refactor semantic checks section in initialize new unit method * Refactor Adding standard units to uses method * Return file_name and compiler_directives original names to avoid internal compilation errors * Refactor GetReferences Method * Initial refactoring of IncludeNamespaces function * Create three more methods and wrap important code in regions * Add TODO's * Resolve merge conflicts * Add returned value to ConstructSyntaxTree method * Fix UnitsSortedList NotFoundError in PCUWriter * Workaround commit * Update PABCSystem after tests' changes * Rename syntax trees in some methods * Delete CurrentSyntaxUnit variable * Revert unnecessary project files changes * Squashed commit of the following: commit f4d7599f1a39252feac97bd5391f46dfdc25f6f4 Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 22 11:43:29 2023 +0300 added links to identarranger commit 3bd5d33e2b2969884e61a3279ff9c353013b57fe Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 22 11:43:03 2023 +0300 Change extension for verybasic to yavb commit 61294c6e7d405e1c68516cc81d3a109e8a1ee295 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Tue Nov 21 09:33:57 2023 +0300 Change Program Example commit 86971488341ed6bf13c39e13a513d7ac0c51c285 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Tue Nov 21 09:28:59 2023 +0300 Add IndentArranger to Compile commit 2ce50bbbf9db22c4243b247b870f6935ce206d26 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Fri Nov 17 10:00:31 2023 +0300 Add Semicolon After Each Statement commit 796309d340e8d8ba730ff9418fa376f34fb7fd36 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Wed Nov 15 18:49:11 2023 +0300 Add Alpha Version of Python-style If-statement commit 5eb88f946fe8254b4f5c5a56ed0a567b3be51227 Merge: ab4ce5b0 0162b637 Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 15 16:54:26 2023 +0300 Merge branch 'IndentArranger' into VeryBasicLanguage commit ab4ce5b0e32d42004726e3dc45cc0d8a65e53f56 Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 15 16:53:51 2023 +0300 Fixes from seminar commit af74012289d0d08517c13499a2a66cb543fc06d2 Author: Владислав Крылов <krylov@sfedu.ru> Date: Sun Nov 12 18:57:29 2023 +0300 finally working! fully implemented compatibility commit 58a39c313324b468d1eec207ba3f5f6eddf74ef2 Author: Владислав Крылов <krylov@sfedu.ru> Date: Sun Nov 12 11:58:16 2023 +0300 more compatibility with pabc Now verybasic statements translate to pascal compiler added .bat script for autobuilding verybasic commit 0162b6376b8fe970704f26213bf9f0f670dfb12e Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Sun Nov 12 10:06:14 2023 +0300 Update test.txt commit 1b759ab1cd7ee2ffeb14afff0418ddf0f30b0399 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Sun Nov 12 10:05:36 2023 +0300 Add Indent and Unindent Keywords to Generated File commit cabda7f3985651cff2a8740f1a5bdea8fe7ac892 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Fri Nov 10 21:25:52 2023 +0300 Add Generation of Output File commit 306f033d0176ab559e3622b8505427dbe2e0e203 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Thu Nov 9 20:42:18 2023 +0300 Update IndentArranger.sln commit 60c0ceced1aa3a7d2e33de0facb1126e295f43b5 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Thu Nov 9 20:41:22 2023 +0300 Add IndentArranger commit 1f4556c4573dae154fcc167b41ff6ab9e8122136 Author: Владислав Крылов <krylov@sfedu.ru> Date: Mon Nov 6 22:48:36 2023 +0300 Made my own VeryBasicParser project Copied some code from SaushkinParser Tried to compile it and implement into Pascal Doesn't work due to grammatik issue * Squashed commit of the following: commit 4e73d9ac3ffef68312f06a74dc83afffcf3ccbee Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 22 15:08:10 2023 +0300 Fixed GPPG (i think so at least) commit e5cfc220828b37fb2f35e565683019716ec3f0ce Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 22 11:44:27 2023 +0300 Update Compiler.cs commit 4698e2e75a5f3b4f523a8bc7733a50e8abb4fca1 Merge: 22aaf2b2 f4d7599f Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 22 11:43:54 2023 +0300 Merge branch 'IndentArrangerTemp' into VeryBasicLanguage commit f4d7599f1a39252feac97bd5391f46dfdc25f6f4 Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 22 11:43:29 2023 +0300 added links to identarranger commit 3bd5d33e2b2969884e61a3279ff9c353013b57fe Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 22 11:43:03 2023 +0300 Change extension for verybasic to yavb commit 22aaf2b2508278a9ffce525ffed52419bf72c23f Merge: c326174f 61294c6e Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 22 11:26:36 2023 +0300 Merge branch 'IndentArrangerTemp' into VeryBasicLanguage commit 61294c6e7d405e1c68516cc81d3a109e8a1ee295 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Tue Nov 21 09:33:57 2023 +0300 Change Program Example commit 86971488341ed6bf13c39e13a513d7ac0c51c285 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Tue Nov 21 09:28:59 2023 +0300 Add IndentArranger to Compile commit c326174ff5ecccf9c4f76d58aea4653f047af049 Author: Владислав Крылов <krylov@sfedu.ru> Date: Sun Nov 19 15:03:19 2023 +0300 Added UniversalParserHelper and GPPG ShiftReduceParser moved to another project UniversalParserHelper project added, most of it copied from SaushkinParser commit 2ce50bbbf9db22c4243b247b870f6935ce206d26 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Fri Nov 17 10:00:31 2023 +0300 Add Semicolon After Each Statement commit 796309d340e8d8ba730ff9418fa376f34fb7fd36 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Wed Nov 15 18:49:11 2023 +0300 Add Alpha Version of Python-style If-statement commit 5eb88f946fe8254b4f5c5a56ed0a567b3be51227 Merge: ab4ce5b0 0162b637 Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 15 16:54:26 2023 +0300 Merge branch 'IndentArranger' into VeryBasicLanguage commit ab4ce5b0e32d42004726e3dc45cc0d8a65e53f56 Author: Владислав Крылов <krylov@sfedu.ru> Date: Wed Nov 15 16:53:51 2023 +0300 Fixes from seminar commit af74012289d0d08517c13499a2a66cb543fc06d2 Author: Владислав Крылов <krylov@sfedu.ru> Date: Sun Nov 12 18:57:29 2023 +0300 finally working! fully implemented compatibility commit 58a39c313324b468d1eec207ba3f5f6eddf74ef2 Author: Владислав Крылов <krylov@sfedu.ru> Date: Sun Nov 12 11:58:16 2023 +0300 more compatibility with pabc Now verybasic statements translate to pascal compiler added .bat script for autobuilding verybasic commit 0162b6376b8fe970704f26213bf9f0f670dfb12e Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Sun Nov 12 10:06:14 2023 +0300 Update test.txt commit 1b759ab1cd7ee2ffeb14afff0418ddf0f30b0399 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Sun Nov 12 10:05:36 2023 +0300 Add Indent and Unindent Keywords to Generated File commit cabda7f3985651cff2a8740f1a5bdea8fe7ac892 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Fri Nov 10 21:25:52 2023 +0300 Add Generation of Output File commit 306f033d0176ab559e3622b8505427dbe2e0e203 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Thu Nov 9 20:42:18 2023 +0300 Update IndentArranger.sln commit 60c0ceced1aa3a7d2e33de0facb1126e295f43b5 Author: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Date: Thu Nov 9 20:41:22 2023 +0300 Add IndentArranger commit 1f4556c4573dae154fcc167b41ff6ab9e8122136 Author: Владислав Крылов <krylov@sfedu.ru> Date: Mon Nov 6 22:48:36 2023 +0300 Made my own VeryBasicParser project Copied some code from SaushkinParser Tried to compile it and implement into Pascal Doesn't work due to grammatik issue * Changed GPPG project NET Framework version, added .dll to gitignore * Adding UniversalParserHelper to project, trying to include VeryBasic * Managed dependencies and got VeryBasicLanguage to work * Change extension of a test program * Rebuild changes What should be added to .gitignore? * Fix bug related to err0524_res_unit.pas * Rebuild Parser * Change Indent and Unindent tokens * Add Symbol Table to ParserABC.y * Change Indent Space Number to 2 * Add While Loop * Add Some Operations to Parser * Make Initialization Node at the Beginning of a program * Create Grammar.txt * Test program added * Add ELIF and SyntaxHighlight * Fix TableSymbol * Add Division * Add Method Call * Add For Loop * Rename SPython Parser Folder * Add documented comments for CompileUnit method * Added Errors to SPython Added Errors.cs Removed link to PABCSaushkinParser Minor fixes * Create default constructor for SourceContext * Move null check of currentUnit to upper level in CompileUnit * Move CreateMainFunction method from Compiler to TreeConverter class * Add gppg and parserhelper to visualpascalabcnet dependencies * Updated installer files to include GPPG and UniversalParserHelper * Rename GPPG to ShiftReduceParser * Fix ShiftReduceParser project dependencies * Fix ShiftReduceParserDependencies second iteration * Workaround commit * Update PABCSystem after tests' changes * Refactor ConvertDirectives method * Get rid of legacy standard modules code * Return varBeginOffset and beginOffset calculation to Compiler class Размещение метода в SyntaxTreeToSemanticTreeConverter не целесообразно. В комментарии видимо имелось в виду что-то другое. * Workaround commit * Update PABCSystem after tests' changes * Revert SPython changes Оставляем только изменения связанные с рефакторингом. * Update .gitignore Co-authored-by: Sun Serega <sunserega2@gmail.com> * Resolve a few Sun Serega treds * Delete comments in ParsersController.cs * Replace specific path with path variable in Studio.bat * Add comment in Studio.bat file and return FileName in CompilerError.cs * Fix TreeSubsidiary.cs encoding and sectCore.nsh indents * Return old version of TestRunner.exe * Rename some variables and polish a few methods * Uncomment accidentally commented code * Replace spaces with tabs * Changed dll name from GPPG * Revert "Changed dll name from GPPG" This reverts commit c485cc8cb787809b7e9dfa8a361e75f17ed39893. * Update .gitignore * Delete Libraries/ShiftReduceParser.dll * Delete bin\ShiftReduceParser.dll * Replace tabs with spaces * Update encoding in Studio.bat * Fix bug with PABCrtl excluded files * Refactor StandardModule class * Add null checks to make debuging easier * Delete unnecessary null checks in SymTable.cs --------- Co-authored-by: Владислав Крылов <krylov@sfedu.ru> Co-authored-by: MovchanGitHub <92666028+MovchanGitHub@users.noreply.github.com> Co-authored-by: Sun Serega <sunserega2@gmail.com>
2023-12-18 22:33:27 +03:00
// syntax_tree_visitor.AddWarning(new Errors.CommonWarning(StringResources.Get(DirInfosTable[dir].ErrorName), syntax_stmts.source_context.file_name, DirInfosTable[dir].SC.begin_position.line_num, DirInfosTable[dir].SC.begin_position.column_num));
2015-05-14 22:35:07 +03:00
//}
//else
if (DirInfosTable[dir].ErrorName != null)
{
syntax_tree_visitor.AddWarning(new Errors.CommonWarning(PascalABCCompiler.StringResources.Get(DirInfosTable[dir].ErrorName), syntax_stmts.source_context.FileName, DirInfosTable[dir].SC.begin_position.line_num, DirInfosTable[dir].SC.begin_position.column_num));
}
Vars.UnionWith(GetVarInfoContainer(VFvis, null, DirInfosTable[dir].Privates, syntax_tree_visitor, dir));
Sections.Add(syntax_statement);
}
}
//сохраняем контекст
ContextInfo contextInfo = new ContextInfo(syntax_tree_visitor);
try
{
//создание и конвертирование класса
SyntaxTree.class_members member;
SyntaxTree.type_declarations Decls = CreateClass(ClassName, out member, Vars);
for (int i = 0; i < Sections.Count; ++i)
member.members.Add(CreateMethod("method" + i.ToString(), Sections[i], "", member, Vars));
syntax_tree_visitor.visit(Decls);
}
finally
{
//восстанавливаем контекст
contextInfo.RestoreContext(syntax_tree_visitor);
}
//создаем инициализацию и финализацию
int NameNum = 0;
string ObjName = GetFreeName("$section_obj", ref NameNum, syntax_tree_visitor.context);
stlInit.subnodes.AddRange(CreateInitPart(ClassName, ObjName, Vars).subnodes);
stlFinal.subnodes.AddRange(CreateFinalPart(ObjName, Vars).subnodes);
SyntaxTree.procedure_call pc = new PascalABCCompiler.SyntaxTree.procedure_call();
SyntaxTree.method_call mc = new PascalABCCompiler.SyntaxTree.method_call();
mc.dereferencing_value = CreateTPLFunctionReference("Invoke");
pc.func_name = mc;
SyntaxTree.expression_list exl = new PascalABCCompiler.SyntaxTree.expression_list();
//foreach (string str in ObjNames)
for (int i=0; i<Sections.Count; ++i)
exl.Add(new SyntaxTree.dot_node(new SyntaxTree.ident(ObjName), new SyntaxTree.ident("Method"+i.ToString())));
mc.parameters = exl;
stlInit.subnodes.Add(CreateNestedRegionBorder(true));
stlInit.subnodes.Add(pc);
stlInit.subnodes.AddRange(stlFinal.subnodes);
stlInit.subnodes.Add(CreateNestedRegionBorder(false));
statement_node st = syntax_tree_visitor.ret.visit(stlInit);
omp_stmts.statements.AddElement(st);
return true;
}
#endregion
#region Создание обьектов-функций для параллельных конструкций
/// <summary>
/// Вспомогательная функция - возвращает подстроку между квадратными скобками, при поиске индексеров массива
/// </summary>
/// <param name="type_str"></param>
/// <returns></returns>
private static string get_indexer_string(string type_str)
{
string res = "";
int from = type_str.IndexOf("[");
if (from == -1)
return res;
int to = type_str.IndexOf("]");
if (to == -1)
return res;
res = type_str.Substring(from + 1, to - from - 1);
return res;
}
/// <summary>
/// Возращает диапазоны массива из строки индексеров
/// </summary>
/// <param name="index_str"></param>
/// <returns></returns>
private static List<SyntaxTree.diapason> get_diapasons(string index_str)
{
List<SyntaxTree.diapason> res = new List<PascalABCCompiler.SyntaxTree.diapason>();
string[] diaps = index_str.Split(',');
foreach (string str in diaps)
{
if (str.Trim() == "")
{
res.Add(null);
}
else
{
string left = str.Substring(0, str.IndexOf('.')).Trim();
int from = str.LastIndexOf('.');
string right = str.Substring(from + 1, str.Length - from - 1).Trim();
int val;
SyntaxTree.expression left_expr, right_expr;
if (Int32.TryParse(left, out val))
{
left_expr = new SyntaxTree.int32_const(val);
}
else left_expr = new SyntaxTree.ident(left);
if (Int32.TryParse(right, out val))
{
right_expr = new SyntaxTree.int32_const(val);
}
else right_expr = new SyntaxTree.ident(right);
res.Add(new PascalABCCompiler.SyntaxTree.diapason(left_expr, right_expr));
}
}
return res;
}
/// <summary>
/// Вспомогательная функция - разбивает строку по точкам и возвращает подстроки в виде списка ident-в
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
2018-09-18 21:57:05 +03:00
private static List<SyntaxTree.ident> get_idents_from_dot_string(string s, SyntaxTree.SourceContext sc)
2015-05-14 22:35:07 +03:00
{
List<SyntaxTree.ident> idents = new List<PascalABCCompiler.SyntaxTree.ident>();
string[] strs = s.Split('.');
foreach (string id in strs)
2018-09-18 21:57:05 +03:00
idents.Add(new SyntaxTree.ident(id, sc));
2015-05-14 22:35:07 +03:00
return idents;
}
/// <summary>
/// Возвращает список ident-в, необходимых для генерации named_type_reference
/// </summary>
/// <param name="sem_type">семантический тип</param>
/// <returns></returns>
2018-09-18 21:57:05 +03:00
private static List<SyntaxTree.ident> get_idents_from_generic_type(type_node sem_type, SyntaxTree.SourceContext sc)
2015-05-14 22:35:07 +03:00
{
if (sem_type != null)
{
List<SyntaxTree.ident> idents = null;
if (sem_type.original_generic != null)
2018-09-18 21:57:05 +03:00
idents = get_idents_from_dot_string(sem_type.original_generic.full_name, sc);
2015-05-14 22:35:07 +03:00
return idents;
}
return null;
}
2023-11-12 14:17:38 +03:00
2015-05-14 22:35:07 +03:00
private static SyntaxTree.type_definition get_diapason(type_node sem_type)
{
if (sem_type is compiled_type_node)
2018-09-18 21:57:05 +03:00
return new PascalABCCompiler.SyntaxTree.named_type_reference(get_idents_from_dot_string(sem_type.PrintableName, sem_type.location));
2015-05-14 22:35:07 +03:00
if (sem_type is common_type_node)
{
SyntaxTree.diapason diap = new PascalABCCompiler.SyntaxTree.diapason();
2018-09-18 21:57:05 +03:00
diap.source_context = sem_type.location;
2015-05-14 22:35:07 +03:00
common_type_node ctn = sem_type as common_type_node;
diap.left = ConvertConstant(ctn.low_bound);
diap.right = ConvertConstant(ctn.upper_bound);
return diap;
}
return null;
}
2023-11-12 14:17:38 +03:00
2015-05-14 22:35:07 +03:00
/// <summary>
/// Возвращает по семантическому типу соответсвующий ему синтаксический тип
/// </summary>
/// <param name="sem_type">семантический тип</param>
/// <returns>Синтаксический тип</returns>
public static SyntaxTree.type_definition ConvertToSyntaxType(type_node sem_type)
{
2018-12-29 11:50:22 +03:00
// SSM 29/12/18 для перечислимого типа возвращает null!
2015-05-14 22:35:07 +03:00
if (sem_type.IsPointer)// если указатель
{
SyntaxTree.ref_type rt = new PascalABCCompiler.SyntaxTree.ref_type();
2019-10-03 12:17:27 +03:00
if (sem_type is compiled_type_node)
rt.pointed_to = ConvertToSyntaxType((sem_type as compiled_type_node).element_type);
else
rt.pointed_to = ConvertToSyntaxType((sem_type as ref_type_node).pointed_type);
2015-05-14 22:35:07 +03:00
return rt;
}
else
if (sem_type.type_special_kind == SemanticTree.type_special_kind.none_kind
|| sem_type.type_special_kind == SemanticTree.type_special_kind.record || sem_type.type_special_kind == SemanticTree.type_special_kind.text_file)
2018-09-18 21:45:24 +03:00
{
if (sem_type.is_generic_type_instance)// это шаблонный тип
2015-05-14 22:35:07 +03:00
{
2018-09-18 21:45:24 +03:00
SyntaxTree.template_type_reference ttr = new PascalABCCompiler.SyntaxTree.template_type_reference();
SyntaxTree.named_type_reference ntr = new PascalABCCompiler.SyntaxTree.named_type_reference();
ttr.name = ntr;
2018-09-18 21:57:05 +03:00
ttr.source_context = sem_type.location;
ntr.source_context = ttr.source_context;
ntr.names.AddRange(get_idents_from_generic_type(sem_type, sem_type.location));
2018-09-18 21:45:24 +03:00
SyntaxTree.template_param_list tpl = new PascalABCCompiler.SyntaxTree.template_param_list();
ttr.params_list = tpl;
foreach (type_node tn in sem_type.instance_params)
tpl.params_list.Add(ConvertToSyntaxType(tn));
return ttr;
2015-05-14 22:35:07 +03:00
}
2018-09-18 21:45:24 +03:00
else if (sem_type.IsEnum)
2018-09-18 21:57:05 +03:00
return new PascalABCCompiler.SyntaxTree.named_type_reference(get_idents_from_dot_string(sem_type.name, sem_type.location), sem_type.location);
else if (sem_type is compiled_type_node ctn1 && ctn1.compiled_type == typeof(System.IntPtr))
return new PascalABCCompiler.SyntaxTree.named_type_reference(get_idents_from_dot_string("System.IntPtr", sem_type.location), sem_type.location);
2020-03-13 21:47:56 +03:00
else if (sem_type is compiled_type_node ctn2 && ctn2.compiled_type == typeof(System.UIntPtr))
return new PascalABCCompiler.SyntaxTree.named_type_reference(get_idents_from_dot_string("System.UIntPtr", sem_type.location), sem_type.location);
2023-08-15 15:18:10 +03:00
else if (sem_type is common_type_node && (sem_type as common_type_node).IsDelegate)
{
var tn = sem_type as common_type_node;
var invokeMeth = tn.find_first_in_type("Invoke");
if (invokeMeth != null)
{
var fn = invokeMeth.sym_info as function_node;
PascalABCCompiler.SyntaxTree.procedure_header header;
if (fn.return_value_type != null)
{
header = new PascalABCCompiler.SyntaxTree.function_header(ConvertToSyntaxType(fn.return_value_type));
}
else
{
header = new PascalABCCompiler.SyntaxTree.procedure_header();
}
header.parameters = new PascalABCCompiler.SyntaxTree.formal_parameters();
foreach (var param in fn.parameters)
{
var tparam = new PascalABCCompiler.SyntaxTree.typed_parameters();
tparam.vars_type = ConvertToSyntaxType(param.type);
tparam.idents = new PascalABCCompiler.SyntaxTree.ident_list();
tparam.idents.Add(new PascalABCCompiler.SyntaxTree.ident(param.name));
header.parameters.Add(tparam);
}
return header;
}
else
return new PascalABCCompiler.SyntaxTree.named_type_reference(get_idents_from_dot_string(sem_type.PrintableName, sem_type.location), sem_type.location);
}
2018-09-18 21:45:24 +03:00
else
2018-09-18 21:57:05 +03:00
return new PascalABCCompiler.SyntaxTree.named_type_reference(get_idents_from_dot_string(sem_type.PrintableName, sem_type.location), sem_type.location);
2018-09-18 21:45:24 +03:00
}
else if (sem_type.type_special_kind == SemanticTree.type_special_kind.array_kind || sem_type.type_special_kind == SemanticTree.type_special_kind.array_wrapper)
{
//значит тип-это массив
SyntaxTree.array_type arr_t = new PascalABCCompiler.SyntaxTree.array_type();
arr_t.source_context = sem_type.location;
// Cоздаем индексер для массива
SyntaxTree.indexers_types indt = new PascalABCCompiler.SyntaxTree.indexers_types();
indt.source_context = arr_t.source_context;
if (sem_type is common_type_node)
2015-05-14 22:35:07 +03:00
{
2018-09-18 21:45:24 +03:00
SyntaxTree.diapason diap = new PascalABCCompiler.SyntaxTree.diapason();
2015-05-14 22:35:07 +03:00
2018-09-18 21:45:24 +03:00
common_type_node ctn = sem_type as common_type_node;
if (ctn.constants.Length > 1)
{
diap.left = ConvertConstant(ctn.constants[0].constant_value);
diap.right = ConvertConstant(ctn.constants[1].constant_value);
indt.indexers.Add(diap);
2015-05-14 22:35:07 +03:00
}
2018-09-18 21:45:24 +03:00
else
2015-05-14 22:35:07 +03:00
{
2018-09-18 21:45:24 +03:00
if (ctn.rank == 1)
indt = null;
else
2015-05-14 22:35:07 +03:00
for (int i = 0; i < ctn.rank; i++)
indt.indexers.Add(null);
}
2018-09-18 21:45:24 +03:00
arr_t.indexers = indt;
2015-05-14 22:35:07 +03:00
}
2018-09-18 21:45:24 +03:00
else if (sem_type is compiled_type_node)
2015-05-14 22:35:07 +03:00
{
2018-09-18 21:45:24 +03:00
compiled_type_node ctn = sem_type as compiled_type_node;
if (ctn.rank > 1)
{
for (int i = 0; i < ctn.rank; i++)
indt.indexers.Add(null);
arr_t.indexers = indt;
}
//Получаем индексеры из строки
//string ind_str = sem_type.PrintableName;
//ind_str = get_indexer_string(ind_str);
//if (ind_str.Length != 0)
//{
// indt.indexers.AddRange(get_diapasons(ind_str).ToArray());
// arr_t.indexers = indt;
//}
2015-05-14 22:35:07 +03:00
}
2018-09-18 21:45:24 +03:00
//проверяем тип элементов массива
if (sem_type.element_type != null)
2015-05-14 22:35:07 +03:00
{
2018-09-18 21:45:24 +03:00
arr_t.elements_type = ConvertToSyntaxType(sem_type.element_type);
2015-05-14 22:35:07 +03:00
}
2018-09-18 21:45:24 +03:00
return arr_t;
}
else if (sem_type.type_special_kind == SemanticTree.type_special_kind.typed_file || sem_type.type_special_kind == SemanticTree.type_special_kind.binary_file)
{
SyntaxTree.file_type ft = new PascalABCCompiler.SyntaxTree.file_type();
2018-09-18 21:57:05 +03:00
ft.source_context = sem_type.location;
2018-09-18 21:45:24 +03:00
if (sem_type.element_type != null)
ft.file_of_type = ConvertToSyntaxType(sem_type.element_type);
//SyntaxTree.named_type_reference ntr = null;
//if (sem_type.element_type!= null)
// ntr= new PascalABCCompiler.SyntaxTree.named_type_reference(get_idents_from_dot_string(sem_type.element_type.name));
//ft.file_of_type = ntr;
return ft;
}
else if (sem_type.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.short_string)
{
SyntaxTree.string_num_definition snd = new PascalABCCompiler.SyntaxTree.string_num_definition();
2018-09-18 21:57:05 +03:00
snd.source_context = sem_type.location;
2018-09-18 21:45:24 +03:00
snd.name = new SyntaxTree.ident(sem_type.name.Substring(0, sem_type.name.IndexOf('[')));
snd.num_of_symbols = new SyntaxTree.int32_const(Int32.Parse(get_indexer_string(sem_type.PrintableName)));
return snd;
}
else if (sem_type.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.set_type)
{
SyntaxTree.set_type_definition std = new PascalABCCompiler.SyntaxTree.set_type_definition();
2018-09-18 21:57:05 +03:00
std.source_context = sem_type.location;
2018-09-18 21:45:24 +03:00
if (sem_type.element_type != null)
std.of_type = ConvertToSyntaxType(sem_type.element_type);
return std;
}
else if (sem_type.type_special_kind == SemanticTree.type_special_kind.diap_type)
{
return get_diapason(sem_type);
2015-05-14 22:35:07 +03:00
2018-09-18 21:45:24 +03:00
}
2018-12-29 11:50:22 +03:00
else if (sem_type.type_special_kind == SemanticTree.type_special_kind.enum_kind)
return new SyntaxTree.semantic_type_node(sem_type);
2015-05-14 22:35:07 +03:00
return null;
}
/// <summary>
/// Возвращает ассоциативный массив диапазонов массива из синтаксического узла
/// </summary>
/// <param name="arr">массив-синтаксический узел</param>
/// <returns></returns>
private static Dictionary<int, List<SyntaxTree.diapason>> get_diapasons_from_array(SyntaxTree.array_type arr)
{
if (arr != null)
{
Dictionary<int, List<SyntaxTree.diapason>> res = new Dictionary<int, List<SyntaxTree.diapason>>();
int i = 0;
while (true)
{
if (arr.indexers != null)
{
List<SyntaxTree.diapason> diaps = new List<PascalABCCompiler.SyntaxTree.diapason>();
foreach (SyntaxTree.type_definition td in arr.indexers.indexers)
{
if (td is SyntaxTree.diapason)
diaps.Add(td as SyntaxTree.diapason);
}
res.Add(i, diaps);
}
if (arr.elements_type is SyntaxTree.array_type)
arr = arr.elements_type as SyntaxTree.array_type;
else break;
i++;
}
return res;
}
return null;
}
/// <summary>
/// Возвращает список диапазонов массива из синтаксического узла
/// </summary>
/// <param name="arr">массив-синтаксический узел</param>
/// <returns></returns>
private static List<List<SyntaxTree.diapason>> get_list_of_diapasons(SyntaxTree.array_type arr)
{
if (arr != null)
{
List<List<SyntaxTree.diapason>> res = new List<List<SyntaxTree.diapason>>();
while (true)
{
List<SyntaxTree.diapason> diaps = new List<PascalABCCompiler.SyntaxTree.diapason>();
if (arr.indexers != null)
{
foreach (SyntaxTree.type_definition td in arr.indexers.indexers)
{
diaps.Add(td as SyntaxTree.diapason);
}
}
res.Add(diaps);
if (arr.elements_type is SyntaxTree.array_type)
arr = arr.elements_type as SyntaxTree.array_type;
else break;
}
return res;
}
return null;
}
private static SyntaxTree.statement_list AssignArrs(SyntaxTree.array_type ArrFrom, SyntaxTree.addressed_value IdFrom, SyntaxTree.addressed_value IdTo)
{
SyntaxTree.statement_list OuterSTL = new PascalABCCompiler.SyntaxTree.statement_list();
SyntaxTree.statement_list InnerSTL = OuterSTL;
List<List<SyntaxTree.diapason>> DiapasonsList = get_list_of_diapasons(ArrFrom);
List<List<SyntaxTree.ident>> IdentsList = new List<List<PascalABCCompiler.SyntaxTree.ident>>();
int VarNum = 0;
if (DiapasonsList == null)
DiapasonsList = new List<List<PascalABCCompiler.SyntaxTree.diapason>>();
foreach (List<SyntaxTree.diapason> Diapasons in DiapasonsList)
{
bool IsDynamicArray = false;
List<SyntaxTree.method_call> Lens = new List<PascalABCCompiler.SyntaxTree.method_call>();
if ((Diapasons.Count == 0) || (Diapasons[0] == null))
{
//массив динамический, нужно делать setlength
IsDynamicArray = true;
SyntaxTree.procedure_call SetLenPC = new PascalABCCompiler.SyntaxTree.procedure_call();
SyntaxTree.method_call SetLenMC = new PascalABCCompiler.SyntaxTree.method_call();
SetLenMC.dereferencing_value = new SyntaxTree.ident("SetLength");
SetLenPC.func_name = SetLenMC;
SyntaxTree.expression_list SetLenParamsExl = new PascalABCCompiler.SyntaxTree.expression_list();
SetLenMC.parameters = SetLenParamsExl;
//индексное выражение для массива-приемника
SyntaxTree.addressed_value IndexerTo = IdTo;
foreach (List<SyntaxTree.ident> Idents in IdentsList)
{
SyntaxTree.indexer InnerInd = new PascalABCCompiler.SyntaxTree.indexer();
InnerInd.dereferencing_value = IndexerTo;
SyntaxTree.expression_list IndexersExl = new PascalABCCompiler.SyntaxTree.expression_list();
foreach (SyntaxTree.ident Ident in Idents)
IndexersExl.expressions.Add(new SyntaxTree.ident(Ident.name));
InnerInd.indexes = IndexersExl;
IndexerTo = InnerInd;
}
//индексное выражение для массива-источника
SyntaxTree.addressed_value IndexerFrom = IdFrom;
foreach (List<SyntaxTree.ident> Idents in IdentsList)
{
SyntaxTree.indexer InnerInd = new PascalABCCompiler.SyntaxTree.indexer();
InnerInd.dereferencing_value = IndexerFrom;
SyntaxTree.expression_list IndexersExl = new PascalABCCompiler.SyntaxTree.expression_list();
foreach (SyntaxTree.ident Ident in Idents)
IndexersExl.expressions.Add(new SyntaxTree.ident(Ident.name));
InnerInd.indexes = IndexersExl;
IndexerFrom = InnerInd;
}
SetLenParamsExl.expressions.Add(IndexerTo);
//List<SyntaxTree.method_call> Lengths = new List<PascalABCCompiler.SyntaxTree.method_call>();
if (Diapasons.Count == 0)
{
SyntaxTree.method_call LengthMC = new PascalABCCompiler.SyntaxTree.method_call();
LengthMC.dereferencing_value = new SyntaxTree.ident("Length");
SyntaxTree.expression_list LenMCExl = new PascalABCCompiler.SyntaxTree.expression_list();
LengthMC.parameters = LenMCExl;
LenMCExl.expressions.Add(IndexerFrom);
SetLenParamsExl.expressions.Add(LengthMC);
Lens.Add(LengthMC);
}
else
{
for (int i = 0; i < Diapasons.Count; ++i)
{
SyntaxTree.method_call LengthMC = new PascalABCCompiler.SyntaxTree.method_call();
LengthMC.dereferencing_value = new SyntaxTree.ident("Length");
SyntaxTree.expression_list LenMCExl = new PascalABCCompiler.SyntaxTree.expression_list();
LengthMC.parameters = LenMCExl;
LenMCExl.expressions.Add(IndexerFrom);
LenMCExl.expressions.Add(new SyntaxTree.int32_const(i));
SetLenParamsExl.expressions.Add(LengthMC);
Lens.Add(LengthMC);
}
}
InnerSTL.subnodes.Add(SetLenPC);
}
//к этому моменту вызов SetLength с параметрами сформирован
//в Lens содержатся вызовы length по нужной размерности если массив динамический
//теперь нужно создать циклы for и список переменных, по которым идут циклы
List<SyntaxTree.ident> LoopIdents = new List<SyntaxTree.ident>();
for (int i = 0; i < Math.Max(Diapasons.Count, 1); ++i)
{
SyntaxTree.for_node ForNode = new PascalABCCompiler.SyntaxTree.for_node();
SyntaxTree.ident LoopVar = new PascalABCCompiler.SyntaxTree.ident("$i" + (VarNum++).ToString());
LoopIdents.Add(LoopVar);
ForNode.loop_variable = LoopVar;
ForNode.create_loop_variable = true;
if (IsDynamicArray)
{
ForNode.initial_value = new SyntaxTree.int32_const(0);
ForNode.finish_value = new PascalABCCompiler.SyntaxTree.bin_expr(Lens[i], new SyntaxTree.int32_const(1), PascalABCCompiler.SyntaxTree.Operators.Minus);
}
else
{
ForNode.initial_value = Diapasons[i].left;
ForNode.finish_value = Diapasons[i].right;
}
InnerSTL.subnodes.Add(ForNode);
ForNode.statements = new PascalABCCompiler.SyntaxTree.statement_list();
InnerSTL = ForNode.statements as SyntaxTree.statement_list;
}
IdentsList.Add(LoopIdents);
}
// к этому моменту создано гнездо циклов с установкой длины динамических массивов и перебором
// вообще всех массивов. Осталось создать самое внутреннее присваивание
SyntaxTree.addressed_value AssignIndexerFrom = IdFrom;
SyntaxTree.addressed_value AssignIndexerTo = IdTo;
foreach (List<SyntaxTree.ident> AssignIdents in IdentsList)
{
SyntaxTree.indexer FromIndexer = new PascalABCCompiler.SyntaxTree.indexer();
SyntaxTree.indexer ToIndexer = new PascalABCCompiler.SyntaxTree.indexer();
FromIndexer.dereferencing_value = AssignIndexerFrom;
ToIndexer.dereferencing_value = AssignIndexerTo;
SyntaxTree.expression_list Exl = new PascalABCCompiler.SyntaxTree.expression_list();
foreach (SyntaxTree.ident id in AssignIdents)
Exl.expressions.Add(id);
FromIndexer.indexes = Exl;
ToIndexer.indexes = Exl;
AssignIndexerFrom = FromIndexer;
AssignIndexerTo = ToIndexer;
}
SyntaxTree.assign Assign = new PascalABCCompiler.SyntaxTree.assign();
Assign.from = AssignIndexerFrom;
Assign.to = AssignIndexerTo;
Assign.operator_type = PascalABCCompiler.SyntaxTree.Operators.Assignment;
InnerSTL.subnodes.Add(Assign);
return OuterSTL;
}
/// <summary>
/// По списку диапазонов, определяет динаимеческий или нет. Если нет, то возвращает в ind номер первого непустого диапазона
/// </summary>
/// <param name="diaps">Ассоциативный массив диапазонов</param>
/// <param name="ind">выходной параметр - индекс непустого дипазона. Если динамический массив, то возвращает -1 </param>
/// <returns></returns>
private static bool is_dyn_arr(SyntaxTree.array_type arr)
{
Dictionary<int, List<SyntaxTree.diapason>> diaps = get_diapasons_from_array(arr);
if (diaps == null)
return true;
foreach (int key in diaps.Keys)
{
foreach (SyntaxTree.diapason d in diaps[key])
if (d != null)
{
return false;
}
}
return true;
}
private static SyntaxTree.type_declarations CreateClass(string ClassName,out SyntaxTree.class_members ClassMember, VarInfoContainer Vars)
{
//генерация класса
SyntaxTree.type_declarations TypeDecls = new PascalABCCompiler.SyntaxTree.type_declarations();
SyntaxTree.type_declaration TypeDecl = new PascalABCCompiler.SyntaxTree.type_declaration();
TypeDecls.types_decl.Add(TypeDecl);
TypeDecl.type_name = new PascalABCCompiler.SyntaxTree.ident(ClassName);
SyntaxTree.class_definition ClassDef = new PascalABCCompiler.SyntaxTree.class_definition();
TypeDecl.type_def = ClassDef;
2017-06-06 05:24:32 +03:00
SyntaxTree.class_body_list ClassBody = new PascalABCCompiler.SyntaxTree.class_body_list();
2015-05-14 22:35:07 +03:00
ClassDef.body = ClassBody;
ClassMember = new PascalABCCompiler.SyntaxTree.class_members();
ClassBody.class_def_blocks.Add(ClassMember);
ClassMember.access_mod = new PascalABCCompiler.SyntaxTree.access_modifer_node(PascalABCCompiler.SyntaxTree.access_modifer.public_modifer);
// генерация полей класса
// shared переменные
for (int i = 0; i < Vars.SharedVariables.Count; ++i)
ClassMember.members.Add(CreateClassMember(Vars.SharedVariables[i], ""));
// переменные редукции - с долларовым префиксом
for (int i = 0; i < Vars.ReductionVariables.Count; ++i)
ClassMember.members.Add(CreateClassMember(Vars.ReductionVariables[i], "$"));
return TypeDecls;
}
private static SyntaxTree.procedure_definition CreateMethod(string MethodName, SyntaxTree.statement Body, string LoopVariableName, SyntaxTree.class_members ClassMember, VarInfoContainer Vars)
{
// генерация метода
SyntaxTree.procedure_definition ProcDef = new PascalABCCompiler.SyntaxTree.procedure_definition();
//ClassMember.members.Add(ProcDef);
SyntaxTree.procedure_header ProcHead = new PascalABCCompiler.SyntaxTree.procedure_header();
ProcDef.proc_header = ProcHead;
ProcHead.name = new PascalABCCompiler.SyntaxTree.method_name(null, null, new PascalABCCompiler.SyntaxTree.ident(MethodName), null);
if (LoopVariableName != "")
{
// параметр, счетчик цикла
string ParamType = "integer";
SyntaxTree.formal_parameters FormalParams = new PascalABCCompiler.SyntaxTree.formal_parameters();
ProcHead.parameters = FormalParams;
SyntaxTree.typed_parameters TypedParams = new PascalABCCompiler.SyntaxTree.typed_parameters();
FormalParams.params_list.Add(TypedParams);
SyntaxTree.ident_list idl = new PascalABCCompiler.SyntaxTree.ident_list();
TypedParams.idents = idl;
idl.Add(new SyntaxTree.ident(LoopVariableName));
SyntaxTree.named_type_reference ntr = new PascalABCCompiler.SyntaxTree.named_type_reference();
TypedParams.vars_type = ntr;
ntr.Add(new SyntaxTree.ident(ParamType));
}
SyntaxTree.block ProcBlock = new PascalABCCompiler.SyntaxTree.block();
ProcDef.proc_body = ProcBlock;
ProcBlock.defs = new PascalABCCompiler.SyntaxTree.declarations();
if (Vars.Constants.Count > 0)
{
SyntaxTree.consts_definitions_list cdl = new PascalABCCompiler.SyntaxTree.consts_definitions_list();
ProcBlock.defs.defs.Add(cdl);
// константы - в методе
for (int i = 0; i < Vars.Constants.Count; ++i)
cdl.Add(CreateClassMember(Vars.Constants[i], "") as SyntaxTree.typed_const_definition);
}
if ((Vars.ReductionVariables.Count > 0) || (Vars.PrivateVariables.Count > 0))
{
// переменные редукции - в методе тоже, но без префикса
SyntaxTree.variable_definitions vds = new PascalABCCompiler.SyntaxTree.variable_definitions();
ProcBlock.defs.defs.Add(vds);
for (int i = 0; i < Vars.ReductionVariables.Count; ++i)
vds.Add(CreateClassMember(Vars.ReductionVariables[i], "") as SyntaxTree.var_def_statement);
// и приватные переменные
for (int i = 0; i < Vars.PrivateVariables.Count; ++i)
vds.Add(CreateClassMember(Vars.PrivateVariables[i], "") as SyntaxTree.var_def_statement);
}
if (Body is SyntaxTree.statement_list)
ProcBlock.program_code = Body as SyntaxTree.statement_list;
else
{
SyntaxTree.statement_list stl = new PascalABCCompiler.SyntaxTree.statement_list();
stl.subnodes.Add(Body);
ProcBlock.program_code = stl;
}
//присваивания для переменных редукции
if (Vars.ReductionVariables.Count > 0)
{
SyntaxTree.statement_list LoopBodyInit = new PascalABCCompiler.SyntaxTree.statement_list();
SyntaxTree.statement_list LoopBodyFinal = new PascalABCCompiler.SyntaxTree.statement_list();
for (int i = 0; i < Vars.ReductionVariables.Count; ++i)
{
//присваивание начального значения
SyntaxTree.assign Assign = new PascalABCCompiler.SyntaxTree.assign();
Assign.operator_type = PascalABCCompiler.SyntaxTree.Operators.Assignment;
Assign.to = new SyntaxTree.ident(Vars.ReductionVariables[i].name);
bool isBool = Vars.ReductionVariables[i].type.name.ToLower() == "boolean";
switch (Vars.ReductionActions[i])
{
case ReductionOperations.and:
{
if (isBool)
Assign.from = new SyntaxTree.bool_const(true);
else
{
//отрицание нуля
Assign.from = new SyntaxTree.int32_const(0);
LoopBodyInit.subnodes.Add(Assign);
Assign = new PascalABCCompiler.SyntaxTree.assign();
Assign.operator_type = PascalABCCompiler.SyntaxTree.Operators.Assignment;
Assign.to = new SyntaxTree.ident(Vars.ReductionVariables[i].name);
SyntaxTree.un_expr ue = new PascalABCCompiler.SyntaxTree.un_expr();
ue.operation_type = PascalABCCompiler.SyntaxTree.Operators.LogicalNOT;
ue.subnode = new SyntaxTree.ident(Vars.ReductionVariables[i].name);
Assign.from = ue;
}
break;
}
case ReductionOperations.or:
if (isBool)
Assign.from = new SyntaxTree.bool_const(false);
else
{
Assign.from = new SyntaxTree.int32_const(0);
}
break;
case ReductionOperations.xor: //
case ReductionOperations.plus: //см следующую ветку
case ReductionOperations.minus: Assign.from = new SyntaxTree.int32_const(0); break;
case ReductionOperations.mult: Assign.from = new SyntaxTree.int32_const(1); break;
}
LoopBodyInit.Add(Assign);
//присваивание после итерации
Assign = new PascalABCCompiler.SyntaxTree.assign();
Assign.operator_type = PascalABCCompiler.SyntaxTree.Operators.Assignment;
Assign.to = new SyntaxTree.ident("$" + Vars.ReductionVariables[i].name);
SyntaxTree.bin_expr From = new PascalABCCompiler.SyntaxTree.bin_expr();
From.left = new SyntaxTree.ident("$" + Vars.ReductionVariables[i].name);
From.right = new SyntaxTree.ident(Vars.ReductionVariables[i].name);
Assign.from = From;
switch (Vars.ReductionActions[i])
{
case ReductionOperations.and: From.operation_type = PascalABCCompiler.SyntaxTree.Operators.LogicalAND; break;
case ReductionOperations.or: From.operation_type = PascalABCCompiler.SyntaxTree.Operators.LogicalOR; break;
case ReductionOperations.xor: From.operation_type = PascalABCCompiler.SyntaxTree.Operators.BitwiseXOR; break;
case ReductionOperations.plus: From.operation_type = PascalABCCompiler.SyntaxTree.Operators.Plus; break;
case ReductionOperations.minus: From.operation_type = PascalABCCompiler.SyntaxTree.Operators.Minus; break;
case ReductionOperations.mult: From.operation_type = PascalABCCompiler.SyntaxTree.Operators.Multiplication; break;
}
LoopBodyFinal.Add(Assign);
}
//создаем обьект для блокировки в классе
SyntaxTree.var_def_statement Lvds = new PascalABCCompiler.SyntaxTree.var_def_statement();
SyntaxTree.ident_list Lidl = new PascalABCCompiler.SyntaxTree.ident_list();
Lvds.vars = Lidl;
Lidl.Add(new SyntaxTree.ident("$ReductionLock"));
SyntaxTree.named_type_reference Lntr = new PascalABCCompiler.SyntaxTree.named_type_reference();
Lvds.vars_type = Lntr;
Lntr.Add(new SyntaxTree.ident("object"));
SyntaxTree.new_expr Lne = new PascalABCCompiler.SyntaxTree.new_expr();
Lvds.inital_value = Lne;
Lne.type = Lntr;
ClassMember.members.Add(Lvds);
//создаем lock Statement на обьекте с присваиваниями в конце итерации
SyntaxTree.lock_stmt reductionLock = new PascalABCCompiler.SyntaxTree.lock_stmt();
reductionLock.lock_object = new SyntaxTree.ident("$ReductionLock");
reductionLock.stmt = LoopBodyFinal;
//собираем все вместе и присваиваем это телу процедуры
LoopBodyInit.subnodes.AddRange(ProcBlock.program_code.subnodes);
LoopBodyInit.subnodes.Add(reductionLock);
ProcBlock.program_code = LoopBodyInit;
}
return ProcDef;
}
private static SyntaxTree.declaration CreateClassMember(SemanticTree.IDefinitionNode Def, string Prefix)
{
if (Def is SemanticTree.IConstantDefinitionNode)
{
SemanticTree.IConstantDefinitionNode ConstDef = Def as SemanticTree.IConstantDefinitionNode;
SyntaxTree.typed_const_definition tcd = new PascalABCCompiler.SyntaxTree.typed_const_definition();
tcd.const_name = new PascalABCCompiler.SyntaxTree.ident(Prefix + ConstDef.name);
tcd.const_type = ConvertToSyntaxType(ConstDef.type as type_node);
tcd.const_value = ConvertConstant(ConstDef.constant_value);
return tcd;
}
else
{
SemanticTree.IVAriableDefinitionNode VarDef = Def as SemanticTree.IVAriableDefinitionNode;
SyntaxTree.var_def_statement vds = new PascalABCCompiler.SyntaxTree.var_def_statement();
SyntaxTree.ident_list idl = new PascalABCCompiler.SyntaxTree.ident_list();
vds.vars = idl;
idl.Add(new SyntaxTree.ident(Prefix + VarDef.name));
vds.vars_type = ConvertToSyntaxType(VarDef.type as type_node);
return vds;
}
}
private static SyntaxTree.statement_list CreateInitPart(string ClassName, string ObjName, VarInfoContainer Vars)
{
SyntaxTree.statement_list stl = new PascalABCCompiler.SyntaxTree.statement_list();
//Var Statement - объявление экземпляра обьекта-функции
SyntaxTree.var_statement ClassVar = new PascalABCCompiler.SyntaxTree.var_statement();
stl.subnodes.Add(ClassVar);
SyntaxTree.var_def_statement ClassVarDef = new PascalABCCompiler.SyntaxTree.var_def_statement();
ClassVar.var_def = ClassVarDef;
SyntaxTree.ident_list ClassIdl = new PascalABCCompiler.SyntaxTree.ident_list();
ClassVarDef.vars = ClassIdl;
ClassIdl.idents.Add(new PascalABCCompiler.SyntaxTree.ident(ObjName));
SyntaxTree.named_type_reference ClassTypeNTR = new PascalABCCompiler.SyntaxTree.named_type_reference();
ClassVarDef.vars_type = ClassTypeNTR;
ClassTypeNTR.names.Add(new PascalABCCompiler.SyntaxTree.ident(ClassName));
SyntaxTree.new_expr ClassInitNE = new PascalABCCompiler.SyntaxTree.new_expr();
ClassVarDef.inital_value = ClassInitNE;
SyntaxTree.named_type_reference ClassInitNTR = new PascalABCCompiler.SyntaxTree.named_type_reference();
ClassInitNE.type = ClassInitNTR;
ClassInitNTR.names.Add(new PascalABCCompiler.SyntaxTree.ident(ClassName));
//создаем присваивания разделяемым переменным
for (int i = 0; i < Vars.SharedVariables.Count; ++i)
{
string VarName = Vars.SharedVariables[i].name;
SyntaxTree.dot_node DotNode = new PascalABCCompiler.SyntaxTree.dot_node();
DotNode.left = new SyntaxTree.ident(ObjName);
DotNode.right = new SyntaxTree.ident(VarName);
SyntaxTree.array_type arrType = ConvertToSyntaxType(Vars.SharedVariables[i].type as type_node) as SyntaxTree.array_type;
if (arrType != null && !is_dyn_arr(arrType))
{
stl.subnodes.Add(AssignArrs(arrType, new SyntaxTree.ident(VarName), DotNode));
}
else
{
SyntaxTree.assign Assign = new PascalABCCompiler.SyntaxTree.assign();
Assign.operator_type = PascalABCCompiler.SyntaxTree.Operators.Assignment;
Assign.from = new SyntaxTree.ident(VarName);
Assign.to = DotNode;
stl.subnodes.Add(Assign);
}
}
//создаем присваивания переменным редукции
for (int i = 0; i < Vars.ReductionVariables.Count; ++i)
{
string VarName = Vars.ReductionVariables[i].name;
SyntaxTree.dot_node DotNode = new PascalABCCompiler.SyntaxTree.dot_node();
DotNode.left = new SyntaxTree.ident(ObjName);
DotNode.right = new SyntaxTree.ident("$" + VarName);
SyntaxTree.array_type arrType = ConvertToSyntaxType(Vars.ReductionVariables[i].type as type_node) as SyntaxTree.array_type;
if (arrType != null && !is_dyn_arr(arrType))
{
stl.subnodes.Add(AssignArrs(arrType, new SyntaxTree.ident(VarName), DotNode));
}
else
{
SyntaxTree.assign Assign = new PascalABCCompiler.SyntaxTree.assign();
Assign.operator_type = PascalABCCompiler.SyntaxTree.Operators.Assignment;
Assign.from = new SyntaxTree.ident(VarName);
Assign.to = DotNode;
stl.subnodes.Add(Assign);
}
}
return stl;
}
private static SyntaxTree.statement_list CreateFinalPart(string ObjName, VarInfoContainer Vars)
{
SyntaxTree.statement_list stl = new PascalABCCompiler.SyntaxTree.statement_list();
//создаем присваивания разделяемым переменным
for (int i = 0; i < Vars.SharedVariables.Count; ++i)
{
string VarName = Vars.SharedVariables[i].name;
if (LoopVariables.Contains(VarName.ToLower()))
continue;
SyntaxTree.dot_node DotNode = new PascalABCCompiler.SyntaxTree.dot_node();
DotNode.left = new SyntaxTree.ident(ObjName);
DotNode.right = new SyntaxTree.ident(VarName);
SyntaxTree.array_type arrType = ConvertToSyntaxType(Vars.SharedVariables[i].type as type_node) as SyntaxTree.array_type;
if (arrType != null && !is_dyn_arr(arrType))
{
stl.subnodes.Add(AssignArrs(arrType, DotNode, new SyntaxTree.ident(VarName)));
}
else
{
SyntaxTree.assign Assign = new PascalABCCompiler.SyntaxTree.assign();
Assign.operator_type = PascalABCCompiler.SyntaxTree.Operators.Assignment;
Assign.to = new SyntaxTree.ident(VarName);
Assign.from = DotNode;
stl.subnodes.Add(Assign);
}
}
//создаем присваивания переменным редукции
for (int i = 0; i < Vars.ReductionVariables.Count; ++i)
{
string VarName = Vars.ReductionVariables[i].name;
SyntaxTree.dot_node DotNode = new PascalABCCompiler.SyntaxTree.dot_node();
DotNode.left = new SyntaxTree.ident(ObjName);
DotNode.right = new SyntaxTree.ident("$" + VarName);
SyntaxTree.array_type arrType = ConvertToSyntaxType(Vars.ReductionVariables[i].type as type_node) as SyntaxTree.array_type;
if (arrType != null && !is_dyn_arr(arrType))
{
stl.subnodes.Add(AssignArrs(arrType, DotNode, new SyntaxTree.ident(VarName)));
}
else
{
SyntaxTree.assign Assign = new PascalABCCompiler.SyntaxTree.assign();
Assign.operator_type = PascalABCCompiler.SyntaxTree.Operators.Assignment;
Assign.to = new SyntaxTree.ident(VarName);
Assign.from = DotNode;
stl.subnodes.Add(Assign);
}
}
return stl;
}
private static SyntaxTree.procedure_call CreateOMPParallelForCall(SyntaxTree.dot_node dn, SyntaxTree.expression FromInclusive, SyntaxTree.expression ToInclusive)
{
SyntaxTree.procedure_call pc = new PascalABCCompiler.SyntaxTree.procedure_call();
SyntaxTree.method_call mc = new PascalABCCompiler.SyntaxTree.method_call();
pc.func_name = mc;
mc.dereferencing_value = CreateTPLFunctionReference("For");
//Здесь прибавляем единицу ко второму параметру, так как в паскале верхняя граница включается, а в parallel.for - нет
SyntaxTree.bin_expr ToExclusive = new SyntaxTree.bin_expr();
ToExclusive.left = ToInclusive;
ToExclusive.right = new SyntaxTree.int32_const(1);
ToExclusive.operation_type = SyntaxTree.Operators.Plus;
mc.parameters = new PascalABCCompiler.SyntaxTree.expression_list();
mc.parameters.Add(FromInclusive);
mc.parameters.Add(ToExclusive);
mc.parameters.Add(dn);
return pc;
}
private static if_node CreateIfCondition(syntax_tree_visitor syntax_tree_visitor, statements_list ifthen, statements_list ifelse, location loc)
{
//сохраняем контекст
ContextInfo contextInfo = new ContextInfo(syntax_tree_visitor);
if_node res = null;
try
{
SyntaxTree.if_node if_node = new PascalABCCompiler.SyntaxTree.if_node();
SyntaxTree.un_expr une = new PascalABCCompiler.SyntaxTree.un_expr();
une.operation_type = SyntaxTree.Operators.LogicalNOT;
une.subnode = new SyntaxTree.ident(InParallelSection);
if_node.condition = une;
if_node.then_body = new SyntaxTree.empty_statement();
if_node.then_body = new SyntaxTree.empty_statement();
res = syntax_tree_visitor.convert_strong(if_node) as if_node;
res.then_body = ifthen;
res.else_body = ifelse;
res.location = loc;
}
finally
{
//восстанавливаем контекст
contextInfo.RestoreContext(syntax_tree_visitor);
}
return res;
}
private static SyntaxTree.dot_node CreateTPLFunctionReference(string FunctionName)
{
//Создаем конструкцию вида "System.Threading.Tasks.Parallel.<FunctionName>"
SyntaxTree.dot_node dn1 = new SyntaxTree.dot_node();
dn1.left = new SyntaxTree.ident("System");
dn1.right = new SyntaxTree.ident("Threading");
SyntaxTree.dot_node dn2 = new SyntaxTree.dot_node();
dn2.right = new SyntaxTree.ident("Tasks");
dn2.left = dn1;
SyntaxTree.dot_node dn3 = new SyntaxTree.dot_node();
dn3.right = new SyntaxTree.ident("Parallel");
dn3.left = dn2;
SyntaxTree.dot_node Result = new SyntaxTree.dot_node();
Result.right = new SyntaxTree.ident(FunctionName);
Result.left = dn3;
return Result;
}
private static void CreateInParallelVariable(syntax_tree_visitor syntax_tree_visitor, out string VarName)
{
//сохраняем контекст
ContextInfo contextInfo = new ContextInfo(syntax_tree_visitor);
VarName = "$InParallelSection";
try
{
//создание и конвертирование переменной
SyntaxTree.var_def_statement vds = new PascalABCCompiler.SyntaxTree.var_def_statement();
SyntaxTree.variable_definitions var_def = new PascalABCCompiler.SyntaxTree.variable_definitions(vds, null);
SyntaxTree.ident_list idl = new PascalABCCompiler.SyntaxTree.ident_list();
vds.vars = idl;
idl.Add(new SyntaxTree.ident(VarName));
SyntaxTree.named_type_reference ntr = new PascalABCCompiler.SyntaxTree.named_type_reference();
vds.vars_type = ntr;
ntr.names.Add(new PascalABCCompiler.SyntaxTree.ident("boolean"));
vds.inital_value = new PascalABCCompiler.SyntaxTree.ident("false");
syntax_tree_visitor.visit(var_def);
}
finally
{
//восстанавливаем контекст
contextInfo.RestoreContext(syntax_tree_visitor);
}
InParallelSectionCreated = true;
}
private static SyntaxTree.if_node CreateNestedRegionBorder(bool ifEnter)
{
SyntaxTree.if_node result = new PascalABCCompiler.SyntaxTree.if_node();
SyntaxTree.un_expr ue = new PascalABCCompiler.SyntaxTree.un_expr();
ue.operation_type = PascalABCCompiler.SyntaxTree.Operators.LogicalNOT;
ue.subnode = new SyntaxTree.ident(StringConstants.OMP_NESTED);
2015-05-14 22:35:07 +03:00
result.condition = ue;
SyntaxTree.assign AssignInParVar = new PascalABCCompiler.SyntaxTree.assign();
AssignInParVar.operator_type = PascalABCCompiler.SyntaxTree.Operators.Assignment;
AssignInParVar.from = new SyntaxTree.ident(ifEnter ? "true" : "false");
AssignInParVar.to = new SyntaxTree.ident(InParallelSection);
result.then_body = AssignInParVar;
return result;
}
private static SyntaxTree.expression ConvertConstant(SemanticTree.IConstantNode value)
{
if (value is bool_const_node)
return new SyntaxTree.ident((value as bool_const_node).constant_value ? "true" : "false");
else if (value is null_const_node)
return new SyntaxTree.nil_const();
else if (value is byte_const_node)
return new SyntaxTree.int32_const((value as byte_const_node).constant_value);
else if (value is char_const_node)
return new SyntaxTree.char_const((value as char_const_node).constant_value);
else if (value is double_const_node)
return new SyntaxTree.double_const((value as double_const_node).constant_value);
else if (value is float_const_node)
return new SyntaxTree.double_const((value as float_const_node).constant_value);
else if (value is int_const_node)
return new SyntaxTree.int32_const((value as int_const_node).constant_value);
else if (value is long_const_node)
return new SyntaxTree.int64_const((value as long_const_node).constant_value);
else if (value is sbyte_const_node)
return new SyntaxTree.int32_const((value as sbyte_const_node).constant_value);
else if (value is short_const_node)
return new SyntaxTree.int32_const((value as short_const_node).constant_value);
else if (value is uint_const_node)
return new SyntaxTree.uint64_const((value as uint_const_node).constant_value);
else if (value is ulong_const_node)
return new SyntaxTree.uint64_const((value as ulong_const_node).constant_value);
else if (value is ushort_const_node)
return new SyntaxTree.int32_const((value as ushort_const_node).constant_value);
else if (value is string_const_node)
return new SyntaxTree.string_const((value as string_const_node).constant_value);
else if (value is array_const)
{
array_const ac = value as array_const;
SyntaxTree.expression_list el = new PascalABCCompiler.SyntaxTree.expression_list();
for (int i = 0; i < ac.element_values.Count; ++i)
el.Add(ConvertConstant(ac.element_values[i]));
SyntaxTree.array_const synAC = new PascalABCCompiler.SyntaxTree.array_const();
synAC.elements = el;
return synAC;
}
else if (value is enum_const_node)
{
//Есть сомнения, что будет работать во всех случаях
enum_const_node ec = value as enum_const_node;
SyntaxTree.ident r = new SyntaxTree.ident((ec.type as common_type_node).const_defs[ec.constant_value].name);
SyntaxTree.ident l = new SyntaxTree.ident(ec.type.name);
return new SyntaxTree.dot_node(l, r);
}
else if (value is record_constant)
{
record_constant rc = value as record_constant;
SyntaxTree.record_const synRC = new PascalABCCompiler.SyntaxTree.record_const();
for (int i = 0; i < rc.field_values.Count; ++i)
{
SyntaxTree.record_const_definition rcd = new PascalABCCompiler.SyntaxTree.record_const_definition();
rcd.name = rc.record_const_definition_list[i].name;
rcd.val = rc.record_const_definition_list[i].val;
synRC.rec_consts.Add(rcd);
}
return synRC;
}
else
throw new Exception("Не реализовано"); //выяснить, что тут может быть
}
/// <summary>
/// выдает свободное имя
/// </summary>
/// <param name="template">шаблон</param>
/// <param name="StartFrom">перебирать имена, приписывая к шаблону числа начиная с этой позиции. После того как найдет - возвращает следующее число</param>
/// <param name="context">контекст, в котором искать</param>
/// <returns>первое свободное имя</returns>
private static string GetFreeName(string template, ref int StartFrom, compilation_context context)
{
string name;
while (context.CurrentScope.Find((name = string.Format(template + StartFrom.ToString(), StartFrom++))) != null)
;
return name;
}
private static VarInfoContainer GetVarInfoContainer(VarFinderSyntaxVisitor VFVis, List<ReductionDirective> Reductions, List<string> PrivateVars, syntax_tree_visitor visitor, SyntaxTree.compiler_directive dir)
{
if (Reductions == null)
Reductions = new List<ReductionDirective>();
if (PrivateVars == null)
PrivateVars = new List<string>();
VarInfoContainer Result = new VarInfoContainer();
//константы копируются сразу
Result.Constants = VFVis.Constants;
//список переменных для редукции
//ищем переменные с такими именами, проверяем их наличие, тип и если все хорошо - добавляем в список
foreach (ReductionDirective rd in Reductions)
foreach (string rdVarName in rd.variables)
{
if (LoopVariables.Contains(rdVarName))
{
visitor.AddWarning(new PascalABCCompiler.Errors.CommonWarning(String.Format(PascalABCCompiler.StringResources.Get("OMPERROR_REDUCTION_WITH_LOOPVAR_{0}"), rdVarName), visitor.CurrentDocument, dir.source_context.begin_position.line_num, dir.source_context.begin_position.column_num));
2015-05-14 22:35:07 +03:00
continue;
}
SymbolInfo si = visitor.context.find_first(rdVarName);
2015-05-14 22:35:07 +03:00
if (si == null)
{
visitor.AddWarning(new PascalABCCompiler.Errors.CommonWarning(String.Format(PascalABCCompiler.StringResources.Get("OMPERROR_UNKNOWN_VARNAME_{0}"), rdVarName), visitor.CurrentDocument, dir.source_context.begin_position.line_num, dir.source_context.begin_position.column_num));
2015-05-14 22:35:07 +03:00
continue;
}
if (!(si.sym_info is SemanticTree.IVAriableDefinitionNode))
2015-05-14 22:35:07 +03:00
{
visitor.AddWarning(new PascalABCCompiler.Errors.CommonWarning(String.Format(PascalABCCompiler.StringResources.Get("OMPERROR_NAME_IS_NOT_VAR_{0}"), rdVarName), visitor.CurrentDocument, dir.source_context.begin_position.line_num, dir.source_context.begin_position.column_num));
2015-05-14 22:35:07 +03:00
continue;
}
if (!IsValidVarForReduction(si.sym_info as SemanticTree.IVAriableDefinitionNode))
2015-05-14 22:35:07 +03:00
{
visitor.AddWarning(new PascalABCCompiler.Errors.CommonWarning(String.Format(PascalABCCompiler.StringResources.Get("OMPERROR_IS_NOT_POSSIBLE_REDUCTION_WITH_THIS_VAR_{0}"), rdVarName), visitor.CurrentDocument, dir.source_context.begin_position.line_num, dir.source_context.begin_position.column_num));
2015-05-14 22:35:07 +03:00
continue;
}
Result.ReductionVariables.Add(si.sym_info as SemanticTree.IVAriableDefinitionNode);
2015-05-14 22:35:07 +03:00
Result.ReductionActions.Add(rd.Oper);
//for (int i = 0; i < VFVis.Variables.Count; ++i)
// if (VFVis.Variables[i].name.ToLower() == rdVarName.ToLower())
// {
// Result.ReductionVariables.Add(VFVis.Variables[i]);
// Result.ReductionActions.Add(rd.Oper);
// break;
// }
}
//приватные переменные - аналогично, но без проверки на тип
foreach (string privateVar in PrivateVars)
{
SymbolInfo si = visitor.context.find_first(privateVar);
2015-05-14 22:35:07 +03:00
if (si == null)
{
visitor.AddWarning(new PascalABCCompiler.Errors.CommonWarning(String.Format(PascalABCCompiler.StringResources.Get("OMPERROR_UNKNOWN_VARNAME_{0}"), privateVar), visitor.CurrentDocument, dir.source_context.begin_position.line_num, dir.source_context.begin_position.column_num));
2015-05-14 22:35:07 +03:00
continue;
}
if (!(si.sym_info is SemanticTree.IVAriableDefinitionNode))
2015-05-14 22:35:07 +03:00
{
visitor.AddWarning(new PascalABCCompiler.Errors.CommonWarning(String.Format(PascalABCCompiler.StringResources.Get("OMPERROR_NAME_IS_NOT_VAR_{0}"), privateVar), visitor.CurrentDocument, dir.source_context.begin_position.line_num, dir.source_context.begin_position.column_num));
2015-05-14 22:35:07 +03:00
continue;
}
Result.PrivateVariables.Add(si.sym_info as SemanticTree.IVAriableDefinitionNode);
2015-05-14 22:35:07 +03:00
}
//по всем переменным:
//если она не приватная и по ней нет редукции - переписываем ее в список разделяемых
foreach (SemanticTree.IVAriableDefinitionNode var in VFVis.Variables)
{
bool NotShared = false;
foreach (SemanticTree.IVAriableDefinitionNode rdn in Result.ReductionVariables)
if (rdn.name.ToLower() == var.name.ToLower())
{
NotShared = true;
break;
}
if (!NotShared)
foreach (SemanticTree.IVAriableDefinitionNode prVar in Result.PrivateVariables)
if (prVar.name.ToLower() == var.name.ToLower())
{
NotShared = true;
break;
}
if (!NotShared)
Result.SharedVariables.Add(var);
}
return Result;
}
private static bool IsValidVarForReduction(SemanticTree.IVAriableDefinitionNode var)
{
//допустимые типы:
//shortint byte smallint word integer longword int64 uint64 single real
//+ страховка на случай наличия записей вида "type integer = object"
if (var.type.type_special_kind != PascalABCCompiler.SemanticTree.type_special_kind.none_kind)
return false;
if (var.type.is_class)
return false;
return ((var.type.name.ToLower() == "shortint")
|| (var.type.name.ToLower() == "byte")
|| (var.type.name.ToLower() == "smallint")
|| (var.type.name.ToLower() == "integer")
|| (var.type.name.ToLower() == "longword")
|| (var.type.name.ToLower() == "word")
|| (var.type.name.ToLower() == "int64")
|| (var.type.name.ToLower() == "uint64")
|| (var.type.name.ToLower() == "single")
|| (var.type.name.ToLower() == "real")
|| (var.type.name.ToLower() == "boolean"));
}
#endregion
}
}