pascalabcnet/TreeConverter/TreeConversion/LambdaHelper.cs

555 lines
28 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 System.Linq;
using PascalABCCompiler.TreeRealization;
using System.Collections;
using PascalABCCompiler.SyntaxTree;
using TreeConverter.LambdaExpressions;
namespace PascalABCCompiler.TreeConverter
{
#region Визитор поиска имен переменных (для поиска захваченных переменных в теле лямбды)
public class FindMainIdentsVisitor : WalkingVisitorNew // SSM
2015-05-14 22:35:07 +03:00
{
public ISet<ident> vars = new HashSet<ident>();
public override void visit(ident id)
{
vars.Add(id);
}
public override void visit(dot_node dn)
{
ProcessNode(dn.left);
if (dn.right.GetType()!=typeof(ident))
ProcessNode(dn.right);
}
}
#endregion
#region Визитор поиска имен локальных переменных
public class FindLocalDefsVisitor : WalkingVisitorNew // SSM
2015-05-14 22:35:07 +03:00
{
public ISet<string> vars = new HashSet<string>();
private bool indef = false;
public override void visit(ident id)
{
if (indef)
vars.Add(id.name);
}
public override void visit(SyntaxTree.var_statement defs)
{
indef = true;
ProcessNode(defs.var_def.vars); // исключаем типы -
// просматриваем только имена переменных
2015-05-14 22:35:07 +03:00
indef = false;
}
}
#endregion
public class LambdaHelper
{
public static string lambdaPrefix = "<>lambda";
private const string nonPublicMembersNamePrefix = "<>nonPublic";
private const string auxiliaryLambdaSuffix = "_$$$auxiliaryFuncName";
private const string auxVarNamePrefix = "$$$auxVar$$$<>";
private static int auxCounter = 0;
private static int nonPublicMembersNameCounter = 0;
private static int auxVarCounter = 0;
public static string GetAuxVarName()
{
return auxVarNamePrefix + auxVarCounter++;
}
public static string GetAuxiliaryLambdaName(string lambdaName)
{
return lambdaName + auxiliaryLambdaSuffix + auxCounter++;
}
public static string GetNameForNonPublicMember(string memberName)
{
return nonPublicMembersNamePrefix + memberName + nonPublicMembersNameCounter++;
}
public static string GetLambdaNamePartWithoutGenerics(string name)
{
if (!name.StartsWith(lambdaPrefix))
{
return name;
}
var ind = name.IndexOf("<", lambdaPrefix.Length);
if (ind < 0)
{
return name;
}
return name.Substring(0, ind);
}
public static void RemoveLambdaInfoFromCompilationContext(compilation_context context, function_lambda_definition lambdaDefinition)
{
if (context.converted_namespace != null
&& context.converted_namespace.functions != null
&& context.converted_namespace.functions.Any())
// Если добавилось в глобальные функции, то удаляем оттуда
{
var lastIndex = context.converted_namespace.functions.Count - 1;
if (context.converted_namespace.functions[lastIndex].name ==
lambdaDefinition.lambda_name)
{
context.converted_namespace.functions.remove_at(lastIndex);
}
}
2016-04-27 13:14:04 +03:00
//else SSM 27/04/16 - грубое исправление ошибки #147
2015-05-14 22:35:07 +03:00
{
// Если добавилась лямбда как метод класса, то удаляем оттуда
if (context.converted_type != null
&& context.converted_type.methods != null
&& context.converted_type.methods.Any())
{
var lastIndex = context.converted_type.methods.Count - 1;
if (context.converted_type.methods[lastIndex].name ==
lambdaDefinition.lambda_name)
{
context.converted_type.methods.remove_at(lastIndex);
}
}
}
}
public static type_definition ConvertSemanticTypeToSyntaxType(type_node semType)
{
2018-12-29 11:50:22 +03:00
// SSM 29/12/18 пробую скомбинировать
//if (semType is compiled_type_node && !(semType as compiled_type_node).is_generic_type_definition && !(semType as compiled_type_node).is_generic_type_instance)
//return new semantic_type_node(semType); // SSM 29/12/18 поменял на современное. Не получилось!
//else
2018-07-15 01:58:21 +03:00
return OpenMP.ConvertToSyntaxType(semType); // Это же надо! Пользоваться для этого хреновиной из OpenMP!!!
2015-05-14 22:35:07 +03:00
}
public static int processingLambdaParametersForTypeInference = 0; // Счетчик для подсчета лямбд
public static bool IsLambdaName(ident id)
{
if (id == null)
return false;
if (id.name == null)
return false;
return id.name.Contains(lambdaPrefix);
}
public static bool IsLambdaName(string id)
{
if (id == null)
return false;
return id.Contains(lambdaPrefix);
}
2018-08-09 21:34:01 +03:00
public static bool IsCapturedSelf(expression_node ex)
{
if (ex is class_field_reference)
{
class_field fld = (ex as class_field_reference).field;
if (fld.name.Contains("<>local_variables_class"))
return true;
}
return false;
}
2015-05-14 22:35:07 +03:00
public static bool IsAuxiliaryLambdaName(ident id)
{
if (id == null)
return false;
if (id.name == null)
return false;
return id.name.Contains(auxiliaryLambdaSuffix);
}
public static bool IsAuxiliaryLambdaName(string id)
{
if (id == null)
return false;
return id.Contains(auxiliaryLambdaSuffix);
}
public static Stack<KeyValuePair<string, statement_list_stack>> StatementListStackStack = new Stack<KeyValuePair<string, statement_list_stack>>();
public static void Reset()
{
CurrentLambdaScopeNum = -1;
capturedVariables = new List<SymbolInfo>();
2015-05-14 22:35:07 +03:00
captureCheck = false;
processingLambdaParametersForTypeInference = 0;
StatementListStackStack.Clear();
auxCounter = 0;
nonPublicMembersNameCounter = 0;
auxVarCounter = 0;
}
public static bool captureCheck = false;
public static List<SymbolInfo> capturedVariables = new List<SymbolInfo>();
2015-05-14 22:35:07 +03:00
public static int CurrentLambdaScopeNum = -1;
/// <summary>
/// Фиктивный блок, представляющий лямбда-выражение. Используется для обхода с целью получения списка захватываемых переменных
/// </summary>
/// <param name="lambdaDef"></param>
/// <returns></returns>
public static block CreateFictiveBlockForLambda(function_lambda_definition lambdaDef)
{
statement_list stmtList = new statement_list();
if (lambdaDef.formal_parameters != null)
for (int i = 0; i < lambdaDef.formal_parameters.params_list.Count; i++)
stmtList.subnodes.Add(SyntaxTreeNodesConstructor.CreateVarStatementNode(lambdaDef.formal_parameters.params_list[i].idents,
lambdaDef.formal_parameters.params_list[i].vars_type,
null));
if (lambdaDef.return_type != null)
stmtList.subnodes.Add(SyntaxTreeNodesConstructor.CreateVarStatementNode("result", lambdaDef.return_type, null)); // переделать, не сработает, если тип возвращаемого значения не указан
stmtList.subnodes.AddRange((lambdaDef.proc_body as statement_list).subnodes);
block resBlock = new block();
resBlock.program_code = stmtList;
return resBlock;
}
/// <summary>
/// Вывод типа возвращаемого значения лямбды
/// </summary>
public static void InferResultType(function_header funcHeader, proc_block procBody, syntax_tree_visitor visitor)
{
var retType = funcHeader.return_type as lambda_inferred_type;
if (retType != null && retType.real_type is lambda_any_type_node)
retType.real_type = new LambdaResultTypeInferrer(funcHeader, procBody, visitor).InferResultType();
}
2016-07-28 00:19:44 +03:00
/// <summary>
/// Заменяет x -> begin result := x.Print end; на x -> begin x.Print end в случае если это один оператор и вызов метода
///
/// </summary>
public static bool TryConvertFuncLambdaBodyWithMethodCallToProcLambdaBody(function_lambda_definition lambdaDef)
{
2016-12-12 21:57:41 +03:00
// SSM 12/12/16 - сделал чтобы всегда эта функция возвращала true.
// Посмотрю далее на её поведение. Мне кажется, что если мы попали сюда, то мы хотим присвоить процедурному типу,
// и в любом случае это надо интерпретировать как процедуру
2016-07-28 00:19:44 +03:00
var stl = lambdaDef.proc_body as SyntaxTree.statement_list;
if (stl.expr_lambda_body)
{
2016-12-12 21:57:41 +03:00
// Очищаем от Result := , который мы создали на предыдущем этапе
2016-07-28 00:19:44 +03:00
var ass = stl.list[0] as assign;
if (ass != null && ass.to is ident && (ass.to as ident).name.ToLower() == "result")
{
var f = ass.from;
if (f is method_call)
{
var ff = f as method_call;
stl.list[0] = new procedure_call(ff, ff.source_context); // заменить result := Print(x) на Print(x)
lambdaDef.return_type = null;
return true;
}
2016-12-12 21:57:41 +03:00
else
return false;
2016-07-28 00:19:44 +03:00
}
2019-06-27 08:56:39 +03:00
else
return false; // Т.е. это - лямбда с коротким телом, но в результате сахарных преобразований Result := переменстился не на первое место - тогда преобразовать нельзя
2016-07-28 00:19:44 +03:00
}
2016-12-12 21:57:41 +03:00
lambdaDef.return_type = null;
return true;
// return false;
2016-07-28 00:19:44 +03:00
}
2015-05-14 22:35:07 +03:00
/// <summary>
/// Вывод типа параметров лямбд и типа возвращаемого значения при присваивании лямбды переменной
/// </summary>
2021-01-06 14:11:41 +03:00
public static void InferTypesFromVarStmt(type_node leftType, function_lambda_definition lambdaDef, syntax_tree_visitor visitor, Operators op = Operators.Undefined)
2015-05-14 22:35:07 +03:00
{
if (lambdaDef == null)
return;
if (leftType != null)
{
delegate_internal_interface dii_left =
(delegate_internal_interface)leftType.get_internal_interface(internal_interface_kind.delegate_interface);
if (dii_left == null)
2017-08-10 20:58:48 +03:00
{
if (leftType != SystemLibrary.SystemLibrary.system_delegate_type)
2021-01-06 14:11:41 +03:00
{
if (op != Operators.Undefined)
{
var sil = leftType.find_in_type(name_reflector.get_name(op));
2021-01-06 14:37:03 +03:00
if (sil != null && sil.Count > 0)
2021-01-06 14:11:41 +03:00
{
foreach (SymbolInfo si in sil)
{
if (si.sym_info is function_node)
{
function_node fn = si.sym_info as function_node;
if (fn.parameters.Count == 2)
{
dii_left = (delegate_internal_interface)fn.parameters[1].type.get_internal_interface(internal_interface_kind.delegate_interface);
if (dii_left != null)
break;
if (fn.parameters[1].type.is_generic_parameter)
{
compiled_type_node ctn = leftType as compiled_type_node;
common_type_node ctn2 = leftType as common_type_node;
if (ctn != null && ctn.is_generic_type_instance && fn.parameters[0].type.is_generic_type_instance && ctn.original_generic == fn.parameters[0].type.original_generic)
{
dii_left = (delegate_internal_interface)ctn.generic_params[0].get_internal_interface(internal_interface_kind.delegate_interface);
if (dii_left != null)
break;
}
if (ctn2 != null && ctn2.is_generic_type_instance && ctn2.instance_params.Count > 0 && fn.parameters[0].type.is_generic_type_instance && ctn2.original_generic == fn.parameters[0].type.original_generic)
{
dii_left = (delegate_internal_interface)ctn2.instance_params[0].get_internal_interface(internal_interface_kind.delegate_interface);
if (dii_left != null)
break;
}
}
}
}
}
}
}
if (dii_left == null)
visitor.AddError(visitor.get_location(lambdaDef), "ILLEGAL_LAMBDA_VARIABLE_TYPE");
}
2017-08-10 20:58:48 +03:00
else
return;
}
2015-05-14 22:35:07 +03:00
int leftTypeParamsNumber = dii_left.parameters.Count;
int lambdaDefParamsCount = 0;
if (lambdaDef.formal_parameters != null && lambdaDef.formal_parameters.params_list.Count != 0)
{
for (int i = 0; i < lambdaDef.formal_parameters.params_list.Count; i++)
lambdaDefParamsCount += lambdaDef.formal_parameters.params_list[i].idents.idents.Count;
if (lambdaDefParamsCount != leftTypeParamsNumber)
visitor.AddError(visitor.get_location(lambdaDef), "ILLEGAL_LAMBDA_PARAMETERS_NUMBER");
bool flag = true;
SyntaxTree.formal_parameters lambdaDefParamsTypes = new formal_parameters();
for (int i = 0; i < lambdaDef.formal_parameters.params_list.Count; i++)
for (int j = 0; j < lambdaDef.formal_parameters.params_list[i].idents.idents.Count; j++)
{
var param = new SyntaxTree.typed_parameters();
param.idents = new ident_list();
param.idents.Add(lambdaDef.formal_parameters.params_list[i].idents.idents[j]);
param.vars_type = lambdaDef.formal_parameters.params_list[i].vars_type;
2018-09-18 22:25:33 +03:00
param.source_context = lambdaDef.formal_parameters.source_context;
2015-05-14 22:35:07 +03:00
lambdaDefParamsTypes.Add(param);
}
for (int i = 0; i < leftTypeParamsNumber && flag; i++)
{
if (lambdaDefParamsTypes.params_list[i].vars_type is SyntaxTree.lambda_inferred_type)
{
if ((lambdaDefParamsTypes.params_list[i].vars_type as SyntaxTree.lambda_inferred_type).real_type is lambda_any_type_node)
{
var curLeftParType = dii_left.parameters[i].type;
lambdaDefParamsTypes.params_list[i].vars_type = new SyntaxTree.lambda_inferred_type();
(lambdaDefParamsTypes.params_list[i].vars_type as SyntaxTree.lambda_inferred_type).real_type = curLeftParType;
continue;
}
}
var lambdaPar = visitor.convert_strong(lambdaDefParamsTypes.params_list[i].vars_type);
if (!convertion_data_and_alghoritms.eq_type_nodes(dii_left.parameters[i].type, lambdaPar))
{
visitor.AddError(visitor.get_location(lambdaDef), "ILLEGAL_LAMBDA_VARIABLE_TYPE");
}
}
lambdaDef.formal_parameters = lambdaDefParamsTypes;
}
if (lambdaDef.return_type != null && lambdaDef.return_type is lambda_inferred_type)
{
if (dii_left.return_value_type != null)
(lambdaDef.return_type as lambda_inferred_type).real_type = dii_left.return_value_type;
2016-07-23 10:14:13 +03:00
else // SSM 23/07/16 - попытка бороться с var p: Shape->() := a->a.Print()
{
// lambdaDef.usedkeyword == 1 // function
var b = lambdaDef.usedkeyword == 0 && TryConvertFuncLambdaBodyWithMethodCallToProcLambdaBody(lambdaDef); // пытаться конвертировать только если мы явно не указали, что это функция
2016-07-28 00:19:44 +03:00
if (!b)
2019-06-23 14:43:27 +03:00
visitor.AddError(visitor.get_location(lambdaDef), "UNABLE_TO_CONVERT_FUNCTIONAL_TYPE_TO_PROCEDURAL_TYPE");
2016-07-23 10:14:13 +03:00
}
2015-05-14 22:35:07 +03:00
}
}
else
{
if (lambdaDef.formal_parameters != null)
for (int i = 0; i < lambdaDef.formal_parameters.params_list.Count; i++)
if (lambdaDef.formal_parameters.params_list[i].vars_type is lambda_inferred_type)
visitor.AddError(visitor.get_location(lambdaDef), "IMPOSSIBLE_TO_INFER_TYPES_IN_LAMBDA");
}
}
/// <summary>
/// Временный узел, который используется при выведении типов параметров
/// </summary>
/// <param name="def"></param>
/// <param name="visitor"></param>
/// <returns></returns>
public static typed_expression GetTempFunctionNodeForTypeInference(SyntaxTree.function_lambda_definition def, syntax_tree_visitor visitor)
{
2017-02-22 23:15:54 +03:00
var res = new common_namespace_function_node(def.lambda_name, visitor.get_location(def), null, null);
2015-05-14 22:35:07 +03:00
if (def.return_type != null)
res.return_value_type = visitor.convert_strong(def.return_type);
else
res.return_value_type = null;
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
res.parameters.Clear();
2015-05-14 22:35:07 +03:00
if (def.formal_parameters != null && def.formal_parameters.params_list.Count != 0)
{
for (int i = 0; i < def.formal_parameters.params_list.Count; i++)
2018-12-29 11:50:22 +03:00
{
var tt = visitor.convert_strong(def.formal_parameters.params_list[i].vars_type); // SSM 29/12/18
2015-05-14 22:35:07 +03:00
for (int j = 0; j < def.formal_parameters.params_list[i].idents.idents.Count; j++)
{
2017-02-22 23:15:54 +03:00
var new_param = new common_parameter(null, SemanticTree.parameter_type.value, res, concrete_parameter_type.cpt_none, visitor.get_location(def.formal_parameters.params_list[i].idents.idents[0]));
2018-12-29 11:50:22 +03:00
new_param.type = tt;
2015-05-14 22:35:07 +03:00
res.parameters.AddElement(new_param);
}
2018-12-29 11:50:22 +03:00
}
2015-05-14 22:35:07 +03:00
}
var hhh = new delegated_methods();
2017-02-22 23:15:54 +03:00
hhh.proper_methods.AddElement(new common_namespace_function_call(res, visitor.get_location(def)));
return new typed_expression(hhh, visitor.get_location(def));
2015-05-14 22:35:07 +03:00
}
public static procedure_definition ConvertLambdaNodeToProcDefNode(function_lambda_definition functionLambdaDef)
{
procedure_definition procDef = null;
if (functionLambdaDef.return_type == null)
2018-09-18 21:45:24 +03:00
procDef = SyntaxTreeNodesConstructor.CreateProcedureDefinitionNode(new method_name(null,null, new ident(functionLambdaDef.lambda_name, functionLambdaDef.source_context), null),
2015-05-14 22:35:07 +03:00
functionLambdaDef.formal_parameters,
false,
false,
functionLambdaDef.proc_body,
functionLambdaDef.source_context);
else
procDef = SyntaxTreeNodesConstructor.CreateFunctionDefinitionNode(new method_name(null, null, new ident(functionLambdaDef.lambda_name), null),
functionLambdaDef.formal_parameters,
false,
false,
functionLambdaDef.proc_body,
functionLambdaDef.return_type,
functionLambdaDef.source_context);
procDef.proc_header.name.meth_name.source_context = procDef.proc_header.source_context;
functionLambdaDef.proc_definition = procDef;
return procDef;
}
#region Поиск всех result - ов
public class ResultNodesSearcher : SyntaxTree.WalkingVisitorNew // Нигде в проекте не используется потому что expr могут использовать локальные переменные, тип которых неизвестен до семантического разбора
2015-05-14 22:35:07 +03:00
{
public List<expression> exprList = new List<expression>();
public ResultNodesSearcher(syntax_tree_node root)
{
ProcessNode(root);
}
2019-06-30 08:41:59 +03:00
public override void visit(function_lambda_definition fd)
{
// не заходить во внутренние лямбды
}
2015-05-14 22:35:07 +03:00
public override void visit(assign value)
{
var to = value.to as ident;
if (to != null && value.operator_type == Operators.Assignment && to.name.ToLower() == "result")
{
exprList.Add(value.from);
}
}
2019-06-19 18:53:05 +03:00
/*public override void visit(function_lambda_definition fld)
{
}*/
2015-05-14 22:35:07 +03:00
}
#endregion
/*
2015-05-14 22:35:07 +03:00
#region Генерация новых узлов синтаксического дерева
/// <summary>
/// Класс для генерации новых узлов синтаксического дерева
/// </summary>
public class SyntaxTreeNodesConstructor
{
public static var_statement CreateVarStatementNode(string idName, type_definition varType, expression initValue)
{
var id = new ident(idName);
var idlist = new ident_list(id);
2015-05-14 22:35:07 +03:00
var vdef = new var_def_statement(idlist, varType, initValue, definition_attribute.None, false, null);
return new var_statement(vdef, null);
}
public static var_statement CreateVarStatementNode(string idName, string varTypeName, expression initValue)
{
var id = new ident(idName);
var idlist = new ident_list(id);
2015-05-14 22:35:07 +03:00
var varType = new named_type_reference(varTypeName, null);
var vdef = new var_def_statement(idlist, varType, initValue, definition_attribute.None, false, null);
return new var_statement(vdef, null);
}
public static var_statement CreateVarStatementNode(ident_list idlist, type_definition varType, expression initValue)
{
var vdef = new var_def_statement(idlist, varType, initValue, definition_attribute.None, false, null);
return new var_statement(vdef, null);
}
public static procedure_definition CreateProcedureDefinitionNode(method_name methName, formal_parameters formalPars, bool ofObject, bool classKeyword, statement procBody, SourceContext sc)
{
procedure_definition procDef = new procedure_definition();
procedure_header procHeader = new procedure_header();
procHeader.name = methName;
procHeader.source_context = sc;
if (procHeader.name.meth_name is template_type_name)
{
procHeader.template_args = (procHeader.name.meth_name as template_type_name).template_args;
ident id = new ident(procHeader.name.meth_name.name);
procHeader.name.meth_name = id;
}
procHeader.parameters = formalPars;
procHeader.of_object = ofObject;
procHeader.class_keyword = classKeyword;
statement_list stmtList = new statement_list();
stmtList.subnodes.Add(procBody);
block bl = new block(null, null);
bl.program_code = stmtList;
procDef.proc_header = procHeader;
procDef.proc_body = (proc_block)bl;
return procDef;
}
public static procedure_definition CreateFunctionDefinitionNode(method_name methName, formal_parameters formalPars, bool ofObject, bool classKeyword, statement procBody, type_definition returnType, SourceContext sc)
{
procedure_definition procDef = new procedure_definition();
function_header procHeader = new function_header();
procHeader.name = methName;
procHeader.source_context = sc;
if (procHeader.name.meth_name is template_type_name)
{
procHeader.template_args = (procHeader.name.meth_name as template_type_name).template_args;
ident id = new ident(procHeader.name.meth_name.name);
procHeader.name.meth_name = id;
}
procHeader.parameters = formalPars;
procHeader.of_object = ofObject;
procHeader.class_keyword = classKeyword;
procHeader.return_type = returnType;
statement_list stmtList = new statement_list();
stmtList.subnodes.Add(procBody);
block bl = new block(null, null);
bl.program_code = stmtList;
procDef.proc_header = procHeader;
procDef.proc_body = (proc_block)bl;
return procDef;
}
}
#endregion
*/
2015-05-14 22:35:07 +03:00
}
}